diff options
author | Kyösti Mälkki <kyosti.malkki@gmail.com> | 2014-12-19 08:20:45 +0200 |
---|---|---|
committer | Kyösti Mälkki <kyosti.malkki@gmail.com> | 2015-01-27 22:50:14 +0100 |
commit | 2fb6b40ed0d4c4d169d4b909ad784e1841b50242 (patch) | |
tree | 6d34fc2c9fd525ba86100881515087cc6dee0d6e /src/lib/dynamic_cbmem.c | |
parent | 02aebb67b394a9cf81eade4a3952fce3a19c974c (diff) | |
download | coreboot-2fb6b40ed0d4c4d169d4b909ad784e1841b50242.tar.xz |
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)
Diffstat (limited to 'src/lib/dynamic_cbmem.c')
-rw-r--r-- | src/lib/dynamic_cbmem.c | 38 |
1 files changed, 34 insertions, 4 deletions
diff --git a/src/lib/dynamic_cbmem.c b/src/lib/dynamic_cbmem.c index 1b46745800..6ec56c773d 100644 --- a/src/lib/dynamic_cbmem.c +++ b/src/lib/dynamic_cbmem.c @@ -24,10 +24,9 @@ #include <string.h> #include <stdlib.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> #endif - #ifndef UINT_MAX #define UINT_MAX 4294967295U #endif @@ -69,11 +68,18 @@ struct cbmem_root { } __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) { #if !defined(__PRE_RAM__) - static void *cached_cbmem_top; - if (cached_cbmem_top == NULL) cached_cbmem_top = cbmem_top(); @@ -100,6 +106,9 @@ static inline void *get_root(void) struct cbmem_root_pointer *pointer; pointer_addr = get_top_aligned(); + if (pointer_addr == 0) + return NULL; + pointer_addr -= sizeof(struct cbmem_root_pointer); pointer = (void *)pointer_addr; @@ -146,6 +155,9 @@ void cbmem_initialize_empty(void) * DYN_CBMEM_ALIGN_SIZE. The pointer falls just below the * address returned by get_top_aligned(). */ pointer_addr = get_top_aligned(); + if (pointer_addr == 0) + return; + root_addr = pointer_addr - ROOT_MIN_SIZE; root_addr &= ~(DYN_CBMEM_ALIGN_SIZE - 1); 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 IS_ENABLED(CONFIG_EARLY_CBMEM_INIT) /* selected cbmem can be initialized early in ramstage. Additionally, that * means cbmem console can be reinitialized early as well. The post_device * 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), }; +#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) { uintptr_t base; |