MpInitLibUp.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446
  1. /** @file
  2. Multiple-Processor initialization Library for uniprocessor platforms.
  3. Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
  4. SPDX-License-Identifier: BSD-2-Clause-Patent
  5. **/
  6. #include <PiDxe.h>
  7. #include <Ppi/SecPlatformInformation.h>
  8. #include <Protocol/MpService.h>
  9. #include <Library/DebugLib.h>
  10. #include <Library/LocalApicLib.h>
  11. #include <Library/HobLib.h>
  12. /**
  13. MP Initialize Library initialization.
  14. This service will allocate AP reset vector and wakeup all APs to do APs
  15. initialization.
  16. This service must be invoked before all other MP Initialize Library
  17. service are invoked.
  18. @retval EFI_SUCCESS MP initialization succeeds.
  19. @retval Others MP initialization fails.
  20. **/
  21. EFI_STATUS
  22. EFIAPI
  23. MpInitLibInitialize (
  24. VOID
  25. )
  26. {
  27. //
  28. // Enable the local APIC for Virtual Wire Mode.
  29. //
  30. ProgramVirtualWireMode ();
  31. return EFI_SUCCESS;
  32. }
  33. /**
  34. Retrieves the number of logical processor in the platform and the number of
  35. those logical processors that are enabled on this boot. This service may only
  36. be called from the BSP.
  37. @param[out] NumberOfProcessors Pointer to the total number of logical
  38. processors in the system, including the BSP
  39. and disabled APs.
  40. @param[out] NumberOfEnabledProcessors Pointer to the number of enabled logical
  41. processors that exist in system, including
  42. the BSP.
  43. @retval EFI_SUCCESS The number of logical processors and enabled
  44. logical processors was retrieved.
  45. @retval EFI_DEVICE_ERROR The calling processor is an AP.
  46. @retval EFI_INVALID_PARAMETER NumberOfProcessors is NULL and NumberOfEnabledProcessors
  47. is NULL.
  48. @retval EFI_NOT_READY MP Initialize Library is not initialized.
  49. **/
  50. EFI_STATUS
  51. EFIAPI
  52. MpInitLibGetNumberOfProcessors (
  53. OUT UINTN *NumberOfProcessors OPTIONAL,
  54. OUT UINTN *NumberOfEnabledProcessors OPTIONAL
  55. )
  56. {
  57. *NumberOfProcessors = 1;
  58. *NumberOfEnabledProcessors = 1;
  59. return EFI_SUCCESS;
  60. }
  61. /**
  62. Gets detailed MP-related information on the requested processor at the
  63. instant this call is made. This service may only be called from the BSP.
  64. @param[in] ProcessorNumber The handle number of processor.
  65. @param[out] ProcessorInfoBuffer A pointer to the buffer where information for
  66. the requested processor is deposited.
  67. @param[out] HealthData Return processor health data.
  68. @retval EFI_SUCCESS Processor information was returned.
  69. @retval EFI_DEVICE_ERROR The calling processor is an AP.
  70. @retval EFI_INVALID_PARAMETER ProcessorInfoBuffer is NULL.
  71. @retval EFI_NOT_FOUND The processor with the handle specified by
  72. ProcessorNumber does not exist in the platform.
  73. @retval EFI_NOT_READY MP Initialize Library is not initialized.
  74. **/
  75. EFI_STATUS
  76. EFIAPI
  77. MpInitLibGetProcessorInfo (
  78. IN UINTN ProcessorNumber,
  79. OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer,
  80. OUT EFI_HEALTH_FLAGS *HealthData OPTIONAL
  81. )
  82. {
  83. EFI_HOB_GUID_TYPE *GuidHob;
  84. EFI_SEC_PLATFORM_INFORMATION_RECORD *SecPlatformInformation;
  85. if (ProcessorInfoBuffer == NULL) {
  86. return EFI_INVALID_PARAMETER;
  87. }
  88. if (ProcessorNumber != 0) {
  89. return EFI_NOT_FOUND;
  90. }
  91. ProcessorInfoBuffer->ProcessorId = 0;
  92. ProcessorInfoBuffer->StatusFlag = PROCESSOR_AS_BSP_BIT |
  93. PROCESSOR_ENABLED_BIT |
  94. PROCESSOR_HEALTH_STATUS_BIT;
  95. ProcessorInfoBuffer->Location.Package = 0;
  96. ProcessorInfoBuffer->Location.Core = 0;
  97. ProcessorInfoBuffer->Location.Thread = 0;
  98. if (HealthData != NULL) {
  99. GuidHob = GetFirstGuidHob (&gEfiSecPlatformInformationPpiGuid);
  100. if (GuidHob != NULL) {
  101. SecPlatformInformation = GET_GUID_HOB_DATA (GuidHob);
  102. HealthData->Uint32 = SecPlatformInformation->IA32HealthFlags.Uint32;
  103. } else {
  104. DEBUG ((DEBUG_INFO, "Does not find any HOB stored CPU BIST information!\n"));
  105. HealthData->Uint32 = 0;
  106. }
  107. }
  108. return EFI_SUCCESS;
  109. }
  110. /**
  111. This service executes a caller provided function on all enabled APs.
  112. @param[in] Procedure A pointer to the function to be run on
  113. enabled APs of the system. See type
  114. EFI_AP_PROCEDURE.
  115. @param[in] SingleThread If TRUE, then all the enabled APs execute
  116. the function specified by Procedure one by
  117. one, in ascending order of processor handle
  118. number. If FALSE, then all the enabled APs
  119. execute the function specified by Procedure
  120. simultaneously.
  121. @param[in] WaitEvent The event created by the caller with CreateEvent()
  122. service. If it is NULL, then execute in
  123. blocking mode. BSP waits until all APs finish
  124. or TimeoutInMicroSeconds expires. If it's
  125. not NULL, then execute in non-blocking mode.
  126. BSP requests the function specified by
  127. Procedure to be started on all the enabled
  128. APs, and go on executing immediately. If
  129. all return from Procedure, or TimeoutInMicroSeconds
  130. expires, this event is signaled. The BSP
  131. can use the CheckEvent() or WaitForEvent()
  132. services to check the state of event. Type
  133. EFI_EVENT is defined in CreateEvent() in
  134. the Unified Extensible Firmware Interface
  135. Specification.
  136. @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for
  137. APs to return from Procedure, either for
  138. blocking or non-blocking mode. Zero means
  139. infinity. If the timeout expires before
  140. all APs return from Procedure, then Procedure
  141. on the failed APs is terminated. All enabled
  142. APs are available for next function assigned
  143. by MpInitLibStartupAllAPs() or
  144. MPInitLibStartupThisAP().
  145. If the timeout expires in blocking mode,
  146. BSP returns EFI_TIMEOUT. If the timeout
  147. expires in non-blocking mode, WaitEvent
  148. is signaled with SignalEvent().
  149. @param[in] ProcedureArgument The parameter passed into Procedure for
  150. all APs.
  151. @param[out] FailedCpuList If NULL, this parameter is ignored. Otherwise,
  152. if all APs finish successfully, then its
  153. content is set to NULL. If not all APs
  154. finish before timeout expires, then its
  155. content is set to address of the buffer
  156. holding handle numbers of the failed APs.
  157. The buffer is allocated by MP Initialization
  158. library, and it's the caller's responsibility to
  159. free the buffer with FreePool() service.
  160. In blocking mode, it is ready for consumption
  161. when the call returns. In non-blocking mode,
  162. it is ready when WaitEvent is signaled. The
  163. list of failed CPU is terminated by
  164. END_OF_CPU_LIST.
  165. @retval EFI_SUCCESS In blocking mode, all APs have finished before
  166. the timeout expired.
  167. @retval EFI_SUCCESS In non-blocking mode, function has been dispatched
  168. to all enabled APs.
  169. @retval EFI_UNSUPPORTED A non-blocking mode request was made after the
  170. UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was
  171. signaled.
  172. @retval EFI_UNSUPPORTED WaitEvent is not NULL if non-blocking mode is not
  173. supported.
  174. @retval EFI_DEVICE_ERROR Caller processor is AP.
  175. @retval EFI_NOT_STARTED No enabled APs exist in the system.
  176. @retval EFI_NOT_READY Any enabled APs are busy.
  177. @retval EFI_NOT_READY MP Initialize Library is not initialized.
  178. @retval EFI_TIMEOUT In blocking mode, the timeout expired before
  179. all enabled APs have finished.
  180. @retval EFI_INVALID_PARAMETER Procedure is NULL.
  181. **/
  182. EFI_STATUS
  183. EFIAPI
  184. MpInitLibStartupAllAPs (
  185. IN EFI_AP_PROCEDURE Procedure,
  186. IN BOOLEAN SingleThread,
  187. IN EFI_EVENT WaitEvent OPTIONAL,
  188. IN UINTN TimeoutInMicroseconds,
  189. IN VOID *ProcedureArgument OPTIONAL,
  190. OUT UINTN **FailedCpuList OPTIONAL
  191. )
  192. {
  193. return EFI_NOT_STARTED;
  194. }
  195. /**
  196. This service lets the caller get one enabled AP to execute a caller-provided
  197. function.
  198. @param[in] Procedure A pointer to the function to be run on the
  199. designated AP of the system. See type
  200. EFI_AP_PROCEDURE.
  201. @param[in] ProcessorNumber The handle number of the AP. The range is
  202. from 0 to the total number of logical
  203. processors minus 1. The total number of
  204. logical processors can be retrieved by
  205. MpInitLibGetNumberOfProcessors().
  206. @param[in] WaitEvent The event created by the caller with CreateEvent()
  207. service. If it is NULL, then execute in
  208. blocking mode. BSP waits until this AP finish
  209. or TimeoutInMicroSeconds expires. If it's
  210. not NULL, then execute in non-blocking mode.
  211. BSP requests the function specified by
  212. Procedure to be started on this AP,
  213. and go on executing immediately. If this AP
  214. return from Procedure or TimeoutInMicroSeconds
  215. expires, this event is signaled. The BSP
  216. can use the CheckEvent() or WaitForEvent()
  217. services to check the state of event. Type
  218. EFI_EVENT is defined in CreateEvent() in
  219. the Unified Extensible Firmware Interface
  220. Specification.
  221. @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for
  222. this AP to finish this Procedure, either for
  223. blocking or non-blocking mode. Zero means
  224. infinity. If the timeout expires before
  225. this AP returns from Procedure, then Procedure
  226. on the AP is terminated. The
  227. AP is available for next function assigned
  228. by MpInitLibStartupAllAPs() or
  229. MpInitLibStartupThisAP().
  230. If the timeout expires in blocking mode,
  231. BSP returns EFI_TIMEOUT. If the timeout
  232. expires in non-blocking mode, WaitEvent
  233. is signaled with SignalEvent().
  234. @param[in] ProcedureArgument The parameter passed into Procedure on the
  235. specified AP.
  236. @param[out] Finished If NULL, this parameter is ignored. In
  237. blocking mode, this parameter is ignored.
  238. In non-blocking mode, if AP returns from
  239. Procedure before the timeout expires, its
  240. content is set to TRUE. Otherwise, the
  241. value is set to FALSE. The caller can
  242. determine if the AP returned from Procedure
  243. by evaluating this value.
  244. @retval EFI_SUCCESS In blocking mode, specified AP finished before
  245. the timeout expires.
  246. @retval EFI_SUCCESS In non-blocking mode, the function has been
  247. dispatched to specified AP.
  248. @retval EFI_UNSUPPORTED A non-blocking mode request was made after the
  249. UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was
  250. signaled.
  251. @retval EFI_UNSUPPORTED WaitEvent is not NULL if non-blocking mode is not
  252. supported.
  253. @retval EFI_DEVICE_ERROR The calling processor is an AP.
  254. @retval EFI_TIMEOUT In blocking mode, the timeout expired before
  255. the specified AP has finished.
  256. @retval EFI_NOT_READY The specified AP is busy.
  257. @retval EFI_NOT_READY MP Initialize Library is not initialized.
  258. @retval EFI_NOT_FOUND The processor with the handle specified by
  259. ProcessorNumber does not exist.
  260. @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP or disabled AP.
  261. @retval EFI_INVALID_PARAMETER Procedure is NULL.
  262. **/
  263. EFI_STATUS
  264. EFIAPI
  265. MpInitLibStartupThisAP (
  266. IN EFI_AP_PROCEDURE Procedure,
  267. IN UINTN ProcessorNumber,
  268. IN EFI_EVENT WaitEvent OPTIONAL,
  269. IN UINTN TimeoutInMicroseconds,
  270. IN VOID *ProcedureArgument OPTIONAL,
  271. OUT BOOLEAN *Finished OPTIONAL
  272. )
  273. {
  274. return EFI_INVALID_PARAMETER;
  275. }
  276. /**
  277. This service switches the requested AP to be the BSP from that point onward.
  278. This service changes the BSP for all purposes. This call can only be performed
  279. by the current BSP.
  280. @param[in] ProcessorNumber The handle number of AP that is to become the new
  281. BSP. The range is from 0 to the total number of
  282. logical processors minus 1. The total number of
  283. logical processors can be retrieved by
  284. MpInitLibGetNumberOfProcessors().
  285. @param[in] EnableOldBSP If TRUE, then the old BSP will be listed as an
  286. enabled AP. Otherwise, it will be disabled.
  287. @retval EFI_SUCCESS BSP successfully switched.
  288. @retval EFI_UNSUPPORTED Switching the BSP cannot be completed prior to
  289. this service returning.
  290. @retval EFI_UNSUPPORTED Switching the BSP is not supported.
  291. @retval EFI_DEVICE_ERROR The calling processor is an AP.
  292. @retval EFI_NOT_FOUND The processor with the handle specified by
  293. ProcessorNumber does not exist.
  294. @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the current BSP or
  295. a disabled AP.
  296. @retval EFI_NOT_READY The specified AP is busy.
  297. @retval EFI_NOT_READY MP Initialize Library is not initialized.
  298. **/
  299. EFI_STATUS
  300. EFIAPI
  301. MpInitLibSwitchBSP (
  302. IN UINTN ProcessorNumber,
  303. IN BOOLEAN EnableOldBSP
  304. )
  305. {
  306. return EFI_UNSUPPORTED;
  307. }
  308. /**
  309. This service lets the caller enable or disable an AP from this point onward.
  310. This service may only be called from the BSP.
  311. @param[in] ProcessorNumber The handle number of AP.
  312. The range is from 0 to the total number of
  313. logical processors minus 1. The total number of
  314. logical processors can be retrieved by
  315. MpInitLibGetNumberOfProcessors().
  316. @param[in] EnableAP Specifies the new state for the processor for
  317. enabled, FALSE for disabled.
  318. @param[in] HealthFlag If not NULL, a pointer to a value that specifies
  319. the new health status of the AP. This flag
  320. corresponds to StatusFlag defined in
  321. EFI_MP_SERVICES_PROTOCOL.GetProcessorInfo(). Only
  322. the PROCESSOR_HEALTH_STATUS_BIT is used. All other
  323. bits are ignored. If it is NULL, this parameter
  324. is ignored.
  325. @retval EFI_SUCCESS The specified AP was enabled or disabled successfully.
  326. @retval EFI_UNSUPPORTED Enabling or disabling an AP cannot be completed
  327. prior to this service returning.
  328. @retval EFI_UNSUPPORTED Enabling or disabling an AP is not supported.
  329. @retval EFI_DEVICE_ERROR The calling processor is an AP.
  330. @retval EFI_NOT_FOUND Processor with the handle specified by ProcessorNumber
  331. does not exist.
  332. @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP.
  333. @retval EFI_NOT_READY MP Initialize Library is not initialized.
  334. **/
  335. EFI_STATUS
  336. EFIAPI
  337. MpInitLibEnableDisableAP (
  338. IN UINTN ProcessorNumber,
  339. IN BOOLEAN EnableAP,
  340. IN UINT32 *HealthFlag OPTIONAL
  341. )
  342. {
  343. return EFI_UNSUPPORTED;
  344. }
  345. /**
  346. This return the handle number for the calling processor. This service may be
  347. called from the BSP and APs.
  348. @param[out] ProcessorNumber Pointer to the handle number of AP.
  349. The range is from 0 to the total number of
  350. logical processors minus 1. The total number of
  351. logical processors can be retrieved by
  352. MpInitLibGetNumberOfProcessors().
  353. @retval EFI_SUCCESS The current processor handle number was returned
  354. in ProcessorNumber.
  355. @retval EFI_INVALID_PARAMETER ProcessorNumber is NULL.
  356. @retval EFI_NOT_READY MP Initialize Library is not initialized.
  357. **/
  358. EFI_STATUS
  359. EFIAPI
  360. MpInitLibWhoAmI (
  361. OUT UINTN *ProcessorNumber
  362. )
  363. {
  364. if (ProcessorNumber == NULL) {
  365. return EFI_INVALID_PARAMETER;
  366. }
  367. *ProcessorNumber = 0;
  368. return EFI_SUCCESS;
  369. }
  370. /**
  371. This service executes a caller provided function on all enabled CPUs.
  372. @param[in] Procedure A pointer to the function to be run on
  373. enabled APs of the system. See type
  374. EFI_AP_PROCEDURE.
  375. @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for
  376. APs to return from Procedure, either for
  377. blocking or non-blocking mode. Zero means
  378. infinity. TimeoutInMicroseconds is ignored
  379. for BSP.
  380. @param[in] ProcedureArgument The parameter passed into Procedure for
  381. all APs.
  382. @retval EFI_SUCCESS CPU have finished the procedure.
  383. @retval EFI_INVALID_PARAMETER Procedure is NULL.
  384. **/
  385. EFI_STATUS
  386. EFIAPI
  387. MpInitLibStartupAllCPUs (
  388. IN EFI_AP_PROCEDURE Procedure,
  389. IN UINTN TimeoutInMicroseconds,
  390. IN VOID *ProcedureArgument OPTIONAL
  391. )
  392. {
  393. if (Procedure == NULL) {
  394. return EFI_INVALID_PARAMETER;
  395. }
  396. Procedure (ProcedureArgument);
  397. return EFI_SUCCESS;
  398. }