]> git.proxmox.com Git - mirror_edk2.git/blame - CorebootModulePkg/CbSupportPei/CbSupportPei.c
CorebootModulePkg: 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
f3342b7a 6SPDX-License-Identifier: BSD-2-Clause-Patent\r
fce4ecd9
MM
7\r
8**/\r
9#include "CbSupportPei.h"\r
10\r
7b7fc3e7
MM
11#define LEGACY_8259_MASK_REGISTER_MASTER 0x21\r
12#define LEGACY_8259_MASK_REGISTER_SLAVE 0xA1\r
13\r
fce4ecd9 14EFI_MEMORY_TYPE_INFORMATION mDefaultMemoryTypeInformation[] = {\r
29845447
MM
15 { EfiACPIReclaimMemory, FixedPcdGet32 (PcdMemoryTypeEfiACPIReclaimMemory) },\r
16 { EfiACPIMemoryNVS, FixedPcdGet32 (PcdMemoryTypeEfiACPIMemoryNVS) },\r
17 { EfiReservedMemoryType, FixedPcdGet32 (PcdMemoryTypeEfiReservedMemoryType) },\r
18 { EfiRuntimeServicesData, FixedPcdGet32 (PcdMemoryTypeEfiRuntimeServicesData) },\r
19 { EfiRuntimeServicesCode, FixedPcdGet32 (PcdMemoryTypeEfiRuntimeServicesCode) },\r
fce4ecd9
MM
20 { EfiMaxMemoryType, 0 }\r
21};\r
22\r
23EFI_PEI_PPI_DESCRIPTOR mPpiBootMode[] = {\r
24 {\r
25 EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,\r
26 &gEfiPeiMasterBootModePpiGuid,\r
27 NULL\r
28 }\r
29};\r
30\r
31/**\r
5930f541
MM
32 Create memory mapped io resource hob.\r
33\r
fce4ecd9
MM
34 @param MmioBase Base address of the memory mapped io range\r
35 @param MmioSize Length of the memory mapped io range\r
5930f541 36\r
fce4ecd9
MM
37**/\r
38VOID\r
39BuildMemoryMappedIoRangeHob (\r
40 EFI_PHYSICAL_ADDRESS MmioBase,\r
41 UINT64 MmioSize\r
42 )\r
43{\r
5930f541 44 BuildResourceDescriptorHob (\r
fce4ecd9
MM
45 EFI_RESOURCE_MEMORY_MAPPED_IO,\r
46 (EFI_RESOURCE_ATTRIBUTE_PRESENT |\r
47 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |\r
48 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |\r
49 EFI_RESOURCE_ATTRIBUTE_TESTED),\r
50 MmioBase,\r
51 MmioSize\r
52 );\r
5930f541 53\r
fce4ecd9
MM
54 BuildMemoryAllocationHob (\r
55 MmioBase,\r
56 MmioSize,\r
57 EfiMemoryMappedIO\r
5930f541 58 );\r
fce4ecd9
MM
59}\r
60\r
61/**\r
62 Check the integrity of firmware volume header\r
63\r
64 @param[in] FwVolHeader A pointer to a firmware volume header\r
65\r
66 @retval TRUE The firmware volume is consistent\r
67 @retval FALSE The firmware volume has corrupted.\r
68\r
69**/\r
70STATIC\r
71BOOLEAN\r
72IsFvHeaderValid (\r
73 IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader\r
74 )\r
75{\r
5930f541
MM
76 UINT16 Checksum;\r
77\r
78 // Skip nv storage fv\r
79 if (CompareMem (&FwVolHeader->FileSystemGuid, &gEfiFirmwareFileSystem2Guid, sizeof(EFI_GUID)) != 0 ) {\r
80 return FALSE;\r
81 }\r
82\r
83 if ( (FwVolHeader->Revision != EFI_FVH_REVISION) ||\r
84 (FwVolHeader->Signature != EFI_FVH_SIGNATURE) ||\r
85 (FwVolHeader->FvLength == ((UINTN) -1)) ||\r
86 ((FwVolHeader->HeaderLength & 0x01 ) !=0) ) {\r
87 return FALSE;\r
88 }\r
89\r
90 Checksum = CalculateCheckSum16 ((UINT16 *) FwVolHeader, FwVolHeader->HeaderLength);\r
fce4ecd9
MM
91 if (Checksum != 0) {\r
92 DEBUG (( DEBUG_ERROR,\r
93 "ERROR - Invalid Firmware Volume Header Checksum, change 0x%04x to 0x%04x\r\n",\r
94 FwVolHeader->Checksum,\r
95 (UINT16)( Checksum + FwVolHeader->Checksum )));\r
96 return FALSE;\r
97 }\r
98\r
5930f541 99 return TRUE;\r
fce4ecd9
MM
100}\r
101\r
102/**\r
103 Install FvInfo PPI and create fv hobs for remained fvs\r
5930f541 104\r
fce4ecd9
MM
105**/\r
106VOID\r
107CbPeiReportRemainedFvs (\r
108 VOID\r
109 )\r
110{\r
5930f541
MM
111 UINT8* TempPtr;\r
112 UINT8* EndPtr;\r
113\r
114 TempPtr = (UINT8* )(UINTN) PcdGet32 (PcdPayloadFdMemBase);\r
115 EndPtr = (UINT8* )(UINTN) (PcdGet32 (PcdPayloadFdMemBase) + PcdGet32 (PcdPayloadFdMemSize));\r
116\r
117 for (;TempPtr < EndPtr;) {\r
118 if (IsFvHeaderValid ((EFI_FIRMWARE_VOLUME_HEADER* )TempPtr)) {\r
119 if (TempPtr != (UINT8* )(UINTN) PcdGet32 (PcdPayloadFdMemBase)) {\r
120 // Skip the PEI FV\r
121 DEBUG((EFI_D_ERROR, "Found one valid fv : 0x%lx.\n", TempPtr, ((EFI_FIRMWARE_VOLUME_HEADER* )TempPtr)->FvLength));\r
122\r
123 PeiServicesInstallFvInfoPpi (\r
124 NULL,\r
125 (VOID *) (UINTN) TempPtr,\r
126 (UINT32) (UINTN) ((EFI_FIRMWARE_VOLUME_HEADER* )TempPtr)->FvLength,\r
127 NULL,\r
128 NULL\r
129 );\r
130 BuildFvHob ((EFI_PHYSICAL_ADDRESS)(UINTN) TempPtr, ((EFI_FIRMWARE_VOLUME_HEADER* )TempPtr)->FvLength);\r
131 }\r
132 }\r
133 TempPtr += ((EFI_FIRMWARE_VOLUME_HEADER* )TempPtr)->FvLength;\r
134 }\r
fce4ecd9
MM
135}\r
136\r
2d90b74d 137/**\r
138 Based on memory base, size and type, build resource descripter HOB.\r
139\r
140 @param Base Memory base address.\r
141 @param Size Memory size.\r
142 @param Type Memory type.\r
143 @param Param A pointer to CB_MEM_INFO.\r
144\r
145 @retval EFI_SUCCESS if it completed successfully.\r
146**/\r
147EFI_STATUS\r
148CbMemInfoCallback (\r
149 UINT64 Base,\r
150 UINT64 Size,\r
151 UINT32 Type,\r
152 VOID *Param\r
153 )\r
154{\r
155 CB_MEM_INFO *MemInfo;\r
156 UINTN Attribue;\r
157\r
158 Attribue = EFI_RESOURCE_ATTRIBUTE_PRESENT |\r
159 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |\r
160 EFI_RESOURCE_ATTRIBUTE_TESTED |\r
161 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |\r
162 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |\r
163 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |\r
164 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE;\r
165\r
4e7872d2
MM
166 if ((Base < 0x100000) && ((Base + Size) > 0x100000)) {\r
167 Size -= (0x100000 - Base);\r
168 Base = 0x100000;\r
169 }\r
170\r
2d90b74d 171 MemInfo = (CB_MEM_INFO *)Param;\r
172 if (Base >= 0x100000) {\r
173 if (Type == CB_MEM_RAM) {\r
174 if (Base < 0x100000000ULL) {\r
175 MemInfo->UsableLowMemTop = (UINT32)(Base + Size);\r
176 } else {\r
177 Attribue &= ~EFI_RESOURCE_ATTRIBUTE_TESTED;\r
178 }\r
179 BuildResourceDescriptorHob (\r
180 EFI_RESOURCE_SYSTEM_MEMORY,\r
181 Attribue,\r
182 (EFI_PHYSICAL_ADDRESS)Base,\r
183 Size\r
184 );\r
185 } else if (Type == CB_MEM_TABLE) {\r
186 BuildResourceDescriptorHob (\r
187 EFI_RESOURCE_MEMORY_RESERVED,\r
188 Attribue,\r
189 (EFI_PHYSICAL_ADDRESS)Base,\r
190 Size\r
191 );\r
192 MemInfo->SystemLowMemTop = ((UINT32)(Base + Size) + 0x0FFFFFFF) & 0xF0000000;\r
193 } else if (Type == CB_MEM_RESERVED) {\r
194 if ((MemInfo->SystemLowMemTop == 0) || (Base < MemInfo->SystemLowMemTop)) {\r
195 BuildResourceDescriptorHob (\r
196 EFI_RESOURCE_MEMORY_RESERVED,\r
197 Attribue,\r
198 (EFI_PHYSICAL_ADDRESS)Base,\r
199 Size\r
200 ); \r
201 }\r
202 }\r
203 }\r
204 \r
205 return EFI_SUCCESS;\r
206}\r
207\r
fce4ecd9
MM
208/**\r
209 This is the entrypoint of PEIM\r
5930f541 210\r
fce4ecd9
MM
211 @param FileHandle Handle of the file being invoked.\r
212 @param PeiServices Describes the list of possible PEI Services.\r
213\r
5930f541 214 @retval EFI_SUCCESS if it completed successfully.\r
fce4ecd9
MM
215**/\r
216EFI_STATUS\r
217EFIAPI\r
218CbPeiEntryPoint (\r
219 IN EFI_PEI_FILE_HANDLE FileHandle,\r
220 IN CONST EFI_PEI_SERVICES **PeiServices\r
221 )\r
222{\r
2d90b74d 223 EFI_STATUS Status;\r
224 UINT64 LowMemorySize;\r
225 UINT64 PeiMemSize = SIZE_64MB; // 64 MB\r
5930f541
MM
226 EFI_PHYSICAL_ADDRESS PeiMemBase = 0;\r
227 UINT32 RegEax;\r
fce4ecd9
MM
228 UINT8 PhysicalAddressBits;\r
229 VOID* pCbHeader;\r
230 VOID* pAcpiTable;\r
5930f541
MM
231 UINT32 AcpiTableSize;\r
232 VOID* pSmbiosTable;\r
233 UINT32 SmbiosTableSize;\r
234 SYSTEM_TABLE_INFO* pSystemTableInfo;\r
235 FRAME_BUFFER_INFO FbInfo;\r
236 FRAME_BUFFER_INFO* pFbInfo;\r
237 ACPI_BOARD_INFO* pAcpiBoardInfo;\r
238 UINTN PmCtrlRegBase, PmTimerRegBase, ResetRegAddress, ResetValue;\r
cb3e201f
GD
239 UINTN PmEvtBase;\r
240 UINTN PmGpeEnBase;\r
2d90b74d 241 CB_MEM_INFO CbMemInfo;\r
5930f541 242\r
1d7258fa
SD
243 //\r
244 // Report lower 640KB of RAM. Attribute EFI_RESOURCE_ATTRIBUTE_TESTED \r
2d90b74d 245 // is intentionally omitted to prevent erasing of the coreboot header \r
246 // record before it is processed by CbParseMemoryInfo.\r
1d7258fa 247 //\r
5930f541 248 BuildResourceDescriptorHob (\r
fce4ecd9
MM
249 EFI_RESOURCE_SYSTEM_MEMORY,\r
250 (\r
251 EFI_RESOURCE_ATTRIBUTE_PRESENT |\r
252 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |\r
fce4ecd9
MM
253 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |\r
254 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |\r
255 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |\r
256 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE\r
257 ),\r
258 (EFI_PHYSICAL_ADDRESS)(0),\r
259 (UINT64)(0xA0000)\r
260 );\r
5930f541
MM
261\r
262\r
263 BuildResourceDescriptorHob (\r
fce4ecd9
MM
264 EFI_RESOURCE_MEMORY_RESERVED,\r
265 (\r
266 EFI_RESOURCE_ATTRIBUTE_PRESENT |\r
267 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |\r
268 EFI_RESOURCE_ATTRIBUTE_TESTED |\r
269 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |\r
270 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |\r
271 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |\r
272 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE\r
273 ),\r
274 (EFI_PHYSICAL_ADDRESS)(0xA0000),\r
275 (UINT64)(0x60000)\r
276 );\r
5930f541 277\r
2d90b74d 278 ZeroMem (&CbMemInfo, sizeof(CbMemInfo));\r
279 Status = CbParseMemoryInfo (CbMemInfoCallback, (VOID *)&CbMemInfo);\r
280 if (EFI_ERROR(Status)) {\r
281 return Status;\r
5930f541
MM
282 }\r
283\r
2d90b74d 284 LowMemorySize = CbMemInfo.UsableLowMemTop;\r
285 DEBUG ((EFI_D_INFO, "Low memory 0x%lx\n", LowMemorySize));\r
286 DEBUG ((EFI_D_INFO, "SystemLowMemTop 0x%x\n", CbMemInfo.SystemLowMemTop));\r
287\r
5930f541
MM
288 //\r
289 // Should be 64k aligned\r
290 //\r
291 PeiMemBase = (LowMemorySize - PeiMemSize) & (~(BASE_64KB - 1));\r
292\r
293 DEBUG((EFI_D_ERROR, "PeiMemBase: 0x%lx.\n", PeiMemBase));\r
294 DEBUG((EFI_D_ERROR, "PeiMemSize: 0x%lx.\n", PeiMemSize));\r
295\r
296 Status = PeiServicesInstallPeiMemory (\r
297 PeiMemBase,\r
298 PeiMemSize\r
299 );\r
300 ASSERT_EFI_ERROR (Status);\r
301\r
302 //\r
303 // Set cache on the physical memory\r
304 //\r
305 MtrrSetMemoryAttribute (BASE_1MB, LowMemorySize - BASE_1MB, CacheWriteBack);\r
fce4ecd9 306 MtrrSetMemoryAttribute (0, 0xA0000, CacheWriteBack);\r
5930f541
MM
307\r
308 //\r
fce4ecd9
MM
309 // Create Memory Type Information HOB\r
310 //\r
311 BuildGuidDataHob (\r
312 &gEfiMemoryTypeInformationGuid,\r
313 mDefaultMemoryTypeInformation,\r
314 sizeof(mDefaultMemoryTypeInformation)\r
315 );\r
5930f541
MM
316\r
317 //\r
318 // Create Fv hob\r
319 //\r
320 CbPeiReportRemainedFvs ();\r
321\r
322 BuildMemoryAllocationHob (\r
fce4ecd9
MM
323 PcdGet32 (PcdPayloadFdMemBase),\r
324 PcdGet32 (PcdPayloadFdMemSize),\r
325 EfiBootServicesData\r
326 );\r
5930f541 327\r
fce4ecd9
MM
328 //\r
329 // Build CPU memory space and IO space hob\r
330 //\r
331 AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);\r
332 if (RegEax >= 0x80000008) {\r
5930f541 333 AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);\r
fce4ecd9
MM
334 PhysicalAddressBits = (UINT8) RegEax;\r
335 } else {\r
336 PhysicalAddressBits = 36;\r
337 }\r
338 //\r
339 // Create a CPU hand-off information\r
5930f541 340 //\r
fce4ecd9 341 BuildCpuHob (PhysicalAddressBits, 16);\r
5930f541 342\r
fce4ecd9
MM
343 //\r
344 // Report Local APIC range\r
345 //\r
346 BuildMemoryMappedIoRangeHob (0xFEC80000, SIZE_512KB);\r
5930f541
MM
347\r
348 //\r
349 // Boot mode\r
350 //\r
351 Status = PeiServicesSetBootMode (BOOT_WITH_FULL_CONFIGURATION);\r
fce4ecd9 352 ASSERT_EFI_ERROR (Status);\r
5930f541 353\r
fce4ecd9
MM
354 Status = PeiServicesInstallPpi (mPpiBootMode);\r
355 ASSERT_EFI_ERROR (Status);\r
5930f541 356\r
fce4ecd9
MM
357 //\r
358 // Set pcd to save the upper coreboot header in case the dxecore will\r
359 // erase 0~4k memory\r
360 //\r
361 pCbHeader = NULL;\r
5930f541
MM
362 if ((CbParseGetCbHeader (1, &pCbHeader) == RETURN_SUCCESS)\r
363 && ((UINTN)pCbHeader > BASE_4KB)) {\r
364 DEBUG((EFI_D_ERROR, "Actual Coreboot header: %p.\n", pCbHeader));\r
3f0edb77
MM
365 Status = PcdSet32S (PcdCbHeaderPointer, (UINT32)(UINTN)pCbHeader);\r
366 ASSERT_EFI_ERROR (Status);\r
fce4ecd9 367 }\r
5930f541 368\r
fce4ecd9
MM
369 //\r
370 // Create guid hob for system tables like acpi table and smbios table\r
371 //\r
372 pAcpiTable = NULL;\r
373 AcpiTableSize = 0;\r
374 pSmbiosTable = NULL;\r
375 SmbiosTableSize = 0;\r
376 Status = CbParseAcpiTable (&pAcpiTable, &AcpiTableSize);\r
377 if (EFI_ERROR (Status)) {\r
5930f541
MM
378 // ACPI table is oblidgible\r
379 DEBUG ((EFI_D_ERROR, "Failed to find the required acpi table\n"));\r
380 ASSERT (FALSE);\r
fce4ecd9
MM
381 }\r
382 CbParseSmbiosTable (&pSmbiosTable, &SmbiosTableSize);\r
5930f541
MM
383\r
384 pSystemTableInfo = NULL;\r
385 pSystemTableInfo = BuildGuidHob (&gUefiSystemTableInfoGuid, sizeof (SYSTEM_TABLE_INFO));\r
386 ASSERT (pSystemTableInfo != NULL);\r
387 pSystemTableInfo->AcpiTableBase = (UINT64) (UINTN)pAcpiTable;\r
388 pSystemTableInfo->AcpiTableSize = AcpiTableSize;\r
389 pSystemTableInfo->SmbiosTableBase = (UINT64) (UINTN)pSmbiosTable;\r
390 pSystemTableInfo->SmbiosTableSize = SmbiosTableSize;\r
391 DEBUG ((EFI_D_ERROR, "Detected Acpi Table at 0x%lx, length 0x%x\n", pSystemTableInfo->AcpiTableBase, pSystemTableInfo->AcpiTableSize));\r
392 DEBUG ((EFI_D_ERROR, "Detected Smbios Table at 0x%lx, length 0x%x\n", pSystemTableInfo->SmbiosTableBase, pSystemTableInfo->SmbiosTableSize));\r
393 DEBUG ((EFI_D_ERROR, "Create system table info guid hob\n"));\r
394\r
395 //\r
396 // Create guid hob for acpi board information\r
397 //\r
cb3e201f 398 Status = CbParseFadtInfo (&PmCtrlRegBase, &PmTimerRegBase, &ResetRegAddress, &ResetValue, &PmEvtBase, &PmGpeEnBase);\r
5930f541
MM
399 ASSERT_EFI_ERROR (Status);\r
400 pAcpiBoardInfo = NULL;\r
401 pAcpiBoardInfo = BuildGuidHob (&gUefiAcpiBoardInfoGuid, sizeof (ACPI_BOARD_INFO));\r
402 ASSERT (pAcpiBoardInfo != NULL);\r
403 pAcpiBoardInfo->PmCtrlRegBase = (UINT64)PmCtrlRegBase;\r
404 pAcpiBoardInfo->PmTimerRegBase = (UINT64)PmTimerRegBase;\r
405 pAcpiBoardInfo->ResetRegAddress = (UINT64)ResetRegAddress;\r
406 pAcpiBoardInfo->ResetValue = (UINT8)ResetValue;\r
cb3e201f
GD
407 pAcpiBoardInfo->PmEvtBase = (UINT64)PmEvtBase;\r
408 pAcpiBoardInfo->PmGpeEnBase = (UINT64)PmGpeEnBase;\r
5930f541
MM
409 DEBUG ((EFI_D_ERROR, "Create acpi board info guid hob\n"));\r
410\r
411 //\r
412 // Create guid hob for frame buffer information\r
413 //\r
414 ZeroMem (&FbInfo, sizeof (FRAME_BUFFER_INFO));\r
415 Status = CbParseFbInfo (&FbInfo);\r
416 if (!EFI_ERROR (Status)) {\r
417 pFbInfo = BuildGuidHob (&gUefiFrameBufferInfoGuid, sizeof (FRAME_BUFFER_INFO));\r
418 ASSERT (pSystemTableInfo != NULL);\r
419 CopyMem (pFbInfo, &FbInfo, sizeof (FRAME_BUFFER_INFO));\r
420 DEBUG ((EFI_D_ERROR, "Create frame buffer info guid hob\n"));\r
421 }\r
7b7fc3e7 422\r
2f20bfd9 423 //\r
424 // Parse platform specific information from coreboot. \r
425 //\r
426 Status = CbParsePlatformInfo ();\r
427 if (EFI_ERROR (Status)) {\r
428 DEBUG ((EFI_D_ERROR, "Error when parsing platform info, Status = %r\n", Status));\r
429 return Status;\r
430 }\r
431\r
7b7fc3e7
MM
432 //\r
433 // Mask off all legacy 8259 interrupt sources\r
434 //\r
435 IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, 0xFF);\r
436 IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, 0xFF);\r
437\r
fce4ecd9
MM
438 return EFI_SUCCESS;\r
439}\r
440\r