CBMEM: Support DYNAMIC_CBMEM with LATE_CBMEM_INIT
We can now create CBMEM with dynamic allocation even if CBMEM location is resolved late in ramstage. Change-Id: I8529ccbcd4a0e567ebe0a46232ac5d16476e81a8 Signed-off-by: Kyösti Mälkki <kyosti.malkki@gmail.com> Reviewed-on: http://review.coreboot.org/7861 Reviewed-by: Aaron Durbin <adurbin@google.com> Tested-by: build bot (Jenkins)
This commit is contained in:
@@ -162,7 +162,6 @@ config EARLY_CBMEM_INIT
|
|||||||
config DYNAMIC_CBMEM
|
config DYNAMIC_CBMEM
|
||||||
bool
|
bool
|
||||||
default n
|
default n
|
||||||
select EARLY_CBMEM_INIT
|
|
||||||
help
|
help
|
||||||
Instead of reserving a static amount of CBMEM space the CBMEM
|
Instead of reserving a static amount of CBMEM space the CBMEM
|
||||||
area grows dynamically. CBMEM can be used both in romstage (after
|
area grows dynamically. CBMEM can be used both in romstage (after
|
||||||
@@ -201,7 +200,7 @@ config RELOCATABLE_MODULES
|
|||||||
loaded anywhere and all the relocations are handled automatically.
|
loaded anywhere and all the relocations are handled automatically.
|
||||||
|
|
||||||
config RELOCATABLE_RAMSTAGE
|
config RELOCATABLE_RAMSTAGE
|
||||||
depends on (RELOCATABLE_MODULES && DYNAMIC_CBMEM)
|
depends on (RELOCATABLE_MODULES && DYNAMIC_CBMEM && EARLY_CBMEM_INIT)
|
||||||
bool "Build the ramstage to be relocatable in 32-bit address space."
|
bool "Build the ramstage to be relocatable in 32-bit address space."
|
||||||
default n
|
default n
|
||||||
help
|
help
|
||||||
|
@@ -39,6 +39,9 @@ void get_cbmem_table(uint64_t *base, uint64_t *size)
|
|||||||
*size = 0;
|
*size = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif /* !DYNAMIC_CBMEM */
|
||||||
|
|
||||||
|
#if IS_ENABLED(CONFIG_LATE_CBMEM_INIT)
|
||||||
|
|
||||||
#if !defined(__PRE_RAM__)
|
#if !defined(__PRE_RAM__)
|
||||||
void __attribute__((weak)) backup_top_of_ram(uint64_t ramtop)
|
void __attribute__((weak)) backup_top_of_ram(uint64_t ramtop)
|
||||||
@@ -46,14 +49,14 @@ 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. */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is for compatibility with old boards only. Any new chipset and board
|
|
||||||
* must implement get_top_of_ram() for both romstage and ramstage to support
|
|
||||||
* early features like COLLECT_TIMESTAMPS and CBMEM_CONSOLE.
|
|
||||||
*/
|
|
||||||
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);
|
||||||
|
#if !CONFIG_DYNAMIC_CBMEM
|
||||||
cbmem_late_set_table(ramtop - HIGH_MEMORY_SIZE, HIGH_MEMORY_SIZE);
|
cbmem_late_set_table(ramtop - HIGH_MEMORY_SIZE, HIGH_MEMORY_SIZE);
|
||||||
|
#else
|
||||||
|
cbmem_set_top((void*)(uintptr_t)ramtop);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif /* !__PRE_RAM__ */
|
#endif /* !__PRE_RAM__ */
|
||||||
|
|
||||||
@@ -70,7 +73,8 @@ void *cbmem_top(void)
|
|||||||
return (void *)get_top_of_ram();
|
return (void *)get_top_of_ram();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif /* !DYNAMIC_CBMEM */
|
|
||||||
|
#endif /* LATE_CBMEM_INIT */
|
||||||
|
|
||||||
void cbmem_run_init_hooks(void)
|
void cbmem_run_init_hooks(void)
|
||||||
{
|
{
|
||||||
|
@@ -151,6 +151,9 @@ void cbmem_initialize_empty(void);
|
|||||||
* below 4GiB. */
|
* below 4GiB. */
|
||||||
void *cbmem_top(void);
|
void *cbmem_top(void);
|
||||||
|
|
||||||
|
/* Set the top address for dynamic cbmem. Not for new designs. */
|
||||||
|
void cbmem_set_top(void *ramtop);
|
||||||
|
|
||||||
/* Add a cbmem entry of a given size and id. These return NULL on failure. The
|
/* Add a cbmem entry of a given size and id. These return NULL on failure. The
|
||||||
* add function performs a find first and do not check against the original
|
* add function performs a find first and do not check against the original
|
||||||
* size. */
|
* size. */
|
||||||
@@ -168,7 +171,6 @@ int cbmem_entry_remove(const struct cbmem_entry *entry);
|
|||||||
void *cbmem_entry_start(const struct cbmem_entry *entry);
|
void *cbmem_entry_start(const struct cbmem_entry *entry);
|
||||||
u64 cbmem_entry_size(const struct cbmem_entry *entry);
|
u64 cbmem_entry_size(const struct cbmem_entry *entry);
|
||||||
|
|
||||||
|
|
||||||
#else /* !CONFIG_DYNAMIC_CBMEM */
|
#else /* !CONFIG_DYNAMIC_CBMEM */
|
||||||
|
|
||||||
/* Allocation with static CBMEM is resolved at build time. We start
|
/* Allocation with static CBMEM is resolved at build time. We start
|
||||||
@@ -183,15 +185,10 @@ u64 cbmem_entry_size(const struct cbmem_entry *entry);
|
|||||||
|
|
||||||
#define HIGH_MEMORY_SIZE ALIGN_UP(_CBMEM_SZ_TOTAL, 0x10000)
|
#define HIGH_MEMORY_SIZE ALIGN_UP(_CBMEM_SZ_TOTAL, 0x10000)
|
||||||
|
|
||||||
|
|
||||||
#ifndef __PRE_RAM__
|
#ifndef __PRE_RAM__
|
||||||
void set_top_of_ram(uint64_t ramtop);
|
|
||||||
void backup_top_of_ram(uint64_t ramtop);
|
|
||||||
void cbmem_late_set_table(uint64_t base, uint64_t size);
|
void cbmem_late_set_table(uint64_t base, uint64_t size);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
unsigned long get_top_of_ram(void);
|
|
||||||
|
|
||||||
void get_cbmem_table(uint64_t *base, uint64_t *size);
|
void get_cbmem_table(uint64_t *base, uint64_t *size);
|
||||||
struct cbmem_entry *get_cbmem_toc(void);
|
struct cbmem_entry *get_cbmem_toc(void);
|
||||||
|
|
||||||
@@ -224,6 +221,16 @@ void cbmem_list(void);
|
|||||||
void cbmem_print_entry(int n, u32 id, u64 start, u64 size);
|
void cbmem_print_entry(int n, u32 id, u64 start, u64 size);
|
||||||
#endif /* __PRE_RAM__ */
|
#endif /* __PRE_RAM__ */
|
||||||
|
|
||||||
|
/* These are for compatibility with old boards only. Any new chipset and board
|
||||||
|
* must implement cbmem_top() for both romstage and ramstage to support
|
||||||
|
* early features like COLLECT_TIMESTAMPS and CBMEM_CONSOLE.
|
||||||
|
*/
|
||||||
|
#if IS_ENABLED(CONFIG_ARCH_X86) && IS_ENABLED(CONFIG_LATE_CBMEM_INIT)
|
||||||
|
unsigned long get_top_of_ram(void);
|
||||||
|
void set_top_of_ram(uint64_t ramtop);
|
||||||
|
void backup_top_of_ram(uint64_t ramtop);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* __ASSEMBLER__ */
|
#endif /* __ASSEMBLER__ */
|
||||||
|
|
||||||
|
|
||||||
|
@@ -58,7 +58,7 @@ extern struct cbmem_console preram_cbmem_console;
|
|||||||
* during the ROM stage, once CBMEM becomes available at RAM stage.
|
* during the ROM stage, once CBMEM becomes available at RAM stage.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if CONFIG_DYNAMIC_CBMEM
|
#if IS_ENABLED(CONFIG_EARLY_CBMEM_INIT)
|
||||||
#define STATIC_CONSOLE_SIZE 1024
|
#define STATIC_CONSOLE_SIZE 1024
|
||||||
#else
|
#else
|
||||||
#define STATIC_CONSOLE_SIZE CONFIG_CONSOLE_CBMEM_BUFFER_SIZE
|
#define STATIC_CONSOLE_SIZE CONFIG_CONSOLE_CBMEM_BUFFER_SIZE
|
||||||
|
@@ -24,10 +24,9 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <arch/early_variables.h>
|
#include <arch/early_variables.h>
|
||||||
#if CONFIG_HAVE_ACPI_RESUME && !defined(__PRE_RAM__)
|
#if IS_ENABLED(CONFIG_ARCH_X86) && !IS_ENABLED(CONFIG_EARLY_CBMEM_INIT)
|
||||||
#include <arch/acpi.h>
|
#include <arch/acpi.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef UINT_MAX
|
#ifndef UINT_MAX
|
||||||
#define UINT_MAX 4294967295U
|
#define UINT_MAX 4294967295U
|
||||||
#endif
|
#endif
|
||||||
@@ -69,11 +68,18 @@ struct cbmem_root {
|
|||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
|
||||||
|
#if !defined(__PRE_RAM__)
|
||||||
|
static void *cached_cbmem_top;
|
||||||
|
|
||||||
|
void cbmem_set_top(void * ramtop)
|
||||||
|
{
|
||||||
|
cached_cbmem_top = ramtop;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static inline void *cbmem_top_cached(void)
|
static inline void *cbmem_top_cached(void)
|
||||||
{
|
{
|
||||||
#if !defined(__PRE_RAM__)
|
#if !defined(__PRE_RAM__)
|
||||||
static void *cached_cbmem_top;
|
|
||||||
|
|
||||||
if (cached_cbmem_top == NULL)
|
if (cached_cbmem_top == NULL)
|
||||||
cached_cbmem_top = cbmem_top();
|
cached_cbmem_top = cbmem_top();
|
||||||
|
|
||||||
@@ -100,6 +106,9 @@ static inline void *get_root(void)
|
|||||||
struct cbmem_root_pointer *pointer;
|
struct cbmem_root_pointer *pointer;
|
||||||
|
|
||||||
pointer_addr = get_top_aligned();
|
pointer_addr = get_top_aligned();
|
||||||
|
if (pointer_addr == 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
pointer_addr -= sizeof(struct cbmem_root_pointer);
|
pointer_addr -= sizeof(struct cbmem_root_pointer);
|
||||||
|
|
||||||
pointer = (void *)pointer_addr;
|
pointer = (void *)pointer_addr;
|
||||||
@@ -146,6 +155,9 @@ void cbmem_initialize_empty(void)
|
|||||||
* DYN_CBMEM_ALIGN_SIZE. The pointer falls just below the
|
* DYN_CBMEM_ALIGN_SIZE. The pointer falls just below the
|
||||||
* address returned by get_top_aligned(). */
|
* address returned by get_top_aligned(). */
|
||||||
pointer_addr = get_top_aligned();
|
pointer_addr = get_top_aligned();
|
||||||
|
if (pointer_addr == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
root_addr = pointer_addr - ROOT_MIN_SIZE;
|
root_addr = pointer_addr - ROOT_MIN_SIZE;
|
||||||
root_addr &= ~(DYN_CBMEM_ALIGN_SIZE - 1);
|
root_addr &= ~(DYN_CBMEM_ALIGN_SIZE - 1);
|
||||||
pointer_addr -= sizeof(struct cbmem_root_pointer);
|
pointer_addr -= sizeof(struct cbmem_root_pointer);
|
||||||
@@ -413,6 +425,8 @@ void *cbmem_entry_start(const struct cbmem_entry *entry)
|
|||||||
|
|
||||||
|
|
||||||
#if !defined(__PRE_RAM__)
|
#if !defined(__PRE_RAM__)
|
||||||
|
|
||||||
|
#if IS_ENABLED(CONFIG_EARLY_CBMEM_INIT)
|
||||||
/* selected cbmem can be initialized early in ramstage. Additionally, that
|
/* selected cbmem can be initialized early in ramstage. Additionally, that
|
||||||
* means cbmem console can be reinitialized early as well. The post_device
|
* means cbmem console can be reinitialized early as well. The post_device
|
||||||
* function is empty since cbmem was initialized early in ramstage. */
|
* function is empty since cbmem was initialized early in ramstage. */
|
||||||
@@ -426,6 +440,22 @@ BOOT_STATE_INIT_ENTRIES(cbmem_bscb) = {
|
|||||||
init_cbmem_pre_device, NULL),
|
init_cbmem_pre_device, NULL),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
static void init_cbmem_post_device(void *unused)
|
||||||
|
{
|
||||||
|
if (acpi_is_wakeup())
|
||||||
|
cbmem_initialize();
|
||||||
|
else
|
||||||
|
cbmem_initialize_empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOT_STATE_INIT_ENTRIES(cbmem_bscb) = {
|
||||||
|
BOOT_STATE_INIT_ENTRY(BS_POST_DEVICE, BS_ON_ENTRY,
|
||||||
|
init_cbmem_post_device, NULL),
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
void cbmem_add_bootmem(void)
|
void cbmem_add_bootmem(void)
|
||||||
{
|
{
|
||||||
uintptr_t base;
|
uintptr_t base;
|
||||||
|
Reference in New Issue
Block a user