]> git.proxmox.com Git - mirror_edk2.git/blobdiff - IntelFspPkg/FspSecCore/Ia32/FspApiEntry.s
Fix FSP GCC error on FspApiCallingCheck().
[mirror_edk2.git] / IntelFspPkg / FspSecCore / Ia32 / FspApiEntry.s
index 203efd9e424c58afa27113393aa404345d3de48e..8f4093ca1940a7adad50ba5b895950ec0ea51fb5 100644 (file)
 #\r
 #------------------------------------------------------------------------------\r
 \r
-#.INCLUDE   "UcodeLoadGcc.inc" - begin\r
 \r
 .equ MSR_IA32_PLATFORM_ID,                   0x00000017\r
 .equ MSR_IA32_BIOS_UPDT_TRIG,                0x00000079\r
 .equ MSR_IA32_BIOS_SIGN_ID,                  0x0000008b\r
 \r
-Ucode:\r
-.equ        UcodeVersion,                    0x0000\r
-.equ        UcodeRevision,                   0x0004\r
-.equ        UcodeDate,                       0x0008\r
-.equ        UcodeProcessor,                  0x000C\r
-.equ        UcodeChecksum,                   0x0010\r
-.equ        UcodeLoader,                     0x0014\r
-.equ        UcodeRsvd,                       0x0018\r
-UcodeEnd:\r
-\r
-UcodeHdr:\r
-.equ        UcodeHdrVersion,                 0x0000\r
-.equ        UcodeHdrRevision,                0x0004\r
-.equ        UcodeHdrDate,                    0x0008\r
-.equ        UcodeHdrProcessor,               0x000c\r
-.equ        UcodeHdrChecksum,                0x0010\r
-.equ        UcodeHdrLoader,                  0x0014\r
-.equ        UcodeHdrFlags,                   0x0018\r
-.equ        UcodeHdrDataSize,                0x001C\r
-.equ        UcodeHdrTotalSize,               0x0020\r
-.equ        UcodeHdrRsvd,                    0x0024\r
-UcodeHdrEnd:\r
-.equ        UcodeHdrLength,                  0x0030  # UcodeHdrLength = UcodeHdrEnd - UcodeHdr\r
+\r
+MicrocodeHdr:\r
+.equ        MicrocodeHdrVersion,                 0x0000\r
+.equ        MicrocodeHdrRevision,                0x0004\r
+.equ        MicrocodeHdrDate,                    0x0008\r
+.equ        MicrocodeHdrProcessor,               0x000c\r
+.equ        MicrocodeHdrChecksum,                0x0010\r
+.equ        MicrocodeHdrLoader,                  0x0014\r
+.equ        MicrocodeHdrFlags,                   0x0018\r
+.equ        MicrocodeHdrDataSize,                0x001C\r
+.equ        MicrocodeHdrTotalSize,               0x0020\r
+.equ        MicrocodeHdrRsvd,                    0x0024\r
+MicrocodeHdrEnd:\r
+.equ        MicrocodeHdrLength,                  0x0030  # MicrocodeHdrLength = MicrocodeHdrEnd - MicrocodeHdr\r
 \r
 \r
 ExtSigHdr:\r
 .equ        ExtSigHdrCount,                  0x0000\r
 .equ        ExtSigHdrChecksum,               0x0004\r
-.equ        rsvd,                            0x0008\r
+.equ        ExtSigHdrRsvd,                   0x0008\r
 ExtSigHdrEnd:\r
 .equ        ExtSigHdrLength,                 0x0014  #ExtSigHdrLength = ExtSigHdrEnd - ExtSigHdr\r
 \r
@@ -60,14 +50,12 @@ ExtSig:
 ExtSigEnd:\r
 .equ        ExtSigLength,                    0x000C  #ExtSigLength = ExtSigEnd - ExtSig\r
 \r
-LoadUcodeParams:\r
-.equ        LoadUcodeParamsUcodeCodeAddr,    0x0000\r
-.equ        LoadUcodeParamsUcodeCodeSize,    0x0004\r
-LoadUcodeParamsEnd:\r
+LoadMicrocodeParams:\r
+.equ        MicrocodeCodeAddr,               0x0000\r
+.equ        MicrocodeCodeSize,               0x0004\r
+LoadMicrocodeParamsEnd:\r
 \r
-#.INCLUDE   "UcodeLoadGcc.inc" - end\r
 \r
