VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/FirmwareNew/OvmfPkg/SmmAccess/SmramInternal.c@ 80820

Last change on this file since 80820 was 80721, checked in by vboxsync, 5 years ago

Devices/EFI/FirmwareNew: Start upgrade process to edk2-stable201908 (compiles on Windows and works to some extent), bugref:4643

  • Property svn:eol-style set to native
File size: 5.4 KB
Line 
1/** @file
2
3 Functions and types shared by the SMM accessor PEI and DXE modules.
4
5 Copyright (C) 2015, Red Hat, Inc.
6
7 SPDX-License-Identifier: BSD-2-Clause-Patent
8
9**/
10
11#include <Guid/AcpiS3Context.h>
12#include <IndustryStandard/Q35MchIch9.h>
13#include <Library/DebugLib.h>
14#include <Library/PcdLib.h>
15#include <Library/PciLib.h>
16
17#include "SmramInternal.h"
18
19//
20// The value of PcdQ35TsegMbytes is saved into this variable at module startup.
21//
22UINT16 mQ35TsegMbytes;
23
24/**
25 Save PcdQ35TsegMbytes into mQ35TsegMbytes.
26**/
27VOID
28InitQ35TsegMbytes (
29 VOID
30 )
31{
32 mQ35TsegMbytes = PcdGet16 (PcdQ35TsegMbytes);
33}
34
35/**
36 Read the MCH_SMRAM and ESMRAMC registers, and update the LockState and
37 OpenState fields in the PEI_SMM_ACCESS_PPI / EFI_SMM_ACCESS2_PROTOCOL object,
38 from the D_LCK and T_EN bits.
39
40 PEI_SMM_ACCESS_PPI and EFI_SMM_ACCESS2_PROTOCOL member functions can rely on
41 the LockState and OpenState fields being up-to-date on entry, and they need
42 to restore the same invariant on exit, if they touch the bits in question.
43
44 @param[out] LockState Reflects the D_LCK bit on output; TRUE iff SMRAM is
45 locked.
46 @param[out] OpenState Reflects the inverse of the T_EN bit on output; TRUE
47 iff SMRAM is open.
48**/
49VOID
50GetStates (
51 OUT BOOLEAN *LockState,
52 OUT BOOLEAN *OpenState
53)
54{
55 UINT8 SmramVal, EsmramcVal;
56
57 SmramVal = PciRead8 (DRAMC_REGISTER_Q35 (MCH_SMRAM));
58 EsmramcVal = PciRead8 (DRAMC_REGISTER_Q35 (MCH_ESMRAMC));
59
60 *LockState = !!(SmramVal & MCH_SMRAM_D_LCK);
61 *OpenState = !(EsmramcVal & MCH_ESMRAMC_T_EN);
62}
63
64//
65// The functions below follow the PEI_SMM_ACCESS_PPI and
66// EFI_SMM_ACCESS2_PROTOCOL member declarations. The PeiServices and This
67// pointers are removed (TSEG doesn't depend on them), and so is the
68// DescriptorIndex parameter (TSEG doesn't support range-wise locking).
69//
70// The LockState and OpenState members that are common to both
71// PEI_SMM_ACCESS_PPI and EFI_SMM_ACCESS2_PROTOCOL are taken and updated in
72// isolation from the rest of the (non-shared) members.
73//
74
75EFI_STATUS
76SmramAccessOpen (
77 OUT BOOLEAN *LockState,
78 OUT BOOLEAN *OpenState
79 )
80{
81 //
82 // Open TSEG by clearing T_EN.
83 //
84 PciAnd8 (DRAMC_REGISTER_Q35 (MCH_ESMRAMC),
85 (UINT8)((~(UINT32)MCH_ESMRAMC_T_EN) & 0xff));
86
87 GetStates (LockState, OpenState);
88 if (!*OpenState) {
89 return EFI_DEVICE_ERROR;
90 }
91 return EFI_SUCCESS;
92}
93
94EFI_STATUS
95SmramAccessClose (
96 OUT BOOLEAN *LockState,
97 OUT BOOLEAN *OpenState
98 )
99{
100 //
101 // Close TSEG by setting T_EN.
102 //
103 PciOr8 (DRAMC_REGISTER_Q35 (MCH_ESMRAMC), MCH_ESMRAMC_T_EN);
104
105 GetStates (LockState, OpenState);
106 if (*OpenState) {
107 return EFI_DEVICE_ERROR;
108 }
109 return EFI_SUCCESS;
110}
111
112EFI_STATUS
113SmramAccessLock (
114 OUT BOOLEAN *LockState,
115 IN OUT BOOLEAN *OpenState
116 )
117{
118 if (*OpenState) {
119 return EFI_DEVICE_ERROR;
120 }
121
122 //
123 // Close & lock TSEG by setting T_EN and D_LCK.
124 //
125 PciOr8 (DRAMC_REGISTER_Q35 (MCH_ESMRAMC), MCH_ESMRAMC_T_EN);
126 PciOr8 (DRAMC_REGISTER_Q35 (MCH_SMRAM), MCH_SMRAM_D_LCK);
127
128 GetStates (LockState, OpenState);
129 if (*OpenState || !*LockState) {
130 return EFI_DEVICE_ERROR;
131 }
132 return EFI_SUCCESS;
133}
134
135EFI_STATUS
136SmramAccessGetCapabilities (
137 IN BOOLEAN LockState,
138 IN BOOLEAN OpenState,
139 IN OUT UINTN *SmramMapSize,
140 IN OUT EFI_SMRAM_DESCRIPTOR *SmramMap
141 )
142{
143 UINTN OriginalSize;
144 UINT32 TsegMemoryBaseMb, TsegMemoryBase;
145 UINT64 CommonRegionState;
146 UINT8 TsegSizeBits;
147
148 OriginalSize = *SmramMapSize;
149 *SmramMapSize = DescIdxCount * sizeof *SmramMap;
150 if (OriginalSize < *SmramMapSize) {
151 return EFI_BUFFER_TOO_SMALL;
152 }
153
154 //
155 // Read the TSEG Memory Base register.
156 //
157 TsegMemoryBaseMb = PciRead32 (DRAMC_REGISTER_Q35 (MCH_TSEGMB));
158 TsegMemoryBase = (TsegMemoryBaseMb >> MCH_TSEGMB_MB_SHIFT) << 20;
159
160 //
161 // Precompute the region state bits that will be set for all regions.
162 //
163 CommonRegionState = (OpenState ? EFI_SMRAM_OPEN : EFI_SMRAM_CLOSED) |
164 (LockState ? EFI_SMRAM_LOCKED : 0) |
165 EFI_CACHEABLE;
166
167 //
168 // The first region hosts an SMM_S3_RESUME_STATE object. It is located at the
169 // start of TSEG. We round up the size to whole pages, and we report it as
170 // EFI_ALLOCATED, so that the SMM_CORE stays away from it.
171 //
172 SmramMap[DescIdxSmmS3ResumeState].PhysicalStart = TsegMemoryBase;
173 SmramMap[DescIdxSmmS3ResumeState].CpuStart = TsegMemoryBase;
174 SmramMap[DescIdxSmmS3ResumeState].PhysicalSize =
175 EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (sizeof (SMM_S3_RESUME_STATE)));
176 SmramMap[DescIdxSmmS3ResumeState].RegionState =
177 CommonRegionState | EFI_ALLOCATED;
178
179 //
180 // Get the TSEG size bits from the ESMRAMC register.
181 //
182 TsegSizeBits = PciRead8 (DRAMC_REGISTER_Q35 (MCH_ESMRAMC)) &
183 MCH_ESMRAMC_TSEG_MASK;
184
185 //
186 // The second region is the main one, following the first.
187 //
188 SmramMap[DescIdxMain].PhysicalStart =
189 SmramMap[DescIdxSmmS3ResumeState].PhysicalStart +
190 SmramMap[DescIdxSmmS3ResumeState].PhysicalSize;
191 SmramMap[DescIdxMain].CpuStart = SmramMap[DescIdxMain].PhysicalStart;
192 SmramMap[DescIdxMain].PhysicalSize =
193 (TsegSizeBits == MCH_ESMRAMC_TSEG_8MB ? SIZE_8MB :
194 TsegSizeBits == MCH_ESMRAMC_TSEG_2MB ? SIZE_2MB :
195 TsegSizeBits == MCH_ESMRAMC_TSEG_1MB ? SIZE_1MB :
196 mQ35TsegMbytes * SIZE_1MB) -
197 SmramMap[DescIdxSmmS3ResumeState].PhysicalSize;
198 SmramMap[DescIdxMain].RegionState = CommonRegionState;
199
200 return EFI_SUCCESS;
201}
Note: See TracBrowser for help on using the repository browser.

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