soc/amd/picasso: Add FSP support for including AGESA
AMD has rewritten AGESA (now at v9) for direct inclusion into UEFI build environments. Therefore, unlike the previous Arch2008 (a.k.a. v5), it can't be built without additional source, e.g. by combining with EDK II, and it has no entry points for easily building it into a legacy BIOS. AGESA in coreboot now relies on the FSP 2.0 framework published by Intel and uses the existing fsp2_0 driver. * Add fsp_memory_init() to romstage.c. Although Picasso comes out of reset with DRAM alive, this call is added to maximize compatibility and facilitate internal development. Future work may look at removing it. AGESA reports the memory map to coreboot via HOBs returned from fsp_memory_init(). * AGESA currently sets up MTRRs, as in most older generations. Take ownership back immediately before running ramstage. * Remove cbmem initialization, as the FSP driver handles this. * Add chipset_handle_reset() for compatibility. * Top of memory is determined by the FSP driver checking the HOBs passed from AGESA. Note that relying on the TOM register happens to be misleading when UMA is below 4GB. BUG=b:147042464 TEST=Boot trembyle to payload Change-Id: Iecb3a3f2599a8ccbc168b1d26a0271f51b71dcf0 Signed-off-by: Marshall Dawson <marshalldawson3rd@gmail.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/34423 Reviewed-by: Furquan Shaikh <furquan@google.com> Reviewed-by: Aaron Durbin <adurbin@chromium.org> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
parent
e04c2c4527
commit
00a220877c
|
@ -47,6 +47,10 @@ config CPU_SPECIFIC_OPTIONS
|
||||||
select HAVE_SMI_HANDLER
|
select HAVE_SMI_HANDLER
|
||||||
select SSE2
|
select SSE2
|
||||||
select RTC
|
select RTC
|
||||||
|
select PLATFORM_USES_FSP2_0
|
||||||
|
select FSP_USES_CB_STACK
|
||||||
|
select UDK_2017_BINDING
|
||||||
|
select HAVE_CF9_RESET
|
||||||
|
|
||||||
config AMD_FP5
|
config AMD_FP5
|
||||||
def_bool y if !AMD_FT5
|
def_bool y if !AMD_FT5
|
||||||
|
@ -225,6 +229,13 @@ config EARLYRAM_BSP_STACK_SIZE
|
||||||
hex
|
hex
|
||||||
default 0x800
|
default 0x800
|
||||||
|
|
||||||
|
config FSP_TEMP_RAM_SIZE
|
||||||
|
hex
|
||||||
|
depends on FSP_USES_CB_STACK
|
||||||
|
default 0x40000
|
||||||
|
help
|
||||||
|
The amount of coreboot-allocated heap and stack usage by the FSP.
|
||||||
|
|
||||||
menu "PSP Configuration Options"
|
menu "PSP Configuration Options"
|
||||||
|
|
||||||
config AMDFW_OUTSIDE_CBFS
|
config AMDFW_OUTSIDE_CBFS
|
||||||
|
|
|
@ -73,6 +73,7 @@ smm-y += psp.c
|
||||||
CPPFLAGS_common += -I$(src)/soc/amd/picasso
|
CPPFLAGS_common += -I$(src)/soc/amd/picasso
|
||||||
CPPFLAGS_common += -I$(src)/soc/amd/picasso/include
|
CPPFLAGS_common += -I$(src)/soc/amd/picasso/include
|
||||||
CPPFLAGS_common += -I$(src)/soc/amd/picasso/acpi
|
CPPFLAGS_common += -I$(src)/soc/amd/picasso/acpi
|
||||||
|
CPPFLAGS_common += -I$(src)/vendorcode/amd/fsp/picasso
|
||||||
|
|
||||||
# ROMSIG Normally At ROMBASE + 0x20000
|
# ROMSIG Normally At ROMBASE + 0x20000
|
||||||
# Overridden by CONFIG_AMD_FWM_POSITION_INDEX
|
# Overridden by CONFIG_AMD_FWM_POSITION_INDEX
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include <soc/pci_devs.h>
|
#include <soc/pci_devs.h>
|
||||||
#include <soc/southbridge.h>
|
#include <soc/southbridge.h>
|
||||||
#include "chip.h"
|
#include "chip.h"
|
||||||
|
#include <fsp/api.h>
|
||||||
|
|
||||||
/* Supplied by i2c.c */
|
/* Supplied by i2c.c */
|
||||||
extern struct device_operations picasso_i2c_mmio_ops;
|
extern struct device_operations picasso_i2c_mmio_ops;
|
||||||
|
@ -99,6 +100,8 @@ static void enable_dev(struct device *dev)
|
||||||
|
|
||||||
static void soc_init(void *chip_info)
|
static void soc_init(void *chip_info)
|
||||||
{
|
{
|
||||||
|
fsp_silicon_init(acpi_is_wakeup_s3());
|
||||||
|
|
||||||
southbridge_init(chip_info);
|
southbridge_init(chip_info);
|
||||||
setup_bsp_ramtop();
|
setup_bsp_ramtop();
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,37 +6,11 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <console/console.h>
|
#include <console/console.h>
|
||||||
#include <cpu/x86/msr.h>
|
|
||||||
#include <cpu/x86/smm.h>
|
#include <cpu/x86/smm.h>
|
||||||
#include <cpu/amd/msr.h>
|
#include <cpu/amd/msr.h>
|
||||||
#include <cpu/amd/mtrr.h>
|
#include <memrange.h>
|
||||||
#include <cbmem.h>
|
#include <fsp/util.h>
|
||||||
#include <arch/bert_storage.h>
|
#include <FspGuids.h>
|
||||||
#include <soc/northbridge.h>
|
|
||||||
#include <soc/iomap.h>
|
|
||||||
#include <amdblocks/acpimmio.h>
|
|
||||||
|
|
||||||
void *cbmem_top_chipset(void)
|
|
||||||
{
|
|
||||||
msr_t tom = rdmsr(TOP_MEM);
|
|
||||||
|
|
||||||
if (!tom.lo)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* 8MB alignment to keep MTRR usage low */
|
|
||||||
return (void *)ALIGN_DOWN(restore_top_of_low_cacheable()
|
|
||||||
- CONFIG_SMM_TSEG_SIZE, 8*MiB);
|
|
||||||
}
|
|
||||||
|
|
||||||
static uintptr_t smm_region_start(void)
|
|
||||||
{
|
|
||||||
return (uintptr_t)cbmem_top();
|
|
||||||
}
|
|
||||||
|
|
||||||
static size_t smm_region_size(void)
|
|
||||||
{
|
|
||||||
return CONFIG_SMM_TSEG_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For data stored in TSEG, ensure TValid is clear so R/W access can reach
|
* For data stored in TSEG, ensure TValid is clear so R/W access can reach
|
||||||
|
@ -63,9 +37,21 @@ static void clear_tvalid(void)
|
||||||
void smm_region(uintptr_t *start, size_t *size)
|
void smm_region(uintptr_t *start, size_t *size)
|
||||||
{
|
{
|
||||||
static int once;
|
static int once;
|
||||||
|
struct range_entry tseg;
|
||||||
|
int status;
|
||||||
|
|
||||||
*start = smm_region_start();
|
*start = 0;
|
||||||
*size = smm_region_size();
|
*size = 0;
|
||||||
|
|
||||||
|
status = fsp_find_range_hob(&tseg, AMD_FSP_TSEG_HOB_GUID.b);
|
||||||
|
|
||||||
|
if (status < 0) {
|
||||||
|
printk(BIOS_ERR, "Error: unable to find TSEG HOB\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
*start = (uintptr_t)range_entry_base(&tseg);
|
||||||
|
*size = range_entry_size(&tseg);
|
||||||
|
|
||||||
if (!once) {
|
if (!once) {
|
||||||
clear_tvalid();
|
clear_tvalid();
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
#include <soc/southbridge.h>
|
#include <soc/southbridge.h>
|
||||||
#include <amdblocks/acpimmio.h>
|
#include <amdblocks/acpimmio.h>
|
||||||
#include <amdblocks/reset.h>
|
#include <amdblocks/reset.h>
|
||||||
|
#include <fsp/util.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
void set_warm_reset_flag(void)
|
void set_warm_reset_flag(void)
|
||||||
{
|
{
|
||||||
|
@ -43,3 +45,11 @@ void do_board_reset(void)
|
||||||
/* TODO: Would a warm_reset() suffice? */
|
/* TODO: Would a warm_reset() suffice? */
|
||||||
do_cold_reset();
|
do_cold_reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void chipset_handle_reset(uint32_t status)
|
||||||
|
{
|
||||||
|
printk(BIOS_ERR, "Error: unexpected call to %s(0x%08x). Doing cold reset.\n",
|
||||||
|
__func__, status);
|
||||||
|
assert(0);
|
||||||
|
do_cold_reset();
|
||||||
|
}
|
||||||
|
|
|
@ -4,8 +4,10 @@
|
||||||
#include <arch/cpu.h>
|
#include <arch/cpu.h>
|
||||||
#include <arch/romstage.h>
|
#include <arch/romstage.h>
|
||||||
#include <arch/acpi.h>
|
#include <arch/acpi.h>
|
||||||
|
#include <cpu/x86/cache.h>
|
||||||
#include <cpu/x86/msr.h>
|
#include <cpu/x86/msr.h>
|
||||||
#include <cpu/amd/mtrr.h>
|
#include <cpu/amd/mtrr.h>
|
||||||
|
#include <console/uart.h>
|
||||||
#include <cbmem.h>
|
#include <cbmem.h>
|
||||||
#include <commonlib/helpers.h>
|
#include <commonlib/helpers.h>
|
||||||
#include <console/console.h>
|
#include <console/console.h>
|
||||||
|
@ -13,15 +15,69 @@
|
||||||
#include <romstage_handoff.h>
|
#include <romstage_handoff.h>
|
||||||
#include <elog.h>
|
#include <elog.h>
|
||||||
#include <soc/romstage.h>
|
#include <soc/romstage.h>
|
||||||
|
#include <soc/mtrr.h>
|
||||||
|
#include "chip.h"
|
||||||
|
#include <fsp/api.h>
|
||||||
|
|
||||||
void __weak mainboard_romstage_entry_s3(int s3_resume)
|
void __weak mainboard_romstage_entry_s3(int s3_resume)
|
||||||
{
|
{
|
||||||
/* By default, don't do anything */
|
/* By default, don't do anything */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO(b/155426691): Make FSP AGESA leave MTRRs alone */
|
||||||
|
static void clear_agesa_mtrrs(void)
|
||||||
|
{
|
||||||
|
disable_cache();
|
||||||
|
|
||||||
|
picasso_restore_mtrrs();
|
||||||
|
|
||||||
|
enable_cache();
|
||||||
|
}
|
||||||
|
|
||||||
|
void platform_fsp_memory_init_params_cb(FSPM_UPD *mupd, uint32_t version)
|
||||||
|
{
|
||||||
|
FSP_M_CONFIG *mcfg = &mupd->FspmConfig;
|
||||||
|
const config_t *config = config_of_soc();
|
||||||
|
|
||||||
|
mcfg->pci_express_base_addr = CONFIG_MMCONF_BASE_ADDRESS;
|
||||||
|
mcfg->tseg_size = CONFIG_SMM_TSEG_SIZE;
|
||||||
|
mcfg->serial_port_base = uart_platform_base(CONFIG_UART_FOR_CONSOLE);
|
||||||
|
mcfg->serial_port_use_mmio = CONFIG(DRIVERS_UART_8250MEM);
|
||||||
|
mcfg->serial_port_stride = CONFIG(DRIVERS_UART_8250MEM_32) ? 4 : 1;
|
||||||
|
mcfg->serial_port_baudrate = get_uart_baudrate();
|
||||||
|
mcfg->serial_port_refclk = uart_platform_refclk();
|
||||||
|
|
||||||
|
mcfg->system_config = config->system_config;
|
||||||
|
|
||||||
|
if ((config->slow_ppt_limit) &&
|
||||||
|
(config->fast_ppt_limit) &&
|
||||||
|
(config->slow_ppt_time_constant) &&
|
||||||
|
(config->stapm_time_constant)) {
|
||||||
|
mcfg->slow_ppt_limit = config->slow_ppt_limit;
|
||||||
|
mcfg->fast_ppt_limit = config->fast_ppt_limit;
|
||||||
|
mcfg->slow_ppt_time_constant = config->slow_ppt_time_constant;
|
||||||
|
mcfg->stapm_time_constant = config->stapm_time_constant;
|
||||||
|
}
|
||||||
|
|
||||||
|
mcfg->sustained_power_limit = config->sustained_power_limit;
|
||||||
|
mcfg->prochot_l_deassertion_ramp_time = config->prochot_l_deassertion_ramp_time;
|
||||||
|
mcfg->thermctl_limit = config->thermctl_limit;
|
||||||
|
mcfg->psi0_current_limit = config->psi0_current_limit;
|
||||||
|
mcfg->psi0_soc_current_limit = config->psi0_soc_current_limit;
|
||||||
|
mcfg->vddcr_soc_voltage_margin = config->vddcr_soc_voltage_margin;
|
||||||
|
mcfg->vddcr_vdd_voltage_margin = config->vddcr_vdd_voltage_margin;
|
||||||
|
mcfg->vrm_maximum_current_limit = config->vrm_maximum_current_limit;
|
||||||
|
mcfg->vrm_soc_maximum_current_limit = config->vrm_soc_maximum_current_limit;
|
||||||
|
mcfg->vrm_current_limit = config->vrm_current_limit;
|
||||||
|
mcfg->vrm_soc_current_limit = config->vrm_soc_current_limit;
|
||||||
|
mcfg->sb_tsi_alert_comparator_mode_en = config->sb_tsi_alert_comparator_mode_en;
|
||||||
|
mcfg->core_dldo_bypass = config->core_dldo_bypass;
|
||||||
|
mcfg->min_soc_vid_offset = config->min_soc_vid_offset;
|
||||||
|
mcfg->aclk_dpm0_freq_400MHz = config->aclk_dpm0_freq_400MHz;
|
||||||
|
}
|
||||||
|
|
||||||
asmlinkage void car_stage_entry(void)
|
asmlinkage void car_stage_entry(void)
|
||||||
{
|
{
|
||||||
uintptr_t top_of_mem;
|
|
||||||
int s3_resume;
|
int s3_resume;
|
||||||
|
|
||||||
post_code(0x40);
|
post_code(0x40);
|
||||||
|
@ -37,16 +93,15 @@ asmlinkage void car_stage_entry(void)
|
||||||
printk(BIOS_DEBUG, "Family_Model: %08x\n", val);
|
printk(BIOS_DEBUG, "Family_Model: %08x\n", val);
|
||||||
|
|
||||||
post_code(0x43);
|
post_code(0x43);
|
||||||
top_of_mem = ALIGN_DOWN(rdmsr(TOP_MEM).lo, 8 * MiB);
|
picasso_save_mtrrs();
|
||||||
backup_top_of_low_cacheable(top_of_mem);
|
|
||||||
|
|
||||||
post_code(0x44);
|
post_code(0x44);
|
||||||
if (cbmem_recovery(s3_resume))
|
fsp_memory_init(s3_resume);
|
||||||
printk(BIOS_CRIT, "Failed to recover cbmem\n");
|
|
||||||
if (romstage_handoff_init(s3_resume))
|
|
||||||
printk(BIOS_ERR, "Failed to set romstage handoff data\n");
|
|
||||||
|
|
||||||
post_code(0x45);
|
post_code(0x45);
|
||||||
|
clear_agesa_mtrrs();
|
||||||
|
|
||||||
|
post_code(0x46);
|
||||||
run_ramstage();
|
run_ramstage();
|
||||||
|
|
||||||
post_code(0x50); /* Should never see this post code. */
|
post_code(0x50); /* Should never see this post code. */
|
||||||
|
|
Loading…
Reference in New Issue