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 <Library/TdxHelperLib.h>
|
---|
21 | #include <ConfidentialComputingGuestAttr.h>
|
---|
22 | #include <Guid/MemoryTypeInformation.h>
|
---|
23 | #include <OvmfPlatforms.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 | VOID *VariableStore;
|
---|
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 | 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 | PlatformInfoHob->LowMemory
|
---|
81 | ));
|
---|
82 |
|
---|
83 | VariableStore = PlatformReserveEmuVariableNvStore ();
|
---|
84 | PlatformInfoHob->PcdEmuVariableNvStoreReserved = (UINT64)(UINTN)VariableStore;
|
---|
85 | if (FeaturePcdGet (PcdSecureBootSupported)) {
|
---|
86 | PlatformInitEmuVariableNvStore (VariableStore);
|
---|
87 | }
|
---|
88 |
|
---|
89 | if (TdIsEnabled ()) {
|
---|
90 | PlatformTdxPublishRamRegions ();
|
---|
91 | } else {
|
---|
92 | PlatformQemuInitializeRam (PlatformInfoHob);
|
---|
93 | PlatformQemuInitializeRamForS3 (PlatformInfoHob);
|
---|
94 | }
|
---|
95 |
|
---|
96 | //
|
---|
97 | // Create Memory Type Information HOB
|
---|
98 | //
|
---|
99 | BuildGuidDataHob (
|
---|
100 | &gEfiMemoryTypeInformationGuid,
|
---|
101 | mDefaultMemoryTypeInformation,
|
---|
102 | sizeof (mDefaultMemoryTypeInformation)
|
---|
103 | );
|
---|
104 |
|
---|
105 | PlatformMemMapInitialization (PlatformInfoHob);
|
---|
106 |
|
---|
107 | PlatformNoexecDxeInitialization (PlatformInfoHob);
|
---|
108 |
|
---|
109 | if (TdIsEnabled ()) {
|
---|
110 | PlatformInfoHob->PcdConfidentialComputingGuestAttr = CCAttrIntelTdx;
|
---|
111 | PlatformInfoHob->PcdTdxSharedBitMask = TdSharedPageMask ();
|
---|
112 | PlatformInfoHob->PcdSetNxForStack = TRUE;
|
---|
113 | }
|
---|
114 |
|
---|
115 | PlatformMiscInitialization (PlatformInfoHob);
|
---|
116 |
|
---|
117 | return EFI_SUCCESS;
|
---|
118 | }
|
---|
119 |
|
---|
120 | /**
|
---|
121 | * This function brings up the Tdx guest from SEC phase to DXE phase.
|
---|
122 | * PEI phase is skipped because most of the components in PEI phase
|
---|
123 | * is not needed for Tdx guest, for example, MP Services, TPM etc.
|
---|
124 | * In this way, the attack surfaces are reduced as much as possible.
|
---|
125 | *
|
---|
126 | * @param Context The pointer to the SecCoreData
|
---|
127 | * @return VOID This function never returns
|
---|
128 | */
|
---|
129 | VOID
|
---|
130 | EFIAPI
|
---|
131 | PeilessStartup (
|
---|
132 | IN VOID *Context
|
---|
133 | )
|
---|
134 | {
|
---|
135 | EFI_SEC_PEI_HAND_OFF *SecCoreData;
|
---|
136 | EFI_FIRMWARE_VOLUME_HEADER *BootFv;
|
---|
137 | EFI_STATUS Status;
|
---|
138 | EFI_HOB_PLATFORM_INFO PlatformInfoHob;
|
---|
139 | UINT32 DxeCodeBase;
|
---|
140 | UINT32 DxeCodeSize;
|
---|
141 | TD_RETURN_DATA TdReturnData;
|
---|
142 | VOID *VmmHobList;
|
---|
143 |
|
---|
144 | Status = EFI_SUCCESS;
|
---|
145 | BootFv = NULL;
|
---|
146 | VmmHobList = NULL;
|
---|
147 | SecCoreData = (EFI_SEC_PEI_HAND_OFF *)Context;
|
---|
148 |
|
---|
149 | ZeroMem (&PlatformInfoHob, sizeof (PlatformInfoHob));
|
---|
150 |
|
---|
151 | if (TdIsEnabled ()) {
|
---|
152 | VmmHobList = (VOID *)(UINTN)FixedPcdGet32 (PcdOvmfSecGhcbBase);
|
---|
153 | Status = TdCall (TDCALL_TDINFO, 0, 0, 0, &TdReturnData);
|
---|
154 | ASSERT (Status == EFI_SUCCESS);
|
---|
155 |
|
---|
156 | DEBUG ((
|
---|
157 | DEBUG_INFO,
|
---|
158 | "Tdx started with(Hob: 0x%x, Gpaw: 0x%x, Cpus: %d)\n",
|
---|
159 | (UINT32)(UINTN)VmmHobList,
|
---|
160 | GET_GPAW_INIT_STATE (TdReturnData.TdInfo.Gpaw),
|
---|
161 | TdReturnData.TdInfo.NumVcpus
|
---|
162 | ));
|
---|
163 |
|
---|
164 | Status = ConstructFwHobList (VmmHobList);
|
---|
165 | } else {
|
---|
166 | DEBUG ((DEBUG_INFO, "Ovmf started\n"));
|
---|
167 | Status = ConstructSecHobList ();
|
---|
168 | }
|
---|
169 |
|
---|
170 | if (EFI_ERROR (Status)) {
|
---|
171 | ASSERT (FALSE);
|
---|
172 | CpuDeadLoop ();
|
---|
173 | }
|
---|
174 |
|
---|
175 | DEBUG ((DEBUG_INFO, "HobList: %p\n", GetHobList ()));
|
---|
176 |
|
---|
177 | if (TdIsEnabled ()) {
|
---|
178 | //
|
---|
179 | // Build GuidHob for the tdx measurements which were done in SEC phase.
|
---|
180 | //
|
---|
181 | Status = TdxHelperBuildGuidHobForTdxMeasurement ();
|
---|
182 | if (EFI_ERROR (Status)) {
|
---|
183 | ASSERT (FALSE);
|
---|
184 | CpuDeadLoop ();
|
---|
185 | }
|
---|
186 | }
|
---|
187 |
|
---|
188 | //
|
---|
189 | // Initialize the Platform
|
---|
190 | //
|
---|
191 | Status = InitializePlatform (&PlatformInfoHob);
|
---|
192 | if (EFI_ERROR (Status)) {
|
---|
193 | ASSERT (FALSE);
|
---|
194 | CpuDeadLoop ();
|
---|
195 | }
|
---|
196 |
|
---|
197 | BuildGuidDataHob (&gUefiOvmfPkgPlatformInfoGuid, &PlatformInfoHob, sizeof (EFI_HOB_PLATFORM_INFO));
|
---|
198 |
|
---|
199 | //
|
---|
200 | // SecFV
|
---|
201 | //
|
---|
202 | BootFv = (EFI_FIRMWARE_VOLUME_HEADER *)SecCoreData->BootFirmwareVolumeBase;
|
---|
203 | BuildFvHob ((UINTN)BootFv, BootFv->FvLength);
|
---|
204 |
|
---|
205 | //
|
---|
206 | // DxeFV
|
---|
207 | //
|
---|
208 | DxeCodeBase = PcdGet32 (PcdBfvBase);
|
---|
209 | DxeCodeSize = PcdGet32 (PcdBfvRawDataSize) - (UINT32)BootFv->FvLength;
|
---|
210 | BuildFvHob (DxeCodeBase, DxeCodeSize);
|
---|
211 |
|
---|
212 | DEBUG ((DEBUG_INFO, "SecFv : %p, 0x%x\n", BootFv, BootFv->FvLength));
|
---|
213 | DEBUG ((DEBUG_INFO, "DxeFv : %x, 0x%x\n", DxeCodeBase, DxeCodeSize));
|
---|
214 |
|
---|
215 | BuildStackHob ((UINTN)SecCoreData->StackBase, SecCoreData->StackSize <<= 1);
|
---|
216 |
|
---|
217 | BuildResourceDescriptorHob (
|
---|
218 | EFI_RESOURCE_SYSTEM_MEMORY,
|
---|
219 | EFI_RESOURCE_ATTRIBUTE_PRESENT |
|
---|
220 | EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
|
---|
221 | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
|
---|
222 | EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
|
---|
223 | EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
|
---|
224 | EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |
|
---|
225 | EFI_RESOURCE_ATTRIBUTE_TESTED,
|
---|
226 | (UINT64)SecCoreData->TemporaryRamBase,
|
---|
227 | (UINT64)SecCoreData->TemporaryRamSize
|
---|
228 | );
|
---|
229 |
|
---|
230 | //
|
---|
231 | // Load the DXE Core and transfer control to it.
|
---|
232 | // Only DxeFV is in the compressed section.
|
---|
233 | //
|
---|
234 | Status = DxeLoadCore (1);
|
---|
235 |
|
---|
236 | //
|
---|
237 | // Never arrive here.
|
---|
238 | //
|
---|
239 | ASSERT (FALSE);
|
---|
240 | CpuDeadLoop ();
|
---|
241 | }
|
---|