nb/intel/sandybridge: Add support for DPR
Include DPR in the memory map calculations if enabled. DPR is required for Intel TXT support. TEST=Boot Debian 10 and see the DPR memory being reserved in E820 and cbmem logs: "BIOS-e820: [mem 0x000000007fc09000-0x00000000829fffff] reserved" "TSEG base 0x80000000 size 8M" "DPR base 0x7fd00000 size 3M" Signed-off-by: Michał Żygowski <michal.zygowski@3mdeb.com> Change-Id: Ia22e49ba58709acfa0afe0921aa71d83cc06c129 Reviewed-on: https://review.coreboot.org/c/coreboot/+/59512 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Arthur Heymans <arthur@aheymans.xyz> Reviewed-by: Angel Pons <th3fanbus@gmail.com>
This commit is contained in:
parent
ffe50fde1a
commit
ede87184f8
|
@ -10,6 +10,7 @@
|
||||||
#include <cpu/x86/smm.h>
|
#include <cpu/x86/smm.h>
|
||||||
#include <program_loading.h>
|
#include <program_loading.h>
|
||||||
#include "sandybridge.h"
|
#include "sandybridge.h"
|
||||||
|
#include <security/intel/txt/txt_platform.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
@ -24,12 +25,38 @@ static size_t northbridge_get_tseg_size(void)
|
||||||
return CONFIG_SMM_TSEG_SIZE;
|
return CONFIG_SMM_TSEG_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
union dpr_register txt_get_chipset_dpr(void)
|
||||||
|
{
|
||||||
|
return (union dpr_register) { .raw = pci_read_config32(HOST_BRIDGE, DPR) };
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the topmost memory address below 4 GiB available for general
|
||||||
|
* use, from software's view of memory. Do not confuse this with TOLUD,
|
||||||
|
* which applies to the DRAM as viewed by the memory controller itself.
|
||||||
|
*/
|
||||||
|
static uintptr_t top_of_low_usable_memory(void)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Base of DPR is top of usable DRAM below 4 GiB. However, DPR
|
||||||
|
* may not always be enabled. Unlike most memory map registers,
|
||||||
|
* the DPR register stores top of DPR instead of its base address.
|
||||||
|
* Top of DPR is R/O, and mirrored from TSEG base by hardware.
|
||||||
|
*/
|
||||||
|
uintptr_t tolum = northbridge_get_tseg_base();
|
||||||
|
|
||||||
|
const union dpr_register dpr = txt_get_chipset_dpr();
|
||||||
|
|
||||||
|
/* Subtract DMA Protected Range size if enabled */
|
||||||
|
if (dpr.epm)
|
||||||
|
tolum -= dpr.size * MiB;
|
||||||
|
|
||||||
|
return tolum;
|
||||||
|
}
|
||||||
|
|
||||||
void *cbmem_top_chipset(void)
|
void *cbmem_top_chipset(void)
|
||||||
{
|
{
|
||||||
/* If DPR is disabled, base of TSEG is top of usable DRAM */
|
return (void *)top_of_low_usable_memory();
|
||||||
uintptr_t top_of_ram = northbridge_get_tseg_base();
|
|
||||||
|
|
||||||
return (void *)top_of_ram;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void smm_region(uintptr_t *start, size_t *size)
|
void smm_region(uintptr_t *start, size_t *size)
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include "chip.h"
|
#include "chip.h"
|
||||||
#include "sandybridge.h"
|
#include "sandybridge.h"
|
||||||
#include <cpu/intel/smm_reloc.h>
|
#include <cpu/intel/smm_reloc.h>
|
||||||
|
#include <security/intel/txt/txt_platform.h>
|
||||||
|
|
||||||
/* IGD UMA memory */
|
/* IGD UMA memory */
|
||||||
static uint64_t uma_memory_base = 0;
|
static uint64_t uma_memory_base = 0;
|
||||||
|
@ -85,9 +86,11 @@ static void mc_read_resources(struct device *dev)
|
||||||
{
|
{
|
||||||
uint64_t tom, me_base, touud;
|
uint64_t tom, me_base, touud;
|
||||||
uint32_t tseg_base, uma_size, tolud;
|
uint32_t tseg_base, uma_size, tolud;
|
||||||
|
uint32_t dpr_base_k, dpr_size_k;
|
||||||
uint16_t ggc;
|
uint16_t ggc;
|
||||||
unsigned long long tomk;
|
unsigned long long tomk;
|
||||||
unsigned long index = 3;
|
unsigned long index = 3;
|
||||||
|
const union dpr_register dpr = txt_get_chipset_dpr();
|
||||||
|
|
||||||
pci_dev_read_resources(dev);
|
pci_dev_read_resources(dev);
|
||||||
|
|
||||||
|
@ -184,6 +187,15 @@ static void mc_read_resources(struct device *dev)
|
||||||
uma_memory_size += uma_size * 1024ULL;
|
uma_memory_size += uma_size * 1024ULL;
|
||||||
printk(BIOS_DEBUG, "TSEG base 0x%08x size %uM\n", tseg_base, uma_size >> 10);
|
printk(BIOS_DEBUG, "TSEG base 0x%08x size %uM\n", tseg_base, uma_size >> 10);
|
||||||
|
|
||||||
|
/* Calculate DMA Protected Region if enabled */
|
||||||
|
if (dpr.epm && dpr.size) {
|
||||||
|
dpr_size_k = dpr.size * MiB / KiB;
|
||||||
|
tomk -= dpr_size_k;
|
||||||
|
dpr_base_k = (tseg_base - dpr.size * MiB) / KiB;
|
||||||
|
reserved_ram_resource(dev, index++, dpr_base_k, dpr_size_k);
|
||||||
|
printk(BIOS_DEBUG, "DPR base 0x%08x size %uM\n", dpr_base_k * KiB, dpr.size);
|
||||||
|
}
|
||||||
|
|
||||||
printk(BIOS_INFO, "Available memory below 4GB: %lluM\n", tomk >> 10);
|
printk(BIOS_INFO, "Available memory below 4GB: %lluM\n", tomk >> 10);
|
||||||
|
|
||||||
/* Report the memory regions */
|
/* Report the memory regions */
|
||||||
|
|
Loading…
Reference in New Issue