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