18#define EXTRA_PAGE_TABLE_PAGES 8
21#define IA32_PG_RW BIT1
22#define IA32_PG_PS BIT7
25VOID *mOriginalHandler;
26UINTN mPageFaultBuffer;
27UINTN mPageFaultIndex = 0;
31UINT64 *mPageFaultUplink[EXTRA_PAGE_TABLE_PAGES];
51 IN IA32_IDT_GATE_DESCRIPTOR *IdtEntry
55 UINT8 PhysicalAddressBits;
56 UINTN PageFaultHandlerHookAddress;
59 if (RegEax >= 0x80000008) {
61 PhysicalAddressBits = (UINT8)RegEax;
63 PhysicalAddressBits = 36;
66 mPhyMask =
LShiftU64 (1, PhysicalAddressBits) - 1;
67 mPhyMask &= (1ull << 48) - SIZE_4KB;
73 mOriginalHandler = (VOID *)(
UINTN)(
LShiftU64 (IdtEntry->Bits.OffsetUpper, 32) + IdtEntry->Bits.OffsetLow + (IdtEntry->Bits.OffsetHigh << 16));
74 IdtEntry->Bits.OffsetLow = (UINT16)PageFaultHandlerHookAddress;
75 IdtEntry->Bits.Selector = (UINT16)
AsmReadCs ();
76 IdtEntry->Bits.Reserved_0 = 0;
77 IdtEntry->Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32;
78 IdtEntry->Bits.OffsetHigh = (UINT16)(PageFaultHandlerHookAddress >> 16);
79 IdtEntry->Bits.OffsetUpper = (UINT32)(PageFaultHandlerHookAddress >> 32);
80 IdtEntry->Bits.Reserved_1 = 0;
88 ZeroMem (mPageFaultUplink,
sizeof (mPageFaultUplink));
107 if ((Facs ==
NULL) ||
109 ((Facs->FirmwareWakingVector == 0) && (Facs->XFirmwareWakingVector == 0)))
115 if (Facs->XFirmwareWakingVector != 0) {
117 ((Facs->Flags & EFI_ACPI_4_0_64BIT_WAKE_SUPPORTED_F) != 0) &&
121 if (
sizeof (
UINTN) ==
sizeof (UINT64)) {
141 IA32_IDT_GATE_DESCRIPTOR *IdtEntry;
142 IA32_DESCRIPTOR *IdtDescriptor;
149 IdtDescriptor = (IA32_DESCRIPTOR *)(
UINTN)(AcpiS3Context->IdtrProfile);
155 Status = InitializeCpuExceptionHandlers (
NULL);
162 S3DebugBuffer = (
UINTN)(AcpiS3Context->S3DebugBufferAddress);
164 IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *)(IdtDescriptor->Base + (3 * sizeof (IA32_IDT_GATE_DESCRIPTOR)));
165 IdtEntry->Bits.OffsetLow = (UINT16)S3DebugBuffer;
166 IdtEntry->Bits.Selector = (UINT16)
AsmReadCs ();
167 IdtEntry->Bits.Reserved_0 = 0;
168 IdtEntry->Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32;
169 IdtEntry->Bits.OffsetHigh = (UINT16)(S3DebugBuffer >> 16);
170 IdtEntry->Bits.OffsetUpper = (UINT32)(S3DebugBuffer >> 32);
171 IdtEntry->Bits.Reserved_1 = 0;
182 IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *)(IdtDescriptor->Base + (14 * sizeof (IA32_IDT_GATE_DESCRIPTOR)));
195 IN OUT UINT64 *Uplink
206 if ((mPageFaultUplink[mPageFaultIndex] !=
NULL) &&
207 ((*mPageFaultUplink[mPageFaultIndex] & ~mAddressEncMask & mPhyMask) == Address))
209 *mPageFaultUplink[mPageFaultIndex] = 0;
215 *Uplink = Address | mAddressEncMask | IA32_PG_P | IA32_PG_RW;
216 mPageFaultUplink[mPageFaultIndex] = Uplink;
218 mPageFaultIndex = (mPageFaultIndex + 1) % EXTRA_PAGE_TABLE_PAGES;
239 DEBUG ((DEBUG_INFO,
"BootScript - PageFaultHandler: Cr2 - %lx\n", PFAddress));
241 if (PFAddress >= mPhyMask + SIZE_4KB) {
245 PFAddress &= mPhyMask;
251 if ((PageTable[PTIndex] & IA32_PG_P) == 0) {
255 PageTable = (UINT64 *)(
UINTN)(PageTable[PTIndex] & ~mAddressEncMask & mPhyMask);
258 if (mPage1GSupport) {
259 PageTable[PTIndex] = ((PFAddress | mAddressEncMask) & ~((1ull << 30) - 1)) | IA32_PG_P | IA32_PG_RW | IA32_PG_PS;
261 if ((PageTable[PTIndex] & IA32_PG_P) == 0) {
265 PageTable = (UINT64 *)(
UINTN)(PageTable[PTIndex] & ~mAddressEncMask & mPhyMask);
268 PageTable[PTIndex] = ((PFAddress | mAddressEncMask) & ~((1ull << 21) - 1)) | IA32_PG_P | IA32_PG_RW | IA32_PG_PS;
#define EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE
#define EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION
#define EFI_ACPI_4_0_OSPM_64BIT_WAKE__F
UINT64 EFIAPI BitFieldRead64(IN UINT64 Operand, IN UINTN StartBit, IN UINTN EndBit)
UINT64 EFIAPI LShiftU64(IN UINT64 Operand, IN UINTN Count)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
VOID SetIdtEntry(IN ACPI_S3_CONTEXT *AcpiS3Context)
UINTN EFIAPI AsmReadCr3(VOID)
UINTN EFIAPI AsmReadCr2(VOID)
UINT16 EFIAPI AsmReadCs(VOID)
#define ASSERT_EFI_ERROR(StatusParameter)
#define DEBUG_CODE_BEGIN()
#define DEBUG(Expression)
UINT32 EFIAPI AsmCpuid(IN UINT32 Index, OUT UINT32 *RegisterEax OPTIONAL, OUT UINT32 *RegisterEbx OPTIONAL, OUT UINT32 *RegisterEcx OPTIONAL, OUT UINT32 *RegisterEdx OPTIONAL)
#define EFI_PAGES_TO_SIZE(Pages)
VOID EFIAPI PageFaultHandlerHook(VOID)
VOID AcquirePage(IN OUT UINT64 *Uplink)
BOOLEAN EFIAPI PageFaultHandler(VOID)
VOID HookPageFaultHandler(IN IA32_IDT_GATE_DESCRIPTOR *IdtEntry)
BOOLEAN IsLongModeWakingVector(IN ACPI_S3_CONTEXT *AcpiS3Context)
VOID EFIAPI AsmWriteIdtr(IN CONST IA32_DESCRIPTOR *Idtr)