blob: 2c0c3ad9bb2a7027d8aa7564727097150cd70f7c [file] [log] [blame]
Vishal Bhoj82c80712015-12-15 21:13:33 +05301/** @file
2
3 Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR>
4 This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php.
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12**/
13
14#include <PiPei.h>
15#include <Library/BaseLib.h>
16#include <Library/DebugLib.h>
17#include <Library/PcdLib.h>
18#include <FspGlobalData.h>
19#include <FspApi.h>
20
21#pragma pack(1)
22
23//
24// Cont Func Parameter 2 +0x3C
25// Cont Func Parameter 1 +0x38
26//
27// API Parameter +0x34
28// API return address +0x30
29//
30// push offset exit +0x2C
31// pushfd +0x28
32// cli
33// pushad +0x24
34// sub esp, 8 +0x00
35// sidt fword ptr [esp]
36//
37typedef struct {
38 UINT16 IdtrLimit;
39 UINT32 IdtrBase;
40 UINT16 Reserved;
41 UINT32 Edi;
42 UINT32 Esi;
43 UINT32 Ebp;
44 UINT32 Esp;
45 UINT32 Ebx;
46 UINT32 Edx;
47 UINT32 Ecx;
48 UINT32 Eax;
49 UINT16 Flags[2];
50 UINT32 ExitOff;
51 UINT32 ApiRet;
52 UINT32 ApiParam;
53} CONTEXT_STACK;
54
55#define CONTEXT_STACK_OFFSET(x) (UINT32)&((CONTEXT_STACK *)(UINTN)0)->x
56
57#pragma pack()
58
59/**
60 This function sets the FSP global data pointer.
61
62 @param[in] FspData Fsp global data pointer.
63
64**/
65VOID
66EFIAPI
67SetFspGlobalDataPointer (
68 IN FSP_GLOBAL_DATA *FspData
69 )
70{
71 ASSERT (FspData != NULL);
72 *((volatile UINT32 *)(UINTN)PcdGet32(PcdGlobalDataPointerAddress)) = (UINT32)(UINTN)FspData;
73}
74
75/**
76 This function gets the FSP global data pointer.
77
78**/
79FSP_GLOBAL_DATA *
80EFIAPI
81GetFspGlobalDataPointer (
82 VOID
83 )
84{
85 FSP_GLOBAL_DATA *FspData;
86
87 FspData = *(FSP_GLOBAL_DATA **)(UINTN)PcdGet32(PcdGlobalDataPointerAddress);
88 return FspData;
89}
90
91/**
92 This function gets back the FSP API paramter passed by the bootlaoder.
93
94 @retval ApiParameter FSP API paramter passed by the bootlaoder.
95**/
96UINT32
97EFIAPI
98GetFspApiParameter (
99 VOID
100 )
101{
102 FSP_GLOBAL_DATA *FspData;
103
104 FspData = GetFspGlobalDataPointer ();
105 return *(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(ApiParam));
106}
107
108/**
109 This function sets the FSP API paramter in the stack.
110
111 @param[in] Value New parameter value.
112
113**/
114VOID
115EFIAPI
116SetFspApiParameter (
117 IN UINT32 Value
118 )
119{
120 FSP_GLOBAL_DATA *FspData;
121
122 FspData = GetFspGlobalDataPointer ();
123 *(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(ApiParam)) = Value;
124}
125
126/**
127 This function sets the FSP continuation function parameters in the stack.
128
129 @param[in] Value New parameter value to set.
130 @param[in] Index Parameter index.
131**/
132VOID
133EFIAPI
134SetFspContinuationFuncParameter (
135 IN UINT32 Value,
136 IN UINT32 Index
137 )
138{
139 FSP_GLOBAL_DATA *FspData;
140
141 FspData = GetFspGlobalDataPointer ();
142 *(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(ApiParam) + (Index + 1) * sizeof(UINT32)) = Value;
143}
144
145
146/**
147 This function changes the Bootloader return address in stack.
148
149 @param[in] ReturnAddress Address to return.
150
151**/
152VOID
153EFIAPI
154SetFspApiReturnAddress (
155 IN UINT32 ReturnAddress
156 )
157{
158 FSP_GLOBAL_DATA *FspData;
159
160 FspData = GetFspGlobalDataPointer ();
161 *(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(ApiRet)) = ReturnAddress;
162}
163
164/**
165 This function set the API status code returned to the bootloader.
166
167 @param[in] ReturnStatus Status code to return.
168
169**/
170VOID
171EFIAPI
172SetFspApiReturnStatus (
173 IN UINT32 ReturnStatus
174 )
175{
176 FSP_GLOBAL_DATA *FspData;
177
178 FspData = GetFspGlobalDataPointer ();
179 *(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(Eax)) = ReturnStatus;
180}
181
182/**
183 This function sets the context switching stack to a new stack frame.
184
185 @param[in] NewStackTop New core stack to be set.
186
187**/
188VOID
189EFIAPI
190SetFspCoreStackPointer (
191 IN VOID *NewStackTop
192 )
193{
194 FSP_GLOBAL_DATA *FspData;
195 UINT32 *OldStack;
196 UINT32 *NewStack;
197 UINT32 StackContextLen;
198
199 FspData = GetFspGlobalDataPointer ();
200 StackContextLen = sizeof(CONTEXT_STACK) / sizeof(UINT32);
201
202 //
203 // Reserve space for the ContinuationFunc two parameters
204 //
205 OldStack = (UINT32 *)FspData->CoreStack;
206 NewStack = (UINT32 *)NewStackTop - StackContextLen - 2;
207 FspData->CoreStack = (UINT32)NewStack;
208 while (StackContextLen-- != 0) {
209 *NewStack++ = *OldStack++;
210 }
211}
212
213/**
214 This function sets the platform specific data pointer.
215
216 @param[in] PlatformData Fsp platform specific data pointer.
217
218**/
219VOID
220EFIAPI
221SetFspPlatformDataPointer (
222 IN VOID *PlatformData
223 )
224{
225 FSP_GLOBAL_DATA *FspData;
226
227 FspData = GetFspGlobalDataPointer ();
228 FspData->PlatformData.DataPtr = PlatformData;
229}
230
231
232/**
233 This function gets the platform specific data pointer.
234
235 @param[in] PlatformData Fsp platform specific data pointer.
236
237**/
238VOID *
239EFIAPI
240GetFspPlatformDataPointer (
241 VOID
242 )
243{
244 FSP_GLOBAL_DATA *FspData;
245
246 FspData = GetFspGlobalDataPointer ();
247 return FspData->PlatformData.DataPtr;
248}
249
250
251/**
252 This function sets the UPD data pointer.
253
254 @param[in] UpdDataRgnPtr UPD data pointer.
255**/
256VOID
257EFIAPI
258SetFspUpdDataPointer (
259 IN VOID *UpdDataRgnPtr
260 )
261{
262 FSP_GLOBAL_DATA *FspData;
263
264 //
265 // Get the Fsp Global Data Pointer
266 //
267 FspData = GetFspGlobalDataPointer ();
268
269 //
270 // Set the UPD pointer.
271 //
272 FspData->UpdDataRgnPtr = UpdDataRgnPtr;
273}
274
275/**
276 This function gets the UPD data pointer.
277
278 @return UpdDataRgnPtr UPD data pointer.
279**/
280VOID *
281EFIAPI
282GetFspUpdDataPointer (
283 VOID
284 )
285{
286 FSP_GLOBAL_DATA *FspData;
287
288 FspData = GetFspGlobalDataPointer ();
289 return FspData->UpdDataRgnPtr;
290}
291
292/**
293 Set FSP measurement point timestamp.
294
295 @param[in] Id Measurement point ID.
296
297 @return performance timestamp.
298**/
299UINT64
300EFIAPI
301SetFspMeasurePoint (
302 IN UINT8 Id
303 )
304{
305 FSP_GLOBAL_DATA *FspData;
306
307 //
308 // Bit [55: 0] will be the timestamp
309 // Bit [63:56] will be the ID
310 //
311 FspData = GetFspGlobalDataPointer ();
312 if (FspData->PerfIdx < sizeof(FspData->PerfData) / sizeof(FspData->PerfData[0])) {
313 FspData->PerfData[FspData->PerfIdx] = AsmReadTsc ();
314 ((UINT8 *)(&FspData->PerfData[FspData->PerfIdx]))[7] = Id;
315 }
316
317 return FspData->PerfData[(FspData->PerfIdx)++];
318}
319
320/**
321 This function gets the FSP info header pointer.
322
323 @retval FspInfoHeader FSP info header pointer
324**/
325FSP_INFO_HEADER *
326EFIAPI
327GetFspInfoHeader (
328 VOID
329 )
330{
331 return GetFspGlobalDataPointer()->FspInfoHeader;
332}
333
334/**
335 This function gets FSP API calling mode.
336
337 @retval API calling mode
338**/
339UINT8
340EFIAPI
341GetFspApiCallingMode (
342 VOID
343 )
344{
345 return GetFspGlobalDataPointer()->ApiMode;
346}
347
348/**
349 This function sets FSP API calling mode.
350
351 @param[in] Mode API calling mode
352**/
353VOID
354EFIAPI
355SetFspApiCallingMode (
356 UINT8 Mode
357 )
358{
359 FSP_GLOBAL_DATA *FspData;
360
361 FspData = GetFspGlobalDataPointer ();
362 FspData->ApiMode = Mode;
363}
364