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