-#.INCLUDE   "SaveRestoreSseGcc.inc" - begin\r
 \r
 .macro SAVE_REGS\r
   pinsrw     $0x00, %ebp, %xmm7\r
@@ -147,12 +135,68 @@ LoadUcodeParamsEnd:
 .endm\r
 \r
 .macro ENABLE_SSE\r
-  movl       %cr4, %eax\r
-  orl        $0x00000600, %eax               # Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10)\r
-  movl       %eax,%cr4\r
+    jmp     NextAddress\r
+.align 4\r
+    #\r
+    # Float control word initial value:\r
+    # all exceptions masked, double-precision, round-to-nearest\r
+    #\r
+ASM_PFX(mFpuControlWord): .word     0x027F\r
+    #\r
+    # Multimedia-extensions control word:\r
+    # all exceptions masked, round-to-nearest, flush to zero for masked underflow\r
+    #\r
+ASM_PFX(mMmxControlWord): .long     0x01F80\r
+SseError:      \r
+    #\r
+    # Processor has to support SSE\r
+    #\r
+    jmp     SseError      \r
+NextAddress:            \r
+    #\r
+    # Initialize floating point units\r
+    #\r
+    finit\r
+    fldcw   ASM_PFX(mFpuControlWord)\r
+\r
+    #\r
+    # Use CpuId instructuion (CPUID.01H:EDX.SSE[bit 25] = 1) to test\r
+    # whether the processor supports SSE instruction.\r
+    #\r
+    movl    $1,  %eax\r
+    cpuid\r
+    btl     $25, %edx\r
+    jnc     SseError\r
+\r
+    #\r
+    # Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10)\r
+    #\r
+    movl    %cr4, %eax\r
+    orl     $BIT9, %eax\r
+    movl    %eax, %cr4\r
+\r
+    #\r
+    # The processor should support SSE instruction and we can use\r
+    # ldmxcsr instruction\r
+    #\r
+    ldmxcsr ASM_PFX(mMmxControlWord)\r
+.endm\r
+\r
+#Save in ECX-SLOT 3 in xmm6.\r
+.macro SAVE_EAX_MICROCODE_RET_STATUS\r
+  pinsrw     $0x6, %eax, %xmm6\r
+  ror        $0x10, %eax\r
+  pinsrw     $0x7, %eax, %xmm6\r
+  rol        $0x10, %eax\r
+.endm\r
+\r
+#Restore from ECX-SLOT 3 in xmm6.\r
+.macro LOAD_EAX_MICROCODE_RET_STATUS\r
+  pshufd     $0x93, %xmm6, %xmm6\r
+  movd       %xmm6, %eax\r
+  pshufd     $0x39, %xmm6, %xmm6\r
 .endm\r
 \r
-#.INCLUDE   "SaveRestoreSseGcc.inc" - end\r
 \r
 \r
 #\r
@@ -171,8 +215,10 @@ ASM_GLOBAL    ASM_PFX(FspApiCallingCheck)
 #\r
 # Following functions will be provided in PlatformSecLib\r
 #\r
+ASM_GLOBAL    ASM_PFX(AsmGetFspBaseAddress)\r
+ASM_GLOBAL    ASM_PFX(AsmGetFspInfoHeader)\r
 ASM_GLOBAL    ASM_PFX(GetBootFirmwareVolumeOffset)\r
-ASM_GLOBAL    ASM_PFX(Pei2LoaderSwitchStack)\r
+ASM_GLOBAL    ASM_PFX(Loader2PeiSwitchStack)\r
 \r
 \r
 #\r
@@ -183,54 +229,32 @@ ASM_GLOBAL    ASM_PFX(Pei2LoaderSwitchStack)
 .equ          DATA_LEN_AT_STACK_TOP, (DATA_LEN_OF_PER0 + DATA_LEN_OF_MCUD + 4)\r
 \r
 #------------------------------------------------------------------------------\r
-# FspSelfCheckDflt\r
+# SecPlatformInitDefault\r
 # Inputs:\r
-#   eax -> Return address\r
+#   mm7 -> Return address\r
 # Outputs:\r
 #   eax -> 0 - Successful, Non-zero - Failed.\r
 # Register Usage:\r
 #   eax is cleared and ebp is used for return address.\r
 #   All others reserved.\r
 #------------------------------------------------------------------------------\r
