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 <Register/Amd/SmramSaveStateMap.h>
|
---|
10 |
|
---|
11 | /**
|
---|
12 | This function configures the SmBase on the currently executing CPU.
|
---|
13 |
|
---|
14 | @param[in] SmBase The SmBase on the currently executing CPU.
|
---|
15 |
|
---|
16 | **/
|
---|
17 | VOID
|
---|
18 | EFIAPI
|
---|
19 | ConfigureSmBase (
|
---|
20 | IN UINT64 SmBase
|
---|
21 | )
|
---|
22 | {
|
---|
23 | AMD_SMRAM_SAVE_STATE_MAP *CpuSaveState;
|
---|
24 |
|
---|
25 | CpuSaveState = (AMD_SMRAM_SAVE_STATE_MAP *)(UINTN)(SMM_DEFAULT_SMBASE + SMRAM_SAVE_STATE_MAP_OFFSET);
|
---|
26 |
|
---|
27 | if ((CpuSaveState->x86.SMMRevId & 0xFFFF) == 0) {
|
---|
28 | CpuSaveState->x86.SMBASE = (UINT32)SmBase;
|
---|
29 | } else {
|
---|
30 | CpuSaveState->x64.SMBASE = (UINT32)SmBase;
|
---|
31 | }
|
---|
32 | }
|
---|
33 |
|
---|
34 | /**
|
---|
35 | This function updates the SMRAM save state on the currently executing CPU
|
---|
36 | to resume execution at a specific address after an RSM instruction. This
|
---|
37 | function must evaluate the SMRAM save state to determine the execution mode
|
---|
38 | the RSM instruction resumes and update the resume execution address with
|
---|
39 | either NewInstructionPointer32 or NewInstructionPoint. The auto HALT restart
|
---|
40 | flag in the SMRAM save state must always be cleared. This function returns
|
---|
41 | the value of the instruction pointer from the SMRAM save state that was
|
---|
42 | replaced. If this function returns 0, then the SMRAM save state was not
|
---|
43 | modified.
|
---|
44 |
|
---|
45 | This function is called during the very first SMI on each CPU after
|
---|
46 | SmmCpuFeaturesInitializeProcessor() to set a flag in normal execution mode
|
---|
47 | to signal that the SMBASE of each CPU has been updated before the default
|
---|
48 | SMBASE address is used for the first SMI to the next CPU.
|
---|
49 |
|
---|
50 | @param[in,out] CpuState Pointer to SMRAM Save State Map for the
|
---|
51 | currently executing CPU.
|
---|
52 | @param[in] NewInstructionPointer32 Instruction pointer to use if resuming to
|
---|
53 | 32-bit mode from 64-bit SMM.
|
---|
54 | @param[in] NewInstructionPointer Instruction pointer to use if resuming to
|
---|
55 | same mode as SMM.
|
---|
56 |
|
---|
57 | @retval The value of the original instruction pointer before it was hooked.
|
---|
58 |
|
---|
59 | **/
|
---|
60 | UINT64
|
---|
61 | EFIAPI
|
---|
62 | HookReturnFromSmm (
|
---|
63 | IN OUT SMRAM_SAVE_STATE_MAP *CpuState,
|
---|
64 | IN UINT64 NewInstructionPointer32,
|
---|
65 | IN UINT64 NewInstructionPointer
|
---|
66 | )
|
---|
67 | {
|
---|
68 | UINT64 OriginalInstructionPointer;
|
---|
69 | AMD_SMRAM_SAVE_STATE_MAP *CpuSaveState;
|
---|
70 |
|
---|
71 | CpuSaveState = (AMD_SMRAM_SAVE_STATE_MAP *)CpuState;
|
---|
72 | if ((CpuSaveState->x86.SMMRevId & 0xFFFF) == 0) {
|
---|
73 | OriginalInstructionPointer = (UINT64)CpuSaveState->x86._EIP;
|
---|
74 | CpuSaveState->x86._EIP = (UINT32)NewInstructionPointer;
|
---|
75 | //
|
---|
76 | // Clear the auto HALT restart flag so the RSM instruction returns
|
---|
77 | // program control to the instruction following the HLT instruction.
|
---|
78 | //
|
---|
79 | if ((CpuSaveState->x86.AutoHALTRestart & BIT0) != 0) {
|
---|
80 | CpuSaveState->x86.AutoHALTRestart &= ~BIT0;
|
---|
81 | }
|
---|
82 | } else {
|
---|
83 | OriginalInstructionPointer = CpuSaveState->x64._RIP;
|
---|
84 | if ((CpuSaveState->x64.EFER & LMA) == 0) {
|
---|
85 | CpuSaveState->x64._RIP = (UINT32)NewInstructionPointer32;
|
---|
86 | } else {
|
---|
87 | CpuSaveState->x64._RIP = (UINT32)NewInstructionPointer;
|
---|
88 | }
|
---|
89 |
|
---|
90 | //
|
---|
91 | // Clear the auto HALT restart flag so the RSM instruction returns
|
---|
92 | // program control to the instruction following the HLT instruction.
|
---|
93 | //
|
---|
94 | if ((CpuSaveState->x64.AutoHALTRestart & BIT0) != 0) {
|
---|
95 | CpuSaveState->x64.AutoHALTRestart &= ~BIT0;
|
---|
96 | }
|
---|
97 | }
|
---|
98 |
|
---|
99 | return OriginalInstructionPointer;
|
---|
100 | }
|
---|