Add IntelFspWrapper to support boot EDKII on FSP bin.

Contributed-under: TianoCore Contribution Agreement 1.0

Signed off by: Jiewen Yao <jiewen.yao@intel.com>
Reviewed by: Ravi Rangarajan <ravi.p.rangarajan@intel.com>
Reviewed by: Maurice Ma <maurice.ma@intel.com>
Reviewed by: Giri Mudusuru <giri.p.mudusuru@intel.com>
Reviewed by: Liming Gao <liming.gao@intel.com>


git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15676 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
jyao1
2014-07-24 06:52:43 +00:00
committed by jyao1
parent 34717ef034
commit a33a2f6221
61 changed files with 6577 additions and 0 deletions

View File

@@ -0,0 +1,66 @@
## @file
# Provide FSP API related function.
#
# Copyright (c) 2014, 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 Section - statements that will be processed to create a Makefile.
#
################################################################################
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = BaseFspApiLib
FILE_GUID = 6E4CB8C5-6144-4ae3-BA52-B6AFBCB2B2F5
MODULE_TYPE = BASE
VERSION_STRING = 1.0
LIBRARY_CLASS = FspApiLib
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64
#
################################################################################
#
# Sources Section - list of files that are required for the build to succeed.
#
################################################################################
[Sources]
FspApiLib.c
[Sources.IA32]
IA32/DispatchExecute.c
[Sources.X64]
X64/DispatchExecute.c
X64/Thunk64To32.asm
X64/Thunk64To32.S
################################################################################
#
# Package Dependency Section - list of Package files that are required for
# this module.
#
################################################################################
[Packages]
MdePkg/MdePkg.dec
IntelFspPkg/IntelFspPkg.dec
IntelFspWrapperPkg/IntelFspWrapperPkg.dec
[LibraryClasses]
[Guids]
gFspHeaderFileGuid

View File

@@ -0,0 +1,127 @@
/** @file
Provide FSP API related function.
Copyright (c) 2014, 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 <PiPei.h>
#include <Guid/FspHeaderFile.h>
#include <Library/FspApiLib.h>
#include <Library/BaseMemoryLib.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[in] Function The 32bit code entry to be executed.
@param[in] Param1 The first parameter to pass to 32bit code.
@return FSP_STATUS.
**/
FSP_STATUS
Execute32BitCode (
IN UINT64 Function,
IN UINT64 Param1
);
/**
Find FSP header pointer.
@param[in] FlashFvFspBase Flash address of FSP FV.
@return FSP header pointer.
**/
FSP_INFO_HEADER *
EFIAPI
FspFindFspHeader (
IN EFI_PHYSICAL_ADDRESS FlashFvFspBase
)
{
UINT8 *CheckPointer;
CheckPointer = (UINT8 *) (UINTN) FlashFvFspBase;
if (((EFI_FIRMWARE_VOLUME_HEADER *)CheckPointer)->Signature != EFI_FVH_SIGNATURE) {
return NULL;
}
if (((EFI_FIRMWARE_VOLUME_HEADER *)CheckPointer)->ExtHeaderOffset != 0) {
CheckPointer = CheckPointer + ((EFI_FIRMWARE_VOLUME_HEADER *)CheckPointer)->ExtHeaderOffset;
CheckPointer = CheckPointer + ((EFI_FIRMWARE_VOLUME_EXT_HEADER *)CheckPointer)->ExtHeaderSize;
CheckPointer = (UINT8 *) ALIGN_POINTER (CheckPointer, 8);
} else {
CheckPointer = CheckPointer + ((EFI_FIRMWARE_VOLUME_HEADER *)CheckPointer)->HeaderLength;
}
if (!CompareGuid (&((EFI_FFS_FILE_HEADER *)CheckPointer)->Name, &gFspHeaderFileGuid)) {
return NULL;
}
CheckPointer = CheckPointer + sizeof (EFI_FFS_FILE_HEADER);
if (((EFI_RAW_SECTION *)CheckPointer)->Type != EFI_SECTION_RAW) {
return NULL;
}
CheckPointer = CheckPointer + sizeof (EFI_RAW_SECTION);
return (FSP_INFO_HEADER *)CheckPointer;
}
/**
Call FSP API - FspInit.
@param[in] FspHeader FSP header pointer.
@param[in] FspInitParams Address pointer to the FSP_INIT_PARAMS structure.
@return FSP status returned by FspInit API.
**/
FSP_STATUS
EFIAPI
CallFspInit (
IN FSP_INFO_HEADER *FspHeader,
IN FSP_INIT_PARAMS *FspInitParams
)
{
FSP_FSP_INIT FspInitApi;
FSP_STATUS FspStatus;
FspInitApi = (FSP_FSP_INIT)(UINTN)(FspHeader->ImageBase + FspHeader->FspInitEntryOffset);
FspStatus = Execute32BitCode ((UINTN)FspInitApi, (UINTN)FspInitParams);
return FspStatus;
}
/**
Call FSP API - FspNotifyPhase.
@param[in] FspHeader FSP header pointer.
@param[in] NotifyPhaseParams Address pointer to the NOTIFY_PHASE_PARAMS structure.
@return FSP status returned by FspNotifyPhase API.
**/
FSP_STATUS
EFIAPI
CallFspNotifyPhase (
IN FSP_INFO_HEADER *FspHeader,
IN NOTIFY_PHASE_PARAMS *NotifyPhaseParams
)
{
FSP_NOTFY_PHASE NotifyPhaseApi;
FSP_STATUS FspStatus;
NotifyPhaseApi = (FSP_NOTFY_PHASE)(UINTN)(FspHeader->ImageBase + FspHeader->NotifyPhaseEntryOffset);
FspStatus = Execute32BitCode ((UINTN)NotifyPhaseApi, (UINTN)NotifyPhaseParams);
return FspStatus;
}

View File

@@ -0,0 +1,47 @@
/** @file
Execute 32-bit code in Protected Mode.
Copyright (c) 2014, 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 <Uefi.h>
#include <FspApi.h>
typedef
FSP_STATUS
(FSPAPI *FSP_FUNCTION) (
IN VOID *Param1
);
/**
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[in] Function The 32bit code entry to be executed.
@param[in] Param1 The first parameter to pass to 32bit code.
@return FSP_STATUS.
**/
FSP_STATUS
Execute32BitCode (
IN UINT64 Function,
IN UINT64 Param1
)
{
FSP_FUNCTION EntryFunc;
FSP_STATUS Status;
EntryFunc = (FSP_FUNCTION) (UINTN) (Function);
Status = EntryFunc ((VOID *)(UINTN)Param1);
return Status;
}

View File

@@ -0,0 +1,94 @@
/** @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) 2014, 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 <Uefi.h>
#include <Library/BaseLib.h>
#include <FspApi.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_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[in] Function The 32bit code entry to be executed.
@param[in] Param1 The first parameter to pass to 32bit code
@param[in] Param2 The second parameter to pass to 32bit code
@param[in] InternalGdtr The GDT and GDT descriptor used by this library
@return status.
**/
UINT32
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[in] Function The 32bit code entry to be executed.
@param[in] Param1 The first parameter to pass to 32bit code.
@return FSP_STATUS.
**/
FSP_STATUS
Execute32BitCode (
IN UINT64 Function,
IN UINT64 Param1
)
{
return AsmExecute32BitCode (Function, Param1, 0, &mGdt);
}

View File

@@ -0,0 +1,230 @@
#
# Copyright (c) 2014, 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:
#
# Thunk64To32.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: UINT32
# 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 IFLAG and disable it
#
pushfq
cli
#
# save orignal GDTR and CS
#
movl %ds, %eax
push %rax
movl %cs, %eax
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
.byte 0xcb # retf
Compatible:
# reload DS/ES/SS to make sure they are correct referred to current GDT
movw %ax, %ds
movw %ax, %es
movw %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:
movl %eax, %ebx # save return status
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
#
.byte 0xcb # 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
#
movl %ebx, %eax # put return status to EAX
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 ReturnToLongMode(%rip), %rcx
orq %r9, %rcx
push %rcx
.byte 0xcb # retf
ReturnToLongMode:
#
# Reload original DS/ES/SS
#
pop %rcx
movl %ecx, %ds
movl %ecx, %es
movl %ecx, %ss
#
# Restore IFLAG
#
popfq
ret

View File

@@ -0,0 +1,230 @@
;
; Copyright (c) 2014, 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:
;
; Thunk64To32.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: UINT32
; 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 IFLAG and disable it
;
pushfq
cli
;
; 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:
mov ebx, eax ; save return status
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
;
mov eax, ebx ; put return status to EAX
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
;
; Restore IFLAG
;
popfq
ret
AsmExecute32BitCode ENDP
END

View File

@@ -0,0 +1,61 @@
## @file
# Sample to provide FSP platform information related function.
#
# Copyright (c) 2014, 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 Section - statements that will be processed to create a Makefile.
#
################################################################################
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = BaseFspPlatformInfoLibSample
FILE_GUID = 24C6F3E2-6ACD-436b-A604-56A5CF742A55
MODULE_TYPE = SEC
VERSION_STRING = 1.0
LIBRARY_CLASS = FspPlatformInfoLib
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64
#
################################################################################
#
# Sources Section - list of files that are required for the build to succeed.
#
################################################################################
[Sources]
FspPlatformInfoLibSample.c
################################################################################
#
# Package Dependency Section - list of Package files that are required for
# this module.
#
################################################################################
[Packages]
MdePkg/MdePkg.dec
IntelFspPkg/IntelFspPkg.dec
IntelFspWrapperPkg/IntelFspWrapperPkg.dec
[LibraryClasses]
[Pcd]
gFspWrapperTokenSpaceGuid.PcdTemporaryRamBase
gFspWrapperTokenSpaceGuid.PcdTemporaryRamSize

