From 279c3e1e7d888af378e85f51bbfa3bbe667909b1 Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Wed, 2 Dec 2020 13:28:53 +0100 Subject: [PATCH] mb/emulation/qemu-q35: Account for TSEG TSEG is located below TOLUD. The size is configured in ESMRAMC but can also be configured with "-global mch.extended-tseg-mbytes=5" command line argument. Note that the size in ESMRAMC needs to be 'invalid' (3) for this to take action. coreboot will leave TSEG at the default 1MiB. Note that even if TSEG does not end up being used, it is likely a good idea to not put anything there as if SMM gets locked down by something else it will suddenly be inaccessible. Change-Id: I5fd82a42d6602f1369bb3c69556c46f537542705 Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/48236 Tested-by: build bot (Jenkins) Reviewed-by: Angel Pons --- src/mainboard/emulation/qemu-i440fx/memmap.c | 6 +++ src/mainboard/emulation/qemu-q35/Makefile.inc | 4 ++ src/mainboard/emulation/qemu-q35/memmap.c | 43 +++++++++++++++++++ 3 files changed, 53 insertions(+) create mode 100644 src/mainboard/emulation/qemu-q35/memmap.c diff --git a/src/mainboard/emulation/qemu-i440fx/memmap.c b/src/mainboard/emulation/qemu-i440fx/memmap.c index b30b3816c5..75ab352b69 100644 --- a/src/mainboard/emulation/qemu-i440fx/memmap.c +++ b/src/mainboard/emulation/qemu-i440fx/memmap.c @@ -4,6 +4,7 @@ #include #include #include +#include #include "memory.h" #include "fw_cfg.h" @@ -50,6 +51,11 @@ void *cbmem_top_chipset(void) top = (uintptr_t)qemu_get_memory_size() * 1024; } + if (CONFIG(BOARD_EMULATION_QEMU_X86_Q35)) { + size_t smm_size; + smm_region(&top, &smm_size); + } + return (void *)top; } diff --git a/src/mainboard/emulation/qemu-q35/Makefile.inc b/src/mainboard/emulation/qemu-q35/Makefile.inc index ddcf6da062..4bd91f0217 100644 --- a/src/mainboard/emulation/qemu-q35/Makefile.inc +++ b/src/mainboard/emulation/qemu-q35/Makefile.inc @@ -2,17 +2,21 @@ bootblock-y += bootblock.c romstage-y += ../qemu-i440fx/fw_cfg.c romstage-y += ../qemu-i440fx/memmap.c +romstage-y += memmap.c postcar-y += ../qemu-i440fx/fw_cfg.c postcar-y += ../qemu-i440fx/memmap.c postcar-y += ../qemu-i440fx/exit_car.S +postcar-y += memmap.c ramstage-y += ../qemu-i440fx/fw_cfg.c ramstage-y += ../qemu-i440fx/memmap.c ramstage-y += ../qemu-i440fx/northbridge.c +ramstage-y += memmap.c verstage-$(CONFIG_CHROMEOS) += chromeos.c verstage-$(CONFIG_CHROMEOS) += ../qemu-i440fx/fw_cfg.c ramstage-$(CONFIG_CHROMEOS) += chromeos.c smm-$(CONFIG_HAVE_SMI_HANDLER) += smi.c +smm-$(CONFIG_HAVE_SMI_HANDLER) += memmap.c diff --git a/src/mainboard/emulation/qemu-q35/memmap.c b/src/mainboard/emulation/qemu-q35/memmap.c new file mode 100644 index 0000000000..a8b1433714 --- /dev/null +++ b/src/mainboard/emulation/qemu-q35/memmap.c @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#define __SIMPLE_DEVICE__ + +#include +#include +#include +#include +#include + +#define EXT_TSEG_MBYTES 0x50 + +#define SMRAMC 0x9d +#define G_SMRAME (1 << 3) +#define D_LCK (1 << 4) +#define D_CLS (1 << 5) +#define D_OPEN (1 << 6) +#define ESMRAMC 0x9e +#define T_EN (1 << 0) +#define TSEG_SZ_MASK (3 << 1) +#define H_SMRAME (1 << 7) + +void smm_region(uintptr_t *start, size_t *size) +{ + uint8_t esmramc = pci_read_config8(PCI_DEV(0, 0, 0), ESMRAMC); + + switch ((esmramc & TSEG_SZ_MASK) >> 1) { + case 0: + *size = 1 * MiB; + break; + case 1: + *size = 2 * MiB; + break; + case 2: + *size = 8 * MiB; + break; + default: + *size = pci_read_config16(PCI_DEV(0, 0, 0), EXT_TSEG_MBYTES) * MiB; + } + + *start = qemu_get_memory_size() * KiB - *size; + printk(BIOS_SPEW, "SMM_BASE: 0x%08lx, SMM_SIZE: %zu MiB\n", *start, *size / MiB); +}