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

337 lines
9.6 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:
#
# 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(_gPcd_FixedAtBuild_PcdFsptBaseAddress)
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 ASM_PFX(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 ASM_PFX(_gPcd_FixedAtBuild_PcdFsptBaseAddress), %edi
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 $0x8000000E, %eax #Check if EFI_NOT_FOUND returned. Error code for Microcode Update not found.
je CallSecFspInit #If microcode not found, don't hang, but continue.
cmp $0x0, %eax
jnz FspApiFailed
# ECX: start of range
# EDX: end of range
CallSecFspInit:
xorl %eax, %eax
movl %edx, %esp
# Align the stack at DWORD
addl $3, %esp
andl $0xFFFFFFFC, %esp
pushl %edx
pushl %ecx
pushl %eax # zero - no hob list yet
call ASM_PFX(CallPeiCoreEntryPoint)
FspApiFailed:
jmp .
.align 0x10
TempRamInitStack:
.long TempRamInitDone
.long ASM_PFX(FsptUpdDataPtr)
#
# 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 ASM_PFX(ProtectedModeEntryPoint) # Offset of our 32 bit code
.word LINEAR_CODE_SEL