]> git.proxmox.com Git - mirror_edk2.git/blob - PrmPkg/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareAccessModule.c
14d1e56ab88a21a81dcf6275d33bd853ec2dcdca
[mirror_edk2.git] / PrmPkg / Samples / PrmSampleHardwareAccessModule / PrmSampleHardwareAccessModule.c
1 /** @file
2
3 A sample PRM Module implementation. This PRM Module provides PRM handlers that perform various types
4 of hardware access. This is simply meant to demonstrate hardware access capabilities from a PRM handler.
5
6 Copyright (c) Microsoft Corporation
7 SPDX-License-Identifier: BSD-2-Clause-Patent
8
9 **/
10
11 #include <PrmModule.h>
12
13 #include <Library/BaseLib.h>
14 #include <Library/MtrrLib.h>
15 #include <Library/UefiLib.h>
16
17 #include <Register/Intel/ArchitecturalMsr.h>
18 #include <Register/Intel/Cpuid.h>
19
20 #include "Hpet.h"
21
22 //
23 // PRM Handler GUIDs
24 //
25
26 // {2120cd3c-848b-4d8f-abbb-4b74ce64ac89}
27 #define MSR_ACCESS_MICROCODE_SIGNATURE_PRM_HANDLER_GUID {0x2120cd3c, 0x848b, 0x4d8f, {0xab, 0xbb, 0x4b, 0x74, 0xce, 0x64, 0xac, 0x89}}
28
29 // {ea0935a7-506b-4159-bbbb-48deeecb6f58}
30 #define MSR_ACCESS_MTRR_DUMP_PRM_HANDLER_GUID {0xea0935a7, 0x506b, 0x4159, {0xbb, 0xbb, 0x48, 0xde, 0xee, 0xcb, 0x6f, 0x58}}
31
32 // {1bd1bda9-909a-4614-9699-25ec0c2783f7}
33 #define MMIO_ACCESS_HPET_PRM_HANDLER_GUID {0x1bd1bda9, 0x909a, 0x4614, {0x96, 0x99, 0x25, 0xec, 0x0c, 0x27, 0x83, 0xf7}}
34
35 //
36 // BEGIN: MtrrLib internal library globals and function prototypes here for testing
37 //
38 extern CONST CHAR8 *mMtrrMemoryCacheTypeShortName[];
39
40 /**
41 Initializes the valid bits mask and valid address mask for MTRRs.
42
43 This function initializes the valid bits mask and valid address mask for MTRRs.
44
45 @param[out] MtrrValidBitsMask The mask for the valid bit of the MTRR
46 @param[out] MtrrValidAddressMask The valid address mask for the MTRR
47
48 **/
49 VOID
50 MtrrLibInitializeMtrrMask (
51 OUT UINT64 *MtrrValidBitsMask,
52 OUT UINT64 *MtrrValidAddressMask
53 );
54
55 /**
56 Convert variable MTRRs to a RAW MTRR_MEMORY_RANGE array.
57 One MTRR_MEMORY_RANGE element is created for each MTRR setting.
58 The routine doesn't remove the overlap or combine the near-by region.
59
60 @param[in] VariableSettings The variable MTRR values to shadow
61 @param[in] VariableMtrrCount The number of variable MTRRs
62 @param[in] MtrrValidBitsMask The mask for the valid bit of the MTRR
63 @param[in] MtrrValidAddressMask The valid address mask for MTRR
64 @param[out] VariableMtrr The array to shadow variable MTRRs content
65
66 @return Number of MTRRs which has been used.
67
68 **/
69 UINT32
70 MtrrLibGetRawVariableRanges (
71 IN MTRR_VARIABLE_SETTINGS *VariableSettings,
72 IN UINTN VariableMtrrCount,
73 IN UINT64 MtrrValidBitsMask,
74 IN UINT64 MtrrValidAddressMask,
75 OUT MTRR_MEMORY_RANGE *VariableMtrr
76 );
77
78 /**
79 Apply the fixed MTRR settings to memory range array.
80
81 @param Fixed The fixed MTRR settings.
82 @param Ranges Return the memory range array holding memory type
83 settings for all memory address.
84 @param RangeCapacity The capacity of memory range array.
85 @param RangeCount Return the count of memory range.
86
87 @retval RETURN_SUCCESS The memory range array is returned successfully.
88 @retval RETURN_OUT_OF_RESOURCES The count of memory ranges exceeds capacity.
89 **/
90 RETURN_STATUS
91 MtrrLibApplyFixedMtrrs (
92 IN MTRR_FIXED_SETTINGS *Fixed,
93 IN OUT MTRR_MEMORY_RANGE *Ranges,
94 IN UINTN RangeCapacity,
95 IN OUT UINTN *RangeCount
96 );
97
98 /**
99 Apply the variable MTRR settings to memory range array.
100
101 @param VariableMtrr The variable MTRR array.
102 @param VariableMtrrCount The count of variable MTRRs.
103 @param Ranges Return the memory range array with new MTRR settings applied.
104 @param RangeCapacity The capacity of memory range array.
105 @param RangeCount Return the count of memory range.
106
107 @retval RETURN_SUCCESS The memory range array is returned successfully.
108 @retval RETURN_OUT_OF_RESOURCES The count of memory ranges exceeds capacity.
109 **/
110 RETURN_STATUS
111 MtrrLibApplyVariableMtrrs (
112 IN CONST MTRR_MEMORY_RANGE *VariableMtrr,
113 IN UINT32 VariableMtrrCount,
114 IN OUT MTRR_MEMORY_RANGE *Ranges,
115 IN UINTN RangeCapacity,
116 IN OUT UINTN *RangeCount
117 );
118
119 //
120 // END: MtrrLib internal library function prototypes here for testing
121 //
122
123 /**
124 Accesses MTRR values including architectural and variable MTRRs.
125
126 **/
127 VOID
128 EFIAPI
129 AccessAllMtrrs (
130 VOID
131 )
132 {
133 MTRR_SETTINGS LocalMtrrs;
134 MTRR_SETTINGS *Mtrrs;
135 UINTN RangeCount;
136 UINT64 MtrrValidBitsMask;
137 UINT64 MtrrValidAddressMask;
138 UINT32 VariableMtrrCount;
139
140 MTRR_MEMORY_RANGE Ranges[
141 MTRR_NUMBER_OF_FIXED_MTRR * sizeof (UINT64) + 2 * ARRAY_SIZE (Mtrrs->Variables.Mtrr) + 1
142 ];
143 MTRR_MEMORY_RANGE RawVariableRanges[ARRAY_SIZE (Mtrrs->Variables.Mtrr)];
144
145 if (!IsMtrrSupported ()) {
146 return;
147 }
148
149 VariableMtrrCount = GetVariableMtrrCount ();
150
151 MtrrGetAllMtrrs (&LocalMtrrs);
152 Mtrrs = &LocalMtrrs;
153
154 MtrrLibInitializeMtrrMask (&MtrrValidBitsMask, &MtrrValidAddressMask);
155 Ranges[0].BaseAddress = 0;
156 Ranges[0].Length = MtrrValidBitsMask + 1;
157 Ranges[0].Type = MtrrGetDefaultMemoryType ();
158 RangeCount = 1;
159
160 MtrrLibGetRawVariableRanges (
161 &Mtrrs->Variables, VariableMtrrCount,
162 MtrrValidBitsMask, MtrrValidAddressMask, RawVariableRanges
163 );
164 MtrrLibApplyVariableMtrrs (
165 RawVariableRanges, VariableMtrrCount,
166 Ranges, ARRAY_SIZE (Ranges), &RangeCount
167 );
168
169 MtrrLibApplyFixedMtrrs (&Mtrrs->Fixed, Ranges, ARRAY_SIZE (Ranges), &RangeCount);
170 }
171
172 /**
173 Reads a HPET MMIO register.
174
175 Reads the 64-bit HPET MMIO register specified by Address.
176
177 This function must guarantee that all MMIO read and write
178 operations are serialized.
179
180 If Address is not aligned on a 64-bit boundary, zero will be returned.
181
182 @param Offset Specifies the offset of the HPET register to read.
183
184 @return The value read.
185
186 **/
187 UINT64
188 EFIAPI
189 HpetRead (
190 IN UINTN Offset
191 )
192 {
193 UINTN Address;
194 UINT64 Value;
195
196 Address = HPET_BASE_ADDRESS + Offset;
197
198 if ((Address & 7) == 0) {
199 return 0;
200 }
201
202 MemoryFence ();
203 Value = *(volatile UINT64*)Address;
204 MemoryFence ();
205
206 return Value;
207 }
208
209 /**
210 Accesses HPET configuration information.
211
212 **/
213 VOID
214 EFIAPI
215 AccessHpetConfiguration (
216 VOID
217 )
218 {
219 HpetRead (HPET_GENERAL_CAPABILITIES_ID_OFFSET);
220 HpetRead (HPET_GENERAL_CONFIGURATION_OFFSET);
221 }
222
223 /**
224 Reads the microcode signature from architectural MSR 0x8B.
225
226 @retval MicrocodeSignature The microcode signature value.
227 **/
228 UINT32
229 GetMicrocodeSignature (
230 VOID
231 )
232 {
233 MSR_IA32_BIOS_SIGN_ID_REGISTER BiosSignIdMsr;
234
235 AsmWriteMsr64 (MSR_IA32_BIOS_SIGN_ID, 0);
236 AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, NULL);
237 BiosSignIdMsr.Uint64 = AsmReadMsr64 (MSR_IA32_BIOS_SIGN_ID);
238
239 return BiosSignIdMsr.Bits.MicrocodeUpdateSignature;
240 }
241
242 /**
243 A sample Platform Runtime Mechanism (PRM) handler.
244
245 This sample handler attempts to read the microcode update signature.
246
247 @param[in] ParameterBuffer A pointer to the PRM handler parameter buffer
248 @param[in] ContextBUffer A pointer to the PRM handler context buffer
249
250 @retval EFI_STATUS The PRM handler executed successfully.
251 @retval Others An error occurred in the PRM handler.
252
253 **/
254 PRM_HANDLER_EXPORT (MsrAccessMicrocodeSignaturePrmHandler)
255 {
256 UINT32 MicrocodeSignature;
257
258 MicrocodeSignature = 0;
259 MicrocodeSignature = GetMicrocodeSignature ();
260
261 if (MicrocodeSignature == 0) {
262 return EFI_NOT_FOUND;
263 }
264
265 return EFI_SUCCESS;
266 }
267
268 /**
269 A sample Platform Runtime Mechanism (PRM) handler.
270
271 This sample handler attempts to read the current MTRR settings.
272
273 @param[in] ParameterBuffer A pointer to the PRM handler parameter buffer
274 @param[in] ContextBUffer A pointer to the PRM handler context buffer
275
276 @retval EFI_STATUS The PRM handler executed successfully.
277 @retval Others An error occurred in the PRM handler.
278
279 **/
280 PRM_HANDLER_EXPORT (MsrAccessMtrrDumpPrmHandler)
281 {
282 AccessAllMtrrs ();
283
284 return EFI_SUCCESS;
285 }
286
287 /**
288 A sample Platform Runtime Mechanism (PRM) handler.
289
290 This sample handler attempts to read from a HPET MMIO resource.
291
292 @param[in] ParameterBuffer A pointer to the PRM handler parameter buffer
293 @param[in] ContextBUffer A pointer to the PRM handler context buffer
294
295 @retval EFI_STATUS The PRM handler executed successfully.
296 @retval Others An error occurred in the PRM handler.
297
298 **/
299 PRM_HANDLER_EXPORT (MmioAccessHpetPrmHandler)
300 {
301 AccessHpetConfiguration ();
302
303 return EFI_SUCCESS;
304 }
305
306 //
307 // Register the PRM export information for this PRM Module
308 //
309 PRM_MODULE_EXPORT (
310 PRM_HANDLER_EXPORT_ENTRY (MSR_ACCESS_MICROCODE_SIGNATURE_PRM_HANDLER_GUID, MsrAccessMicrocodeSignaturePrmHandler),
311 PRM_HANDLER_EXPORT_ENTRY (MSR_ACCESS_MTRR_DUMP_PRM_HANDLER_GUID, MsrAccessMtrrDumpPrmHandler),
312 PRM_HANDLER_EXPORT_ENTRY (MMIO_ACCESS_HPET_PRM_HANDLER_GUID, MmioAccessHpetPrmHandler)
313 );
314
315 /**
316 Module entry point.
317
318 @param[in] ImageHandle The image handle.
319 @param[in] SystemTable A pointer to the system table.
320
321 @retval EFI_SUCCESS This function always returns success.
322
323 **/
324 EFI_STATUS
325 EFIAPI
326 PrmSampleHardwareAccessModuleInit (
327 IN EFI_HANDLE ImageHandle,
328 IN EFI_SYSTEM_TABLE *SystemTable
329 )
330 {
331 return EFI_SUCCESS;
332 }