summaryrefslogtreecommitdiff
path: root/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32
diff options
context:
space:
mode:
Diffstat (limited to 'IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32')
-rw-r--r--IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/Fsp.h51
-rw-r--r--IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/PeiCoreEntry.S130
-rw-r--r--IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/PeiCoreEntry.asm140
-rw-r--r--IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/SecEntry.S336
-rw-r--r--IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/SecEntry.asm353
-rw-r--r--IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/Stack.S77
-rw-r--r--IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/Stack.asm82
7 files changed, 1169 insertions, 0 deletions
diff --git a/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/Fsp.h b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/Fsp.h
new file mode 100644
index 000000000..c625a884d
--- /dev/null
+++ b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/Fsp.h
@@ -0,0 +1,51 @@
+/** @file
+ Fsp related definitions
+
+ 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.
+
+**/
+
+#ifndef __FSP_H__
+#define __FSP_H__
+
+//
+// Fv Header
+//
+#define FVH_FV_LENGTH_OFFSET 0x20
+#define FVH_SIGINATURE_OFFSET 0x28
+#define FVH_SIGINATURE_VALID_VALUE 0x4856465F // valid signature:_FVH
+#define FVH_HEADER_LENGTH_OFFSET 0x30
+#define FVH_EXTHEADER_OFFSET_OFFSET 0x34
+#define FVH_EXTHEADER_SIZE_OFFSET 0x10
+
+//
+// Ffs Header
+//
+#define FSP_HEADER_SIGNATURE_OFFSET 0x1C
+#define FSP_HEADER_SIGNATURE 0x48505346 ; valid signature:FSPH
+#define FSP_HEADER_GUID_DWORD1 0x912740BE
+#define FSP_HEADER_GUID_DWORD2 0x47342284
+#define FSP_HEADER_GUID_DWORD3 0xB08471B9
+#define FSP_HEADER_GUID_DWORD4 0x0C3F3527
+#define FFS_HEADER_SIZE_VALUE 0x18
+
+//
+// Section Header
+//
+#define SECTION_HEADER_TYPE_OFFSET 0x03
+#define RAW_SECTION_HEADER_SIZE_VALUE 0x04
+
+//
+// Fsp Header
+//
+#define FSP_HEADER_IMAGEBASE_OFFSET 0x1C
+#define FSP_HEADER_TEMPRAMINIT_OFFSET 0x30
+
+#endif
diff --git a/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/PeiCoreEntry.S b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/PeiCoreEntry.S
new file mode 100644
index 000000000..c35f02b77
--- /dev/null
+++ b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/PeiCoreEntry.S
@@ -0,0 +1,130 @@
+#------------------------------------------------------------------------------
+#
+# 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:
+#
+# PeiCoreEntry.S
+#
+# Abstract:
+#
+# Find and call SecStartup
+#
+#------------------------------------------------------------------------------
+
+ASM_GLOBAL ASM_PFX(CallPeiCoreEntryPoint)
+ASM_PFX(CallPeiCoreEntryPoint):
+ #
+ # Obtain the hob list pointer
+ #
+ movl 0x4(%esp), %eax
+ #
+ # Obtain the stack information
+ # ECX: start of range
+ # EDX: end of range
+ #
+ movl 0x8(%esp), %ecx
+ movl 0xC(%esp), %edx
+
+ #
+ # Platform init
+ #
+ pushal
+ pushl %edx
+ pushl %ecx
+ pushl %eax
+ call ASM_PFX(PlatformInit)
+ popl %eax
+ popl %eax
+ popl %eax
+ popal
+
+ #
+ # Set stack top pointer
+ #
+ movl %edx, %esp
+
+ #
+ # Push the hob list pointer
+ #
+ pushl %eax
+
+ #
+ # Save the value
+ # ECX: start of range
+ # EDX: end of range
+ #
+ movl %esp, %ebp
+ pushl %ecx
+ pushl %edx
+
+ #
+ # Push processor count to stack first, then BIST status (AP then BSP)
+ #
+ movl $1, %eax
+ cpuid
+ shr $16, %ebx
+ andl $0x000000FF, %ebx
+ cmp $1, %bl
+ jae PushProcessorCount
+
+ #
+ # Some processors report 0 logical processors. Effectively 0 = 1.
+ # So we fix up the processor count
+ #
+ inc %ebx
+
+PushProcessorCount:
+ pushl %ebx
+
+ #
+ # We need to implement a long-term solution for BIST capture. For now, we just copy BSP BIST
+ # for all processor threads
+ #
+ xorl %ecx, %ecx
+ movb %bl, %cl
+PushBist:
+ movd %mm0, %eax
+ pushl %eax
+ loop PushBist
+
+ # Save Time-Stamp Counter
+ movd %mm5, %eax
+ pushl %eax
+
+ movd %mm6, %eax
+ pushl %eax
+
+ #
+ # Pass entry point of the PEI core
+ #
+ movl $0xFFFFFFE0, %edi
+ pushl %ds:(%edi)
+
+ #
+ # Pass BFV into the PEI Core
+ #
+ movl $0xFFFFFFFC, %edi
+ pushl %ds:(%edi)
+
+ #
+ # Pass stack size into the PEI Core
+ #
+ movl -4(%ebp), %ecx
+ movl -8(%ebp), %edx
+ pushl %ecx # RamBase
+
+ subl %ecx, %edx
+ pushl %edx # RamSize
+
+ #
+ # Pass Control into the PEI Core
+ #
+ call ASM_PFX(SecStartup)
diff --git a/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/PeiCoreEntry.asm b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/PeiCoreEntry.asm
new file mode 100644
index 000000000..cd1c7b8c5
--- /dev/null
+++ b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/PeiCoreEntry.asm
@@ -0,0 +1,140 @@
+;------------------------------------------------------------------------------
+;
+; 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:
+;
+; PeiCoreEntry.asm
+;
+; Abstract:
+;
+; Find and call SecStartup
+;
+;------------------------------------------------------------------------------
+
+.686p
+.xmm
+.model flat, c
+.code
+
+EXTRN SecStartup:NEAR
+EXTRN PlatformInit:NEAR
+
+CallPeiCoreEntryPoint PROC PUBLIC
+ ;
+ ; Obtain the hob list pointer
+ ;
+ mov eax, [esp+4]
+ ;
+ ; Obtain the stack information
+ ; ECX: start of range
+ ; EDX: end of range
+ ;
+ mov ecx, [esp+8]
+ mov edx, [esp+0Ch]
+
+ ;
+ ; Platform init
+ ;
+ pushad
+ push edx
+ push ecx
+ push eax
+ call PlatformInit
+ pop eax
+ pop eax
+ pop eax
+ popad
+
+ ;
+ ; Set stack top pointer
+ ;
+ mov esp, edx
+
+ ;
+ ; Push the hob list pointer
+ ;
+ push eax
+
+ ;
+ ; Save the value
+ ; ECX: start of range
+ ; EDX: end of range
+ ;
+ mov ebp, esp
+ push ecx
+ push edx
+
+ ;
+ ; Push processor count to stack first, then BIST status (AP then BSP)
+ ;
+ mov eax, 1
+ cpuid
+ shr ebx, 16
+ and ebx, 0000000FFh
+ cmp bl, 1
+ jae PushProcessorCount
+
+ ;
+ ; Some processors report 0 logical processors. Effectively 0 = 1.
+ ; So we fix up the processor count
+ ;
+ inc ebx
+
+PushProcessorCount:
+ push ebx
+
+ ;
+ ; We need to implement a long-term solution for BIST capture. For now, we just copy BSP BIST
+ ; for all processor threads
+ ;
+ xor ecx, ecx
+ mov cl, bl
+PushBist:
+ movd eax, mm0
+ push eax
+ loop PushBist
+
+ ; Save Time-Stamp Counter
+ movd eax, mm5
+ push eax
+
+ movd eax, mm6
+ push eax
+
+ ;
+ ; Pass entry point of the PEI core
+ ;
+ mov edi, 0FFFFFFE0h
+ push DWORD PTR ds:[edi]
+
+ ;
+ ; Pass BFV into the PEI Core
+ ;
+ mov edi, 0FFFFFFFCh
+ push DWORD PTR ds:[edi]
+
+ ;
+ ; Pass stack size into the PEI Core
+ ;
+ mov ecx, [ebp - 4]
+ mov edx, [ebp - 8]
+ push ecx ; RamBase
+
+ sub edx, ecx
+ push edx ; RamSize
+
+ ;
+ ; Pass Control into the PEI Core
+ ;
+ call SecStartup
+CallPeiCoreEntryPoint ENDP
+
+END
diff --git a/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/SecEntry.S b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/SecEntry.S
new file mode 100644
index 000000000..aff77f6f1
--- /dev/null
+++ b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/SecEntry.S
@@ -0,0 +1,336 @@
+#------------------------------------------------------------------------------
+#
+# 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
diff --git a/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/SecEntry.asm b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/SecEntry.asm
new file mode 100644
index 000000000..ab8d46e9e
--- /dev/null
+++ b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/SecEntry.asm
@@ -0,0 +1,353 @@
+;------------------------------------------------------------------------------
+;
+; 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.asm
+;
+; 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"
+
+.686p
+.xmm
+.model small, c
+
+EXTRN CallPeiCoreEntryPoint:NEAR
+EXTRN FsptUpdDataPtr:FAR
+
+; Pcds
+EXTRN PcdGet32 (PcdFsptBaseAddress):DWORD
+
+_TEXT_REALMODE SEGMENT PARA PUBLIC USE16 'CODE'
+ ASSUME CS:_TEXT_REALMODE, DS:_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
+_ModuleEntryPoint PROC NEAR C PUBLIC
+ fninit ; clear any pending Floating point exceptions
+ ;
+ ; Store the BIST value in mm0
+ ;
+ movd mm0, eax
+
+ ;
+ ; Save time-stamp counter value
+ ; rdtsc load 64bit time-stamp counter to EDX:EAX
+ ;
+ rdtsc
+ movd mm5, edx
+ movd mm6, eax
+
+ ;
+ ; Load the GDT table in GdtDesc
+ ;
+ mov esi, OFFSET GdtDesc
+ DB 66h
+ lgdt fword ptr cs:[si]
+
+ ;
+ ; Transition to 16 bit protected mode
+ ;
+ mov eax, cr0 ; Get control register 0
+ or eax, 00000003h ; Set PE bit (bit #0) & MP bit (bit #1)
+ mov cr0, eax ; Activate protected mode
+
+ mov eax, cr4 ; Get control register 4
+ or eax, 00000600h ; Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10)
+ mov cr4, eax
+
+ ;
+ ; Now we're in 16 bit protected mode
+ ; Set up the selectors for 32 bit protected mode entry
+ ;
+ mov ax, SYS_DATA_SEL
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+ mov ss, ax
+
+ ;
+ ; Transition to Flat 32 bit protected mode
+ ; The jump to a far pointer causes the transition to 32 bit mode
+ ;
+ mov esi, offset ProtectedModeEntryLinearAddress
+ jmp fword ptr cs:[si]
+
+_ModuleEntryPoint ENDP
+_TEXT_REALMODE ENDS
+
+_TEXT_PROTECTED_MODE SEGMENT PARA PUBLIC USE32 'CODE'
+ ASSUME CS:_TEXT_PROTECTED_MODE, DS:_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
+ProtectedModeEntryPoint PROC NEAR PUBLIC
+
+ ; Find the fsp info header
+ mov edi, PcdGet32 (PcdFsptBaseAddress)
+
+ mov eax, dword ptr [edi + FVH_SIGINATURE_OFFSET]
+ cmp eax, FVH_SIGINATURE_VALID_VALUE
+ jnz FspHeaderNotFound
+
+ xor eax, eax
+ mov ax, word ptr [edi + FVH_EXTHEADER_OFFSET_OFFSET]
+ cmp ax, 0
+ jnz FspFvExtHeaderExist
+
+ xor eax, eax
+ mov ax, word ptr [edi + FVH_HEADER_LENGTH_OFFSET] ; Bypass Fv Header
+ add edi, eax
+ jmp FspCheckFfsHeader
+
+FspFvExtHeaderExist:
+ add edi, eax
+ mov eax, dword ptr [edi + FVH_EXTHEADER_SIZE_OFFSET] ; Bypass Ext Fv Header
+ add edi, eax
+
+ ; Round up to 8 byte alignment
+ mov eax, edi
+ and al, 07h
+ jz FspCheckFfsHeader
+
+ and edi, 0FFFFFFF8h
+ add edi, 08h
+
+FspCheckFfsHeader:
+ ; Check the ffs guid
+ mov eax, dword ptr [edi]
+ cmp eax, FSP_HEADER_GUID_DWORD1
+ jnz FspHeaderNotFound
+
+ mov eax, dword ptr [edi + 4]
+ cmp eax, FSP_HEADER_GUID_DWORD2
+ jnz FspHeaderNotFound
+
+ mov eax, dword ptr [edi + 8]
+ cmp eax, FSP_HEADER_GUID_DWORD3
+ jnz FspHeaderNotFound
+
+ mov eax, dword ptr [edi + 0Ch]
+ cmp eax, FSP_HEADER_GUID_DWORD4
+ jnz FspHeaderNotFound
+
+ add edi, FFS_HEADER_SIZE_VALUE ; Bypass the ffs header
+
+ ; Check the section type as raw section
+ mov al, byte ptr [edi + SECTION_HEADER_TYPE_OFFSET]
+ cmp al, 019h
+ jnz FspHeaderNotFound
+
+ add edi, RAW_SECTION_HEADER_SIZE_VALUE ; Bypass the section header
+ jmp FspHeaderFound
+
+FspHeaderNotFound:
+ jmp $
+
+FspHeaderFound:
+ ; Get the fsp TempRamInit Api address
+ mov eax, dword ptr [edi + FSP_HEADER_IMAGEBASE_OFFSET]
+ add eax, dword ptr [edi + FSP_HEADER_TEMPRAMINIT_OFFSET]
+
+ ; Setup the hardcode stack
+ mov esp, OFFSET TempRamInitStack
+
+ ; Call the fsp TempRamInit Api
+ jmp eax
+
+TempRamInitDone:
+ cmp eax, 8000000Eh ;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 eax, 0 ;Check if EFI_SUCCESS retuned.
+ jnz FspApiFailed
+
+ ; ECX: start of range
+ ; EDX: end of range
+CallSecFspInit:
+ xor eax, eax
+ mov esp, edx
+
+ ; Align the stack at DWORD
+ add esp, 3
+ and esp, 0FFFFFFFCh
+
+ push edx
+ push ecx
+ push eax ; zero - no hob list yet
+ call CallPeiCoreEntryPoint
+
+FspApiFailed:
+ jmp $
+
+align 10h
+TempRamInitStack:
+ DD OFFSET TempRamInitDone
+ DD OFFSET FsptUpdDataPtr ; TempRamInitParams
+
+ProtectedModeEntryPoint ENDP
+
+;
+; ROM-based Global-Descriptor Table for the Tiano PEI Phase
+;
+align 16
+PUBLIC BootGdtTable
+
+;
+; GDT[0]: 0x00: Null entry, never used.
+;
+NULL_SEL EQU $ - GDT_BASE ; Selector [0]
+GDT_BASE:
+BootGdtTable DD 0
+ DD 0
+;
+; Linear data segment descriptor
+;
+LINEAR_SEL EQU $ - GDT_BASE ; Selector [0x8]
+ DW 0FFFFh ; limit 0xFFFFF
+ DW 0 ; base 0
+ DB 0
+ DB 092h ; present, ring 0, data, expand-up, writable
+ DB 0CFh ; page-granular, 32-bit
+ DB 0
+;
+; Linear code segment descriptor
+;
+LINEAR_CODE_SEL EQU $ - GDT_BASE ; Selector [0x10]
+ DW 0FFFFh ; limit 0xFFFFF
+ DW 0 ; base 0
+ DB 0
+ DB 09Bh ; present, ring 0, data, expand-up, not-writable
+ DB 0CFh ; page-granular, 32-bit
+ DB 0
+;
+; System data segment descriptor
+;
+SYS_DATA_SEL EQU $ - GDT_BASE ; Selector [0x18]
+ DW 0FFFFh ; limit 0xFFFFF
+ DW 0 ; base 0
+ DB 0
+ DB 093h ; present, ring 0, data, expand-up, not-writable
+ DB 0CFh ; page-granular, 32-bit
+ DB 0
+
+;
+; System code segment descriptor
+;
+SYS_CODE_SEL EQU $ - GDT_BASE ; Selector [0x20]
+ DW 0FFFFh ; limit 0xFFFFF
+ DW 0 ; base 0
+ DB 0
+ DB 09Ah ; present, ring 0, data, expand-up, writable
+ DB 0CFh ; page-granular, 32-bit
+ DB 0
+;
+; Spare segment descriptor
+;
+SYS16_CODE_SEL EQU $ - GDT_BASE ; Selector [0x28]
+ DW 0FFFFh ; limit 0xFFFFF
+ DW 0 ; base 0
+ DB 0Eh ; Changed from F000 to E000.
+ DB 09Bh ; present, ring 0, code, expand-up, writable
+ DB 00h ; byte-granular, 16-bit
+ DB 0
+;
+; Spare segment descriptor
+;
+SYS16_DATA_SEL EQU $ - GDT_BASE ; Selector [0x30]
+ DW 0FFFFh ; limit 0xFFFF
+ DW 0 ; base 0
+ DB 0
+ DB 093h ; present, ring 0, data, expand-up, not-writable
+ DB 00h ; byte-granular, 16-bit
+ DB 0
+
+;
+; Spare segment descriptor
+;
+SPARE5_SEL EQU $ - GDT_BASE ; Selector [0x38]
+ DW 0 ; limit 0
+ DW 0 ; base 0
+ DB 0
+ DB 0 ; present, ring 0, data, expand-up, writable
+ DB 0 ; page-granular, 32-bit
+ DB 0
+GDT_SIZE EQU $ - BootGdtTable ; Size, in bytes
+
+;
+; GDT Descriptor
+;
+GdtDesc: ; GDT descriptor
+ DW GDT_SIZE - 1 ; GDT limit
+ DD OFFSET BootGdtTable ; GDT base address
+
+
+ProtectedModeEntryLinearAddress LABEL FWORD
+ProtectedModeEntryLinearOffset LABEL DWORD
+ DD OFFSET ProtectedModeEntryPoint ; Offset of our 32 bit code
+ DW LINEAR_CODE_SEL
+
+_TEXT_PROTECTED_MODE ENDS
+END
diff --git a/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/Stack.S b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/Stack.S
new file mode 100644
index 000000000..ae4293589
--- /dev/null
+++ b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/Stack.S
@@ -0,0 +1,77 @@
+#------------------------------------------------------------------------------
+#
+# 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.
+#
+# Abstract:
+#
+# Switch the stack from temporary memory to permenent memory.
+#
+#------------------------------------------------------------------------------
+
+
+#------------------------------------------------------------------------------
+# VOID
+# EFIAPI
+# SecSwitchStack (
+# UINT32 TemporaryMemoryBase,
+# UINT32 PermanentMemoryBase
+# )#
+#------------------------------------------------------------------------------
+ASM_GLOBAL ASM_PFX (SecSwitchStack)
+ASM_PFX(SecSwitchStack):
+ #
+ # Save standard registers so they can be used to change stack
+ #
+ pushl %eax
+ pushl %ebx
+ pushl %ecx
+ pushl %edx
+
+ #
+ # !!CAUTION!! this function address's is pushed into stack after
+ # migration of whole temporary memory, so need save it to permanent
+ # memory at first!
+ #
+ movl 20(%esp), %ebx # Save the first parameter
+ movl 24(%esp), %ecx # Save the second parameter
+
+ #
+ # Save this function's return address into permanent memory at first.
+ # Then, Fixup the esp point to permanent memory
+ #
+ movl %esp, %eax
+ subl %ebx, %eax
+ addl %ecx, %eax
+ movl 0(%esp), %edx # copy pushed register's value to permanent memory
+ movl %edx, 0(%eax)
+ movl 4(%esp), %edx
+ movl %edx, 4(%eax)
+ movl 8(%esp), %edx
+ movl %edx, 8(%eax)
+ movl 12(%esp), %edx
+ movl %edx, 12(%eax)
+ movl 16(%esp), %edx # Update this function's return address into permanent memory
+ movl %edx, 16(%eax)
+ movl %eax, %esp # From now, esp is pointed to permanent memory
+
+ #
+ # Fixup the ebp point to permanent memory
+ #
+ movl %ebp, %eax
+ subl %ebx, %eax
+ addl %ecx, %eax
+ movl %eax, %ebp # From now, ebp is pointed to permanent memory
+
+ popl %edx
+ popl %ecx
+ popl %ebx
+ popl %eax
+ ret
+
diff --git a/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/Stack.asm b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/Stack.asm
new file mode 100644
index 000000000..116b738fc
--- /dev/null
+++ b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/Stack.asm
@@ -0,0 +1,82 @@
+;------------------------------------------------------------------------------
+;
+; 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.
+;
+; Abstract:
+;
+; Switch the stack from temporary memory to permenent memory.
+;
+;------------------------------------------------------------------------------
+
+ .586p
+ .model flat,C
+ .code
+
+;------------------------------------------------------------------------------
+; VOID
+; EFIAPI
+; SecSwitchStack (
+; UINT32 TemporaryMemoryBase,
+; UINT32 PermanentMemoryBase
+; );
+;------------------------------------------------------------------------------
+SecSwitchStack PROC
+ ;
+ ; Save three register: eax, ebx, ecx
+ ;
+ push eax
+ push ebx
+ push ecx
+ push edx
+
+ ;
+ ; !!CAUTION!! this function address's is pushed into stack after
+ ; migration of whole temporary memory, so need save it to permanent
+ ; memory at first!
+ ;
+
+ mov ebx, [esp + 20] ; Save the first parameter
+ mov ecx, [esp + 24] ; Save the second parameter
+
+ ;
+ ; Save this function's return address into permanent memory at first.
+ ; Then, Fixup the esp point to permanent memory
+ ;
+ mov eax, esp
+ sub eax, ebx
+ add eax, ecx
+ mov edx, dword ptr [esp] ; copy pushed register's value to permanent memory
+ mov dword ptr [eax], edx
+ mov edx, dword ptr [esp + 4]
+ mov dword ptr [eax + 4], edx
+ mov edx, dword ptr [esp + 8]
+ mov dword ptr [eax + 8], edx
+ mov edx, dword ptr [esp + 12]
+ mov dword ptr [eax + 12], edx
+ mov edx, dword ptr [esp + 16] ; Update this function's return address into permanent memory
+ mov dword ptr [eax + 16], edx
+ mov esp, eax ; From now, esp is pointed to permanent memory
+
+ ;
+ ; Fixup the ebp point to permanent memory
+ ;
+ mov eax, ebp
+ sub eax, ebx
+ add eax, ecx
+ mov ebp, eax ; From now, ebp is pointed to permanent memory
+
+ pop edx
+ pop ecx
+ pop ebx
+ pop eax
+ ret
+SecSwitchStack ENDP
+
+ END