Add IntelFsp2Pkg and IntelFsp2WrapperPkg.

Add FSP2.0 support.
This series of patch is to support FSP2.0 specification at
https://firmware.intel.com/sites/default/files/FSP_EAS_v2.0_Draft%20External.pdf

Some major updates include:
1) One FSP binary is separated to multiple components:
FSP-T, FSP-M, FSP-S, and optional FSP-O.
Each component has its own configuration data region.
2) All FSP-APIs use same UPD format - FSP_UPD_HEADER.
3) Add EnumInitPhaseEndOfFirmware notifyphase.
4) FSP1.1/FSP1.0 compatibility is NOT maintained.
5) We also add rename Fsp* to FspWrapper* in IntelFsp2WrapperPkg,
to indicate that it is for FspWrapper only.

IntelFspPkg and IntelFspWrapperPkg will be deprecated.
The new Intel platform will follow FSP2.0 and use IntelFsp2Pkg
and IntelFsp2WrapperPkg.
The old platform can still use IntelFspPkg and IntelFspWrapperPkg
for compatibility consideration.

Cc: Giri P Mudusuru <giri.p.mudusuru@intel.com>
Cc: Maurice Ma <maurice.ma@intel.com>
Cc: Ravi P Rangarajan <ravi.p.rangarajan@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
Reviewed-by: Giri P Mudusuru <giri.p.mudusuru@intel.com>
Reviewed-by: Maurice Ma <maurice.ma@intel.com>
Reviewed-by: Ravi P Rangarajan <ravi.p.rangarajan@intel.com>
This commit is contained in:
Jiewen Yao
2016-05-13 13:00:53 +08:00
parent c9802c4564
commit cf1d454983
118 changed files with 15633 additions and 0 deletions

View File

@@ -0,0 +1,108 @@
/** @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 - 2016, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php.
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include <Uefi.h>
#include <Library/BaseLib.h>
#include <FspEas.h>
#pragma pack(1)
typedef union {
struct {
UINT32 LimitLow : 16;
UINT32 BaseLow : 16;
UINT32 BaseMid : 8;
UINT32 Type : 4;
UINT32 System : 1;
UINT32 Dpl : 2;
UINT32 Present : 1;
UINT32 LimitHigh : 4;
UINT32 Software : 1;
UINT32 Reserved : 1;
UINT32 DefaultSize : 1;
UINT32 Granularity : 1;
UINT32 BaseHigh : 8;
} Bits;
UINT64 Uint64;
} IA32_GDT;
#pragma pack()
GLOBAL_REMOVE_IF_UNREFERENCED IA32_GDT mGdtEntries[] = {
{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 0x0: reserve */
{{0xFFFF, 0, 0, 0xB, 1, 0, 1, 0xF, 0, 0, 1, 1, 0}}, /* 0x8: compatibility mode */
{{0xFFFF, 0, 0, 0xB, 1, 0, 1, 0xF, 0, 1, 0, 1, 0}}, /* 0x10: for long mode */
{{0xFFFF, 0, 0, 0x3, 1, 0, 1, 0xF, 0, 0, 1, 1, 0}}, /* 0x18: data */
{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 0x20: reserve */
};
//
// IA32 Gdt register
//
GLOBAL_REMOVE_IF_UNREFERENCED IA32_DESCRIPTOR mGdt = {
sizeof (mGdtEntries) - 1,
(UINTN) mGdtEntries
};
/**
Assembly function to transition from long mode to compatibility mode to execute 32-bit code and then transit back to
long mode.
@param[in] Function The 32bit code entry to be executed.
@param[in] Param1 The first parameter to pass to 32bit code
@param[in] Param2 The second parameter to pass to 32bit code
@param[in] InternalGdtr The GDT and GDT descriptor used by this library
@return status.
**/
UINT32
AsmExecute32BitCode (
IN UINT64 Function,
IN UINT64 Param1,
IN UINT64 Param2,
IN IA32_DESCRIPTOR *InternalGdtr
);
/**
Wrapper for a thunk to transition from long mode to compatibility mode to execute 32-bit code and then transit back to
long mode.
@param[in] Function The 32bit code entry to be executed.
@param[in] Param1 The first parameter to pass to 32bit code.
@param[in] Param2 The second parameter to pass to 32bit code.
@return EFI_STATUS.
**/
EFI_STATUS
Execute32BitCode (
IN UINT64 Function,
IN UINT64 Param1,
IN UINT64 Param2
)
{
EFI_STATUS Status;
IA32_DESCRIPTOR Idtr;
//
// Idtr might be changed inside of FSP. 32bit FSP only knows the <4G address.
// If IDTR.Base is >4G, FSP can not handle. So we need save/restore IDTR here for X64 only.
// Interrupt is already disabled here, so it is safety to update IDTR.
//
AsmReadIdtr (&Idtr);
Status = AsmExecute32BitCode (Function, Param1, Param2, &mGdt);
AsmWriteIdtr (&Idtr);
return Status;
}

View File

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

View File

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