-ASM_GLOBAL ASM_PFX(FspSelfCheckDflt)\r
-ASM_PFX(FspSelfCheckDflt):\r
+ASM_GLOBAL ASM_PFX(SecPlatformInitDefault)\r
+ASM_PFX(SecPlatformInitDefault):\r
    #\r
    # Save return address to EBP\r
    #\r
-   movl  %eax, %ebp\r
-   xorl  %eax, %eax\r
-\r
-FspSelfCheckDfltExit:\r
-   jmp   *%ebp\r
-\r
-\r
-#------------------------------------------------------------------------------\r
-# PlatformBasicInitDflt\r
-# Inputs:\r
-#   eax -> Return address\r
-# Outputs:\r
-#   eax -> 0 - Successful, Non-zero - Failed.\r
-# Register Usage:\r
-#   eax is cleared and ebp is used for return address.\r
-#   All others reserved.\r
-#------------------------------------------------------------------------------\r
-ASM_GLOBAL ASM_PFX(PlatformBasicInitDflt)\r
-ASM_PFX(PlatformBasicInitDflt):\r
-   #\r
-   # Save return address to EBP\r
-   #\r
-   movl   %eax, %ebp\r
+   movd   %mm7, %ebp\r
    xorl   %eax, %eax\r
 \r
-PlatformBasicInitDfltExit:\r
+SecPlatformInitDefaultExit:\r
    jmp   *%ebp\r
 \r
 \r
 #------------------------------------------------------------------------------\r
-# LoadUcode\r
+# LoadMicrocodeDefault\r
 #\r
 # Inputs:\r
-#   esp -> LOAD_UCODE_PARAMS pointer\r
+#   esp -> LoadMicrocodeParams pointer\r
 # Register Usage:\r
 #   esp  Preserved\r
 #   All others destroyed\r
@@ -239,26 +263,26 @@ PlatformBasicInitDfltExit:
 #   Executed by SBSP and NBSP\r
 #   Beginning of microcode update region starts on paragraph boundary\r
 #------------------------------------------------------------------------------\r
-ASM_GLOBAL ASM_PFX(LoadUcode)\r
-ASM_PFX(LoadUcode):   \r
+ASM_GLOBAL ASM_PFX(LoadMicrocodeDefault)\r
+ASM_PFX(LoadMicrocodeDefault):\r
    #\r
    # Save return address to EBP\r
    #\r
-   movd   %xmm7, %ebp\r
+   movd   %mm7, %ebp\r
 \r
    cmpl   $0x00, %esp\r
    jz     ParamError\r
-   movl   (%esp), %eax                       #dword ptr []     Parameter pointer\r
+   movl   4(%esp), %eax                       #dword ptr []     Parameter pointer\r
    cmpl   $0x00, %eax\r
    jz     ParamError\r
    movl   %eax, %esp\r
-   movl   LoadUcodeParamsUcodeCodeAddr(%esp), %esi          #mov    esi, [esp].LOAD_UCODE_PARAMS.ucode_code_addr\r
+   movl   MicrocodeCodeAddr(%esp), %esi\r
    cmpl   $0x00, %esi\r
    jnz    CheckMainHeader\r
 \r
 ParamError:\r
    movl   $0x080000002, %eax\r
-   jmp    LoadUcodeExit\r
+   jmp    LoadMicrocodeExit\r
 \r
 CheckMainHeader:\r
    #\r
@@ -291,68 +315,68 @@ CheckMainHeader:
    # Minimal test checking for header version and loader version as 1\r
    #\r
    movl   $0x01, %eax\r
-   cmpl   %eax, UcodeHdrVersion(%esi)        #cmp   [esi].ucode_hdr.version, eax\r
+   cmpl   %eax, MicrocodeHdrVersion(%esi)\r
    jne    AdvanceFixedSize\r
-   cmpl   %eax, UcodeHdrLoader(%esi)         #cmp   [esi].ucode_hdr.loader, eax\r
+   cmpl   %eax, MicrocodeHdrLoader(%esi)\r
    jne    AdvanceFixedSize\r
 \r
    #\r
    # Check if signature and plaform ID match\r
    #\r
-   cmpl   UcodeHdrProcessor(%esi), %ebx      #cmp   ebx, [esi].ucode_hdr.processor \r
-   jne    LoadUcodeL0\r
-   testl  UcodeHdrFlags(%esi), %edx          #test  edx, [esi].ucode_hdr.flags\r
+   cmpl   MicrocodeHdrProcessor(%esi), %ebx\r
+   jne    LoadMicrocodeL0\r
+   testl  MicrocodeHdrFlags(%esi), %edx\r
    jnz    LoadCheck                          #Jif signature and platform ID match\r
 \r
