Fix boot script thunk issue that we need dispatch in PEI mode for Framework dispatch function, not in DXE mode.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11189 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
jyao1 2010-12-22 04:26:08 +00:00
parent 23228db382
commit d766b22843
9 changed files with 862 additions and 19 deletions

View File

@ -29,31 +29,46 @@
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
# VALID_ARCHITECTURES = IA32 X64
#
[Sources]
ScriptSave.c
ScriptSave.h
[Sources.X64]
X64/AsmDispatchExecute.asm
X64/AsmDispatchExecute.S
X64/DispatchExecute.c
[Sources.Ia32]
IA32/DispatchExecute.c
[Packages]
MdePkg/MdePkg.dec
IntelFrameworkPkg/IntelFrameworkPkg.dec
MdeModulePkg/MdeModulePkg.dec
EdkCompatibilityPkg/EdkCompatibilityPkg.dec
[LibraryClasses]
UefiBootServicesTableLib
UefiRuntimeServicesTableLib
UefiDriverEntryPoint
BaseMemoryLib
MemoryAllocationLib
DebugLib
BaseLib
PeCoffLib
PcdLib
DxeServicesLib
CacheMaintenanceLib
[Protocols]
gEfiBootScriptSaveProtocolGuid ## PRODUCES
gEfiS3SaveStateProtocolGuid ## CONSUMES
[Pcd]
gEfiEdkCompatibilityPkgTokenSpaceGuid.BootScriptThunkDataPtr
[Depex]
gEfiS3SaveStateProtocolGuid

View File

@ -0,0 +1,43 @@
/** @file
Execute 32-bit code in Long Mode
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>
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
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "ScriptSave.h"
/**
Wrapper for a thunk to transition from long mode to compatibility mode to execute 32-bit code and then transit back to
long mode.
@param Function The 32bit code entry to be executed.
@param Param1 The first parameter to pass to 32bit code
@param Param2 The second parameter to pass to 32bit code
@retval EFI_SUCCESS Execute 32bit code successfully.
@retval other Something wrong when execute the 32bit code
**/
EFI_STATUS
Execute32BitCode (
IN UINT64 Function,
IN UINT64 Param1,
IN UINT64 Param2
)
{
DISPATCH_ENTRYPOINT_FUNC EntryFunc;
EFI_STATUS Status;
EntryFunc = (DISPATCH_ENTRYPOINT_FUNC) (UINTN) (Function);
Status = EntryFunc ((VOID *)(UINTN)Param1, (VOID *)(UINTN)Param2);
return Status;
}

View File

@ -20,6 +20,60 @@ EFI_BOOT_SCRIPT_SAVE_PROTOCOL mS3ScriptSave = {
BootScriptCloseTable
};
EFI_S3_SAVE_STATE_PROTOCOL *mS3SaveState;
/**
Wrapper for a thunk to transition from long mode to compatibility mode to execute 32-bit code and then transit back to
long mode.
@param Function The 32bit code entry to be executed.
@param Param1 The first parameter to pass to 32bit code
@param Param2 The second parameter to pass to 32bit code
@retval EFI_SUCCESS Execute 32bit code successfully.
@retval other Something wrong when execute the 32bit code
**/
EFI_STATUS
Execute32BitCode (
IN UINT64 Function,
IN UINT64 Param1,
IN UINT64 Param2
);
/**
A stub to convert framework boot script dispatch to PI boot script dispatch.
@param ImageHandle It should be is NULL.
@param Context The first parameter to pass to 32bit code
@return dispatch value.
**/
EFI_STATUS
EFIAPI
FrameworkBootScriptDispatchStub (
IN EFI_HANDLE ImageHandle,
IN VOID *Context
)
{
EFI_STATUS Status;
DISPATCH_ENTRYPOINT_FUNC EntryFunc;
VOID *PeiServices;
IA32_DESCRIPTOR Idtr;
DEBUG ((EFI_D_ERROR, "FrameworkBootScriptDispatchStub - 0x%08x\n", (UINTN)Context));
EntryFunc = (DISPATCH_ENTRYPOINT_FUNC) (UINTN) (Context);
AsmReadIdtr (&Idtr);
PeiServices = (VOID *)(UINTN)(*(UINT32 *)(Idtr.Base - sizeof (UINT32)));
//
// ECP assumes first parameter is NULL, and second parameter is PeiServices.
//
Status = Execute32BitCode ((UINT64)(UINTN)EntryFunc, 0, (UINT64)(UINTN)PeiServices);
return Status;
}
/**
Internal function to add IO write opcode to the table.
@ -395,6 +449,42 @@ BootScriptDispatch (
);
}
/**
Internal function to add Save jmp address according to DISPATCH_OPCODE.
We ignore "Context" parameter.
We need create thunk stub to convert PEI entrypoint (used in Framework version)
to DXE entrypoint (defined in PI spec).
@param Marker The variable argument list to get the opcode
and associated attributes.
@retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.
@retval EFI_SUCCESS Opcode is added.
**/
EFI_STATUS
FrameworkBootScriptDispatch (
IN VA_LIST Marker
)
{
VOID *EntryPoint;
VOID *Context;
EntryPoint = (VOID*)(UINTN)VA_ARG (Marker, EFI_PHYSICAL_ADDRESS);
//
// Register callback
//
Context = EntryPoint;
EntryPoint = (VOID *)(UINTN)FrameworkBootScriptDispatchStub;
return mS3SaveState->Write (
mS3SaveState,
EFI_BOOT_SCRIPT_DISPATCH_2_OPCODE,
EntryPoint,
Context
);
}
/**
Internal function to add memory pool operation to the table.
@ -539,9 +629,9 @@ BootScriptWrite (
VA_LIST Marker;
if (TableName != FRAMEWORK_EFI_ACPI_S3_RESUME_SCRIPT_TABLE) {
//
// Only S3 boot script is supported for now
//
//
// Only S3 boot script is supported for now
//
return EFI_OUT_OF_RESOURCES;
}
//
@ -600,7 +690,7 @@ BootScriptWrite (
case EFI_BOOT_SCRIPT_DISPATCH_OPCODE:
VA_START (Marker, OpCode);
Status = BootScriptDispatch (Marker);
Status = FrameworkBootScriptDispatch (Marker);
VA_END (Marker);
break;
@ -705,24 +795,133 @@ InitializeScriptSaveOnS3SaveState (
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
//
// Locate and cache PI S3 Save State Protocol.
//
Status = gBS->LocateProtocol (
&gEfiS3SaveStateProtocolGuid,
NULL,
(VOID **) &mS3SaveState
);
ASSERT_EFI_ERROR (Status);
UINT8 *Buffer;
UINTN BufferSize;
VOID *FfsBuffer;
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
BOOT_SCRIPT_THUNK_DATA *BootScriptThunkData;
EFI_STATUS Status;
VOID *DevicePath;
return gBS->InstallProtocolInterface (
//
// Test if the gEfiCallerIdGuid of this image is already installed. if not, the entry
// point is loaded by DXE code which is the first time loaded. or else, it is already
// be reloaded be itself.This is a work-around
//
Status = gBS->LocateProtocol (&gEfiCallerIdGuid, NULL, &DevicePath);
if (EFI_ERROR (Status)) {
//
// This is the first-time loaded by DXE core. reload itself to NVS mem
//
//
// A workarouond: Here we install a dummy handle
//
Status = gBS->InstallProtocolInterface (
&ImageHandle,
&gEfiCallerIdGuid,
EFI_NATIVE_INTERFACE,
DevicePath
);
Status = GetSectionFromAnyFv (
&gEfiCallerIdGuid,
EFI_SECTION_PE32,
0,
(VOID **) &Buffer,
&BufferSize
);
ImageContext.Handle = Buffer;
ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;
//
// Get information about the image being loaded
//
Status = PeCoffLoaderGetImageInfo (&ImageContext);
if (EFI_ERROR (Status)) {
return Status;
}
Status = gBS->AllocatePool (
EfiACPIMemoryNVS,
BufferSize + ImageContext.SectionAlignment,
&FfsBuffer
);
if (EFI_ERROR (Status)) {
return EFI_OUT_OF_RESOURCES;
}
ImageContext.ImageAddress = (PHYSICAL_ADDRESS)(UINTN)FfsBuffer;
//
// Align buffer on section boundry
//
ImageContext.ImageAddress += ImageContext.SectionAlignment - 1;
ImageContext.ImageAddress &= ~(ImageContext.SectionAlignment - 1);
//
// Load the image to our new buffer
//
Status = PeCoffLoaderLoadImage (&ImageContext);
if (EFI_ERROR (Status)) {
gBS->FreePool (FfsBuffer);
return Status;
}
//
// Relocate the image in our new buffer
//
Status = PeCoffLoaderRelocateImage (&ImageContext);
if (EFI_ERROR (Status)) {
PeCoffLoaderUnloadImage (&ImageContext);
gBS->FreePool (FfsBuffer);
return Status;
}
//
// Flush the instruction cache so the image data is written before we execute it
//
InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize);
Status = ((EFI_IMAGE_ENTRY_POINT)(UINTN)(ImageContext.EntryPoint)) ((EFI_HANDLE)(UINTN)(ImageContext.ImageAddress), SystemTable);
if (EFI_ERROR (Status)) {
gBS->FreePool (FfsBuffer);
return Status;
}
//
// Additional step for BootScriptThunk integrity
//
//
// Allocate BootScriptThunkData
//
BootScriptThunkData = AllocatePool (sizeof (BOOT_SCRIPT_THUNK_DATA));
if (EFI_ERROR (Status)) {
return EFI_OUT_OF_RESOURCES;
}
BootScriptThunkData->BootScriptThunkBase = ImageContext.ImageAddress;
BootScriptThunkData->BootScriptThunkLength = ImageContext.ImageSize;
//
// Set BootScriptThunkData
//
PcdSet64 (BootScriptThunkDataPtr, (UINT64)(UINTN)BootScriptThunkData);
return EFI_SUCCESS;
} else {
//
// the entry point is invoked after reloading. following code only run in ACPI NVS
//
//
// Locate and cache PI S3 Save State Protocol.
//
Status = gBS->LocateProtocol (
&gEfiS3SaveStateProtocolGuid,
NULL,
(VOID **) &mS3SaveState
);
ASSERT_EFI_ERROR (Status);
return gBS->InstallProtocolInterface (
&mHandle,
&gEfiBootScriptSaveProtocolGuid,
EFI_NATIVE_INTERFACE,
&mS3ScriptSave
);
}
}

View File

@ -21,9 +21,25 @@
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/SmbusLib.h>
#include <Library/PeCoffLib.h>
#include <Library/PcdLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/DxeServicesLib.h>
#include <Library/CacheMaintenanceLib.h>
#include <Guid/BootScriptThunkData.h>
#include <IndustryStandard/SmBus.h>
typedef
EFI_STATUS
(EFIAPI *DISPATCH_ENTRYPOINT_FUNC) (
IN EFI_HANDLE ImageHandle,
IN VOID *Context
);
/**
Adds a record into a specified Framework boot script table.

View File

@ -0,0 +1,216 @@
#
# Copyright (c) 2010, 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
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
#
# Module Name:
#
# AsmDispatchExecute.asm
#
# Abstract:
#
# This is the assembly code to transition from long mode to compatibility mode to execute 32-bit code and then
# transit back to long mode.
#
#-------------------------------------------------------------------------------
#----------------------------------------------------------------------------
# Procedure: AsmExecute32BitCode
#
# Input: None
#
# Output: None
#
# Prototype: EFI_STATUS
# AsmExecute32BitCode (
# IN UINT64 Function,
# IN UINT64 Param1,
# IN UINT64 Param2,
# IN IA32_DESCRIPTOR *InternalGdtr
# );
#
#
# Description: A thunk function to execute 32-bit code in long mode.
#
#----------------------------------------------------------------------------
ASM_GLOBAL ASM_PFX(AsmExecute32BitCode)
ASM_PFX(AsmExecute32BitCode):
#
# save orignal GDTR and CS
#
movq %ds, %rax
push %rax
movq %cs, %rax
push %rax
subq $0x10, %rsp
sgdt (%rsp)
#
# load internal GDT
#
lgdt (%r9)
#
# Save general purpose register and rflag register
#
pushfq
push %rdi
push %rsi
push %rbp
push %rbx
#
# save CR3
#
movq %cr3, %rax
movq %rax, %rbp
#
# Prepare the CS and return address for the transition from 32-bit to 64-bit mode
#
movq $0x10, %rax # load long mode selector
shl $32, %rax
lea ReloadCS(%rip), %r9 #Assume the ReloadCS is under 4G
orq %r9, %rax
push %rax
#
# Save parameters for 32-bit function call
#
movq %r8, %rax
shl $32, %rax
orq %rdx, %rax
push %rax
#
# save the 32-bit function entry and the return address into stack which will be
# retrieve in compatibility mode.
#
lea ReturnBack(%rip), %rax #Assume the ReloadCS is under 4G
shl $32, %rax
orq %rcx, %rax
push %rax
#
# let rax save DS
#
movq $0x18, %rax
#
# Change to Compatible Segment
#
movq $8, %rcx # load compatible mode selector
shl $32, %rcx
lea Compatible(%rip), %rdx # assume address < 4G
orq %rdx, %rcx
push %rcx
retf
Compatible:
# reload DS/ES/SS to make sure they are correct referred to current GDT
movs %ax, %ds
movs %ax, %es
movs %ax, %ss
#
# Disable paging
#
movq %cr0, %rcx
btc $31, %ecx
movq %rcx, %cr0
#
# Clear EFER.LME
#
movl $0xC0000080, %ecx
rdmsr
btc $8, %eax
wrmsr
# Now we are in protected mode
#
# Call 32-bit function. Assume the function entry address and parameter value is less than 4G
#
pop %rax # Here is the function entry
#
# Now the parameter is at the bottom of the stack, then call in to IA32 function.
#
jmp *%rax
ReturnBack:
pop %rcx # drop param1
pop %rcx # drop param2
#
# restore CR4
#
movq %cr4, %rax
bts $5, %eax
movq %rax, %cr4
#
# restore CR3
#
movl %ebp, %eax
movq %rax, %cr3
#
# Set EFER.LME to re-enable ia32-e
#
movl $0xC0000080, %ecx
rdmsr
bts $8, %eax
wrmsr
#
# Enable paging
#
movq %cr0, %rax
bts $31, %eax
mov %rax, %cr0
# Now we are in compatible mode
#
# Reload cs register
#
retf
ReloadCS:
#
# Now we're in Long Mode
#
#
# Restore C register and eax hold the return status from 32-bit function.
# Note: Do not touch rax from now which hold the return value from IA32 function
#
pop %rbx
pop %rbp
pop %rsi
pop %rdi
popfq
#
# Switch to orignal GDT and CS. here rsp is pointer to the orignal GDT descriptor.
#
lgdt (%rsp)
#
# drop GDT descriptor in stack
#
addq $0x10, %rsp
#
# switch to orignal CS and GDTR
#
pop %r9 # get CS
shl $32, %r9 # rcx[32..47] <- Cs
lea @F(%rip), %rcx
orq %r9, %rcx
push %rcx
retf
@@:
#
# Reload original DS/ES/SS
#
pop %rcx
movq %rcx, %ds
movq %rcx, %es
movq %rcx, %ss
ret

View File

@ -0,0 +1,216 @@
;
; Copyright (c) 2010, 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
; http://opensource.org/licenses/bsd-license.php
;
; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
;
;
; Module Name:
;
; AsmDispatchExecute.asm
;
; Abstract:
;
; This is the assembly code to transition from long mode to compatibility mode to execute 32-bit code and then
; transit back to long mode.
;
;-------------------------------------------------------------------------------
.code
;----------------------------------------------------------------------------
; Procedure: AsmExecute32BitCode
;
; Input: None
;
; Output: None
;
; Prototype: EFI_STATUS
; AsmExecute32BitCode (
; IN UINT64 Function,
; IN UINT64 Param1,
; IN UINT64 Param2,
; IN IA32_DESCRIPTOR *InternalGdtr
; );
;
;
; Description: A thunk function to execute 32-bit code in long mode.
;
;----------------------------------------------------------------------------
AsmExecute32BitCode PROC
;
; save orignal GDTR and CS
;
mov rax, ds
push rax
mov rax, cs
push rax
sub rsp, 10h
sgdt fword ptr [rsp]
;
; load internal GDT
;
lgdt fword ptr [r9]
;
; Save general purpose register and rflag register
;
pushfq
push rdi
push rsi
push rbp
push rbx
;
; save CR3
;
mov rax, cr3
mov rbp, rax
;
; Prepare the CS and return address for the transition from 32-bit to 64-bit mode
;
mov rax, 10h ; load long mode selector
shl rax, 32
mov r9, OFFSET ReloadCS ;Assume the ReloadCS is under 4G
or rax, r9
push rax
;
; Save parameters for 32-bit function call
;
mov rax, r8
shl rax, 32
or rax, rdx
push rax
;
; save the 32-bit function entry and the return address into stack which will be
; retrieve in compatibility mode.
;
mov rax, OFFSET ReturnBack ;Assume the ReloadCS is under 4G
shl rax, 32
or rax, rcx
push rax
;
; let rax save DS
;
mov rax, 018h
;
; Change to Compatible Segment
;
mov rcx, 08h ; load compatible mode selector
shl rcx, 32
mov rdx, OFFSET Compatible ; assume address < 4G
or rcx, rdx
push rcx
retf
Compatible:
; reload DS/ES/SS to make sure they are correct referred to current GDT
mov ds, ax
mov es, ax
mov ss, ax
;
; Disable paging
;
mov rcx, cr0
btc ecx, 31
mov cr0, rcx
;
; Clear EFER.LME
;
mov ecx, 0C0000080h
rdmsr
btc eax, 8
wrmsr
; Now we are in protected mode
;
; Call 32-bit function. Assume the function entry address and parameter value is less than 4G
;
pop rax ; Here is the function entry
;
; Now the parameter is at the bottom of the stack, then call in to IA32 function.
;
jmp rax
ReturnBack:
pop rcx ; drop param1
pop rcx ; drop param2
;
; restore CR4
;
mov rax, cr4
bts eax, 5
mov cr4, rax
;
; restore CR3
;
mov eax, ebp
mov cr3, rax
;
; Set EFER.LME to re-enable ia32-e
;
mov ecx, 0C0000080h
rdmsr
bts eax, 8
wrmsr
;
; Enable paging
;
mov rax, cr0
bts eax, 31
mov cr0, rax
; Now we are in compatible mode
;
; Reload cs register
;
retf
ReloadCS:
;
; Now we're in Long Mode
;
;
; Restore C register and eax hold the return status from 32-bit function.
; Note: Do not touch rax from now which hold the return value from IA32 function
;
pop rbx
pop rbp
pop rsi
pop rdi
popfq
;
; Switch to orignal GDT and CS. here rsp is pointer to the orignal GDT descriptor.
;
lgdt fword ptr[rsp]
;
; drop GDT descriptor in stack
;
add rsp, 10h
;
; switch to orignal CS and GDTR
;
pop r9 ; get CS
shl r9, 32 ; rcx[32..47] <- Cs
mov rcx, OFFSET @F
or rcx, r9
push rcx
retf
@@:
;
; Reload original DS/ES/SS
;
pop rcx
mov ds, rcx
mov es, rcx
mov ss, rcx
ret
AsmExecute32BitCode ENDP
END

View File

@ -0,0 +1,106 @@
/** @file
Execute 32-bit code in Long Mode
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>
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
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "ScriptSave.h"
#pragma pack(1)
typedef union {
struct {
UINT32 LimitLow : 16;
UINT32 BaseLow : 16;
UINT32 BaseMid : 8;
UINT32 Type : 4;
UINT32 System : 1;
UINT32 Dpl : 2;
UINT32 Present : 1;
UINT32 LimitHigh : 4;
UINT32 Software : 1;
UINT32 Reserved : 1;
UINT32 DefaultSize : 1;
UINT32 Granularity : 1;
UINT32 BaseHigh : 8;
} Bits;
UINT64 Uint64;
} IA32_GDT;
#pragma pack()
//
// Global Descriptor Table (GDT)
//
GLOBAL_REMOVE_IF_UNREFERENCED IA32_GDT mGdtEntries[] = {
{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 0x0: reserve */
{{0xFFFF, 0, 0, 0xB, 1, 0, 1, 0xF, 0, 0, 1, 1, 0}}, /* 0x8: compatibility mode */
{{0xFFFF, 0, 0, 0xB, 1, 0, 1, 0xF, 0, 1, 0, 1, 0}}, /* 0x10: for long mode */
{{0xFFFF, 0, 0, 0x3, 1, 0, 1, 0xF, 0, 0, 1, 1, 0}}, /* 0x18: data */
{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 0x20: reserve */
};
//
// IA32 Gdt register
//
GLOBAL_REMOVE_IF_UNREFERENCED IA32_DESCRIPTOR mGdt = {
sizeof (mGdtEntries) - 1,
(UINTN) mGdtEntries
};
/**
Assembly function to transition from long mode to compatibility mode to execute 32-bit code and then transit back to
long mode.
@param Function The 32bit code entry to be executed.
@param Param1 The first parameter to pass to 32bit code
@param Param2 The second parameter to pass to 32bit code
@param InternalGdtr The GDT and GDT descriptor used by this library
@retval EFI_SUCCESS Execute 32bit code successfully.
@retval other Something wrong when execute the 32bit code
**/
EFI_STATUS
AsmExecute32BitCode (
IN UINT64 Function,
IN UINT64 Param1,
IN UINT64 Param2,
IN IA32_DESCRIPTOR *InternalGdtr
);
/**
Wrapper for a thunk to transition from long mode to compatibility mode to execute 32-bit code and then transit back to
long mode.
@param Function The 32bit code entry to be executed.
@param Param1 The first parameter to pass to 32bit code
@param Param2 The second parameter to pass to 32bit code
@retval EFI_SUCCESS Execute 32bit code successfully.
@retval other Something wrong when execute the 32bit code
**/
EFI_STATUS
Execute32BitCode (
IN UINT64 Function,
IN UINT64 Param1,
IN UINT64 Param2
)
{
EFI_STATUS Status;
ASSERT (Function != 0);
Status = AsmExecute32BitCode (
Function,
Param1,
Param2,
&mGdt
);
return Status;
}

