2 This library will parse the coreboot table in memory and extract those required
5 Copyright (c) 2014 - 2021, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
10 #include <Uefi/UefiBaseType.h>
11 #include <Library/BaseLib.h>
12 #include <Library/BaseMemoryLib.h>
13 #include <Library/DebugLib.h>
14 #include <Library/PcdLib.h>
15 #include <Library/IoLib.h>
16 #include <Library/BlParseLib.h>
17 #include <IndustryStandard/Acpi.h>
21 Convert a packed value from cbuint64 to a UINT64 value.
23 @param val The pointer to packed data.
25 @return the UNIT64 value after conversion.
30 IN
struct cbuint64 val
33 return LShiftU64 (val
.hi
, 32) | val
.lo
;
37 Returns the sum of all elements in a buffer of 16-bit values. During
38 calculation, the carry bits are also been added.
40 @param Buffer The pointer to the buffer to carry out the sum operation.
41 @param Length The size, in bytes, of Buffer.
43 @return Sum The sum of Buffer with carry bits included during additions.
58 TmpPtr
= (UINT8
*)Buffer
;
59 for (Idx
= 0; Idx
< Length
; Idx
++) {
60 TmpValue
= TmpPtr
[Idx
];
69 Sum
= (Sum
+ (Sum
>> 16)) & 0xFFFF;
73 return (UINT16
)((~Sum
) & 0xFFFF);
77 Check the coreboot table if it is valid.
79 @param Header Pointer to coreboot table
81 @retval TRUE The coreboot table is valid.
82 @retval Others The coreboot table is not valid.
87 IN
struct cb_header
*Header
92 if ((Header
== NULL
) || (Header
->table_bytes
== 0)) {
96 if (Header
->signature
!= CB_HEADER_SIGNATURE
) {
101 // Check the checksum of the coreboot table header
103 CheckSum
= CbCheckSum16 ((UINT16
*)Header
, sizeof (*Header
));
105 DEBUG ((DEBUG_ERROR
, "Invalid coreboot table header checksum\n"));
109 CheckSum
= CbCheckSum16 ((UINT16
*)((UINT8
*)Header
+ sizeof (*Header
)), Header
->table_bytes
);
110 if (CheckSum
!= Header
->table_checksum
) {
111 DEBUG ((DEBUG_ERROR
, "Incorrect checksum of all the coreboot table entries\n"));
119 This function retrieves the parameter base address from boot loader.
121 This function will get bootloader specific parameter address for UEFI payload.
122 e.g. HobList pointer for Slim Bootloader, and coreboot table header for Coreboot.
124 @retval NULL Failed to find the GUID HOB.
125 @retval others GUIDed HOB data pointer.
134 struct cb_header
*Header
;
135 struct cb_record
*Record
;
142 // coreboot could pass coreboot table to UEFI payload
144 Header
= (struct cb_header
*)(UINTN
)GET_BOOTLOADER_PARAMETER ();
145 if (IsValidCbTable (Header
)) {
150 // Find simplified coreboot table in memory range 0 ~ 4KB.
151 // Some GCC version does not allow directly access to NULL pointer,
152 // so start the search from 0x10 instead.
154 for (Idx
= 16; Idx
< 4096; Idx
+= 16) {
155 Header
= (struct cb_header
*)Idx
;
156 if (Header
->signature
== CB_HEADER_SIGNATURE
) {
166 // Check the coreboot header
168 if (!IsValidCbTable (Header
)) {
173 // Find full coreboot table in high memory
176 TmpPtr
= (UINT8
*)Header
+ Header
->header_bytes
;
177 for (Idx
= 0; Idx
< Header
->table_entries
; Idx
++) {
178 Record
= (struct cb_record
*)TmpPtr
;
179 if (Record
->tag
== CB_TAG_FORWARD
) {
180 CbTablePtr
= (VOID
*)(UINTN
)((struct cb_forward
*)(UINTN
)Record
)->forward
;
184 TmpPtr
+= Record
->size
;
188 // Check the coreboot header in high memory
190 if (!IsValidCbTable ((struct cb_header
*)CbTablePtr
)) {
194 Status
= PcdSet64S (PcdBootloaderParameter
, (UINTN
)CbTablePtr
);
195 ASSERT_EFI_ERROR (Status
);
201 Find coreboot record with given Tag.
203 @param Tag The tag id to be found
205 @retval NULL The Tag is not found.
206 @retval Others The pointer to the record found.
214 struct cb_header
*Header
;
215 struct cb_record
*Record
;
220 Header
= (struct cb_header
*)GetParameterBase ();
223 TmpPtr
= (UINT8
*)Header
+ Header
->header_bytes
;
224 for (Idx
= 0; Idx
< Header
->table_entries
; Idx
++) {
225 Record
= (struct cb_record
*)TmpPtr
;
226 if (Record
->tag
== Tag
) {
231 TmpPtr
+= Record
->size
;
238 Find the given table with TableId from the given coreboot memory Root.
240 @param Root The coreboot memory table to be searched in
241 @param TableId Table id to be found
242 @param MemTable To save the base address of the memory table found
243 @param MemTableSize To save the size of memory table found
245 @retval RETURN_SUCCESS Successfully find out the memory table.
246 @retval RETURN_INVALID_PARAMETER Invalid input parameters.
247 @retval RETURN_NOT_FOUND Failed to find the memory table.
252 IN
struct cbmem_root
*Root
,
255 OUT UINT32
*MemTableSize
260 struct cbmem_entry
*Entries
;
262 if ((Root
== NULL
) || (MemTable
== NULL
)) {
263 return RETURN_INVALID_PARAMETER
;
267 // Check if the entry is CBMEM or IMD
268 // and handle them separately
270 Entries
= Root
->entries
;
271 if (Entries
[0].magic
== CBMEM_ENTRY_MAGIC
) {
274 Entries
= (struct cbmem_entry
*)((struct imd_root
*)Root
)->entries
;
275 if (Entries
[0].magic
== IMD_ENTRY_MAGIC
) {
278 return RETURN_NOT_FOUND
;
282 for (Idx
= 0; Idx
< Root
->num_entries
; Idx
++) {
283 if (Entries
[Idx
].id
== TableId
) {
285 *MemTable
= (VOID
*)((UINTN
)Entries
[Idx
].start
+ (UINTN
)Root
);
287 *MemTable
= (VOID
*)(UINTN
)Entries
[Idx
].start
;
290 if (MemTableSize
!= NULL
) {
291 *MemTableSize
= Entries
[Idx
].size
;
296 "Find CbMemTable Id 0x%x, base %p, size 0x%x\n",
301 return RETURN_SUCCESS
;
305 return RETURN_NOT_FOUND
;
309 Acquire the coreboot memory table with the given table id
311 @param TableId Table id to be searched
312 @param MemTable Pointer to the base address of the memory table
313 @param MemTableSize Pointer to the size of the memory table
315 @retval RETURN_SUCCESS Successfully find out the memory table.
316 @retval RETURN_INVALID_PARAMETER Invalid input parameters.
317 @retval RETURN_NOT_FOUND Failed to find the memory table.
324 OUT UINT32
*MemTableSize
329 struct cb_memory_range
*Range
;
333 struct cbmem_root
*CbMemRoot
;
335 if (MemTable
== NULL
) {
336 return RETURN_INVALID_PARAMETER
;
340 Status
= RETURN_NOT_FOUND
;
343 // Get the coreboot memory table
345 Rec
= (CB_MEMORY
*)FindCbTag (CB_TAG_MEMORY
);
350 for (Index
= 0; Index
< MEM_RANGE_COUNT (Rec
); Index
++) {
351 Range
= MEM_RANGE_PTR (Rec
, Index
);
352 Start
= cb_unpack64 (Range
->start
);
353 Size
= cb_unpack64 (Range
->size
);
355 if ((Range
->type
== CB_MEM_TABLE
) && (Start
> 0x1000)) {
356 CbMemRoot
= (struct cbmem_root
*)(UINTN
)(Start
+ Size
- DYN_CBMEM_ALIGN_SIZE
);
357 Status
= FindCbMemTable (CbMemRoot
, TableId
, MemTable
, MemTableSize
);
358 if (!EFI_ERROR (Status
)) {
368 Acquire the memory information from the coreboot table in memory.
370 @param MemInfoCallback The callback routine
371 @param Params Pointer to the callback routine parameter
373 @retval RETURN_SUCCESS Successfully find out the memory information.
374 @retval RETURN_NOT_FOUND Failed to find the memory information.
380 IN BL_MEM_INFO_CALLBACK MemInfoCallback
,
385 struct cb_memory_range
*Range
;
387 MEMORY_MAP_ENTRY MemoryMap
;
390 // Get the coreboot memory table
392 Rec
= (CB_MEMORY
*)FindCbTag (CB_TAG_MEMORY
);
394 return RETURN_NOT_FOUND
;
397 for (Index
= 0; Index
< MEM_RANGE_COUNT (Rec
); Index
++) {
398 Range
= MEM_RANGE_PTR (Rec
, Index
);
399 MemoryMap
.Base
= cb_unpack64 (Range
->start
);
400 MemoryMap
.Size
= cb_unpack64 (Range
->size
);
401 MemoryMap
.Type
= (UINT8
)Range
->type
;
405 "%d. %016lx - %016lx [%02x]\n",
408 MemoryMap
.Base
+ MemoryMap
.Size
- 1,
412 MemInfoCallback (&MemoryMap
, Params
);
415 return RETURN_SUCCESS
;
419 Acquire SMBIOS table from coreboot.
421 @param SmbiosTable Pointer to the SMBIOS table info.
423 @retval RETURN_SUCCESS Successfully find out the tables.
424 @retval RETURN_NOT_FOUND Failed to find the tables.
430 OUT UNIVERSAL_PAYLOAD_SMBIOS_TABLE
*SmbiosTable
437 Status
= ParseCbMemTable (SIGNATURE_32 ('T', 'B', 'M', 'S'), &MemTable
, &MemTableSize
);
438 if (EFI_ERROR (Status
)) {
439 return EFI_NOT_FOUND
;
442 SmbiosTable
->SmBiosEntryPoint
= (UINT64
)(UINTN
)MemTable
;
444 return RETURN_SUCCESS
;
448 Acquire ACPI table from coreboot.
450 @param AcpiTableHob Pointer to the ACPI table info.
452 @retval RETURN_SUCCESS Successfully find out the tables.
453 @retval RETURN_NOT_FOUND Failed to find the tables.
459 OUT UNIVERSAL_PAYLOAD_ACPI_TABLE
*AcpiTableHob
466 Status
= ParseCbMemTable (SIGNATURE_32 ('I', 'P', 'C', 'A'), &MemTable
, &MemTableSize
);
467 if (EFI_ERROR (Status
)) {
468 return EFI_NOT_FOUND
;
471 AcpiTableHob
->Rsdp
= (UINT64
)(UINTN
)MemTable
;
473 return RETURN_SUCCESS
;
477 Find the serial port information
479 @param SerialPortInfo Pointer to serial port info structure
481 @retval RETURN_SUCCESS Successfully find the serial port information.
482 @retval RETURN_NOT_FOUND Failed to find the serial port information .
488 OUT SERIAL_PORT_INFO
*SerialPortInfo
491 struct cb_serial
*CbSerial
;
493 CbSerial
= FindCbTag (CB_TAG_SERIAL
);
494 if (CbSerial
== NULL
) {
495 return RETURN_NOT_FOUND
;
498 SerialPortInfo
->BaseAddr
= CbSerial
->baseaddr
;
499 SerialPortInfo
->RegWidth
= CbSerial
->regwidth
;
500 SerialPortInfo
->Type
= CbSerial
->type
;
501 SerialPortInfo
->Baud
= CbSerial
->baud
;
502 SerialPortInfo
->InputHertz
= CbSerial
->input_hertz
;
503 SerialPortInfo
->UartPciAddr
= CbSerial
->uart_pci_addr
;
505 return RETURN_SUCCESS
;
509 Find the video frame buffer information
511 @param GfxInfo Pointer to the EFI_PEI_GRAPHICS_INFO_HOB structure
513 @retval RETURN_SUCCESS Successfully find the video frame buffer information.
514 @retval RETURN_NOT_FOUND Failed to find the video frame buffer information .
520 OUT EFI_PEI_GRAPHICS_INFO_HOB
*GfxInfo
523 struct cb_framebuffer
*CbFbRec
;
524 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*GfxMode
;
526 if (GfxInfo
== NULL
) {
527 return RETURN_INVALID_PARAMETER
;
530 CbFbRec
= FindCbTag (CB_TAG_FRAMEBUFFER
);
531 if (CbFbRec
== NULL
) {
532 return RETURN_NOT_FOUND
;
535 DEBUG ((DEBUG_INFO
, "Found coreboot video frame buffer information\n"));
536 DEBUG ((DEBUG_INFO
, "physical_address: 0x%lx\n", CbFbRec
->physical_address
));
537 DEBUG ((DEBUG_INFO
, "x_resolution: 0x%x\n", CbFbRec
->x_resolution
));
538 DEBUG ((DEBUG_INFO
, "y_resolution: 0x%x\n", CbFbRec
->y_resolution
));
539 DEBUG ((DEBUG_INFO
, "bits_per_pixel: 0x%x\n", CbFbRec
->bits_per_pixel
));
540 DEBUG ((DEBUG_INFO
, "bytes_per_line: 0x%x\n", CbFbRec
->bytes_per_line
));
542 DEBUG ((DEBUG_INFO
, "red_mask_size: 0x%x\n", CbFbRec
->red_mask_size
));
543 DEBUG ((DEBUG_INFO
, "red_mask_pos: 0x%x\n", CbFbRec
->red_mask_pos
));
544 DEBUG ((DEBUG_INFO
, "green_mask_size: 0x%x\n", CbFbRec
->green_mask_size
));
545 DEBUG ((DEBUG_INFO
, "green_mask_pos: 0x%x\n", CbFbRec
->green_mask_pos
));
546 DEBUG ((DEBUG_INFO
, "blue_mask_size: 0x%x\n", CbFbRec
->blue_mask_size
));
547 DEBUG ((DEBUG_INFO
, "blue_mask_pos: 0x%x\n", CbFbRec
->blue_mask_pos
));
548 DEBUG ((DEBUG_INFO
, "reserved_mask_size: 0x%x\n", CbFbRec
->reserved_mask_size
));
549 DEBUG ((DEBUG_INFO
, "reserved_mask_pos: 0x%x\n", CbFbRec
->reserved_mask_pos
));
551 GfxMode
= &GfxInfo
->GraphicsMode
;
552 GfxMode
->Version
= 0;
553 GfxMode
->HorizontalResolution
= CbFbRec
->x_resolution
;
554 GfxMode
->VerticalResolution
= CbFbRec
->y_resolution
;
555 GfxMode
->PixelsPerScanLine
= (CbFbRec
->bytes_per_line
<< 3) / CbFbRec
->bits_per_pixel
;
556 if ((CbFbRec
->red_mask_pos
== 0) && (CbFbRec
->green_mask_pos
== 8) && (CbFbRec
->blue_mask_pos
== 16)) {
557 GfxMode
->PixelFormat
= PixelRedGreenBlueReserved8BitPerColor
;
558 } else if ((CbFbRec
->blue_mask_pos
== 0) && (CbFbRec
->green_mask_pos
== 8) && (CbFbRec
->red_mask_pos
== 16)) {
559 GfxMode
->PixelFormat
= PixelBlueGreenRedReserved8BitPerColor
;
562 GfxMode
->PixelInformation
.RedMask
= ((1 << CbFbRec
->red_mask_size
) - 1) << CbFbRec
->red_mask_pos
;
563 GfxMode
->PixelInformation
.GreenMask
= ((1 << CbFbRec
->green_mask_size
) - 1) << CbFbRec
->green_mask_pos
;
564 GfxMode
->PixelInformation
.BlueMask
= ((1 << CbFbRec
->blue_mask_size
) - 1) << CbFbRec
->blue_mask_pos
;
565 GfxMode
->PixelInformation
.ReservedMask
= ((1 << CbFbRec
->reserved_mask_size
) - 1) << CbFbRec
->reserved_mask_pos
;
567 GfxInfo
->FrameBufferBase
= CbFbRec
->physical_address
;
568 GfxInfo
->FrameBufferSize
= CbFbRec
->bytes_per_line
* CbFbRec
->y_resolution
;
570 return RETURN_SUCCESS
;
574 Find the video frame buffer device information
576 @param GfxDeviceInfo Pointer to the EFI_PEI_GRAPHICS_DEVICE_INFO_HOB structure
578 @retval RETURN_SUCCESS Successfully find the video frame buffer information.
579 @retval RETURN_NOT_FOUND Failed to find the video frame buffer information.
585 OUT EFI_PEI_GRAPHICS_DEVICE_INFO_HOB
*GfxDeviceInfo
588 return RETURN_NOT_FOUND
;
592 Parse and handle the misc info provided by bootloader
594 @retval RETURN_SUCCESS The misc information was parsed successfully.
595 @retval RETURN_NOT_FOUND Could not find required misc info.
596 @retval RETURN_OUT_OF_RESOURCES Insufficant memory space.
605 return RETURN_SUCCESS
;