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
16BITS    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;
27Flat32SearchForSecEntryPoint:
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
45moveForwardWhileSearchingForFfsFileHeaderLoop:
46    ;
47    ; Make forward progress in the search
48    ;
49    inc     eax
50    jc      secEntryPointWasNotFound
51
52searchingForFfsFileHeaderLoop:
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
76jumpSinceWeFoundTheLastFfsFile:
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
84fileTypeIsSecCore:
85    OneTimeCall GetEntryPointOfFfsFile
86    test    eax, eax
87    jnz     doneSeachingForSecEntryPoint
88
89readyToTryFfsFileAtEcx:
90    ;
91    ; Try the next FFS file at ECX
92    ;
93    mov     eax, ecx
94    jmp     searchingForFfsFileHeaderLoop
95
96secEntryPointWasNotFound:
97    xor     eax, eax
98
99doneSeachingForSecEntryPoint:
100    mov     esi, eax
101
102    test    esi, esi
103    jnz     secCoreEntryPointWasFound
104
105secCoreEntryPointWasNotFound:
106    ;
107    ; Hang if the SEC entry point was not found
108    ;
109    debugShowPostCode POSTCODE_SEC_NOT_FOUND
110    jz      $
111
112secCoreEntryPointWasFound:
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;
131GetEntryPointOfFfsFile:
132    test    eax, eax
133    jz      getEntryPointOfFfsFileErrorReturn
134    add     eax, 0x18       ; EAX = Start of section
135
136getEntryPointOfFfsFileLoopForSections:
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
162getEntryPointOfFfsFileFoundPe32Section:
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
179getEntryPointOfFfsFileFoundTeSection:
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
195getEntryPointOfFfsFileErrorReturn:
196    mov     eax, 0
197
198getEntryPointOfFfsFileReturn:
199    OneTimeCallRet GetEntryPointOfFfsFile
200
201