]> git.proxmox.com Git - mirror_edk2.git/blob - CorebootModulePkg/Library/CbParseLib/CbParseLib.c
38f31bd9751c3641013a769bf912e5dc7c09842a
[mirror_edk2.git] / CorebootModulePkg / Library / CbParseLib / CbParseLib.c
1 /** @file
2 This library will parse the coreboot table in memory and extract those required
3 information.
4
5 Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8 **/
9
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/CbParseLib.h>
17
18 #include <IndustryStandard/Acpi.h>
19
20 #include "Coreboot.h"
21
22
23 /**
24 Convert a packed value from cbuint64 to a UINT64 value.
25
26 @param val The pointer to packed data.
27
28 @return the UNIT64 value after conversion.
29
30 **/
31 UINT64
32 cb_unpack64 (
33 IN struct cbuint64 val
34 )
35 {
36 return LShiftU64 (val.hi, 32) | val.lo;
37 }
38
39
40 /**
41 Returns the sum of all elements in a buffer of 16-bit values. During
42 calculation, the carry bits are also been added.
43
44 @param Buffer The pointer to the buffer to carry out the sum operation.
45 @param Length The size, in bytes, of Buffer.
46
47 @return Sum The sum of Buffer with carry bits included during additions.
48
49 **/
50 UINT16
51 CbCheckSum16 (
52 IN UINT16 *Buffer,
53 IN UINTN Length
54 )
55 {
56 UINT32 Sum, TmpValue;
57 UINTN Idx;
58 UINT8 *TmpPtr;
59
60 Sum = 0;
61 TmpPtr = (UINT8 *)Buffer;
62 for(Idx = 0; Idx < Length; Idx++) {
63 TmpValue = TmpPtr[Idx];
64 if (Idx % 2 == 1) {
65 TmpValue <<= 8;
66 }
67
68 Sum += TmpValue;
69
70 // Wrap
71 if (Sum >= 0x10000) {
72 Sum = (Sum + (Sum >> 16)) & 0xFFFF;
73 }
74 }
75
76 return (UINT16)((~Sum) & 0xFFFF);
77 }
78
79
80 /**
81 Find coreboot record with given Tag from the memory Start in 4096
82 bytes range.
83
84 @param Start The start memory to be searched in
85 @param Tag The tag id to be found
86
87 @retval NULL The Tag is not found.
88 @retval Others The pointer to the record found.
89
90 **/
91 VOID *
92 EFIAPI
93 FindCbTag (
94 IN VOID *Start,
95 IN UINT32 Tag
96 )
97 {
98 struct cb_header *Header;
99 struct cb_record *Record;
100 UINT8 *TmpPtr;
101 UINT8 *TagPtr;
102 UINTN Idx;
103 UINT16 CheckSum;
104
105 Header = NULL;
106 TmpPtr = (UINT8 *)Start;
107 for (Idx = 0; Idx < 4096; Idx += 16, TmpPtr += 16) {
108 Header = (struct cb_header *)TmpPtr;
109 if (Header->signature == CB_HEADER_SIGNATURE) {
110 break;
111 }
112 }
113
114 if (Idx >= 4096) {
115 return NULL;
116 }
117
118 if ((Header == NULL) || (Header->table_bytes == 0)) {
119 return NULL;
120 }
121
122 //
123 // Check the checksum of the coreboot table header
124 //
125 CheckSum = CbCheckSum16 ((UINT16 *)Header, sizeof (*Header));
126 if (CheckSum != 0) {
127 DEBUG ((EFI_D_ERROR, "Invalid coreboot table header checksum\n"));
128 return NULL;
129 }
130
131 CheckSum = CbCheckSum16 ((UINT16 *)(TmpPtr + sizeof (*Header)), Header->table_bytes);
132 if (CheckSum != Header->table_checksum) {
133 DEBUG ((EFI_D_ERROR, "Incorrect checksum of all the coreboot table entries\n"));
134 return NULL;
135 }
136
137 TagPtr = NULL;
138 TmpPtr += Header->header_bytes;
139 for (Idx = 0; Idx < Header->table_entries; Idx++) {
140 Record = (struct cb_record *)TmpPtr;
141 if (Record->tag == CB_TAG_FORWARD) {
142 TmpPtr = (VOID *)(UINTN)((struct cb_forward *)(UINTN)Record)->forward;
143 if (Tag == CB_TAG_FORWARD) {
144 return TmpPtr;
145 } else {
146 return FindCbTag (TmpPtr, Tag);
147 }
148 }
149 if (Record->tag == Tag) {
150 TagPtr = TmpPtr;
151 break;
152 }
153 TmpPtr += Record->size;
154 }
155
156 return TagPtr;
157 }
158
159
160 /**
161 Find the given table with TableId from the given coreboot memory Root.
162
163 @param Root The coreboot memory table to be searched in
164 @param TableId Table id to be found
165 @param pMemTable To save the base address of the memory table found
166 @param pMemTableSize To save the size of memory table found
167
168 @retval RETURN_SUCCESS Successfully find out the memory table.
169 @retval RETURN_INVALID_PARAMETER Invalid input parameters.
170 @retval RETURN_NOT_FOUND Failed to find the memory table.
171
172 **/
173 RETURN_STATUS
174 EFIAPI
175 FindCbMemTable (
176 IN struct cbmem_root *Root,
177 IN UINT32 TableId,
178 OUT VOID **pMemTable,
179 OUT UINT32 *pMemTableSize
180 )
181 {
182 UINTN Idx;
183 BOOLEAN IsImdEntry;
184 struct cbmem_entry *Entries;
185
186 if ((Root == NULL) || (pMemTable == NULL)) {
187 return RETURN_INVALID_PARAMETER;
188 }
189 //
190 // Check if the entry is CBMEM or IMD
191 // and handle them separately
192 //
193 Entries = Root->entries;
194 if (Entries[0].magic == CBMEM_ENTRY_MAGIC) {
195 IsImdEntry = FALSE;
196 } else {
197 Entries = (struct cbmem_entry *)((struct imd_root *)Root)->entries;
198 if (Entries[0].magic == IMD_ENTRY_MAGIC) {
199 IsImdEntry = TRUE;
200 } else {
201 return RETURN_NOT_FOUND;
202 }
203 }
204
205 for (Idx = 0; Idx < Root->num_entries; Idx++) {
206 if (Entries[Idx].id == TableId) {
207 if (IsImdEntry) {
208 *pMemTable = (VOID *) ((UINTN)Entries[Idx].start + (UINTN)Root);
209 } else {
210 *pMemTable = (VOID *) (UINTN)Entries[Idx].start;
211 }
212 if (pMemTableSize != NULL) {
213 *pMemTableSize = Entries[Idx].size;
214 }
215
216 DEBUG ((EFI_D_INFO, "Find CbMemTable Id 0x%x, base %p, size 0x%x\n",
217 TableId, *pMemTable, Entries[Idx].size));
218 return RETURN_SUCCESS;
219 }
220 }
221
222 return RETURN_NOT_FOUND;
223 }
224
225
226 /**
227 Acquire the memory information from the coreboot table in memory.
228
229 @param MemInfoCallback The callback routine
230 @param pParam Pointer to the callback routine parameter
231
232 @retval RETURN_SUCCESS Successfully find out the memory information.
233 @retval RETURN_NOT_FOUND Failed to find the memory information.
234
235 **/
236 RETURN_STATUS
237 EFIAPI
238 CbParseMemoryInfo (
239 IN CB_MEM_INFO_CALLBACK MemInfoCallback,
240 IN VOID *pParam
241 )
242 {
243 struct cb_memory *rec;
244 struct cb_memory_range *Range;
245 UINT64 Start;
246 UINT64 Size;
247 UINTN Index;
248
249 //
250 // Get the coreboot memory table
251 //
252 rec = (struct cb_memory *)FindCbTag (0, CB_TAG_MEMORY);
253 if (rec == NULL) {
254 rec = (struct cb_memory *)FindCbTag ((VOID *)(UINTN)PcdGet32 (PcdCbHeaderPointer), CB_TAG_MEMORY);
255 }
256
257 if (rec == NULL) {
258 return RETURN_NOT_FOUND;
259 }
260
261 for (Index = 0; Index < MEM_RANGE_COUNT(rec); Index++) {
262 Range = MEM_RANGE_PTR(rec, Index);
263 Start = cb_unpack64(Range->start);
264 Size = cb_unpack64(Range->size);
265 DEBUG ((EFI_D_INFO, "%d. %016lx - %016lx [%02x]\n",
266 Index, Start, Start + Size - 1, Range->type));
267
268 MemInfoCallback (Start, Size, Range->type, pParam);
269 }
270
271 return RETURN_SUCCESS;
272 }
273
274
275 /**
276 Acquire the coreboot memory table with the given table id
277
278 @param TableId Table id to be searched
279 @param pMemTable Pointer to the base address of the memory table
280 @param pMemTableSize Pointer to the size of the memory table
281
282 @retval RETURN_SUCCESS Successfully find out the memory table.
283 @retval RETURN_INVALID_PARAMETER Invalid input parameters.
284 @retval RETURN_NOT_FOUND Failed to find the memory table.
285
286 **/
287 RETURN_STATUS
288 EFIAPI
289 CbParseCbMemTable (
290 IN UINT32 TableId,
291 OUT VOID **pMemTable,
292 OUT UINT32 *pMemTableSize
293 )
294 {
295 struct cb_memory *rec;
296 struct cb_memory_range *Range;
297 UINT64 Start;
298 UINT64 Size;
299 UINTN Index;
300
301 if (pMemTable == NULL) {
302 return RETURN_INVALID_PARAMETER;
303 }
304 *pMemTable = NULL;
305
306 //
307 // Get the coreboot memory table
308 //
309 rec = (struct cb_memory *)FindCbTag (0, CB_TAG_MEMORY);
310 if (rec == NULL) {
311 rec = (struct cb_memory *)FindCbTag ((VOID *)(UINTN)PcdGet32 (PcdCbHeaderPointer), CB_TAG_MEMORY);
312 }
313
314 if (rec == NULL) {
315 return RETURN_NOT_FOUND;
316 }
317
318 for (Index = 0; Index < MEM_RANGE_COUNT(rec); Index++) {
319 Range = MEM_RANGE_PTR(rec, Index);
320 Start = cb_unpack64(Range->start);
321 Size = cb_unpack64(Range->size);
322
323 if ((Range->type == CB_MEM_TABLE) && (Start > 0x1000)) {
324 if (FindCbMemTable ((struct cbmem_root *)(UINTN)(Start + Size - DYN_CBMEM_ALIGN_SIZE), TableId, pMemTable, pMemTableSize) == RETURN_SUCCESS)
325 return RETURN_SUCCESS;
326 }
327 }
328
329 return RETURN_NOT_FOUND;
330 }
331
332
333 /**
334 Acquire the acpi table from coreboot
335
336 @param pMemTable Pointer to the base address of the memory table
337 @param pMemTableSize Pointer to the size of the memory table
338
339 @retval RETURN_SUCCESS Successfully find out the memory table.
340 @retval RETURN_INVALID_PARAMETER Invalid input parameters.
341 @retval RETURN_NOT_FOUND Failed to find the memory table.
342
343 **/
344 RETURN_STATUS
345 EFIAPI
346 CbParseAcpiTable (
347 OUT VOID **pMemTable,
348 OUT UINT32 *pMemTableSize
349 )
350 {
351 return CbParseCbMemTable (SIGNATURE_32 ('I', 'P', 'C', 'A'), pMemTable, pMemTableSize);
352 }
353
354 /**
355 Acquire the smbios table from coreboot
356
357 @param pMemTable Pointer to the base address of the memory table
358 @param pMemTableSize Pointer to the size of the memory table
359
360 @retval RETURN_SUCCESS Successfully find out the memory table.
361 @retval RETURN_INVALID_PARAMETER Invalid input parameters.
362 @retval RETURN_NOT_FOUND Failed to find the memory table.
363
364 **/
365 RETURN_STATUS
366 EFIAPI
367 CbParseSmbiosTable (
368 OUT VOID **pMemTable,
369 OUT UINT32 *pMemTableSize
370 )
371 {
372 return CbParseCbMemTable (SIGNATURE_32 ('T', 'B', 'M', 'S'), pMemTable, pMemTableSize);
373 }
374
375 /**
376 Find the required fadt information
377
378 @param pPmCtrlReg Pointer to the address of power management control register
379 @param pPmTimerReg Pointer to the address of power management timer register
380 @param pResetReg Pointer to the address of system reset register
381 @param pResetValue Pointer to the value to be written to the system reset register
382 @param pPmEvtReg Pointer to the address of power management event register
383 @param pPmGpeEnReg Pointer to the address of power management GPE enable register
384
385 @retval RETURN_SUCCESS Successfully find out all the required fadt information.
386 @retval RETURN_NOT_FOUND Failed to find the fadt table.
387
388 **/
389 RETURN_STATUS
390 EFIAPI
391 CbParseFadtInfo (
392 OUT UINTN *pPmCtrlReg,
393 OUT UINTN *pPmTimerReg,
394 OUT UINTN *pResetReg,
395 OUT UINTN *pResetValue,
396 OUT UINTN *pPmEvtReg,
397 OUT UINTN *pPmGpeEnReg
398 )
399 {
400 EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp;
401 EFI_ACPI_DESCRIPTION_HEADER *Rsdt;
402 UINT32 *Entry32;
403 UINTN Entry32Num;
404 EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt;
405 EFI_ACPI_DESCRIPTION_HEADER *Xsdt;
406 UINT64 *Entry64;
407 UINTN Entry64Num;
408 UINTN Idx;
409 RETURN_STATUS Status;
410
411 Rsdp = NULL;
412 Status = RETURN_SUCCESS;
413
414 Status = CbParseAcpiTable ((VOID **)&Rsdp, NULL);
415 if (RETURN_ERROR(Status)) {
416 return Status;
417 }
418
419 if (Rsdp == NULL) {
420 return RETURN_NOT_FOUND;
421 }
422
423 DEBUG ((EFI_D_INFO, "Find Rsdp at %p\n", Rsdp));
424 DEBUG ((EFI_D_INFO, "Find Rsdt 0x%x, Xsdt 0x%lx\n", Rsdp->RsdtAddress, Rsdp->XsdtAddress));
425
426 //
427 // Search Rsdt First
428 //
429 Rsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)(Rsdp->RsdtAddress);
430 if (Rsdt != NULL) {
431 Entry32 = (UINT32 *)(Rsdt + 1);
432 Entry32Num = (Rsdt->Length - sizeof(EFI_ACPI_DESCRIPTION_HEADER)) >> 2;
433 for (Idx = 0; Idx < Entry32Num; Idx++) {
434 if (*(UINT32 *)(UINTN)(Entry32[Idx]) == EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE) {
435 Fadt = (EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *)(UINTN)(Entry32[Idx]);
436 if (pPmCtrlReg != NULL) {
437 *pPmCtrlReg = Fadt->Pm1aCntBlk;
438 }
439 DEBUG ((EFI_D_INFO, "PmCtrl Reg 0x%x\n", Fadt->Pm1aCntBlk));
440
441 if (pPmTimerReg != NULL) {
442 *pPmTimerReg = Fadt->PmTmrBlk;
443 }
444 DEBUG ((EFI_D_INFO, "PmTimer Reg 0x%x\n", Fadt->PmTmrBlk));
445
446 if (pResetReg != NULL) {
447 *pResetReg = (UINTN)Fadt->ResetReg.Address;
448 }
449 DEBUG ((EFI_D_INFO, "Reset Reg 0x%lx\n", Fadt->ResetReg.Address));
450
451 if (pResetValue != NULL) {
452 *pResetValue = Fadt->ResetValue;
453 }
454 DEBUG ((EFI_D_INFO, "Reset Value 0x%x\n", Fadt->ResetValue));
455
456 if (pPmEvtReg != NULL) {
457 *pPmEvtReg = Fadt->Pm1aEvtBlk;
458 DEBUG ((EFI_D_INFO, "PmEvt Reg 0x%x\n", Fadt->Pm1aEvtBlk));
459 }
460
461 if (pPmGpeEnReg != NULL) {
462 *pPmGpeEnReg = Fadt->Gpe0Blk + Fadt->Gpe0BlkLen / 2;
463 DEBUG ((EFI_D_INFO, "PmGpeEn Reg 0x%x\n", *pPmGpeEnReg));
464 }
465
466 //
467 // Verify values for proper operation
468 //
469 ASSERT(Fadt->Pm1aCntBlk != 0);
470 ASSERT(Fadt->PmTmrBlk != 0);
471 ASSERT(Fadt->ResetReg.Address != 0);
472 ASSERT(Fadt->Pm1aEvtBlk != 0);
473 ASSERT(Fadt->Gpe0Blk != 0);
474
475 DEBUG_CODE_BEGIN ();
476 BOOLEAN SciEnabled;
477
478 //
479 // Check the consistency of SCI enabling
480 //
481
482 //
483 // Get SCI_EN value
484 //
485 if (Fadt->Pm1CntLen == 4) {
486 SciEnabled = (IoRead32 (Fadt->Pm1aCntBlk) & BIT0)? TRUE : FALSE;
487 } else {
488 //
489 // if (Pm1CntLen == 2), use 16 bit IO read;
490 // if (Pm1CntLen != 2 && Pm1CntLen != 4), use 16 bit IO read as a fallback
491 //
492 SciEnabled = (IoRead16 (Fadt->Pm1aCntBlk) & BIT0)? TRUE : FALSE;
493 }
494
495 if (!(Fadt->Flags & EFI_ACPI_5_0_HW_REDUCED_ACPI) &&
496 (Fadt->SmiCmd == 0) &&
497 !SciEnabled) {
498 //
499 // The ACPI enabling status is inconsistent: SCI is not enabled but ACPI
500 // table does not provide a means to enable it through FADT->SmiCmd
501 //
502 DEBUG ((DEBUG_ERROR, "ERROR: The ACPI enabling status is inconsistent: SCI is not"
503 " enabled but the ACPI table does not provide a means to enable it through FADT->SmiCmd."
504 " This may cause issues in OS.\n"));
505 ASSERT (FALSE);
506 }
507 DEBUG_CODE_END ();
508 return RETURN_SUCCESS;
509 }
510 }
511 }
512
513 //
514 // Search Xsdt Second
515 //
516 Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)(Rsdp->XsdtAddress);
517 if (Xsdt != NULL) {
518 Entry64 = (UINT64 *)(Xsdt + 1);
519 Entry64Num = (Xsdt->Length - sizeof(EFI_ACPI_DESCRIPTION_HEADER)) >> 3;
520 for (Idx = 0; Idx < Entry64Num; Idx++) {
521 if (*(UINT32 *)(UINTN)(Entry64[Idx]) == EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE) {
522 Fadt = (EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *)(UINTN)(Entry64[Idx]);
523 if (pPmCtrlReg)
524 *pPmCtrlReg = Fadt->Pm1aCntBlk;
525 DEBUG ((EFI_D_ERROR, "PmCtrl Reg 0x%x\n", Fadt->Pm1aCntBlk));
526
527 if (pPmTimerReg)
528 *pPmTimerReg = Fadt->PmTmrBlk;
529 DEBUG ((EFI_D_ERROR, "PmTimer Reg 0x%x\n", Fadt->PmTmrBlk));
530
531 if (pResetReg)
532 *pResetReg = (UINTN)Fadt->ResetReg.Address;
533 DEBUG ((EFI_D_ERROR, "Reset Reg 0x%lx\n", Fadt->ResetReg.Address));
534
535 if (pResetValue)
536 *pResetValue = Fadt->ResetValue;
537 DEBUG ((EFI_D_ERROR, "Reset Value 0x%x\n", Fadt->ResetValue));
538
539 if (pPmEvtReg != NULL) {
540 *pPmEvtReg = Fadt->Pm1aEvtBlk;
541 DEBUG ((EFI_D_INFO, "PmEvt Reg 0x%x\n", Fadt->Pm1aEvtBlk));
542 }
543
544 if (pPmGpeEnReg != NULL) {
545 *pPmGpeEnReg = Fadt->Gpe0Blk + Fadt->Gpe0BlkLen / 2;
546 DEBUG ((EFI_D_INFO, "PmGpeEn Reg 0x%x\n", *pPmGpeEnReg));
547 }
548 return RETURN_SUCCESS;
549 }
550 }
551 }
552
553 return RETURN_NOT_FOUND;
554 }
555
556 /**
557 Find the serial port information
558
559 @param pRegBase Pointer to the base address of serial port registers
560 @param pRegAccessType Pointer to the access type of serial port registers
561 @param pRegWidth Pointer to the register width in bytes
562 @param pBaudrate Pointer to the serial port baudrate
563 @param pInputHertz Pointer to the input clock frequency
564 @param pUartPciAddr Pointer to the UART PCI bus, dev and func address
565
566 @retval RETURN_SUCCESS Successfully find the serial port information.
567 @retval RETURN_NOT_FOUND Failed to find the serial port information .
568
569 **/
570 RETURN_STATUS
571 EFIAPI
572 CbParseSerialInfo (
573 OUT UINT32 *pRegBase,
574 OUT UINT32 *pRegAccessType,
575 OUT UINT32 *pRegWidth,
576 OUT UINT32 *pBaudrate,
577 OUT UINT32 *pInputHertz,
578 OUT UINT32 *pUartPciAddr
579 )
580 {
581 struct cb_serial *CbSerial;
582
583 CbSerial = FindCbTag (0, CB_TAG_SERIAL);
584 if (CbSerial == NULL) {
585 CbSerial = FindCbTag ((VOID *)(UINTN)PcdGet32 (PcdCbHeaderPointer), CB_TAG_SERIAL);
586 }
587
588 if (CbSerial == NULL) {
589 return RETURN_NOT_FOUND;
590 }
591
592 if (pRegBase != NULL) {
593 *pRegBase = CbSerial->baseaddr;
594 }
595
596 if (pRegWidth != NULL) {
597 *pRegWidth = CbSerial->regwidth;
598 }
599
600 if (pRegAccessType != NULL) {
601 *pRegAccessType = CbSerial->type;
602 }
603
604 if (pBaudrate != NULL) {
605 *pBaudrate = CbSerial->baud;
606 }
607
608 if (pInputHertz != NULL) {
609 *pInputHertz = CbSerial->input_hertz;
610 }
611
612 if (pUartPciAddr != NULL) {
613 *pUartPciAddr = CbSerial->uart_pci_addr;
614 }
615
616 return RETURN_SUCCESS;
617 }
618
619 /**
620 Search for the coreboot table header
621
622 @param Level Level of the search depth
623 @param HeaderPtr Pointer to the pointer of coreboot table header
624
625 @retval RETURN_SUCCESS Successfully find the coreboot table header .
626 @retval RETURN_NOT_FOUND Failed to find the coreboot table header .
627
628 **/
629 RETURN_STATUS
630 EFIAPI
631 CbParseGetCbHeader (
632 IN UINTN Level,
633 OUT VOID **HeaderPtr
634 )
635 {
636 UINTN Index;
637 VOID *TempPtr;
638
639 if (HeaderPtr == NULL) {
640 return RETURN_NOT_FOUND;
641 }
642
643 TempPtr = NULL;
644 for (Index = 0; Index < Level; Index++) {
645 TempPtr = FindCbTag (TempPtr, CB_TAG_FORWARD);
646 if (TempPtr == NULL) {
647 break;
648 }
649 }
650
651 if ((Index >= Level) && (TempPtr != NULL)) {
652 *HeaderPtr = TempPtr;
653 return RETURN_SUCCESS;
654 }
655
656 return RETURN_NOT_FOUND;
657 }
658
659 /**
660 Find the video frame buffer information
661
662 @param pFbInfo Pointer to the FRAME_BUFFER_INFO structure
663
664 @retval RETURN_SUCCESS Successfully find the video frame buffer information.
665 @retval RETURN_NOT_FOUND Failed to find the video frame buffer information .
666
667 **/
668 RETURN_STATUS
669 EFIAPI
670 CbParseFbInfo (
671 OUT FRAME_BUFFER_INFO *pFbInfo
672 )
673 {
674 struct cb_framebuffer *CbFbRec;
675
676 if (pFbInfo == NULL) {
677 return RETURN_INVALID_PARAMETER;
678 }
679
680 CbFbRec = FindCbTag (0, CB_TAG_FRAMEBUFFER);
681 if (CbFbRec == NULL) {
682 CbFbRec = FindCbTag ((VOID *)(UINTN)PcdGet32 (PcdCbHeaderPointer), CB_TAG_FRAMEBUFFER);
683 }
684
685 if (CbFbRec == NULL) {
686 return RETURN_NOT_FOUND;
687 }
688
689 DEBUG ((EFI_D_INFO, "Found coreboot video frame buffer information\n"));
690 DEBUG ((EFI_D_INFO, "physical_address: 0x%lx\n", CbFbRec->physical_address));
691 DEBUG ((EFI_D_INFO, "x_resolution: 0x%x\n", CbFbRec->x_resolution));
692 DEBUG ((EFI_D_INFO, "y_resolution: 0x%x\n", CbFbRec->y_resolution));
693 DEBUG ((EFI_D_INFO, "bits_per_pixel: 0x%x\n", CbFbRec->bits_per_pixel));
694 DEBUG ((EFI_D_INFO, "bytes_per_line: 0x%x\n", CbFbRec->bytes_per_line));
695
696 DEBUG ((EFI_D_INFO, "red_mask_size: 0x%x\n", CbFbRec->red_mask_size));
697 DEBUG ((EFI_D_INFO, "red_mask_pos: 0x%x\n", CbFbRec->red_mask_pos));
698 DEBUG ((EFI_D_INFO, "green_mask_size: 0x%x\n", CbFbRec->green_mask_size));
699 DEBUG ((EFI_D_INFO, "green_mask_pos: 0x%x\n", CbFbRec->green_mask_pos));
700 DEBUG ((EFI_D_INFO, "blue_mask_size: 0x%x\n", CbFbRec->blue_mask_size));
701 DEBUG ((EFI_D_INFO, "blue_mask_pos: 0x%x\n", CbFbRec->blue_mask_pos));
702 DEBUG ((EFI_D_INFO, "reserved_mask_size: 0x%x\n", CbFbRec->reserved_mask_size));
703 DEBUG ((EFI_D_INFO, "reserved_mask_pos: 0x%x\n", CbFbRec->reserved_mask_pos));
704
705 pFbInfo->LinearFrameBuffer = CbFbRec->physical_address;
706 pFbInfo->HorizontalResolution = CbFbRec->x_resolution;
707 pFbInfo->VerticalResolution = CbFbRec->y_resolution;
708 pFbInfo->BitsPerPixel = CbFbRec->bits_per_pixel;
709 pFbInfo->BytesPerScanLine = (UINT16)CbFbRec->bytes_per_line;
710 pFbInfo->Red.Mask = (1 << CbFbRec->red_mask_size) - 1;
711 pFbInfo->Red.Position = CbFbRec->red_mask_pos;
712 pFbInfo->Green.Mask = (1 << CbFbRec->green_mask_size) - 1;
713 pFbInfo->Green.Position = CbFbRec->green_mask_pos;
714 pFbInfo->Blue.Mask = (1 << CbFbRec->blue_mask_size) - 1;
715 pFbInfo->Blue.Position = CbFbRec->blue_mask_pos;
716 pFbInfo->Reserved.Mask = (1 << CbFbRec->reserved_mask_size) - 1;
717 pFbInfo->Reserved.Position = CbFbRec->reserved_mask_pos;
718
719 return RETURN_SUCCESS;
720 }
721