soc/intel/xeon_sp: Reserve PRMRR

PRMRR (Protected Region Memory Range Region) are not accessible as
normal DRAM regions and needs to be explicitly reserved in memory
map.

Change-Id: I81d17b1376459510f7c0d43ba4b519b1f2bd3e1f
Signed-off-by: Gang Chen <gang.c.chen@intel.com>
Signed-off-by: Shuo Liu <shuo.liu@intel.com>
Signed-off-by: Jincheng Li <jincheng.li@intel.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/84314
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
This commit is contained in:
Gang Chen 2024-06-18 06:39:12 +08:00 committed by Lean Sheng Tan
commit 3d32f915a9
7 changed files with 75 additions and 16 deletions

View file

@ -97,22 +97,6 @@ static void enable_var_mtrr(unsigned char deftype)
wrmsr(MTRR_DEF_TYPE_MSR, msr);
}
#define MTRR_VERBOSE_LEVEL BIOS_NEVER
/* MTRRs are at a 4KiB granularity. */
#define RANGE_SHIFT 12
#define ADDR_SHIFT_TO_RANGE_SHIFT(x) \
(((x) > RANGE_SHIFT) ? ((x) - RANGE_SHIFT) : RANGE_SHIFT)
#define PHYS_TO_RANGE_ADDR(x) ((x) >> RANGE_SHIFT)
#define RANGE_TO_PHYS_ADDR(x) (((resource_t)(x)) << RANGE_SHIFT)
/* Helpful constants. */
#define RANGE_1MB PHYS_TO_RANGE_ADDR(1ULL << 20)
#define RANGE_4GB (1ULL << (ADDR_SHIFT_TO_RANGE_SHIFT(32)))
#define MTRR_ALGO_SHIFT (8)
#define MTRR_TAG_MASK ((1 << MTRR_ALGO_SHIFT) - 1)
static inline uint64_t range_entry_base_mtrr_addr(struct range_entry *r)
{
return PHYS_TO_RANGE_ADDR(range_entry_base(r));

View file

@ -8,6 +8,22 @@
#include <arch/cpu.h>
#endif
#define MTRR_VERBOSE_LEVEL BIOS_NEVER
/* MTRRs are at a 4KiB granularity. */
#define RANGE_SHIFT 12
#define ADDR_SHIFT_TO_RANGE_SHIFT(x) \
(((x) > RANGE_SHIFT) ? ((x) - RANGE_SHIFT) : RANGE_SHIFT)
#define PHYS_TO_RANGE_ADDR(x) ((x) >> RANGE_SHIFT)
#define RANGE_TO_PHYS_ADDR(x) (((resource_t)(x)) << RANGE_SHIFT)
/* Helpful constants. */
#define RANGE_1MB PHYS_TO_RANGE_ADDR(1ULL << 20)
#define RANGE_4GB (1ULL << (ADDR_SHIFT_TO_RANGE_SHIFT(32)))
#define MTRR_ALGO_SHIFT (8)
#define MTRR_TAG_MASK ((1 << MTRR_ALGO_SHIFT) - 1)
/* These are the region types */
#define MTRR_TYPE_UNCACHEABLE 0
#define MTRR_TYPE_WRCOMB 1
@ -129,6 +145,11 @@ int var_mtrr_set(struct var_mtrr_context *ctx, uintptr_t addr, size_t size, int
void commit_mtrr_setup(const struct var_mtrr_context *ctx);
void postcar_mtrr_setup(void);
static inline uint64_t calculate_var_mtrr_size(uint64_t mask)
{
return 1 << (__ffs64(mask >> RANGE_SHIFT) + RANGE_SHIFT);
}
#endif /* !defined(__ASSEMBLER__) */
/* Align up/down to next power of 2, suitable for assembler

View file

@ -55,6 +55,7 @@
#define PWR_PERF_PLATFORM_OVR (1 << 18)
#define VR_THERM_ALERT_DISABLE_LOCK (1 << 23)
#define MSR_PRMRR_BASE_0 0x2a0
#define MSR_PRMRR_BASE(reg) (MSR_PRMRR_BASE_0 + (reg))
#define MSR_EVICT_CTL 0x2e0
#define MSR_LT_CONTROL 0x2e7
#define LT_CONTROL_LOCK (1 << 0)

View file

@ -134,6 +134,20 @@ uint8_t get_cxl_node_count(void)
return count;
}
unsigned int get_prmrr_count(void)
{
uint32_t cpu_id = cpu_get_cpuid();
switch (cpu_id & CPUID_ALL_STEPPINGS_MASK) {
case CPUID_GRANITERAPIDS:
return 0x7;
case CPUID_SIERRAFOREST:
return 0x4;
default:
return 0;
}
}
bool is_memtype_reserved(uint16_t mem_type)
{
return false;

View file

@ -28,6 +28,7 @@ bool is_iio_cxl_stack_res(const xSTACK_RES *res);
void bios_done_msr(void *unused);
union p2sb_bdf soc_get_hpet_bdf(void);
union p2sb_bdf soc_get_ioapic_bdf(void);
unsigned int get_prmrr_count(void);
bool get_mmio_high_base_size(resource_t *base, resource_t *size);

View file

@ -175,6 +175,11 @@ bool is_memtype_processor_attached(uint16_t mem_type)
return (mem_type < MemTypeCxlAccVolatileMem);
}
unsigned int get_prmrr_count(void)
{
return 0x7;
}
bool get_mmio_high_base_size(resource_t *base, resource_t *size)
{
const IIO_UDS *hob = get_iio_uds();

View file

@ -4,8 +4,10 @@
#include <cbmem.h>
#include <console/console.h>
#include <cpu/x86/lapic_def.h>
#include <cpu/x86/mtrr.h>
#include <device/pci.h>
#include <device/pci_ids.h>
#include <intelblocks/msr.h>
#include <soc/acpi.h>
#include <soc/chip_common.h>
#include <soc/iomap.h>
@ -154,6 +156,29 @@ static void configure_dpr(struct device *dev)
#define MC_DRAM_RESOURCE_MMIO_HIGH 0x1000
#define MC_DRAM_RESOURCE_ANON_START 0x1001
__weak unsigned int get_prmrr_count(void)
{
return 0x0;
}
static bool get_prmrr_region(unsigned int msr_addr, uint64_t *base, uint64_t *size)
{
/* Check if processor supports PRMRR */
msr_t msr1 = rdmsr(MTRR_CAP_MSR);
if (!(msr1.lo & MTRR_CAP_PRMRR)) {
printk(BIOS_ERR, "%s(): PRMRR is not supported.\n", __func__);
return false;
}
/* Mask out bits 0-11 to get the base address */
*base = msr_read(msr_addr) & ~((1 << RANGE_SHIFT) - 1);
uint64_t mask = msr_read(MSR_PRMRR_PHYS_MASK);
*size = calculate_var_mtrr_size(mask);
return (*base && *size);
}
/*
* Host Memory Map:
*
@ -302,6 +327,14 @@ static void mc_add_dram_resources(struct device *dev, int *res_count)
LOG_RESOURCE("high_ram", dev, res);
}
uint64_t prmrr_base, prmrr_size;
for (unsigned int i = 0; i < get_prmrr_count(); i++) {
if (get_prmrr_region(MSR_PRMRR_BASE(i), &prmrr_base, &prmrr_size)) {
res = reserved_ram_range(dev, index++, prmrr_base, prmrr_size);
LOG_RESOURCE("prmrr", dev, res);
}
}
if (CONFIG(SOC_INTEL_HAS_CXL)) {
/* CXL Memory */
uint8_t i;