summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cpu/x86/mtrr/mtrr.c16
-rw-r--r--src/include/cpu/x86/mtrr.h21
-rw-r--r--src/soc/intel/common/block/include/intelblocks/msr.h1
-rw-r--r--src/soc/intel/xeon_sp/gnr/soc_util.c14
-rw-r--r--src/soc/intel/xeon_sp/include/soc/util.h1
-rw-r--r--src/soc/intel/xeon_sp/spr/soc_util.c5
-rw-r--r--src/soc/intel/xeon_sp/uncore.c33
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;