From ff01957a5e683aee8970f1690b4c78b8dac67ad9 Mon Sep 17 00:00:00 2001 From: Krystian Hebel Date: Mon, 15 Aug 2022 22:36:23 +0200 Subject: [PATCH 01/11] cpu/amd/pi: add skeleton for DRTM Signed-off-by: Krystian Hebel --- .gitignore | 1 + payloads/external/Makefile.inc | 11 +++++++++++ payloads/external/skl/Makefile | 20 ++++++++++++++++++++ src/cpu/amd/pi/Kconfig | 8 ++++++++ src/cpu/amd/pi/Makefile.inc | 2 ++ src/cpu/amd/pi/skinit.c | 8 ++++++++ 6 files changed, 50 insertions(+) create mode 100644 payloads/external/skl/Makefile create mode 100644 src/cpu/amd/pi/skinit.c diff --git a/.gitignore b/.gitignore index deb81882de7..a456dca8db3 100644 --- a/.gitignore +++ b/.gitignore @@ -21,6 +21,7 @@ payloads/external/U-Boot/u-boot/ payloads/external/Memtest86Plus/memtest86plus/ payloads/external/iPXE/ipxe/ payloads/external/sortbootorder/sortbootorder +payloads/external/skl/secure-kernel-loader/ util/crossgcc/acpica-unix-*/ util/crossgcc/binutils-*/ util/crossgcc/build-*BINUTILS/ diff --git a/payloads/external/Makefile.inc b/payloads/external/Makefile.inc index 7873c071de3..265b8c26960 100644 --- a/payloads/external/Makefile.inc +++ b/payloads/external/Makefile.inc @@ -475,3 +475,14 @@ doom.wad-file := $(strip $(CONFIG_COREDOOM_WAD_FILE)) doom.wad-type := raw doom.wad-compression := $(CBFS_SECONDARY_PAYLOAD_COMPRESS_FLAG) endif + +# SKL + +payloads/external/skl/secure-kernel-loader/skl.bin: + $(MAKE) -C payloads/external/skl CC="$(HOSTCC)" + +cbfs-files-$(CONFIG_LAUNCH_DRTM_PAYLOAD) += $(CONFIG_CBFS_PREFIX)/drtm_payload +$(CONFIG_CBFS_PREFIX)/drtm_payload-file := payloads/external/skl/secure-kernel-loader/skl.bin +$(CONFIG_CBFS_PREFIX)/drtm_payload-type := raw +$(CONFIG_CBFS_PREFIX)/drtm_payload-compression := $(CBFS_PAYLOAD_COMPRESS_FLAG) +$(CONFIG_CBFS_PREFIX)/drtm_payload-options := $(ADDITIONAL_PAYLOAD_CONFIG) diff --git a/payloads/external/skl/Makefile b/payloads/external/skl/Makefile new file mode 100644 index 00000000000..2ae018fbd6d --- /dev/null +++ b/payloads/external/skl/Makefile @@ -0,0 +1,20 @@ +## SPDX-License-Identifier: GPL-2.0-only +project_git_repo=https://github.com/TrenchBoot/secure-kernel-loader.git +project_dir=secure-kernel-loader + +all: skl + +checkout: + test -d $(project_dir) || \ + git clone $(project_git_repo) $(project_dir) + +skl: checkout + $(MAKE) -C $(project_dir) DEBUG=y + +clean: + test -d $(project_dir) && $(MAKE) -C $(project_dir) clean || exit 0 + +distclean: + rm -rf $(project_dir) + +.PHONY: checkout skl clean distclean diff --git a/src/cpu/amd/pi/Kconfig b/src/cpu/amd/pi/Kconfig index 2336d68f968..1a4a05b7630 100644 --- a/src/cpu/amd/pi/Kconfig +++ b/src/cpu/amd/pi/Kconfig @@ -35,6 +35,14 @@ config DCACHE_BSP_STACK_SIZE hex default 0x4000 +config LAUNCH_DRTM_PAYLOAD + bool "Launch DRTM payload before the real one" + default n + depends on MEMORY_MAPPED_TPM + help + Launch DRTM payload before the real one. This makes it possible to + put root of trust in hardware for platforms that don't support SRTM. + endif # CPU_AMD_PI source "src/cpu/amd/pi/00730F01/Kconfig" diff --git a/src/cpu/amd/pi/Makefile.inc b/src/cpu/amd/pi/Makefile.inc index ae042532150..bb7d09b3ad1 100644 --- a/src/cpu/amd/pi/Makefile.inc +++ b/src/cpu/amd/pi/Makefile.inc @@ -1,3 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-only subdirs-$(CONFIG_CPU_AMD_PI_00730F01) += 00730F01 + +ramstage-$(CONFIG_LAUNCH_DRTM_PAYLOAD) += skinit.c diff --git a/src/cpu/amd/pi/skinit.c b/src/cpu/amd/pi/skinit.c new file mode 100644 index 00000000000..976d6abe2fd --- /dev/null +++ b/src/cpu/amd/pi/skinit.c @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include + +void platform_prog_run(struct prog *prog) +{ + /* do nothing */ +} From c0181c90c85a8c157728c05553c6702f89f52245 Mon Sep 17 00:00:00 2001 From: Krystian Hebel Date: Wed, 31 Aug 2022 23:44:36 +0200 Subject: [PATCH 02/11] cpu/amd/pi/skinit: load and start DRTM payload Signed-off-by: Krystian Hebel --- src/cpu/amd/pi/skinit.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/cpu/amd/pi/skinit.c b/src/cpu/amd/pi/skinit.c index 976d6abe2fd..66d2003cc0e 100644 --- a/src/cpu/amd/pi/skinit.c +++ b/src/cpu/amd/pi/skinit.c @@ -1,8 +1,29 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include +#include #include +#include +#include void platform_prog_run(struct prog *prog) { - /* do nothing */ + void *skl = NULL; + + /* + * APs have to be in wait-for-SIPI state for at least 1000 cycles before + * SKINIT. Send INIT now and assume that loading SKL from CBFS is long + * enough. + */ + lapic_send_ipi_others(LAPIC_INT_LEVELTRIG | LAPIC_INT_ASSERT | LAPIC_DM_INIT); + + skl = memalign(64*KiB, 64*KiB); + + cbfs_load(CONFIG_CBFS_PREFIX "/drtm_payload", skl, 64*KiB); + + /* TODO: fill SKL input data */ + + tis_close(); + + asm volatile ("skinit" :: "a"(skl)); } From 51a179840121a95ced12219f9f694e691c89b3b8 Mon Sep 17 00:00:00 2001 From: Krystian Hebel Date: Fri, 9 Sep 2022 18:47:07 +0200 Subject: [PATCH 03/11] cpu/amd/skinit.c: pass minimal set of info required to boot to SKL Signed-off-by: Krystian Hebel --- src/cpu/amd/pi/skinit.c | 106 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 105 insertions(+), 1 deletion(-) diff --git a/src/cpu/amd/pi/skinit.c b/src/cpu/amd/pi/skinit.c index 66d2003cc0e..fb81e4e391f 100644 --- a/src/cpu/amd/pi/skinit.c +++ b/src/cpu/amd/pi/skinit.c @@ -6,9 +6,90 @@ #include #include +#include + +static uintptr_t payload_start, payload_size; + +/* For SELF, prog->start and prog->size are not set so obtain it differently. */ +void platform_segment_loaded(uintptr_t start, size_t size, int flags) +{ + if (payload_start != 0 || payload_size != 0 || flags != SEG_FINAL) + die("ELF payload must have only one loadable segment for DRTM!\n"); + + /* SIPI vector loading also goes through this function, skip it. */ + if (size <= 4*KiB) + return; + + payload_start = start; + payload_size = size; +} + +/* TODO: include tags.h from SKL somehow */ +#define SKL_TAG_CLASS_MASK 0xF0 + +/* Tags with no particular class */ +#define SKL_TAG_NO_CLASS 0x00 +#define SKL_TAG_END 0x00 +#define SKL_TAG_SETUP_INDIRECT 0x01 +#define SKL_TAG_TAGS_SIZE 0x0F /* Always first */ + +/* Tags specifying kernel type */ +#define SKL_TAG_BOOT_CLASS 0x10 +#define SKL_TAG_BOOT_LINUX 0x10 +#define SKL_TAG_BOOT_MB2 0x11 +#define SKL_TAG_BOOT_SIMPLE 0x12 + +struct skl_tag_hdr { + uint8_t type; + uint8_t len; +} __packed; + +struct skl_tag_tags_size { + struct skl_tag_hdr hdr; + uint16_t size; +} __packed; + +struct skl_tag_boot_simple_payload { + struct skl_tag_hdr hdr; + uint32_t base; + uint32_t size; + uint32_t entry; + uint32_t arg; +} __packed; + +struct skl_tag_evtlog { + struct skl_tag_hdr hdr; + uint32_t address; + uint32_t size; +} __packed; + +struct skl_tag_hash { + struct skl_tag_hdr hdr; + uint16_t algo_id; + uint8_t digest[]; +} __packed; + +static inline void *next_tag(void* t) +{ + void *x = t + ((struct skl_tag_hdr*)t)->len; + return x; +} + void platform_prog_run(struct prog *prog) { void *skl = NULL; + uint16_t bootloader_data_offset; + struct skl_tag_tags_size *tags; + struct skl_tag_boot_simple_payload *sp; + struct skl_tag_hdr *end; + + /* + * Check if we're on 32b platform. + * TODO: add support for 64b? + */ + assert(sizeof(skl) == 4); + + hexdump(prog, sizeof(*prog)); /* * APs have to be in wait-for-SIPI state for at least 1000 cycles before @@ -21,7 +102,30 @@ void platform_prog_run(struct prog *prog) cbfs_load(CONFIG_CBFS_PREFIX "/drtm_payload", skl, 64*KiB); - /* TODO: fill SKL input data */ + bootloader_data_offset = ((uint16_t *)skl)[1]; + tags = (struct skl_tag_tags_size *)(skl + bootloader_data_offset); + + memset(tags, 0, 64*KiB - (skl - (void *)tags)); + + tags->hdr.type = SKL_TAG_TAGS_SIZE; + tags->hdr.len = sizeof(struct skl_tag_tags_size); + tags->size += tags->hdr.len; + + sp = next_tag(tags); + sp->hdr.type = SKL_TAG_BOOT_SIMPLE; + sp->hdr.len = sizeof(struct skl_tag_boot_simple_payload); + sp->base = payload_start; + sp->size = payload_size; + sp->entry = (uint32_t)prog->entry; + sp->arg = (uint32_t)prog->arg; + tags->size += sp->hdr.len; + + /* TODO: DRTM TPM event log */ + + end = next_tag(sp); + end->type = SKL_TAG_END; + end->len = sizeof(struct skl_tag_hdr); + tags->size += end->len; tis_close(); From 60a75d8fc63d691b0a7da298d21e9d69936f8560 Mon Sep 17 00:00:00 2001 From: Krystian Hebel Date: Fri, 16 Sep 2022 13:19:55 +0200 Subject: [PATCH 04/11] cpu/x86/lapic: use TSC in SMM LAPIC timer can be re-configured and used by OS. TSC should have constant rate, and even if it doesn't, TSC is only read. LAPIC on the other hand requires writes during initialization, which can mess up whatever OS uses it for. Signed-off-by: Krystian Hebel --- src/cpu/x86/lapic/Makefile.inc | 3 +++ src/cpu/x86/tsc/delay_tsc.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/cpu/x86/lapic/Makefile.inc b/src/cpu/x86/lapic/Makefile.inc index 91a41f76a59..d457b35182e 100644 --- a/src/cpu/x86/lapic/Makefile.inc +++ b/src/cpu/x86/lapic/Makefile.inc @@ -6,6 +6,9 @@ bootblock-$(CONFIG_UDELAY_LAPIC) += apic_timer.c romstage-$(CONFIG_UDELAY_LAPIC) += apic_timer.c ramstage-$(CONFIG_UDELAY_LAPIC) += apic_timer.c postcar-$(CONFIG_UDELAY_LAPIC) += apic_timer.c +# Use TSC for SMM, should be safer than LAPIC after OS takes over +smm-$(CONFIG_UDELAY_LAPIC) += ../tsc/delay_tsc.c + bootblock-y += boot_cpu.c verstage_x86-y += boot_cpu.c romstage-y += boot_cpu.c diff --git a/src/cpu/x86/tsc/delay_tsc.c b/src/cpu/x86/tsc/delay_tsc.c index 9607c2c6eb2..0a4b554c9ac 100644 --- a/src/cpu/x86/tsc/delay_tsc.c +++ b/src/cpu/x86/tsc/delay_tsc.c @@ -29,7 +29,7 @@ void udelay(unsigned int us) } } -#if CONFIG(TSC_MONOTONIC_TIMER) +#if CONFIG(TSC_MONOTONIC_TIMER) || (CONFIG(LAPIC_MONOTONIC_TIMER) && ENV_SMM) #include static struct monotonic_counter { From afc598efc66f4819aef061733213f6b92205a7b2 Mon Sep 17 00:00:00 2001 From: Krystian Hebel Date: Fri, 16 Sep 2022 13:44:52 +0200 Subject: [PATCH 05/11] cpu/amd/skinit: print MSRs connected with SMM Signed-off-by: Krystian Hebel --- src/cpu/amd/pi/skinit.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/cpu/amd/pi/skinit.c b/src/cpu/amd/pi/skinit.c index fb81e4e391f..cb36d10bbf3 100644 --- a/src/cpu/amd/pi/skinit.c +++ b/src/cpu/amd/pi/skinit.c @@ -5,6 +5,7 @@ #include #include #include +#include #include @@ -13,13 +14,10 @@ static uintptr_t payload_start, payload_size; /* For SELF, prog->start and prog->size are not set so obtain it differently. */ void platform_segment_loaded(uintptr_t start, size_t size, int flags) { - if (payload_start != 0 || payload_size != 0 || flags != SEG_FINAL) + /* FIXME: need to differentiate between payload and other loaded segments */ + if (/*payload_start != 0 || payload_size != 0 || */flags != SEG_FINAL) die("ELF payload must have only one loadable segment for DRTM!\n"); - /* SIPI vector loading also goes through this function, skip it. */ - if (size <= 4*KiB) - return; - payload_start = start; payload_size = size; } @@ -120,13 +118,27 @@ void platform_prog_run(struct prog *prog) sp->arg = (uint32_t)prog->arg; tags->size += sp->hdr.len; - /* TODO: DRTM TPM event log */ + /* TODO: DRTM TPM event log and SKL hash(es) */ end = next_tag(sp); end->type = SKL_TAG_END; end->len = sizeof(struct skl_tag_hdr); tags->size += end->len; + msr_t msr; + + msr = rdmsr(SMM_BASE_MSR); + printk(BIOS_DEBUG, "SMM_BASE_MSR = %#8.8x%8.8x\n", msr.hi, msr.lo); + + msr = rdmsr(SMM_ADDR_MSR); + printk(BIOS_DEBUG, "SMM_ADDR_MSR = %#8.8x%8.8x\n", msr.hi, msr.lo); + + msr = rdmsr(SMM_MASK_MSR); + printk(BIOS_DEBUG, "SMM_MASK_MSR = %#8.8x%8.8x\n", msr.hi, msr.lo); + + msr = rdmsr(HWCR_MSR); + printk(BIOS_DEBUG, "HWCR_MSR = %#8.8x%8.8x\n", msr.hi, msr.lo); + tis_close(); asm volatile ("skinit" :: "a"(skl)); From c7291af18f866880e558a29d16da7bb6fa80cc8c Mon Sep 17 00:00:00 2001 From: Krystian Hebel Date: Fri, 16 Sep 2022 14:50:50 +0200 Subject: [PATCH 06/11] amd/pi/00730F01: make changes required to start SMM in TSEG Signed-off-by: Krystian Hebel --- src/cpu/amd/pi/00730F01/model_16_init.c | 10 +- src/cpu/amd/pi/Kconfig | 13 +- src/northbridge/amd/pi/00730F01/northbridge.c | 5 + .../amd/pi/00730F01/state_machine.c | 4 +- src/southbridge/amd/pi/hudson/Makefile.inc | 1 + src/southbridge/amd/pi/hudson/hudson.c | 7 - src/southbridge/amd/pi/hudson/lpc_simpledev.c | 17 +++ src/southbridge/amd/pi/hudson/smi.c | 13 +- src/southbridge/amd/pi/hudson/smihandler.c | 128 +++--------------- src/southbridge/amd/pi/hudson/soc/acpi.h | 6 + src/southbridge/amd/pi/hudson/soc/nvs.h | 19 +++ src/southbridge/amd/pi/hudson/soc/smi.h | 34 +++++ .../amd/pi/hudson/soc/southbridge.h | 17 +++ src/vendorcode/amd/pi/Makefile.inc | 1 + 14 files changed, 141 insertions(+), 134 deletions(-) create mode 100644 src/southbridge/amd/pi/hudson/lpc_simpledev.c create mode 100644 src/southbridge/amd/pi/hudson/soc/acpi.h create mode 100644 src/southbridge/amd/pi/hudson/soc/nvs.h create mode 100644 src/southbridge/amd/pi/hudson/soc/southbridge.h diff --git a/src/cpu/amd/pi/00730F01/model_16_init.c b/src/cpu/amd/pi/00730F01/model_16_init.c index 1a9a2e3a639..dd568f9d915 100644 --- a/src/cpu/amd/pi/00730F01/model_16_init.c +++ b/src/cpu/amd/pi/00730F01/model_16_init.c @@ -43,10 +43,12 @@ static void model_16_init(struct device *dev) msr.hi &= ~(1 << (46 - 32)); wrmsr(NB_CFG_MSR, msr); - /* Write protect SMM space with SMMLOCK. */ - msr = rdmsr(HWCR_MSR); - msr.lo |= (1 << 0); - wrmsr(HWCR_MSR, msr); + /* Write protect SMM space with SMMLOCK, or let SMI handler do it if any. */ + if (!CONFIG(HAVE_SMI_HANDLER)) { + msr = rdmsr(HWCR_MSR); + msr.lo |= (1 << 0); + wrmsr(HWCR_MSR, msr); + } amd_update_microcode_from_cbfs(); diff --git a/src/cpu/amd/pi/Kconfig b/src/cpu/amd/pi/Kconfig index 1a4a05b7630..e457b64cbca 100644 --- a/src/cpu/amd/pi/Kconfig +++ b/src/cpu/amd/pi/Kconfig @@ -10,7 +10,11 @@ config CPU_AMD_PI select UDELAY_LAPIC select LAPIC_MONOTONIC_TIMER select SPI_FLASH if HAVE_ACPI_RESUME - select NO_SMM + select SMM_TSEG + select PARALLEL_MP_AP_WORK + select SOC_AMD_COMMON_BLOCK_SMM + select SOC_AMD_COMMON_BLOCK_SMI + select SOC_AMD_COMMON_BLOCK_ACPI select SSE2 if CPU_AMD_PI @@ -35,6 +39,13 @@ config DCACHE_BSP_STACK_SIZE hex default 0x4000 +config SMM_MODULE_STACK_SIZE + default 0x800 + +config SMM_TSEG_SIZE + default 0x100000 if HAVE_SMI_HANDLER + default 0 + config LAUNCH_DRTM_PAYLOAD bool "Launch DRTM payload before the real one" default n diff --git a/src/northbridge/amd/pi/00730F01/northbridge.c b/src/northbridge/amd/pi/00730F01/northbridge.c index 6c3d214aaaa..7942cd1697d 100644 --- a/src/northbridge/amd/pi/00730F01/northbridge.c +++ b/src/northbridge/amd/pi/00730F01/northbridge.c @@ -28,6 +28,8 @@ #include "mainboard/pcengines/apu2/bios_knobs.h" +#include + #define MAX_NODE_NUMS MAX_NODES #define PCIE_CAP_AER BIT(5) #define PCIE_CAP_ACS BIT(6) @@ -982,6 +984,9 @@ static int get_cpu_count(void) static const struct mp_ops mp_ops = { .pre_mp_init = pre_mp_init, .get_cpu_count = get_cpu_count, + .relocation_handler = smm_relocation_handler, + .get_smm_info = get_smm_info, + .post_mp_init = global_smi_enable, }; void mp_init_cpus(struct bus *cpu_bus) diff --git a/src/northbridge/amd/pi/00730F01/state_machine.c b/src/northbridge/amd/pi/00730F01/state_machine.c index 9215f7a86b3..7f20387d65e 100644 --- a/src/northbridge/amd/pi/00730F01/state_machine.c +++ b/src/northbridge/amd/pi/00730F01/state_machine.c @@ -32,9 +32,9 @@ void platform_AfterInitPost(struct sysinfo *cb, AMD_POST_PARAMS *Post) * UMA may or may not be cacheable, so Sub4GCacheTop could be * higher than UmaBase. With UMA_NONE we see UmaBase==0. */ if (Post->MemConfig.UmaBase) - backup_top_of_low_cacheable(Post->MemConfig.UmaBase << 16); + backup_top_of_low_cacheable((Post->MemConfig.UmaBase << 16) - CONFIG_SMM_TSEG_SIZE); else - backup_top_of_low_cacheable(Post->MemConfig.Sub4GCacheTop); + backup_top_of_low_cacheable(Post->MemConfig.Sub4GCacheTop - CONFIG_SMM_TSEG_SIZE); } void platform_BeforeInitEnv(struct sysinfo *cb, AMD_ENV_PARAMS *Env) diff --git a/src/southbridge/amd/pi/hudson/Makefile.inc b/src/southbridge/amd/pi/hudson/Makefile.inc index c3e9c76988d..aef5e8e4fb3 100644 --- a/src/southbridge/amd/pi/hudson/Makefile.inc +++ b/src/southbridge/amd/pi/hudson/Makefile.inc @@ -56,6 +56,7 @@ all-y += reset.c smm-y += smihandler.c smm-y += smi_util.c +smm-y += lpc_simpledev.c # ROMSIG At ROMBASE + 0x20000: # +-----------+---------------+----------------+------------+ diff --git a/src/southbridge/amd/pi/hudson/hudson.c b/src/southbridge/amd/pi/hudson/hudson.c index e9b26e0ad0d..4367d344513 100644 --- a/src/southbridge/amd/pi/hudson/hudson.c +++ b/src/southbridge/amd/pi/hudson/hudson.c @@ -17,13 +17,6 @@ #include "smi.h" #include "fchec.h" -int acpi_get_sleep_type(void) -{ - u16 tmp = inw(ACPI_PM1_CNT_BLK); - tmp = ((tmp & (7 << 10)) >> 10); - return (int)tmp; -} - void hudson_enable(struct device *dev) { printk(BIOS_DEBUG, "%s()\n", __func__); diff --git a/src/southbridge/amd/pi/hudson/lpc_simpledev.c b/src/southbridge/amd/pi/hudson/lpc_simpledev.c new file mode 100644 index 00000000000..7feedd27229 --- /dev/null +++ b/src/southbridge/amd/pi/hudson/lpc_simpledev.c @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include + +#include "hudson.h" +#include "pci_devs.h" + +uintptr_t lpc_get_spibase(void) +{ + u32 base; + + base = pci_read_config32(PCI_DEV(0, LPC_DEV, LPC_FUNC), + SPIROM_BASE_ADDRESS_REGISTER); + base &= 0xffffffc0; + return (uintptr_t)base; +} diff --git a/src/southbridge/amd/pi/hudson/smi.c b/src/southbridge/amd/pi/hudson/smi.c index 560b66679b5..193e64d2c84 100644 --- a/src/southbridge/amd/pi/hudson/smi.c +++ b/src/southbridge/amd/pi/hudson/smi.c @@ -4,16 +4,11 @@ * Utilities for SMM setup */ -#include +#include #include -#include "smi.h" - -/** Set the EOS bit and enable SMI generation from southbridge */ -void global_smi_enable(void) +void smm_region(uintptr_t *start, size_t *size) { - uint32_t reg = smi_read32(SMI_REG_SMITRIG0); - reg &= ~SMITRG0_SMIENB; /* Enable SMI generation */ - reg |= SMITRG0_EOS; /* Set EOS bit */ - smi_write32(SMI_REG_SMITRIG0, reg); + *start = (uintptr_t)cbmem_top(); + *size = CONFIG_SMM_TSEG_SIZE; } diff --git a/src/southbridge/amd/pi/hudson/smihandler.c b/src/southbridge/amd/pi/hudson/smihandler.c index a942c24adae..34105603db7 100644 --- a/src/southbridge/amd/pi/hudson/smihandler.c +++ b/src/southbridge/amd/pi/hudson/smihandler.c @@ -4,130 +4,36 @@ * SMI handler for Hudson southbridges */ -#include +#include +#include +#include #include #include -#include "hudson.h" -#include "smi.h" - -#define SMI_0x88_ACPI_COMMAND (1 << 11) - -enum smi_source { - SMI_SOURCE_SCI = (1 << 0), - SMI_SOURCE_GPE = (1 << 1), - SMI_SOURCE_0x84 = (1 << 2), - SMI_SOURCE_0x88 = (1 << 3), - SMI_SOURCE_IRQ_TRAP = (1 << 4), - SMI_SOURCE_0x90 = (1 << 5) -}; - -static void hudson_apmc_smi_handler(void) +static void fch_apmc_smi_handler(void) { - u32 reg32; - const uint8_t cmd = inb(ACPI_SMI_CTL_PORT); + const uint8_t cmd = inb(pm_acpi_smi_cmd_port()); switch (cmd) { - case ACPI_SMI_CMD_ENABLE: - reg32 = inl(ACPI_PM1_CNT_BLK); - reg32 |= (1 << 0); /* SCI_EN */ - outl(reg32, ACPI_PM1_CNT_BLK); - break; - case ACPI_SMI_CMD_DISABLE: - reg32 = inl(ACPI_PM1_CNT_BLK); - reg32 &= ~(1 << 0); /* clear SCI_EN */ - outl(ACPI_PM1_CNT_BLK, reg32); + case APM_CNT_SMMSTORE: + if (CONFIG(SMMSTORE)) + handle_smi_store(); break; } mainboard_smi_apmc(cmd); } -int southbridge_io_trap_handler(int smif) -{ - return 0; -} - -static void process_smi_sci(void) -{ - const uint32_t status = smi_read32(0x10); - - /* Clear events to prevent re-entering SMI if event isn't handled */ - smi_write32(0x10, status); -} - -static void process_gpe_smi(void) -{ - const uint32_t status = smi_read32(0x80); - const uint32_t gevent_mask = (1 << 24) - 1; - - /* Only Bits [23:0] indicate GEVENT SMIs. */ - if (status & gevent_mask) { - /* A GEVENT SMI occurred */ - mainboard_smi_gpi(status & gevent_mask); - } - - /* Clear events to prevent re-entering SMI if event isn't handled */ - smi_write32(0x80, status); -} - -static void process_smi_0x84(void) -{ - const uint32_t status = smi_read32(0x84); - - /* Clear events to prevent re-entering SMI if event isn't handled */ - smi_write32(0x84, status); -} - -static void process_smi_0x88(void) -{ - const uint32_t status = smi_read32(0x88); - - if (status & SMI_0x88_ACPI_COMMAND) { - /* Command received via ACPI SMI command port */ - hudson_apmc_smi_handler(); - } - /* Clear events to prevent re-entering SMI if event isn't handled */ - smi_write32(0x88, status); -} - -static void process_smi_0x8c(void) -{ - const uint32_t status = smi_read32(0x8c); - - /* Clear events to prevent re-entering SMI if event isn't handled */ - smi_write32(0x8c, status); -} - -static void process_smi_0x90(void) -{ - const uint32_t status = smi_read32(0x90); - - /* Clear events to prevent re-entering SMI if event isn't handled */ - smi_write32(0x90, status); -} +static const struct smi_sources_t smi_sources[] = { + { .type = SMITYPE_SMI_CMD_PORT, .handler = fch_apmc_smi_handler }, +}; -void southbridge_smi_handler(void) +void *get_smi_source_handler(int source) { - const uint16_t smi_src = smi_read16(0x94); - - if (smi_src & SMI_SOURCE_SCI) - process_smi_sci(); - if (smi_src & SMI_SOURCE_GPE) - process_gpe_smi(); - if (smi_src & SMI_SOURCE_0x84) - process_smi_0x84(); - if (smi_src & SMI_SOURCE_0x88) - process_smi_0x88(); - if (smi_src & SMI_SOURCE_IRQ_TRAP) - process_smi_0x8c(); - if (smi_src & SMI_SOURCE_0x90) - process_smi_0x90(); -} + size_t i; -void southbridge_smi_set_eos(void) -{ - uint32_t reg = smi_read32(SMI_REG_SMITRIG0); - reg |= SMITRG0_EOS; - smi_write32(SMI_REG_SMITRIG0, reg); + for (i = 0 ; i < ARRAY_SIZE(smi_sources) ; i++) + if (smi_sources[i].type == source) + return smi_sources[i].handler; + return NULL; } diff --git a/src/southbridge/amd/pi/hudson/soc/acpi.h b/src/southbridge/amd/pi/hudson/soc/acpi.h new file mode 100644 index 00000000000..80fcc9921ec --- /dev/null +++ b/src/southbridge/amd/pi/hudson/soc/acpi.h @@ -0,0 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef SOC_ACPI_H +#define SOC_ACPI_H + +#endif /* SOC_ACPI_H */ diff --git a/src/southbridge/amd/pi/hudson/soc/nvs.h b/src/southbridge/amd/pi/hudson/soc/nvs.h new file mode 100644 index 00000000000..c4db17e8db7 --- /dev/null +++ b/src/southbridge/amd/pi/hudson/soc/nvs.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef SOC_NVS_H +#define SOC_NVS_H + +struct __packed global_nvs { + // TODO + uint8_t rsv0; + uint8_t rsv1; + uint8_t rsv2; + uint32_t rsv3; + uint64_t pm1i; /* 0x07 - 0x0e - System Wake Source - PM1 Index */ + uint64_t gpei; /* 0x0f - 0x16 - GPE Wake Source */ + uint8_t rsv4; + uint8_t rsv5; + uint8_t rsv6; +}; + +#endif /* SOC_NVS_H */ diff --git a/src/southbridge/amd/pi/hudson/soc/smi.h b/src/southbridge/amd/pi/hudson/soc/smi.h index da5ddbc2f73..0ee3721c0f4 100644 --- a/src/southbridge/amd/pi/hudson/soc/smi.h +++ b/src/southbridge/amd/pi/hudson/soc/smi.h @@ -3,9 +3,43 @@ #ifndef SOC_SMI_H #define SOC_SMI_H +/* TODO: include Fch.h and use macros from there? */ + +#define SCI_GPES 32 +#define SCIMAPS 64 +#define SMI_GEVENTS 24 +#define NUMBER_SMITYPES 160 + +#define SMITYPE_SMI_CMD_PORT 0x4b + +#define SMI_EVENT_STATUS 0x00 #define SMI_SCI_TRIG 0x08 #define SMI_SCI_LEVEL 0x0c #define SMI_SCI_STATUS 0x10 #define SMI_SCI_EN 0x14 +#define SMI_SCI_MAP0 0x40 +#define SMI_SCI_MAP(X) (SMI_SCI_MAP0 + (X)) + +#define SMI_REG_SMISTS0 0x80 +#define GEVENT_MASK 0x00ffffff +#define SMI_REG_SMISTS1 0x84 +#define SMI_REG_SMISTS2 0x88 +#define SMI_REG_SMISTS3 0x8c +#define SMI_REG_SMISTS4 0x90 + +#define SMI_REG_POINTER 0x94 +#define SMI_STATUS_SRC_SCI (1 << 0) +#define SMI_STATUS_SRC_0 (1 << 1) +#define SMI_STATUS_SRC_1 (1 << 2) +#define SMI_STATUS_SRC_2 (1 << 3) +#define SMI_STATUS_SRC_3 (1 << 4) +#define SMI_STATUS_SRC_4 (1 << 5) + +#define SMI_REG_SMITRIG0 0x98 +#define SMITRG0_SMIENB (1 << 31) +#define SMITRG0_EOS (1 << 28) + +#define SMI_REG_CONTROL0 0xa0 + #endif /* SOC_SMI_H */ diff --git a/src/southbridge/amd/pi/hudson/soc/southbridge.h b/src/southbridge/amd/pi/hudson/soc/southbridge.h new file mode 100644 index 00000000000..bea21c50e38 --- /dev/null +++ b/src/southbridge/amd/pi/hudson/soc/southbridge.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef SOC_SOUTHBRIDGE_H +#define SOC_SOUTHBRIDGE_H + +#define PM1_LIMIT 16 +#define GPE0_LIMIT 32 +#define TOTAL_BITS(a) (8 * sizeof(a)) + +#define PM_ACPI_SMI_CMD 0x6a + +#define PWRBTN_STS (1 << 8) +#define RTC_STS (1 << 10) +#define PCIEXPWAK_STS (1 << 14) +#define WAK_STS (1 << 15) + +#endif /* SOC_SOUTHBRIDGE_H */ diff --git a/src/vendorcode/amd/pi/Makefile.inc b/src/vendorcode/amd/pi/Makefile.inc index 5b8d041afc2..9dcb6075d34 100644 --- a/src/vendorcode/amd/pi/Makefile.inc +++ b/src/vendorcode/amd/pi/Makefile.inc @@ -75,6 +75,7 @@ CC_bootblock := $(CC_bootblock) $(AGESA_INC) $(AGESA_CFLAGS) CC_romstage := $(CC_romstage) $(AGESA_INC) $(AGESA_CFLAGS) CC_postcar:= $(CC_postcar) -I$(src)/southbridge/amd/pi/hudson -I$(AGESA_ROOT)/binaryPI CC_ramstage := $(CC_ramstage) $(AGESA_INC) $(AGESA_CFLAGS) +CC_smm := $(CC_ramstage) $(AGESA_INC) $(AGESA_CFLAGS) CC_x86_32 := $(CC_x86_32) $(AGESA_INC) $(AGESA_CFLAGS) CC_x86_64 := $(CC_x86_64) $(AGESA_INC) $(AGESA_CFLAGS) From cdffa698726bbedf4c99b55b73631c28534c693e Mon Sep 17 00:00:00 2001 From: Krystian Hebel Date: Fri, 16 Sep 2022 14:52:40 +0200 Subject: [PATCH 07/11] mb/pcengines/apu2: changes required for SMMSTORE Signed-off-by: Krystian Hebel --- src/drivers/uart/uart8250io.c | 2 ++ src/mainboard/pcengines/apu2/Kconfig | 1 + src/mainboard/pcengines/apu2/Makefile.inc | 2 ++ src/mainboard/pcengines/apu2/board.fmd | 4 ++-- 4 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/drivers/uart/uart8250io.c b/src/drivers/uart/uart8250io.c index d8955779eeb..8dd7b773533 100644 --- a/src/drivers/uart/uart8250io.c +++ b/src/drivers/uart/uart8250io.c @@ -89,6 +89,8 @@ uintptr_t uart_platform_base(unsigned int idx) return 0; } +__weak int check_com2(void) { return 0; } + void uart_init(unsigned int idx) { if (!CONFIG(DRIVERS_UART_8250IO_SKIP_INIT)) { diff --git a/src/mainboard/pcengines/apu2/Kconfig b/src/mainboard/pcengines/apu2/Kconfig index 1316a90f93d..f2c733d8fbe 100644 --- a/src/mainboard/pcengines/apu2/Kconfig +++ b/src/mainboard/pcengines/apu2/Kconfig @@ -23,6 +23,7 @@ config BOARD_SPECIFIC_OPTIONS select PCIEXP_CLK_PM select PCIEXP_COMMON_CLOCK select PCIEXP_L1_SUB_STATE + select HAVE_SMI_HANDLER config MAINBOARD_DIR default "pcengines/apu2" diff --git a/src/mainboard/pcengines/apu2/Makefile.inc b/src/mainboard/pcengines/apu2/Makefile.inc index f69983fc18e..231997ad628 100644 --- a/src/mainboard/pcengines/apu2/Makefile.inc +++ b/src/mainboard/pcengines/apu2/Makefile.inc @@ -13,6 +13,8 @@ romstage-y += pmutil.c postcar-y += bios_knobs.c +smm-y += bios_knobs.c + ramstage-y += bios_knobs.c ramstage-y += BiosCallOuts.c ramstage-y += OemCustomize.c diff --git a/src/mainboard/pcengines/apu2/board.fmd b/src/mainboard/pcengines/apu2/board.fmd index 0f344e580ca..8414c9e7142 100644 --- a/src/mainboard/pcengines/apu2/board.fmd +++ b/src/mainboard/pcengines/apu2/board.fmd @@ -2,8 +2,8 @@ FLASH 8M { SI_BIOS@0x0 0x800000 { BOOTORDER(PRESERVE)@0x0 0x1000 RW_VPD(PRESERVE)@0x1000 0x4000 - SMMSTORE(PRESERVE)@0x5000 0x20000 - RW_UNUSED@0x25000 0x1db000 + SMMSTORE(PRESERVE)@0x10000 0x20000 + RW_UNUSED@0x30000 0x1d0000 WP_RO@0x200000 0x600000{ RO_VPD(PRESERVE)@0x0 0x4000 RO_SECTION@0x4000 0x5fc000{ From 77706e5c4a463064e98a725365f56b484a8089dd Mon Sep 17 00:00:00 2001 From: Krystian Hebel Date: Fri, 16 Sep 2022 16:45:29 +0200 Subject: [PATCH 08/11] mb/pcengines/apu2: make SMMSTORE bigger Signed-off-by: Krystian Hebel --- src/mainboard/pcengines/apu2/board.fmd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mainboard/pcengines/apu2/board.fmd b/src/mainboard/pcengines/apu2/board.fmd index 8414c9e7142..8e46bcc74b6 100644 --- a/src/mainboard/pcengines/apu2/board.fmd +++ b/src/mainboard/pcengines/apu2/board.fmd @@ -2,8 +2,8 @@ FLASH 8M { SI_BIOS@0x0 0x800000 { BOOTORDER(PRESERVE)@0x0 0x1000 RW_VPD(PRESERVE)@0x1000 0x4000 - SMMSTORE(PRESERVE)@0x10000 0x20000 - RW_UNUSED@0x30000 0x1d0000 + SMMSTORE(PRESERVE)@0x10000 0x40000 + RW_UNUSED@0x50000 0x1b0000 WP_RO@0x200000 0x600000{ RO_VPD(PRESERVE)@0x0 0x4000 RO_SECTION@0x4000 0x5fc000{ From 3abd33a7ffbfe0bf8145104d6098282603099e83 Mon Sep 17 00:00:00 2001 From: Krystian Hebel Date: Fri, 16 Sep 2022 16:59:54 +0200 Subject: [PATCH 09/11] mb/pcengines/apu2/bios_knobs.c: always enable IOMMU with DRTM payload Signed-off-by: Krystian Hebel --- src/mainboard/pcengines/apu2/Makefile.inc | 2 -- src/mainboard/pcengines/apu2/bios_knobs.c | 3 +++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/mainboard/pcengines/apu2/Makefile.inc b/src/mainboard/pcengines/apu2/Makefile.inc index 231997ad628..f69983fc18e 100644 --- a/src/mainboard/pcengines/apu2/Makefile.inc +++ b/src/mainboard/pcengines/apu2/Makefile.inc @@ -13,8 +13,6 @@ romstage-y += pmutil.c postcar-y += bios_knobs.c -smm-y += bios_knobs.c - ramstage-y += bios_knobs.c ramstage-y += BiosCallOuts.c ramstage-y += OemCustomize.c diff --git a/src/mainboard/pcengines/apu2/bios_knobs.c b/src/mainboard/pcengines/apu2/bios_knobs.c index 5ae0da8e3a5..736ccaed091 100644 --- a/src/mainboard/pcengines/apu2/bios_knobs.c +++ b/src/mainboard/pcengines/apu2/bios_knobs.c @@ -98,6 +98,9 @@ static u8 check_knob_value(const char *s) u8 check_iommu(void) { + if (CONFIG(LAUNCH_DRTM_PAYLOAD)) + return 1; + u8 iommu; iommu = check_knob_value("iommu"); From 11f4d864cdb191c8681d1e9ff8f0973dd53b14fd Mon Sep 17 00:00:00 2001 From: Krystian Hebel Date: Sun, 18 Sep 2022 13:42:30 +0200 Subject: [PATCH 10/11] configs/config.pcengines_apu2_drtm_payload: add file Signed-off-by: Krystian Hebel --- configs/config.pcengines_apu2_drtm_payload | 26 ++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 configs/config.pcengines_apu2_drtm_payload diff --git a/configs/config.pcengines_apu2_drtm_payload b/configs/config.pcengines_apu2_drtm_payload new file mode 100644 index 00000000000..8d2bfcda11b --- /dev/null +++ b/configs/config.pcengines_apu2_drtm_payload @@ -0,0 +1,26 @@ +CONFIG_LOCALVERSION="v4.9.0.4" +CONFIG_VENDOR_PCENGINES=y +CONFIG_FMDFILE="$(top)/src/mainboard/$(CONFIG_MAINBOARD_DIR)/board.fmd" +CONFIG_CONSOLE_CBMEM_BUFFER_SIZE=0x20000 +CONFIG_BOARD_PCENGINES_APU2=y +CONFIG_BOTTOMIO_POSITION=0xD0000000 +CONFIG_UART_PCI_ADDR=0x0 +CONFIG_LAUNCH_DRTM_PAYLOAD=y +CONFIG_HUDSON_SATA_MODE=2 +CONFIG_AGESA_BINARY_PI_LOCATION=0xFFE00000 +CONFIG_NO_GFX_INIT=y +CONFIG_SUBSYSTEM_VENDOR_ID=0x0000 +CONFIG_SUBSYSTEM_DEVICE_ID=0x0000 +CONFIG_I2C_TRANSFER_TIMEOUT_US=500000 +CONFIG_SMMSTORE_V2=y +CONFIG_SMMSTORE_SIZE=0x40000 +CONFIG_TPM2=y +CONFIG_POST_IO_PORT=0x80 +CONFIG_PAYLOAD_TIANOCORE=y +CONFIG_TIANOCORE_CUSTOM=y +CONFIG_TIANOCORE_REPOSITORY="https://github.com/3mdeb/edk2" +CONFIG_TIANOCORE_TAG_OR_REV="origin/drtm_payload" +CONFIG_TIANOCORE_DEBUG=y +CONFIG_TIANOCORE_CUSTOM_BUILD_PARAMS="-DSECURE_BOOT_ENABLE -DNETWORK_ENABLE" +CONFIG_SORTBOOTORDER_SECONDARY_PAYLOAD=y +CONFIG_SORTBOOTORDER_MASTER=y From eaff925a9d95c1cbf53fae9fef4ce86a86250342 Mon Sep 17 00:00:00 2001 From: Krystian Hebel Date: Fri, 30 Sep 2022 09:45:32 +0200 Subject: [PATCH 11/11] configs/config.pcengines_apu2_drtm_payload: enable UEFI shell, reduce log level Signed-off-by: Krystian Hebel --- configs/config.pcengines_apu2_drtm_payload | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/configs/config.pcengines_apu2_drtm_payload b/configs/config.pcengines_apu2_drtm_payload index 8d2bfcda11b..9cdec2c00ef 100644 --- a/configs/config.pcengines_apu2_drtm_payload +++ b/configs/config.pcengines_apu2_drtm_payload @@ -15,12 +15,13 @@ CONFIG_I2C_TRANSFER_TIMEOUT_US=500000 CONFIG_SMMSTORE_V2=y CONFIG_SMMSTORE_SIZE=0x40000 CONFIG_TPM2=y +CONFIG_DEFAULT_CONSOLE_LOGLEVEL_1=y CONFIG_POST_IO_PORT=0x80 CONFIG_PAYLOAD_TIANOCORE=y CONFIG_TIANOCORE_CUSTOM=y CONFIG_TIANOCORE_REPOSITORY="https://github.com/3mdeb/edk2" CONFIG_TIANOCORE_TAG_OR_REV="origin/drtm_payload" CONFIG_TIANOCORE_DEBUG=y -CONFIG_TIANOCORE_CUSTOM_BUILD_PARAMS="-DSECURE_BOOT_ENABLE -DNETWORK_ENABLE" +CONFIG_TIANOCORE_CUSTOM_BUILD_PARAMS="-DSECURE_BOOT_ENABLE -DNETWORK_ENABLE -DSHELL_TYPE=BUILD_SHELL -DSERIAL_TERMINAL=TRUE" CONFIG_SORTBOOTORDER_SECONDARY_PAYLOAD=y CONFIG_SORTBOOTORDER_MASTER=y