2 This PEIM will parse coreboot table in memory and report resource information into pei core.
3 This file contains the main entrypoint of the PEIM.
5 Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
9 #include "CbSupportPei.h"
11 #define LEGACY_8259_MASK_REGISTER_MASTER 0x21
12 #define LEGACY_8259_MASK_REGISTER_SLAVE 0xA1
14 EFI_MEMORY_TYPE_INFORMATION mDefaultMemoryTypeInformation
[] = {
15 { EfiACPIReclaimMemory
, FixedPcdGet32 (PcdMemoryTypeEfiACPIReclaimMemory
) },
16 { EfiACPIMemoryNVS
, FixedPcdGet32 (PcdMemoryTypeEfiACPIMemoryNVS
) },
17 { EfiReservedMemoryType
, FixedPcdGet32 (PcdMemoryTypeEfiReservedMemoryType
) },
18 { EfiRuntimeServicesData
, FixedPcdGet32 (PcdMemoryTypeEfiRuntimeServicesData
) },
19 { EfiRuntimeServicesCode
, FixedPcdGet32 (PcdMemoryTypeEfiRuntimeServicesCode
) },
20 { EfiMaxMemoryType
, 0 }
23 EFI_PEI_PPI_DESCRIPTOR mPpiBootMode
[] = {
25 EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
,
26 &gEfiPeiMasterBootModePpiGuid
,
32 Create memory mapped io resource hob.
34 @param MmioBase Base address of the memory mapped io range
35 @param MmioSize Length of the memory mapped io range
39 BuildMemoryMappedIoRangeHob (
40 EFI_PHYSICAL_ADDRESS MmioBase
,
44 BuildResourceDescriptorHob (
45 EFI_RESOURCE_MEMORY_MAPPED_IO
,
46 (EFI_RESOURCE_ATTRIBUTE_PRESENT
|
47 EFI_RESOURCE_ATTRIBUTE_INITIALIZED
|
48 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE
|
49 EFI_RESOURCE_ATTRIBUTE_TESTED
),
54 BuildMemoryAllocationHob (
62 Check the integrity of firmware volume header
64 @param[in] FwVolHeader A pointer to a firmware volume header
66 @retval TRUE The firmware volume is consistent
67 @retval FALSE The firmware volume has corrupted.
73 IN EFI_FIRMWARE_VOLUME_HEADER
*FwVolHeader
79 if (CompareMem (&FwVolHeader
->FileSystemGuid
, &gEfiFirmwareFileSystem2Guid
, sizeof(EFI_GUID
)) != 0 ) {
83 if ( (FwVolHeader
->Revision
!= EFI_FVH_REVISION
) ||
84 (FwVolHeader
->Signature
!= EFI_FVH_SIGNATURE
) ||
85 (FwVolHeader
->FvLength
== ((UINTN
) -1)) ||
86 ((FwVolHeader
->HeaderLength
& 0x01 ) !=0) ) {
90 Checksum
= CalculateCheckSum16 ((UINT16
*) FwVolHeader
, FwVolHeader
->HeaderLength
);
93 "ERROR - Invalid Firmware Volume Header Checksum, change 0x%04x to 0x%04x\r\n",
94 FwVolHeader
->Checksum
,
95 (UINT16
)( Checksum
+ FwVolHeader
->Checksum
)));
103 Install FvInfo PPI and create fv hobs for remained fvs
107 CbPeiReportRemainedFvs (
114 TempPtr
= (UINT8
* )(UINTN
) PcdGet32 (PcdPayloadFdMemBase
);
115 EndPtr
= (UINT8
* )(UINTN
) (PcdGet32 (PcdPayloadFdMemBase
) + PcdGet32 (PcdPayloadFdMemSize
));
117 for (;TempPtr
< EndPtr
;) {
118 if (IsFvHeaderValid ((EFI_FIRMWARE_VOLUME_HEADER
* )TempPtr
)) {
119 if (TempPtr
!= (UINT8
* )(UINTN
) PcdGet32 (PcdPayloadFdMemBase
)) {
121 DEBUG((EFI_D_ERROR
, "Found one valid fv : 0x%lx.\n", TempPtr
, ((EFI_FIRMWARE_VOLUME_HEADER
* )TempPtr
)->FvLength
));
123 PeiServicesInstallFvInfoPpi (
125 (VOID
*) (UINTN
) TempPtr
,
126 (UINT32
) (UINTN
) ((EFI_FIRMWARE_VOLUME_HEADER
* )TempPtr
)->FvLength
,
130 BuildFvHob ((EFI_PHYSICAL_ADDRESS
)(UINTN
) TempPtr
, ((EFI_FIRMWARE_VOLUME_HEADER
* )TempPtr
)->FvLength
);
133 TempPtr
+= ((EFI_FIRMWARE_VOLUME_HEADER
* )TempPtr
)->FvLength
;
138 Based on memory base, size and type, build resource descripter HOB.
140 @param Base Memory base address.
141 @param Size Memory size.
142 @param Type Memory type.
143 @param Param A pointer to CB_MEM_INFO.
145 @retval EFI_SUCCESS if it completed successfully.
155 CB_MEM_INFO
*MemInfo
;
158 Attribue
= EFI_RESOURCE_ATTRIBUTE_PRESENT
|
159 EFI_RESOURCE_ATTRIBUTE_INITIALIZED
|
160 EFI_RESOURCE_ATTRIBUTE_TESTED
|
161 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE
|
162 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE
|
163 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE
|
164 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
;
166 if ((Base
< 0x100000) && ((Base
+ Size
) > 0x100000)) {
167 Size
-= (0x100000 - Base
);
171 MemInfo
= (CB_MEM_INFO
*)Param
;
172 if (Base
>= 0x100000) {
173 if (Type
== CB_MEM_RAM
) {
174 if (Base
< 0x100000000ULL
) {
175 MemInfo
->UsableLowMemTop
= (UINT32
)(Base
+ Size
);
177 Attribue
&= ~EFI_RESOURCE_ATTRIBUTE_TESTED
;
179 BuildResourceDescriptorHob (
180 EFI_RESOURCE_SYSTEM_MEMORY
,
182 (EFI_PHYSICAL_ADDRESS
)Base
,
185 } else if (Type
== CB_MEM_TABLE
) {
186 BuildResourceDescriptorHob (
187 EFI_RESOURCE_MEMORY_RESERVED
,
189 (EFI_PHYSICAL_ADDRESS
)Base
,
192 MemInfo
->SystemLowMemTop
= ((UINT32
)(Base
+ Size
) + 0x0FFFFFFF) & 0xF0000000;
193 } else if (Type
== CB_MEM_RESERVED
) {
194 if ((MemInfo
->SystemLowMemTop
== 0) || (Base
< MemInfo
->SystemLowMemTop
)) {
195 BuildResourceDescriptorHob (
196 EFI_RESOURCE_MEMORY_RESERVED
,
198 (EFI_PHYSICAL_ADDRESS
)Base
,
209 This is the entrypoint of PEIM
211 @param FileHandle Handle of the file being invoked.
212 @param PeiServices Describes the list of possible PEI Services.
214 @retval EFI_SUCCESS if it completed successfully.
219 IN EFI_PEI_FILE_HANDLE FileHandle
,
220 IN CONST EFI_PEI_SERVICES
**PeiServices
224 UINT64 LowMemorySize
;
225 UINT64 PeiMemSize
= SIZE_64MB
; // 64 MB
226 EFI_PHYSICAL_ADDRESS PeiMemBase
= 0;
228 UINT8 PhysicalAddressBits
;
231 UINT32 AcpiTableSize
;
233 UINT32 SmbiosTableSize
;
234 SYSTEM_TABLE_INFO
* pSystemTableInfo
;
235 FRAME_BUFFER_INFO FbInfo
;
236 FRAME_BUFFER_INFO
* pFbInfo
;
237 ACPI_BOARD_INFO
* pAcpiBoardInfo
;
238 UINTN PmCtrlRegBase
, PmTimerRegBase
, ResetRegAddress
, ResetValue
;
241 CB_MEM_INFO CbMemInfo
;
244 // Report lower 640KB of RAM. Attribute EFI_RESOURCE_ATTRIBUTE_TESTED
245 // is intentionally omitted to prevent erasing of the coreboot header
246 // record before it is processed by CbParseMemoryInfo.
248 BuildResourceDescriptorHob (
249 EFI_RESOURCE_SYSTEM_MEMORY
,
251 EFI_RESOURCE_ATTRIBUTE_PRESENT
|
252 EFI_RESOURCE_ATTRIBUTE_INITIALIZED
|
253 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE
|
254 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE
|
255 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE
|
256 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
258 (EFI_PHYSICAL_ADDRESS
)(0),
263 BuildResourceDescriptorHob (
264 EFI_RESOURCE_MEMORY_RESERVED
,
266 EFI_RESOURCE_ATTRIBUTE_PRESENT
|
267 EFI_RESOURCE_ATTRIBUTE_INITIALIZED
|
268 EFI_RESOURCE_ATTRIBUTE_TESTED
|
269 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE
|
270 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE
|
271 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE
|
272 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
274 (EFI_PHYSICAL_ADDRESS
)(0xA0000),
278 ZeroMem (&CbMemInfo
, sizeof(CbMemInfo
));
279 Status
= CbParseMemoryInfo (CbMemInfoCallback
, (VOID
*)&CbMemInfo
);
280 if (EFI_ERROR(Status
)) {
284 LowMemorySize
= CbMemInfo
.UsableLowMemTop
;
285 DEBUG ((EFI_D_INFO
, "Low memory 0x%lx\n", LowMemorySize
));
286 DEBUG ((EFI_D_INFO
, "SystemLowMemTop 0x%x\n", CbMemInfo
.SystemLowMemTop
));
289 // Should be 64k aligned
291 PeiMemBase
= (LowMemorySize
- PeiMemSize
) & (~(BASE_64KB
- 1));
293 DEBUG((EFI_D_ERROR
, "PeiMemBase: 0x%lx.\n", PeiMemBase
));
294 DEBUG((EFI_D_ERROR
, "PeiMemSize: 0x%lx.\n", PeiMemSize
));
296 Status
= PeiServicesInstallPeiMemory (
300 ASSERT_EFI_ERROR (Status
);
303 // Set cache on the physical memory
305 MtrrSetMemoryAttribute (BASE_1MB
, LowMemorySize
- BASE_1MB
, CacheWriteBack
);
306 MtrrSetMemoryAttribute (0, 0xA0000, CacheWriteBack
);
309 // Create Memory Type Information HOB
312 &gEfiMemoryTypeInformationGuid
,
313 mDefaultMemoryTypeInformation
,
314 sizeof(mDefaultMemoryTypeInformation
)
320 CbPeiReportRemainedFvs ();
322 BuildMemoryAllocationHob (
323 PcdGet32 (PcdPayloadFdMemBase
),
324 PcdGet32 (PcdPayloadFdMemSize
),
329 // Build CPU memory space and IO space hob
331 AsmCpuid (0x80000000, &RegEax
, NULL
, NULL
, NULL
);
332 if (RegEax
>= 0x80000008) {
333 AsmCpuid (0x80000008, &RegEax
, NULL
, NULL
, NULL
);
334 PhysicalAddressBits
= (UINT8
) RegEax
;
336 PhysicalAddressBits
= 36;
339 // Create a CPU hand-off information
341 BuildCpuHob (PhysicalAddressBits
, 16);
344 // Report Local APIC range
346 BuildMemoryMappedIoRangeHob (0xFEC80000, SIZE_512KB
);
351 Status
= PeiServicesSetBootMode (BOOT_WITH_FULL_CONFIGURATION
);
352 ASSERT_EFI_ERROR (Status
);
354 Status
= PeiServicesInstallPpi (mPpiBootMode
);
355 ASSERT_EFI_ERROR (Status
);
358 // Set pcd to save the upper coreboot header in case the dxecore will
362 if ((CbParseGetCbHeader (1, &pCbHeader
) == RETURN_SUCCESS
)
363 && ((UINTN
)pCbHeader
> BASE_4KB
)) {
364 DEBUG((EFI_D_ERROR
, "Actual Coreboot header: %p.\n", pCbHeader
));
365 Status
= PcdSet32S (PcdCbHeaderPointer
, (UINT32
)(UINTN
)pCbHeader
);
366 ASSERT_EFI_ERROR (Status
);
370 // Create guid hob for system tables like acpi table and smbios table
376 Status
= CbParseAcpiTable (&pAcpiTable
, &AcpiTableSize
);
377 if (EFI_ERROR (Status
)) {
378 // ACPI table is oblidgible
379 DEBUG ((EFI_D_ERROR
, "Failed to find the required acpi table\n"));
382 CbParseSmbiosTable (&pSmbiosTable
, &SmbiosTableSize
);
384 pSystemTableInfo
= NULL
;
385 pSystemTableInfo
= BuildGuidHob (&gUefiSystemTableInfoGuid
, sizeof (SYSTEM_TABLE_INFO
));
386 ASSERT (pSystemTableInfo
!= NULL
);
387 pSystemTableInfo
->AcpiTableBase
= (UINT64
) (UINTN
)pAcpiTable
;
388 pSystemTableInfo
->AcpiTableSize
= AcpiTableSize
;
389 pSystemTableInfo
->SmbiosTableBase
= (UINT64
) (UINTN
)pSmbiosTable
;
390 pSystemTableInfo
->SmbiosTableSize
= SmbiosTableSize
;
391 DEBUG ((EFI_D_ERROR
, "Detected Acpi Table at 0x%lx, length 0x%x\n", pSystemTableInfo
->AcpiTableBase
, pSystemTableInfo
->AcpiTableSize
));
392 DEBUG ((EFI_D_ERROR
, "Detected Smbios Table at 0x%lx, length 0x%x\n", pSystemTableInfo
->SmbiosTableBase
, pSystemTableInfo
->SmbiosTableSize
));
393 DEBUG ((EFI_D_ERROR
, "Create system table info guid hob\n"));
396 // Create guid hob for acpi board information
398 Status
= CbParseFadtInfo (&PmCtrlRegBase
, &PmTimerRegBase
, &ResetRegAddress
, &ResetValue
, &PmEvtBase
, &PmGpeEnBase
);
399 ASSERT_EFI_ERROR (Status
);
400 pAcpiBoardInfo
= NULL
;
401 pAcpiBoardInfo
= BuildGuidHob (&gUefiAcpiBoardInfoGuid
, sizeof (ACPI_BOARD_INFO
));
402 ASSERT (pAcpiBoardInfo
!= NULL
);
403 pAcpiBoardInfo
->PmCtrlRegBase
= (UINT64
)PmCtrlRegBase
;
404 pAcpiBoardInfo
->PmTimerRegBase
= (UINT64
)PmTimerRegBase
;
405 pAcpiBoardInfo
->ResetRegAddress
= (UINT64
)ResetRegAddress
;
406 pAcpiBoardInfo
->ResetValue
= (UINT8
)ResetValue
;
407 pAcpiBoardInfo
->PmEvtBase
= (UINT64
)PmEvtBase
;
408 pAcpiBoardInfo
->PmGpeEnBase
= (UINT64
)PmGpeEnBase
;
409 DEBUG ((EFI_D_ERROR
, "Create acpi board info guid hob\n"));
412 // Create guid hob for frame buffer information
414 ZeroMem (&FbInfo
, sizeof (FRAME_BUFFER_INFO
));
415 Status
= CbParseFbInfo (&FbInfo
);
416 if (!EFI_ERROR (Status
)) {
417 pFbInfo
= BuildGuidHob (&gUefiFrameBufferInfoGuid
, sizeof (FRAME_BUFFER_INFO
));
418 ASSERT (pSystemTableInfo
!= NULL
);
419 CopyMem (pFbInfo
, &FbInfo
, sizeof (FRAME_BUFFER_INFO
));
420 DEBUG ((EFI_D_ERROR
, "Create frame buffer info guid hob\n"));
424 // Parse platform specific information from coreboot.
426 Status
= CbParsePlatformInfo ();
427 if (EFI_ERROR (Status
)) {
428 DEBUG ((EFI_D_ERROR
, "Error when parsing platform info, Status = %r\n", Status
));
433 // Mask off all legacy 8259 interrupt sources
435 IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER
, 0xFF);
436 IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE
, 0xFF);