]> git.proxmox.com Git - mirror_edk2.git/blobdiff - IntelFspPkg/FspSecCore/Ia32/FspApiEntry.s
Update IntelFspPkg to support FSP1.1
[mirror_edk2.git] / IntelFspPkg / FspSecCore / Ia32 / FspApiEntry.s
index d914075edcccd2b97b915905bd354f4f332a6479..1d8fe0bcd299e821f9c4e289ededd349bb14d22a 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
@@ -182,28 +226,6 @@ ASM_GLOBAL    ASM_PFX(Pei2LoaderSwitchStack)
 .equ          DATA_LEN_OF_MCUD, 0x018\r
 .equ          DATA_LEN_AT_STACK_TOP, (DATA_LEN_OF_PER0 + DATA_LEN_OF_MCUD + 4)\r
 \r
-#------------------------------------------------------------------------------\r
-# FspSelfCheckDefault\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(FspSelfCheckDefault)\r
-ASM_PFX(FspSelfCheckDefault):\r
-   #\r
-   # Save return address to EBP\r
-   #\r
-   movl  %eax, %ebp\r
-   xorl  %eax, %eax\r
-\r
-FspSelfCheckDefaultExit:\r
-   jmp   *%ebp\r
-\r
-\r
 #------------------------------------------------------------------------------\r
 # SecPlatformInitDefault\r
 # Inputs:\r
@@ -227,10 +249,10 @@ SecPlatformInitDefaultExit:
 \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,8 +261,8 @@ SecPlatformInitDefaultExit:
 #   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
@@ -248,17 +270,17 @@ ASM_PFX(LoadUcode):
 \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 +313,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 +382,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 +400,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 +435,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 +446,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,10 +463,10 @@ 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
@@ -455,10 +477,10 @@ LoadUcodeExit:
 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
@@ -469,17 +491,9 @@ 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
@@ -495,11 +509,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
@@ -507,7 +521,7 @@ EstablishStackFspExit:
   subl       PcdGet32 (PcdFspTemporaryRamSize), %edx\r
 \r
   xorl       %eax, %eax\r
\r
+\r
   movd       %mm7, %esi                      #RET_ESI\r
   jmp        *%esi\r
 \r
@@ -548,18 +562,12 @@ ASM_PFX(TempRamInitApi):
 \r
   #\r
   # CPUID/DeviceID check\r
-  #\r
-  movl    $TempRamInitApiL0, %eax\r
-  jmp     ASM_PFX(FspSelfCheckDefault)  # @note: ESP can not be changed.\r
-TempRamInitApiL0:\r
-  cmpl    $0x00, %eax\r
-  jnz     NemInitExit\r
-\r
-  #\r
-  # Sec Platform Init\r
+  # and 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
@@ -569,19 +577,21 @@ TempRamInitApiL1:
   # Load microcode\r
   #\r
   LOAD_ESP\r
-  movl    $TempRamInitApiL2, %esi            #CALL_MMX  LoadUcode\r
-  movd    %mm7, %esi\r
-  jmp     ASM_PFX(LoadUcode)\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
-  cmpl    $0x00, %eax\r
-  jnz     NemInitExit\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
   # Call Sec CAR Init\r
   #\r
   LOAD_ESP\r
   movl    $TempRamInitApiL3, %esi            #CALL_MMX  SecCarInit\r
-  movd    %mm7, %esi\r
+  movd    %esi, %mm7\r
   jmp     ASM_PFX(SecCarInit)\r
 TempRamInitApiL3:\r
   cmpl    $0x00, %eax\r
@@ -592,10 +602,12 @@ TempRamInitApiL3:
   #\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
@@ -603,6 +615,7 @@ NemInitExit:
   LOAD_REGS\r
   ret\r
 \r
+\r
 #----------------------------------------------------------------------------\r
 # FspInit API\r
 #\r
@@ -743,7 +756,7 @@ 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
@@ -787,4 +800,3 @@ FspApiCommonL2:
 FspApiCommonExit:\r
   ret\r
 \r
-\r