Add IntelFspWrapper to support boot EDKII on FSP bin.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed off by: Jiewen Yao <jiewen.yao@intel.com> Reviewed by: Ravi Rangarajan <ravi.p.rangarajan@intel.com> Reviewed by: Maurice Ma <maurice.ma@intel.com> Reviewed by: Giri Mudusuru <giri.p.mudusuru@intel.com> Reviewed by: Liming Gao <liming.gao@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15676 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
@@ -0,0 +1,325 @@
|
||||
#------------------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
|
||||
# This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
# which accompanies this distribution. The full text of the license may be found at
|
||||
# http://opensource.org/licenses/bsd-license.php.
|
||||
#
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
# Module Name:
|
||||
#
|
||||
# SecEntry.S
|
||||
#
|
||||
# Abstract:
|
||||
#
|
||||
# This is the code that goes from real-mode to protected mode.
|
||||
# It consumes the reset vector, calls TempRamInit API from FSP binary.
|
||||
#
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
#include "Fsp.h"
|
||||
|
||||
ASM_GLOBAL ASM_PFX(_TEXT_REALMODE)
|
||||
ASM_PFX(_TEXT_REALMODE):
|
||||
#----------------------------------------------------------------------------
|
||||
#
|
||||
# Procedure: _ModuleEntryPoint
|
||||
#
|
||||
# Input: None
|
||||
#
|
||||
# Output: None
|
||||
#
|
||||
# Destroys: Assume all registers
|
||||
#
|
||||
# Description:
|
||||
#
|
||||
# Transition to non-paged flat-model protected mode from a
|
||||
# hard-coded GDT that provides exactly two descriptors.
|
||||
# This is a bare bones transition to protected mode only
|
||||
# used for a while in PEI and possibly DXE.
|
||||
#
|
||||
# After enabling protected mode, a far jump is executed to
|
||||
# transfer to PEI using the newly loaded GDT.
|
||||
#
|
||||
# Return: None
|
||||
#
|
||||
# MMX Usage:
|
||||
# MM0 = BIST State
|
||||
# MM5 = Save time-stamp counter value high32bit
|
||||
# MM6 = Save time-stamp counter value low32bit.
|
||||
#
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
.align 4
|
||||
ASM_GLOBAL ASM_PFX(_ModuleEntryPoint)
|
||||
ASM_PFX(_ModuleEntryPoint):
|
||||
fninit # clear any pending Floating point exceptions
|
||||
#
|
||||
# Store the BIST value in mm0
|
||||
#
|
||||
movd %eax, %mm0
|
||||
|
||||
#
|
||||
# Save time-stamp counter value
|
||||
# rdtsc load 64bit time-stamp counter to EDX:EAX
|
||||
#
|
||||
rdtsc
|
||||
movd %edx, %mm5
|
||||
movd %ecx, %mm6
|
||||
|
||||
#
|
||||
# Load the GDT table in GdtDesc
|
||||
#
|
||||
movl $GdtDesc, %esi
|
||||
.byte 0x66
|
||||
lgdt %cs:(%si)
|
||||
|
||||
#
|
||||
# Transition to 16 bit protected mode
|
||||
#
|
||||
movl %cr0, %eax # Get control register 0
|
||||
orl $0x00000003, %eax # Set PE bit (bit #0) & MP bit (bit #1)
|
||||
movl %eax, %cr0 # Activate protected mode
|
||||
|
||||
movl %cr4, %eax # Get control register 4
|
||||
orl $0x00000600, %eax # Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10)
|
||||
movl %eax, %cr4
|
||||
|
||||
#
|
||||
# Now we're in 16 bit protected mode
|
||||
# Set up the selectors for 32 bit protected mode entry
|
||||
#
|
||||
movw SYS_DATA_SEL, %ax
|
||||
movw %ax, %ds
|
||||
movw %ax, %es
|
||||
movw %ax, %fs
|
||||
movw %ax, %gs
|
||||
movw %ax, %ss
|
||||
|
||||
#
|
||||
# Transition to Flat 32 bit protected mode
|
||||
# The jump to a far pointer causes the transition to 32 bit mode
|
||||
#
|
||||
movl $ProtectedModeEntryLinearAddress, %esi
|
||||
jmp *%cs:(%si)
|
||||
|
||||
ASM_GLOBAL ASM_PFX(_TEXT_PROTECTED_MODE)
|
||||
ASM_PFX(_TEXT_PROTECTED_MODE):
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
#
|
||||
# Procedure: ProtectedModeEntryPoint
|
||||
#
|
||||
# Input: None
|
||||
#
|
||||
# Output: None
|
||||
#
|
||||
# Destroys: Assume all registers
|
||||
#
|
||||
# Description:
|
||||
#
|
||||
# This function handles:
|
||||
# Call two basic APIs from FSP binary
|
||||
# Initializes stack with some early data (BIST, PEI entry, etc)
|
||||
#
|
||||
# Return: None
|
||||
#
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
.align 4
|
||||
ASM_GLOBAL ASM_PFX(ProtectedModeEntryPoint)
|
||||
ASM_PFX(ProtectedModeEntryPoint):
|
||||
|
||||
# Find the fsp info header
|
||||
movl PcdGet32 (PcdFlashFvFspBase), %edi
|
||||
movl PcdGet32 (PcdFlashFvFspSize), %ecx
|
||||
|
||||
movl FVH_SIGINATURE_OFFSET(%edi), %eax
|
||||
cmp $FVH_SIGINATURE_VALID_VALUE, %eax
|
||||
jnz FspHeaderNotFound
|
||||
|
||||
xorl %eax, %eax
|
||||
movw FVH_EXTHEADER_OFFSET_OFFSET(%edi), %ax
|
||||
cmp %ax, 0
|
||||
jnz FspFvExtHeaderExist
|
||||
|
||||
xorl %eax, %eax
|
||||
movw FVH_HEADER_LENGTH_OFFSET(%edi), %ax # Bypass Fv Header
|
||||
addl %eax, %edi
|
||||
jmp FspCheckFfsHeader
|
||||
|
||||
FspFvExtHeaderExist:
|
||||
addl %eax, %edi
|
||||
movl FVH_EXTHEADER_SIZE_OFFSET(%edi), %eax # Bypass Ext Fv Header
|
||||
addl %eax, %edi
|
||||
|
||||
# Round up to 8 byte alignment
|
||||
movl %edi, %eax
|
||||
andb $0x07, %al
|
||||
jz FspCheckFfsHeader
|
||||
|
||||
and $0xFFFFFFF8, %edi
|
||||
add $0x08, %edi
|
||||
|
||||
FspCheckFfsHeader:
|
||||
# Check the ffs guid
|
||||
movl (%edi), %eax
|
||||
cmp $FSP_HEADER_GUID_DWORD1, %eax
|
||||
jnz FspHeaderNotFound
|
||||
|
||||
movl 0x4(%edi), %eax
|
||||
cmp $FSP_HEADER_GUID_DWORD2, %eax
|
||||
jnz FspHeaderNotFound
|
||||
|
||||
movl 0x08(%edi), %eax
|
||||
cmp $FSP_HEADER_GUID_DWORD3, %eax
|
||||
jnz FspHeaderNotFound
|
||||
|
||||
movl 0x0c(%edi), %eax
|
||||
cmp $FSP_HEADER_GUID_DWORD4, %eax
|
||||
jnz FspHeaderNotFound
|
||||
|
||||
add $FFS_HEADER_SIZE_VALUE, %edi # Bypass the ffs header
|
||||
|
||||
# Check the section type as raw section
|
||||
movb SECTION_HEADER_TYPE_OFFSET(%edi), %al
|
||||
cmp $0x19, %al
|
||||
jnz FspHeaderNotFound
|
||||
|
||||
addl $RAW_SECTION_HEADER_SIZE_VALUE, %edi # Bypass the section header
|
||||
jmp FspHeaderFound
|
||||
|
||||
FspHeaderNotFound:
|
||||
jmp .
|
||||
|
||||
FspHeaderFound:
|
||||
# Get the fsp TempRamInit Api address
|
||||
movl FSP_HEADER_IMAGEBASE_OFFSET(%edi), %eax
|
||||
addl FSP_HEADER_TEMPRAMINIT_OFFSET(%edi), %eax
|
||||
|
||||
# Setup the hardcode stack
|
||||
movl $TempRamInitStack, %esp
|
||||
|
||||
# Call the fsp TempRamInit Api
|
||||
jmp *%eax
|
||||
|
||||
TempRamInitDone:
|
||||
cmp $0x0, %eax
|
||||
jnz FspApiFailed
|
||||
|
||||
# ECX: start of range
|
||||
# EDX: end of range
|
||||
movl %edx, %esp
|
||||
pushl %edx
|
||||
pushl %ecx
|
||||
pushl %eax # zero - no hob list yet
|
||||
call ASM_PFX(CallPeiCoreEntryPoint)
|
||||
|
||||
FspApiFailed:
|
||||
jmp .
|
||||
|
||||
.align 0x10
|
||||
TempRamInitStack:
|
||||
.long TempRamInitDone
|
||||
.long TempRamInitParams
|
||||
|
||||
#
|
||||
# ROM-based Global-Descriptor Table for the Tiano PEI Phase
|
||||
#
|
||||
.align 16
|
||||
|
||||
#
|
||||
# GDT[0]: 0x00: Null entry, never used.
|
||||
#
|
||||
.equ NULL_SEL, . - GDT_BASE # Selector [0]
|
||||
GDT_BASE:
|
||||
BootGdtTable: .long 0
|
||||
.long 0
|
||||
#
|
||||
# Linear data segment descriptor
|
||||
#
|
||||
.equ LINEAR_SEL, . - GDT_BASE # Selector [0x8]
|
||||
.word 0xFFFF # limit 0xFFFFF
|
||||
.word 0 # base 0
|
||||
.byte 0
|
||||
.byte 0x92 # present, ring 0, data, expand-up, writable
|
||||
.byte 0xCF # page-granular, 32-bit
|
||||
.byte 0
|
||||
#
|
||||
# Linear code segment descriptor
|
||||
#
|
||||
.equ LINEAR_CODE_SEL, . - GDT_BASE # Selector [0x10]
|
||||
.word 0xFFFF # limit 0xFFFFF
|
||||
.word 0 # base 0
|
||||
.byte 0
|
||||
.byte 0x9B # present, ring 0, data, expand-up, not-writable
|
||||
.byte 0xCF # page-granular, 32-bit
|
||||
.byte 0
|
||||
#
|
||||
# System data segment descriptor
|
||||
#
|
||||
.equ SYS_DATA_SEL, . - GDT_BASE # Selector [0x18]
|
||||
.word 0xFFFF # limit 0xFFFFF
|
||||
.word 0 # base 0
|
||||
.byte 0
|
||||
.byte 0x93 # present, ring 0, data, expand-up, not-writable
|
||||
.byte 0xCF # page-granular, 32-bit
|
||||
.byte 0
|
||||
|
||||
#
|
||||
# System code segment descriptor
|
||||
#
|
||||
.equ SYS_CODE_SEL, . - GDT_BASE # Selector [0x20]
|
||||
.word 0xFFFF # limit 0xFFFFF
|
||||
.word 0 # base 0
|
||||
.byte 0
|
||||
.byte 0x9A # present, ring 0, data, expand-up, writable
|
||||
.byte 0xCF # page-granular, 32-bit
|
||||
.byte 0
|
||||
#
|
||||
# Spare segment descriptor
|
||||
#
|
||||
.equ SYS16_CODE_SEL, . - GDT_BASE # Selector [0x28]
|
||||
.word 0xFFFF # limit 0xFFFFF
|
||||
.word 0 # base 0
|
||||
.byte 0x0E # Changed from F000 to E000.
|
||||
.byte 0x9B # present, ring 0, code, expand-up, writable
|
||||
.byte 0x00 # byte-granular, 16-bit
|
||||
.byte 0
|
||||
#
|
||||
# Spare segment descriptor
|
||||
#
|
||||
.equ SYS16_DATA_SEL, . - GDT_BASE # Selector [0x30]
|
||||
.word 0xFFFF # limit 0xFFFF
|
||||
.word 0 # base 0
|
||||
.byte 0
|
||||
.byte 0x93 # present, ring 0, data, expand-up, not-writable
|
||||
.byte 0x00 # byte-granular, 16-bit
|
||||
.byte 0
|
||||
|
||||
#
|
||||
# Spare segment descriptor
|
||||
#
|
||||
.equ SPARE5_SEL, . - GDT_BASE # Selector [0x38]
|
||||
.word 0 # limit 0
|
||||
.word 0 # base 0
|
||||
.byte 0
|
||||
.byte 0 # present, ring 0, data, expand-up, writable
|
||||
.byte 0 # page-granular, 32-bit
|
||||
.byte 0
|
||||
.equ GDT_SIZE, . - BootGdtTable # Size, in bytes
|
||||
|
||||
#
|
||||
# GDT Descriptor
|
||||
#
|
||||
GdtDesc: # GDT descriptor
|
||||
.word GDT_SIZE - 1 # GDT limit
|
||||
.long BootGdtTable # GDT base address
|
||||
|
||||
ASM_PFX(ProtectedModeEntryLinearAddress):
|
||||
ProtectedModeEntryLinearOffset:
|
||||
.long ProtectedModeEntryPoint # Offset of our 32 bit code
|
||||
.word LINEAR_CODE_SEL
|
Reference in New Issue
Block a user