From a33a2f62218e6e49a25d63474b7fe423d8ee4b71 Mon Sep 17 00:00:00 2001 From: jyao1 Date: Thu, 24 Jul 2014 06:52:43 +0000 Subject: Add IntelFspWrapper to support boot EDKII on FSP bin. Contributed-under: TianoCore Contribution Agreement 1.0 Signed off by: Jiewen Yao Reviewed by: Ravi Rangarajan Reviewed by: Maurice Ma Reviewed by: Giri Mudusuru Reviewed by: Liming Gao git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15676 6f19259b-4bc3-4df7-8a09-765794883524 --- .../Library/BaseFspApiLib/BaseFspApiLib.inf | 66 ++++ .../Library/BaseFspApiLib/FspApiLib.c | 127 ++++++++ .../Library/BaseFspApiLib/IA32/DispatchExecute.c | 47 +++ .../Library/BaseFspApiLib/X64/DispatchExecute.c | 94 ++++++ .../Library/BaseFspApiLib/X64/Thunk64To32.S | 230 ++++++++++++++ .../Library/BaseFspApiLib/X64/Thunk64To32.asm | 230 ++++++++++++++ .../BaseFspPlatformInfoLibSample.inf | 61 ++++ .../FspPlatformInfoLibSample.c | 147 +++++++++ .../FspHobProcessLibSample.c | 337 ++++++++++++++++++++ .../PeiFspHobProcessLibSample.inf | 75 +++++ .../FspPlatformSecLibSample.c | 151 +++++++++ .../Ia32/AsmSaveSecContext.S | 43 +++ .../Ia32/AsmSaveSecContext.asm | 50 +++ .../SecPeiFspPlatformSecLibSample/Ia32/Fsp.h | 43 +++ .../Ia32/PeiCoreEntry.S | 130 ++++++++ .../Ia32/PeiCoreEntry.asm | 140 +++++++++ .../SecPeiFspPlatformSecLibSample/Ia32/SecEntry.S | 325 +++++++++++++++++++ .../Ia32/SecEntry.asm | 345 +++++++++++++++++++++ .../SecPeiFspPlatformSecLibSample/Ia32/Stack.S | 77 +++++ .../SecPeiFspPlatformSecLibSample/Ia32/Stack.asm | 82 +++++ .../SecPeiFspPlatformSecLibSample/PlatformInit.c | 43 +++ .../SecPeiFspPlatformSecLibSample/SaveSecContext.c | 111 +++++++ .../SecGetPerformance.c | 90 ++++++ .../SecPeiFspPlatformSecLibSample.inf | 93 ++++++ .../SecPlatformInformation.c | 84 +++++ .../SecPeiFspPlatformSecLibSample/SecRamInitData.c | 22 ++ .../SecTempRamSupport.c | 154 +++++++++ 27 files changed, 3397 insertions(+) create mode 100644 IntelFspWrapperPkg/Library/BaseFspApiLib/BaseFspApiLib.inf create mode 100644 IntelFspWrapperPkg/Library/BaseFspApiLib/FspApiLib.c create mode 100644 IntelFspWrapperPkg/Library/BaseFspApiLib/IA32/DispatchExecute.c create mode 100644 IntelFspWrapperPkg/Library/BaseFspApiLib/X64/DispatchExecute.c create mode 100644 IntelFspWrapperPkg/Library/BaseFspApiLib/X64/Thunk64To32.S create mode 100644 IntelFspWrapperPkg/Library/BaseFspApiLib/X64/Thunk64To32.asm create mode 100644 IntelFspWrapperPkg/Library/BaseFspPlatformInfoLibSample/BaseFspPlatformInfoLibSample.inf create mode 100644 IntelFspWrapperPkg/Library/BaseFspPlatformInfoLibSample/FspPlatformInfoLibSample.c create mode 100644 IntelFspWrapperPkg/Library/PeiFspHobProcessLibSample/FspHobProcessLibSample.c create mode 100644 IntelFspWrapperPkg/Library/PeiFspHobProcessLibSample/PeiFspHobProcessLibSample.inf create mode 100644 IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/FspPlatformSecLibSample.c create mode 100644 IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/AsmSaveSecContext.S create mode 100644 IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/AsmSaveSecContext.asm create mode 100644 IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Fsp.h create mode 100644 IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/PeiCoreEntry.S create mode 100644 IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/PeiCoreEntry.asm create mode 100644 IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/SecEntry.S create mode 100644 IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/SecEntry.asm create mode 100644 IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Stack.S create mode 100644 IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Stack.asm create mode 100644 IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/PlatformInit.c create mode 100644 IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SaveSecContext.c create mode 100644 IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecGetPerformance.c create mode 100644 IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecPeiFspPlatformSecLibSample.inf create mode 100644 IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecPlatformInformation.c create mode 100644 IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecRamInitData.c create mode 100644 IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecTempRamSupport.c (limited to 'IntelFspWrapperPkg/Library') diff --git a/IntelFspWrapperPkg/Library/BaseFspApiLib/BaseFspApiLib.inf b/IntelFspWrapperPkg/Library/BaseFspApiLib/BaseFspApiLib.inf new file mode 100644 index 0000000000..451698d8d0 --- /dev/null +++ b/IntelFspWrapperPkg/Library/BaseFspApiLib/BaseFspApiLib.inf @@ -0,0 +1,66 @@ +## @file +# Provide FSP API related function. +# +# Copyright (c) 2014, Intel Corporation. All rights reserved.
+# +# 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 diff --git a/IntelFspWrapperPkg/Library/BaseFspApiLib/FspApiLib.c b/IntelFspWrapperPkg/Library/BaseFspApiLib/FspApiLib.c new file mode 100644 index 0000000000..590238e391 --- /dev/null +++ b/IntelFspWrapperPkg/Library/BaseFspApiLib/FspApiLib.c @@ -0,0 +1,127 @@ +/** @file + Provide FSP API related function. + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ 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 + +#include + +#include +#include + +/** + 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; +} diff --git a/IntelFspWrapperPkg/Library/BaseFspApiLib/IA32/DispatchExecute.c b/IntelFspWrapperPkg/Library/BaseFspApiLib/IA32/DispatchExecute.c new file mode 100644 index 0000000000..15d0a023b8 --- /dev/null +++ b/IntelFspWrapperPkg/Library/BaseFspApiLib/IA32/DispatchExecute.c @@ -0,0 +1,47 @@ +/** @file + Execute 32-bit code in Protected Mode. + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ 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 +#include + +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; +} + diff --git a/IntelFspWrapperPkg/Library/BaseFspApiLib/X64/DispatchExecute.c b/IntelFspWrapperPkg/Library/BaseFspApiLib/X64/DispatchExecute.c new file mode 100644 index 0000000000..17a9ebc8b5 --- /dev/null +++ b/IntelFspWrapperPkg/Library/BaseFspApiLib/X64/DispatchExecute.c @@ -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.
+ 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 +#include +#include + +#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); +} + diff --git a/IntelFspWrapperPkg/Library/BaseFspApiLib/X64/Thunk64To32.S b/IntelFspWrapperPkg/Library/BaseFspApiLib/X64/Thunk64To32.S new file mode 100644 index 0000000000..b6b5c1aca8 --- /dev/null +++ b/IntelFspWrapperPkg/Library/BaseFspApiLib/X64/Thunk64To32.S @@ -0,0 +1,230 @@ +# +# Copyright (c) 2014, Intel Corporation. All rights reserved.
+# 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 + diff --git a/IntelFspWrapperPkg/Library/BaseFspApiLib/X64/Thunk64To32.asm b/IntelFspWrapperPkg/Library/BaseFspApiLib/X64/Thunk64To32.asm new file mode 100644 index 0000000000..70e7b5f408 --- /dev/null +++ b/IntelFspWrapperPkg/Library/BaseFspApiLib/X64/Thunk64To32.asm @@ -0,0 +1,230 @@ +; +; Copyright (c) 2014, Intel Corporation. All rights reserved.
+; 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 diff --git a/IntelFspWrapperPkg/Library/BaseFspPlatformInfoLibSample/BaseFspPlatformInfoLibSample.inf b/IntelFspWrapperPkg/Library/BaseFspPlatformInfoLibSample/BaseFspPlatformInfoLibSample.inf new file mode 100644 index 0000000000..68cd9a9a56 --- /dev/null +++ b/IntelFspWrapperPkg/Library/BaseFspPlatformInfoLibSample/BaseFspPlatformInfoLibSample.inf @@ -0,0 +1,61 @@ +## @file +# Sample to provide FSP platform information related function. +# +# Copyright (c) 2014, Intel Corporation. All rights reserved.
+# +# 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 diff --git a/IntelFspWrapperPkg/Library/BaseFspPlatformInfoLibSample/FspPlatformInfoLibSample.c b/IntelFspWrapperPkg/Library/BaseFspPlatformInfoLibSample/FspPlatformInfoLibSample.c new file mode 100644 index 0000000000..7c57e7bb46 --- /dev/null +++ b/IntelFspWrapperPkg/Library/BaseFspPlatformInfoLibSample/FspPlatformInfoLibSample.c @@ -0,0 +1,147 @@ +/** @file + Sample to provide FSP platform information related function. + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ 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 +#include + +/** + 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; +} diff --git a/IntelFspWrapperPkg/Library/PeiFspHobProcessLibSample/FspHobProcessLibSample.c b/IntelFspWrapperPkg/Library/PeiFspHobProcessLibSample/FspHobProcessLibSample.c new file mode 100644 index 0000000000..f293dc8be8 --- /dev/null +++ b/IntelFspWrapperPkg/Library/PeiFspHobProcessLibSample/FspHobProcessLibSample.c @@ -0,0 +1,337 @@ +/** @file + Sample to provide FSP hob process related function. + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ 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 + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +// +// 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; +} diff --git a/IntelFspWrapperPkg/Library/PeiFspHobProcessLibSample/PeiFspHobProcessLibSample.inf b/IntelFspWrapperPkg/Library/PeiFspHobProcessLibSample/PeiFspHobProcessLibSample.inf new file mode 100644 index 0000000000..cbba3d41f6 --- /dev/null +++ b/IntelFspWrapperPkg/Library/PeiFspHobProcessLibSample/PeiFspHobProcessLibSample.inf @@ -0,0 +1,75 @@ +## @file +# Sample to provide FSP hob process related function. +# +# Copyright (c) 2014, Intel Corporation. All rights reserved.
+# +# 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 diff --git a/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/FspPlatformSecLibSample.c b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/FspPlatformSecLibSample.c new file mode 100644 index 0000000000..6bf2e8662d --- /dev/null +++ b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/FspPlatformSecLibSample.c @@ -0,0 +1,151 @@ +/** @file + Sample to provide FSP wrapper platform sec related function. + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ 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 + +#include +#include +#include + +#include + +/** + 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; +} diff --git a/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/AsmSaveSecContext.S b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/AsmSaveSecContext.S new file mode 100644 index 0000000000..3838cc8292 --- /dev/null +++ b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/AsmSaveSecContext.S @@ -0,0 +1,43 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2014, Intel Corporation. All rights reserved.
+# 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 diff --git a/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/AsmSaveSecContext.asm b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/AsmSaveSecContext.asm new file mode 100644 index 0000000000..bb147a93db --- /dev/null +++ b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/AsmSaveSecContext.asm @@ -0,0 +1,50 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2014, Intel Corporation. All rights reserved.
+; 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 diff --git a/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Fsp.h b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Fsp.h new file mode 100644 index 0000000000..289d6638b0 --- /dev/null +++ b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Fsp.h @@ -0,0 +1,43 @@ +/** @file + Fsp related definitions + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ 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 diff --git a/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/PeiCoreEntry.S b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/PeiCoreEntry.S new file mode 100644 index 0000000000..c35f02b77e --- /dev/null +++ b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/PeiCoreEntry.S @@ -0,0 +1,130 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2014, Intel Corporation. All rights reserved.
+# 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) diff --git a/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/PeiCoreEntry.asm b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/PeiCoreEntry.asm new file mode 100644 index 0000000000..cd1c7b8c5d --- /dev/null +++ b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/PeiCoreEntry.asm @@ -0,0 +1,140 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2014, Intel Corporation. All rights reserved.
+; 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 diff --git a/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/SecEntry.S b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/SecEntry.S new file mode 100644 index 0000000000..3145a484a3 --- /dev/null +++ b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/SecEntry.S @@ -0,0 +1,325 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2014, Intel Corporation. All rights reserved.
+# 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 diff --git a/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/SecEntry.asm b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/SecEntry.asm new file mode 100644 index 0000000000..0e0c5c5883 --- /dev/null +++ b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/SecEntry.asm @@ -0,0 +1,345 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2014, Intel Corporation. All rights reserved.
+; 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 diff --git a/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Stack.S b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Stack.S new file mode 100644 index 0000000000..950b3a1f0a --- /dev/null +++ b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Stack.S @@ -0,0 +1,77 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2014, Intel Corporation. All rights reserved.
+# 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 + diff --git a/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Stack.asm b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Stack.asm new file mode 100644 index 0000000000..f96a55f040 --- /dev/null +++ b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Stack.asm @@ -0,0 +1,82 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2014, Intel Corporation. All rights reserved.
+; 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 diff --git a/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/PlatformInit.c b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/PlatformInit.c new file mode 100644 index 0000000000..e8b71667de --- /dev/null +++ b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/PlatformInit.c @@ -0,0 +1,43 @@ +/** @file + Sample to provide platform init function. + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ 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 +#include + +/** + 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)); +} diff --git a/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SaveSecContext.c b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SaveSecContext.c new file mode 100644 index 0000000000..3d37441183 --- /dev/null +++ b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SaveSecContext.c @@ -0,0 +1,111 @@ +/** @file + Sample to provide SaveSecContext function. + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ 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 +#include + +#include +#include + +/** + 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); +} diff --git a/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecGetPerformance.c b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecGetPerformance.c new file mode 100644 index 0000000000..e2d6b3da57 --- /dev/null +++ b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecGetPerformance.c @@ -0,0 +1,90 @@ +/** @file + Sample to provide SecGetPerformance function. + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ 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 + +#include +#include + +#include +#include +#include + +/** + 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; +} diff --git a/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecPeiFspPlatformSecLibSample.inf b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecPeiFspPlatformSecLibSample.inf new file mode 100644 index 0000000000..09b8036918 --- /dev/null +++ b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecPeiFspPlatformSecLibSample.inf @@ -0,0 +1,93 @@ +## @file +# Sample to provide FSP wrapper platform sec related function. +# +# Copyright (c) 2014, Intel Corporation. All rights reserved.
+# +# 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 diff --git a/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecPlatformInformation.c b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecPlatformInformation.c new file mode 100644 index 0000000000..b879080dfa --- /dev/null +++ b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecPlatformInformation.c @@ -0,0 +1,84 @@ +/** @file + Sample to provide SecPlatformInformation function. + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ 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 + +#include +#include + +#include +#include + +/** + 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; +} diff --git a/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecRamInitData.c b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecRamInitData.c new file mode 100644 index 0000000000..0c7da4447b --- /dev/null +++ b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecRamInitData.c @@ -0,0 +1,22 @@ +/** @file + Sample to provide TempRamInitParams data. + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ 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 + +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 TempRamInitParams[4] = { + ((UINT32)FixedPcdGet64 (PcdCpuMicrocodePatchAddress) + FixedPcdGet32 (PcdFlashMicroCodeOffset)), + ((UINT32)FixedPcdGet64 (PcdCpuMicrocodePatchRegionSize) - FixedPcdGet32 (PcdFlashMicroCodeOffset)), + FixedPcdGet32 (PcdFlashCodeCacheAddress), + FixedPcdGet32 (PcdFlashCodeCacheSize) +}; diff --git a/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecTempRamSupport.c b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecTempRamSupport.c new file mode 100644 index 0000000000..7f7a6af0bd --- /dev/null +++ b/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecTempRamSupport.c @@ -0,0 +1,154 @@ +/** @file + Sample to provide SecTemporaryRamSupport function. + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ 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 + +#include + +#include +#include +#include +#include + +/** + 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; +} + -- cgit v1.2.3