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> Reviewed-on: http://review.coreboot.org/10961 Tested-by: build bot (Jenkins) Tested-by: Raptor Engineering Automated Test Stand <noreply@raptorengineeringinc.com> Reviewed-by: Patrick Georgi <pgeorgi@google.com>
This commit is contained in:
parent
db01ddfd49
commit
0dc7354760
|
@ -20,6 +20,8 @@
|
||||||
#ifndef ARCH_EARLY_VARIABLES_H
|
#ifndef ARCH_EARLY_VARIABLES_H
|
||||||
#define ARCH_EARLY_VARIABLES_H
|
#define ARCH_EARLY_VARIABLES_H
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#if defined(__PRE_RAM__) && IS_ENABLED(CONFIG_CACHE_AS_RAM)
|
#if defined(__PRE_RAM__) && IS_ENABLED(CONFIG_CACHE_AS_RAM)
|
||||||
asm(".section .car.global_data,\"w\",@nobits");
|
asm(".section .car.global_data,\"w\",@nobits");
|
||||||
asm(".previous");
|
asm(".previous");
|
||||||
|
@ -43,6 +45,20 @@ void *car_sync_var_ptr(void *var);
|
||||||
#define car_set_var(var, val) \
|
#define car_set_var(var, val) \
|
||||||
do { car_get_var(var) = (val); } while(0)
|
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
|
#else
|
||||||
#define CAR_GLOBAL
|
#define CAR_GLOBAL
|
||||||
static inline void *car_get_var_ptr(void *var) { return var; }
|
static inline void *car_get_var_ptr(void *var) { return var; }
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
*/
|
*/
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <arch/stages.h>
|
#include <arch/stages.h>
|
||||||
|
#include <arch/early_variables.h>
|
||||||
#include <cpu/x86/mtrr.h>
|
#include <cpu/x86/mtrr.h>
|
||||||
#include <cpu/amd/mtrr.h>
|
#include <cpu/amd/mtrr.h>
|
||||||
#include <cpu/amd/car.h>
|
#include <cpu/amd/car.h>
|
||||||
|
@ -22,18 +23,9 @@
|
||||||
#define print_car_debug(x)
|
#define print_car_debug(x)
|
||||||
#endif
|
#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)
|
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);
|
return ALIGN(car_size + 1024, 1024);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,9 +30,6 @@ typedef void (* const car_migration_func_t)(void);
|
||||||
|
|
||||||
extern car_migration_func_t _car_migrate_start;
|
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
|
* 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:
|
* 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)
|
static void do_car_migrate_variables(void)
|
||||||
{
|
{
|
||||||
void *migrated_base;
|
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. */
|
/* Check if already migrated. */
|
||||||
if (car_migrated)
|
if (car_migrated)
|
||||||
return;
|
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) {
|
if (migrated_base == NULL) {
|
||||||
printk(BIOS_ERR, "Could not migrate CAR data!\n");
|
printk(BIOS_ERR, "Could not migrate CAR data!\n");
|
||||||
return;
|
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. */
|
/* Mark that the data has been moved. */
|
||||||
car_migrated = ~0;
|
car_migrated = ~0;
|
||||||
|
|
|
@ -519,7 +519,8 @@ struct sys_info {
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
#ifdef __PRE_RAM__
|
#ifdef __PRE_RAM__
|
||||||
extern struct sys_info sysinfo_car;
|
#include <arch/early_variables.h>
|
||||||
|
struct sys_info sysinfo_car CAR_GLOBAL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <reset.h>
|
#include <reset.h>
|
||||||
|
|
|
@ -263,7 +263,8 @@ struct sys_info {
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
#ifdef __PRE_RAM__
|
#ifdef __PRE_RAM__
|
||||||
extern struct sys_info sysinfo_car;
|
#include <arch/early_variables.h>
|
||||||
|
struct sys_info sysinfo_car CAR_GLOBAL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* AMDK8_PRE_F_H */
|
#endif /* AMDK8_PRE_F_H */
|
||||||
|
|
|
@ -17,9 +17,6 @@
|
||||||
#include "option_table.h"
|
#include "option_table.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <arch/early_variables.h>
|
|
||||||
struct sys_info sysinfo_car CAR_GLOBAL;
|
|
||||||
|
|
||||||
void setup_resource_map(const unsigned int *register_values, int max)
|
void setup_resource_map(const unsigned int *register_values, int max)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
|
@ -42,9 +42,6 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#include <arch/early_variables.h>
|
|
||||||
struct sys_info sysinfo_car CAR_GLOBAL;
|
|
||||||
|
|
||||||
#include "f_pci.c"
|
#include "f_pci.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)
|
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
|
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
|
wait_till_sysinfo_in_ram(); // use pci to get it
|
||||||
|
|
||||||
if(sysinfox->mem_trained[nodeid] == 0x80) {
|
if(sysinfox->mem_trained[nodeid] == 0x80) {
|
||||||
|
|
Loading…
Reference in New Issue