]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryM.nasm
IntelFsp2Pkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / IntelFsp2Pkg / FspSecCore / Ia32 / FspApiEntryM.nasm
CommitLineData
cf1d4549
JY
1;; @file\r
2; Provide FSP API entry points.\r
3;\r
12a0a80b 4; Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.<BR>\r
9672cd30 5; SPDX-License-Identifier: BSD-2-Clause-Patent\r
cf1d4549
JY
6;;\r
7\r
8 SECTION .text\r
9\r
10;\r
11; Following are fixed PCDs\r
12;\r
13extern ASM_PFX(PcdGet32(PcdTemporaryRamBase))\r
14extern ASM_PFX(PcdGet32(PcdTemporaryRamSize))\r
15extern ASM_PFX(PcdGet32(PcdFspTemporaryRamSize))\r
12a0a80b 16extern ASM_PFX(PcdGet8 (PcdFspHeapSizePercentage))\r
cf1d4549
JY
17\r
18struc FSPM_UPD_COMMON\r
19 ; FSP_UPD_HEADER {\r
20 .FspUpdHeader: resd 8\r
21 ; }\r
22 ; FSPM_ARCH_UPD {\r
23 .Revision: resb 1\r
24 .Reserved: resb 3\r
25 .NvsBufferPtr: resd 1\r
26 .StackBase: resd 1\r
27 .StackSize: resd 1\r
28 .BootLoaderTolumSize: resd 1\r
29 .BootMode: resd 1\r
30 .Reserved1: resb 8\r
31 ; }\r
32 .size:\r
33endstruc\r
34\r
35;\r
36; Following functions will be provided in C\r
37;\r
38extern ASM_PFX(SecStartup)\r
39extern ASM_PFX(FspApiCommon)\r
40\r
41;\r
42; Following functions will be provided in PlatformSecLib\r
43;\r
44extern ASM_PFX(AsmGetFspBaseAddress)\r
45extern ASM_PFX(AsmGetFspInfoHeader)\r
46\r
47API_PARAM1_OFFSET EQU 34h ; ApiParam1 [ sub esp,8 + pushad + pushfd + push eax + call]\r
48FSP_HEADER_IMGBASE_OFFSET EQU 1Ch\r
49FSP_HEADER_CFGREG_OFFSET EQU 24h\r
50\r
51;----------------------------------------------------------------------------\r
52; FspMemoryInit API\r
53;\r
54; This FSP API is called after TempRamInit and initializes the memory.\r
55;\r
56;----------------------------------------------------------------------------\r
57global ASM_PFX(FspMemoryInitApi)\r
58ASM_PFX(FspMemoryInitApi):\r
59 mov eax, 3 ; FSP_API_INDEX.FspMemoryInitApiIndex\r
60 jmp ASM_PFX(FspApiCommon)\r
61\r
62;----------------------------------------------------------------------------\r
63; TempRamExitApi API\r
64;\r
65; This API tears down temporary RAM\r
66;\r
67;----------------------------------------------------------------------------\r
68global ASM_PFX(TempRamExitApi)\r
69ASM_PFX(TempRamExitApi):\r
70 mov eax, 4 ; FSP_API_INDEX.TempRamExitApiIndex\r
71 jmp ASM_PFX(FspApiCommon)\r
72\r
73;----------------------------------------------------------------------------\r
74; FspApiCommonContinue API\r
75;\r
76; This is the FSP API common entry point to resume the FSP execution\r
77;\r
78;----------------------------------------------------------------------------\r
79global ASM_PFX(FspApiCommonContinue)\r
80ASM_PFX(FspApiCommonContinue):\r
81 ;\r
82 ; EAX holds the API index\r
83 ;\r
84\r
85 ;\r
86 ; FspMemoryInit API setup the initial stack frame\r
87 ;\r
88\r
89 ;\r
90 ; Place holder to store the FspInfoHeader pointer\r
91 ;\r
92 push eax\r
93\r
94 ;\r
95 ; Update the FspInfoHeader pointer\r
96 ;\r
97 push eax\r
98 call ASM_PFX(AsmGetFspInfoHeader)\r
99 mov [esp + 4], eax\r
100 pop eax\r
101\r
102 ;\r
103 ; Create a Task Frame in the stack for the Boot Loader\r
104 ;\r
105 pushfd ; 2 pushf for 4 byte alignment\r
106 cli\r
107 pushad\r
108\r
109 ; Reserve 8 bytes for IDT save/restore\r
110 sub esp, 8\r
111 sidt [esp]\r
112\r
113\r
e37bb20c
LG
114 ; Get Stackbase and StackSize from FSPM_UPD Param\r
115 mov edx, [esp + API_PARAM1_OFFSET]\r
cf1d4549 116 cmp edx, 0\r
e37bb20c 117 jnz FspStackSetup\r
cf1d4549
JY
118\r
119 ; Get UPD default values if FspmUpdDataPtr (ApiParam1) is null\r
120 push eax\r
121 call ASM_PFX(AsmGetFspInfoHeader)\r
122 mov edx, [eax + FSP_HEADER_IMGBASE_OFFSET]\r
123 add edx, [eax + FSP_HEADER_CFGREG_OFFSET]\r
124 pop eax\r
e37bb20c 125\r
12a0a80b
CC
126FspStackSetup:\r
127 ;\r
128 ; StackBase = temp memory base, StackSize = temp memory size\r
129 ;\r
cf1d4549
JY
130 mov edi, [edx + FSPM_UPD_COMMON.StackBase]\r
131 mov ecx, [edx + FSPM_UPD_COMMON.StackSize]\r
12a0a80b
CC
132\r
133 ;\r
134 ; Keep using bootloader stack if heap size % is 0\r
135 ;\r
136 mov bl, BYTE [ASM_PFX(PcdGet8 (PcdFspHeapSizePercentage))]\r
137 cmp bl, 0\r
138 jz SkipStackSwitch\r
139\r
140 ;\r
141 ; Set up a dedicated temp ram stack for FSP if FSP heap size % doesn't equal 0\r
142 ;\r
cf1d4549
JY
143 add edi, ecx\r
144 ;\r
12a0a80b 145 ; Switch to new FSP stack\r
cf1d4549 146 ;\r
12a0a80b
CC
147 xchg edi, esp ; Exchange edi and esp, edi will be assigned to the current esp pointer and esp will be Stack base + Stack size\r
148\r
149SkipStackSwitch:\r
150 ;\r
151 ; If heap size % is 0:\r
152 ; EDI is FSPM_UPD_COMMON.StackBase and will hold ESP later (boot loader stack pointer)\r
153 ; ECX is FSPM_UPD_COMMON.StackSize\r
154 ; ESP is boot loader stack pointer (no stack switch)\r
155 ; BL is 0 to indicate no stack switch (EBX will hold FSPM_UPD_COMMON.StackBase later)\r
156 ;\r
157 ; If heap size % is not 0\r
158 ; EDI is boot loader stack pointer\r
159 ; ECX is FSPM_UPD_COMMON.StackSize\r
160 ; ESP is new stack (FSPM_UPD_COMMON.StackBase + FSPM_UPD_COMMON.StackSize)\r
161 ; BL is NOT 0 to indicate stack has switched\r
162 ;\r
163 cmp bl, 0\r
164 jnz StackHasBeenSwitched\r
165\r
166 mov ebx, edi ; Put FSPM_UPD_COMMON.StackBase to ebx as temp memory base\r
167 mov edi, esp ; Put boot loader stack pointer to edi\r
168 jmp StackSetupDone\r
169\r
170StackHasBeenSwitched:\r
171 mov ebx, esp ; Put Stack base + Stack size in ebx\r
172 sub ebx, ecx ; Stack base + Stack size - Stack size as temp memory base\r
173\r
174StackSetupDone:\r
cf1d4549
JY
175\r
176 ;\r
177 ; Pass the API Idx to SecStartup\r
178 ;\r
179 push eax\r
180\r
181 ;\r
182 ; Pass the BootLoader stack to SecStartup\r
183 ;\r
184 push edi\r
185\r
186 ;\r
187 ; Pass entry point of the PEI core\r
188 ;\r
189 call ASM_PFX(AsmGetFspBaseAddress)\r
190 mov edi, eax\r
191 call ASM_PFX(AsmGetPeiCoreOffset)\r
192 add edi, eax\r
193 push edi\r
194\r
195 ;\r
196 ; Pass BFV into the PEI Core\r
197 ; It uses relative address to calucate the actual boot FV base\r
198 ; For FSP implementation with single FV, PcdFspBootFirmwareVolumeBase and\r
199 ; PcdFspAreaBaseAddress are the same. For FSP with mulitple FVs,\r
200 ; they are different. The code below can handle both cases.\r
201 ;\r
202 call ASM_PFX(AsmGetFspBaseAddress)\r
203 push eax\r
204\r
205 ;\r
206 ; Pass stack base and size into the PEI Core\r
207 ;\r
cf1d4549
JY
208 push ebx\r
209 push ecx\r
210\r
211 ;\r
212 ; Pass Control into the PEI Core\r
213 ;\r
214 call ASM_PFX(SecStartup)\r
215 add esp, 4\r
216exit:\r
217 ret\r
218\r
219global ASM_PFX(FspPeiCoreEntryOff)\r
220ASM_PFX(FspPeiCoreEntryOff):\r
221 ;\r
222 ; This value will be pached by the build script\r
223 ;\r
224 DD 0x12345678\r
225\r
226global ASM_PFX(AsmGetPeiCoreOffset)\r
227ASM_PFX(AsmGetPeiCoreOffset):\r
228 mov eax, dword [ASM_PFX(FspPeiCoreEntryOff)]\r
229 ret\r
230\r
c69071bd
SB
231;----------------------------------------------------------------------------\r
232; TempRamInit API\r
233;\r
234; Empty function for WHOLEARCHIVE build option\r
235;\r
236;----------------------------------------------------------------------------\r
237global ASM_PFX(TempRamInitApi)\r
238ASM_PFX(TempRamInitApi):\r
239 jmp $\r
240 ret\r
241\r
cf1d4549
JY
242;----------------------------------------------------------------------------\r
243; Module Entrypoint API\r
244;----------------------------------------------------------------------------\r
245global ASM_PFX(_ModuleEntryPoint)\r
246ASM_PFX(_ModuleEntryPoint):\r
247 jmp $\r