131 changes: 3 additions & 128 deletions src/arch/x86/acpi_s3.c
Expand Up @@ -24,6 +24,7 @@
#include <program_loading.h>
#include <romstage_handoff.h>
#include <symbols.h>
#include <cpu/x86/smm.h>

#if ENV_RAMSTAGE || ENV_POSTCAR

Expand Down Expand Up @@ -69,154 +70,28 @@ void acpi_fail_wakeup(void)
}
#endif /* ENV_RAMSTAGE */

struct resume_backup {
uint64_t cbmem;
uint64_t lowmem;
uint64_t size;
uint8_t valid;
};

#define BACKUP_PAGE_SZ 4096

static int backup_create_or_update(struct resume_backup *backup_mem,
uintptr_t base, size_t size)
{
uintptr_t top;

if (CONFIG(ACPI_HUGE_LOWMEM_BACKUP)) {
base = CONFIG_RAMBASE;
size = HIGH_MEMORY_SAVE;
}

/* Align backup region to complete pages. */
top = ALIGN_UP(base + size, BACKUP_PAGE_SZ);
base = ALIGN_DOWN(base, BACKUP_PAGE_SZ);
size = top - base;

/* Cannot extend existing region, should not happen. */
if (backup_mem && (backup_mem->size < size))
return -1;

/* Allocate backup with room for header. */
if (!backup_mem) {
size_t header_sz = ALIGN_UP(sizeof(*backup_mem),
BACKUP_PAGE_SZ);
backup_mem = cbmem_add(CBMEM_ID_RESUME, header_sz + size);
if (!backup_mem)
return -1;

/* Container starts from boundary after header. */
backup_mem->cbmem = (uintptr_t)backup_mem + header_sz;
}

backup_mem->valid = 0;
backup_mem->lowmem = base;
backup_mem->size = size;
return 0;
}

void *acpi_backup_container(uintptr_t base, size_t size)
{
struct resume_backup *backup_mem = cbmem_find(CBMEM_ID_RESUME);
if (!backup_mem)
return NULL;

if (!IS_ALIGNED(base, BACKUP_PAGE_SZ) || !IS_ALIGNED(size,
BACKUP_PAGE_SZ))
return NULL;

if (backup_create_or_update(backup_mem, base, size) < 0)
return NULL;

backup_mem->valid = 1;
return (void *)(uintptr_t)backup_mem->cbmem;
}

void backup_ramstage_section(uintptr_t base, size_t size)
{
struct resume_backup *backup_mem = cbmem_find(CBMEM_ID_RESUME);

/* For first boot we exit here as CBMEM_ID_RESUME is only
* created late in ramstage with acpi_prepare_resume_backup().
*/
if (!backup_mem)
return;

/* Check that the backup is not done twice. */
if (backup_mem->valid)
return;

/* When we are called from ramstage loader, update header with
* properties of the ramstage we will load.
*/
if (backup_create_or_update(backup_mem, base, size) < 0)
return;

/* Back up the OS-controlled memory where ramstage will be loaded. */
memcpy((void *)(uintptr_t)backup_mem->cbmem,
(void *)(uintptr_t)backup_mem->lowmem,
(size_t)backup_mem->size);
backup_mem->valid = 1;
}

/* Let's prepare the ACPI S3 Resume area now already, so we can rely on
* it being there during reboot time. If this fails, ACPI resume will
* be disabled. We assume that ramstage does not change while in suspend,
* so base and size of the currently running ramstage are used
* for allocation.
*/
void acpi_prepare_resume_backup(void)
{
if (!acpi_s3_resume_allowed())
return;

if (CONFIG(RELOCATABLE_RAMSTAGE))
return;

backup_create_or_update(NULL, (uintptr_t)_program,
REGION_SIZE(program));
}

#define WAKEUP_BASE 0x600

asmlinkage void (*acpi_do_wakeup)(uintptr_t vector, u32 backup_source,
u32 backup_target, u32 backup_size) = (void *)WAKEUP_BASE;
asmlinkage void (*acpi_do_wakeup)(uintptr_t vector) = (void *)WAKEUP_BASE;

extern unsigned char __wakeup;
extern unsigned int __wakeup_size;

static void acpi_jump_to_wakeup(void *vector)
{
uintptr_t source = 0, target = 0;
size_t size = 0;

if (!acpi_s3_resume_allowed()) {
printk(BIOS_WARNING, "ACPI: S3 resume not allowed.\n");
return;
}

if (!CONFIG(RELOCATABLE_RAMSTAGE)) {
struct resume_backup *backup_mem = cbmem_find(CBMEM_ID_RESUME);
if (backup_mem && backup_mem->valid) {
backup_mem->valid = 0;
target = backup_mem->lowmem;
source = backup_mem->cbmem;
size = backup_mem->size;
} else {
printk(BIOS_WARNING, "ACPI: Backup memory missing. "
"No S3 resume.\n");
return;
}
}

/* Copy wakeup trampoline in place. */
memcpy((void *)WAKEUP_BASE, &__wakeup, __wakeup_size);

set_boot_successful();

timestamp_add_now(TS_ACPI_WAKE_JUMP);

acpi_do_wakeup((uintptr_t)vector, source, target, size);
acpi_do_wakeup((uintptr_t)vector);
}

void __weak mainboard_suspend_resume(void)
Expand Down
5 changes: 2 additions & 3 deletions src/arch/x86/assembly_entry.S
Expand Up @@ -41,6 +41,7 @@ _start:
movl $(_car_global_end), %ecx
movl $(_car_global_start), %edi
sub %edi, %ecx
shrl $2, %ecx
rep stosl

#if ((ENV_VERSTAGE && CONFIG(VERSTAGE_DEBUG_SPINLOOP)) \
Expand All @@ -60,9 +61,7 @@ debug_spinloop:
#endif
call car_stage_entry

/* This is here for linking purposes. */
.weak car_stage_entry
car_stage_entry:
/* Expect to never return. */
1:
jmp 1b

