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