Attention is currently required from: Arthur Heymans, Chen, Gang C, Christian Walter, Jincheng Li, Johnny Lin, Jonathan Zhang, Jérémy Compostella, Lean Sheng Tan, Patrick Rudolph, Tim Chu.
Hello Chen, Gang C, Jincheng Li,
I'd like you to do a code review. Please visit
https://review.coreboot.org/c/coreboot/+/84314?usp=email
to review the following change.
Change subject: soc/intel/xeon_sp: Reserve PRMRR ......................................................................
soc/intel/xeon_sp: Reserve PRMRR
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 --- M src/cpu/x86/mtrr/mtrr.c M src/include/cpu/x86/mtrr.h M src/soc/intel/common/block/include/intelblocks/msr.h M src/soc/intel/xeon_sp/gnr/soc_util.c M src/soc/intel/xeon_sp/include/soc/util.h M src/soc/intel/xeon_sp/uncore.c 6 files changed, 65 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/14/84314/1
diff --git a/src/cpu/x86/mtrr/mtrr.c b/src/cpu/x86/mtrr/mtrr.c index f467145..d2c8e5c 100644 --- a/src/cpu/x86/mtrr/mtrr.c +++ b/src/cpu/x86/mtrr/mtrr.c @@ -943,5 +943,10 @@ commit_var_mtrrs(&mtrr_global_solution); }
+uint64_t calculate_var_mtrr_size(uint64_t mask) +{ + return 1 << (fls64(mask >> RANGE_SHIFT) + RANGE_SHIFT); +} + BOOT_STATE_INIT_ENTRY(BS_OS_RESUME, BS_ON_ENTRY, remove_temp_solution, NULL); BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_BOOT, BS_ON_ENTRY, remove_temp_solution, NULL); diff --git a/src/include/cpu/x86/mtrr.h b/src/include/cpu/x86/mtrr.h index 5741afb..7f9381b 100644 --- a/src/include/cpu/x86/mtrr.h +++ b/src/include/cpu/x86/mtrr.h @@ -127,6 +127,7 @@ int var_mtrr_set(struct var_mtrr_context *ctx, uintptr_t addr, size_t size, int type); void commit_mtrr_setup(const struct var_mtrr_context *ctx); void postcar_mtrr_setup(void); +uint64_t calculate_var_mtrr_size(uint64_t mask);
/* fms: find most significant bit set, stolen from Linux Kernel Source. */ static inline unsigned int fms(unsigned int x) diff --git a/src/soc/intel/common/block/include/intelblocks/msr.h b/src/soc/intel/common/block/include/intelblocks/msr.h index a030328..4bdd90c 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 9d8e815..05f31bf 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 @@ return count; }
+uint8_t 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 a7b98f3..b1743a0 100644 --- a/src/soc/intel/xeon_sp/include/soc/util.h +++ b/src/soc/intel/xeon_sp/include/soc/util.h @@ -30,6 +30,7 @@ void bios_done_msr(void *unused); union p2sb_bdf soc_get_hpet_bdf(void); union p2sb_bdf soc_get_ioapic_bdf(void); +uint8_t get_prmrr_count(void);
bool get_mmio_high_base_size(resource_t *base, resource_t *size);
diff --git a/src/soc/intel/xeon_sp/uncore.c b/src/soc/intel/xeon_sp/uncore.c index 22f7e8e..8696074 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,38 @@ #define MC_DRAM_RESOURCE_MMIO_HIGH 0x1000 #define MC_DRAM_RESOURCE_ANON_START 0x1001
+__weak uint8_t get_prmrr_count(void) +{ + return 0x7; +} + +static bool get_prmrr_region(unsigned int msr_addr, uint64_t *base, uint64_t *size) +{ + /* Check on the processor if PRMRR is supported. */ + 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; + } + + msr_t msr = rdmsr(msr_addr); + uint64_t mask; + + *base = (uint64_t)msr.hi << 32 | msr.lo; + + /* Clean the BIT0-BIT11 to get the base address */ + *base = (*base >> 12) << 12; + + msr = rdmsr(MSR_PRMRR_PHYS_MASK); + mask = (uint64_t)msr.hi << 32 | msr.lo; + + *size = calculate_var_mtrr_size(mask); + + if ((*base != 0) && (*size != 0)) + return true; + return false; +} + /* * Host Memory Map: * @@ -302,6 +336,15 @@ LOG_RESOURCE("high_ram", dev, res); }
+ uint64_t prmrr_base, prmrr_size; + for (uint8_t 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); + printk(BIOS_DEBUG, "[LJDEBUG] PRMRR: %llx, %llx\n", prmrr_base, prmrr_size); + } + } + if (CONFIG(SOC_INTEL_HAS_CXL)) { /* CXL Memory */ uint8_t i;