TianoCore EDK2 master
Loading...
Searching...
No Matches
CbParseLib.c
Go to the documentation of this file.
1
10#include <Uefi/UefiBaseType.h>
11#include <Library/BaseLib.h>
13#include <Library/DebugLib.h>
14#include <Library/PcdLib.h>
15#include <Library/IoLib.h>
16#include <Library/BlParseLib.h>
18#include <Coreboot.h>
19
28UINT64
30 IN struct cbuint64 val
31 )
32{
33 return LShiftU64 (val.hi, 32) | val.lo;
34}
35
46UINT16
48 IN UINT16 *Buffer,
49 IN UINTN Length
50 )
51{
52 UINT32 Sum;
53 UINT32 TmpValue;
54 UINTN Idx;
55 UINT8 *TmpPtr;
56
57 Sum = 0;
58 TmpPtr = (UINT8 *)Buffer;
59 for (Idx = 0; Idx < Length; Idx++) {
60 TmpValue = TmpPtr[Idx];
61 if (Idx % 2 == 1) {
62 TmpValue <<= 8;
63 }
64
65 Sum += TmpValue;
66
67 // Wrap
68 if (Sum >= 0x10000) {
69 Sum = (Sum + (Sum >> 16)) & 0xFFFF;
70 }
71 }
72
73 return (UINT16)((~Sum) & 0xFFFF);
74}
75
85BOOLEAN
87 IN struct cb_header *Header
88 )
89{
90 UINT16 CheckSum;
91
92 if ((Header == NULL) || (Header->table_bytes == 0)) {
93 return FALSE;
94 }
95
96 if (Header->signature != CB_HEADER_SIGNATURE) {
97 return FALSE;
98 }
99
100 //
101 // Check the checksum of the coreboot table header
102 //
103 CheckSum = CbCheckSum16 ((UINT16 *)Header, sizeof (*Header));
104 if (CheckSum != 0) {
105 DEBUG ((DEBUG_ERROR, "Invalid coreboot table header checksum\n"));
106 return FALSE;
107 }
108
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"));
112 return FALSE;
113 }
114
115 return TRUE;
116}
117
128VOID *
129EFIAPI
131 VOID
132 )
133{
134 struct cb_header *Header;
135 struct cb_record *Record;
136 UINT8 *TmpPtr;
137 UINT8 *CbTablePtr;
138 UINTN Idx;
139 EFI_STATUS Status;
140
141 //
142 // coreboot could pass coreboot table to UEFI payload
143 //
144 Header = (struct cb_header *)(UINTN)GET_BOOTLOADER_PARAMETER ();
145 if (IsValidCbTable (Header)) {
146 return Header;
147 }
148
149 //
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.
153 //
154 for (Idx = 16; Idx < 4096; Idx += 16) {
155 Header = (struct cb_header *)Idx;
156 if (Header->signature == CB_HEADER_SIGNATURE) {
157 break;
158 }
159 }
160
161 if (Idx >= 4096) {
162 return NULL;
163 }
164
165 //
166 // Check the coreboot header
167 //
168 if (!IsValidCbTable (Header)) {
169 return NULL;
170 }
171
172 //
173 // Find full coreboot table in high memory
174 //
175 CbTablePtr = NULL;
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;
181 break;
182 }
183
184 TmpPtr += Record->size;
185 }
186
187 //
188 // Check the coreboot header in high memory
189 //
190 if (!IsValidCbTable ((struct cb_header *)CbTablePtr)) {
191 return NULL;
192 }
193
194 Status = PcdSet64S (PcdBootloaderParameter, (UINTN)CbTablePtr);
195 ASSERT_EFI_ERROR (Status);
196
197 return CbTablePtr;
198}
199
209VOID *
211 IN UINT32 Tag
212 )
213{
214 struct cb_header *Header;
215 struct cb_record *Record;
216 UINT8 *TmpPtr;
217 UINT8 *TagPtr;
218 UINTN Idx;
219
220 Header = (struct cb_header *)GetParameterBase ();
221
222 TagPtr = NULL;
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) {
227 TagPtr = TmpPtr;
228 break;
229 }
230
231 TmpPtr += Record->size;
232 }
233
234 return TagPtr;
235}
236
250RETURN_STATUS
252 IN struct cbmem_root *Root,
253 IN UINT32 TableId,
254 OUT VOID **MemTable,
255 OUT UINT32 *MemTableSize
256 )
257{
258 UINTN Idx;
259 BOOLEAN IsImdEntry;
260 struct cbmem_entry *Entries;
261
262 if ((Root == NULL) || (MemTable == NULL)) {
264 }
265
266 //
267 // Check if the entry is CBMEM or IMD
268 // and handle them separately
269 //
270 Entries = Root->entries;
271 if (Entries[0].magic == CBMEM_ENTRY_MAGIC) {
272 IsImdEntry = FALSE;
273 } else {
274 Entries = (struct cbmem_entry *)((struct imd_root *)Root)->entries;
275 if (Entries[0].magic == IMD_ENTRY_MAGIC) {
276 IsImdEntry = TRUE;
277 } else {
278 return RETURN_NOT_FOUND;
279 }
280 }
281
282 for (Idx = 0; Idx < Root->num_entries; Idx++) {
283 if (Entries[Idx].id == TableId) {
284 if (IsImdEntry) {
285 *MemTable = (VOID *)((INTN)(INT32)Entries[Idx].start + (UINTN)Root);
286 } else {
287 *MemTable = (VOID *)(UINTN)Entries[Idx].start;
288 }
289
290 if (MemTableSize != NULL) {
291 *MemTableSize = Entries[Idx].size;
292 }
293
294 DEBUG ((
295 DEBUG_INFO,
296 "Find CbMemTable Id 0x%x, base %p, size 0x%x\n",
297 TableId,
298 *MemTable,
299 Entries[Idx].size
300 ));
301 return RETURN_SUCCESS;
302 }
303 }
304
305 return RETURN_NOT_FOUND;
306}
307
320RETURN_STATUS
322 IN UINT32 TableId,
323 OUT VOID **MemTable,
324 OUT UINT32 *MemTableSize
325 )
326{
327 EFI_STATUS Status;
328 CB_MEMORY *Rec;
329 struct cb_memory_range *Range;
330 UINT64 Start;
331 UINT64 Size;
332 UINTN Index;
333 struct cbmem_root *CbMemRoot;
334
335 if (MemTable == NULL) {
337 }
338
339 *MemTable = NULL;
340 Status = RETURN_NOT_FOUND;
341
342 //
343 // Get the coreboot memory table
344 //
345 Rec = (CB_MEMORY *)FindCbTag (CB_TAG_MEMORY);
346 if (Rec == NULL) {
347 return Status;
348 }
349
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);
354
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)) {
359 break;
360 }
361 }
362 }
363
364 return Status;
365}
366
377RETURN_STATUS
378EFIAPI
380 IN BL_MEM_INFO_CALLBACK MemInfoCallback,
381 IN VOID *Params
382 )
383{
384 CB_MEMORY *Rec;
385 struct cb_memory_range *Range;
386 UINTN Index;
387 MEMORY_MAP_ENTRY MemoryMap;
388
389 //
390 // Get the coreboot memory table
391 //
392 Rec = (CB_MEMORY *)FindCbTag (CB_TAG_MEMORY);
393 if (Rec == NULL) {
394 return RETURN_NOT_FOUND;
395 }
396
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;
402 MemoryMap.Flag = 0;
403 DEBUG ((
404 DEBUG_INFO,
405 "%d. %016lx - %016lx [%02x]\n",
406 Index,
407 MemoryMap.Base,
408 MemoryMap.Base + MemoryMap.Size - 1,
409 MemoryMap.Type
410 ));
411
412 MemInfoCallback (&MemoryMap, Params);
413 }
414
415 return RETURN_SUCCESS;
416}
417
427RETURN_STATUS
428EFIAPI
431 )
432{
433 EFI_STATUS Status;
434 VOID *MemTable;
435 UINT32 MemTableSize;
436
437 Status = ParseCbMemTable (SIGNATURE_32 ('T', 'B', 'M', 'S'), &MemTable, &MemTableSize);
438 if (EFI_ERROR (Status)) {
439 return EFI_NOT_FOUND;
440 }
441
442 SmbiosTable->SmBiosEntryPoint = (UINT64)(UINTN)MemTable;
443
444 return RETURN_SUCCESS;
445}
446
456RETURN_STATUS
457EFIAPI
460 )
461{
462 EFI_STATUS Status;
463 VOID *MemTable;
464 UINT32 MemTableSize;
465
466 Status = ParseCbMemTable (SIGNATURE_32 ('I', 'P', 'C', 'A'), &MemTable, &MemTableSize);
467 if (EFI_ERROR (Status)) {
468 return EFI_NOT_FOUND;
469 }
470
471 AcpiTableHob->Rsdp = (UINT64)(UINTN)MemTable;
472
473 return RETURN_SUCCESS;
474}
475
485RETURN_STATUS
486EFIAPI
488 OUT SERIAL_PORT_INFO *SerialPortInfo
489 )
490{
491 struct cb_serial *CbSerial;
492
493 CbSerial = FindCbTag (CB_TAG_SERIAL);
494 if (CbSerial == NULL) {
495 return RETURN_NOT_FOUND;
496 }
497
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;
504
505 return RETURN_SUCCESS;
506}
507
517RETURN_STATUS
518EFIAPI
521 )
522{
523 struct cb_framebuffer *CbFbRec;
525
526 if (GfxInfo == NULL) {
528 }
529
530 CbFbRec = FindCbTag (CB_TAG_FRAMEBUFFER);
531 if (CbFbRec == NULL) {
532 return RETURN_NOT_FOUND;
533 }
534
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));
541
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));
550
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)) {
558 } else if ((CbFbRec->blue_mask_pos == 0) && (CbFbRec->green_mask_pos == 8) && (CbFbRec->red_mask_pos == 16)) {
560 }
561
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;
566
567 GfxInfo->FrameBufferBase = CbFbRec->physical_address;
568 GfxInfo->FrameBufferSize = CbFbRec->bytes_per_line * CbFbRec->y_resolution;
569
570 return RETURN_SUCCESS;
571}
572
582RETURN_STATUS
583EFIAPI
586 )
587{
588 return RETURN_NOT_FOUND;
589}
590
599RETURN_STATUS
600EFIAPI
602 VOID
603 )
604{
605 return RETURN_SUCCESS;
606}
UINT64 UINTN
INT64 INTN
UINT64 EFIAPI LShiftU64(IN UINT64 Operand, IN UINTN Count)
Definition: LShiftU64.c:28
UINT64 cb_unpack64(IN struct cbuint64 val)
Definition: CbParseLib.c:29
RETURN_STATUS EFIAPI ParseSmbiosTable(OUT UNIVERSAL_PAYLOAD_SMBIOS_TABLE *SmbiosTable)
Definition: CbParseLib.c:429
UINT16 CbCheckSum16(IN UINT16 *Buffer, IN UINTN Length)
Definition: CbParseLib.c:47
BOOLEAN IsValidCbTable(IN struct cb_header *Header)
Definition: CbParseLib.c:86
VOID * FindCbTag(IN UINT32 Tag)
Definition: CbParseLib.c:210
RETURN_STATUS EFIAPI ParseMemoryInfo(IN BL_MEM_INFO_CALLBACK MemInfoCallback, IN VOID *Params)
Definition: CbParseLib.c:379
RETURN_STATUS ParseCbMemTable(IN UINT32 TableId, OUT VOID **MemTable, OUT UINT32 *MemTableSize)
Definition: CbParseLib.c:321
RETURN_STATUS EFIAPI ParseGfxDeviceInfo(OUT EFI_PEI_GRAPHICS_DEVICE_INFO_HOB *GfxDeviceInfo)
Definition: CbParseLib.c:584
RETURN_STATUS EFIAPI ParseGfxInfo(OUT EFI_PEI_GRAPHICS_INFO_HOB *GfxInfo)
Definition: CbParseLib.c:519
RETURN_STATUS EFIAPI ParseAcpiTableInfo(OUT UNIVERSAL_PAYLOAD_ACPI_TABLE *AcpiTableHob)
Definition: CbParseLib.c:458
RETURN_STATUS EFIAPI ParseSerialInfo(OUT SERIAL_PORT_INFO *SerialPortInfo)
Definition: CbParseLib.c:487
VOID *EFIAPI GetParameterBase(VOID)
Definition: CbParseLib.c:130
RETURN_STATUS EFIAPI ParseMiscInfo(VOID)
Definition: CbParseLib.c:601
RETURN_STATUS FindCbMemTable(IN struct cbmem_root *Root, IN UINT32 TableId, OUT VOID **MemTable, OUT UINT32 *MemTableSize)
Definition: CbParseLib.c:251
#define NULL
Definition: Base.h:319
#define RETURN_NOT_FOUND
Definition: Base.h:1142
#define RETURN_SUCCESS
Definition: Base.h:1066
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define SIGNATURE_32(A, B, C, D)
Definition: Base.h:1310
#define OUT
Definition: Base.h:284
#define RETURN_INVALID_PARAMETER
Definition: Base.h:1076
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG(Expression)
Definition: DebugLib.h:434
@ PixelRedGreenBlueReserved8BitPerColor
@ PixelBlueGreenRedReserved8BitPerColor
#define PcdSet64S(TokenName, Value)
Definition: PcdLib.h:511
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
EFI_STATUS MemInfoCallback(IN MEMORY_MAP_ENTRY *MemoryMapEntry, IN VOID *Params)
EFI_GRAPHICS_PIXEL_FORMAT PixelFormat
Definition: Coreboot.h:50