View File

@@ -0,0 +1,147 @@
/** @file
Sample to provide FSP platform information related function.
Copyright (c) 2014, 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 <PiPei.h>
#include <Library/PcdLib.h>
/**
Get current boot mode.
@note At this point, memory is ready, PeiServices are NOT available to use.
Platform can get some data from chipset register.
@return BootMode current boot mode.
**/
UINT32
EFIAPI
GetBootMode (
VOID
)
{
return BOOT_WITH_FULL_CONFIGURATION;
}
/**
Get NVS buffer parameter.
@note At this point, memory is NOT ready, PeiServices are available to use.
@return NvsBuffer NVS buffer parameter.
**/
VOID *
EFIAPI
GetNvsBuffer (
VOID
)
{
return NULL;
}
/**
Get UPD region size.
@note At this point, memory is NOT ready, PeiServices are available to use.
@return UPD region size.
**/
UINT32
EFIAPI
GetUpdRegionSize (
VOID
)
{
return 0;
}
/**
This function overrides the default configurations in the UPD data region.
@note At this point, memory is NOT ready, PeiServices are available to use.
@param[in,out] FspUpdRgnPtr A pointer to the UPD data region data strcture.
@return FspUpdRgnPtr A pointer to the UPD data region data strcture.
**/
VOID *
EFIAPI
UpdateFspUpdConfigs (
IN OUT VOID *FspUpdRgnPtr
)
{
return NULL;
}
/**
Get S3 PEI memory information.
@note At this point, memory is ready, and PeiServices are available to use.
Platform can get some data from SMRAM directly.
@param[out] S3PeiMemSize PEI memory size to be installed in S3 phase.
@param[out] S3PeiMemBase PEI memory base to be installed in S3 phase.
@return If S3 PEI memory information is got successfully.
**/
EFI_STATUS
EFIAPI
GetS3MemoryInfo (
OUT UINT64 *S3PeiMemSize,
OUT EFI_PHYSICAL_ADDRESS *S3PeiMemBase
)
{
return EFI_UNSUPPORTED;
}
/**
Get stack information according to boot mode.
@note If BootMode is BOOT_ON_S3_RESUME or BOOT_ON_FLASH_UPDATE,
this stack should be in some reserved memory space.
@note If FspInitDone is TRUE, memory is ready, but no PeiServices there.
Platform can get some data from SMRAM directly.
@note If FspInitDone is FALSE, memory is NOT ready, but PeiServices are available to use.
Platform can get some data from variable via VariablePpi.
@param[in] BootMode Current boot mode.
@param[in] FspInitDone If FspInit is called.
@param[out] StackSize Stack size to be used in PEI phase.
@param[out] StackBase Stack base to be used in PEI phase.
@return If Stack information is got successfully.
**/
EFI_STATUS
EFIAPI
GetStackInfo (
IN UINT32 BootMode,
IN BOOLEAN FspInitDone,
OUT UINT64 *StackSize,
OUT EFI_PHYSICAL_ADDRESS *StackBase
)
{
*StackBase = PcdGet32 (PcdTemporaryRamBase);
*StackSize = PcdGet32 (PcdTemporaryRamSize);
if (BootMode == BOOT_ON_S3_RESUME) {
if (!FspInitDone) {
} else {
}
} else if (BootMode == BOOT_ON_FLASH_UPDATE) {
if (!FspInitDone) {
} else {
}
}
return EFI_SUCCESS;
}

View File

@@ -0,0 +1,337 @@
/** @file
Sample to provide FSP hob process related function.
Copyright (c) 2014, 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 <PiPei.h>
#include <Library/PeiServicesLib.h>
#include <Library/PeiServicesTablePointerLib.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/HobLib.h>
#include <Library/PcdLib.h>
#include <Library/FspPlatformInfoLib.h>
#include <Guid/GuidHobFspEas.h>
#include <Guid/MemoryTypeInformation.h>
#include <Ppi/Capsule.h>
//
// Additional pages are used by DXE memory manager.
// It should be consistent between RetrieveRequiredMemorySize() and GetPeiMemSize()
//
#define PEI_ADDITIONAL_MEMORY_SIZE (16 * EFI_PAGE_SIZE)
/**
Get the mem size in memory type infromation table.
@param[in] PeiServices PEI Services table.
@return the mem size in memory type infromation table.
**/
UINT64
GetMemorySizeInMemoryTypeInformation (
IN EFI_PEI_SERVICES **PeiServices
)
{
EFI_STATUS Status;
EFI_PEI_HOB_POINTERS Hob;
EFI_MEMORY_TYPE_INFORMATION *MemoryData;
UINT8 Index;
UINTN TempPageNum;
MemoryData = NULL;
Status = (*PeiServices)->GetHobList ((CONST EFI_PEI_SERVICES**)PeiServices, (VOID **) &Hob.Raw);
while (!END_OF_HOB_LIST (Hob)) {
if (Hob.Header->HobType == EFI_HOB_TYPE_GUID_EXTENSION &&
CompareGuid (&Hob.Guid->Name, &gEfiMemoryTypeInformationGuid)) {
MemoryData = (EFI_MEMORY_TYPE_INFORMATION *) (Hob.Raw + sizeof (EFI_HOB_GENERIC_HEADER) + sizeof (EFI_GUID));
break;
}
Hob.Raw = GET_NEXT_HOB (Hob);
}
if (MemoryData == NULL) {
return 0;
}
TempPageNum = 0;
for (Index = 0; MemoryData[Index].Type != EfiMaxMemoryType; Index++) {
//
// Accumulate default memory size requirements
//
TempPageNum += MemoryData[Index].NumberOfPages;
}
return TempPageNum * EFI_PAGE_SIZE;
}
/**
Get the mem size need to be reserved in PEI phase.
@param[in] PeiServices PEI Services table.
@return the mem size need to be reserved in PEI phase.
**/
UINT64
RetrieveRequiredMemorySize (
IN EFI_PEI_SERVICES **PeiServices
)
{
UINT64 Size;
Size = GetMemorySizeInMemoryTypeInformation (PeiServices);
return Size + PEI_ADDITIONAL_MEMORY_SIZE;
}
/**
Get the mem size need to be consumed and reserved in PEI phase.
@param[in] PeiServices PEI Services table.
@param[in] BootMode Current boot mode.
@return the mem size need to be consumed and reserved in PEI phase.
**/
UINT64
GetPeiMemSize (
IN EFI_PEI_SERVICES **PeiServices,
IN UINT32 BootMode
)
{
UINT64 Size;
UINT64 MinSize;
if (BootMode == BOOT_IN_RECOVERY_MODE) {
return PcdGet32 (PcdPeiRecoveryMinMemSize);
}
Size = GetMemorySizeInMemoryTypeInformation (PeiServices);
if (BootMode == BOOT_ON_FLASH_UPDATE) {
//
// Maybe more size when in CapsuleUpdate phase ?
//
MinSize = PcdGet32 (PcdPeiMinMemSize);
} else {
MinSize = PcdGet32 (PcdPeiMinMemSize);
}
return MinSize + Size + PEI_ADDITIONAL_MEMORY_SIZE;
}
/**
BIOS process FspBobList.
@param[in] FspHobList Pointer to the HOB data structure produced by FSP.
@return If platform process the FSP hob list successfully.
**/
EFI_STATUS
EFIAPI
FspHobProcess (
IN VOID *FspHobList
)
{
EFI_PEI_HOB_POINTERS Hob;
UINT64 LowMemorySize;
UINT64 FspMemorySize;
EFI_PHYSICAL_ADDRESS FspMemoryBase;
UINT64 PeiMemSize;
EFI_PHYSICAL_ADDRESS PeiMemBase;
UINT64 S3PeiMemSize;
EFI_PHYSICAL_ADDRESS S3PeiMemBase;
BOOLEAN FoundFspMemHob;
EFI_STATUS Status;
EFI_BOOT_MODE BootMode;
PEI_CAPSULE_PPI *Capsule;
VOID *CapsuleBuffer;
UINTN CapsuleBufferLength;
UINT64 RequiredMemSize;
EFI_PEI_SERVICES **PeiServices;
PeiServices = (EFI_PEI_SERVICES **)GetPeiServicesTablePointer ();
PeiServicesGetBootMode (&BootMode);
PeiMemBase = 0;
LowMemorySize = 0;
FspMemorySize = 0;
FspMemoryBase = 0;
FoundFspMemHob = FALSE;
//
// Parse the hob list from fsp
// Report all the resource hob except the memory between 1M and 4G
//
Hob.Raw = (UINT8 *)(UINTN)FspHobList;
DEBUG((DEBUG_INFO, "FspHobList - 0x%x\n", FspHobList));
while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, Hob.Raw)) != NULL) {
DEBUG((DEBUG_INFO, "\nResourceType: 0x%x\n", Hob.ResourceDescriptor->ResourceType));
if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) ||
(Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_RESERVED)) {
DEBUG((DEBUG_INFO, "ResourceAttribute: 0x%x\n", Hob.ResourceDescriptor->ResourceAttribute));
DEBUG((DEBUG_INFO, "PhysicalStart: 0x%x\n", Hob.ResourceDescriptor->PhysicalStart));
DEBUG((DEBUG_INFO, "ResourceLength: 0x%x\n", Hob.ResourceDescriptor->ResourceLength));
DEBUG((DEBUG_INFO, "Owner: %g\n\n", &Hob.ResourceDescriptor->Owner));
}
if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) // Found the low memory length below 4G
&& (Hob.ResourceDescriptor->PhysicalStart >= BASE_1MB)
&& (Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength <= BASE_4GB)) {
LowMemorySize += Hob.ResourceDescriptor->ResourceLength;
Hob.Raw = GET_NEXT_HOB (Hob);
continue;
}
if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_RESERVED) // Found the low memory length below 4G
&& (Hob.ResourceDescriptor->PhysicalStart >= BASE_1MB)
&& (Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength <= BASE_4GB)
&& (CompareGuid (&Hob.ResourceDescriptor->Owner, &gFspReservedMemoryResourceHobGuid))) {
FoundFspMemHob = TRUE;
FspMemoryBase = Hob.ResourceDescriptor->PhysicalStart;
FspMemorySize = Hob.ResourceDescriptor->ResourceLength;
DEBUG((DEBUG_INFO, "Find fsp mem hob, base 0x%x, len 0x%x\n", FspMemoryBase, FspMemorySize));
}
//
// Report the resource hob
//
BuildResourceDescriptorHob (
Hob.ResourceDescriptor->ResourceType,
Hob.ResourceDescriptor->ResourceAttribute,
Hob.ResourceDescriptor->PhysicalStart,
Hob.ResourceDescriptor->ResourceLength
);
Hob.Raw = GET_NEXT_HOB (Hob);
}
if (!FoundFspMemHob) {
DEBUG((DEBUG_INFO, "Didn't find the fsp used memory information.\n"));
//ASSERT(FALSE);
}
DEBUG((DEBUG_INFO, "LowMemorySize: 0x%x.\n", LowMemorySize));
DEBUG((DEBUG_INFO, "FspMemoryBase: 0x%x.\n", FspMemoryBase));
DEBUG((DEBUG_INFO, "FspMemorySize: 0x%x.\n", FspMemorySize));
if (BootMode == BOOT_ON_S3_RESUME) {
BuildResourceDescriptorHob (
EFI_RESOURCE_SYSTEM_MEMORY,
(
EFI_RESOURCE_ATTRIBUTE_PRESENT |
EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
// EFI_RESOURCE_ATTRIBUTE_TESTED |
EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
),
BASE_1MB,
LowMemorySize
);
Status = GetS3MemoryInfo (&S3PeiMemBase, &S3PeiMemSize);
ASSERT_EFI_ERROR (Status);
DEBUG((DEBUG_INFO, "S3 memory %Xh - %Xh bytes\n", S3PeiMemBase, S3PeiMemSize));
//
// Make sure Stack and PeiMemory are not overlap - JYAO1
//
Status = PeiServicesInstallPeiMemory (
S3PeiMemBase,
S3PeiMemSize
);
ASSERT_EFI_ERROR (Status);
} else {
PeiMemSize = GetPeiMemSize (PeiServices, BootMode);
DEBUG((DEBUG_INFO, "PEI memory size = %Xh bytes\n", PeiMemSize));
//
// Capsule mode
//
Capsule = NULL;
CapsuleBuffer = NULL;
CapsuleBufferLength = 0;
if (BootMode == BOOT_ON_FLASH_UPDATE) {
Status = PeiServicesLocatePpi (
&gPeiCapsulePpiGuid,
0,
NULL,
(VOID **) &Capsule
);
ASSERT_EFI_ERROR (Status);
if (Status == EFI_SUCCESS) {
//
// Make sure Stack and CapsuleBuffer are not overlap - JYAO1
//
CapsuleBuffer = (VOID *)(UINTN)BASE_1MB;
CapsuleBufferLength = (UINTN)(LowMemorySize - PeiMemSize);
//
// Call the Capsule PPI Coalesce function to coalesce the capsule data.
//
Status = Capsule->Coalesce (PeiServices, &CapsuleBuffer, &CapsuleBufferLength);
}
}
RequiredMemSize = RetrieveRequiredMemorySize (PeiServices);
DEBUG((DEBUG_INFO, "Required memory size = %Xh bytes\n", RequiredMemSize));
//
// Report the main memory
//
BuildResourceDescriptorHob (
EFI_RESOURCE_SYSTEM_MEMORY,
(
EFI_RESOURCE_ATTRIBUTE_PRESENT |
EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
EFI_RESOURCE_ATTRIBUTE_TESTED |
EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
),
BASE_1MB,
LowMemorySize
);
//
// Make sure Stack and CapsuleBuffer are not overlap - JYAO1
//
//
// Install efi memory
//
PeiMemBase = BASE_1MB + LowMemorySize - PeiMemSize;
Status = PeiServicesInstallPeiMemory (
PeiMemBase,
PeiMemSize - RequiredMemSize
);
ASSERT_EFI_ERROR (Status);
if (Capsule != NULL) {
Status = Capsule->CreateState (PeiServices, CapsuleBuffer, CapsuleBufferLength);
}
}
//
// NV Storage Hob
//
return EFI_SUCCESS;
}

