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