]> git.proxmox.com Git - mirror_edk2.git/blame - CorebootModulePkg/CbSupportPei/CbSupportPei.c
BeagleBoardPkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / CorebootModulePkg / CbSupportPei / CbSupportPei.c
CommitLineData
fce4ecd9 1/** @file\r
5930f541 2 This PEIM will parse coreboot table in memory and report resource information into pei core.\r
fce4ecd9 3 This file contains the main entrypoint of the PEIM.\r
5930f541 4\r
29845447 5Copyright (c) 2014 - 2016, 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 20EFI_MEMORY_TYPE_INFORMATION mDefaultMemoryTypeInformation[] = {\r
29845447
MM
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
fce4ecd9
MM
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
5930f541
MM
38 Create memory mapped io resource hob.\r
39\r
fce4ecd9
MM
40 @param MmioBase Base address of the memory mapped io range\r
41 @param MmioSize Length of the memory mapped io range\r
5930f541 42\r
fce4ecd9
MM
43**/\r
44VOID\r
45BuildMemoryMappedIoRangeHob (\r
46 EFI_PHYSICAL_ADDRESS MmioBase,\r
47 UINT64 MmioSize\r
48 )\r
49{\r
5930f541 50 BuildResourceDescriptorHob (\r
fce4ecd9
MM
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
5930f541 59\r
fce4ecd9
MM
60 BuildMemoryAllocationHob (\r
61 MmioBase,\r
62 MmioSize,\r
63 EfiMemoryMappedIO\r
5930f541 64 );\r
fce4ecd9
MM
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
5930f541
MM
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
fce4ecd9
MM
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
5930f541 105 return TRUE;\r
fce4ecd9
MM
106}\r
107\r
108/**\r
109 Install FvInfo PPI and create fv hobs for remained fvs\r
5930f541 110\r
fce4ecd9
MM
111**/\r
112VOID\r
113CbPeiReportRemainedFvs (\r
114 VOID\r
115 )\r
116{\r
5930f541
MM
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
fce4ecd9
MM
141}\r
142\r
2d90b74d 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
4e7872d2
MM
172 if ((Base < 0x100000) && ((Base + Size) > 0x100000)) {\r
173 Size -= (0x100000 - Base);\r
174 Base = 0x100000;\r
175 }\r
176\r
2d90b74d 177 MemInfo = (CB_MEM_INFO *)Param;\r
178 if (Base >= 0x100000) {\r
179 if (Type == CB_MEM_RAM) {\r
180 if (Base < 0x100000000ULL) {\r
181 MemInfo->UsableLowMemTop = (UINT32)(Base + Size);\r
182 } else {\r
183 Attribue &= ~EFI_RESOURCE_ATTRIBUTE_TESTED;\r
184 }\r
185 BuildResourceDescriptorHob (\r
186 EFI_RESOURCE_SYSTEM_MEMORY,\r
187 Attribue,\r
188 (EFI_PHYSICAL_ADDRESS)Base,\r
189 Size\r
190 );\r
191 } else if (Type == CB_MEM_TABLE) {\r
192 BuildResourceDescriptorHob (\r
193 EFI_RESOURCE_MEMORY_RESERVED,\r
194 Attribue,\r
195 (EFI_PHYSICAL_ADDRESS)Base,\r
196 Size\r
197 );\r
198 MemInfo->SystemLowMemTop = ((UINT32)(Base + Size) + 0x0FFFFFFF) & 0xF0000000;\r
199 } else if (Type == CB_MEM_RESERVED) {\r
200 if ((MemInfo->SystemLowMemTop == 0) || (Base < MemInfo->SystemLowMemTop)) {\r
201 BuildResourceDescriptorHob (\r
202 EFI_RESOURCE_MEMORY_RESERVED,\r
203 Attribue,\r
204 (EFI_PHYSICAL_ADDRESS)Base,\r
205 Size\r
206 ); \r
207 }\r
208 }\r
209 }\r
210 \r
211 return EFI_SUCCESS;\r
212}\r
213\r
fce4ecd9
MM
214/**\r
215 This is the entrypoint of PEIM\r
5930f541 216\r
fce4ecd9
MM
217 @param FileHandle Handle of the file being invoked.\r
218 @param PeiServices Describes the list of possible PEI Services.\r
219\r
5930f541 220 @retval EFI_SUCCESS if it completed successfully.\r
fce4ecd9
MM
221**/\r
222EFI_STATUS\r
223EFIAPI\r
224CbPeiEntryPoint (\r
225 IN EFI_PEI_FILE_HANDLE FileHandle,\r
226 IN CONST EFI_PEI_SERVICES **PeiServices\r
227 )\r
228{\r
2d90b74d 229 EFI_STATUS Status;\r
230 UINT64 LowMemorySize;\r
231 UINT64 PeiMemSize = SIZE_64MB; // 64 MB\r
5930f541
MM
232 EFI_PHYSICAL_ADDRESS PeiMemBase = 0;\r
233 UINT32 RegEax;\r
fce4ecd9
MM
234 UINT8 PhysicalAddressBits;\r
235 VOID* pCbHeader;\r
236 VOID* pAcpiTable;\r
5930f541
MM
237 UINT32 AcpiTableSize;\r
238 VOID* pSmbiosTable;\r
239 UINT32 SmbiosTableSize;\r
240 SYSTEM_TABLE_INFO* pSystemTableInfo;\r
241 FRAME_BUFFER_INFO FbInfo;\r
242 FRAME_BUFFER_INFO* pFbInfo;\r
243 ACPI_BOARD_INFO* pAcpiBoardInfo;\r
244 UINTN PmCtrlRegBase, PmTimerRegBase, ResetRegAddress, ResetValue;\r
cb3e201f
GD
245 UINTN PmEvtBase;\r
246 UINTN PmGpeEnBase;\r
2d90b74d 247 CB_MEM_INFO CbMemInfo;\r
5930f541 248\r
1d7258fa
SD
249 //\r
250 // Report lower 640KB of RAM. Attribute EFI_RESOURCE_ATTRIBUTE_TESTED \r
2d90b74d 251 // is intentionally omitted to prevent erasing of the coreboot header \r
252 // record before it is processed by CbParseMemoryInfo.\r
1d7258fa 253 //\r
5930f541 254 BuildResourceDescriptorHob (\r
fce4ecd9
MM
255 EFI_RESOURCE_SYSTEM_MEMORY,\r
256 (\r
257 EFI_RESOURCE_ATTRIBUTE_PRESENT |\r
258 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |\r
fce4ecd9
MM
259 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |\r
260 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |\r
261 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |\r
262 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE\r
263 ),\r
264 (EFI_PHYSICAL_ADDRESS)(0),\r
265 (UINT64)(0xA0000)\r
266 );\r
5930f541
MM
267\r
268\r
269 BuildResourceDescriptorHob (\r
fce4ecd9
MM
270 EFI_RESOURCE_MEMORY_RESERVED,\r
271 (\r
272 EFI_RESOURCE_ATTRIBUTE_PRESENT |\r
273 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |\r
274 EFI_RESOURCE_ATTRIBUTE_TESTED |\r
275 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |\r
276 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |\r
277 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |\r
278 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE\r
279 ),\r
280 (EFI_PHYSICAL_ADDRESS)(0xA0000),\r
281 (UINT64)(0x60000)\r
282 );\r
5930f541 283\r
2d90b74d 284 ZeroMem (&CbMemInfo, sizeof(CbMemInfo));\r
285 Status = CbParseMemoryInfo (CbMemInfoCallback, (VOID *)&CbMemInfo);\r
286 if (EFI_ERROR(Status)) {\r
287 return Status;\r
5930f541
MM
288 }\r
289\r
2d90b74d 290 LowMemorySize = CbMemInfo.UsableLowMemTop;\r
291 DEBUG ((EFI_D_INFO, "Low memory 0x%lx\n", LowMemorySize));\r
292 DEBUG ((EFI_D_INFO, "SystemLowMemTop 0x%x\n", CbMemInfo.SystemLowMemTop));\r
293\r
5930f541
MM
294 //\r
295 // Should be 64k aligned\r
296 //\r
297 PeiMemBase = (LowMemorySize - PeiMemSize) & (~(BASE_64KB - 1));\r
298\r
299 DEBUG((EFI_D_ERROR, "PeiMemBase: 0x%lx.\n", PeiMemBase));\r
300 DEBUG((EFI_D_ERROR, "PeiMemSize: 0x%lx.\n", PeiMemSize));\r
301\r
302 Status = PeiServicesInstallPeiMemory (\r
303 PeiMemBase,\r
304 PeiMemSize\r
305 );\r
306 ASSERT_EFI_ERROR (Status);\r
307\r
308 //\r
309 // Set cache on the physical memory\r
310 //\r
311 MtrrSetMemoryAttribute (BASE_1MB, LowMemorySize - BASE_1MB, CacheWriteBack);\r
fce4ecd9 312 MtrrSetMemoryAttribute (0, 0xA0000, CacheWriteBack);\r
5930f541
MM
313\r
314 //\r
fce4ecd9
MM
315 // Create Memory Type Information HOB\r
316 //\r
317 BuildGuidDataHob (\r
318 &gEfiMemoryTypeInformationGuid,\r
319 mDefaultMemoryTypeInformation,\r
320 sizeof(mDefaultMemoryTypeInformation)\r
321 );\r
5930f541
MM
322\r
323 //\r
324 // Create Fv hob\r
325 //\r
326 CbPeiReportRemainedFvs ();\r
327\r
328 BuildMemoryAllocationHob (\r
fce4ecd9
MM
329 PcdGet32 (PcdPayloadFdMemBase),\r
330 PcdGet32 (PcdPayloadFdMemSize),\r
331 EfiBootServicesData\r
332 );\r
5930f541 333\r
fce4ecd9
MM
334 //\r
335 // Build CPU memory space and IO space hob\r
336 //\r
337 AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);\r
338 if (RegEax >= 0x80000008) {\r
5930f541 339 AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);\r
fce4ecd9
MM
340 PhysicalAddressBits = (UINT8) RegEax;\r
341 } else {\r
342 PhysicalAddressBits = 36;\r
343 }\r
344 //\r
345 // Create a CPU hand-off information\r
5930f541 346 //\r
fce4ecd9 347 BuildCpuHob (PhysicalAddressBits, 16);\r
5930f541 348\r
fce4ecd9
MM
349 //\r
350 // Report Local APIC range\r
351 //\r
352 BuildMemoryMappedIoRangeHob (0xFEC80000, SIZE_512KB);\r
5930f541
MM
353\r
354 //\r
355 // Boot mode\r
356 //\r
357 Status = PeiServicesSetBootMode (BOOT_WITH_FULL_CONFIGURATION);\r
fce4ecd9 358 ASSERT_EFI_ERROR (Status);\r
5930f541 359\r
fce4ecd9
MM
360 Status = PeiServicesInstallPpi (mPpiBootMode);\r
361 ASSERT_EFI_ERROR (Status);\r
5930f541 362\r
fce4ecd9
MM
363 //\r
364 // Set pcd to save the upper coreboot header in case the dxecore will\r
365 // erase 0~4k memory\r
366 //\r
367 pCbHeader = NULL;\r
5930f541
MM
368 if ((CbParseGetCbHeader (1, &pCbHeader) == RETURN_SUCCESS)\r
369 && ((UINTN)pCbHeader > BASE_4KB)) {\r
370 DEBUG((EFI_D_ERROR, "Actual Coreboot header: %p.\n", pCbHeader));\r
3f0edb77
MM
371 Status = PcdSet32S (PcdCbHeaderPointer, (UINT32)(UINTN)pCbHeader);\r
372 ASSERT_EFI_ERROR (Status);\r
fce4ecd9 373 }\r
5930f541 374\r
fce4ecd9
MM
375 //\r
376 // Create guid hob for system tables like acpi table and smbios table\r
377 //\r
378 pAcpiTable = NULL;\r
379 AcpiTableSize = 0;\r
380 pSmbiosTable = NULL;\r
381 SmbiosTableSize = 0;\r
382 Status = CbParseAcpiTable (&pAcpiTable, &AcpiTableSize);\r
383 if (EFI_ERROR (Status)) {\r
5930f541
MM
384 // ACPI table is oblidgible\r
385 DEBUG ((EFI_D_ERROR, "Failed to find the required acpi table\n"));\r
386 ASSERT (FALSE);\r
fce4ecd9
MM
387 }\r
388 CbParseSmbiosTable (&pSmbiosTable, &SmbiosTableSize);\r
5930f541
MM
389\r
390 pSystemTableInfo = NULL;\r
391 pSystemTableInfo = BuildGuidHob (&gUefiSystemTableInfoGuid, sizeof (SYSTEM_TABLE_INFO));\r
392 ASSERT (pSystemTableInfo != NULL);\r
393 pSystemTableInfo->AcpiTableBase = (UINT64) (UINTN)pAcpiTable;\r
394 pSystemTableInfo->AcpiTableSize = AcpiTableSize;\r
395 pSystemTableInfo->SmbiosTableBase = (UINT64) (UINTN)pSmbiosTable;\r
396 pSystemTableInfo->SmbiosTableSize = SmbiosTableSize;\r
397 DEBUG ((EFI_D_ERROR, "Detected Acpi Table at 0x%lx, length 0x%x\n", pSystemTableInfo->AcpiTableBase, pSystemTableInfo->AcpiTableSize));\r
398 DEBUG ((EFI_D_ERROR, "Detected Smbios Table at 0x%lx, length 0x%x\n", pSystemTableInfo->SmbiosTableBase, pSystemTableInfo->SmbiosTableSize));\r
399 DEBUG ((EFI_D_ERROR, "Create system table info guid hob\n"));\r
400\r
401 //\r
402 // Create guid hob for acpi board information\r
403 //\r
cb3e201f 404 Status = CbParseFadtInfo (&PmCtrlRegBase, &PmTimerRegBase, &ResetRegAddress, &ResetValue, &PmEvtBase, &PmGpeEnBase);\r
5930f541
MM
405 ASSERT_EFI_ERROR (Status);\r
406 pAcpiBoardInfo = NULL;\r
407 pAcpiBoardInfo = BuildGuidHob (&gUefiAcpiBoardInfoGuid, sizeof (ACPI_BOARD_INFO));\r
408 ASSERT (pAcpiBoardInfo != NULL);\r
409 pAcpiBoardInfo->PmCtrlRegBase = (UINT64)PmCtrlRegBase;\r
410 pAcpiBoardInfo->PmTimerRegBase = (UINT64)PmTimerRegBase;\r
411 pAcpiBoardInfo->ResetRegAddress = (UINT64)ResetRegAddress;\r
412 pAcpiBoardInfo->ResetValue = (UINT8)ResetValue;\r
cb3e201f
GD
413 pAcpiBoardInfo->PmEvtBase = (UINT64)PmEvtBase;\r
414 pAcpiBoardInfo->PmGpeEnBase = (UINT64)PmGpeEnBase;\r
5930f541
MM
415 DEBUG ((EFI_D_ERROR, "Create acpi board info guid hob\n"));\r
416\r
417 //\r
418 // Create guid hob for frame buffer information\r
419 //\r
420 ZeroMem (&FbInfo, sizeof (FRAME_BUFFER_INFO));\r
421 Status = CbParseFbInfo (&FbInfo);\r
422 if (!EFI_ERROR (Status)) {\r
423 pFbInfo = BuildGuidHob (&gUefiFrameBufferInfoGuid, sizeof (FRAME_BUFFER_INFO));\r
424 ASSERT (pSystemTableInfo != NULL);\r
425 CopyMem (pFbInfo, &FbInfo, sizeof (FRAME_BUFFER_INFO));\r
426 DEBUG ((EFI_D_ERROR, "Create frame buffer info guid hob\n"));\r
427 }\r
7b7fc3e7 428\r
2f20bfd9 429 //\r
430 // Parse platform specific information from coreboot. \r
431 //\r
432 Status = CbParsePlatformInfo ();\r
433 if (EFI_ERROR (Status)) {\r
434 DEBUG ((EFI_D_ERROR, "Error when parsing platform info, Status = %r\n", Status));\r
435 return Status;\r
436 }\r
437\r
7b7fc3e7
MM
438 //\r
439 // Mask off all legacy 8259 interrupt sources\r
440 //\r
441 IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, 0xFF);\r
442 IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, 0xFF);\r
443\r
fce4ecd9
MM
444 return EFI_SUCCESS;\r
445}\r
446\r