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 <Library/FspWrapperApiLib.h>
12 #include <Library/BaseLib.h>
13 #include <Library/BaseMemoryLib.h>
14 
15 /**
16   Wrapper for a thunk  to transition from long mode to compatibility mode to execute 32-bit code and then transit back to
17   long mode.
18 
19   @param[in] Function     The 32bit code entry to be executed.
20   @param[in] Param1       The first parameter to pass to 32bit code.
21   @param[in] Param2       The second parameter to pass to 32bit code.
22 
23   @return EFI_STATUS.
24 **/
25 EFI_STATUS
26 Execute32BitCode (
27   IN UINT64      Function,
28   IN UINT64      Param1,
29   IN UINT64      Param2
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 
62   CheckPointer = CheckPointer + sizeof (EFI_FFS_FILE_HEADER);
63 
64   if (((EFI_RAW_SECTION *)CheckPointer)->Type != EFI_SECTION_RAW) {
65     return NULL;
66   }
67 
68   CheckPointer = CheckPointer + sizeof (EFI_RAW_SECTION);
69 
70   return (FSP_INFO_HEADER *)CheckPointer;
71 }
72 
73 /**
74   Call FSP API - FspNotifyPhase.
75 
76   @param[in] NotifyPhaseParams Address pointer to the NOTIFY_PHASE_PARAMS structure.
77 
78   @return EFI status returned by FspNotifyPhase API.
79 **/
80 EFI_STATUS
81 EFIAPI
CallFspNotifyPhase(IN NOTIFY_PHASE_PARAMS * NotifyPhaseParams)82 CallFspNotifyPhase (
83   IN NOTIFY_PHASE_PARAMS *NotifyPhaseParams
84   )
85 {
86   FSP_INFO_HEADER     *FspHeader;
87   FSP_NOTIFY_PHASE    NotifyPhaseApi;
88   EFI_STATUS          Status;
89   BOOLEAN             InterruptState;
90 
91   FspHeader = (FSP_INFO_HEADER *)FspFindFspHeader (PcdGet32 (PcdFspsBaseAddress));
92   if (FspHeader == NULL) {
93     return EFI_DEVICE_ERROR;
94   }
95 
96   NotifyPhaseApi = (FSP_NOTIFY_PHASE)((UINTN)FspHeader->ImageBase + FspHeader->NotifyPhaseEntryOffset);
97   InterruptState = SaveAndDisableInterrupts ();
98   Status = Execute32BitCode ((UINTN)NotifyPhaseApi, (UINTN)NotifyPhaseParams, (UINTN)NULL);
99   SetInterruptState (InterruptState);
100 
101   return Status;
102 }
103 
104 /**
105   Call FSP API - FspMemoryInit.
106 
107   @param[in]  FspmUpdDataPtr Address pointer to the FSP_MEMORY_INIT_PARAMS structure.
108   @param[out] HobListPtr     Address of the HobList pointer.
109 
110   @return EFI status returned by FspMemoryInit API.
111 **/
112 EFI_STATUS
113 EFIAPI
CallFspMemoryInit(IN VOID * FspmUpdDataPtr,OUT VOID ** HobListPtr)114 CallFspMemoryInit (
115   IN VOID                       *FspmUpdDataPtr,
116   OUT VOID                      **HobListPtr
117   )
118 {
119   FSP_INFO_HEADER     *FspHeader;
120   FSP_MEMORY_INIT     FspMemoryInitApi;
121   EFI_STATUS          Status;
122   BOOLEAN             InterruptState;
123 
124   FspHeader = (FSP_INFO_HEADER *)FspFindFspHeader (PcdGet32 (PcdFspmBaseAddress));
125   if (FspHeader == NULL) {
126     return EFI_DEVICE_ERROR;
127   }
128 
129   FspMemoryInitApi = (FSP_MEMORY_INIT)((UINTN)FspHeader->ImageBase + FspHeader->FspMemoryInitEntryOffset);
130   InterruptState = SaveAndDisableInterrupts ();
131   Status = Execute32BitCode ((UINTN)FspMemoryInitApi, (UINTN)FspmUpdDataPtr, (UINTN)HobListPtr);
132   SetInterruptState (InterruptState);
133 
134   return Status;
135 }
136 
137 /**
138   Call FSP API - TempRamExit.
139 
140   @param[in] TempRamExitParam    Address pointer to the TempRamExit parameters structure.
141 
142   @return EFI status returned by TempRamExit API.
143 **/
144 EFI_STATUS
145 EFIAPI
CallTempRamExit(IN VOID * TempRamExitParam)146 CallTempRamExit (
147   IN VOID                       *TempRamExitParam
148   )
149 {
150   FSP_INFO_HEADER     *FspHeader;
151   FSP_TEMP_RAM_EXIT   TempRamExitApi;
152   EFI_STATUS          Status;
153   BOOLEAN             InterruptState;
154 
155   FspHeader = (FSP_INFO_HEADER *)FspFindFspHeader (PcdGet32 (PcdFspmBaseAddress));
156   if (FspHeader == NULL) {
157     return EFI_DEVICE_ERROR;
158   }
159 
160   TempRamExitApi = (FSP_TEMP_RAM_EXIT)((UINTN)FspHeader->ImageBase + FspHeader->TempRamExitEntryOffset);
161   InterruptState = SaveAndDisableInterrupts ();
162   Status = Execute32BitCode ((UINTN)TempRamExitApi, (UINTN)TempRamExitParam, (UINTN)NULL);
163   SetInterruptState (InterruptState);
164 
165   return Status;
166 }
167 
168 /**
169   Call FSP API - FspSiliconInit.
170 
171   @param[in] FspsUpdDataPtr Address pointer to the Silicon Init parameters structure.
172 
173   @return EFI status returned by FspSiliconInit API.
174 **/
175 EFI_STATUS
176 EFIAPI
CallFspSiliconInit(IN VOID * FspsUpdDataPtr)177 CallFspSiliconInit (
178   IN VOID                       *FspsUpdDataPtr
179   )
180 {
181   FSP_INFO_HEADER     *FspHeader;
182   FSP_SILICON_INIT    FspSiliconInitApi;
183   EFI_STATUS          Status;
184   BOOLEAN             InterruptState;
185 
186   FspHeader = (FSP_INFO_HEADER *)FspFindFspHeader (PcdGet32 (PcdFspsBaseAddress));
187   if (FspHeader == NULL) {
188     return EFI_DEVICE_ERROR;
189   }
190 
191   FspSiliconInitApi = (FSP_SILICON_INIT)((UINTN)FspHeader->ImageBase + FspHeader->FspSiliconInitEntryOffset);
192   InterruptState = SaveAndDisableInterrupts ();
193   Status = Execute32BitCode ((UINTN)FspSiliconInitApi, (UINTN)FspsUpdDataPtr, (UINTN)NULL);
194   SetInterruptState (InterruptState);
195 
196   return Status;
197 }
198