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