]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/IntelTdx/Sec/SecMain.c
OvmfPkg/IntelTdx: Measure TdHob and Configuration FV in SecMain
[mirror_edk2.git] / OvmfPkg / IntelTdx / Sec / SecMain.c
CommitLineData
1f29de4d
MX
1/** @file\r
2 Main SEC phase code. Transitions to PEI.\r
3\r
4 Copyright (c) 2008 - 2015, Intel Corporation. All rights reserved.<BR>\r
5 (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>\r
6 Copyright (c) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>\r
7\r
8 SPDX-License-Identifier: BSD-2-Clause-Patent\r
9\r
10**/\r
11\r
12#include <PiPei.h>\r
13\r
14#include <Library/PeimEntryPoint.h>\r
15#include <Library/BaseLib.h>\r
16#include <Library/DebugLib.h>\r
17#include <Library/BaseMemoryLib.h>\r
18#include <Library/PcdLib.h>\r
19#include <Library/UefiCpuLib.h>\r
20#include <Library/DebugAgentLib.h>\r
21#include <Library/IoLib.h>\r
22#include <Library/PeCoffLib.h>\r
23#include <Library/PeCoffGetEntryPointLib.h>\r
24#include <Library/LocalApicLib.h>\r
25#include <Library/CpuExceptionHandlerLib.h>\r
26#include <IndustryStandard/Tdx.h>\r
c0984d1f 27#include <Library/TdxHelperLib.h>\r
76fda1de 28#include <Library/CcProbeLib.h>\r
1f29de4d
MX
29#include <Library/PeilessStartupLib.h>\r
30\r
31#define SEC_IDT_ENTRY_COUNT 34\r
32\r
33typedef struct _SEC_IDT_TABLE {\r
34 EFI_PEI_SERVICES *PeiService;\r
35 IA32_IDT_GATE_DESCRIPTOR IdtTable[SEC_IDT_ENTRY_COUNT];\r
36} SEC_IDT_TABLE;\r
37\r
38//\r
39// Template of an IDT entry pointing to 10:FFFFFFE4h.\r
40//\r
41IA32_IDT_GATE_DESCRIPTOR mIdtEntryTemplate = {\r
42 { // Bits\r
43 0xffe4, // OffsetLow\r
44 0x10, // Selector\r
45 0x0, // Reserved_0\r
46 IA32_IDT_GATE_TYPE_INTERRUPT_32, // GateType\r
47 0xffff // OffsetHigh\r
48 }\r
49};\r
50\r
51VOID\r
52EFIAPI\r
53SecCoreStartupWithStack (\r
54 IN EFI_FIRMWARE_VOLUME_HEADER *BootFv,\r
55 IN VOID *TopOfCurrentStack\r
56 )\r
57{\r
58 EFI_SEC_PEI_HAND_OFF SecCoreData;\r
59 SEC_IDT_TABLE IdtTableInStack;\r
60 IA32_DESCRIPTOR IdtDescriptor;\r
61 UINT32 Index;\r
62 volatile UINT8 *Table;\r
63\r
76fda1de 64 if (CcProbe () == CcGuestTypeIntelTdx) {\r
019621d0
MX
65 //\r
66 // From the security perspective all the external input should be measured before\r
67 // it is consumed. TdHob and Configuration FV (Cfv) image are passed from VMM\r
68 // and should be measured here.\r
69 //\r
70 if (EFI_ERROR (TdxHelperMeasureTdHob ())) {\r
71 CpuDeadLoop ();\r
72 }\r
73\r
74 if (EFI_ERROR (TdxHelperMeasureCfvImage ())) {\r
75 CpuDeadLoop ();\r
76 }\r
77\r
1f29de4d
MX
78 //\r
79 // For Td guests, the memory map info is in TdHobLib. It should be processed\r
80 // first so that the memory is accepted. Otherwise access to the unaccepted\r
81 // memory will trigger tripple fault.\r
82 //\r
c0984d1f 83 if (TdxHelperProcessTdHob () != EFI_SUCCESS) {\r
1f29de4d
MX
84 CpuDeadLoop ();\r
85 }\r
86 }\r
87\r
88 //\r
89 // To ensure SMM can't be compromised on S3 resume, we must force re-init of\r
90 // the BaseExtractGuidedSectionLib. Since this is before library contructors\r
91 // are called, we must use a loop rather than SetMem.\r
92 //\r
93 Table = (UINT8 *)(UINTN)FixedPcdGet64 (PcdGuidedExtractHandlerTableAddress);\r
94 for (Index = 0;\r
95 Index < FixedPcdGet32 (PcdGuidedExtractHandlerTableSize);\r
96 ++Index)\r
97 {\r
98 Table[Index] = 0;\r
99 }\r
100\r
101 //\r
102 // Initialize IDT - Since this is before library constructors are called,\r
103 // we use a loop rather than CopyMem.\r
104 //\r
105 IdtTableInStack.PeiService = NULL;\r
106\r
107 for (Index = 0; Index < SEC_IDT_ENTRY_COUNT; Index++) {\r
108 //\r
109 // Declare the local variables that actually move the data elements as\r
110 // volatile to prevent the optimizer from replacing this function with\r
111 // the intrinsic memcpy()\r
112 //\r
113 CONST UINT8 *Src;\r
114 volatile UINT8 *Dst;\r
115 UINTN Byte;\r
116\r
117 Src = (CONST UINT8 *)&mIdtEntryTemplate;\r
118 Dst = (volatile UINT8 *)&IdtTableInStack.IdtTable[Index];\r
119\r
120 for (Byte = 0; Byte < sizeof (mIdtEntryTemplate); Byte++) {\r
121 Dst[Byte] = Src[Byte];\r
122 }\r
123 }\r
124\r
125 IdtDescriptor.Base = (UINTN)&IdtTableInStack.IdtTable;\r
126 IdtDescriptor.Limit = (UINT16)(sizeof (IdtTableInStack.IdtTable) - 1);\r
127\r
128 ProcessLibraryConstructorList (NULL, NULL);\r
129\r
130 //\r
131 // Load the IDTR.\r
132 //\r
133 AsmWriteIdtr (&IdtDescriptor);\r
134\r
76fda1de 135 if (CcProbe () == CcGuestTypeIntelTdx) {\r
1f29de4d
MX
136 //\r
137 // InitializeCpuExceptionHandlers () should be called in Td guests so that\r
138 // #VE exceptions can be handled correctly.\r
139 //\r
140 InitializeCpuExceptionHandlers (NULL);\r
141 }\r
142\r
143 DEBUG ((\r
144 DEBUG_INFO,\r
145 "SecCoreStartupWithStack(0x%x, 0x%x)\n",\r
146 (UINT32)(UINTN)BootFv,\r
147 (UINT32)(UINTN)TopOfCurrentStack\r
148 ));\r
149\r
150 //\r
151 // Initialize floating point operating environment\r
152 // to be compliant with UEFI spec.\r
153 //\r
154 InitializeFloatingPointUnits ();\r
155\r
156 //\r
157 // ASSERT that the Page Tables were set by the reset vector code to\r
158 // the address we expect.\r
159 //\r
160 ASSERT (AsmReadCr3 () == (UINTN)PcdGet32 (PcdOvmfSecPageTablesBase));\r
161\r
162 //\r
163 // |-------------| <-- TopOfCurrentStack\r
164 // | Stack | 32k\r
165 // |-------------|\r
166 // | Heap | 32k\r
167 // |-------------| <-- SecCoreData.TemporaryRamBase\r
168 //\r
169\r
170 ASSERT (\r
171 (UINTN)(PcdGet32 (PcdOvmfSecPeiTempRamBase) +\r
172 PcdGet32 (PcdOvmfSecPeiTempRamSize)) ==\r
173 (UINTN)TopOfCurrentStack\r
174 );\r
175\r
176 //\r
177 // Initialize SEC hand-off state\r
178 //\r
179 SecCoreData.DataSize = sizeof (EFI_SEC_PEI_HAND_OFF);\r
180\r
181 SecCoreData.TemporaryRamSize = (UINTN)PcdGet32 (PcdOvmfSecPeiTempRamSize);\r
182 SecCoreData.TemporaryRamBase = (VOID *)((UINT8 *)TopOfCurrentStack - SecCoreData.TemporaryRamSize);\r
183\r
184 SecCoreData.PeiTemporaryRamBase = SecCoreData.TemporaryRamBase;\r
185 SecCoreData.PeiTemporaryRamSize = SecCoreData.TemporaryRamSize >> 1;\r
186\r
187 SecCoreData.StackBase = (UINT8 *)SecCoreData.TemporaryRamBase + SecCoreData.PeiTemporaryRamSize;\r
188 SecCoreData.StackSize = SecCoreData.TemporaryRamSize >> 1;\r
189\r
190 SecCoreData.BootFirmwareVolumeBase = BootFv;\r
191 SecCoreData.BootFirmwareVolumeSize = (UINTN)BootFv->FvLength;\r
192\r
193 //\r
194 // Make sure the 8259 is masked before initializing the Debug Agent and the debug timer is enabled\r
195 //\r
196 IoWrite8 (0x21, 0xff);\r
197 IoWrite8 (0xA1, 0xff);\r
198\r
199 //\r
200 // Initialize Local APIC Timer hardware and disable Local APIC Timer\r
201 // interrupts before initializing the Debug Agent and the debug timer is\r
202 // enabled.\r
203 //\r
204 InitializeApicTimer (0, MAX_UINT32, TRUE, 5);\r
205 DisableApicTimerInterrupt ();\r
206\r
207 PeilessStartup (&SecCoreData);\r
208\r
209 ASSERT (FALSE);\r
210 CpuDeadLoop ();\r
211}\r