2 Main SEC phase code. Transitions to PEI.
4 Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 #include <Library/PeimEntryPoint.h>
19 #include <Library/BaseLib.h>
20 #include <Library/DebugLib.h>
21 #include <Library/BaseMemoryLib.h>
22 #include <Library/PeiServicesLib.h>
23 #include <Library/PcdLib.h>
24 #include <Library/UefiCpuLib.h>
25 #include <Library/DebugAgentLib.h>
26 #include <Library/IoLib.h>
27 #include <Library/PeCoffLib.h>
28 #include <Library/PeCoffGetEntryPointLib.h>
29 #include <Library/PeCoffExtraActionLib.h>
30 #include <Library/ExtractGuidedSectionLib.h>
32 #include <Ppi/TemporaryRamSupport.h>
34 #define SEC_IDT_ENTRY_COUNT 34
36 typedef struct _SEC_IDT_TABLE
{
37 EFI_PEI_SERVICES
*PeiService
;
38 IA32_IDT_GATE_DESCRIPTOR IdtTable
[SEC_IDT_ENTRY_COUNT
];
49 TemporaryRamMigration (
50 IN CONST EFI_PEI_SERVICES
**PeiServices
,
51 IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase
,
52 IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase
,
59 EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI mTemporaryRamSupportPpi
= {
63 EFI_PEI_PPI_DESCRIPTOR mPrivateDispatchTable
[] = {
65 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
66 &gEfiTemporaryRamSupportPpiGuid
,
67 &mTemporaryRamSupportPpi
72 // Template of an IDT entry pointing to 10:FFFFFFE4h.
74 IA32_IDT_GATE_DESCRIPTOR mIdtEntryTemplate
= {
79 IA32_IDT_GATE_TYPE_INTERRUPT_32
, // GateType
85 Locates the main boot firmware volume.
87 @param[in,out] BootFv On input, the base of the BootFv
88 On output, the decompressed main firmware volume
90 @retval EFI_SUCCESS The main firmware volume was located and decompressed
91 @retval EFI_NOT_FOUND The main firmware volume was not found
96 IN OUT EFI_FIRMWARE_VOLUME_HEADER
**BootFv
99 EFI_FIRMWARE_VOLUME_HEADER
*Fv
;
103 ASSERT (((UINTN
) *BootFv
& EFI_PAGE_MASK
) == 0);
107 Distance
= (UINTN
) (*BootFv
)->FvLength
;
109 Fv
= (EFI_FIRMWARE_VOLUME_HEADER
*) ((UINT8
*) Fv
- EFI_PAGE_SIZE
);
110 Distance
+= EFI_PAGE_SIZE
;
111 if (Distance
> SIZE_32MB
) {
112 return EFI_NOT_FOUND
;
115 if (Fv
->Signature
!= EFI_FVH_SIGNATURE
) {
119 if ((UINTN
) Fv
->FvLength
> Distance
) {
130 Locates a section within a series of sections
131 with the specified section type.
133 @param[in] Sections The sections to search
134 @param[in] SizeOfSections Total size of all sections
135 @param[in] SectionType The section type to locate
136 @param[out] FoundSection The FFS section if found
138 @retval EFI_SUCCESS The file and section was found
139 @retval EFI_NOT_FOUND The file and section was not found
140 @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
144 FindFfsSectionInSections (
146 IN UINTN SizeOfSections
,
147 IN EFI_SECTION_TYPE SectionType
,
148 OUT EFI_COMMON_SECTION_HEADER
**FoundSection
151 EFI_PHYSICAL_ADDRESS CurrentAddress
;
153 EFI_PHYSICAL_ADDRESS EndOfSections
;
154 EFI_COMMON_SECTION_HEADER
*Section
;
155 EFI_PHYSICAL_ADDRESS EndOfSection
;
158 // Loop through the FFS file sections within the PEI Core FFS file
160 EndOfSection
= (EFI_PHYSICAL_ADDRESS
)(UINTN
) Sections
;
161 EndOfSections
= EndOfSection
+ SizeOfSections
;
163 if (EndOfSection
== EndOfSections
) {
166 CurrentAddress
= (EndOfSection
+ 3) & ~(3ULL);
167 if (CurrentAddress
>= EndOfSections
) {
168 return EFI_VOLUME_CORRUPTED
;
171 Section
= (EFI_COMMON_SECTION_HEADER
*)(UINTN
) CurrentAddress
;
172 DEBUG ((EFI_D_INFO
, "Section->Type: 0x%x\n", Section
->Type
));
174 Size
= SECTION_SIZE (Section
);
175 if (Size
< sizeof (*Section
)) {
176 return EFI_VOLUME_CORRUPTED
;
179 EndOfSection
= CurrentAddress
+ Size
;
180 if (EndOfSection
> EndOfSections
) {
181 return EFI_VOLUME_CORRUPTED
;
185 // Look for the requested section type
187 if (Section
->Type
== SectionType
) {
188 *FoundSection
= Section
;
191 DEBUG ((EFI_D_INFO
, "Section->Type (0x%x) != SectionType (0x%x)\n", Section
->Type
, SectionType
));
194 return EFI_NOT_FOUND
;
198 Locates a FFS file with the specified file type and a section
199 within that file with the specified section type.
201 @param[in] Fv The firmware volume to search
202 @param[in] FileType The file type to locate
203 @param[in] SectionType The section type to locate
204 @param[out] FoundSection The FFS section if found
206 @retval EFI_SUCCESS The file and section was found
207 @retval EFI_NOT_FOUND The file and section was not found
208 @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
213 FindFfsFileAndSection (
214 IN EFI_FIRMWARE_VOLUME_HEADER
*Fv
,
215 IN EFI_FV_FILETYPE FileType
,
216 IN EFI_SECTION_TYPE SectionType
,
217 OUT EFI_COMMON_SECTION_HEADER
**FoundSection
221 EFI_PHYSICAL_ADDRESS CurrentAddress
;
222 EFI_PHYSICAL_ADDRESS EndOfFirmwareVolume
;
223 EFI_FFS_FILE_HEADER
*File
;
225 EFI_PHYSICAL_ADDRESS EndOfFile
;
227 if (Fv
->Signature
!= EFI_FVH_SIGNATURE
) {
228 DEBUG ((EFI_D_INFO
, "FV at %p does not have FV header signature\n", Fv
));
229 return EFI_VOLUME_CORRUPTED
;
232 CurrentAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
) Fv
;
233 EndOfFirmwareVolume
= CurrentAddress
+ Fv
->FvLength
;
236 // Loop through the FFS files in the Boot Firmware Volume
238 for (EndOfFile
= CurrentAddress
+ Fv
->HeaderLength
; ; ) {
240 CurrentAddress
= (EndOfFile
+ 7) & ~(7ULL);
241 if (CurrentAddress
> EndOfFirmwareVolume
) {
242 return EFI_VOLUME_CORRUPTED
;
245 File
= (EFI_FFS_FILE_HEADER
*)(UINTN
) CurrentAddress
;
246 Size
= *(UINT32
*) File
->Size
& 0xffffff;
247 if (Size
< (sizeof (*File
) + sizeof (EFI_COMMON_SECTION_HEADER
))) {
248 return EFI_VOLUME_CORRUPTED
;
250 DEBUG ((EFI_D_INFO
, "File->Type: 0x%x\n", File
->Type
));
252 EndOfFile
= CurrentAddress
+ Size
;
253 if (EndOfFile
> EndOfFirmwareVolume
) {
254 return EFI_VOLUME_CORRUPTED
;
258 // Look for the request file type
260 if (File
->Type
!= FileType
) {
261 DEBUG ((EFI_D_INFO
, "File->Type (0x%x) != FileType (0x%x)\n", File
->Type
, FileType
));
265 Status
= FindFfsSectionInSections (
267 (UINTN
) EndOfFile
- (UINTN
) (File
+ 1),
271 if (!EFI_ERROR (Status
) || (Status
== EFI_VOLUME_CORRUPTED
)) {
278 Locates the compressed main firmware volume and decompresses it.
280 @param[in,out] Fv On input, the firmware volume to search
281 On output, the decompressed main FV
283 @retval EFI_SUCCESS The file and section was found
284 @retval EFI_NOT_FOUND The file and section was not found
285 @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
291 IN OUT EFI_FIRMWARE_VOLUME_HEADER
**Fv
295 EFI_GUID_DEFINED_SECTION
*Section
;
296 UINT32 OutputBufferSize
;
297 UINT32 ScratchBufferSize
;
298 UINT16 SectionAttribute
;
299 UINT32 AuthenticationStatus
;
302 EFI_FIRMWARE_VOLUME_IMAGE_SECTION
*NewFvSection
;
303 EFI_FIRMWARE_VOLUME_HEADER
*NewFv
;
305 NewFvSection
= (EFI_FIRMWARE_VOLUME_IMAGE_SECTION
*) NULL
;
307 Status
= FindFfsFileAndSection (
309 EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
,
310 EFI_SECTION_GUID_DEFINED
,
311 (EFI_COMMON_SECTION_HEADER
**) &Section
313 if (EFI_ERROR (Status
)) {
314 DEBUG ((EFI_D_ERROR
, "Unable to find GUID defined section\n"));
318 Status
= ExtractGuidedSectionGetInfo (
324 if (EFI_ERROR (Status
)) {
325 DEBUG ((EFI_D_ERROR
, "Unable to GetInfo for GUIDed section\n"));
329 //PcdGet32 (PcdOvmfMemFvBase), PcdGet32 (PcdOvmfMemFvSize)
330 OutputBuffer
= (VOID
*) ((UINT8
*)(UINTN
) PcdGet32 (PcdOvmfMemFvBase
) + SIZE_1MB
);
331 ScratchBuffer
= ALIGN_POINTER ((UINT8
*) OutputBuffer
+ OutputBufferSize
, SIZE_1MB
);
332 Status
= ExtractGuidedSectionDecode (
336 &AuthenticationStatus
338 if (EFI_ERROR (Status
)) {
339 DEBUG ((EFI_D_ERROR
, "Error during GUID section decode\n"));
343 Status
= FindFfsSectionInSections (
346 EFI_SECTION_FIRMWARE_VOLUME_IMAGE
,
347 (EFI_COMMON_SECTION_HEADER
**) &NewFvSection
349 if (EFI_ERROR (Status
)) {
350 DEBUG ((EFI_D_ERROR
, "Unable to find FV image in extracted data\n"));
354 NewFv
= (EFI_FIRMWARE_VOLUME_HEADER
*)(UINTN
) PcdGet32 (PcdOvmfMemFvBase
);
355 CopyMem (NewFv
, (VOID
*) (NewFvSection
+ 1), PcdGet32 (PcdOvmfMemFvSize
));
357 if (NewFv
->Signature
!= EFI_FVH_SIGNATURE
) {
358 DEBUG ((EFI_D_ERROR
, "Extracted FV at %p does not have FV header signature\n", NewFv
));
360 return EFI_VOLUME_CORRUPTED
;
368 Locates the PEI Core entry point address
370 @param[in] Fv The firmware volume to search
371 @param[out] PeiCoreEntryPoint The entry point of the PEI Core image
373 @retval EFI_SUCCESS The file and section was found
374 @retval EFI_NOT_FOUND The file and section was not found
375 @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
380 FindPeiCoreImageBaseInFv (
381 IN EFI_FIRMWARE_VOLUME_HEADER
*Fv
,
382 OUT EFI_PHYSICAL_ADDRESS
*PeiCoreImageBase
386 EFI_COMMON_SECTION_HEADER
*Section
;
388 Status
= FindFfsFileAndSection (
390 EFI_FV_FILETYPE_PEI_CORE
,
394 if (EFI_ERROR (Status
)) {
395 Status
= FindFfsFileAndSection (
397 EFI_FV_FILETYPE_PEI_CORE
,
401 if (EFI_ERROR (Status
)) {
402 DEBUG ((EFI_D_ERROR
, "Unable to find PEI Core image\n"));
407 *PeiCoreImageBase
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)(Section
+ 1);
412 Locates the PEI Core entry point address
414 @param[in,out] Fv The firmware volume to search
415 @param[out] PeiCoreEntryPoint The entry point of the PEI Core image
417 @retval EFI_SUCCESS The file and section was found
418 @retval EFI_NOT_FOUND The file and section was not found
419 @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
424 FindPeiCoreImageBase (
425 IN OUT EFI_FIRMWARE_VOLUME_HEADER
**BootFv
,
426 OUT EFI_PHYSICAL_ADDRESS
*PeiCoreImageBase
429 *PeiCoreImageBase
= 0;
433 DecompressGuidedFv (BootFv
);
435 FindPeiCoreImageBaseInFv (*BootFv
, PeiCoreImageBase
);
439 Find core image base.
445 IN EFI_FIRMWARE_VOLUME_HEADER
*BootFirmwareVolumePtr
,
446 OUT EFI_PHYSICAL_ADDRESS
*SecCoreImageBase
449 EFI_PHYSICAL_ADDRESS CurrentAddress
;
450 EFI_PHYSICAL_ADDRESS EndOfFirmwareVolume
;
451 EFI_FFS_FILE_HEADER
*File
;
453 EFI_PHYSICAL_ADDRESS EndOfFile
;
454 EFI_COMMON_SECTION_HEADER
*Section
;
455 EFI_PHYSICAL_ADDRESS EndOfSection
;
457 *SecCoreImageBase
= 0;
459 CurrentAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
) BootFirmwareVolumePtr
;
460 EndOfFirmwareVolume
= CurrentAddress
+ BootFirmwareVolumePtr
->FvLength
;
463 // Loop through the FFS files in the Boot Firmware Volume
465 for (EndOfFile
= CurrentAddress
+ BootFirmwareVolumePtr
->HeaderLength
; ; ) {
467 CurrentAddress
= (EndOfFile
+ 7) & 0xfffffffffffffff8ULL
;
468 if (CurrentAddress
> EndOfFirmwareVolume
) {
469 return EFI_NOT_FOUND
;
472 File
= (EFI_FFS_FILE_HEADER
*)(UINTN
) CurrentAddress
;
473 Size
= *(UINT32
*) File
->Size
& 0xffffff;
474 if (Size
< sizeof (*File
)) {
475 return EFI_NOT_FOUND
;
478 EndOfFile
= CurrentAddress
+ Size
;
479 if (EndOfFile
> EndOfFirmwareVolume
) {
480 return EFI_NOT_FOUND
;
486 if (File
->Type
!= EFI_FV_FILETYPE_SECURITY_CORE
) {
491 // Loop through the FFS file sections within the FFS file
493 EndOfSection
= (EFI_PHYSICAL_ADDRESS
)(UINTN
) (File
+ 1);
495 CurrentAddress
= (EndOfSection
+ 3) & 0xfffffffffffffffcULL
;
496 Section
= (EFI_COMMON_SECTION_HEADER
*)(UINTN
) CurrentAddress
;
498 Size
= *(UINT32
*) Section
->Size
& 0xffffff;
499 if (Size
< sizeof (*Section
)) {
500 return EFI_NOT_FOUND
;
503 EndOfSection
= CurrentAddress
+ Size
;
504 if (EndOfSection
> EndOfFile
) {
505 return EFI_NOT_FOUND
;
509 // Look for executable sections
511 if (Section
->Type
== EFI_SECTION_PE32
|| Section
->Type
== EFI_SECTION_TE
) {
512 if (File
->Type
== EFI_FV_FILETYPE_SECURITY_CORE
) {
513 *SecCoreImageBase
= (PHYSICAL_ADDRESS
) (UINTN
) (Section
+ 1);
520 // SEC Core image found
522 if (*SecCoreImageBase
!= 0) {
529 Find and return Pei Core entry point.
531 It also find SEC and PEI Core file debug inforamtion. It will report them if
532 remote debug is enabled.
537 FindAndReportEntryPoints (
538 IN EFI_FIRMWARE_VOLUME_HEADER
**BootFirmwareVolumePtr
,
539 OUT EFI_PEI_CORE_ENTRY_POINT
*PeiCoreEntryPoint
543 EFI_PHYSICAL_ADDRESS SecCoreImageBase
;
544 EFI_PHYSICAL_ADDRESS PeiCoreImageBase
;
545 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext
;
548 // Find SEC Core and PEI Core image base
550 Status
= FindImageBase (*BootFirmwareVolumePtr
, &SecCoreImageBase
);
551 ASSERT_EFI_ERROR (Status
);
553 FindPeiCoreImageBase (BootFirmwareVolumePtr
, &PeiCoreImageBase
);
555 ZeroMem ((VOID
*) &ImageContext
, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT
));
557 // Report SEC Core debug information when remote debug is enabled
559 ImageContext
.ImageAddress
= SecCoreImageBase
;
560 ImageContext
.PdbPointer
= PeCoffLoaderGetPdbPointer ((VOID
*) (UINTN
) ImageContext
.ImageAddress
);
561 PeCoffLoaderRelocateImageExtraAction (&ImageContext
);
564 // Report PEI Core debug information when remote debug is enabled
566 ImageContext
.ImageAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)PeiCoreImageBase
;
567 ImageContext
.PdbPointer
= PeCoffLoaderGetPdbPointer ((VOID
*) (UINTN
) ImageContext
.ImageAddress
);
568 PeCoffLoaderRelocateImageExtraAction (&ImageContext
);
571 // Find PEI Core entry point
573 Status
= PeCoffLoaderGetEntryPoint ((VOID
*) (UINTN
) PeiCoreImageBase
, (VOID
**) PeiCoreEntryPoint
);
574 if (EFI_ERROR (Status
)) {
575 *PeiCoreEntryPoint
= 0;
583 SecCoreStartupWithStack (
584 IN EFI_FIRMWARE_VOLUME_HEADER
*BootFv
,
585 IN VOID
*TopOfCurrentStack
588 EFI_SEC_PEI_HAND_OFF SecCoreData
;
589 SEC_IDT_TABLE IdtTableInStack
;
590 IA32_DESCRIPTOR IdtDescriptor
;
593 ProcessLibraryConstructorList (NULL
, NULL
);
596 "SecCoreStartupWithStack(0x%x, 0x%x)\n",
597 (UINT32
)(UINTN
)BootFv
,
598 (UINT32
)(UINTN
)TopOfCurrentStack
602 // Initialize floating point operating environment
603 // to be compliant with UEFI spec.
605 InitializeFloatingPointUnits ();
610 IdtTableInStack
.PeiService
= NULL
;
611 for (Index
= 0; Index
< SEC_IDT_ENTRY_COUNT
; Index
++) {
612 CopyMem (&IdtTableInStack
.IdtTable
[Index
], &mIdtEntryTemplate
, sizeof (mIdtEntryTemplate
));
615 IdtDescriptor
.Base
= (UINTN
)&IdtTableInStack
.IdtTable
;
616 IdtDescriptor
.Limit
= (UINT16
)(sizeof (IdtTableInStack
.IdtTable
) - 1);
618 AsmWriteIdtr (&IdtDescriptor
);
621 // |-------------| <-- TopOfCurrentStack
625 // |-------------| <-- SecCoreData.TemporaryRamBase
629 // Initialize SEC hand-off state
631 SecCoreData
.DataSize
= sizeof(EFI_SEC_PEI_HAND_OFF
);
633 SecCoreData
.TemporaryRamSize
= SIZE_64KB
;
634 SecCoreData
.TemporaryRamBase
= (VOID
*)((UINT8
*)TopOfCurrentStack
- SecCoreData
.TemporaryRamSize
);
636 SecCoreData
.PeiTemporaryRamBase
= SecCoreData
.TemporaryRamBase
;
637 SecCoreData
.PeiTemporaryRamSize
= SecCoreData
.TemporaryRamSize
>> 1;
639 SecCoreData
.StackBase
= (UINT8
*)SecCoreData
.TemporaryRamBase
+ SecCoreData
.PeiTemporaryRamSize
;
640 SecCoreData
.StackSize
= SecCoreData
.TemporaryRamSize
>> 1;
642 SecCoreData
.BootFirmwareVolumeBase
= BootFv
;
643 SecCoreData
.BootFirmwareVolumeSize
= (UINTN
) BootFv
->FvLength
;
646 // Make sure the 8259 is masked before initializing the Debug Agent and the debug timer is enabled
648 IoWrite8 (0x21, 0xff);
649 IoWrite8 (0xA1, 0xff);
652 // Initialize Debug Agent to support source level debug in SEC/PEI phases before memory ready.
654 InitializeDebugAgent (DEBUG_AGENT_INIT_PREMEM_SEC
, &SecCoreData
, SecStartupPhase2
);
658 Caller provided function to be invoked at the end of InitializeDebugAgent().
660 Entry point to the C language phase of SEC. After the SEC assembly
661 code has initialized some temporary memory and set up the stack,
662 the control is transferred to this function.
664 @param[in] Context The first input parameter of InitializeDebugAgent().
673 EFI_SEC_PEI_HAND_OFF
*SecCoreData
;
674 EFI_FIRMWARE_VOLUME_HEADER
*BootFv
;
675 EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint
;
677 SecCoreData
= (EFI_SEC_PEI_HAND_OFF
*) Context
;
680 // Find PEI Core entry point. It will report SEC and Pei Core debug information if remote debug
683 BootFv
= (EFI_FIRMWARE_VOLUME_HEADER
*)SecCoreData
->BootFirmwareVolumeBase
;
684 FindAndReportEntryPoints (&BootFv
, &PeiCoreEntryPoint
);
685 SecCoreData
->BootFirmwareVolumeBase
= BootFv
;
686 SecCoreData
->BootFirmwareVolumeSize
= (UINTN
) BootFv
->FvLength
;
689 // Transfer the control to the PEI core
691 (*PeiCoreEntryPoint
) (SecCoreData
, (EFI_PEI_PPI_DESCRIPTOR
*)&mPrivateDispatchTable
);
694 // If we get here then the PEI Core returned, which is not recoverable.
702 TemporaryRamMigration (
703 IN CONST EFI_PEI_SERVICES
**PeiServices
,
704 IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase
,
705 IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase
,
709 IA32_DESCRIPTOR IdtDescriptor
;
714 DEBUG_AGENT_CONTEXT_POSTMEM_SEC DebugAgentContext
;
716 BASE_LIBRARY_JUMP_BUFFER JumpBuffer
;
718 DEBUG ((EFI_D_ERROR
, "TemporaryRamMigration(0x%x, 0x%x, 0x%x)\n", (UINTN
)TemporaryMemoryBase
, (UINTN
)PermanentMemoryBase
, CopySize
));
720 OldHeap
= (VOID
*)(UINTN
)TemporaryMemoryBase
;
721 NewHeap
= (VOID
*)((UINTN
)PermanentMemoryBase
+ (CopySize
>> 1));
723 OldStack
= (VOID
*)((UINTN
)TemporaryMemoryBase
+ (CopySize
>> 1));
724 NewStack
= (VOID
*)(UINTN
)PermanentMemoryBase
;
726 DebugAgentContext
.HeapMigrateOffset
= (UINTN
)NewHeap
- (UINTN
)OldHeap
;
727 DebugAgentContext
.StackMigrateOffset
= (UINTN
)NewStack
- (UINTN
)OldStack
;
729 OldStatus
= SaveAndSetDebugTimerInterrupt (FALSE
);
730 InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC
, (VOID
*) &DebugAgentContext
, NULL
);
735 CopyMem (NewHeap
, OldHeap
, CopySize
>> 1);
740 CopyMem (NewStack
, OldStack
, CopySize
>> 1);
743 // Rebase IDT table in permanent memory
745 AsmReadIdtr (&IdtDescriptor
);
746 IdtDescriptor
.Base
= IdtDescriptor
.Base
- (UINTN
)OldStack
+ (UINTN
)NewStack
;
748 AsmWriteIdtr (&IdtDescriptor
);
751 // Use SetJump()/LongJump() to switch to a new stack.
753 if (SetJump (&JumpBuffer
) == 0) {
754 #if defined (MDE_CPU_IA32)
755 JumpBuffer
.Esp
= JumpBuffer
.Esp
+ DebugAgentContext
.StackMigrateOffset
;
757 #if defined (MDE_CPU_X64)
758 JumpBuffer
.Rsp
= JumpBuffer
.Rsp
+ DebugAgentContext
.StackMigrateOffset
;
760 LongJump (&JumpBuffer
, (UINTN
)-1);
763 SaveAndSetDebugTimerInterrupt (OldStatus
);