-LoadUcodeL0:\r
+LoadMicrocodeL0:\r
    #\r
    # Check if extended header exists\r
-   # First check if total_size and data_size are valid\r
+   # First check if MicrocodeHdrTotalSize and MicrocodeHdrDataSize are valid\r
    #\r
    xorl   %eax, %eax\r
-   cmpl   %eax, UcodeHdrTotalSize(%esi)      #cmp   [esi].ucode_hdr.total_size, eax\r
+   cmpl   %eax, MicrocodeHdrTotalSize(%esi)\r
    je     NextMicrocode\r
-   cmpl   %eax, UcodeHdrDataSize(%esi)       #cmp   [esi].ucode_hdr.data_size, eax\r
+   cmpl   %eax, MicrocodeHdrDataSize(%esi)\r
    je     NextMicrocode\r
 \r
    #\r
    # Then verify total size - sizeof header > data size\r
    #\r
-   movl   UcodeHdrTotalSize(%esi), %ecx      #mov   ecx, [esi].ucode_hdr.total_size\r
-   subl   $UcodeHdrLength, %ecx              #sub   ecx, sizeof ucode_hdr\r
-   cmpl   UcodeHdrDataSize(%esi), %ecx       #cmp   ecx, [esi].ucode_hdr.data_size\r
-   jle NextMicrocode                         \r
+   movl   MicrocodeHdrTotalSize(%esi), %ecx\r
+   subl   $MicrocodeHdrLength, %ecx\r
+   cmpl   MicrocodeHdrDataSize(%esi), %ecx\r
+   jle NextMicrocode\r
 \r
    #\r
    # Set edi -> extended header\r
    #\r
    movl   %esi, %edi\r
-   addl   $UcodeHdrLength, %edi              #add   edi, sizeof ucode_hdr\r
-   addl   UcodeHdrDataSize(%esi), %edi       #add   edi, [esi].ucode_hdr.data_size\r
+   addl   $MicrocodeHdrLength, %edi\r
+   addl   MicrocodeHdrDataSize(%esi), %edi\r
 \r
    #\r
    # Get count of extended structures\r
    #\r
-   movl   ExtSigHdrCount(%edi), %ecx         #mov   ecx, [edi].ext_sig_hdr.count\r
+   movl   ExtSigHdrCount(%edi), %ecx\r
 \r
    #\r
    # Move pointer to first signature structure\r
    #\r
-   addl   ExtSigHdrLength, %edi              #add   edi, sizeof ext_sig_hdr\r
+   addl   ExtSigHdrLength, %edi\r
 \r
 CheckExtSig:\r
    #\r
    # Check if extended signature and platform ID match\r
    #\r
-   cmpl   %ebx, ExtSigProcessor(%edi)        #cmp   [edi].ext_sig.processor, ebx\r
-   jne    LoadUcodeL1\r
-   test   %edx, ExtSigFlags(%edi)            #test  [edi].ext_sig.flags, edx\r
+   cmpl   %ebx, ExtSigProcessor(%edi)\r
+   jne    LoadMicrocodeL1\r
+   test   %edx, ExtSigFlags(%edi)\r
    jnz    LoadCheck                          # Jif signature and platform ID match\r
-LoadUcodeL1:\r
+LoadMicrocodeL1:\r
    #\r
    # Check if any more extended signatures exist\r
    #\r
-   addl   $ExtSigLength, %edi                #add   edi, sizeof ext_sig\r
+   addl   $ExtSigLength, %edi\r
    loop   CheckExtSig\r
 \r
 NextMicrocode:\r
@@ -360,11 +384,11 @@ NextMicrocode:
    # Advance just after end of this microcode\r
    #\r
    xorl   %eax, %eax\r
-   cmpl   %eax, UcodeHdrTotalSize(%esi)      #cmp   [esi].ucode_hdr.total_size, eax\r
-   je     LoadUcodeL2\r
-   addl   UcodeHdrTotalSize(%esi), %esi      #add   esi, [esi].ucode_hdr.total_size\r
+   cmpl   %eax, MicrocodeHdrTotalSize(%esi)\r
+   je     LoadMicrocodeL2\r
+   addl   MicrocodeHdrTotalSize(%esi), %esi\r
    jmp    CheckAddress\r
