Add IntelFspPkg to support create FSP bin based on EDKII.
[mirror_edk2.git] / IntelFspPkg / Library / BaseFspCommonLib / FspCommonLib.c
CommitLineData
c8ec22a2
JY
1/** @file\r
2\r
3 Copyright (c) 2014, 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**/\r
13\r
14#include <PiPei.h>\r
15#include <Library/BaseLib.h>\r
16#include <Library/DebugLib.h>\r
17#include <Library/PcdLib.h>\r
18#include <FspGlobalData.h>\r
19#include <FspApi.h>\r
20\r
21#pragma pack(1)\r
22\r
23//\r
24// Cont Func Parameter 2 +0x3C\r
25// Cont Func Parameter 1 +0x38\r
26//\r
27// API Parameter +0x34\r
28// API return address +0x30\r
29//\r
30// push offset exit +0x2C\r
31// pushfd +0x28\r
32// cli\r
33// pushad +0x24\r
34// sub esp, 8 +0x00\r
35// sidt fword ptr [esp]\r
36//\r
37typedef struct {\r
38 UINT16 IdtrLimit;\r
39 UINT32 IdtrBase;\r
40 UINT16 Reserved;\r
41 UINT32 Edi;\r
42 UINT32 Esi;\r
43 UINT32 Ebp;\r
44 UINT32 Esp;\r
45 UINT32 Ebx;\r
46 UINT32 Edx;\r
47 UINT32 Ecx;\r
48 UINT32 Eax;\r
49 UINT16 Flags[2];\r
50 UINT32 ExitOff;\r
51 UINT32 ApiRet;\r
52 UINT32 ApiParam;\r
53} CONTEXT_STACK;\r
54\r
55#define CONTEXT_STACK_OFFSET(x) (UINT32)&((CONTEXT_STACK *)(UINTN)0)->x\r
56\r
57#pragma pack()\r
58\r
59/**\r
60 This function sets the FSP global data pointer.\r
61\r
62 @param[in] FspData Fsp global data pointer.\r
63\r
64**/\r
65VOID\r
66EFIAPI\r
67SetFspGlobalDataPointer (\r
68 IN FSP_GLOBAL_DATA *FspData\r
69 )\r
70{\r
71 ASSERT (FspData != NULL);\r
72 *((volatile UINT32 *)(UINTN)PcdGet32(PcdGlobalDataPointerAddress)) = (UINT32)(UINTN)FspData;\r
73}\r
74\r
75/**\r
76 This function gets the FSP global data pointer.\r
77\r
78**/\r
79FSP_GLOBAL_DATA *\r
80EFIAPI\r
81GetFspGlobalDataPointer (\r
82 VOID\r
83 )\r
84{\r
85 FSP_GLOBAL_DATA *FspData;\r
86\r
87 FspData = *(FSP_GLOBAL_DATA **)(UINTN)PcdGet32(PcdGlobalDataPointerAddress);\r
88 return FspData;\r
89}\r
90\r
91/**\r
92 This function gets back the FSP API paramter passed by the bootlaoder.\r
93\r
94 @retval ApiParameter FSP API paramter passed by the bootlaoder.\r
95**/\r
96UINT32\r
97EFIAPI\r
98GetFspApiParameter (\r
99 VOID\r
100 )\r
101{\r
102 FSP_GLOBAL_DATA *FspData;\r
103\r
104 FspData = GetFspGlobalDataPointer ();\r
105 return *(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(ApiParam));\r
106}\r
107\r
108/**\r
109 This function sets the FSP API paramter in the stack.\r
110\r
111 @param[in] Value New parameter value.\r
112\r
113**/\r
114VOID\r
115EFIAPI\r
116SetFspApiParameter (\r
117 IN UINT32 Value\r
118 )\r
119{\r
120 FSP_GLOBAL_DATA *FspData;\r
121\r
122 FspData = GetFspGlobalDataPointer ();\r
123 *(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(ApiParam)) = Value;\r
124}\r
125\r
126/**\r
127 This function sets the FSP continuation function parameters in the stack.\r
128\r
129 @param[in] Value New parameter value to set.\r
130 @param[in] Index Parameter index.\r
131**/\r
132VOID\r
133EFIAPI\r
134SetFspContinuationFuncParameter (\r
135 IN UINT32 Value,\r
136 IN UINT32 Index\r
137 )\r
138{\r
139 FSP_GLOBAL_DATA *FspData;\r
140\r
141 FspData = GetFspGlobalDataPointer ();\r
142 *(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(ApiParam) + (Index + 1) * sizeof(UINT32)) = Value;\r
143}\r
144\r
145\r
146/**\r
147 This function changes the Bootloader return address in stack.\r
148\r
149 @param[in] ReturnAddress Address to return.\r
150\r
151**/\r
152VOID\r
153EFIAPI\r
154SetFspApiReturnAddress (\r
155 IN UINT32 ReturnAddress\r
156 )\r
157{\r
158 FSP_GLOBAL_DATA *FspData;\r
159\r
160 FspData = GetFspGlobalDataPointer ();\r
161 *(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(ApiRet)) = ReturnAddress;\r
162}\r
163\r
164/**\r
165 This function set the API status code returned to the bootloader.\r
166\r
167 @param[in] ReturnStatus Status code to return.\r
168\r
169**/\r
170VOID\r
171EFIAPI\r
172SetFspApiReturnStatus (\r
173 IN UINT32 ReturnStatus\r
174 )\r
175{\r
176 FSP_GLOBAL_DATA *FspData;\r
177\r
178 FspData = GetFspGlobalDataPointer ();\r
179 *(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(Eax)) = ReturnStatus;\r
180}\r
181\r
182/**\r
183 This function sets the context switching stack to a new stack frame.\r
184\r
185 @param[in] NewStackTop New core stack to be set.\r
186\r
187**/\r
188VOID\r
189EFIAPI\r
190SetFspCoreStackPointer (\r
191 IN VOID *NewStackTop\r
192 )\r
193{\r
194 FSP_GLOBAL_DATA *FspData;\r
195 UINT32 *OldStack;\r
196 UINT32 *NewStack;\r
197 UINT32 StackContextLen;\r
198\r
199 FspData = GetFspGlobalDataPointer ();\r
200 StackContextLen = sizeof(CONTEXT_STACK) / sizeof(UINT32);\r
201\r
202 //\r
203 // Reserve space for the ContinuationFunc two parameters\r
204 //\r
205 OldStack = (UINT32 *)FspData->CoreStack;\r
206 NewStack = (UINT32 *)NewStackTop - StackContextLen - 2;\r
207 FspData->CoreStack = (UINT32)NewStack;\r
208 while (StackContextLen-- != 0) {\r
209 *NewStack++ = *OldStack++;\r
210 }\r
211}\r
212\r
213/**\r
214 This function sets the platform specific data pointer.\r
215\r
216 @param[in] PlatformData Fsp platform specific data pointer.\r
217\r
218**/\r
219VOID\r
220EFIAPI\r
221SetFspPlatformDataPointer (\r
222 IN VOID *PlatformData\r
223 )\r
224{\r
225 FSP_GLOBAL_DATA *FspData;\r
226\r
227 FspData = GetFspGlobalDataPointer ();\r
228 FspData->PlatformData.DataPtr = PlatformData;\r
229}\r
230\r
231\r
232/**\r
233 This function gets the platform specific data pointer.\r
234\r
235 @param[in] PlatformData Fsp platform specific data pointer.\r
236\r
237**/\r
238VOID *\r
239EFIAPI\r
240GetFspPlatformDataPointer (\r
241 VOID\r
242 )\r
243{\r
244 FSP_GLOBAL_DATA *FspData;\r
245\r
246 FspData = GetFspGlobalDataPointer ();\r
247 return FspData->PlatformData.DataPtr;\r
248}\r
249\r
250\r
251/**\r
252 This function sets the UPD data pointer.\r
253\r
254 @param[in] UpdDataRgnPtr UPD data pointer.\r
255**/\r
256VOID\r
257EFIAPI\r
258SetFspUpdDataPointer (\r
259 IN VOID *UpdDataRgnPtr\r
260 )\r
261{\r
262 FSP_GLOBAL_DATA *FspData;\r
263\r
264 //\r
265 // Get the Fsp Global Data Pointer\r
266 //\r
267 FspData = GetFspGlobalDataPointer ();\r
268\r
269 //\r
270 // Set the UPD pointer.\r
271 //\r
272 FspData->UpdDataRgnPtr = UpdDataRgnPtr;\r
273}\r
274\r
275/**\r
276 This function gets the UPD data pointer.\r
277\r
278 @return UpdDataRgnPtr UPD data pointer.\r
279**/\r
280VOID *\r
281EFIAPI\r
282GetFspUpdDataPointer (\r
283 VOID\r
284 )\r
285{\r
286 FSP_GLOBAL_DATA *FspData;\r
287\r
288 FspData = GetFspGlobalDataPointer ();\r
289 return FspData->UpdDataRgnPtr;\r
290}\r
291\r
292/**\r
293 Set FSP measurement point timestamp.\r
294\r
295 @param[in] Id Measurement point ID.\r
296\r
297 @return performance timestamp.\r
298**/\r
299UINT64\r
300EFIAPI\r
301SetFspMeasurePoint (\r
302 IN UINT8 Id\r
303 )\r
304{\r
305 FSP_GLOBAL_DATA *FspData;\r
306\r
307 //\r
308 // Bit [55: 0] will be the timestamp\r
309 // Bit [63:56] will be the ID\r
310 //\r
311 FspData = GetFspGlobalDataPointer ();\r
312 if (FspData->PerfIdx < sizeof(FspData->PerfData) / sizeof(FspData->PerfData[0])) {\r
313 FspData->PerfData[FspData->PerfIdx] = AsmReadTsc ();\r
314 ((UINT8 *)(&FspData->PerfData[FspData->PerfIdx]))[7] = Id;\r
315 }\r
316\r
317 return FspData->PerfData[(FspData->PerfIdx)++];\r
318}\r