2 Main SEC phase code. Transitions to PEI.
4 Copyright (c) 2008 - 2015, Intel Corporation. All rights reserved.<BR>
5 (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
6 Copyright (c) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>
8 SPDX-License-Identifier: BSD-2-Clause-Patent
14 #include <Library/PeimEntryPoint.h>
15 #include <Library/BaseLib.h>
16 #include <Library/DebugLib.h>
17 #include <Library/BaseMemoryLib.h>
18 #include <Library/PcdLib.h>
19 #include <Library/UefiCpuLib.h>
20 #include <Library/DebugAgentLib.h>
21 #include <Library/IoLib.h>
22 #include <Library/PeCoffLib.h>
23 #include <Library/PeCoffGetEntryPointLib.h>
24 #include <Library/LocalApicLib.h>
25 #include <Library/CpuExceptionHandlerLib.h>
26 #include <IndustryStandard/Tdx.h>
27 #include <Library/PlatformInitLib.h>
28 #include <Library/CcProbeLib.h>
29 #include <Library/PeilessStartupLib.h>
31 #define SEC_IDT_ENTRY_COUNT 34
33 typedef struct _SEC_IDT_TABLE
{
34 EFI_PEI_SERVICES
*PeiService
;
35 IA32_IDT_GATE_DESCRIPTOR IdtTable
[SEC_IDT_ENTRY_COUNT
];
39 // Template of an IDT entry pointing to 10:FFFFFFE4h.
41 IA32_IDT_GATE_DESCRIPTOR mIdtEntryTemplate
= {
46 IA32_IDT_GATE_TYPE_INTERRUPT_32
, // GateType
53 SecCoreStartupWithStack (
54 IN EFI_FIRMWARE_VOLUME_HEADER
*BootFv
,
55 IN VOID
*TopOfCurrentStack
58 EFI_SEC_PEI_HAND_OFF SecCoreData
;
59 SEC_IDT_TABLE IdtTableInStack
;
60 IA32_DESCRIPTOR IdtDescriptor
;
62 volatile UINT8
*Table
;
64 if (CcProbe () == CcGuestTypeIntelTdx
) {
66 // For Td guests, the memory map info is in TdHobLib. It should be processed
67 // first so that the memory is accepted. Otherwise access to the unaccepted
68 // memory will trigger tripple fault.
70 if (ProcessTdxHobList () != EFI_SUCCESS
) {
76 // To ensure SMM can't be compromised on S3 resume, we must force re-init of
77 // the BaseExtractGuidedSectionLib. Since this is before library contructors
78 // are called, we must use a loop rather than SetMem.
80 Table
= (UINT8
*)(UINTN
)FixedPcdGet64 (PcdGuidedExtractHandlerTableAddress
);
82 Index
< FixedPcdGet32 (PcdGuidedExtractHandlerTableSize
);
89 // Initialize IDT - Since this is before library constructors are called,
90 // we use a loop rather than CopyMem.
92 IdtTableInStack
.PeiService
= NULL
;
94 for (Index
= 0; Index
< SEC_IDT_ENTRY_COUNT
; Index
++) {
96 // Declare the local variables that actually move the data elements as
97 // volatile to prevent the optimizer from replacing this function with
98 // the intrinsic memcpy()
104 Src
= (CONST UINT8
*)&mIdtEntryTemplate
;
105 Dst
= (volatile UINT8
*)&IdtTableInStack
.IdtTable
[Index
];
107 for (Byte
= 0; Byte
< sizeof (mIdtEntryTemplate
); Byte
++) {
108 Dst
[Byte
] = Src
[Byte
];
112 IdtDescriptor
.Base
= (UINTN
)&IdtTableInStack
.IdtTable
;
113 IdtDescriptor
.Limit
= (UINT16
)(sizeof (IdtTableInStack
.IdtTable
) - 1);
115 ProcessLibraryConstructorList (NULL
, NULL
);
120 AsmWriteIdtr (&IdtDescriptor
);
122 if (CcProbe () == CcGuestTypeIntelTdx
) {
124 // InitializeCpuExceptionHandlers () should be called in Td guests so that
125 // #VE exceptions can be handled correctly.
127 InitializeCpuExceptionHandlers (NULL
);
132 "SecCoreStartupWithStack(0x%x, 0x%x)\n",
133 (UINT32
)(UINTN
)BootFv
,
134 (UINT32
)(UINTN
)TopOfCurrentStack
138 // Initialize floating point operating environment
139 // to be compliant with UEFI spec.
141 InitializeFloatingPointUnits ();
144 // ASSERT that the Page Tables were set by the reset vector code to
145 // the address we expect.
147 ASSERT (AsmReadCr3 () == (UINTN
)PcdGet32 (PcdOvmfSecPageTablesBase
));
150 // |-------------| <-- TopOfCurrentStack
154 // |-------------| <-- SecCoreData.TemporaryRamBase
158 (UINTN
)(PcdGet32 (PcdOvmfSecPeiTempRamBase
) +
159 PcdGet32 (PcdOvmfSecPeiTempRamSize
)) ==
160 (UINTN
)TopOfCurrentStack
164 // Initialize SEC hand-off state
166 SecCoreData
.DataSize
= sizeof (EFI_SEC_PEI_HAND_OFF
);
168 SecCoreData
.TemporaryRamSize
= (UINTN
)PcdGet32 (PcdOvmfSecPeiTempRamSize
);
169 SecCoreData
.TemporaryRamBase
= (VOID
*)((UINT8
*)TopOfCurrentStack
- SecCoreData
.TemporaryRamSize
);
171 SecCoreData
.PeiTemporaryRamBase
= SecCoreData
.TemporaryRamBase
;
172 SecCoreData
.PeiTemporaryRamSize
= SecCoreData
.TemporaryRamSize
>> 1;
174 SecCoreData
.StackBase
= (UINT8
*)SecCoreData
.TemporaryRamBase
+ SecCoreData
.PeiTemporaryRamSize
;
175 SecCoreData
.StackSize
= SecCoreData
.TemporaryRamSize
>> 1;
177 SecCoreData
.BootFirmwareVolumeBase
= BootFv
;
178 SecCoreData
.BootFirmwareVolumeSize
= (UINTN
)BootFv
->FvLength
;
181 // Make sure the 8259 is masked before initializing the Debug Agent and the debug timer is enabled
183 IoWrite8 (0x21, 0xff);
184 IoWrite8 (0xA1, 0xff);
187 // Initialize Local APIC Timer hardware and disable Local APIC Timer
188 // interrupts before initializing the Debug Agent and the debug timer is
191 InitializeApicTimer (0, MAX_UINT32
, TRUE
, 5);
192 DisableApicTimerInterrupt ();
194 PeilessStartup (&SecCoreData
);