PeilessStartup.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. /** @file
  2. Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
  3. SPDX-License-Identifier: BSD-2-Clause-Patent
  4. **/
  5. #include <PiPei.h>
  6. #include <Library/BaseLib.h>
  7. #include <Library/BaseMemoryLib.h>
  8. #include <Library/MemoryAllocationLib.h>
  9. #include <Library/DebugLib.h>
  10. #include <Protocol/DebugSupport.h>
  11. #include <Library/TdxLib.h>
  12. #include <IndustryStandard/Tdx.h>
  13. #include <Library/PrePiLib.h>
  14. #include <Library/PeilessStartupLib.h>
  15. #include <Library/PlatformInitLib.h>
  16. #include <ConfidentialComputingGuestAttr.h>
  17. #include <Guid/MemoryTypeInformation.h>
  18. #include <OvmfPlatforms.h>
  19. #include "PeilessStartupInternal.h"
  20. #define GET_GPAW_INIT_STATE(INFO) ((UINT8) ((INFO) & 0x3f))
  21. EFI_MEMORY_TYPE_INFORMATION mDefaultMemoryTypeInformation[] = {
  22. { EfiACPIMemoryNVS, 0x004 },
  23. { EfiACPIReclaimMemory, 0x008 },
  24. { EfiReservedMemoryType, 0x004 },
  25. { EfiRuntimeServicesData, 0x024 },
  26. { EfiRuntimeServicesCode, 0x030 },
  27. { EfiBootServicesCode, 0x180 },
  28. { EfiBootServicesData, 0xF00 },
  29. { EfiMaxMemoryType, 0x000 }
  30. };
  31. EFI_STATUS
  32. EFIAPI
  33. InitializePlatform (
  34. EFI_HOB_PLATFORM_INFO *PlatformInfoHob
  35. )
  36. {
  37. UINT32 LowerMemorySize;
  38. VOID *VariableStore;
  39. DEBUG ((DEBUG_INFO, "InitializePlatform in Pei-less boot\n"));
  40. PlatformDebugDumpCmos ();
  41. PlatformInfoHob->DefaultMaxCpuNumber = 64;
  42. PlatformInfoHob->PcdPciMmio64Size = 0x800000000;
  43. PlatformInfoHob->HostBridgeDevId = PciRead16 (OVMF_HOSTBRIDGE_DID);
  44. DEBUG ((DEBUG_INFO, "HostBridgeDeviceId = 0x%x\n", PlatformInfoHob->HostBridgeDevId));
  45. PlatformAddressWidthInitialization (PlatformInfoHob);
  46. DEBUG ((
  47. DEBUG_INFO,
  48. "PhysMemAddressWidth=0x%x, Pci64Base=0x%llx, Pci64Size=0x%llx\n",
  49. PlatformInfoHob->PhysMemAddressWidth,
  50. PlatformInfoHob->PcdPciMmio64Base,
  51. PlatformInfoHob->PcdPciMmio64Size
  52. ));
  53. PlatformMaxCpuCountInitialization (PlatformInfoHob);
  54. DEBUG ((
  55. DEBUG_INFO,
  56. "MaxCpuCount=%d, BootCpuCount=%d\n",
  57. PlatformInfoHob->PcdCpuMaxLogicalProcessorNumber,
  58. PlatformInfoHob->PcdCpuBootLogicalProcessorNumber
  59. ));
  60. LowerMemorySize = PlatformGetSystemMemorySizeBelow4gb (PlatformInfoHob);
  61. PlatformQemuUc32BaseInitialization (PlatformInfoHob);
  62. DEBUG ((
  63. DEBUG_INFO,
  64. "Uc32Base = 0x%x, Uc32Size = 0x%x, LowerMemorySize = 0x%x\n",
  65. PlatformInfoHob->Uc32Base,
  66. PlatformInfoHob->Uc32Size,
  67. LowerMemorySize
  68. ));
  69. VariableStore = PlatformReserveEmuVariableNvStore ();
  70. PlatformInfoHob->PcdEmuVariableNvStoreReserved = (UINT64)(UINTN)VariableStore;
  71. #ifdef SECURE_BOOT_FEATURE_ENABLED
  72. PlatformInitEmuVariableNvStore (VariableStore);
  73. #endif
  74. if (TdIsEnabled ()) {
  75. PlatformTdxPublishRamRegions ();
  76. } else {
  77. PlatformQemuInitializeRam (PlatformInfoHob);
  78. PlatformQemuInitializeRamForS3 (PlatformInfoHob);
  79. }
  80. //
  81. // Create Memory Type Information HOB
  82. //
  83. BuildGuidDataHob (
  84. &gEfiMemoryTypeInformationGuid,
  85. mDefaultMemoryTypeInformation,
  86. sizeof (mDefaultMemoryTypeInformation)
  87. );
  88. PlatformMemMapInitialization (PlatformInfoHob);
  89. PlatformNoexecDxeInitialization (PlatformInfoHob);
  90. if (TdIsEnabled ()) {
  91. PlatformInfoHob->PcdConfidentialComputingGuestAttr = CCAttrIntelTdx;
  92. PlatformInfoHob->PcdTdxSharedBitMask = TdSharedPageMask ();
  93. PlatformInfoHob->PcdSetNxForStack = TRUE;
  94. }
  95. PlatformMiscInitialization (PlatformInfoHob);
  96. return EFI_SUCCESS;
  97. }
  98. /**
  99. * This function brings up the Tdx guest from SEC phase to DXE phase.
  100. * PEI phase is skipped because most of the components in PEI phase
  101. * is not needed for Tdx guest, for example, MP Services, TPM etc.
  102. * In this way, the attack surfaces are reduced as much as possible.
  103. *
  104. * @param Context The pointer to the SecCoreData
  105. * @return VOID This function never returns
  106. */
  107. VOID
  108. EFIAPI
  109. PeilessStartup (
  110. IN VOID *Context
  111. )
  112. {
  113. EFI_SEC_PEI_HAND_OFF *SecCoreData;
  114. EFI_FIRMWARE_VOLUME_HEADER *BootFv;
  115. EFI_STATUS Status;
  116. EFI_HOB_PLATFORM_INFO PlatformInfoHob;
  117. UINT32 DxeCodeBase;
  118. UINT32 DxeCodeSize;
  119. TD_RETURN_DATA TdReturnData;
  120. VOID *VmmHobList;
  121. UINT8 *CfvBase;
  122. Status = EFI_SUCCESS;
  123. BootFv = NULL;
  124. VmmHobList = NULL;
  125. SecCoreData = (EFI_SEC_PEI_HAND_OFF *)Context;
  126. CfvBase = (UINT8 *)(UINTN)FixedPcdGet32 (PcdCfvBase);
  127. ZeroMem (&PlatformInfoHob, sizeof (PlatformInfoHob));
  128. if (TdIsEnabled ()) {
  129. VmmHobList = (VOID *)(UINTN)FixedPcdGet32 (PcdOvmfSecGhcbBase);
  130. Status = TdCall (TDCALL_TDINFO, 0, 0, 0, &TdReturnData);
  131. ASSERT (Status == EFI_SUCCESS);
  132. DEBUG ((
  133. DEBUG_INFO,
  134. "Tdx started with(Hob: 0x%x, Gpaw: 0x%x, Cpus: %d)\n",
  135. (UINT32)(UINTN)VmmHobList,
  136. GET_GPAW_INIT_STATE (TdReturnData.TdInfo.Gpaw),
  137. TdReturnData.TdInfo.NumVcpus
  138. ));
  139. Status = ConstructFwHobList (VmmHobList);
  140. } else {
  141. DEBUG ((DEBUG_INFO, "Ovmf started\n"));
  142. Status = ConstructSecHobList ();
  143. }
  144. if (EFI_ERROR (Status)) {
  145. ASSERT (FALSE);
  146. CpuDeadLoop ();
  147. }
  148. DEBUG ((DEBUG_INFO, "HobList: %p\n", GetHobList ()));
  149. if (TdIsEnabled ()) {
  150. //
  151. // Measure HobList
  152. //
  153. Status = MeasureHobList (VmmHobList);
  154. if (EFI_ERROR (Status)) {
  155. ASSERT (FALSE);
  156. CpuDeadLoop ();
  157. }
  158. //
  159. // Measure Tdx CFV
  160. //
  161. Status = MeasureFvImage ((EFI_PHYSICAL_ADDRESS)(UINTN)CfvBase, FixedPcdGet32 (PcdCfvRawDataSize), 1);
  162. if (EFI_ERROR (Status)) {
  163. ASSERT (FALSE);
  164. CpuDeadLoop ();
  165. }
  166. }
  167. //
  168. // Initialize the Platform
  169. //
  170. Status = InitializePlatform (&PlatformInfoHob);
  171. if (EFI_ERROR (Status)) {
  172. ASSERT (FALSE);
  173. CpuDeadLoop ();
  174. }
  175. BuildGuidDataHob (&gUefiOvmfPkgPlatformInfoGuid, &PlatformInfoHob, sizeof (EFI_HOB_PLATFORM_INFO));
  176. //
  177. // SecFV
  178. //
  179. BootFv = (EFI_FIRMWARE_VOLUME_HEADER *)SecCoreData->BootFirmwareVolumeBase;
  180. BuildFvHob ((UINTN)BootFv, BootFv->FvLength);
  181. //
  182. // DxeFV
  183. //
  184. DxeCodeBase = PcdGet32 (PcdBfvBase);
  185. DxeCodeSize = PcdGet32 (PcdBfvRawDataSize) - (UINT32)BootFv->FvLength;
  186. BuildFvHob (DxeCodeBase, DxeCodeSize);
  187. DEBUG ((DEBUG_INFO, "SecFv : %p, 0x%x\n", BootFv, BootFv->FvLength));
  188. DEBUG ((DEBUG_INFO, "DxeFv : %x, 0x%x\n", DxeCodeBase, DxeCodeSize));
  189. BuildStackHob ((UINTN)SecCoreData->StackBase, SecCoreData->StackSize <<= 1);
  190. BuildResourceDescriptorHob (
  191. EFI_RESOURCE_SYSTEM_MEMORY,
  192. EFI_RESOURCE_ATTRIBUTE_PRESENT |
  193. EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
  194. EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
  195. EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
  196. EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
  197. EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |
  198. EFI_RESOURCE_ATTRIBUTE_TESTED,
  199. (UINT64)SecCoreData->TemporaryRamBase,
  200. (UINT64)SecCoreData->TemporaryRamSize
  201. );
  202. //
  203. // Load the DXE Core and transfer control to it.
  204. // Only DxeFV is in the compressed section.
  205. //
  206. Status = DxeLoadCore (1);
  207. //
  208. // Never arrive here.
  209. //
  210. ASSERT (FALSE);
  211. CpuDeadLoop ();
  212. }