Patrick Georgi | 593124d | 2020-05-10 19:44:08 +0200 | [diff] [blame] | 1 | /* SPDX-License-Identifier: BSD-2-Clause */ |
Eugene Myers | ae438be | 2020-01-21 17:01:47 -0500 | [diff] [blame] | 2 | |
| 3 | #include <stdint.h> |
| 4 | #include <security/intel/stm/StmApi.h> |
| 5 | #include <security/intel/stm/SmmStm.h> |
| 6 | #include <security/intel/stm/StmPlatformResource.h> |
| 7 | |
| 8 | #if CONFIG(SOUTHBRIDGE_INTEL_COMMON_PMCLIB) |
| 9 | #include <southbridge/intel/common/pmutil.h> |
| 10 | #else |
| 11 | #include <soc/pm.h> |
| 12 | #endif |
| 13 | #include <cpu/x86/msr.h> |
| 14 | #include <console/console.h> |
| 15 | |
| 16 | #define RDWR_ACCS 3 |
| 17 | #define FULL_ACCS 7 |
| 18 | |
| 19 | // Fixed memory ranges |
| 20 | // |
| 21 | // TSEG memory! |
| 22 | static STM_RSC_MEM_DESC rsc_tseg_memory = {{MEM_RANGE, sizeof(STM_RSC_MEM_DESC)}, |
| 23 | 0, |
| 24 | 0, |
| 25 | FULL_ACCS}; |
| 26 | |
| 27 | // Flash part |
| 28 | static STM_RSC_MEM_DESC rsc_spi_memory = { |
| 29 | {MEM_RANGE, sizeof(STM_RSC_MEM_DESC)}, |
| 30 | 0xFE000000, |
| 31 | 0x01000000, |
| 32 | FULL_ACCS}; |
| 33 | |
| 34 | // ACPI |
| 35 | static STM_RSC_IO_DESC rsc_pm_io = {{IO_RANGE, sizeof(STM_RSC_IO_DESC)}, 0, 128}; |
| 36 | |
| 37 | // PCIE MMIO |
| 38 | static STM_RSC_MMIO_DESC rsc_pcie_mmio = {{MMIO_RANGE, sizeof(STM_RSC_MMIO_DESC)}, |
| 39 | 0, |
| 40 | 0, // Length |
| 41 | RDWR_ACCS}; |
| 42 | |
| 43 | // Local APIC |
| 44 | static STM_RSC_MMIO_DESC rsc_apic_mmio = {{MMIO_RANGE, sizeof(STM_RSC_MMIO_DESC)}, |
| 45 | 0, |
| 46 | 0x400, |
| 47 | RDWR_ACCS}; |
| 48 | |
| 49 | // Software SMI |
| 50 | static STM_RSC_TRAPPED_IO_DESC rsc_sw_smi_trap_io = { |
| 51 | {TRAPPED_IO_RANGE, sizeof(STM_RSC_TRAPPED_IO_DESC)}, |
| 52 | 0xB2, |
| 53 | 2}; |
| 54 | |
| 55 | // End of list |
| 56 | static STM_RSC_END rsc_list_end __attribute__((used)) = { |
| 57 | {END_OF_RESOURCES, sizeof(STM_RSC_END)}, 0}; |
| 58 | |
| 59 | // Common PCI devices |
| 60 | // |
| 61 | // LPC bridge |
| 62 | STM_RSC_PCI_CFG_DESC rsc_lpc_bridge_pci = { |
| 63 | {PCI_CFG_RANGE, sizeof(STM_RSC_PCI_CFG_DESC)}, |
| 64 | RDWR_ACCS, |
| 65 | 0, |
| 66 | 0, |
| 67 | 0x1000, |
| 68 | 0, |
| 69 | 0, |
| 70 | { |
| 71 | {1, 1, sizeof(STM_PCI_DEVICE_PATH_NODE), LPC_FUNCTION, |
| 72 | LPC_DEVICE}, |
| 73 | }, |
| 74 | }; |
| 75 | |
| 76 | // Template for MSR resources. |
| 77 | STM_RSC_MSR_DESC rsc_msr_tpl = { |
| 78 | {MACHINE_SPECIFIC_REG, sizeof(STM_RSC_MSR_DESC)}, |
| 79 | }; |
| 80 | |
| 81 | // MSR indices to register |
| 82 | typedef struct { |
| 83 | uint32_t msr_index; |
| 84 | uint64_t read_mask; |
| 85 | uint64_t write_mask; |
| 86 | } MSR_TABLE_ENTRY; |
| 87 | |
| 88 | MSR_TABLE_ENTRY msr_table[] = { |
| 89 | // Index Read Write |
| 90 | // MASK64 means need access, MASK0 means no need access. |
| 91 | {SMRR_PHYSBASE_MSR, MASK64, MASK0}, |
| 92 | {SMRR_PHYSMASK_MSR, MASK64, MASK0}, |
| 93 | }; |
| 94 | |
| 95 | /* |
| 96 | * Fix up PCIE resource. |
| 97 | */ |
| 98 | static void fixup_pciex_resource(void) |
| 99 | { |
| 100 | // Find max bus number and PCIEX length |
Angel Pons | 9849488 | 2021-01-29 11:35:16 +0100 | [diff] [blame^] | 101 | rsc_pcie_mmio.length = CONFIG_MMCONF_LENGTH; // 0x10000000;// 256 MB |
Eugene Myers | ae438be | 2020-01-21 17:01:47 -0500 | [diff] [blame] | 102 | rsc_pcie_mmio.base = CONFIG_MMCONF_BASE_ADDRESS; |
| 103 | } |
| 104 | |
| 105 | /* |
| 106 | * Add basic resources to BIOS resource database. |
| 107 | */ |
| 108 | static void add_simple_resources(void) |
| 109 | { |
| 110 | int Status = 0; |
| 111 | msr_t ReadMsr; |
| 112 | |
| 113 | ReadMsr = rdmsr(SMRR_PHYSBASE_MSR); |
| 114 | rsc_tseg_memory.base = ReadMsr.lo & 0xFFFFF000; |
| 115 | |
| 116 | ReadMsr = rdmsr(SMRR_PHYSMASK_MSR); |
| 117 | rsc_tseg_memory.length = (~(ReadMsr.lo & 0xFFFFF000) + 1); |
| 118 | |
| 119 | rsc_pm_io.base = (uint16_t)get_pmbase(); |
| 120 | |
| 121 | // Local APIC. We assume that all thteads are programmed identically |
| 122 | // despite that it is possible to have individual APIC address for |
| 123 | // each of the threads. If this is the case this programming should |
| 124 | // be corrected. |
| 125 | ReadMsr = rdmsr(IA32_APIC_BASE_MSR_INDEX); |
| 126 | rsc_apic_mmio.base = ((uint64_t)ReadMsr.lo & 0xFFFFF000) | |
| 127 | ((uint64_t)(ReadMsr.hi & 0x0000000F) << 32); |
| 128 | |
| 129 | // PCIEX BAR |
| 130 | fixup_pciex_resource(); |
| 131 | |
| 132 | Status |= add_pi_resource((void *)&rsc_tseg_memory, 1); |
| 133 | Status |= add_pi_resource((void *)&rsc_spi_memory, 1); |
| 134 | |
| 135 | Status |= add_pi_resource((void *)&rsc_pm_io, 1); |
| 136 | Status |= add_pi_resource((void *)&rsc_pcie_mmio, 1); |
| 137 | Status |= add_pi_resource((void *)&rsc_apic_mmio, 1); |
| 138 | Status |= add_pi_resource((void *)&rsc_sw_smi_trap_io, 1); |
| 139 | |
| 140 | Status |= add_pi_resource((void *)&rsc_lpc_bridge_pci, 1); |
| 141 | |
| 142 | if (Status != 0) |
| 143 | printk(BIOS_DEBUG, "STM - Error in adding simple resources\n"); |
| 144 | } |
| 145 | |
| 146 | /* |
| 147 | * Add MSR resources to BIOS resource database. |
| 148 | */ |
| 149 | static void add_msr_resources(void) |
| 150 | { |
| 151 | uint32_t Status = 0; |
| 152 | uint32_t Index; |
| 153 | |
| 154 | for (Index = 0; Index < ARRAY_SIZE(msr_table); Index++) { |
| 155 | |
| 156 | rsc_msr_tpl.msr_index = (uint32_t)msr_table[Index].msr_index; |
| 157 | rsc_msr_tpl.read_mask = (uint64_t)msr_table[Index].read_mask; |
| 158 | rsc_msr_tpl.write_mask = (uint64_t)msr_table[Index].write_mask; |
| 159 | |
| 160 | Status |= add_pi_resource((void *)&rsc_msr_tpl, 1); |
| 161 | } |
| 162 | |
| 163 | if (Status != 0) |
| 164 | printk(BIOS_DEBUG, "STM - Error in adding MSR resources\n"); |
| 165 | } |
| 166 | |
| 167 | /* |
| 168 | * Add resources to BIOS resource database. |
| 169 | */ |
| 170 | void add_resources_cmd(void) |
| 171 | { |
| 172 | |
| 173 | add_simple_resources(); |
| 174 | |
| 175 | add_msr_resources(); |
| 176 | } |