| /* @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(); |
| } |