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