View File

@@ -0,0 +1,75 @@
## @file
# Sample to provide FSP hob process related function.
#
# Copyright (c) 2014, 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 Section - statements that will be processed to create a Makefile.
#
################################################################################
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = PeiFspHobProcessLibSample
FILE_GUID = C7B7070B-E5A8-4b86-9110-BDCA1095F496
MODULE_TYPE = SEC
VERSION_STRING = 1.0
LIBRARY_CLASS = FspHobProcessLib
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64
#
################################################################################
#
# Sources Section - list of files that are required for the build to succeed.
#
################################################################################
[Sources]
FspHobProcessLibSample.c
################################################################################
#
# Package Dependency Section - list of Package files that are required for
# this module.
#
################################################################################
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
IntelFspPkg/IntelFspPkg.dec
IntelFspWrapperPkg/IntelFspWrapperPkg.dec
[LibraryClasses]
BaseLib
BaseMemoryLib
HobLib
DebugLib
FspPlatformInfoLib
PeiServicesLib
PeiServicesTablePointerLib
[Pcd]
gFspWrapperTokenSpaceGuid.PcdPeiMinMemSize
gFspWrapperTokenSpaceGuid.PcdPeiRecoveryMinMemSize
[Guids]
gFspReservedMemoryResourceHobGuid
gEfiMemoryTypeInformationGuid
[Ppis]
gPeiCapsulePpiGuid

View File

@@ -0,0 +1,151 @@
/** @file
Sample to provide FSP wrapper platform sec related function.
Copyright (c) 2014, 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 <PiPei.h>
#include <Ppi/SecPlatformInformation.h>
#include <Ppi/SecPerformance.h>
#include <Ppi/TemporaryRamSupport.h>
#include <Library/LocalApicLib.h>
/**
This interface conveys state information out of the Security (SEC) phase into PEI.
@param[in] PeiServices Pointer to the PEI Services Table.
@param[in,out] StructureSize Pointer to the variable describing size of the input buffer.
@param[out] PlatformInformationRecord Pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD.
@retval EFI_SUCCESS The data was successfully returned.
@retval EFI_BUFFER_TOO_SMALL The buffer was too small.
**/
EFI_STATUS
EFIAPI
SecPlatformInformation (
IN CONST EFI_PEI_SERVICES **PeiServices,
IN OUT UINT64 *StructureSize,
OUT EFI_SEC_PLATFORM_INFORMATION_RECORD *PlatformInformationRecord
);
/**
This interface conveys performance information out of the Security (SEC) phase into PEI.
This service is published by the SEC phase. The SEC phase handoff has an optional
EFI_PEI_PPI_DESCRIPTOR list as its final argument when control is passed from SEC into the
PEI Foundation. As such, if the platform supports collecting performance data in SEC,
this information is encapsulated into the data structure abstracted by this service.
This information is collected for the boot-strap processor (BSP) on IA-32.
@param[in] PeiServices The pointer to the PEI Services Table.
@param[in] This The pointer to this instance of the PEI_SEC_PERFORMANCE_PPI.
@param[out] Performance The pointer to performance data collected in SEC phase.
@retval EFI_SUCCESS The data was successfully returned.
**/
EFI_STATUS
EFIAPI
SecGetPerformance (
IN CONST EFI_PEI_SERVICES **PeiServices,
IN PEI_SEC_PERFORMANCE_PPI *This,
OUT FIRMWARE_SEC_PERFORMANCE *Performance
);
/**
This service of the TEMPORARY_RAM_SUPPORT_PPI that migrates temporary RAM into
permanent memory.
@param[in] PeiServices Pointer to the PEI Services Table.
@param[in] TemporaryMemoryBase Source Address in temporary memory from which the SEC or PEIM will copy the
Temporary RAM contents.
@param[in] PermanentMemoryBase Destination Address in permanent memory into which the SEC or PEIM will copy the
Temporary RAM contents.
@param[in] CopySize Amount of memory to migrate from temporary to permanent memory.
@retval EFI_SUCCESS The data was successfully returned.
@retval EFI_INVALID_PARAMETER PermanentMemoryBase + CopySize > TemporaryMemoryBase when
TemporaryMemoryBase > PermanentMemoryBase.
**/
EFI_STATUS
EFIAPI
SecTemporaryRamSupport (
IN CONST EFI_PEI_SERVICES **PeiServices,
IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,
IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,
IN UINTN CopySize
);
EFI_SEC_PLATFORM_INFORMATION_PPI mSecPlatformInformationPpi = {
SecPlatformInformation
};
PEI_SEC_PERFORMANCE_PPI mSecPerformancePpi = {
SecGetPerformance
};
EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI gSecTemporaryRamSupportPpi = {
SecTemporaryRamSupport
};
EFI_PEI_PPI_DESCRIPTOR mPeiSecPlatformPpi[] = {
{
EFI_PEI_PPI_DESCRIPTOR_PPI,
&gEfiSecPlatformInformationPpiGuid,
&mSecPlatformInformationPpi
},
{
EFI_PEI_PPI_DESCRIPTOR_PPI,
&gPeiSecPerformancePpiGuid,
&mSecPerformancePpi
},
{
EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
&gEfiTemporaryRamSupportPpiGuid,
&gSecTemporaryRamSupportPpi
},
};
/**
A developer supplied function to perform platform specific operations.
It's a developer supplied function to perform any operations appropriate to a
given platform. It's invoked just before passing control to PEI core by SEC
core. Platform developer may modify the SecCoreData passed to PEI Core.
It returns a platform specific PPI list that platform wishes to pass to PEI core.
The Generic SEC core module will merge this list to join the final list passed to
PEI core.
@param[in,out] SecCoreData The same parameter as passing to PEI core. It
could be overridden by this function.
@return The platform specific PPI list to be passed to PEI core or
NULL if there is no need of such platform specific PPI list.
**/
EFI_PEI_PPI_DESCRIPTOR *
EFIAPI
SecPlatformMain (
IN OUT EFI_SEC_PEI_HAND_OFF *SecCoreData
)
{
EFI_PEI_PPI_DESCRIPTOR *PpiList;
InitializeApicTimer (0, (UINT32) -1, TRUE, 5);
PpiList = &mPeiSecPlatformPpi[0];
return PpiList;
}