View File

@ -0,0 +1,31 @@
/** @file
Define Name, GUID and data format for an EFI PCD that is used to save the image base and size
of a code segment which will be loaded and executed by a boot script thunk on S3 boot path.
Copyright (c) 2010, 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
http://opensource.org/licenses/bsd-license.php.
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _BOOT_SCRIPT_THUNK_VARIABLE_H_
#define _BOOT_SCRIPT_THUNK_VARIABLE_H_
//
// The following structure boosts performance by combining structure all ACPI related variables into one.
//
#pragma pack(1)
typedef struct {
EFI_PHYSICAL_ADDRESS BootScriptThunkBase;
EFI_PHYSICAL_ADDRESS BootScriptThunkLength;
} BOOT_SCRIPT_THUNK_DATA;
#pragma pack()
#endif

View File

@ -69,6 +69,7 @@ define GCC_MACRO = -DEFI_SPECIFICATION_VERSION=0x00020000 -DPI_S
CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
LocalApicLib|UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf
DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
[LibraryClasses.common.PEIM]
MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
@ -256,7 +257,6 @@ define GCC_MACRO = -DEFI_SPECIFICATION_VERSION=0x00020000 -DPI_S
EdkCompatibilityPkg/Compatibility/LegacyRegion2OnLegacyRegionThunk/LegacyRegion2OnLegacyRegionThunk.inf
EdkCompatibilityPkg/Compatibility/PiSmbiosRecordOnDataHubSmbiosRecordThunk/PiSmbiosRecordOnDataHubSmbiosRecordThunk.inf
EdkCompatibilityPkg/Compatibility/CpuIo2OnCpuIoThunk/CpuIo2OnCpuIoThunk.inf
EdkCompatibilityPkg/Compatibility/BootScriptSaveOnS3SaveStateThunk/BootScriptSaveOnS3SaveStateThunk.inf
#
# User needs to turn on the compatibility switches for VFRC and EDK II build tool for Framework HII modules
@ -285,6 +285,7 @@ define GCC_MACRO = -DEFI_SPECIFICATION_VERSION=0x00020000 -DPI_S
EdkCompatibilityPkg/Compatibility/SmmControl2OnSmmControlThunk/SmmControl2OnSmmControlThunk.inf
EdkCompatibilityPkg/Compatibility/PiSmmStatusCodeOnFrameworkSmmStatusCodeThunk/PiSmmStatusCodeOnFrameworkSmmStatusCodeThunk.inf
EdkCompatibilityPkg/Compatibility/FrameworkSmmStatusCodeOnPiSmmStatusCodeThunk/FrameworkSmmStatusCodeOnPiSmmStatusCodeThunk.inf
EdkCompatibilityPkg/Compatibility/BootScriptSaveOnS3SaveStateThunk/BootScriptSaveOnS3SaveStateThunk.inf
[Components.IPF]
EdkCompatibilityPkg/Foundation/Cpu/Itanium/CpuIa64Lib/CpuIA64Lib.inf