diff options
author | Gang Chen <gang.c.chen@intel.com> | 2024-06-18 06:39:12 +0800 |
---|---|---|
committer | Lean Sheng Tan <sheng.tan@9elements.com> | 2024-11-14 14:29:23 +0000 |
commit | 3d32f915a9c4d60046574690db966d1f14eebe65 (patch) | |
tree | 79cb2533cca5fb7fa593bc77ac23b5873268eba2 | |
parent | 97412d1929e88a929f73a229e40ca85a38168d7e (diff) |
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>
-rw-r--r-- | src/cpu/x86/mtrr/mtrr.c | 16 | ||||
-rw-r--r-- | src/include/cpu/x86/mtrr.h | 21 | ||||
-rw-r--r-- | src/soc/intel/common/block/include/intelblocks/msr.h | 1 | ||||
-rw-r--r-- | src/soc/intel/xeon_sp/gnr/soc_util.c | 14 | ||||
-rw-r--r-- | src/soc/intel/xeon_sp/include/soc/util.h | 1 | ||||
-rw-r--r-- | src/soc/intel/xeon_sp/spr/soc_util.c | 5 | ||||
-rw-r--r-- | src/soc/intel/xeon_sp/uncore.c | 33 |
7 files changed, 75 insertions, 16 deletions
diff --git a/src/cpu/x86/mtrr/mtrr.c b/src/cpu/x86/mtrr/mtrr.c index f3a9025d53..64ab8294f5 100644 --- a/src/cpu/x86/mtrr/mtrr.c +++ b/src/cpu/x86/mtrr/mtrr.c @@ -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)); diff --git a/src/include/cpu/x86/mtrr.h b/src/include/cpu/x86/mtrr.h index 2d7a8416c1..16efbb6eef 100644 --- a/src/include/cpu/x86/mtrr.h +++ b/src/include/cpu/x86/mtrr.h @@ -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 diff --git a/src/soc/intel/common/block/include/intelblocks/msr.h b/src/soc/intel/common/block/include/intelblocks/msr.h index a03032899d..4bdd90c536 100644 --- a/src/soc/intel/common/block/include/intelblocks/msr.h +++ b/src/soc/intel/common/block/include/intelblocks/msr.h @@ -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) diff --git a/src/soc/intel/xeon_sp/gnr/soc_util.c b/src/soc/intel/xeon_sp/gnr/soc_util.c index 9d8e815f8e..6912809d2d 100644 --- a/src/soc/intel/xeon_sp/gnr/soc_util.c +++ b/src/soc/intel/xeon_sp/gnr/soc_util.c @@ -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; diff --git a/src/soc/intel/xeon_sp/include/soc/util.h b/src/soc/intel/xeon_sp/include/soc/util.h index 4c7c75fdeb..95d127d825 100644 --- a/src/soc/intel/xeon_sp/include/soc/util.h +++ b/src/soc/intel/xeon_sp/include/soc/util.h @@ -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); diff --git a/src/soc/intel/xeon_sp/spr/soc_util.c b/src/soc/intel/xeon_sp/spr/soc_util.c index a6f00c07e0..3b13f53a14 100644 --- a/src/soc/intel/xeon_sp/spr/soc_util.c +++ b/src/soc/intel/xeon_sp/spr/soc_util.c @@ -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(); diff --git a/src/soc/intel/xeon_sp/uncore.c b/src/soc/intel/xeon_sp/uncore.c index c20e55fdce..1d77675aeb 100644 --- a/src/soc/intel/xeon_sp/uncore.c +++ b/src/soc/intel/xeon_sp/uncore.c @@ -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; |