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 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "CbSupportPei.h"
17 #define LEGACY_8259_MASK_REGISTER_MASTER 0x21
18 #define LEGACY_8259_MASK_REGISTER_SLAVE 0xA1
20 EFI_MEMORY_TYPE_INFORMATION mDefaultMemoryTypeInformation
[] = {
21 { EfiACPIReclaimMemory
, FixedPcdGet32 (PcdMemoryTypeEfiACPIReclaimMemory
) },
22 { EfiACPIMemoryNVS
, FixedPcdGet32 (PcdMemoryTypeEfiACPIMemoryNVS
) },
23 { EfiReservedMemoryType
, FixedPcdGet32 (PcdMemoryTypeEfiReservedMemoryType
) },
24 { EfiRuntimeServicesData
, FixedPcdGet32 (PcdMemoryTypeEfiRuntimeServicesData
) },
25 { EfiRuntimeServicesCode
, FixedPcdGet32 (PcdMemoryTypeEfiRuntimeServicesCode
) },
26 { EfiMaxMemoryType
, 0 }
29 EFI_PEI_PPI_DESCRIPTOR mPpiBootMode
[] = {
31 EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
,
32 &gEfiPeiMasterBootModePpiGuid
,
38 Create memory mapped io resource hob.
40 @param MmioBase Base address of the memory mapped io range
41 @param MmioSize Length of the memory mapped io range
45 BuildMemoryMappedIoRangeHob (
46 EFI_PHYSICAL_ADDRESS MmioBase
,
50 BuildResourceDescriptorHob (
51 EFI_RESOURCE_MEMORY_MAPPED_IO
,
52 (EFI_RESOURCE_ATTRIBUTE_PRESENT
|
53 EFI_RESOURCE_ATTRIBUTE_INITIALIZED
|
54 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE
|
55 EFI_RESOURCE_ATTRIBUTE_TESTED
),
60 BuildMemoryAllocationHob (
68 Check the integrity of firmware volume header
70 @param[in] FwVolHeader A pointer to a firmware volume header
72 @retval TRUE The firmware volume is consistent
73 @retval FALSE The firmware volume has corrupted.
79 IN EFI_FIRMWARE_VOLUME_HEADER
*FwVolHeader
85 if (CompareMem (&FwVolHeader
->FileSystemGuid
, &gEfiFirmwareFileSystem2Guid
, sizeof(EFI_GUID
)) != 0 ) {
89 if ( (FwVolHeader
->Revision
!= EFI_FVH_REVISION
) ||
90 (FwVolHeader
->Signature
!= EFI_FVH_SIGNATURE
) ||
91 (FwVolHeader
->FvLength
== ((UINTN
) -1)) ||
92 ((FwVolHeader
->HeaderLength
& 0x01 ) !=0) ) {
96 Checksum
= CalculateCheckSum16 ((UINT16
*) FwVolHeader
, FwVolHeader
->HeaderLength
);
99 "ERROR - Invalid Firmware Volume Header Checksum, change 0x%04x to 0x%04x\r\n",
100 FwVolHeader
->Checksum
,
101 (UINT16
)( Checksum
+ FwVolHeader
->Checksum
)));
109 Install FvInfo PPI and create fv hobs for remained fvs
113 CbPeiReportRemainedFvs (
120 TempPtr
= (UINT8
* )(UINTN
) PcdGet32 (PcdPayloadFdMemBase
);
121 EndPtr
= (UINT8
* )(UINTN
) (PcdGet32 (PcdPayloadFdMemBase
) + PcdGet32 (PcdPayloadFdMemSize
));
123 for (;TempPtr
< EndPtr
;) {
124 if (IsFvHeaderValid ((EFI_FIRMWARE_VOLUME_HEADER
* )TempPtr
)) {
125 if (TempPtr
!= (UINT8
* )(UINTN
) PcdGet32 (PcdPayloadFdMemBase
)) {
127 DEBUG((EFI_D_ERROR
, "Found one valid fv : 0x%lx.\n", TempPtr
, ((EFI_FIRMWARE_VOLUME_HEADER
* )TempPtr
)->FvLength
));
129 PeiServicesInstallFvInfoPpi (
131 (VOID
*) (UINTN
) TempPtr
,
132 (UINT32
) (UINTN
) ((EFI_FIRMWARE_VOLUME_HEADER
* )TempPtr
)->FvLength
,
136 BuildFvHob ((EFI_PHYSICAL_ADDRESS
)(UINTN
) TempPtr
, ((EFI_FIRMWARE_VOLUME_HEADER
* )TempPtr
)->FvLength
);
139 TempPtr
+= ((EFI_FIRMWARE_VOLUME_HEADER
* )TempPtr
)->FvLength
;
144 Based on memory base, size and type, build resource descripter HOB.
146 @param Base Memory base address.
147 @param Size Memory size.
148 @param Type Memory type.
149 @param Param A pointer to CB_MEM_INFO.
151 @retval EFI_SUCCESS if it completed successfully.
161 CB_MEM_INFO
*MemInfo
;
164 Attribue
= EFI_RESOURCE_ATTRIBUTE_PRESENT
|
165 EFI_RESOURCE_ATTRIBUTE_INITIALIZED
|
166 EFI_RESOURCE_ATTRIBUTE_TESTED
|
167 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE
|
168 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE
|
169 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE
|
170 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
;
172 if ((Base
< 0x100000) && ((Base
+ Size
) > 0x100000)) {
173 Size
-= (0x100000 - Base
);
177 MemInfo
= (CB_MEM_INFO
*)Param
;
178 if (Base
>= 0x100000) {
179 if (Type
== CB_MEM_RAM
) {
180 if (Base
< 0x100000000ULL
) {
181 MemInfo
->UsableLowMemTop
= (UINT32
)(Base
+ Size
);
183 Attribue
&= ~EFI_RESOURCE_ATTRIBUTE_TESTED
;
185 BuildResourceDescriptorHob (
186 EFI_RESOURCE_SYSTEM_MEMORY
,
188 (EFI_PHYSICAL_ADDRESS
)Base
,
191 } else if (Type
== CB_MEM_TABLE
) {
192 BuildResourceDescriptorHob (
193 EFI_RESOURCE_MEMORY_RESERVED
,
195 (EFI_PHYSICAL_ADDRESS
)Base
,
198 MemInfo
->SystemLowMemTop
= ((UINT32
)(Base
+ Size
) + 0x0FFFFFFF) & 0xF0000000;
199 } else if (Type
== CB_MEM_RESERVED
) {
200 if ((MemInfo
->SystemLowMemTop
== 0) || (Base
< MemInfo
->SystemLowMemTop
)) {
201 BuildResourceDescriptorHob (
202 EFI_RESOURCE_MEMORY_RESERVED
,
204 (EFI_PHYSICAL_ADDRESS
)Base
,
215 This is the entrypoint of PEIM
217 @param FileHandle Handle of the file being invoked.
218 @param PeiServices Describes the list of possible PEI Services.
220 @retval EFI_SUCCESS if it completed successfully.
225 IN EFI_PEI_FILE_HANDLE FileHandle
,
226 IN CONST EFI_PEI_SERVICES
**PeiServices
230 UINT64 LowMemorySize
;
231 UINT64 PeiMemSize
= SIZE_64MB
; // 64 MB
232 EFI_PHYSICAL_ADDRESS PeiMemBase
= 0;
234 UINT8 PhysicalAddressBits
;
237 UINT32 AcpiTableSize
;
239 UINT32 SmbiosTableSize
;
240 SYSTEM_TABLE_INFO
* pSystemTableInfo
;
241 FRAME_BUFFER_INFO FbInfo
;
242 FRAME_BUFFER_INFO
* pFbInfo
;
243 ACPI_BOARD_INFO
* pAcpiBoardInfo
;
244 UINTN PmCtrlRegBase
, PmTimerRegBase
, ResetRegAddress
, ResetValue
;
247 CB_MEM_INFO CbMemInfo
;
250 // Report lower 640KB of RAM. Attribute EFI_RESOURCE_ATTRIBUTE_TESTED
251 // is intentionally omitted to prevent erasing of the coreboot header
252 // record before it is processed by CbParseMemoryInfo.
254 BuildResourceDescriptorHob (
255 EFI_RESOURCE_SYSTEM_MEMORY
,
257 EFI_RESOURCE_ATTRIBUTE_PRESENT
|
258 EFI_RESOURCE_ATTRIBUTE_INITIALIZED
|
259 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE
|
260 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE
|
261 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE
|
262 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
264 (EFI_PHYSICAL_ADDRESS
)(0),
269 BuildResourceDescriptorHob (
270 EFI_RESOURCE_MEMORY_RESERVED
,
272 EFI_RESOURCE_ATTRIBUTE_PRESENT
|
273 EFI_RESOURCE_ATTRIBUTE_INITIALIZED
|
274 EFI_RESOURCE_ATTRIBUTE_TESTED
|
275 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE
|
276 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE
|
277 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE
|
278 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
280 (EFI_PHYSICAL_ADDRESS
)(0xA0000),
284 ZeroMem (&CbMemInfo
, sizeof(CbMemInfo
));
285 Status
= CbParseMemoryInfo (CbMemInfoCallback
, (VOID
*)&CbMemInfo
);
286 if (EFI_ERROR(Status
)) {
290 LowMemorySize
= CbMemInfo
.UsableLowMemTop
;
291 DEBUG ((EFI_D_INFO
, "Low memory 0x%lx\n", LowMemorySize
));
292 DEBUG ((EFI_D_INFO
, "SystemLowMemTop 0x%x\n", CbMemInfo
.SystemLowMemTop
));
295 // Should be 64k aligned
297 PeiMemBase
= (LowMemorySize
- PeiMemSize
) & (~(BASE_64KB
- 1));
299 DEBUG((EFI_D_ERROR
, "PeiMemBase: 0x%lx.\n", PeiMemBase
));
300 DEBUG((EFI_D_ERROR
, "PeiMemSize: 0x%lx.\n", PeiMemSize
));
302 Status
= PeiServicesInstallPeiMemory (
306 ASSERT_EFI_ERROR (Status
);
309 // Set cache on the physical memory
311 MtrrSetMemoryAttribute (BASE_1MB
, LowMemorySize
- BASE_1MB
, CacheWriteBack
);
312 MtrrSetMemoryAttribute (0, 0xA0000, CacheWriteBack
);
315 // Create Memory Type Information HOB
318 &gEfiMemoryTypeInformationGuid
,
319 mDefaultMemoryTypeInformation
,
320 sizeof(mDefaultMemoryTypeInformation
)
326 CbPeiReportRemainedFvs ();
328 BuildMemoryAllocationHob (
329 PcdGet32 (PcdPayloadFdMemBase
),
330 PcdGet32 (PcdPayloadFdMemSize
),
335 // Build CPU memory space and IO space hob
337 AsmCpuid (0x80000000, &RegEax
, NULL
, NULL
, NULL
);
338 if (RegEax
>= 0x80000008) {
339 AsmCpuid (0x80000008, &RegEax
, NULL
, NULL
, NULL
);
340 PhysicalAddressBits
= (UINT8
) RegEax
;
342 PhysicalAddressBits
= 36;
345 // Create a CPU hand-off information
347 BuildCpuHob (PhysicalAddressBits
, 16);
350 // Report Local APIC range
352 BuildMemoryMappedIoRangeHob (0xFEC80000, SIZE_512KB
);
357 Status
= PeiServicesSetBootMode (BOOT_WITH_FULL_CONFIGURATION
);
358 ASSERT_EFI_ERROR (Status
);
360 Status
= PeiServicesInstallPpi (mPpiBootMode
);
361 ASSERT_EFI_ERROR (Status
);
364 // Set pcd to save the upper coreboot header in case the dxecore will
368 if ((CbParseGetCbHeader (1, &pCbHeader
) == RETURN_SUCCESS
)
369 && ((UINTN
)pCbHeader
> BASE_4KB
)) {
370 DEBUG((EFI_D_ERROR
, "Actual Coreboot header: %p.\n", pCbHeader
));
371 Status
= PcdSet32S (PcdCbHeaderPointer
, (UINT32
)(UINTN
)pCbHeader
);
372 ASSERT_EFI_ERROR (Status
);
376 // Create guid hob for system tables like acpi table and smbios table
382 Status
= CbParseAcpiTable (&pAcpiTable
, &AcpiTableSize
);
383 if (EFI_ERROR (Status
)) {
384 // ACPI table is oblidgible
385 DEBUG ((EFI_D_ERROR
, "Failed to find the required acpi table\n"));
388 CbParseSmbiosTable (&pSmbiosTable
, &SmbiosTableSize
);
390 pSystemTableInfo
= NULL
;
391 pSystemTableInfo
= BuildGuidHob (&gUefiSystemTableInfoGuid
, sizeof (SYSTEM_TABLE_INFO
));
392 ASSERT (pSystemTableInfo
!= NULL
);
393 pSystemTableInfo
->AcpiTableBase
= (UINT64
) (UINTN
)pAcpiTable
;
394 pSystemTableInfo
->AcpiTableSize
= AcpiTableSize
;
395 pSystemTableInfo
->SmbiosTableBase
= (UINT64
) (UINTN
)pSmbiosTable
;
396 pSystemTableInfo
->SmbiosTableSize
= SmbiosTableSize
;
397 DEBUG ((EFI_D_ERROR
, "Detected Acpi Table at 0x%lx, length 0x%x\n", pSystemTableInfo
->AcpiTableBase
, pSystemTableInfo
->AcpiTableSize
));
398 DEBUG ((EFI_D_ERROR
, "Detected Smbios Table at 0x%lx, length 0x%x\n", pSystemTableInfo
->SmbiosTableBase
, pSystemTableInfo
->SmbiosTableSize
));
399 DEBUG ((EFI_D_ERROR
, "Create system table info guid hob\n"));
402 // Create guid hob for acpi board information
404 Status
= CbParseFadtInfo (&PmCtrlRegBase
, &PmTimerRegBase
, &ResetRegAddress
, &ResetValue
, &PmEvtBase
, &PmGpeEnBase
);
405 ASSERT_EFI_ERROR (Status
);
406 pAcpiBoardInfo
= NULL
;
407 pAcpiBoardInfo
= BuildGuidHob (&gUefiAcpiBoardInfoGuid
, sizeof (ACPI_BOARD_INFO
));
408 ASSERT (pAcpiBoardInfo
!= NULL
);
409 pAcpiBoardInfo
->PmCtrlRegBase
= (UINT64
)PmCtrlRegBase
;
410 pAcpiBoardInfo
->PmTimerRegBase
= (UINT64
)PmTimerRegBase
;
411 pAcpiBoardInfo
->ResetRegAddress
= (UINT64
)ResetRegAddress
;
412 pAcpiBoardInfo
->ResetValue
= (UINT8
)ResetValue
;
413 pAcpiBoardInfo
->PmEvtBase
= (UINT64
)PmEvtBase
;
414 pAcpiBoardInfo
->PmGpeEnBase
= (UINT64
)PmGpeEnBase
;
415 DEBUG ((EFI_D_ERROR
, "Create acpi board info guid hob\n"));
418 // Create guid hob for frame buffer information
420 ZeroMem (&FbInfo
, sizeof (FRAME_BUFFER_INFO
));
421 Status
= CbParseFbInfo (&FbInfo
);
422 if (!EFI_ERROR (Status
)) {
423 pFbInfo
= BuildGuidHob (&gUefiFrameBufferInfoGuid
, sizeof (FRAME_BUFFER_INFO
));
424 ASSERT (pSystemTableInfo
!= NULL
);
425 CopyMem (pFbInfo
, &FbInfo
, sizeof (FRAME_BUFFER_INFO
));
426 DEBUG ((EFI_D_ERROR
, "Create frame buffer info guid hob\n"));
430 // Parse platform specific information from coreboot.
432 Status
= CbParsePlatformInfo ();
433 if (EFI_ERROR (Status
)) {
434 DEBUG ((EFI_D_ERROR
, "Error when parsing platform info, Status = %r\n", Status
));
439 // Mask off all legacy 8259 interrupt sources
441 IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER
, 0xFF);
442 IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE
, 0xFF);