Expand Down
8 changes: 4 additions & 4 deletions src/arch/x86/car.ld
Expand Up @@ -76,15 +76,15 @@
* cbmem console. This is useful for clearing this area on a per-stage
* basis when more than one stage uses cache-as-ram for CAR_GLOBALs. */
_car_global_start = .;
#if CONFIG(NO_CAR_GLOBAL_MIGRATION)
/* Allow global unitialized variables when CAR_GLOBALs are not used. */
#if ENV_STAGE_HAS_BSS_SECTION
/* Allow global uninitialized variables for stages without CAR teardown. */
*(.bss)
*(.bss.*)
*(.sbss)
*(.sbss.*)
#else
/* .car.global_data objects only around when
* !CONFIG_NO_CAR_GLOBAL_MIGRATION is employed. */
* CONFIG_CAR_GLOBAL_MIGRATION is employed. */
*(.car.global_data);
#endif
. = ALIGN(ARCH_POINTER_ALIGN_SIZE);
Expand All @@ -107,7 +107,7 @@
.illegal_globals . : {
*(EXCLUDE_FILE ("*/libagesa.*.a:" "*/romstage*/buildOpts.o" "*/romstage*/agesawrapper.o" "*/vendorcode/amd/agesa/*" "*/vendorcode/amd/cimx/*") .data)
*(EXCLUDE_FILE ("*/libagesa.*.a:" "*/romstage*/buildOpts.o" "*/romstage*/agesawrapper.o" "*/vendorcode/amd/agesa/*" "*/vendorcode/amd/cimx/*") .data.*)
#if !CONFIG(NO_CAR_GLOBAL_MIGRATION)
#if CONFIG(CAR_GLOBAL_MIGRATION)
*(.bss)
*(.bss.*)
*(.sbss)
Expand Down
18 changes: 8 additions & 10 deletions src/arch/x86/include/arch/acpi.h
Expand Up @@ -26,8 +26,6 @@
#ifndef __ASM_ACPI_H
#define __ASM_ACPI_H

#define HIGH_MEMORY_SAVE (CONFIG_RAMTOP - CONFIG_RAMBASE)

/*
* The type and enable fields are common in ACPI, but the
* values themselves are hardware implementation defined.
Expand Down Expand Up @@ -131,6 +129,14 @@ typedef struct acpi_gen_regaddr {
#define ACPI_ACCESS_SIZE_DWORD_ACCESS 3
#define ACPI_ACCESS_SIZE_QWORD_ACCESS 4

/* Common ACPI HIDs */
#define ACPI_HID_FDC "PNP0700"
#define ACPI_HID_KEYBOARD "PNP0303"
#define ACPI_HID_MOUSE "PNP0F03"
#define ACPI_HID_COM "PNP0501"
#define ACPI_HID_LPT "PNP0400"
#define ACPI_HID_PNP "PNP0C02"

/* Generic ACPI header, provided by (almost) all tables */
typedef struct acpi_table_header {
char signature[4]; /* ACPI signature (4 ASCII characters) */
Expand Down Expand Up @@ -936,7 +942,6 @@ unsigned long acpi_create_hest_error_source(acpi_hest_t *hest,
/* For ACPI S3 support. */
void acpi_fail_wakeup(void);
void acpi_resume(void *wake_vec);
void acpi_prepare_resume_backup(void);
void mainboard_suspend_resume(void);
void *acpi_find_wakeup_vector(void);

Expand Down Expand Up @@ -976,13 +981,6 @@ static inline int acpi_s3_resume_allowed(void)
return CONFIG(HAVE_ACPI_RESUME);
}

/* Return address in reserved memory where to backup low memory
* while platform resumes from S3 suspend. Caller is responsible of
* making a complete copy of the region base..base+size, with
* parameteres base and size that meet page alignment requirement.
*/
void *acpi_backup_container(uintptr_t base, size_t size);

#if CONFIG(HAVE_ACPI_RESUME)

#ifdef __PRE_RAM__
Expand Down
1 change: 1 addition & 0 deletions src/arch/x86/include/arch/acpi_device.h
Expand Up @@ -63,6 +63,7 @@ struct acpi_dp {

struct device;
const char *acpi_device_name(const struct device *dev);
const char *acpi_device_hid(const struct device *dev);
const char *acpi_device_path(const struct device *dev);
const char *acpi_device_scope(const struct device *dev);
const char *acpi_device_path_join(const struct device *dev, const char *name);
Expand Down
63 changes: 1 addition & 62 deletions src/arch/x86/include/arch/cpu.h
Expand Up @@ -203,12 +203,6 @@ static inline unsigned int cpuid_edx(unsigned int op)
unsigned int cpu_cpuid_extended_level(void);
int cpu_have_cpuid(void);

/* Only with !PARALLEL_MP. */
void smm_init(void);
void smm_init_completion(void);

void smm_setup_structures(void *gnvs, void *tcg, void *smi1);

static inline bool cpu_is_amd(void)
{
return CONFIG(CPU_AMD_AGESA) || CONFIG(CPU_AMD_PI)
Expand Down Expand Up @@ -285,72 +279,17 @@ static inline void get_fms(struct cpuinfo_x86 *c, uint32_t tfms)
c->x86_model += ((tfms >> 16) & 0xF) << 4;

}
#endif

/* romcc does not understand regparm. */
#define asmlinkage __attribute__((regparm(0)))

#ifndef __ROMCC__
/*
* When using CONFIG_C_ENVIRONMENT_BOOTBLOCK the car_stage_entry()
* is the symbol jumped to for each stage after bootblock using
* cache-as-ram.
*/
asmlinkage void car_stage_entry(void);

/*
* Support setting up a stack frame consisting of MTRR information
* for use in bootstrapping the caching attributes after cache-as-ram
* is torn down.
*/

struct postcar_frame {
uintptr_t stack;
uint32_t upper_mask;
int max_var_mtrrs;
int num_var_mtrrs;
};

/*
* Initialize postcar_frame object allocating stack from cbmem,
* with stack_size == 0, default 4 KiB is allocated.
* Returns 0 on success, < 0 on error.
*/
int postcar_frame_init(struct postcar_frame *pcf, size_t stack_size);

/*
* Add variable MTRR covering the provided range with MTRR type.
*/
void postcar_frame_add_mtrr(struct postcar_frame *pcf,
uintptr_t addr, size_t size, int type);

/*
* Add variable MTRR covering the memory-mapped ROM with given MTRR type.
*/
void postcar_frame_add_romcache(struct postcar_frame *pcf, int type);

/*
* Push used MTRR and Max MTRRs on to the stack
* and return pointer to stack top.
*/
void *postcar_commit_mtrrs(struct postcar_frame *pcf);

/*
* Load and run a program that takes control of execution that
* tears down CAR and loads ramstage. The postcar_frame object
* indicates how to set up the frame. If caching is enabled at
* the time of the call it is up to the platform code to handle
* coherency with dirty lines in the cache using some mechansim
* such as platform_prog_run() because run_postcar_phase()
* utilizes prog_run() internally.
*/
void run_postcar_phase(struct postcar_frame *pcf);

/*
* Systems without a native coreboot cache-as-ram teardown may implement
* this to use an alternate method.
*/
void late_car_teardown(void);

#endif

/*
Expand Down
54 changes: 16 additions & 38 deletions src/arch/x86/include/arch/early_variables.h
Expand Up @@ -20,7 +20,8 @@
#include <commonlib/helpers.h>
#include <stdlib.h>

#if ENV_CACHE_AS_RAM && !CONFIG(NO_CAR_GLOBAL_MIGRATION)
#if ENV_ROMSTAGE && CONFIG(CAR_GLOBAL_MIGRATION)

asm(".section .car.global_data,\"w\",@nobits");
asm(".previous");
#ifdef __clang__
Expand All @@ -29,27 +30,6 @@ asm(".previous");
#define CAR_GLOBAL __attribute__((used, section(".car.global_data#")))
#endif /* __clang__ */

/*
* In stages that use CAR (verstage, C bootblock) all CAR_GLOBAL variables are
* accessed unconditionally because cbmem is never initialized until romstage
* when dram comes up.
*/
#if !ENV_ROMSTAGE
static inline void *car_get_var_ptr(void *var)
{
return var;
}

static inline void *car_sync_var_ptr(void *var)
{
return var;
}

static inline int car_active(void)
{
return 1;
}
#else
/* Get the correct pointer for the CAR global variable. */
void *car_get_var_ptr(void *var);

Expand All @@ -58,7 +38,6 @@ void *car_sync_var_ptr(void *var);

/* Return 1 when currently running with globals in Cache-as-RAM, 0 otherwise. */
int car_active(void);
#endif /* !ENV_ROMSTAGE */

/* Get and set a primitive type global variable. */
#define car_get_var(var) \
Expand All @@ -81,26 +60,25 @@ static inline size_t car_object_offset(void *ptr)
#else

/*
* We might end up here if:
* 1. ENV_CACHE_AS_RAM is not set for the stage or
* 2. ENV_CACHE_AS_RAM is set for the stage but CONFIG_NO_CAR_GLOBAL_MIGRATION
* is also set. In this case, there is no need to migrate CAR global
* variables. But, since we might still be running out of CAR, car_active needs
* to return 1 if ENV_CACHE_AS_RAM is set.
* For all stages other than romstage, all CAR_GLOBAL variables are accessed
* unconditionally as there is no migration of symbols.
*/

#define CAR_GLOBAL
static inline void *car_get_var_ptr(void *var) { return var; }

#if ENV_CACHE_AS_RAM
static inline int car_active(void) { return 1; }
#else
static inline int car_active(void) { return 0; }
#endif /* ENV_CACHE_AS_RAM */

#define car_get_var(var) (var)
#define car_sync_var(var) (var)
#define car_set_var(var, val) (var) = (val)
#endif /* ENV_CACHE_AS_RAM && !CONFIG(NO_CAR_GLOBAL_MIGRATION) */

static inline void *car_get_var_ptr(void *var)
{
return var;
}

static inline int car_active(void)
{
return ENV_CACHE_AS_RAM;
}

#endif

#endif /* ARCH_EARLY_VARIABLES_H */
86 changes: 0 additions & 86 deletions src/arch/x86/include/arch/intel-family.h

This file was deleted.

7 changes: 0 additions & 7 deletions src/arch/x86/include/arch/memlayout.h
Expand Up @@ -16,13 +16,6 @@
#ifndef __ARCH_MEMLAYOUT_H
#define __ARCH_MEMLAYOUT_H


#if ENV_BOOTBLOCK || ENV_ROMSTAGE || ENV_VERSTAGE
/* No .data or .bss sections. Cache as RAM is handled separately. */
#define ARCH_STAGE_HAS_DATA_SECTION 0
#define ARCH_STAGE_HAS_BSS_SECTION 0
#endif

#if (CONFIG_RAMTOP == 0)
# error "CONFIG_RAMTOP not configured"
#endif
Expand Down
91 changes: 91 additions & 0 deletions src/arch/x86/include/arch/romstage.h
@@ -0,0 +1,91 @@
/*
* This file is part of the coreboot project.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/

#ifndef __ARCH_ROMSTAGE_H__
#define __ARCH_ROMSTAGE_H__

#include <arch/cpu.h>
#include <stddef.h>
#include <stdint.h>

void mainboard_romstage_entry(void);

/*
* Support setting up a stack frame consisting of MTRR information
* for use in bootstrapping the caching attributes after cache-as-ram
* is torn down.
*/

struct postcar_frame {
uintptr_t stack;
uint32_t upper_mask;
int max_var_mtrrs;
int num_var_mtrrs;
int skip_common_mtrr;
};

/*
* Initialize postcar_frame object allocating stack from cbmem,
* with stack_size == 0, default 4 KiB is allocated.
* Returns 0 on success, < 0 on error.
*/
int postcar_frame_init(struct postcar_frame *pcf, size_t stack_size);

/*
* Add variable MTRR covering the provided range with MTRR type.
*/
void postcar_frame_add_mtrr(struct postcar_frame *pcf,
uintptr_t addr, size_t size, int type);

/*
* Add variable MTRR covering the memory-mapped ROM with given MTRR type.
*/
void postcar_frame_add_romcache(struct postcar_frame *pcf, int type);

/*
* Add a common MTRR setup most platforms will have as a subset.
*/
void postcar_frame_common_mtrrs(struct postcar_frame *pcf);

/*
* fill_postcar_frame() is called after raminit completes and right before
* calling run_postcar_phase(). Implementation should call postcar_frame_add_mtrr()
* to tag memory ranges as cacheable to speed up execution of postcar and
* early ramstage.
*/
void fill_postcar_frame(struct postcar_frame *pcf);

/*
* prepare_and_run_postcar() determines the stack to use after
* cache-as-ram is torn down as well as the MTRR settings to use.
*/
void prepare_and_run_postcar(struct postcar_frame *pcf);

/*
* Load and run a program that takes control of execution that
* tears down CAR and loads ramstage. The postcar_frame object
* indicates how to set up the frame. If caching is enabled at
* the time of the call it is up to the platform code to handle
* coherency with dirty lines in the cache using some mechansim
* such as platform_prog_run() because run_postcar_phase()
* utilizes prog_run() internally.
*/
void run_postcar_phase(struct postcar_frame *pcf);

/*
* Systems without a native coreboot cache-as-ram teardown may implement
* this to use an alternate method.
*/
void late_car_teardown(void);

#endif /* __ARCH_ROMSTAGE_H__ */
18 changes: 12 additions & 6 deletions src/arch/x86/memlayout.ld
Expand Up @@ -16,6 +16,15 @@
#include <memlayout.h>
#include <arch/header.ld>

/* Pull in the either CAR or early DRAM rules. */
#if ENV_ROMSTAGE_OR_BEFORE
#if ENV_CACHE_AS_RAM
#define EARLY_MEMLAYOUT "car.ld"
#else
#error "Early DRAM environment for x86 is work-in-progress. */
#endif
#endif

SECTIONS
{
/*
Expand All @@ -34,23 +43,20 @@ SECTIONS
* Link at 32MiB address and rely on cbfstool to relocate to XIP. */
ROMSTAGE(CONFIG_ROMSTAGE_ADDR, 1M)

/* Pull in the cache-as-ram rules. */
#include "car.ld"
#include EARLY_MEMLAYOUT
#elif ENV_VERSTAGE
/* The 1M size is not allocated. It's just for basic size checking.
* Link at 32MiB address and rely on cbfstool to relocate to XIP. */
VERSTAGE(CONFIG_VERSTAGE_ADDR, 1M)

/* Pull in the cache-as-ram rules. */
#include "car.ld"
#include EARLY_MEMLAYOUT
#elif ENV_BOOTBLOCK
/* This is for C_ENVIRONMENT_BOOTBLOCK. arch/x86/bootblock.ld contains
* the logic for the romcc linking. */
BOOTBLOCK(0xffffffff - CONFIG_C_ENV_BOOTBLOCK_SIZE + 1,
CONFIG_C_ENV_BOOTBLOCK_SIZE)

/* Pull in the cache-as-ram rules. */
#include "car.ld"
#include EARLY_MEMLAYOUT

#elif ENV_POSTCAR
POSTCAR(32M, 1M)
Expand Down
2 changes: 1 addition & 1 deletion src/arch/x86/postcar.c
Expand Up @@ -13,7 +13,7 @@
* GNU General Public License for more details.
*/

#include <arch/cpu.h>
#include <arch/romstage.h>
#include <cbmem.h>
#include <console/console.h>
#include <cpu/x86/mtrr.h>
Expand Down
29 changes: 26 additions & 3 deletions src/arch/x86/postcar_loader.c
Expand Up @@ -13,7 +13,7 @@
* GNU General Public License for more details.
*/

#include <arch/cpu.h>
#include <arch/romstage.h>
#include <cbmem.h>
#include <console/console.h>
#include <cpu/cpu.h>
Expand Down Expand Up @@ -120,15 +120,38 @@ void postcar_frame_add_romcache(struct postcar_frame *pcf, int type)
postcar_frame_add_mtrr(pcf, CACHE_ROM_BASE, CACHE_ROM_SIZE, type);
}

void *postcar_commit_mtrrs(struct postcar_frame *pcf)
void postcar_frame_common_mtrrs(struct postcar_frame *pcf)
{
if (pcf->skip_common_mtrr)
return;

/* Cache the ROM as WP just below 4GiB. */
postcar_frame_add_romcache(pcf, MTRR_TYPE_WRPROT);
}

/* prepare_and_run_postcar() determines the stack to use after
* cache-as-ram is torn down as well as the MTRR settings to use. */
void prepare_and_run_postcar(struct postcar_frame *pcf)
{
if (postcar_frame_init(pcf, 0))
die("Unable to initialize postcar frame.\n");

fill_postcar_frame(pcf);

postcar_frame_common_mtrrs(pcf);

run_postcar_phase(pcf);
/* We do not return here. */
}

static void postcar_commit_mtrrs(struct postcar_frame *pcf)
{
/*
* Place the number of used variable MTRRs on stack then max number
* of variable MTRRs supported in the system.
*/
stack_push(pcf, pcf->num_var_mtrrs);
stack_push(pcf, pcf->max_var_mtrrs);
return (void *) pcf->stack;
}

static void finalize_load(uintptr_t *stack_top_ptr, uintptr_t stack_top)
Expand Down
13 changes: 5 additions & 8 deletions src/arch/x86/smbios.c
Expand Up @@ -275,20 +275,18 @@ static void trim_trailing_whitespace(char *buffer, size_t buffer_size)
static void smbios_fill_dimm_part_number(const char *part_number,
struct smbios_type17 *t)
{
const size_t trimmed_buffer_size = DIMM_INFO_PART_NUMBER_SIZE;

int invalid;
size_t i, len;
char trimmed_part_number[trimmed_buffer_size];
char trimmed_part_number[DIMM_INFO_PART_NUMBER_SIZE];

strncpy(trimmed_part_number, part_number, trimmed_buffer_size);
trimmed_part_number[trimmed_buffer_size - 1] = '\0';
strncpy(trimmed_part_number, part_number, sizeof(trimmed_part_number));
trimmed_part_number[sizeof(trimmed_part_number) - 1] = '\0';

/*
* SPD mandates that unused characters be represented with a ' '.
* We don't want to publish the whitespace in the SMBIOS tables.
*/
trim_trailing_whitespace(trimmed_part_number, trimmed_buffer_size);
trim_trailing_whitespace(trimmed_part_number, sizeof(trimmed_part_number));

len = strlen(trimmed_part_number);

Expand All @@ -304,8 +302,7 @@ static void smbios_fill_dimm_part_number(const char *part_number,
/* Null String in Part Number will have "None" instead. */
t->part_number = smbios_add_string(t->eos, "None");
} else if (invalid) {
char string_buffer[trimmed_buffer_size +
10 /* strlen("Invalid ()") */];
char string_buffer[sizeof(trimmed_part_number) + 10];

snprintf(string_buffer, sizeof(string_buffer), "Invalid (%s)",
trimmed_part_number);
Expand Down
8 changes: 0 additions & 8 deletions src/arch/x86/wakeup.S
Expand Up @@ -64,14 +64,6 @@ __wakeup:
shr $4, %eax
movw %ax, (__wakeup_segment)

/* Then overwrite coreboot with our backed up memory */
cld
movl 8(%esp), %esi
movl 12(%esp), %edi
movl 16(%esp), %ecx
shrl $2, %ecx
rep movsl

/* Activate the right segment descriptor real mode. */
ljmp $0x28, $RELOCATED(1f)
1:
Expand Down
4 changes: 2 additions & 2 deletions src/commonlib/region.c
Expand Up @@ -27,10 +27,10 @@ int region_is_subregion(const struct region *p, const struct region *c)
if (region_offset(c) < region_offset(p))
return 0;

if (region_sz(c) > region_sz(p))
if (region_end(c) > region_end(p))
return 0;

if (region_end(c) > region_end(p))
if (region_end(c) < region_offset(c))
return 0;

return 1;
Expand Down
2 changes: 1 addition & 1 deletion src/console/Kconfig
Expand Up @@ -13,7 +13,7 @@ config BOOTBLOCK_CONSOLE
config POSTCAR_CONSOLE
bool "Enable console output during postcar."
depends on POSTCAR_STAGE
default n
default y
help
Use console during the postcar if supported

Expand Down
3 changes: 1 addition & 2 deletions src/console/printk.c
Expand Up @@ -49,8 +49,7 @@ int do_vprintk(int msg_level, const char *fmt, va_list args)
{
int i, log_this;

if (CONFIG(SQUELCH_EARLY_SMP) && ENV_CACHE_AS_RAM &&
!boot_cpu())
if (CONFIG(SQUELCH_EARLY_SMP) && ENV_ROMSTAGE_OR_BEFORE && !boot_cpu())
return 0;

log_this = console_log_level(msg_level);
Expand Down
15 changes: 2 additions & 13 deletions src/cpu/Kconfig
Expand Up @@ -6,16 +6,11 @@ source "src/cpu/*/Kconfig"

if ARCH_X86

config CACHE_AS_RAM
bool
default y

config NO_CAR_GLOBAL_MIGRATION
config CAR_GLOBAL_MIGRATION
bool
default n
depends on CACHE_AS_RAM
help
This option is selected if there is no need to migrate CAR globals.
This option is selected if there is need to migrate CAR globals.
All stages which use CAR globals can directly access the variables
from their linked addresses.

Expand All @@ -28,12 +23,6 @@ config DCACHE_RAM_SIZE
config DCACHE_BSP_STACK_SIZE
hex

config DCACHE_BSP_STACK_SLUSH
hex

config DCACHE_AP_STACK_SIZE
hex

config SMP
bool
default y if MAX_CPUS != 1
Expand Down
1 change: 0 additions & 1 deletion src/cpu/amd/agesa/Kconfig
Expand Up @@ -29,7 +29,6 @@ config CPU_AMD_AGESA
select UDELAY_LAPIC
select LAPIC_MONOTONIC_TIMER
select SPI_FLASH if HAVE_ACPI_RESUME
select POSTCAR_STAGE
select SMM_ASEG

if CPU_AMD_AGESA
Expand Down
4 changes: 2 additions & 2 deletions src/cpu/amd/car/cache_as_ram.inc
Expand Up @@ -22,8 +22,8 @@

#define CacheSize CONFIG_DCACHE_RAM_SIZE
#define CacheBase CONFIG_DCACHE_RAM_BASE
#define CacheSizeBSPStack CONFIG_DCACHE_BSP_STACK_SIZE
#define CacheSizeBSPSlush CONFIG_DCACHE_BSP_STACK_SLUSH
#define CacheSizeBSPStack CONFIG_DCACHE_BSP_TOP_STACK_SIZE
#define CacheSizeBSPSlush CONFIG_DCACHE_BSP_TOP_STACK_SLUSH

/* For CAR with Fam10h. */
#define CacheSizeAPStack CONFIG_DCACHE_AP_STACK_SIZE
Expand Down
62 changes: 7 additions & 55 deletions src/cpu/amd/car/post_cache_as_ram.c
Expand Up @@ -27,6 +27,7 @@
#include <cpu/amd/car.h>
#include <cpu/amd/msr.h>
#include <arch/acpi.h>
#include <program_loading.h>
#include <romstage_handoff.h>

#include "cpu/amd/car/disable_cache_as_ram.c"
Expand All @@ -44,12 +45,6 @@
#define print_car_debug(format, arg...)
#endif

static size_t backup_size(void)
{
size_t car_size = car_data_size();
return ALIGN_UP(car_size + 1024, 1024);
}

static void memcpy_(void *d, const void *s, size_t len)
{
print_car_debug(" Copy [%08x-%08x] to [%08x - %08x] ...",
Expand All @@ -58,13 +53,6 @@ static void memcpy_(void *d, const void *s, size_t len)
memcpy(d, s, len);
}

static void memset_(void *d, int val, size_t len)
{
print_car_debug(" Fill [%08x-%08x] ...",
(uint32_t) d, (uint32_t) (d + len - 1));
memset(d, val, len);
}

static int memcmp_(void *d, const void *s, size_t len)
{
print_car_debug(" Compare [%08x-%08x] with [%08x - %08x] ...",
Expand All @@ -73,41 +61,6 @@ static int memcmp_(void *d, const void *s, size_t len)
return memcmp(d, s, len);
}

static void prepare_romstage_ramstack(int s3resume)
{
size_t backup_top = backup_size();
print_car_debug("Prepare CAR migration and stack regions...");

if (s3resume) {
void *resume_backup_memory =
acpi_backup_container(CONFIG_RAMBASE, HIGH_MEMORY_SAVE);
if (resume_backup_memory)
memcpy_(resume_backup_memory
+ HIGH_MEMORY_SAVE - backup_top,
(void *)(CONFIG_RAMTOP - backup_top),
backup_top);
}
memset_((void *)(CONFIG_RAMTOP - backup_top), 0, backup_top);

print_car_debug(" Done\n");
}

static void prepare_ramstage_region(int s3resume)
{
size_t backup_top = backup_size();
print_car_debug("Prepare ramstage memory region...");

if (s3resume) {
void *resume_backup_memory =
acpi_backup_container(CONFIG_RAMBASE, HIGH_MEMORY_SAVE);
if (resume_backup_memory)
memcpy_(resume_backup_memory, (void *) CONFIG_RAMBASE,
HIGH_MEMORY_SAVE - backup_top);
}

print_car_debug(" Done\n");
}

/* Disable Erratum 343 Workaround, see RevGuide for Fam10h, Pub#41322 Rev 3.33
* and RevGuide for Fam12h, Pub#44739 Rev 3.10
*/
Expand All @@ -131,15 +84,16 @@ asmlinkage void *post_cache_as_ram(void)
* boundary during romstage execution
*/
volatile uint32_t *lower_stack_boundary;
lower_stack_boundary =
(void *)((CONFIG_DCACHE_RAM_BASE + CONFIG_DCACHE_RAM_SIZE)
- CONFIG_DCACHE_BSP_STACK_SIZE);
lower_stack_boundary = (void *)((CONFIG_DCACHE_RAM_BASE + CONFIG_DCACHE_RAM_SIZE) -
CONFIG_DCACHE_BSP_TOP_STACK_SIZE);

if ((*lower_stack_boundary) != 0xdeadbeef)
printk(BIOS_WARNING, "BSP overran lower stack boundary. Undefined behaviour may result!\n");

s3resume = acpi_is_wakeup_s3();

prepare_romstage_ramstack(s3resume);
/* ACPI S3 is not supported without RELOCATABLE_RAMSTAGE and
* this will always return 0. */
s3resume = acpi_is_wakeup_s3();

romstage_handoff_init(s3resume);

Expand Down Expand Up @@ -177,8 +131,6 @@ asmlinkage void cache_as_ram_new_stack(void)
set_var_mtrr(0, 0x00000000, CACHE_TMP_RAMTOP, MTRR_TYPE_WRBACK);
enable_cache();

prepare_ramstage_region(acpi_is_wakeup_s3());

set_sysinfo_in_ram(1); // So other core0 could start to train mem

/*copy and execute ramstage */
Expand Down
6 changes: 3 additions & 3 deletions src/cpu/amd/family_10h-family_15h/Kconfig
Expand Up @@ -9,7 +9,7 @@ config CPU_AMD_MODEL_10XXX
select UDELAY_LAPIC
select SUPPORT_CPU_UCODE_IN_CBFS
select CPU_MICROCODE_MULTIPLE_FILES
select ACPI_HUGE_LOWMEM_BACKUP
select CAR_GLOBAL_MIGRATION

if CPU_AMD_MODEL_10XXX

Expand All @@ -36,11 +36,11 @@ config DCACHE_RAM_SIZE
hex
default 0x0c000

config DCACHE_BSP_STACK_SIZE
config DCACHE_BSP_TOP_STACK_SIZE
hex
default 0x4000

config DCACHE_BSP_STACK_SLUSH
config DCACHE_BSP_TOP_STACK_SLUSH
hex
default 0x4000 if USE_LARGE_DCACHE
default 0x1000
Expand Down
2 changes: 1 addition & 1 deletion src/cpu/amd/family_10h-family_15h/fidvid.c
Expand Up @@ -92,7 +92,7 @@ b.- prep_fid_change(...)
#include <console/console.h>
#include <cpu/amd/msr.h>
#include <device/pci_ops.h>
#include <inttypes.h>
#include <stdint.h>
#include <northbridge/amd/amdht/AsPsDefs.h>

static inline void print_debug_fv(const char *str, u32 val)
Expand Down
17 changes: 12 additions & 5 deletions src/cpu/amd/family_10h-family_15h/init_cpus.c
Expand Up @@ -379,12 +379,19 @@ u32 init_cpus(u32 cpu_init_detectedx, struct sys_info *sysinfo)
uint8_t fam15_bsp_core1_apicid;
struct node_core_id id;

/* Please refer to the calculations and explaination in cache_as_ram.inc before modifying these values */
/* Please refer to the calculations and explaination in cache_as_ram.inc
* before modifying these values */
uint32_t max_ap_stack_region_size = CONFIG_MAX_CPUS * CONFIG_DCACHE_AP_STACK_SIZE;
uint32_t max_bsp_stack_region_size = CONFIG_DCACHE_BSP_STACK_SIZE + CONFIG_DCACHE_BSP_STACK_SLUSH;
uint32_t bsp_stack_region_upper_boundary = CONFIG_DCACHE_RAM_BASE + CONFIG_DCACHE_RAM_SIZE;
uint32_t bsp_stack_region_lower_boundary = bsp_stack_region_upper_boundary - max_bsp_stack_region_size;
void *lower_stack_region_boundary = (void *)(bsp_stack_region_lower_boundary - max_ap_stack_region_size);
uint32_t max_bsp_stack_region_size = CONFIG_DCACHE_BSP_TOP_STACK_SIZE +
CONFIG_DCACHE_BSP_TOP_STACK_SLUSH;
uint32_t bsp_stack_region_upper_boundary = CONFIG_DCACHE_RAM_BASE +
CONFIG_DCACHE_RAM_SIZE;
uint32_t bsp_stack_region_lower_boundary = bsp_stack_region_upper_boundary -
max_bsp_stack_region_size;

void *lower_stack_region_boundary = (void *)(bsp_stack_region_lower_boundary -
max_ap_stack_region_size);

if (((void*)(sysinfo + 1)) > lower_stack_region_boundary)
printk(BIOS_WARNING,
"sysinfo extends into stack region (sysinfo range: [%p,%p] lower stack region boundary: %p)\n",
Expand Down
2 changes: 1 addition & 1 deletion src/cpu/amd/family_10h-family_15h/ram_calc.c
Expand Up @@ -68,7 +68,7 @@ uint64_t get_cc6_memory_size()
if (is_fam15h()) {
enable_cc6 = 0;

#ifdef __PRE_RAM__
#ifdef __SIMPLE_DEVICE__
if (pci_read_config32(PCI_DEV(0, 0x18, 2), 0x118) & (0x1 << 18))
enable_cc6 = 1;
#else
Expand Down
2 changes: 1 addition & 1 deletion src/cpu/amd/pi/Kconfig
Expand Up @@ -28,7 +28,7 @@ config CPU_AMD_PI
select UDELAY_LAPIC
select LAPIC_MONOTONIC_TIMER
select SPI_FLASH if HAVE_ACPI_RESUME
select POSTCAR_STAGE if !BINARYPI_LEGACY_WRAPPER
select CAR_GLOBAL_MIGRATION if BINARYPI_LEGACY_WRAPPER
select SMM_ASEG

if CPU_AMD_PI
Expand Down
8 changes: 3 additions & 5 deletions src/cpu/amd/quadcore/quadcore_id.c
Expand Up @@ -17,11 +17,9 @@


#include <arch/cpu.h>
#include <cpu/amd/msr.h>
#include <cpu/amd/multicore.h>
#include <device/pci_ops.h>
#ifdef __PRE_RAM__
#include <cpu/amd/msr.h>
#endif

//called by bus_cpu_scan too
u32 read_nb_cfg_54(void)
Expand All @@ -48,7 +46,7 @@ struct node_core_id get_node_core_id(u32 nb_cfg_54)
uint32_t family;
uint32_t model;

#ifdef __PRE_RAM__
#ifdef __SIMPLE_DEVICE__
f3xe8 = pci_read_config32(NODE_PCI(0, 3), 0xe8);
#else
f3xe8 = pci_read_config32(get_node_pci(0, 3), 0xe8);
Expand Down Expand Up @@ -115,7 +113,7 @@ struct node_core_id get_node_core_id(u32 nb_cfg_54)
uint32_t f5x84;
uint8_t core_count;

#ifdef __PRE_RAM__
#ifdef __SIMPLE_DEVICE__
f5x84 = pci_read_config32(NODE_PCI(0, 5), 0x84);
#else
f5x84 = pci_read_config32(get_node_pci(0, 5), 0x84);
Expand Down
1 change: 1 addition & 0 deletions src/cpu/amd/smm/smm_init.c
Expand Up @@ -21,6 +21,7 @@
#include <cpu/amd/msr.h>
#include <cpu/x86/cache.h>
#include <cpu/x86/smm.h>
#include <cpu/x86/smi_deprecated.h>
#include <string.h>

void smm_init(void)
Expand Down
2 changes: 1 addition & 1 deletion src/cpu/intel/car/bootblock.c
Expand Up @@ -21,7 +21,7 @@ asmlinkage void bootblock_c_entry_bist(uint64_t base_timestamp, uint32_t bist)
{
saved_bist = bist;
/* Call lib/bootblock.c main */
bootblock_main_with_timestamp(base_timestamp, NULL, 0);
bootblock_main_with_basetime(base_timestamp);
}

void __weak bootblock_early_northbridge_init(void) { }
Expand Down
26 changes: 20 additions & 6 deletions src/cpu/intel/car/romstage.c
Expand Up @@ -11,30 +11,38 @@
* GNU General Public License for more details.
*/

#include <arch/cpu.h>
#include <arch/romstage.h>
#include <bootblock_common.h>
#include <console/console.h>
#include <cpu/intel/romstage.h>
#include <cpu/x86/mtrr.h>
#include <cpu/x86/smm.h>
#include <arch/symbols.h>
#include <commonlib/helpers.h>
#include <program_loading.h>
#include <timestamp.h>

/* If we do not have a constrained _car_stack region size, use the
following as a guideline for acceptable stack usage. */
#define DCACHE_RAM_ROMSTAGE_STACK_SIZE 0x2000

static struct postcar_frame early_mtrrs;

static void romstage_main(unsigned long bist)
{
int i;
const int num_guards = 4;
const int num_guards = 64;
const u32 stack_guard = 0xdeadbeef;
u32 *stack_base;
u32 size;
const size_t stack_size = MAX(CONFIG_DCACHE_BSP_STACK_SIZE,
DCACHE_RAM_ROMSTAGE_STACK_SIZE);

/* Size of unallocated CAR. */
size = ALIGN_DOWN(_car_stack_size, 16);

size = MIN(size, DCACHE_RAM_ROMSTAGE_STACK_SIZE);
if (size < DCACHE_RAM_ROMSTAGE_STACK_SIZE)
size = MIN(size, stack_size);
if (size < stack_size)
printk(BIOS_DEBUG, "Romstage stack size limited to 0x%x!\n",
size);

Expand All @@ -43,7 +51,7 @@ static void romstage_main(unsigned long bist)
for (i = 0; i < num_guards; i++)
stack_base[i] = stack_guard;

mainboard_romstage_entry(bist);
mainboard_romstage_entry();

/* Check the stack. */
for (i = 0; i < num_guards; i++) {
Expand All @@ -52,7 +60,11 @@ static void romstage_main(unsigned long bist)
printk(BIOS_DEBUG, "Smashed stack detected in romstage!\n");
}

platform_enter_postcar();
if (CONFIG(SMM_TSEG))
smm_list_regions();

prepare_and_run_postcar(&early_mtrrs);
/* We do not return here. */
}

#if !CONFIG(C_ENVIRONMENT_BOOTBLOCK)
Expand All @@ -75,6 +87,8 @@ asmlinkage void bootblock_c_entry_bist(uint64_t base_timestamp, uint32_t bist)

asmlinkage void car_stage_entry(void)
{
timestamp_add_now(TS_START_ROMSTAGE);

/* Assumes the hardware was set up during the bootblock */
console_init();

Expand Down
1 change: 1 addition & 0 deletions src/cpu/intel/fit/Kconfig
Expand Up @@ -5,6 +5,7 @@ config CPU_INTEL_FIRMWARE_INTERFACE_TABLE

config CPU_INTEL_NUM_FIT_ENTRIES
int
default 16 if INTEL_TXT
default 4
depends on CPU_INTEL_FIRMWARE_INTERFACE_TABLE
help
Expand Down
2 changes: 0 additions & 2 deletions src/cpu/intel/haswell/chip.h
Expand Up @@ -13,8 +13,6 @@
* GNU General Public License for more details.
*/

extern struct chip_operations cpu_intel_haswell_ops;

/* Magic value used to locate this chip in the device tree */
#define SPEEDSTEP_APIC_MAGIC 0xACAC

Expand Down
10 changes: 0 additions & 10 deletions src/cpu/intel/haswell/haswell.h
Expand Up @@ -141,7 +141,6 @@ struct romstage_params {
struct pei_data *pei_data;
const void *gpio_map;
const struct rcba_config_instruction *rcba_config;
unsigned long bist;
void (*copy_spd)(struct pei_data *);
};
void romstage_common(const struct romstage_params *params);
Expand All @@ -154,15 +153,6 @@ void intel_cpu_haswell_finalize_smm(void);
/* Configure power limits for turbo mode */
void set_power_limits(u8 power_limit_1_time);
int cpu_config_tdp_levels(void);
void smm_relocation_handler(int cpu, uintptr_t curr_smbase,
uintptr_t staggered_smbase);
void smm_info(uintptr_t *perm_smbase, size_t *perm_smsize,
size_t *smm_save_state_size);
void smm_initialize(void);
void smm_relocate(void);
void smm_lock(void);
struct bus;
void bsp_init_and_start_aps(struct bus *cpu_bus);
/* Determine if HyperThreading is disabled. The variable is not valid until
* setup_ap_init() has been called. */
#endif
Expand Down
5 changes: 3 additions & 2 deletions src/cpu/intel/haswell/haswell_init.c
Expand Up @@ -24,6 +24,7 @@
#include <cpu/x86/mp.h>
#include <cpu/x86/lapic.h>
#include <cpu/intel/microcode.h>
#include <cpu/intel/smm_reloc.h>
#include <cpu/intel/speedstep.h>
#include <cpu/intel/turbo.h>
#include <cpu/x86/cache.h>
Expand Down Expand Up @@ -761,7 +762,7 @@ static void post_mp_init(void)
{
/* Now that all APs have been relocated as well as the BSP let SMIs
* start flowing. */
southbridge_smm_enable_smi();
smm_southbridge_enable_smi();

/* Lock down the SMRAM space. */
smm_lock();
Expand All @@ -778,7 +779,7 @@ static const struct mp_ops mp_ops = {
.post_mp_init = post_mp_init,
};

void bsp_init_and_start_aps(struct bus *cpu_bus)
void mp_init_cpus(struct bus *cpu_bus)
{
if (mp_init_with_smm(cpu_bus, &mp_ops))
printk(BIOS_ERR, "MP initialization failure.\n");
Expand Down
43 changes: 1 addition & 42 deletions src/cpu/intel/haswell/romstage.c
Expand Up @@ -15,69 +15,28 @@

#include <stdint.h>
#include <console/console.h>
#include <arch/cpu.h>
#include <cf9_reset.h>
#include <cpu/x86/bist.h>
#include <cpu/x86/msr.h>
#include <cpu/x86/mtrr.h>
#include <timestamp.h>
#include <device/pci_def.h>
#include <cpu/x86/lapic.h>
#include <cbmem.h>
#include <commonlib/helpers.h>
#include <program_loading.h>
#include <romstage_handoff.h>
#include <vendorcode/google/chromeos/chromeos.h>
#if CONFIG(EC_GOOGLE_CHROMEEC)
#include <ec/google/chromeec/ec.h>
#endif
#include <northbridge/intel/haswell/haswell.h>
#include <northbridge/intel/haswell/raminit.h>
#include <southbridge/intel/lynxpoint/pch.h>
#include <southbridge/intel/lynxpoint/me.h>
#include <cpu/intel/romstage.h>
#include "haswell.h"

/* platform_enter_postcar() determines the stack to use after
* cache-as-ram is torn down as well as the MTRR settings to use,
* and continues execution in postcar stage. */
void platform_enter_postcar(void)
{
struct postcar_frame pcf;
uintptr_t top_of_ram;

if (postcar_frame_init(&pcf, 0))
die("Unable to initialize postcar frame.\n");
/* Cache the ROM as WP just below 4GiB. */
postcar_frame_add_romcache(&pcf, MTRR_TYPE_WRPROT);

/* Cache RAM as WB from 0 -> CACHE_TMP_RAMTOP. */
postcar_frame_add_mtrr(&pcf, 0, CACHE_TMP_RAMTOP, MTRR_TYPE_WRBACK);

/* Cache at least 8 MiB below the top of ram, and at most 8 MiB
* above top of the ram. This satisfies MTRR alignment requirement
* with different TSEG size configurations.
*/
top_of_ram = ALIGN_DOWN((uintptr_t)cbmem_top(), 8*MiB);
postcar_frame_add_mtrr(&pcf, top_of_ram - 8*MiB, 16*MiB,
MTRR_TYPE_WRBACK);

run_postcar_phase(&pcf);
}

void romstage_common(const struct romstage_params *params)
{
int boot_mode;
int wake_from_s3;

if (params->bist == 0)
enable_lapic();
enable_lapic();

wake_from_s3 = early_pch_init(params->gpio_map, params->rcba_config);

/* Halt if there was a built in self test failure */
report_bist_failure(params->bist);

/* Perform some early chipset initialization required
* before RAM initialization can work
*/
Expand Down
136 changes: 57 additions & 79 deletions src/cpu/intel/haswell/smmrelocate.c
Expand Up @@ -24,15 +24,17 @@
#include <cpu/x86/msr.h>
#include <cpu/x86/mtrr.h>
#include <cpu/x86/smm.h>
#include <cpu/intel/em64t101_save_state.h>
#include <cpu/intel/smm_reloc.h>
#include <console/console.h>
#include <northbridge/intel/haswell/haswell.h>
#include <southbridge/intel/lynxpoint/pch.h>
#include "haswell.h"

#define EMRRphysBase_MSR 0x1f4
#define EMRRphysMask_MSR 0x1f5
#define UNCORE_EMRRphysBase_MSR 0x2f4
#define UNCORE_EMRRphysMask_MSR 0x2f5
#define MSR_PRMRR_PHYS_BASE 0x1f4
#define MSR_PRMRR_PHYS_MASK 0x1f5
#define MSR_UNCORE_PRMRR_PHYS_BASE 0x2f4
#define MSR_UNCORE_PRMRR_PHYS_MASK 0x2f5
#define SMM_MCA_CAP_MSR 0x17d
#define SMM_CPU_SVRSTR_BIT 57
#define SMM_CPU_SVRSTR_MASK (1 << (SMM_CPU_SVRSTR_BIT - 32))
Expand All @@ -43,19 +45,17 @@
#define IEDBASE_MSR 0xc22

#define SMRR_SUPPORTED (1 << 11)
#define EMRR_SUPPORTED (1 << 12)
#define PRMRR_SUPPORTED (1 << 12)

struct smm_relocation_params {
u32 smram_base;
u32 smram_size;
u32 ied_base;
u32 ied_size;
uintptr_t ied_base;
size_t ied_size;
msr_t smrr_base;
msr_t smrr_mask;
msr_t emrr_base;
msr_t emrr_mask;
msr_t uncore_emrr_base;
msr_t uncore_emrr_mask;
msr_t prmrr_base;
msr_t prmrr_mask;
msr_t uncore_prmrr_base;
msr_t uncore_prmrr_mask;
/* The smm_save_state_in_msrs field indicates if SMM save state
* locations live in MSRs. This indicates to the CPUs how to adjust
* the SMMBASE and IEDBASE */
Expand All @@ -73,22 +73,22 @@ static inline void write_smrr(struct smm_relocation_params *relo_params)
wrmsr(IA32_SMRR_PHYS_MASK, relo_params->smrr_mask);
}

static inline void write_emrr(struct smm_relocation_params *relo_params)
static inline void write_prmrr(struct smm_relocation_params *relo_params)
{
printk(BIOS_DEBUG, "Writing EMRR. base = 0x%08x, mask=0x%08x\n",
relo_params->emrr_base.lo, relo_params->emrr_mask.lo);
wrmsr(EMRRphysBase_MSR, relo_params->emrr_base);
wrmsr(EMRRphysMask_MSR, relo_params->emrr_mask);
printk(BIOS_DEBUG, "Writing PRMRR. base = 0x%08x, mask=0x%08x\n",
relo_params->prmrr_base.lo, relo_params->prmrr_mask.lo);
wrmsr(MSR_PRMRR_PHYS_BASE, relo_params->prmrr_base);
wrmsr(MSR_PRMRR_PHYS_MASK, relo_params->prmrr_mask);
}

static inline void write_uncore_emrr(struct smm_relocation_params *relo_params)
static inline void write_uncore_prmrr(struct smm_relocation_params *relo_params)
{
printk(BIOS_DEBUG,
"Writing UNCORE_EMRR. base = 0x%08x, mask=0x%08x\n",
relo_params->uncore_emrr_base.lo,
relo_params->uncore_emrr_mask.lo);
wrmsr(UNCORE_EMRRphysBase_MSR, relo_params->uncore_emrr_base);
wrmsr(UNCORE_EMRRphysMask_MSR, relo_params->uncore_emrr_mask);
"Writing UNCORE_PRMRR. base = 0x%08x, mask=0x%08x\n",
relo_params->uncore_prmrr_base.lo,
relo_params->uncore_prmrr_mask.lo);
wrmsr(MSR_UNCORE_PRMRR_PHYS_BASE, relo_params->uncore_prmrr_base);
wrmsr(MSR_UNCORE_PRMRR_PHYS_MASK, relo_params->uncore_prmrr_mask);
}

static void update_save_state(int cpu, uintptr_t curr_smbase,
Expand Down Expand Up @@ -196,38 +196,27 @@ void smm_relocation_handler(int cpu, uintptr_t curr_smbase,
/* Make appropriate changes to the save state map. */
update_save_state(cpu, curr_smbase, staggered_smbase, relo_params);

/* Write EMRR and SMRR MSRs based on indicated support. */
/* Write PRMRR and SMRR MSRs based on indicated support. */
mtrr_cap = rdmsr(MTRR_CAP_MSR);
if (mtrr_cap.lo & SMRR_SUPPORTED)
write_smrr(relo_params);

if (mtrr_cap.lo & EMRR_SUPPORTED) {
write_emrr(relo_params);
/* UNCORE_EMRR msrs are package level. Therefore, only
if (mtrr_cap.lo & PRMRR_SUPPORTED) {
write_prmrr(relo_params);
/* UNCORE_PRMRR msrs are package level. Therefore, only
* configure these MSRs on the BSP. */
if (cpu == 0)
write_uncore_emrr(relo_params);
write_uncore_prmrr(relo_params);
}
}

static u32 northbridge_get_base_reg(struct device *dev, int reg)
static void fill_in_relocation_params(struct smm_relocation_params *params)
{
u32 value;
uintptr_t tseg_base;
size_t tseg_size;

value = pci_read_config32(dev, reg);
/* Base registers are at 1MiB granularity. */
value &= ~((1 << 20) - 1);
return value;
}

static void fill_in_relocation_params(struct device *dev,
struct smm_relocation_params *params)
{
u32 tseg_size;
u32 tsegmb;
u32 bgsm;
u32 emrr_base;
u32 emrr_size;
u32 prmrr_base;
u32 prmrr_size;
int phys_bits;
/* All range registers are aligned to 4KiB */
const u32 rmask = ~((1 << 12) - 1);
Expand All @@ -240,43 +229,34 @@ static void fill_in_relocation_params(struct device *dev,
* SMRAM range as well as the IED range. However, the SMRAM available
* to the handler is 4MiB since the IEDRAM lives TSEGMB + 4MiB.
*/
tsegmb = northbridge_get_base_reg(dev, TSEG);
bgsm = northbridge_get_base_reg(dev, BGSM);
tseg_size = bgsm - tsegmb;

params->smram_base = tsegmb;
params->smram_size = 4 << 20;
params->ied_base = tsegmb + params->smram_size;
params->ied_size = tseg_size - params->smram_size;

/* Adjust available SMM handler memory size. */
params->smram_size -= CONFIG_SMM_RESERVED_SIZE;
smm_region(&tseg_base, &tseg_size);

/* SMRR has 32-bits of valid address aligned to 4KiB. */
params->smrr_base.lo = (params->smram_base & rmask) | MTRR_TYPE_WRBACK;
params->smrr_base.lo = (tseg_base & rmask) | MTRR_TYPE_WRBACK;
params->smrr_base.hi = 0;
params->smrr_mask.lo = (~(tseg_size - 1) & rmask)
| MTRR_PHYS_MASK_VALID;
params->smrr_mask.lo = (~(tseg_size - 1) & rmask) | MTRR_PHYS_MASK_VALID;
params->smrr_mask.hi = 0;

/* The EMRR and UNCORE_EMRR are at IEDBASE + 2MiB */
emrr_base = (params->ied_base + (2 << 20)) & rmask;
emrr_size = params->ied_size - (2 << 20);
smm_subregion(SMM_SUBREGION_CHIPSET, &params->ied_base, &params->ied_size);

/* The PRMRR and UNCORE_PRMRR are at IEDBASE + 2MiB */
prmrr_base = (params->ied_base + (2 << 20)) & rmask;
prmrr_size = params->ied_size - (2 << 20);

/* EMRR has 46 bits of valid address aligned to 4KiB. It's dependent
/* PRMRR has 46 bits of valid address aligned to 4KiB. It's dependent
* on the number of physical address bits supported. */
params->emrr_base.lo = emrr_base | MTRR_TYPE_WRBACK;
params->emrr_base.hi = 0;
params->emrr_mask.lo = (~(emrr_size - 1) & rmask)
params->prmrr_base.lo = prmrr_base | MTRR_TYPE_WRBACK;
params->prmrr_base.hi = 0;
params->prmrr_mask.lo = (~(prmrr_size - 1) & rmask)
| MTRR_PHYS_MASK_VALID;
params->emrr_mask.hi = (1 << (phys_bits - 32)) - 1;
params->prmrr_mask.hi = (1 << (phys_bits - 32)) - 1;

/* UNCORE_EMRR has 39 bits of valid address aligned to 4KiB. */
params->uncore_emrr_base.lo = emrr_base;
params->uncore_emrr_base.hi = 0;
params->uncore_emrr_mask.lo = (~(emrr_size - 1) & rmask) |
/* UNCORE_PRMRR has 39 bits of valid address aligned to 4KiB. */
params->uncore_prmrr_base.lo = prmrr_base;
params->uncore_prmrr_base.hi = 0;
params->uncore_prmrr_mask.lo = (~(prmrr_size - 1) & rmask) |
MTRR_PHYS_MASK_VALID;
params->uncore_emrr_mask.hi = (1 << (39 - 32)) - 1;
params->uncore_prmrr_mask.hi = (1 << (39 - 32)) - 1;
}

static void setup_ied_area(struct smm_relocation_params *params)
Expand All @@ -299,7 +279,7 @@ static void setup_ied_area(struct smm_relocation_params *params)

/* According to the BWG MP init section 2MiB of memory at IEDBASE +
* 2MiB should be zeroed as well. However, I suspect what is intended
* is to clear the memory covered by EMRR. TODO(adurbin): figure out if
* is to clear the memory covered by PRMRR. TODO(adurbin): figure out if
* this is really required.
*/
//memset(ied_base + (2 << 20), 0, (2 << 20));
Expand All @@ -308,23 +288,21 @@ static void setup_ied_area(struct smm_relocation_params *params)
void smm_info(uintptr_t *perm_smbase, size_t *perm_smsize,
size_t *smm_save_state_size)
{
struct device *dev = pcidev_on_root(0, 0);

printk(BIOS_DEBUG, "Setting up SMI for CPU\n");

fill_in_relocation_params(dev, &smm_reloc_params);
fill_in_relocation_params(&smm_reloc_params);

smm_subregion(SMM_SUBREGION_HANDLER, perm_smbase, perm_smsize);

setup_ied_area(&smm_reloc_params);

*perm_smbase = smm_reloc_params.smram_base;
*perm_smsize = smm_reloc_params.smram_size;
*smm_save_state_size = sizeof(em64t101_smm_state_save_area_t);
}

void smm_initialize(void)
{
/* Clear the SMM state in the southbridge. */
southbridge_smm_clear_state();
smm_southbridge_clear_state();

/*
* Run the relocation handler for on the BSP to check and set up
Expand Down
2 changes: 1 addition & 1 deletion src/cpu/intel/model_1067x/model_1067x_init.c
Expand Up @@ -24,7 +24,7 @@
#include <cpu/intel/speedstep.h>
#include <cpu/x86/cache.h>
#include <cpu/x86/name.h>
#include <cpu/intel/smm/gen1/smi.h>
#include <cpu/intel/smm_reloc.h>
#include <cpu/intel/common/common.h>
#include "chip.h"

Expand Down
7 changes: 4 additions & 3 deletions src/cpu/intel/model_1067x/mp_init.c
Expand Up @@ -19,8 +19,9 @@
#include <cpu/x86/mtrr.h>
#include <cpu/x86/mp.h>
#include <cpu/intel/microcode.h>
#include <cpu/intel/smm/gen1/smi.h>
#include <cpu/intel/smm_reloc.h>
#include <cpu/intel/common/common.h>
#include <device/device.h>

/* Parallel MP initialization support. */
static const void *microcode_patch;
Expand Down Expand Up @@ -93,7 +94,7 @@ static void post_mp_init(void)
{
/* Now that all APs have been relocated as well as the BSP let SMIs
* start flowing. */
southbridge_smm_init();
smm_southbridge_enable_smi();

/* Lock down the SMRAM space. */
smm_lock();
Expand All @@ -110,7 +111,7 @@ static const struct mp_ops mp_ops = {
.post_mp_init = post_mp_init,
};

void bsp_init_and_start_aps(struct bus *cpu_bus)
void mp_init_cpus(struct bus *cpu_bus)
{
microcode_patch = intel_microcode_find();

Expand Down
6 changes: 3 additions & 3 deletions src/cpu/intel/model_2065x/model_2065x_init.c
Expand Up @@ -31,7 +31,7 @@
#include <cpu/x86/name.h>
#include "model_2065x.h"
#include "chip.h"
#include <cpu/intel/smm/gen1/smi.h>
#include <cpu/intel/smm_reloc.h>
#include <cpu/intel/common/common.h>

/*
Expand Down Expand Up @@ -316,7 +316,7 @@ static void post_mp_init(void)
{
/* Now that all APs have been relocated as well as the BSP let SMIs
* start flowing. */
southbridge_smm_init();
smm_southbridge_enable_smi();

/* Lock down the SMRAM space. */
smm_lock();
Expand All @@ -334,7 +334,7 @@ static const struct mp_ops mp_ops = {
.post_mp_init = post_mp_init,
};

void bsp_init_and_start_aps(struct bus *cpu_bus)
void mp_init_cpus(struct bus *cpu_bus)
{
if (mp_init_with_smm(cpu_bus, &mp_ops))
printk(BIOS_ERR, "MP initialization failure.\n");
Expand Down
6 changes: 3 additions & 3 deletions src/cpu/intel/model_206ax/model_206ax_init.c
Expand Up @@ -32,7 +32,7 @@
#include <pc80/mc146818rtc.h>
#include "model_206ax.h"
#include "chip.h"
#include <cpu/intel/smm/gen1/smi.h>
#include <cpu/intel/smm_reloc.h>
#include <cpu/intel/common/common.h>

/*
Expand Down Expand Up @@ -542,7 +542,7 @@ static void post_mp_init(void)
{
/* Now that all APs have been relocated as well as the BSP let SMIs
* start flowing. */
southbridge_smm_init();
smm_southbridge_enable_smi();

/* Lock down the SMRAM space. */
smm_lock();
Expand All @@ -560,7 +560,7 @@ static const struct mp_ops mp_ops = {
.post_mp_init = post_mp_init,
};

void bsp_init_and_start_aps(struct bus *cpu_bus)
void mp_init_cpus(struct bus *cpu_bus)
{
if (mp_init_with_smm(cpu_bus, &mp_ops))
printk(BIOS_ERR, "MP initialization failure.\n");
Expand Down
34 changes: 0 additions & 34 deletions src/cpu/intel/smm/gen1/smi.h

This file was deleted.

123 changes: 54 additions & 69 deletions src/cpu/intel/smm/gen1/smmrelocate.c
Expand Up @@ -27,9 +27,10 @@
#include <cpu/x86/msr.h>
#include <cpu/x86/mtrr.h>
#include <cpu/x86/smm.h>
#include <cpu/intel/em64t101_save_state.h>
#include <cpu/intel/smm_reloc.h>
#include <console/console.h>
#include <smp/node.h>
#include "smi.h"

#define SMRR_SUPPORTED (1 << 11)

Expand All @@ -39,18 +40,11 @@
#define G_SMRAME (1 << 3)
#define C_BASE_SEG ((0 << 2) | (1 << 1) | (0 << 0))

struct ied_header {
char signature[10];
u32 size;
u8 reserved[34];
} __packed;


struct smm_relocation_params {
u32 smram_base;
u32 smram_size;
u32 ied_base;
u32 ied_size;
uintptr_t ied_base;
size_t ied_size;
msr_t smrr_base;
msr_t smrr_mask;
};
Expand All @@ -77,75 +71,61 @@ bool cpu_has_alternative_smrr(void)
}
}

static void write_smrr_alt(struct smm_relocation_params *relo_params)
{
msr_t msr;
msr = rdmsr(IA32_FEATURE_CONTROL);
/* SMRR enabled and feature locked */
if (!((msr.lo & SMRR_ENABLE)
&& (msr.lo & FEATURE_CONTROL_LOCK_BIT))) {
printk(BIOS_WARNING,
"SMRR not enabled, skip writing SMRR...\n");
return;
}

printk(BIOS_DEBUG, "Writing SMRR. base = 0x%08x, mask=0x%08x\n",
relo_params->smrr_base.lo, relo_params->smrr_mask.lo);

wrmsr(MSR_SMRR_PHYS_BASE, relo_params->smrr_base);
wrmsr(MSR_SMRR_PHYS_MASK, relo_params->smrr_mask);
}

static void write_smrr(struct smm_relocation_params *relo_params)
{
printk(BIOS_DEBUG, "Writing SMRR. base = 0x%08x, mask=0x%08x\n",
relo_params->smrr_base.lo, relo_params->smrr_mask.lo);

if (cpu_has_alternative_smrr()) {
msr_t msr;
msr = rdmsr(IA32_FEATURE_CONTROL);
/* SMRR enabled and feature locked */
if (!((msr.lo & SMRR_ENABLE)
&& (msr.lo & FEATURE_CONTROL_LOCK_BIT))) {
printk(BIOS_WARNING,
"SMRR not enabled, skip writing SMRR...\n");
return;
}
wrmsr(MSR_SMRR_PHYS_BASE, relo_params->smrr_base);
wrmsr(MSR_SMRR_PHYS_MASK, relo_params->smrr_mask);
} else {
wrmsr(IA32_SMRR_PHYS_BASE, relo_params->smrr_base);
wrmsr(IA32_SMRR_PHYS_MASK, relo_params->smrr_mask);
}
wrmsr(IA32_SMRR_PHYS_BASE, relo_params->smrr_base);
wrmsr(IA32_SMRR_PHYS_MASK, relo_params->smrr_mask);
}

static void fill_in_relocation_params(struct smm_relocation_params *params)
{
uintptr_t tseg_base;
size_t tseg_size;

/* All range registers are aligned to 4KiB */
const u32 rmask = ~((1 << 12) - 1);

const u32 tsegmb = northbridge_get_tseg_base();
/* TSEG base is usually aligned down (to 8MiB). So we can't
derive the TSEG size from the distance to GTT but use the
configuration value instead. */
const u32 tseg_size = northbridge_get_tseg_size();

params->smram_base = tsegmb;
params->smram_size = tseg_size;
if (CONFIG_IED_REGION_SIZE != 0) {
ASSERT(params->smram_size > CONFIG_IED_REGION_SIZE);
params->smram_size -= CONFIG_IED_REGION_SIZE;
params->ied_base = tsegmb + tseg_size - CONFIG_IED_REGION_SIZE;
params->ied_size = CONFIG_IED_REGION_SIZE;
}
smm_region(&tseg_base, &tseg_size);

/* Adjust available SMM handler memory size. */
if (CONFIG(TSEG_STAGE_CACHE)) {
ASSERT(params->smram_size > CONFIG_SMM_RESERVED_SIZE);
params->smram_size -= CONFIG_SMM_RESERVED_SIZE;
}

if (IS_ALIGNED(tsegmb, tseg_size)) {
/* SMRR has 32-bits of valid address aligned to 4KiB. */
struct cpuinfo_x86 c;

/* On model_6fx and model_1067x bits [0:11] on smrr_base
are reserved */
get_fms(&c, cpuid_eax(1));
if (cpu_has_alternative_smrr())
params->smrr_base.lo = (params->smram_base & rmask);
else
params->smrr_base.lo = (params->smram_base & rmask)
| MTRR_TYPE_WRBACK;
params->smrr_base.hi = 0;
params->smrr_mask.lo = (~(tseg_size - 1) & rmask)
| MTRR_PHYS_MASK_VALID;
params->smrr_mask.hi = 0;
} else {
if (!IS_ALIGNED(tseg_base, tseg_size)) {
printk(BIOS_WARNING,
"TSEG base not aligned with TSEG SIZE! Not setting SMRR\n");
return;
}

/* SMRR has 32-bits of valid address aligned to 4KiB. */
params->smrr_base.lo = (tseg_base & rmask) | MTRR_TYPE_WRBACK;
params->smrr_base.hi = 0;
params->smrr_mask.lo = (~(tseg_size - 1) & rmask) | MTRR_PHYS_MASK_VALID;
params->smrr_mask.hi = 0;

/* On model_6fx and model_1067x bits [0:11] on smrr_base are reserved */
if (cpu_has_alternative_smrr())
params->smrr_base.lo &= ~rmask;

smm_subregion(SMM_SUBREGION_CHIPSET, &params->ied_base, &params->ied_size);
}

static void setup_ied_area(struct smm_relocation_params *params)
Expand Down Expand Up @@ -185,18 +165,18 @@ void smm_info(uintptr_t *perm_smbase, size_t *perm_smsize,

fill_in_relocation_params(&smm_reloc_params);

if (CONFIG_IED_REGION_SIZE != 0)
smm_subregion(SMM_SUBREGION_HANDLER, perm_smbase, perm_smsize);

if (smm_reloc_params.ied_size)
setup_ied_area(&smm_reloc_params);

*perm_smbase = smm_reloc_params.smram_base;
*perm_smsize = smm_reloc_params.smram_size;
*smm_save_state_size = sizeof(em64t101_smm_state_save_area_t);
}

void smm_initialize(void)
{
/* Clear the SMM state in the southbridge. */
southbridge_smm_clear_state();
smm_southbridge_clear_state();

/*
* Run the relocation handler for on the BSP to check and set up
Expand All @@ -220,7 +200,7 @@ void smm_relocation_handler(int cpu, uintptr_t curr_smbase,
printk(BIOS_DEBUG, "In relocation handler: cpu %d\n", cpu);

/* Make appropriate changes to the save state map. */
if (CONFIG_IED_REGION_SIZE != 0)
if (relo_params->ied_size)
printk(BIOS_DEBUG, "New SMBASE=0x%08x IEDBASE=0x%08x\n",
smbase, iedbase);
else
Expand All @@ -234,7 +214,12 @@ void smm_relocation_handler(int cpu, uintptr_t curr_smbase,

/* Write EMRR and SMRR MSRs based on indicated support. */
mtrr_cap = rdmsr(MTRR_CAP_MSR);
if (mtrr_cap.lo & SMRR_SUPPORTED && relo_params->smrr_mask.lo != 0)
if (!(mtrr_cap.lo & SMRR_SUPPORTED))
return;

if (cpu_has_alternative_smrr())
write_smrr_alt(relo_params);
else
write_smrr(relo_params);
}

Expand Down
4 changes: 4 additions & 0 deletions src/cpu/qemu-x86/Makefile.inc
Expand Up @@ -14,7 +14,11 @@

bootblock-y += cache_as_ram_bootblock.S
bootblock-y += bootblock.c

romstage-y += ../intel/car/romstage.c

ramstage-y += qemu.c

subdirs-y += ../x86/mtrr
subdirs-y += ../x86/lapic
subdirs-y += ../x86/smm
Expand Down
2 changes: 1 addition & 1 deletion src/cpu/qemu-x86/bootblock.c
Expand Up @@ -29,5 +29,5 @@ asmlinkage void bootblock_c_entry_bist(uint64_t base_timestamp, uint32_t bist)
}

/* Call lib/bootblock.c main */
bootblock_main_with_timestamp(base_timestamp, NULL, 0);
bootblock_main_with_basetime(base_timestamp);
}
20 changes: 10 additions & 10 deletions src/cpu/qemu-x86/cache_as_ram_bootblock.S
Expand Up @@ -28,22 +28,22 @@ cache_as_ram:
* initialization.
*/

post_code(0x21)

movl $_car_stack_end, %esp
/* Align the stack and keep aligned for call to bootblock_c_entry() */
and $0xfffffff0, %esp
sub $12, %esp

/* Clear the cache memory region. This will also clear CAR GLOBAL */
movl $_car_region_start, %esi
movl %esi, %edi
movl $_car_region_start, %edi
movl $_car_region_end, %ecx
sub $_car_region_start, %ecx
sub %edi, %ecx
shr $2, %ecx
xorl %eax, %eax
rep stosl

post_code(0x21)

movl $_car_stack_end, %esp

/* Align the stack and keep aligned for call to bootblock_c_entry() */
and $0xfffffff0, %esp
sub $4, %esp

/* Restore the BIST result and timestamps. */
movd %mm0, %ebx
movd %mm1, %eax
Expand Down
2 changes: 0 additions & 2 deletions src/cpu/ti/am335x/uart.c
Expand Up @@ -182,7 +182,6 @@ void uart_tx_flush(int idx)
{
}

#ifndef __PRE_RAM__
void uart_fill_lb(void *data)
{
struct lb_serial serial;
Expand All @@ -194,4 +193,3 @@ void uart_fill_lb(void *data)

lb_add_console(LB_TAG_CONSOLE_SERIAL8250MEM, data);
}
#endif
1 change: 1 addition & 0 deletions src/cpu/via/nano/Kconfig
Expand Up @@ -30,6 +30,7 @@ config CPU_SPECIFIC_OPTIONS
select MMX
select SSE2
select SUPPORT_CPU_UCODE_IN_CBFS
select CAR_GLOBAL_MIGRATION

config DCACHE_RAM_BASE
hex
Expand Down
8 changes: 8 additions & 0 deletions src/cpu/x86/Kconfig
Expand Up @@ -155,6 +155,14 @@ config X86_AMD_FIXED_MTRRS
This option informs the MTRR code to use the RdMem and WrMem fields
in the fixed MTRR MSRs.

config X86_AMD_INIT_SIPI
bool
default n
help
This option limits the number of SIPI signals sent during during the
common AP setup. Intel documentation specifies an INIT SIPI SIPI
sequence, however this doesn't work on some AMD platforms.

config MIRROR_PAYLOAD_TO_RAM_BEFORE_LOADING
def_bool n
help
Expand Down
6 changes: 1 addition & 5 deletions src/cpu/x86/Makefile.inc
@@ -1,8 +1,4 @@
ifeq ($(CONFIG_ARCH_ROMSTAGE_X86_32)$(CONFIG_ARCH_ROMSTAGE_X86_64),y)
ifneq ($(CONFIG_NO_CAR_GLOBAL_MIGRATION),y)
romstage-$(CONFIG_CACHE_AS_RAM) += car.c
endif
endif
romstage-$(CONFIG_CAR_GLOBAL_MIGRATION) += car.c

subdirs-y += pae
subdirs-$(CONFIG_PARALLEL_MP) += name
Expand Down
12 changes: 1 addition & 11 deletions src/cpu/x86/lapic/lapic_cpu_init.c
Expand Up @@ -21,6 +21,7 @@
#include <cpu/x86/cr.h>
#include <cpu/x86/gdt.h>
#include <cpu/x86/lapic.h>
#include <cpu/x86/smi_deprecated.h>
#include <arch/acpi.h>
#include <delay.h>
#include <halt.h>
Expand Down Expand Up @@ -590,14 +591,3 @@ void initialize_cpus(struct bus *cpu_bus)
if (is_smp_boot())
recover_lowest_1M();
}

#if !CONFIG(HAVE_SMI_HANDLER)
/* Empty stubs for platforms without SMI handlers. */
void smm_init(void)
{
}

void smm_init_completion(void)
{
}
#endif
10 changes: 7 additions & 3 deletions src/cpu/x86/mp_init.c
Expand Up @@ -482,6 +482,9 @@ static int start_aps(struct bus *cpu_bus, int ap_count, atomic_t *num_aps)
/* Wait for CPUs to check in up to 200 us. */
wait_for_aps(num_aps, ap_count, 200 /* us */, 15 /* us */);

if (CONFIG(X86_AMD_INIT_SIPI))
return 0;

/* Send 2nd SIPI */
if ((lapic_read(LAPIC_ICR) & LAPIC_ICR_BUSY)) {
printk(BIOS_DEBUG, "Waiting for ICR not to be busy...");
Expand Down Expand Up @@ -961,12 +964,13 @@ int mp_run_on_aps(void (*func)(void *), void *arg, int logical_cpu_num,
return run_ap_work(&lcb, expire_us);
}

int mp_run_on_all_cpus(void (*func)(void *), void *arg, long expire_us)
int mp_run_on_all_cpus(void (*func)(void *), void *arg)
{
/* Run on BSP first. */
func(arg);

return mp_run_on_aps(func, arg, MP_RUN_ON_ALL_CPUS, expire_us);
/* For up to 1 second for AP to finish previous work. */
return mp_run_on_aps(func, arg, MP_RUN_ON_ALL_CPUS, 1000 * USECS_PER_MSEC);
}

int mp_park_aps(void)
Expand All @@ -978,7 +982,7 @@ int mp_park_aps(void)
stopwatch_init(&sw);

ret = mp_run_on_aps(park_this_cpu, NULL, MP_RUN_ON_ALL_CPUS,
250 * USECS_PER_MSEC);
1000 * USECS_PER_MSEC);

duration_msecs = stopwatch_duration_msecs(&sw);

Expand Down
4 changes: 2 additions & 2 deletions src/cpu/x86/pae/pgtbl.c
Expand Up @@ -363,7 +363,7 @@ static int read_from_cbfs(const char *name, void *buf, size_t size)

int paging_enable_for_car(const char *pdpt_name, const char *pt_name)
{
if (!ENV_CACHE_AS_RAM)
if (!preram_symbols_available())
return -1;

if (read_from_cbfs(pdpt_name, _pdpt, REGION_SIZE(pdpt))) {
Expand All @@ -383,7 +383,7 @@ int paging_enable_for_car(const char *pdpt_name, const char *pt_name)

static void *get_pdpt_addr(void)
{
if (ENV_CACHE_AS_RAM)
if (preram_symbols_available())
return _pdpt;
return (void *)(uintptr_t)read_cr3();
}
Expand Down
6 changes: 3 additions & 3 deletions src/cpu/x86/smm/Makefile.inc
Expand Up @@ -42,9 +42,9 @@ endif

ifeq ($(CONFIG_SMM_TSEG),y)

ramstage-y += stage_cache.c
romstage-y += stage_cache.c
postcar-y += stage_cache.c
ramstage-y += tseg_region.c
romstage-y += tseg_region.c
postcar-y += tseg_region.c

smmstub-y += smm_stub.S

Expand Down
34 changes: 25 additions & 9 deletions src/cpu/x86/smm/smihandler.c
Expand Up @@ -18,11 +18,34 @@
#include <console/console.h>
#include <cpu/x86/cache.h>
#include <cpu/x86/smm.h>
#include <cpu/x86/smi_deprecated.h>
#include <cpu/amd/amd64_save_state.h>
#include <cpu/intel/em64t_save_state.h>
#include <cpu/intel/em64t100_save_state.h>
#include <cpu/intel/em64t101_save_state.h>
#include <cpu/x86/legacy_save_state.h>

#if CONFIG(SPI_FLASH_SMM)
#include <spi-generic.h>
#endif

typedef enum {
AMD64,
EM64T,
EM64T101,
LEGACY
} save_state_type_t;

typedef struct {
save_state_type_t type;
union {
amd64_smm_state_save_area_t *amd64_state_save;
em64t_smm_state_save_area_t *em64t_state_save;
em64t101_smm_state_save_area_t *em64t101_state_save;
legacy_smm_state_save_area_t *legacy_state_save;
};
} smm_state_save_area_t;

static int do_driver_init = 1;

typedef enum { SMI_LOCKED, SMI_UNLOCKED } smi_semaphore;
Expand Down Expand Up @@ -193,9 +216,7 @@ void smi_handler(u32 smm_revision)
}

/* Call chipset specific SMI handlers. */
cpu_smi_handler(node, &state_save);
northbridge_smi_handler(node, &state_save);
southbridge_smi_handler(node, &state_save);
southbridge_smi_handler();

smi_restore_pci_address();

Expand All @@ -210,12 +231,7 @@ void smi_handler(u32 smm_revision)
* weak relocations w/o a symbol have a 0 address which is where the modules
* are linked at. */
int __weak mainboard_io_trap_handler(int smif) { return 0; }
void __weak cpu_smi_handler(unsigned int node,
smm_state_save_area_t *state_save) {}
void __weak northbridge_smi_handler(unsigned int node,
smm_state_save_area_t *state_save) {}
void __weak southbridge_smi_handler(unsigned int node,
smm_state_save_area_t *state_save) {}
void __weak southbridge_smi_handler(void) {}
void __weak mainboard_smi_gpi(u32 gpi_sts) {}
int __weak mainboard_smi_apmc(u8 data) { return 0; }
void __weak mainboard_smi_sleep(u8 slp_typ) {}
3 changes: 0 additions & 3 deletions src/cpu/x86/smm/smmrelocate.S
Expand Up @@ -14,9 +14,6 @@
* GNU General Public License for more details.
*/

// Make sure no stage 2 code is included:
#define __PRE_RAM__

// FIXME: Is this piece of code southbridge specific, or
// can it be cleaned up so this include is not required?
// It's needed right now because we get our DEFAULT_PMBASE from
Expand Down
100 changes: 100 additions & 0 deletions src/cpu/x86/smm/tseg_region.c
@@ -0,0 +1,100 @@
/*
* This file is part of the coreboot project.
*
* Copyright 2013 Google Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/

#include <assert.h>
#include <commonlib/helpers.h>
#include <console/console.h>
#include <cpu/x86/smm.h>
#include <stage_cache.h>
#include <types.h>

/*
* Subregions within SMM
* +-------------------------+
* | IED | IED_REGION_SIZE
* +-------------------------+
* | External Stage Cache | SMM_RESERVED_SIZE
* +-------------------------+
* | code and data |
* | (TSEG) |
* +-------------------------+ TSEG
*/
int smm_subregion(int sub, uintptr_t *start, size_t *size)
{
uintptr_t sub_base;
size_t sub_size;
const size_t ied_size = CONFIG_IED_REGION_SIZE;
const size_t cache_size = CONFIG_SMM_RESERVED_SIZE;

smm_region(&sub_base, &sub_size);

ASSERT(IS_ALIGNED(sub_base, sub_size));
ASSERT(sub_size > (cache_size + ied_size));

switch (sub) {
case SMM_SUBREGION_HANDLER:
/* Handler starts at the base of TSEG. */
sub_size -= ied_size;
sub_size -= cache_size;
break;
case SMM_SUBREGION_CACHE:
/* External cache is in the middle of TSEG. */
sub_base += sub_size - (ied_size + cache_size);
sub_size = cache_size;
break;
case SMM_SUBREGION_CHIPSET:
/* IED is at the top. */
sub_base += sub_size - ied_size;
sub_size = ied_size;
break;
default:
*start = 0;
*size = 0;
return -1;
}

*start = sub_base;
*size = sub_size;
return 0;
}

void stage_cache_external_region(void **base, size_t *size)
{
if (smm_subregion(SMM_SUBREGION_CACHE, (uintptr_t *)base, size)) {
printk(BIOS_ERR, "ERROR: No cache SMM subregion.\n");
*base = NULL;
*size = 0;
}
}

void smm_list_regions(void)
{
uintptr_t base;
size_t size;
int i;

smm_region(&base, &size);
if (!size)
return;

printk(BIOS_DEBUG, "SMM Memory Map\n");
printk(BIOS_DEBUG, "SMRAM : 0x%zx 0x%zx\n", base, size);

for (i = 0; i < SMM_SUBREGION_NUM; i++) {
if (smm_subregion(i, &base, &size))
continue;
printk(BIOS_DEBUG, " Subregion %d: 0x%zx 0x%zx\n", i, base, size);
}
}
5 changes: 5 additions & 0 deletions src/device/Makefile.inc
Expand Up @@ -53,3 +53,8 @@ verstage-y += i2c.c
romstage-y += i2c.c
ramstage-y += i2c.c
ramstage-y += i2c_bus.c

bootblock-y += mmio.c
verstage-y += mmio.c
romstage-y += mmio.c
ramstage-y += mmio.c
2 changes: 1 addition & 1 deletion src/device/device_const.c
Expand Up @@ -204,7 +204,7 @@ DEVTREE_CONST struct device *pcidev_path_on_bus(unsigned int bus, pci_devfn_t de
DEVTREE_CONST struct bus *pci_root_bus(void)
{
DEVTREE_CONST struct device *pci_domain;
MAYBE_STATIC DEVTREE_CONST struct bus *pci_root = NULL;
MAYBE_STATIC_BSS DEVTREE_CONST struct bus *pci_root = NULL;

if (pci_root)
return pci_root;
Expand Down
4 changes: 2 additions & 2 deletions src/device/dram/Makefile.inc
@@ -1,2 +1,2 @@
romstage-y += ddr3.c
ramstage-y += ddr3.c
romstage-y += ddr4.c ddr3.c ddr2.c ddr_common.c
ramstage-y += ddr4.c ddr3.c ddr2.c ddr_common.c
2 changes: 1 addition & 1 deletion src/device/dram/ddr2.c
Expand Up @@ -93,7 +93,7 @@ u16 spd_ddr2_calc_unique_crc(const u8 *spd, int len)
for (i = 93; i <= 98; i++)
id_bytes[j++] = spd[i];

return ddr3_crc16(id_bytes, 15);
return ddr_crc16(id_bytes, 15);
}

/**
Expand Down
23 changes: 3 additions & 20 deletions src/device/dram/ddr3.c
Expand Up @@ -23,6 +23,7 @@
#include <console/console.h>
#include <device/device.h>
#include <device/dram/ddr3.h>
#include <device/dram/common.h>
#include <string.h>
#include <memory_info.h>
#include <cbmem.h>
Expand Down Expand Up @@ -50,24 +51,6 @@ int spd_dimm_is_registered_ddr3(enum spd_dimm_type type)
return 0;
}

u16 ddr3_crc16(const u8 *ptr, int n_crc)
{
int i;
u16 crc = 0;

while (--n_crc >= 0) {
crc = crc ^ ((int)*ptr++ << 8);
for (i = 0; i < 8; ++i)
if (crc & 0x8000) {
crc = (crc << 1) ^ 0x1021;
} else {
crc = crc << 1;
}
}

return crc;
}

/**
* \brief Calculate the CRC of a DDR3 SPD
*
Expand All @@ -91,7 +74,7 @@ u16 spd_ddr3_calc_crc(u8 *spd, int len)
/* Not enough bytes available to get the CRC */
return 0;

return ddr3_crc16(spd, n_crc);
return ddr_crc16(spd, n_crc);
}

/**
Expand All @@ -108,7 +91,7 @@ u16 spd_ddr3_calc_unique_crc(u8 *spd, int len)
/* Not enough bytes available to get the CRC */
return 0;

return ddr3_crc16(&spd[117], 11);
return ddr_crc16(&spd[117], 11);
}

/**
Expand Down
248 changes: 248 additions & 0 deletions src/device/dram/ddr4.c
@@ -0,0 +1,248 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2019 Facebook, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/

#include <console/console.h>
#include <cbmem.h>
#include <device/device.h>
#include <device/dram/ddr4.h>
#include <string.h>
#include <memory_info.h>
#include <smbios.h>
#include <types.h>

typedef enum {
BLOCK_0, /* Base Configuration and DRAM Parameters */
BLOCK_1,
BLOCK_1_L, /* Standard Module Parameters */
BLOCK_1_H, /* Hybrid Module Parameters */
BLOCK_2,
BLOCK_2_L, /* Hybrid Module Extended Function Parameters */
BLOCK_2_H, /* Manufacturing Information */
BLOCK_3 /* End user programmable */
} spd_block_type;

typedef struct {
spd_block_type type;
uint16_t start; /* starting offset from beginning of the spd */
uint16_t len; /* size of the block */
uint16_t crc_start; /* offset from start of crc bytes, 0 if none */
} spd_block;

/* 'SPD contents architecture' as per datasheet */
const spd_block spd_blocks[] = {
{.type = BLOCK_0, 0, 128, 126}, {.type = BLOCK_1, 128, 128, 126},
{.type = BLOCK_1_L, 128, 64, 0}, {.type = BLOCK_1_H, 192, 64, 0},
{.type = BLOCK_2_L, 256, 64, 62}, {.type = BLOCK_2_H, 320, 64, 0},
{.type = BLOCK_3, 384, 128, 0} };

static bool verify_block(const spd_block *block, spd_raw_data spd)
{
uint16_t crc, spd_crc;

spd_crc = (spd[block->start + block->crc_start + 1] << 8)
| spd[block->start + block->crc_start];
crc = ddr_crc16(&spd[block->start], block->len - 2);

return spd_crc == crc;
}

/* Check if given block is 'reserved' for a given module type */
static bool block_exists(spd_block_type type, u8 dimm_type)
{
bool is_hybrid;

switch (type) {
case BLOCK_0: /* fall-through */
case BLOCK_1: /* fall-through */
case BLOCK_1_L: /* fall-through */
case BLOCK_1_H: /* fall-through */
case BLOCK_2_H: /* fall-through */
case BLOCK_3: /* fall-through */
return true;
case BLOCK_2_L:
is_hybrid = (dimm_type >> 4) & ((1 << 3) - 1);
if (is_hybrid)
return true;
return false;
default: /* fall-through */
return false;
}
}


/**
* \brief Decode the raw SPD data
*
* Decodes a raw SPD data from a DDR4 DIMM, and organizes it into a
* @ref dimm_attr structure. The SPD data must first be read in a contiguous
* array, and passed to this function.
*
* @param dimm pointer to @ref dimm_attr structure where the decoded data is to
* be stored
* @param spd array of raw data previously read from the SPD.
*
* @return @ref spd_status enumerator
* SPD_STATUS_OK -- decoding was successful
* SPD_STATUS_INVALID -- invalid SPD or not a DDR4 SPD
* SPD_STATUS_CRC_ERROR -- checksum mismatch
*/
int spd_decode_ddr4(dimm_attr *dimm, spd_raw_data spd)
{
u8 reg8;
u8 bus_width, sdram_width;
u16 cap_per_die_mbit;
u16 spd_bytes_total, spd_bytes_used;
const uint16_t spd_bytes_used_table[] = {0, 128, 256, 384, 512};

/* Make sure that the SPD dump is indeed from a DDR4 module */
if (spd[2] != SPD_MEMORY_TYPE_DDR4_SDRAM) {
printk(BIOS_ERR, "Not a DDR4 SPD!\n");
dimm->dram_type = SPD_MEMORY_TYPE_UNDEFINED;
return SPD_STATUS_INVALID;
}

spd_bytes_total = (spd[0] >> 4) & ((1 << 3) - 1);
spd_bytes_used = spd[0] & ((1 << 4) - 1);

if (!spd_bytes_total || !spd_bytes_used) {
printk(BIOS_ERR, "SPD failed basic sanity checks\n");
return SPD_STATUS_INVALID;
}

spd_bytes_total = 256 << (spd_bytes_total - 1);
spd_bytes_used = spd_bytes_used_table[spd_bytes_used];

/* Verify CRC of blocks that have them, do not step over 'used' length */
for (int i = 0; i < ARRAY_SIZE(spd_blocks); i++) {
/* this block is not checksumed */
if (spd_blocks[i].crc_start == 0)
continue;
/* we shouldn't have this block */
if (spd_blocks[i].start + spd_blocks[i].len > spd_bytes_used)
continue;
/* check if block exists in the current schema */
if (!block_exists(spd_blocks[i].type, spd[3]))
continue;
if (!verify_block(&spd_blocks[i], spd)) {
printk(BIOS_ERR, "CRC failed for block %d\n", i);
return SPD_STATUS_CRC_ERROR;
}
}

dimm->dram_type = SPD_MEMORY_TYPE_DDR4_SDRAM;
dimm->dimm_type = spd[3] & ((1 << 4) - 1);

reg8 = spd[13] & ((1 << 4) - 1);
dimm->bus_width = reg8;
bus_width = 8 << (reg8 & ((1 << 3) - 1));

reg8 = spd[12] & ((1 << 3) - 1);
dimm->sdram_width = reg8;
sdram_width = 4 << reg8;

reg8 = spd[4] & ((1 << 4) - 1);
dimm->cap_per_die_mbit = reg8;
cap_per_die_mbit = (1 << reg8) * 256;

reg8 = (spd[12] >> 3) & ((1 << 3) - 1);
dimm->ranks = reg8 + 1;

if (!bus_width || !sdram_width) {
printk(BIOS_ERR, "SPD information is invalid");
dimm->size_mb = 0;
return SPD_STATUS_INVALID;
}

/* seems to be only one, in mV */
dimm->vdd_voltage = 1200;

/* calculate size */
dimm->size_mb = cap_per_die_mbit / 8 * bus_width / sdram_width * dimm->ranks;

/* make sure we have the manufacturing information block */
if (spd_bytes_used > 320) {
dimm->manufacturer_id = (spd[351] << 8) | spd[350];
memcpy(dimm->part_number, &spd[329], SPD_DDR4_PART_LEN);
dimm->part_number[SPD_DDR4_PART_LEN] = 0;
memcpy(dimm->serial_number, &spd[325], sizeof(dimm->serial_number));
}
return SPD_STATUS_OK;
}

enum cb_err spd_add_smbios17_ddr4(const u8 channel, const u8 slot, const u16 selected_freq,
const dimm_attr *info)
{
struct memory_info *mem_info;
struct dimm_info *dimm;

/*
* Allocate CBMEM area for DIMM information used to populate SMBIOS
* table 17
*/
mem_info = cbmem_find(CBMEM_ID_MEMINFO);
if (!mem_info) {
mem_info = cbmem_add(CBMEM_ID_MEMINFO, sizeof(*mem_info));

printk(BIOS_DEBUG, "CBMEM entry for DIMM info: 0x%p\n", mem_info);
if (!mem_info)
return CB_ERR;

memset(mem_info, 0, sizeof(*mem_info));
}

if (mem_info->dimm_cnt >= ARRAY_SIZE(mem_info->dimm)) {
printk(BIOS_WARNING, "BUG: Too many DIMM infos for %s.\n", __func__);
return CB_ERR;
}

dimm = &mem_info->dimm[mem_info->dimm_cnt];
if (info->size_mb) {
dimm->ddr_type = MEMORY_TYPE_DDR4;
dimm->ddr_frequency = selected_freq;
dimm->dimm_size = info->size_mb;
dimm->channel_num = channel;
dimm->rank_per_dimm = info->ranks;
dimm->dimm_num = slot;
memcpy(dimm->module_part_number, info->part_number, SPD_DDR4_PART_LEN);
dimm->mod_id = info->manufacturer_id;

switch (info->dimm_type) {
case SPD_DIMM_TYPE_SO_DIMM:
dimm->mod_type = SPD_SODIMM;
break;
case SPD_DIMM_TYPE_72B_SO_RDIMM:
dimm->mod_type = SPD_72B_SO_RDIMM;
break;
case SPD_DIMM_TYPE_UDIMM:
dimm->mod_type = SPD_UDIMM;
break;
case SPD_DIMM_TYPE_RDIMM:
dimm->mod_type = SPD_RDIMM;
break;
default:
dimm->mod_type = SPD_UNDEFINED;
break;
}

dimm->bus_width = info->bus_width;
memcpy(dimm->serial, info->serial_number,
MIN(sizeof(dimm->serial), sizeof(info->serial_number)));

dimm->vdd_voltage = info->vdd_voltage;
mem_info->dimm_cnt++;
}

return CB_SUCCESS;
}
43 changes: 43 additions & 0 deletions src/device/dram/ddr_common.c
@@ -0,0 +1,43 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2019 Facebook, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/

#include <console/console.h>
#include <device/dram/common.h>
#include <types.h>

/**
* \brief Calculate the CRC of a DDR SPD data
*
* @param spd pointer to raw SPD data
* @param len length of data in SPD
*
* @return the CRC of the SPD data
*/
u16 ddr_crc16(const u8 *ptr, int n_crc)
{
int i;
u16 crc = 0;

while (--n_crc >= 0) {
crc = crc ^ ((int)*ptr++ << 8);
for (i = 0; i < 8; ++i)
if (crc & 0x8000)
crc = (crc << 1) ^ 0x1021;
else
crc = crc << 1;
}

return crc;
}
55 changes: 55 additions & 0 deletions src/device/mmio.c
@@ -0,0 +1,55 @@
/*
* This file is part of the coreboot project.
*
* Copyright 2019 Google LLC
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/

#include <assert.h>
#include <device/mmio.h>

/* Helper functions for various MMIO access patterns. */

void buffer_from_fifo32(void *buffer, size_t size, void *fifo,
int fifo_stride, int fifo_width)
{
u8 *p = buffer;
int i, j;

assert(fifo_width > 0 && fifo_width <= sizeof(u32) &&
fifo_stride % sizeof(u32) == 0);

for (i = 0; i < size; i += fifo_width, fifo += fifo_stride) {
u32 val = read32(fifo);
for (j = 0; j < MIN(size - i, fifo_width); j++)
*p++ = (u8)(val >> (j * 8));
}
}

void buffer_to_fifo32_prefix(void *buffer, u32 prefix, int prefsz, size_t size,
void *fifo, int fifo_stride, int fifo_width)
{
u8 *p = buffer;
int i, j = prefsz;

assert(fifo_width > 0 && fifo_width <= sizeof(u32) &&
fifo_stride % sizeof(u32) == 0 && prefsz <= fifo_width);

uint32_t val = prefix;
for (i = 0; i < size; i += fifo_width, fifo += fifo_stride) {
for (; j < MIN(size - i, fifo_width); j++)
val |= *p++ << (j * 8);
write32(fifo, val);
val = 0;
j = 0;
}

}
2 changes: 0 additions & 2 deletions src/device/oprom/realmode/x86.c
Expand Up @@ -19,8 +19,6 @@
#include <arch/registers.h>
#include <boot/coreboot_tables.h>
#include <console/console.h>
#include <cpu/amd/lxdef.h>
#include <cpu/amd/vr.h>
#include <delay.h>
#include <device/pci.h>
#include <device/pci_ids.h>
Expand Down
19 changes: 9 additions & 10 deletions src/drivers/amd/agesa/def_callouts.c
Expand Up @@ -160,18 +160,19 @@ AGESA_STATUS agesa_GfxGetVbiosImage(UINT32 Func, UINTN FchData, VOID *ConfigPrt)

AGESA_STATUS agesa_ReadSpd (UINT32 Func, UINTN Data, VOID *ConfigPtr)
{
AGESA_STATUS Status = AGESA_UNSUPPORTED;
#ifdef __PRE_RAM__
Status = AmdMemoryReadSPD (Func, Data, ConfigPtr);
#endif
return Status;
if (!ENV_ROMSTAGE)
return AGESA_UNSUPPORTED;

return AmdMemoryReadSPD (Func, Data, ConfigPtr);
}

AGESA_STATUS agesa_ReadSpd_from_cbfs(UINT32 Func, UINTN Data, VOID *ConfigPtr)
{
AGESA_STATUS Status = AGESA_UNSUPPORTED;
#ifdef __PRE_RAM__
AGESA_READ_SPD_PARAMS *info = ConfigPtr;

if (!ENV_ROMSTAGE)
return AGESA_UNSUPPORTED;

if (info->MemChannelId > 0)
return AGESA_UNSUPPORTED;
if (info->SocketId != 0)
Expand All @@ -183,9 +184,7 @@ AGESA_STATUS agesa_ReadSpd_from_cbfs(UINT32 Func, UINTN Data, VOID *ConfigPtr)
if (read_ddr3_spd_from_cbfs((u8*)info->Buffer, 0) < 0)
die("No SPD data\n");

Status = AGESA_SUCCESS;
#endif
return Status;
return AGESA_SUCCESS;
}

#if HAS_AGESA_FCH_OEM_CALLOUT
Expand Down
2 changes: 1 addition & 1 deletion src/drivers/amd/agesa/mtrr_fixme.c
Expand Up @@ -11,7 +11,7 @@
* GNU General Public License for more details.
*/

#include <arch/cpu.h>
#include <arch/romstage.h>
#include <cbmem.h>
#include <console/console.h>
#include <commonlib/helpers.h>
Expand Down
1 change: 1 addition & 0 deletions src/drivers/amd/agesa/romstage.c
Expand Up @@ -15,6 +15,7 @@

#include <arch/acpi.h>
#include <arch/cpu.h>
#include <arch/romstage.h>
#include <cbmem.h>
#include <cpu/amd/car.h>
#include <cpu/x86/bist.h>
Expand Down
1 change: 1 addition & 0 deletions src/drivers/i2c/generic/chip.h
Expand Up @@ -28,6 +28,7 @@ struct drivers_i2c_generic_config {
const char *desc; /* Device Description */
unsigned uid; /* ACPI _UID */
enum i2c_speed speed; /* Bus speed in Hz, default is I2C_SPEED_FAST */
const char *compat_string; /* Compatible string for _HID=PRP0001 */
unsigned wake; /* Wake GPE */
struct acpi_irq irq; /* Interrupt */

Expand Down
5 changes: 4 additions & 1 deletion src/drivers/i2c/generic/generic.c
Expand Up @@ -116,10 +116,13 @@ void i2c_generic_fill_ssdt(struct device *dev,
}

/* DSD */
if (config->probed || config->property_count ||
if (config->probed || config->property_count || config->compat_string ||
(reset_gpio_index != -1) ||
(enable_gpio_index != -1) || (irq_gpio_index != -1)) {
dsd = acpi_dp_new_table("_DSD");
if (config->compat_string)
acpi_dp_add_string(dsd, "compatible",
config->compat_string);
if (config->probed)
acpi_dp_add_integer(dsd, "linux,probed", 1);
if (irq_gpio_index != -1)
Expand Down
1 change: 1 addition & 0 deletions src/drivers/intel/fsp1_0/Kconfig
Expand Up @@ -16,6 +16,7 @@
config PLATFORM_USES_FSP1_0
bool
default n
select CAR_GLOBAL_MIGRATION
help
Selected for Intel processors/platform combinations that use the
Intel Firmware Support Package (FSP) 1.0 for initialization.
Expand Down
6 changes: 0 additions & 6 deletions src/drivers/intel/fsp1_0/fastboot_cache.c
Expand Up @@ -116,10 +116,6 @@ static struct mrc_data_container *find_current_mrc_cache_local
return mrc_cache;
}

/* SPI code needs malloc/free.
* Also unknown if writing flash from XIP-flash code is a good idea
*/
#if !defined(__PRE_RAM__)
/* find the first empty block in the MRC cache area.
* If there's none, return NULL.
*
Expand Down Expand Up @@ -221,8 +217,6 @@ void update_mrc_cache(void *unused)
current->mrc_data_size + sizeof(*current), current);
}

#endif /* !defined(__PRE_RAM__) */

void *find_and_set_fastboot_cache(void)
{
struct mrc_data_container *mrc_cache = NULL;
Expand Down
26 changes: 7 additions & 19 deletions src/drivers/intel/fsp1_0/fsp_util.c
Expand Up @@ -25,7 +25,6 @@
#include <cpu/intel/microcode.h>
#include <cf9_reset.h>

#ifndef __PRE_RAM__
/* Globals pointers for FSP structures */
void *FspHobListPtr = NULL;
FSP_INFO_HEADER *fsp_header_ptr = NULL;
Expand Down Expand Up @@ -60,9 +59,6 @@ void FspNotify (u32 Phase)
if (Status != 0)
printk(BIOS_ERR,"FSP API NotifyPhase failed for phase 0x%x with status: 0x%x\n", Phase, Status);
}
#endif /* #ifndef __PRE_RAM__ */

#ifdef __PRE_RAM__

/* The FSP returns here after the fsp_early_init call */
static void ChipsetFspReturnPoint(EFI_STATUS Status, VOID *HobListPtr)
Expand Down Expand Up @@ -115,12 +111,10 @@ void __noreturn fsp_early_init (FSP_INFO_HEADER *fsp_ptr)
/* Should never return. Control will continue from ContinuationFunc */
die("Uh Oh! FspInitApi returned");
}
#endif /* __PRE_RAM__ */

volatile u8 *find_fsp()
{

#ifdef __PRE_RAM__
#if ENV_ROMSTAGE
volatile register u8 *fsp_ptr asm ("eax");

/* Entry point for CAR assembly routine */
Expand All @@ -130,7 +124,7 @@ volatile u8 *find_fsp()
);
#else
volatile u8 *fsp_ptr;
#endif /* __PRE_RAM__ */
#endif

/* The FSP is stored in CBFS */
fsp_ptr = (u8 *) CONFIG_FSP_LOC;
Expand Down Expand Up @@ -225,8 +219,6 @@ void *find_fsp_reserved_mem(void *hob_list_ptr)
}
#endif /* FSP_RESERVE_MEMORY_SIZE */

#ifndef __PRE_RAM__ /* Only parse HOB data in ramstage */

void print_fsp_info(void) {

if (fsp_header_ptr == NULL)
Expand All @@ -249,12 +241,10 @@ void print_fsp_info(void) {
(u8)(fsp_header_ptr->ImageRevision & 0xff));
}


#if CONFIG(ENABLE_MRC_CACHE)
/**
* Save the FSP memory HOB (mrc data) to the MRC area in CBMEM
*/
int save_mrc_data(void *hob_start)
static int save_mrc_data(void *hob_start)
{
u32 *mrc_hob;
u32 *mrc_hob_data;
Expand Down Expand Up @@ -307,7 +297,6 @@ int save_mrc_data(void *hob_start)
hexdump32(BIOS_SPEW, (void *)mrc_data->mrc_data, output_len / 4);
return (1);
}
#endif /* CONFIG_ENABLE_MRC_CACHE */

static void find_fsp_hob_update_mrc(void *unused)
{
Expand All @@ -319,13 +308,13 @@ static void find_fsp_hob_update_mrc(void *unused)
} else {
/* 0x0000: Print all types */
print_hob_type_structure(0x000, FspHobListPtr);
}

#if CONFIG(ENABLE_MRC_CACHE)
if (CONFIG(ENABLE_MRC_CACHE)) {
if (save_mrc_data(FspHobListPtr))
update_mrc_cache(NULL);
else
printk(BIOS_DEBUG,"Not updating MRC data in flash.\n");
#endif
}
}

Expand Down Expand Up @@ -356,11 +345,10 @@ static void fsp_finalize(void *unused)
printk(BIOS_DEBUG, "Returned from FspNotify(EnumInitPhaseReadyToBoot)\n");
}


/* Set up for the ramstage FSP calls */
BOOT_STATE_INIT_ENTRY(BS_DEV_ENUMERATE, BS_ON_EXIT, fsp_after_pci_enum, NULL);
BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_BOOT, BS_ON_ENTRY, fsp_finalize, NULL);

/* Update the MRC/fast boot cache as part of the late table writing stage */
BOOT_STATE_INIT_ENTRY(BS_WRITE_TABLES, BS_ON_ENTRY,
find_fsp_hob_update_mrc, NULL);
#endif /* #ifndef __PRE_RAM__ */
BOOT_STATE_INIT_ENTRY(BS_WRITE_TABLES, BS_ON_ENTRY, find_fsp_hob_update_mrc, NULL);
10 changes: 0 additions & 10 deletions src/drivers/intel/fsp1_0/fsp_util.h
Expand Up @@ -21,10 +21,7 @@

#include "fsp_values.h"

#if CONFIG(ENABLE_MRC_CACHE)
int save_mrc_data(void *hob_start);
void *find_and_set_fastboot_cache(void);
#endif

volatile u8 *find_fsp(void);
void fsp_early_init(FSP_INFO_HEADER *fsp_info);
Expand Down Expand Up @@ -65,7 +62,6 @@ void printguid(EFI_GUID *guid);
#define EFI_HOB_TYPE_HANDOFF 0x0001
#define EFI_HOB_TYPE_MEMORY_POOL 0x0007

#if CONFIG(ENABLE_MRC_CACHE)
#define MRC_DATA_ALIGN 0x1000
#define MRC_DATA_SIGNATURE (('M'<<0)|('R'<<8)|('C'<<16)|('D'<<24))

Expand All @@ -79,11 +75,7 @@ struct mrc_data_container {

struct mrc_data_container *find_current_mrc_cache(void);

#if !defined(__PRE_RAM__)
void update_mrc_cache(void *unused);
#endif

#endif

/* The offset in bytes from the start of the info structure */
#define FSP_IMAGE_SIG_LOC 0
Expand All @@ -99,9 +91,7 @@ void update_mrc_cache(void *unused);
#define ERROR_INFO_HEAD_SIG_MISMATCH 5
#define ERROR_FSP_SIG_MISMATCH 6

#ifndef __PRE_RAM__
extern void *FspHobListPtr;
#endif

#define UPD_DEFAULT_CHECK(member) \
if (config->member != UPD_DEFAULT) { \
Expand Down
2 changes: 0 additions & 2 deletions src/drivers/intel/fsp1_1/Kconfig
Expand Up @@ -18,8 +18,6 @@ config PLATFORM_USES_FSP1_1
bool
select UEFI_2_4_BINDING
select INTEL_GMA_ADD_VBT if RUN_FSP_GOP
select POSTCAR_STAGE
select POSTCAR_CONSOLE
help
Does the code require the Intel Firmware Support Package?

Expand Down
22 changes: 4 additions & 18 deletions src/drivers/intel/fsp1_1/car.c
Expand Up @@ -13,45 +13,31 @@
* GNU General Public License for more details.
*/

#include <arch/romstage.h>
#include <arch/symbols.h>
#include <cbmem.h>
#include <console/console.h>
#include <commonlib/helpers.h>
#include <cpu/intel/romstage.h>
#include <cpu/x86/mtrr.h>
#include <cpu/x86/smm.h>
#include <fsp/car.h>
#include <fsp/util.h>
#include <program_loading.h>

/* platform_enter_postcar() determines the stack to use after
* cache-as-ram is torn down as well as the MTRR settings to use,
* and continues execution in postcar stage. */
void platform_enter_postcar(void)
void fill_postcar_frame(struct postcar_frame *pcf)
{
struct postcar_frame pcf;
uintptr_t top_of_ram;

if (postcar_frame_init(&pcf, 0))
die("Unable to initialize postcar frame.\n");
/* Cache the ROM as WP just below 4GiB. */
postcar_frame_add_mtrr(&pcf, CACHE_ROM_BASE, CACHE_ROM_SIZE,
MTRR_TYPE_WRPROT);

/* Cache RAM as WB from 0 -> CACHE_TMP_RAMTOP. */
postcar_frame_add_mtrr(&pcf, 0, CACHE_TMP_RAMTOP, MTRR_TYPE_WRBACK);

/* Cache at least 8 MiB below the top of ram, and at most 8 MiB
* above top of the ram. This satisfies MTRR alignment requirement
* with different TSEG size configurations. */
top_of_ram = ALIGN_DOWN((uintptr_t)cbmem_top(), 8*MiB);
postcar_frame_add_mtrr(&pcf, top_of_ram - 8*MiB, 16*MiB, MTRR_TYPE_WRBACK);
postcar_frame_add_mtrr(pcf, top_of_ram - 8*MiB, 16*MiB, MTRR_TYPE_WRBACK);

run_postcar_phase(&pcf);
}

/* This is the romstage entry called from cpu/intel/car/romstage.c */
void mainboard_romstage_entry(unsigned long bist)
void mainboard_romstage_entry(void)
{
/* Need to locate the current FSP_INFO_HEADER. The cache-as-ram
* is still enabled. We can directly access work buffer here. */
Expand Down