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