View File

@@ -0,0 +1,43 @@
#------------------------------------------------------------------------------
#
# Copyright (c) 2014, 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:
#
# AsmSaveSecContext.S
#
# Abstract:
#
# Save Sec Conext before call FspInit API
#
#------------------------------------------------------------------------------
#----------------------------------------------------------------------------
# MMX Usage:
# MM0 = BIST State
# MM5 = Save time-stamp counter value high32bit
# MM6 = Save time-stamp counter value low32bit.
#
# It should be same as SecEntry.asm and PeiCoreEntry.asm.
#----------------------------------------------------------------------------
ASM_GLOBAL ASM_PFX(AsmSaveBistValue)
ASM_PFX(AsmSaveBistValue):
movl 4(%esp), %eax
movd %eax, %mm0
ret
ASM_GLOBAL ASM_PFX(AsmSaveTickerValue)
ASM_PFX(AsmSaveTickerValue):
movl 4(%esp), %eax
movd %eax, %mm6
movl 8(%esp), %eax
movd %eax, %mm5
ret

View File

@@ -0,0 +1,50 @@
;------------------------------------------------------------------------------
;
; Copyright (c) 2014, 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:
;
; AsmSaveSecContext.asm
;
; Abstract:
;
; Save Sec Conext before call FspInit API
;
;------------------------------------------------------------------------------
.686p
.xmm
.model flat,c
.code
;----------------------------------------------------------------------------
; MMX Usage:
; MM0 = BIST State
; MM5 = Save time-stamp counter value high32bit
; MM6 = Save time-stamp counter value low32bit.
;
; It should be same as SecEntry.asm and PeiCoreEntry.asm.
;----------------------------------------------------------------------------
AsmSaveBistValue PROC PUBLIC
mov eax, [esp+4]
movd mm0, eax
ret
AsmSaveBistValue ENDP
AsmSaveTickerValue PROC PUBLIC
mov eax, [esp+4]
movd mm6, eax
mov eax, [esp+8]
movd mm5, eax
ret
AsmSaveTickerValue ENDP
END

View File

@@ -0,0 +1,43 @@
/** @file
Fsp related definitions
Copyright (c) 2014, 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.
**/
//
// Fv Header
//
#define FVH_SIGINATURE_OFFSET 0x28
#define FVH_SIGINATURE_VALID_VALUE 0x4856465F // valid signature:_FVH
#define FVH_HEADER_LENGTH_OFFSET 0x30
#define FVH_EXTHEADER_OFFSET_OFFSET 0x34
#define FVH_EXTHEADER_SIZE_OFFSET 0x10
//
// Ffs Header
//
#define FSP_HEADER_GUID_DWORD1 0x912740BE
#define FSP_HEADER_GUID_DWORD2 0x47342284
#define FSP_HEADER_GUID_DWORD3 0xB08471B9
#define FSP_HEADER_GUID_DWORD4 0x0C3F3527
#define FFS_HEADER_SIZE_VALUE 0x18
//
// Section Header
//
#define SECTION_HEADER_TYPE_OFFSET 0x03
#define RAW_SECTION_HEADER_SIZE_VALUE 0x04
//
// Fsp Header
//
#define FSP_HEADER_IMAGEBASE_OFFSET 0x1C
#define FSP_HEADER_TEMPRAMINIT_OFFSET 0x30

View File

@@ -0,0 +1,130 @@
#------------------------------------------------------------------------------
#
# Copyright (c) 2014, 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:
#
# PeiCoreEntry.S
#
# Abstract:
#
# Find and call SecStartup
#
#------------------------------------------------------------------------------
ASM_GLOBAL ASM_PFX(CallPeiCoreEntryPoint)
ASM_PFX(CallPeiCoreEntryPoint):
#
# Obtain the hob list pointer
#
movl 0x4(%esp), %eax
#
# Obtain the stack information
# ECX: start of range
# EDX: end of range
#
movl 0x8(%esp), %ecx
movl 0xC(%esp), %edx
#
# Platform init
#
pushal
pushl %edx
pushl %ecx
pushl %eax
call ASM_PFX(PlatformInit)
popl %eax
popl %eax
popl %eax
popal
#
# Set stack top pointer
#
movl %edx, %esp
#
# Push the hob list pointer
#
pushl %eax
#
# Save the value
# ECX: start of range
# EDX: end of range
#
movl %esp, %ebp
pushl %ecx
pushl %edx
#
# Push processor count to stack first, then BIST status (AP then BSP)
#
movl $1, %eax
cpuid
shr $16, %ebx
andl $0x000000FF, %ebx
cmp $1, %bl
jae PushProcessorCount
#
# Some processors report 0 logical processors. Effectively 0 = 1.
# So we fix up the processor count
#
inc %ebx
PushProcessorCount:
pushl %ebx
#
# We need to implement a long-term solution for BIST capture. For now, we just copy BSP BIST
# for all processor threads
#
xorl %ecx, %ecx
movb %bl, %cl
PushBist:
movd %mm0, %eax
pushl %eax
loop PushBist
# Save Time-Stamp Counter
movd %mm5, %eax
pushl %eax
movd %mm6, %eax
pushl %eax
#
# Pass entry point of the PEI core
#
movl $0xFFFFFFE0, %edi
pushl %ds:(%edi)
#
# Pass BFV into the PEI Core
#
movl $0xFFFFFFFC, %edi
pushl %ds:(%edi)
#
# Pass stack size into the PEI Core
#
movl -4(%ebp), %ecx
movl -8(%ebp), %edx
pushl %ecx # RamBase
subl %ecx, %edx
pushl %edx # RamSize
#
# Pass Control into the PEI Core
#
call ASM_PFX(SecStartup)

View File

@@ -0,0 +1,140 @@
;------------------------------------------------------------------------------
;
; Copyright (c) 2014, 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:
;
; PeiCoreEntry.asm
;
; Abstract:
;
; Find and call SecStartup
;
;------------------------------------------------------------------------------
.686p
.xmm
.model flat, c
.code
EXTRN SecStartup:NEAR
EXTRN PlatformInit:NEAR
CallPeiCoreEntryPoint PROC PUBLIC
;
; Obtain the hob list pointer
;
mov eax, [esp+4]
;
; Obtain the stack information
; ECX: start of range
; EDX: end of range
;
mov ecx, [esp+8]
mov edx, [esp+0Ch]
;
; Platform init
;
pushad
push edx
push ecx
push eax
call PlatformInit
pop eax
pop eax
pop eax
popad
;
; Set stack top pointer
;
mov esp, edx
;
; Push the hob list pointer
;
push eax
;
; Save the value
; ECX: start of range
; EDX: end of range
;
mov ebp, esp
push ecx
push edx
;
; Push processor count to stack first, then BIST status (AP then BSP)
;
mov eax, 1
cpuid
shr ebx, 16
and ebx, 0000000FFh
cmp bl, 1
jae PushProcessorCount
;
; Some processors report 0 logical processors. Effectively 0 = 1.
; So we fix up the processor count
;
inc ebx
PushProcessorCount:
push ebx
;
; We need to implement a long-term solution for BIST capture. For now, we just copy BSP BIST
; for all processor threads
;
xor ecx, ecx
mov cl, bl
PushBist:
movd eax, mm0
push eax
loop PushBist
; Save Time-Stamp Counter
movd eax, mm5
push eax
movd eax, mm6
push eax
;
; Pass entry point of the PEI core
;
mov edi, 0FFFFFFE0h
push DWORD PTR ds:[edi]
;
; Pass BFV into the PEI Core
;
mov edi, 0FFFFFFFCh
push DWORD PTR ds:[edi]
;
; Pass stack size into the PEI Core
;
mov ecx, [ebp - 4]
mov edx, [ebp - 8]
push ecx ; RamBase
sub edx, ecx
push edx ; RamSize
;
; Pass Control into the PEI Core
;
call SecStartup
CallPeiCoreEntryPoint ENDP
END

View File

