Home | History | Annotate | Download | only in Ia32
      1 ;------------------------------------------------------------------------------
      2 ; @file
      3 ; Search for the SEC Core entry point
      4 ;
      5 ; Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.<BR>
      6 ; This program and the accompanying materials
      7 ; are licensed and made available under the terms and conditions of the BSD License
      8 ; which accompanies this distribution.  The full text of the license may be found at
      9 ; http://opensource.org/licenses/bsd-license.php
     10 ;
     11 ; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     12 ; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     13 ;
     14 ;------------------------------------------------------------------------------
     15 
     16 BITS    32
     17 
     18 %define EFI_FV_FILETYPE_SECURITY_CORE         0x03
     19 
     20 ;
     21 ; Modified:  EAX, EBX, ECX, EDX
     22 ; Preserved: EDI, EBP, ESP
     23 ;
     24 ; @param[in]   EBP  Address of Boot Firmware Volume (BFV)
     25 ; @param[out]  ESI  SEC Core Entry Point Address
     26 ;
     27 Flat32SearchForSecEntryPoint:
     28 
     29     ;
     30     ; Initialize EBP and ESI to 0
     31     ;
     32     xor     ebx, ebx
     33     mov     esi, ebx
     34 
     35     ;
     36     ; Pass over the BFV header
     37     ;
     38     mov     eax, ebp
     39     mov     bx, [ebp + 0x30]
     40     add     eax, ebx
     41     jc      secEntryPointWasNotFound
     42 
     43     jmp     searchingForFfsFileHeaderLoop
     44 
     45 moveForwardWhileSearchingForFfsFileHeaderLoop:
     46     ;
     47     ; Make forward progress in the search
     48     ;
     49     inc     eax
     50     jc      secEntryPointWasNotFound
     51 
     52 searchingForFfsFileHeaderLoop:
     53     test    eax, eax
     54     jz      secEntryPointWasNotFound
     55 
     56     ;
     57     ; Ensure 8 byte alignment
     58     ;
     59     add     eax, 7
     60     jc      secEntryPointWasNotFound
     61     and     al, 0xf8
     62 
     63     ;
     64     ; Look to see if there is an FFS file at eax
     65     ;
     66     mov     bl, [eax + 0x17]
     67     test    bl, 0x20
     68     jz      moveForwardWhileSearchingForFfsFileHeaderLoop
     69     mov     ecx, [eax + 0x14]
     70     and     ecx, 0x00ffffff
     71     or      ecx, ecx
     72     jz      moveForwardWhileSearchingForFfsFileHeaderLoop
     73     add     ecx, eax
     74     jz      jumpSinceWeFoundTheLastFfsFile
     75     jc      moveForwardWhileSearchingForFfsFileHeaderLoop
     76 jumpSinceWeFoundTheLastFfsFile:
     77 
     78     ;
     79     ; There seems to be a valid file at eax
     80     ;
     81     cmp     byte [eax + 0x12], EFI_FV_FILETYPE_SECURITY_CORE ; Check File Type
     82     jne     readyToTryFfsFileAtEcx
     83 
     84 fileTypeIsSecCore:
     85     OneTimeCall GetEntryPointOfFfsFile
     86     test    eax, eax
     87     jnz     doneSeachingForSecEntryPoint
     88 
     89 readyToTryFfsFileAtEcx:
     90     ;
     91     ; Try the next FFS file at ECX
     92     ;
     93     mov     eax, ecx
     94     jmp     searchingForFfsFileHeaderLoop
     95 
     96 secEntryPointWasNotFound:
     97     xor     eax, eax
     98 
     99 doneSeachingForSecEntryPoint:
    100     mov     esi, eax
    101 
    102     test    esi, esi
    103     jnz     secCoreEntryPointWasFound
    104 
    105 secCoreEntryPointWasNotFound:
    106     ;
    107     ; Hang if the SEC entry point was not found
    108     ;
    109     debugShowPostCode POSTCODE_SEC_NOT_FOUND
    110     jz      $
    111 
    112 secCoreEntryPointWasFound:
    113     debugShowPostCode POSTCODE_SEC_FOUND
    114 
    115     OneTimeCallRet Flat32SearchForSecEntryPoint
    116 
    117 %define EFI_SECTION_PE32                  0x10
    118 %define EFI_SECTION_TE                    0x12
    119 
    120 ;
    121 ; Input:
    122 ;   EAX - Start of FFS file
    123 ;   ECX - End of FFS file
    124 ;
    125 ; Output:
    126 ;   EAX - Entry point of PE32 (or 0 if not found)
    127 ;
    128 ; Modified:
    129 ;   EBX
    130 ;
    131 GetEntryPointOfFfsFile:
    132     test    eax, eax
    133     jz      getEntryPointOfFfsFileErrorReturn
    134     add     eax, 0x18       ; EAX = Start of section
    135 
    136 getEntryPointOfFfsFileLoopForSections:
    137     cmp     eax, ecx
    138     jae     getEntryPointOfFfsFileErrorReturn
    139 
    140     cmp     byte [eax + 3], EFI_SECTION_PE32
    141     je      getEntryPointOfFfsFileFoundPe32Section
    142 
    143     cmp     byte [eax + 3], EFI_SECTION_TE
    144     je      getEntryPointOfFfsFileFoundTeSection
    145 
    146     ;
    147     ; The section type was not PE32 or TE, so move to next section
    148     ;
    149     mov     ebx, dword [eax]
    150     and     ebx, 0x00ffffff
    151     add     eax, ebx
    152     jc      getEntryPointOfFfsFileErrorReturn
    153 
    154     ;
    155     ; Ensure that FFS section is 32-bit aligned
    156     ;
    157     add     eax, 3
    158     jc      getEntryPointOfFfsFileErrorReturn
    159     and     al, 0xfc
    160     jmp     getEntryPointOfFfsFileLoopForSections
    161 
    162 getEntryPointOfFfsFileFoundPe32Section:
    163     add     eax, 4       ; EAX = Start of PE32 image
    164 
    165     cmp     word [eax], 'MZ'
    166     jne     getEntryPointOfFfsFileErrorReturn
    167     movzx   ebx, word [eax + 0x3c]
    168     add     ebx, eax
    169 
    170     ; if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE)
    171     cmp     dword [ebx], `PE\x00\x00`
    172     jne     getEntryPointOfFfsFileErrorReturn
    173 
    174     ; *EntryPoint = (VOID *)((UINTN)Pe32Data +
    175     ;   (UINTN)(Hdr.Pe32->OptionalHeader.AddressOfEntryPoint & 0x0ffffffff));
    176     add     eax, [ebx + 0x4 + 0x14 + 0x10]
    177     jmp     getEntryPointOfFfsFileReturn
    178 
    179 getEntryPointOfFfsFileFoundTeSection:
    180     add     eax, 4       ; EAX = Start of TE image
    181     mov     ebx, eax
    182 
    183     ; if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE)
    184     cmp     word [ebx], 'VZ'
    185     jne     getEntryPointOfFfsFileErrorReturn
    186     ; *EntryPoint = (VOID *)((UINTN)Pe32Data +
    187     ;   (UINTN)(Hdr.Te->AddressOfEntryPoint & 0x0ffffffff) +
    188     ;   sizeof(EFI_TE_IMAGE_HEADER) - Hdr.Te->StrippedSize);
    189     add     eax, [ebx + 0x8]
    190     add     eax, 0x28
    191     movzx   ebx, word [ebx + 0x6]
    192     sub     eax, ebx
    193     jmp     getEntryPointOfFfsFileReturn
    194 
    195 getEntryPointOfFfsFileErrorReturn:
    196     mov     eax, 0
    197 
    198 getEntryPointOfFfsFileReturn:
    199     OneTimeCallRet GetEntryPointOfFfsFile
    200 
    201