From ede87184f8a3f21926ae3458418ec225052e07a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Sun, 21 Nov 2021 11:53:42 +0100 Subject: nb/intel/sandybridge: Add support for DPR MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Change-Id: Ia22e49ba58709acfa0afe0921aa71d83cc06c129 Reviewed-on: https://review.coreboot.org/c/coreboot/+/59512 Tested-by: build bot (Jenkins) Reviewed-by: Arthur Heymans Reviewed-by: Angel Pons --- src/northbridge/intel/sandybridge/memmap.c | 35 ++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) (limited to 'src/northbridge/intel/sandybridge/memmap.c') diff --git a/src/northbridge/intel/sandybridge/memmap.c b/src/northbridge/intel/sandybridge/memmap.c index 7f46d6663e..f667544c68 100644 --- a/src/northbridge/intel/sandybridge/memmap.c +++ b/src/northbridge/intel/sandybridge/memmap.c @@ -10,6 +10,7 @@ #include #include #include "sandybridge.h" +#include #include #include @@ -24,12 +25,38 @@ static size_t northbridge_get_tseg_size(void) return CONFIG_SMM_TSEG_SIZE; } -void *cbmem_top_chipset(void) +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) { - /* If DPR is disabled, base of TSEG is top of usable DRAM */ - uintptr_t top_of_ram = northbridge_get_tseg_base(); + /* + * 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(); - return (void *)top_of_ram; + 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) +{ + return (void *)top_of_low_usable_memory(); } void smm_region(uintptr_t *start, size_t *size) -- cgit v1.2.3