-LoadUcodeL2:\r
+LoadMicrocodeL2:\r
    addl   $0x800, %esi                       #add   esi, dword ptr 2048\r
    jmp    CheckAddress\r
 \r
@@ -378,24 +402,24 @@ CheckAddress:
    #\r
    # Is valid Microcode start point ?\r
    #\r
-   cmpl   $0x0ffffffff, UcodeHdrVersion(%esi)\r
+   cmpl   $0x0ffffffff, MicrocodeHdrVersion(%esi)\r
 \r
    #\r
    # Is automatic size detection ?\r
    #\r
-   movl   LoadUcodeParamsUcodeCodeSize(%esp), %eax\r
+   movl   MicrocodeCodeSize(%esp), %eax\r
    cmpl   $0x0ffffffff, %eax\r
-   jz     LoadUcodeL3\r
+   jz     LoadMicrocodeL3\r
    #\r
    # Address >= microcode region address + microcode region size?\r
    #\r
-   addl   LoadUcodeParamsUcodeCodeAddr(%esp), %eax                    #mov   eax, [esp].LOAD_UCODE_PARAMS.ucode_code_addr\r
+   addl   MicrocodeCodeAddr(%esp), %eax\r
 \r
    cmpl   %eax, %esi\r
-   jae    Done                               #Jif address is outside of ucode region\r
+   jae    Done                               #Jif address is outside of microcode region\r
    jmp    CheckMainHeader\r
 \r
-LoadUcodeL3:\r
+LoadMicrocodeL3:\r
 LoadCheck:\r
    #\r
    # Get the revision of the current microcode update loaded\r
@@ -413,10 +437,10 @@ LoadCheck:
    #\r
    # Verify this microcode update is not already loaded\r
    #\r
-   cmpl   %edx, UcodeHdrRevision(%esi)       #cmp   [esi].ucode_hdr.revision, edx\r
+   cmpl   %edx, MicrocodeHdrRevision(%esi)\r
    je     Continue\r
 \r
-LoadMicrocode:\r
+LoadMicrocode0:\r
    #\r
    # EAX contains the linear address of the start of the Update Data\r
    # EDX contains zero\r
@@ -424,7 +448,7 @@ LoadMicrocode:
    # Start microcode load with wrmsr\r
    #\r
    movl   %esi, %eax\r
-   addl   $UcodeHdrLength, %eax              #add   eax, sizeof ucode_hdr\r
+   addl   $MicrocodeHdrLength, %eax\r
    xorl   %edx, %edx\r
    movl   $MSR_IA32_BIOS_UPDT_TRIG, %ecx\r
    wrmsr\r
@@ -441,26 +465,24 @@ Done:
    rdmsr                                     # Get current microcode signature\r
    xorl   %eax, %eax\r
    cmpl   $0x00, %edx\r
-   jnz    LoadUcodeExit\r
+   jnz    LoadMicrocodeExit\r
    movl   $0x08000000E, %eax\r
 \r
-LoadUcodeExit:\r
+LoadMicrocodeExit:\r
    jmp   *%ebp\r
 \r
 \r
 #----------------------------------------------------------------------------\r
 # EstablishStackFsp\r
 #\r
-# Following is the code copied from BYTFSP, need to figure out what it is doing..\r
-#\r
 #----------------------------------------------------------------------------\r
 ASM_GLOBAL ASM_PFX(EstablishStackFsp)\r
 ASM_PFX(EstablishStackFsp):\r
   #\r
-  # Save parameter pointer in edx  \r
+  # Save parameter pointer in edx\r
   #\r
   movl    4(%esp), %edx\r
-              \r
+\r
   #\r
   # Enable FSP STACK\r
   #\r
@@ -471,25 +493,17 @@ ASM_PFX(EstablishStackFsp):
   pushl   $0x4455434D                        # Signature of the  data region 'MCUD'\r
   pushl   12(%edx)                           # Code size\r
   pushl   8(%edx)                            # Code base\r
-  cmpl    $0, %edx                           # Is parameter pointer valid ?\r
-  jz      InvalidMicrocodeRegion\r
   pushl   4(%edx)                            # Microcode size\r
   pushl   (%edx)                             # Microcode base\r
-  jmp     EstablishStackFspExit\r
 \r
