PiSmmCpuDxeSmm.h 50 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511
  1. /** @file
  2. Agent Module to load other modules to deploy SMM Entry Vector for X86 CPU.
  3. Copyright (c) 2009 - 2022, Intel Corporation. All rights reserved.<BR>
  4. Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
  5. SPDX-License-Identifier: BSD-2-Clause-Patent
  6. **/
  7. #ifndef _CPU_PISMMCPUDXESMM_H_
  8. #define _CPU_PISMMCPUDXESMM_H_
  9. #include <PiSmm.h>
  10. #include <Protocol/MpService.h>
  11. #include <Protocol/SmmConfiguration.h>
  12. #include <Protocol/SmmCpu.h>
  13. #include <Protocol/SmmAccess2.h>
  14. #include <Protocol/SmmReadyToLock.h>
  15. #include <Protocol/SmmCpuService.h>
  16. #include <Protocol/SmmMemoryAttribute.h>
  17. #include <Protocol/MmMp.h>
  18. #include <Guid/AcpiS3Context.h>
  19. #include <Guid/MemoryAttributesTable.h>
  20. #include <Guid/PiSmmMemoryAttributesTable.h>
  21. #include <Library/BaseLib.h>
  22. #include <Library/IoLib.h>
  23. #include <Library/TimerLib.h>
  24. #include <Library/SynchronizationLib.h>
  25. #include <Library/DebugLib.h>
  26. #include <Library/BaseMemoryLib.h>
  27. #include <Library/PcdLib.h>
  28. #include <Library/MtrrLib.h>
  29. #include <Library/SmmCpuPlatformHookLib.h>
  30. #include <Library/SmmServicesTableLib.h>
  31. #include <Library/MemoryAllocationLib.h>
  32. #include <Library/UefiBootServicesTableLib.h>
  33. #include <Library/UefiRuntimeServicesTableLib.h>
  34. #include <Library/DebugAgentLib.h>
  35. #include <Library/UefiLib.h>
  36. #include <Library/HobLib.h>
  37. #include <Library/LocalApicLib.h>
  38. #include <Library/CpuLib.h>
  39. #include <Library/UefiCpuLib.h>
  40. #include <Library/CpuExceptionHandlerLib.h>
  41. #include <Library/ReportStatusCodeLib.h>
  42. #include <Library/SmmCpuFeaturesLib.h>
  43. #include <Library/PeCoffGetEntryPointLib.h>
  44. #include <Library/RegisterCpuFeaturesLib.h>
  45. #include <AcpiCpuData.h>
  46. #include <CpuHotPlugData.h>
  47. #include <Register/Intel/Cpuid.h>
  48. #include <Register/Intel/Msr.h>
  49. #include "CpuService.h"
  50. #include "SmmProfile.h"
  51. //
  52. // CET definition
  53. //
  54. #define CPUID_CET_SS BIT7
  55. #define CPUID_CET_IBT BIT20
  56. #define CR4_CET_ENABLE BIT23
  57. #define MSR_IA32_S_CET 0x6A2
  58. #define MSR_IA32_PL0_SSP 0x6A4
  59. #define MSR_IA32_INTERRUPT_SSP_TABLE_ADDR 0x6A8
  60. typedef union {
  61. struct {
  62. // enable shadow stacks
  63. UINT32 SH_STK_ENP : 1;
  64. // enable the WRSS{D,Q}W instructions.
  65. UINT32 WR_SHSTK_EN : 1;
  66. // enable tracking of indirect call/jmp targets to be ENDBRANCH instruction.
  67. UINT32 ENDBR_EN : 1;
  68. // enable legacy compatibility treatment for indirect call/jmp tracking.
  69. UINT32 LEG_IW_EN : 1;
  70. // enable use of no-track prefix on indirect call/jmp.
  71. UINT32 NO_TRACK_EN : 1;
  72. // disable suppression of CET indirect branch tracking on legacy compatibility.
  73. UINT32 SUPPRESS_DIS : 1;
  74. UINT32 RSVD : 4;
  75. // indirect branch tracking is suppressed.
  76. // This bit can be written to 1 only if TRACKER is written as IDLE.
  77. UINT32 SUPPRESS : 1;
  78. // Value of the endbranch state machine
  79. // Values: IDLE (0), WAIT_FOR_ENDBRANCH(1).
  80. UINT32 TRACKER : 1;
  81. // linear address of a bitmap in memory indicating valid
  82. // pages as target of CALL/JMP_indirect that do not land on ENDBRANCH when CET is enabled
  83. // and not suppressed. Valid when ENDBR_EN is 1. Must be machine canonical when written on
  84. // parts that support 64 bit mode. On parts that do not support 64 bit mode, the bits 63:32 are
  85. // reserved and must be 0. This value is extended by 12 bits at the low end to form the base address
  86. // (this automatically aligns the address on a 4-Kbyte boundary).
  87. UINT32 EB_LEG_BITMAP_BASE_low : 12;
  88. UINT32 EB_LEG_BITMAP_BASE_high : 32;
  89. } Bits;
  90. UINT64 Uint64;
  91. } MSR_IA32_CET;
  92. //
  93. // MSRs required for configuration of SMM Code Access Check
  94. //
  95. #define EFI_MSR_SMM_MCA_CAP 0x17D
  96. #define SMM_CODE_ACCESS_CHK_BIT BIT58
  97. #define SMM_FEATURE_CONTROL_LOCK_BIT BIT0
  98. #define SMM_CODE_CHK_EN_BIT BIT2
  99. ///
  100. /// Page Table Entry
  101. ///
  102. #define IA32_PG_P BIT0
  103. #define IA32_PG_RW BIT1
  104. #define IA32_PG_U BIT2
  105. #define IA32_PG_WT BIT3
  106. #define IA32_PG_CD BIT4
  107. #define IA32_PG_A BIT5
  108. #define IA32_PG_D BIT6
  109. #define IA32_PG_PS BIT7
  110. #define IA32_PG_PAT_2M BIT12
  111. #define IA32_PG_PAT_4K IA32_PG_PS
  112. #define IA32_PG_PMNT BIT62
  113. #define IA32_PG_NX BIT63
  114. #define PAGE_ATTRIBUTE_BITS (IA32_PG_D | IA32_PG_A | IA32_PG_U | IA32_PG_RW | IA32_PG_P)
  115. //
  116. // Bits 1, 2, 5, 6 are reserved in the IA32 PAE PDPTE
  117. // X64 PAE PDPTE does not have such restriction
  118. //
  119. #define IA32_PAE_PDPTE_ATTRIBUTE_BITS (IA32_PG_P)
  120. #define PAGE_PROGATE_BITS (IA32_PG_NX | PAGE_ATTRIBUTE_BITS)
  121. #define PAGING_4K_MASK 0xFFF
  122. #define PAGING_2M_MASK 0x1FFFFF
  123. #define PAGING_1G_MASK 0x3FFFFFFF
  124. #define PAGING_PAE_INDEX_MASK 0x1FF
  125. #define PAGING_4K_ADDRESS_MASK_64 0x000FFFFFFFFFF000ull
  126. #define PAGING_2M_ADDRESS_MASK_64 0x000FFFFFFFE00000ull
  127. #define PAGING_1G_ADDRESS_MASK_64 0x000FFFFFC0000000ull
  128. #define SMRR_MAX_ADDRESS BASE_4GB
  129. typedef enum {
  130. PageNone,
  131. Page4K,
  132. Page2M,
  133. Page1G,
  134. } PAGE_ATTRIBUTE;
  135. typedef struct {
  136. PAGE_ATTRIBUTE Attribute;
  137. UINT64 Length;
  138. UINT64 AddressMask;
  139. } PAGE_ATTRIBUTE_TABLE;
  140. //
  141. // Size of Task-State Segment defined in IA32 Manual
  142. //
  143. #define TSS_SIZE 104
  144. #define EXCEPTION_TSS_SIZE (TSS_SIZE + 4) // Add 4 bytes SSP
  145. #define TSS_X64_IST1_OFFSET 36
  146. #define TSS_IA32_CR3_OFFSET 28
  147. #define TSS_IA32_ESP_OFFSET 56
  148. #define TSS_IA32_SSP_OFFSET 104
  149. #define CR0_WP BIT16
  150. //
  151. // Code select value
  152. //
  153. #define PROTECT_MODE_CODE_SEGMENT 0x08
  154. #define LONG_MODE_CODE_SEGMENT 0x38
  155. //
  156. // The size 0x20 must be bigger than
  157. // the size of template code of SmmInit. Currently,
  158. // the size of SmmInit requires the 0x16 Bytes buffer
  159. // at least.
  160. //
  161. #define BACK_BUF_SIZE 0x20
  162. #define EXCEPTION_VECTOR_NUMBER 0x20
  163. #define INVALID_APIC_ID 0xFFFFFFFFFFFFFFFFULL
  164. typedef UINT32 SMM_CPU_ARRIVAL_EXCEPTIONS;
  165. #define ARRIVAL_EXCEPTION_BLOCKED 0x1
  166. #define ARRIVAL_EXCEPTION_DELAYED 0x2
  167. #define ARRIVAL_EXCEPTION_SMI_DISABLED 0x4
  168. //
  169. // Wrapper used to convert EFI_AP_PROCEDURE2 and EFI_AP_PROCEDURE.
  170. //
  171. typedef struct {
  172. EFI_AP_PROCEDURE Procedure;
  173. VOID *ProcedureArgument;
  174. } PROCEDURE_WRAPPER;
  175. #define PROCEDURE_TOKEN_SIGNATURE SIGNATURE_32 ('P', 'R', 'T', 'S')
  176. typedef struct {
  177. UINTN Signature;
  178. LIST_ENTRY Link;
  179. SPIN_LOCK *SpinLock;
  180. volatile UINT32 RunningApCount;
  181. } PROCEDURE_TOKEN;
  182. #define PROCEDURE_TOKEN_FROM_LINK(a) CR (a, PROCEDURE_TOKEN, Link, PROCEDURE_TOKEN_SIGNATURE)
  183. #define TOKEN_BUFFER_SIGNATURE SIGNATURE_32 ('T', 'K', 'B', 'S')
  184. typedef struct {
  185. UINTN Signature;
  186. LIST_ENTRY Link;
  187. UINT8 *Buffer;
  188. } TOKEN_BUFFER;
  189. #define TOKEN_BUFFER_FROM_LINK(a) CR (a, TOKEN_BUFFER, Link, TOKEN_BUFFER_SIGNATURE)
  190. //
  191. // Private structure for the SMM CPU module that is stored in DXE Runtime memory
  192. // Contains the SMM Configuration Protocols that is produced.
  193. // Contains a mix of DXE and SMM contents. All the fields must be used properly.
  194. //
  195. #define SMM_CPU_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('s', 'c', 'p', 'u')
  196. typedef struct {
  197. UINTN Signature;
  198. EFI_HANDLE SmmCpuHandle;
  199. EFI_PROCESSOR_INFORMATION *ProcessorInfo;
  200. SMM_CPU_OPERATION *Operation;
  201. UINTN *CpuSaveStateSize;
  202. VOID **CpuSaveState;
  203. EFI_SMM_RESERVED_SMRAM_REGION SmmReservedSmramRegion[1];
  204. EFI_SMM_ENTRY_CONTEXT SmmCoreEntryContext;
  205. EFI_SMM_ENTRY_POINT SmmCoreEntry;
  206. EFI_SMM_CONFIGURATION_PROTOCOL SmmConfiguration;
  207. PROCEDURE_WRAPPER *ApWrapperFunc;
  208. LIST_ENTRY TokenList;
  209. LIST_ENTRY *FirstFreeToken;
  210. } SMM_CPU_PRIVATE_DATA;
  211. extern SMM_CPU_PRIVATE_DATA *gSmmCpuPrivate;
  212. extern CPU_HOT_PLUG_DATA mCpuHotPlugData;
  213. extern UINTN mMaxNumberOfCpus;
  214. extern UINTN mNumberOfCpus;
  215. extern EFI_SMM_CPU_PROTOCOL mSmmCpu;
  216. extern EFI_MM_MP_PROTOCOL mSmmMp;
  217. extern BOOLEAN m5LevelPagingNeeded;
  218. ///
  219. /// The mode of the CPU at the time an SMI occurs
  220. ///
  221. extern UINT8 mSmmSaveStateRegisterLma;
  222. //
  223. // SMM CPU Protocol function prototypes.
  224. //
  225. /**
  226. Read information from the CPU save state.
  227. @param This EFI_SMM_CPU_PROTOCOL instance
  228. @param Width The number of bytes to read from the CPU save state.
  229. @param Register Specifies the CPU register to read form the save state.
  230. @param CpuIndex Specifies the zero-based index of the CPU save state
  231. @param Buffer Upon return, this holds the CPU register value read from the save state.
  232. @retval EFI_SUCCESS The register was read from Save State
  233. @retval EFI_NOT_FOUND The register is not defined for the Save State of Processor
  234. @retval EFI_INVALID_PARAMETER This or Buffer is NULL.
  235. **/
  236. EFI_STATUS
  237. EFIAPI
  238. SmmReadSaveState (
  239. IN CONST EFI_SMM_CPU_PROTOCOL *This,
  240. IN UINTN Width,
  241. IN EFI_SMM_SAVE_STATE_REGISTER Register,
  242. IN UINTN CpuIndex,
  243. OUT VOID *Buffer
  244. );
  245. /**
  246. Write data to the CPU save state.
  247. @param This EFI_SMM_CPU_PROTOCOL instance
  248. @param Width The number of bytes to read from the CPU save state.
  249. @param Register Specifies the CPU register to write to the save state.
  250. @param CpuIndex Specifies the zero-based index of the CPU save state
  251. @param Buffer Upon entry, this holds the new CPU register value.
  252. @retval EFI_SUCCESS The register was written from Save State
  253. @retval EFI_NOT_FOUND The register is not defined for the Save State of Processor
  254. @retval EFI_INVALID_PARAMETER ProcessorIndex or Width is not correct
  255. **/
  256. EFI_STATUS
  257. EFIAPI
  258. SmmWriteSaveState (
  259. IN CONST EFI_SMM_CPU_PROTOCOL *This,
  260. IN UINTN Width,
  261. IN EFI_SMM_SAVE_STATE_REGISTER Register,
  262. IN UINTN CpuIndex,
  263. IN CONST VOID *Buffer
  264. );
  265. /**
  266. Read a CPU Save State register on the target processor.
  267. This function abstracts the differences that whether the CPU Save State register is in the
  268. IA32 CPU Save State Map or X64 CPU Save State Map.
  269. This function supports reading a CPU Save State register in SMBase relocation handler.
  270. @param[in] CpuIndex Specifies the zero-based index of the CPU save state.
  271. @param[in] RegisterIndex Index into mSmmCpuWidthOffset[] look up table.
  272. @param[in] Width The number of bytes to read from the CPU save state.
  273. @param[out] Buffer Upon return, this holds the CPU register value read from the save state.
  274. @retval EFI_SUCCESS The register was read from Save State.
  275. @retval EFI_NOT_FOUND The register is not defined for the Save State of Processor.
  276. @retval EFI_INVALID_PARAMETER Buffer is NULL, or Width does not meet requirement per Register type.
  277. **/
  278. EFI_STATUS
  279. EFIAPI
  280. ReadSaveStateRegister (
  281. IN UINTN CpuIndex,
  282. IN EFI_SMM_SAVE_STATE_REGISTER Register,
  283. IN UINTN Width,
  284. OUT VOID *Buffer
  285. );
  286. /**
  287. Write value to a CPU Save State register on the target processor.
  288. This function abstracts the differences that whether the CPU Save State register is in the
  289. IA32 CPU Save State Map or X64 CPU Save State Map.
  290. This function supports writing a CPU Save State register in SMBase relocation handler.
  291. @param[in] CpuIndex Specifies the zero-based index of the CPU save state.
  292. @param[in] RegisterIndex Index into mSmmCpuWidthOffset[] look up table.
  293. @param[in] Width The number of bytes to read from the CPU save state.
  294. @param[in] Buffer Upon entry, this holds the new CPU register value.
  295. @retval EFI_SUCCESS The register was written to Save State.
  296. @retval EFI_NOT_FOUND The register is not defined for the Save State of Processor.
  297. @retval EFI_INVALID_PARAMETER ProcessorIndex or Width is not correct.
  298. **/
  299. EFI_STATUS
  300. EFIAPI
  301. WriteSaveStateRegister (
  302. IN UINTN CpuIndex,
  303. IN EFI_SMM_SAVE_STATE_REGISTER Register,
  304. IN UINTN Width,
  305. IN CONST VOID *Buffer
  306. );
  307. extern CONST UINT8 gcSmmInitTemplate[];
  308. extern CONST UINT16 gcSmmInitSize;
  309. X86_ASSEMBLY_PATCH_LABEL gPatchSmmCr0;
  310. extern UINT32 mSmmCr0;
  311. X86_ASSEMBLY_PATCH_LABEL gPatchSmmCr3;
  312. extern UINT32 mSmmCr4;
  313. X86_ASSEMBLY_PATCH_LABEL gPatchSmmCr4;
  314. X86_ASSEMBLY_PATCH_LABEL gPatchSmmInitStack;
  315. X86_ASSEMBLY_PATCH_LABEL mPatchCetSupported;
  316. extern BOOLEAN mCetSupported;
  317. /**
  318. Semaphore operation for all processor relocate SMMBase.
  319. **/
  320. VOID
  321. EFIAPI
  322. SmmRelocationSemaphoreComplete (
  323. VOID
  324. );
  325. ///
  326. /// The type of SMM CPU Information
  327. ///
  328. typedef struct {
  329. SPIN_LOCK *Busy;
  330. volatile EFI_AP_PROCEDURE2 Procedure;
  331. volatile VOID *Parameter;
  332. volatile UINT32 *Run;
  333. volatile BOOLEAN *Present;
  334. PROCEDURE_TOKEN *Token;
  335. EFI_STATUS *Status;
  336. } SMM_CPU_DATA_BLOCK;
  337. typedef enum {
  338. SmmCpuSyncModeTradition,
  339. SmmCpuSyncModeRelaxedAp,
  340. SmmCpuSyncModeMax
  341. } SMM_CPU_SYNC_MODE;
  342. typedef struct {
  343. //
  344. // Pointer to an array. The array should be located immediately after this structure
  345. // so that UC cache-ability can be set together.
  346. //
  347. SMM_CPU_DATA_BLOCK *CpuData;
  348. volatile UINT32 *Counter;
  349. volatile UINT32 BspIndex;
  350. volatile BOOLEAN *InsideSmm;
  351. volatile BOOLEAN *AllCpusInSync;
  352. volatile SMM_CPU_SYNC_MODE EffectiveSyncMode;
  353. volatile BOOLEAN SwitchBsp;
  354. volatile BOOLEAN *CandidateBsp;
  355. volatile BOOLEAN AllApArrivedWithException;
  356. EFI_AP_PROCEDURE StartupProcedure;
  357. VOID *StartupProcArgs;
  358. } SMM_DISPATCHER_MP_SYNC_DATA;
  359. #define SMM_PSD_OFFSET 0xfb00
  360. ///
  361. /// All global semaphores' pointer
  362. ///
  363. typedef struct {
  364. volatile UINT32 *Counter;
  365. volatile BOOLEAN *InsideSmm;
  366. volatile BOOLEAN *AllCpusInSync;
  367. SPIN_LOCK *PFLock;
  368. SPIN_LOCK *CodeAccessCheckLock;
  369. } SMM_CPU_SEMAPHORE_GLOBAL;
  370. ///
  371. /// All semaphores for each processor
  372. ///
  373. typedef struct {
  374. SPIN_LOCK *Busy;
  375. volatile UINT32 *Run;
  376. volatile BOOLEAN *Present;
  377. SPIN_LOCK *Token;
  378. } SMM_CPU_SEMAPHORE_CPU;
  379. ///
  380. /// All semaphores' information
  381. ///
  382. typedef struct {
  383. SMM_CPU_SEMAPHORE_GLOBAL SemaphoreGlobal;
  384. SMM_CPU_SEMAPHORE_CPU SemaphoreCpu;
  385. } SMM_CPU_SEMAPHORES;
  386. extern IA32_DESCRIPTOR gcSmiGdtr;
  387. extern EFI_PHYSICAL_ADDRESS mGdtBuffer;
  388. extern UINTN mGdtBufferSize;
  389. extern IA32_DESCRIPTOR gcSmiIdtr;
  390. extern VOID *gcSmiIdtrPtr;
  391. extern UINT64 gPhyMask;
  392. extern SMM_DISPATCHER_MP_SYNC_DATA *mSmmMpSyncData;
  393. extern UINTN mSmmStackArrayBase;
  394. extern UINTN mSmmStackArrayEnd;
  395. extern UINTN mSmmStackSize;
  396. extern EFI_SMM_CPU_SERVICE_PROTOCOL mSmmCpuService;
  397. extern IA32_DESCRIPTOR gcSmiInitGdtr;
  398. extern SMM_CPU_SEMAPHORES mSmmCpuSemaphores;
  399. extern UINTN mSemaphoreSize;
  400. extern SPIN_LOCK *mPFLock;
  401. extern SPIN_LOCK *mConfigSmmCodeAccessCheckLock;
  402. extern EFI_SMRAM_DESCRIPTOR *mSmmCpuSmramRanges;
  403. extern UINTN mSmmCpuSmramRangeCount;
  404. extern UINT8 mPhysicalAddressBits;
  405. //
  406. // Copy of the PcdPteMemoryEncryptionAddressOrMask
  407. //
  408. extern UINT64 mAddressEncMask;
  409. /**
  410. Create 4G PageTable in SMRAM.
  411. @param[in] Is32BitPageTable Whether the page table is 32-bit PAE
  412. @return PageTable Address
  413. **/
  414. UINT32
  415. Gen4GPageTable (
  416. IN BOOLEAN Is32BitPageTable
  417. );
  418. /**
  419. Initialize global data for MP synchronization.
  420. @param Stacks Base address of SMI stack buffer for all processors.
  421. @param StackSize Stack size for each processor in SMM.
  422. @param ShadowStackSize Shadow Stack size for each processor in SMM.
  423. **/
  424. UINT32
  425. InitializeMpServiceData (
  426. IN VOID *Stacks,
  427. IN UINTN StackSize,
  428. IN UINTN ShadowStackSize
  429. );
  430. /**
  431. Initialize Timer for SMM AP Sync.
  432. **/
  433. VOID
  434. InitializeSmmTimer (
  435. VOID
  436. );
  437. /**
  438. Start Timer for SMM AP Sync.
  439. **/
  440. UINT64
  441. EFIAPI
  442. StartSyncTimer (
  443. VOID
  444. );
  445. /**
  446. Check if the SMM AP Sync timer is timeout.
  447. @param Timer The start timer from the begin.
  448. **/
  449. BOOLEAN
  450. EFIAPI
  451. IsSyncTimerTimeout (
  452. IN UINT64 Timer
  453. );
  454. /**
  455. Initialize IDT for SMM Stack Guard.
  456. **/
  457. VOID
  458. EFIAPI
  459. InitializeIDTSmmStackGuard (
  460. VOID
  461. );
  462. /**
  463. Initialize IDT IST Field.
  464. @param[in] ExceptionType Exception type.
  465. @param[in] Ist IST value.
  466. **/
  467. VOID
  468. EFIAPI
  469. InitializeIdtIst (
  470. IN EFI_EXCEPTION_TYPE ExceptionType,
  471. IN UINT8 Ist
  472. );
  473. /**
  474. Initialize Gdt for all processors.
  475. @param[in] Cr3 CR3 value.
  476. @param[out] GdtStepSize The step size for GDT table.
  477. @return GdtBase for processor 0.
  478. GdtBase for processor X is: GdtBase + (GdtStepSize * X)
  479. **/
  480. VOID *
  481. InitGdt (
  482. IN UINTN Cr3,
  483. OUT UINTN *GdtStepSize
  484. );
  485. /**
  486. Register the SMM Foundation entry point.
  487. @param This Pointer to EFI_SMM_CONFIGURATION_PROTOCOL instance
  488. @param SmmEntryPoint SMM Foundation EntryPoint
  489. @retval EFI_SUCCESS Successfully to register SMM foundation entry point
  490. **/
  491. EFI_STATUS
  492. EFIAPI
  493. RegisterSmmEntry (
  494. IN CONST EFI_SMM_CONFIGURATION_PROTOCOL *This,
  495. IN EFI_SMM_ENTRY_POINT SmmEntryPoint
  496. );
  497. /**
  498. Create PageTable for SMM use.
  499. @return PageTable Address
  500. **/
  501. UINT32
  502. SmmInitPageTable (
  503. VOID
  504. );
  505. /**
  506. Schedule a procedure to run on the specified CPU.
  507. @param Procedure The address of the procedure to run
  508. @param CpuIndex Target CPU number
  509. @param ProcArguments The parameter to pass to the procedure
  510. @retval EFI_INVALID_PARAMETER CpuNumber not valid
  511. @retval EFI_INVALID_PARAMETER CpuNumber specifying BSP
  512. @retval EFI_INVALID_PARAMETER The AP specified by CpuNumber did not enter SMM
  513. @retval EFI_INVALID_PARAMETER The AP specified by CpuNumber is busy
  514. @retval EFI_SUCCESS - The procedure has been successfully scheduled
  515. **/
  516. EFI_STATUS
  517. EFIAPI
  518. SmmStartupThisAp (
  519. IN EFI_AP_PROCEDURE Procedure,
  520. IN UINTN CpuIndex,
  521. IN OUT VOID *ProcArguments OPTIONAL
  522. );
  523. /**
  524. Schedule a procedure to run on the specified CPU in a blocking fashion.
  525. @param Procedure The address of the procedure to run
  526. @param CpuIndex Target CPU Index
  527. @param ProcArguments The parameter to pass to the procedure
  528. @retval EFI_INVALID_PARAMETER CpuNumber not valid
  529. @retval EFI_INVALID_PARAMETER CpuNumber specifying BSP
  530. @retval EFI_INVALID_PARAMETER The AP specified by CpuNumber did not enter SMM
  531. @retval EFI_INVALID_PARAMETER The AP specified by CpuNumber is busy
  532. @retval EFI_SUCCESS The procedure has been successfully scheduled
  533. **/
  534. EFI_STATUS
  535. EFIAPI
  536. SmmBlockingStartupThisAp (
  537. IN EFI_AP_PROCEDURE Procedure,
  538. IN UINTN CpuIndex,
  539. IN OUT VOID *ProcArguments OPTIONAL
  540. );
  541. /**
  542. This function sets the attributes for the memory region specified by BaseAddress and
  543. Length from their current attributes to the attributes specified by Attributes.
  544. @param[in] BaseAddress The physical address that is the start address of a memory region.
  545. @param[in] Length The size in bytes of the memory region.
  546. @param[in] Attributes The bit mask of attributes to set for the memory region.
  547. @retval EFI_SUCCESS The attributes were set for the memory region.
  548. @retval EFI_ACCESS_DENIED The attributes for the memory resource range specified by
  549. BaseAddress and Length cannot be modified.
  550. @retval EFI_INVALID_PARAMETER Length is zero.
  551. Attributes specified an illegal combination of attributes that
  552. cannot be set together.
  553. @retval EFI_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of
  554. the memory resource range.
  555. @retval EFI_UNSUPPORTED The processor does not support one or more bytes of the memory
  556. resource range specified by BaseAddress and Length.
  557. The bit mask of attributes is not support for the memory resource
  558. range specified by BaseAddress and Length.
  559. **/
  560. EFI_STATUS
  561. SmmSetMemoryAttributes (
  562. IN EFI_PHYSICAL_ADDRESS BaseAddress,
  563. IN UINT64 Length,
  564. IN UINT64 Attributes
  565. );
  566. /**
  567. This function clears the attributes for the memory region specified by BaseAddress and
  568. Length from their current attributes to the attributes specified by Attributes.
  569. @param[in] BaseAddress The physical address that is the start address of a memory region.
  570. @param[in] Length The size in bytes of the memory region.
  571. @param[in] Attributes The bit mask of attributes to clear for the memory region.
  572. @retval EFI_SUCCESS The attributes were cleared for the memory region.
  573. @retval EFI_ACCESS_DENIED The attributes for the memory resource range specified by
  574. BaseAddress and Length cannot be modified.
  575. @retval EFI_INVALID_PARAMETER Length is zero.
  576. Attributes specified an illegal combination of attributes that
  577. cannot be set together.
  578. @retval EFI_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of
  579. the memory resource range.
  580. @retval EFI_UNSUPPORTED The processor does not support one or more bytes of the memory
  581. resource range specified by BaseAddress and Length.
  582. The bit mask of attributes is not support for the memory resource
  583. range specified by BaseAddress and Length.
  584. **/
  585. EFI_STATUS
  586. SmmClearMemoryAttributes (
  587. IN EFI_PHYSICAL_ADDRESS BaseAddress,
  588. IN UINT64 Length,
  589. IN UINT64 Attributes
  590. );
  591. /**
  592. Initialize MP synchronization data.
  593. **/
  594. VOID
  595. EFIAPI
  596. InitializeMpSyncData (
  597. VOID
  598. );
  599. /**
  600. Find out SMRAM information including SMRR base and SMRR size.
  601. @param SmrrBase SMRR base
  602. @param SmrrSize SMRR size
  603. **/
  604. VOID
  605. FindSmramInfo (
  606. OUT UINT32 *SmrrBase,
  607. OUT UINT32 *SmrrSize
  608. );
  609. /**
  610. Relocate SmmBases for each processor.
  611. Execute on first boot and all S3 resumes
  612. **/
  613. VOID
  614. EFIAPI
  615. SmmRelocateBases (
  616. VOID
  617. );
  618. /**
  619. Page Fault handler for SMM use.
  620. @param InterruptType Defines the type of interrupt or exception that
  621. occurred on the processor.This parameter is processor architecture specific.
  622. @param SystemContext A pointer to the processor context when
  623. the interrupt occurred on the processor.
  624. **/
  625. VOID
  626. EFIAPI
  627. SmiPFHandler (
  628. IN EFI_EXCEPTION_TYPE InterruptType,
  629. IN EFI_SYSTEM_CONTEXT SystemContext
  630. );
  631. /**
  632. Perform the remaining tasks.
  633. **/
  634. VOID
  635. PerformRemainingTasks (
  636. VOID
  637. );
  638. /**
  639. Perform the pre tasks.
  640. **/
  641. VOID
  642. PerformPreTasks (
  643. VOID
  644. );
  645. /**
  646. Initialize MSR spin lock by MSR index.
  647. @param MsrIndex MSR index value.
  648. **/
  649. VOID
  650. InitMsrSpinLockByIndex (
  651. IN UINT32 MsrIndex
  652. );
  653. /**
  654. Hook return address of SMM Save State so that semaphore code
  655. can be executed immediately after AP exits SMM to indicate to
  656. the BSP that an AP has exited SMM after SMBASE relocation.
  657. @param[in] CpuIndex The processor index.
  658. @param[in] RebasedFlag A pointer to a flag that is set to TRUE
  659. immediately after AP exits SMM.
  660. **/
  661. VOID
  662. SemaphoreHook (
  663. IN UINTN CpuIndex,
  664. IN volatile BOOLEAN *RebasedFlag
  665. );
  666. /**
  667. Configure SMM Code Access Check feature for all processors.
  668. SMM Feature Control MSR will be locked after configuration.
  669. **/
  670. VOID
  671. ConfigSmmCodeAccessCheck (
  672. VOID
  673. );
  674. /**
  675. Hook the code executed immediately after an RSM instruction on the currently
  676. executing CPU. The mode of code executed immediately after RSM must be
  677. detected, and the appropriate hook must be selected. Always clear the auto
  678. HALT restart flag if it is set.
  679. @param[in] CpuIndex The processor index for the currently
  680. executing CPU.
  681. @param[in] CpuState Pointer to SMRAM Save State Map for the
  682. currently executing CPU.
  683. @param[in] NewInstructionPointer32 Instruction pointer to use if resuming to
  684. 32-bit mode from 64-bit SMM.
  685. @param[in] NewInstructionPointer Instruction pointer to use if resuming to
  686. same mode as SMM.
  687. @retval The value of the original instruction pointer before it was hooked.
  688. **/
  689. UINT64
  690. EFIAPI
  691. HookReturnFromSmm (
  692. IN UINTN CpuIndex,
  693. SMRAM_SAVE_STATE_MAP *CpuState,
  694. UINT64 NewInstructionPointer32,
  695. UINT64 NewInstructionPointer
  696. );
  697. /**
  698. Get the size of the SMI Handler in bytes.
  699. @retval The size, in bytes, of the SMI Handler.
  700. **/
  701. UINTN
  702. EFIAPI
  703. GetSmiHandlerSize (
  704. VOID
  705. );
  706. /**
  707. Install the SMI handler for the CPU specified by CpuIndex. This function
  708. is called by the CPU that was elected as monarch during System Management
  709. Mode initialization.
  710. @param[in] CpuIndex The index of the CPU to install the custom SMI handler.
  711. The value must be between 0 and the NumberOfCpus field
  712. in the System Management System Table (SMST).
  713. @param[in] SmBase The SMBASE address for the CPU specified by CpuIndex.
  714. @param[in] SmiStack The stack to use when an SMI is processed by the
  715. the CPU specified by CpuIndex.
  716. @param[in] StackSize The size, in bytes, if the stack used when an SMI is
  717. processed by the CPU specified by CpuIndex.
  718. @param[in] GdtBase The base address of the GDT to use when an SMI is
  719. processed by the CPU specified by CpuIndex.
  720. @param[in] GdtSize The size, in bytes, of the GDT used when an SMI is
  721. processed by the CPU specified by CpuIndex.
  722. @param[in] IdtBase The base address of the IDT to use when an SMI is
  723. processed by the CPU specified by CpuIndex.
  724. @param[in] IdtSize The size, in bytes, of the IDT used when an SMI is
  725. processed by the CPU specified by CpuIndex.
  726. @param[in] Cr3 The base address of the page tables to use when an SMI
  727. is processed by the CPU specified by CpuIndex.
  728. **/
  729. VOID
  730. EFIAPI
  731. InstallSmiHandler (
  732. IN UINTN CpuIndex,
  733. IN UINT32 SmBase,
  734. IN VOID *SmiStack,
  735. IN UINTN StackSize,
  736. IN UINTN GdtBase,
  737. IN UINTN GdtSize,
  738. IN UINTN IdtBase,
  739. IN UINTN IdtSize,
  740. IN UINT32 Cr3
  741. );
  742. /**
  743. Search module name by input IP address and output it.
  744. @param CallerIpAddress Caller instruction pointer.
  745. **/
  746. VOID
  747. DumpModuleInfoByIp (
  748. IN UINTN CallerIpAddress
  749. );
  750. /**
  751. This function sets memory attribute according to MemoryAttributesTable.
  752. **/
  753. VOID
  754. SetMemMapAttributes (
  755. VOID
  756. );
  757. /**
  758. This function sets UEFI memory attribute according to UEFI memory map.
  759. **/
  760. VOID
  761. SetUefiMemMapAttributes (
  762. VOID
  763. );
  764. /**
  765. Return if the Address is forbidden as SMM communication buffer.
  766. @param[in] Address the address to be checked
  767. @return TRUE The address is forbidden as SMM communication buffer.
  768. @return FALSE The address is allowed as SMM communication buffer.
  769. **/
  770. BOOLEAN
  771. IsSmmCommBufferForbiddenAddress (
  772. IN UINT64 Address
  773. );
  774. /**
  775. This function caches the UEFI memory map information.
  776. **/
  777. VOID
  778. GetUefiMemoryMap (
  779. VOID
  780. );
  781. /**
  782. This function sets memory attribute for page table.
  783. **/
  784. VOID
  785. SetPageTableAttributes (
  786. VOID
  787. );
  788. /**
  789. This function sets the attributes for the memory region specified by BaseAddress and
  790. Length from their current attributes to the attributes specified by Attributes.
  791. @param[in] PageTableBase The page table base.
  792. @param[in] EnablePML5Paging If PML5 paging is enabled.
  793. @param[in] BaseAddress The physical address that is the start address of a memory region.
  794. @param[in] Length The size in bytes of the memory region.
  795. @param[in] Attributes The bit mask of attributes to set for the memory region.
  796. @param[out] IsSplitted TRUE means page table splitted. FALSE means page table not splitted.
  797. @retval EFI_SUCCESS The attributes were set for the memory region.
  798. @retval EFI_ACCESS_DENIED The attributes for the memory resource range specified by
  799. BaseAddress and Length cannot be modified.
  800. @retval EFI_INVALID_PARAMETER Length is zero.
  801. Attributes specified an illegal combination of attributes that
  802. cannot be set together.
  803. @retval EFI_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of
  804. the memory resource range.
  805. @retval EFI_UNSUPPORTED The processor does not support one or more bytes of the memory
  806. resource range specified by BaseAddress and Length.
  807. The bit mask of attributes is not support for the memory resource
  808. range specified by BaseAddress and Length.
  809. **/
  810. EFI_STATUS
  811. SmmSetMemoryAttributesEx (
  812. IN UINTN PageTableBase,
  813. IN BOOLEAN EnablePML5Paging,
  814. IN EFI_PHYSICAL_ADDRESS BaseAddress,
  815. IN UINT64 Length,
  816. IN UINT64 Attributes,
  817. OUT BOOLEAN *IsSplitted OPTIONAL
  818. );
  819. /**
  820. This function clears the attributes for the memory region specified by BaseAddress and
  821. Length from their current attributes to the attributes specified by Attributes.
  822. @param[in] PageTableBase The page table base.
  823. @param[in] EnablePML5Paging If PML5 paging is enabled.
  824. @param[in] BaseAddress The physical address that is the start address of a memory region.
  825. @param[in] Length The size in bytes of the memory region.
  826. @param[in] Attributes The bit mask of attributes to clear for the memory region.
  827. @param[out] IsSplitted TRUE means page table splitted. FALSE means page table not splitted.
  828. @retval EFI_SUCCESS The attributes were cleared for the memory region.
  829. @retval EFI_ACCESS_DENIED The attributes for the memory resource range specified by
  830. BaseAddress and Length cannot be modified.
  831. @retval EFI_INVALID_PARAMETER Length is zero.
  832. Attributes specified an illegal combination of attributes that
  833. cannot be set together.
  834. @retval EFI_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of
  835. the memory resource range.
  836. @retval EFI_UNSUPPORTED The processor does not support one or more bytes of the memory
  837. resource range specified by BaseAddress and Length.
  838. The bit mask of attributes is not support for the memory resource
  839. range specified by BaseAddress and Length.
  840. **/
  841. EFI_STATUS
  842. SmmClearMemoryAttributesEx (
  843. IN UINTN PageTableBase,
  844. IN BOOLEAN EnablePML5Paging,
  845. IN EFI_PHYSICAL_ADDRESS BaseAddress,
  846. IN UINT64 Length,
  847. IN UINT64 Attributes,
  848. OUT BOOLEAN *IsSplitted OPTIONAL
  849. );
  850. /**
  851. This API provides a way to allocate memory for page table.
  852. This API can be called more once to allocate memory for page tables.
  853. Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the
  854. allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
  855. is returned. If there is not enough memory remaining to satisfy the request, then NULL is
  856. returned.
  857. @param Pages The number of 4 KB pages to allocate.
  858. @return A pointer to the allocated buffer or NULL if allocation fails.
  859. **/
  860. VOID *
  861. AllocatePageTableMemory (
  862. IN UINTN Pages
  863. );
  864. /**
  865. Allocate pages for code.
  866. @param[in] Pages Number of pages to be allocated.
  867. @return Allocated memory.
  868. **/
  869. VOID *
  870. AllocateCodePages (
  871. IN UINTN Pages
  872. );
  873. /**
  874. Allocate aligned pages for code.
  875. @param[in] Pages Number of pages to be allocated.
  876. @param[in] Alignment The requested alignment of the allocation.
  877. Must be a power of two.
  878. If Alignment is zero, then byte alignment is used.
  879. @return Allocated memory.
  880. **/
  881. VOID *
  882. AllocateAlignedCodePages (
  883. IN UINTN Pages,
  884. IN UINTN Alignment
  885. );
  886. //
  887. // S3 related global variable and function prototype.
  888. //
  889. extern BOOLEAN mSmmS3Flag;
  890. /**
  891. Initialize SMM S3 resume state structure used during S3 Resume.
  892. @param[in] Cr3 The base address of the page tables to use in SMM.
  893. **/
  894. VOID
  895. InitSmmS3ResumeState (
  896. IN UINT32 Cr3
  897. );
  898. /**
  899. Get ACPI CPU data.
  900. **/
  901. VOID
  902. GetAcpiCpuData (
  903. VOID
  904. );
  905. /**
  906. Restore SMM Configuration in S3 boot path.
  907. **/
  908. VOID
  909. RestoreSmmConfigurationInS3 (
  910. VOID
  911. );
  912. /**
  913. Get ACPI S3 enable flag.
  914. **/
  915. VOID
  916. GetAcpiS3EnableFlag (
  917. VOID
  918. );
  919. /**
  920. Transfer AP to safe hlt-loop after it finished restore CPU features on S3 patch.
  921. @param[in] ApHltLoopCode The address of the safe hlt-loop function.
  922. @param[in] TopOfStack A pointer to the new stack to use for the ApHltLoopCode.
  923. @param[in] NumberToFinishAddress Address of Semaphore of APs finish count.
  924. **/
  925. VOID
  926. TransferApToSafeState (
  927. IN UINTN ApHltLoopCode,
  928. IN UINTN TopOfStack,
  929. IN UINTN NumberToFinishAddress
  930. );
  931. /**
  932. Set ShadowStack memory.
  933. @param[in] Cr3 The page table base address.
  934. @param[in] BaseAddress The physical address that is the start address of a memory region.
  935. @param[in] Length The size in bytes of the memory region.
  936. @retval EFI_SUCCESS The shadow stack memory is set.
  937. **/
  938. EFI_STATUS
  939. SetShadowStack (
  940. IN UINTN Cr3,
  941. IN EFI_PHYSICAL_ADDRESS BaseAddress,
  942. IN UINT64 Length
  943. );
  944. /**
  945. Set not present memory.
  946. @param[in] Cr3 The page table base address.
  947. @param[in] BaseAddress The physical address that is the start address of a memory region.
  948. @param[in] Length The size in bytes of the memory region.
  949. @retval EFI_SUCCESS The not present memory is set.
  950. **/
  951. EFI_STATUS
  952. SetNotPresentPage (
  953. IN UINTN Cr3,
  954. IN EFI_PHYSICAL_ADDRESS BaseAddress,
  955. IN UINT64 Length
  956. );
  957. /**
  958. Initialize the shadow stack related data structure.
  959. @param CpuIndex The index of CPU.
  960. @param ShadowStack The bottom of the shadow stack for this CPU.
  961. **/
  962. VOID
  963. InitShadowStack (
  964. IN UINTN CpuIndex,
  965. IN VOID *ShadowStack
  966. );
  967. /**
  968. This function set given attributes of the memory region specified by
  969. BaseAddress and Length.
  970. @param This The EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL instance.
  971. @param BaseAddress The physical address that is the start address of
  972. a memory region.
  973. @param Length The size in bytes of the memory region.
  974. @param Attributes The bit mask of attributes to set for the memory
  975. region.
  976. @retval EFI_SUCCESS The attributes were set for the memory region.
  977. @retval EFI_INVALID_PARAMETER Length is zero.
  978. Attributes specified an illegal combination of
  979. attributes that cannot be set together.
  980. @retval EFI_UNSUPPORTED The processor does not support one or more
  981. bytes of the memory resource range specified
  982. by BaseAddress and Length.
  983. The bit mask of attributes is not supported for
  984. the memory resource range specified by
  985. BaseAddress and Length.
  986. **/
  987. EFI_STATUS
  988. EFIAPI
  989. EdkiiSmmSetMemoryAttributes (
  990. IN EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL *This,
  991. IN EFI_PHYSICAL_ADDRESS BaseAddress,
  992. IN UINT64 Length,
  993. IN UINT64 Attributes
  994. );
  995. /**
  996. This function clears given attributes of the memory region specified by
  997. BaseAddress and Length.
  998. @param This The EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL instance.
  999. @param BaseAddress The physical address that is the start address of
  1000. a memory region.
  1001. @param Length The size in bytes of the memory region.
  1002. @param Attributes The bit mask of attributes to clear for the memory
  1003. region.
  1004. @retval EFI_SUCCESS The attributes were cleared for the memory region.
  1005. @retval EFI_INVALID_PARAMETER Length is zero.
  1006. Attributes specified an illegal combination of
  1007. attributes that cannot be cleared together.
  1008. @retval EFI_UNSUPPORTED The processor does not support one or more
  1009. bytes of the memory resource range specified
  1010. by BaseAddress and Length.
  1011. The bit mask of attributes is not supported for
  1012. the memory resource range specified by
  1013. BaseAddress and Length.
  1014. **/
  1015. EFI_STATUS
  1016. EFIAPI
  1017. EdkiiSmmClearMemoryAttributes (
  1018. IN EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL *This,
  1019. IN EFI_PHYSICAL_ADDRESS BaseAddress,
  1020. IN UINT64 Length,
  1021. IN UINT64 Attributes
  1022. );
  1023. /**
  1024. This function retrieves the attributes of the memory region specified by
  1025. BaseAddress and Length. If different attributes are got from different part
  1026. of the memory region, EFI_NO_MAPPING will be returned.
  1027. @param This The EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL instance.
  1028. @param BaseAddress The physical address that is the start address of
  1029. a memory region.
  1030. @param Length The size in bytes of the memory region.
  1031. @param Attributes Pointer to attributes returned.
  1032. @retval EFI_SUCCESS The attributes got for the memory region.
  1033. @retval EFI_INVALID_PARAMETER Length is zero.
  1034. Attributes is NULL.
  1035. @retval EFI_NO_MAPPING Attributes are not consistent cross the memory
  1036. region.
  1037. @retval EFI_UNSUPPORTED The processor does not support one or more
  1038. bytes of the memory resource range specified
  1039. by BaseAddress and Length.
  1040. **/
  1041. EFI_STATUS
  1042. EFIAPI
  1043. EdkiiSmmGetMemoryAttributes (
  1044. IN EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL *This,
  1045. IN EFI_PHYSICAL_ADDRESS BaseAddress,
  1046. IN UINT64 Length,
  1047. IN UINT64 *Attributes
  1048. );
  1049. /**
  1050. This function fixes up the address of the global variable or function
  1051. referred in SmmInit assembly files to be the absolute address.
  1052. **/
  1053. VOID
  1054. EFIAPI
  1055. PiSmmCpuSmmInitFixupAddress (
  1056. );
  1057. /**
  1058. This function fixes up the address of the global variable or function
  1059. referred in SmiEntry assembly files to be the absolute address.
  1060. **/
  1061. VOID
  1062. EFIAPI
  1063. PiSmmCpuSmiEntryFixupAddress (
  1064. );
  1065. /**
  1066. This function reads CR2 register when on-demand paging is enabled
  1067. for 64 bit and no action for 32 bit.
  1068. @param[out] *Cr2 Pointer to variable to hold CR2 register value.
  1069. **/
  1070. VOID
  1071. SaveCr2 (
  1072. OUT UINTN *Cr2
  1073. );
  1074. /**
  1075. This function writes into CR2 register when on-demand paging is enabled
  1076. for 64 bit and no action for 32 bit.
  1077. @param[in] Cr2 Value to write into CR2 register.
  1078. **/
  1079. VOID
  1080. RestoreCr2 (
  1081. IN UINTN Cr2
  1082. );
  1083. /**
  1084. Schedule a procedure to run on the specified CPU.
  1085. @param[in] Procedure The address of the procedure to run
  1086. @param[in] CpuIndex Target CPU Index
  1087. @param[in,out] ProcArguments The parameter to pass to the procedure
  1088. @param[in,out] Token This is an optional parameter that allows the caller to execute the
  1089. procedure in a blocking or non-blocking fashion. If it is NULL the
  1090. call is blocking, and the call will not return until the AP has
  1091. completed the procedure. If the token is not NULL, the call will
  1092. return immediately. The caller can check whether the procedure has
  1093. completed with CheckOnProcedure or WaitForProcedure.
  1094. @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for the APs to finish
  1095. execution of Procedure, either for blocking or non-blocking mode.
  1096. Zero means infinity. If the timeout expires before all APs return
  1097. from Procedure, then Procedure on the failed APs is terminated. If
  1098. the timeout expires in blocking mode, the call returns EFI_TIMEOUT.
  1099. If the timeout expires in non-blocking mode, the timeout determined
  1100. can be through CheckOnProcedure or WaitForProcedure.
  1101. Note that timeout support is optional. Whether an implementation
  1102. supports this feature can be determined via the Attributes data
  1103. member.
  1104. @param[in,out] CpuStatus This optional pointer may be used to get the status code returned
  1105. by Procedure when it completes execution on the target AP, or with
  1106. EFI_TIMEOUT if the Procedure fails to complete within the optional
  1107. timeout. The implementation will update this variable with
  1108. EFI_NOT_READY prior to starting Procedure on the target AP.
  1109. @retval EFI_INVALID_PARAMETER CpuNumber not valid
  1110. @retval EFI_INVALID_PARAMETER CpuNumber specifying BSP
  1111. @retval EFI_INVALID_PARAMETER The AP specified by CpuNumber did not enter SMM
  1112. @retval EFI_INVALID_PARAMETER The AP specified by CpuNumber is busy
  1113. @retval EFI_SUCCESS The procedure has been successfully scheduled
  1114. **/
  1115. EFI_STATUS
  1116. InternalSmmStartupThisAp (
  1117. IN EFI_AP_PROCEDURE2 Procedure,
  1118. IN UINTN CpuIndex,
  1119. IN OUT VOID *ProcArguments OPTIONAL,
  1120. IN OUT MM_COMPLETION *Token,
  1121. IN UINTN TimeoutInMicroseconds,
  1122. IN OUT EFI_STATUS *CpuStatus
  1123. );
  1124. /**
  1125. Checks whether the input token is the current used token.
  1126. @param[in] Token This parameter describes the token that was passed into DispatchProcedure or
  1127. BroadcastProcedure.
  1128. @retval TRUE The input token is the current used token.
  1129. @retval FALSE The input token is not the current used token.
  1130. **/
  1131. BOOLEAN
  1132. IsTokenInUse (
  1133. IN SPIN_LOCK *Token
  1134. );
  1135. /**
  1136. Checks status of specified AP.
  1137. This function checks whether the specified AP has finished the task assigned
  1138. by StartupThisAP(), and whether timeout expires.
  1139. @param[in] Token This parameter describes the token that was passed into DispatchProcedure or
  1140. BroadcastProcedure.
  1141. @retval EFI_SUCCESS Specified AP has finished task assigned by StartupThisAPs().
  1142. @retval EFI_NOT_READY Specified AP has not finished task and timeout has not expired.
  1143. **/
  1144. EFI_STATUS
  1145. IsApReady (
  1146. IN SPIN_LOCK *Token
  1147. );
  1148. /**
  1149. Check whether it is an present AP.
  1150. @param CpuIndex The AP index which calls this function.
  1151. @retval TRUE It's a present AP.
  1152. @retval TRUE This is not an AP or it is not present.
  1153. **/
  1154. BOOLEAN
  1155. IsPresentAp (
  1156. IN UINTN CpuIndex
  1157. );
  1158. /**
  1159. Worker function to execute a caller provided function on all enabled APs.
  1160. @param[in] Procedure A pointer to the function to be run on
  1161. enabled APs of the system.
  1162. @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for
  1163. APs to return from Procedure, either for
  1164. blocking or non-blocking mode.
  1165. @param[in,out] ProcedureArguments The parameter passed into Procedure for
  1166. all APs.
  1167. @param[in,out] Token This is an optional parameter that allows the caller to execute the
  1168. procedure in a blocking or non-blocking fashion. If it is NULL the
  1169. call is blocking, and the call will not return until the AP has
  1170. completed the procedure. If the token is not NULL, the call will
  1171. return immediately. The caller can check whether the procedure has
  1172. completed with CheckOnProcedure or WaitForProcedure.
  1173. @param[in,out] CPUStatus This optional pointer may be used to get the status code returned
  1174. by Procedure when it completes execution on the target AP, or with
  1175. EFI_TIMEOUT if the Procedure fails to complete within the optional
  1176. timeout. The implementation will update this variable with
  1177. EFI_NOT_READY prior to starting Procedure on the target AP.
  1178. @retval EFI_SUCCESS In blocking mode, all APs have finished before
  1179. the timeout expired.
  1180. @retval EFI_SUCCESS In non-blocking mode, function has been dispatched
  1181. to all enabled APs.
  1182. @retval others Failed to Startup all APs.
  1183. **/
  1184. EFI_STATUS
  1185. InternalSmmStartupAllAPs (
  1186. IN EFI_AP_PROCEDURE2 Procedure,
  1187. IN UINTN TimeoutInMicroseconds,
  1188. IN OUT VOID *ProcedureArguments OPTIONAL,
  1189. IN OUT MM_COMPLETION *Token,
  1190. IN OUT EFI_STATUS *CPUStatus
  1191. );
  1192. /**
  1193. Register the SMM Foundation entry point.
  1194. @param[in] Procedure A pointer to the code stream to be run on the designated target AP
  1195. of the system. Type EFI_AP_PROCEDURE is defined below in Volume 2
  1196. with the related definitions of
  1197. EFI_MP_SERVICES_PROTOCOL.StartupAllAPs.
  1198. If caller may pass a value of NULL to deregister any existing
  1199. startup procedure.
  1200. @param[in,out] ProcedureArguments Allows the caller to pass a list of parameters to the code that is
  1201. run by the AP. It is an optional common mailbox between APs and
  1202. the caller to share information
  1203. @retval EFI_SUCCESS The Procedure has been set successfully.
  1204. @retval EFI_INVALID_PARAMETER The Procedure is NULL but ProcedureArguments not NULL.
  1205. **/
  1206. EFI_STATUS
  1207. RegisterStartupProcedure (
  1208. IN EFI_AP_PROCEDURE Procedure,
  1209. IN OUT VOID *ProcedureArguments OPTIONAL
  1210. );
  1211. /**
  1212. Allocate buffer for SpinLock and Wrapper function buffer.
  1213. **/
  1214. VOID
  1215. InitializeDataForMmMp (
  1216. VOID
  1217. );
  1218. /**
  1219. Return whether access to non-SMRAM is restricted.
  1220. @retval TRUE Access to non-SMRAM is restricted.
  1221. @retval FALSE Access to non-SMRAM is not restricted.
  1222. **/
  1223. BOOLEAN
  1224. IsRestrictedMemoryAccess (
  1225. VOID
  1226. );
  1227. /**
  1228. Choose blocking or non-blocking mode to Wait for all APs.
  1229. @param[in] This A pointer to the EDKII_SMM_CPU_RENDEZVOUS_PROTOCOL instance.
  1230. @param[in] BlockingMode Blocking or non-blocking mode.
  1231. @retval EFI_SUCCESS All APs have arrived SMM mode except SMI disabled APs.
  1232. @retval EFI_TIMEOUT There are APs not in SMM mode in given timeout constraint.
  1233. **/
  1234. EFI_STATUS
  1235. EFIAPI
  1236. SmmCpuRendezvous (
  1237. IN EDKII_SMM_CPU_RENDEZVOUS_PROTOCOL *This,
  1238. IN BOOLEAN BlockingMode
  1239. );
  1240. /**
  1241. Insure when this function returns, no AP will execute normal mode code before entering SMM, except SMI disabled APs.
  1242. **/
  1243. VOID
  1244. SmmWaitForApArrival (
  1245. VOID
  1246. );
  1247. #endif