]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/Sec/SecMain.c
OvmfPkg: Add CpuLib to module INFs that depend on UefiCpuLib.
[mirror_edk2.git] / OvmfPkg / Sec / SecMain.c
CommitLineData
bb4aa855
JJ
1/** @file\r
2 Main SEC phase code. Transitions to PEI.\r
3\r
f3e34b9d 4 Copyright (c) 2008 - 2015, Intel Corporation. All rights reserved.<BR>\r
5e443e37 5 (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>\r
b78de543 6 Copyright (c) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>\r
bb4aa855 7\r
b26f0cf9 8 SPDX-License-Identifier: BSD-2-Clause-Patent\r
bb4aa855
JJ
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/PeiServicesLib.h>\r
19#include <Library/PcdLib.h>\r
1783b099 20#include <Library/CpuLib.h>\r
bb4aa855
JJ
21#include <Library/UefiCpuLib.h>\r
22#include <Library/DebugAgentLib.h>\r
23#include <Library/IoLib.h>\r
24#include <Library/PeCoffLib.h>\r
25#include <Library/PeCoffGetEntryPointLib.h>\r
26#include <Library/PeCoffExtraActionLib.h>\r
27#include <Library/ExtractGuidedSectionLib.h>\r
f3e34b9d 28#include <Library/LocalApicLib.h>\r
13e5492b 29#include <Library/CpuExceptionHandlerLib.h>\r
bb4aa855 30#include <Ppi/TemporaryRamSupport.h>\r
2b80269d 31#include <Library/PlatformInitLib.h>\r
76fda1de 32#include <Library/CcProbeLib.h>\r
2ddacfb6
BS
33#include "AmdSev.h"\r
34\r
bb4aa855
JJ
35#define SEC_IDT_ENTRY_COUNT 34\r
36\r
37typedef struct _SEC_IDT_TABLE {\r
ac0a286f
MK
38 EFI_PEI_SERVICES *PeiService;\r
39 IA32_IDT_GATE_DESCRIPTOR IdtTable[SEC_IDT_ENTRY_COUNT];\r
bb4aa855
JJ
40} SEC_IDT_TABLE;\r
41\r
42VOID\r
43EFIAPI\r
44SecStartupPhase2 (\r
ac0a286f 45 IN VOID *Context\r
bb4aa855
JJ
46 );\r
47\r
48EFI_STATUS\r
49EFIAPI\r
50TemporaryRamMigration (\r
ac0a286f
MK
51 IN CONST EFI_PEI_SERVICES **PeiServices,\r
52 IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,\r
53 IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,\r
54 IN UINTN CopySize\r
bb4aa855
JJ
55 );\r
56\r
57//\r
58//\r
4040754d 59//\r
ac0a286f 60EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI mTemporaryRamSupportPpi = {\r
bb4aa855
JJ
61 TemporaryRamMigration\r
62};\r
63\r
ac0a286f 64EFI_PEI_PPI_DESCRIPTOR mPrivateDispatchTable[] = {\r
bb4aa855
JJ
65 {\r
66 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
67 &gEfiTemporaryRamSupportPpiGuid,\r
68 &mTemporaryRamSupportPpi\r
69 },\r
70};\r
71\r
72//\r
73// Template of an IDT entry pointing to 10:FFFFFFE4h.\r
74//\r
75IA32_IDT_GATE_DESCRIPTOR mIdtEntryTemplate = {\r
76 { // Bits\r
77 0xffe4, // OffsetLow\r
78 0x10, // Selector\r
79 0x0, // Reserved_0\r
80 IA32_IDT_GATE_TYPE_INTERRUPT_32, // GateType\r
81 0xffff // OffsetHigh\r
4040754d 82 }\r
bb4aa855
JJ
83};\r
84\r
85/**\r
86 Locates the main boot firmware volume.\r
87\r
88 @param[in,out] BootFv On input, the base of the BootFv\r
89 On output, the decompressed main firmware volume\r
90\r
91 @retval EFI_SUCCESS The main firmware volume was located and decompressed\r
92 @retval EFI_NOT_FOUND The main firmware volume was not found\r
93\r
94**/\r
95EFI_STATUS\r
96FindMainFv (\r
ac0a286f 97 IN OUT EFI_FIRMWARE_VOLUME_HEADER **BootFv\r
bb4aa855
JJ
98 )\r
99{\r
100 EFI_FIRMWARE_VOLUME_HEADER *Fv;\r
101 UINTN Distance;\r
102\r
ac0a286f 103 ASSERT (((UINTN)*BootFv & EFI_PAGE_MASK) == 0);\r
bb4aa855 104\r
ac0a286f
MK
105 Fv = *BootFv;\r
106 Distance = (UINTN)(*BootFv)->FvLength;\r
bb4aa855 107 do {\r
ac0a286f 108 Fv = (EFI_FIRMWARE_VOLUME_HEADER *)((UINT8 *)Fv - EFI_PAGE_SIZE);\r
bb4aa855
JJ
109 Distance += EFI_PAGE_SIZE;\r
110 if (Distance > SIZE_32MB) {\r
111 return EFI_NOT_FOUND;\r
112 }\r
113\r
114 if (Fv->Signature != EFI_FVH_SIGNATURE) {\r
115 continue;\r
116 }\r
117\r
ac0a286f 118 if ((UINTN)Fv->FvLength > Distance) {\r
bb4aa855
JJ
119 continue;\r
120 }\r
121\r
122 *BootFv = Fv;\r
123 return EFI_SUCCESS;\r
bb4aa855
JJ
124 } while (TRUE);\r
125}\r
126\r
127/**\r
128 Locates a section within a series of sections\r
129 with the specified section type.\r
130\r
4b4b783d
JJ
131 The Instance parameter indicates which instance of the section\r
132 type to return. (0 is first instance, 1 is second...)\r
133\r
bb4aa855
JJ
134 @param[in] Sections The sections to search\r
135 @param[in] SizeOfSections Total size of all sections\r
136 @param[in] SectionType The section type to locate\r
4b4b783d 137 @param[in] Instance The section instance number\r
bb4aa855
JJ
138 @param[out] FoundSection The FFS section if found\r
139\r
140 @retval EFI_SUCCESS The file and section was found\r
141 @retval EFI_NOT_FOUND The file and section was not found\r
142 @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted\r
143\r
144**/\r
145EFI_STATUS\r
4b4b783d 146FindFfsSectionInstance (\r
ac0a286f
MK
147 IN VOID *Sections,\r
148 IN UINTN SizeOfSections,\r
149 IN EFI_SECTION_TYPE SectionType,\r
150 IN UINTN Instance,\r
151 OUT EFI_COMMON_SECTION_HEADER **FoundSection\r
bb4aa855
JJ
152 )\r
153{\r
ac0a286f
MK
154 EFI_PHYSICAL_ADDRESS CurrentAddress;\r
155 UINT32 Size;\r
156 EFI_PHYSICAL_ADDRESS EndOfSections;\r
157 EFI_COMMON_SECTION_HEADER *Section;\r
158 EFI_PHYSICAL_ADDRESS EndOfSection;\r
bb4aa855
JJ
159\r
160 //\r
161 // Loop through the FFS file sections within the PEI Core FFS file\r
162 //\r
ac0a286f 163 EndOfSection = (EFI_PHYSICAL_ADDRESS)(UINTN)Sections;\r
bb4aa855 164 EndOfSections = EndOfSection + SizeOfSections;\r
ac0a286f 165 for ( ; ;) {\r
bb4aa855
JJ
166 if (EndOfSection == EndOfSections) {\r
167 break;\r
168 }\r
ac0a286f 169\r
bb4aa855
JJ
170 CurrentAddress = (EndOfSection + 3) & ~(3ULL);\r
171 if (CurrentAddress >= EndOfSections) {\r
172 return EFI_VOLUME_CORRUPTED;\r
173 }\r
174\r
ac0a286f 175 Section = (EFI_COMMON_SECTION_HEADER *)(UINTN)CurrentAddress;\r
bb4aa855
JJ
176\r
177 Size = SECTION_SIZE (Section);\r
178 if (Size < sizeof (*Section)) {\r
179 return EFI_VOLUME_CORRUPTED;\r
180 }\r
181\r
182 EndOfSection = CurrentAddress + Size;\r
183 if (EndOfSection > EndOfSections) {\r
184 return EFI_VOLUME_CORRUPTED;\r
185 }\r
186\r
187 //\r
188 // Look for the requested section type\r
189 //\r
190 if (Section->Type == SectionType) {\r
4b4b783d
JJ
191 if (Instance == 0) {\r
192 *FoundSection = Section;\r
193 return EFI_SUCCESS;\r
194 } else {\r
195 Instance--;\r
196 }\r
bb4aa855 197 }\r
bb4aa855
JJ
198 }\r
199\r
200 return EFI_NOT_FOUND;\r
201}\r
202\r
4b4b783d
JJ
203/**\r
204 Locates a section within a series of sections\r
205 with the specified section type.\r
206\r
207 @param[in] Sections The sections to search\r
208 @param[in] SizeOfSections Total size of all sections\r
209 @param[in] SectionType The section type to locate\r
210 @param[out] FoundSection The FFS section if found\r
211\r
212 @retval EFI_SUCCESS The file and section was found\r
213 @retval EFI_NOT_FOUND The file and section was not found\r
214 @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted\r
215\r
216**/\r
217EFI_STATUS\r
218FindFfsSectionInSections (\r
ac0a286f
MK
219 IN VOID *Sections,\r
220 IN UINTN SizeOfSections,\r
221 IN EFI_SECTION_TYPE SectionType,\r
222 OUT EFI_COMMON_SECTION_HEADER **FoundSection\r
4b4b783d
JJ
223 )\r
224{\r
225 return FindFfsSectionInstance (\r
226 Sections,\r
227 SizeOfSections,\r
228 SectionType,\r
229 0,\r
230 FoundSection\r
231 );\r
232}\r
233\r
bb4aa855
JJ
234/**\r
235 Locates a FFS file with the specified file type and a section\r
236 within that file with the specified section type.\r
237\r
238 @param[in] Fv The firmware volume to search\r
239 @param[in] FileType The file type to locate\r
240 @param[in] SectionType The section type to locate\r
241 @param[out] FoundSection The FFS section if found\r
242\r
243 @retval EFI_SUCCESS The file and section was found\r
244 @retval EFI_NOT_FOUND The file and section was not found\r
245 @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted\r
246\r
247**/\r
248EFI_STATUS\r
bb4aa855 249FindFfsFileAndSection (\r
ac0a286f
MK
250 IN EFI_FIRMWARE_VOLUME_HEADER *Fv,\r
251 IN EFI_FV_FILETYPE FileType,\r
252 IN EFI_SECTION_TYPE SectionType,\r
253 OUT EFI_COMMON_SECTION_HEADER **FoundSection\r
bb4aa855
JJ
254 )\r
255{\r
ac0a286f
MK
256 EFI_STATUS Status;\r
257 EFI_PHYSICAL_ADDRESS CurrentAddress;\r
258 EFI_PHYSICAL_ADDRESS EndOfFirmwareVolume;\r
259 EFI_FFS_FILE_HEADER *File;\r
260 UINT32 Size;\r
261 EFI_PHYSICAL_ADDRESS EndOfFile;\r
bb4aa855
JJ
262\r
263 if (Fv->Signature != EFI_FVH_SIGNATURE) {\r
70d5086c 264 DEBUG ((DEBUG_ERROR, "FV at %p does not have FV header signature\n", Fv));\r
bb4aa855
JJ
265 return EFI_VOLUME_CORRUPTED;\r
266 }\r
267\r
ac0a286f 268 CurrentAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Fv;\r
bb4aa855
JJ
269 EndOfFirmwareVolume = CurrentAddress + Fv->FvLength;\r
270\r
271 //\r
272 // Loop through the FFS files in the Boot Firmware Volume\r
273 //\r
274 for (EndOfFile = CurrentAddress + Fv->HeaderLength; ; ) {\r
bb4aa855
JJ
275 CurrentAddress = (EndOfFile + 7) & ~(7ULL);\r
276 if (CurrentAddress > EndOfFirmwareVolume) {\r
277 return EFI_VOLUME_CORRUPTED;\r
278 }\r
279\r
ac0a286f 280 File = (EFI_FFS_FILE_HEADER *)(UINTN)CurrentAddress;\r
b9d4847e 281 Size = FFS_FILE_SIZE (File);\r
bb4aa855
JJ
282 if (Size < (sizeof (*File) + sizeof (EFI_COMMON_SECTION_HEADER))) {\r
283 return EFI_VOLUME_CORRUPTED;\r
284 }\r
bb4aa855
JJ
285\r
286 EndOfFile = CurrentAddress + Size;\r
287 if (EndOfFile > EndOfFirmwareVolume) {\r
288 return EFI_VOLUME_CORRUPTED;\r
289 }\r
290\r
291 //\r
292 // Look for the request file type\r
293 //\r
294 if (File->Type != FileType) {\r
bb4aa855
JJ
295 continue;\r
296 }\r
297\r
298 Status = FindFfsSectionInSections (\r
ac0a286f
MK
299 (VOID *)(File + 1),\r
300 (UINTN)EndOfFile - (UINTN)(File + 1),\r
bb4aa855
JJ
301 SectionType,\r
302 FoundSection\r
303 );\r
304 if (!EFI_ERROR (Status) || (Status == EFI_VOLUME_CORRUPTED)) {\r
305 return Status;\r
306 }\r
307 }\r
308}\r
309\r
310/**\r
311 Locates the compressed main firmware volume and decompresses it.\r
312\r
313 @param[in,out] Fv On input, the firmware volume to search\r
b36f701d 314 On output, the decompressed BOOT/PEI FV\r
bb4aa855
JJ
315\r
316 @retval EFI_SUCCESS The file and section was found\r
317 @retval EFI_NOT_FOUND The file and section was not found\r
318 @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted\r
319\r
320**/\r
321EFI_STATUS\r
b36f701d 322DecompressMemFvs (\r
ac0a286f 323 IN OUT EFI_FIRMWARE_VOLUME_HEADER **Fv\r
bb4aa855
JJ
324 )\r
325{\r
ac0a286f
MK
326 EFI_STATUS Status;\r
327 EFI_GUID_DEFINED_SECTION *Section;\r
328 UINT32 OutputBufferSize;\r
329 UINT32 ScratchBufferSize;\r
330 UINT16 SectionAttribute;\r
331 UINT32 AuthenticationStatus;\r
332 VOID *OutputBuffer;\r
333 VOID *ScratchBuffer;\r
334 EFI_COMMON_SECTION_HEADER *FvSection;\r
335 EFI_FIRMWARE_VOLUME_HEADER *PeiMemFv;\r
336 EFI_FIRMWARE_VOLUME_HEADER *DxeMemFv;\r
337 UINT32 FvHeaderSize;\r
338 UINT32 FvSectionSize;\r
339\r
340 FvSection = (EFI_COMMON_SECTION_HEADER *)NULL;\r
bb4aa855
JJ
341\r
342 Status = FindFfsFileAndSection (\r
343 *Fv,\r
344 EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE,\r
345 EFI_SECTION_GUID_DEFINED,\r
ac0a286f 346 (EFI_COMMON_SECTION_HEADER **)&Section\r
bb4aa855
JJ
347 );\r
348 if (EFI_ERROR (Status)) {\r
70d5086c 349 DEBUG ((DEBUG_ERROR, "Unable to find GUID defined section\n"));\r
bb4aa855
JJ
350 return Status;\r
351 }\r
352\r
353 Status = ExtractGuidedSectionGetInfo (\r
354 Section,\r
355 &OutputBufferSize,\r
356 &ScratchBufferSize,\r
357 &SectionAttribute\r
358 );\r
359 if (EFI_ERROR (Status)) {\r
70d5086c 360 DEBUG ((DEBUG_ERROR, "Unable to GetInfo for GUIDed section\n"));\r
bb4aa855
JJ
361 return Status;\r
362 }\r
363\r
ac0a286f
MK
364 OutputBuffer = (VOID *)((UINT8 *)(UINTN)PcdGet32 (PcdOvmfDxeMemFvBase) + SIZE_1MB);\r
365 ScratchBuffer = ALIGN_POINTER ((UINT8 *)OutputBuffer + OutputBufferSize, SIZE_1MB);\r
366\r
367 DEBUG ((\r
368 DEBUG_VERBOSE,\r
369 "%a: OutputBuffer@%p+0x%x ScratchBuffer@%p+0x%x "\r
370 "PcdOvmfDecompressionScratchEnd=0x%x\n",\r
371 __FUNCTION__,\r
372 OutputBuffer,\r
373 OutputBufferSize,\r
374 ScratchBuffer,\r
375 ScratchBufferSize,\r
376 PcdGet32 (PcdOvmfDecompressionScratchEnd)\r
377 ));\r
378 ASSERT (\r
379 (UINTN)ScratchBuffer + ScratchBufferSize ==\r
380 PcdGet32 (PcdOvmfDecompressionScratchEnd)\r
381 );\r
9beac0d8 382\r
bb4aa855
JJ
383 Status = ExtractGuidedSectionDecode (\r
384 Section,\r
385 &OutputBuffer,\r
386 ScratchBuffer,\r
387 &AuthenticationStatus\r
388 );\r
389 if (EFI_ERROR (Status)) {\r
70d5086c 390 DEBUG ((DEBUG_ERROR, "Error during GUID section decode\n"));\r
bb4aa855
JJ
391 return Status;\r
392 }\r
393\r
b36f701d 394 Status = FindFfsSectionInstance (\r
bb4aa855
JJ
395 OutputBuffer,\r
396 OutputBufferSize,\r
397 EFI_SECTION_FIRMWARE_VOLUME_IMAGE,\r
b36f701d 398 0,\r
5e443e37 399 &FvSection\r
bb4aa855
JJ
400 );\r
401 if (EFI_ERROR (Status)) {\r
70d5086c 402 DEBUG ((DEBUG_ERROR, "Unable to find PEI FV section\n"));\r
bb4aa855
JJ
403 return Status;\r
404 }\r
405\r
ac0a286f
MK
406 ASSERT (\r
407 SECTION_SIZE (FvSection) ==\r
408 (PcdGet32 (PcdOvmfPeiMemFvSize) + sizeof (*FvSection))\r
409 );\r
b36f701d 410 ASSERT (FvSection->Type == EFI_SECTION_FIRMWARE_VOLUME_IMAGE);\r
bb4aa855 411\r
ac0a286f
MK
412 PeiMemFv = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)PcdGet32 (PcdOvmfPeiMemFvBase);\r
413 CopyMem (PeiMemFv, (VOID *)(FvSection + 1), PcdGet32 (PcdOvmfPeiMemFvSize));\r
b36f701d
JJ
414\r
415 if (PeiMemFv->Signature != EFI_FVH_SIGNATURE) {\r
70d5086c 416 DEBUG ((DEBUG_ERROR, "Extracted FV at %p does not have FV header signature\n", PeiMemFv));\r
b36f701d
JJ
417 CpuDeadLoop ();\r
418 return EFI_VOLUME_CORRUPTED;\r
419 }\r
420\r
421 Status = FindFfsSectionInstance (\r
422 OutputBuffer,\r
423 OutputBufferSize,\r
424 EFI_SECTION_FIRMWARE_VOLUME_IMAGE,\r
425 1,\r
5e443e37 426 &FvSection\r
b36f701d
JJ
427 );\r
428 if (EFI_ERROR (Status)) {\r
70d5086c 429 DEBUG ((DEBUG_ERROR, "Unable to find DXE FV section\n"));\r
b36f701d
JJ
430 return Status;\r
431 }\r
432\r
433 ASSERT (FvSection->Type == EFI_SECTION_FIRMWARE_VOLUME_IMAGE);\r
39dbc4d5
TP
434\r
435 if (IS_SECTION2 (FvSection)) {\r
436 FvSectionSize = SECTION2_SIZE (FvSection);\r
ac0a286f 437 FvHeaderSize = sizeof (EFI_COMMON_SECTION_HEADER2);\r
39dbc4d5
TP
438 } else {\r
439 FvSectionSize = SECTION_SIZE (FvSection);\r
ac0a286f 440 FvHeaderSize = sizeof (EFI_COMMON_SECTION_HEADER);\r
39dbc4d5
TP
441 }\r
442\r
443 ASSERT (FvSectionSize == (PcdGet32 (PcdOvmfDxeMemFvSize) + FvHeaderSize));\r
b36f701d 444\r
ac0a286f
MK
445 DxeMemFv = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)PcdGet32 (PcdOvmfDxeMemFvBase);\r
446 CopyMem (DxeMemFv, (VOID *)((UINTN)FvSection + FvHeaderSize), PcdGet32 (PcdOvmfDxeMemFvSize));\r
b36f701d
JJ
447\r
448 if (DxeMemFv->Signature != EFI_FVH_SIGNATURE) {\r
70d5086c 449 DEBUG ((DEBUG_ERROR, "Extracted FV at %p does not have FV header signature\n", DxeMemFv));\r
bb4aa855
JJ
450 CpuDeadLoop ();\r
451 return EFI_VOLUME_CORRUPTED;\r
452 }\r
453\r
b36f701d 454 *Fv = PeiMemFv;\r
bb4aa855
JJ
455 return EFI_SUCCESS;\r
456}\r
457\r
458/**\r
459 Locates the PEI Core entry point address\r
460\r
461 @param[in] Fv The firmware volume to search\r
462 @param[out] PeiCoreEntryPoint The entry point of the PEI Core image\r
463\r
464 @retval EFI_SUCCESS The file and section was found\r
465 @retval EFI_NOT_FOUND The file and section was not found\r
466 @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted\r
467\r
468**/\r
469EFI_STATUS\r
bb4aa855 470FindPeiCoreImageBaseInFv (\r
ac0a286f
MK
471 IN EFI_FIRMWARE_VOLUME_HEADER *Fv,\r
472 OUT EFI_PHYSICAL_ADDRESS *PeiCoreImageBase\r
bb4aa855
JJ
473 )\r
474{\r
ac0a286f
MK
475 EFI_STATUS Status;\r
476 EFI_COMMON_SECTION_HEADER *Section;\r
bb4aa855
JJ
477\r
478 Status = FindFfsFileAndSection (\r
479 Fv,\r
480 EFI_FV_FILETYPE_PEI_CORE,\r
481 EFI_SECTION_PE32,\r
482 &Section\r
483 );\r
484 if (EFI_ERROR (Status)) {\r
485 Status = FindFfsFileAndSection (\r
486 Fv,\r
487 EFI_FV_FILETYPE_PEI_CORE,\r
488 EFI_SECTION_TE,\r
489 &Section\r
490 );\r
491 if (EFI_ERROR (Status)) {\r
70d5086c 492 DEBUG ((DEBUG_ERROR, "Unable to find PEI Core image\n"));\r
bb4aa855
JJ
493 return Status;\r
494 }\r
495 }\r
496\r
497 *PeiCoreImageBase = (EFI_PHYSICAL_ADDRESS)(UINTN)(Section + 1);\r
498 return EFI_SUCCESS;\r
499}\r
500\r
a781f709
JJ
501/**\r
502 Reads 8-bits of CMOS data.\r
503\r
504 Reads the 8-bits of CMOS data at the location specified by Index.\r
505 The 8-bit read value is returned.\r
506\r
507 @param Index The CMOS location to read.\r
508\r
509 @return The value read.\r
510\r
511**/\r
512STATIC\r
513UINT8\r
514CmosRead8 (\r
ac0a286f 515 IN UINTN Index\r
a781f709
JJ
516 )\r
517{\r
ac0a286f 518 IoWrite8 (0x70, (UINT8)Index);\r
a781f709
JJ
519 return IoRead8 (0x71);\r
520}\r
521\r
a781f709
JJ
522STATIC\r
523BOOLEAN\r
524IsS3Resume (\r
525 VOID\r
526 )\r
527{\r
528 return (CmosRead8 (0xF) == 0xFE);\r
529}\r
530\r
a781f709
JJ
531STATIC\r
532EFI_STATUS\r
533GetS3ResumePeiFv (\r
ac0a286f 534 IN OUT EFI_FIRMWARE_VOLUME_HEADER **PeiFv\r
a781f709
JJ
535 )\r
536{\r
ac0a286f 537 *PeiFv = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)PcdGet32 (PcdOvmfPeiMemFvBase);\r
a781f709
JJ
538 return EFI_SUCCESS;\r
539}\r
540\r
bb4aa855
JJ
541/**\r
542 Locates the PEI Core entry point address\r
543\r
544 @param[in,out] Fv The firmware volume to search\r
545 @param[out] PeiCoreEntryPoint The entry point of the PEI Core image\r
546\r
547 @retval EFI_SUCCESS The file and section was found\r
548 @retval EFI_NOT_FOUND The file and section was not found\r
549 @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted\r
550\r
551**/\r
552VOID\r
bb4aa855 553FindPeiCoreImageBase (\r
ac0a286f
MK
554 IN OUT EFI_FIRMWARE_VOLUME_HEADER **BootFv,\r
555 OUT EFI_PHYSICAL_ADDRESS *PeiCoreImageBase\r
bb4aa855
JJ
556 )\r
557{\r
ac0a286f 558 BOOLEAN S3Resume;\r
efb0f16e 559\r
bb4aa855
JJ
560 *PeiCoreImageBase = 0;\r
561\r
efb0f16e
LE
562 S3Resume = IsS3Resume ();\r
563 if (S3Resume && !FeaturePcdGet (PcdSmmSmramRequire)) {\r
564 //\r
565 // A malicious runtime OS may have injected something into our previously\r
566 // decoded PEI FV, but we don't care about that unless SMM/SMRAM is required.\r
567 //\r
70d5086c 568 DEBUG ((DEBUG_VERBOSE, "SEC: S3 resume\n"));\r
a781f709
JJ
569 GetS3ResumePeiFv (BootFv);\r
570 } else {\r
efb0f16e
LE
571 //\r
572 // We're either not resuming, or resuming "securely" -- we'll decompress\r
573 // both PEI FV and DXE FV from pristine flash.\r
574 //\r
ac0a286f
MK
575 DEBUG ((\r
576 DEBUG_VERBOSE,\r
577 "SEC: %a\n",\r
578 S3Resume ? "S3 resume (with PEI decompression)" : "Normal boot"\r
579 ));\r
a781f709 580 FindMainFv (BootFv);\r
bb4aa855 581\r
a781f709
JJ
582 DecompressMemFvs (BootFv);\r
583 }\r
bb4aa855
JJ
584\r
585 FindPeiCoreImageBaseInFv (*BootFv, PeiCoreImageBase);\r
586}\r
587\r
588/**\r
589 Find core image base.\r
590\r
591**/\r
592EFI_STATUS\r
bb4aa855 593FindImageBase (\r
ac0a286f
MK
594 IN EFI_FIRMWARE_VOLUME_HEADER *BootFirmwareVolumePtr,\r
595 OUT EFI_PHYSICAL_ADDRESS *SecCoreImageBase\r
bb4aa855
JJ
596 )\r
597{\r
ac0a286f
MK
598 EFI_PHYSICAL_ADDRESS CurrentAddress;\r
599 EFI_PHYSICAL_ADDRESS EndOfFirmwareVolume;\r
600 EFI_FFS_FILE_HEADER *File;\r
601 UINT32 Size;\r
602 EFI_PHYSICAL_ADDRESS EndOfFile;\r
603 EFI_COMMON_SECTION_HEADER *Section;\r
604 EFI_PHYSICAL_ADDRESS EndOfSection;\r
bb4aa855
JJ
605\r
606 *SecCoreImageBase = 0;\r
607\r
ac0a286f 608 CurrentAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)BootFirmwareVolumePtr;\r
bb4aa855
JJ
609 EndOfFirmwareVolume = CurrentAddress + BootFirmwareVolumePtr->FvLength;\r
610\r
611 //\r
612 // Loop through the FFS files in the Boot Firmware Volume\r
613 //\r
614 for (EndOfFile = CurrentAddress + BootFirmwareVolumePtr->HeaderLength; ; ) {\r
bb4aa855
JJ
615 CurrentAddress = (EndOfFile + 7) & 0xfffffffffffffff8ULL;\r
616 if (CurrentAddress > EndOfFirmwareVolume) {\r
617 return EFI_NOT_FOUND;\r
618 }\r
619\r
ac0a286f 620 File = (EFI_FFS_FILE_HEADER *)(UINTN)CurrentAddress;\r
b9d4847e 621 Size = FFS_FILE_SIZE (File);\r
bb4aa855
JJ
622 if (Size < sizeof (*File)) {\r
623 return EFI_NOT_FOUND;\r
624 }\r
625\r
626 EndOfFile = CurrentAddress + Size;\r
627 if (EndOfFile > EndOfFirmwareVolume) {\r
628 return EFI_NOT_FOUND;\r
629 }\r
630\r
631 //\r
632 // Look for SEC Core\r
633 //\r
634 if (File->Type != EFI_FV_FILETYPE_SECURITY_CORE) {\r
635 continue;\r
636 }\r
637\r
638 //\r
639 // Loop through the FFS file sections within the FFS file\r
640 //\r
ac0a286f
MK
641 EndOfSection = (EFI_PHYSICAL_ADDRESS)(UINTN)(File + 1);\r
642 for ( ; ;) {\r
bb4aa855 643 CurrentAddress = (EndOfSection + 3) & 0xfffffffffffffffcULL;\r
ac0a286f 644 Section = (EFI_COMMON_SECTION_HEADER *)(UINTN)CurrentAddress;\r
bb4aa855 645\r
b9d4847e 646 Size = SECTION_SIZE (Section);\r
bb4aa855
JJ
647 if (Size < sizeof (*Section)) {\r
648 return EFI_NOT_FOUND;\r
649 }\r
650\r
651 EndOfSection = CurrentAddress + Size;\r
652 if (EndOfSection > EndOfFile) {\r
653 return EFI_NOT_FOUND;\r
654 }\r
655\r
656 //\r
657 // Look for executable sections\r
658 //\r
ac0a286f 659 if ((Section->Type == EFI_SECTION_PE32) || (Section->Type == EFI_SECTION_TE)) {\r
bb4aa855 660 if (File->Type == EFI_FV_FILETYPE_SECURITY_CORE) {\r
ac0a286f 661 *SecCoreImageBase = (PHYSICAL_ADDRESS)(UINTN)(Section + 1);\r
bb4aa855 662 }\r
ac0a286f 663\r
bb4aa855
JJ
664 break;\r
665 }\r
666 }\r
667\r
668 //\r
669 // SEC Core image found\r
670 //\r
671 if (*SecCoreImageBase != 0) {\r
672 return EFI_SUCCESS;\r
673 }\r
674 }\r
675}\r
676\r
677/*\r
678 Find and return Pei Core entry point.\r
679\r
f17c0ab6 680 It also find SEC and PEI Core file debug information. It will report them if\r
bb4aa855
JJ
681 remote debug is enabled.\r
682\r
683**/\r
684VOID\r
bb4aa855 685FindAndReportEntryPoints (\r
ac0a286f
MK
686 IN EFI_FIRMWARE_VOLUME_HEADER **BootFirmwareVolumePtr,\r
687 OUT EFI_PEI_CORE_ENTRY_POINT *PeiCoreEntryPoint\r
bb4aa855
JJ
688 )\r
689{\r
ac0a286f
MK
690 EFI_STATUS Status;\r
691 EFI_PHYSICAL_ADDRESS SecCoreImageBase;\r
692 EFI_PHYSICAL_ADDRESS PeiCoreImageBase;\r
693 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
bb4aa855
JJ
694\r
695 //\r
696 // Find SEC Core and PEI Core image base\r
ac0a286f 697 //\r
bb4aa855
JJ
698 Status = FindImageBase (*BootFirmwareVolumePtr, &SecCoreImageBase);\r
699 ASSERT_EFI_ERROR (Status);\r
700\r
701 FindPeiCoreImageBase (BootFirmwareVolumePtr, &PeiCoreImageBase);\r
4040754d 702\r
ac0a286f 703 ZeroMem ((VOID *)&ImageContext, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT));\r
bb4aa855
JJ
704 //\r
705 // Report SEC Core debug information when remote debug is enabled\r
706 //\r
707 ImageContext.ImageAddress = SecCoreImageBase;\r
ac0a286f 708 ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)ImageContext.ImageAddress);\r
bb4aa855
JJ
709 PeCoffLoaderRelocateImageExtraAction (&ImageContext);\r
710\r
711 //\r
712 // Report PEI Core debug information when remote debug is enabled\r
713 //\r
714 ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)PeiCoreImageBase;\r
ac0a286f 715 ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)ImageContext.ImageAddress);\r
bb4aa855
JJ
716 PeCoffLoaderRelocateImageExtraAction (&ImageContext);\r
717\r
718 //\r
719 // Find PEI Core entry point\r
720 //\r
ac0a286f 721 Status = PeCoffLoaderGetEntryPoint ((VOID *)(UINTN)PeiCoreImageBase, (VOID **)PeiCoreEntryPoint);\r
bb4aa855
JJ
722 if (EFI_ERROR (Status)) {\r
723 *PeiCoreEntryPoint = 0;\r
724 }\r
725\r
726 return;\r
727}\r
728\r
729VOID\r
730EFIAPI\r
731SecCoreStartupWithStack (\r
ac0a286f
MK
732 IN EFI_FIRMWARE_VOLUME_HEADER *BootFv,\r
733 IN VOID *TopOfCurrentStack\r
bb4aa855
JJ
734 )\r
735{\r
ac0a286f
MK
736 EFI_SEC_PEI_HAND_OFF SecCoreData;\r
737 SEC_IDT_TABLE IdtTableInStack;\r
738 IA32_DESCRIPTOR IdtDescriptor;\r
739 UINT32 Index;\r
740 volatile UINT8 *Table;\r
320b4f08 741\r
2b80269d 742 #if defined (TDX_GUEST_SUPPORTED)\r
76fda1de 743 if (CcProbe () == CcGuestTypeIntelTdx) {\r
2b80269d
MX
744 //\r
745 // For Td guests, the memory map info is in TdHobLib. It should be processed\r
746 // first so that the memory is accepted. Otherwise access to the unaccepted\r
747 // memory will trigger tripple fault.\r
748 //\r
749 if (ProcessTdxHobList () != EFI_SUCCESS) {\r
750 CpuDeadLoop ();\r
751 }\r
752 }\r
753\r
754 #endif\r
755\r
320b4f08
LE
756 //\r
757 // To ensure SMM can't be compromised on S3 resume, we must force re-init of\r
758 // the BaseExtractGuidedSectionLib. Since this is before library contructors\r
759 // are called, we must use a loop rather than SetMem.\r
760 //\r
ac0a286f 761 Table = (UINT8 *)(UINTN)FixedPcdGet64 (PcdGuidedExtractHandlerTableAddress);\r
320b4f08
LE
762 for (Index = 0;\r
763 Index < FixedPcdGet32 (PcdGuidedExtractHandlerTableSize);\r
ac0a286f
MK
764 ++Index)\r
765 {\r
320b4f08
LE
766 Table[Index] = 0;\r
767 }\r
bb4aa855 768\r
13e5492b
TL
769 //\r
770 // Initialize IDT - Since this is before library constructors are called,\r
771 // we use a loop rather than CopyMem.\r
772 //\r
773 IdtTableInStack.PeiService = NULL;\r
2b80269d 774\r
ac0a286f 775 for (Index = 0; Index < SEC_IDT_ENTRY_COUNT; Index++) {\r
ccca1c2d
MX
776 //\r
777 // Declare the local variables that actually move the data elements as\r
778 // volatile to prevent the optimizer from replacing this function with\r
779 // the intrinsic memcpy()\r
780 //\r
781 CONST UINT8 *Src;\r
782 volatile UINT8 *Dst;\r
783 UINTN Byte;\r
13e5492b 784\r
ccca1c2d
MX
785 Src = (CONST UINT8 *)&mIdtEntryTemplate;\r
786 Dst = (volatile UINT8 *)&IdtTableInStack.IdtTable[Index];\r
13e5492b
TL
787 for (Byte = 0; Byte < sizeof (mIdtEntryTemplate); Byte++) {\r
788 Dst[Byte] = Src[Byte];\r
789 }\r
790 }\r
791\r
792 IdtDescriptor.Base = (UINTN)&IdtTableInStack.IdtTable;\r
793 IdtDescriptor.Limit = (UINT16)(sizeof (IdtTableInStack.IdtTable) - 1);\r
794\r
795 if (SevEsIsEnabled ()) {\r
796 SevEsProtocolCheck ();\r
797\r
798 //\r
799 // For SEV-ES guests, the exception handler is needed before calling\r
800 // ProcessLibraryConstructorList() because some of the library constructors\r
801 // perform some functions that result in #VC exceptions being generated.\r
802 //\r
803 // Due to this code executing before library constructors, *all* library\r
804 // API calls are theoretically interface contract violations. However,\r
805 // because this is SEC (executing in flash), those constructors cannot\r
806 // write variables with static storage duration anyway. Furthermore, only\r
807 // a small, restricted set of APIs, such as AsmWriteIdtr() and\r
808 // InitializeCpuExceptionHandlers(), are called, where we require that the\r
809 // underlying library not require constructors to have been invoked and\r
810 // that the library instance not trigger any #VC exceptions.\r
811 //\r
812 AsmWriteIdtr (&IdtDescriptor);\r
813 InitializeCpuExceptionHandlers (NULL);\r
814 }\r
815\r
bb4aa855
JJ
816 ProcessLibraryConstructorList (NULL, NULL);\r
817\r
13e5492b
TL
818 if (!SevEsIsEnabled ()) {\r
819 //\r
820 // For non SEV-ES guests, just load the IDTR.\r
821 //\r
822 AsmWriteIdtr (&IdtDescriptor);\r
e2db781f
TL
823 } else {\r
824 //\r
825 // Under SEV-ES, the hypervisor can't modify CR0 and so can't enable\r
826 // caching in order to speed up the boot. Enable caching early for\r
827 // an SEV-ES guest.\r
828 //\r
829 AsmEnableCache ();\r
13e5492b
TL
830 }\r
831\r
2b80269d 832 #if defined (TDX_GUEST_SUPPORTED)\r
76fda1de 833 if (CcProbe () == CcGuestTypeIntelTdx) {\r
2b80269d
MX
834 //\r
835 // InitializeCpuExceptionHandlers () should be called in Td guests so that\r
836 // #VE exceptions can be handled correctly.\r
837 //\r
838 InitializeCpuExceptionHandlers (NULL);\r
839 }\r
840\r
841 #endif\r
842\r
ac0a286f
MK
843 DEBUG ((\r
844 DEBUG_INFO,\r
bb4aa855
JJ
845 "SecCoreStartupWithStack(0x%x, 0x%x)\n",\r
846 (UINT32)(UINTN)BootFv,\r
847 (UINT32)(UINTN)TopOfCurrentStack\r
848 ));\r
849\r
850 //\r
851 // Initialize floating point operating environment\r
852 // to be compliant with UEFI spec.\r
853 //\r
854 InitializeFloatingPointUnits ();\r
855\r
ac0a286f 856 #if defined (MDE_CPU_X64)\r
b382ede3
JJ
857 //\r
858 // ASSERT that the Page Tables were set by the reset vector code to\r
859 // the address we expect.\r
860 //\r
ac0a286f
MK
861 ASSERT (AsmReadCr3 () == (UINTN)PcdGet32 (PcdOvmfSecPageTablesBase));\r
862 #endif\r
b382ede3 863\r
bb4aa855
JJ
864 //\r
865 // |-------------| <-- TopOfCurrentStack\r
866 // | Stack | 32k\r
867 // |-------------|\r
868 // | Heap | 32k\r
869 // |-------------| <-- SecCoreData.TemporaryRamBase\r
870 //\r
871\r
ac0a286f
MK
872 ASSERT (\r
873 (UINTN)(PcdGet32 (PcdOvmfSecPeiTempRamBase) +\r
874 PcdGet32 (PcdOvmfSecPeiTempRamSize)) ==\r
875 (UINTN)TopOfCurrentStack\r
876 );\r
7cb6b0e0 877\r
bb4aa855
JJ
878 //\r
879 // Initialize SEC hand-off state\r
880 //\r
ac0a286f 881 SecCoreData.DataSize = sizeof (EFI_SEC_PEI_HAND_OFF);\r
bb4aa855 882\r
ac0a286f
MK
883 SecCoreData.TemporaryRamSize = (UINTN)PcdGet32 (PcdOvmfSecPeiTempRamSize);\r
884 SecCoreData.TemporaryRamBase = (VOID *)((UINT8 *)TopOfCurrentStack - SecCoreData.TemporaryRamSize);\r
bb4aa855 885\r
ac0a286f
MK
886 SecCoreData.PeiTemporaryRamBase = SecCoreData.TemporaryRamBase;\r
887 SecCoreData.PeiTemporaryRamSize = SecCoreData.TemporaryRamSize >> 1;\r
bb4aa855 888\r
ac0a286f
MK
889 SecCoreData.StackBase = (UINT8 *)SecCoreData.TemporaryRamBase + SecCoreData.PeiTemporaryRamSize;\r
890 SecCoreData.StackSize = SecCoreData.TemporaryRamSize >> 1;\r
bb4aa855
JJ
891\r
892 SecCoreData.BootFirmwareVolumeBase = BootFv;\r
ac0a286f 893 SecCoreData.BootFirmwareVolumeSize = (UINTN)BootFv->FvLength;\r
bb4aa855 894\r
202fb22b
BS
895 //\r
896 // Validate the System RAM used in the SEC Phase\r
897 //\r
898 SecValidateSystemRam ();\r
899\r
bb4aa855
JJ
900 //\r
901 // Make sure the 8259 is masked before initializing the Debug Agent and the debug timer is enabled\r
902 //\r
903 IoWrite8 (0x21, 0xff);\r
904 IoWrite8 (0xA1, 0xff);\r
f3e34b9d
MK
905\r
906 //\r
907 // Initialize Local APIC Timer hardware and disable Local APIC Timer\r
908 // interrupts before initializing the Debug Agent and the debug timer is\r
909 // enabled.\r
910 //\r
911 InitializeApicTimer (0, MAX_UINT32, TRUE, 5);\r
912 DisableApicTimerInterrupt ();\r
4040754d 913\r
bb4aa855
JJ
914 //\r
915 // Initialize Debug Agent to support source level debug in SEC/PEI phases before memory ready.\r
916 //\r
917 InitializeDebugAgent (DEBUG_AGENT_INIT_PREMEM_SEC, &SecCoreData, SecStartupPhase2);\r
918}\r
4040754d 919\r
bb4aa855
JJ
920/**\r
921 Caller provided function to be invoked at the end of InitializeDebugAgent().\r
922\r
923 Entry point to the C language phase of SEC. After the SEC assembly\r
924 code has initialized some temporary memory and set up the stack,\r
925 the control is transferred to this function.\r
926\r
927 @param[in] Context The first input parameter of InitializeDebugAgent().\r
928\r
929**/\r
930VOID\r
931EFIAPI\r
ac0a286f
MK
932SecStartupPhase2 (\r
933 IN VOID *Context\r
bb4aa855
JJ
934 )\r
935{\r
936 EFI_SEC_PEI_HAND_OFF *SecCoreData;\r
937 EFI_FIRMWARE_VOLUME_HEADER *BootFv;\r
938 EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint;\r
4040754d 939\r
ac0a286f 940 SecCoreData = (EFI_SEC_PEI_HAND_OFF *)Context;\r
4040754d 941\r
bb4aa855
JJ
942 //\r
943 // Find PEI Core entry point. It will report SEC and Pei Core debug information if remote debug\r
944 // is enabled.\r
945 //\r
946 BootFv = (EFI_FIRMWARE_VOLUME_HEADER *)SecCoreData->BootFirmwareVolumeBase;\r
947 FindAndReportEntryPoints (&BootFv, &PeiCoreEntryPoint);\r
948 SecCoreData->BootFirmwareVolumeBase = BootFv;\r
ac0a286f 949 SecCoreData->BootFirmwareVolumeSize = (UINTN)BootFv->FvLength;\r
bb4aa855
JJ
950\r
951 //\r
952 // Transfer the control to the PEI core\r
953 //\r
ac0a286f 954 (*PeiCoreEntryPoint)(SecCoreData, (EFI_PEI_PPI_DESCRIPTOR *)&mPrivateDispatchTable);\r
4040754d 955\r
bb4aa855
JJ
956 //\r
957 // If we get here then the PEI Core returned, which is not recoverable.\r
958 //\r
959 ASSERT (FALSE);\r
960 CpuDeadLoop ();\r
961}\r
962\r
963EFI_STATUS\r
964EFIAPI\r
965TemporaryRamMigration (\r
ac0a286f
MK
966 IN CONST EFI_PEI_SERVICES **PeiServices,\r
967 IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,\r
968 IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,\r
969 IN UINTN CopySize\r
bb4aa855
JJ
970 )\r
971{\r
972 IA32_DESCRIPTOR IdtDescriptor;\r
973 VOID *OldHeap;\r
974 VOID *NewHeap;\r
975 VOID *OldStack;\r
976 VOID *NewStack;\r
977 DEBUG_AGENT_CONTEXT_POSTMEM_SEC DebugAgentContext;\r
978 BOOLEAN OldStatus;\r
979 BASE_LIBRARY_JUMP_BUFFER JumpBuffer;\r
4040754d 980\r
ac0a286f
MK
981 DEBUG ((\r
982 DEBUG_INFO,\r
6394c35a
LE
983 "TemporaryRamMigration(0x%Lx, 0x%Lx, 0x%Lx)\n",\r
984 TemporaryMemoryBase,\r
985 PermanentMemoryBase,\r
986 (UINT64)CopySize\r
c67178b7 987 ));\r
4040754d 988\r
ac0a286f
MK
989 OldHeap = (VOID *)(UINTN)TemporaryMemoryBase;\r
990 NewHeap = (VOID *)((UINTN)PermanentMemoryBase + (CopySize >> 1));\r
4040754d 991\r
ac0a286f
MK
992 OldStack = (VOID *)((UINTN)TemporaryMemoryBase + (CopySize >> 1));\r
993 NewStack = (VOID *)(UINTN)PermanentMemoryBase;\r
bb4aa855 994\r
ac0a286f 995 DebugAgentContext.HeapMigrateOffset = (UINTN)NewHeap - (UINTN)OldHeap;\r
bb4aa855 996 DebugAgentContext.StackMigrateOffset = (UINTN)NewStack - (UINTN)OldStack;\r
4040754d 997\r
bb4aa855 998 OldStatus = SaveAndSetDebugTimerInterrupt (FALSE);\r
ac0a286f 999 InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, (VOID *)&DebugAgentContext, NULL);\r
bb4aa855
JJ
1000\r
1001 //\r
1002 // Migrate Heap\r
1003 //\r
1004 CopyMem (NewHeap, OldHeap, CopySize >> 1);\r
1005\r
1006 //\r
1007 // Migrate Stack\r
1008 //\r
1009 CopyMem (NewStack, OldStack, CopySize >> 1);\r
4040754d 1010\r
bb4aa855
JJ
1011 //\r
1012 // Rebase IDT table in permanent memory\r
1013 //\r
1014 AsmReadIdtr (&IdtDescriptor);\r
1015 IdtDescriptor.Base = IdtDescriptor.Base - (UINTN)OldStack + (UINTN)NewStack;\r
1016\r
1017 AsmWriteIdtr (&IdtDescriptor);\r
1018\r
1019 //\r
1020 // Use SetJump()/LongJump() to switch to a new stack.\r
4040754d 1021 //\r
bb4aa855 1022 if (SetJump (&JumpBuffer) == 0) {\r
ac0a286f 1023 #if defined (MDE_CPU_IA32)\r
bb4aa855 1024 JumpBuffer.Esp = JumpBuffer.Esp + DebugAgentContext.StackMigrateOffset;\r
89796c69 1025 JumpBuffer.Ebp = JumpBuffer.Ebp + DebugAgentContext.StackMigrateOffset;\r
ac0a286f
MK
1026 #endif\r
1027 #if defined (MDE_CPU_X64)\r
bb4aa855 1028 JumpBuffer.Rsp = JumpBuffer.Rsp + DebugAgentContext.StackMigrateOffset;\r
89796c69 1029 JumpBuffer.Rbp = JumpBuffer.Rbp + DebugAgentContext.StackMigrateOffset;\r
ac0a286f 1030 #endif\r
bb4aa855
JJ
1031 LongJump (&JumpBuffer, (UINTN)-1);\r
1032 }\r
1033\r
1034 SaveAndSetDebugTimerInterrupt (OldStatus);\r
1035\r
1036 return EFI_SUCCESS;\r
1037}\r