]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/IntelTdx/Sec/SecMain.c
OvmfPkg: Refactor ProcessHobList
[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
1f29de4d
MX
65 //\r
66 // For Td guests, the memory map info is in TdHobLib. It should be processed\r
67 // first so that the memory is accepted. Otherwise access to the unaccepted\r
68 // memory will trigger tripple fault.\r
69 //\r
c0984d1f 70 if (TdxHelperProcessTdHob () != EFI_SUCCESS) {\r
1f29de4d
MX
71 CpuDeadLoop ();\r
72 }\r
73 }\r
74\r
75 //\r
76 // To ensure SMM can't be compromised on S3 resume, we must force re-init of\r
77 // the BaseExtractGuidedSectionLib. Since this is before library contructors\r
78 // are called, we must use a loop rather than SetMem.\r
79 //\r
80 Table = (UINT8 *)(UINTN)FixedPcdGet64 (PcdGuidedExtractHandlerTableAddress);\r
81 for (Index = 0;\r
82 Index < FixedPcdGet32 (PcdGuidedExtractHandlerTableSize);\r
83 ++Index)\r
84 {\r
85 Table[Index] = 0;\r
86 }\r
87\r
88 //\r
89 // Initialize IDT - Since this is before library constructors are called,\r
90 // we use a loop rather than CopyMem.\r
91 //\r
92 IdtTableInStack.PeiService = NULL;\r
93\r
94 for (Index = 0; Index < SEC_IDT_ENTRY_COUNT; Index++) {\r
95 //\r
96 // Declare the local variables that actually move the data elements as\r
97 // volatile to prevent the optimizer from replacing this function with\r
98 // the intrinsic memcpy()\r
99 //\r
100 CONST UINT8 *Src;\r
101 volatile UINT8 *Dst;\r
102 UINTN Byte;\r
103\r
104 Src = (CONST UINT8 *)&mIdtEntryTemplate;\r
105 Dst = (volatile UINT8 *)&IdtTableInStack.IdtTable[Index];\r
106\r
107 for (Byte = 0; Byte < sizeof (mIdtEntryTemplate); Byte++) {\r
108 Dst[Byte] = Src[Byte];\r
109 }\r
110 }\r
111\r
112 IdtDescriptor.Base = (UINTN)&IdtTableInStack.IdtTable;\r
113 IdtDescriptor.Limit = (UINT16)(sizeof (IdtTableInStack.IdtTable) - 1);\r
114\r
115 ProcessLibraryConstructorList (NULL, NULL);\r
116\r
117 //\r
118 // Load the IDTR.\r
119 //\r
120 AsmWriteIdtr (&IdtDescriptor);\r
121\r
76fda1de 122 if (CcProbe () == CcGuestTypeIntelTdx) {\r
1f29de4d
MX
123 //\r
124 // InitializeCpuExceptionHandlers () should be called in Td guests so that\r
125 // #VE exceptions can be handled correctly.\r
126 //\r
127 InitializeCpuExceptionHandlers (NULL);\r
128 }\r
129\r
130 DEBUG ((\r
131 DEBUG_INFO,\r
132 "SecCoreStartupWithStack(0x%x, 0x%x)\n",\r
133 (UINT32)(UINTN)BootFv,\r
134 (UINT32)(UINTN)TopOfCurrentStack\r
135 ));\r
136\r
137 //\r
138 // Initialize floating point operating environment\r
139 // to be compliant with UEFI spec.\r
140 //\r
141 InitializeFloatingPointUnits ();\r
142\r
143 //\r
144 // ASSERT that the Page Tables were set by the reset vector code to\r
145 // the address we expect.\r
146 //\r
147 ASSERT (AsmReadCr3 () == (UINTN)PcdGet32 (PcdOvmfSecPageTablesBase));\r
148\r
149 //\r
150 // |-------------| <-- TopOfCurrentStack\r
151 // | Stack | 32k\r
152 // |-------------|\r
153 // | Heap | 32k\r
154 // |-------------| <-- SecCoreData.TemporaryRamBase\r
155 //\r
156\r
157 ASSERT (\r
158 (UINTN)(PcdGet32 (PcdOvmfSecPeiTempRamBase) +\r
159 PcdGet32 (PcdOvmfSecPeiTempRamSize)) ==\r
160 (UINTN)TopOfCurrentStack\r
161 );\r
162\r
163 //\r
164 // Initialize SEC hand-off state\r
165 //\r
166 SecCoreData.DataSize = sizeof (EFI_SEC_PEI_HAND_OFF);\r
167\r
168 SecCoreData.TemporaryRamSize = (UINTN)PcdGet32 (PcdOvmfSecPeiTempRamSize);\r
169 SecCoreData.TemporaryRamBase = (VOID *)((UINT8 *)TopOfCurrentStack - SecCoreData.TemporaryRamSize);\r
170\r
171 SecCoreData.PeiTemporaryRamBase = SecCoreData.TemporaryRamBase;\r
172 SecCoreData.PeiTemporaryRamSize = SecCoreData.TemporaryRamSize >> 1;\r
173\r
174 SecCoreData.StackBase = (UINT8 *)SecCoreData.TemporaryRamBase + SecCoreData.PeiTemporaryRamSize;\r
175 SecCoreData.StackSize = SecCoreData.TemporaryRamSize >> 1;\r
176\r
177 SecCoreData.BootFirmwareVolumeBase = BootFv;\r
178 SecCoreData.BootFirmwareVolumeSize = (UINTN)BootFv->FvLength;\r
179\r
180 //\r
181 // Make sure the 8259 is masked before initializing the Debug Agent and the debug timer is enabled\r
182 //\r
183 IoWrite8 (0x21, 0xff);\r
184 IoWrite8 (0xA1, 0xff);\r
185\r
186 //\r
187 // Initialize Local APIC Timer hardware and disable Local APIC Timer\r
188 // interrupts before initializing the Debug Agent and the debug timer is\r
189 // enabled.\r
190 //\r
191 InitializeApicTimer (0, MAX_UINT32, TRUE, 5);\r
192 DisableApicTimerInterrupt ();\r
193\r
194 PeilessStartup (&SecCoreData);\r
195\r
196 ASSERT (FALSE);\r
197 CpuDeadLoop ();\r
198}\r