VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/FirmwareNew/UefiCpuPkg/PiSmmCpuDxeSmm/SmramSaveState.c@ 108794

Last change on this file since 108794 was 108794, checked in by vboxsync, 2 weeks ago

Devices/EFI/FirmwareNew: Merge edk2-stable202502 from the vendor branch and make it build for the important platforms, bugref:4643

  • Property svn:eol-style set to native
File size: 5.9 KB
Line 
1/** @file
2Provides services to access SMRAM Save State Map
3
4Copyright (c) 2010 - 2024, Intel Corporation. All rights reserved.<BR>
5Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.<BR>
6
7SPDX-License-Identifier: BSD-2-Clause-Patent
8
9**/
10
11#include <PiSmm.h>
12
13#include <Library/SmmCpuFeaturesLib.h>
14
15#include <Library/BaseLib.h>
16#include <Library/BaseMemoryLib.h>
17#include <Library/SmmServicesTableLib.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
44} PROCESSOR_SMM_DESCRIPTOR;
45
46extern CONST PROCESSOR_SMM_DESCRIPTOR gcPsd;
47
48//
49// EFER register LMA bit
50//
51#define LMA BIT10
52
53///
54/// Variables from SMI Handler
55///
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
67///
68/// The mode of the CPU at the time an SMI occurs
69///
70UINT8 mSmmSaveStateRegisterLma;
71
72/**
73 Get the size of the SMI Handler in bytes.
74
75 @retval The size, in bytes, of the SMI Handler.
76
77**/
78UINTN
79EFIAPI
80GetSmiHandlerSize (
81 VOID
82 )
83{
84 UINTN Size;
85
86 Size = SmmCpuFeaturesGetSmiHandlerSize ();
87 if (Size != 0) {
88 return Size;
89 }
90
91 return gcSmiHandlerSize;
92}
93
94/**
95 Install the SMI handler for the CPU specified by CpuIndex. This function
96 is called by the CPU that was elected as monarch during System Management
97 Mode initialization.
98
99 @param[in] CpuIndex The index of the CPU to install the custom SMI handler.
100 The value must be between 0 and the NumberOfCpus field
101 in the System Management System Table (SMST).
102 @param[in] SmBase The SMBASE address for the CPU specified by CpuIndex.
103 @param[in] SmiStack The stack to use when an SMI is processed by the
104 the CPU specified by CpuIndex.
105 @param[in] StackSize The size, in bytes, if the stack used when an SMI is
106 processed by the CPU specified by CpuIndex.
107 @param[in] GdtBase The base address of the GDT to use when an SMI is
108 processed by the CPU specified by CpuIndex.
109 @param[in] GdtSize The size, in bytes, of the GDT used when an SMI is
110 processed by the CPU specified by CpuIndex.
111 @param[in] IdtBase The base address of the IDT to use when an SMI is
112 processed by the CPU specified by CpuIndex.
113 @param[in] IdtSize The size, in bytes, of the IDT used when an SMI is
114 processed by the CPU specified by CpuIndex.
115 @param[in] Cr3 The base address of the page tables to use when an SMI
116 is processed by the CPU specified by CpuIndex.
117**/
118VOID
119EFIAPI
120InstallSmiHandler (
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{
132 PROCESSOR_SMM_DESCRIPTOR *Psd;
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
143 if (SmmCpuFeaturesGetSmiHandlerSize () != 0) {
144 //
145 // Install SMI handler provided by library
146 //
147 SmmCpuFeaturesInstallSmiHandler (
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);
169 PatchInstructionX86 (gPatchSmbase, SmBase, 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}
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette