cbmem: Extend hooks to ramstage, fix timestamp synching

Commit 7dd5bbd71 (cbmem: Unify random on-CBMEM-init tasks under common
CBMEM_INIT_HOOK() API) inadvertently broke ramstage timestamps since
timestamp_sync() was no longer called there. Oops.

This patch fixes the issue by extending the CBMEM_INIT_HOOK() mechanism
to the cbmem_initialize() call in ramstage. The macro is split into
explicit ROMSTAGE_/RAMSTAGE_ versions to make the behavior as clear as
possible and prevent surprises (although just using a single macro and
relying on the Makefiles to link an object into all appropriate stages
would also work).

This allows us to get rid of the explicit cbmemc_reinit() in ramstage
(which I somehow accounted for in the last patch without realizing that
timestamps work exactly the same way...), and replace the older and less
flexible cbmem_arch_init() mechanism.

Also added a size assertion for the pre-RAM CBMEM console to memlayout
that could prevent a very unlikely buffer overflow I just noticed.

BRANCH=None
BUG=None
TEST=Booted on Pinky and Falco, confirmed that ramstage timestamps once
again show up. Compile-tested for Rambi and Samus.

Change-Id: If907266c3f20dc3d599b5c968ea5b39fe5c00e9c
Signed-off-by: Julius Werner <jwerner@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/233533
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
This commit is contained in:
Julius Werner 2014-12-05 10:22:52 -08:00 committed by chrome-internal-fetch
commit 18fdeb7d32
15 changed files with 32 additions and 41 deletions

View file

@ -38,10 +38,6 @@ uint64_t high_tables_base = 0;
uint64_t high_tables_size;
#endif
void cbmem_arch_init(void)
{
}
struct lb_memory *write_tables(void)
{
unsigned long table_pointer, new_table_pointer;

View file

@ -38,10 +38,6 @@ uint64_t high_tables_base = 0;
uint64_t high_tables_size;
#endif
void cbmem_arch_init(void)
{
}
struct lb_memory *write_tables(void)
{
unsigned long table_pointer, new_table_pointer;

View file

@ -30,10 +30,6 @@
#define MAX_COREBOOT_TABLE_SIZE (8 * 1024)
void cbmem_arch_init(void)
{
}
struct lb_memory *write_tables(void)
{
unsigned long table_pointer, new_table_pointer;

View file

@ -35,11 +35,12 @@
uint64_t high_tables_base = 0;
uint64_t high_tables_size;
void cbmem_arch_init(void)
static void cbmem_arch_init(void)
{
/* defined in gdt.c */
move_gdt();
}
RAMSTAGE_CBMEM_INIT_HOOK(cbmem_arch_init)
struct lb_memory *write_tables(void)
{

View file

@ -204,19 +204,24 @@ void *cbmem_add(u32 id, u64 size);
void *cbmem_find(u32 id);
typedef void (* const cbmem_init_hook_t)(void);
#define CBMEM_INIT_HOOK(init_fn_) static cbmem_init_hook_t init_fn_ ## _ptr \
__attribute__((used, section(".rodata.cbmem_init_hooks"))) = init_fn_;
void cbmem_run_init_hooks(void);
#ifndef __PRE_RAM__
/* Ramstage only functions. */
void cbmem_list(void);
void cbmem_arch_init(void);
void cbmem_print_entry(int n, u32 id, u64 start, u64 size);
static inline void cbmem_run_init_hooks(void) {}
#else
static inline void cbmem_arch_init(void) {}
void cbmem_run_init_hooks(void);
#endif /* __PRE_RAM__ */
#define ROMSTAGE_CBMEM_INIT_HOOK(init_fn_) static cbmem_init_hook_t \
init_fn_ ## _unused_ __attribute__((unused)) = init_fn_;
#define RAMSTAGE_CBMEM_INIT_HOOK(init_fn_) \
static cbmem_init_hook_t init_fn_ ## _ptr_ __attribute__((used, \
section(".rodata.cbmem_init_hooks"))) = init_fn_;
#else /* __PRE_RAM__ */
#define ROMSTAGE_CBMEM_INIT_HOOK(init_fn_) \
static cbmem_init_hook_t init_fn_ ## _ptr_ __attribute__((used, \
section(".rodata.cbmem_init_hooks"))) = init_fn_;
#define RAMSTAGE_CBMEM_INIT_HOOK(init_fn_) static cbmem_init_hook_t \
init_fn_ ## _unused_ __attribute__((unused)) = init_fn_;
#endif /* !__PRE_RAM__ */
#endif /* __ASSEMBLER__ */

View file

@ -51,7 +51,9 @@
REGION(timestamp, addr, size, 8)
#define PRERAM_CBMEM_CONSOLE(addr, size) \
REGION(preram_cbmem_console, addr, size, 4)
REGION(preram_cbmem_console, addr, size, 4) \
_ = ASSERT(size <= CONFIG_CONSOLE_CBMEM_BUFFER_SIZE, \
"pre-RAM CBMEM console size must not be larger than post-RAM!");
/* Use either CBFS_CACHE (unified) or both (PRERAM|POSTRAM)_CBFS_CACHE */
#define CBFS_CACHE(addr, size) REGION(cbfs_cache, addr, size, 4)

