On 12/23/2014 01:05 PM, Simon Glass wrote:
Hi Stephen,
On 23 December 2014 at 10:34, Stephen Warren <swar...@wwwdotorg.org> wrote:
From: Stephen Warren <swar...@nvidia.com>
Some systems have so much RAM that the end of RAM is beyond 4GB. An
example would be a Tegra124 system (where RAM starts at 2GB physical)
that has more than 2GB of RAM.
In this case, we want gd->ram_size to represent the actual RAM size, so
that the actual RAM size is passed to the OS. This is useful if the OS
implements LPAE, and can actually use the "extra" RAM.
However, we can't use get_ram_size() to verify the actual amount of RAM
present on such systems, since some of the RAM can't be accesses, which
confuses that function. Avoid calling get_ram_size() when the RAM size
is too large for it to work correctly. It's never actually needed anyway,
since there's no reason for the BCT to report the wrong RAM size.
In systems with >=4GB RAM, we still need to clip the reported RAM size
since U-Boot uses a 32-bit variable to represent the RAM size in bytes.
diff --git a/arch/arm/cpu/tegra-common/board.c
b/arch/arm/cpu/tegra-common/board.c
@@ -40,7 +40,27 @@ unsigned int query_sdram_size(void)
size_bytes = get_ram_size((void *)PHYS_SDRAM_1, emem_cfg * 1024);
#else
debug("mc->mc_emem_cfg (MEM_SIZE_MB) = 0x%08x\n", emem_cfg);
- size_bytes = get_ram_size((void *)PHYS_SDRAM_1, emem_cfg * 1024 * 1024);
+ /*
+ * If >=4GB RAM is present, the byte RAM size won't fit into 32-bits
+ * and will wrap. Clip the reported size to the maximum that a 32-bit
+ * variable can represent (rounded to a page).
+ */
+ if (emem_cfg >= 4096) {
+ size_bytes = U32_MAX & ~(0x1000 - 1);
Will this return 4GB - 4KB? Why not return the full size?
A U32 can only store 4GB-1 at most, so we can never put the full 4GB
value into size_bytes.
I aligned the value down to page alignment rather than storing 4GB-1
there to prevent surprises elsewhere. For example, not all adjustments
to gd->relocaddr in board_f.c page-align the allocations. In particular,
I have enabled reserve_pram() locally for other reasons, and it just
blindly subtracts the size from the current value of gd->relocaddr.
Arguably that's a bug in that code, but I figured it was simplest to
return a sensibly aligned size irrespective of that.
_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot