]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/SecEntry.asm
Do not deadloop if Microcode not found in FspTempRamInit.
[mirror_edk2.git] / IntelFspWrapperPkg / Library / SecPeiFspPlatformSecLibSample / Ia32 / SecEntry.asm
1 ;------------------------------------------------------------------------------
2 ;
3 ; Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
4 ; This program and the accompanying materials
5 ; are licensed and made available under the terms and conditions of the BSD License
6 ; which accompanies this distribution. The full text of the license may be found at
7 ; http://opensource.org/licenses/bsd-license.php.
8 ;
9 ; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 ; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11 ;
12 ; Module Name:
13 ;
14 ; SecEntry.asm
15 ;
16 ; Abstract:
17 ;
18 ; This is the code that goes from real-mode to protected mode.
19 ; It consumes the reset vector, calls TempRamInit API from FSP binary.
20 ;
21 ;------------------------------------------------------------------------------
22
23 #include "Fsp.h"
24
25 .686p
26 .xmm
27 .model small, c
28
29 EXTRN CallPeiCoreEntryPoint:NEAR
30 EXTRN TempRamInitParams:FAR
31
32 ; Pcds
33 EXTRN PcdGet32 (PcdFlashFvFspBase):DWORD
34 EXTRN PcdGet32 (PcdFlashFvFspSize):DWORD
35
36 _TEXT_REALMODE SEGMENT PARA PUBLIC USE16 'CODE'
37 ASSUME CS:_TEXT_REALMODE, DS:_TEXT_REALMODE
38
39 ;----------------------------------------------------------------------------
40 ;
41 ; Procedure: _ModuleEntryPoint
42 ;
43 ; Input: None
44 ;
45 ; Output: None
46 ;
47 ; Destroys: Assume all registers
48 ;
49 ; Description:
50 ;
51 ; Transition to non-paged flat-model protected mode from a
52 ; hard-coded GDT that provides exactly two descriptors.
53 ; This is a bare bones transition to protected mode only
54 ; used for a while in PEI and possibly DXE.
55 ;
56 ; After enabling protected mode, a far jump is executed to
57 ; transfer to PEI using the newly loaded GDT.
58 ;
59 ; Return: None
60 ;
61 ; MMX Usage:
62 ; MM0 = BIST State
63 ; MM5 = Save time-stamp counter value high32bit
64 ; MM6 = Save time-stamp counter value low32bit.
65 ;
66 ;----------------------------------------------------------------------------
67
68 align 4
69 _ModuleEntryPoint PROC NEAR C PUBLIC
70 fninit ; clear any pending Floating point exceptions
71 ;
72 ; Store the BIST value in mm0
73 ;
74 movd mm0, eax
75
76 ;
77 ; Save time-stamp counter value
78 ; rdtsc load 64bit time-stamp counter to EDX:EAX
79 ;
80 rdtsc
81 movd mm5, edx
82 movd mm6, eax
83
84 ;
85 ; Load the GDT table in GdtDesc
86 ;
87 mov esi, OFFSET GdtDesc
88 DB 66h
89 lgdt fword ptr cs:[si]
90
91 ;
92 ; Transition to 16 bit protected mode
93 ;
94 mov eax, cr0 ; Get control register 0
95 or eax, 00000003h ; Set PE bit (bit #0) & MP bit (bit #1)
96 mov cr0, eax ; Activate protected mode
97
98 mov eax, cr4 ; Get control register 4
99 or eax, 00000600h ; Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10)
100 mov cr4, eax
101
102 ;
103 ; Now we're in 16 bit protected mode
104 ; Set up the selectors for 32 bit protected mode entry
105 ;
106 mov ax, SYS_DATA_SEL
107 mov ds, ax
108 mov es, ax
109 mov fs, ax
110 mov gs, ax
111 mov ss, ax
112
113 ;
114 ; Transition to Flat 32 bit protected mode
115 ; The jump to a far pointer causes the transition to 32 bit mode
116 ;
117 mov esi, offset ProtectedModeEntryLinearAddress
118 jmp fword ptr cs:[si]
119
120 _ModuleEntryPoint ENDP
121 _TEXT_REALMODE ENDS
122
123 _TEXT_PROTECTED_MODE SEGMENT PARA PUBLIC USE32 'CODE'
124 ASSUME CS:_TEXT_PROTECTED_MODE, DS:_TEXT_PROTECTED_MODE
125
126 ;----------------------------------------------------------------------------
127 ;
128 ; Procedure: ProtectedModeEntryPoint
129 ;
130 ; Input: None
131 ;
132 ; Output: None
133 ;
134 ; Destroys: Assume all registers
135 ;
136 ; Description:
137 ;
138 ; This function handles:
139 ; Call two basic APIs from FSP binary
140 ; Initializes stack with some early data (BIST, PEI entry, etc)
141 ;
142 ; Return: None
143 ;
144 ;----------------------------------------------------------------------------
145
146 align 4
147 ProtectedModeEntryPoint PROC NEAR PUBLIC
148
149 ; Find the fsp info header
150 mov edi, PcdGet32 (PcdFlashFvFspBase)
151 mov ecx, PcdGet32 (PcdFlashFvFspSize)
152
153 mov eax, dword ptr [edi + FVH_SIGINATURE_OFFSET]
154 cmp eax, FVH_SIGINATURE_VALID_VALUE
155 jnz FspHeaderNotFound
156
157 xor eax, eax
158 mov ax, word ptr [edi + FVH_EXTHEADER_OFFSET_OFFSET]
159 cmp ax, 0
160 jnz FspFvExtHeaderExist
161
162 xor eax, eax
163 mov ax, word ptr [edi + FVH_HEADER_LENGTH_OFFSET] ; Bypass Fv Header
164 add edi, eax
165 jmp FspCheckFfsHeader
166
167 FspFvExtHeaderExist:
168 add edi, eax
169 mov eax, dword ptr [edi + FVH_EXTHEADER_SIZE_OFFSET] ; Bypass Ext Fv Header
170 add edi, eax
171
172 ; Round up to 8 byte alignment
173 mov eax, edi
174 and al, 07h
175 jz FspCheckFfsHeader
176
177 and edi, 0FFFFFFF8h
178 add edi, 08h
179
180 FspCheckFfsHeader:
181 ; Check the ffs guid
182 mov eax, dword ptr [edi]
183 cmp eax, FSP_HEADER_GUID_DWORD1
184 jnz FspHeaderNotFound
185
186 mov eax, dword ptr [edi + 4]
187 cmp eax, FSP_HEADER_GUID_DWORD2
188 jnz FspHeaderNotFound
189
190 mov eax, dword ptr [edi + 8]
191 cmp eax, FSP_HEADER_GUID_DWORD3
192 jnz FspHeaderNotFound
193
194 mov eax, dword ptr [edi + 0Ch]
195 cmp eax, FSP_HEADER_GUID_DWORD4
196 jnz FspHeaderNotFound
197
198 add edi, FFS_HEADER_SIZE_VALUE ; Bypass the ffs header
199
200 ; Check the section type as raw section
201 mov al, byte ptr [edi + SECTION_HEADER_TYPE_OFFSET]
202 cmp al, 019h
203 jnz FspHeaderNotFound
204
205 add edi, RAW_SECTION_HEADER_SIZE_VALUE ; Bypass the section header
206 jmp FspHeaderFound
207
208 FspHeaderNotFound:
209 jmp $
210
211 FspHeaderFound:
212 ; Get the fsp TempRamInit Api address
213 mov eax, dword ptr [edi + FSP_HEADER_IMAGEBASE_OFFSET]
214 add eax, dword ptr [edi + FSP_HEADER_TEMPRAMINIT_OFFSET]
215
216 ; Setup the hardcode stack
217 mov esp, OFFSET TempRamInitStack
218
219 ; Call the fsp TempRamInit Api
220 jmp eax
221
222 TempRamInitDone:
223 cmp eax, 8000000Eh ;Check if EFI_NOT_FOUND returned. Error code for Microcode Update not found.
224 je CallSecFspInit ;If microcode not found, don't hang, but continue.
225
226 cmp eax, 0 ;Check if EFI_SUCCESS retuned.
227 jnz FspApiFailed
228
229 ; ECX: start of range
230 ; EDX: end of range
231 CallSecFspInit:
232 xor eax, eax
233 mov esp, edx
234
235 ; Align the stack at DWORD
236 add esp, 3
237 and esp, 0FFFFFFFCh
238
239 push edx
240 push ecx
241 push eax ; zero - no hob list yet
242 call CallPeiCoreEntryPoint
243
244 FspApiFailed:
245 jmp $
246
247 align 10h
248 TempRamInitStack:
249 DD OFFSET TempRamInitDone
250 DD OFFSET TempRamInitParams
251
252 ProtectedModeEntryPoint ENDP
253
254 ;
255 ; ROM-based Global-Descriptor Table for the Tiano PEI Phase
256 ;
257 align 16
258 PUBLIC BootGdtTable
259
260 ;
261 ; GDT[0]: 0x00: Null entry, never used.
262 ;
263 NULL_SEL EQU $ - GDT_BASE ; Selector [0]
264 GDT_BASE:
265 BootGdtTable DD 0
266 DD 0
267 ;
268 ; Linear data segment descriptor
269 ;
270 LINEAR_SEL EQU $ - GDT_BASE ; Selector [0x8]
271 DW 0FFFFh ; limit 0xFFFFF
272 DW 0 ; base 0
273 DB 0
274 DB 092h ; present, ring 0, data, expand-up, writable
275 DB 0CFh ; page-granular, 32-bit
276 DB 0
277 ;
278 ; Linear code segment descriptor
279 ;
280 LINEAR_CODE_SEL EQU $ - GDT_BASE ; Selector [0x10]
281 DW 0FFFFh ; limit 0xFFFFF
282 DW 0 ; base 0
283 DB 0
284 DB 09Bh ; present, ring 0, data, expand-up, not-writable
285 DB 0CFh ; page-granular, 32-bit
286 DB 0
287 ;
288 ; System data segment descriptor
289 ;
290 SYS_DATA_SEL EQU $ - GDT_BASE ; Selector [0x18]
291 DW 0FFFFh ; limit 0xFFFFF
292 DW 0 ; base 0
293 DB 0
294 DB 093h ; present, ring 0, data, expand-up, not-writable
295 DB 0CFh ; page-granular, 32-bit
296 DB 0
297
298 ;
299 ; System code segment descriptor
300 ;
301 SYS_CODE_SEL EQU $ - GDT_BASE ; Selector [0x20]
302 DW 0FFFFh ; limit 0xFFFFF
303 DW 0 ; base 0
304 DB 0
305 DB 09Ah ; present, ring 0, data, expand-up, writable
306 DB 0CFh ; page-granular, 32-bit
307 DB 0
308 ;
309 ; Spare segment descriptor
310 ;
311 SYS16_CODE_SEL EQU $ - GDT_BASE ; Selector [0x28]
312 DW 0FFFFh ; limit 0xFFFFF
313 DW 0 ; base 0
314 DB 0Eh ; Changed from F000 to E000.
315 DB 09Bh ; present, ring 0, code, expand-up, writable
316 DB 00h ; byte-granular, 16-bit
317 DB 0
318 ;
319 ; Spare segment descriptor
320 ;
321 SYS16_DATA_SEL EQU $ - GDT_BASE ; Selector [0x30]
322 DW 0FFFFh ; limit 0xFFFF
323 DW 0 ; base 0
324 DB 0
325 DB 093h ; present, ring 0, data, expand-up, not-writable
326 DB 00h ; byte-granular, 16-bit
327 DB 0
328
329 ;
330 ; Spare segment descriptor
331 ;
332 SPARE5_SEL EQU $ - GDT_BASE ; Selector [0x38]
333 DW 0 ; limit 0
334 DW 0 ; base 0
335 DB 0
336 DB 0 ; present, ring 0, data, expand-up, writable
337 DB 0 ; page-granular, 32-bit
338 DB 0
339 GDT_SIZE EQU $ - BootGdtTable ; Size, in bytes
340
341 ;
342 ; GDT Descriptor
343 ;
344 GdtDesc: ; GDT descriptor
345 DW GDT_SIZE - 1 ; GDT limit
346 DD OFFSET BootGdtTable ; GDT base address
347
348
349 ProtectedModeEntryLinearAddress LABEL FWORD
350 ProtectedModeEntryLinearOffset LABEL DWORD
351 DD OFFSET ProtectedModeEntryPoint ; Offset of our 32 bit code
352 DW LINEAR_CODE_SEL
353
354 _TEXT_PROTECTED_MODE ENDS
355 END