@@ -0,0 +1,325 @@
#------------------------------------------------------------------------------
#
# Copyright (c) 2014, 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:
#
# SecEntry.S
#
# Abstract:
#
# This is the code that goes from real-mode to protected mode.
# It consumes the reset vector, calls TempRamInit API from FSP binary.
#
#------------------------------------------------------------------------------
#include "Fsp.h"
ASM_GLOBAL ASM_PFX(_TEXT_REALMODE)
ASM_PFX(_TEXT_REALMODE):
#----------------------------------------------------------------------------
#
# Procedure: _ModuleEntryPoint
#
# Input: None
#
# Output: None
#
# Destroys: Assume all registers
#
# Description:
#
# Transition to non-paged flat-model protected mode from a
# hard-coded GDT that provides exactly two descriptors.
# This is a bare bones transition to protected mode only
# used for a while in PEI and possibly DXE.
#
# After enabling protected mode, a far jump is executed to
# transfer to PEI using the newly loaded GDT.
#
# Return: None
#
# MMX Usage:
# MM0 = BIST State
# MM5 = Save time-stamp counter value high32bit
# MM6 = Save time-stamp counter value low32bit.
#
#----------------------------------------------------------------------------
.align 4
ASM_GLOBAL ASM_PFX(_ModuleEntryPoint)
ASM_PFX(_ModuleEntryPoint):
fninit # clear any pending Floating point exceptions
#
# Store the BIST value in mm0
#
movd %eax, %mm0
#
# Save time-stamp counter value
# rdtsc load 64bit time-stamp counter to EDX:EAX
#
rdtsc
movd %edx, %mm5
movd %ecx, %mm6
#
# Load the GDT table in GdtDesc
#
movl $GdtDesc, %esi
.byte 0x66
lgdt %cs:(%si)
#
# Transition to 16 bit protected mode
#
movl %cr0, %eax # Get control register 0
orl $0x00000003, %eax # Set PE bit (bit #0) & MP bit (bit #1)
movl %eax, %cr0 # Activate protected mode
movl %cr4, %eax # Get control register 4
orl $0x00000600, %eax # Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10)
movl %eax, %cr4
#
# Now we're in 16 bit protected mode
# Set up the selectors for 32 bit protected mode entry
#
movw SYS_DATA_SEL, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %fs
movw %ax, %gs
movw %ax, %ss
#
# Transition to Flat 32 bit protected mode
# The jump to a far pointer causes the transition to 32 bit mode
#
movl $ProtectedModeEntryLinearAddress, %esi
jmp *%cs:(%si)
ASM_GLOBAL ASM_PFX(_TEXT_PROTECTED_MODE)
ASM_PFX(_TEXT_PROTECTED_MODE):
#----------------------------------------------------------------------------
#
# Procedure: ProtectedModeEntryPoint
#
# Input: None
#
# Output: None
#
# Destroys: Assume all registers
#
# Description:
#
# This function handles:
# Call two basic APIs from FSP binary
# Initializes stack with some early data (BIST, PEI entry, etc)
#
# Return: None
#
#----------------------------------------------------------------------------
.align 4
ASM_GLOBAL ASM_PFX(ProtectedModeEntryPoint)
ASM_PFX(ProtectedModeEntryPoint):
# Find the fsp info header
movl PcdGet32 (PcdFlashFvFspBase), %edi
movl PcdGet32 (PcdFlashFvFspSize), %ecx
movl FVH_SIGINATURE_OFFSET(%edi), %eax
cmp $FVH_SIGINATURE_VALID_VALUE, %eax
jnz FspHeaderNotFound
xorl %eax, %eax
movw FVH_EXTHEADER_OFFSET_OFFSET(%edi), %ax
cmp %ax, 0
jnz FspFvExtHeaderExist
xorl %eax, %eax
movw FVH_HEADER_LENGTH_OFFSET(%edi), %ax # Bypass Fv Header
addl %eax, %edi
jmp FspCheckFfsHeader
FspFvExtHeaderExist:
addl %eax, %edi
movl FVH_EXTHEADER_SIZE_OFFSET(%edi), %eax # Bypass Ext Fv Header
addl %eax, %edi
# Round up to 8 byte alignment
movl %edi, %eax
andb $0x07, %al
jz FspCheckFfsHeader
and $0xFFFFFFF8, %edi
add $0x08, %edi
FspCheckFfsHeader:
# Check the ffs guid
movl (%edi), %eax
cmp $FSP_HEADER_GUID_DWORD1, %eax
jnz FspHeaderNotFound
movl 0x4(%edi), %eax
cmp $FSP_HEADER_GUID_DWORD2, %eax
jnz FspHeaderNotFound
movl 0x08(%edi), %eax
cmp $FSP_HEADER_GUID_DWORD3, %eax
jnz FspHeaderNotFound
movl 0x0c(%edi), %eax
cmp $FSP_HEADER_GUID_DWORD4, %eax
jnz FspHeaderNotFound
add $FFS_HEADER_SIZE_VALUE, %edi # Bypass the ffs header
# Check the section type as raw section
movb SECTION_HEADER_TYPE_OFFSET(%edi), %al
cmp $0x19, %al
jnz FspHeaderNotFound
addl $RAW_SECTION_HEADER_SIZE_VALUE, %edi # Bypass the section header
jmp FspHeaderFound
FspHeaderNotFound:
jmp .
FspHeaderFound:
# Get the fsp TempRamInit Api address
movl FSP_HEADER_IMAGEBASE_OFFSET(%edi), %eax
addl FSP_HEADER_TEMPRAMINIT_OFFSET(%edi), %eax
# Setup the hardcode stack
movl $TempRamInitStack, %esp
# Call the fsp TempRamInit Api
jmp *%eax
TempRamInitDone:
cmp $0x0, %eax
jnz FspApiFailed
# ECX: start of range
# EDX: end of range
movl %edx, %esp
pushl %edx
pushl %ecx
pushl %eax # zero - no hob list yet
call ASM_PFX(CallPeiCoreEntryPoint)
FspApiFailed:
jmp .
.align 0x10
TempRamInitStack:
.long TempRamInitDone
.long TempRamInitParams
#
# ROM-based Global-Descriptor Table for the Tiano PEI Phase
#
.align 16
#
# GDT[0]: 0x00: Null entry, never used.
#
.equ NULL_SEL, . - GDT_BASE # Selector [0]
GDT_BASE:
BootGdtTable: .long 0
.long 0
#
# Linear data segment descriptor
#
.equ LINEAR_SEL, . - GDT_BASE # Selector [0x8]
.word 0xFFFF # limit 0xFFFFF
.word 0 # base 0
.byte 0
.byte 0x92 # present, ring 0, data, expand-up, writable
.byte 0xCF # page-granular, 32-bit
.byte 0
#
# Linear code segment descriptor
#
.equ LINEAR_CODE_SEL, . - GDT_BASE # Selector [0x10]
.word 0xFFFF # limit 0xFFFFF
.word 0 # base 0
.byte 0
.byte 0x9B # present, ring 0, data, expand-up, not-writable
.byte 0xCF # page-granular, 32-bit
.byte 0
#
# System data segment descriptor
#
.equ SYS_DATA_SEL, . - GDT_BASE # Selector [0x18]
.word 0xFFFF # limit 0xFFFFF
.word 0 # base 0
.byte 0
.byte 0x93 # present, ring 0, data, expand-up, not-writable
.byte 0xCF # page-granular, 32-bit
.byte 0
#
# System code segment descriptor
#
.equ SYS_CODE_SEL, . - GDT_BASE # Selector [0x20]
.word 0xFFFF # limit 0xFFFFF
.word 0 # base 0
.byte 0
.byte 0x9A # present, ring 0, data, expand-up, writable
.byte 0xCF # page-granular, 32-bit
.byte 0
#
# Spare segment descriptor
#
.equ SYS16_CODE_SEL, . - GDT_BASE # Selector [0x28]
.word 0xFFFF # limit 0xFFFFF
.word 0 # base 0
.byte 0x0E # Changed from F000 to E000.
.byte 0x9B # present, ring 0, code, expand-up, writable
.byte 0x00 # byte-granular, 16-bit
.byte 0
#
# Spare segment descriptor
#
.equ SYS16_DATA_SEL, . - GDT_BASE # Selector [0x30]
.word 0xFFFF # limit 0xFFFF
.word 0 # base 0
.byte 0
.byte 0x93 # present, ring 0, data, expand-up, not-writable
.byte 0x00 # byte-granular, 16-bit
.byte 0
#
# Spare segment descriptor
#
.equ SPARE5_SEL, . - GDT_BASE # Selector [0x38]
.word 0 # limit 0
.word 0 # base 0
.byte 0
.byte 0 # present, ring 0, data, expand-up, writable
.byte 0 # page-granular, 32-bit
.byte 0
.equ GDT_SIZE, . - BootGdtTable # Size, in bytes
#
# GDT Descriptor
#
GdtDesc: # GDT descriptor
.word GDT_SIZE - 1 # GDT limit
.long BootGdtTable # GDT base address
ASM_PFX(ProtectedModeEntryLinearAddress):
ProtectedModeEntryLinearOffset:
.long ProtectedModeEntryPoint # Offset of our 32 bit code
.word LINEAR_CODE_SEL

View File

