2 This library will parse the coreboot table in memory and extract those required
5 Copyright (c) 2014 - 2016, 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
;
145 // coreboot could pass coreboot table to UEFI payload
147 Header
= (struct cb_header
*)(UINTN
)GET_BOOTLOADER_PARAMETER ();
148 if (IsValidCbTable (Header
)) {
153 // Find simplified coreboot table in memory range 0 ~ 4KB.
154 // Some GCC version does not allow directly access to NULL pointer,
155 // so start the search from 0x10 instead.
157 for (Idx
= 16; Idx
< 4096; Idx
+= 16) {
158 Header
= (struct cb_header
*)Idx
;
159 if (Header
->signature
== CB_HEADER_SIGNATURE
) {
169 // Check the coreboot header
171 if (!IsValidCbTable (Header
)) {
176 // Find full coreboot table in high memory
179 TmpPtr
= (UINT8
*)Header
+ Header
->header_bytes
;
180 for (Idx
= 0; Idx
< Header
->table_entries
; Idx
++) {
181 Record
= (struct cb_record
*)TmpPtr
;
182 if (Record
->tag
== CB_TAG_FORWARD
) {
183 CbTablePtr
= (VOID
*)(UINTN
)((struct cb_forward
*)(UINTN
)Record
)->forward
;
186 TmpPtr
+= Record
->size
;
190 // Check the coreboot header in high memory
192 if (!IsValidCbTable ((struct cb_header
*)CbTablePtr
)) {
196 SET_BOOTLOADER_PARAMETER ((UINT32
)(UINTN
)CbTablePtr
);
203 Find coreboot record with given Tag.
205 @param Tag The tag id to be found
207 @retval NULL The Tag is not found.
208 @retval Others The pointer to the record found.
216 struct cb_header
*Header
;
217 struct cb_record
*Record
;
222 Header
= (struct cb_header
*) GetParameterBase ();
225 TmpPtr
= (UINT8
*)Header
+ Header
->header_bytes
;
226 for (Idx
= 0; Idx
< Header
->table_entries
; Idx
++) {
227 Record
= (struct cb_record
*)TmpPtr
;
228 if (Record
->tag
== Tag
) {
232 TmpPtr
+= Record
->size
;
240 Find the given table with TableId from the given coreboot memory Root.
242 @param Root The coreboot memory table to be searched in
243 @param TableId Table id to be found
244 @param MemTable To save the base address of the memory table found
245 @param MemTableSize To save the size of memory table found
247 @retval RETURN_SUCCESS Successfully find out the memory table.
248 @retval RETURN_INVALID_PARAMETER Invalid input parameters.
249 @retval RETURN_NOT_FOUND Failed to find the memory table.
254 IN
struct cbmem_root
*Root
,
257 OUT UINT32
*MemTableSize
262 struct cbmem_entry
*Entries
;
264 if ((Root
== NULL
) || (MemTable
== NULL
)) {
265 return RETURN_INVALID_PARAMETER
;
268 // Check if the entry is CBMEM or IMD
269 // and handle them separately
271 Entries
= Root
->entries
;
272 if (Entries
[0].magic
== CBMEM_ENTRY_MAGIC
) {
275 Entries
= (struct cbmem_entry
*)((struct imd_root
*)Root
)->entries
;
276 if (Entries
[0].magic
== IMD_ENTRY_MAGIC
) {
279 return RETURN_NOT_FOUND
;
283 for (Idx
= 0; Idx
< Root
->num_entries
; Idx
++) {
284 if (Entries
[Idx
].id
== TableId
) {
286 *MemTable
= (VOID
*) ((UINTN
)Entries
[Idx
].start
+ (UINTN
)Root
);
288 *MemTable
= (VOID
*) (UINTN
)Entries
[Idx
].start
;
290 if (MemTableSize
!= NULL
) {
291 *MemTableSize
= Entries
[Idx
].size
;
294 DEBUG ((DEBUG_INFO
, "Find CbMemTable Id 0x%x, base %p, size 0x%x\n",
295 TableId
, *MemTable
, Entries
[Idx
].size
));
296 return RETURN_SUCCESS
;
300 return RETURN_NOT_FOUND
;
304 Acquire the coreboot memory table with the given table id
306 @param TableId Table id to be searched
307 @param MemTable Pointer to the base address of the memory table
308 @param MemTableSize Pointer to the size of the memory table
310 @retval RETURN_SUCCESS Successfully find out the memory table.
311 @retval RETURN_INVALID_PARAMETER Invalid input parameters.
312 @retval RETURN_NOT_FOUND Failed to find the memory table.
319 OUT UINT32
*MemTableSize
323 struct cb_memory
*rec
;
324 struct cb_memory_range
*Range
;
328 struct cbmem_root
*CbMemRoot
;
330 if (MemTable
== NULL
) {
331 return RETURN_INVALID_PARAMETER
;
335 Status
= RETURN_NOT_FOUND
;
338 // Get the coreboot memory table
340 rec
= (struct cb_memory
*)FindCbTag (CB_TAG_MEMORY
);
345 for (Index
= 0; Index
< MEM_RANGE_COUNT(rec
); Index
++) {
346 Range
= MEM_RANGE_PTR(rec
, Index
);
347 Start
= cb_unpack64(Range
->start
);
348 Size
= cb_unpack64(Range
->size
);
350 if ((Range
->type
== CB_MEM_TABLE
) && (Start
> 0x1000)) {
351 CbMemRoot
= (struct cbmem_root
*)(UINTN
)(Start
+ Size
- DYN_CBMEM_ALIGN_SIZE
);
352 Status
= FindCbMemTable (CbMemRoot
, TableId
, MemTable
, MemTableSize
);
353 if (!EFI_ERROR (Status
)) {
365 Acquire the memory information from the coreboot table in memory.
367 @param MemInfoCallback The callback routine
368 @param Params Pointer to the callback routine parameter
370 @retval RETURN_SUCCESS Successfully find out the memory information.
371 @retval RETURN_NOT_FOUND Failed to find the memory information.
377 IN BL_MEM_INFO_CALLBACK MemInfoCallback
,
381 struct cb_memory
*rec
;
382 struct cb_memory_range
*Range
;
384 MEMROY_MAP_ENTRY MemoryMap
;
387 // Get the coreboot memory table
389 rec
= (struct cb_memory
*)FindCbTag (CB_TAG_MEMORY
);
391 return RETURN_NOT_FOUND
;
394 for (Index
= 0; Index
< MEM_RANGE_COUNT(rec
); Index
++) {
395 Range
= MEM_RANGE_PTR(rec
, Index
);
396 MemoryMap
.Base
= cb_unpack64(Range
->start
);
397 MemoryMap
.Size
= cb_unpack64(Range
->size
);
398 MemoryMap
.Type
= (UINT8
)Range
->type
;
400 DEBUG ((DEBUG_INFO
, "%d. %016lx - %016lx [%02x]\n",
401 Index
, MemoryMap
.Base
, MemoryMap
.Base
+ MemoryMap
.Size
- 1, MemoryMap
.Type
));
403 MemInfoCallback (&MemoryMap
, Params
);
406 return RETURN_SUCCESS
;
411 Acquire acpi table and smbios table from coreboot
413 @param SystemTableInfo Pointer to the system table info
415 @retval RETURN_SUCCESS Successfully find out the tables.
416 @retval RETURN_NOT_FOUND Failed to find the tables.
422 OUT SYSTEM_TABLE_INFO
*SystemTableInfo
429 Status
= ParseCbMemTable (SIGNATURE_32 ('T', 'B', 'M', 'S'), &MemTable
, &MemTableSize
);
430 if (EFI_ERROR (Status
)) {
431 return EFI_NOT_FOUND
;
433 SystemTableInfo
->SmbiosTableBase
= (UINT64
) (UINTN
)MemTable
;
434 SystemTableInfo
->SmbiosTableSize
= MemTableSize
;
436 Status
= ParseCbMemTable (SIGNATURE_32 ('I', 'P', 'C', 'A'), &MemTable
, &MemTableSize
);
437 if (EFI_ERROR (Status
)) {
438 return EFI_NOT_FOUND
;
440 SystemTableInfo
->AcpiTableBase
= (UINT64
) (UINTN
)MemTable
;
441 SystemTableInfo
->AcpiTableSize
= MemTableSize
;
448 Find the serial port information
450 @param SERIAL_PORT_INFO Pointer to serial port info structure
452 @retval RETURN_SUCCESS Successfully find the serial port information.
453 @retval RETURN_NOT_FOUND Failed to find the serial port information .
459 OUT SERIAL_PORT_INFO
*SerialPortInfo
462 struct cb_serial
*CbSerial
;
464 CbSerial
= FindCbTag (CB_TAG_SERIAL
);
465 if (CbSerial
== NULL
) {
466 return RETURN_NOT_FOUND
;
469 SerialPortInfo
->BaseAddr
= CbSerial
->baseaddr
;
470 SerialPortInfo
->RegWidth
= CbSerial
->regwidth
;
471 SerialPortInfo
->Type
= CbSerial
->type
;
472 SerialPortInfo
->Baud
= CbSerial
->baud
;
473 SerialPortInfo
->InputHertz
= CbSerial
->input_hertz
;
474 SerialPortInfo
->UartPciAddr
= CbSerial
->uart_pci_addr
;
476 return RETURN_SUCCESS
;
480 Find the video frame buffer information
482 @param GfxInfo Pointer to the EFI_PEI_GRAPHICS_INFO_HOB structure
484 @retval RETURN_SUCCESS Successfully find the video frame buffer information.
485 @retval RETURN_NOT_FOUND Failed to find the video frame buffer information .
491 OUT EFI_PEI_GRAPHICS_INFO_HOB
*GfxInfo
494 struct cb_framebuffer
*CbFbRec
;
495 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*GfxMode
;
497 if (GfxInfo
== NULL
) {
498 return RETURN_INVALID_PARAMETER
;
501 CbFbRec
= FindCbTag (CB_TAG_FRAMEBUFFER
);
502 if (CbFbRec
== NULL
) {
503 return RETURN_NOT_FOUND
;
506 DEBUG ((DEBUG_INFO
, "Found coreboot video frame buffer information\n"));
507 DEBUG ((DEBUG_INFO
, "physical_address: 0x%lx\n", CbFbRec
->physical_address
));
508 DEBUG ((DEBUG_INFO
, "x_resolution: 0x%x\n", CbFbRec
->x_resolution
));
509 DEBUG ((DEBUG_INFO
, "y_resolution: 0x%x\n", CbFbRec
->y_resolution
));
510 DEBUG ((DEBUG_INFO
, "bits_per_pixel: 0x%x\n", CbFbRec
->bits_per_pixel
));
511 DEBUG ((DEBUG_INFO
, "bytes_per_line: 0x%x\n", CbFbRec
->bytes_per_line
));
513 DEBUG ((DEBUG_INFO
, "red_mask_size: 0x%x\n", CbFbRec
->red_mask_size
));
514 DEBUG ((DEBUG_INFO
, "red_mask_pos: 0x%x\n", CbFbRec
->red_mask_pos
));
515 DEBUG ((DEBUG_INFO
, "green_mask_size: 0x%x\n", CbFbRec
->green_mask_size
));
516 DEBUG ((DEBUG_INFO
, "green_mask_pos: 0x%x\n", CbFbRec
->green_mask_pos
));
517 DEBUG ((DEBUG_INFO
, "blue_mask_size: 0x%x\n", CbFbRec
->blue_mask_size
));
518 DEBUG ((DEBUG_INFO
, "blue_mask_pos: 0x%x\n", CbFbRec
->blue_mask_pos
));
519 DEBUG ((DEBUG_INFO
, "reserved_mask_size: 0x%x\n", CbFbRec
->reserved_mask_size
));
520 DEBUG ((DEBUG_INFO
, "reserved_mask_pos: 0x%x\n", CbFbRec
->reserved_mask_pos
));
522 GfxMode
= &GfxInfo
->GraphicsMode
;
523 GfxMode
->Version
= 0;
524 GfxMode
->HorizontalResolution
= CbFbRec
->x_resolution
;
525 GfxMode
->VerticalResolution
= CbFbRec
->y_resolution
;
526 GfxMode
->PixelsPerScanLine
= (CbFbRec
->bytes_per_line
<< 3) / CbFbRec
->bits_per_pixel
;
527 if ((CbFbRec
->red_mask_pos
== 0) && (CbFbRec
->green_mask_pos
== 8) && (CbFbRec
->blue_mask_pos
== 16)) {
528 GfxMode
->PixelFormat
= PixelRedGreenBlueReserved8BitPerColor
;
529 } else if ((CbFbRec
->blue_mask_pos
== 0) && (CbFbRec
->green_mask_pos
== 8) && (CbFbRec
->red_mask_pos
== 16)) {
530 GfxMode
->PixelFormat
= PixelBlueGreenRedReserved8BitPerColor
;
532 GfxMode
->PixelInformation
.RedMask
= ((1 << CbFbRec
->red_mask_size
) - 1) << CbFbRec
->red_mask_pos
;
533 GfxMode
->PixelInformation
.GreenMask
= ((1 << CbFbRec
->green_mask_size
) - 1) << CbFbRec
->green_mask_pos
;
534 GfxMode
->PixelInformation
.BlueMask
= ((1 << CbFbRec
->blue_mask_size
) - 1) << CbFbRec
->blue_mask_pos
;
535 GfxMode
->PixelInformation
.ReservedMask
= ((1 << CbFbRec
->reserved_mask_size
) - 1) << CbFbRec
->reserved_mask_pos
;
537 GfxInfo
->FrameBufferBase
= CbFbRec
->physical_address
;
538 GfxInfo
->FrameBufferSize
= CbFbRec
->bytes_per_line
* CbFbRec
->y_resolution
;
540 return RETURN_SUCCESS
;
544 Find the video frame buffer device information
546 @param GfxDeviceInfo Pointer to the EFI_PEI_GRAPHICS_DEVICE_INFO_HOB structure
548 @retval RETURN_SUCCESS Successfully find the video frame buffer information.
549 @retval RETURN_NOT_FOUND Failed to find the video frame buffer information.
555 OUT EFI_PEI_GRAPHICS_DEVICE_INFO_HOB
*GfxDeviceInfo
558 return RETURN_NOT_FOUND
;