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    FspInfoHeader        +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    FspInfoHeader;
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/**
294  This function sets the memory init UPD data pointer.
295
296  @param[in] MemoryInitUpdPtr   memory init UPD data pointer.
297**/
298VOID
299EFIAPI
300SetFspMemoryInitUpdDataPointer (
301  IN VOID    *MemoryInitUpdPtr
302  )
303{
304  FSP_GLOBAL_DATA  *FspData;
305
306  //
307  // Get the Fsp Global Data Pointer
308  //
309  FspData  = GetFspGlobalDataPointer ();
310
311  //
312  // Set the memory init UPD pointer.
313  //
314  FspData->MemoryInitUpdPtr = MemoryInitUpdPtr;
315}
316
317/**
318  This function gets the memory init UPD data pointer.
319
320  @return memory init UPD data pointer.
321**/
322VOID *
323EFIAPI
324GetFspMemoryInitUpdDataPointer (
325  VOID
326  )
327{
328  FSP_GLOBAL_DATA  *FspData;
329
330  FspData  = GetFspGlobalDataPointer ();
331  return FspData->MemoryInitUpdPtr;
332}
333
334
335/**
336  This function sets the silicon init UPD data pointer.
337
338  @param[in] SiliconInitUpdPtr   silicon init UPD data pointer.
339**/
340VOID
341EFIAPI
342SetFspSiliconInitUpdDataPointer (
343  IN VOID    *SiliconInitUpdPtr
344  )
345{
346  FSP_GLOBAL_DATA  *FspData;
347
348  //
349  // Get the Fsp Global Data Pointer
350  //
351  FspData  = GetFspGlobalDataPointer ();
352
353  //
354  // Set the silicon init UPD data pointer.
355  //
356  FspData->SiliconInitUpdPtr = SiliconInitUpdPtr;
357}
358
359/**
360  This function gets the silicon init UPD data pointer.
361
362  @return silicon init UPD data pointer.
363**/
364VOID *
365EFIAPI
366GetFspSiliconInitUpdDataPointer (
367  VOID
368  )
369{
370  FSP_GLOBAL_DATA  *FspData;
371
372  FspData  = GetFspGlobalDataPointer ();
373  return FspData->SiliconInitUpdPtr;
374}
375
376
377/**
378  Set FSP measurement point timestamp.
379
380  @param[in] Id       Measurement point ID.
381
382  @return performance timestamp.
383**/
384UINT64
385EFIAPI
386SetFspMeasurePoint (
387  IN UINT8  Id
388  )
389{
390  FSP_GLOBAL_DATA  *FspData;
391
392  //
393  // Bit [55: 0]  will be the timestamp
394  // Bit [63:56]  will be the ID
395  //
396  FspData  = GetFspGlobalDataPointer ();
397  if (FspData->PerfIdx < sizeof(FspData->PerfData) / sizeof(FspData->PerfData[0])) {
398    FspData->PerfData[FspData->PerfIdx] = AsmReadTsc ();
399    ((UINT8 *)(&FspData->PerfData[FspData->PerfIdx]))[7] = Id;
400  }
401
402  return FspData->PerfData[(FspData->PerfIdx)++];
403}
404
405/**
406  This function gets the FSP info header pointer.
407
408  @retval FspInfoHeader   FSP info header pointer
409**/
410FSP_INFO_HEADER *
411EFIAPI
412GetFspInfoHeader (
413  VOID
414  )
415{
416  return  GetFspGlobalDataPointer()->FspInfoHeader;
417}
418
419/**
420  This function gets the FSP info header pointer using the API stack context.
421
422  @retval FspInfoHeader   FSP info header pointer using the API stack context
423**/
424FSP_INFO_HEADER *
425EFIAPI
426GetFspInfoHeaderFromApiContext (
427  VOID
428  )
429{
430  FSP_GLOBAL_DATA  *FspData;
431
432  FspData  = GetFspGlobalDataPointer ();
433  return  (FSP_INFO_HEADER *)(*(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(FspInfoHeader)));
434}
435
436/**
437  This function gets the VPD data pointer.
438
439  @return VpdDataRgnPtr   VPD data pointer.
440**/
441VOID *
442EFIAPI
443GetFspVpdDataPointer (
444  VOID
445  )
446{
447  FSP_INFO_HEADER   *FspInfoHeader;
448
449  FspInfoHeader = GetFspInfoHeader ();
450  return (VOID *)(FspInfoHeader->ImageBase + FspInfoHeader->CfgRegionOffset);
451}
452
453/**
454  This function gets FSP API calling mode.
455
456  @retval API calling mode
457**/
458UINT8
459EFIAPI
460GetFspApiCallingMode (
461  VOID
462  )
463{
464  return  GetFspGlobalDataPointer()->ApiMode;
465}
466
467/**
468  This function sets FSP API calling mode.
469
470  @param[in] Mode     API calling mode
471**/
472VOID
473EFIAPI
474SetFspApiCallingMode (
475  UINT8  Mode
476  )
477{
478  FSP_GLOBAL_DATA  *FspData;
479
480  FspData  = GetFspGlobalDataPointer ();
481  FspData->ApiMode = Mode;
482}
483
484