@@ -0,0 +1,345 @@
;------------------------------------------------------------------------------
;
; Copyright (c) 2014, 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:
;
; SecEntry.asm
;
; Abstract:
;
; This is the code that goes from real-mode to protected mode.
; It consumes the reset vector, calls TempRamInit API from FSP binary.
;
;------------------------------------------------------------------------------
#include "Fsp.h"
.686p
.xmm
.model small, c
EXTRN CallPeiCoreEntryPoint:NEAR
EXTRN TempRamInitParams:FAR
; Pcds
EXTRN PcdGet32 (PcdFlashFvFspBase):DWORD
EXTRN PcdGet32 (PcdFlashFvFspSize):DWORD
_TEXT_REALMODE SEGMENT PARA PUBLIC USE16 'CODE'
ASSUME CS:_TEXT_REALMODE, DS:_TEXT_REALMODE
;----------------------------------------------------------------------------
;
; Procedure: _ModuleEntryPoint
;
; Input: None
;
; Output: None
;
; Destroys: Assume all registers
;
; Description:
;
; Transition to non-paged flat-model protected mode from a
; hard-coded GDT that provides exactly two descriptors.
; This is a bare bones transition to protected mode only
; used for a while in PEI and possibly DXE.
;
; After enabling protected mode, a far jump is executed to
; transfer to PEI using the newly loaded GDT.
;
; Return: None
;
; MMX Usage:
; MM0 = BIST State
; MM5 = Save time-stamp counter value high32bit
; MM6 = Save time-stamp counter value low32bit.
;
;----------------------------------------------------------------------------
align 4
_ModuleEntryPoint PROC NEAR C PUBLIC
fninit ; clear any pending Floating point exceptions
;
; Store the BIST value in mm0
;
movd mm0, eax
;
; Save time-stamp counter value
; rdtsc load 64bit time-stamp counter to EDX:EAX
;
rdtsc
movd mm5, edx
movd mm6, eax
;
; Load the GDT table in GdtDesc
;
mov esi, OFFSET GdtDesc
DB 66h
lgdt fword ptr cs:[si]
;
; Transition to 16 bit protected mode
;
mov eax, cr0 ; Get control register 0
or eax, 00000003h ; Set PE bit (bit #0) & MP bit (bit #1)
mov cr0, eax ; Activate protected mode
mov eax, cr4 ; Get control register 4
or eax, 00000600h ; Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10)
mov cr4, eax
;
; Now we're in 16 bit protected mode
; Set up the selectors for 32 bit protected mode entry
;
mov ax, SYS_DATA_SEL
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
;
; Transition to Flat 32 bit protected mode
; The jump to a far pointer causes the transition to 32 bit mode
;
mov esi, offset ProtectedModeEntryLinearAddress
jmp fword ptr cs:[si]
_ModuleEntryPoint ENDP
_TEXT_REALMODE ENDS
_TEXT_PROTECTED_MODE SEGMENT PARA PUBLIC USE32 'CODE'
ASSUME CS:_TEXT_PROTECTED_MODE, DS:_TEXT_PROTECTED_MODE
;----------------------------------------------------------------------------
;
; Procedure: ProtectedModeEntryPoint
;
; Input: None
;
; Output: None
;
; Destroys: Assume all registers
;
; Description:
;
; This function handles:
; Call two basic APIs from FSP binary
; Initializes stack with some early data (BIST, PEI entry, etc)
;
; Return: None
;
;----------------------------------------------------------------------------
align 4
ProtectedModeEntryPoint PROC NEAR PUBLIC
; Find the fsp info header
mov edi, PcdGet32 (PcdFlashFvFspBase)
mov ecx, PcdGet32 (PcdFlashFvFspSize)
mov eax, dword ptr [edi + FVH_SIGINATURE_OFFSET]
cmp eax, FVH_SIGINATURE_VALID_VALUE
jnz FspHeaderNotFound
xor eax, eax
mov ax, word ptr [edi + FVH_EXTHEADER_OFFSET_OFFSET]
cmp ax, 0
jnz FspFvExtHeaderExist
xor eax, eax
mov ax, word ptr [edi + FVH_HEADER_LENGTH_OFFSET] ; Bypass Fv Header
add edi, eax
jmp FspCheckFfsHeader
FspFvExtHeaderExist:
add edi, eax
mov eax, dword ptr [edi + FVH_EXTHEADER_SIZE_OFFSET] ; Bypass Ext Fv Header
add edi, eax
; Round up to 8 byte alignment
mov eax, edi
and al, 07h
jz FspCheckFfsHeader
and edi, 0FFFFFFF8h
add edi, 08h
FspCheckFfsHeader:
; Check the ffs guid
mov eax, dword ptr [edi]
cmp eax, FSP_HEADER_GUID_DWORD1
jnz FspHeaderNotFound
mov eax, dword ptr [edi + 4]
cmp eax, FSP_HEADER_GUID_DWORD2
jnz FspHeaderNotFound
mov eax, dword ptr [edi + 8]
cmp eax, FSP_HEADER_GUID_DWORD3
jnz FspHeaderNotFound
mov eax, dword ptr [edi + 0Ch]
cmp eax, FSP_HEADER_GUID_DWORD4
jnz FspHeaderNotFound
add edi, FFS_HEADER_SIZE_VALUE ; Bypass the ffs header
; Check the section type as raw section
mov al, byte ptr [edi + SECTION_HEADER_TYPE_OFFSET]
cmp al, 019h
jnz FspHeaderNotFound
add edi, RAW_SECTION_HEADER_SIZE_VALUE ; Bypass the section header
jmp FspHeaderFound
FspHeaderNotFound:
jmp $
FspHeaderFound:
; Get the fsp TempRamInit Api address
mov eax, dword ptr [edi + FSP_HEADER_IMAGEBASE_OFFSET]
add eax, dword ptr [edi + FSP_HEADER_TEMPRAMINIT_OFFSET]
; Setup the hardcode stack
mov esp, OFFSET TempRamInitStack
; Call the fsp TempRamInit Api
jmp eax
TempRamInitDone:
cmp eax, 0
jnz FspApiFailed
; ECX: start of range
; EDX: end of range
mov esp, edx
push edx
push ecx
push eax ; zero - no hob list yet
call CallPeiCoreEntryPoint
FspApiFailed:
jmp $
align 10h
TempRamInitStack:
DD OFFSET TempRamInitDone
DD OFFSET TempRamInitParams
ProtectedModeEntryPoint ENDP
;
; ROM-based Global-Descriptor Table for the Tiano PEI Phase
;
align 16
PUBLIC BootGdtTable
;
; GDT[0]: 0x00: Null entry, never used.
;
NULL_SEL EQU $ - GDT_BASE ; Selector [0]
GDT_BASE:
BootGdtTable DD 0
DD 0
;
; Linear data segment descriptor
;
LINEAR_SEL EQU $ - GDT_BASE ; Selector [0x8]
DW 0FFFFh ; limit 0xFFFFF
DW 0 ; base 0
DB 0
DB 092h ; present, ring 0, data, expand-up, writable
DB 0CFh ; page-granular, 32-bit
DB 0
;
; Linear code segment descriptor
;
LINEAR_CODE_SEL EQU $ - GDT_BASE ; Selector [0x10]
DW 0FFFFh ; limit 0xFFFFF
DW 0 ; base 0
DB 0
DB 09Bh ; present, ring 0, data, expand-up, not-writable
DB 0CFh ; page-granular, 32-bit
DB 0
;
; System data segment descriptor
;
SYS_DATA_SEL EQU $ - GDT_BASE ; Selector [0x18]
DW 0FFFFh ; limit 0xFFFFF
DW 0 ; base 0
DB 0
DB 093h ; present, ring 0, data, expand-up, not-writable
DB 0CFh ; page-granular, 32-bit
DB 0
;
; System code segment descriptor
;
SYS_CODE_SEL EQU $ - GDT_BASE ; Selector [0x20]
DW 0FFFFh ; limit 0xFFFFF
DW 0 ; base 0
DB 0
DB 09Ah ; present, ring 0, data, expand-up, writable
DB 0CFh ; page-granular, 32-bit
DB 0
;
; Spare segment descriptor
;
SYS16_CODE_SEL EQU $ - GDT_BASE ; Selector [0x28]
DW 0FFFFh ; limit 0xFFFFF
DW 0 ; base 0
DB 0Eh ; Changed from F000 to E000.
DB 09Bh ; present, ring 0, code, expand-up, writable
DB 00h ; byte-granular, 16-bit
DB 0
;
; Spare segment descriptor
;
SYS16_DATA_SEL EQU $ - GDT_BASE ; Selector [0x30]
DW 0FFFFh ; limit 0xFFFF
DW 0 ; base 0
DB 0
DB 093h ; present, ring 0, data, expand-up, not-writable
DB 00h ; byte-granular, 16-bit
DB 0
;
; Spare segment descriptor
;
SPARE5_SEL EQU $ - GDT_BASE ; Selector [0x38]
DW 0 ; limit 0
DW 0 ; base 0
DB 0
DB 0 ; present, ring 0, data, expand-up, writable
DB 0 ; page-granular, 32-bit
DB 0
GDT_SIZE EQU $ - BootGdtTable ; Size, in bytes
;
; GDT Descriptor
;
GdtDesc: ; GDT descriptor
DW GDT_SIZE - 1 ; GDT limit
DD OFFSET BootGdtTable ; GDT base address
ProtectedModeEntryLinearAddress LABEL FWORD
ProtectedModeEntryLinearOffset LABEL DWORD
DD OFFSET ProtectedModeEntryPoint ; Offset of our 32 bit code
DW LINEAR_CODE_SEL
_TEXT_PROTECTED_MODE ENDS
END

View File

@@ -0,0 +1,77 @@
#------------------------------------------------------------------------------
#
# Copyright (c) 2014, 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.
#
# Abstract:
#
# Switch the stack from temporary memory to permenent memory.
#
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
# VOID
# EFIAPI
# SecSwitchStack (
# UINT32 TemporaryMemoryBase,
# UINT32 PermenentMemoryBase
# )#
#------------------------------------------------------------------------------
ASM_GLOBAL ASM_PFX (SecSwitchStack)
ASM_PFX(SecSwitchStack):
#
# Save standard registers so they can be used to change stack
#
pushl %eax
pushl %ebx
pushl %ecx
pushl %edx
#
# !!CAUTION!! this function address's is pushed into stack after
# migration of whole temporary memory, so need save it to permenent
# memory at first!
#
movl 20(%esp), %ebx # Save the first parameter
movl 24(%esp), %ecx # Save the second parameter
#
# Save this function's return address into permenent memory at first.
# Then, Fixup the esp point to permenent memory
#
movl %esp, %eax
subl %ebx, %eax
addl %ecx, %eax
movl 0(%esp), %edx # copy pushed register's value to permenent memory
movl %edx, 0(%eax)
movl 4(%esp), %edx
movl %edx, 4(%eax)
movl 8(%esp), %edx
movl %edx, 8(%eax)
movl 12(%esp), %edx
movl %edx, 12(%eax)
movl 16(%esp), %edx # Update this function's return address into permenent memory
movl %edx, 16(%eax)
movl %eax, %esp # From now, esp is pointed to permenent memory
#
# Fixup the ebp point to permenent memory
#
movl %ebp, %eax
subl %ebx, %eax
addl %ecx, %eax
movl %eax, %ebp # From now, ebp is pointed to permenent memory
popl %edx
popl %ecx
popl %ebx
popl %eax
ret

