From 8ecd9d2096db2bded6f27ef6ee9a9b39ce2dfec6 Mon Sep 17 00:00:00 2001 From: Duncan Laurie Date: Thu, 22 May 2014 09:07:34 -0700 Subject: [PATCH] broadwell: Reserve DPR region Broadwell CPUs can have a region reserved just below TSEG for a PCODE patch or TXT/BootGuard data. The DPR register reports the TOP of this region with the size also reported in bits 8:4. Compute and use the DPR base address as the top of memory for coreboot. BUG=chrome-os-partner:28234 TEST=Build and boot on wtm2+broadwell, check that the usable memory is adjusted by 1MB: - 3. 0000000000100000-000000007ce3efff: RAM - 4. 000000007ce3f000-000000007cffffff: CONFIGURATION TABLES - 5. 000000007d000000-000000007f9fffff: RESERVED + 3. 0000000000100000-000000007cd3efff: RAM + 4. 000000007cd3f000-000000007cefffff: CONFIGURATION TABLES + 5. 000000007cf00000-000000007f9fffff: RESERVED Change-Id: Ia6ba25bc9992c3a3f859edd8d4a9c64aa42cfa98 Signed-off-by: Duncan Laurie Reviewed-on: https://chromium-review.googlesource.com/201081 Reviewed-by: Aaron Durbin --- .../intel/broadwell/broadwell/systemagent.h | 4 ++++ src/soc/intel/broadwell/memmap.c | 15 +++++++++---- src/soc/intel/broadwell/systemagent.c | 22 ++++++++++++++++--- 3 files changed, 34 insertions(+), 7 deletions(-) diff --git a/src/soc/intel/broadwell/broadwell/systemagent.h b/src/soc/intel/broadwell/broadwell/systemagent.h index 27c06f7608..f95370b2b5 100644 --- a/src/soc/intel/broadwell/broadwell/systemagent.h +++ b/src/soc/intel/broadwell/broadwell/systemagent.h @@ -52,6 +52,10 @@ #define DEVEN_D1F1EN (1 << 2) #define DEVEN_D1F2EN (1 << 1) #define DEVEN_D0EN (1 << 0) +#define DPR 0x5c +#define DPR_EPM (1 << 2) +#define DPR_PRS (1 << 1) +#define DPR_SIZE_MASK 0xff0 #define PAM0 0x80 #define PAM1 0x81 diff --git a/src/soc/intel/broadwell/memmap.c b/src/soc/intel/broadwell/memmap.c index c960347cf2..698ff6b83c 100644 --- a/src/soc/intel/broadwell/memmap.c +++ b/src/soc/intel/broadwell/memmap.c @@ -26,11 +26,18 @@ static unsigned long get_top_of_ram(void) { /* - * Base of TSEG is top of usable DRAM below 4GiB. The register has - * 1 MiB alignement. + * Base of DPR is top of usable DRAM below 4GiB. The register has + * 1 MiB alignment and reports the TOP of the range, the base + * must be calculated from the size in MiB in bits 11:4. */ - u32 tom = pci_read_config32(SA_DEV_ROOT, TSEG); - return (unsigned long) tom & ~((1 << 20) - 1); + u32 dpr = pci_read_config32(SA_DEV_ROOT, DPR); + u32 tom = dpr & ~((1 << 20) - 1); + + /* Subtract DMA Protected Range size if enabled */ + if (dpr & DPR_EPM) + tom -= (dpr & DPR_SIZE_MASK) << 16; + + return (unsigned long)tom; } void *cbmem_top(void) diff --git a/src/soc/intel/broadwell/systemagent.c b/src/soc/intel/broadwell/systemagent.c index 56a44d99e5..787a62b2ee 100644 --- a/src/soc/intel/broadwell/systemagent.c +++ b/src/soc/intel/broadwell/systemagent.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -278,11 +279,25 @@ static void mc_add_dram_resources(device_t dev) unsigned long index; struct resource *resource; uint64_t mc_values[NUM_MAP_ENTRIES]; + unsigned long dpr_size = 0; + u32 dpr_reg; /* Read in the MAP registers and report their values. */ mc_read_map_entries(dev, &mc_values[0]); mc_report_map_entries(dev, &mc_values[0]); + /* + * DMA Protected Range can be reserved below TSEG for PCODE patch + * or TXT/BootGuard related data. Rather than report a base address + * the DPR register reports the TOP of the region, which is the same + * as TSEG base. The region size is reported in MiB in bits 11:4. + */ + dpr_reg = pci_read_config32(SA_DEV_ROOT, DPR); + if (dpr_reg & DPR_EPM) { + dpr_size = (dpr_reg & DPR_SIZE_MASK) << 16; + printk(BIOS_INFO, "DPR SIZE: 0x%lx\n", dpr_size); + } + /* * These are the host memory ranges that should be added: * - 0 -> 0xa0000: cacheable @@ -320,14 +335,15 @@ static void mc_add_dram_resources(device_t dev) size_k = (0xa0000 >> 10) - base_k; ram_resource(dev, index++, base_k, size_k); - /* 0xc0000 -> TSEG */ + /* 0xc0000 -> TSEG - DPR */ base_k = 0xc0000 >> 10; size_k = (unsigned long)(mc_values[TSEG_REG] >> 10) - base_k; + size_k -= dpr_size >> 10; ram_resource(dev, index++, base_k, size_k); - /* TSEG -> BGSM */ + /* TSEG - DPR -> BGSM */ resource = new_resource(dev, index++); - resource->base = mc_values[TSEG_REG]; + resource->base = mc_values[TSEG_REG] - dpr_size; resource->size = mc_values[BGSM_REG] - resource->base; resource->flags = IORESOURCE_MEM | IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_RESERVE |