]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFspPkg/FspSecCore/SecFsp.c
00eb224c6f0e553650f7d0ecb48fa0c5b07f643a
[mirror_edk2.git] / IntelFspPkg / FspSecCore / SecFsp.c
1 /** @file
2
3 Copyright (c) 2014, 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 "SecFsp.h"
15
16 UINT32 FspImageSizeOffset = FSP_INFO_HEADER_OFF + OFFSET_IN_FSP_INFO_HEADER(ImageSize);
17
18 /**
19
20 Calculate the FSP IDT gate descriptor.
21
22 @param[in] IdtEntryTemplate IDT gate descriptor template.
23
24 @return FSP specific IDT gate descriptor.
25
26 **/
27 UINT64
28 FspGetExceptionHandler(
29 IN UINT64 IdtEntryTemplate
30 )
31 {
32 UINT32 Entry;
33 UINT64 ExceptionHandler;
34 IA32_IDT_GATE_DESCRIPTOR *IdtGateDescriptor;
35 FSP_INFO_HEADER *FspInfoHeader;
36
37 FspInfoHeader = (FSP_INFO_HEADER *)(GetFspBaseAddress() + FSP_INFO_HEADER_OFF);
38 ExceptionHandler = IdtEntryTemplate;
39 IdtGateDescriptor = (IA32_IDT_GATE_DESCRIPTOR *)&ExceptionHandler;
40 Entry = (IdtGateDescriptor->Bits.OffsetHigh << 16) | IdtGateDescriptor->Bits.OffsetLow;
41 Entry = FspInfoHeader->ImageBase + FspInfoHeader->ImageSize - (~Entry + 1);
42 IdtGateDescriptor->Bits.OffsetHigh = (UINT16)(Entry >> 16);
43 IdtGateDescriptor->Bits.OffsetLow = (UINT16)Entry;
44
45 return ExceptionHandler;
46 }
47
48 /**
49 This function gets the FSP UPD region offset in flash.
50
51 @return the offset of the UPD region.
52
53 **/
54 UINT32
55 EFIAPI
56 GetFspUpdRegionOffset (
57 VOID
58 )
59 {
60 FSP_GLOBAL_DATA *FspData;
61 UINT32 *Offset;
62
63 FspData = GetFspGlobalDataPointer ();
64
65 //
66 // It is required to put PcdUpdRegionOffset at offset 0x000C
67 // for all FSPs.
68 // gPlatformFspPkgTokenSpaceGuid.PcdUpdRegionOffset | 0x000C | 0x12345678
69 //
70 Offset = (UINT32 *)(FspData->FspInfoHeader->ImageBase + \
71 FspData->FspInfoHeader->CfgRegionOffset + 0x0C);
72
73 return *Offset;
74 }
75
76 /**
77 This interface fills platform specific data.
78
79 @param[in,out] FspData Pointer to the FSP global data.
80
81 **/
82 VOID
83 EFIAPI
84 SecGetPlatformData (
85 IN OUT FSP_GLOBAL_DATA *FspData
86 )
87 {
88 FSP_PLAT_DATA *FspPlatformData;
89 UINT32 TopOfCar;
90 UINT32 *StackPtr;
91 UINT32 DwordSize;
92
93 FspPlatformData = &FspData->PlatformData;
94
95 //
96 // The entries of platform information, together with the number of them,
97 // reside in the bottom of stack, left untouched by normal stack operation.
98 //
99 TopOfCar = PcdGet32 (PcdTemporaryRamBase) + PcdGet32 (PcdTemporaryRamSize);
100
101 FspPlatformData->DataPtr = NULL;
102 FspPlatformData->CodeRegionSize = 0;
103 FspPlatformData->CodeRegionBase = 0;
104 FspPlatformData->MicorcodeRegionBase = 0;
105 FspPlatformData->MicorcodeRegionSize = 0;
106
107 //
108 // Pointer to the size field
109 //
110 StackPtr = (UINT32 *)(TopOfCar - sizeof(UINT32));
111
112 while (*StackPtr != 0) {
113 if (*(StackPtr - 1) == FSP_MCUD_SIGNATURE) {
114 //
115 // This following data was pushed onto stack after TempRamInit API
116 //
117 DwordSize = 4;
118 StackPtr = StackPtr - 1 - DwordSize;
119 CopyMem (&(FspPlatformData->CodeRegionBase), StackPtr, (DwordSize << 2));
120 StackPtr--;
121 } else if (*(StackPtr - 1) == FSP_PER0_SIGNATURE) {
122 //
123 // This is the performance data for InitTempMemory API entry/exit
124 //
125 DwordSize = 4;
126 StackPtr = StackPtr - 1 - DwordSize;
127 CopyMem (FspData->PerfData, StackPtr, (DwordSize << 2));
128 ((UINT8 *)(&FspData->PerfData[0]))[7] = FSP_PERF_ID_API_TMPRAMINIT_ENTRY;
129 ((UINT8 *)(&FspData->PerfData[1]))[7] = FSP_PERF_ID_API_TMPRAMINIT_EXIT;
130 StackPtr--;
131 } else {
132 StackPtr -= (*StackPtr);
133 }
134 }
135 }
136
137 /**
138
139 Initialize the FSP global data region.
140 It needs to be done as soon as possible after the stack is setup.
141
142 @param[in,out] PeiFspData Pointer of the FSP global data.
143 @param[in] BootFirmwareVolume Point to the address of BootFirmwareVolume in stack.
144
145 **/
146 VOID
147 FspGlobalDataInit (
148 IN OUT FSP_GLOBAL_DATA *PeiFspData,
149 IN VOID **BootFirmwareVolume
150 )
151 {
152 VOID *UpdDataRgnPtr;
153 FSP_INIT_PARAMS *FspInitParams;
154 CHAR8 ImageId[9];
155 UINTN Idx;
156
157 //
158 // Init PCIE_BAR with value and set global FSP data pointer.
159 // PciExpress Base should have been programmed by platform already.
160 //
161 SetFspGlobalDataPointer (PeiFspData);
162 ZeroMem ((VOID *)PeiFspData, sizeof(FSP_GLOBAL_DATA));
163
164 PeiFspData->Signature = FSP_GLOBAL_DATA_SIGNATURE;
165 PeiFspData->CoreStack = *(UINTN *)(BootFirmwareVolume + 2);
166 PeiFspData->PerfIdx = 2;
167
168 SetFspMeasurePoint (FSP_PERF_ID_API_FSPINIT_ENTRY);
169
170 //
171 // Get FSP Header offset
172 // It may have multiple FVs, so look into the last one for FSP header
173 //
174 PeiFspData->FspInfoHeader = (FSP_INFO_HEADER *)(GetFspBaseAddress() + FSP_INFO_HEADER_OFF);
175 SecGetPlatformData (PeiFspData);
176
177 //
178 // Initialize UPD pointer.
179 //
180 FspInitParams = (FSP_INIT_PARAMS *)GetFspApiParameter ();
181 UpdDataRgnPtr = ((FSP_INIT_RT_COMMON_BUFFER *)FspInitParams->RtBufferPtr)->UpdDataRgnPtr;
182 if (UpdDataRgnPtr == NULL) {
183 UpdDataRgnPtr = (VOID *)(PeiFspData->FspInfoHeader->ImageBase + GetFspUpdRegionOffset());
184 }
185 SetFspUpdDataPointer (UpdDataRgnPtr);
186
187 //
188 // Initialize serial port
189 // It might have been done in ProcessLibraryConstructorList(), however,
190 // the FSP global data is not initialized at that time. So do it again
191 // for safe.
192 //
193 SerialPortInitialize ();
194
195 //
196 // Ensure the golbal data pointer is valid
197 //
198 ASSERT (GetFspGlobalDataPointer () == PeiFspData);
199
200 for (Idx = 0; Idx < 8; Idx++) {
201 ImageId[Idx] = PeiFspData->FspInfoHeader->ImageId[Idx];
202 }
203 ImageId[Idx] = 0;
204
205 DEBUG ((DEBUG_INFO | DEBUG_INIT, "\n============= PEIM FSP (%a 0x%08X) =============\n", \
206 ImageId, PeiFspData->FspInfoHeader->ImageRevision));
207
208 }
209
210 /**
211
212 Adjust the FSP data pointers after the stack is migrated to memory.
213
214 @param[in] OffsetGap The offset gap between the old stack and the new stack.
215
216 **/
217 VOID
218 FspDataPointerFixUp (
219 IN UINT32 OffsetGap
220 )
221 {
222 FSP_GLOBAL_DATA *NewFspData;
223
224 NewFspData = (FSP_GLOBAL_DATA *)((UINTN)GetFspGlobalDataPointer() + (UINTN)OffsetGap);
225 SetFspGlobalDataPointer (NewFspData);
226 }
227
228 /**
229 This function check the FSP API calling condition.
230
231 @param[in] ApiIdx Internal index of the FSP API.
232
233 **/
234 EFI_STATUS
235 EFIAPI
236 FspApiCallingCheck (
237 UINT32 ApiIdx
238 )
239 {
240 EFI_STATUS Status;
241 FSP_GLOBAL_DATA *FspData;
242
243 Status = EFI_SUCCESS;
244 FspData = GetFspGlobalDataPointer ();
245 if (ApiIdx == 1) {
246 //
247 // FspInit check
248 //
249 if ((UINT32)FspData != 0xFFFFFFFF) {
250 Status = EFI_UNSUPPORTED;
251 }
252 } else if (ApiIdx == 2) {
253 //
254 // NotifyPhase check
255 //
256 if ((FspData == NULL) || ((UINT32)FspData == 0xFFFFFFFF)) {
257 Status = EFI_UNSUPPORTED;
258 } else {
259 if (FspData->Signature != FSP_GLOBAL_DATA_SIGNATURE) {
260 Status = EFI_UNSUPPORTED;
261 }
262 }
263 } else {
264 Status = EFI_UNSUPPORTED;
265 }
266
267 return Status;
268 }