View File

@@ -0,0 +1,82 @@
;------------------------------------------------------------------------------
;
; Copyright (c) 2014, 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.
;
; Abstract:
;
; Switch the stack from temporary memory to permenent memory.
;
;------------------------------------------------------------------------------
.586p
.model flat,C
.code
;------------------------------------------------------------------------------
; VOID
; EFIAPI
; SecSwitchStack (
; UINT32 TemporaryMemoryBase,
; UINT32 PermenentMemoryBase
; );
;------------------------------------------------------------------------------
SecSwitchStack PROC
;
; Save three register: eax, ebx, ecx
;
push eax
push ebx
push ecx
push edx
;
; !!CAUTION!! this function address's is pushed into stack after
; migration of whole temporary memory, so need save it to permenent
; memory at first!
;
mov ebx, [esp + 20] ; Save the first parameter
mov ecx, [esp + 24] ; Save the second parameter
;
; Save this function's return address into permenent memory at first.
; Then, Fixup the esp point to permenent memory
;
mov eax, esp
sub eax, ebx
add eax, ecx
mov edx, dword ptr [esp] ; copy pushed register's value to permenent memory
mov dword ptr [eax], edx
mov edx, dword ptr [esp + 4]
mov dword ptr [eax + 4], edx
mov edx, dword ptr [esp + 8]
mov dword ptr [eax + 8], edx
mov edx, dword ptr [esp + 12]
mov dword ptr [eax + 12], edx
mov edx, dword ptr [esp + 16] ; Update this function's return address into permenent memory
mov dword ptr [eax + 16], edx
mov esp, eax ; From now, esp is pointed to permenent memory
;
; Fixup the ebp point to permenent memory
;
mov eax, ebp
sub eax, ebx
add eax, ecx
mov ebp, eax ; From now, ebp is pointed to permenent memory
pop edx
pop ecx
pop ebx
pop eax
ret
SecSwitchStack ENDP
END

View File

@@ -0,0 +1,43 @@
/** @file
Sample to provide platform init function.
Copyright (c) 2014, 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 <PiPei.h>
#include <Library/DebugLib.h>
/**
Platform initialization.
@param[in] FspHobList HobList produced by FSP.
@param[in] StartOfRange Start of temporary RAM.
@param[in] EndOfRange End of temporary RAM.
**/
VOID
EFIAPI
PlatformInit (
IN VOID *FspHobList,
IN VOID *StartOfRange,
IN VOID *EndOfRange
)
{
//
// Platform initialization
// Enable Serial port here
//
DEBUG ((DEBUG_INFO, "PrintPeiCoreEntryPointParam\n"));
DEBUG ((DEBUG_INFO, "FspHobList - 0x%x\n", FspHobList));
DEBUG ((DEBUG_INFO, "StartOfRange - 0x%x\n", StartOfRange));
DEBUG ((DEBUG_INFO, "EndOfRange - 0x%x\n", EndOfRange));
}

View File

@@ -0,0 +1,111 @@
/** @file
Sample to provide SaveSecContext function.
Copyright (c) 2014, 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 <PiPei.h>
#include <Library/DebugLib.h>
#include <Ppi/TopOfTemporaryRam.h>
#include <Ppi/SecPlatformInformation.h>
/**
Save BIST value before call FspInit.
@param[in] Bist BIST value.
**/
VOID
AsmSaveBistValue (
IN UINT32 Bist
);
/**
Save Ticker value before call FspInit.
@param[in] Ticker Ticker value.
**/
VOID
AsmSaveTickerValue (
IN UINT64 Ticker
);
/**
Save SEC context before call FspInit.
@param[in] PeiServices Pointer to PEI Services Table.
**/
VOID
EFIAPI
SaveSecContext (
IN CONST EFI_PEI_SERVICES **PeiServices
)
{
UINT32 *Bist;
UINT64 *Ticker;
UINT32 Size;
UINT32 Count;
UINT32 TopOfTemporaryRam;
VOID *TopOfTemporaryRamPpi;
EFI_STATUS Status;
DEBUG ((DEBUG_INFO, "SaveSecContext - 0x%x\n", PeiServices));
Status = (*PeiServices)->LocatePpi (
PeiServices,
&gTopOfTemporaryRamPpiGuid,
0,
NULL,
(VOID **) &TopOfTemporaryRamPpi
);
if (EFI_ERROR (Status)) {
return ;
}
DEBUG ((DEBUG_INFO, "TopOfTemporaryRamPpi - 0x%x\n", TopOfTemporaryRamPpi));
//
// The entries of BIST information, together with the number of them,
// reside in the bottom of stack, left untouched by normal stack operation.
// This routine copies the BIST information to the buffer pointed by
// PlatformInformationRecord for output.
//
// |--------------| <- TopOfTemporaryRam
// |Number of BSPs|
// |--------------|
// | BIST |
// |--------------|
// | .... |
// |--------------|
// | TSC[63:32] |
// |--------------|
// | TSC[31:00] |
// |--------------|
//
TopOfTemporaryRam = (UINT32)(UINTN)TopOfTemporaryRamPpi - sizeof(UINT32);
TopOfTemporaryRam -= sizeof(UINT32) * 2;
DEBUG ((DEBUG_INFO, "TopOfTemporaryRam - 0x%x\n", TopOfTemporaryRam));
Count = *(UINT32 *)(UINTN)(TopOfTemporaryRam - sizeof(UINT32));
DEBUG ((DEBUG_INFO, "Count - 0x%x\n", Count));
Size = Count * sizeof (IA32_HANDOFF_STATUS);
DEBUG ((DEBUG_INFO, "Size - 0x%x\n", Size));
Bist = (UINT32 *)(UINTN)(TopOfTemporaryRam - sizeof(UINT32) - Size);
DEBUG ((DEBUG_INFO, "Bist - 0x%x\n", *Bist));
Ticker = (UINT64 *)(UINTN)(TopOfTemporaryRam - sizeof(UINT32) - Size - sizeof(UINT64));
DEBUG ((DEBUG_INFO, "Ticker - 0x%lx\n", *Ticker));
// Just need record BSP
AsmSaveBistValue (*Bist);
AsmSaveTickerValue (*Ticker);
}

View File

@@ -0,0 +1,90 @@
/** @file
Sample to provide SecGetPerformance function.
Copyright (c) 2014, 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 <PiPei.h>
#include <Ppi/SecPerformance.h>
#include <Ppi/TopOfTemporaryRam.h>
#include <Library/BaseMemoryLib.h>
#include <Library/TimerLib.h>
#include <Library/DebugLib.h>
/**
This interface conveys performance information out of the Security (SEC) phase into PEI.
This service is published by the SEC phase. The SEC phase handoff has an optional
EFI_PEI_PPI_DESCRIPTOR list as its final argument when control is passed from SEC into the
PEI Foundation. As such, if the platform supports collecting performance data in SEC,
this information is encapsulated into the data structure abstracted by this service.
This information is collected for the boot-strap processor (BSP) on IA-32.
@param[in] PeiServices The pointer to the PEI Services Table.
@param[in] This The pointer to this instance of the PEI_SEC_PERFORMANCE_PPI.
@param[out] Performance The pointer to performance data collected in SEC phase.
@retval EFI_SUCCESS The data was successfully returned.
**/
EFI_STATUS
EFIAPI
SecGetPerformance (
IN CONST EFI_PEI_SERVICES **PeiServices,
IN PEI_SEC_PERFORMANCE_PPI *This,
OUT FIRMWARE_SEC_PERFORMANCE *Performance
)
{
UINT32 Size;
UINT32 Count;
UINT32 TopOfTemporaryRam;
UINT64 Ticker;
VOID *TopOfTemporaryRamPpi;
EFI_STATUS Status;
DEBUG ((DEBUG_INFO, "SecGetPerformance\n"));
Status = (*PeiServices)->LocatePpi (
PeiServices,
&gTopOfTemporaryRamPpiGuid,
0,
NULL,
(VOID **) &TopOfTemporaryRamPpi
);
if (EFI_ERROR (Status)) {
return EFI_NOT_FOUND;
}
//
// |--------------| <- TopOfTemporaryRam
// |Number of BSPs|
// |--------------|
// | BIST |
// |--------------|
// | .... |
// |--------------|
// | TSC[63:32] |
// |--------------|
// | TSC[31:00] |
// |--------------|
//
TopOfTemporaryRam = (UINT32)(UINTN)TopOfTemporaryRamPpi - sizeof(UINT32);
TopOfTemporaryRam -= sizeof(UINT32) * 2;
Count = *(UINT32 *) (UINTN) (TopOfTemporaryRam - sizeof (UINT32));
Size = Count * sizeof (UINT64);
Ticker = *(UINT64 *) (UINTN) (TopOfTemporaryRam - sizeof (UINT32) - Size - sizeof (UINT32) * 2);
Performance->ResetEnd = GetTimeInNanoSecond (Ticker);
return EFI_SUCCESS;
}

View File

