summaryrefslogtreecommitdiff
path: root/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32
diff options
context:
space:
mode:
Diffstat (limited to 'Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32')
-rw-r--r--Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/AsmSaveSecContext.asm51
-rw-r--r--Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/Fsp.inc51
-rw-r--r--Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/PeiCoreEntry.asm141
-rw-r--r--Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/SecEntry.asm344
-rw-r--r--Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/Stack.S77
-rw-r--r--Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/Stack.asm82
6 files changed, 746 insertions, 0 deletions
diff --git a/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/AsmSaveSecContext.asm b/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/AsmSaveSecContext.asm
new file mode 100644
index 0000000000..703b38b52e
--- /dev/null
+++ b/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/AsmSaveSecContext.asm
@@ -0,0 +1,51 @@
+;------------------------------------------------------------------------------
+;
+; 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 two basic APIs from FSP binary.
+;
+;------------------------------------------------------------------------------
+
+.686p
+.xmm
+.model flat,c
+.code
+
+;----------------------------------------------------------------------------
+; MMX Usage:
+; MM0 = BIST State
+; MM5 = Save time-stamp counter value high32bit
+; MM6 = Save time-stamp counter value low32bit.
+;
+; It should be same as SecEntry.asm and PeiCoreEntry.asm.
+;----------------------------------------------------------------------------
+
+AsmSaveBistValue PROC PUBLIC
+ mov eax, [esp+4]
+ movd mm0, eax
+ ret
+AsmSaveBistValue ENDP
+
+AsmSaveTickerValue PROC PUBLIC
+ mov eax, [esp+4]
+ movd mm6, eax
+ mov eax, [esp+8]
+ movd mm5, eax
+ ret
+AsmSaveTickerValue ENDP
+
+END
diff --git a/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/Fsp.inc b/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/Fsp.inc
new file mode 100644
index 0000000000..296c47eb1d
--- /dev/null
+++ b/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/Fsp.inc
@@ -0,0 +1,51 @@
+;------------------------------------------------------------------------------
+;
+; 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:
+;
+; Fsp.inc
+;
+; Abstract:
+;
+; Fsp related definitions
+;
+;------------------------------------------------------------------------------
+
+
+;
+; Fv Header
+;
+FVH_SIGINATURE_OFFSET EQU 028h
+FVH_SIGINATURE_VALID_VALUE EQU 04856465Fh ; valid signature:_FVH
+FVH_HEADER_LENGTH_OFFSET EQU 030h
+FVH_EXTHEADER_OFFSET_OFFSET EQU 034h
+FVH_EXTHEADER_SIZE_OFFSET EQU 010h
+
+;
+; Ffs Header
+;
+FSP_HEADER_GUID_DWORD1 EQU 0912740BEh
+FSP_HEADER_GUID_DWORD2 EQU 047342284h
+FSP_HEADER_GUID_DWORD3 EQU 0B08471B9h
+FSP_HEADER_GUID_DWORD4 EQU 00C3F3527h
+FFS_HEADER_SIZE_VALUE EQU 018h
+
+;
+; Section Header
+;
+SECTION_HEADER_TYPE_OFFSET EQU 03h
+RAW_SECTION_HEADER_SIZE_VALUE EQU 04h
+
+;
+; Fsp Header
+;
+FSP_HEADER_IMAGEBASE_OFFSET EQU 01Ch
+FSP_HEADER_TEMPRAMINIT_OFFSET EQU 030h
diff --git a/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/PeiCoreEntry.asm b/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/PeiCoreEntry.asm
new file mode 100644
index 0000000000..59350344b4
--- /dev/null
+++ b/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/PeiCoreEntry.asm
@@ -0,0 +1,141 @@
+;------------------------------------------------------------------------------
+;
+; 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 two basic APIs from FSP binary.
+;
+;------------------------------------------------------------------------------
+
+.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/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/SecEntry.asm b/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/SecEntry.asm
new file mode 100644
index 0000000000..f8a318252e
--- /dev/null
+++ b/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/SecEntry.asm
@@ -0,0 +1,344 @@
+;------------------------------------------------------------------------------
+;
+; 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 two basic APIs from FSP binary.
+;
+;------------------------------------------------------------------------------
+ INCLUDE Fsp.inc
+
+.686p
+.xmm
+.model small, c
+
+EXTRN CallPeiCoreEntryPoint:NEAR
+EXTRN TempRamInitParams:FAR
+
+; Pcds
+EXTRN PcdGet32 (PcdFlashFvFspBase):DWORD
+EXTRN PcdGet32 (PcdFlashFvFspSize):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 (PcdFlashFvFspBase)
+ mov ecx, PcdGet32 (PcdFlashFvFspSize)
+
+ 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, 0
+ jnz FspApiFailed
+
+ ; ECX: start of range
+ ; EDX: end of range
+ mov esp, edx
+ push edx
+ push ecx
+ push eax ; zero - no hob list yet
+ call CallPeiCoreEntryPoint
+
+FspApiFailed:
+ jmp $
+
+align 10h
+TempRamInitStack:
+ DD OFFSET TempRamInitDone
+ DD OFFSET 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/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/Stack.S b/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/Stack.S
new file mode 100644
index 0000000000..950b3a1f0a
--- /dev/null
+++ b/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/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 PermenentMemoryBase
+# )#
+#------------------------------------------------------------------------------
+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 permenent
+ # 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 permenent memory at first.
+ # Then, Fixup the esp point to permenent memory
+ #
+ movl %esp, %eax
+ subl %ebx, %eax
+ addl %ecx, %eax
+ movl 0(%esp), %edx # copy pushed register's value to permenent 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 permenent memory
+ movl %edx, 16(%eax)
+ movl %eax, %esp # From now, esp is pointed to permenent memory
+
+ #
+ # Fixup the ebp point to permenent memory
+ #
+ movl %ebp, %eax
+ subl %ebx, %eax
+ addl %ecx, %eax
+ movl %eax, %ebp # From now, ebp is pointed to permenent memory
+
+ popl %edx
+ popl %ecx
+ popl %ebx
+ popl %eax
+ ret
+
diff --git a/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/Stack.asm b/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/Stack.asm
new file mode 100644
index 0000000000..f96a55f040
--- /dev/null
+++ b/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/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 PermenentMemoryBase
+; );
+;------------------------------------------------------------------------------
+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 permenent
+ ; 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 permenent memory at first.
+ ; Then, Fixup the esp point to permenent memory
+ ;
+ mov eax, esp
+ sub eax, ebx
+ add eax, ecx
+ mov edx, dword ptr [esp] ; copy pushed register's value to permenent 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 permenent memory
+ mov dword ptr [eax + 16], edx
+ mov esp, eax ; From now, esp is pointed to permenent memory
+
+ ;
+ ; Fixup the ebp point to permenent memory
+ ;
+ mov eax, ebp
+ sub eax, ebx
+ add eax, ecx
+ mov ebp, eax ; From now, ebp is pointed to permenent memory
+
+ pop edx
+ pop ecx
+ pop ebx
+ pop eax
+ ret
+SecSwitchStack ENDP
+
+ END