]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c
ShellPkg/UefiShellAcpiViewCommandLib: Fix ECC issues
[mirror_edk2.git] / ShellPkg / Library / UefiShellAcpiViewCommandLib / AcpiParser.c
CommitLineData
a6eaba4d 1/** @file\r
ee4dc24f
RN
2 ACPI parser\r
3\r
4 Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.\r
5 This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12**/\r
13\r
14#include <Uefi.h>\r
15#include <Library/UefiLib.h>\r
16#include <Library/UefiBootServicesTableLib.h>\r
17#include "AcpiParser.h"\r
18#include "AcpiView.h"\r
19\r
20STATIC UINT32 gIndent;\r
21STATIC UINT32 mTableErrorCount;\r
22STATIC UINT32 mTableWarningCount;\r
23\r
a6eaba4d
DB
24/**\r
25 This function resets the ACPI table error counter to Zero.\r
26**/\r
ee4dc24f
RN
27VOID\r
28ResetErrorCount (\r
29 VOID\r
30 )\r
31{\r
32 mTableErrorCount = 0;\r
33}\r
34\r
a6eaba4d
DB
35/**\r
36 This function returns the ACPI table error count.\r
ee4dc24f
RN
37\r
38 @retval Returns the count of errors detected in the ACPI tables.\r
a6eaba4d 39**/\r
ee4dc24f
RN
40UINT32\r
41GetErrorCount (\r
42 VOID\r
43 )\r
44{\r
45 return mTableErrorCount;\r
46}\r
47\r
a6eaba4d
DB
48/**\r
49 This function resets the ACPI table warning counter to Zero.\r
50**/\r
ee4dc24f
RN
51VOID\r
52ResetWarningCount (\r
53 VOID\r
54 )\r
55{\r
56 mTableWarningCount = 0;\r
57}\r
58\r
a6eaba4d
DB
59/**\r
60 This function returns the ACPI table warning count.\r
ee4dc24f
RN
61\r
62 @retval Returns the count of warning detected in the ACPI tables.\r
a6eaba4d 63**/\r
ee4dc24f
RN
64UINT32\r
65GetWarningCount (\r
66 VOID\r
67 )\r
68{\r
69 return mTableWarningCount;\r
70}\r
71\r
a6eaba4d
DB
72/**\r
73 This function increments the ACPI table error counter.\r
74**/\r
ee4dc24f
RN
75VOID\r
76EFIAPI\r
77IncrementErrorCount (\r
78 VOID\r
79 )\r
80{\r
81 mTableErrorCount++;\r
82}\r
83\r
a6eaba4d
DB
84/**\r
85 This function increments the ACPI table warning counter.\r
86**/\r
ee4dc24f
RN
87VOID\r
88EFIAPI\r
89IncrementWarningCount (\r
90 VOID\r
91 )\r
92{\r
93 mTableWarningCount++;\r
94}\r
95\r
a6eaba4d
DB
96/**\r
97 This function verifies the ACPI table checksum.\r
ee4dc24f
RN
98\r
99 This function verifies the checksum for the ACPI table and optionally\r
100 prints the status.\r
101\r
102 @param [in] Log If TRUE log the status of the checksum.\r
103 @param [in] Ptr Pointer to the start of the table buffer.\r
104 @param [in] Length The length of the buffer.\r
105\r
106 @retval TRUE The checksum is OK.\r
107 @retval FALSE The checksum failed.\r
a6eaba4d 108**/\r
ee4dc24f
RN
109BOOLEAN\r
110EFIAPI\r
111VerifyChecksum (\r
112 IN BOOLEAN Log,\r
113 IN UINT8* Ptr,\r
114 IN UINT32 Length\r
115 )\r
116{\r
117 UINTN ByteCount = 0;\r
118 UINT8 Checksum = 0;\r
119 UINTN OriginalAttribute;\r
120\r
121 while (ByteCount < Length) {\r
122 Checksum += *(Ptr++);\r
123 ByteCount++;\r
124 }\r
125\r
126 if (Log) {\r
127 OriginalAttribute = gST->ConOut->Mode->Attribute;\r
128 if (Checksum == 0) {\r
129 if (GetColourHighlighting ()) {\r
130 gST->ConOut->SetAttribute (\r
131 gST->ConOut,\r
132 EFI_TEXT_ATTR (EFI_GREEN,\r
133 ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4))\r
134 );\r
135 }\r
136 Print (L"\n\nTable Checksum : OK\n\n");\r
137 } else {\r
138 IncrementErrorCount ();\r
139 if (GetColourHighlighting ()) {\r
140 gST->ConOut->SetAttribute (\r
141 gST->ConOut,\r
142 EFI_TEXT_ATTR (EFI_RED,\r
143 ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4))\r
144 );\r
145 }\r
146 Print (L"\n\nTable Checksum : FAILED (0x%X)\n\n", Checksum);\r
147 }\r
148 if (GetColourHighlighting ()) {\r
149 gST->ConOut->SetAttribute (gST->ConOut, OriginalAttribute);\r
150 }\r
151 }\r
152\r
153 return (Checksum == 0);\r
154}\r
155\r
a6eaba4d
DB
156/**\r
157 This function performs a raw data dump of the ACPI table.\r
ee4dc24f
RN
158\r
159 @param [in] Ptr Pointer to the start of the table buffer.\r
160 @param [in] Length The length of the buffer.\r
a6eaba4d 161**/\r
ee4dc24f
RN
162VOID\r
163EFIAPI\r
164DumpRaw (\r
165 IN UINT8* Ptr,\r
166 IN UINT32 Length\r
167 )\r
168{\r
169 UINTN ByteCount = 0;\r
170 UINTN PartLineChars;\r
171 UINTN AsciiBufferIndex = 0;\r
172 CHAR8 AsciiBuffer[17];\r
173\r
174 Print (L"Address : 0x%p\n", Ptr);\r
175 Print (L"Length : %d\n", Length);\r
176\r
177 while (ByteCount < Length) {\r
178 if ((ByteCount & 0x0F) == 0) {\r
179 AsciiBuffer[AsciiBufferIndex] = '\0';\r
180 Print (L" %a\n%08X : ", AsciiBuffer, ByteCount);\r
181 AsciiBufferIndex = 0;\r
182 } else if ((ByteCount & 0x07) == 0) {\r
183 Print (L"- ");\r
184 }\r
185\r
186 if ((*Ptr >= ' ') && (*Ptr < 0x7F)) {\r
187 AsciiBuffer[AsciiBufferIndex++] = *Ptr;\r
188 } else {\r
189 AsciiBuffer[AsciiBufferIndex++] = '.';\r
190 }\r
191\r
192 Print (L"%02X ", *Ptr++);\r
193\r
194 ByteCount++;\r
195 }\r
196\r
197 // Justify the final line using spaces before printing\r
198 // the ASCII data.\r
199 PartLineChars = (Length & 0x0F);\r
200 if (PartLineChars != 0) {\r
201 PartLineChars = 48 - (PartLineChars * 3);\r
202 if ((Length & 0x0F) <= 8) {\r
203 PartLineChars += 2;\r
204 }\r
205 while (PartLineChars > 0) {\r
206 Print (L" ");\r
207 PartLineChars--;\r
208 }\r
209 }\r
210\r
211 // Print ASCII data for the final line.\r
212 AsciiBuffer[AsciiBufferIndex] = '\0';\r
213 Print (L" %a", AsciiBuffer);\r
214}\r
215\r
a6eaba4d
DB
216/**\r
217 This function traces 1 byte of data as specified in the format string.\r
ee4dc24f
RN
218\r
219 @param [in] Format The format string for tracing the data.\r
220 @param [in] Ptr Pointer to the start of the buffer.\r
a6eaba4d 221**/\r
ee4dc24f
RN
222VOID\r
223EFIAPI\r
224DumpUint8 (\r
225 IN CONST CHAR16* Format,\r
226 IN UINT8* Ptr\r
227 )\r
228{\r
229 Print (Format, *Ptr);\r
230}\r
231\r
a6eaba4d
DB
232/**\r
233 This function traces 2 bytes of data as specified in the format string.\r
ee4dc24f
RN
234\r
235 @param [in] Format The format string for tracing the data.\r
236 @param [in] Ptr Pointer to the start of the buffer.\r
a6eaba4d 237**/\r
ee4dc24f
RN
238VOID\r
239EFIAPI\r
240DumpUint16 (\r
241 IN CONST CHAR16* Format,\r
242 IN UINT8* Ptr\r
243 )\r
244{\r
245 Print (Format, *(UINT16*)Ptr);\r
246}\r
247\r
a6eaba4d
DB
248/**\r
249 This function traces 4 bytes of data as specified in the format string.\r
ee4dc24f
RN
250\r
251 @param [in] Format The format string for tracing the data.\r
252 @param [in] Ptr Pointer to the start of the buffer.\r
a6eaba4d 253**/\r
ee4dc24f
RN
254VOID\r
255EFIAPI\r
256DumpUint32 (\r
257 IN CONST CHAR16* Format,\r
258 IN UINT8* Ptr\r
259 )\r
260{\r
261 Print (Format, *(UINT32*)Ptr);\r
262}\r
263\r
a6eaba4d
DB
264/**\r
265 This function traces 8 bytes of data as specified by the format string.\r
ee4dc24f
RN
266\r
267 @param [in] Format The format string for tracing the data.\r
268 @param [in] Ptr Pointer to the start of the buffer.\r
a6eaba4d 269**/\r
ee4dc24f
RN
270VOID\r
271EFIAPI\r
272DumpUint64 (\r
273 IN CONST CHAR16* Format,\r
274 IN UINT8* Ptr\r
275 )\r
276{\r
277 // Some fields are not aligned and this causes alignment faults\r
278 // on ARM platforms if the compiler generates LDRD instructions.\r
279 // Perform word access so that LDRD instructions are not generated.\r
280 UINT64 Val = *(UINT32*)(Ptr + sizeof (UINT32));\r
281 Val <<= 32;\r
282 Val |= *(UINT32*)Ptr;\r
283\r
284 Print (Format, Val);\r
285}\r
286\r
a6eaba4d
DB
287/**\r
288 This function traces 3 characters which can be optionally\r
289 formated using the format string if specified.\r
ee4dc24f
RN
290\r
291 If no format string is specified the Format must be NULL.\r
292\r
293 @param [in] Format Optional format string for tracing the data.\r
294 @param [in] Ptr Pointer to the start of the buffer.\r
a6eaba4d 295**/\r
ee4dc24f
RN
296VOID\r
297EFIAPI\r
298Dump3Chars (\r
299 IN CONST CHAR16* Format OPTIONAL,\r
300 IN UINT8* Ptr\r
301 )\r
302{\r
303 Print (\r
304 (Format != NULL) ? Format : L"%c%c%c",\r
305 Ptr[0],\r
306 Ptr[1],\r
307 Ptr[2]\r
308 );\r
309}\r
310\r
a6eaba4d
DB
311/**\r
312 This function traces 4 characters which can be optionally\r
313 formated using the format string if specified.\r
ee4dc24f
RN
314\r
315 If no format string is specified the Format must be NULL.\r
316\r
317 @param [in] Format Optional format string for tracing the data.\r
318 @param [in] Ptr Pointer to the start of the buffer.\r
a6eaba4d 319**/\r
ee4dc24f
RN
320VOID\r
321EFIAPI\r
322Dump4Chars (\r
323 IN CONST CHAR16* Format OPTIONAL,\r
324 IN UINT8* Ptr\r
325 )\r
326{\r
327 Print (\r
328 (Format != NULL) ? Format : L"%c%c%c%c",\r
329 Ptr[0],\r
330 Ptr[1],\r
331 Ptr[2],\r
332 Ptr[3]\r
333 );\r
334}\r
335\r
a6eaba4d
DB
336/**\r
337 This function traces 6 characters which can be optionally\r
338 formated using the format string if specified.\r
ee4dc24f
RN
339\r
340 If no format string is specified the Format must be NULL.\r
341\r
342 @param [in] Format Optional format string for tracing the data.\r
343 @param [in] Ptr Pointer to the start of the buffer.\r
a6eaba4d 344**/\r
ee4dc24f
RN
345VOID\r
346EFIAPI\r
347Dump6Chars (\r
348 IN CONST CHAR16* Format OPTIONAL,\r
349 IN UINT8* Ptr\r
350 )\r
351{\r
352 Print (\r
353 (Format != NULL) ? Format : L"%c%c%c%c%c%c",\r
354 Ptr[0],\r
355 Ptr[1],\r
356 Ptr[2],\r
357 Ptr[3],\r
358 Ptr[4],\r
359 Ptr[5]\r
360 );\r
361}\r
362\r
a6eaba4d
DB
363/**\r
364 This function traces 8 characters which can be optionally\r
365 formated using the format string if specified.\r
ee4dc24f
RN
366\r
367 If no format string is specified the Format must be NULL.\r
368\r
369 @param [in] Format Optional format string for tracing the data.\r
370 @param [in] Ptr Pointer to the start of the buffer.\r
a6eaba4d 371**/\r
ee4dc24f
RN
372VOID\r
373EFIAPI\r
374Dump8Chars (\r
375 IN CONST CHAR16* Format OPTIONAL,\r
376 IN UINT8* Ptr\r
377 )\r
378{\r
379 Print (\r
380 (Format != NULL) ? Format : L"%c%c%c%c%c%c%c%c",\r
381 Ptr[0],\r
382 Ptr[1],\r
383 Ptr[2],\r
384 Ptr[3],\r
385 Ptr[4],\r
386 Ptr[5],\r
387 Ptr[6],\r
388 Ptr[7]\r
389 );\r
390}\r
391\r
a6eaba4d
DB
392/**\r
393 This function indents and prints the ACPI table Field Name.\r
ee4dc24f
RN
394\r
395 @param [in] Indent Number of spaces to add to the global table indent.\r
396 The global table indent is 0 by default; however\r
397 this value is updated on entry to the ParseAcpi()\r
398 by adding the indent value provided to ParseAcpi()\r
399 and restored back on exit.\r
400 Therefore the total indent in the output is\r
401 dependent on from where this function is called.\r
402 @param [in] FieldName Pointer to the Field Name.\r
a6eaba4d 403**/\r
ee4dc24f
RN
404VOID\r
405EFIAPI\r
406PrintFieldName (\r
407 IN UINT32 Indent,\r
408 IN CONST CHAR16* FieldName\r
409)\r
410{\r
411 Print (\r
412 L"%*a%-*s : ",\r
413 gIndent + Indent,\r
414 "",\r
415 (OUTPUT_FIELD_COLUMN_WIDTH - gIndent - Indent),\r
416 FieldName\r
417 );\r
418}\r
419\r
a6eaba4d
DB
420/**\r
421 This function is used to parse an ACPI table buffer.\r
ee4dc24f
RN
422\r
423 The ACPI table buffer is parsed using the ACPI table parser information\r
424 specified by a pointer to an array of ACPI_PARSER elements. This parser\r
425 function iterates through each item on the ACPI_PARSER array and logs the\r
426 ACPI table fields.\r
427\r
428 This function can optionally be used to parse ACPI tables and fetch specific\r
429 field values. The ItemPtr member of the ACPI_PARSER structure (where used)\r
430 is updated by this parser function to point to the selected field data\r
431 (e.g. useful for variable length nested fields).\r
432\r
433 @param [in] Trace Trace the ACPI fields TRUE else only parse the\r
434 table.\r
435 @param [in] Indent Number of spaces to indent the output.\r
436 @param [in] AsciiName Optional pointer to an ASCII string that describes\r
437 the table being parsed.\r
438 @param [in] Ptr Pointer to the start of the buffer.\r
439 @param [in] Length Length of the buffer pointed by Ptr.\r
440 @param [in] Parser Pointer to an array of ACPI_PARSER structure that\r
441 describes the table being parsed.\r
442 @param [in] ParserItems Number of items in the ACPI_PARSER array.\r
443\r
444 @retval Number of bytes parsed.\r
a6eaba4d 445**/\r
ee4dc24f
RN
446UINT32\r
447EFIAPI\r
448ParseAcpi (\r
449 IN BOOLEAN Trace,\r
450 IN UINT32 Indent,\r
451 IN CONST CHAR8* AsciiName OPTIONAL,\r
452 IN UINT8* Ptr,\r
453 IN UINT32 Length,\r
454 IN CONST ACPI_PARSER* Parser,\r
455 IN UINT32 ParserItems\r
456)\r
457{\r
458 UINT32 Index;\r
459 UINT32 Offset = 0;\r
460\r
461 // Increment the Indent\r
462 gIndent += Indent;\r
463\r
464 if (Trace && (AsciiName != NULL)){\r
465 BOOLEAN HighLight = GetColourHighlighting ();\r
466 UINTN OriginalAttribute;\r
467\r
468 if (HighLight) {\r
469 OriginalAttribute = gST->ConOut->Mode->Attribute;\r
470 gST->ConOut->SetAttribute (\r
471 gST->ConOut,\r
472 EFI_TEXT_ATTR(EFI_YELLOW,\r
473 ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4))\r
474 );\r
475 }\r
476 Print (\r
477 L"%*a%-*a :\n",\r
478 gIndent,\r
479 "",\r
480 (OUTPUT_FIELD_COLUMN_WIDTH - gIndent),\r
481 AsciiName\r
482 );\r
483 if (HighLight) {\r
484 gST->ConOut->SetAttribute (gST->ConOut, OriginalAttribute);\r
485 }\r
486 }\r
487\r
488 for (Index = 0; Index < ParserItems; Index++) {\r
489 if ((Offset + Parser[Index].Length) > Length) {\r
490 // We don't parse past the end of the max length specified\r
491 break;\r
492 }\r
493\r
494 if (Offset != Parser[Index].Offset) {\r
495 IncrementErrorCount ();\r
496 Print (\r
497 L"\nERROR: %a: Offset Mismatch for %s\n"\r
498 "CurrentOffset = %d FieldOffset = %d\n",\r
499 AsciiName,\r
500 Parser[Index].NameStr,\r
501 Offset,\r
502 Parser[Index].Offset\r
503 );\r
504 }\r
505\r
506 if (Trace) {\r
507 // if there is a Formatter function let the function handle\r
508 // the printing else if a Format is specified in the table use\r
509 // the Format for printing\r
510 PrintFieldName (2, Parser[Index].NameStr);\r
511 if (Parser[Index].PrintFormatter != NULL) {\r
512 Parser[Index].PrintFormatter (Parser[Index].Format, Ptr);\r
513 } else if (Parser[Index].Format != NULL) {\r
514 switch (Parser[Index].Length) {\r
515 case 1:\r
516 DumpUint8 (Parser[Index].Format, Ptr);\r
517 break;\r
518 case 2:\r
519 DumpUint16 (Parser[Index].Format, Ptr);\r
520 break;\r
521 case 4:\r
522 DumpUint32 (Parser[Index].Format, Ptr);\r
523 break;\r
524 case 8:\r
525 DumpUint64 (Parser[Index].Format, Ptr);\r
526 break;\r
527 default:\r
528 Print (\r
529 L"\nERROR: %a: CANNOT PARSE THIS FIELD, Field Length = %d\n",\r
530 AsciiName,\r
531 Parser[Index].Length\r
532 );\r
533 } // switch\r
534\r
535 // Validating only makes sense if we are tracing\r
536 // the parsed table entries, to report by table name.\r
537 if (Parser[Index].FieldValidator != NULL) {\r
538 Parser[Index].FieldValidator (Ptr, Parser[Index].Context);\r
539 }\r
540 }\r
541 Print (L"\n");\r
542 } // if (Trace)\r
543\r
544 if (Parser[Index].ItemPtr != NULL) {\r
545 *Parser[Index].ItemPtr = (VOID*)Ptr;\r
546 }\r
547\r
548 Ptr += Parser[Index].Length;\r
549 Offset += Parser[Index].Length;\r
550 } // for\r
551\r
552 // Decrement the Indent\r
553 gIndent -= Indent;\r
554 return Offset;\r
555}\r
556\r
a6eaba4d
DB
557/**\r
558 An array describing the ACPI Generic Address Structure.\r
ee4dc24f
RN
559 The GasParser array is used by the ParseAcpi function to parse and/or trace\r
560 the GAS structure.\r
a6eaba4d 561**/\r
ee4dc24f
RN
562STATIC CONST ACPI_PARSER GasParser[] = {\r
563 {L"Address Space ID", 1, 0, L"0x%x", NULL, NULL, NULL, NULL},\r
564 {L"Register Bit Width", 1, 1, L"0x%x", NULL, NULL, NULL, NULL},\r
565 {L"Register Bit Offset", 1, 2, L"0x%x", NULL, NULL, NULL, NULL},\r
566 {L"Address Size", 1, 3, L"0x%x", NULL, NULL, NULL, NULL},\r
567 {L"Address", 8, 4, L"0x%lx", NULL, NULL, NULL, NULL}\r
568};\r
569\r
a6eaba4d
DB
570/**\r
571 This function indents and traces the GAS structure as described by the GasParser.\r
ee4dc24f
RN
572\r
573 @param [in] Ptr Pointer to the start of the buffer.\r
574 @param [in] Indent Number of spaces to indent the output.\r
a6eaba4d 575**/\r
ee4dc24f
RN
576VOID\r
577EFIAPI\r
578DumpGasStruct (\r
579 IN UINT8* Ptr,\r
580 IN UINT32 Indent\r
581 )\r
582{\r
583 Print (L"\n");\r
584 ParseAcpi (\r
585 TRUE,\r
586 Indent,\r
587 NULL,\r
588 Ptr,\r
589 GAS_LENGTH,\r
590 PARSER_PARAMS (GasParser)\r
591 );\r
592}\r
593\r
a6eaba4d
DB
594/**\r
595 This function traces the GAS structure as described by the GasParser.\r
ee4dc24f
RN
596\r
597 @param [in] Format Optional format string for tracing the data.\r
598 @param [in] Ptr Pointer to the start of the buffer.\r
a6eaba4d 599**/\r
ee4dc24f
RN
600VOID\r
601EFIAPI\r
602DumpGas (\r
603 IN CONST CHAR16* Format OPTIONAL,\r
604 IN UINT8* Ptr\r
605 )\r
606{\r
607 DumpGasStruct (Ptr, 2);\r
608}\r
609\r
a6eaba4d
DB
610/**\r
611 This function traces the ACPI header as described by the AcpiHeaderParser.\r
ee4dc24f
RN
612\r
613 @param [in] Ptr Pointer to the start of the buffer.\r
614\r
615 @retval Number of bytes parsed.\r
a6eaba4d 616**/\r
ee4dc24f
RN
617UINT32\r
618EFIAPI\r
619DumpAcpiHeader (\r
620 IN UINT8* Ptr\r
621 )\r
622{\r
623 ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;\r
624 ACPI_PARSER AcpiHeaderParser[] = {\r
625 PARSE_ACPI_HEADER (&AcpiHdrInfo)\r
626 };\r
627\r
628 return ParseAcpi (\r
629 TRUE,\r
630 0,\r
631 "ACPI Table Header",\r
632 Ptr,\r
633 ACPI_DESCRIPTION_HEADER_LENGTH,\r
634 PARSER_PARAMS (AcpiHeaderParser)\r
635 );\r
636}\r
637\r
a6eaba4d
DB
638/**\r
639 This function parses the ACPI header as described by the AcpiHeaderParser.\r
ee4dc24f
RN
640\r
641 This function optionally returns the signature, length and revision of the\r
642 ACPI table.\r
643\r
644 @param [in] Ptr Pointer to the start of the buffer.\r
645 @param [out] Signature Gets location of the ACPI table signature.\r
646 @param [out] Length Gets location of the length of the ACPI table.\r
647 @param [out] Revision Gets location of the revision of the ACPI table.\r
648\r
649 @retval Number of bytes parsed.\r
a6eaba4d 650**/\r
ee4dc24f
RN
651UINT32\r
652EFIAPI\r
653ParseAcpiHeader (\r
654 IN UINT8* Ptr,\r
655 OUT CONST UINT32** Signature,\r
656 OUT CONST UINT32** Length,\r
657 OUT CONST UINT8** Revision\r
658 )\r
659{\r
660 UINT32 BytesParsed;\r
661 ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;\r
662 ACPI_PARSER AcpiHeaderParser[] = {\r
663 PARSE_ACPI_HEADER (&AcpiHdrInfo)\r
664 };\r
665\r
666 BytesParsed = ParseAcpi (\r
667 FALSE,\r
668 0,\r
669 NULL,\r
670 Ptr,\r
671 ACPI_DESCRIPTION_HEADER_LENGTH,\r
672 PARSER_PARAMS (AcpiHeaderParser)\r
673 );\r
674\r
675 *Signature = AcpiHdrInfo.Signature;\r
676 *Length = AcpiHdrInfo.Length;\r
677 *Revision = AcpiHdrInfo.Revision;\r
678\r
679 return BytesParsed;\r
680}\r