FspCommonLib.c revision d5fb1edfb16a2af29486ffbf5aa32a036da9caa4
1/** @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
365