TianoCore EDK2 master
Loading...
Searching...
No Matches
SmramSaveState.c
Go to the documentation of this file.
1
11#include <PiSmm.h>
12
14
15#include <Library/BaseLib.h>
18#include <Library/DebugLib.h>
19
20#include "PiSmmCpuCommon.h"
21
22typedef struct {
23 UINT64 Signature; // Offset 0x00
24 UINT16 Reserved1; // Offset 0x08
25 UINT16 Reserved2; // Offset 0x0A
26 UINT16 Reserved3; // Offset 0x0C
27 UINT16 SmmCs; // Offset 0x0E
28 UINT16 SmmDs; // Offset 0x10
29 UINT16 SmmSs; // Offset 0x12
30 UINT16 SmmOtherSegment; // Offset 0x14
31 UINT16 Reserved4; // Offset 0x16
32 UINT64 Reserved5; // Offset 0x18
33 UINT64 Reserved6; // Offset 0x20
34 UINT64 Reserved7; // Offset 0x28
35 UINT64 SmmGdtPtr; // Offset 0x30
36 UINT32 SmmGdtSize; // Offset 0x38
37 UINT32 Reserved8; // Offset 0x3C
38 UINT64 Reserved9; // Offset 0x40
39 UINT64 Reserved10; // Offset 0x48
40 UINT16 Reserved11; // Offset 0x50
41 UINT16 Reserved12; // Offset 0x52
42 UINT32 Reserved13; // Offset 0x54
43 UINT64 Reserved14; // Offset 0x58
45
47
48//
49// EFER register LMA bit
50//
51#define LMA BIT10
52
56X86_ASSEMBLY_PATCH_LABEL gPatchSmbase;
57X86_ASSEMBLY_PATCH_LABEL gPatchSmiStack;
58X86_ASSEMBLY_PATCH_LABEL gPatchSmiCr3;
59extern volatile UINT8 gcSmiHandlerTemplate[];
60extern CONST UINT16 gcSmiHandlerSize;
61
62//
63// Variables used by SMI Handler
64//
65IA32_DESCRIPTOR gSmiHandlerIdtr;
66
71
79EFIAPI
81 VOID
82 )
83{
84 UINTN Size;
85
87 if (Size != 0) {
88 return Size;
89 }
90
91 return gcSmiHandlerSize;
92}
93
118VOID
119EFIAPI
121 IN UINTN CpuIndex,
122 IN UINT32 SmBase,
123 IN VOID *SmiStack,
124 IN UINTN StackSize,
125 IN UINTN GdtBase,
126 IN UINTN GdtSize,
127 IN UINTN IdtBase,
128 IN UINTN IdtSize,
129 IN UINT32 Cr3
130 )
131{
133 UINT32 CpuSmiStack;
134
135 //
136 // Initialize PROCESSOR_SMM_DESCRIPTOR
137 //
138 Psd = (PROCESSOR_SMM_DESCRIPTOR *)(VOID *)((UINTN)SmBase + SMM_PSD_OFFSET);
139 CopyMem (Psd, &gcPsd, sizeof (gcPsd));
140 Psd->SmmGdtPtr = (UINT64)GdtBase;
141 Psd->SmmGdtSize = (UINT32)GdtSize;
142
144 //
145 // Install SMI handler provided by library
146 //
148 CpuIndex,
149 SmBase,
150 SmiStack,
151 StackSize,
152 GdtBase,
153 GdtSize,
154 IdtBase,
155 IdtSize,
156 Cr3
157 );
158 return;
159 }
160
161 InitShadowStack (CpuIndex, (VOID *)((UINTN)SmiStack + StackSize));
162
163 //
164 // Initialize values in template before copy
165 //
166 CpuSmiStack = (UINT32)((UINTN)SmiStack + StackSize - sizeof (UINTN));
167 PatchInstructionX86 (gPatchSmiStack, CpuSmiStack, 4);
168 PatchInstructionX86 (gPatchSmiCr3, Cr3, 4);
170 gSmiHandlerIdtr.Base = IdtBase;
171 gSmiHandlerIdtr.Limit = (UINT16)(IdtSize - 1);
172
173 //
174 // Set the value at the top of the CPU stack to the CPU Index
175 //
176 *(UINTN *)(UINTN)CpuSmiStack = CpuIndex;
177
178 //
179 // Copy template to CPU specific SMI handler location
180 //
181 CopyMem (
182 (VOID *)((UINTN)SmBase + SMM_HANDLER_OFFSET),
183 (VOID *)gcSmiHandlerTemplate,
184 gcSmiHandlerSize
185 );
186}
UINT64 UINTN
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID InitShadowStack(IN UINTN CpuIndex, IN VOID *ShadowStack)
Definition: SmmFuncsArch.c:151
#define CONST
Definition: Base.h:259
#define IN
Definition: Base.h:279
#define SMM_HANDLER_OFFSET
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)
UINTN EFIAPI SmmCpuFeaturesGetSmiHandlerSize(VOID)
UINTN EFIAPI GetSmiHandlerSize(VOID)
X86_ASSEMBLY_PATCH_LABEL gPatchSmbase
UINT8 mSmmSaveStateRegisterLma
VOID EFIAPI InstallSmiHandler(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)
VOID EFIAPI PatchInstructionX86(OUT X86_ASSEMBLY_PATCH_LABEL *InstructionEnd, IN UINT64 PatchValue, IN UINTN ValueSize)