SmmCpuFeaturesLibCommon.c 21 KB

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