]> git.proxmox.com Git - mirror_edk2.git/blob - UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibCommon.c
50379f3aea1945ac0158ba2882644722810d8107
[mirror_edk2.git] / UefiCpuPkg / Library / SmmCpuFeaturesLib / SmmCpuFeaturesLibCommon.c
1 /** @file
2 Implementation shared across all library instances.
3
4 Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.<BR>
5 Copyright (c) Microsoft Corporation.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8 **/
9
10 #include <PiSmm.h>
11 #include <Library/SmmCpuFeaturesLib.h>
12 #include <Library/BaseLib.h>
13 #include <Library/MtrrLib.h>
14 #include <Library/PcdLib.h>
15 #include <Library/MemoryAllocationLib.h>
16 #include <Library/DebugLib.h>
17 #include <Register/Intel/Cpuid.h>
18 #include <Register/Intel/SmramSaveStateMap.h>
19 #include "CpuFeaturesLib.h"
20
21 //
22 // Machine Specific Registers (MSRs)
23 //
24 #define SMM_FEATURES_LIB_IA32_MTRR_CAP 0x0FE
25 #define SMM_FEATURES_LIB_IA32_FEATURE_CONTROL 0x03A
26 #define SMM_FEATURES_LIB_IA32_SMRR_PHYSBASE 0x1F2
27 #define SMM_FEATURES_LIB_IA32_SMRR_PHYSMASK 0x1F3
28 #define SMM_FEATURES_LIB_IA32_CORE_SMRR_PHYSBASE 0x0A0
29 #define SMM_FEATURES_LIB_IA32_CORE_SMRR_PHYSMASK 0x0A1
30 #define EFI_MSR_SMRR_MASK 0xFFFFF000
31 #define EFI_MSR_SMRR_PHYS_MASK_VALID BIT11
32 #define SMM_FEATURES_LIB_SMM_FEATURE_CONTROL 0x4E0
33
34 //
35 // MSRs required for configuration of SMM Code Access Check
36 //
37 #define SMM_FEATURES_LIB_IA32_MCA_CAP 0x17D
38 #define SMM_CODE_ACCESS_CHK_BIT BIT58
39
40 //
41 // Set default value to assume SMRR is not supported
42 //
43 BOOLEAN mSmrrSupported = FALSE;
44
45 //
46 // Set default value to assume MSR_SMM_FEATURE_CONTROL is not supported
47 //
48 BOOLEAN mSmmFeatureControlSupported = FALSE;
49
50 //
51 // Set default value to assume IA-32 Architectural MSRs are used
52 //
53 UINT32 mSmrrPhysBaseMsr = SMM_FEATURES_LIB_IA32_SMRR_PHYSBASE;
54 UINT32 mSmrrPhysMaskMsr = SMM_FEATURES_LIB_IA32_SMRR_PHYSMASK;
55
56 //
57 // Set default value to assume MTRRs need to be configured on each SMI
58 //
59 BOOLEAN mNeedConfigureMtrrs = TRUE;
60
61 //
62 // Array for state of SMRR enable on all CPUs
63 //
64 BOOLEAN *mSmrrEnabled;
65
66 /**
67 Performs library initialization.
68
69 This initialization function contains common functionality shared betwen all
70 library instance constructors.
71
72 **/
73 VOID
74 CpuFeaturesLibInitialization (
75 VOID
76 )
77 {
78 UINT32 RegEax;
79 UINT32 RegEdx;
80 UINTN FamilyId;
81 UINTN ModelId;
82
83 //
84 // Retrieve CPU Family and Model
85 //
86 AsmCpuid (CPUID_VERSION_INFO, &RegEax, NULL, NULL, &RegEdx);
87 FamilyId = (RegEax >> 8) & 0xf;
88 ModelId = (RegEax >> 4) & 0xf;
89 if (FamilyId == 0x06 || FamilyId == 0x0f) {
90 ModelId = ModelId | ((RegEax >> 12) & 0xf0);
91 }
92
93 //
94 // Check CPUID(CPUID_VERSION_INFO).EDX[12] for MTRR capability
95 //
96 if ((RegEdx & BIT12) != 0) {
97 //
98 // Check MTRR_CAP MSR bit 11 for SMRR support
99 //
100 if ((AsmReadMsr64 (SMM_FEATURES_LIB_IA32_MTRR_CAP) & BIT11) != 0) {
101 mSmrrSupported = TRUE;
102 }
103 }
104
105 //
106 // Intel(R) 64 and IA-32 Architectures Software Developer's Manual
107 // Volume 3C, Section 35.3 MSRs in the Intel(R) Atom(TM) Processor Family
108 //
109 // If CPU Family/Model is 06_1CH, 06_26H, 06_27H, 06_35H or 06_36H, then
110 // SMRR Physical Base and SMM Physical Mask MSRs are not available.
111 //
112 if (FamilyId == 0x06) {
113 if (ModelId == 0x1C || ModelId == 0x26 || ModelId == 0x27 || ModelId == 0x35 || ModelId == 0x36) {
114 mSmrrSupported = FALSE;
115 }
116 }
117
118 //
119 // Intel(R) 64 and IA-32 Architectures Software Developer's Manual
120 // Volume 3C, Section 35.2 MSRs in the Intel(R) Core(TM) 2 Processor Family
121 //
122 // If CPU Family/Model is 06_0F or 06_17, then use Intel(R) Core(TM) 2
123 // Processor Family MSRs
124 //
125 if (FamilyId == 0x06) {
126 if (ModelId == 0x17 || ModelId == 0x0f) {
127 mSmrrPhysBaseMsr = SMM_FEATURES_LIB_IA32_CORE_SMRR_PHYSBASE;
128 mSmrrPhysMaskMsr = SMM_FEATURES_LIB_IA32_CORE_SMRR_PHYSMASK;
129 }
130 }
131
132 //
133 // Intel(R) 64 and IA-32 Architectures Software Developer's Manual
134 // Volume 3C, Section 34.4.2 SMRAM Caching
135 // An IA-32 processor does not automatically write back and invalidate its
136 // caches before entering SMM or before exiting SMM. Because of this behavior,
137 // care must be taken in the placement of the SMRAM in system memory and in
138 // the caching of the SMRAM to prevent cache incoherence when switching back
139 // and forth between SMM and protected mode operation.
140 //
141 // An IA-32 processor is a processor that does not support the Intel 64
142 // Architecture. Support for the Intel 64 Architecture can be detected from
143 // CPUID(CPUID_EXTENDED_CPU_SIG).EDX[29]
144 //
145 // If an IA-32 processor is detected, then set mNeedConfigureMtrrs to TRUE,
146 // so caches are flushed on SMI entry and SMI exit, the interrupted code
147 // MTRRs are saved/restored, and MTRRs for SMM are loaded.
148 //
149 AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);
150 if (RegEax >= CPUID_EXTENDED_CPU_SIG) {
151 AsmCpuid (CPUID_EXTENDED_CPU_SIG, NULL, NULL, NULL, &RegEdx);
152 if ((RegEdx & BIT29) != 0) {
153 mNeedConfigureMtrrs = FALSE;
154 }
155 }
156
157 //
158 // Allocate array for state of SMRR enable on all CPUs
159 //
160 mSmrrEnabled = (BOOLEAN *)AllocatePool (sizeof (BOOLEAN) * GetCpuMaxLogicalProcessorNumber ());
161 ASSERT (mSmrrEnabled != NULL);
162 }
163
164 /**
165 Called during the very first SMI into System Management Mode to initialize
166 CPU features, including SMBASE, for the currently executing CPU. Since this
167 is the first SMI, the SMRAM Save State Map is at the default address of
168 SMM_DEFAULT_SMBASE + SMRAM_SAVE_STATE_MAP_OFFSET. The currently executing
169 CPU is specified by CpuIndex and CpuIndex can be used to access information
170 about the currently executing CPU in the ProcessorInfo array and the
171 HotPlugCpuData data structure.
172
173 @param[in] CpuIndex The index of the CPU to initialize. The value
174 must be between 0 and the NumberOfCpus field in
175 the System Management System Table (SMST).
176 @param[in] IsMonarch TRUE if the CpuIndex is the index of the CPU that
177 was elected as monarch during System Management
178 Mode initialization.
179 FALSE if the CpuIndex is not the index of the CPU
180 that was elected as monarch during System
181 Management Mode initialization.
182 @param[in] ProcessorInfo Pointer to an array of EFI_PROCESSOR_INFORMATION
183 structures. ProcessorInfo[CpuIndex] contains the
184 information for the currently executing CPU.
185 @param[in] CpuHotPlugData Pointer to the CPU_HOT_PLUG_DATA structure that
186 contains the ApidId and SmBase arrays.
187 **/
188 VOID
189 EFIAPI
190 SmmCpuFeaturesInitializeProcessor (
191 IN UINTN CpuIndex,
192 IN BOOLEAN IsMonarch,
193 IN EFI_PROCESSOR_INFORMATION *ProcessorInfo,
194 IN CPU_HOT_PLUG_DATA *CpuHotPlugData
195 )
196 {
197 SMRAM_SAVE_STATE_MAP *CpuState;
198 UINT64 FeatureControl;
199 UINT32 RegEax;
200 UINT32 RegEdx;
201 UINTN FamilyId;
202 UINTN ModelId;
203
204 //
205 // Configure SMBASE.
206 //
207 CpuState = (SMRAM_SAVE_STATE_MAP *)(UINTN)(SMM_DEFAULT_SMBASE + SMRAM_SAVE_STATE_MAP_OFFSET);
208 CpuState->x86.SMBASE = (UINT32)CpuHotPlugData->SmBase[CpuIndex];
209
210 //
211 // Intel(R) 64 and IA-32 Architectures Software Developer's Manual
212 // Volume 3C, Section 35.2 MSRs in the Intel(R) Core(TM) 2 Processor Family
213 //
214 // If Intel(R) Core(TM) Core(TM) 2 Processor Family MSRs are being used, then
215 // make sure SMRR Enable(BIT3) of MSR_FEATURE_CONTROL MSR(0x3A) is set before
216 // accessing SMRR base/mask MSRs. If Lock(BIT0) of MSR_FEATURE_CONTROL MSR(0x3A)
217 // is set, then the MSR is locked and can not be modified.
218 //
219 if (mSmrrSupported && mSmrrPhysBaseMsr == SMM_FEATURES_LIB_IA32_CORE_SMRR_PHYSBASE) {
220 FeatureControl = AsmReadMsr64 (SMM_FEATURES_LIB_IA32_FEATURE_CONTROL);
221 if ((FeatureControl & BIT3) == 0) {
222 if ((FeatureControl & BIT0) == 0) {
223 AsmWriteMsr64 (SMM_FEATURES_LIB_IA32_FEATURE_CONTROL, FeatureControl | BIT3);
224 } else {
225 mSmrrSupported = FALSE;
226 }
227 }
228 }
229
230 //
231 // If SMRR is supported, then program SMRR base/mask MSRs.
232 // The EFI_MSR_SMRR_PHYS_MASK_VALID bit is not set until the first normal SMI.
233 // The code that initializes SMM environment is running in normal mode
234 // from SMRAM region. If SMRR is enabled here, then the SMRAM region
235 // is protected and the normal mode code execution will fail.
236 //
237 if (mSmrrSupported) {
238 //
239 // SMRR size cannot be less than 4-KBytes
240 // SMRR size must be of length 2^n
241 // SMRR base alignment cannot be less than SMRR length
242 //
243 if ((CpuHotPlugData->SmrrSize < SIZE_4KB) ||
244 (CpuHotPlugData->SmrrSize != GetPowerOfTwo32 (CpuHotPlugData->SmrrSize)) ||
245 ((CpuHotPlugData->SmrrBase & ~(CpuHotPlugData->SmrrSize - 1)) != CpuHotPlugData->SmrrBase)) {
246 //
247 // Print message and halt if CPU is Monarch
248 //
249 if (IsMonarch) {
250 DEBUG ((DEBUG_ERROR, "SMM Base/Size does not meet alignment/size requirement!\n"));
251 CpuDeadLoop ();
252 }
253 } else {
254 AsmWriteMsr64 (mSmrrPhysBaseMsr, CpuHotPlugData->SmrrBase | MTRR_CACHE_WRITE_BACK);
255 AsmWriteMsr64 (mSmrrPhysMaskMsr, (~(CpuHotPlugData->SmrrSize - 1) & EFI_MSR_SMRR_MASK));
256 mSmrrEnabled[CpuIndex] = FALSE;
257 }
258 }
259
260 //
261 // Retrieve CPU Family and Model
262 //
263 AsmCpuid (CPUID_VERSION_INFO, &RegEax, NULL, NULL, &RegEdx);
264 FamilyId = (RegEax >> 8) & 0xf;
265 ModelId = (RegEax >> 4) & 0xf;
266 if (FamilyId == 0x06 || FamilyId == 0x0f) {
267 ModelId = ModelId | ((RegEax >> 12) & 0xf0);
268 }
269
270 //
271 // Intel(R) 64 and IA-32 Architectures Software Developer's Manual
272 // Volume 3C, Section 35.10.1 MSRs in 4th Generation Intel(R) Core(TM)
273 // Processor Family.
274 //
275 // If CPU Family/Model is 06_3C, 06_45, or 06_46 then use 4th Generation
276 // Intel(R) Core(TM) Processor Family MSRs.
277 //
278 if (FamilyId == 0x06) {
279 if (ModelId == 0x3C || ModelId == 0x45 || ModelId == 0x46 ||
280 ModelId == 0x3D || ModelId == 0x47 || ModelId == 0x4E || ModelId == 0x4F ||
281 ModelId == 0x3F || ModelId == 0x56 || ModelId == 0x57 || ModelId == 0x5C ||
282 ModelId == 0x8C) {
283 //
284 // Check to see if the CPU supports the SMM Code Access Check feature
285 // Do not access this MSR unless the CPU supports the SmmRegFeatureControl
286 //
287 if ((AsmReadMsr64 (SMM_FEATURES_LIB_IA32_MCA_CAP) & SMM_CODE_ACCESS_CHK_BIT) != 0) {
288 mSmmFeatureControlSupported = TRUE;
289 }
290 }
291 }
292
293 //
294 // Call internal worker function that completes the CPU initialization
295 //
296 FinishSmmCpuFeaturesInitializeProcessor ();
297 }
298
299 /**
300 This function updates the SMRAM save state on the currently executing CPU
301 to resume execution at a specific address after an RSM instruction. This
302 function must evaluate the SMRAM save state to determine the execution mode
303 the RSM instruction resumes and update the resume execution address with
304 either NewInstructionPointer32 or NewInstructionPoint. The auto HALT restart
305 flag in the SMRAM save state must always be cleared. This function returns
306 the value of the instruction pointer from the SMRAM save state that was
307 replaced. If this function returns 0, then the SMRAM save state was not
308 modified.
309
310 This function is called during the very first SMI on each CPU after
311 SmmCpuFeaturesInitializeProcessor() to set a flag in normal execution mode
312 to signal that the SMBASE of each CPU has been updated before the default
313 SMBASE address is used for the first SMI to the next CPU.
314
315 @param[in] CpuIndex The index of the CPU to hook. The value
316 must be between 0 and the NumberOfCpus
317 field in the System Management System Table
318 (SMST).
319 @param[in] CpuState Pointer to SMRAM Save State Map for the
320 currently executing CPU.
321 @param[in] NewInstructionPointer32 Instruction pointer to use if resuming to
322 32-bit execution mode from 64-bit SMM.
323 @param[in] NewInstructionPointer Instruction pointer to use if resuming to
324 same execution mode as SMM.
325
326 @retval 0 This function did modify the SMRAM save state.
327 @retval > 0 The original instruction pointer value from the SMRAM save state
328 before it was replaced.
329 **/
330 UINT64
331 EFIAPI
332 SmmCpuFeaturesHookReturnFromSmm (
333 IN UINTN CpuIndex,
334 IN SMRAM_SAVE_STATE_MAP *CpuState,
335 IN UINT64 NewInstructionPointer32,
336 IN UINT64 NewInstructionPointer
337 )
338 {
339 return 0;
340 }
341
342 /**
343 Hook point in normal execution mode that allows the one CPU that was elected
344 as monarch during System Management Mode initialization to perform additional
345 initialization actions immediately after all of the CPUs have processed their
346 first SMI and called SmmCpuFeaturesInitializeProcessor() relocating SMBASE
347 into a buffer in SMRAM and called SmmCpuFeaturesHookReturnFromSmm().
348 **/
349 VOID
350 EFIAPI
351 SmmCpuFeaturesSmmRelocationComplete (
352 VOID
353 )
354 {
355 }
356
357 /**
358 Determines if MTRR registers must be configured to set SMRAM cache-ability
359 when executing in System Management Mode.
360
361 @retval TRUE MTRR registers must be configured to set SMRAM cache-ability.
362 @retval FALSE MTRR registers do not need to be configured to set SMRAM
363 cache-ability.
364 **/
365 BOOLEAN
366 EFIAPI
367 SmmCpuFeaturesNeedConfigureMtrrs (
368 VOID
369 )
370 {
371 return mNeedConfigureMtrrs;
372 }
373
374 /**
375 Disable SMRR register if SMRR is supported and SmmCpuFeaturesNeedConfigureMtrrs()
376 returns TRUE.
377 **/
378 VOID
379 EFIAPI
380 SmmCpuFeaturesDisableSmrr (
381 VOID
382 )
383 {
384 if (mSmrrSupported && mNeedConfigureMtrrs) {
385 AsmWriteMsr64 (mSmrrPhysMaskMsr, AsmReadMsr64(mSmrrPhysMaskMsr) & ~EFI_MSR_SMRR_PHYS_MASK_VALID);
386 }
387 }
388
389 /**
390 Enable SMRR register if SMRR is supported and SmmCpuFeaturesNeedConfigureMtrrs()
391 returns TRUE.
392 **/
393 VOID
394 EFIAPI
395 SmmCpuFeaturesReenableSmrr (
396 VOID
397 )
398 {
399 if (mSmrrSupported && mNeedConfigureMtrrs) {
400 AsmWriteMsr64 (mSmrrPhysMaskMsr, AsmReadMsr64(mSmrrPhysMaskMsr) | EFI_MSR_SMRR_PHYS_MASK_VALID);
401 }
402 }
403
404 /**
405 Processor specific hook point each time a CPU enters System Management Mode.
406
407 @param[in] CpuIndex The index of the CPU that has entered SMM. The value
408 must be between 0 and the NumberOfCpus field in the
409 System Management System Table (SMST).
410 **/
411 VOID
412 EFIAPI
413 SmmCpuFeaturesRendezvousEntry (
414 IN UINTN CpuIndex
415 )
416 {
417 //
418 // If SMRR is supported and this is the first normal SMI, then enable SMRR
419 //
420 if (mSmrrSupported && !mSmrrEnabled[CpuIndex]) {
421 AsmWriteMsr64 (mSmrrPhysMaskMsr, AsmReadMsr64 (mSmrrPhysMaskMsr) | EFI_MSR_SMRR_PHYS_MASK_VALID);
422 mSmrrEnabled[CpuIndex] = TRUE;
423 }
424 }
425
426 /**
427 Processor specific hook point each time a CPU exits System Management Mode.
428
429 @param[in] CpuIndex The index of the CPU that is exiting SMM. The value must
430 be between 0 and the NumberOfCpus field in the System
431 Management System Table (SMST).
432 **/
433 VOID
434 EFIAPI
435 SmmCpuFeaturesRendezvousExit (
436 IN UINTN CpuIndex
437 )
438 {
439 }
440
441 /**
442 Check to see if an SMM register is supported by a specified CPU.
443
444 @param[in] CpuIndex The index of the CPU to check for SMM register support.
445 The value must be between 0 and the NumberOfCpus field
446 in the System Management System Table (SMST).
447 @param[in] RegName Identifies the SMM register to check for support.
448
449 @retval TRUE The SMM register specified by RegName is supported by the CPU
450 specified by CpuIndex.
451 @retval FALSE The SMM register specified by RegName is not supported by the
452 CPU specified by CpuIndex.
453 **/
454 BOOLEAN
455 EFIAPI
456 SmmCpuFeaturesIsSmmRegisterSupported (
457 IN UINTN CpuIndex,
458 IN SMM_REG_NAME RegName
459 )
460 {
461 if (mSmmFeatureControlSupported && RegName == SmmRegFeatureControl) {
462 return TRUE;
463 }
464 return FALSE;
465 }
466
467 /**
468 Returns the current value of the SMM register for the specified CPU.
469 If the SMM register is not supported, then 0 is returned.
470
471 @param[in] CpuIndex The index of the CPU to read the SMM register. The
472 value must be between 0 and the NumberOfCpus field in
473 the System Management System Table (SMST).
474 @param[in] RegName Identifies the SMM register to read.
475
476 @return The value of the SMM register specified by RegName from the CPU
477 specified by CpuIndex.
478 **/
479 UINT64
480 EFIAPI
481 SmmCpuFeaturesGetSmmRegister (
482 IN UINTN CpuIndex,
483 IN SMM_REG_NAME RegName
484 )
485 {
486 if (mSmmFeatureControlSupported && RegName == SmmRegFeatureControl) {
487 return AsmReadMsr64 (SMM_FEATURES_LIB_SMM_FEATURE_CONTROL);
488 }
489 return 0;
490 }
491
492 /**
493 Sets the value of an SMM register on a specified CPU.
494 If the SMM register is not supported, then no action is performed.
495
496 @param[in] CpuIndex The index of the CPU to write the SMM register. The
497 value must be between 0 and the NumberOfCpus field in
498 the System Management System Table (SMST).
499 @param[in] RegName Identifies the SMM register to write.
500 registers are read-only.
501 @param[in] Value The value to write to the SMM register.
502 **/
503 VOID
504 EFIAPI
505 SmmCpuFeaturesSetSmmRegister (
506 IN UINTN CpuIndex,
507 IN SMM_REG_NAME RegName,
508 IN UINT64 Value
509 )
510 {
511 if (mSmmFeatureControlSupported && RegName == SmmRegFeatureControl) {
512 AsmWriteMsr64 (SMM_FEATURES_LIB_SMM_FEATURE_CONTROL, Value);
513 }
514 }
515
516 /**
517 Read an SMM Save State register on the target processor. If this function
518 returns EFI_UNSUPPORTED, then the caller is responsible for reading the
519 SMM Save Sate register.
520
521 @param[in] CpuIndex The index of the CPU to read the SMM Save State. The
522 value must be between 0 and the NumberOfCpus field in
523 the System Management System Table (SMST).
524 @param[in] Register The SMM Save State register to read.
525 @param[in] Width The number of bytes to read from the CPU save state.
526 @param[out] Buffer Upon return, this holds the CPU register value read
527 from the save state.
528
529 @retval EFI_SUCCESS The register was read from Save State.
530 @retval EFI_INVALID_PARAMETER Buffer is NULL.
531 @retval EFI_UNSUPPORTED This function does not support reading Register.
532
533 **/
534 EFI_STATUS
535 EFIAPI
536 SmmCpuFeaturesReadSaveStateRegister (
537 IN UINTN CpuIndex,
538 IN EFI_SMM_SAVE_STATE_REGISTER Register,
539 IN UINTN Width,
540 OUT VOID *Buffer
541 )
542 {
543 return EFI_UNSUPPORTED;
544 }
545
546 /**
547 Writes an SMM Save State register on the target processor. If this function
548 returns EFI_UNSUPPORTED, then the caller is responsible for writing the
549 SMM Save Sate register.
550
551 @param[in] CpuIndex The index of the CPU to write the SMM Save State. The
552 value must be between 0 and the NumberOfCpus field in
553 the System Management System Table (SMST).
554 @param[in] Register The SMM Save State register to write.
555 @param[in] Width The number of bytes to write to the CPU save state.
556 @param[in] Buffer Upon entry, this holds the new CPU register value.
557
558 @retval EFI_SUCCESS The register was written to Save State.
559 @retval EFI_INVALID_PARAMETER Buffer is NULL.
560 @retval EFI_UNSUPPORTED This function does not support writing Register.
561 **/
562 EFI_STATUS
563 EFIAPI
564 SmmCpuFeaturesWriteSaveStateRegister (
565 IN UINTN CpuIndex,
566 IN EFI_SMM_SAVE_STATE_REGISTER Register,
567 IN UINTN Width,
568 IN CONST VOID *Buffer
569 )
570 {
571 return EFI_UNSUPPORTED;
572 }
573
574 /**
575 This function is hook point called after the gEfiSmmReadyToLockProtocolGuid
576 notification is completely processed.
577 **/
578 VOID
579 EFIAPI
580 SmmCpuFeaturesCompleteSmmReadyToLock (
581 VOID
582 )
583 {
584 }
585
586 /**
587 This API provides a method for a CPU to allocate a specific region for storing page tables.
588
589 This API can be called more once to allocate memory for page tables.
590
591 Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the
592 allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
593 is returned. If there is not enough memory remaining to satisfy the request, then NULL is
594 returned.
595
596 This function can also return NULL if there is no preference on where the page tables are allocated in SMRAM.
597
598 @param Pages The number of 4 KB pages to allocate.
599
600 @return A pointer to the allocated buffer for page tables.
601 @retval NULL Fail to allocate a specific region for storing page tables,
602 Or there is no preference on where the page tables are allocated in SMRAM.
603
604 **/
605 VOID *
606 EFIAPI
607 SmmCpuFeaturesAllocatePageTableMemory (
608 IN UINTN Pages
609 )
610 {
611 return NULL;
612 }
613