2 Page table manipulation functions for IA-32 processors
4 Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "PiSmmCpuDxeSmm.h"
18 Create PageTable for SMM use.
20 @return PageTable Address
28 UINTN PageFaultHandlerHookAddress
;
29 IA32_IDT_GATE_DESCRIPTOR
*IdtEntry
;
32 // Initialize spin lock
34 InitializeSpinLock (mPFLock
);
36 if (FeaturePcdGet (PcdCpuSmmProfileEnable
)) {
38 // Set own Page Fault entry instead of the default one, because SMM Profile
39 // feature depends on IRET instruction to do Single Step
41 PageFaultHandlerHookAddress
= (UINTN
)PageFaultIdtHandlerSmmProfile
;
42 IdtEntry
= (IA32_IDT_GATE_DESCRIPTOR
*) gcSmiIdtr
.Base
;
43 IdtEntry
+= EXCEPT_IA32_PAGE_FAULT
;
44 IdtEntry
->Bits
.OffsetLow
= (UINT16
)PageFaultHandlerHookAddress
;
45 IdtEntry
->Bits
.Reserved_0
= 0;
46 IdtEntry
->Bits
.GateType
= IA32_IDT_GATE_TYPE_INTERRUPT_32
;
47 IdtEntry
->Bits
.OffsetHigh
= (UINT16
)(PageFaultHandlerHookAddress
>> 16);
50 // Register SMM Page Fault Handler
52 SmmRegisterExceptionHandler (&mSmmCpuService
, EXCEPT_IA32_PAGE_FAULT
, SmiPFHandler
);
56 // Additional SMM IDT initialization for SMM stack guard
58 if (FeaturePcdGet (PcdCpuSmmStackGuard
)) {
59 InitializeIDTSmmStackGuard ();
61 return Gen4GPageTable (0, TRUE
);
65 Page Fault handler for SMM use.
77 ThePage Fault handler wrapper for SMM use.
79 @param InterruptType Defines the type of interrupt or exception that
80 occurred on the processor.This parameter is processor architecture specific.
81 @param SystemContext A pointer to the processor context when
82 the interrupt occurred on the processor.
87 IN EFI_EXCEPTION_TYPE InterruptType
,
88 IN EFI_SYSTEM_CONTEXT SystemContext
93 ASSERT (InterruptType
== EXCEPT_IA32_PAGE_FAULT
);
95 AcquireSpinLock (mPFLock
);
97 PFAddress
= AsmReadCr2 ();
99 if ((FeaturePcdGet (PcdCpuSmmStackGuard
)) &&
100 (PFAddress
>= mCpuHotPlugData
.SmrrBase
) &&
101 (PFAddress
< (mCpuHotPlugData
.SmrrBase
+ mCpuHotPlugData
.SmrrSize
))) {
102 DEBUG ((EFI_D_ERROR
, "SMM stack overflow!\n"));
107 // If a page fault occurs in SMM range
109 if ((PFAddress
< mCpuHotPlugData
.SmrrBase
) ||
110 (PFAddress
>= mCpuHotPlugData
.SmrrBase
+ mCpuHotPlugData
.SmrrSize
)) {
111 if ((SystemContext
.SystemContextIa32
->ExceptionData
& IA32_PF_EC_ID
) != 0) {
112 DEBUG ((EFI_D_ERROR
, "Code executed on IP(0x%x) out of SMM range after SMM is locked!\n", PFAddress
));
114 DumpModuleInfoByIp (*(UINTN
*)(UINTN
)SystemContext
.SystemContextIa32
->Esp
);
120 if (FeaturePcdGet (PcdCpuSmmProfileEnable
)) {
121 SmmProfilePFHandler (
122 SystemContext
.SystemContextIa32
->Eip
,
123 SystemContext
.SystemContextIa32
->ExceptionData
126 SmiDefaultPFHandler ();
129 ReleaseSpinLock (mPFLock
);