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)
This commit is contained in:
parent
aadf2b8b59
commit
28d5ec9a7d
|
@ -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. */
|
/* Do nothing. Chipset may have implementation to save ramtop in NVRAM. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void *ramtop_pointer;
|
||||||
|
|
||||||
void set_top_of_ram(uint64_t ramtop)
|
void set_top_of_ram(uint64_t ramtop)
|
||||||
{
|
{
|
||||||
backup_top_of_ram(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__ */
|
#endif /* !__PRE_RAM__ */
|
||||||
|
|
||||||
|
@ -50,6 +63,11 @@ unsigned long __attribute__((weak)) get_top_of_ram(void)
|
||||||
void *cbmem_top(void)
|
void *cbmem_top(void)
|
||||||
{
|
{
|
||||||
/* Top of cbmem is at lowest usable DRAM address below 4GiB. */
|
/* 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();
|
return (void *)get_top_of_ram();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -221,6 +221,9 @@ void cbmem_list(void);
|
||||||
* early features like COLLECT_TIMESTAMPS and CBMEM_CONSOLE.
|
* early features like COLLECT_TIMESTAMPS and CBMEM_CONSOLE.
|
||||||
*/
|
*/
|
||||||
#if IS_ENABLED(CONFIG_ARCH_X86) && IS_ENABLED(CONFIG_LATE_CBMEM_INIT)
|
#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);
|
unsigned long get_top_of_ram(void);
|
||||||
void set_top_of_ram(uint64_t ramtop);
|
void set_top_of_ram(uint64_t ramtop);
|
||||||
void backup_top_of_ram(uint64_t ramtop);
|
void backup_top_of_ram(uint64_t ramtop);
|
||||||
|
|
Loading…
Reference in New Issue