VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/FirmwareNew/UefiCpuPkg/Library/SmmRelocationLib/SmramSaveStateConfig.c@ 109019

Last change on this file since 109019 was 108794, checked in by vboxsync, 4 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: 4.2 KB
Line 
1/** @file
2 Config SMRAM Save State for SmmBases Relocation.
3
4 Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7**/
8#include "InternalSmmRelocationLib.h"
9#include <Library/CpuLib.h>
10
11/**
12 Get the mode of the CPU at the time an SMI occurs
13
14 @retval EFI_MM_SAVE_STATE_REGISTER_LMA_32BIT 32 bit.
15 @retval EFI_MM_SAVE_STATE_REGISTER_LMA_64BIT 64 bit.
16
17**/
18UINT8
19GetMmSaveStateRegisterLma (
20 VOID
21 )
22{
23 CPUID_VERSION_INFO_EAX RegEax;
24 CPUID_EXTENDED_CPU_SIG_EDX RegEdx;
25 UINTN FamilyId;
26 UINTN ModelId;
27 UINT32 Eax;
28 UINT8 SmmSaveStateRegisterLma;
29
30 //
31 // Determine the mode of the CPU at the time an SMI occurs
32 // Intel(R) 64 and IA-32 Architectures Software Developer's Manual
33 // Volume 3C, Section 34.4.1.1
34 //
35 RegEax.Uint32 = GetCpuFamilyModel ();
36 FamilyId = RegEax.Bits.FamilyId;
37 ModelId = RegEax.Bits.Model;
38 if ((FamilyId == 0x06) || (FamilyId == 0x0f)) {
39 ModelId = ModelId | RegEax.Bits.ExtendedModelId << 4;
40 }
41
42 RegEdx.Uint32 = 0;
43 AsmCpuid (CPUID_EXTENDED_FUNCTION, &Eax, NULL, NULL, NULL);
44 if (Eax >= CPUID_EXTENDED_CPU_SIG) {
45 AsmCpuid (CPUID_EXTENDED_CPU_SIG, NULL, NULL, NULL, &(RegEdx.Uint32));
46 }
47
48 SmmSaveStateRegisterLma = (UINT8)EFI_MM_SAVE_STATE_REGISTER_LMA_32BIT;
49 if (RegEdx.Bits.LM) {
50 SmmSaveStateRegisterLma = (UINT8)EFI_MM_SAVE_STATE_REGISTER_LMA_64BIT;
51 }
52
53 if (FamilyId == 0x06) {
54 if ((ModelId == 0x17) || (ModelId == 0x0f) || (ModelId == 0x1c)) {
55 SmmSaveStateRegisterLma = (UINT8)EFI_MM_SAVE_STATE_REGISTER_LMA_64BIT;
56 }
57 }
58
59 return SmmSaveStateRegisterLma;
60}
61
62/**
63 This function configures the SmBase on the currently executing CPU.
64
65 @param[in] SmBase The SmBase on the currently executing CPU.
66
67**/
68VOID
69EFIAPI
70ConfigureSmBase (
71 IN UINT64 SmBase
72 )
73{
74 SMRAM_SAVE_STATE_MAP *CpuState;
75
76 CpuState = (SMRAM_SAVE_STATE_MAP *)(UINTN)(SMM_DEFAULT_SMBASE + SMRAM_SAVE_STATE_MAP_OFFSET);
77
78 CpuState->x86.SMBASE = (UINT32)SmBase;
79}
80
81/**
82 Hook the code executed immediately after an RSM instruction on the currently
83 executing CPU. The mode of code executed immediately after RSM must be
84 detected, and the appropriate hook must be selected. Always clear the auto
85 HALT restart flag if it is set.
86
87 @param[in,out] CpuState Pointer to SMRAM Save State Map for the
88 currently executing CPU.
89 @param[in] NewInstructionPointer32 Instruction pointer to use if resuming to
90 32-bit mode from 64-bit SMM.
91 @param[in] NewInstructionPointer Instruction pointer to use if resuming to
92 same mode as SMM.
93
94 @retval The value of the original instruction pointer before it was hooked.
95
96**/
97UINT64
98EFIAPI
99HookReturnFromSmm (
100 IN OUT SMRAM_SAVE_STATE_MAP *CpuState,
101 IN UINT64 NewInstructionPointer32,
102 IN UINT64 NewInstructionPointer
103 )
104{
105 UINT64 OriginalInstructionPointer;
106 MSR_IA32_EFER_REGISTER Msr;
107
108 if (GetMmSaveStateRegisterLma () == EFI_MM_SAVE_STATE_REGISTER_LMA_32BIT) {
109 OriginalInstructionPointer = (UINT64)CpuState->x86._EIP;
110 CpuState->x86._EIP = (UINT32)NewInstructionPointer;
111
112 //
113 // Clear the auto HALT restart flag so the RSM instruction returns
114 // program control to the instruction following the HLT instruction.
115 //
116 if ((CpuState->x86.AutoHALTRestart & BIT0) != 0) {
117 CpuState->x86.AutoHALTRestart &= ~BIT0;
118 }
119 } else {
120 OriginalInstructionPointer = CpuState->x64._RIP;
121 Msr.Uint64 = CpuState->x64.IA32_EFER;
122 if (!Msr.Bits.LMA) {
123 CpuState->x64._RIP = (UINT32)NewInstructionPointer32;
124 } else {
125 CpuState->x64._RIP = (UINT32)NewInstructionPointer;
126 }
127
128 //
129 // Clear the auto HALT restart flag so the RSM instruction returns
130 // program control to the instruction following the HLT instruction.
131 //
132 if ((CpuState->x64.AutoHALTRestart & BIT0) != 0) {
133 CpuState->x64.AutoHALTRestart &= ~BIT0;
134 }
135 }
136
137 return OriginalInstructionPointer;
138}
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