]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryT.nasm
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / IntelFsp2Pkg / FspSecCore / Ia32 / FspApiEntryT.nasm
1 ;; @file
2 ; Provide FSP API entry points.
3 ;
4 ; Copyright (c) 2016 - 2022, Intel Corporation. All rights reserved.<BR>
5 ; SPDX-License-Identifier: BSD-2-Clause-Patent
6 ;;
7
8 SECTION .text
9
10 %include "SaveRestoreSseNasm.inc"
11 %include "MicrocodeLoadNasm.inc"
12
13 ;
14 ; Following are fixed PCDs
15 ;
16 extern ASM_PFX(PcdGet32 (PcdTemporaryRamBase))
17 extern ASM_PFX(PcdGet32 (PcdTemporaryRamSize))
18 extern ASM_PFX(PcdGet32 (PcdFspReservedBufferSize))
19
20 ;
21 ; Following functions will be provided in PlatformSecLib
22 ;
23 extern ASM_PFX(AsmGetFspBaseAddress)
24 extern ASM_PFX(AsmGetFspInfoHeaderNoStack)
25 ;extern ASM_PFX(LoadMicrocode) ; @todo: needs a weak implementation
26 extern ASM_PFX(SecPlatformInit) ; @todo: needs a weak implementation
27 extern ASM_PFX(SecCarInit)
28
29 ;
30 ; Define the data length that we saved on the stack top
31 ;
32 DATA_LEN_OF_PER0 EQU 18h
33 DATA_LEN_OF_MCUD EQU 18h
34 DATA_LEN_AT_STACK_TOP EQU (DATA_LEN_OF_PER0 + DATA_LEN_OF_MCUD + 4)
35
36 ;
37 ; @todo: These structures are moved from MicrocodeLoadNasm.inc to avoid
38 ; build error. This needs to be fixed later on.
39 ;
40 struc MicrocodeHdr
41 .MicrocodeHdrVersion: resd 1
42 .MicrocodeHdrRevision: resd 1
43 .MicrocodeHdrDate: resd 1
44 .MicrocodeHdrProcessor: resd 1
45 .MicrocodeHdrChecksum: resd 1
46 .MicrocodeHdrLoader: resd 1
47 .MicrocodeHdrFlags: resd 1
48 .MicrocodeHdrDataSize: resd 1
49 .MicrocodeHdrTotalSize: resd 1
50 .MicrocodeHdrRsvd: resd 3
51 .size:
52 endstruc
53
54 struc ExtSigHdr
55 .ExtSigHdrCount: resd 1
56 .ExtSigHdrChecksum: resd 1
57 .ExtSigHdrRsvd: resd 3
58 .size:
59 endstruc
60
61 struc ExtSig
62 .ExtSigProcessor: resd 1
63 .ExtSigFlags: resd 1
64 .ExtSigChecksum: resd 1
65 .size:
66 endstruc
67
68 struc LoadMicrocodeParams
69 ; FSP_UPD_HEADER {
70 .FspUpdHeader: resd 8
71 ; }
72 ; FSPT_CORE_UPD {
73 .MicrocodeCodeAddr: resd 1
74 .MicrocodeCodeSize: resd 1
75 .CodeRegionBase: resd 1
76 .CodeRegionSize: resd 1
77 ; }
78 .size:
79 endstruc
80
81 struc LoadMicrocodeParamsFsp22
82 ; FSP_UPD_HEADER {
83 .FspUpdHeaderSignature: resd 2
84 .FspUpdHeaderRevision: resb 1
85 .FspUpdHeaderReserved: resb 23
86 ; }
87 ; FSPT_ARCH_UPD {
88 .FsptArchRevision: resb 1
89 .FsptArchReserved: resb 3
90 .FsptArchUpd: resd 7
91 ; }
92 ; FSPT_CORE_UPD {
93 .MicrocodeCodeAddr: resd 1
94 .MicrocodeCodeSize: resd 1
95 .CodeRegionBase: resd 1
96 .CodeRegionSize: resd 1
97 ; }
98 .size:
99 endstruc
100
101 struc LoadMicrocodeParamsFsp24
102 ; FSP_UPD_HEADER {
103 .FspUpdHeaderSignature: resd 2
104 .FspUpdHeaderRevision: resb 1
105 .FspUpdHeaderReserved: resb 23
106 ; }
107 ; FSPT_ARCH2_UPD {
108 .FsptArchRevision: resb 1
109 .FsptArchReserved: resb 3
110 .FsptArchLength: resd 1
111 .FspDebugHandler resq 1
112 .FsptArchUpd: resd 4
113 ; }
114 ; FSPT_CORE_UPD {
115 .MicrocodeCodeAddr: resq 1
116 .MicrocodeCodeSize: resq 1
117 .CodeRegionBase: resq 1
118 .CodeRegionSize: resq 1
119 ; }
120 .size:
121 endstruc
122
123 ;
124 ; Define SSE macros
125 ;
126 ;
127 ;args 1: ReturnAddress 2:MmxRegister
128 ;
129 %macro LOAD_MMX_EXT 2
130 mov esi, %1
131 movd %2, esi ; save ReturnAddress into MMX
132 %endmacro
133
134 ;
135 ;args 1: RoutineLabel 2:MmxRegister
136 ;
137 %macro CALL_MMX_EXT 2
138 mov esi, %%ReturnAddress
139 movd %2, esi ; save ReturnAddress into MMX
140 jmp %1
141 %%ReturnAddress:
142 %endmacro
143
144 ;
145 ;arg 1:MmxRegister
146 ;
147 %macro RET_ESI_EXT 1
148 movd esi, %1 ; move ReturnAddress from MMX to ESI
149 jmp esi
150 %endmacro
151
152 ;
153 ;arg 1:RoutineLabel
154 ;
155 %macro CALL_MMX 1
156 CALL_MMX_EXT %1, mm7
157 %endmacro
158
159 %macro RET_ESI 0
160 RET_ESI_EXT mm7
161 %endmacro
162
163 %macro CALL_EDI 1
164
165 mov edi, %%ReturnAddress
166 jmp %1
167 %%ReturnAddress:
168
169 %endmacro
170
171 %macro CALL_EBP 1
172 mov ebp, %%ReturnAddress
173 jmp %1
174 %%ReturnAddress:
175 %endmacro
176
177 %macro RET_EBP 0
178 jmp ebp ; restore EIP from EBP
179 %endmacro
180
181 ;
182 ; Load UPD region pointer in ECX
183 ;
184 global ASM_PFX(LoadUpdPointerToECX)
185 ASM_PFX(LoadUpdPointerToECX):
186 ;
187 ; esp + 4 is input UPD parameter
188 ; If esp + 4 is NULL the default UPD should be used
189 ; ecx will be the UPD region that should be used
190 ;
191 mov ecx, dword [esp + 4]
192 cmp ecx, 0
193 jnz ParamValid
194
195 ;
196 ; Fall back to default UPD region
197 ;
198 CALL_EDI ASM_PFX(AsmGetFspInfoHeaderNoStack)
199 mov ecx, DWORD [eax + 01Ch] ; Read FsptImageBaseAddress
200 add ecx, DWORD [eax + 024h] ; Get Cfg Region base address = FsptImageBaseAddress + CfgRegionOffset
201 ParamValid:
202 RET_EBP
203
204 ;
205 ; @todo: The strong/weak implementation does not work.
206 ; This needs to be reviewed later.
207 ;
208 ;------------------------------------------------------------------------------
209 ;
210 ;;global ASM_PFX(SecPlatformInitDefault)
211 ;ASM_PFX(SecPlatformInitDefault):
212 ; ; Inputs:
213 ; ; mm7 -> Return address
214 ; ; Outputs:
215 ; ; eax -> 0 - Successful, Non-zero - Failed.
216 ; ; Register Usage:
217 ; ; eax is cleared and ebp is used for return address.
218 ; ; All others reserved.
219 ;
220 ; ; Save return address to EBP
221 ; movd ebp, mm7
222 ;
223 ; xor eax, eax
224 ;Exit1:
225 ; jmp ebp
226
227 ;------------------------------------------------------------------------------
228 global ASM_PFX(LoadMicrocodeDefault)
229 ASM_PFX(LoadMicrocodeDefault):
230 ; Inputs:
231 ; ecx -> UPD region contains LoadMicrocodeParams pointer
232 ; Register Usage:
233 ; All are destroyed
234 ; Assumptions:
235 ; No memory available, stack is hard-coded and used for return address
236 ; Executed by SBSP and NBSP
237 ; Beginning of microcode update region starts on paragraph boundary
238
239 ;
240 ; Save return address to EBP
241 ;
242 movd ebp, mm7
243
244 mov esp, ecx ; ECX has been assigned to UPD region
245 cmp esp, 0
246 jz ParamError
247
248 ; skip loading Microcode if the MicrocodeCodeSize is zero
249 ; and report error if size is less than 2k
250 ; first check UPD header revision
251 cmp byte [esp + LoadMicrocodeParamsFsp22.FspUpdHeaderRevision], 2
252 jb Fsp20UpdHeader
253 cmp byte [esp + LoadMicrocodeParamsFsp22.FsptArchRevision], 2
254 je Fsp24UpdHeader
255 jmp Fsp22UpdHeader
256
257 Fsp20UpdHeader:
258 ; UPD structure is compliant with FSP spec 2.0/2.1
259 mov eax, dword [esp + LoadMicrocodeParams.MicrocodeCodeSize]
260 cmp eax, 0
261 jz Exit2
262 cmp eax, 0800h
263 jl ParamError
264
265 mov esi, dword [esp + LoadMicrocodeParams.MicrocodeCodeAddr]
266 cmp esi, 0
267 jnz CheckMainHeader
268 jmp ParamError
269
270 Fsp22UpdHeader:
271 ; UPD structure is compliant with FSP spec 2.2
272 mov eax, dword [esp + LoadMicrocodeParamsFsp22.MicrocodeCodeSize]
273 cmp eax, 0
274 jz Exit2
275 cmp eax, 0800h
276 jl ParamError
277
278 mov esi, dword [esp + LoadMicrocodeParamsFsp22.MicrocodeCodeAddr]
279 cmp esi, 0
280 jnz CheckMainHeader
281 jmp ParamError
282
283 Fsp24UpdHeader:
284 ; UPD structure is compliant with FSP spec 2.4
285 mov eax, dword [esp + LoadMicrocodeParamsFsp24.MicrocodeCodeSize]
286 cmp eax, 0
287 jz Exit2
288 cmp eax, 0800h
289 jl ParamError
290
291 mov esi, dword [esp + LoadMicrocodeParamsFsp24.MicrocodeCodeAddr]
292 cmp esi, 0
293 jnz CheckMainHeader
294
295 ParamError:
296 mov eax, 080000002h
297 jmp Exit2
298
299 CheckMainHeader:
300 ; Get processor signature and platform ID from the installed processor
301 ; and save into registers for later use
302 ; ebx = processor signature
303 ; edx = platform ID
304 mov eax, 1
305 cpuid
306 mov ebx, eax
307 mov ecx, MSR_IA32_PLATFORM_ID
308 rdmsr
309 mov ecx, edx
310 shr ecx, 50-32 ; shift (50d-32d=18d=0x12) bits
311 and ecx, 7h ; platform id at bit[52..50]
312 mov edx, 1
313 shl edx, cl
314
315 ; Current register usage
316 ; esp -> stack with parameters
317 ; esi -> microcode update to check
318 ; ebx = processor signature
319 ; edx = platform ID
320
321 ; Check for valid microcode header
322 ; Minimal test checking for header version and loader version as 1
323 mov eax, dword 1
324 cmp dword [esi + MicrocodeHdr.MicrocodeHdrVersion], eax
325 jne AdvanceFixedSize
326 cmp dword [esi + MicrocodeHdr.MicrocodeHdrLoader], eax
327 jne AdvanceFixedSize
328
329 ; Check if signature and plaform ID match
330 cmp ebx, dword [esi + MicrocodeHdr.MicrocodeHdrProcessor]
331 jne LoadMicrocodeDefault1
332 test edx, dword [esi + MicrocodeHdr.MicrocodeHdrFlags ]
333 jnz LoadCheck ; Jif signature and platform ID match
334
335 LoadMicrocodeDefault1:
336 ; Check if extended header exists
337 ; First check if MicrocodeHdrTotalSize and MicrocodeHdrDataSize are valid
338 xor eax, eax
339 cmp dword [esi + MicrocodeHdr.MicrocodeHdrTotalSize], eax
340 je NextMicrocode
341 cmp dword [esi + MicrocodeHdr.MicrocodeHdrDataSize], eax
342 je NextMicrocode
343
344 ; Then verify total size - sizeof header > data size
345 mov ecx, dword [esi + MicrocodeHdr.MicrocodeHdrTotalSize]
346 sub ecx, MicrocodeHdr.size
347 cmp ecx, dword [esi + MicrocodeHdr.MicrocodeHdrDataSize]
348 jng NextMicrocode ; Jif extended header does not exist
349
350 ; Set edi -> extended header
351 mov edi, esi
352 add edi, MicrocodeHdr.size
353 add edi, dword [esi + MicrocodeHdr.MicrocodeHdrDataSize]
354
355 ; Get count of extended structures
356 mov ecx, dword [edi + ExtSigHdr.ExtSigHdrCount]
357
358 ; Move pointer to first signature structure
359 add edi, ExtSigHdr.size
360
361 CheckExtSig:
362 ; Check if extended signature and platform ID match
363 cmp dword [edi + ExtSig.ExtSigProcessor], ebx
364 jne LoadMicrocodeDefault2
365 test dword [edi + ExtSig.ExtSigFlags], edx
366 jnz LoadCheck ; Jif signature and platform ID match
367 LoadMicrocodeDefault2:
368 ; Check if any more extended signatures exist
369 add edi, ExtSig.size
370 loop CheckExtSig
371
372 NextMicrocode:
373 ; Advance just after end of this microcode
374 xor eax, eax
375 cmp dword [esi + MicrocodeHdr.MicrocodeHdrTotalSize], eax
376 je LoadMicrocodeDefault3
377 add esi, dword [esi + MicrocodeHdr.MicrocodeHdrTotalSize]
378 jmp CheckAddress
379 LoadMicrocodeDefault3:
380 add esi, dword 2048
381 jmp CheckAddress
382
383 AdvanceFixedSize:
384 ; Advance by 4X dwords
385 add esi, dword 1024
386
387 CheckAddress:
388 ; Check UPD header revision
389 cmp byte [esp + LoadMicrocodeParamsFsp22.FspUpdHeaderRevision], 2
390 jb Fsp20UpdHeader1
391 cmp byte [esp + LoadMicrocodeParamsFsp22.FsptArchRevision], 2
392 je Fsp24UpdHeader1;
393 jmp Fsp22UpdHeader1
394
395 Fsp20UpdHeader1:
396 ; UPD structure is compliant with FSP spec 2.0/2.1
397 ; Is automatic size detection ?
398 mov eax, dword [esp + LoadMicrocodeParams.MicrocodeCodeSize]
399 cmp eax, 0ffffffffh
400 jz LoadMicrocodeDefault4
401
402 ; Address >= microcode region address + microcode region size?
403 add eax, dword [esp + LoadMicrocodeParams.MicrocodeCodeAddr]
404 cmp esi, eax
405 jae Done ;Jif address is outside of microcode region
406 jmp CheckMainHeader
407
408 Fsp22UpdHeader1:
409 ; UPD structure is compliant with FSP spec 2.2
410 ; Is automatic size detection ?
411 mov eax, dword [esp + LoadMicrocodeParamsFsp22.MicrocodeCodeSize]
412 cmp eax, 0ffffffffh
413 jz LoadMicrocodeDefault4
414
415 ; Address >= microcode region address + microcode region size?
416 add eax, dword [esp + LoadMicrocodeParamsFsp22.MicrocodeCodeAddr]
417 cmp esi, eax
418 jae Done ;Jif address is outside of microcode region
419 jmp CheckMainHeader
420
421 Fsp24UpdHeader1:
422 ; UPD structure is compliant with FSP spec 2.4
423 ; Is automatic size detection ?
424 mov eax, dword [esp + LoadMicrocodeParamsFsp24.MicrocodeCodeSize]
425 cmp eax, 0ffffffffh
426 jz LoadMicrocodeDefault4
427
428 ; Address >= microcode region address + microcode region size?
429 add eax, dword [esp + LoadMicrocodeParamsFsp24.MicrocodeCodeAddr]
430 cmp esi, eax
431 jae Done ;Jif address is outside of microcode region
432 jmp CheckMainHeader
433
434 LoadMicrocodeDefault4:
435 ; Is valid Microcode start point ?
436 cmp dword [esi + MicrocodeHdr.MicrocodeHdrVersion], 0ffffffffh
437 jz Done
438
439 LoadCheck:
440 ; Get the revision of the current microcode update loaded
441 mov ecx, MSR_IA32_BIOS_SIGN_ID
442 xor eax, eax ; Clear EAX
443 xor edx, edx ; Clear EDX
444 wrmsr ; Load 0 to MSR at 8Bh
445
446 mov eax, 1
447 cpuid
448 mov ecx, MSR_IA32_BIOS_SIGN_ID
449 rdmsr ; Get current microcode signature
450
451 ; Verify this microcode update is not already loaded
452 cmp dword [esi + MicrocodeHdr.MicrocodeHdrRevision], edx
453 je Continue
454
455 LoadMicrocode:
456 ; EAX contains the linear address of the start of the Update Data
457 ; EDX contains zero
458 ; ECX contains 79h (IA32_BIOS_UPDT_TRIG)
459 ; Start microcode load with wrmsr
460 mov eax, esi
461 add eax, MicrocodeHdr.size
462 xor edx, edx
463 mov ecx, MSR_IA32_BIOS_UPDT_TRIG
464 wrmsr
465 mov eax, 1
466 cpuid
467
468 Continue:
469 jmp NextMicrocode
470
471 Done:
472 mov eax, 1
473 cpuid
474 mov ecx, MSR_IA32_BIOS_SIGN_ID
475 rdmsr ; Get current microcode signature
476 xor eax, eax
477 cmp edx, 0
478 jnz Exit2
479 mov eax, 08000000Eh
480
481 Exit2:
482 jmp ebp
483
484 ;
485 ; EstablishStackFsp: EDI should be preserved cross this function
486 ;
487 global ASM_PFX(EstablishStackFsp)
488 ASM_PFX(EstablishStackFsp):
489 ;
490 ; Save parameter pointer in edx
491 ;
492 mov edx, ecx ; ECX has been assigned to UPD region
493
494 ;
495 ; Enable FSP STACK
496 ;
497 mov esp, DWORD [ASM_PFX(PcdGet32 (PcdTemporaryRamBase))]
498 add esp, DWORD [ASM_PFX(PcdGet32 (PcdTemporaryRamSize))]
499
500 push DATA_LEN_OF_MCUD ; Size of the data region
501 push 4455434Dh ; Signature of the data region 'MCUD'
502
503 ; check UPD structure revision (edx + 8)
504 cmp byte [edx + LoadMicrocodeParamsFsp22.FspUpdHeaderRevision], 2
505 jb Fsp20UpdHeader2
506 cmp byte [esp + LoadMicrocodeParamsFsp22.FsptArchRevision], 2
507 je Fsp24UpdHeader2
508 jmp Fsp22UpdHeader2
509
510 Fsp20UpdHeader2:
511 ; UPD structure is compliant with FSP spec 2.0/2.1
512 push dword [edx + LoadMicrocodeParams.CodeRegionSize] ; Code size sizeof(FSPT_UPD_COMMON) + 12
513 push dword [edx + LoadMicrocodeParams.CodeRegionBase] ; Code base sizeof(FSPT_UPD_COMMON) + 8
514 push dword [edx + LoadMicrocodeParams.MicrocodeCodeSize] ; Microcode size sizeof(FSPT_UPD_COMMON) + 4
515 push dword [edx + LoadMicrocodeParams.MicrocodeCodeAddr] ; Microcode base sizeof(FSPT_UPD_COMMON) + 0
516 jmp ContinueAfterUpdPush
517
518 Fsp22UpdHeader2:
519 ; UPD structure is compliant with FSP spec 2.2
520 push dword [edx + LoadMicrocodeParamsFsp22.CodeRegionSize] ; Code size sizeof(FSPT_UPD_COMMON) + 12
521 push dword [edx + LoadMicrocodeParamsFsp22.CodeRegionBase] ; Code base sizeof(FSPT_UPD_COMMON) + 8
522 push dword [edx + LoadMicrocodeParamsFsp22.MicrocodeCodeSize] ; Microcode size sizeof(FSPT_UPD_COMMON) + 4
523 push dword [edx + LoadMicrocodeParamsFsp22.MicrocodeCodeAddr] ; Microcode base sizeof(FSPT_UPD_COMMON) + 0
524 jmp ContinueAfterUpdPush
525
526 Fsp24UpdHeader2:
527 ; UPD structure is compliant with FSP spec 2.4
528 push dword [edx + LoadMicrocodeParamsFsp24.CodeRegionSize] ; Code size sizeof(FSPT_UPD_COMMON) + 24
529 push dword [edx + LoadMicrocodeParamsFsp24.CodeRegionBase] ; Code base sizeof(FSPT_UPD_COMMON) + 16
530 push dword [edx + LoadMicrocodeParamsFsp24.MicrocodeCodeSize] ; Microcode size sizeof(FSPT_UPD_COMMON) + 8
531 push dword [edx + LoadMicrocodeParamsFsp24.MicrocodeCodeAddr] ; Microcode base sizeof(FSPT_UPD_COMMON) + 0
532
533 ContinueAfterUpdPush:
534 ;
535 ; Save API entry/exit timestamp into stack
536 ;
537 push DATA_LEN_OF_PER0 ; Size of the data region
538 push 30524550h ; Signature of the data region 'PER0'
539 rdtsc
540 push edx
541 push eax
542 LOAD_EDX
543 push edx
544 LOAD_EAX
545 push eax
546
547 ;
548 ; Terminator for the data on stack
549 ;
550 push 0
551
552 ;
553 ; Set ECX/EDX to the BootLoader temporary memory range
554 ;
555 mov ecx, [ASM_PFX(PcdGet32 (PcdTemporaryRamBase))]
556 mov edx, ecx
557 add edx, [ASM_PFX(PcdGet32 (PcdTemporaryRamSize))]
558 sub edx, [ASM_PFX(PcdGet32 (PcdFspReservedBufferSize))]
559
560 cmp ecx, edx ;If PcdFspReservedBufferSize >= PcdTemporaryRamSize, then error.
561 jb EstablishStackFspSuccess
562 mov eax, 80000003h ;EFI_UNSUPPORTED
563 jmp EstablishStackFspExit
564 EstablishStackFspSuccess:
565 xor eax, eax
566
567 EstablishStackFspExit:
568 RET_ESI
569
570 ;----------------------------------------------------------------------------
571 ; TempRamInit API
572 ;
573 ; This FSP API will load the microcode update, enable code caching for the
574 ; region specified by the boot loader and also setup a temporary stack to be
575 ; used till main memory is initialized.
576 ;
577 ;----------------------------------------------------------------------------
578 global ASM_PFX(TempRamInitApi)
579 ASM_PFX(TempRamInitApi):
580 ;
581 ; Ensure SSE is enabled
582 ;
583 ENABLE_SSE
584
585 ;
586 ; Save EBP, EBX, ESI, EDI & ESP in XMM7 & XMM6
587 ;
588 SAVE_REGS
589
590 ;
591 ; Save timestamp into XMM6
592 ;
593 rdtsc
594 SAVE_EAX
595 SAVE_EDX
596
597 CALL_EBP ASM_PFX(LoadUpdPointerToECX) ; ECX for UPD param
598 SAVE_ECX ; save UPD param to slot 3 in xmm6
599
600 ;
601 ; Sec Platform Init
602 ;
603 CALL_MMX ASM_PFX(SecPlatformInit)
604 cmp eax, 0
605 jnz TempRamInitExit
606
607 ; Load microcode
608 LOAD_ESP
609 LOAD_ECX
610 CALL_MMX ASM_PFX(LoadMicrocodeDefault)
611 SAVE_UCODE_STATUS ; Save microcode return status in slot 1 in xmm5.
612 ;@note If return value eax is not 0, microcode did not load, but continue and attempt to boot.
613
614 ; Call Sec CAR Init
615 LOAD_ESP
616 LOAD_ECX
617 CALL_MMX ASM_PFX(SecCarInit)
618 cmp eax, 0
619 jnz TempRamInitExit
620
621 LOAD_ESP
622 LOAD_ECX
623 mov edi, ecx ; Save UPD param to EDI for later code use
624 CALL_MMX ASM_PFX(EstablishStackFsp)
625 cmp eax, 0
626 jnz TempRamInitExit
627
628 LOAD_UCODE_STATUS ; Restore microcode status if no CAR init error from slot 1 in xmm5.
629
630 TempRamInitExit:
631 mov bl, al ; save al data in bl
632 mov al, 07Fh ; API exit postcode 7f
633 out 080h, al
634 mov al, bl ; restore al data from bl
635
636 ;
637 ; Load EBP, EBX, ESI, EDI & ESP from XMM7 & XMM6
638 ;
639 LOAD_REGS
640 ret
641
642 ;----------------------------------------------------------------------------
643 ; Module Entrypoint API
644 ;----------------------------------------------------------------------------
645 global ASM_PFX(_ModuleEntryPoint)
646 ASM_PFX(_ModuleEntryPoint):
647 jmp $