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