1 /** @file
2   Provide FSP API related function.
3 
4   Copyright (c) 2014 - 2017, Intel Corporation. All rights reserved.<BR>
5   SPDX-License-Identifier: BSD-2-Clause-Patent
6 
7 **/
8 
9 #include <PiPei.h>
10 
11 #include <Guid/FspHeaderFile.h>
12 
13 #include <Library/FspApiLib.h>
14 #include <Library/BaseLib.h>
15 #include <Library/BaseMemoryLib.h>
16 
17 /**
18   Wrapper for a thunk  to transition from long mode to compatibility mode to execute 32-bit code and then transit back to
19   long mode.
20 
21   @param[in] Function     The 32bit code entry to be executed.
22   @param[in] Param1       The first parameter to pass to 32bit code.
23 
24   @return EFI_STATUS.
25 **/
26 EFI_STATUS
27 Execute32BitCode (
28   IN UINT64      Function,
29   IN UINT64      Param1
30   );
31 
32 /**
33   Find FSP header pointer.
34 
35   @param[in] FlashFvFspBase Flash address of FSP FV.
36 
37   @return FSP header pointer.
38 **/
39 FSP_INFO_HEADER *
40 EFIAPI
FspFindFspHeader(IN EFI_PHYSICAL_ADDRESS FlashFvFspBase)41 FspFindFspHeader (
42   IN EFI_PHYSICAL_ADDRESS  FlashFvFspBase
43   )
44 {
45   UINT8 *CheckPointer;
46 
47   CheckPointer = (UINT8 *) (UINTN) FlashFvFspBase;
48 
49   if (((EFI_FIRMWARE_VOLUME_HEADER *)CheckPointer)->Signature != EFI_FVH_SIGNATURE) {
50     return NULL;
51   }
52 
53   if (((EFI_FIRMWARE_VOLUME_HEADER *)CheckPointer)->ExtHeaderOffset != 0) {
54     CheckPointer = CheckPointer + ((EFI_FIRMWARE_VOLUME_HEADER *)CheckPointer)->ExtHeaderOffset;
55     CheckPointer = CheckPointer + ((EFI_FIRMWARE_VOLUME_EXT_HEADER *)CheckPointer)->ExtHeaderSize;
56     CheckPointer = (UINT8 *) ALIGN_POINTER (CheckPointer, 8);
57   } else {
58     CheckPointer = CheckPointer + ((EFI_FIRMWARE_VOLUME_HEADER *)CheckPointer)->HeaderLength;
59   }
60 
61   if (!CompareGuid (&((EFI_FFS_FILE_HEADER *)CheckPointer)->Name, &gFspHeaderFileGuid)) {
62     return NULL;
63   }
64 
65   CheckPointer = CheckPointer + sizeof (EFI_FFS_FILE_HEADER);
66 
67   if (((EFI_RAW_SECTION *)CheckPointer)->Type != EFI_SECTION_RAW) {
68     return NULL;
69   }
70 
71   CheckPointer = CheckPointer + sizeof (EFI_RAW_SECTION);
72 
73   return (FSP_INFO_HEADER *)CheckPointer;
74 }
75 
76 /**
77   Call FSP API - FspInit.
78 
79   @param[in] FspHeader     FSP header pointer.
80   @param[in] FspInitParams Address pointer to the FSP_INIT_PARAMS structure.
81 
82   @return EFI status returned by FspInit API.
83 **/
84 EFI_STATUS
85 EFIAPI
CallFspInit(IN FSP_INFO_HEADER * FspHeader,IN FSP_INIT_PARAMS * FspInitParams)86 CallFspInit (
87   IN FSP_INFO_HEADER     *FspHeader,
88   IN FSP_INIT_PARAMS     *FspInitParams
89   )
90 {
91   FSP_INIT            FspInitApi;
92   EFI_STATUS          Status;
93   BOOLEAN             InterruptState;
94 
95   FspInitApi = (FSP_INIT)((UINTN)FspHeader->ImageBase + FspHeader->FspInitEntryOffset);
96   InterruptState = SaveAndDisableInterrupts ();
97   Status = Execute32BitCode ((UINTN)FspInitApi, (UINTN)FspInitParams);
98   SetInterruptState (InterruptState);
99 
100   return Status;
101 }
102 
103 /**
104   Call FSP API - FspNotifyPhase.
105 
106   @param[in] FspHeader         FSP header pointer.
107   @param[in] NotifyPhaseParams Address pointer to the NOTIFY_PHASE_PARAMS structure.
108 
109   @return EFI status returned by FspNotifyPhase API.
110 **/
111 EFI_STATUS
112 EFIAPI
CallFspNotifyPhase(IN FSP_INFO_HEADER * FspHeader,IN NOTIFY_PHASE_PARAMS * NotifyPhaseParams)113 CallFspNotifyPhase (
114   IN FSP_INFO_HEADER     *FspHeader,
115   IN NOTIFY_PHASE_PARAMS *NotifyPhaseParams
116   )
117 {
118   FSP_NOTIFY_PHASE    NotifyPhaseApi;
119   EFI_STATUS          Status;
120   BOOLEAN             InterruptState;
121 
122   NotifyPhaseApi = (FSP_NOTIFY_PHASE)((UINTN)FspHeader->ImageBase + FspHeader->NotifyPhaseEntryOffset);
123   InterruptState = SaveAndDisableInterrupts ();
124   Status = Execute32BitCode ((UINTN)NotifyPhaseApi, (UINTN)NotifyPhaseParams);
125   SetInterruptState (InterruptState);
126 
127   return Status;
128 }
129 
130 /**
131   Call FSP API - FspMemoryInit.
132 
133   @param[in]     FspHeader           FSP header pointer.
134   @param[in,out] FspMemoryInitParams Address pointer to the FSP_MEMORY_INIT_PARAMS structure.
135 
136   @return EFI status returned by FspMemoryInit API.
137 **/
138 EFI_STATUS
139 EFIAPI
CallFspMemoryInit(IN FSP_INFO_HEADER * FspHeader,IN OUT FSP_MEMORY_INIT_PARAMS * FspMemoryInitParams)140 CallFspMemoryInit (
141   IN FSP_INFO_HEADER            *FspHeader,
142   IN OUT FSP_MEMORY_INIT_PARAMS *FspMemoryInitParams
143   )
144 {
145   FSP_MEMORY_INIT     FspMemoryInitApi;
146   EFI_STATUS          Status;
147   BOOLEAN             InterruptState;
148 
149   FspMemoryInitApi = (FSP_MEMORY_INIT)((UINTN)FspHeader->ImageBase + FspHeader->FspMemoryInitEntryOffset);
150   InterruptState = SaveAndDisableInterrupts ();
151   Status = Execute32BitCode ((UINTN)FspMemoryInitApi, (UINTN)FspMemoryInitParams);
152   SetInterruptState (InterruptState);
153 
154   return Status;
155 }
156 
157 /**
158   Call FSP API - TempRamExit.
159 
160   @param[in]     FspHeader           FSP header pointer.
161   @param[in,out] TempRamExitParam    Address pointer to the TempRamExit parameters structure.
162 
163   @return EFI status returned by TempRamExit API.
164 **/
165 EFI_STATUS
166 EFIAPI
CallTempRamExit(IN FSP_INFO_HEADER * FspHeader,IN OUT VOID * TempRamExitParam)167 CallTempRamExit (
168   IN FSP_INFO_HEADER            *FspHeader,
169   IN OUT VOID                   *TempRamExitParam
170   )
171 {
172   FSP_TEMP_RAM_EXIT   TempRamExitApi;
173   EFI_STATUS          Status;
174   BOOLEAN             InterruptState;
175 
176   TempRamExitApi = (FSP_TEMP_RAM_EXIT)((UINTN)FspHeader->ImageBase + FspHeader->TempRamExitEntryOffset);
177   InterruptState = SaveAndDisableInterrupts ();
178   Status = Execute32BitCode ((UINTN)TempRamExitApi, (UINTN)TempRamExitParam);
179   SetInterruptState (InterruptState);
180 
181   return Status;
182 }
183 
184 /**
185   Call FSP API - FspSiliconInit.
186 
187   @param[in]     FspHeader           FSP header pointer.
188   @param[in,out] FspSiliconInitParam Address pointer to the Silicon Init parameters structure.
189 
190   @return EFI status returned by FspSiliconInit API.
191 **/
192 EFI_STATUS
193 EFIAPI
CallFspSiliconInit(IN FSP_INFO_HEADER * FspHeader,IN OUT VOID * FspSiliconInitParam)194 CallFspSiliconInit (
195   IN FSP_INFO_HEADER            *FspHeader,
196   IN OUT VOID                   *FspSiliconInitParam
197   )
198 {
199   FSP_SILICON_INIT    FspSiliconInitApi;
200   EFI_STATUS          Status;
201   BOOLEAN             InterruptState;
202 
203   FspSiliconInitApi = (FSP_SILICON_INIT)((UINTN)FspHeader->ImageBase + FspHeader->FspSiliconInitEntryOffset);
204   InterruptState = SaveAndDisableInterrupts ();
205   Status = Execute32BitCode ((UINTN)FspSiliconInitApi, (UINTN)FspSiliconInitParam);
206   SetInterruptState (InterruptState);
207 
208   return Status;
209 }
210