summaryrefslogtreecommitdiffstats
path: root/sys/amd64
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2015-01-26 21:41:54 +0000
committerdim <dim@FreeBSD.org>2015-01-26 21:41:54 +0000
commita53e4d44d0463dae21283fdb3ca61a1e38df799f (patch)
tree6f5baa0292e962bb69dc0020ada66d60ea578642 /sys/amd64
parentc9e57e45aceb65bdac0c758538375582075c8a97 (diff)
parent191df99881cad772b533cb8ad72897ab307efdb9 (diff)
downloadFreeBSD-src-a53e4d44d0463dae21283fdb3ca61a1e38df799f.zip
FreeBSD-src-a53e4d44d0463dae21283fdb3ca61a1e38df799f.tar.gz
Merge ^/head r277719 through 277776.
Diffstat (limited to 'sys/amd64')
-rw-r--r--sys/amd64/amd64/machdep.c38
1 files changed, 25 insertions, 13 deletions
diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c
index 07378fdd..839da01 100644
--- a/sys/amd64/amd64/machdep.c
+++ b/sys/amd64/amd64/machdep.c
@@ -1355,8 +1355,10 @@ add_physmap_entry(uint64_t base, uint64_t length, vm_paddr_t *physmap,
/*
* Find insertion point while checking for overlap. Start off by
* assuming the new entry will be added to the end.
+ *
+ * NB: physmap_idx points to the next free slot.
*/
- insert_idx = physmap_idx + 2;
+ insert_idx = physmap_idx;
for (i = 0; i <= physmap_idx; i += 2) {
if (base < physmap[i + 1]) {
if (base + length <= physmap[i]) {
@@ -1394,7 +1396,7 @@ add_physmap_entry(uint64_t base, uint64_t length, vm_paddr_t *physmap,
* Move the last 'N' entries down to make room for the new
* entry if needed.
*/
- for (i = physmap_idx; i > insert_idx; i -= 2) {
+ for (i = (physmap_idx - 2); i > insert_idx; i -= 2) {
physmap[i] = physmap[i - 2];
physmap[i + 1] = physmap[i - 1];
}
@@ -1580,23 +1582,27 @@ getmemsize(caddr_t kmdp, u_int64_t first)
int page_counter;
bzero(physmap, sizeof(physmap));
- basemem = 0;
physmap_idx = 0;
init_ops.parse_memmap(kmdp, physmap, &physmap_idx);
+ physmap_idx -= 2;
/*
* Find the 'base memory' segment for SMP
*/
basemem = 0;
for (i = 0; i <= physmap_idx; i += 2) {
- if (physmap[i] == 0x00000000) {
+ if (physmap[i] <= 0xA0000) {
basemem = physmap[i + 1] / 1024;
break;
}
}
- if (basemem == 0)
- panic("BIOS smap did not include a basemem segment!");
+ if (basemem == 0 || basemem > 640) {
+ if (bootverbose)
+ printf(
+ "Memory map doesn't contain a basemem segment, faking it");
+ basemem = 640;
+ }
/*
* Make hole for "AP -> long mode" bootstrap code. The
@@ -1604,8 +1610,12 @@ getmemsize(caddr_t kmdp, u_int64_t first)
* is configured to support APs and APs for the system start
* in 32bit mode (e.g. SMP bare metal).
*/
- if (init_ops.mp_bootaddress)
+ if (init_ops.mp_bootaddress) {
+ if (physmap[1] >= 0x100000000)
+ panic(
+ "Basemem segment is not suitable for AP bootstrap code!");
physmap[1] = init_ops.mp_bootaddress(physmap[1] / 1024);
+ }
/*
* Maxmem isn't the "maximum memory", it's one larger than the
@@ -1657,12 +1667,14 @@ getmemsize(caddr_t kmdp, u_int64_t first)
*/
physmem_start = (vm_guest > VM_GUEST_NO ? 1 : 16) << PAGE_SHIFT;
TUNABLE_ULONG_FETCH("hw.physmem.start", &physmem_start);
- if (physmem_start < PAGE_SIZE)
- physmap[0] = PAGE_SIZE;
- else if (physmem_start >= physmap[1])
- physmap[0] = round_page(physmap[1] - PAGE_SIZE);
- else
- physmap[0] = round_page(physmem_start);
+ if (physmap[0] < physmem_start) {
+ if (physmem_start < PAGE_SIZE)
+ physmap[0] = PAGE_SIZE;
+ else if (physmem_start >= physmap[1])
+ physmap[0] = round_page(physmap[1] - PAGE_SIZE);
+ else
+ physmap[0] = round_page(physmem_start);
+ }
pa_indx = 0;
da_indx = 1;
phys_avail[pa_indx++] = physmap[0];
OpenPOWER on IntegriCloud