Patrick Georgi (pgeorgi@google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/10961
-gerrit
commit 17e508a01735c723ca9194fa9d875d9c5eea200c Author: Aaron Durbin adurbin@chromium.org Date: Thu Jul 16 16:07:02 2015 -0500
amd: raminit sysinfo offset fix
The sysinfo object within the k8 ram init is used to communicate progess/status from all the nodes in the system. However, the code was assuming where the sysinfo object lived in cache-as-ram. The layout of cache-as-ram is dynamic so one needs to do the lookup of the correct address at runtime. The way the amd code is compiled by #include'ing .c files makes the solution a little more complex in that some cache-as-ram support code needed to be refactored.
Change-Id: I6500fa7b005dc082c4c0b3382ee2c3a138d9ac31 Signed-off-by: Aaron Durbin adurbin@chromium.org --- src/arch/x86/include/arch/early_variables.h | 16 ++++++++++++++++ src/cpu/amd/car/post_cache_as_ram.c | 12 ++---------- src/cpu/x86/car.c | 9 +++------ src/northbridge/amd/amdk8/f.h | 3 ++- src/northbridge/amd/amdk8/pre_f.h | 3 ++- src/northbridge/amd/amdk8/raminit.c | 3 --- src/northbridge/amd/amdk8/raminit_f.c | 3 --- src/northbridge/amd/amdk8/raminit_f_dqs.c | 6 +++++- 8 files changed, 30 insertions(+), 25 deletions(-)
diff --git a/src/arch/x86/include/arch/early_variables.h b/src/arch/x86/include/arch/early_variables.h index d9f1cd7..7ccb340 100644 --- a/src/arch/x86/include/arch/early_variables.h +++ b/src/arch/x86/include/arch/early_variables.h @@ -20,6 +20,8 @@ #ifndef ARCH_EARLY_VARIABLES_H #define ARCH_EARLY_VARIABLES_H
+#include <stdlib.h> + #if defined(__PRE_RAM__) && IS_ENABLED(CONFIG_CACHE_AS_RAM) asm(".section .car.global_data,"w",@nobits"); asm(".previous"); @@ -43,6 +45,20 @@ void *car_sync_var_ptr(void *var); #define car_set_var(var, val) \ do { car_get_var(var) = (val); } while(0)
+extern char _car_data_start[]; +extern char _car_data_end[]; + +static inline size_t car_data_size(void) +{ + size_t car_size = &_car_data_end[0] - &_car_data_start[0]; + return ALIGN(car_size, 64); +} + +static inline size_t car_object_offset(void *ptr) +{ + return (char *)ptr - &_car_data_start[0]; +} + #else #define CAR_GLOBAL static inline void *car_get_var_ptr(void *var) { return var; } diff --git a/src/cpu/amd/car/post_cache_as_ram.c b/src/cpu/amd/car/post_cache_as_ram.c index 6c32090..96df3e7 100644 --- a/src/cpu/amd/car/post_cache_as_ram.c +++ b/src/cpu/amd/car/post_cache_as_ram.c @@ -3,6 +3,7 @@ */ #include <string.h> #include <arch/stages.h> +#include <arch/early_variables.h> #include <cpu/x86/mtrr.h> #include <cpu/amd/mtrr.h> #include <cpu/amd/car.h> @@ -22,18 +23,9 @@ #define print_car_debug(x) #endif
-extern char _car_data_start[]; -extern char _car_data_end[]; - -static size_t car_data_size(void) -{ - size_t car_size = &_car_data_end[0] - &_car_data_start[0]; - return ALIGN(car_size, 64); -} - static size_t backup_size(void) { - size_t car_size = &_car_data_end[0] - &_car_data_start[0]; + size_t car_size = car_data_size(); return ALIGN(car_size + 1024, 1024); }
diff --git a/src/cpu/x86/car.c b/src/cpu/x86/car.c index b4345ea..cdf7cfc 100644 --- a/src/cpu/x86/car.c +++ b/src/cpu/x86/car.c @@ -30,9 +30,6 @@ typedef void (* const car_migration_func_t)(void);
extern car_migration_func_t _car_migrate_start;
-extern char _car_data_start[]; -extern char _car_data_end[]; - /* * The car_migrated global variable determines if the cache-as-ram space has * been migrated to real RAM. It does this by assuming the following things: @@ -117,20 +114,20 @@ void *car_sync_var_ptr(void *var) static void do_car_migrate_variables(void) { void *migrated_base; - size_t car_data_size = &_car_data_end[0] - &_car_data_start[0]; + size_t car_size = car_data_size();
/* Check if already migrated. */ if (car_migrated) return;
- migrated_base = cbmem_add(CBMEM_ID_CAR_GLOBALS, car_data_size); + migrated_base = cbmem_add(CBMEM_ID_CAR_GLOBALS, car_size);
if (migrated_base == NULL) { printk(BIOS_ERR, "Could not migrate CAR data!\n"); return; }
- memcpy(migrated_base, &_car_data_start[0], car_data_size); + memcpy(migrated_base, &_car_data_start[0], car_size);
/* Mark that the data has been moved. */ car_migrated = ~0; diff --git a/src/northbridge/amd/amdk8/f.h b/src/northbridge/amd/amdk8/f.h index 4f958c5..af4658d 100644 --- a/src/northbridge/amd/amdk8/f.h +++ b/src/northbridge/amd/amdk8/f.h @@ -519,7 +519,8 @@ struct sys_info { } __attribute__((packed));
#ifdef __PRE_RAM__ -extern struct sys_info sysinfo_car; +#include <arch/early_variables.h> +struct sys_info sysinfo_car CAR_GLOBAL; #endif
#include <reset.h> diff --git a/src/northbridge/amd/amdk8/pre_f.h b/src/northbridge/amd/amdk8/pre_f.h index 0e0f9f4..c413b5b 100644 --- a/src/northbridge/amd/amdk8/pre_f.h +++ b/src/northbridge/amd/amdk8/pre_f.h @@ -263,7 +263,8 @@ struct sys_info { } __attribute__((packed));
#ifdef __PRE_RAM__ -extern struct sys_info sysinfo_car; +#include <arch/early_variables.h> +struct sys_info sysinfo_car CAR_GLOBAL; #endif
#endif /* AMDK8_PRE_F_H */ diff --git a/src/northbridge/amd/amdk8/raminit.c b/src/northbridge/amd/amdk8/raminit.c index c58abb1..fbcb887 100644 --- a/src/northbridge/amd/amdk8/raminit.c +++ b/src/northbridge/amd/amdk8/raminit.c @@ -17,9 +17,6 @@ #include "option_table.h" #endif
-#include <arch/early_variables.h> -struct sys_info sysinfo_car CAR_GLOBAL; - void setup_resource_map(const unsigned int *register_values, int max) { int i; diff --git a/src/northbridge/amd/amdk8/raminit_f.c b/src/northbridge/amd/amdk8/raminit_f.c index 1c1a6ea..a116d76 100644 --- a/src/northbridge/amd/amdk8/raminit_f.c +++ b/src/northbridge/amd/amdk8/raminit_f.c @@ -42,9 +42,6 @@ #endif
-#include <arch/early_variables.h> -struct sys_info sysinfo_car CAR_GLOBAL; - #include "f_pci.c"
diff --git a/src/northbridge/amd/amdk8/raminit_f_dqs.c b/src/northbridge/amd/amdk8/raminit_f_dqs.c index ee3b609..609cddf 100644 --- a/src/northbridge/amd/amdk8/raminit_f_dqs.c +++ b/src/northbridge/amd/amdk8/raminit_f_dqs.c @@ -2074,7 +2074,11 @@ static void train_ram(unsigned nodeid, struct sys_info *sysinfo, struct sys_info static inline void train_ram_on_node(unsigned nodeid, unsigned coreid, struct sys_info *sysinfo, unsigned retcall) { if(coreid) return; // only do it on core0 - struct sys_info *sysinfox = (void *)((CONFIG_RAMTOP) - sizeof(*sysinfox)); + struct sys_info *sysinfox; + uintptr_t migrated_base = CONFIG_RAMTOP - car_data_size(); + + sysinfox = (void *)(migrated_base + car_object_offset(&sysinfo_car)); + wait_till_sysinfo_in_ram(); // use pci to get it
if(sysinfox->mem_trained[nodeid] == 0x80) {