CbParseLib.c 21 KB

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