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:
vanjeff 2012-03-15 05:33:43 +00:00
parent 8f07f895fb
commit e47459e635
2 changed files with 60 additions and 3 deletions

View File

@ -3,7 +3,7 @@
Provide a thunk function to transition from long mode to compatibility mode to execute 32-bit code and then transit Provide a thunk function to transition from long mode to compatibility mode to execute 32-bit code and then transit
back to long mode. 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 This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License 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 which accompanies this distribution. The full text of the license may be found at
@ -34,8 +34,24 @@ typedef union {
} Bits; } Bits;
UINT64 Uint64; UINT64 Uint64;
} IA32_GDT; } 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() #pragma pack()
#define COMPATIBILITY_MODE_SELECTOR 8
// //
// Global Descriptor Table (GDT) // Global Descriptor Table (GDT)
// //
@ -92,7 +108,36 @@ Execute32BitCode (
) )
{ {
EFI_STATUS Status; 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); ASSERT (Function != 0);
Status = AsmExecute32BitCode ( Status = AsmExecute32BitCode (
@ -101,6 +146,12 @@ Execute32BitCode (
Param2, Param2,
&mGdt &mGdt
); );
//
// Restore X64 IDT table
//
AsmWriteIdtr ((IA32_DESCRIPTOR *) &X64Idtr);
return Status; return Status;
} }

View File

@ -4,7 +4,7 @@
This module will excute the boot script saved during last boot and after that, This module will excute the boot script saved during last boot and after that,
control is passed to OS waking up handler. 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 This program and the accompanying materials
are licensed and made available under the terms and conditions 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)); IdtBuffer = AllocatePages (EFI_SIZE_TO_PAGES((IdtDescriptor->Limit + 1) + 16));
ASSERT (IdtBuffer != NULL); 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)); CopyMem ((VOID*)((UINT8*)IdtBuffer + 16),(VOID*)(IdtDescriptor->Base), (IdtDescriptor->Limit + 1));
IdtDescriptor->Base = (UINTN)((UINT8*)IdtBuffer + 16); IdtDescriptor->Base = (UINTN)((UINT8*)IdtBuffer + 16);
*(UINTN*)(IdtDescriptor->Base - sizeof(UINTN)) = (UINTN)GetPeiServicesTablePointer (); *(UINTN*)(IdtDescriptor->Base - sizeof(UINTN)) = (UINTN)GetPeiServicesTablePointer ();