+++ /dev/null
-#------------------------------------------------------------------------------\r
-#\r
-# Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
-# SPDX-License-Identifier: BSD-2-Clause-Patent\r
-#\r
-# Module Name:\r
-#\r
-# SecEntry.S\r
-#\r
-# Abstract:\r
-#\r
-# This is the code that goes from real-mode to protected mode.\r
-# It consumes the reset vector, calls TempRamInit API from FSP binary.\r
-#\r
-#------------------------------------------------------------------------------\r
-\r
-#include "Fsp.h"\r
-\r
-ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdFlashFvFspBase)\r
-ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdFlashFvFspSize)\r
-\r
-ASM_GLOBAL ASM_PFX(_TEXT_REALMODE)\r
-ASM_PFX(_TEXT_REALMODE):\r
-#----------------------------------------------------------------------------\r
-#\r
-# Procedure: _ModuleEntryPoint\r
-#\r
-# Input: None\r
-#\r
-# Output: None\r
-#\r
-# Destroys: Assume all registers\r
-#\r
-# Description:\r
-#\r
-# Transition to non-paged flat-model protected mode from a\r
-# hard-coded GDT that provides exactly two descriptors.\r
-# This is a bare bones transition to protected mode only\r
-# used for a while in PEI and possibly DXE.\r
-#\r
-# After enabling protected mode, a far jump is executed to\r
-# transfer to PEI using the newly loaded GDT.\r
-#\r
-# Return: None\r
-#\r
-# MMX Usage:\r
-# MM0 = BIST State\r
-# MM5 = Save time-stamp counter value high32bit\r
-# MM6 = Save time-stamp counter value low32bit.\r
-#\r
-#----------------------------------------------------------------------------\r
-\r
-.align 4\r
-ASM_GLOBAL ASM_PFX(_ModuleEntryPoint)\r
-ASM_PFX(_ModuleEntryPoint):\r
- fninit # clear any pending Floating point exceptions\r
- #\r
- # Store the BIST value in mm0\r
- #\r
- movd %eax, %mm0\r
-\r
- #\r
- # Save time-stamp counter value\r
- # rdtsc load 64bit time-stamp counter to EDX:EAX\r
- #\r
- rdtsc\r
- movd %edx, %mm5\r
- movd %ecx, %mm6\r
-\r
- #\r
- # Load the GDT table in GdtDesc\r
- #\r
- movl $GdtDesc, %esi\r
- .byte 0x66\r
- lgdt %cs:(%si)\r
-\r
- #\r
- # Transition to 16 bit protected mode\r
- #\r
- movl %cr0, %eax # Get control register 0\r
- orl $0x00000003, %eax # Set PE bit (bit #0) & MP bit (bit #1)\r
- movl %eax, %cr0 # Activate protected mode\r
-\r
- movl %cr4, %eax # Get control register 4\r
- orl $0x00000600, %eax # Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10)\r
- movl %eax, %cr4\r
-\r
- #\r
- # Now we're in 16 bit protected mode\r
- # Set up the selectors for 32 bit protected mode entry\r
- #\r
- movw SYS_DATA_SEL, %ax\r
- movw %ax, %ds\r
- movw %ax, %es\r
- movw %ax, %fs\r
- movw %ax, %gs\r
- movw %ax, %ss\r
-\r
- #\r
- # Transition to Flat 32 bit protected mode\r
- # The jump to a far pointer causes the transition to 32 bit mode\r
- #\r
- movl ASM_PFX(ProtectedModeEntryLinearAddress), %esi\r
- jmp *%cs:(%si)\r
-\r
-ASM_GLOBAL ASM_PFX(_TEXT_PROTECTED_MODE)\r
-ASM_PFX(_TEXT_PROTECTED_MODE):\r
-\r
-#----------------------------------------------------------------------------\r
-#\r
-# Procedure: ProtectedModeEntryPoint\r
-#\r
-# Input: None\r
-#\r
-# Output: None\r
-#\r
-# Destroys: Assume all registers\r
-#\r
-# Description:\r
-#\r
-# This function handles:\r
-# Call two basic APIs from FSP binary\r
-# Initializes stack with some early data (BIST, PEI entry, etc)\r
-#\r
-# Return: None\r
-#\r
-#----------------------------------------------------------------------------\r
-\r
-.align 4\r
-ASM_GLOBAL ASM_PFX(ProtectedModeEntryPoint)\r
-ASM_PFX(ProtectedModeEntryPoint):\r
-\r
- # Find the fsp info header\r
- movl ASM_PFX(_gPcd_FixedAtBuild_PcdFlashFvFspBase), %edi\r
- movl ASM_PFX(_gPcd_FixedAtBuild_PcdFlashFvFspSize), %ecx\r
-\r
- movl FVH_SIGINATURE_OFFSET(%edi), %eax\r
- cmp $FVH_SIGINATURE_VALID_VALUE, %eax\r
- jnz FspHeaderNotFound\r
-\r
- xorl %eax, %eax\r
- movw FVH_EXTHEADER_OFFSET_OFFSET(%edi), %ax\r
- cmp %ax, 0\r
- jnz FspFvExtHeaderExist\r
-\r
- xorl %eax, %eax\r
- movw FVH_HEADER_LENGTH_OFFSET(%edi), %ax # Bypass Fv Header\r
- addl %eax, %edi\r
- jmp FspCheckFfsHeader\r
-\r
-FspFvExtHeaderExist:\r
- addl %eax, %edi\r
- movl FVH_EXTHEADER_SIZE_OFFSET(%edi), %eax # Bypass Ext Fv Header\r
- addl %eax, %edi\r
-\r
- # Round up to 8 byte alignment\r
- movl %edi, %eax\r
- andb $0x07, %al\r
- jz FspCheckFfsHeader\r
-\r
- and $0xFFFFFFF8, %edi\r
- add $0x08, %edi\r
-\r
-FspCheckFfsHeader:\r
- # Check the ffs guid\r
- movl (%edi), %eax\r
- cmp $FSP_HEADER_GUID_DWORD1, %eax\r
- jnz FspHeaderNotFound\r
-\r
- movl 0x4(%edi), %eax\r
- cmp $FSP_HEADER_GUID_DWORD2, %eax\r
- jnz FspHeaderNotFound\r
-\r
- movl 0x08(%edi), %eax\r
- cmp $FSP_HEADER_GUID_DWORD3, %eax\r
- jnz FspHeaderNotFound\r
-\r
- movl 0x0c(%edi), %eax\r
- cmp $FSP_HEADER_GUID_DWORD4, %eax\r
- jnz FspHeaderNotFound\r
-\r
- add $FFS_HEADER_SIZE_VALUE, %edi # Bypass the ffs header\r
-\r
- # Check the section type as raw section\r
- movb SECTION_HEADER_TYPE_OFFSET(%edi), %al\r
- cmp $0x19, %al\r
- jnz FspHeaderNotFound\r
-\r
- addl $RAW_SECTION_HEADER_SIZE_VALUE, %edi # Bypass the section header\r
- jmp FspHeaderFound\r
-\r
-FspHeaderNotFound:\r
- jmp .\r
-\r
-FspHeaderFound:\r
- # Get the fsp TempRamInit Api address\r
- movl FSP_HEADER_IMAGEBASE_OFFSET(%edi), %eax\r
- addl FSP_HEADER_TEMPRAMINIT_OFFSET(%edi), %eax\r
-\r
- # Setup the hardcode stack\r
- movl $TempRamInitStack, %esp\r
-\r
- # Call the fsp TempRamInit Api\r
- jmp *%eax\r
-\r
-TempRamInitDone:\r
- cmp $0x8000000E, %eax #Check if EFI_NOT_FOUND returned. Error code for Microcode Update not found.\r
- je CallSecFspInit #If microcode not found, don't hang, but continue.\r
-\r
- cmp $0x0, %eax\r
- jnz FspApiFailed\r
-\r
- # ECX: start of range\r
- # EDX: end of range\r
-CallSecFspInit:\r
- xorl %eax, %eax\r
- movl %edx, %esp\r
-\r
- # Align the stack at DWORD\r
- addl $3, %esp\r
- andl $0xFFFFFFFC, %esp\r
-\r
- pushl %edx\r
- pushl %ecx\r
- pushl %eax # zero - no hob list yet\r
- call ASM_PFX(CallPeiCoreEntryPoint)\r
-\r
-FspApiFailed:\r
- jmp .\r
-\r
-.align 0x10\r
-TempRamInitStack:\r
- .long TempRamInitDone\r
- .long ASM_PFX(TempRamInitParams)\r
-\r
-#\r
-# ROM-based Global-Descriptor Table for the Tiano PEI Phase\r
-#\r
-.align 16\r
-\r
-#\r
-# GDT[0]: 0x00: Null entry, never used.\r
-#\r
-.equ NULL_SEL, . - GDT_BASE # Selector [0]\r
-GDT_BASE:\r
-BootGdtTable: .long 0\r
- .long 0\r
-#\r
-# Linear data segment descriptor\r
-#\r
-.equ LINEAR_SEL, . - GDT_BASE # Selector [0x8]\r
- .word 0xFFFF # limit 0xFFFFF\r
- .word 0 # base 0\r
- .byte 0\r
- .byte 0x92 # present, ring 0, data, expand-up, writable\r
- .byte 0xCF # page-granular, 32-bit\r
- .byte 0\r
-#\r
-# Linear code segment descriptor\r
-#\r
-.equ LINEAR_CODE_SEL, . - GDT_BASE # Selector [0x10]\r
- .word 0xFFFF # limit 0xFFFFF\r
- .word 0 # base 0\r
- .byte 0\r
- .byte 0x9B # present, ring 0, data, expand-up, not-writable\r
- .byte 0xCF # page-granular, 32-bit\r
- .byte 0\r
-#\r
-# System data segment descriptor\r
-#\r
-.equ SYS_DATA_SEL, . - GDT_BASE # Selector [0x18]\r
- .word 0xFFFF # limit 0xFFFFF\r
- .word 0 # base 0\r
- .byte 0\r
- .byte 0x93 # present, ring 0, data, expand-up, not-writable\r
- .byte 0xCF # page-granular, 32-bit\r
- .byte 0\r
-\r
-#\r
-# System code segment descriptor\r
-#\r
-.equ SYS_CODE_SEL, . - GDT_BASE # Selector [0x20]\r
- .word 0xFFFF # limit 0xFFFFF\r
- .word 0 # base 0\r
- .byte 0\r
- .byte 0x9A # present, ring 0, data, expand-up, writable\r
- .byte 0xCF # page-granular, 32-bit\r
- .byte 0\r
-#\r
-# Spare segment descriptor\r
-#\r
-.equ SYS16_CODE_SEL, . - GDT_BASE # Selector [0x28]\r
- .word 0xFFFF # limit 0xFFFFF\r
- .word 0 # base 0\r
- .byte 0x0E # Changed from F000 to E000.\r
- .byte 0x9B # present, ring 0, code, expand-up, writable\r
- .byte 0x00 # byte-granular, 16-bit\r
- .byte 0\r
-#\r
-# Spare segment descriptor\r
-#\r
-.equ SYS16_DATA_SEL, . - GDT_BASE # Selector [0x30]\r
- .word 0xFFFF # limit 0xFFFF\r
- .word 0 # base 0\r
- .byte 0\r
- .byte 0x93 # present, ring 0, data, expand-up, not-writable\r
- .byte 0x00 # byte-granular, 16-bit\r
- .byte 0\r
-\r
-#\r
-# Spare segment descriptor\r
-#\r
-.equ SPARE5_SEL, . - GDT_BASE # Selector [0x38]\r
- .word 0 # limit 0\r
- .word 0 # base 0\r
- .byte 0\r
- .byte 0 # present, ring 0, data, expand-up, writable\r
- .byte 0 # page-granular, 32-bit\r
- .byte 0\r
-.equ GDT_SIZE, . - BootGdtTable # Size, in bytes\r
-\r
-#\r
-# GDT Descriptor\r
-#\r
-GdtDesc: # GDT descriptor\r
- .word GDT_SIZE - 1 # GDT limit\r
- .long BootGdtTable # GDT base address\r
-\r
-ASM_PFX(ProtectedModeEntryLinearAddress):\r
-ProtectedModeEntryLinearOffset:\r
- .long ASM_PFX(ProtectedModeEntryPoint) # Offset of our 32 bit code\r
- .word LINEAR_CODE_SEL\r