@@ -0,0 +1,93 @@
## @file
# Sample to provide FSP wrapper platform sec related function.
#
# Copyright (c) 2014, 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 Section - statements that will be processed to create a Makefile.
#
################################################################################
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = SecPeiFspPlatformSecLibSample
FILE_GUID = 4E1C4F95-90EA-47de-9ACC-B8920189A1F5
MODULE_TYPE = SEC
VERSION_STRING = 1.0
LIBRARY_CLASS = FspPlatformSecLib
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64
#
################################################################################
#
# Sources Section - list of files that are required for the build to succeed.
#
################################################################################
[Sources]
FspPlatformSecLibSample.c
SecRamInitData.c
SaveSecContext.c
SecPlatformInformation.c
SecGetPerformance.c
SecTempRamSupport.c
PlatformInit.c
[Sources.IA32]
Ia32/SecEntry.asm
Ia32/PeiCoreEntry.asm
Ia32/AsmSaveSecContext.asm
Ia32/Stack.asm
Ia32/SecEntry.S
Ia32/PeiCoreEntry.S
Ia32/AsmSaveSecContext.S
Ia32/Stack.S
################################################################################
#
# Package Dependency Section - list of Package files that are required for
# this module.
#
################################################################################
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
UefiCpuPkg/UefiCpuPkg.dec
IntelFspPkg/IntelFspPkg.dec
IntelFspWrapperPkg/IntelFspWrapperPkg.dec
[LibraryClasses]
LocalApicLib
[Ppis]
gEfiSecPlatformInformationPpiGuid
gPeiSecPerformancePpiGuid
gEfiTemporaryRamSupportPpiGuid
[Pcd]
gFspWrapperTokenSpaceGuid.PcdPeiTemporaryRamStackSize
gFspWrapperTokenSpaceGuid.PcdFlashFvFspBase
gFspWrapperTokenSpaceGuid.PcdFlashFvFspSize
[FixedPcd]
gFspWrapperTokenSpaceGuid.PcdCpuMicrocodePatchAddress
gFspWrapperTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize
gFspWrapperTokenSpaceGuid.PcdFlashMicroCodeOffset
gFspWrapperTokenSpaceGuid.PcdFlashCodeCacheAddress
gFspWrapperTokenSpaceGuid.PcdFlashCodeCacheSize

View File

@@ -0,0 +1,84 @@
/** @file
Sample to provide SecPlatformInformation function.
Copyright (c) 2014, 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 <PiPei.h>
#include <Ppi/SecPlatformInformation.h>
#include <Ppi/TopOfTemporaryRam.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
/**
This interface conveys state information out of the Security (SEC) phase into PEI.
@param[in] PeiServices Pointer to the PEI Services Table.
@param[in,out] StructureSize Pointer to the variable describing size of the input buffer.
@param[out] PlatformInformationRecord Pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD.
@retval EFI_SUCCESS The data was successfully returned.
@retval EFI_BUFFER_TOO_SMALL The buffer was too small.
**/
EFI_STATUS
EFIAPI
SecPlatformInformation (
IN CONST EFI_PEI_SERVICES **PeiServices,
IN OUT UINT64 *StructureSize,
OUT EFI_SEC_PLATFORM_INFORMATION_RECORD *PlatformInformationRecord
)
{
UINT32 *Bist;
UINT32 Size;
UINT32 Count;
UINT32 TopOfTemporaryRam;
VOID *TopOfTemporaryRamPpi;
EFI_STATUS Status;
DEBUG ((DEBUG_INFO, "SecPlatformInformation\n"));
Status = (*PeiServices)->LocatePpi (
PeiServices,
&gTopOfTemporaryRamPpiGuid,
0,
NULL,
(VOID **) &TopOfTemporaryRamPpi
);
if (EFI_ERROR (Status)) {
return EFI_NOT_FOUND;
}
//
// The entries of BIST information, together with the number of them,
// reside in the bottom of stack, left untouched by normal stack operation.
// This routine copies the BIST information to the buffer pointed by
// PlatformInformationRecord for output.
//
TopOfTemporaryRam = (UINT32)(UINTN)TopOfTemporaryRamPpi - sizeof (UINT32);
TopOfTemporaryRam -= sizeof(UINT32) * 2;
Count = *((UINT32 *)(UINTN) (TopOfTemporaryRam - sizeof (UINT32)));
Size = Count * sizeof (IA32_HANDOFF_STATUS);
if ((*StructureSize) < (UINT64) Size) {
*StructureSize = Size;
return EFI_BUFFER_TOO_SMALL;
}
*StructureSize = Size;
Bist = (UINT32 *) (TopOfTemporaryRam - sizeof (UINT32) - Size);
CopyMem (PlatformInformationRecord, Bist, Size);
return EFI_SUCCESS;
}

View File

@@ -0,0 +1,22 @@
/** @file
Sample to provide TempRamInitParams data.
Copyright (c) 2014, 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 <Library/PcdLib.h>
GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 TempRamInitParams[4] = {
((UINT32)FixedPcdGet64 (PcdCpuMicrocodePatchAddress) + FixedPcdGet32 (PcdFlashMicroCodeOffset)),
((UINT32)FixedPcdGet64 (PcdCpuMicrocodePatchRegionSize) - FixedPcdGet32 (PcdFlashMicroCodeOffset)),
FixedPcdGet32 (PcdFlashCodeCacheAddress),
FixedPcdGet32 (PcdFlashCodeCacheSize)
};

View File

@@ -0,0 +1,154 @@
/** @file
Sample to provide SecTemporaryRamSupport function.
Copyright (c) 2014, 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 <PiPei.h>
#include <Ppi/TemporaryRamSupport.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/PcdLib.h>
#include <Library/DebugAgentLib.h>
/**
Switch the stack in the temporary memory to the one in the permanent memory.
This function must be invoked after the memory migration immediately. The relative
position of the stack in the temporary and permanent memory is same.
@param[in] TemporaryMemoryBase Base address of the temporary memory.
@param[in] PermenentMemoryBase Base address of the permanent memory.
**/
VOID
EFIAPI
SecSwitchStack (
IN UINT32 TemporaryMemoryBase,
IN UINT32 PermenentMemoryBase
);
/**
This service of the TEMPORARY_RAM_SUPPORT_PPI that migrates temporary RAM into
permanent memory.
@param[in] PeiServices Pointer to the PEI Services Table.
@param[in] TemporaryMemoryBase Source Address in temporary memory from which the SEC or PEIM will copy the
Temporary RAM contents.
@param[in] PermanentMemoryBase Destination Address in permanent memory into which the SEC or PEIM will copy the
Temporary RAM contents.
@param[in] CopySize Amount of memory to migrate from temporary to permanent memory.
@retval EFI_SUCCESS The data was successfully returned.
@retval EFI_INVALID_PARAMETER PermanentMemoryBase + CopySize > TemporaryMemoryBase when
TemporaryMemoryBase > PermanentMemoryBase.
**/
EFI_STATUS
EFIAPI
SecTemporaryRamSupport (
IN CONST EFI_PEI_SERVICES **PeiServices,
IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,
IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,
IN UINTN CopySize
)
{
IA32_DESCRIPTOR IdtDescriptor;
VOID* OldHeap;
VOID* NewHeap;
VOID* OldStack;
VOID* NewStack;
DEBUG_AGENT_CONTEXT_POSTMEM_SEC DebugAgentContext;
BOOLEAN OldStatus;
UINTN PeiStackSize;
PeiStackSize = (UINTN)PcdGet32 (PcdPeiTemporaryRamStackSize);
if (PeiStackSize == 0) {
PeiStackSize = (CopySize >> 1);
}
ASSERT (PeiStackSize < CopySize);
//
// |-------------------|---->
// | Stack | PeiStackSize
// |-------------------|---->
// | Heap | PeiTemporayRamSize
// |-------------------|----> TempRamBase
//
// |-------------------|---->
// | Heap | PeiTemporayRamSize
// |-------------------|---->
// | Stack | PeiStackSize
// |-------------------|----> PermanentMemoryBase
//
OldHeap = (VOID*)(UINTN)TemporaryMemoryBase;
NewHeap = (VOID*)((UINTN)PermanentMemoryBase + PeiStackSize);
OldStack = (VOID*)((UINTN)TemporaryMemoryBase + CopySize - PeiStackSize);
NewStack = (VOID*)(UINTN)PermanentMemoryBase;
DebugAgentContext.HeapMigrateOffset = (UINTN)NewHeap - (UINTN)OldHeap;
DebugAgentContext.StackMigrateOffset = (UINTN)NewStack - (UINTN)OldStack;
OldStatus = SaveAndSetDebugTimerInterrupt (FALSE);
//
// Initialize Debug Agent to support source level debug in PEI phase after memory ready.
// It will build HOB and fix up the pointer in IDT table.
//
InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, (VOID *) &DebugAgentContext, NULL);
//
// Migrate Heap
//
CopyMem (NewHeap, OldHeap, CopySize - PeiStackSize);
//
// Migrate Stack
//
CopyMem (NewStack, OldStack, PeiStackSize);
//
// We need *not* fix the return address because currently,
// The PeiCore is executed in flash.
//
//
// Rebase IDT table in permanent memory
//
AsmReadIdtr (&IdtDescriptor);
IdtDescriptor.Base = IdtDescriptor.Base - (UINTN)OldStack + (UINTN)NewStack;
AsmWriteIdtr (&IdtDescriptor);
//
// Program MTRR
//
//
// SecSwitchStack function must be invoked after the memory migration
// immediatly, also we need fixup the stack change caused by new call into
// permenent memory.
//
SecSwitchStack (
(UINT32) (UINTN) OldStack,
(UINT32) (UINTN) NewStack
);
SaveAndSetDebugTimerInterrupt (OldStatus);
return EFI_SUCCESS;
}