]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryT.nasm
IntelFsp2Pkg: Add missing OEM status code defines.
[mirror_edk2.git] / IntelFsp2Pkg / FspSecCore / Ia32 / FspApiEntryT.nasm
1 ;; @file
2 ; Provide FSP API entry points.
3 ;
4 ; Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
5 ; This program and the accompanying materials
6 ; are licensed and made available under the terms and conditions of the BSD License
7 ; which accompanies this distribution. The full text of the license may be found at
8 ; http://opensource.org/licenses/bsd-license.php.
9 ;
10 ; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 ; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12 ;;
13
14 SECTION .text
15
16 %include "SaveRestoreSseNasm.inc"
17 %include "MicrocodeLoadNasm.inc"
18
19 ;
20 ; Following are fixed PCDs
21 ;
22 extern ASM_PFX(PcdGet32 (PcdTemporaryRamBase))
23 extern ASM_PFX(PcdGet32 (PcdTemporaryRamSize))
24 extern ASM_PFX(PcdGet32 (PcdFspReservedBufferSize))
25
26 ;
27 ; Following functions will be provided in PlatformSecLib
28 ;
29 extern ASM_PFX(AsmGetFspBaseAddress)
30 extern ASM_PFX(AsmGetFspInfoHeader)
31 ;extern ASM_PFX(LoadMicrocode) ; @todo: needs a weak implementation
32 extern ASM_PFX(SecPlatformInit) ; @todo: needs a weak implementation
33 extern ASM_PFX(SecCarInit)
34
35 ;
36 ; Define the data length that we saved on the stack top
37 ;
38 DATA_LEN_OF_PER0 EQU 18h
39 DATA_LEN_OF_MCUD EQU 18h
40 DATA_LEN_AT_STACK_TOP EQU (DATA_LEN_OF_PER0 + DATA_LEN_OF_MCUD + 4)
41
42 ;
43 ; @todo: These structures are moved from MicrocodeLoadNasm.inc to avoid
44 ; build error. This needs to be fixed later on.
45 ;
46 struc MicrocodeHdr
47 .MicrocodeHdrVersion: resd 1
48 .MicrocodeHdrRevision: resd 1
49 .MicrocodeHdrDate: resd 1
50 .MicrocodeHdrProcessor: resd 1
51 .MicrocodeHdrChecksum: resd 1
52 .MicrocodeHdrLoader: resd 1
53 .MicrocodeHdrFlags: resd 1
54 .MicrocodeHdrDataSize: resd 1
55 .MicrocodeHdrTotalSize: resd 1
56 .MicrocodeHdrRsvd: resd 3
57 .size:
58 endstruc
59
60 struc ExtSigHdr
61 .ExtSigHdrCount: resd 1
62 .ExtSigHdrChecksum: resd 1
63 .ExtSigHdrRsvd: resd 3
64 .size:
65 endstruc
66
67 struc ExtSig
68 .ExtSigProcessor: resd 1
69 .ExtSigFlags: resd 1
70 .ExtSigChecksum: resd 1
71 .size:
72 endstruc
73
74 struc LoadMicrocodeParams
75 ; FSP_UPD_HEADER {
76 .FspUpdHeader: resd 8
77 ; }
78 ; FSPT_CORE_UPD {
79 .MicrocodeCodeAddr: resd 1
80 .MicrocodeCodeSize: resd 1
81 .CodeRegionBase: resd 1
82 .CodeRegionSize: resd 1
83 ; }
84 .size:
85 endstruc
86
87
88 ;
89 ; Define SSE macros
90 ;
91 ;
92 ;args 1: ReturnAddress 2:MmxRegister
93 ;
94 %macro LOAD_MMX_EXT 2
95 mov esi, %1
96 movd %2, esi ; save ReturnAddress into MMX
97 %endmacro
98
99 ;
100 ;args 1: RoutineLabel 2:MmxRegister
101 ;
102 %macro CALL_MMX_EXT 2
103 mov esi, %%ReturnAddress
104 movd %2, esi ; save ReturnAddress into MMX
105 jmp %1
106 %%ReturnAddress:
107 %endmacro
108
109 ;
110 ;arg 1:MmxRegister
111 ;
112 %macro RET_ESI_EXT 1
113 movd esi, %1 ; move ReturnAddress from MMX to ESI
114 jmp esi
115 %endmacro
116
117 ;
118 ;arg 1:RoutineLabel
119 ;
120 %macro CALL_MMX 1
121 CALL_MMX_EXT %1, mm7
122 %endmacro
123
124 %macro RET_ESI 0
125 RET_ESI_EXT mm7
126 %endmacro
127
128 ;
129 ; @todo: The strong/weak implementation does not work.
130 ; This needs to be reviewed later.
131 ;
132 ;------------------------------------------------------------------------------
133 ;
134 ;;global ASM_PFX(SecPlatformInitDefault)
135 ;ASM_PFX(SecPlatformInitDefault):
136 ; ; Inputs:
137 ; ; mm7 -> Return address
138 ; ; Outputs:
139 ; ; eax -> 0 - Successful, Non-zero - Failed.
140 ; ; Register Usage:
141 ; ; eax is cleared and ebp is used for return address.
142 ; ; All others reserved.
143 ;
144 ; ; Save return address to EBP
145 ; movd ebp, mm7
146 ;
147 ; xor eax, eax
148 ;Exit1:
149 ; jmp ebp
150
151 ;------------------------------------------------------------------------------
152 global ASM_PFX(LoadMicrocodeDefault)
153 ASM_PFX(LoadMicrocodeDefault):
154 ; Inputs:
155 ; esp -> LoadMicrocodeParams pointer
156 ; Register Usage:
157 ; esp Preserved
158 ; All others destroyed
159 ; Assumptions:
160 ; No memory available, stack is hard-coded and used for return address
161 ; Executed by SBSP and NBSP
162 ; Beginning of microcode update region starts on paragraph boundary
163
164 ;
165 ;
166 ; Save return address to EBP
167 movd ebp, mm7
168
169 cmp esp, 0
170 jz ParamError
171 mov eax, dword [esp + 4] ; Parameter pointer
172 cmp eax, 0
173 jz ParamError
174 mov esp, eax
175
176 mov esi, dword [esp + LoadMicrocodeParams.MicrocodeCodeAddr]
177 cmp esi, 0
178 jnz CheckMainHeader
179
180 ParamError:
181 mov eax, 080000002h
182 jmp Exit2
183
184 CheckMainHeader:
185 ; Get processor signature and platform ID from the installed processor
186 ; and save into registers for later use
187 ; ebx = processor signature
188 ; edx = platform ID
189 mov eax, 1
190 cpuid
191 mov ebx, eax
192 mov ecx, MSR_IA32_PLATFORM_ID
193 rdmsr
194 mov ecx, edx
195 shr ecx, 50-32 ; shift (50d-32d=18d=0x12) bits
196 and ecx, 7h ; platform id at bit[52..50]
197 mov edx, 1
198 shl edx, cl
199
200 ; Current register usage
201 ; esp -> stack with parameters
202 ; esi -> microcode update to check
203 ; ebx = processor signature
204 ; edx = platform ID
205
206 ; Check for valid microcode header
207 ; Minimal test checking for header version and loader version as 1
208 mov eax, dword 1
209 cmp dword [esi + MicrocodeHdr.MicrocodeHdrVersion], eax
210 jne AdvanceFixedSize
211 cmp dword [esi + MicrocodeHdr.MicrocodeHdrLoader], eax
212 jne AdvanceFixedSize
213
214 ; Check if signature and plaform ID match
215 cmp ebx, dword [esi + MicrocodeHdr.MicrocodeHdrProcessor]
216 jne LoadMicrocodeDefault1
217 test edx, dword [esi + MicrocodeHdr.MicrocodeHdrFlags ]
218 jnz LoadCheck ; Jif signature and platform ID match
219
220 LoadMicrocodeDefault1:
221 ; Check if extended header exists
222 ; First check if MicrocodeHdrTotalSize and MicrocodeHdrDataSize are valid
223 xor eax, eax
224 cmp dword [esi + MicrocodeHdr.MicrocodeHdrTotalSize], eax
225 je NextMicrocode
226 cmp dword [esi + MicrocodeHdr.MicrocodeHdrDataSize], eax
227 je NextMicrocode
228
229 ; Then verify total size - sizeof header > data size
230 mov ecx, dword [esi + MicrocodeHdr.MicrocodeHdrTotalSize]
231 sub ecx, MicrocodeHdr.size
232 cmp ecx, dword [esi + MicrocodeHdr.MicrocodeHdrDataSize]
233 jng NextMicrocode ; Jif extended header does not exist
234
235 ; Set edi -> extended header
236 mov edi, esi
237 add edi, MicrocodeHdr.size
238 add edi, dword [esi + MicrocodeHdr.MicrocodeHdrDataSize]
239
240 ; Get count of extended structures
241 mov ecx, dword [edi + ExtSigHdr.ExtSigHdrCount]
242
243 ; Move pointer to first signature structure
244 add edi, ExtSigHdr.size
245
246 CheckExtSig:
247 ; Check if extended signature and platform ID match
248 cmp dword [edi + ExtSig.ExtSigProcessor], ebx
249 jne LoadMicrocodeDefault2
250 test dword [edi + ExtSig.ExtSigFlags], edx
251 jnz LoadCheck ; Jif signature and platform ID match
252 LoadMicrocodeDefault2:
253 ; Check if any more extended signatures exist
254 add edi, ExtSig.size
255 loop CheckExtSig
256
257 NextMicrocode:
258 ; Advance just after end of this microcode
259 xor eax, eax
260 cmp dword [esi + MicrocodeHdr.MicrocodeHdrTotalSize], eax
261 je LoadMicrocodeDefault3
262 add esi, dword [esi + MicrocodeHdr.MicrocodeHdrTotalSize]
263 jmp CheckAddress
264 LoadMicrocodeDefault3:
265 add esi, dword 2048
266 jmp CheckAddress
267
268 AdvanceFixedSize:
269 ; Advance by 4X dwords
270 add esi, dword 1024
271
272 CheckAddress:
273 ; Is valid Microcode start point ?
274 cmp dword [esi + MicrocodeHdr.MicrocodeHdrVersion], 0ffffffffh
275 jz Done
276
277 ; Is automatic size detection ?
278 mov eax, dword [esp + LoadMicrocodeParams.MicrocodeCodeSize]
279 cmp eax, 0ffffffffh
280 jz LoadMicrocodeDefault4
281
282 ; Address >= microcode region address + microcode region size?
283 add eax, dword [esp + LoadMicrocodeParams.MicrocodeCodeAddr]
284 cmp esi, eax
285 jae Done ;Jif address is outside of microcode region
286 jmp CheckMainHeader
287
288 LoadMicrocodeDefault4:
289 LoadCheck:
290 ; Get the revision of the current microcode update loaded
291 mov ecx, MSR_IA32_BIOS_SIGN_ID
292 xor eax, eax ; Clear EAX
293 xor edx, edx ; Clear EDX
294 wrmsr ; Load 0 to MSR at 8Bh
295
296 mov eax, 1
297 cpuid
298 mov ecx, MSR_IA32_BIOS_SIGN_ID
299 rdmsr ; Get current microcode signature
300
301 ; Verify this microcode update is not already loaded
302 cmp dword [esi + MicrocodeHdr.MicrocodeHdrRevision], edx
303 je Continue
304
305 LoadMicrocode:
306 ; EAX contains the linear address of the start of the Update Data
307 ; EDX contains zero
308 ; ECX contains 79h (IA32_BIOS_UPDT_TRIG)
309 ; Start microcode load with wrmsr
310 mov eax, esi
311 add eax, MicrocodeHdr.size
312 xor edx, edx
313 mov ecx, MSR_IA32_BIOS_UPDT_TRIG
314 wrmsr
315 mov eax, 1
316 cpuid
317
318 Continue:
319 jmp NextMicrocode
320
321 Done:
322 mov eax, 1
323 cpuid
324 mov ecx, MSR_IA32_BIOS_SIGN_ID
325 rdmsr ; Get current microcode signature
326 xor eax, eax
327 cmp edx, 0
328 jnz Exit2
329 mov eax, 08000000Eh
330
331 Exit2:
332 jmp ebp
333
334
335 global ASM_PFX(EstablishStackFsp)
336 ASM_PFX(EstablishStackFsp):
337 ;
338 ; Save parameter pointer in edx
339 ;
340 mov edx, dword [esp + 4]
341
342 ;
343 ; Enable FSP STACK
344 ;
345 mov esp, DWORD [ASM_PFX(PcdGet32 (PcdTemporaryRamBase))]
346 add esp, DWORD [ASM_PFX(PcdGet32 (PcdTemporaryRamSize))]
347
348 push DATA_LEN_OF_MCUD ; Size of the data region
349 push 4455434Dh ; Signature of the data region 'MCUD'
350 push dword [edx + 2Ch] ; Code size sizeof(FSPT_UPD_COMMON) + 12
351 push dword [edx + 28h] ; Code base sizeof(FSPT_UPD_COMMON) + 8
352 push dword [edx + 24h] ; Microcode size sizeof(FSPT_UPD_COMMON) + 4
353 push dword [edx + 20h] ; Microcode base sizeof(FSPT_UPD_COMMON) + 0
354
355 ;
356 ; Save API entry/exit timestamp into stack
357 ;
358 push DATA_LEN_OF_PER0 ; Size of the data region
359 push 30524550h ; Signature of the data region 'PER0'
360 rdtsc
361 push edx
362 push eax
363 LOAD_EDX
364 push edx
365 LOAD_EAX
366 push eax
367
368 ;
369 ; Terminator for the data on stack
370 ;
371 push 0
372
373 ;
374 ; Set ECX/EDX to the BootLoader temporary memory range
375 ;
376 mov ecx, [ASM_PFX(PcdGet32 (PcdTemporaryRamBase))]
377 mov edx, ecx
378 add edx, [ASM_PFX(PcdGet32 (PcdTemporaryRamSize))]
379 sub edx, [ASM_PFX(PcdGet32 (PcdFspReservedBufferSize))]
380
381 cmp ecx, edx ;If PcdFspReservedBufferSize >= PcdTemporaryRamSize, then error.
382 jb EstablishStackFspSuccess
383 mov eax, 80000003h ;EFI_UNSUPPORTED
384 jmp EstablishStackFspExit
385 EstablishStackFspSuccess:
386 xor eax, eax
387
388 EstablishStackFspExit:
389 RET_ESI
390
391 ;----------------------------------------------------------------------------
392 ; TempRamInit API
393 ;
394 ; This FSP API will load the microcode update, enable code caching for the
395 ; region specified by the boot loader and also setup a temporary stack to be
396 ; used till main memory is initialized.
397 ;
398 ;----------------------------------------------------------------------------
399 global ASM_PFX(TempRamInitApi)
400 ASM_PFX(TempRamInitApi):
401 ;
402 ; Ensure SSE is enabled
403 ;
404 ENABLE_SSE
405
406 ;
407 ; Save EBP, EBX, ESI, EDI & ESP in XMM7 & XMM6
408 ;
409 SAVE_REGS
410
411 ;
412 ; Save timestamp into XMM6
413 ;
414 rdtsc
415 SAVE_EAX
416 SAVE_EDX
417
418 ;
419 ; Check Parameter
420 ;
421 mov eax, dword [esp + 4]
422 cmp eax, 0
423 mov eax, 80000002h
424 jz TempRamInitExit
425
426 ;
427 ; Sec Platform Init
428 ;
429 CALL_MMX ASM_PFX(SecPlatformInit)
430 cmp eax, 0
431 jnz TempRamInitExit
432
433 ; Load microcode
434 LOAD_ESP
435 CALL_MMX ASM_PFX(LoadMicrocodeDefault)
436 SXMMN xmm6, 3, eax ;Save microcode return status in ECX-SLOT 3 in xmm6.
437 ;@note If return value eax is not 0, microcode did not load, but continue and attempt to boot.
438
439 ; Call Sec CAR Init
440 LOAD_ESP
441 CALL_MMX ASM_PFX(SecCarInit)
442 cmp eax, 0
443 jnz TempRamInitExit
444
445 LOAD_ESP
446 CALL_MMX ASM_PFX(EstablishStackFsp)
447 cmp eax, 0
448 jnz TempRamInitExit
449
450 LXMMN xmm6, eax, 3 ;Restore microcode status if no CAR init error from ECX-SLOT 3 in xmm6.
451
452 TempRamInitExit:
453 mov bl, al ; save al data in bl
454 mov al, 07Fh ; API exit postcode 7f
455 out 080h, al
456 mov al, bl ; restore al data from bl
457
458 ;
459 ; Load EBP, EBX, ESI, EDI & ESP from XMM7 & XMM6
460 ;
461 LOAD_REGS
462 ret
463
464 ;----------------------------------------------------------------------------
465 ; Module Entrypoint API
466 ;----------------------------------------------------------------------------
467 global ASM_PFX(_ModuleEntryPoint)
468 ASM_PFX(_ModuleEntryPoint):
469 jmp $