]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFsp2Pkg/FspSecCore/SecFsp.c
IntelFsp2Pkg: Update SEC_IDT_TABLE struct
[mirror_edk2.git] / IntelFsp2Pkg / FspSecCore / SecFsp.c
1 /** @file
2
3 Copyright (c) 2014 - 2022, Intel Corporation. All rights reserved.<BR>
4 SPDX-License-Identifier: BSD-2-Clause-Patent
5
6 **/
7
8 #include "SecFsp.h"
9
10 /**
11
12 Calculate the FSP IDT gate descriptor.
13
14 @param[in] IdtEntryTemplate IDT gate descriptor template.
15
16 @return FSP specific IDT gate descriptor.
17
18 **/
19 IA32_IDT_GATE_DESCRIPTOR
20 FspGetExceptionHandler (
21 IN UINT64 IdtEntryTemplate
22 )
23 {
24 UINT32 Entry;
25 IA32_IDT_GATE_DESCRIPTOR ExceptionHandler;
26 IA32_IDT_GATE_DESCRIPTOR *IdtGateDescriptor;
27 FSP_INFO_HEADER *FspInfoHeader;
28
29 ZeroMem ((VOID *)&ExceptionHandler, sizeof (IA32_IDT_GATE_DESCRIPTOR));
30 FspInfoHeader = (FSP_INFO_HEADER *)(UINTN)AsmGetFspInfoHeader ();
31 *(UINT64 *) &ExceptionHandler = IdtEntryTemplate;
32 IdtGateDescriptor = &ExceptionHandler;
33 Entry = (IdtGateDescriptor->Bits.OffsetHigh << 16) | IdtGateDescriptor->Bits.OffsetLow;
34 Entry = FspInfoHeader->ImageBase + FspInfoHeader->ImageSize - (~Entry + 1);
35 IdtGateDescriptor->Bits.OffsetHigh = (UINT16)(Entry >> 16);
36 IdtGateDescriptor->Bits.OffsetLow = (UINT16)Entry;
37
38 return ExceptionHandler;
39 }
40
41 /**
42 This interface fills platform specific data.
43
44 @param[in,out] FspData Pointer to the FSP global data.
45
46 **/
47 VOID
48 EFIAPI
49 SecGetPlatformData (
50 IN OUT FSP_GLOBAL_DATA *FspData
51 )
52 {
53 FSP_PLAT_DATA *FspPlatformData;
54 UINT32 TopOfCar;
55 UINT32 *StackPtr;
56 UINT32 DwordSize;
57
58 FspPlatformData = &FspData->PlatformData;
59
60 //
61 // The entries of platform information, together with the number of them,
62 // reside in the bottom of stack, left untouched by normal stack operation.
63 //
64
65 FspPlatformData->DataPtr = NULL;
66 FspPlatformData->MicrocodeRegionBase = 0;
67 FspPlatformData->MicrocodeRegionSize = 0;
68 FspPlatformData->CodeRegionBase = 0;
69 FspPlatformData->CodeRegionSize = 0;
70
71 //
72 // Pointer to the size field
73 //
74 TopOfCar = PcdGet32 (PcdTemporaryRamBase) + PcdGet32 (PcdTemporaryRamSize);
75 StackPtr = (UINT32 *)(TopOfCar - sizeof (UINT32));
76
77 if (*(StackPtr - 1) == FSP_MCUD_SIGNATURE) {
78 while (*StackPtr != 0) {
79 if (*(StackPtr - 1) == FSP_MCUD_SIGNATURE) {
80 //
81 // This following data was pushed onto stack after TempRamInit API
82 //
83 DwordSize = 4;
84 StackPtr = StackPtr - 1 - DwordSize;
85 CopyMem (&(FspPlatformData->MicrocodeRegionBase), StackPtr, (DwordSize << 2));
86 StackPtr--;
87 } else if (*(StackPtr - 1) == FSP_PER0_SIGNATURE) {
88 //
89 // This is the performance data for InitTempMemory API entry/exit
90 //
91 DwordSize = 4;
92 StackPtr = StackPtr - 1 - DwordSize;
93 CopyMem (FspData->PerfData, StackPtr, (DwordSize << 2));
94
95 ((UINT8 *)(&FspData->PerfData[0]))[7] = FSP_PERF_ID_API_TEMP_RAM_INIT_ENTRY;
96 ((UINT8 *)(&FspData->PerfData[1]))[7] = FSP_PERF_ID_API_TEMP_RAM_INIT_EXIT;
97
98 StackPtr--;
99 } else {
100 StackPtr -= (*StackPtr);
101 }
102 }
103 }
104 }
105
106 /**
107
108 Initialize the FSP global data region.
109 It needs to be done as soon as possible after the stack is setup.
110
111 @param[in,out] PeiFspData Pointer of the FSP global data.
112 @param[in] BootLoaderStack BootLoader stack.
113 @param[in] ApiIdx The index of the FSP API.
114
115 **/
116 VOID
117 FspGlobalDataInit (
118 IN OUT FSP_GLOBAL_DATA *PeiFspData,
119 IN UINTN BootLoaderStack,
120 IN UINT8 ApiIdx
121 )
122 {
123 VOID *FspmUpdDataPtr;
124 CHAR8 ImageId[9];
125 UINTN Idx;
126
127 //
128 // Set FSP Global Data pointer
129 //
130 SetFspGlobalDataPointer (PeiFspData);
131 ZeroMem ((VOID *)PeiFspData, sizeof (FSP_GLOBAL_DATA));
132
133 PeiFspData->Signature = FSP_GLOBAL_DATA_SIGNATURE;
134 PeiFspData->Version = FSP_GLOBAL_DATA_VERSION;
135 PeiFspData->CoreStack = BootLoaderStack;
136 PeiFspData->PerfIdx = 2;
137 PeiFspData->PerfSig = FSP_PERFORMANCE_DATA_SIGNATURE;
138
139 SetFspMeasurePoint (FSP_PERF_ID_API_FSP_MEMORY_INIT_ENTRY);
140
141 //
142 // Get FSP Header offset
143 // It may have multiple FVs, so look into the last one for FSP header
144 //
145 PeiFspData->FspInfoHeader = (FSP_INFO_HEADER *)(UINTN)AsmGetFspInfoHeader ();
146 SecGetPlatformData (PeiFspData);
147
148 //
149 // Set API calling mode
150 //
151 SetFspApiCallingIndex (ApiIdx);
152
153 //
154 // Set UPD pointer
155 //
156 FspmUpdDataPtr = (VOID *)GetFspApiParameter ();
157 if (FspmUpdDataPtr == NULL) {
158 FspmUpdDataPtr = (VOID *)(UINTN)(PeiFspData->FspInfoHeader->ImageBase + PeiFspData->FspInfoHeader->CfgRegionOffset);
159 }
160
161 SetFspUpdDataPointer (FspmUpdDataPtr);
162 SetFspMemoryInitUpdDataPointer (FspmUpdDataPtr);
163 SetFspSiliconInitUpdDataPointer (NULL);
164
165 //
166 // Initialize OnSeparateStack value.
167 //
168 if (PcdGet8 (PcdFspHeapSizePercentage) != 0) {
169 //
170 // FSP is running on its own stack and may need switching stack when calling bootloader functions.
171 //
172 GetFspGlobalDataPointer ()->OnSeparateStack = 1;
173 }
174
175 //
176 // Initialize serial port
177 // It might have been done in ProcessLibraryConstructorList(), however,
178 // the FSP global data is not initialized at that time. So do it again
179 // for safe.
180 //
181 SerialPortInitialize ();
182
183 //
184 // Ensure the global data pointer is valid
185 //
186 ASSERT (GetFspGlobalDataPointer () == PeiFspData);
187
188 for (Idx = 0; Idx < 8; Idx++) {
189 ImageId[Idx] = PeiFspData->FspInfoHeader->ImageId[Idx];
190 }
191
192 ImageId[Idx] = 0;
193
194 DEBUG ((
195 DEBUG_INFO | DEBUG_INIT,
196 "\n============= FSP Spec v%d.%d Header Revision v%x (%a v%x.%x.%x.%x) =============\n", \
197 (PeiFspData->FspInfoHeader->SpecVersion >> 4) & 0xF, \
198 PeiFspData->FspInfoHeader->SpecVersion & 0xF, \
199 PeiFspData->FspInfoHeader->HeaderRevision, \
200 ImageId, \
201 (PeiFspData->FspInfoHeader->ImageRevision >> 24) & 0xFF, \
202 (PeiFspData->FspInfoHeader->ImageRevision >> 16) & 0xFF, \
203 (PeiFspData->FspInfoHeader->HeaderRevision >= 6) ? \
204 (((PeiFspData->FspInfoHeader->ImageRevision >> 8) & 0xFF) | (PeiFspData->FspInfoHeader->ExtendedImageRevision & 0xFF00)) : \
205 ((PeiFspData->FspInfoHeader->ImageRevision >> 8) & 0xFF), \
206 (PeiFspData->FspInfoHeader->HeaderRevision >= 6) ? \
207 ((PeiFspData->FspInfoHeader->ImageRevision & 0xFF) | ((PeiFspData->FspInfoHeader->ExtendedImageRevision & 0xFF) << 8)) : \
208 (PeiFspData->FspInfoHeader->ImageRevision & 0xFF)
209 ));
210 }
211
212 /**
213
214 Adjust the FSP data pointers after the stack is migrated to memory.
215
216 @param[in] OffsetGap The offset gap between the old stack and the new stack.
217
218 **/
219 VOID
220 FspDataPointerFixUp (
221 IN UINTN OffsetGap
222 )
223 {
224 FSP_GLOBAL_DATA *NewFspData;
225
226 NewFspData = (FSP_GLOBAL_DATA *)((UINTN)GetFspGlobalDataPointer () + (UINTN)OffsetGap);
227 SetFspGlobalDataPointer (NewFspData);
228 }