/** @file The CPU specific programming for PiSmmCpuDxeSmm module. @copyright INTEL CONFIDENTIAL Copyright 2010 - 2020 Intel Corporation. The source code contained or described herein and all documents related to the source code ("Material") are owned by Intel Corporation or its suppliers or licensors. Title to the Material remains with Intel Corporation or its suppliers and licensors. The Material may contain trade secrets and proprietary and confidential information of Intel Corporation and its suppliers and licensors, and is protected by worldwide copyright and trade secret laws and treaty provisions. No part of the Material may be used, copied, reproduced, modified, published, uploaded, posted, transmitted, distributed, or disclosed in any way without Intel's prior express written permission. No license under any patent, copyright, trade secret or other intellectual property right is granted to or conferred upon you by disclosure or delivery of the Materials, either expressly, by implication, inducement, estoppel or otherwise. Any license under such intellectual property rights must be express and approved by Intel in writing. Unless otherwise agreed by Intel in writing, you may not remove or alter this notice or any other notice embedded in Materials by Intel or Intel's suppliers or licensors in any way. This file contains an 'Intel Peripheral Driver' and is uniquely identified as "Intel Reference Module" and is licensed for Intel CPUs and chipsets under the terms of your license agreement with Intel or your vendor. This file may be modified by the user, subject to additional terms of the license agreement. @par Specification Reference: **/ #ifndef __SMM_FEATURES_H__ #define __SMM_FEATURES_H__ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "SmmPpam.h" #include "SmmSps.h" #define SUPERVISOR_PAGE_NUM 2 #define PROTECT_MODE_CS 0x8 #define SMMSEG_PROTECT_MODE_CS 0x10 #define SMMSEG_PROTECT_MODE_DS 0x18 #define PROTECT_MODE_DS 0x20 #define REAL_MODE_CS 0x28 #define REAL_MODE_DS 0x30 #define LONG_MODE_CS 0x38 #define LONG_MODE_DS 0x40 #define R3_CS_32 0x48 #define R3_DS_32 0x50 #define R3_CS 0x58 #define R3_DS 0x60 #define TSS_SEGMENT 0x70 // // CET definition // #define CPUID_CET_SS BIT7 #define CPUID_CET_IBT BIT20 #define CR4_CET_ENABLE BIT23 #define CPUID1_EDX_XD_SUPPORT 0x100000 #define CR0_WP BIT16 // // Define for Protected Mode SMM Entry Template // #define SMMSEG_PROTECT_MODE_CODE_SEGMENT 0x10 #pragma pack(1) typedef struct { UINT16 Limit; UINT32 Base; } IA32_PROT_DESCRIPTOR; #pragma pack() //////// // Below section is definition for CPU SMM Feature context //////// // // Structure to describe CPU_SMM_FEATURE_CONTEXT // typedef struct { BOOLEAN SmrrEnabled; BOOLEAN Smrr2Enabled; } CPU_SMM_FEATURE_CONTEXT; // // SMMSEG_FEATURE_ENABLES bitmap // #define SMMSEG_FEATURE_ENABLE BIT0 #define SMMSEG_FEATURE_CR4_MCE_CTL_ENABLE BIT1 // // Structure to describe CPU SMM Protected Mode // typedef struct { UINT32 Reserved1; UINT32 SmmSegFeatureEnables; // SMM_SEG_FEATURE_ENABLES UINT32 GDTRLimit; UINT32 GDTRBaseOffset; UINT32 CSSelector; UINT32 Reserved3; UINT32 ESPOffset; UINT32 Reserved4; UINT32 IDTRLimit; UINT32 IDTRBaseOffset; } SMMSEG; #define SMM_PROT_MODE_GDT_ENTRY_COUNT 27 // // SMM PROT MODE CONTEXT (total 0x100 bytes) // typedef struct { SMMSEG SmmProtectedModeSMMSEG; // 40 bytes IA32_SEGMENT_DESCRIPTOR SmmProtectedModeGdt[SMM_PROT_MODE_GDT_ENTRY_COUNT]; // 27 * 8 = 216 bytes } SMM_PROT_MODE_CONTEXT; // // SMM CPU synchronization features available on a processor // typedef struct { BOOLEAN TargetedSmiSupported; BOOLEAN DelayIndicationSupported; BOOLEAN BlockIndicationSupported; // // This processor's LOG_PROC_EN bit used in SMM_ENABLE, SMM_DELAYED, and SMM_BLOCKED MSRs // (introduced in Haswell processor). // Value of "-1" indicates this field is invalid (i.e. LOG_PROC_EN bit is not // supported) // UINT64 HaswellLogProcEnBit; } SMM_CPU_SYNC_FEATURE; /// /// /// extern BOOLEAN mSaveStateInMsr; extern BOOLEAN mSmmInitSaveStateInMsr; extern UINT8 mSmmFeatureSaveStateRegisterLma; extern SPIN_LOCK *mMsrSpinLock; extern BOOLEAN mSmmPpamEnable; extern BOOLEAN mSmmProcTraceEnable; extern UINT64 gSmmSupovrStateLockData; /** Read MSR or CSR based on the CPU type Register to read. NOTE: Since platform may uses I/O ports 0xCF8 and 0xCFC to access CSR, we need to use SPIN_LOCK to avoid collision on MP System. @param[in] CpuIndex The processor index. @param[in] RegName Register name. @return 64-bit value read from register. **/ UINT64 SmmReadReg64 ( IN UINTN CpuIndex, IN SMM_REG_NAME RegName ); /** Write MSR or CSR based on the CPU type Register to write. NOTE: Since platform may uses I/O ports 0xCF8 and 0xCFC to access CSR, we need to use SPIN_LOCK to avoid collision on MP System. @param[in] CpuIndex The processor index. @param[in] RegName Register name. @param[in] RegValue 64-bit Register value. **/ VOID SmmWriteReg64 ( IN UINTN CpuIndex, IN SMM_REG_NAME RegName, IN UINT64 RegValue ); /** Initialize SMM Protected Mode IDT table. @param[in] Cr3 CR3 value. **/ VOID InitProtectedModeIdt ( IN UINT32 Cr3 ); /** Allocate pages for code. @param[in] Pages Number of pages to be allocated. @return Allocated memory. **/ VOID * SmmFeatureAllocateCodePages ( IN UINTN Pages ); /** This function sets SmmSupovrStateLock MSR. NOTE: This function does not take effect before SmmCpuFeaturesCompleteSmmReadyToLock(). **/ VOID EFIAPI SmmSupovrStateLock ( VOID ); /** This function initializes CPU Shadow Stack. @param[in] CpuIndex The processor index. @param[in] ShadowStack A pointer to Shadow Stack. **/ VOID SmmCpuFeaturesInitShadowStack ( IN UINTN CpuIndex, IN VOID *ShadowStack ); /** This function fixes up the address of the global variable or function referred in SmiEntry assembly files to be the absoute address. **/ VOID EFIAPI SmmCpuFeaturesLibSmiEntryFixupAddress ( VOID ); #endif