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>
22 Convert a packed value from cbuint64 to a UINT64 value.
24 @param val The pointer to packed data.
26 @return the UNIT64 value after conversion.
31 IN
struct cbuint64 val
34 return LShiftU64 (val
.hi
, 32) | val
.lo
;
39 Returns the sum of all elements in a buffer of 16-bit values. During
40 calculation, the carry bits are also been added.
42 @param Buffer The pointer to the buffer to carry out the sum operation.
43 @param Length The size, in bytes, of Buffer.
45 @return Sum The sum of Buffer with carry bits included during additions.
60 TmpPtr
= (UINT8
*)Buffer
;
61 for(Idx
= 0; Idx
< Length
; Idx
++) {
62 TmpValue
= TmpPtr
[Idx
];
71 Sum
= (Sum
+ (Sum
>> 16)) & 0xFFFF;
75 return (UINT16
)((~Sum
) & 0xFFFF);
80 Check the coreboot table if it is valid.
82 @param Header Pointer to coreboot table
84 @retval TRUE The coreboot table is valid.
85 @retval Others The coreboot table is not valid.
90 IN
struct cb_header
*Header
95 if ((Header
== NULL
) || (Header
->table_bytes
== 0)) {
99 if (Header
->signature
!= CB_HEADER_SIGNATURE
) {
104 // Check the checksum of the coreboot table header
106 CheckSum
= CbCheckSum16 ((UINT16
*)Header
, sizeof (*Header
));
108 DEBUG ((DEBUG_ERROR
, "Invalid coreboot table header checksum\n"));
112 CheckSum
= CbCheckSum16 ((UINT16
*)((UINT8
*)Header
+ sizeof (*Header
)), Header
->table_bytes
);
113 if (CheckSum
!= Header
->table_checksum
) {
114 DEBUG ((DEBUG_ERROR
, "Incorrect checksum of all the coreboot table entries\n"));
123 This function retrieves the parameter base address from boot loader.
125 This function will get bootloader specific parameter address for UEFI payload.
126 e.g. HobList pointer for Slim Bootloader, and coreboot table header for Coreboot.
128 @retval NULL Failed to find the GUID HOB.
129 @retval others GUIDed HOB data pointer.
138 struct cb_header
*Header
;
139 struct cb_record
*Record
;
146 // coreboot could pass coreboot table to UEFI payload
148 Header
= (struct cb_header
*)(UINTN
)GET_BOOTLOADER_PARAMETER ();
149 if (IsValidCbTable (Header
)) {
154 // Find simplified coreboot table in memory range 0 ~ 4KB.
155 // Some GCC version does not allow directly access to NULL pointer,
156 // so start the search from 0x10 instead.
158 for (Idx
= 16; Idx
< 4096; Idx
+= 16) {
159 Header
= (struct cb_header
*)Idx
;
160 if (Header
->signature
== CB_HEADER_SIGNATURE
) {
170 // Check the coreboot header
172 if (!IsValidCbTable (Header
)) {
177 // Find full coreboot table in high memory
180 TmpPtr
= (UINT8
*)Header
+ Header
->header_bytes
;
181 for (Idx
= 0; Idx
< Header
->table_entries
; Idx
++) {
182 Record
= (struct cb_record
*)TmpPtr
;
183 if (Record
->tag
== CB_TAG_FORWARD
) {
184 CbTablePtr
= (VOID
*)(UINTN
)((struct cb_forward
*)(UINTN
)Record
)->forward
;
187 TmpPtr
+= Record
->size
;
191 // Check the coreboot header in high memory
193 if (!IsValidCbTable ((struct cb_header
*)CbTablePtr
)) {
197 Status
= PcdSet64S (PcdBootloaderParameter
, (UINTN
)CbTablePtr
);
198 ASSERT_EFI_ERROR (Status
);
205 Find coreboot record with given Tag.
207 @param Tag The tag id to be found
209 @retval NULL The Tag is not found.
210 @retval Others The pointer to the record found.
218 struct cb_header
*Header
;
219 struct cb_record
*Record
;
224 Header
= (struct cb_header
*) GetParameterBase ();
227 TmpPtr
= (UINT8
*)Header
+ Header
->header_bytes
;
228 for (Idx
= 0; Idx
< Header
->table_entries
; Idx
++) {
229 Record
= (struct cb_record
*)TmpPtr
;
230 if (Record
->tag
== Tag
) {
234 TmpPtr
+= Record
->size
;
242 Find the given table with TableId from the given coreboot memory Root.
244 @param Root The coreboot memory table to be searched in
245 @param TableId Table id to be found
246 @param MemTable To save the base address of the memory table found
247 @param MemTableSize To save the size of memory table found
249 @retval RETURN_SUCCESS Successfully find out the memory table.
250 @retval RETURN_INVALID_PARAMETER Invalid input parameters.
251 @retval RETURN_NOT_FOUND Failed to find the memory table.
256 IN
struct cbmem_root
*Root
,
259 OUT UINT32
*MemTableSize
264 struct cbmem_entry
*Entries
;
266 if ((Root
== NULL
) || (MemTable
== NULL
)) {
267 return RETURN_INVALID_PARAMETER
;
270 // Check if the entry is CBMEM or IMD
271 // and handle them separately
273 Entries
= Root
->entries
;
274 if (Entries
[0].magic
== CBMEM_ENTRY_MAGIC
) {
277 Entries
= (struct cbmem_entry
*)((struct imd_root
*)Root
)->entries
;
278 if (Entries
[0].magic
== IMD_ENTRY_MAGIC
) {
281 return RETURN_NOT_FOUND
;
285 for (Idx
= 0; Idx
< Root
->num_entries
; Idx
++) {
286 if (Entries
[Idx
].id
== TableId
) {
288 *MemTable
= (VOID
*) ((UINTN
)Entries
[Idx
].start
+ (UINTN
)Root
);
290 *MemTable
= (VOID
*) (UINTN
)Entries
[Idx
].start
;
292 if (MemTableSize
!= NULL
) {
293 *MemTableSize
= Entries
[Idx
].size
;
296 DEBUG ((DEBUG_INFO
, "Find CbMemTable Id 0x%x, base %p, size 0x%x\n",
297 TableId
, *MemTable
, Entries
[Idx
].size
));
298 return RETURN_SUCCESS
;
302 return RETURN_NOT_FOUND
;
306 Acquire the coreboot memory table with the given table id
308 @param TableId Table id to be searched
309 @param MemTable Pointer to the base address of the memory table
310 @param MemTableSize Pointer to the size of the memory table
312 @retval RETURN_SUCCESS Successfully find out the memory table.
313 @retval RETURN_INVALID_PARAMETER Invalid input parameters.
314 @retval RETURN_NOT_FOUND Failed to find the memory table.
321 OUT UINT32
*MemTableSize
326 struct cb_memory_range
*Range
;
330 struct cbmem_root
*CbMemRoot
;
332 if (MemTable
== NULL
) {
333 return RETURN_INVALID_PARAMETER
;
337 Status
= RETURN_NOT_FOUND
;
340 // Get the coreboot memory table
342 Rec
= (CB_MEMORY
*)FindCbTag (CB_TAG_MEMORY
);
347 for (Index
= 0; Index
< MEM_RANGE_COUNT(Rec
); Index
++) {
348 Range
= MEM_RANGE_PTR(Rec
, Index
);
349 Start
= cb_unpack64(Range
->start
);
350 Size
= cb_unpack64(Range
->size
);
352 if ((Range
->type
== CB_MEM_TABLE
) && (Start
> 0x1000)) {
353 CbMemRoot
= (struct cbmem_root
*)(UINTN
)(Start
+ Size
- DYN_CBMEM_ALIGN_SIZE
);
354 Status
= FindCbMemTable (CbMemRoot
, TableId
, MemTable
, MemTableSize
);
355 if (!EFI_ERROR (Status
)) {
367 Acquire the memory information from the coreboot table in memory.
369 @param MemInfoCallback The callback routine
370 @param Params Pointer to the callback routine parameter
372 @retval RETURN_SUCCESS Successfully find out the memory information.
373 @retval RETURN_NOT_FOUND Failed to find the memory information.
379 IN BL_MEM_INFO_CALLBACK MemInfoCallback
,
384 struct cb_memory_range
*Range
;
386 MEMORY_MAP_ENTRY MemoryMap
;
389 // Get the coreboot memory table
391 Rec
= (CB_MEMORY
*)FindCbTag (CB_TAG_MEMORY
);
393 return RETURN_NOT_FOUND
;
396 for (Index
= 0; Index
< MEM_RANGE_COUNT(Rec
); Index
++) {
397 Range
= MEM_RANGE_PTR(Rec
, Index
);
398 MemoryMap
.Base
= cb_unpack64(Range
->start
);
399 MemoryMap
.Size
= cb_unpack64(Range
->size
);
400 MemoryMap
.Type
= (UINT8
)Range
->type
;
402 DEBUG ((DEBUG_INFO
, "%d. %016lx - %016lx [%02x]\n",
403 Index
, MemoryMap
.Base
, MemoryMap
.Base
+ MemoryMap
.Size
- 1, MemoryMap
.Type
));
405 MemInfoCallback (&MemoryMap
, Params
);
408 return RETURN_SUCCESS
;
413 Acquire acpi table and smbios table from coreboot
415 @param SystemTableInfo Pointer to the system table info
417 @retval RETURN_SUCCESS Successfully find out the tables.
418 @retval RETURN_NOT_FOUND Failed to find the tables.
424 OUT SYSTEM_TABLE_INFO
*SystemTableInfo
431 Status
= ParseCbMemTable (SIGNATURE_32 ('T', 'B', 'M', 'S'), &MemTable
, &MemTableSize
);
432 if (EFI_ERROR (Status
)) {
433 return EFI_NOT_FOUND
;
435 SystemTableInfo
->SmbiosTableBase
= (UINT64
) (UINTN
)MemTable
;
436 SystemTableInfo
->SmbiosTableSize
= MemTableSize
;
438 Status
= ParseCbMemTable (SIGNATURE_32 ('I', 'P', 'C', 'A'), &MemTable
, &MemTableSize
);
439 if (EFI_ERROR (Status
)) {
440 return EFI_NOT_FOUND
;
442 SystemTableInfo
->AcpiTableBase
= (UINT64
) (UINTN
)MemTable
;
443 SystemTableInfo
->AcpiTableSize
= MemTableSize
;
450 Find the serial port information
452 @param SerialPortInfo Pointer to serial port info structure
454 @retval RETURN_SUCCESS Successfully find the serial port information.
455 @retval RETURN_NOT_FOUND Failed to find the serial port information .
461 OUT SERIAL_PORT_INFO
*SerialPortInfo
464 struct cb_serial
*CbSerial
;
466 CbSerial
= FindCbTag (CB_TAG_SERIAL
);
467 if (CbSerial
== NULL
) {
468 return RETURN_NOT_FOUND
;
471 SerialPortInfo
->BaseAddr
= CbSerial
->baseaddr
;
472 SerialPortInfo
->RegWidth
= CbSerial
->regwidth
;
473 SerialPortInfo
->Type
= CbSerial
->type
;
474 SerialPortInfo
->Baud
= CbSerial
->baud
;
475 SerialPortInfo
->InputHertz
= CbSerial
->input_hertz
;
476 SerialPortInfo
->UartPciAddr
= CbSerial
->uart_pci_addr
;
478 return RETURN_SUCCESS
;
482 Find the video frame buffer information
484 @param GfxInfo Pointer to the EFI_PEI_GRAPHICS_INFO_HOB structure
486 @retval RETURN_SUCCESS Successfully find the video frame buffer information.
487 @retval RETURN_NOT_FOUND Failed to find the video frame buffer information .
493 OUT EFI_PEI_GRAPHICS_INFO_HOB
*GfxInfo
496 struct cb_framebuffer
*CbFbRec
;
497 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*GfxMode
;
499 if (GfxInfo
== NULL
) {
500 return RETURN_INVALID_PARAMETER
;
503 CbFbRec
= FindCbTag (CB_TAG_FRAMEBUFFER
);
504 if (CbFbRec
== NULL
) {
505 return RETURN_NOT_FOUND
;
508 DEBUG ((DEBUG_INFO
, "Found coreboot video frame buffer information\n"));
509 DEBUG ((DEBUG_INFO
, "physical_address: 0x%lx\n", CbFbRec
->physical_address
));
510 DEBUG ((DEBUG_INFO
, "x_resolution: 0x%x\n", CbFbRec
->x_resolution
));
511 DEBUG ((DEBUG_INFO
, "y_resolution: 0x%x\n", CbFbRec
->y_resolution
));
512 DEBUG ((DEBUG_INFO
, "bits_per_pixel: 0x%x\n", CbFbRec
->bits_per_pixel
));
513 DEBUG ((DEBUG_INFO
, "bytes_per_line: 0x%x\n", CbFbRec
->bytes_per_line
));
515 DEBUG ((DEBUG_INFO
, "red_mask_size: 0x%x\n", CbFbRec
->red_mask_size
));
516 DEBUG ((DEBUG_INFO
, "red_mask_pos: 0x%x\n", CbFbRec
->red_mask_pos
));
517 DEBUG ((DEBUG_INFO
, "green_mask_size: 0x%x\n", CbFbRec
->green_mask_size
));
518 DEBUG ((DEBUG_INFO
, "green_mask_pos: 0x%x\n", CbFbRec
->green_mask_pos
));
519 DEBUG ((DEBUG_INFO
, "blue_mask_size: 0x%x\n", CbFbRec
->blue_mask_size
));
520 DEBUG ((DEBUG_INFO
, "blue_mask_pos: 0x%x\n", CbFbRec
->blue_mask_pos
));
521 DEBUG ((DEBUG_INFO
, "reserved_mask_size: 0x%x\n", CbFbRec
->reserved_mask_size
));
522 DEBUG ((DEBUG_INFO
, "reserved_mask_pos: 0x%x\n", CbFbRec
->reserved_mask_pos
));
524 GfxMode
= &GfxInfo
->GraphicsMode
;
525 GfxMode
->Version
= 0;
526 GfxMode
->HorizontalResolution
= CbFbRec
->x_resolution
;
527 GfxMode
->VerticalResolution
= CbFbRec
->y_resolution
;
528 GfxMode
->PixelsPerScanLine
= (CbFbRec
->bytes_per_line
<< 3) / CbFbRec
->bits_per_pixel
;
529 if ((CbFbRec
->red_mask_pos
== 0) && (CbFbRec
->green_mask_pos
== 8) && (CbFbRec
->blue_mask_pos
== 16)) {
530 GfxMode
->PixelFormat
= PixelRedGreenBlueReserved8BitPerColor
;
531 } else if ((CbFbRec
->blue_mask_pos
== 0) && (CbFbRec
->green_mask_pos
== 8) && (CbFbRec
->red_mask_pos
== 16)) {
532 GfxMode
->PixelFormat
= PixelBlueGreenRedReserved8BitPerColor
;
534 GfxMode
->PixelInformation
.RedMask
= ((1 << CbFbRec
->red_mask_size
) - 1) << CbFbRec
->red_mask_pos
;
535 GfxMode
->PixelInformation
.GreenMask
= ((1 << CbFbRec
->green_mask_size
) - 1) << CbFbRec
->green_mask_pos
;
536 GfxMode
->PixelInformation
.BlueMask
= ((1 << CbFbRec
->blue_mask_size
) - 1) << CbFbRec
->blue_mask_pos
;
537 GfxMode
->PixelInformation
.ReservedMask
= ((1 << CbFbRec
->reserved_mask_size
) - 1) << CbFbRec
->reserved_mask_pos
;
539 GfxInfo
->FrameBufferBase
= CbFbRec
->physical_address
;
540 GfxInfo
->FrameBufferSize
= CbFbRec
->bytes_per_line
* CbFbRec
->y_resolution
;
542 return RETURN_SUCCESS
;
546 Find the video frame buffer device information
548 @param GfxDeviceInfo Pointer to the EFI_PEI_GRAPHICS_DEVICE_INFO_HOB structure
550 @retval RETURN_SUCCESS Successfully find the video frame buffer information.
551 @retval RETURN_NOT_FOUND Failed to find the video frame buffer information.
557 OUT EFI_PEI_GRAPHICS_DEVICE_INFO_HOB
*GfxDeviceInfo
560 return RETURN_NOT_FOUND
;
564 Parse and handle the misc info provided by bootloader
566 @retval RETURN_SUCCESS The misc information was parsed successfully.
567 @retval RETURN_NOT_FOUND Could not find required misc info.
568 @retval RETURN_OUT_OF_RESOURCES Insufficant memory space.
577 return RETURN_SUCCESS
;