/** Create PageTable for SMM use. @return The address of PML4 (to set CR3). **/ UINT32 SmmInitPageTable ( VOID ) { EFI_PHYSICAL_ADDRESS Pages; UINT64 *PTEntry; LIST_ENTRY *FreePage; UINTN Index; UINTN PageFaultHandlerHookAddress; IA32_IDT_GATE_DESCRIPTOR *IdtEntry; EFI_STATUS Status; // // Initialize spin lock // InitializeSpinLock (mPFLock); mCpuSmmStaticPageTable = PcdGetBool (PcdCpuSmmStaticPageTable); m1GPageTableSupport = Is1GPageSupport (); DEBUG ((DEBUG_INFO, "1GPageTableSupport - 0x%x\n", m1GPageTableSupport)); DEBUG ((DEBUG_INFO, "PcdCpuSmmStaticPageTable - 0x%x\n", mCpuSmmStaticPageTable)); mPhysicalAddressBits = CalculateMaximumSupportAddress (); DEBUG ((DEBUG_INFO, "PhysicalAddressBits - 0x%x\n", mPhysicalAddressBits)); // // Generate PAE page table for the first 4GB memory space // Pages = Gen4GPageTable (FALSE); // // Set IA32_PG_PMNT bit to mask this entry // PTEntry = (UINT64*)(UINTN)Pages; for (Index = 0; Index < 4; Index++) { PTEntry[Index] |= IA32_PG_PMNT; } // // Fill Page-Table-Level4 (PML4) entry // PTEntry = (UINT64*)AllocatePageTableMemory (1); ASSERT (PTEntry != NULL); *PTEntry = Pages | PAGE_ATTRIBUTE_BITS; ZeroMem (PTEntry + 1, EFI_PAGE_SIZE - sizeof (*PTEntry)); // // Set sub-entries number // SetSubEntriesNum (PTEntry, 3); if (mCpuSmmStaticPageTable) { SetStaticPageTable ((UINTN)PTEntry); } else { // // Add pages to page pool // FreePage = (LIST_ENTRY*)AllocatePageTableMemory (PAGE_TABLE_PAGES); ASSERT (FreePage != NULL); for (Index = 0; Index < PAGE_TABLE_PAGES; Index++) { InsertTailList (&mPagePool, FreePage); FreePage += EFI_PAGE_SIZE / sizeof (*FreePage); } } if (FeaturePcdGet (PcdCpuSmmProfileEnable)) { // // Set own Page Fault entry instead of the default one, because SMM Profile // feature depends on IRET instruction to do Single Step // PageFaultHandlerHookAddress = (UINTN)PageFaultIdtHandlerSmmProfile; IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) gcSmiIdtr.Base; IdtEntry += EXCEPT_IA32_PAGE_FAULT; IdtEntry->Bits.OffsetLow = (UINT16)PageFaultHandlerHookAddress; IdtEntry->Bits.Reserved_0 = 0; IdtEntry->Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32; IdtEntry->Bits.OffsetHigh = (UINT16)(PageFaultHandlerHookAddress >> 16); IdtEntry->Bits.OffsetUpper = (UINT32)(PageFaultHandlerHookAddress >> 32); IdtEntry->Bits.Reserved_1 = 0; } else {
/** Create PageTable for SMM use. @return The address of PML4 (to set CR3). **/ UINT32 SmmInitPageTable ( VOID ) { EFI_PHYSICAL_ADDRESS Pages; UINT64 *PTEntry; LIST_ENTRY *FreePage; UINTN Index; UINTN PageFaultHandlerHookAddress; IA32_IDT_GATE_DESCRIPTOR *IdtEntry; // // Initialize spin lock // InitializeSpinLock (&mPFLock); m1GPageTableSupport = Is1GPageSupport (); // // Generate PAE page table for the first 4GB memory space // Pages = Gen4GPageTable (PAGE_TABLE_PAGES + 1); // // Set IA32_PG_PMNT bit to mask this entry // PTEntry = (UINT64*)(UINTN)Pages; for (Index = 0; Index < 4; Index++) { PTEntry[Index] |= IA32_PG_PMNT; } // // Fill Page-Table-Level4 (PML4) entry // PTEntry = (UINT64*)(UINTN)(Pages - EFI_PAGES_TO_SIZE (PAGE_TABLE_PAGES + 1)); *PTEntry = Pages + PAGE_ATTRIBUTE_BITS; ZeroMem (PTEntry + 1, EFI_PAGE_SIZE - sizeof (*PTEntry)); // // Set sub-entries number // SetSubEntriesNum (PTEntry, 3); // // Add remaining pages to page pool // FreePage = (LIST_ENTRY*)(PTEntry + EFI_PAGE_SIZE / sizeof (*PTEntry)); while ((UINTN)FreePage < Pages) { InsertTailList (&mPagePool, FreePage); FreePage += EFI_PAGE_SIZE / sizeof (*FreePage); } if (FeaturePcdGet (PcdCpuSmmProfileEnable)) { // // Set own Page Fault entry instead of the default one, because SMM Profile // feature depends on IRET instruction to do Single Step // PageFaultHandlerHookAddress = (UINTN)PageFaultIdtHandlerSmmProfile; IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) gcSmiIdtr.Base; IdtEntry += EXCEPT_IA32_PAGE_FAULT; IdtEntry->Bits.OffsetLow = (UINT16)PageFaultHandlerHookAddress; IdtEntry->Bits.Reserved_0 = 0; IdtEntry->Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32; IdtEntry->Bits.OffsetHigh = (UINT16)(PageFaultHandlerHookAddress >> 16); IdtEntry->Bits.OffsetUpper = (UINT32)(PageFaultHandlerHookAddress >> 32); IdtEntry->Bits.Reserved_1 = 0; } else {