Microcode.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386
  1. /** @file
  2. Implementation of loading microcode on processors.
  3. Copyright (c) 2015 - 2021, Intel Corporation. All rights reserved.<BR>
  4. SPDX-License-Identifier: BSD-2-Clause-Patent
  5. **/
  6. #include "MpLib.h"
  7. /**
  8. Detect whether specified processor can find matching microcode patch and load it.
  9. @param[in] CpuMpData The pointer to CPU MP Data structure.
  10. @param[in] ProcessorNumber The handle number of the processor. The range is
  11. from 0 to the total number of logical processors
  12. minus 1.
  13. **/
  14. VOID
  15. MicrocodeDetect (
  16. IN CPU_MP_DATA *CpuMpData,
  17. IN UINTN ProcessorNumber
  18. )
  19. {
  20. CPU_MICROCODE_HEADER *Microcode;
  21. UINTN MicrocodeEnd;
  22. CPU_AP_DATA *BspData;
  23. UINT32 LatestRevision;
  24. CPU_MICROCODE_HEADER *LatestMicrocode;
  25. UINT32 ThreadId;
  26. EDKII_PEI_MICROCODE_CPU_ID MicrocodeCpuId;
  27. if (CpuMpData->MicrocodePatchRegionSize == 0) {
  28. //
  29. // There is no microcode patches
  30. //
  31. return;
  32. }
  33. GetProcessorLocationByApicId (GetInitialApicId (), NULL, NULL, &ThreadId);
  34. if (ThreadId != 0) {
  35. //
  36. // Skip loading microcode if it is not the first thread in one core.
  37. //
  38. return;
  39. }
  40. GetProcessorMicrocodeCpuId (&MicrocodeCpuId);
  41. if (ProcessorNumber != (UINTN)CpuMpData->BspNumber) {
  42. //
  43. // Direct use microcode of BSP if AP is the same as BSP.
  44. // Assume BSP calls this routine() before AP.
  45. //
  46. BspData = &(CpuMpData->CpuData[CpuMpData->BspNumber]);
  47. if ((BspData->ProcessorSignature == MicrocodeCpuId.ProcessorSignature) &&
  48. (BspData->PlatformId == MicrocodeCpuId.PlatformId) &&
  49. (BspData->MicrocodeEntryAddr != 0))
  50. {
  51. LatestMicrocode = (CPU_MICROCODE_HEADER *)(UINTN)BspData->MicrocodeEntryAddr;
  52. LatestRevision = LatestMicrocode->UpdateRevision;
  53. goto LoadMicrocode;
  54. }
  55. }
  56. //
  57. // BSP or AP which is different from BSP runs here
  58. // Use 0 as the starting revision to search for microcode because MicrocodePatchInfo HOB needs
  59. // the latest microcode location even it's loaded to the processor.
  60. //
  61. LatestRevision = 0;
  62. LatestMicrocode = NULL;
  63. Microcode = (CPU_MICROCODE_HEADER *)(UINTN)CpuMpData->MicrocodePatchAddress;
  64. MicrocodeEnd = (UINTN)Microcode + (UINTN)CpuMpData->MicrocodePatchRegionSize;
  65. do {
  66. if (!IsValidMicrocode (Microcode, MicrocodeEnd - (UINTN)Microcode, LatestRevision, &MicrocodeCpuId, 1, TRUE)) {
  67. //
  68. // It is the padding data between the microcode patches for microcode patches alignment.
  69. // Because the microcode patch is the multiple of 1-KByte, the padding data should not
  70. // exist if the microcode patch alignment value is not larger than 1-KByte. So, the microcode
  71. // alignment value should be larger than 1-KByte. We could skip SIZE_1KB padding data to
  72. // find the next possible microcode patch header.
  73. //
  74. Microcode = (CPU_MICROCODE_HEADER *)((UINTN)Microcode + SIZE_1KB);
  75. continue;
  76. }
  77. LatestMicrocode = Microcode;
  78. LatestRevision = LatestMicrocode->UpdateRevision;
  79. Microcode = (CPU_MICROCODE_HEADER *)(((UINTN)Microcode) + GetMicrocodeLength (Microcode));
  80. } while ((UINTN)Microcode < MicrocodeEnd);
  81. LoadMicrocode:
  82. if (LatestRevision != 0) {
  83. //
  84. // Save the detected microcode patch entry address (including the microcode
  85. // patch header) for each processor even it's the same as the loaded one.
  86. // It will be used when building the microcode patch cache HOB.
  87. //
  88. CpuMpData->CpuData[ProcessorNumber].MicrocodeEntryAddr = (UINTN)LatestMicrocode;
  89. }
  90. if (LatestRevision > GetProcessorMicrocodeSignature ()) {
  91. //
  92. // BIOS only authenticate updates that contain a numerically larger revision
  93. // than the currently loaded revision, where Current Signature < New Update
  94. // Revision. A processor with no loaded update is considered to have a
  95. // revision equal to zero.
  96. //
  97. LoadMicrocode (LatestMicrocode);
  98. }
  99. //
  100. // It's possible that the microcode fails to load. Just capture the CPU microcode revision after loading.
  101. //
  102. CpuMpData->CpuData[ProcessorNumber].MicrocodeRevision = GetProcessorMicrocodeSignature ();
  103. }
  104. /**
  105. Actual worker function that shadows the required microcode patches into memory.
  106. @param[in, out] CpuMpData The pointer to CPU MP Data structure.
  107. @param[in] Patches The pointer to an array of information on
  108. the microcode patches that will be loaded
  109. into memory.
  110. @param[in] PatchCount The number of microcode patches that will
  111. be loaded into memory.
  112. @param[in] TotalLoadSize The total size of all the microcode patches
  113. to be loaded.
  114. **/
  115. VOID
  116. ShadowMicrocodePatchWorker (
  117. IN OUT CPU_MP_DATA *CpuMpData,
  118. IN MICROCODE_PATCH_INFO *Patches,
  119. IN UINTN PatchCount,
  120. IN UINTN TotalLoadSize
  121. )
  122. {
  123. UINTN Index;
  124. VOID *MicrocodePatchInRam;
  125. UINT8 *Walker;
  126. ASSERT ((Patches != NULL) && (PatchCount != 0));
  127. MicrocodePatchInRam = AllocatePages (EFI_SIZE_TO_PAGES (TotalLoadSize));
  128. if (MicrocodePatchInRam == NULL) {
  129. return;
  130. }
  131. //
  132. // Load all the required microcode patches into memory
  133. //
  134. for (Walker = MicrocodePatchInRam, Index = 0; Index < PatchCount; Index++) {
  135. CopyMem (
  136. Walker,
  137. (VOID *)Patches[Index].Address,
  138. Patches[Index].Size
  139. );
  140. Walker += Patches[Index].Size;
  141. }
  142. //
  143. // Update the microcode patch related fields in CpuMpData
  144. //
  145. CpuMpData->MicrocodePatchAddress = (UINTN)MicrocodePatchInRam;
  146. CpuMpData->MicrocodePatchRegionSize = TotalLoadSize;
  147. DEBUG ((
  148. DEBUG_INFO,
  149. "%a: Required microcode patches have been loaded at 0x%lx, with size 0x%lx.\n",
  150. __FUNCTION__,
  151. CpuMpData->MicrocodePatchAddress,
  152. CpuMpData->MicrocodePatchRegionSize
  153. ));
  154. return;
  155. }
  156. /**
  157. Shadow the required microcode patches data into memory according to PCD
  158. PcdCpuMicrocodePatchAddress and PcdCpuMicrocodePatchRegionSize.
  159. @param[in, out] CpuMpData The pointer to CPU MP Data structure.
  160. **/
  161. VOID
  162. ShadowMicrocodePatchByPcd (
  163. IN OUT CPU_MP_DATA *CpuMpData
  164. )
  165. {
  166. UINTN Index;
  167. CPU_MICROCODE_HEADER *MicrocodeEntryPoint;
  168. UINTN MicrocodeEnd;
  169. UINTN TotalSize;
  170. MICROCODE_PATCH_INFO *PatchInfoBuffer;
  171. UINTN MaxPatchNumber;
  172. UINTN PatchCount;
  173. UINTN TotalLoadSize;
  174. EDKII_PEI_MICROCODE_CPU_ID *MicrocodeCpuIds;
  175. BOOLEAN Valid;
  176. //
  177. // Initialize the microcode patch related fields in CpuMpData as the values
  178. // specified by the PCD pair. If the microcode patches are loaded into memory,
  179. // these fields will be updated.
  180. //
  181. CpuMpData->MicrocodePatchAddress = PcdGet64 (PcdCpuMicrocodePatchAddress);
  182. CpuMpData->MicrocodePatchRegionSize = PcdGet64 (PcdCpuMicrocodePatchRegionSize);
  183. MicrocodeEntryPoint = (CPU_MICROCODE_HEADER *)(UINTN)CpuMpData->MicrocodePatchAddress;
  184. MicrocodeEnd = (UINTN)MicrocodeEntryPoint +
  185. (UINTN)CpuMpData->MicrocodePatchRegionSize;
  186. if ((MicrocodeEntryPoint == NULL) || ((UINTN)MicrocodeEntryPoint == MicrocodeEnd)) {
  187. //
  188. // There is no microcode patches
  189. //
  190. return;
  191. }
  192. PatchCount = 0;
  193. MaxPatchNumber = DEFAULT_MAX_MICROCODE_PATCH_NUM;
  194. TotalLoadSize = 0;
  195. PatchInfoBuffer = AllocatePool (MaxPatchNumber * sizeof (MICROCODE_PATCH_INFO));
  196. if (PatchInfoBuffer == NULL) {
  197. return;
  198. }
  199. MicrocodeCpuIds = AllocatePages (
  200. EFI_SIZE_TO_PAGES (CpuMpData->CpuCount * sizeof (EDKII_PEI_MICROCODE_CPU_ID))
  201. );
  202. if (MicrocodeCpuIds == NULL) {
  203. FreePool (PatchInfoBuffer);
  204. return;
  205. }
  206. for (Index = 0; Index < CpuMpData->CpuCount; Index++) {
  207. MicrocodeCpuIds[Index].PlatformId = CpuMpData->CpuData[Index].PlatformId;
  208. MicrocodeCpuIds[Index].ProcessorSignature = CpuMpData->CpuData[Index].ProcessorSignature;
  209. }
  210. //
  211. // Process the header of each microcode patch within the region.
  212. // The purpose is to decide which microcode patch(es) will be loaded into memory.
  213. // Microcode checksum is not verified because it's slow when performing on flash.
  214. //
  215. do {
  216. Valid = IsValidMicrocode (
  217. MicrocodeEntryPoint,
  218. MicrocodeEnd - (UINTN)MicrocodeEntryPoint,
  219. 0,
  220. MicrocodeCpuIds,
  221. CpuMpData->CpuCount,
  222. FALSE
  223. );
  224. if (!Valid) {
  225. //
  226. // Padding data between the microcode patches, skip 1KB to check next entry.
  227. //
  228. MicrocodeEntryPoint = (CPU_MICROCODE_HEADER *)(((UINTN)MicrocodeEntryPoint) + SIZE_1KB);
  229. continue;
  230. }
  231. PatchCount++;
  232. if (PatchCount > MaxPatchNumber) {
  233. //
  234. // Current 'PatchInfoBuffer' cannot hold the information, double the size
  235. // and allocate a new buffer.
  236. //
  237. if (MaxPatchNumber > MAX_UINTN / 2 / sizeof (MICROCODE_PATCH_INFO)) {
  238. //
  239. // Overflow check for MaxPatchNumber
  240. //
  241. goto OnExit;
  242. }
  243. PatchInfoBuffer = ReallocatePool (
  244. MaxPatchNumber * sizeof (MICROCODE_PATCH_INFO),
  245. 2 * MaxPatchNumber * sizeof (MICROCODE_PATCH_INFO),
  246. PatchInfoBuffer
  247. );
  248. if (PatchInfoBuffer == NULL) {
  249. goto OnExit;
  250. }
  251. MaxPatchNumber = MaxPatchNumber * 2;
  252. }
  253. TotalSize = GetMicrocodeLength (MicrocodeEntryPoint);
  254. //
  255. // Store the information of this microcode patch
  256. //
  257. PatchInfoBuffer[PatchCount - 1].Address = (UINTN)MicrocodeEntryPoint;
  258. PatchInfoBuffer[PatchCount - 1].Size = TotalSize;
  259. TotalLoadSize += TotalSize;
  260. //
  261. // Process the next microcode patch
  262. //
  263. MicrocodeEntryPoint = (CPU_MICROCODE_HEADER *)((UINTN)MicrocodeEntryPoint + TotalSize);
  264. } while ((UINTN)MicrocodeEntryPoint < MicrocodeEnd);
  265. if (PatchCount != 0) {
  266. DEBUG ((
  267. DEBUG_INFO,
  268. "%a: 0x%x microcode patches will be loaded into memory, with size 0x%x.\n",
  269. __FUNCTION__,
  270. PatchCount,
  271. TotalLoadSize
  272. ));
  273. ShadowMicrocodePatchWorker (CpuMpData, PatchInfoBuffer, PatchCount, TotalLoadSize);
  274. }
  275. OnExit:
  276. if (PatchInfoBuffer != NULL) {
  277. FreePool (PatchInfoBuffer);
  278. }
  279. FreePages (MicrocodeCpuIds, EFI_SIZE_TO_PAGES (CpuMpData->CpuCount * sizeof (EDKII_PEI_MICROCODE_CPU_ID)));
  280. }
  281. /**
  282. Shadow the required microcode patches data into memory.
  283. @param[in, out] CpuMpData The pointer to CPU MP Data structure.
  284. **/
  285. VOID
  286. ShadowMicrocodeUpdatePatch (
  287. IN OUT CPU_MP_DATA *CpuMpData
  288. )
  289. {
  290. EFI_STATUS Status;
  291. Status = PlatformShadowMicrocode (CpuMpData);
  292. if (EFI_ERROR (Status)) {
  293. ShadowMicrocodePatchByPcd (CpuMpData);
  294. }
  295. }
  296. /**
  297. Get the cached microcode patch base address and size from the microcode patch
  298. information cache HOB.
  299. @param[out] Address Base address of the microcode patches data.
  300. It will be updated if the microcode patch
  301. information cache HOB is found.
  302. @param[out] RegionSize Size of the microcode patches data.
  303. It will be updated if the microcode patch
  304. information cache HOB is found.
  305. @retval TRUE The microcode patch information cache HOB is found.
  306. @retval FALSE The microcode patch information cache HOB is not found.
  307. **/
  308. BOOLEAN
  309. GetMicrocodePatchInfoFromHob (
  310. UINT64 *Address,
  311. UINT64 *RegionSize
  312. )
  313. {
  314. EFI_HOB_GUID_TYPE *GuidHob;
  315. EDKII_MICROCODE_PATCH_HOB *MicrocodePathHob;
  316. GuidHob = GetFirstGuidHob (&gEdkiiMicrocodePatchHobGuid);
  317. if (GuidHob == NULL) {
  318. DEBUG ((DEBUG_INFO, "%a: Microcode patch cache HOB is not found.\n", __FUNCTION__));
  319. return FALSE;
  320. }
  321. MicrocodePathHob = GET_GUID_HOB_DATA (GuidHob);
  322. *Address = MicrocodePathHob->MicrocodePatchAddress;
  323. *RegionSize = MicrocodePathHob->MicrocodePatchRegionSize;
  324. DEBUG ((
  325. DEBUG_INFO,
  326. "%a: MicrocodeBase = 0x%lx, MicrocodeSize = 0x%lx\n",
  327. __FUNCTION__,
  328. *Address,
  329. *RegionSize
  330. ));
  331. return TRUE;
  332. }