/** @file This file contains the tests for the SecureMemoryMapConfiguration bit Copyright (c) 2017, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include "HstiSiliconDxe.h" typedef struct { UINT64 Base; UINT64 End; } MEMORY_RANGE; typedef enum { LockableMemoryRangeLtSpace, LockableMemoryRangeHighBios, LockableMemoryRangeLowDram, LockableMemoryRangeHighDram, LockableMemoryRangeMchBar, LockableMemoryRangeDmiBar, LockableMemoryRangePxpEpBar, LockableMemoryRangeGfxVtBar, LockableMemoryRangeVtdPvc0Bar, LockableMemoryRangeGdxcBar, LockableMemoryRangeEdramBar, LockableMemoryRangeCpuRsvd1Bar, LockableMemoryRangeCpuRsvd2Bar, LockableMemoryRangeMax, } LOCKABLE_MEMORY_RAMGE; MEMORY_RANGE mLockableMemoryRange[LockableMemoryRangeMax] = { // 1. LT space (0xFED20000 - 0xFED7FFFF) {0xFED20000, 0xFED7FFFF}, // 2. High BIOS {0x0, SIZE_4GB - 1}, // 3. Low DRAM (0 - TOLUD) {0x0, 0}, // 4. High DRAM (4GB - TOUUD) {SIZE_4GB, 0}, // 5. MCHBAR {0, 0}, // 6. DMIBAR {0, 0}, // 7. PXPEPBAR {0, 0}, // 8. GFXVTBAR {0, 0}, // 9. VTDPVC0BAR {0, 0}, // 10. GDXCBAR {0, 0}, // 11. EDRAMBAR (MCHBAR + 0x5408) {0, 0}, // 12. CPU Reserved space: 0xFEB00000 to 0xFEB0FFFF {0xFEB00000, 0xFEB0FFFF}, // 13. CPU Reserved space: 0xFEB80000 to 0xFEB8FFFF {0xFEB80000, 0xFEB8FFFF}, }; typedef enum { NonLockableMemoryRangeMBASE0, NonLockableMemoryRangePMBASE0, NonLockableMemoryRangePMBASEU0, NonLockableMemoryRangeMBASE1, NonLockableMemoryRangePMBASE1, NonLockableMemoryRangePMBASEU1, NonLockableMemoryRangeMBASE2, NonLockableMemoryRangePMBASE2, NonLockableMemoryRangePMBASEU2, NonLockableMemoryRangeGTTMMADR, NonLockableMemoryRangeGMADR, NonLockableMemoryRangeTMBAR, NonLockableMemoryRangeABAR, NonLockableMemoryRangeSBREG_BAR, NonLockableMemoryRangePWRMBASE, NonLockableMemoryRangeSPI_BAR0, NonLockableMemoryRangeMax, } NONLOCKABLE_MEMORY_RAMGE; MEMORY_RANGE mNonLockableMemoryRange[NonLockableMemoryRangeMax] = { {0, 0}, // 1. Local Apic for each CPU thread (IA32_APICBASE MSR 0x1B) // 2. MBASE0, (PEG) BDF 0:1:0 + 0x20 // 3. PMBASE0, (PEG) BDF 0:1:0 + 0x24 LOW // BDF 0:1:1 + 0x28 HIGH // 4. MBASE1, (PEG) BDF 0:1:1 + 0x20 // 5. PMBASE1, (PEG) BDF 0:1:1 + 0x24 LOW // BDF 0:1:1 + 0x28 HIGH // 6. MBASE2, (PEG) BDF 0:1:2 + 0x20 // 7. PMBASE2, (PEG) BDF 0:1:2 + 0x24 LOW // BDF 0:1:1 + 0x28 HIGH // 8. GTTMMADR, BDF 0:2:0 + 0x10 // 9. GMADR, BDF 0:2:0 + 0x18 (Need to account for MSAC) // 10. TMBAR, BDF 0:4:0 + 0x10 (if Device 4 is enabled in BDF 0:0:0 + 0x54[7]) // 11. ABAR, BDF 0:31:2 + 0x24 // 12. SBREG_BAR (BDF 0:31:1 + 0x10) // 13. PWRMBASE (BDF 0:31:2 + 0x48) // 14. SPI_BAR0 (BDF 0:31:5 + 0x10) }; /** Check for overlaps in single range array @param[in] Range - Pointer to Range array @param[in] Count - Number of Enties @retval BOOLEAN - Overlap Exists **/ BOOLEAN CheckOverlap ( IN MEMORY_RANGE *Range, IN UINTN Count ) { UINTN Index; UINTN SubIndex; for (Index = 0; Index < Count - 1; Index++) { if ((Range[Index].Base == 0) && (Range[Index].End == 0)) { continue; } for (SubIndex = Index + 1; SubIndex < Count; SubIndex++) { if ((Range[SubIndex].Base == 0) && (Range[SubIndex].End == 0)) { continue; } if (((Range[Index].Base >= Range[SubIndex].Base) && (Range[Index].Base <= Range[SubIndex].End)) || ((Range[SubIndex].Base >= Range[Index].Base) && (Range[SubIndex].Base <= Range[Index].End))) { DEBUG ((DEBUG_ERROR, "OVERLAP: \n")); DEBUG ((DEBUG_ERROR, " 0x%016lx - 0x%016lx\n", Range[Index].Base, Range[Index].End)); DEBUG ((DEBUG_ERROR, " 0x%016lx - 0x%016lx\n", Range[SubIndex].Base, Range[SubIndex].End)); return TRUE; } } } DEBUG ((DEBUG_INFO, "CheckOverlap: PASS\n")); return FALSE; } /** Check for overlaps between two arrays of memory ranges @param[in] Range1 - Pointer to Range1 array @param[in] Count1 - Number of Enties @param[in] Range2 - Pointer to Range2 array @param[in] Count2 - Number of Enties @retval BOOLEAN - Overlap Exists **/ BOOLEAN CheckOverlap2 ( IN MEMORY_RANGE *Range1, IN UINTN Count1, IN MEMORY_RANGE *Range2, IN UINTN Count2 ) { UINTN Index1; UINTN Index2; for (Index1 = 0; Index1 < Count1; Index1++) { if ((Range1[Index1].Base == 0) && (Range1[Index1].End == 0)) { continue; } for (Index2 = 0; Index2 < Count2; Index2++) { if ((Range2[Index2].Base == 0) && (Range2[Index2].End == 0)) { continue; } if (((Range1[Index1].Base >= Range2[Index2].Base) && (Range1[Index1].Base <= Range2[Index2].End)) || ((Range2[Index2].Base >= Range1[Index1].Base) && (Range2[Index2].Base <= Range1[Index1].End))) { DEBUG ((DEBUG_ERROR, "OVERLAP2: \n")); DEBUG ((DEBUG_ERROR, " 0x%016lx - 0x%016lx\n", Range1[Index1].Base, Range1[Index1].End)); DEBUG ((DEBUG_ERROR, " 0x%016lx - 0x%016lx\n", Range2[Index2].Base, Range2[Index2].End)); return TRUE; } } } DEBUG ((DEBUG_INFO, "CheckOverlap2: PASS\n")); return FALSE; } /** Dumps Ranges to Serial @param[in] Range - Pointer to Range array @param[in] Count - Number of Enties **/ VOID DumpRange ( IN MEMORY_RANGE *Range, IN UINTN Count ) { UINTN Index; for (Index = 0; Index < Count; Index ++) { DEBUG ((DEBUG_INFO, " [%02d] 0x%016lx - 0x%016lx\n", Index, Range[Index].Base, Range[Index].End)); } } // // mPchSpiResvMmioAddr keeps the reserved MMIO range assiged to SPI. // In SMM it always set back the reserved MMIO address to SPI BAR0 to ensure the MMIO range // won't overlap with SMRAM range, and trusted. // GLOBAL_REMOVE_IF_UNREFERENCED UINT32 mSpiResvMmioAddr; /** Acquire PCH spi mmio address. It is not expected for this BAR0 to change because the SPI device is hidden from the OS for SKL PCH LP/H B stepping and above (refer to section 3.5.1), but if it is ever different from the preallocated address, reassign it back. In SMM, it always override the BAR0 and returns the reserved MMIO range for SPI. @retval PchSpiBar0 return SPI MMIO address **/ UINTN AcquireSpiBar0 ( VOID ) { UINT32 SpiBar0; UINTN PchSpiBase; // // Init PCH spi reserved MMIO address. // mSpiResvMmioAddr = PCH_SPI_BASE_ADDRESS; PchSpiBase = MmPciBase ( DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_SPI, PCI_FUNCTION_NUMBER_PCH_SPI ); // // Save original SPI physical MMIO address // SpiBar0 = MmioRead32 (PchSpiBase + R_PCH_SPI_BAR0) & ~(B_PCH_SPI_BAR0_MASK); if (SpiBar0 != mSpiResvMmioAddr) { // // Temporary disable MSE, and override with SPI reserved MMIO address, then enable MSE. // MmioAnd8 (PchSpiBase + PCI_COMMAND_OFFSET, (UINT8) ~EFI_PCI_COMMAND_MEMORY_SPACE); MmioWrite32 (PchSpiBase + R_PCH_SPI_BAR0, mSpiResvMmioAddr); MmioOr8 (PchSpiBase + PCI_COMMAND_OFFSET, EFI_PCI_COMMAND_MEMORY_SPACE); } // // SPIBAR0 will be different before and after PCI enum so need to get it from SPI BAR0 reg. // return mSpiResvMmioAddr; } /** Release pch spi mmio address. Do nothing. @retval None **/ VOID ReleaseSpiBar0 ( VOID ) { } /** Get the SPI region base and size, based on the enum type @param[in] This Pointer to the PCH_SPI_PROTOCOL instance. @param[in] FlashRegionType The Flash Region type for for the base address which is listed in the Descriptor. @param[out] BaseAddress The Flash Linear Address for the Region 'n' Base @param[out] RegionSize The size for the Region 'n' @retval EFI_SUCCESS Read success @retval EFI_INVALID_PARAMETER Invalid region type given @retval EFI_DEVICE_ERROR The region is not used **/ EFI_STATUS EFIAPI GetRegionAddress ( IN FLASH_REGION_TYPE FlashRegionType, OUT UINT32 *BaseAddress, OUT UINT32 *RegionSize ) { UINTN PchSpiBar0; UINT32 ReadValue; if (FlashRegionType >= FlashRegionMax) { return EFI_INVALID_PARAMETER; } if (FlashRegionType == FlashRegionAll) { return EFI_UNSUPPORTED; } PchSpiBar0 = AcquireSpiBar0 (); ReadValue = MmioRead32 (PchSpiBar0 + (R_PCH_SPI_FREG0_FLASHD + (S_PCH_SPI_FREGX * ((UINT32) FlashRegionType)))); ReleaseSpiBar0 (); // // If the region is not used, the Region Base is 7FFFh and Region Limit is 0000h // if (ReadValue == B_PCH_SPI_FREGX_BASE_MASK) { return EFI_DEVICE_ERROR; } *BaseAddress = ((ReadValue & B_PCH_SPI_FREGX_BASE_MASK) >> N_PCH_SPI_FREGX_BASE) << N_PCH_SPI_FREGX_BASE_REPR; // // Region limit address Bits[11:0] are assumed to be FFFh // *RegionSize = ((((ReadValue & B_PCH_SPI_FREGX_LIMIT_MASK) >> N_PCH_SPI_FREGX_LIMIT) + 1) << N_PCH_SPI_FREGX_LIMIT_REPR) - *BaseAddress; return EFI_SUCCESS; } /** Run tests for SecureMemoryMapConfiguration bit **/ VOID CheckSecureMemoryMapConfiguration ( VOID ) { EFI_STATUS Status; BOOLEAN Result; UINT32 MchBar; UINT32 Dpr; UINT32 MeSegMask; UINT64 RemapBase; UINT64 RemapLimit; UINT32 Tom; UINT32 Touud; UINT32 Tolud; UINT64 Data64; UINT32 ApertureSize; UINT8 Msac; CHAR16 *HstiErrorString; UINT32 BarRead; UINT16 VendorIdRead; UINTN PchSpiBase; UINT32 PwrmBase; UINT32 AbarSize; UINT32 BaseAddress; UINT32 RegionSize; if ((mFeatureImplemented[1] & HSTI_BYTE1_SECURE_MEMORY_MAP_CONFIGURATION) == 0) { return; } Result = TRUE; MchBar = (UINT32) MmioRead64 (MmPciBase (DEFAULT_PCI_BUS_NUMBER_PCH,SA_MC_DEV,SA_MC_FUN) + R_SA_MCHBAR) & B_SA_MCHBAR_MCHBAR_MASK; DEBUG ((DEBUG_INFO, " Table 3-3. Memory Map Secure Configuration\n")); DEBUG ((DEBUG_INFO, " 1. DPR\n")); Dpr = MmioRead32 (MmPciBase (DEFAULT_PCI_BUS_NUMBER_PCH,SA_MC_DEV,SA_MC_FUN) + R_SA_DPR); if ((Dpr & B_SA_DPR_LOCK_MASK) == 0) { DEBUG ((DEBUG_INFO, "Fail: DPR not locked\n")); HstiErrorString = BuildHstiErrorString (HSTI_BYTE1_SECURE_MEMORY_MAP_CONFIGURATION_ERROR_CODE_1 ,HSTI_MEMORY_MAP_SECURITY_CONFIGURATION, HSTI_BYTE1_SECURE_MEMORY_MAP_CONFIGURATION_ERROR_STRING_1); Status = HstiLibAppendErrorString ( PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE, NULL, HstiErrorString ); ASSERT_EFI_ERROR (Status); Result = FALSE; FreePool (HstiErrorString); } DEBUG ((DEBUG_INFO, " 2. MESEG\n")); MeSegMask = MmioRead32 (MmPciBase (DEFAULT_PCI_BUS_NUMBER_PCH,SA_MC_DEV,SA_MC_FUN) + R_SA_MESEG_MASK); if ((MeSegMask & B_SA_MESEG_MASK_MELCK_MASK) == 0) { DEBUG ((DEBUG_INFO, "Fail: MESEG not locked\n")); HstiErrorString = BuildHstiErrorString (HSTI_BYTE1_SECURE_MEMORY_MAP_CONFIGURATION_ERROR_CODE_1 ,HSTI_MEMORY_MAP_SECURITY_CONFIGURATION, HSTI_BYTE1_SECURE_MEMORY_MAP_CONFIGURATION_ERROR_STRING_1); Status = HstiLibAppendErrorString ( PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE, NULL, HstiErrorString ); ASSERT_EFI_ERROR (Status); Result = FALSE; FreePool (HstiErrorString); } DEBUG ((DEBUG_INFO, " 3. REMAPBASE\n")); RemapBase = MmioRead64 (MmPciBase (0,SA_MC_DEV,SA_MC_FUN) + R_SA_REMAPBASE); if ((RemapBase & B_SA_REMAPBASE_LOCK_MASK) == 0) { DEBUG ((DEBUG_INFO, "Fail: REMAPBASE lock not set\n")); HstiErrorString = BuildHstiErrorString (HSTI_BYTE1_SECURE_MEMORY_MAP_CONFIGURATION_ERROR_CODE_1 ,HSTI_MEMORY_MAP_SECURITY_CONFIGURATION, HSTI_BYTE1_SECURE_MEMORY_MAP_CONFIGURATION_ERROR_STRING_1); Status = HstiLibAppendErrorString ( PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE, NULL, HstiErrorString ); ASSERT_EFI_ERROR (Status); Result = FALSE; FreePool (HstiErrorString); } DEBUG ((DEBUG_INFO, " 4. REMAPLIMIT\n")); RemapLimit = MmioRead64 (MmPciBase (0,SA_MC_DEV,SA_MC_FUN) + R_SA_REMAPLIMIT); if ((RemapLimit & B_SA_REMAPLIMIT_LOCK_MASK) == 0) { DEBUG ((DEBUG_INFO, "Fail: REMAPLIMIT lock not set\n")); HstiErrorString = BuildHstiErrorString (HSTI_BYTE1_SECURE_MEMORY_MAP_CONFIGURATION_ERROR_CODE_1 ,HSTI_MEMORY_MAP_SECURITY_CONFIGURATION, HSTI_BYTE1_SECURE_MEMORY_MAP_CONFIGURATION_ERROR_STRING_1); Status = HstiLibAppendErrorString ( PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE, NULL, HstiErrorString ); ASSERT_EFI_ERROR (Status); Result = FALSE; FreePool (HstiErrorString); } DEBUG ((DEBUG_INFO, " 5. Top Of Memory (TOM)\n")); Tom = MmioRead32 (MmPciBase (0,SA_MC_DEV,SA_MC_FUN) + R_SA_TOM); if ((Tom & B_SA_TOM_LOCK_MASK) == 0) { DEBUG ((DEBUG_INFO, "Fail: TOM lock not set\n")); HstiErrorString = BuildHstiErrorString (HSTI_BYTE1_SECURE_MEMORY_MAP_CONFIGURATION_ERROR_CODE_1 ,HSTI_MEMORY_MAP_SECURITY_CONFIGURATION, HSTI_BYTE1_SECURE_MEMORY_MAP_CONFIGURATION_ERROR_STRING_1); Status = HstiLibAppendErrorString ( PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE, NULL, HstiErrorString ); ASSERT_EFI_ERROR (Status); Result = FALSE; FreePool (HstiErrorString); } DEBUG ((DEBUG_INFO, " 6. Top Of Upper Usable DRAM (TOUUD)\n")); Touud = MmioRead32 (MmPciBase (0,SA_MC_DEV,SA_MC_FUN) + R_SA_TOUUD); if ((Touud & B_SA_TOUUD_LOCK_MASK) == 0) { DEBUG ((DEBUG_INFO, "Fail: TOUUD lock not set\n")); HstiErrorString = BuildHstiErrorString (HSTI_BYTE1_SECURE_MEMORY_MAP_CONFIGURATION_ERROR_CODE_1 ,HSTI_MEMORY_MAP_SECURITY_CONFIGURATION, HSTI_BYTE1_SECURE_MEMORY_MAP_CONFIGURATION_ERROR_STRING_1); Status = HstiLibAppendErrorString ( PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE, NULL, HstiErrorString ); ASSERT_EFI_ERROR (Status); Result = FALSE; FreePool (HstiErrorString); } DEBUG ((DEBUG_INFO, " 7. Top Of Lower Usable Memory (TOLUD)\n")); Tolud =MmioRead32 (MmPciBase (0,SA_MC_DEV,SA_MC_FUN) + R_SA_TOLUD); if ((Touud & B_SA_TOLUD_LOCK_MASK) == 0) { DEBUG ((DEBUG_INFO, "Fail: TOLUD lock not set\n")); HstiErrorString = BuildHstiErrorString (HSTI_BYTE1_SECURE_MEMORY_MAP_CONFIGURATION_ERROR_CODE_1 ,HSTI_MEMORY_MAP_SECURITY_CONFIGURATION, HSTI_BYTE1_SECURE_MEMORY_MAP_CONFIGURATION_ERROR_STRING_1); Status = HstiLibAppendErrorString ( PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE, NULL, HstiErrorString ); ASSERT_EFI_ERROR (Status); Result = FALSE; FreePool (HstiErrorString); } DEBUG ((DEBUG_INFO, " 8. Lockable/fixed memory ranges overlap\n")); // // Locate BIOS region size to update High bios base address // GetRegionAddress (FlashRegionBios, &BaseAddress, &RegionSize); DEBUG ((DEBUG_INFO, "Bios Region Size %x:\n", RegionSize)); mLockableMemoryRange[LockableMemoryRangeHighBios].Base = SIZE_4GB - RegionSize; mLockableMemoryRange[LockableMemoryRangeLowDram].End = (MmioRead32 (MmPciBase (0,SA_MC_DEV,SA_MC_FUN) + R_SA_TOLUD) & B_SA_TOLUD_TOLUD_MASK) - 1; mLockableMemoryRange[LockableMemoryRangeHighDram].End = (MmioRead64 (MmPciBase (0,SA_MC_DEV,SA_MC_FUN) + R_SA_TOUUD) & B_SA_TOUUD_TOUUD_MASK) - 1; mLockableMemoryRange[LockableMemoryRangeMchBar].Base = MmioRead64 (MmPciBase (0,SA_MC_DEV,SA_MC_FUN) + R_SA_MCHBAR) & B_SA_MCHBAR_MCHBAR_MASK; mLockableMemoryRange[LockableMemoryRangeMchBar].End = mLockableMemoryRange[LockableMemoryRangeMchBar].Base + SIZE_32KB - 1; mLockableMemoryRange[LockableMemoryRangeDmiBar].Base = MmioRead64 (MmPciBase (0,SA_MC_DEV,SA_MC_FUN) + R_SA_DMIBAR) & B_SA_DMIBAR_DMIBAR_MASK; mLockableMemoryRange[LockableMemoryRangeDmiBar].End = mLockableMemoryRange[LockableMemoryRangeDmiBar].Base + SIZE_4KB - 1; mLockableMemoryRange[LockableMemoryRangePxpEpBar].Base = MmioRead64 (MmPciBase (0,SA_MC_DEV,SA_MC_FUN) + R_SA_PXPEPBAR) & B_SA_PXPEPBAR_PXPEPBAR_MASK; mLockableMemoryRange[LockableMemoryRangePxpEpBar].End = mLockableMemoryRange[LockableMemoryRangePxpEpBar].Base + SIZE_4KB - 1; Data64 = MmioRead64 (MchBar + 0x5400); if ((Data64 & BIT0) != 0) { mLockableMemoryRange[LockableMemoryRangeGfxVtBar].Base = Data64 & 0x7FFFFFF000; mLockableMemoryRange[LockableMemoryRangeGfxVtBar].End = mLockableMemoryRange[LockableMemoryRangeGfxVtBar].Base + 0x1000 - 1; } Data64 = MmioRead64 (MchBar + 0x5410); if ((Data64 & BIT0) != 0) { mLockableMemoryRange[LockableMemoryRangeVtdPvc0Bar].Base = Data64 & 0x7FFFFFF000; mLockableMemoryRange[LockableMemoryRangeVtdPvc0Bar].End = mLockableMemoryRange[LockableMemoryRangeVtdPvc0Bar].Base + 0x1000 - 1; } Data64 = MmioRead64 (MchBar + 0x5420); if ((Data64 & BIT0) != 0) { mLockableMemoryRange[LockableMemoryRangeGdxcBar].Base = Data64 & 0x7FFFFFF000; mLockableMemoryRange[LockableMemoryRangeGdxcBar].End = mLockableMemoryRange[LockableMemoryRangeGdxcBar].Base + 0x1000 - 1; } Data64 = MmioRead64 (MchBar + 0x5408); if ((Data64 & BIT0) != 0) { mLockableMemoryRange[LockableMemoryRangeEdramBar].Base = Data64 & 0x7FFFFFC000; mLockableMemoryRange[LockableMemoryRangeEdramBar].End = mLockableMemoryRange[LockableMemoryRangeEdramBar].Base + 0x4000 - 1; } DEBUG ((DEBUG_INFO, "Lockable memory ranges:\n")); DumpRange (mLockableMemoryRange, LockableMemoryRangeMax); if (CheckOverlap (mLockableMemoryRange, LockableMemoryRangeMax) || EFI_ERROR (Status)) { HstiErrorString = BuildHstiErrorString (HSTI_BYTE1_SECURE_MEMORY_MAP_CONFIGURATION_ERROR_CODE_2 ,HSTI_MEMORY_MAP_SECURITY_CONFIGURATION, HSTI_BYTE1_SECURE_MEMORY_MAP_CONFIGURATION_ERROR_STRING_2); Status = HstiLibAppendErrorString ( PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE, NULL, HstiErrorString ); ASSERT_EFI_ERROR (Status); Result = FALSE; FreePool (HstiErrorString); } DEBUG ((DEBUG_INFO, " 9. Non lockable memory ranges overlap\n")); if (MmioRead32 (MmPciBase (0,0,0) + 0x54) & BIT3) { mNonLockableMemoryRange[NonLockableMemoryRangeMBASE0].Base = LShiftU64 ((MmioRead16 (MmPciBase (0,SA_PEG10_DEV_NUM,SA_PEG10_FUN_NUM) + 0x20) & 0xFFF0),16); mNonLockableMemoryRange[NonLockableMemoryRangeMBASE0].End = LShiftU64 ((MmioRead16 (MmPciBase (0,SA_PEG10_DEV_NUM,SA_PEG10_FUN_NUM) + 0x22) & 0xFFF0),16); BarRead = MmioRead16 (MmPciBase (0,SA_PEG10_DEV_NUM,SA_PEG10_FUN_NUM) + 0x24); if ((BarRead & 0xF) != 0) { mNonLockableMemoryRange[NonLockableMemoryRangePMBASE0].Base = LShiftU64 ((BarRead & 0xFFF0),16) + LShiftU64 ((MmioRead32 (MmPciBase (0,SA_PEG10_DEV_NUM,SA_PEG10_FUN_NUM) + 0x28)),32); } else { mNonLockableMemoryRange[NonLockableMemoryRangePMBASE0].Base = LShiftU64 ((BarRead & 0xFFF0),16); } BarRead = MmioRead16 (MmPciBase (0,SA_PEG10_DEV_NUM,SA_PEG10_FUN_NUM) + 0x26); if ((BarRead & 0xF) != 0) { mNonLockableMemoryRange[NonLockableMemoryRangePMBASE0].End = LShiftU64 ((BarRead & 0xFFF0),16) + LShiftU64 ((MmioRead32 (MmPciBase (0,SA_PEG10_DEV_NUM,SA_PEG10_FUN_NUM) + 0x2C)),32); } else { mNonLockableMemoryRange[NonLockableMemoryRangePMBASE0].End = LShiftU64 ((BarRead & 0xFFF0),16); } } // // Check to make sure that if PEG0 is enabled but nothing is connected that we ignore these ranges // if(mNonLockableMemoryRange[NonLockableMemoryRangeMBASE0].End < mNonLockableMemoryRange[NonLockableMemoryRangeMBASE0].Base) { mNonLockableMemoryRange[NonLockableMemoryRangeMBASE0].Base = 0; mNonLockableMemoryRange[NonLockableMemoryRangeMBASE0].End = 0; } if(mNonLockableMemoryRange[NonLockableMemoryRangePMBASE0].End < mNonLockableMemoryRange[NonLockableMemoryRangePMBASE0].Base) { mNonLockableMemoryRange[NonLockableMemoryRangePMBASE0].Base = 0; mNonLockableMemoryRange[NonLockableMemoryRangePMBASE0].End = 0; } if (MmioRead32 (MmPciBase (0,0,0) + 0x54) & BIT2) { mNonLockableMemoryRange[NonLockableMemoryRangeMBASE1].Base = LShiftU64 ((MmioRead16 (MmPciBase (DEFAULT_PCI_BUS_NUMBER_PCH,SA_PEG11_DEV_NUM,SA_PEG11_FUN_NUM) + 0x20) & 0xFFF0),16); mNonLockableMemoryRange[NonLockableMemoryRangeMBASE1].End = LShiftU64 ((MmioRead16 (MmPciBase (DEFAULT_PCI_BUS_NUMBER_PCH,SA_PEG11_DEV_NUM,SA_PEG11_FUN_NUM) + 0x22) & 0xFFF0),16); BarRead = MmioRead16 (MmPciBase (DEFAULT_PCI_BUS_NUMBER_PCH,SA_PEG11_DEV_NUM,SA_PEG11_FUN_NUM) + 0x24); if ((BarRead & 0xF) != 0) { mNonLockableMemoryRange[NonLockableMemoryRangePMBASE1].Base = LShiftU64 ((BarRead & 0xFFF0),16) + LShiftU64 ((MmioRead16 (MmPciBase (DEFAULT_PCI_BUS_NUMBER_PCH,SA_PEG11_DEV_NUM,SA_PEG11_FUN_NUM) + 0x28)),32); } else { mNonLockableMemoryRange[NonLockableMemoryRangePMBASE1].Base = LShiftU64 ((BarRead & 0xFFF0),16); } BarRead = MmioRead16 (MmPciBase (DEFAULT_PCI_BUS_NUMBER_PCH,SA_PEG11_DEV_NUM,SA_PEG11_FUN_NUM) + 0x26); if ((BarRead & 0xF) != 0) { mNonLockableMemoryRange[NonLockableMemoryRangePMBASE1].End = LShiftU64 ((BarRead & 0xFFF0),16) + LShiftU64 ((MmioRead16 (MmPciBase (DEFAULT_PCI_BUS_NUMBER_PCH,SA_PEG11_DEV_NUM,SA_PEG11_FUN_NUM) + 0x2C)),32); } else { mNonLockableMemoryRange[NonLockableMemoryRangePMBASE1].End = LShiftU64 ((BarRead & 0xFFF0),16); } } // // Check to make sure that if PEG1 is enabled but nothing is connected that we ignore these ranges // if(mNonLockableMemoryRange[NonLockableMemoryRangeMBASE1].End < mNonLockableMemoryRange[NonLockableMemoryRangeMBASE1].Base) { mNonLockableMemoryRange[NonLockableMemoryRangeMBASE1].Base = 0; mNonLockableMemoryRange[NonLockableMemoryRangeMBASE1].End = 0; } if(mNonLockableMemoryRange[NonLockableMemoryRangePMBASE1].End < mNonLockableMemoryRange[NonLockableMemoryRangePMBASE1].Base) { mNonLockableMemoryRange[NonLockableMemoryRangePMBASE1].Base = 0; mNonLockableMemoryRange[NonLockableMemoryRangePMBASE1].End = 0; } if (MmioRead32 (MmPciBase (0,0,0) + 0x54) & BIT1) { mNonLockableMemoryRange[NonLockableMemoryRangeMBASE2].Base = LShiftU64 ((MmioRead16 (MmPciBase (DEFAULT_PCI_BUS_NUMBER_PCH,SA_PEG12_DEV_NUM,SA_PEG12_FUN_NUM) + 0x20) & 0xFFF0),16); mNonLockableMemoryRange[NonLockableMemoryRangeMBASE2].End = LShiftU64 ((MmioRead16 (MmPciBase (DEFAULT_PCI_BUS_NUMBER_PCH,SA_PEG12_DEV_NUM,SA_PEG12_FUN_NUM) + 0x22) & 0xFFF0),16); BarRead = MmioRead16 (MmPciBase (DEFAULT_PCI_BUS_NUMBER_PCH,SA_PEG12_DEV_NUM,SA_PEG12_FUN_NUM) + 0x24); if ((BarRead & 0xF) != 0) { mNonLockableMemoryRange[NonLockableMemoryRangePMBASE2].Base = LShiftU64 ((BarRead & 0xFFF0),16) + LShiftU64 ((MmioRead16 (MmPciBase (DEFAULT_PCI_BUS_NUMBER_PCH,SA_PEG12_DEV_NUM,SA_PEG12_FUN_NUM) + 0x28)),32); } else { mNonLockableMemoryRange[NonLockableMemoryRangePMBASE2].Base = LShiftU64 ((BarRead & 0xFFF0),16); } BarRead = MmioRead16 (MmPciBase (DEFAULT_PCI_BUS_NUMBER_PCH,SA_PEG12_DEV_NUM,SA_PEG12_FUN_NUM) + 0x26); if ((BarRead & 0xF) != 0) { mNonLockableMemoryRange[NonLockableMemoryRangePMBASE2].End = LShiftU64 ((BarRead & 0xFFF0),16) + LShiftU64 ((MmioRead16 (MmPciBase (DEFAULT_PCI_BUS_NUMBER_PCH,SA_PEG12_DEV_NUM,SA_PEG12_FUN_NUM) + 0x2C)),32); } else { mNonLockableMemoryRange[NonLockableMemoryRangePMBASE2].End = LShiftU64 ((BarRead & 0xFFF0),16); } } // // Check to make sure that if PEG2 is enabled but nothing is connected that we ignore these ranges // if(mNonLockableMemoryRange[NonLockableMemoryRangeMBASE2].End < mNonLockableMemoryRange[NonLockableMemoryRangeMBASE2].Base) { mNonLockableMemoryRange[NonLockableMemoryRangeMBASE2].Base = 0; mNonLockableMemoryRange[NonLockableMemoryRangeMBASE2].End = 0; } if(mNonLockableMemoryRange[NonLockableMemoryRangePMBASE2].End < mNonLockableMemoryRange[NonLockableMemoryRangePMBASE2].Base) { mNonLockableMemoryRange[NonLockableMemoryRangePMBASE2].Base = 0; mNonLockableMemoryRange[NonLockableMemoryRangePMBASE2].End = 0; } if (MmioRead32 (MmPciBase (0,0,0) + 0x54) & BIT4) { mNonLockableMemoryRange[NonLockableMemoryRangeGTTMMADR].Base = (LShiftU64 (MmioRead32 (MmPciBase (DEFAULT_PCI_BUS_NUMBER_PCH,SA_IGD_DEV,SA_IGD_FUN_0) + R_SA_IGD_GTTMMADR + 4), 32) + \ (MmioRead32 (MmPciBase(DEFAULT_PCI_BUS_NUMBER_PCH,SA_IGD_DEV,SA_IGD_FUN_0) + R_SA_IGD_GTTMMADR))) & 0x7FFF000000; mNonLockableMemoryRange[NonLockableMemoryRangeGTTMMADR].End = mNonLockableMemoryRange[NonLockableMemoryRangeGTTMMADR].Base + SIZE_16MB - 1; Msac = MmioRead8 (MmPciBase (DEFAULT_PCI_BUS_NUMBER_PCH,SA_IGD_DEV,SA_MC_FUN) + R_SA_IGD_MSAC_OFFSET); ApertureSize = ((Msac & (BIT0 | BIT1 | BIT2 | BIT3 | BIT4)) + 1) * SIZE_128MB; mNonLockableMemoryRange[NonLockableMemoryRangeGMADR].Base = (LShiftU64 (MmioRead32 (MmPciBase (DEFAULT_PCI_BUS_NUMBER_PCH,SA_IGD_DEV,SA_IGD_FUN_0) + R_SA_IGD_GMADR + 4), 32) + \ (MmioRead32 (MmPciBase(DEFAULT_PCI_BUS_NUMBER_PCH,SA_IGD_DEV,SA_IGD_FUN_0) + R_SA_IGD_GMADR))) & 0x7FF8000000; mNonLockableMemoryRange[NonLockableMemoryRangeGMADR].End = mNonLockableMemoryRange[NonLockableMemoryRangeGMADR].Base + ApertureSize - 1; } if (MmioRead32 (MmPciBase (0,0,0) + 0x54) & BIT7) { mNonLockableMemoryRange[NonLockableMemoryRangeTMBAR].Base = MmioRead64 (MmPciBase (0,4,0) + 0x10) & 0x7FFFFF8000; mNonLockableMemoryRange[NonLockableMemoryRangeTMBAR].End = mNonLockableMemoryRange[NonLockableMemoryRangeTMBAR].Base + SIZE_32KB-1; } VendorIdRead = MmioRead16 (MmPciBase (DEFAULT_PCI_BUS_NUMBER_PCH,PCI_DEVICE_NUMBER_PCH_SATA,PCI_FUNCTION_NUMBER_PCH_SATA) +0); DEBUG ((DEBUG_INFO, "VendorIdRead SATA: %x\n",VendorIdRead)); if (VendorIdRead != 0xFFFF) { BarRead = MmioRead32 (MmPciBase (DEFAULT_PCI_BUS_NUMBER_PCH,PCI_DEVICE_NUMBER_PCH_SATA,PCI_FUNCTION_NUMBER_PCH_SATA) + R_PCH_SATA_SATAGC); if ((BarRead & BIT10) == 0 ) { mNonLockableMemoryRange[NonLockableMemoryRangeABAR].Base = MmioRead32 (MmPciBase (DEFAULT_PCI_BUS_NUMBER_PCH,PCI_DEVICE_NUMBER_PCH_SATA,PCI_FUNCTION_NUMBER_PCH_SATA) + R_PCH_SATA_AHCI_BAR) & 0xFFFFF800; switch (BarRead & 0x7) { case V_PCH_SATA_SATAGC_ASSEL_2K: AbarSize = SIZE_2KB; break; case V_PCH_SATA_SATAGC_ASSEL_16K: AbarSize = SIZE_16KB; break; case V_PCH_SATA_SATAGC_ASSEL_32K: AbarSize = SIZE_32KB; break; case V_PCH_SATA_SATAGC_ASSEL_64K: AbarSize = SIZE_64KB; break; case V_PCH_SATA_SATAGC_ASSEL_128K: AbarSize = SIZE_128KB; break; case V_PCH_SATA_SATAGC_ASSEL_512K: AbarSize = SIZE_256KB; break; default: AbarSize= SIZE_2KB; break; } mNonLockableMemoryRange[NonLockableMemoryRangeABAR].End = mNonLockableMemoryRange[NonLockableMemoryRangeABAR].Base + AbarSize - 1; } } mNonLockableMemoryRange[NonLockableMemoryRangeSBREG_BAR].Base = PCH_PCR_BASE_ADDRESS; mNonLockableMemoryRange[NonLockableMemoryRangeSBREG_BAR].End = PCH_PCR_BASE_ADDRESS + SIZE_16MB-1; PchPwrmBaseGet (&PwrmBase); mNonLockableMemoryRange[NonLockableMemoryRangePWRMBASE].Base = PwrmBase; mNonLockableMemoryRange[NonLockableMemoryRangePWRMBASE].End = PwrmBase + PCH_PWRM_MMIO_SIZE - 1; PchSpiBase = MmioRead32 (MmPciBase ( DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_SPI, PCI_FUNCTION_NUMBER_PCH_SPI) + R_PCH_SPI_BAR0) & ~B_PCH_SPI_BAR0_MASK; mNonLockableMemoryRange[NonLockableMemoryRangeSPI_BAR0].Base = PchSpiBase; mNonLockableMemoryRange[NonLockableMemoryRangeSPI_BAR0].End = PchSpiBase + SIZE_4KB-1; DEBUG ((DEBUG_INFO, "Non lockable memory ranges:\n")); DumpRange (mNonLockableMemoryRange, NonLockableMemoryRangeMax); if (CheckOverlap (mNonLockableMemoryRange, NonLockableMemoryRangeMax) || CheckOverlap2 (mLockableMemoryRange, LockableMemoryRangeMax, mNonLockableMemoryRange, NonLockableMemoryRangeMax)) { HstiErrorString = BuildHstiErrorString (HSTI_BYTE1_SECURE_MEMORY_MAP_CONFIGURATION_ERROR_CODE_3 ,HSTI_MEMORY_MAP_SECURITY_CONFIGURATION, HSTI_BYTE1_SECURE_MEMORY_MAP_CONFIGURATION_ERROR_STRING_3); Status = HstiLibAppendErrorString ( PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE, NULL, HstiErrorString ); ASSERT_EFI_ERROR (Status); Result = FALSE; FreePool (HstiErrorString); } // // ALL PASS // if (Result) { Status = HstiLibSetFeaturesVerified ( PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE, NULL, 1, HSTI_BYTE1_SECURE_MEMORY_MAP_CONFIGURATION ); ASSERT_EFI_ERROR (Status); } return; }