diff options
author | dim <dim@FreeBSD.org> | 2015-01-26 21:41:54 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2015-01-26 21:41:54 +0000 |
commit | a53e4d44d0463dae21283fdb3ca61a1e38df799f (patch) | |
tree | 6f5baa0292e962bb69dc0020ada66d60ea578642 /sys/amd64 | |
parent | c9e57e45aceb65bdac0c758538375582075c8a97 (diff) | |
parent | 191df99881cad772b533cb8ad72897ab307efdb9 (diff) | |
download | FreeBSD-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.c | 38 |
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]; |