]>
Commit | Line | Data |
---|---|---|
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 | |
33 | typedef 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 | |
41 | IA32_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 | |
51 | VOID\r | |
52 | EFIAPI\r | |
53 | SecCoreStartupWithStack (\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 |