mirror of https://github.com/acidanthera/audk.git
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:
parent
23228db382
commit
d766b22843
|
@ -29,31 +29,46 @@
|
||||||
#
|
#
|
||||||
# The following information is for reference only and not required by the build tools.
|
# 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]
|
[Sources]
|
||||||
ScriptSave.c
|
ScriptSave.c
|
||||||
ScriptSave.h
|
ScriptSave.h
|
||||||
|
|
||||||
|
[Sources.X64]
|
||||||
|
X64/AsmDispatchExecute.asm
|
||||||
|
X64/AsmDispatchExecute.S
|
||||||
|
X64/DispatchExecute.c
|
||||||
|
|
||||||
|
[Sources.Ia32]
|
||||||
|
IA32/DispatchExecute.c
|
||||||
|
|
||||||
[Packages]
|
[Packages]
|
||||||
MdePkg/MdePkg.dec
|
MdePkg/MdePkg.dec
|
||||||
IntelFrameworkPkg/IntelFrameworkPkg.dec
|
IntelFrameworkPkg/IntelFrameworkPkg.dec
|
||||||
MdeModulePkg/MdeModulePkg.dec
|
MdeModulePkg/MdeModulePkg.dec
|
||||||
|
EdkCompatibilityPkg/EdkCompatibilityPkg.dec
|
||||||
|
|
||||||
[LibraryClasses]
|
[LibraryClasses]
|
||||||
UefiBootServicesTableLib
|
UefiBootServicesTableLib
|
||||||
|
UefiRuntimeServicesTableLib
|
||||||
UefiDriverEntryPoint
|
UefiDriverEntryPoint
|
||||||
BaseMemoryLib
|
BaseMemoryLib
|
||||||
|
MemoryAllocationLib
|
||||||
DebugLib
|
DebugLib
|
||||||
BaseLib
|
BaseLib
|
||||||
|
PeCoffLib
|
||||||
|
PcdLib
|
||||||
|
DxeServicesLib
|
||||||
|
CacheMaintenanceLib
|
||||||
|
|
||||||
[Protocols]
|
[Protocols]
|
||||||
gEfiBootScriptSaveProtocolGuid ## PRODUCES
|
gEfiBootScriptSaveProtocolGuid ## PRODUCES
|
||||||
gEfiS3SaveStateProtocolGuid ## CONSUMES
|
gEfiS3SaveStateProtocolGuid ## CONSUMES
|
||||||
|
|
||||||
|
[Pcd]
|
||||||
|
gEfiEdkCompatibilityPkgTokenSpaceGuid.BootScriptThunkDataPtr
|
||||||
|
|
||||||
[Depex]
|
[Depex]
|
||||||
gEfiS3SaveStateProtocolGuid
|
gEfiS3SaveStateProtocolGuid
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -20,6 +20,60 @@ EFI_BOOT_SCRIPT_SAVE_PROTOCOL mS3ScriptSave = {
|
||||||
BootScriptCloseTable
|
BootScriptCloseTable
|
||||||
};
|
};
|
||||||
EFI_S3_SAVE_STATE_PROTOCOL *mS3SaveState;
|
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.
|
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.
|
Internal function to add memory pool operation to the table.
|
||||||
|
|
||||||
|
@ -600,7 +690,7 @@ BootScriptWrite (
|
||||||
|
|
||||||
case EFI_BOOT_SCRIPT_DISPATCH_OPCODE:
|
case EFI_BOOT_SCRIPT_DISPATCH_OPCODE:
|
||||||
VA_START (Marker, OpCode);
|
VA_START (Marker, OpCode);
|
||||||
Status = BootScriptDispatch (Marker);
|
Status = FrameworkBootScriptDispatch (Marker);
|
||||||
VA_END (Marker);
|
VA_END (Marker);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -705,7 +795,116 @@ InitializeScriptSaveOnS3SaveState (
|
||||||
IN EFI_SYSTEM_TABLE *SystemTable
|
IN EFI_SYSTEM_TABLE *SystemTable
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
UINT8 *Buffer;
|
||||||
|
UINTN BufferSize;
|
||||||
|
VOID *FfsBuffer;
|
||||||
|
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
|
||||||
|
BOOT_SCRIPT_THUNK_DATA *BootScriptThunkData;
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
|
VOID *DevicePath;
|
||||||
|
|
||||||
|
//
|
||||||
|
// 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.
|
// Locate and cache PI S3 Save State Protocol.
|
||||||
//
|
//
|
||||||
|
@ -722,7 +921,7 @@ InitializeScriptSaveOnS3SaveState (
|
||||||
EFI_NATIVE_INTERFACE,
|
EFI_NATIVE_INTERFACE,
|
||||||
&mS3ScriptSave
|
&mS3ScriptSave
|
||||||
);
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -21,9 +21,25 @@
|
||||||
#include <Library/BaseLib.h>
|
#include <Library/BaseLib.h>
|
||||||
#include <Library/DebugLib.h>
|
#include <Library/DebugLib.h>
|
||||||
#include <Library/UefiBootServicesTableLib.h>
|
#include <Library/UefiBootServicesTableLib.h>
|
||||||
|
#include <Library/UefiRuntimeServicesTableLib.h>
|
||||||
#include <Library/SmbusLib.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>
|
#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.
|
Adds a record into a specified Framework boot script table.
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
|
@ -69,6 +69,7 @@ define GCC_MACRO = -DEFI_SPECIFICATION_VERSION=0x00020000 -DPI_S
|
||||||
CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
|
CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
|
||||||
DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
|
DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
|
||||||
LocalApicLib|UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf
|
LocalApicLib|UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf
|
||||||
|
DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
|
||||||
|
|
||||||
[LibraryClasses.common.PEIM]
|
[LibraryClasses.common.PEIM]
|
||||||
MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
|
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/LegacyRegion2OnLegacyRegionThunk/LegacyRegion2OnLegacyRegionThunk.inf
|
||||||
EdkCompatibilityPkg/Compatibility/PiSmbiosRecordOnDataHubSmbiosRecordThunk/PiSmbiosRecordOnDataHubSmbiosRecordThunk.inf
|
EdkCompatibilityPkg/Compatibility/PiSmbiosRecordOnDataHubSmbiosRecordThunk/PiSmbiosRecordOnDataHubSmbiosRecordThunk.inf
|
||||||
EdkCompatibilityPkg/Compatibility/CpuIo2OnCpuIoThunk/CpuIo2OnCpuIoThunk.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
|
# 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/SmmControl2OnSmmControlThunk/SmmControl2OnSmmControlThunk.inf
|
||||||
EdkCompatibilityPkg/Compatibility/PiSmmStatusCodeOnFrameworkSmmStatusCodeThunk/PiSmmStatusCodeOnFrameworkSmmStatusCodeThunk.inf
|
EdkCompatibilityPkg/Compatibility/PiSmmStatusCodeOnFrameworkSmmStatusCodeThunk/PiSmmStatusCodeOnFrameworkSmmStatusCodeThunk.inf
|
||||||
EdkCompatibilityPkg/Compatibility/FrameworkSmmStatusCodeOnPiSmmStatusCodeThunk/FrameworkSmmStatusCodeOnPiSmmStatusCodeThunk.inf
|
EdkCompatibilityPkg/Compatibility/FrameworkSmmStatusCodeOnPiSmmStatusCodeThunk/FrameworkSmmStatusCodeOnPiSmmStatusCodeThunk.inf
|
||||||
|
EdkCompatibilityPkg/Compatibility/BootScriptSaveOnS3SaveStateThunk/BootScriptSaveOnS3SaveStateThunk.inf
|
||||||
|
|
||||||
[Components.IPF]
|
[Components.IPF]
|
||||||
EdkCompatibilityPkg/Foundation/Cpu/Itanium/CpuIa64Lib/CpuIA64Lib.inf
|
EdkCompatibilityPkg/Foundation/Cpu/Itanium/CpuIa64Lib/CpuIA64Lib.inf
|
||||||
|
|
Loading…
Reference in New Issue