mirror of
https://github.com/acidanthera/audk.git
synced 2025-04-07 19:45:07 +02:00
1. Updated S3Resume2Pei to save IA32 IDT table setup in protected mode.
2. Updated BootScriptSaveOnS3SaveStateThunk restore IA32 IDT table before transferring to protected mode. It could support exception handler in 32-bit Framework Boot Script code. Signed-off-by: vanjeff Reviewed-by: jyao1 git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13099 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
8f07f895fb
commit
e47459e635
EdkCompatibilityPkg/Compatibility/BootScriptSaveOnS3SaveStateThunk/X64
UefiCpuPkg/Universal/Acpi/S3Resume2Pei
@ -3,7 +3,7 @@
|
||||
Provide a thunk function to transition from long mode to compatibility mode to execute 32-bit code and then transit
|
||||
back to long mode.
|
||||
|
||||
Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
@ -34,8 +34,24 @@ typedef union {
|
||||
} Bits;
|
||||
UINT64 Uint64;
|
||||
} IA32_GDT;
|
||||
|
||||
///
|
||||
/// Byte packed structure for an IA-32 Interrupt Gate Descriptor.
|
||||
///
|
||||
typedef union {
|
||||
struct {
|
||||
UINT32 OffsetLow:16; ///< Offset bits 15..0.
|
||||
UINT32 Selector:16; ///< Selector.
|
||||
UINT32 Reserved_0:8; ///< Reserved.
|
||||
UINT32 GateType:8; ///< Gate Type. See #defines above.
|
||||
UINT32 OffsetHigh:16; ///< Offset bits 31..16.
|
||||
} Bits;
|
||||
UINT64 Uint64;
|
||||
} IA32_IDT_ENTRY;
|
||||
#pragma pack()
|
||||
|
||||
#define COMPATIBILITY_MODE_SELECTOR 8
|
||||
|
||||
//
|
||||
// Global Descriptor Table (GDT)
|
||||
//
|
||||
@ -92,7 +108,36 @@ Execute32BitCode (
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
IA32_DESCRIPTOR *Ia32Idtr;
|
||||
IA32_DESCRIPTOR X64Idtr;
|
||||
UINTN Ia32IdtEntryCount;
|
||||
UINTN Index;
|
||||
IA32_IDT_ENTRY *Ia32IdtEntry;
|
||||
|
||||
//
|
||||
// Save x64 IDT Descriptor
|
||||
//
|
||||
AsmReadIdtr ((IA32_DESCRIPTOR *) &X64Idtr);
|
||||
|
||||
//
|
||||
// Get the IA32 IDT Descriptor saved in 16 bytes in front of X64 IDT table.
|
||||
//
|
||||
Ia32Idtr = (IA32_DESCRIPTOR *) (UINTN) (X64Idtr.Base - 16);
|
||||
Ia32IdtEntryCount = (Ia32Idtr->Limit + 1) / sizeof (IA32_IDT_ENTRY);
|
||||
|
||||
Ia32IdtEntry = (IA32_IDT_ENTRY *)(Ia32Idtr->Base);
|
||||
for (Index = 0; Index < Ia32IdtEntryCount; Index ++ ) {
|
||||
//
|
||||
// Use the new Code Selector value
|
||||
//
|
||||
Ia32IdtEntry[Index].Bits.Selector = COMPATIBILITY_MODE_SELECTOR;
|
||||
}
|
||||
|
||||
//
|
||||
// Setup IA32 IDT table for 32-bit framework Boot Script code
|
||||
//
|
||||
AsmWriteIdtr (Ia32Idtr);
|
||||
|
||||
ASSERT (Function != 0);
|
||||
|
||||
Status = AsmExecute32BitCode (
|
||||
@ -101,6 +146,12 @@ Execute32BitCode (
|
||||
Param2,
|
||||
&mGdt
|
||||
);
|
||||
|
||||
//
|
||||
// Restore X64 IDT table
|
||||
//
|
||||
AsmWriteIdtr ((IA32_DESCRIPTOR *) &X64Idtr);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
This module will excute the boot script saved during last boot and after that,
|
||||
control is passed to OS waking up handler.
|
||||
|
||||
Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
|
||||
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions
|
||||
@ -712,6 +712,12 @@ S3ResumeExecuteBootScript (
|
||||
//
|
||||
IdtBuffer = AllocatePages (EFI_SIZE_TO_PAGES((IdtDescriptor->Limit + 1) + 16));
|
||||
ASSERT (IdtBuffer != NULL);
|
||||
//
|
||||
// Additional 16 bytes allocated to save IA32 IDT descriptor and Pei Service Table Pointer
|
||||
// IA32 IDT descriptor will be used to setup IA32 IDT table for 32-bit Framework Boot Script code
|
||||
//
|
||||
ZeroMem (IdtBuffer, 16);
|
||||
AsmReadIdtr ((IA32_DESCRIPTOR *)IdtBuffer);
|
||||
CopyMem ((VOID*)((UINT8*)IdtBuffer + 16),(VOID*)(IdtDescriptor->Base), (IdtDescriptor->Limit + 1));
|
||||
IdtDescriptor->Base = (UINTN)((UINT8*)IdtBuffer + 16);
|
||||
*(UINTN*)(IdtDescriptor->Base - sizeof(UINTN)) = (UINTN)GetPeiServicesTablePointer ();
|
||||
|
Loading…
x
Reference in New Issue
Block a user