]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - IntelFspPkg/FspSecCore/Ia32/FspApiEntry.s
Fix FSP GCC error on FspApiCallingCheck().
[mirror_edk2.git] / IntelFspPkg / FspSecCore / Ia32 / FspApiEntry.s
... / ...
CommitLineData
1#------------------------------------------------------------------------------\r
2#\r
3# Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR>\r
4# This program and the accompanying materials\r
5# are licensed and made available under the terms and conditions of the BSD License\r
6# which accompanies this distribution. The full text of the license may be found at\r
7# http://opensource.org/licenses/bsd-license.php.\r
8#\r
9# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
10# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
11#\r
12# Abstract:\r
13#\r
14# Provide FSP API entry points.\r
15#\r
16#------------------------------------------------------------------------------\r
17\r
18\r
19.equ MSR_IA32_PLATFORM_ID, 0x00000017\r
20.equ MSR_IA32_BIOS_UPDT_TRIG, 0x00000079\r
21.equ MSR_IA32_BIOS_SIGN_ID, 0x0000008b\r
22\r
23\r
24MicrocodeHdr:\r
25.equ MicrocodeHdrVersion, 0x0000\r
26.equ MicrocodeHdrRevision, 0x0004\r
27.equ MicrocodeHdrDate, 0x0008\r
28.equ MicrocodeHdrProcessor, 0x000c\r
29.equ MicrocodeHdrChecksum, 0x0010\r
30.equ MicrocodeHdrLoader, 0x0014\r
31.equ MicrocodeHdrFlags, 0x0018\r
32.equ MicrocodeHdrDataSize, 0x001C\r
33.equ MicrocodeHdrTotalSize, 0x0020\r
34.equ MicrocodeHdrRsvd, 0x0024\r
35MicrocodeHdrEnd:\r
36.equ MicrocodeHdrLength, 0x0030 # MicrocodeHdrLength = MicrocodeHdrEnd - MicrocodeHdr\r
37\r
38\r
39ExtSigHdr:\r
40.equ ExtSigHdrCount, 0x0000\r
41.equ ExtSigHdrChecksum, 0x0004\r
42.equ ExtSigHdrRsvd, 0x0008\r
43ExtSigHdrEnd:\r
44.equ ExtSigHdrLength, 0x0014 #ExtSigHdrLength = ExtSigHdrEnd - ExtSigHdr\r
45\r
46ExtSig:\r
47.equ ExtSigProcessor, 0x0000\r
48.equ ExtSigFlags, 0x0004\r
49.equ ExtSigChecksum, 0x0008\r
50ExtSigEnd:\r
51.equ ExtSigLength, 0x000C #ExtSigLength = ExtSigEnd - ExtSig\r
52\r
53LoadMicrocodeParams:\r
54.equ MicrocodeCodeAddr, 0x0000\r
55.equ MicrocodeCodeSize, 0x0004\r
56LoadMicrocodeParamsEnd:\r
57\r
58\r
59\r
60.macro SAVE_REGS\r
61 pinsrw $0x00, %ebp, %xmm7\r
62 ror $0x10, %ebp\r
63 pinsrw $0x01, %ebp, %xmm7\r
64 ror $0x10, %ebp\r
65#\r
66 pinsrw $0x02, %ebx, %xmm7\r
67 ror $0x10, %ebx\r
68 pinsrw $0x03, %ebx, %xmm7\r
69 ror $0x10, %ebx\r
70#\r
71 pinsrw $0x04, %esi, %xmm7\r
72 ror $0x10, %esi\r
73 pinsrw $0x05, %esi, %xmm7\r
74 ror $0x10, %esi\r
75#\r
76 pinsrw $0x06, %edi, %xmm7\r
77 ror $0x10, %edi\r
78 pinsrw $0x07, %edi, %xmm7\r
79 ror $0x10, %edi\r
80#\r
81 pinsrw $0x00, %esp, %xmm6\r
82 ror $0x10, %esp\r
83 pinsrw $0x01, %esp, %xmm6\r
84 ror $0x10, %esp\r
85.endm\r
86\r
87.macro LOAD_REGS\r
88 pshufd $0xe4, %xmm7, %xmm7\r
89 movd %xmm7, %ebp \r
90 pshufd $0xe4, %xmm7, %xmm7\r
91#\r
92 pshufd $0x39, %xmm7, %xmm7\r
93 movd %xmm7, %ebx\r
94 pshufd $0x93, %xmm7, %xmm7\r
95#\r
96 pshufd $0x4e, %xmm7, %xmm7\r
97 movd %xmm7, %esi\r
98 pshufd $0x4e, %xmm7, %xmm7\r
99#\r
100 pshufd $0x93, %xmm7, %xmm7\r
101 movd %xmm7, %edi\r
102 pshufd $0x39, %xmm7, %xmm7\r
103#\r
104 movd %xmm6, %esp\r
105.endm\r
106\r
107.macro LOAD_EAX\r
108 pshufd $0x39, %xmm6, %xmm6\r
109 movd %xmm6, %eax\r
110 pshufd $0x93, %xmm6, %xmm6\r
111.endm\r
112\r
113.macro LOAD_EDX\r
114 pshufd $0xe4, %xmm6, %xmm6\r
115 movd %xmm6, %edx\r
116 pshufd $0xe4, %xmm6, %xmm6\r
117.endm\r
118\r
119.macro SAVE_EAX\r
120 pinsrw $0x02, %eax, %xmm6\r
121 ror $0x10, %eax\r
122 pinsrw $0x03, %eax, %xmm6\r
123 ror $0x10, %eax\r
124.endm\r
125\r
126.macro SAVE_EDX\r
127 pinsrw $0x04, %edx, %xmm6\r
128 ror $0x10, %edx\r
129 pinsrw $0x05, %edx, %xmm6\r
130 ror $0x10, %edx\r
131.endm\r
132\r
133.macro LOAD_ESP\r
134 movd %xmm6, %esp\r
135.endm\r
136\r
137.macro ENABLE_SSE\r
138 jmp NextAddress\r
139.align 4\r
140 #\r
141 # Float control word initial value:\r
142 # all exceptions masked, double-precision, round-to-nearest\r
143 #\r
144ASM_PFX(mFpuControlWord): .word 0x027F\r
145 #\r
146 # Multimedia-extensions control word:\r
147 # all exceptions masked, round-to-nearest, flush to zero for masked underflow\r
148 #\r
149ASM_PFX(mMmxControlWord): .long 0x01F80\r
150SseError: \r
151 #\r
152 # Processor has to support SSE\r
153 #\r
154 jmp SseError \r
155NextAddress: \r
156 #\r
157 # Initialize floating point units\r
158 #\r
159 finit\r
160 fldcw ASM_PFX(mFpuControlWord)\r
161\r
162 #\r
163 # Use CpuId instructuion (CPUID.01H:EDX.SSE[bit 25] = 1) to test\r
164 # whether the processor supports SSE instruction.\r
165 #\r
166 movl $1, %eax\r
167 cpuid\r
168 btl $25, %edx\r
169 jnc SseError\r
170\r
171 #\r
172 # Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10)\r
173 #\r
174 movl %cr4, %eax\r
175 orl $BIT9, %eax\r
176 movl %eax, %cr4\r
177\r
178 #\r
179 # The processor should support SSE instruction and we can use\r
180 # ldmxcsr instruction\r
181 #\r
182 ldmxcsr ASM_PFX(mMmxControlWord)\r
183.endm\r
184\r
185#Save in ECX-SLOT 3 in xmm6.\r
186.macro SAVE_EAX_MICROCODE_RET_STATUS\r
187 pinsrw $0x6, %eax, %xmm6\r
188 ror $0x10, %eax\r
189 pinsrw $0x7, %eax, %xmm6\r
190 rol $0x10, %eax\r
191.endm\r
192\r
193#Restore from ECX-SLOT 3 in xmm6.\r
194.macro LOAD_EAX_MICROCODE_RET_STATUS\r
195 pshufd $0x93, %xmm6, %xmm6\r
196 movd %xmm6, %eax\r
197 pshufd $0x39, %xmm6, %xmm6\r
198.endm\r
199\r
200\r
201\r
202#\r
203# Following are fixed PCDs\r
204#\r
205ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamBase)\r
206ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamSize)\r
207ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdFspTemporaryRamSize)\r
208\r
209#\r
210# Following functions will be provided in C\r
211#\r
212ASM_GLOBAL ASM_PFX(SecStartup)\r
213ASM_GLOBAL ASM_PFX(FspApiCallingCheck)\r
214\r
215#\r
216# Following functions will be provided in PlatformSecLib\r
217#\r
218ASM_GLOBAL ASM_PFX(AsmGetFspBaseAddress)\r
219ASM_GLOBAL ASM_PFX(AsmGetFspInfoHeader)\r
220ASM_GLOBAL ASM_PFX(GetBootFirmwareVolumeOffset)\r
221ASM_GLOBAL ASM_PFX(Loader2PeiSwitchStack)\r
222\r
223\r
224#\r
225# Define the data length that we saved on the stack top\r
226#\r
227.equ DATA_LEN_OF_PER0, 0x018\r
228.equ DATA_LEN_OF_MCUD, 0x018\r
229.equ DATA_LEN_AT_STACK_TOP, (DATA_LEN_OF_PER0 + DATA_LEN_OF_MCUD + 4)\r
230\r
231#------------------------------------------------------------------------------\r
232# SecPlatformInitDefault\r
233# Inputs:\r
234# mm7 -> Return address\r
235# Outputs:\r
236# eax -> 0 - Successful, Non-zero - Failed.\r
237# Register Usage:\r
238# eax is cleared and ebp is used for return address.\r
239# All others reserved.\r
240#------------------------------------------------------------------------------\r
241ASM_GLOBAL ASM_PFX(SecPlatformInitDefault)\r
242ASM_PFX(SecPlatformInitDefault):\r
243 #\r
244 # Save return address to EBP\r
245 #\r
246 movd %mm7, %ebp\r
247 xorl %eax, %eax\r
248\r
249SecPlatformInitDefaultExit:\r
250 jmp *%ebp\r
251\r
252\r
253#------------------------------------------------------------------------------\r
254# LoadMicrocodeDefault\r
255#\r
256# Inputs:\r
257# esp -> LoadMicrocodeParams pointer\r
258# Register Usage:\r
259# esp Preserved\r
260# All others destroyed\r
261# Assumptions:\r
262# No memory available, stack is hard-coded and used for return address\r
263# Executed by SBSP and NBSP\r
264# Beginning of microcode update region starts on paragraph boundary\r
265#------------------------------------------------------------------------------\r
266ASM_GLOBAL ASM_PFX(LoadMicrocodeDefault)\r
267ASM_PFX(LoadMicrocodeDefault):\r
268 #\r
269 # Save return address to EBP\r
270 #\r
271 movd %mm7, %ebp\r
272\r
273 cmpl $0x00, %esp\r
274 jz ParamError\r
275 movl 4(%esp), %eax #dword ptr [] Parameter pointer\r
276 cmpl $0x00, %eax\r
277 jz ParamError\r
278 movl %eax, %esp\r
279 movl MicrocodeCodeAddr(%esp), %esi\r
280 cmpl $0x00, %esi\r
281 jnz CheckMainHeader\r
282\r
283ParamError:\r
284 movl $0x080000002, %eax\r
285 jmp LoadMicrocodeExit\r
286\r
287CheckMainHeader:\r
288 #\r
289 # Get processor signature and platform ID from the installed processor\r
290 # and save into registers for later use\r
291 # ebx = processor signature\r
292 # edx = platform ID\r
293 #\r
294 movl $0x01, %eax\r
295 cpuid\r
296 movl %eax, %ebx\r
297 movl $MSR_IA32_PLATFORM_ID, %ecx\r
298 rdmsr\r
299 movl %edx, %ecx\r
300 shrl $0x12, %ecx #($50-$32)\r
301 andl $0x07, %ecx\r
302 movl $0x01, %edx\r
303 shll %cl,%edx\r
304\r
305 #\r
306 # Current register usage\r
307 # esp -> stack with paramters\r
308 # esi -> microcode update to check\r
309 # ebx = processor signature\r
310 # edx = platform ID\r
311 #\r
312\r
313 #\r
314 # Check for valid microcode header\r
315 # Minimal test checking for header version and loader version as 1\r
316 #\r
317 movl $0x01, %eax\r
318 cmpl %eax, MicrocodeHdrVersion(%esi)\r
319 jne AdvanceFixedSize\r
320 cmpl %eax, MicrocodeHdrLoader(%esi)\r
321 jne AdvanceFixedSize\r
322\r
323 #\r
324 # Check if signature and plaform ID match\r
325 #\r
326 cmpl MicrocodeHdrProcessor(%esi), %ebx\r
327 jne LoadMicrocodeL0\r
328 testl MicrocodeHdrFlags(%esi), %edx\r
329 jnz LoadCheck #Jif signature and platform ID match\r
330\r
331LoadMicrocodeL0:\r
332 #\r
333 # Check if extended header exists\r
334 # First check if MicrocodeHdrTotalSize and MicrocodeHdrDataSize are valid\r
335 #\r
336 xorl %eax, %eax\r
337 cmpl %eax, MicrocodeHdrTotalSize(%esi)\r
338 je NextMicrocode\r
339 cmpl %eax, MicrocodeHdrDataSize(%esi)\r
340 je NextMicrocode\r
341\r
342 #\r
343 # Then verify total size - sizeof header > data size\r
344 #\r
345 movl MicrocodeHdrTotalSize(%esi), %ecx\r
346 subl $MicrocodeHdrLength, %ecx\r
347 cmpl MicrocodeHdrDataSize(%esi), %ecx\r
348 jle NextMicrocode\r
349\r
350 #\r
351 # Set edi -> extended header\r
352 #\r
353 movl %esi, %edi\r
354 addl $MicrocodeHdrLength, %edi\r
355 addl MicrocodeHdrDataSize(%esi), %edi\r
356\r
357 #\r
358 # Get count of extended structures\r
359 #\r
360 movl ExtSigHdrCount(%edi), %ecx\r
361\r
362 #\r
363 # Move pointer to first signature structure\r
364 #\r
365 addl ExtSigHdrLength, %edi\r
366\r
367CheckExtSig:\r
368 #\r
369 # Check if extended signature and platform ID match\r
370 #\r
371 cmpl %ebx, ExtSigProcessor(%edi)\r
372 jne LoadMicrocodeL1\r
373 test %edx, ExtSigFlags(%edi)\r
374 jnz LoadCheck # Jif signature and platform ID match\r
375LoadMicrocodeL1:\r
376 #\r
377 # Check if any more extended signatures exist\r
378 #\r
379 addl $ExtSigLength, %edi\r
380 loop CheckExtSig\r
381\r
382NextMicrocode:\r
383 #\r
384 # Advance just after end of this microcode\r
385 #\r
386 xorl %eax, %eax\r
387 cmpl %eax, MicrocodeHdrTotalSize(%esi)\r
388 je LoadMicrocodeL2\r
389 addl MicrocodeHdrTotalSize(%esi), %esi\r
390 jmp CheckAddress\r
391LoadMicrocodeL2:\r
392 addl $0x800, %esi #add esi, dword ptr 2048\r
393 jmp CheckAddress\r
394\r
395AdvanceFixedSize:\r
396 #\r
397 # Advance by 4X dwords\r
398 #\r
399 addl $0x400, %esi #add esi, dword ptr 1024\r
400\r
401CheckAddress:\r
402 #\r
403 # Is valid Microcode start point ?\r
404 #\r
405 cmpl $0x0ffffffff, MicrocodeHdrVersion(%esi)\r
406\r
407 #\r
408 # Is automatic size detection ?\r
409 #\r
410 movl MicrocodeCodeSize(%esp), %eax\r
411 cmpl $0x0ffffffff, %eax\r
412 jz LoadMicrocodeL3\r
413 #\r
414 # Address >= microcode region address + microcode region size?\r
415 #\r
416 addl MicrocodeCodeAddr(%esp), %eax\r
417\r
418 cmpl %eax, %esi\r
419 jae Done #Jif address is outside of microcode region\r
420 jmp CheckMainHeader\r
421\r
422LoadMicrocodeL3:\r
423LoadCheck:\r
424 #\r
425 # Get the revision of the current microcode update loaded\r
426 #\r
427 movl $MSR_IA32_BIOS_SIGN_ID, %ecx\r
428 xorl %eax, %eax # Clear EAX\r
429 xorl %edx, %edx # Clear EDX\r
430 wrmsr # Load 0 to MSR at 8Bh\r
431\r
432 movl $0x01, %eax\r
433 cpuid\r
434 movl $MSR_IA32_BIOS_SIGN_ID, %ecx\r
435 rdmsr # Get current microcode signature\r
436\r
437 #\r
438 # Verify this microcode update is not already loaded\r
439 #\r
440 cmpl %edx, MicrocodeHdrRevision(%esi)\r
441 je Continue\r
442\r
443LoadMicrocode0:\r
444 #\r
445 # EAX contains the linear address of the start of the Update Data\r
446 # EDX contains zero\r
447 # ECX contains 79h (IA32_BIOS_UPDT_TRIG)\r
448 # Start microcode load with wrmsr\r
449 #\r
450 movl %esi, %eax\r
451 addl $MicrocodeHdrLength, %eax\r
452 xorl %edx, %edx\r
453 movl $MSR_IA32_BIOS_UPDT_TRIG, %ecx\r
454 wrmsr\r
455 movl $0x01, %eax\r
456 cpuid\r
457\r
458Continue:\r
459 jmp NextMicrocode\r
460\r
461Done:\r
462 movl $0x01, %eax\r
463 cpuid\r
464 movl $MSR_IA32_BIOS_SIGN_ID, %ecx\r
465 rdmsr # Get current microcode signature\r
466 xorl %eax, %eax\r
467 cmpl $0x00, %edx\r
468 jnz LoadMicrocodeExit\r
469 movl $0x08000000E, %eax\r
470\r
471LoadMicrocodeExit:\r
472 jmp *%ebp\r
473\r
474\r
475#----------------------------------------------------------------------------\r
476# EstablishStackFsp\r
477#\r
478#----------------------------------------------------------------------------\r
479ASM_GLOBAL ASM_PFX(EstablishStackFsp)\r
480ASM_PFX(EstablishStackFsp):\r
481 #\r
482 # Save parameter pointer in edx\r
483 #\r
484 movl 4(%esp), %edx\r
485\r
486 #\r
487 # Enable FSP STACK\r
488 #\r
489 movl PcdGet32(PcdTemporaryRamBase), %esp\r
490 addl PcdGet32(PcdTemporaryRamSize), %esp\r
491\r
492 pushl $DATA_LEN_OF_MCUD # Size of the data region\r
493 pushl $0x4455434D # Signature of the data region 'MCUD'\r
494 pushl 12(%edx) # Code size\r
495 pushl 8(%edx) # Code base\r
496 pushl 4(%edx) # Microcode size\r
497 pushl (%edx) # Microcode base\r
498\r
499 #\r
500 # Save API entry/exit timestamp into stack\r
501 #\r
502 pushl $DATA_LEN_OF_PER0 # Size of the data region\r
503 pushl $0x30524550 # Signature of the data region 'PER0'\r
504 LOAD_EDX\r
505 pushl %edx\r
506 LOAD_EAX\r
507 pushl %eax\r
508 rdtsc\r
509 pushl %edx\r
510 pushl %eax\r
511\r
512 #\r
513 # Terminator for the data on stack\r
514 #\r
515 push $0x00\r
516\r
517 #\r
518 # Set ECX/EDX to the BootLoader temporary memory range\r
519 #\r
520 movl PcdGet32 (PcdTemporaryRamBase), %ecx\r
521 movl %ecx, %edx\r
522 addl PcdGet32 (PcdTemporaryRamSize), %edx\r
523 subl PcdGet32 (PcdFspTemporaryRamSize), %edx\r
524\r
525 xorl %eax, %eax\r
526\r
527 movd %mm7, %esi #RET_ESI\r
528 jmp *%esi\r
529\r
530#----------------------------------------------------------------------------\r
531# TempRamInit API\r
532#\r
533# This FSP API will load the microcode update, enable code caching for the\r
534# region specified by the boot loader and also setup a temporary stack to be\r
535# used till main memory is initialized.\r
536#\r
537#----------------------------------------------------------------------------\r
538ASM_GLOBAL ASM_PFX(TempRamInitApi)\r
539ASM_PFX(TempRamInitApi):\r
540 #\r
541 # Ensure SSE is enabled\r
542 #\r
543 ENABLE_SSE\r
544\r
545 #\r
546 # Save EBP, EBX, ESI, EDI & ESP in XMM7 & XMM6\r
547 #\r
548 SAVE_REGS\r
549\r
550 #\r
551 # Save timestamp into XMM6\r
552 #\r
553 rdtsc\r
554 SAVE_EAX\r
555 SAVE_EDX\r
556\r
557 #\r
558 # Check Parameter\r
559 #\r
560 movl 4(%esp), %eax\r
561 cmpl $0x00, %eax\r
562 movl $0x80000002, %eax\r
563 jz NemInitExit\r
564\r
565 #\r
566 # Sec Platform Init\r
567 #\r
568 movl $TempRamInitApiL1, %esi #CALL_MMX SecPlatformInit\r
569 movd %esi, %mm7\r
570 .weak ASM_PFX(SecPlatformInit)\r
571 .set ASM_PFX(SecPlatformInit), ASM_PFX(SecPlatformInitDefault)\r
572 jmp ASM_PFX(SecPlatformInit)\r
573TempRamInitApiL1:\r
574 cmpl $0x00, %eax\r
575 jnz NemInitExit\r
576\r
577 #\r
578 # Load microcode\r
579 #\r
580 LOAD_ESP\r
581 movl $TempRamInitApiL2, %esi #CALL_MMX LoadMicrocode\r
582 movd %esi, %mm7\r
583 .weak ASM_PFX(LoadMicrocode)\r
584 .set ASM_PFX(LoadMicrocode), ASM_PFX(LoadMicrocodeDefault)\r
585 jmp ASM_PFX(LoadMicrocode)\r
586TempRamInitApiL2:\r
587 SAVE_EAX_MICROCODE_RET_STATUS #Save microcode return status in ECX-SLOT 3 in xmm6.\r
588 #@note If return value eax is not 0, microcode did not load, but continue and attempt to boot from ECX-SLOT 3 in xmm6.\r
589\r
590 #\r
591 # Call Sec CAR Init\r
592 #\r
593 LOAD_ESP\r
594 movl $TempRamInitApiL3, %esi #CALL_MMX SecCarInit\r
595 movd %esi, %mm7\r
596 jmp ASM_PFX(SecCarInit)\r
597TempRamInitApiL3:\r
598 cmpl $0x00, %eax\r
599 jnz NemInitExit\r
600\r
601 #\r
602 # EstablishStackFsp\r
603 #\r
604 LOAD_ESP\r
605 movl $TempRamInitApiL4, %esi #CALL_MMX EstablishStackFsp\r
606 movd %esi, %mm7\r
607 jmp ASM_PFX(EstablishStackFsp)\r
608TempRamInitApiL4:\r
609\r
610 LOAD_EAX_MICROCODE_RET_STATUS #Restore microcode status if no CAR init error.\r
611\r
612NemInitExit:\r
613 #\r
614 # Load EBP, EBX, ESI, EDI & ESP from XMM7 & XMM6\r
615 #\r
616 LOAD_REGS\r
617 ret\r
618\r
619\r
620#----------------------------------------------------------------------------\r
621# FspInit API\r
622#\r
623# This FSP API will perform the processor and chipset initialization.\r
624# This API will not return. Instead, it transfers the control to the\r
625# ContinuationFunc provided in the parameter.\r
626#\r
627#----------------------------------------------------------------------------\r
628ASM_GLOBAL ASM_PFX(FspInitApi)\r
629ASM_PFX(FspInitApi):\r
630 movl $0x01, %eax\r
631 jmp FspApiCommon\r
632\r
633#----------------------------------------------------------------------------\r
634# NotifyPhase API\r
635#\r
636# This FSP API will notify the FSP about the different phases in the boot\r
637# process\r
638#\r
639#----------------------------------------------------------------------------\r
640ASM_GLOBAL ASM_PFX(NotifyPhaseApi)\r
641ASM_PFX(NotifyPhaseApi):\r
642 movl $0x02, %eax\r
643 jmp FspApiCommon\r
644\r
645#----------------------------------------------------------------------------\r
646# FspMemoryInit API\r
647#\r
648# This FSP API is called after TempRamInit and initializes the memory.\r
649#\r
650#----------------------------------------------------------------------------\r
651ASM_GLOBAL ASM_PFX(FspMemoryInitApi)\r
652ASM_PFX(FspMemoryInitApi):\r
653 movl $0x03, %eax\r
654 jmp FspApiCommon\r
655\r
656#----------------------------------------------------------------------------\r
657# TempRamExitApi API\r
658#\r
659# This API tears down temporary RAM\r
660#\r
661#----------------------------------------------------------------------------\r
662ASM_GLOBAL ASM_PFX(TempRamExitApi)\r
663ASM_PFX(TempRamExitApi):\r
664 movl $0x04, %eax\r
665 jmp FspApiCommon\r
666\r
667#----------------------------------------------------------------------------\r
668# FspSiliconInit API\r
669#\r
670# This FSP API initializes the CPU and the chipset including the IO\r
671# controllers in the chipset to enable normal operation of these devices.\r
672#\r
673#----------------------------------------------------------------------------\r
674ASM_GLOBAL ASM_PFX(FspSiliconInitApi)\r
675ASM_PFX(FspSiliconInitApi):\r
676 movl $0x05, %eax\r
677 jmp FspApiCommon\r
678\r
679#----------------------------------------------------------------------------\r
680# FspApiCommon API\r
681#\r
682# This is the FSP API common entry point to resume the FSP execution\r
683#\r
684#----------------------------------------------------------------------------\r
685ASM_GLOBAL ASM_PFX(FspApiCommon)\r
686ASM_PFX(FspApiCommon):\r
687 #\r
688 # EAX holds the API index\r
689 #\r
690\r
691 #\r
692 # Stack must be ready\r
693 # \r
694 pushl %eax\r
695 addl $0x04, %esp\r
696 cmpl -4(%esp), %eax\r
697 jz FspApiCommonL0\r
698 movl $0x080000003, %eax\r
699 jmp FspApiCommonExit\r
700\r
701FspApiCommonL0:\r
702 #\r
703 # Verify the calling condition\r
704 #\r
705 pushal\r
706 pushl 36(%esp) #push ApiParam [esp + 4 * 8 + 4]\r
707 pushl %eax #push ApiIdx\r
708 call ASM_PFX(FspApiCallingCheck)\r
709 addl $0x08, %esp\r
710 cmpl $0x00, %eax\r
711 jz FspApiCommonL1\r
712 movl %eax, 0x1C(%esp) # mov dword ptr [esp + 4 * 7], eax\r
713 popal\r
714 ret\r
715\r
716FspApiCommonL1:\r
717 popal\r
718 cmpl $0x01, %eax # FspInit API\r
719 jz FspApiCommonL2\r
720 cmpl $0x03, %eax # FspMemoryInit API\r
721 jz FspApiCommonL2\r
722 call ASM_PFX(AsmGetFspInfoHeader)\r
723 jmp Loader2PeiSwitchStack\r
724\r
725FspApiCommonL2:\r
726 #\r
727 # FspInit and FspMemoryInit APIs, setup the initial stack frame\r
728 # \r
729 \r
730 #\r
731 # Place holder to store the FspInfoHeader pointer\r
732 #\r
733 pushl %eax\r
734\r
735 #\r
736 # Update the FspInfoHeader pointer\r
737 #\r
738 pushl %eax\r
739 call ASM_PFX(AsmGetFspInfoHeader)\r
740 movl %eax, 4(%esp)\r
741 popl %eax\r
742\r
743 #\r
744 # Create a Task Frame in the stack for the Boot Loader\r
745 #\r
746 pushfl # 2 pushf for 4 byte alignment\r
747 cli\r
748 pushal\r
749\r
750 #\r
751 # Reserve 8 bytes for IDT save/restore\r
752 #\r
753 subl $0x08, %esp\r
754 sidt (%esp)\r
755\r
756 #\r
757 # Setup new FSP stack\r
758 #\r
759 movl %esp, %edi\r
760 movl PcdGet32(PcdTemporaryRamBase), %esp\r
761 addl PcdGet32(PcdTemporaryRamSize), %esp\r
762 subl $(DATA_LEN_AT_STACK_TOP + 0x40), %esp\r
763\r
764 #\r
765 # Pass the API Idx to SecStartup\r
766 #\r
767 pushl %eax\r
768 \r
769 #\r
770 # Pass the BootLoader stack to SecStartup\r
771 #\r
772 pushl %edi\r
773\r
774 #\r
775 # Pass entry point of the PEI core\r
776 #\r
777 call ASM_PFX(AsmGetFspBaseAddress)\r
778 movl %eax, %edi\r
779 addl PcdGet32(PcdFspAreaSize), %edi\r
780 subl $0x20, %edi\r
781 addl %ds:(%edi), %eax\r
782 pushl %eax\r
783\r
784 #\r
785 # Pass BFV into the PEI Core\r
786 # It uses relative address to calucate the actual boot FV base\r
787 # For FSP impleantion with single FV, PcdFlashFvRecoveryBase and\r
788 # PcdFspAreaBaseAddress are the same. For FSP with mulitple FVs,\r
789 # they are different. The code below can handle both cases.\r
790 #\r
791 call ASM_PFX(AsmGetFspBaseAddress)\r
792 movl %eax, %edi\r
793 call ASM_PFX(GetBootFirmwareVolumeOffset)\r
794 addl %edi, %eax\r
795 pushl %eax\r
796\r
797 #\r
798 # Pass stack base and size into the PEI Core\r
799 #\r
800 movl PcdGet32(PcdTemporaryRamBase), %eax\r
801 addl PcdGet32(PcdTemporaryRamSize), %eax\r
802 subl PcdGet32(PcdFspTemporaryRamSize), %eax\r
803 pushl %eax\r
804 pushl PcdGet32(PcdFspTemporaryRamSize)\r
805\r
806 #\r
807 # Pass Control into the PEI Core\r
808 #\r
809 call ASM_PFX(SecStartup)\r
810 addl $4, %esp\r
811FspApiCommonExit:\r
812 ret\r
813\r