-InvalidMicrocodeRegion:\r
-  push    $0                                 # Microcode size\r
-  push    $0                                 # Microcode base\r
-    \r
-EstablishStackFspExit:\r
   #\r
   # Save API entry/exit timestamp into stack\r
   #\r
   pushl   $DATA_LEN_OF_PER0                  # Size of the data region\r
   pushl   $0x30524550                        # Signature of the  data region 'PER0'\r
-  movd    %xmm4, %eax\r
-  pushl   %eax\r
-  movd    %xmm5, %eax\r
+  LOAD_EDX\r
+  pushl   %edx\r
+  LOAD_EAX\r
   pushl   %eax\r
   rdtsc\r
   pushl   %edx\r
@@ -497,11 +511,11 @@ EstablishStackFspExit:
 \r
   #\r
   # Terminator for the data on stack\r
-  # \r
+  #\r
   push    $0x00\r
 \r
   #\r
-  # Set ECX/EDX to the bootloader temporary memory range\r
+  # Set ECX/EDX to the BootLoader temporary memory range\r
   #\r
   movl       PcdGet32 (PcdTemporaryRamBase), %ecx\r
   movl       %ecx, %edx\r
@@ -509,7 +523,7 @@ EstablishStackFspExit:
   subl       PcdGet32 (PcdFspTemporaryRamSize), %edx\r
 \r
   xorl       %eax, %eax\r
\r
+\r
   movd       %mm7, %esi                      #RET_ESI\r
   jmp        *%esi\r
 \r
@@ -534,58 +548,67 @@ ASM_PFX(TempRamInitApi):
   SAVE_REGS\r
 \r
   #\r
-  # Save timestamp into XMM4 & XMM5\r
+  # Save timestamp into XMM6\r
   #\r
   rdtsc\r
-  movd    %edx, %xmm4\r
-  movd    %eax, %xmm5\r
+  SAVE_EAX\r
+  SAVE_EDX\r
 \r
   #\r
-  # CPUID/DeviceID check\r
+  # Check Parameter\r
   #\r
-  movl    $TempRamInitApiL0, %eax\r
-  jmp     ASM_PFX(FspSelfCheckDflt)  # @note: ESP can not be changed.\r
-TempRamInitApiL0:\r
+  movl    4(%esp), %eax\r
   cmpl    $0x00, %eax\r
-  jnz     NemInitExit\r
+  movl    $0x80000002, %eax\r
+  jz      NemInitExit\r
 \r
   #\r
   # Sec Platform Init\r
   #\r
   movl    $TempRamInitApiL1, %esi            #CALL_MMX  SecPlatformInit\r
-  movd    %mm7, %esi\r
+  movd    %esi, %mm7\r
+  .weak   ASM_PFX(SecPlatformInit)\r
+  .set    ASM_PFX(SecPlatformInit), ASM_PFX(SecPlatformInitDefault)\r
   jmp     ASM_PFX(SecPlatformInit)\r
 TempRamInitApiL1:\r
+  cmpl    $0x00, %eax\r
+  jnz     NemInitExit\r
 \r
   #\r
-  # Call Sec CAR Init\r
+  # Load microcode\r
   #\r
-  movl    $TempRamInitApiL2, %esi            #CALL_MMX  SecCarInit\r
-  movd    %mm7, %esi\r
-  jmp     ASM_PFX(SecCarInit)\r
+  LOAD_ESP\r
+  movl    $TempRamInitApiL2, %esi            #CALL_MMX  LoadMicrocode\r
+  movd    %esi, %mm7\r
+  .weak   ASM_PFX(LoadMicrocode)\r
+  .set    ASM_PFX(LoadMicrocode), ASM_PFX(LoadMicrocodeDefault)\r
+  jmp     ASM_PFX(LoadMicrocode)\r
 TempRamInitApiL2:\r
-\r
-  # @todo: ESP has been modified, we need to restore here.\r
-\r
-  LOAD_REGS\r
-  SAVE_REGS\r
+  SAVE_EAX_MICROCODE_RET_STATUS              #Save microcode return status in ECX-SLOT 3 in xmm6.\r
+  #@note If return value eax is not 0, microcode did not load, but continue and attempt to boot from ECX-SLOT 3 in xmm6.\r
 \r
   #\r
-  # Load microcode\r
+  # Call Sec CAR Init\r
   #\r
