]> git.proxmox.com Git - mirror_edk2.git/blame - CorebootModulePkg/CbSupportPei/CbSupportPei.c
CorebootModulePkg/CbSupportPei: Mask off all legacy 8259 interrupt sources
[mirror_edk2.git] / CorebootModulePkg / CbSupportPei / CbSupportPei.c
CommitLineData
fce4ecd9
MM
1/** @file\r
2 This PEIM will parse coreboot table in memory and report resource information into pei core. \r
3 This file contains the main entrypoint of the PEIM.\r
4 \r
7b7fc3e7 5Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR>\r
fce4ecd9
MM
6This program and the accompanying materials\r
7are licensed and made available under the terms and conditions of the BSD License\r
8which accompanies this distribution. The full text of the license may be found at\r
9http://opensource.org/licenses/bsd-license.php\r
10\r
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15#include "CbSupportPei.h"\r
16\r
7b7fc3e7
MM
17#define LEGACY_8259_MASK_REGISTER_MASTER 0x21\r
18#define LEGACY_8259_MASK_REGISTER_SLAVE 0xA1\r
19\r
fce4ecd9
MM
20EFI_MEMORY_TYPE_INFORMATION mDefaultMemoryTypeInformation[] = {\r
21 { EfiACPIReclaimMemory, 0x008 }, \r
22 { EfiACPIMemoryNVS, 0x004 }, \r
23 { EfiReservedMemoryType, 0x004 }, \r
24 { EfiRuntimeServicesData, 0x080 },\r
25 { EfiRuntimeServicesCode, 0x080 },\r
26 { EfiMaxMemoryType, 0 }\r
27};\r
28\r
29EFI_PEI_PPI_DESCRIPTOR mPpiBootMode[] = {\r
30 {\r
31 EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,\r
32 &gEfiPeiMasterBootModePpiGuid,\r
33 NULL\r
34 }\r
35};\r
36\r
37/**\r
38 Create memory mapped io resource hob. \r
39 \r
40 @param MmioBase Base address of the memory mapped io range\r
41 @param MmioSize Length of the memory mapped io range\r
42 \r
43**/\r
44VOID\r
45BuildMemoryMappedIoRangeHob (\r
46 EFI_PHYSICAL_ADDRESS MmioBase,\r
47 UINT64 MmioSize\r
48 )\r
49{\r
50 BuildResourceDescriptorHob (\r
51 EFI_RESOURCE_MEMORY_MAPPED_IO,\r
52 (EFI_RESOURCE_ATTRIBUTE_PRESENT |\r
53 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |\r
54 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |\r
55 EFI_RESOURCE_ATTRIBUTE_TESTED),\r
56 MmioBase,\r
57 MmioSize\r
58 );\r
59 \r
60 BuildMemoryAllocationHob (\r
61 MmioBase,\r
62 MmioSize,\r
63 EfiMemoryMappedIO\r
64 ); \r
65}\r
66\r
67/**\r
68 Check the integrity of firmware volume header\r
69\r
70 @param[in] FwVolHeader A pointer to a firmware volume header\r
71\r
72 @retval TRUE The firmware volume is consistent\r
73 @retval FALSE The firmware volume has corrupted.\r
74\r
75**/\r
76STATIC\r
77BOOLEAN\r
78IsFvHeaderValid (\r
79 IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader\r
80 )\r
81{\r
82 UINT16 Checksum;\r
83 \r
84 // Skip nv storage fv\r
85 if (CompareMem (&FwVolHeader->FileSystemGuid, &gEfiFirmwareFileSystem2Guid, sizeof(EFI_GUID)) != 0 ) {\r
86 return FALSE;\r
87 }\r
88 \r
89 if ( (FwVolHeader->Revision != EFI_FVH_REVISION) ||\r
90 (FwVolHeader->Signature != EFI_FVH_SIGNATURE) ||\r
91 (FwVolHeader->FvLength == ((UINTN) -1)) ||\r
92 ((FwVolHeader->HeaderLength & 0x01 ) !=0) ) {\r
93 return FALSE;\r
94 }\r
95 \r
96 Checksum = CalculateCheckSum16 ((UINT16 *) FwVolHeader, FwVolHeader->HeaderLength);\r
97 if (Checksum != 0) {\r
98 DEBUG (( DEBUG_ERROR,\r
99 "ERROR - Invalid Firmware Volume Header Checksum, change 0x%04x to 0x%04x\r\n",\r
100 FwVolHeader->Checksum,\r
101 (UINT16)( Checksum + FwVolHeader->Checksum )));\r
102 return FALSE;\r
103 }\r
104\r
105 return TRUE; \r
106}\r
107\r
108/**\r
109 Install FvInfo PPI and create fv hobs for remained fvs\r
110 \r
111**/\r
112VOID\r
113CbPeiReportRemainedFvs (\r
114 VOID\r
115 )\r
116{\r
117 UINT8* TempPtr;\r
118 UINT8* EndPtr;\r
119 \r
120 TempPtr = (UINT8* )(UINTN) PcdGet32 (PcdPayloadFdMemBase);\r
121 EndPtr = (UINT8* )(UINTN) (PcdGet32 (PcdPayloadFdMemBase) + PcdGet32 (PcdPayloadFdMemSize));\r
122 \r
123 for (;TempPtr < EndPtr;) {\r
124 if (IsFvHeaderValid ((EFI_FIRMWARE_VOLUME_HEADER* )TempPtr)) {\r
125 if (TempPtr != (UINT8* )(UINTN) PcdGet32 (PcdPayloadFdMemBase)) {\r
126 // Skip the PEI FV\r
42e548a8 127 DEBUG((EFI_D_ERROR, "Found one valid fv : 0x%lx.\n", TempPtr, ((EFI_FIRMWARE_VOLUME_HEADER* )TempPtr)->FvLength)); \r
fce4ecd9
MM
128 \r
129 PeiServicesInstallFvInfoPpi (\r
130 NULL,\r
131 (VOID *) (UINTN) TempPtr,\r
132 (UINT32) (UINTN) ((EFI_FIRMWARE_VOLUME_HEADER* )TempPtr)->FvLength,\r
133 NULL,\r
134 NULL\r
135 );\r
136 BuildFvHob ((EFI_PHYSICAL_ADDRESS)(UINTN) TempPtr, ((EFI_FIRMWARE_VOLUME_HEADER* )TempPtr)->FvLength); \r
137 } \r
138 }\r
139 TempPtr += ((EFI_FIRMWARE_VOLUME_HEADER* )TempPtr)->FvLength; \r
140 } \r
141}\r
142\r
143/**\r
144 This is the entrypoint of PEIM\r
145 \r
146 @param FileHandle Handle of the file being invoked.\r
147 @param PeiServices Describes the list of possible PEI Services.\r
148\r
149 @retval EFI_SUCCESS if it completed successfully. \r
150**/\r
151EFI_STATUS\r
152EFIAPI\r
153CbPeiEntryPoint (\r
154 IN EFI_PEI_FILE_HANDLE FileHandle,\r
155 IN CONST EFI_PEI_SERVICES **PeiServices\r
156 )\r
157{\r
158 EFI_STATUS Status;\r
159 UINT64 LowMemorySize, HighMemorySize;\r
160 UINT64 PeiMemSize = SIZE_64MB; // 64 MB\r
161 EFI_PHYSICAL_ADDRESS PeiMemBase = 0;\r
162 UINT32 RegEax;\r
163 UINT8 PhysicalAddressBits;\r
164 VOID* pCbHeader;\r
165 VOID* pAcpiTable;\r
166 UINT32 AcpiTableSize;\r
167 VOID* pSmbiosTable;\r
168 UINT32 SmbiosTableSize;\r
169 SYSTEM_TABLE_INFO* pSystemTableInfo;\r
170 FRAME_BUFFER_INFO FbInfo;\r
171 FRAME_BUFFER_INFO* pFbInfo;\r
172 ACPI_BOARD_INFO* pAcpiBoardInfo;\r
173 UINTN PmCtrlRegBase, PmTimerRegBase, ResetRegAddress, ResetValue;\r
174 \r
175 LowMemorySize = 0;\r
176 HighMemorySize = 0;\r
177 \r
178 Status = CbParseMemoryInfo (&LowMemorySize, &HighMemorySize);\r
179 if (EFI_ERROR(Status)) \r
180 return Status;\r
181 \r
42e548a8
SD
182 DEBUG((EFI_D_ERROR, "LowMemorySize: 0x%lx.\n", LowMemorySize));\r
183 DEBUG((EFI_D_ERROR, "HighMemorySize: 0x%lx.\n", HighMemorySize));\r
fce4ecd9
MM
184 \r
185 ASSERT (LowMemorySize > 0);\r
186 \r
187 BuildResourceDescriptorHob ( \r
188 EFI_RESOURCE_SYSTEM_MEMORY,\r
189 (\r
190 EFI_RESOURCE_ATTRIBUTE_PRESENT |\r
191 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |\r
192 EFI_RESOURCE_ATTRIBUTE_TESTED |\r
193 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |\r
194 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |\r
195 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |\r
196 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE\r
197 ),\r
198 (EFI_PHYSICAL_ADDRESS)(0),\r
199 (UINT64)(0xA0000)\r
200 );\r
201 \r
202 \r
203 BuildResourceDescriptorHob ( \r
204 EFI_RESOURCE_MEMORY_RESERVED,\r
205 (\r
206 EFI_RESOURCE_ATTRIBUTE_PRESENT |\r
207 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |\r
208 EFI_RESOURCE_ATTRIBUTE_TESTED |\r
209 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |\r
210 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |\r
211 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |\r
212 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE\r
213 ),\r
214 (EFI_PHYSICAL_ADDRESS)(0xA0000),\r
215 (UINT64)(0x60000)\r
216 );\r
217 \r
218 BuildResourceDescriptorHob (\r
219 EFI_RESOURCE_SYSTEM_MEMORY,\r
220 (\r
221 EFI_RESOURCE_ATTRIBUTE_PRESENT |\r
222 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |\r
223 EFI_RESOURCE_ATTRIBUTE_TESTED |\r
224 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |\r
225 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |\r
226 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |\r
227 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE\r
228 ),\r
229 (EFI_PHYSICAL_ADDRESS)(0x100000),\r
230 (UINT64) (LowMemorySize - 0x100000)\r
231 );\r
232 \r
233 if (HighMemorySize > 0) {\r
234 BuildResourceDescriptorHob (\r
235 EFI_RESOURCE_SYSTEM_MEMORY,\r
236 (\r
237 EFI_RESOURCE_ATTRIBUTE_PRESENT |\r
238 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |\r
239 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |\r
240 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |\r
241 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |\r
242 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE\r
243 ),\r
c3911fd8 244 (EFI_PHYSICAL_ADDRESS)(0x100000000ULL),\r
fce4ecd9
MM
245 HighMemorySize\r
246 ); \r
247 } \r
248 \r
249 //\r
250 // Should be 64k aligned\r
251 //\r
252 PeiMemBase = (LowMemorySize - PeiMemSize) & (~(BASE_64KB - 1));\r
253 \r
42e548a8
SD
254 DEBUG((EFI_D_ERROR, "PeiMemBase: 0x%lx.\n", PeiMemBase));\r
255 DEBUG((EFI_D_ERROR, "PeiMemSize: 0x%lx.\n", PeiMemSize)); \r
fce4ecd9
MM
256 \r
257 Status = PeiServicesInstallPeiMemory (\r
258 PeiMemBase, \r
259 PeiMemSize\r
260 );\r
261 ASSERT_EFI_ERROR (Status); \r
262 \r
263 //\r
264 // Set cache on the physical memory\r
265 // \r
266 MtrrSetMemoryAttribute (BASE_1MB, LowMemorySize - BASE_1MB, CacheWriteBack);\r
267 MtrrSetMemoryAttribute (0, 0xA0000, CacheWriteBack);\r
268 \r
269 //\r
270 // Create Memory Type Information HOB\r
271 //\r
272 BuildGuidDataHob (\r
273 &gEfiMemoryTypeInformationGuid,\r
274 mDefaultMemoryTypeInformation,\r
275 sizeof(mDefaultMemoryTypeInformation)\r
276 );\r
277 \r
278 //\r
279 // Create Fv hob\r
280 //\r
281 CbPeiReportRemainedFvs (); \r
282 \r
283 BuildMemoryAllocationHob (\r
284 PcdGet32 (PcdPayloadFdMemBase),\r
285 PcdGet32 (PcdPayloadFdMemSize),\r
286 EfiBootServicesData\r
287 );\r
288 \r
289 //\r
290 // Build CPU memory space and IO space hob\r
291 //\r
292 AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);\r
293 if (RegEax >= 0x80000008) {\r
294 AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL); \r
295 PhysicalAddressBits = (UINT8) RegEax;\r
296 } else {\r
297 PhysicalAddressBits = 36;\r
298 }\r
299 //\r
300 // Create a CPU hand-off information\r
301 // \r
302 BuildCpuHob (PhysicalAddressBits, 16);\r
303 \r
304 //\r
305 // Report Local APIC range\r
306 //\r
307 BuildMemoryMappedIoRangeHob (0xFEC80000, SIZE_512KB);\r
308 \r
309 //\r
310 // Boot mode\r
311 //\r
312 Status = PeiServicesSetBootMode (BOOT_WITH_FULL_CONFIGURATION);\r
313 ASSERT_EFI_ERROR (Status);\r
314 \r
315 Status = PeiServicesInstallPpi (mPpiBootMode);\r
316 ASSERT_EFI_ERROR (Status);\r
317 \r
318 //\r
319 // Set pcd to save the upper coreboot header in case the dxecore will\r
320 // erase 0~4k memory\r
321 //\r
322 pCbHeader = NULL;\r
323 if ((CbParseGetCbHeader (1, &pCbHeader) == RETURN_SUCCESS) \r
324 && ((UINTN)pCbHeader > BASE_4KB)) {\r
42e548a8 325 DEBUG((EFI_D_ERROR, "Actual Coreboot header: %p.\n", pCbHeader)); \r
fce4ecd9
MM
326 PcdSet32 (PcdCbHeaderPointer, (UINT32)(UINTN)pCbHeader);\r
327 }\r
328 \r
329 //\r
330 // Create guid hob for system tables like acpi table and smbios table\r
331 //\r
332 pAcpiTable = NULL;\r
333 AcpiTableSize = 0;\r
334 pSmbiosTable = NULL;\r
335 SmbiosTableSize = 0;\r
336 Status = CbParseAcpiTable (&pAcpiTable, &AcpiTableSize);\r
337 if (EFI_ERROR (Status)) {\r
338 // ACPI table is oblidgible \r
339 DEBUG ((EFI_D_ERROR, "Failed to find the required acpi table\n"));\r
340 ASSERT (FALSE);\r
341 }\r
342 CbParseSmbiosTable (&pSmbiosTable, &SmbiosTableSize);\r
343 \r
344 pSystemTableInfo = NULL;\r
345 pSystemTableInfo = BuildGuidHob (&gUefiSystemTableInfoGuid, sizeof (SYSTEM_TABLE_INFO));\r
346 ASSERT (pSystemTableInfo != NULL);\r
347 pSystemTableInfo->AcpiTableBase = (UINT64) (UINTN)pAcpiTable;\r
348 pSystemTableInfo->AcpiTableSize = AcpiTableSize; \r
349 pSystemTableInfo->SmbiosTableBase = (UINT64) (UINTN)pSmbiosTable;\r
350 pSystemTableInfo->SmbiosTableSize = SmbiosTableSize;\r
42e548a8
SD
351 DEBUG ((EFI_D_ERROR, "Detected Acpi Table at 0x%lx, length 0x%x\n", pSystemTableInfo->AcpiTableBase, pSystemTableInfo->AcpiTableSize)); \r
352 DEBUG ((EFI_D_ERROR, "Detected Smbios Table at 0x%lx, length 0x%x\n", pSystemTableInfo->SmbiosTableBase, pSystemTableInfo->SmbiosTableSize)); \r
fce4ecd9
MM
353 DEBUG ((EFI_D_ERROR, "Create system table info guid hob\n"));\r
354 \r
355 //\r
356 // Create guid hob for acpi board information\r
357 // \r
358 Status = CbParseFadtInfo (&PmCtrlRegBase, &PmTimerRegBase, &ResetRegAddress, &ResetValue);\r
359 ASSERT_EFI_ERROR (Status);\r
360 pAcpiBoardInfo = NULL;\r
361 pAcpiBoardInfo = BuildGuidHob (&gUefiAcpiBoardInfoGuid, sizeof (ACPI_BOARD_INFO));\r
362 ASSERT (pAcpiBoardInfo != NULL);\r
363 pAcpiBoardInfo->PmCtrlRegBase = (UINT64)PmCtrlRegBase;\r
364 pAcpiBoardInfo->PmTimerRegBase = (UINT64)PmTimerRegBase;\r
365 pAcpiBoardInfo->ResetRegAddress = (UINT64)ResetRegAddress;\r
366 pAcpiBoardInfo->ResetValue = (UINT8)ResetValue; \r
367 DEBUG ((EFI_D_ERROR, "Create acpi board info guid hob\n"));\r
368 \r
369 //\r
370 // Create guid hob for frame buffer information\r
371 //\r
372 ZeroMem (&FbInfo, sizeof (FRAME_BUFFER_INFO)); \r
373 Status = CbParseFbInfo (&FbInfo);\r
374 if (!EFI_ERROR (Status)) {\r
375 pFbInfo = BuildGuidHob (&gUefiFrameBufferInfoGuid, sizeof (FRAME_BUFFER_INFO));\r
376 ASSERT (pSystemTableInfo != NULL);\r
377 CopyMem (pFbInfo, &FbInfo, sizeof (FRAME_BUFFER_INFO)); \r
378 DEBUG ((EFI_D_ERROR, "Create frame buffer info guid hob\n")); \r
379 }\r
7b7fc3e7
MM
380\r
381 //\r
382 // Mask off all legacy 8259 interrupt sources\r
383 //\r
384 IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, 0xFF);\r
385 IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, 0xFF);\r
386\r
fce4ecd9
MM
387 return EFI_SUCCESS;\r
388}\r
389\r