]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - CorebootModulePkg/CbSupportPei/CbSupportPei.c
QuarkSocPkg/Library: Remove extra UefiBaseType.h includes
[mirror_edk2.git] / CorebootModulePkg / CbSupportPei / CbSupportPei.c
... / ...
CommitLineData
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
5Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>\r
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
17#define LEGACY_8259_MASK_REGISTER_MASTER 0x21\r
18#define LEGACY_8259_MASK_REGISTER_SLAVE 0xA1\r
19\r
20EFI_MEMORY_TYPE_INFORMATION mDefaultMemoryTypeInformation[] = {\r
21 { EfiACPIReclaimMemory, FixedPcdGet32 (PcdMemoryTypeEfiACPIReclaimMemory) },\r
22 { EfiACPIMemoryNVS, FixedPcdGet32 (PcdMemoryTypeEfiACPIMemoryNVS) },\r
23 { EfiReservedMemoryType, FixedPcdGet32 (PcdMemoryTypeEfiReservedMemoryType) },\r
24 { EfiRuntimeServicesData, FixedPcdGet32 (PcdMemoryTypeEfiRuntimeServicesData) },\r
25 { EfiRuntimeServicesCode, FixedPcdGet32 (PcdMemoryTypeEfiRuntimeServicesCode) },\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
127 DEBUG((EFI_D_ERROR, "Found one valid fv : 0x%lx.\n", TempPtr, ((EFI_FIRMWARE_VOLUME_HEADER* )TempPtr)->FvLength));\r
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 Based on memory base, size and type, build resource descripter HOB.\r
145\r
146 @param Base Memory base address.\r
147 @param Size Memory size.\r
148 @param Type Memory type.\r
149 @param Param A pointer to CB_MEM_INFO.\r
150\r
151 @retval EFI_SUCCESS if it completed successfully.\r
152**/\r
153EFI_STATUS\r
154CbMemInfoCallback (\r
155 UINT64 Base,\r
156 UINT64 Size,\r
157 UINT32 Type,\r
158 VOID *Param\r
159 )\r
160{\r
161 CB_MEM_INFO *MemInfo;\r
162 UINTN Attribue;\r
163\r
164 Attribue = EFI_RESOURCE_ATTRIBUTE_PRESENT |\r
165 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |\r
166 EFI_RESOURCE_ATTRIBUTE_TESTED |\r
167 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |\r
168 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |\r
169 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |\r
170 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE;\r
171\r
172 MemInfo = (CB_MEM_INFO *)Param;\r
173 if (Base >= 0x100000) {\r
174 if (Type == CB_MEM_RAM) {\r
175 if (Base < 0x100000000ULL) {\r
176 MemInfo->UsableLowMemTop = (UINT32)(Base + Size);\r
177 } else {\r
178 Attribue &= ~EFI_RESOURCE_ATTRIBUTE_TESTED;\r
179 }\r
180 BuildResourceDescriptorHob (\r
181 EFI_RESOURCE_SYSTEM_MEMORY,\r
182 Attribue,\r
183 (EFI_PHYSICAL_ADDRESS)Base,\r
184 Size\r
185 );\r
186 } else if (Type == CB_MEM_TABLE) {\r
187 BuildResourceDescriptorHob (\r
188 EFI_RESOURCE_MEMORY_RESERVED,\r
189 Attribue,\r
190 (EFI_PHYSICAL_ADDRESS)Base,\r
191 Size\r
192 );\r
193 MemInfo->SystemLowMemTop = ((UINT32)(Base + Size) + 0x0FFFFFFF) & 0xF0000000;\r
194 } else if (Type == CB_MEM_RESERVED) {\r
195 if ((MemInfo->SystemLowMemTop == 0) || (Base < MemInfo->SystemLowMemTop)) {\r
196 BuildResourceDescriptorHob (\r
197 EFI_RESOURCE_MEMORY_RESERVED,\r
198 Attribue,\r
199 (EFI_PHYSICAL_ADDRESS)Base,\r
200 Size\r
201 ); \r
202 }\r
203 }\r
204 }\r
205 \r
206 return EFI_SUCCESS;\r
207}\r
208\r
209/**\r
210 This is the entrypoint of PEIM\r
211\r
212 @param FileHandle Handle of the file being invoked.\r
213 @param PeiServices Describes the list of possible PEI Services.\r
214\r
215 @retval EFI_SUCCESS if it completed successfully.\r
216**/\r
217EFI_STATUS\r
218EFIAPI\r
219CbPeiEntryPoint (\r
220 IN EFI_PEI_FILE_HANDLE FileHandle,\r
221 IN CONST EFI_PEI_SERVICES **PeiServices\r
222 )\r
223{\r
224 EFI_STATUS Status;\r
225 UINT64 LowMemorySize;\r
226 UINT64 PeiMemSize = SIZE_64MB; // 64 MB\r
227 EFI_PHYSICAL_ADDRESS PeiMemBase = 0;\r
228 UINT32 RegEax;\r
229 UINT8 PhysicalAddressBits;\r
230 VOID* pCbHeader;\r
231 VOID* pAcpiTable;\r
232 UINT32 AcpiTableSize;\r
233 VOID* pSmbiosTable;\r
234 UINT32 SmbiosTableSize;\r
235 SYSTEM_TABLE_INFO* pSystemTableInfo;\r
236 FRAME_BUFFER_INFO FbInfo;\r
237 FRAME_BUFFER_INFO* pFbInfo;\r
238 ACPI_BOARD_INFO* pAcpiBoardInfo;\r
239 UINTN PmCtrlRegBase, PmTimerRegBase, ResetRegAddress, ResetValue;\r
240 UINTN PmEvtBase;\r
241 UINTN PmGpeEnBase;\r
242 CB_MEM_INFO CbMemInfo;\r
243\r
244 //\r
245 // Report lower 640KB of RAM. Attribute EFI_RESOURCE_ATTRIBUTE_TESTED \r
246 // is intentionally omitted to prevent erasing of the coreboot header \r
247 // record before it is processed by CbParseMemoryInfo.\r
248 //\r
249 BuildResourceDescriptorHob (\r
250 EFI_RESOURCE_SYSTEM_MEMORY,\r
251 (\r
252 EFI_RESOURCE_ATTRIBUTE_PRESENT |\r
253 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |\r
254 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |\r
255 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |\r
256 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |\r
257 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE\r
258 ),\r
259 (EFI_PHYSICAL_ADDRESS)(0),\r
260 (UINT64)(0xA0000)\r
261 );\r
262\r
263\r
264 BuildResourceDescriptorHob (\r
265 EFI_RESOURCE_MEMORY_RESERVED,\r
266 (\r
267 EFI_RESOURCE_ATTRIBUTE_PRESENT |\r
268 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |\r
269 EFI_RESOURCE_ATTRIBUTE_TESTED |\r
270 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |\r
271 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |\r
272 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |\r
273 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE\r
274 ),\r
275 (EFI_PHYSICAL_ADDRESS)(0xA0000),\r
276 (UINT64)(0x60000)\r
277 );\r
278\r
279 ZeroMem (&CbMemInfo, sizeof(CbMemInfo));\r
280 Status = CbParseMemoryInfo (CbMemInfoCallback, (VOID *)&CbMemInfo);\r
281 if (EFI_ERROR(Status)) {\r
282 return Status;\r
283 }\r
284\r
285 LowMemorySize = CbMemInfo.UsableLowMemTop;\r
286 DEBUG ((EFI_D_INFO, "Low memory 0x%lx\n", LowMemorySize));\r
287 DEBUG ((EFI_D_INFO, "SystemLowMemTop 0x%x\n", CbMemInfo.SystemLowMemTop));\r
288\r
289 //\r
290 // Should be 64k aligned\r
291 //\r
292 PeiMemBase = (LowMemorySize - PeiMemSize) & (~(BASE_64KB - 1));\r
293\r
294 DEBUG((EFI_D_ERROR, "PeiMemBase: 0x%lx.\n", PeiMemBase));\r
295 DEBUG((EFI_D_ERROR, "PeiMemSize: 0x%lx.\n", PeiMemSize));\r
296\r
297 Status = PeiServicesInstallPeiMemory (\r
298 PeiMemBase,\r
299 PeiMemSize\r
300 );\r
301 ASSERT_EFI_ERROR (Status);\r
302\r
303 //\r
304 // Set cache on the physical memory\r
305 //\r
306 MtrrSetMemoryAttribute (BASE_1MB, LowMemorySize - BASE_1MB, CacheWriteBack);\r
307 MtrrSetMemoryAttribute (0, 0xA0000, CacheWriteBack);\r
308\r
309 //\r
310 // Create Memory Type Information HOB\r
311 //\r
312 BuildGuidDataHob (\r
313 &gEfiMemoryTypeInformationGuid,\r
314 mDefaultMemoryTypeInformation,\r
315 sizeof(mDefaultMemoryTypeInformation)\r
316 );\r
317\r
318 //\r
319 // Create Fv hob\r
320 //\r
321 CbPeiReportRemainedFvs ();\r
322\r
323 BuildMemoryAllocationHob (\r
324 PcdGet32 (PcdPayloadFdMemBase),\r
325 PcdGet32 (PcdPayloadFdMemSize),\r
326 EfiBootServicesData\r
327 );\r
328\r
329 //\r
330 // Build CPU memory space and IO space hob\r
331 //\r
332 AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);\r
333 if (RegEax >= 0x80000008) {\r
334 AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);\r
335 PhysicalAddressBits = (UINT8) RegEax;\r
336 } else {\r
337 PhysicalAddressBits = 36;\r
338 }\r
339 //\r
340 // Create a CPU hand-off information\r
341 //\r
342 BuildCpuHob (PhysicalAddressBits, 16);\r
343\r
344 //\r
345 // Report Local APIC range\r
346 //\r
347 BuildMemoryMappedIoRangeHob (0xFEC80000, SIZE_512KB);\r
348\r
349 //\r
350 // Boot mode\r
351 //\r
352 Status = PeiServicesSetBootMode (BOOT_WITH_FULL_CONFIGURATION);\r
353 ASSERT_EFI_ERROR (Status);\r
354\r
355 Status = PeiServicesInstallPpi (mPpiBootMode);\r
356 ASSERT_EFI_ERROR (Status);\r
357\r
358 //\r
359 // Set pcd to save the upper coreboot header in case the dxecore will\r
360 // erase 0~4k memory\r
361 //\r
362 pCbHeader = NULL;\r
363 if ((CbParseGetCbHeader (1, &pCbHeader) == RETURN_SUCCESS)\r
364 && ((UINTN)pCbHeader > BASE_4KB)) {\r
365 DEBUG((EFI_D_ERROR, "Actual Coreboot header: %p.\n", pCbHeader));\r
366 Status = PcdSet32S (PcdCbHeaderPointer, (UINT32)(UINTN)pCbHeader);\r
367 ASSERT_EFI_ERROR (Status);\r
368 }\r
369\r
370 //\r
371 // Create guid hob for system tables like acpi table and smbios table\r
372 //\r
373 pAcpiTable = NULL;\r
374 AcpiTableSize = 0;\r
375 pSmbiosTable = NULL;\r
376 SmbiosTableSize = 0;\r
377 Status = CbParseAcpiTable (&pAcpiTable, &AcpiTableSize);\r
378 if (EFI_ERROR (Status)) {\r
379 // ACPI table is oblidgible\r
380 DEBUG ((EFI_D_ERROR, "Failed to find the required acpi table\n"));\r
381 ASSERT (FALSE);\r
382 }\r
383 CbParseSmbiosTable (&pSmbiosTable, &SmbiosTableSize);\r
384\r
385 pSystemTableInfo = NULL;\r
386 pSystemTableInfo = BuildGuidHob (&gUefiSystemTableInfoGuid, sizeof (SYSTEM_TABLE_INFO));\r
387 ASSERT (pSystemTableInfo != NULL);\r
388 pSystemTableInfo->AcpiTableBase = (UINT64) (UINTN)pAcpiTable;\r
389 pSystemTableInfo->AcpiTableSize = AcpiTableSize;\r
390 pSystemTableInfo->SmbiosTableBase = (UINT64) (UINTN)pSmbiosTable;\r
391 pSystemTableInfo->SmbiosTableSize = SmbiosTableSize;\r
392 DEBUG ((EFI_D_ERROR, "Detected Acpi Table at 0x%lx, length 0x%x\n", pSystemTableInfo->AcpiTableBase, pSystemTableInfo->AcpiTableSize));\r
393 DEBUG ((EFI_D_ERROR, "Detected Smbios Table at 0x%lx, length 0x%x\n", pSystemTableInfo->SmbiosTableBase, pSystemTableInfo->SmbiosTableSize));\r
394 DEBUG ((EFI_D_ERROR, "Create system table info guid hob\n"));\r
395\r
396 //\r
397 // Create guid hob for acpi board information\r
398 //\r
399 Status = CbParseFadtInfo (&PmCtrlRegBase, &PmTimerRegBase, &ResetRegAddress, &ResetValue, &PmEvtBase, &PmGpeEnBase);\r
400 ASSERT_EFI_ERROR (Status);\r
401 pAcpiBoardInfo = NULL;\r
402 pAcpiBoardInfo = BuildGuidHob (&gUefiAcpiBoardInfoGuid, sizeof (ACPI_BOARD_INFO));\r
403 ASSERT (pAcpiBoardInfo != NULL);\r
404 pAcpiBoardInfo->PmCtrlRegBase = (UINT64)PmCtrlRegBase;\r
405 pAcpiBoardInfo->PmTimerRegBase = (UINT64)PmTimerRegBase;\r
406 pAcpiBoardInfo->ResetRegAddress = (UINT64)ResetRegAddress;\r
407 pAcpiBoardInfo->ResetValue = (UINT8)ResetValue;\r
408 pAcpiBoardInfo->PmEvtBase = (UINT64)PmEvtBase;\r
409 pAcpiBoardInfo->PmGpeEnBase = (UINT64)PmGpeEnBase;\r
410 DEBUG ((EFI_D_ERROR, "Create acpi board info guid hob\n"));\r
411\r
412 //\r
413 // Create guid hob for frame buffer information\r
414 //\r
415 ZeroMem (&FbInfo, sizeof (FRAME_BUFFER_INFO));\r
416 Status = CbParseFbInfo (&FbInfo);\r
417 if (!EFI_ERROR (Status)) {\r
418 pFbInfo = BuildGuidHob (&gUefiFrameBufferInfoGuid, sizeof (FRAME_BUFFER_INFO));\r
419 ASSERT (pSystemTableInfo != NULL);\r
420 CopyMem (pFbInfo, &FbInfo, sizeof (FRAME_BUFFER_INFO));\r
421 DEBUG ((EFI_D_ERROR, "Create frame buffer info guid hob\n"));\r
422 }\r
423\r
424 //\r
425 // Parse platform specific information from coreboot. \r
426 //\r
427 Status = CbParsePlatformInfo ();\r
428 if (EFI_ERROR (Status)) {\r
429 DEBUG ((EFI_D_ERROR, "Error when parsing platform info, Status = %r\n", Status));\r
430 return Status;\r
431 }\r
432\r
433 //\r
434 // Mask off all legacy 8259 interrupt sources\r
435 //\r
436 IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, 0xFF);\r
437 IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, 0xFF);\r
438\r
439 return EFI_SUCCESS;\r
440}\r
441\r