]> git.proxmox.com Git - mirror_edk2.git/blame - CorebootModulePkg/CbSupportPei/CbSupportPei.c
QuarkSocPkg/Library: Remove extra UefiBaseType.h includes
[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
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
fce4ecd9
MM
209/**\r
210 This is the entrypoint of PEIM\r
5930f541 211\r
fce4ecd9
MM
212 @param FileHandle Handle of the file being invoked.\r
213 @param PeiServices Describes the list of possible PEI Services.\r
214\r
5930f541 215 @retval EFI_SUCCESS if it completed successfully.\r
fce4ecd9
MM
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
2d90b74d 224 EFI_STATUS Status;\r
225 UINT64 LowMemorySize;\r
226 UINT64 PeiMemSize = SIZE_64MB; // 64 MB\r
5930f541
MM
227 EFI_PHYSICAL_ADDRESS PeiMemBase = 0;\r
228 UINT32 RegEax;\r
fce4ecd9
MM
229 UINT8 PhysicalAddressBits;\r
230 VOID* pCbHeader;\r
231 VOID* pAcpiTable;\r
5930f541
MM
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
cb3e201f
GD
240 UINTN PmEvtBase;\r
241 UINTN PmGpeEnBase;\r
2d90b74d 242 CB_MEM_INFO CbMemInfo;\r
5930f541 243\r
1d7258fa
SD
244 //\r
245 // Report lower 640KB of RAM. Attribute EFI_RESOURCE_ATTRIBUTE_TESTED \r
2d90b74d 246 // is intentionally omitted to prevent erasing of the coreboot header \r
247 // record before it is processed by CbParseMemoryInfo.\r
1d7258fa 248 //\r
5930f541 249 BuildResourceDescriptorHob (\r
fce4ecd9
MM
250 EFI_RESOURCE_SYSTEM_MEMORY,\r
251 (\r
252 EFI_RESOURCE_ATTRIBUTE_PRESENT |\r
253 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |\r
fce4ecd9
MM
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
5930f541
MM
262\r
263\r
264 BuildResourceDescriptorHob (\r
fce4ecd9
MM
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
5930f541 278\r
2d90b74d 279 ZeroMem (&CbMemInfo, sizeof(CbMemInfo));\r
280 Status = CbParseMemoryInfo (CbMemInfoCallback, (VOID *)&CbMemInfo);\r
281 if (EFI_ERROR(Status)) {\r
282 return Status;\r
5930f541
MM
283 }\r
284\r
2d90b74d 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
5930f541
MM
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
fce4ecd9 307 MtrrSetMemoryAttribute (0, 0xA0000, CacheWriteBack);\r
5930f541
MM
308\r
309 //\r
fce4ecd9
MM
310 // Create Memory Type Information HOB\r
311 //\r
312 BuildGuidDataHob (\r
313 &gEfiMemoryTypeInformationGuid,\r
314 mDefaultMemoryTypeInformation,\r
315 sizeof(mDefaultMemoryTypeInformation)\r
316 );\r
5930f541
MM
317\r
318 //\r
319 // Create Fv hob\r
320 //\r
321 CbPeiReportRemainedFvs ();\r
322\r
323 BuildMemoryAllocationHob (\r
fce4ecd9
MM
324 PcdGet32 (PcdPayloadFdMemBase),\r
325 PcdGet32 (PcdPayloadFdMemSize),\r
326 EfiBootServicesData\r
327 );\r
5930f541 328\r
fce4ecd9
MM
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
5930f541 334 AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);\r
fce4ecd9
MM
335 PhysicalAddressBits = (UINT8) RegEax;\r
336 } else {\r
337 PhysicalAddressBits = 36;\r
338 }\r
339 //\r
340 // Create a CPU hand-off information\r
5930f541 341 //\r
fce4ecd9 342 BuildCpuHob (PhysicalAddressBits, 16);\r
5930f541 343\r
fce4ecd9
MM
344 //\r
345 // Report Local APIC range\r
346 //\r
347 BuildMemoryMappedIoRangeHob (0xFEC80000, SIZE_512KB);\r
5930f541
MM
348\r
349 //\r
350 // Boot mode\r
351 //\r
352 Status = PeiServicesSetBootMode (BOOT_WITH_FULL_CONFIGURATION);\r
fce4ecd9 353 ASSERT_EFI_ERROR (Status);\r
5930f541 354\r
fce4ecd9
MM
355 Status = PeiServicesInstallPpi (mPpiBootMode);\r
356 ASSERT_EFI_ERROR (Status);\r
5930f541 357\r
fce4ecd9
MM
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
5930f541
MM
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
3f0edb77
MM
366 Status = PcdSet32S (PcdCbHeaderPointer, (UINT32)(UINTN)pCbHeader);\r
367 ASSERT_EFI_ERROR (Status);\r
fce4ecd9 368 }\r
5930f541 369\r
fce4ecd9
MM
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
5930f541
MM
379 // ACPI table is oblidgible\r
380 DEBUG ((EFI_D_ERROR, "Failed to find the required acpi table\n"));\r
381 ASSERT (FALSE);\r
fce4ecd9
MM
382 }\r
383 CbParseSmbiosTable (&pSmbiosTable, &SmbiosTableSize);\r
5930f541
MM
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
cb3e201f 399 Status = CbParseFadtInfo (&PmCtrlRegBase, &PmTimerRegBase, &ResetRegAddress, &ResetValue, &PmEvtBase, &PmGpeEnBase);\r
5930f541
MM
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
cb3e201f
GD
408 pAcpiBoardInfo->PmEvtBase = (UINT64)PmEvtBase;\r
409 pAcpiBoardInfo->PmGpeEnBase = (UINT64)PmGpeEnBase;\r
5930f541
MM
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
7b7fc3e7 423\r
2f20bfd9 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
7b7fc3e7
MM
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
fce4ecd9
MM
439 return EFI_SUCCESS;\r
440}\r
441\r