-  movl    $TempRamInitApiL3, %esi            #CALL_MMX  LoadUcode\r
-  movd    %mm7, %esi\r
-  jmp     ASM_PFX(LoadUcode)\r
+  LOAD_ESP\r
+  movl    $TempRamInitApiL3, %esi            #CALL_MMX  SecCarInit\r
+  movd    %esi, %mm7\r
+  jmp     ASM_PFX(SecCarInit)\r
 TempRamInitApiL3:\r
+  cmpl    $0x00, %eax\r
+  jnz     NemInitExit\r
 \r
   #\r
   # EstablishStackFsp\r
   #\r
+  LOAD_ESP\r
   movl    $TempRamInitApiL4, %esi            #CALL_MMX  EstablishStackFsp\r
-  movd    %mm7, %esi\r
+  movd    %esi, %mm7\r
   jmp     ASM_PFX(EstablishStackFsp)\r
 TempRamInitApiL4:\r
 \r
+  LOAD_EAX_MICROCODE_RET_STATUS              #Restore microcode status if no CAR init error.\r
+\r
 NemInitExit:\r
   #\r
   # Load EBP, EBX, ESI, EDI & ESP from XMM7 & XMM6\r
@@ -593,6 +616,7 @@ NemInitExit:
   LOAD_REGS\r
   ret\r
 \r
+\r
 #----------------------------------------------------------------------------\r
 # FspInit API\r
 #\r
@@ -679,9 +703,10 @@ FspApiCommonL0:
   # Verify the calling condition\r
   #\r
   pushal\r
-  pushl   %eax\r
+  pushl   36(%esp)  #push ApiParam  [esp + 4 * 8 + 4]\r
+  pushl   %eax      #push ApiIdx\r
   call    ASM_PFX(FspApiCallingCheck)\r
-  addl    $0x04, %esp\r
+  addl    $0x08, %esp\r
   cmpl    $0x00, %eax\r
   jz      FspApiCommonL1\r
   movl    %eax, 0x1C(%esp)                   # mov    dword ptr [esp + 4 * 7], eax\r
@@ -694,7 +719,8 @@ FspApiCommonL1:
   jz      FspApiCommonL2\r
   cmpl    $0x03, %eax                        # FspMemoryInit API\r
   jz      FspApiCommonL2\r
-  jmp     Pei2LoaderSwitchStack\r
+  call    ASM_PFX(AsmGetFspInfoHeader)\r
+  jmp     Loader2PeiSwitchStack\r
 \r
 FspApiCommonL2:\r
   #\r
@@ -702,9 +728,17 @@ FspApiCommonL2:
   #  \r
   \r
   #\r
-  # Store the address in FSP which will return control to the BL\r
+  # Place holder to store the FspInfoHeader pointer\r
+  #\r
+  pushl  %eax\r
+\r
+  #\r
+  # Update the FspInfoHeader pointer\r
   #\r
-  pushl   $FspApiCommonExit\r
+  pushl  %eax\r
+  call   ASM_PFX(AsmGetFspInfoHeader)\r
+  movl   %eax, 4(%esp)\r
+  popl   %eax\r
 \r
   #\r
   # Create a Task Frame in the stack for the Boot Loader\r
@@ -733,14 +767,14 @@ FspApiCommonL2:
   pushl   %eax\r
   \r
   #\r
-  # Pass the bootloader stack to SecStartup\r
+  # Pass the BootLoader stack to SecStartup\r
   #\r
   pushl   %edi\r
 \r
   #\r
   # Pass entry point of the PEI core\r
   #\r
-  call    ASM_PFX(GetFspBaseAddress)\r
+  call    ASM_PFX(AsmGetFspBaseAddress)\r
   movl    %eax, %edi\r
   addl    PcdGet32(PcdFspAreaSize), %edi\r
   subl    $0x20, %edi\r
@@ -754,7 +788,7 @@ FspApiCommonL2:
   # PcdFspAreaBaseAddress are the same. For FSP with mulitple FVs,\r
   # they are different. The code below can handle both cases.\r
   #\r
-  call    ASM_PFX(GetFspBaseAddress)\r
+  call    ASM_PFX(AsmGetFspBaseAddress)\r
   movl    %eax, %edi\r
   call    ASM_PFX(GetBootFirmwareVolumeOffset)\r
   addl    %edi, %eax\r
@@ -773,8 +807,7 @@ FspApiCommonL2:
   # Pass Control into the PEI Core\r
   #\r
   call    ASM_PFX(SecStartup)\r
-\r
+  addl    $4, %esp\r
 FspApiCommonExit:\r
   ret\r
 \r
-\r