]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFsp2Pkg/FspSecCore/SecFsp.c
Add IntelFsp2Pkg and IntelFsp2WrapperPkg.
[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 = FspPlatformData->CarBase + FspPlatformData->CarSize;
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 PeiFspData->PlatformData.CarBase = AsmReadMsr32 (0x200) & ~(0x6);
144 PeiFspData->PlatformData.CarSize = ~(AsmReadMsr32(0x201) & ~(0x800)) + 1;
145
146 SetFspMeasurePoint (FSP_PERF_ID_API_FSP_MEMORY_INIT_ENTRY);
147
148 //
149 // Get FSP Header offset
150 // It may have multiple FVs, so look into the last one for FSP header
151 //
152 PeiFspData->FspInfoHeader = (FSP_INFO_HEADER *)AsmGetFspInfoHeader();
153 SecGetPlatformData (PeiFspData);
154
155 //
156 // Set API calling mode
157 //
158 SetFspApiCallingIndex (ApiIdx);
159
160 //
161 // Set UPD pointer
162 //
163 FspmUpdDataPtr = (VOID *) GetFspApiParameter ();
164 if (FspmUpdDataPtr == NULL) {
165 FspmUpdDataPtr = (VOID *)(PeiFspData->FspInfoHeader->ImageBase + PeiFspData->FspInfoHeader->CfgRegionOffset);
166 }
167 SetFspUpdDataPointer (FspmUpdDataPtr);
168 SetFspMemoryInitUpdDataPointer (FspmUpdDataPtr);
169 SetFspSiliconInitUpdDataPointer (NULL);
170
171 //
172 // Initialize serial port
173 // It might have been done in ProcessLibraryConstructorList(), however,
174 // the FSP global data is not initialized at that time. So do it again
175 // for safe.
176 //
177 SerialPortInitialize ();
178
179 //
180 // Ensure the golbal data pointer is valid
181 //
182 ASSERT (GetFspGlobalDataPointer () == PeiFspData);
183
184 for (Idx = 0; Idx < 8; Idx++) {
185 ImageId[Idx] = PeiFspData->FspInfoHeader->ImageId[Idx];
186 }
187 ImageId[Idx] = 0;
188
189 DEBUG ((DEBUG_INFO | DEBUG_INIT, "\n============= FSP Spec v%d.%d Header Revision v%x (%a v%x.%x.%x.%x) =============\n", \
190 (PeiFspData->FspInfoHeader->SpecVersion >> 4) & 0xF, \
191 PeiFspData->FspInfoHeader->SpecVersion & 0xF, \
192 PeiFspData->FspInfoHeader->HeaderRevision, \
193 ImageId, \
194 (PeiFspData->FspInfoHeader->ImageRevision >> 24) & 0xFF, \
195 (PeiFspData->FspInfoHeader->ImageRevision >> 16) & 0xFF, \
196 (PeiFspData->FspInfoHeader->ImageRevision >> 8) & 0xFF, \
197 PeiFspData->FspInfoHeader->ImageRevision & 0xFF));
198 }
199
200 /**
201
202 Adjust the FSP data pointers after the stack is migrated to memory.
203
204 @param[in] OffsetGap The offset gap between the old stack and the new stack.
205
206 **/
207 VOID
208 FspDataPointerFixUp (
209 IN UINT32 OffsetGap
210 )
211 {
212 FSP_GLOBAL_DATA *NewFspData;
213
214 NewFspData = (FSP_GLOBAL_DATA *)((UINTN)GetFspGlobalDataPointer() + (UINTN)OffsetGap);
215 SetFspGlobalDataPointer (NewFspData);
216 }