mirror of https://github.com/acidanthera/audk.git
MdeModulePkg: Add BootScriptExecutorDxe driver
Signed-off-by: jljusten Reviewed-by: mdkinney Reviewed-by: rsun3 Reviewed-by: jyao1 git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12225 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
64d14edfeb
commit
be46cd5f85
|
@ -0,0 +1,49 @@
|
||||||
|
/** @file
|
||||||
|
Define Name, GUID and data format for an EFI Variable that is used to save the entry point
|
||||||
|
of a code segment which will be loaded and executed by a standalone boot script
|
||||||
|
executor on S3 boot path.
|
||||||
|
|
||||||
|
Copyright (c) 2006 - 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_EXECUTOR_VARIABLE_H_
|
||||||
|
#define _BOOT_SCRIPT_EXECUTOR_VARIABLE_H_
|
||||||
|
|
||||||
|
#define EFI_BOOT_SCRIPT_EXECUTOR_VARIABLE_GUID \
|
||||||
|
{ \
|
||||||
|
0x3079818c, 0x46d4, 0x4a73, {0xae, 0xf3, 0xe3, 0xe4, 0x6c, 0xf1, 0xee, 0xdb} \
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// The following structure boosts performance by combining structure all ACPI related variables into one.
|
||||||
|
//
|
||||||
|
#pragma pack(1)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
EFI_PHYSICAL_ADDRESS BootScriptExecutorEntrypoint;
|
||||||
|
} BOOT_SCRIPT_EXECUTOR_VARIABLE;
|
||||||
|
|
||||||
|
#pragma pack()
|
||||||
|
|
||||||
|
#define BOOT_SCRIPT_EXECUTOR_VARIABLE_NAME L"BootScriptExecutorVariable"
|
||||||
|
|
||||||
|
extern EFI_GUID gEfiBootScriptExecutorVariableGuid;
|
||||||
|
|
||||||
|
#define EFI_BOOT_SCRIPT_EXECUTOR_CONTEXT_GUID \
|
||||||
|
{ \
|
||||||
|
0x79cb58c4, 0xac51, 0x442f, {0xaf, 0xd7, 0x98, 0xe4, 0x7d, 0x2e, 0x99, 0x8} \
|
||||||
|
}
|
||||||
|
|
||||||
|
extern EFI_GUID gEfiBootScriptExecutorContextGuid;
|
||||||
|
|
||||||
|
#endif
|
|
@ -198,6 +198,10 @@
|
||||||
## Include/Guid/AcpiS3Context.h
|
## Include/Guid/AcpiS3Context.h
|
||||||
gEfiAcpiS3ContextGuid = { 0xef98d3a, 0x3e33, 0x497a, { 0xa4, 0x1, 0x77, 0xbe, 0x3e, 0xb7, 0x4f, 0x38 }}
|
gEfiAcpiS3ContextGuid = { 0xef98d3a, 0x3e33, 0x497a, { 0xa4, 0x1, 0x77, 0xbe, 0x3e, 0xb7, 0x4f, 0x38 }}
|
||||||
|
|
||||||
|
## Include/Guid/BootScriptExecutorVariable.h
|
||||||
|
gEfiBootScriptExecutorVariableGuid = { 0x3079818c, 0x46d4, 0x4a73, { 0xae, 0xf3, 0xe3, 0xe4, 0x6c, 0xf1, 0xee, 0xdb }}
|
||||||
|
gEfiBootScriptExecutorContextGuid = { 0x79cb58c4, 0xac51, 0x442f, { 0xaf, 0xd7, 0x98, 0xe4, 0x7d, 0x2e, 0x99, 0x8 }}
|
||||||
|
|
||||||
[Ppis]
|
[Ppis]
|
||||||
## Include/Ppi/AtaController.h
|
## Include/Ppi/AtaController.h
|
||||||
gPeiAtaControllerPpiGuid = { 0xa45e60d1, 0xc719, 0x44aa, { 0xb0, 0x7a, 0xaa, 0x77, 0x7f, 0x85, 0x90, 0x6d }}
|
gPeiAtaControllerPpiGuid = { 0xa45e60d1, 0xc719, 0x44aa, { 0xb0, 0x7a, 0xaa, 0x77, 0x7f, 0x85, 0x90, 0x6d }}
|
||||||
|
|
|
@ -87,6 +87,8 @@
|
||||||
DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
|
DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
|
||||||
PlatformHookLib|MdeModulePkg/Library/BasePlatformHookLibNull/BasePlatformHookLibNull.inf
|
PlatformHookLib|MdeModulePkg/Library/BasePlatformHookLibNull/BasePlatformHookLibNull.inf
|
||||||
ResetSystemLib|MdeModulePkg/Library/BaseResetSystemLibNull/BaseResetSystemLibNull.inf
|
ResetSystemLib|MdeModulePkg/Library/BaseResetSystemLibNull/BaseResetSystemLibNull.inf
|
||||||
|
SmbusLib|MdePkg/Library/DxeSmbusLib/DxeSmbusLib.inf
|
||||||
|
S3BootScriptLib|MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf
|
||||||
|
|
||||||
[LibraryClasses.EBC.PEIM]
|
[LibraryClasses.EBC.PEIM]
|
||||||
IoLib|MdePkg/Library/PeiIoLibCpuIo/PeiIoLibCpuIo.inf
|
IoLib|MdePkg/Library/PeiIoLibCpuIo/PeiIoLibCpuIo.inf
|
||||||
|
@ -325,4 +327,5 @@
|
||||||
MdeModulePkg/Library/DxeSmmPerformanceLib/DxeSmmPerformanceLib.inf
|
MdeModulePkg/Library/DxeSmmPerformanceLib/DxeSmmPerformanceLib.inf
|
||||||
MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxPeiLib.inf
|
MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxPeiLib.inf
|
||||||
MdeModulePkg/Library/SmmCorePlatformHookLibNull/SmmCorePlatformHookLibNull.inf
|
MdeModulePkg/Library/SmmCorePlatformHookLibNull/SmmCorePlatformHookLibNull.inf
|
||||||
|
MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
## @file
|
||||||
|
# Boot Script Executor Module
|
||||||
|
#
|
||||||
|
# This is a standalone Boot Script Executor. Standalone means it does not
|
||||||
|
# depends on any PEI or DXE service.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2006 - 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.
|
||||||
|
#
|
||||||
|
##
|
||||||
|
|
||||||
|
[Defines]
|
||||||
|
INF_VERSION = 0x00010005
|
||||||
|
BASE_NAME = BootScriptExecutorDxe
|
||||||
|
FILE_GUID = FA20568B-548B-4b2b-81EF-1BA08D4A3CEC
|
||||||
|
MODULE_TYPE = DXE_DRIVER
|
||||||
|
VERSION_STRING = 1.0
|
||||||
|
|
||||||
|
ENTRY_POINT = BootScriptExecutorEntryPoint
|
||||||
|
|
||||||
|
#
|
||||||
|
# The following information is for reference only and not required by the build tools.
|
||||||
|
#
|
||||||
|
# VALID_ARCHITECTURES = IA32 X64
|
||||||
|
#
|
||||||
|
|
||||||
|
[Sources]
|
||||||
|
ScriptExecute.h
|
||||||
|
ScriptExecute.c
|
||||||
|
|
||||||
|
[Sources.X64]
|
||||||
|
X64/SetIdtEntry.c
|
||||||
|
X64/S3Asm.asm
|
||||||
|
X64/S3Asm.S
|
||||||
|
|
||||||
|
[Sources.Ia32]
|
||||||
|
IA32/SetIdtEntry.c
|
||||||
|
IA32/S3Asm.asm
|
||||||
|
IA32/S3Asm.S
|
||||||
|
|
||||||
|
[Packages]
|
||||||
|
MdePkg/MdePkg.dec
|
||||||
|
MdeModulePkg/MdeModulePkg.dec
|
||||||
|
|
||||||
|
[LibraryClasses]
|
||||||
|
TimerLib
|
||||||
|
PcdLib
|
||||||
|
BaseMemoryLib
|
||||||
|
SmbusLib
|
||||||
|
UefiDriverEntryPoint
|
||||||
|
BaseLib
|
||||||
|
PciLib
|
||||||
|
IoLib
|
||||||
|
S3BootScriptLib
|
||||||
|
PeCoffLib
|
||||||
|
DxeServicesLib
|
||||||
|
UefiBootServicesTableLib
|
||||||
|
UefiRuntimeServicesTableLib
|
||||||
|
CacheMaintenanceLib
|
||||||
|
PerformanceLib
|
||||||
|
UefiLib
|
||||||
|
DebugAgentLib
|
||||||
|
LockBoxLib
|
||||||
|
|
||||||
|
[Guids]
|
||||||
|
gEfiBootScriptExecutorVariableGuid
|
||||||
|
gEfiBootScriptExecutorContextGuid
|
||||||
|
gPerformanceProtocolGuid
|
||||||
|
gEfiEventExitBootServicesGuid
|
||||||
|
|
||||||
|
[FeaturePcd]
|
||||||
|
gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode
|
||||||
|
|
||||||
|
[Depex]
|
||||||
|
gEfiLockBoxProtocolGuid
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
## @file
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
##
|
||||||
|
|
||||||
|
#-----------------------------------------
|
||||||
|
#VOID
|
||||||
|
#AsmTransferControl (
|
||||||
|
# IN UINT32 S3WakingVector,
|
||||||
|
# IN UINT32 AcpiLowMemoryBase
|
||||||
|
# );
|
||||||
|
#-----------------------------------------
|
||||||
|
|
||||||
|
ASM_GLOBAL ASM_PFX(AsmTransferControl)
|
||||||
|
ASM_PFX(AsmTransferControl):
|
||||||
|
# S3WakingVector :DWORD
|
||||||
|
# AcpiLowMemoryBase :DWORD
|
||||||
|
pushl %ebp
|
||||||
|
movl %esp,%ebp
|
||||||
|
leal LABLE, %eax
|
||||||
|
pushl $0x28 # CS
|
||||||
|
pushl %eax
|
||||||
|
movl 8(%ebp),%ecx
|
||||||
|
shrdl $20,%ecx,%ebx
|
||||||
|
andl $0xf,%ecx
|
||||||
|
movw %cx,%bx
|
||||||
|
movl %ebx, jmp_addr
|
||||||
|
lret
|
||||||
|
LABLE:
|
||||||
|
.byte 0xb8,0x30,0 # mov ax, 30h as selector
|
||||||
|
movw %ax,%ds
|
||||||
|
movw %ax,%es
|
||||||
|
movw %ax,%fs
|
||||||
|
movw %ax,%gs
|
||||||
|
movw %ax,%ss
|
||||||
|
movl %cr0, %eax # Get control register 0
|
||||||
|
.byte 0x66
|
||||||
|
.byte 0x83,0xe0,0xfe # and eax, 0fffffffeh ; Clear PE bit (bit #0)
|
||||||
|
.byte 0xf,0x22,0xc0 # mov cr0, eax ; Activate real mode
|
||||||
|
.byte 0xea # jmp far @jmp_addr
|
||||||
|
jmp_addr:
|
||||||
|
.long 0
|
||||||
|
|
||||||
|
ASM_GLOBAL ASM_PFX(AsmTransferControl32)
|
||||||
|
ASM_PFX(AsmTransferControl32):
|
||||||
|
jmp ASM_PFX(AsmTransferControl)
|
||||||
|
|
||||||
|
# dummy
|
||||||
|
ASM_GLOBAL ASM_PFX(AsmTransferControl16)
|
||||||
|
ASM_PFX(AsmTransferControl16):
|
||||||
|
ASM_GLOBAL ASM_PFX(AsmFixAddress16)
|
||||||
|
ASM_PFX(AsmFixAddress16):
|
||||||
|
.long 0
|
||||||
|
ASM_GLOBAL ASM_PFX(AsmJmpAddr32)
|
||||||
|
ASM_PFX(AsmJmpAddr32):
|
||||||
|
.long 0
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
;; @file
|
||||||
|
; This is the assembly code for transferring to control to OS S3 waking vector
|
||||||
|
; for IA32 platform
|
||||||
|
;
|
||||||
|
; Copyright (c) 2006, 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.
|
||||||
|
;
|
||||||
|
;;
|
||||||
|
.586P
|
||||||
|
.model flat,C
|
||||||
|
.code
|
||||||
|
|
||||||
|
EXTERNDEF AsmFixAddress16:DWORD
|
||||||
|
EXTERNDEF AsmJmpAddr32:DWORD
|
||||||
|
|
||||||
|
;-----------------------------------------
|
||||||
|
;VOID
|
||||||
|
;AsmTransferControl (
|
||||||
|
; IN UINT32 S3WakingVector,
|
||||||
|
; IN UINT32 AcpiLowMemoryBase
|
||||||
|
; );
|
||||||
|
;-----------------------------------------
|
||||||
|
|
||||||
|
AsmTransferControl PROC
|
||||||
|
; S3WakingVector :DWORD
|
||||||
|
; AcpiLowMemoryBase :DWORD
|
||||||
|
push ebp
|
||||||
|
mov ebp, esp
|
||||||
|
lea eax, @F
|
||||||
|
push 28h ; CS
|
||||||
|
push eax
|
||||||
|
mov ecx, [ebp + 8]
|
||||||
|
shrd ebx, ecx, 20
|
||||||
|
and ecx, 0fh
|
||||||
|
mov bx, cx
|
||||||
|
mov @jmp_addr, ebx
|
||||||
|
retf
|
||||||
|
@@:
|
||||||
|
DB 0b8h, 30h, 0 ; mov ax, 30h as selector
|
||||||
|
mov ds, ax
|
||||||
|
mov es, ax
|
||||||
|
mov fs, ax
|
||||||
|
mov gs, ax
|
||||||
|
mov ss, ax
|
||||||
|
mov eax, cr0 ; Get control register 0
|
||||||
|
DB 66h
|
||||||
|
DB 83h, 0e0h, 0feh ; and eax, 0fffffffeh ; Clear PE bit (bit #0)
|
||||||
|
DB 0fh, 22h, 0c0h ; mov cr0, eax ; Activate real mode
|
||||||
|
DB 0eah ; jmp far @jmp_addr
|
||||||
|
@jmp_addr DD ?
|
||||||
|
|
||||||
|
AsmTransferControl ENDP
|
||||||
|
|
||||||
|
AsmTransferControl32 PROC
|
||||||
|
jmp AsmTransferControl
|
||||||
|
AsmTransferControl32 ENDP
|
||||||
|
|
||||||
|
; dummy
|
||||||
|
AsmTransferControl16 PROC
|
||||||
|
AsmFixAddress16 DD ?
|
||||||
|
AsmJmpAddr32 DD ?
|
||||||
|
AsmTransferControl16 ENDP
|
||||||
|
|
||||||
|
END
|
|
@ -0,0 +1,63 @@
|
||||||
|
/** @file
|
||||||
|
Set a IDT entry for debug purpose
|
||||||
|
|
||||||
|
Set a IDT entry for interrupt vector 3 for debug purpose for IA32 platform
|
||||||
|
|
||||||
|
Copyright (c) 2006 - 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 "ScriptExecute.h"
|
||||||
|
//
|
||||||
|
// INTERRUPT_GATE_DESCRIPTOR and SetIdtEntry () are used to setup IDT to do debug
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma pack(1)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
UINT16 OffsetLow;
|
||||||
|
UINT16 SegmentSelector;
|
||||||
|
UINT16 Attributes;
|
||||||
|
UINT16 OffsetHigh;
|
||||||
|
} INTERRUPT_GATE_DESCRIPTOR;
|
||||||
|
|
||||||
|
#define INTERRUPT_GATE_ATTRIBUTE 0x8e00
|
||||||
|
|
||||||
|
#pragma pack()
|
||||||
|
/**
|
||||||
|
Set a IDT entry for interrupt vector 3 for debug purpose.
|
||||||
|
|
||||||
|
@param AcpiS3Context a pointer to a structure of ACPI_S3_CONTEXT
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
SetIdtEntry (
|
||||||
|
IN ACPI_S3_CONTEXT *AcpiS3Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
INTERRUPT_GATE_DESCRIPTOR *IdtEntry;
|
||||||
|
IA32_DESCRIPTOR *IdtDescriptor;
|
||||||
|
UINTN S3DebugBuffer;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Restore IDT for debug
|
||||||
|
//
|
||||||
|
IdtDescriptor = (IA32_DESCRIPTOR *) (UINTN) (AcpiS3Context->IdtrProfile);
|
||||||
|
IdtEntry = (INTERRUPT_GATE_DESCRIPTOR *)(IdtDescriptor->Base + (3 * sizeof (INTERRUPT_GATE_DESCRIPTOR)));
|
||||||
|
S3DebugBuffer = (UINTN) (AcpiS3Context->S3DebugBufferAddress);
|
||||||
|
|
||||||
|
IdtEntry->OffsetLow = (UINT16)S3DebugBuffer;
|
||||||
|
IdtEntry->SegmentSelector = (UINT16)AsmReadCs ();;
|
||||||
|
IdtEntry->Attributes = (UINT16)INTERRUPT_GATE_ATTRIBUTE;
|
||||||
|
IdtEntry->OffsetHigh = (UINT16)(S3DebugBuffer >> 16);
|
||||||
|
|
||||||
|
AsmWriteIdtr (IdtDescriptor);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,477 @@
|
||||||
|
/** @file
|
||||||
|
This is the code for Boot Script Executer module.
|
||||||
|
|
||||||
|
This driver is dispatched by Dxe core and the driver will reload itself to ACPI NVS memory
|
||||||
|
in the entry point. The functionality is to interpret and restore the S3 boot script
|
||||||
|
|
||||||
|
Copyright (c) 2006 - 2011, 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 "ScriptExecute.h"
|
||||||
|
|
||||||
|
EFI_PHYSICAL_ADDRESS mPerfDataMemAddress;
|
||||||
|
UINT64 mS3BootScriptEntryTick;
|
||||||
|
UINT64 mScriptStartTick;
|
||||||
|
UINT64 mScriptEndTick;
|
||||||
|
|
||||||
|
EFI_GUID mBootScriptExecutorImageGuid = {
|
||||||
|
0x9a8d3433, 0x9fe8, 0x42b6, 0x87, 0xb, 0x1e, 0x31, 0xc8, 0x4e, 0xbe, 0x3b
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
The event callback is used to get the base address of boot performance data structure on
|
||||||
|
LegacyBoot event and ExitBootServices event.
|
||||||
|
|
||||||
|
@param Event The event handle.
|
||||||
|
@param Context The event context.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
OnBootEvent (
|
||||||
|
IN EFI_EVENT Event,
|
||||||
|
IN VOID *Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
UINTN VarSize;
|
||||||
|
|
||||||
|
VarSize = sizeof (EFI_PHYSICAL_ADDRESS);
|
||||||
|
Status = gRT->GetVariable (
|
||||||
|
L"PerfDataMemAddr",
|
||||||
|
&gPerformanceProtocolGuid,
|
||||||
|
NULL,
|
||||||
|
&VarSize,
|
||||||
|
&mPerfDataMemAddress
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
mPerfDataMemAddress = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Record S3 Script execution time and adjust total S3 resume time for script running.
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
WriteToOsS3PerformanceData (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINT64 Ticker;
|
||||||
|
UINT64 StartValue;
|
||||||
|
UINT64 EndValue;
|
||||||
|
UINT64 Freq;
|
||||||
|
UINT64 ScriptExecuteTicks;
|
||||||
|
PERF_HEADER *PerfHeader;
|
||||||
|
PERF_DATA *PerfData;
|
||||||
|
|
||||||
|
Ticker = GetPerformanceCounter ();
|
||||||
|
|
||||||
|
PerfHeader = (PERF_HEADER *)(UINTN)mPerfDataMemAddress;
|
||||||
|
if (PerfHeader == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Freq = GetPerformanceCounterProperties (&StartValue, &EndValue);
|
||||||
|
Freq = DivU64x32 (Freq, 1000);
|
||||||
|
|
||||||
|
if (EndValue >= StartValue) {
|
||||||
|
ScriptExecuteTicks = mScriptEndTick - mScriptStartTick;
|
||||||
|
PerfHeader->S3Resume += Ticker - mS3BootScriptEntryTick;
|
||||||
|
} else {
|
||||||
|
ScriptExecuteTicks = mScriptStartTick - mScriptEndTick;
|
||||||
|
PerfHeader->S3Resume += mS3BootScriptEntryTick - Ticker;
|
||||||
|
}
|
||||||
|
if (PerfHeader->S3EntryNum < PERF_PEI_ENTRY_MAX_NUM) {
|
||||||
|
PerfData = &PerfHeader->S3Entry[PerfHeader->S3EntryNum];
|
||||||
|
PerfData->Duration = (UINT32) DivU64x32 (ScriptExecuteTicks, (UINT32) Freq);;
|
||||||
|
AsciiStrnCpy (PerfData->Token, "ScriptExec", PERF_TOKEN_LENGTH);
|
||||||
|
PerfHeader->S3EntryNum++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Entry function of Boot script exector. This function will be executed in
|
||||||
|
S3 boot path.
|
||||||
|
This function should not return, because it is invoked by switch stack.
|
||||||
|
|
||||||
|
@param AcpiS3Context a pointer to a structure of ACPI_S3_CONTEXT
|
||||||
|
@param PeiS3ResumeState a pointer to a structure of PEI_S3_RESUME_STATE
|
||||||
|
|
||||||
|
@retval EFI_INVALID_PARAMETER - OS waking vector not found
|
||||||
|
@retval EFI_UNSUPPORTED - something wrong when we resume to OS
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
S3BootScriptExecutorEntryFunction (
|
||||||
|
IN ACPI_S3_CONTEXT *AcpiS3Context,
|
||||||
|
IN PEI_S3_RESUME_STATE *PeiS3ResumeState
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *Facs;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
UINTN TempStackTop;
|
||||||
|
UINTN TempStack[0x10];
|
||||||
|
UINTN AsmTransferControl16Address;
|
||||||
|
|
||||||
|
PERF_CODE (
|
||||||
|
mS3BootScriptEntryTick = GetPerformanceCounter ();
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Disable interrupt of Debug timer, since new IDT table cannot handle it.
|
||||||
|
//
|
||||||
|
SaveAndSetDebugTimerInterrupt (FALSE);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Restore IDT for debug
|
||||||
|
//
|
||||||
|
SetIdtEntry (AcpiS3Context);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize Debug Agent to support source level debug in S3 path.
|
||||||
|
//
|
||||||
|
InitializeDebugAgent (DEBUG_AGENT_INIT_S3, NULL, NULL);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Because not install BootScriptExecute PPI(used just in this module), So just pass NULL
|
||||||
|
// for that parameter.
|
||||||
|
//
|
||||||
|
PERF_CODE (
|
||||||
|
mScriptStartTick = GetPerformanceCounter ();
|
||||||
|
);
|
||||||
|
Status = S3BootScriptExecute ();
|
||||||
|
PERF_CODE (
|
||||||
|
mScriptEndTick = GetPerformanceCounter ();
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
AsmWbinvd ();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Get ACPI Table Address
|
||||||
|
//
|
||||||
|
Facs = (EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *) ((UINTN) (AcpiS3Context->AcpiFacsTable));
|
||||||
|
|
||||||
|
if ((Facs == NULL) ||
|
||||||
|
(Facs->Signature != EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE) ||
|
||||||
|
((Facs->FirmwareWakingVector == 0) && (Facs->XFirmwareWakingVector == 0)) ) {
|
||||||
|
CpuDeadLoop();
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// We need turn back to S3Resume - install boot script done ppi and report status code on S3resume.
|
||||||
|
//
|
||||||
|
if (PeiS3ResumeState != 0) {
|
||||||
|
if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {
|
||||||
|
//
|
||||||
|
// X64 S3 Resume
|
||||||
|
//
|
||||||
|
DEBUG ((EFI_D_ERROR, "Call AsmDisablePaging64() to return to S3 Resume in PEI Phase\n"));
|
||||||
|
PeiS3ResumeState->AsmTransferControl = (EFI_PHYSICAL_ADDRESS)(UINTN)AsmTransferControl32;
|
||||||
|
|
||||||
|
//
|
||||||
|
// more step needed - because relative address is handled differently between X64 and IA32.
|
||||||
|
//
|
||||||
|
AsmTransferControl16Address = (UINTN)AsmTransferControl16;
|
||||||
|
AsmFixAddress16 = (UINT32)AsmTransferControl16Address;
|
||||||
|
AsmJmpAddr32 = (UINT32)((Facs->FirmwareWakingVector & 0xF) | ((Facs->FirmwareWakingVector & 0xFFFF0) << 12));
|
||||||
|
|
||||||
|
AsmDisablePaging64 (
|
||||||
|
PeiS3ResumeState->ReturnCs,
|
||||||
|
(UINT32)PeiS3ResumeState->ReturnEntryPoint,
|
||||||
|
(UINT32)(UINTN)AcpiS3Context,
|
||||||
|
(UINT32)(UINTN)PeiS3ResumeState,
|
||||||
|
(UINT32)PeiS3ResumeState->ReturnStackPointer
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
//
|
||||||
|
// IA32 S3 Resume
|
||||||
|
//
|
||||||
|
DEBUG ((EFI_D_ERROR, "Call SwitchStack() to return to S3 Resume in PEI Phase\n"));
|
||||||
|
PeiS3ResumeState->AsmTransferControl = (EFI_PHYSICAL_ADDRESS)(UINTN)AsmTransferControl;
|
||||||
|
|
||||||
|
SwitchStack (
|
||||||
|
(SWITCH_STACK_ENTRY_POINT)(UINTN)PeiS3ResumeState->ReturnEntryPoint,
|
||||||
|
(VOID *)(UINTN)AcpiS3Context,
|
||||||
|
(VOID *)(UINTN)PeiS3ResumeState,
|
||||||
|
(VOID *)(UINTN)PeiS3ResumeState->ReturnStackPointer
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Never run to here
|
||||||
|
//
|
||||||
|
CpuDeadLoop();
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
PERF_CODE (
|
||||||
|
WriteToOsS3PerformanceData ();
|
||||||
|
);
|
||||||
|
|
||||||
|
if (Facs->XFirmwareWakingVector != 0) {
|
||||||
|
//
|
||||||
|
// Switch to native waking vector
|
||||||
|
//
|
||||||
|
TempStackTop = (UINTN)&TempStack + sizeof(TempStack);
|
||||||
|
if ((Facs->Version == EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION) &&
|
||||||
|
((Facs->Flags & EFI_ACPI_4_0_64BIT_WAKE_SUPPORTED_F) != 0) &&
|
||||||
|
((Facs->Flags & EFI_ACPI_4_0_OSPM_64BIT_WAKE__F) != 0)) {
|
||||||
|
//
|
||||||
|
// X64 long mode waking vector
|
||||||
|
//
|
||||||
|
DEBUG (( EFI_D_ERROR, "Transfer to 64bit OS waking vector - %x\r\n", (UINTN)Facs->XFirmwareWakingVector));
|
||||||
|
if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {
|
||||||
|
SwitchStack (
|
||||||
|
(SWITCH_STACK_ENTRY_POINT)(UINTN)Facs->XFirmwareWakingVector,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
(VOID *)(UINTN)TempStackTop
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// Unsupported for 32bit DXE, 64bit OS vector
|
||||||
|
DEBUG (( EFI_D_ERROR, "Unsupported for 32bit DXE transfer to 64bit OS waking vector!\r\n"));
|
||||||
|
ASSERT (FALSE);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//
|
||||||
|
// IA32 protected mode waking vector (Page disabled)
|
||||||
|
//
|
||||||
|
DEBUG (( EFI_D_ERROR, "Transfer to 32bit OS waking vector - %x\r\n", (UINTN)Facs->XFirmwareWakingVector));
|
||||||
|
if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {
|
||||||
|
AsmDisablePaging64 (
|
||||||
|
0x10,
|
||||||
|
(UINT32)Facs->XFirmwareWakingVector,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
(UINT32)TempStackTop
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
SwitchStack (
|
||||||
|
(SWITCH_STACK_ENTRY_POINT)(UINTN)Facs->XFirmwareWakingVector,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
(VOID *)(UINTN)TempStackTop
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//
|
||||||
|
// 16bit Realmode waking vector
|
||||||
|
//
|
||||||
|
DEBUG (( EFI_D_ERROR, "Transfer to 16bit OS waking vector - %x\r\n", (UINTN)Facs->FirmwareWakingVector));
|
||||||
|
AsmTransferControl (Facs->FirmwareWakingVector, 0x0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Never run to here
|
||||||
|
//
|
||||||
|
CpuDeadLoop();
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
Entrypoint of Boot script exector driver, this function will be executed in
|
||||||
|
normal boot phase and invoked by DXE dispatch.
|
||||||
|
|
||||||
|
@param[in] ImageHandle The firmware allocated handle for the EFI image.
|
||||||
|
@param[in] SystemTable A pointer to the EFI System Table.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The entry point is executed successfully.
|
||||||
|
@retval other Some error occurs when executing this entry point.
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
BootScriptExecutorEntryPoint (
|
||||||
|
IN EFI_HANDLE ImageHandle,
|
||||||
|
IN EFI_SYSTEM_TABLE *SystemTable
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINT8 *Buffer;
|
||||||
|
UINTN BufferSize;
|
||||||
|
UINTN Pages;
|
||||||
|
EFI_PHYSICAL_ADDRESS FfsBuffer;
|
||||||
|
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
|
||||||
|
BOOT_SCRIPT_EXECUTOR_VARIABLE *EfiBootScriptExecutorVariable;
|
||||||
|
EFI_PHYSICAL_ADDRESS BootScriptExecutorBuffer;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
VOID *DevicePath;
|
||||||
|
EFI_HANDLE NewImageHandle;
|
||||||
|
|
||||||
|
//
|
||||||
|
// 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
|
||||||
|
//
|
||||||
|
NewImageHandle = NULL;
|
||||||
|
Status = gBS->InstallProtocolInterface (
|
||||||
|
&NewImageHandle,
|
||||||
|
&gEfiCallerIdGuid,
|
||||||
|
EFI_NATIVE_INTERFACE,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
Pages = EFI_SIZE_TO_PAGES(BufferSize + ImageContext.SectionAlignment);
|
||||||
|
FfsBuffer = 0xFFFFFFFF;
|
||||||
|
Status = gBS->AllocatePages (
|
||||||
|
AllocateMaxAddress,
|
||||||
|
EfiACPIMemoryNVS,
|
||||||
|
Pages,
|
||||||
|
&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->FreePages (FfsBuffer, Pages);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Relocate the image in our new buffer
|
||||||
|
//
|
||||||
|
Status = PeCoffLoaderRelocateImage (&ImageContext);
|
||||||
|
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
PeCoffLoaderUnloadImage (&ImageContext);
|
||||||
|
gBS->FreePages (FfsBuffer, Pages);
|
||||||
|
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)) (NewImageHandle, SystemTable);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
gBS->FreePages (FfsBuffer, Pages);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Additional step for BootScript integrity
|
||||||
|
// Save BootScriptExecutor image
|
||||||
|
//
|
||||||
|
Status = SaveLockBox (
|
||||||
|
&mBootScriptExecutorImageGuid,
|
||||||
|
(VOID *)(UINTN)ImageContext.ImageAddress,
|
||||||
|
(UINTN)ImageContext.ImageSize
|
||||||
|
);
|
||||||
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
|
||||||
|
Status = SetLockBoxAttributes (&mBootScriptExecutorImageGuid, LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE);
|
||||||
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
//
|
||||||
|
// the entry point is invoked after reloading. following code only run in ACPI NVS
|
||||||
|
//
|
||||||
|
BufferSize = sizeof (BOOT_SCRIPT_EXECUTOR_VARIABLE);
|
||||||
|
|
||||||
|
BootScriptExecutorBuffer = 0xFFFFFFFF;
|
||||||
|
Pages = EFI_SIZE_TO_PAGES(BufferSize);
|
||||||
|
Status = gBS->AllocatePages (
|
||||||
|
AllocateMaxAddress,
|
||||||
|
EfiACPIMemoryNVS,
|
||||||
|
Pages,
|
||||||
|
&BootScriptExecutorBuffer
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
EfiBootScriptExecutorVariable = (BOOT_SCRIPT_EXECUTOR_VARIABLE *)(UINTN)BootScriptExecutorBuffer;
|
||||||
|
EfiBootScriptExecutorVariable->BootScriptExecutorEntrypoint = (UINTN) S3BootScriptExecutorEntryFunction ;
|
||||||
|
|
||||||
|
Status = SaveLockBox (
|
||||||
|
&gEfiBootScriptExecutorVariableGuid,
|
||||||
|
&BootScriptExecutorBuffer,
|
||||||
|
sizeof(BootScriptExecutorBuffer)
|
||||||
|
);
|
||||||
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Additional step for BootScript integrity
|
||||||
|
// Save BootScriptExecutor context
|
||||||
|
//
|
||||||
|
Status = SaveLockBox (
|
||||||
|
&gEfiBootScriptExecutorContextGuid,
|
||||||
|
EfiBootScriptExecutorVariable,
|
||||||
|
sizeof(*EfiBootScriptExecutorVariable)
|
||||||
|
);
|
||||||
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
|
||||||
|
Status = SetLockBoxAttributes (&gEfiBootScriptExecutorContextGuid, LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE);
|
||||||
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
|
||||||
|
PERF_CODE (
|
||||||
|
EFI_EVENT Event;
|
||||||
|
|
||||||
|
gBS->CreateEventEx (
|
||||||
|
EVT_NOTIFY_SIGNAL,
|
||||||
|
TPL_NOTIFY,
|
||||||
|
OnBootEvent,
|
||||||
|
NULL,
|
||||||
|
&gEfiEventExitBootServicesGuid,
|
||||||
|
&Event
|
||||||
|
);
|
||||||
|
|
||||||
|
EfiCreateEventLegacyBootEx(
|
||||||
|
TPL_NOTIFY,
|
||||||
|
OnBootEvent,
|
||||||
|
NULL,
|
||||||
|
&Event
|
||||||
|
);
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
/** @file
|
||||||
|
The header file for Boot Script Executer module.
|
||||||
|
|
||||||
|
This driver is dispatched by Dxe core and the driver will reload itself to ACPI NVS memory
|
||||||
|
in the entry point. The functionality is to interpret and restore the S3 boot script
|
||||||
|
|
||||||
|
Copyright (c) 2006 - 2011, 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_EXECUTOR_H_
|
||||||
|
#define _BOOT_SCRIPT_EXECUTOR_H_
|
||||||
|
|
||||||
|
#include <PiDxe.h>
|
||||||
|
|
||||||
|
#include <Library/BaseLib.h>
|
||||||
|
#include <Library/UefiDriverEntryPoint.h>
|
||||||
|
#include <Library/BaseMemoryLib.h>
|
||||||
|
#include <Library/DebugLib.h>
|
||||||
|
#include <Library/S3BootScriptLib.h>
|
||||||
|
#include <Library/PeCoffLib.h>
|
||||||
|
#include <Library/DxeServicesLib.h>
|
||||||
|
#include <Library/UefiBootServicesTableLib.h>
|
||||||
|
#include <Library/UefiRuntimeServicesTableLib.h>
|
||||||
|
#include <Library/PcdLib.h>
|
||||||
|
#include <Library/CacheMaintenanceLib.h>
|
||||||
|
#include <Library/PerformanceLib.h>
|
||||||
|
#include <Library/TimerLib.h>
|
||||||
|
#include <Library/UefiLib.h>
|
||||||
|
#include <Library/DebugAgentLib.h>
|
||||||
|
#include <Library/LockBoxLib.h>
|
||||||
|
|
||||||
|
#include <Guid/AcpiS3Context.h>
|
||||||
|
#include <Guid/BootScriptExecutorVariable.h>
|
||||||
|
#include <Guid/EventGroup.h>
|
||||||
|
#include <Guid/Performance.h>
|
||||||
|
#include <IndustryStandard/Acpi.h>
|
||||||
|
/**
|
||||||
|
a ASM function to transfer control to OS.
|
||||||
|
|
||||||
|
@param S3WakingVector The S3 waking up vector saved in ACPI Facs table
|
||||||
|
@param AcpiLowMemoryBase a buffer under 1M which could be used during the transfer
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
AsmTransferControl (
|
||||||
|
IN UINT32 S3WakingVector,
|
||||||
|
IN UINT32 AcpiLowMemoryBase
|
||||||
|
);
|
||||||
|
/**
|
||||||
|
a 32bit ASM function to transfer control to OS.
|
||||||
|
|
||||||
|
@param S3WakingVector The S3 waking up vector saved in ACPI Facs table
|
||||||
|
@param AcpiLowMemoryBase a buffer under 1M which could be used during the transfer
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
AsmTransferControl32 (
|
||||||
|
IN UINT32 S3WakingVector,
|
||||||
|
IN UINT32 AcpiLowMemoryBase
|
||||||
|
);
|
||||||
|
/**
|
||||||
|
a 16bit ASM function to transfer control to OS.
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
AsmTransferControl16 (
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
/**
|
||||||
|
Set a IDT entry for interrupt vector 3 for debug purpose.
|
||||||
|
|
||||||
|
@param AcpiS3Context a pointer to a structure of ACPI_S3_CONTEXT
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
SetIdtEntry (
|
||||||
|
IN ACPI_S3_CONTEXT *AcpiS3Context
|
||||||
|
);
|
||||||
|
|
||||||
|
extern UINT32 AsmFixAddress16;
|
||||||
|
extern UINT32 AsmJmpAddr32;
|
||||||
|
|
||||||
|
#endif //_BOOT_SCRIPT_EXECUTOR_H_
|
|
@ -0,0 +1,82 @@
|
||||||
|
## @file
|
||||||
|
# This is the assembly code for transferring to control to OS S3 waking vector
|
||||||
|
# for X64 platform
|
||||||
|
#
|
||||||
|
# Copyright (c) 2006, 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.
|
||||||
|
#
|
||||||
|
##
|
||||||
|
|
||||||
|
ASM_GLOBAL ASM_PFX(AsmTransferControl)
|
||||||
|
ASM_PFX(AsmTransferControl):
|
||||||
|
# rcx S3WakingVector :DWORD
|
||||||
|
# rdx AcpiLowMemoryBase :DWORD
|
||||||
|
lea _AsmTransferControl_al_0000, %eax
|
||||||
|
movq $0x2800000000, %r8
|
||||||
|
orq %r8, %rax
|
||||||
|
pushq %rax
|
||||||
|
shrd $20, %ecx, %ebx
|
||||||
|
andl $0x0f, %ecx
|
||||||
|
movw %cx, %bx
|
||||||
|
movl %ebx, jmp_addr
|
||||||
|
lret
|
||||||
|
_AsmTransferControl_al_0000:
|
||||||
|
.byte 0x0b8, 0x30, 0 # mov ax, 30h as selector
|
||||||
|
movl %eax, %ds
|
||||||
|
movl %eax, %es
|
||||||
|
movl %eax, %fs
|
||||||
|
movl %eax, %gs
|
||||||
|
movl %eax, %ss
|
||||||
|
movq %cr0, %rax
|
||||||
|
movq %cr4, %rbx
|
||||||
|
.byte 0x66
|
||||||
|
andl $0x7ffffffe, %eax
|
||||||
|
andb $0xdf, %bl
|
||||||
|
movq %rax, %cr0
|
||||||
|
.byte 0x66
|
||||||
|
movl $0x0c0000080, %ecx
|
||||||
|
rdmsr
|
||||||
|
andb $0xfe, %ah
|
||||||
|
wrmsr
|
||||||
|
movq %rbx, %cr4
|
||||||
|
.byte 0x0ea # jmp far jmp_addr
|
||||||
|
jmp_addr:
|
||||||
|
.long 0
|
||||||
|
|
||||||
|
ASM_GLOBAL ASM_PFX(AsmTransferControl32)
|
||||||
|
ASM_PFX(AsmTransferControl32):
|
||||||
|
# S3WakingVector :DWORD
|
||||||
|
# AcpiLowMemoryBase :DWORD
|
||||||
|
pushq %rbp
|
||||||
|
movl %esp,%ebp
|
||||||
|
.byte 0x8d, 0x05 # lea eax, AsmTransferControl16
|
||||||
|
ASM_GLOBAL ASM_PFX(AsmFixAddress16)
|
||||||
|
ASM_PFX(AsmFixAddress16):
|
||||||
|
.long 0
|
||||||
|
pushq $0x28 # CS
|
||||||
|
pushq %rax
|
||||||
|
lret
|
||||||
|
|
||||||
|
ASM_GLOBAL ASM_PFX(AsmTransferControl16)
|
||||||
|
ASM_PFX(AsmTransferControl16):
|
||||||
|
.byte 0xb8,0x30,0 # mov ax, 30h as selector
|
||||||
|
movw %ax,%ds
|
||||||
|
movw %ax,%es
|
||||||
|
movw %ax,%fs
|
||||||
|
movw %ax,%gs
|
||||||
|
movw %ax,%ss
|
||||||
|
movq %cr0, %rax # Get control register 0
|
||||||
|
.byte 0x66
|
||||||
|
.byte 0x83,0xe0,0xfe # and eax, 0fffffffeh ; Clear PE bit (bit #0)
|
||||||
|
.byte 0xf,0x22,0xc0 # mov cr0, eax ; Activate real mode
|
||||||
|
.byte 0xea # jmp far AsmJmpAddr32
|
||||||
|
ASM_GLOBAL ASM_PFX(AsmJmpAddr32)
|
||||||
|
ASM_PFX(AsmJmpAddr32):
|
||||||
|
.long 0
|
|
@ -0,0 +1,84 @@
|
||||||
|
;; @file
|
||||||
|
; This is the assembly code for transferring to control to OS S3 waking vector
|
||||||
|
; for X64 platform
|
||||||
|
;
|
||||||
|
; Copyright (c) 2006, 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.
|
||||||
|
;
|
||||||
|
;;
|
||||||
|
|
||||||
|
.code
|
||||||
|
|
||||||
|
EXTERNDEF AsmFixAddress16:DWORD
|
||||||
|
EXTERNDEF AsmJmpAddr32:DWORD
|
||||||
|
|
||||||
|
AsmTransferControl PROC
|
||||||
|
; rcx S3WakingVector :DWORD
|
||||||
|
; rdx AcpiLowMemoryBase :DWORD
|
||||||
|
lea eax, @F
|
||||||
|
mov r8, 2800000000h
|
||||||
|
or rax, r8
|
||||||
|
push rax
|
||||||
|
shrd ebx, ecx, 20
|
||||||
|
and ecx, 0fh
|
||||||
|
mov bx, cx
|
||||||
|
mov @jmp_addr, ebx
|
||||||
|
retf
|
||||||
|
@@:
|
||||||
|
DB 0b8h, 30h, 0 ; mov ax, 30h as selector
|
||||||
|
mov ds, eax
|
||||||
|
mov es, eax
|
||||||
|
mov fs, eax
|
||||||
|
mov gs, eax
|
||||||
|
mov ss, eax
|
||||||
|
mov rax, cr0
|
||||||
|
mov rbx, cr4
|
||||||
|
DB 66h
|
||||||
|
and eax, ((NOT 080000001h) AND 0ffffffffh)
|
||||||
|
and bl, NOT (1 SHL 5)
|
||||||
|
mov cr0, rax
|
||||||
|
DB 66h
|
||||||
|
mov ecx, 0c0000080h
|
||||||
|
rdmsr
|
||||||
|
and ah, NOT 1
|
||||||
|
wrmsr
|
||||||
|
mov cr4, rbx
|
||||||
|
DB 0eah ; jmp far @jmp_addr
|
||||||
|
@jmp_addr DD ?
|
||||||
|
AsmTransferControl ENDP
|
||||||
|
|
||||||
|
AsmTransferControl32 PROC
|
||||||
|
; S3WakingVector :DWORD
|
||||||
|
; AcpiLowMemoryBase :DWORD
|
||||||
|
push rbp
|
||||||
|
mov ebp, esp
|
||||||
|
DB 8dh, 05h ; lea eax, AsmTransferControl16
|
||||||
|
AsmFixAddress16 DD ?
|
||||||
|
push 28h ; CS
|
||||||
|
push rax
|
||||||
|
retf
|
||||||
|
AsmTransferControl32 ENDP
|
||||||
|
|
||||||
|
AsmTransferControl16 PROC
|
||||||
|
DB 0b8h, 30h, 0 ; mov ax, 30h as selector
|
||||||
|
mov ds, ax
|
||||||
|
mov es, ax
|
||||||
|
mov fs, ax
|
||||||
|
mov gs, ax
|
||||||
|
mov ss, ax
|
||||||
|
mov rax, cr0 ; Get control register 0
|
||||||
|
DB 66h
|
||||||
|
DB 83h, 0e0h, 0feh ; and eax, 0fffffffeh ; Clear PE bit (bit #0)
|
||||||
|
DB 0fh, 22h, 0c0h ; mov cr0, eax ; Activate real mode
|
||||||
|
DB 0eah ; jmp far AsmJmpAddr32
|
||||||
|
AsmJmpAddr32 DD ?
|
||||||
|
AsmTransferControl16 ENDP
|
||||||
|
|
||||||
|
END
|
|
@ -0,0 +1,67 @@
|
||||||
|
/** @file
|
||||||
|
Set a IDT entry for debug purpose
|
||||||
|
|
||||||
|
Set a IDT entry for interrupt vector 3 for debug purpose for x64 platform
|
||||||
|
|
||||||
|
Copyright (c) 2006 - 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 "ScriptExecute.h"
|
||||||
|
//
|
||||||
|
// INTERRUPT_GATE_DESCRIPTOR and SetIdtEntry () are used to setup IDT to do debug
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma pack(1)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
UINT16 Offset15To0;
|
||||||
|
UINT16 SegmentSelector;
|
||||||
|
UINT16 Attributes;
|
||||||
|
UINT16 Offset31To16;
|
||||||
|
UINT32 Offset63To32;
|
||||||
|
UINT32 Reserved;
|
||||||
|
} INTERRUPT_GATE_DESCRIPTOR;
|
||||||
|
|
||||||
|
#define INTERRUPT_GATE_ATTRIBUTE 0x8e00
|
||||||
|
|
||||||
|
#pragma pack()
|
||||||
|
/**
|
||||||
|
Set a IDT entry for interrupt vector 3 for debug purpose.
|
||||||
|
|
||||||
|
@param AcpiS3Context a pointer to a structure of ACPI_S3_CONTEXT
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
SetIdtEntry (
|
||||||
|
IN ACPI_S3_CONTEXT *AcpiS3Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
INTERRUPT_GATE_DESCRIPTOR *IdtEntry;
|
||||||
|
IA32_DESCRIPTOR *IdtDescriptor;
|
||||||
|
UINTN S3DebugBuffer;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Restore IDT for debug
|
||||||
|
//
|
||||||
|
IdtDescriptor = (IA32_DESCRIPTOR *) (UINTN) (AcpiS3Context->IdtrProfile);
|
||||||
|
IdtEntry = (INTERRUPT_GATE_DESCRIPTOR *)(IdtDescriptor->Base + (3 * sizeof (INTERRUPT_GATE_DESCRIPTOR)));
|
||||||
|
S3DebugBuffer = (UINTN) (AcpiS3Context->S3DebugBufferAddress);
|
||||||
|
|
||||||
|
IdtEntry->Offset15To0 = (UINT16)S3DebugBuffer;
|
||||||
|
IdtEntry->SegmentSelector = (UINT16)AsmReadCs ();;
|
||||||
|
IdtEntry->Attributes = (UINT16)INTERRUPT_GATE_ATTRIBUTE;
|
||||||
|
IdtEntry->Offset31To16 = (UINT16)(S3DebugBuffer >> 16);
|
||||||
|
IdtEntry->Offset63To32 = (UINT32)(S3DebugBuffer >> 32);
|
||||||
|
IdtEntry->Reserved = 0;
|
||||||
|
|
||||||
|
AsmWriteIdtr (IdtDescriptor);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue