Jiewen Yao cf1d454983 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>
2016-05-13 13:00:53 +08:00

231 lines
5.4 KiB
ArmAsm

#
# 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