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