]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFspPkg/FspSecCore/Ia32/FspApiEntry.asm
MdePkg/BaseLib: Preserve EBX register and fix stack offset to LinearAddress in AsmFlu...
[mirror_edk2.git] / IntelFspPkg / FspSecCore / Ia32 / FspApiEntry.asm
CommitLineData
d5fb1edf
JY
1;; @file\r
2; Provide FSP API entry points.\r
c8ec22a2 3;\r
d5fb1edf 4; Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR>\r
c8ec22a2
JY
5; This program and the accompanying materials\r
6; are licensed and made available under the terms and conditions of the BSD License\r
7; which accompanies this distribution. The full text of the license may be found at\r
8; http://opensource.org/licenses/bsd-license.php.\r
9;\r
10; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
d5fb1edf 12;;\r
c8ec22a2
JY
13\r
14 .586p\r
15 .model flat,C\r
16 .code\r
17 .xmm\r
18\r
19INCLUDE SaveRestoreSse.inc\r
9da59186 20INCLUDE MicrocodeLoad.inc\r
c8ec22a2
JY
21\r
22;\r
23; Following are fixed PCDs\r
24;\r
25EXTERN PcdGet32(PcdTemporaryRamBase):DWORD\r
26EXTERN PcdGet32(PcdTemporaryRamSize):DWORD\r
27EXTERN PcdGet32(PcdFspTemporaryRamSize):DWORD\r
d5fb1edf 28EXTERN PcdGet32(PcdFspAreaSize):DWORD\r
c8ec22a2
JY
29\r
30;\r
31; Following functions will be provided in C\r
32;\r
d5fb1edf 33\r
c8ec22a2
JY
34EXTERN SecStartup:PROC\r
35EXTERN FspApiCallingCheck:PROC\r
36\r
37;\r
38; Following functions will be provided in PlatformSecLib\r
39;\r
16b7e82c
JY
40EXTERN AsmGetFspBaseAddress:PROC\r
41EXTERN AsmGetFspInfoHeader:PROC\r
c8ec22a2 42EXTERN GetBootFirmwareVolumeOffset:PROC\r
3b17b245 43EXTERN Loader2PeiSwitchStack:PROC\r
9da59186 44EXTERN LoadMicrocode(LoadMicrocodeDefault):PROC\r
c030e74c 45EXTERN SecPlatformInit(SecPlatformInitDefault):PROC\r
d5fb1edf 46EXTERN SecCarInit:PROC\r
c8ec22a2
JY
47\r
48;\r
49; Define the data length that we saved on the stack top\r
50;\r
51DATA_LEN_OF_PER0 EQU 18h\r
52DATA_LEN_OF_MCUD EQU 18h\r
53DATA_LEN_AT_STACK_TOP EQU (DATA_LEN_OF_PER0 + DATA_LEN_OF_MCUD + 4)\r
54\r
d5fb1edf
JY
55;\r
56; Define SSE macros\r
57;\r
58LOAD_MMX_EXT MACRO ReturnAddress, MmxRegister\r
59 mov esi, ReturnAddress\r
1c54ceb7 60 movd MmxRegister, esi ; save ReturnAddress into MMX\r
d5fb1edf
JY
61ENDM\r
62\r
63CALL_MMX_EXT MACRO RoutineLabel, MmxRegister\r
64 local ReturnAddress\r
65 mov esi, offset ReturnAddress\r
1c54ceb7 66 movd MmxRegister, esi ; save ReturnAddress into MMX\r
d5fb1edf
JY
67 jmp RoutineLabel\r
68ReturnAddress:\r
69ENDM\r
70\r
71RET_ESI_EXT MACRO MmxRegister\r
9da59186 72 movd esi, MmxRegister ; move ReturnAddress from MMX to ESI\r
d5fb1edf
JY
73 jmp esi\r
74ENDM\r
75\r
76CALL_MMX MACRO RoutineLabel\r
77 CALL_MMX_EXT RoutineLabel, mm7\r
78ENDM\r
79\r
80RET_ESI MACRO\r
9da59186 81 RET_ESI_EXT mm7\r
d5fb1edf
JY
82ENDM\r
83\r
c8ec22a2 84;------------------------------------------------------------------------------\r
c030e74c 85SecPlatformInitDefault PROC NEAR PUBLIC\r
c8ec22a2 86 ; Inputs:\r
1c54ceb7 87 ; mm7 -> Return address\r
c8ec22a2
JY
88 ; Outputs:\r
89 ; eax -> 0 - Successful, Non-zero - Failed.\r
90 ; Register Usage:\r
91 ; eax is cleared and ebp is used for return address.\r
92 ; All others reserved.\r
1c54ceb7 93 \r
c8ec22a2 94 ; Save return address to EBP\r
c0a8cf34 95 movd ebp, mm7\r
c8ec22a2
JY
96\r
97 xor eax, eax\r
98exit:\r
99 jmp ebp\r
c030e74c 100SecPlatformInitDefault ENDP\r
c8ec22a2
JY
101\r
102;------------------------------------------------------------------------------\r
9da59186 103LoadMicrocodeDefault PROC NEAR PUBLIC\r
c8ec22a2 104 ; Inputs:\r
9da59186 105 ; esp -> LoadMicrocodeParams pointer\r
c8ec22a2
JY
106 ; Register Usage:\r
107 ; esp Preserved\r
108 ; All others destroyed\r
109 ; Assumptions:\r
110 ; No memory available, stack is hard-coded and used for return address\r
111 ; Executed by SBSP and NBSP\r
112 ; Beginning of microcode update region starts on paragraph boundary\r
113\r
114 ;\r
115 ;\r
116 ; Save return address to EBP\r
d5fb1edf 117 movd ebp, mm7\r
c8ec22a2
JY
118\r
119 cmp esp, 0\r
120 jz paramerror\r
9da59186 121 mov eax, dword ptr [esp + 4] ; Parameter pointer\r
c8ec22a2
JY
122 cmp eax, 0\r
123 jz paramerror\r
124 mov esp, eax\r
9da59186 125 mov esi, [esp].LoadMicrocodeParams.MicrocodeCodeAddr\r
c8ec22a2
JY
126 cmp esi, 0\r
127 jnz check_main_header\r
128\r
129paramerror:\r
130 mov eax, 080000002h\r
131 jmp exit\r
132\r
9da59186 133 mov esi, [esp].LoadMicrocodeParams.MicrocodeCodeAddr\r
c8ec22a2
JY
134\r
135check_main_header:\r
136 ; Get processor signature and platform ID from the installed processor\r
137 ; and save into registers for later use\r
138 ; ebx = processor signature\r
139 ; edx = platform ID\r
140 mov eax, 1\r
141 cpuid\r
142 mov ebx, eax\r
143 mov ecx, MSR_IA32_PLATFORM_ID\r
144 rdmsr\r
145 mov ecx, edx\r
146 shr ecx, 50-32\r
147 and ecx, 7h\r
148 mov edx, 1\r
149 shl edx, cl\r
150\r
151 ; Current register usage\r
152 ; esp -> stack with paramters\r
153 ; esi -> microcode update to check\r
154 ; ebx = processor signature\r
155 ; edx = platform ID\r
156\r
157 ; Check for valid microcode header\r
158 ; Minimal test checking for header version and loader version as 1\r
159 mov eax, dword ptr 1\r
9da59186 160 cmp [esi].MicrocodeHdr.MicrocodeHdrVersion, eax\r
c8ec22a2 161 jne advance_fixed_size\r
9da59186 162 cmp [esi].MicrocodeHdr.MicrocodeHdrLoader, eax\r
c8ec22a2
JY
163 jne advance_fixed_size\r
164\r
165 ; Check if signature and plaform ID match\r
9da59186 166 cmp ebx, [esi].MicrocodeHdr.MicrocodeHdrProcessor\r
c8ec22a2 167 jne @f\r
9da59186 168 test edx, [esi].MicrocodeHdr.MicrocodeHdrFlags\r
c8ec22a2
JY
169 jnz load_check ; Jif signature and platform ID match\r
170\r
171@@:\r
172 ; Check if extended header exists\r
9da59186 173 ; First check if MicrocodeHdrTotalSize and MicrocodeHdrDataSize are valid\r
c8ec22a2 174 xor eax, eax\r
9da59186 175 cmp [esi].MicrocodeHdr.MicrocodeHdrTotalSize, eax\r
c8ec22a2 176 je next_microcode\r
9da59186 177 cmp [esi].MicrocodeHdr.MicrocodeHdrDataSize, eax\r
c8ec22a2
JY
178 je next_microcode\r
179\r
180 ; Then verify total size - sizeof header > data size\r
9da59186
JY
181 mov ecx, [esi].MicrocodeHdr.MicrocodeHdrTotalSize\r
182 sub ecx, sizeof MicrocodeHdr\r
183 cmp ecx, [esi].MicrocodeHdr.MicrocodeHdrDataSize\r
c8ec22a2
JY
184 jng next_microcode ; Jif extended header does not exist\r
185\r
186 ; Set edi -> extended header\r
187 mov edi, esi\r
9da59186
JY
188 add edi, sizeof MicrocodeHdr\r
189 add edi, [esi].MicrocodeHdr.MicrocodeHdrDataSize\r
c8ec22a2
JY
190\r
191 ; Get count of extended structures\r
9da59186 192 mov ecx, [edi].ExtSigHdr.ExtSigHdrCount\r
c8ec22a2
JY
193\r
194 ; Move pointer to first signature structure\r
9da59186 195 add edi, sizeof ExtSigHdr\r
c8ec22a2
JY
196\r
197check_ext_sig:\r
198 ; Check if extended signature and platform ID match\r
9da59186 199 cmp [edi].ExtSig.ExtSigProcessor, ebx\r
c8ec22a2 200 jne @f\r
9da59186 201 test [edi].ExtSig.ExtSigFlags, edx\r
c8ec22a2
JY
202 jnz load_check ; Jif signature and platform ID match\r
203@@:\r
204 ; Check if any more extended signatures exist\r
9da59186 205 add edi, sizeof ExtSig\r
c8ec22a2
JY
206 loop check_ext_sig\r
207\r
208next_microcode:\r
209 ; Advance just after end of this microcode\r
210 xor eax, eax\r
9da59186 211 cmp [esi].MicrocodeHdr.MicrocodeHdrTotalSize, eax\r
c8ec22a2 212 je @f\r
9da59186 213 add esi, [esi].MicrocodeHdr.MicrocodeHdrTotalSize\r
c8ec22a2
JY
214 jmp check_address\r
215@@:\r
216 add esi, dword ptr 2048\r
217 jmp check_address\r
218\r
219advance_fixed_size:\r
220 ; Advance by 4X dwords\r
221 add esi, dword ptr 1024\r
222\r
223check_address:\r
224 ; Is valid Microcode start point ?\r
9da59186 225 cmp dword ptr [esi].MicrocodeHdr.MicrocodeHdrVersion, 0ffffffffh\r
c8ec22a2
JY
226 jz done\r
227\r
975f1c64 228 ; Is automatic size detection ?\r
9da59186 229 mov eax, [esp].LoadMicrocodeParams.MicrocodeCodeSize\r
975f1c64
JY
230 cmp eax, 0ffffffffh\r
231 jz @f\r
232\r
c8ec22a2 233 ; Address >= microcode region address + microcode region size?\r
9da59186 234 add eax, [esp].LoadMicrocodeParams.MicrocodeCodeAddr\r
c8ec22a2 235 cmp esi, eax\r
9da59186 236 jae done ;Jif address is outside of microcode region\r
c8ec22a2
JY
237 jmp check_main_header\r
238\r
975f1c64 239@@:\r
c8ec22a2
JY
240load_check:\r
241 ; Get the revision of the current microcode update loaded\r
242 mov ecx, MSR_IA32_BIOS_SIGN_ID\r
243 xor eax, eax ; Clear EAX\r
244 xor edx, edx ; Clear EDX\r
245 wrmsr ; Load 0 to MSR at 8Bh\r
246\r
247 mov eax, 1\r
248 cpuid\r
249 mov ecx, MSR_IA32_BIOS_SIGN_ID\r
250 rdmsr ; Get current microcode signature\r
251\r
252 ; Verify this microcode update is not already loaded\r
9da59186 253 cmp [esi].MicrocodeHdr.MicrocodeHdrRevision, edx\r
c8ec22a2
JY
254 je continue\r
255\r
256load_microcode:\r
257 ; EAX contains the linear address of the start of the Update Data\r
258 ; EDX contains zero\r
259 ; ECX contains 79h (IA32_BIOS_UPDT_TRIG)\r
260 ; Start microcode load with wrmsr\r
261 mov eax, esi\r
9da59186 262 add eax, sizeof MicrocodeHdr\r
c8ec22a2
JY
263 xor edx, edx\r
264 mov ecx, MSR_IA32_BIOS_UPDT_TRIG\r
265 wrmsr\r
266 mov eax, 1\r
267 cpuid\r
268\r
269continue:\r
270 jmp next_microcode\r
271\r
272done:\r
273 mov eax, 1\r
274 cpuid\r
275 mov ecx, MSR_IA32_BIOS_SIGN_ID\r
276 rdmsr ; Get current microcode signature\r
277 xor eax, eax\r
278 cmp edx, 0\r
279 jnz exit\r
280 mov eax, 08000000Eh\r
281\r
282exit:\r
283 jmp ebp\r
284\r
9da59186 285LoadMicrocodeDefault ENDP\r
c8ec22a2 286\r
d5fb1edf 287EstablishStackFsp PROC NEAR PRIVATE\r
d5fb1edf 288 ;\r
9da59186 289 ; Save parameter pointer in edx\r
d5fb1edf 290 ;\r
9da59186
JY
291 mov edx, dword ptr [esp + 4]\r
292\r
d5fb1edf
JY
293 ;\r
294 ; Enable FSP STACK\r
295 ;\r
296 mov esp, PcdGet32 (PcdTemporaryRamBase)\r
9da59186 297 add esp, PcdGet32 (PcdTemporaryRamSize)\r
d5fb1edf 298\r
9da59186 299 push DATA_LEN_OF_MCUD ; Size of the data region\r
d5fb1edf
JY
300 push 4455434Dh ; Signature of the data region 'MCUD'\r
301 push dword ptr [edx + 12] ; Code size\r
302 push dword ptr [edx + 8] ; Code base\r
d5fb1edf 303 push dword ptr [edx + 4] ; Microcode size\r
9da59186 304 push dword ptr [edx] ; Microcode base\r
d5fb1edf 305\r
d5fb1edf
JY
306 ;\r
307 ; Save API entry/exit timestamp into stack\r
308 ;\r
309 push DATA_LEN_OF_PER0 ; Size of the data region \r
310 push 30524550h ; Signature of the data region 'PER0'\r
95c95ac0
JY
311 LOAD_EDX\r
312 push edx\r
313 LOAD_EAX\r
d5fb1edf
JY
314 push eax\r
315 rdtsc\r
316 push edx\r
317 push eax\r
318\r
319 ;\r
320 ; Terminator for the data on stack\r
321 ; \r
322 push 0\r
323\r
324 ;\r
9da59186 325 ; Set ECX/EDX to the BootLoader temporary memory range\r
d5fb1edf
JY
326 ;\r
327 mov ecx, PcdGet32 (PcdTemporaryRamBase)\r
328 mov edx, ecx\r
329 add edx, PcdGet32 (PcdTemporaryRamSize)\r
330 sub edx, PcdGet32 (PcdFspTemporaryRamSize)\r
331\r
332 xor eax, eax\r
9da59186 333\r
d5fb1edf
JY
334 RET_ESI\r
335\r
336EstablishStackFsp ENDP\r
337\r
338\r
c8ec22a2
JY
339;----------------------------------------------------------------------------\r
340; TempRamInit API\r
341;\r
342; This FSP API will load the microcode update, enable code caching for the\r
343; region specified by the boot loader and also setup a temporary stack to be\r
344; used till main memory is initialized.\r
345;\r
346;----------------------------------------------------------------------------\r
347TempRamInitApi PROC NEAR PUBLIC\r
348 ;\r
349 ; Ensure SSE is enabled\r
350 ;\r
351 ENABLE_SSE\r
352\r
353 ;\r
354 ; Save EBP, EBX, ESI, EDI & ESP in XMM7 & XMM6\r
355 ;\r
356 SAVE_REGS\r
357\r
358 ;\r
1c54ceb7 359 ; Save timestamp into XMM6\r
c8ec22a2
JY
360 ;\r
361 rdtsc\r
95c95ac0
JY
362 SAVE_EAX\r
363 SAVE_EDX\r
364\r
365 ;\r
366 ; Check Parameter\r
367 ;\r
368 mov eax, dword ptr [esp + 4]\r
369 cmp eax, 0\r
370 mov eax, 80000002h\r
371 jz NemInitExit\r
372\r
c8ec22a2 373 ;\r
3b17b245 374 ; Sec Platform Init\r
c8ec22a2 375 ;\r
d5fb1edf 376 CALL_MMX SecPlatformInit\r
95c95ac0
JY
377 cmp eax, 0\r
378 jnz NemInitExit\r
d5fb1edf 379 \r
c8ec22a2 380 ; Load microcode\r
95c95ac0 381 LOAD_ESP\r
9da59186
JY
382 CALL_MMX LoadMicrocode\r
383 SXMMN xmm6, 3, eax ;Save microcode return status in ECX-SLOT 3 in xmm6.\r
384 ;@note If return value eax is not 0, microcode did not load, but continue and attempt to boot.\r
95c95ac0
JY
385\r
386 ; Call Sec CAR Init\r
387 LOAD_ESP\r
388 CALL_MMX SecCarInit\r
389 cmp eax, 0\r
390 jnz NemInitExit\r
c8ec22a2 391\r
95c95ac0 392 LOAD_ESP\r
d5fb1edf 393 CALL_MMX EstablishStackFsp\r
c8ec22a2 394\r
9da59186
JY
395 LXMMN xmm6, eax, 3 ;Restore microcode status if no CAR init error from ECX-SLOT 3 in xmm6.\r
396\r
c8ec22a2
JY
397NemInitExit:\r
398 ;\r
399 ; Load EBP, EBX, ESI, EDI & ESP from XMM7 & XMM6\r
400 ;\r
401 LOAD_REGS\r
402 ret\r
403TempRamInitApi ENDP\r
404\r
405;----------------------------------------------------------------------------\r
406; FspInit API\r
407;\r
408; This FSP API will perform the processor and chipset initialization.\r
409; This API will not return. Instead, it transfers the control to the\r
410; ContinuationFunc provided in the parameter.\r
411;\r
412;----------------------------------------------------------------------------\r
413FspInitApi PROC NEAR PUBLIC\r
d5fb1edf
JY
414 mov eax, 1\r
415 jmp FspApiCommon\r
416 FspInitApi ENDP\r
417\r
418;----------------------------------------------------------------------------\r
419; NotifyPhase API\r
420;\r
421; This FSP API will notify the FSP about the different phases in the boot\r
422; process\r
423;\r
424;----------------------------------------------------------------------------\r
425NotifyPhaseApi PROC C PUBLIC\r
426 mov eax, 2\r
427 jmp FspApiCommon\r
428NotifyPhaseApi ENDP\r
429\r
430;----------------------------------------------------------------------------\r
431; FspMemoryInit API\r
432;\r
433; This FSP API is called after TempRamInit and initializes the memory.\r
434;\r
435;----------------------------------------------------------------------------\r
436FspMemoryInitApi PROC NEAR PUBLIC\r
437 mov eax, 3\r
438 jmp FspApiCommon\r
439FspMemoryInitApi ENDP\r
440\r
441\r
442;----------------------------------------------------------------------------\r
443; TempRamExitApi API\r
444;\r
445; This API tears down temporary RAM\r
446;\r
447;----------------------------------------------------------------------------\r
448TempRamExitApi PROC C PUBLIC\r
449 mov eax, 4\r
450 jmp FspApiCommon\r
451TempRamExitApi ENDP\r
452\r
453\r
454;----------------------------------------------------------------------------\r
455; FspSiliconInit API\r
456;\r
457; This FSP API initializes the CPU and the chipset including the IO\r
458; controllers in the chipset to enable normal operation of these devices.\r
459;\r
460;----------------------------------------------------------------------------\r
461FspSiliconInitApi PROC C PUBLIC\r
462 mov eax, 5\r
463 jmp FspApiCommon\r
464FspSiliconInitApi ENDP\r
465\r
466;----------------------------------------------------------------------------\r
467; FspApiCommon API\r
468;\r
469; This is the FSP API common entry point to resume the FSP execution\r
470;\r
471;----------------------------------------------------------------------------\r
472FspApiCommon PROC C PUBLIC\r
c8ec22a2 473 ;\r
d5fb1edf 474 ; EAX holds the API index\r
c8ec22a2 475 ;\r
d5fb1edf
JY
476\r
477 ;\r
478 ; Stack must be ready\r
479 ; \r
480 push eax\r
481 add esp, 4\r
482 cmp eax, dword ptr [esp - 4]\r
c8ec22a2
JY
483 jz @F\r
484 mov eax, 080000003h\r
485 jmp exit\r
486\r
487@@:\r
488 ;\r
d5fb1edf 489 ; Verify the calling condition\r
c8ec22a2
JY
490 ;\r
491 pushad\r
9da59186 492 push [esp + 4 * 8 + 4]\r
d5fb1edf 493 push eax\r
c8ec22a2 494 call FspApiCallingCheck\r
9da59186 495 add esp, 8\r
c8ec22a2
JY
496 cmp eax, 0\r
497 jz @F\r
d5fb1edf
JY
498 mov dword ptr [esp + 4 * 7], eax\r
499 popad\r
500 ret\r
c8ec22a2
JY
501\r
502@@:\r
d5fb1edf
JY
503 popad\r
504 cmp eax, 1 ; FspInit API\r
505 jz @F\r
506 cmp eax, 3 ; FspMemoryInit API\r
507 jz @F\r
3b17b245 508\r
16b7e82c 509 call AsmGetFspInfoHeader\r
3b17b245 510 jmp Loader2PeiSwitchStack\r
d5fb1edf 511\r
9da59186 512@@:\r
d5fb1edf
JY
513 ;\r
514 ; FspInit and FspMemoryInit APIs, setup the initial stack frame\r
9da59186 515 ;\r
d5fb1edf 516 \r
c8ec22a2 517 ;\r
3b17b245 518 ; Place holder to store the FspInfoHeader pointer\r
c8ec22a2 519 ;\r
3b17b245
MM
520 push eax\r
521\r
522 ;\r
523 ; Update the FspInfoHeader pointer\r
524 ;\r
525 push eax\r
16b7e82c 526 call AsmGetFspInfoHeader\r
3b17b245
MM
527 mov [esp + 4], eax\r
528 pop eax\r
c8ec22a2
JY
529\r
530 ;\r
531 ; Create a Task Frame in the stack for the Boot Loader\r
532 ;\r
533 pushfd ; 2 pushf for 4 byte alignment\r
534 cli\r
535 pushad\r
536\r
537 ; Reserve 8 bytes for IDT save/restore\r
538 sub esp, 8\r
9da59186 539 sidt fword ptr [esp]\r
c8ec22a2
JY
540\r
541 ;\r
542 ; Setup new FSP stack\r
543 ;\r
d5fb1edf 544 mov edi, esp\r
c8ec22a2
JY
545 mov esp, PcdGet32(PcdTemporaryRamBase)\r
546 add esp, PcdGet32(PcdTemporaryRamSize)\r
547 sub esp, (DATA_LEN_AT_STACK_TOP + 40h)\r
548\r
549 ;\r
d5fb1edf 550 ; Pass the API Idx to SecStartup\r
c8ec22a2
JY
551 ;\r
552 push eax\r
d5fb1edf
JY
553 \r
554 ;\r
9da59186 555 ; Pass the BootLoader stack to SecStartup\r
d5fb1edf
JY
556 ;\r
557 push edi\r
c8ec22a2
JY
558\r
559 ;\r
560 ; Pass entry point of the PEI core\r
561 ;\r
16b7e82c 562 call AsmGetFspBaseAddress\r
d5fb1edf
JY
563 mov edi, eax\r
564 add edi, PcdGet32 (PcdFspAreaSize) \r
c8ec22a2 565 sub edi, 20h\r
d5fb1edf 566 add eax, DWORD PTR ds:[edi]\r
c8ec22a2
JY
567 push eax\r
568\r
569 ;\r
570 ; Pass BFV into the PEI Core\r
571 ; It uses relative address to calucate the actual boot FV base\r
572 ; For FSP impleantion with single FV, PcdFlashFvRecoveryBase and\r
573 ; PcdFspAreaBaseAddress are the same. For FSP with mulitple FVs,\r
574 ; they are different. The code below can handle both cases.\r
575 ;\r
16b7e82c 576 call AsmGetFspBaseAddress\r
c8ec22a2
JY
577 mov edi, eax\r
578 call GetBootFirmwareVolumeOffset\r
579 add eax, edi\r
580 push eax\r
581\r
582 ;\r
583 ; Pass stack base and size into the PEI Core\r
584 ;\r
585 mov eax, PcdGet32(PcdTemporaryRamBase)\r
586 add eax, PcdGet32(PcdTemporaryRamSize)\r
587 sub eax, PcdGet32(PcdFspTemporaryRamSize)\r
588 push eax\r
589 push PcdGet32(PcdFspTemporaryRamSize)\r
590\r
591 ;\r
592 ; Pass Control into the PEI Core\r
593 ;\r
594 call SecStartup\r
3b17b245 595 add esp, 4\r
9da59186 596exit:\r
c8ec22a2
JY
597 ret\r
598\r
d5fb1edf 599FspApiCommon ENDP\r
c8ec22a2
JY
600\r
601END\r