d91d2df2cc
Picasso's BERT region should not have been moved to cbmem in commit
901cb9c
"soc/amd/picasso: Move BERT region to cbmem". This
causes an error of "APEI: Can not request [] for APEI BERT registers.
FSP has been modified to set aside a requested region size for BERT,
simiar to TSEG. Remove the cbmem reservation and locate the region
by searching for the HOB.
BUG=b:136987699
TEST=Check that BERT is allocated
Signed-off-by: Marshall Dawson <marshalldawson3rd@gmail.com>
Change-Id: I20e99390141986913dd45c2074aa184e992c8ebb
Reviewed-on: https://review.coreboot.org/c/coreboot/+/42530
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
104 lines
2.1 KiB
C
104 lines
2.1 KiB
C
/* SPDX-License-Identifier: GPL-2.0-only */
|
|
|
|
#define __SIMPLE_DEVICE__
|
|
|
|
#include <assert.h>
|
|
#include <stdint.h>
|
|
#include <cbmem.h>
|
|
#include <console/console.h>
|
|
#include <cpu/x86/smm.h>
|
|
#include <cpu/amd/msr.h>
|
|
#include <arch/bert_storage.h>
|
|
#include <memrange.h>
|
|
#include <fsp/util.h>
|
|
#include <FspGuids.h>
|
|
#include <soc/memmap.h>
|
|
|
|
/*
|
|
* For data stored in TSEG, ensure TValid is clear so R/W access can reach
|
|
* the DRAM when not in SMM.
|
|
*/
|
|
static void clear_tvalid(void)
|
|
{
|
|
msr_t hwcr = rdmsr(HWCR_MSR);
|
|
msr_t mask = rdmsr(SMM_MASK_MSR);
|
|
int tvalid = !!(mask.lo & SMM_TSEG_VALID);
|
|
|
|
if (hwcr.lo & SMM_LOCK) {
|
|
if (!tvalid) /* not valid but locked means still accessible */
|
|
return;
|
|
|
|
printk(BIOS_ERR, "Error: can't clear TValid, already locked\n");
|
|
return;
|
|
}
|
|
|
|
mask.lo &= ~SMM_TSEG_VALID;
|
|
wrmsr(SMM_MASK_MSR, mask);
|
|
}
|
|
|
|
void smm_region(uintptr_t *start, size_t *size)
|
|
{
|
|
static int once;
|
|
struct range_entry tseg;
|
|
int status;
|
|
|
|
*start = 0;
|
|
*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) {
|
|
clear_tvalid();
|
|
once = 1;
|
|
}
|
|
}
|
|
|
|
void bert_reserved_region(void **start, size_t *size)
|
|
{
|
|
struct range_entry bert;
|
|
int status;
|
|
|
|
*start = NULL;
|
|
*size = 0;
|
|
|
|
status = fsp_find_range_hob(&bert, AMD_FSP_BERT_HOB_GUID.b);
|
|
|
|
if (status < 0) {
|
|
printk(BIOS_ERR, "Error: unable to find BERT HOB\n");
|
|
return;
|
|
}
|
|
|
|
*start = (void *)(uintptr_t)range_entry_base(&bert);
|
|
*size = range_entry_size(&bert);
|
|
}
|
|
|
|
void memmap_stash_early_dram_usage(void)
|
|
{
|
|
struct memmap_early_dram *e;
|
|
|
|
e = cbmem_add(CBMEM_ID_CB_EARLY_DRAM, sizeof(*e));
|
|
|
|
if (!e)
|
|
die("ERROR: Failed to stash early dram usage!\n");
|
|
|
|
e->base = (uint32_t)(uintptr_t)_early_reserved_dram;
|
|
e->size = REGION_SIZE(early_reserved_dram);
|
|
}
|
|
|
|
const struct memmap_early_dram *memmap_get_early_dram_usage(void)
|
|
{
|
|
struct memmap_early_dram *e = cbmem_find(CBMEM_ID_CB_EARLY_DRAM);
|
|
|
|
if (!e)
|
|
die("ERROR: Failed to read early dram usage!\n");
|
|
|
|
return e;
|
|
}
|