View file

@ -227,9 +227,6 @@ int cbmem_initialize(void)
cbmem_init(high_tables_base, high_tables_size);
rv = 1;
}
#ifndef __PRE_RAM__
cbmem_arch_init();
#endif
cbmem_run_init_hooks();
/* Migrate cache-as-ram variables. */
@ -243,9 +240,6 @@ int cbmem_initialize(void)
static void init_cbmem_post_device(void *unused)
{
cbmem_initialize();
#if CONFIG_CONSOLE_CBMEM
cbmemc_reinit();
#endif
}
BOOT_STATE_INIT_ENTRIES(cbmem_bscb) = {

View file

@ -20,7 +20,7 @@
#include <cbmem.h>
#include <stdlib.h>
#ifndef __PRE_RAM__
#ifndef __PRE_RAM__ /* TODO clean up ifdefs after x86 has --gc-sections */
static const struct cbmem_id_to_name cbmem_ids[] = { CBMEM_ID_TO_NAME_TABLE };
@ -46,7 +46,7 @@ void cbmem_print_entry(int n, u32 id, u64 base, u64 size)
printk(BIOS_DEBUG, "%08llx\n", size);
}
#else /* __PRE_RAM__ */
#endif /* !__PRE_RAM__ */
extern cbmem_init_hook_t _cbmem_init_hooks;
extern cbmem_init_hook_t _ecbmem_init_hooks;
@ -59,5 +59,3 @@ void cbmem_run_init_hooks(void)
init_hook_ptr++;
}
}
#endif /* __PRE_RAM__ */

View file

@ -234,4 +234,5 @@ void cbmemc_reinit(void)
}
/* Call cbmemc_reinit() at cbmem_initialize() time. */
CBMEM_INIT_HOOK(cbmemc_reinit)
ROMSTAGE_CBMEM_INIT_HOOK(cbmemc_reinit)
RAMSTAGE_CBMEM_INIT_HOOK(cbmemc_reinit)

View file

@ -183,7 +183,6 @@ void cbmem_initialize_empty(void)
printk(BIOS_DEBUG, "CBMEM: root @ %p %d entries.\n",
root, root->max_entries);
cbmem_arch_init();
cbmem_run_init_hooks();
/* Migrate cache-as-ram variables. */
@ -260,7 +259,6 @@ int cbmem_initialize(void)
root->locked = 1;
#endif
cbmem_arch_init();
cbmem_run_init_hooks();
/* Migrate cache-as-ram variables. */
@ -425,9 +423,6 @@ void *cbmem_entry_start(const struct cbmem_entry *entry)
static void init_cbmem_pre_device(void *unused)
{
cbmem_initialize();
#if CONFIG_CONSOLE_CBMEM
cbmemc_reinit();
#endif /* CONFIG_CONSOLE_CBMEM */
}
BOOT_STATE_INIT_ENTRIES(cbmem_bscb) = {

View file

@ -66,6 +66,9 @@
_bs_init_begin = .;
KEEP(*(.bs_init));
_bs_init_end = .;
_cbmem_init_hooks = .;
KEEP(*(.rodata.cbmem_init_hooks));
_ecbmem_init_hooks = .;
*(.rodata)
*(.rodata.*)

View file

@ -55,6 +55,9 @@ SECTIONS
_bs_init_begin = .;
*(.bs_init)
_bs_init_end = .;
_cbmem_init_hooks = .;
KEEP(*(.rodata.cbmem_init_hooks));
_ecbmem_init_hooks = .;
. = ALIGN(8);

View file

@ -214,7 +214,8 @@ static void timestamp_sync(void)
if (ts_cbmem_table->base_time == 0)
ts_cbmem_table->base_time = ts_cache_table->base_time;
}
CBMEM_INIT_HOOK(timestamp_sync)
ROMSTAGE_CBMEM_INIT_HOOK(timestamp_sync)
RAMSTAGE_CBMEM_INIT_HOOK(timestamp_sync)
void timestamp_early_init(uint64_t base)
{

View file

@ -154,7 +154,7 @@ static void migrate_power_state(void)
}
memcpy(ps_cbmem, ps_car, sizeof(*ps_cbmem));
}
CBMEM_INIT_HOOK(migrate_power_state)
ROMSTAGE_CBMEM_INIT_HOOK(migrate_power_state)
static struct chipset_power_state *fill_power_state(void)
{

View file

@ -50,7 +50,7 @@ static void migrate_power_state(void)
}
memcpy(ps_cbmem, ps_car, sizeof(*ps_cbmem));
}
CBMEM_INIT_HOOK(migrate_power_state)
ROMSTAGE_CBMEM_INIT_HOOK(migrate_power_state)
/* Return 0, 3, or 5 to indicate the previous sleep state. */
static int prev_sleep_state(struct chipset_power_state *ps)