aboutsummaryrefslogtreecommitdiff
path: root/src/security/intel/stm/StmPlatformResource.c
diff options
context:
space:
mode:
authorEugene Myers <edmyers@tycho.nsa.gov>2020-01-21 17:01:47 -0500
committerPatrick Georgi <pgeorgi@google.com>2020-02-05 18:49:27 +0000
commitae438be57856e994774ec0e2521d49f1ad09bd6f (patch)
treeb174c6b496de3524bca2dd027c686fa5c9b5bd8b /src/security/intel/stm/StmPlatformResource.c
parentd498e52c3f024971f342da9029fd7f11668c0a3d (diff)
security/intel/stm: Add STM support
This update is a combination of all four of the patches so that the commit can be done without breaking parts of coreboot. This possible breakage is because of the cross-dependencies between the original separate patches would cause failure because of data structure changes. security/intel/stm This directory contains the functions that check and move the STM to the MSEG, create its page tables, and create the BIOS resource list. The STM page tables is a six page region located in the MSEG and are pointed to by the CR3 Offset field in the MSEG header. The initial page tables will identity map all memory between 0-4G. The STM starts in IA32e mode, which requires page tables to exist at startup. The BIOS resource list defines the resources that the SMI Handler is allowed to access. This includes the SMM memory area where the SMI handler resides and other resources such as I/O devices. The STM uses the BIOS resource list to restrict the SMI handler's accesses. The BIOS resource list is currently located in the same area as the SMI handler. This location is shown in the comment section before smm_load_module in smm_module_loader.c Note: The files within security/intel/stm come directly from their Tianocore counterparts. Unnecessary code has been removed and the remaining code has been converted to meet coreboot coding requirements. For more information see: SMI Transfer Monitor (STM) User Guide, Intel Corp., August 2015, Rev 1.0, can be found at firmware.intel.com include/cpu/x86: Addtions to include/cpu/x86 for STM support. cpu/x86: STM Set up - The STM needs to be loaded into the MSEG during BIOS initialization and the SMM Monitor Control MSR be set to indicate that an STM is in the system. cpu/x86/smm: SMI module loader modifications needed to set up the SMM descriptors used by the STM during its initialization Change-Id: If4adcd92c341162630ce1ec357ffcf8a135785ec Signed-off-by: Eugene D. Myers <edmyers@tycho.nsa.gov> Reviewed-on: https://review.coreboot.org/c/coreboot/+/33234 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Patrick Georgi <pgeorgi@google.com> Reviewed-by: ron minnich <rminnich@gmail.com>
Diffstat (limited to 'src/security/intel/stm/StmPlatformResource.c')
-rw-r--r--src/security/intel/stm/StmPlatformResource.c188
1 files changed, 188 insertions, 0 deletions
diff --git a/src/security/intel/stm/StmPlatformResource.c b/src/security/intel/stm/StmPlatformResource.c
new file mode 100644
index 0000000000..6fef515052
--- /dev/null
+++ b/src/security/intel/stm/StmPlatformResource.c
@@ -0,0 +1,188 @@
+/* @file
+ * STM platform SMM resource
+ *
+ * Copyright (c) 2015, Intel Corporation. All rights reserved.
+ * This program and the accompanying materials are licensed and made
+ * available under the terms and conditions of the BSD License which
+ * accompanies this distribution. The full text of the license may be found
+ * at http://opensource.org/licenses/bsd-license.php.
+ *
+ * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR
+ * IMPLIED.
+ */
+
+#include <stdint.h>
+#include <security/intel/stm/StmApi.h>
+#include <security/intel/stm/SmmStm.h>
+#include <security/intel/stm/StmPlatformResource.h>
+
+#if CONFIG(SOUTHBRIDGE_INTEL_COMMON_PMCLIB)
+#include <southbridge/intel/common/pmutil.h>
+#else
+#include <soc/pm.h>
+#endif
+#include <cpu/x86/msr.h>
+#include <console/console.h>
+
+#define RDWR_ACCS 3
+#define FULL_ACCS 7
+
+// Fixed memory ranges
+//
+// TSEG memory!
+static STM_RSC_MEM_DESC rsc_tseg_memory = {{MEM_RANGE, sizeof(STM_RSC_MEM_DESC)},
+ 0,
+ 0,
+ FULL_ACCS};
+
+// Flash part
+static STM_RSC_MEM_DESC rsc_spi_memory = {
+ {MEM_RANGE, sizeof(STM_RSC_MEM_DESC)},
+ 0xFE000000,
+ 0x01000000,
+ FULL_ACCS};
+
+// ACPI
+static STM_RSC_IO_DESC rsc_pm_io = {{IO_RANGE, sizeof(STM_RSC_IO_DESC)}, 0, 128};
+
+// PCIE MMIO
+static STM_RSC_MMIO_DESC rsc_pcie_mmio = {{MMIO_RANGE, sizeof(STM_RSC_MMIO_DESC)},
+ 0,
+ 0, // Length
+ RDWR_ACCS};
+
+// Local APIC
+static STM_RSC_MMIO_DESC rsc_apic_mmio = {{MMIO_RANGE, sizeof(STM_RSC_MMIO_DESC)},
+ 0,
+ 0x400,
+ RDWR_ACCS};
+
+// Software SMI
+static STM_RSC_TRAPPED_IO_DESC rsc_sw_smi_trap_io = {
+ {TRAPPED_IO_RANGE, sizeof(STM_RSC_TRAPPED_IO_DESC)},
+ 0xB2,
+ 2};
+
+// End of list
+static STM_RSC_END rsc_list_end __attribute__((used)) = {
+ {END_OF_RESOURCES, sizeof(STM_RSC_END)}, 0};
+
+// Common PCI devices
+//
+// LPC bridge
+STM_RSC_PCI_CFG_DESC rsc_lpc_bridge_pci = {
+ {PCI_CFG_RANGE, sizeof(STM_RSC_PCI_CFG_DESC)},
+ RDWR_ACCS,
+ 0,
+ 0,
+ 0x1000,
+ 0,
+ 0,
+ {
+ {1, 1, sizeof(STM_PCI_DEVICE_PATH_NODE), LPC_FUNCTION,
+ LPC_DEVICE},
+ },
+};
+
+// Template for MSR resources.
+STM_RSC_MSR_DESC rsc_msr_tpl = {
+ {MACHINE_SPECIFIC_REG, sizeof(STM_RSC_MSR_DESC)},
+};
+
+// MSR indices to register
+typedef struct {
+ uint32_t msr_index;
+ uint64_t read_mask;
+ uint64_t write_mask;
+} MSR_TABLE_ENTRY;
+
+MSR_TABLE_ENTRY msr_table[] = {
+ // Index Read Write
+ // MASK64 means need access, MASK0 means no need access.
+ {SMRR_PHYSBASE_MSR, MASK64, MASK0},
+ {SMRR_PHYSMASK_MSR, MASK64, MASK0},
+};
+
+/*
+ * Fix up PCIE resource.
+ */
+static void fixup_pciex_resource(void)
+{
+ // Find max bus number and PCIEX length
+ rsc_pcie_mmio.length = CONFIG_SA_PCIEX_LENGTH; // 0x10000000;// 256 MB
+ rsc_pcie_mmio.base = CONFIG_MMCONF_BASE_ADDRESS;
+}
+
+/*
+ * Add basic resources to BIOS resource database.
+ */
+static void add_simple_resources(void)
+{
+ int Status = 0;
+ msr_t ReadMsr;
+
+ ReadMsr = rdmsr(SMRR_PHYSBASE_MSR);
+ rsc_tseg_memory.base = ReadMsr.lo & 0xFFFFF000;
+
+ ReadMsr = rdmsr(SMRR_PHYSMASK_MSR);
+ rsc_tseg_memory.length = (~(ReadMsr.lo & 0xFFFFF000) + 1);
+
+ rsc_pm_io.base = (uint16_t)get_pmbase();
+
+ // Local APIC. We assume that all thteads are programmed identically
+ // despite that it is possible to have individual APIC address for
+ // each of the threads. If this is the case this programming should
+ // be corrected.
+ ReadMsr = rdmsr(IA32_APIC_BASE_MSR_INDEX);
+ rsc_apic_mmio.base = ((uint64_t)ReadMsr.lo & 0xFFFFF000) |
+ ((uint64_t)(ReadMsr.hi & 0x0000000F) << 32);
+
+ // PCIEX BAR
+ fixup_pciex_resource();
+
+ Status |= add_pi_resource((void *)&rsc_tseg_memory, 1);
+ Status |= add_pi_resource((void *)&rsc_spi_memory, 1);
+
+ Status |= add_pi_resource((void *)&rsc_pm_io, 1);
+ Status |= add_pi_resource((void *)&rsc_pcie_mmio, 1);
+ Status |= add_pi_resource((void *)&rsc_apic_mmio, 1);
+ Status |= add_pi_resource((void *)&rsc_sw_smi_trap_io, 1);
+
+ Status |= add_pi_resource((void *)&rsc_lpc_bridge_pci, 1);
+
+ if (Status != 0)
+ printk(BIOS_DEBUG, "STM - Error in adding simple resources\n");
+}
+
+/*
+ * Add MSR resources to BIOS resource database.
+ */
+static void add_msr_resources(void)
+{
+ uint32_t Status = 0;
+ uint32_t Index;
+
+ for (Index = 0; Index < ARRAY_SIZE(msr_table); Index++) {
+
+ rsc_msr_tpl.msr_index = (uint32_t)msr_table[Index].msr_index;
+ rsc_msr_tpl.read_mask = (uint64_t)msr_table[Index].read_mask;
+ rsc_msr_tpl.write_mask = (uint64_t)msr_table[Index].write_mask;
+
+ Status |= add_pi_resource((void *)&rsc_msr_tpl, 1);
+ }
+
+ if (Status != 0)
+ printk(BIOS_DEBUG, "STM - Error in adding MSR resources\n");
+}
+
+/*
+ * Add resources to BIOS resource database.
+ */
+void add_resources_cmd(void)
+{
+
+ add_simple_resources();
+
+ add_msr_resources();
+}