23#define TXT_EVTYPE_BASE 0x400
24#define TXT_EVTYPE_STM_HASH (TXT_EVTYPE_BASE + 14)
31BOOLEAN mLockLoadMonitor =
FALSE;
59#define CPUID1_EDX_XD_SUPPORT 0x100000
65extern UINT32 gStmSmbase;
66extern volatile UINT32 gStmSmiStack;
67extern UINT32 gStmSmiCr3;
68extern volatile UINT8 gcStmSmiHandlerTemplate[];
69extern CONST UINT16 gcStmSmiHandlerSize;
70extern UINT16 gcStmSmiHandlerOffset;
71extern BOOLEAN gStmXdSupported;
76IA32_DESCRIPTOR gStmSmiHandlerIdtr;
89BOOLEAN mStmConfigurationTableInitialized =
FALSE;
125 Status =
gBS->LocateProtocol (
126 &gEfiMpServiceProtocolGuid,
128 (VOID **)&mSmmCpuFeaturesLibMpService
138 if (GuidHob !=
NULL) {
147 }
else if (
PcdGet32 (PcdCpuMsegSize) > 0) {
155 DEBUG ((DEBUG_ERROR,
"Not enough SMRAM resource to allocate MSEG size %08x\n",
PcdGet32 (PcdCpuMsegSize)));
160 DEBUG ((DEBUG_INFO,
"MsegBase: 0x%08x, MsegSize: 0x%08x\n", mMsegBase, mMsegSize));
206 return gcStmSmiHandlerSize;
255 CopyMem ((VOID *)((
UINTN)SmBase + TXT_SMM_PSD_OFFSET), &gcStmPsd,
sizeof (gcStmPsd));
257 Psd->SmmGdtPtr = GdtBase;
258 Psd->SmmGdtSize = (UINT32)GdtSize;
263 gStmSmiStack = (UINT32)((
UINTN)SmiStack + StackSize -
sizeof (
UINTN));
266 gStmSmiHandlerIdtr.Base = IdtBase;
267 gStmSmiHandlerIdtr.Limit = (UINT16)(IdtSize - 1);
269 if (gStmXdSupported) {
271 if (RegEax <= CPUID_EXTENDED_FUNCTION) {
275 gStmXdSupported =
FALSE;
279 if ((RegEdx & CPUID1_EDX_XD_SUPPORT) == 0) {
283 gStmXdSupported =
FALSE;
297 (VOID *)gcStmSmiHandlerTemplate,
302 Psd->SmmSmiHandlerRsp = (
UINTN)SmiStack + StackSize -
sizeof (
UINTN);
305 DEBUG ((DEBUG_INFO,
"CpuSmmStmExceptionStackSize - %x\n",
PcdGet32 (PcdCpuSmmStmExceptionStackSize)));
315 Status = mSmmCpuFeaturesLibMpService->GetProcessorInfo (
316 mSmmCpuFeaturesLibMpService,
322 Psd->LocalApicId = (UINT32)ProcessorInfo.
ProcessorId;
327 Psd->PhysicalAddressBits = ((
EFI_HOB_CPU *)Hob)->SizeOfMemorySpace;
330 if (RegEax >= 0x80000008) {
332 Psd->PhysicalAddressBits = (UINT8)RegEax;
334 Psd->PhysicalAddressBits = 36;
338 if (!mStmConfigurationTableInitialized) {
340 mStmConfigurationTableInitialized =
TRUE;
367 DEBUG ((DEBUG_INFO,
"SmmEndOfDxeEventNotify\n"));
397 DEBUG ((DEBUG_INFO,
"Index=%d Psd=%p Rsdp=%p\n", Index, Psd, Rsdp));
398 Psd->AcpiRsdp = (UINT64)(
UINTN)Rsdp;
401 mLockLoadMonitor =
TRUE;
419 &gEfiSmMonitorInitProtocolGuid,
421 &mSmMonitorInitProtocol
429 Status =
gSmst->SmmRegisterProtocolNotify (
430 &gEfiSmmEndOfDxeProtocolGuid,
485 switch (Resource->Header.RscType) {
488 ResourceLo = Resource->Mem.Base;
489 ResourceHi = Resource->Mem.Base + Resource->Mem.Length;
490 RecordLo = Record->Mem.Base;
491 RecordHi = Record->Mem.Base + Record->Mem.Length;
492 if (Resource->Mem.RWXAttributes != Record->Mem.RWXAttributes) {
493 if ((ResourceLo == RecordLo) && (ResourceHi == RecordHi)) {
494 Record->Mem.RWXAttributes = Resource->Mem.RWXAttributes | Record->Mem.RWXAttributes;
503 case TRAPPED_IO_RANGE:
504 ResourceLo = (UINT64)Resource->Io.Base;
505 ResourceHi = (UINT64)Resource->Io.Base + (UINT64)Resource->Io.Length;
506 RecordLo = (UINT64)Record->Io.Base;
507 RecordHi = (UINT64)Record->Io.Base + (UINT64)Record->Io.Length;
510 if ((Resource->PciCfg.OriginatingBusNumber != Record->PciCfg.OriginatingBusNumber) ||
511 (Resource->PciCfg.LastNodeIndex != Record->PciCfg.LastNodeIndex))
520 ResourceLo = (UINT64)Resource->PciCfg.Base;
521 ResourceHi = (UINT64)Resource->PciCfg.Base + (UINT64)Resource->PciCfg.Length;
522 RecordLo = (UINT64)Record->PciCfg.Base;
523 RecordHi = (UINT64)Record->PciCfg.Base + (UINT64)Record->PciCfg.Length;
524 if (Resource->PciCfg.RWAttributes != Record->PciCfg.RWAttributes) {
525 if ((ResourceLo == RecordLo) && (ResourceHi == RecordHi)) {
526 Record->PciCfg.RWAttributes = Resource->PciCfg.RWAttributes | Record->PciCfg.RWAttributes;
534 case MACHINE_SPECIFIC_REG:
538 if (Resource->Msr.MsrIndex != Record->Msr.MsrIndex) {
542 Record->Msr.ReadMask |= Resource->Msr.ReadMask;
543 Record->Msr.WriteMask |= Resource->Msr.WriteMask;
552 if ((ResourceHi < RecordLo) || (ResourceLo > RecordHi)) {
559 if ((ResourceLo >= RecordLo) && (ResourceHi <= RecordHi)) {
567 ResourceLo = (ResourceLo < RecordLo) ? ResourceLo : RecordLo;
568 ResourceHi = (ResourceHi > RecordHi) ? ResourceHi : RecordHi;
570 switch (Resource->Header.RscType) {
573 Record->Mem.Base = ResourceLo;
574 Record->Mem.Length = ResourceHi - ResourceLo;
577 case TRAPPED_IO_RANGE:
578 Record->Io.Base = (UINT16)ResourceLo;
579 Record->Io.Length = (UINT16)(ResourceHi - ResourceLo);
582 Record->PciCfg.Base = (UINT16)ResourceLo;
583 Record->PciCfg.Length = (UINT16)(ResourceHi - ResourceLo);
606 Record = (
STM_RSC *)mStmResourcesPtr;
616 if (Resource->Header.RscType != Record->Header.RscType) {
617 Record = (
STM_RSC *)((
UINTN)Record + Record->Header.Length);
628 Record = (
STM_RSC *)((
UINTN)Record + Record->Header.Length);
635 mStmResourcesPtr + mStmResourceSizeUsed -
sizeof (mRscEndNode),
637 Resource->Header.Length
640 mStmResourcesPtr + mStmResourceSizeUsed -
sizeof (mRscEndNode) + Resource->Header.Length,
644 mStmResourceSizeUsed += Resource->Header.Length;
645 mStmResourceSizeAvailable = mStmResourceTotalSize - mStmResourceSizeUsed;
662 IN UINT32 NumEntries OPTIONAL
669 if (NumEntries == 0) {
675 Resource = ResourceList;
677 for (Index = 0; Index < Count; Index++) {
683 Resource = (
STM_RSC *)((
UINTN)Resource + Resource->Header.Length);
704 IN UINT32 NumEntries OPTIONAL
716 if (NumEntries == 0) {
725 Resource = ResourceList;
727 for (Index = 0; Index < Count; Index++) {
728 DEBUG ((DEBUG_INFO,
"ValidateResource (%d) - RscType(%x)\n", Index, Resource->Header.RscType));
732 switch (Resource->Header.RscType) {
734 if (Resource->Header.Length != sizeof (
STM_RSC_END)) {
743 if (NumEntries != 0) {
760 if (Resource->Mem.RWXAttributes > FULL_ACCS) {
767 case TRAPPED_IO_RANGE:
772 if ((Resource->Io.Base + Resource->Io.Length) > 0xFFFF) {
779 DEBUG ((DEBUG_INFO,
"ValidateResource - PCI (0x%02x, 0x%08x, 0x%02x, 0x%02x)\n", Resource->PciCfg.OriginatingBusNumber, Resource->PciCfg.LastNodeIndex, Resource->PciCfg.PciDevicePath[0].PciDevice, Resource->PciCfg.PciDevicePath[0].PciFunction));
784 for (SubIndex = 0; SubIndex <= Resource->PciCfg.LastNodeIndex; SubIndex++) {
785 if ((Resource->PciCfg.PciDevicePath[SubIndex].PciDevice > 0x1F) || (Resource->PciCfg.PciDevicePath[SubIndex].PciFunction > 7)) {
790 if ((Resource->PciCfg.Base + Resource->PciCfg.Length) > 0x1000) {
796 case MACHINE_SPECIFIC_REG:
804 DEBUG ((DEBUG_ERROR,
"ValidateResource - Unknown RscType(%x)\n", Resource->Header.RscType));
808 Resource = (
STM_RSC *)((
UINTN)Resource + Resource->Header.Length);
830 IN UINT32 NumEntries OPTIONAL
837 Resource = ResourceList;
843 if (NumEntries == 0) {
852 Resource = ResourceList;
854 for (Index = 0; Index < Count; Index++) {
859 Resource = (
STM_RSC *)((
UINTN)Resource + Resource->Header.Length);
882 IN UINT32 NumEntries OPTIONAL
888 UINTN NewResourceSize;
890 DEBUG ((DEBUG_INFO,
"AddPiResource - Enter\n"));
893 return EFI_INVALID_PARAMETER;
897 DEBUG ((DEBUG_INFO,
"ResourceSize - 0x%08x\n", ResourceSize));
898 if (ResourceSize == 0) {
899 return EFI_INVALID_PARAMETER;
902 if (mStmResourcesPtr ==
NULL) {
907 DEBUG ((DEBUG_INFO,
"Allocate - 0x%08x\n", NewResourceSize));
908 Status =
gSmst->SmmAllocatePages (
914 if (EFI_ERROR (Status)) {
921 mStmResourcesPtr = (UINT8 *)(
UINTN)NewResource;
922 mStmResourceTotalSize = NewResourceSize;
923 CopyMem (mStmResourcesPtr, &mRscEndNode,
sizeof (mRscEndNode));
924 mStmResourceSizeUsed =
sizeof (mRscEndNode);
925 mStmResourceSizeAvailable = mStmResourceTotalSize -
sizeof (mRscEndNode);
931 }
else if (mStmResourceSizeAvailable < ResourceSize) {
935 NewResourceSize = mStmResourceTotalSize + (ResourceSize - mStmResourceSizeAvailable);
937 DEBUG ((DEBUG_INFO,
"ReAllocate - 0x%08x\n", NewResourceSize));
938 Status =
gSmst->SmmAllocatePages (
944 if (EFI_ERROR (Status)) {
948 CopyMem ((VOID *)(
UINTN)NewResource, mStmResourcesPtr, mStmResourceSizeUsed);
949 mStmResourceSizeAvailable = NewResourceSize - mStmResourceSizeUsed;
951 gSmst->SmmFreePages (
956 mStmResourceTotalSize = NewResourceSize;
957 mStmResourcesPtr = (UINT8 *)(
UINTN)NewResource;
990 IN UINT32 NumEntries OPTIONAL
993 if (ResourceList !=
NULL) {
996 return EFI_UNSUPPORTED;
1002 CopyMem (mStmResourcesPtr, &mRscEndNode,
sizeof (mRscEndNode));
1003 mStmResourceSizeUsed =
sizeof (mRscEndNode);
1004 mStmResourceSizeAvailable = mStmResourceTotalSize -
sizeof (mRscEndNode);
1025 IN OUT UINT32 *ResourceSize
1028 if (*ResourceSize < mStmResourceSizeUsed) {
1029 *ResourceSize = (UINT32)mStmResourceSizeUsed;
1030 return EFI_BUFFER_TOO_SMALL;
1033 CopyMem (ResourceList, mStmResourcesPtr, mStmResourceSizeUsed);
1034 *ResourceSize = (UINT32)mStmResourceSizeUsed;
1105 DEBUG ((DEBUG_ERROR,
"STM Image not compatible with CPU\n"));
1106 DEBUG ((DEBUG_ERROR,
" StmHeader->HwStmHdr.MsegHeaderRevision = %08x\n", StmHeader->HwStmHdr.
MsegHeaderRevision));
1115 StmHeader->SwStmHdr.AdditionalDynamicMemorySize +
1117 if (MinMsegSize < StmImageSize) {
1118 MinMsegSize = StmImageSize;
1121 if (StmHeader->HwStmHdr.Cr3Offset >= StmHeader->SwStmHdr.StaticImageSize) {
1133 if (MinMsegSize > mMsegSize) {
1134 DEBUG ((DEBUG_ERROR,
"MSEG too small. Min MSEG Size = %08x Current MSEG Size = %08x\n", MinMsegSize, mMsegSize));
1135 DEBUG ((DEBUG_ERROR,
" StmHeader->SwStmHdr.StaticImageSize = %08x\n", StmHeader->SwStmHdr.StaticImageSize));
1136 DEBUG ((DEBUG_ERROR,
" StmHeader->SwStmHdr.AdditionalDynamicMemorySize = %08x\n", StmHeader->SwStmHdr.AdditionalDynamicMemorySize));
1137 DEBUG ((DEBUG_ERROR,
" StmHeader->SwStmHdr.PerProcDynamicMemorySize = %08x\n", StmHeader->SwStmHdr.PerProcDynamicMemorySize));
1140 DEBUG ((DEBUG_ERROR,
" StmHeader->HwStmHdr.Cr3Offset = %08x\n", StmHeader->HwStmHdr.Cr3Offset));
1211 if (mLockLoadMonitor) {
1212 return EFI_ACCESS_DENIED;
1217 return EFI_UNSUPPORTED;
1221 return EFI_BUFFER_TOO_SMALL;
1227 TXT_EVTYPE_STM_HASH,
1230 (VOID *)(
UINTN)StmImage,
1236 mStmState |= EFI_SM_MONITOR_STATE_ENABLED;
1254 return mStmResourcesPtr;
1273 Psd->BiosHwResourceRequirementsPtr = (UINT64)(
UINTN)StmResource;
1288 mStmState |= EFI_SM_MONITOR_STATE_ACTIVATED;
1300 mStmState &= ~EFI_SM_MONITOR_STATE_ACTIVATED;
VOID CpuFeaturesLibInitialization(VOID)
VOID *EFIAPI GetFirstHob(IN UINT16 Type)
VOID *EFIAPI GetFirstGuidHob(IN CONST EFI_GUID *Guid)
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
UINT64 EFIAPI AsmReadMsr64(IN UINT32 Index)
UINT64 EFIAPI AsmWriteMsr64(IN UINT32 Index, IN UINT64 Value)
VOID StmGen4GPageTable(IN UINTN PageTableBase)
#define ALIGN_VALUE(Value, Alignment)
#define GLOBAL_REMOVE_IF_UNREFERENCED
#define ASSERT_EFI_ERROR(StatusParameter)
#define DEBUG(Expression)
#define SMM_HANDLER_OFFSET
#define MSR_IA32_VMX_BASIC
#define MSR_IA32_VMX_MISC
#define MSR_IA32_SMM_MONITOR_CTL
#define CPUID_VERSION_INFO
#define CPUID_EXTENDED_CPU_SIG
#define SMRAM_SAVE_STATE_MAP_OFFSET
UINT32 EFIAPI AsmCpuid(IN UINT32 Index, OUT UINT32 *RegisterEax OPTIONAL, OUT UINT32 *RegisterEbx OPTIONAL, OUT UINT32 *RegisterEcx OPTIONAL, OUT UINT32 *RegisterEdx OPTIONAL)
#define PcdGet32(TokenName)
EFI_SMM_SYSTEM_TABLE2 * gSmst
VOID *EFIAPI AllocatePages(IN UINTN Pages)
BOOLEAN ValidateResource(IN STM_RSC *ResourceList, IN UINT32 NumEntries OPTIONAL)
EFI_STATUS EFIAPI DeletePiResource(IN STM_RSC *ResourceList, IN UINT32 NumEntries OPTIONAL)
VOID StmSmmConfigurationTableInit(VOID)
VOID EFIAPI EnableMsegMsr(IN VOID *Buffer)
VOID AddResource(IN STM_RSC *ResourceList, IN UINT32 NumEntries OPTIONAL)
VOID EFIAPI SmmStmTeardown(VOID)
BOOLEAN StmCheckStmImage(IN EFI_PHYSICAL_ADDRESS StmImage, IN UINTN StmImageSize)
VOID AddSingleResource(IN STM_RSC *Resource)
UINTN GetResourceSize(IN STM_RSC *ResourceList, IN UINT32 NumEntries OPTIONAL)
EFI_SM_MONITOR_STATE EFIAPI GetMonitorState(VOID)
EFI_STATUS EFIAPI SmmEndOfDxeEventNotify(IN CONST EFI_GUID *Protocol, IN VOID *Interface, IN EFI_HANDLE Handle)
EFI_STATUS EFIAPI GetPiResource(OUT STM_RSC *ResourceList, IN OUT UINT32 *ResourceSize)
EFI_STATUS EFIAPI SmmCpuFeaturesLibStmConstructor(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
VOID * GetStmResource(VOID)
EFI_STATUS EFIAPI AddPiResource(IN STM_RSC *ResourceList, IN UINT32 NumEntries OPTIONAL)
VOID EFIAPI SmmCpuFeaturesInstallSmiHandler(IN UINTN CpuIndex, IN UINT32 SmBase, IN VOID *SmiStack, IN UINTN StackSize, IN UINTN GdtBase, IN UINTN GdtSize, IN UINTN IdtBase, IN UINTN IdtSize, IN UINT32 Cr3)
BOOLEAN HandleSingleResource(IN STM_RSC *Resource, IN STM_RSC *Record)
VOID EFIAPI SmmStmSetup(VOID)
VOID FinishSmmCpuFeaturesInitializeProcessor(VOID)
VOID StmLoadStmImage(IN EFI_PHYSICAL_ADDRESS StmImage, IN UINTN StmImageSize)
EFI_STATUS EFIAPI LoadMonitor(IN EFI_PHYSICAL_ADDRESS StmImage, IN UINTN StmImageSize)
VOID NotifyStmResourceChange(VOID *StmResource)
UINTN EFIAPI SmmCpuFeaturesGetSmiHandlerSize(VOID)
VOID EFIAPI SmmCpuFeaturesLibStmSmiEntryFixupAddress()
EFI_STATUS EFIAPI TpmMeasureAndLogData(IN UINT32 PcrIndex, IN UINT32 EventType, IN VOID *EventLog, IN UINT32 LogLen, IN VOID *HashData, IN UINT64 HashDataLen)
UINT64 EFI_PHYSICAL_ADDRESS
#define EFI_PAGES_TO_SIZE(Pages)
#define EFI_SIZE_TO_PAGES(Size)
EFI_INSTALL_PROTOCOL_INTERFACE SmmInstallProtocolInterface
EFI_PHYSICAL_ADDRESS CpuStart
EFI_CONFIGURATION_TABLE * ConfigurationTable
UINTN NumberOfTableEntries
UINT32 MsegHeaderRevision
struct CPUID_VERSION_INFO_ECX::@695 Bits
struct IA32_VMX_MISC_REGISTER::@664 Bits
UINT32 MsegRevisionIdentifier
struct MSR_IA32_SMM_MONITOR_CTL_REGISTER::@630 Bits
struct MSR_IA32_VMX_BASIC_REGISTER::@663 Bits