diff options
author | ian <ian@FreeBSD.org> | 2016-01-24 22:00:36 +0000 |
---|---|---|
committer | ian <ian@FreeBSD.org> | 2016-01-24 22:00:36 +0000 |
commit | 650a9addf1aa6411b6dfefe94fcf78fe0b856fe8 (patch) | |
tree | 9ab101a5aad57290be783adabad116d206466c4d /sys/boot | |
parent | 33902405d5bbd7b2931c254ec445012ce3f55107 (diff) | |
download | FreeBSD-src-650a9addf1aa6411b6dfefe94fcf78fe0b856fe8.zip FreeBSD-src-650a9addf1aa6411b6dfefe94fcf78fe0b856fe8.tar.gz |
MFC r293053, r293061, r293063, r293064, r293065, r293775, r293792:
Use 64-bit math when finding a block of ram to hold the kernel. This fixes
a problem on 32-bit systems which have ram occupying the end of the physical
address space -- for example, a block of ram at 0x80000000 with a size of
0x80000000 was overflowing 32 bit math and ending up with a calculated size
of zero.
Use 64-bit math when processing the lists of physical and excluded memory
to generate the phys_avail and dump_avail arrays.
Work around problems that happen when there is ram at the end of the
physical address space.
Cast pointer through uintptr_t on the way to uint64_t to squelch a warning.
Reword the comment to better describe what I found while researching the
problem that led to this temporary workaround (and also so I can properly
cite the PR in the commit this time).
Cast using uintfptr_t and eliminate the cast to uint64_t which is uneeded
because rounding down cannot increase the number of bits needed to express
the result.
Go back to using uintptr_t, because code that actually compiles is
infinitely less buggy than code that is theoretically correct in some
alternate universe.
PR: 201614
Diffstat (limited to 'sys/boot')
-rw-r--r-- | sys/boot/uboot/lib/copy.c | 22 |
1 files changed, 12 insertions, 10 deletions
diff --git a/sys/boot/uboot/lib/copy.c b/sys/boot/uboot/lib/copy.c index bb658e3..76f2faf 100644 --- a/sys/boot/uboot/lib/copy.c +++ b/sys/boot/uboot/lib/copy.c @@ -69,11 +69,11 @@ uint64_t uboot_loadaddr(u_int type, void *data, uint64_t addr) { struct sys_info *si; - uintptr_t sblock, eblock, subldr, eubldr; - uintptr_t biggest_block, this_block; - size_t biggest_size, this_size; + uint64_t sblock, eblock, subldr, eubldr; + uint64_t biggest_block, this_block; + uint64_t biggest_size, this_size; int i; - char * envstr; + char *envstr; if (addr == 0) { /* @@ -101,13 +101,14 @@ uboot_loadaddr(u_int type, void *data, uint64_t addr) biggest_block = 0; biggest_size = 0; subldr = rounddown2((uintptr_t)_start, KERN_ALIGN); - eubldr = roundup2(uboot_heap_end, KERN_ALIGN); + eubldr = roundup2((uint64_t)uboot_heap_end, KERN_ALIGN); for (i = 0; i < si->mr_no; i++) { if (si->mr[i].flags != MR_ATTR_DRAM) continue; - sblock = roundup2(si->mr[i].start, KERN_ALIGN); - eblock = rounddown2(si->mr[i].start + si->mr[i].size, + sblock = roundup2((uint64_t)si->mr[i].start, KERN_ALIGN); + eblock = rounddown2((uint64_t)si->mr[i].start + + si->mr[i].size, KERN_ALIGN); if (biggest_size == 0) sblock += KERN_MINADDR; if (subldr >= sblock && subldr < eblock) { @@ -127,9 +128,10 @@ uboot_loadaddr(u_int type, void *data, uint64_t addr) if (biggest_size == 0) panic("Not enough DRAM to load kernel\n"); #if 0 - printf("Loading kernel into region 0x%08x-0x%08x (%u MiB)\n", - biggest_block, biggest_block + biggest_size - 1, - biggest_size / 1024 / 1024); + printf("Loading kernel into region 0x%08jx-0x%08jx (%ju MiB)\n", + (uintmax_t)biggest_block, + (uintmax_t)biggest_block + biggest_size - 1, + (uintmax_t)biggest_size / 1024 / 1024); #endif return (biggest_block); } |