diff options
author | Aaron Durbin <adurbin@chromium.org> | 2015-05-26 11:15:45 -0500 |
---|---|---|
committer | Aaron Durbin <adurbin@chromium.org> | 2015-05-26 19:06:48 +0200 |
commit | 28d5ec9a7d8fe11175c8907cc6fa0305c469b194 (patch) | |
tree | 6e5f82e8b0f6fe01c283398e6faa2fbc96b3bae5 /src | |
parent | aadf2b8b59adec05a84e4884ba76bc2ebc4d9b00 (diff) |
x86: provide consistent cbmem_top() for CONFIG_LATE_CBMEM_INIT
For x86 systems employing CONFIG_LATE_CBMEM_INIT, set_top_of_ram() is
called in ramstage to note the upper address of the 32-bit address
space. This in turn is consumed by cbmem. However, in this scenario
cbmem_top() cannot always be relied upon because get_top_of_ram()
doesn't return the same value provided to set_top_of_ram().
To fix the inconsistency in ramstage save the value passed in
to set_top_of_ram() and defer to it as the return value for
cbmem_top().
Change-Id: Ida796fb836c59b9776019e7f8b3f2cd71156f0e5
Signed-off-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/10313
Reviewed-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
Tested-by: build bot (Jenkins)
Diffstat (limited to 'src')
-rw-r--r-- | src/arch/x86/boot/cbmem.c | 20 | ||||
-rw-r--r-- | src/include/cbmem.h | 3 |
2 files changed, 22 insertions, 1 deletions
diff --git a/src/arch/x86/boot/cbmem.c b/src/arch/x86/boot/cbmem.c index 9ee5db49f0..f48e46aa80 100644 --- a/src/arch/x86/boot/cbmem.c +++ b/src/arch/x86/boot/cbmem.c @@ -34,10 +34,23 @@ void __attribute__((weak)) backup_top_of_ram(uint64_t ramtop) /* Do nothing. Chipset may have implementation to save ramtop in NVRAM. */ } +static void *ramtop_pointer; + void set_top_of_ram(uint64_t ramtop) { backup_top_of_ram(ramtop); - cbmem_set_top((void*)(uintptr_t)ramtop); + ramtop_pointer = (void *)(uintptr_t)ramtop; + cbmem_set_top(ramtop_pointer); +} + +static inline void *saved_ramtop(void) +{ + return ramtop_pointer; +} +#else +static inline void *saved_ramtop(void) +{ + return NULL; } #endif /* !__PRE_RAM__ */ @@ -50,6 +63,11 @@ unsigned long __attribute__((weak)) get_top_of_ram(void) void *cbmem_top(void) { /* Top of cbmem is at lowest usable DRAM address below 4GiB. */ + void *ptr = saved_ramtop(); + + if (ptr != NULL) + return ptr; + return (void *)get_top_of_ram(); } diff --git a/src/include/cbmem.h b/src/include/cbmem.h index 20cc174d05..0a7ca89cd4 100644 --- a/src/include/cbmem.h +++ b/src/include/cbmem.h @@ -221,6 +221,9 @@ void cbmem_list(void); * early features like COLLECT_TIMESTAMPS and CBMEM_CONSOLE. */ #if IS_ENABLED(CONFIG_ARCH_X86) && IS_ENABLED(CONFIG_LATE_CBMEM_INIT) +/* Note that many of the current providers of get_top_of_ram() conditionally + * return 0 when the sleep type is non S3. i.e. cold and warm boots would + * return 0 from get_top_of_ram(). */ unsigned long get_top_of_ram(void); void set_top_of_ram(uint64_t ramtop); void backup_top_of_ram(uint64_t ramtop); |