TianoCore EDK2 master
AcpiParser.c
Go to the documentation of this file.
1
9#include <Uefi.h>
10#include <Library/UefiLib.h>
13#include "AcpiParser.h"
14#include "AcpiView.h"
15#include "AcpiViewConfig.h"
16
17STATIC UINT32 gIndent;
18STATIC UINT32 mTableErrorCount;
19STATIC UINT32 mTableWarningCount;
20
22
27 PARSE_ACPI_HEADER (&AcpiHdrInfo)
28};
29
33VOID
35 VOID
36 )
37{
38 mTableErrorCount = 0;
39}
40
46UINT32
48 VOID
49 )
50{
51 return mTableErrorCount;
52}
53
57VOID
59 VOID
60 )
61{
62 mTableWarningCount = 0;
63}
64
70UINT32
72 VOID
73 )
74{
75 return mTableWarningCount;
76}
77
81VOID
82EFIAPI
84 VOID
85 )
86{
87 mTableErrorCount++;
88}
89
93VOID
94EFIAPI
96 VOID
97 )
98{
99 mTableWarningCount++;
100}
101
115BOOLEAN
116EFIAPI
118 IN BOOLEAN Log,
119 IN UINT8 *Ptr,
120 IN UINT32 Length
121 )
122{
123 UINTN ByteCount;
124 UINT8 Checksum;
125 UINTN OriginalAttribute;
126
127 //
128 // set local variables to suppress incorrect compiler/analyzer warnings
129 //
130 OriginalAttribute = 0;
131 ByteCount = 0;
132 Checksum = 0;
133
134 while (ByteCount < Length) {
135 Checksum += *(Ptr++);
136 ByteCount++;
137 }
138
139 if (Log) {
140 OriginalAttribute = gST->ConOut->Mode->Attribute;
141 if (Checksum == 0) {
142 if (GetColourHighlighting ()) {
143 gST->ConOut->SetAttribute (
144 gST->ConOut,
145 EFI_TEXT_ATTR (
146 EFI_GREEN,
147 ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)
148 )
149 );
150 }
151
152 Print (L"Table Checksum : OK\n\n");
153 } else {
155 if (GetColourHighlighting ()) {
156 gST->ConOut->SetAttribute (
157 gST->ConOut,
158 EFI_TEXT_ATTR (
159 EFI_RED,
160 ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)
161 )
162 );
163 }
164
165 Print (L"Table Checksum : FAILED (0x%X)\n\n", Checksum);
166 }
167
168 if (GetColourHighlighting ()) {
169 gST->ConOut->SetAttribute (gST->ConOut, OriginalAttribute);
170 }
171 }
172
173 return (Checksum == 0);
174}
175
182VOID
183EFIAPI
185 IN UINT8 *Ptr,
186 IN UINT32 Length
187 )
188{
189 UINTN ByteCount;
190 UINTN PartLineChars;
191 UINTN AsciiBufferIndex;
192 CHAR8 AsciiBuffer[17];
193
194 ByteCount = 0;
195 AsciiBufferIndex = 0;
196
197 Print (L"Address : 0x%p\n", Ptr);
198 Print (L"Length : %d\n", Length);
199
200 while (ByteCount < Length) {
201 if ((ByteCount & 0x0F) == 0) {
202 AsciiBuffer[AsciiBufferIndex] = '\0';
203 Print (L" %a\n%08X : ", AsciiBuffer, ByteCount);
204 AsciiBufferIndex = 0;
205 } else if ((ByteCount & 0x07) == 0) {
206 Print (L"- ");
207 }
208
209 if ((*Ptr >= ' ') && (*Ptr < 0x7F)) {
210 AsciiBuffer[AsciiBufferIndex++] = *Ptr;
211 } else {
212 AsciiBuffer[AsciiBufferIndex++] = '.';
213 }
214
215 Print (L"%02X ", *Ptr++);
216
217 ByteCount++;
218 }
219
220 // Justify the final line using spaces before printing
221 // the ASCII data.
222 PartLineChars = (Length & 0x0F);
223 if (PartLineChars != 0) {
224 PartLineChars = 48 - (PartLineChars * 3);
225 if ((Length & 0x0F) <= 8) {
226 PartLineChars += 2;
227 }
228
229 while (PartLineChars > 0) {
230 Print (L" ");
231 PartLineChars--;
232 }
233 }
234
235 // Print ASCII data for the final line.
236 AsciiBuffer[AsciiBufferIndex] = '\0';
237 Print (L" %a\n\n", AsciiBuffer);
238}
239
246VOID
247EFIAPI
249 IN CONST CHAR16 *Format,
250 IN UINT8 *Ptr
251 )
252{
253 Print (Format, *Ptr);
254}
255
262VOID
263EFIAPI
265 IN CONST CHAR16 *Format,
266 IN UINT8 *Ptr
267 )
268{
269 Print (Format, *(UINT16 *)Ptr);
270}
271
278VOID
279EFIAPI
281 IN CONST CHAR16 *Format,
282 IN UINT8 *Ptr
283 )
284{
285 Print (Format, *(UINT32 *)Ptr);
286}
287
294VOID
295EFIAPI
297 IN CONST CHAR16 *Format,
298 IN UINT8 *Ptr
299 )
300{
301 // Some fields are not aligned and this causes alignment faults
302 // on ARM platforms if the compiler generates LDRD instructions.
303 // Perform word access so that LDRD instructions are not generated.
304 UINT64 Val;
305
306 Val = *(UINT32 *)(Ptr + sizeof (UINT32));
307
308 Val = LShiftU64 (Val, 32);
309 Val |= (UINT64)*(UINT32 *)Ptr;
310
311 Print (Format, Val);
312}
313
323VOID
324EFIAPI
326 IN CONST CHAR16 *Format OPTIONAL,
327 IN UINT8 *Ptr
328 )
329{
330 Print (
331 (Format != NULL) ? Format : L"%c%c%c",
332 Ptr[0],
333 Ptr[1],
334 Ptr[2]
335 );
336}
337
347VOID
348EFIAPI
350 IN CONST CHAR16 *Format OPTIONAL,
351 IN UINT8 *Ptr
352 )
353{
354 Print (
355 (Format != NULL) ? Format : L"%c%c%c%c",
356 Ptr[0],
357 Ptr[1],
358 Ptr[2],
359 Ptr[3]
360 );
361}
362
372VOID
373EFIAPI
375 IN CONST CHAR16 *Format OPTIONAL,
376 IN UINT8 *Ptr
377 )
378{
379 Print (
380 (Format != NULL) ? Format : L"%c%c%c%c%c%c",
381 Ptr[0],
382 Ptr[1],
383 Ptr[2],
384 Ptr[3],
385 Ptr[4],
386 Ptr[5]
387 );
388}
389
399VOID
400EFIAPI
402 IN CONST CHAR16 *Format OPTIONAL,
403 IN UINT8 *Ptr
404 )
405{
406 Print (
407 (Format != NULL) ? Format : L"%c%c%c%c%c%c%c%c",
408 Ptr[0],
409 Ptr[1],
410 Ptr[2],
411 Ptr[3],
412 Ptr[4],
413 Ptr[5],
414 Ptr[6],
415 Ptr[7]
416 );
417}
418
428VOID
429EFIAPI
431 IN CONST CHAR16 *Format OPTIONAL,
432 IN UINT8 *Ptr
433 )
434{
435 Print (
436 (Format != NULL) ? Format : L"%c%c%c%c%c%c%c%c%c%c%c%c",
437 Ptr[0],
438 Ptr[1],
439 Ptr[2],
440 Ptr[3],
441 Ptr[4],
442 Ptr[5],
443 Ptr[6],
444 Ptr[7],
445 Ptr[8],
446 Ptr[9],
447 Ptr[10],
448 Ptr[11]
449 );
450}
451
464VOID
465EFIAPI
467 IN UINT32 Indent,
468 IN CONST CHAR16 *FieldName
469 )
470{
471 Print (
472 L"%*a%-*s : ",
473 gIndent + Indent,
474 "",
475 (OUTPUT_FIELD_COLUMN_WIDTH - gIndent - Indent),
476 FieldName
477 );
478}
479
506UINT32
507EFIAPI
509 IN BOOLEAN Trace,
510 IN UINT32 Indent,
511 IN CONST CHAR8 *AsciiName OPTIONAL,
512 IN UINT8 *Ptr,
513 IN UINT32 Length,
514 IN CONST ACPI_PARSER *Parser,
515 IN UINT32 ParserItems
516 )
517{
518 UINT32 Index;
519 UINT32 Offset;
520 BOOLEAN HighLight;
521 UINTN OriginalAttribute;
522
523 //
524 // set local variables to suppress incorrect compiler/analyzer warnings
525 //
526 OriginalAttribute = 0;
527 Offset = 0;
528
529 // Increment the Indent
530 gIndent += Indent;
531
532 if (Trace && (AsciiName != NULL)) {
533 HighLight = GetColourHighlighting ();
534
535 if (HighLight) {
536 OriginalAttribute = gST->ConOut->Mode->Attribute;
537 gST->ConOut->SetAttribute (
538 gST->ConOut,
539 EFI_TEXT_ATTR (
540 EFI_YELLOW,
541 ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)
542 )
543 );
544 }
545
546 Print (
547 L"%*a%-*a :\n",
548 gIndent,
549 "",
550 (OUTPUT_FIELD_COLUMN_WIDTH - gIndent),
551 AsciiName
552 );
553 if (HighLight) {
554 gST->ConOut->SetAttribute (gST->ConOut, OriginalAttribute);
555 }
556 }
557
558 for (Index = 0; Index < ParserItems; Index++) {
559 if ((Offset + Parser[Index].Length) > Length) {
560 // For fields outside the buffer length provided, reset any pointers
561 // which were supposed to be updated by this function call
562 if (Parser[Index].ItemPtr != NULL) {
563 *Parser[Index].ItemPtr = NULL;
564 }
565
566 // We don't parse past the end of the max length specified
567 continue;
568 }
569
570 if (GetConsistencyChecking () &&
571 (Offset != Parser[Index].Offset))
572 {
574 Print (
575 L"\nERROR: %a: Offset Mismatch for %s\n"
576 L"CurrentOffset = %d FieldOffset = %d\n",
577 AsciiName,
578 Parser[Index].NameStr,
579 Offset,
580 Parser[Index].Offset
581 );
582 }
583
584 if (Trace) {
585 // if there is a Formatter function let the function handle
586 // the printing else if a Format is specified in the table use
587 // the Format for printing
588 PrintFieldName (2, Parser[Index].NameStr);
589 if (Parser[Index].PrintFormatter != NULL) {
590 Parser[Index].PrintFormatter (Parser[Index].Format, Ptr);
591 } else if (Parser[Index].Format != NULL) {
592 switch (Parser[Index].Length) {
593 case 1:
594 DumpUint8 (Parser[Index].Format, Ptr);
595 break;
596 case 2:
597 DumpUint16 (Parser[Index].Format, Ptr);
598 break;
599 case 4:
600 DumpUint32 (Parser[Index].Format, Ptr);
601 break;
602 case 8:
603 DumpUint64 (Parser[Index].Format, Ptr);
604 break;
605 default:
606 Print (
607 L"\nERROR: %a: CANNOT PARSE THIS FIELD, Field Length = %d\n",
608 AsciiName,
609 Parser[Index].Length
610 );
611 } // switch
612 }
613
614 // Validating only makes sense if we are tracing
615 // the parsed table entries, to report by table name.
616 if (GetConsistencyChecking () &&
617 (Parser[Index].FieldValidator != NULL))
618 {
619 Parser[Index].FieldValidator (Ptr, Parser[Index].Context);
620 }
621
622 Print (L"\n");
623 } // if (Trace)
624
625 if (Parser[Index].ItemPtr != NULL) {
626 *Parser[Index].ItemPtr = (VOID *)Ptr;
627 }
628
629 Ptr += Parser[Index].Length;
630 Offset += Parser[Index].Length;
631 } // for
632
633 // Decrement the Indent
634 gIndent -= Indent;
635 return Offset;
636}
637
644 { L"Address Space ID", 1, 0, L"0x%x", NULL, NULL, NULL, NULL },
645 { L"Register Bit Width", 1, 1, L"0x%x", NULL, NULL, NULL, NULL },
646 { L"Register Bit Offset", 1, 2, L"0x%x", NULL, NULL, NULL, NULL },
647 { L"Access Size", 1, 3, L"0x%x", NULL, NULL, NULL, NULL },
648 { L"Address", 8, 4, L"0x%lx", NULL, NULL, NULL, NULL }
649};
650
660UINT32
661EFIAPI
663 IN UINT8 *Ptr,
664 IN UINT32 Indent,
665 IN UINT32 Length
666 )
667{
668 Print (L"\n");
669 return ParseAcpi (
670 TRUE,
671 Indent,
672 NULL,
673 Ptr,
674 Length,
676 );
677}
678
685VOID
686EFIAPI
688 IN CONST CHAR16 *Format OPTIONAL,
689 IN UINT8 *Ptr
690 )
691{
693}
694
702UINT32
703EFIAPI
705 IN UINT8 *Ptr
706 )
707{
708 return ParseAcpi (
709 TRUE,
710 0,
711 "ACPI Table Header",
712 Ptr,
715 );
716}
717
731UINT32
732EFIAPI
734 IN UINT8 *Ptr,
735 OUT CONST UINT32 **Signature,
736 OUT CONST UINT32 **Length,
737 OUT CONST UINT8 **Revision
738 )
739{
740 UINT32 BytesParsed;
741
742 BytesParsed = ParseAcpi (
743 FALSE,
744 0,
745 NULL,
746 Ptr,
749 );
750
751 *Signature = AcpiHdrInfo.Signature;
752 *Length = AcpiHdrInfo.Length;
753 *Revision = AcpiHdrInfo.Revision;
754
755 return BytesParsed;
756}
757
785UINT32
786EFIAPI
788 IN BOOLEAN Trace,
789 IN UINT32 Indent,
790 IN CONST CHAR8 *AsciiName OPTIONAL,
791 IN UINT8 *Ptr,
792 IN UINT32 Length,
793 IN CONST ACPI_PARSER *Parser,
794 IN UINT32 ParserItems
795 )
796{
797 UINT32 Index;
798 UINT32 Offset;
799 BOOLEAN HighLight;
800 UINTN OriginalAttribute;
801
802 UINT64 Data;
803 UINT64 BitsData;
804
805 if ((Length == 0) || (Length > 8)) {
807 Print (
808 L"\nERROR: Bitfield Length(%d) is zero or exceeding the 64 bit limit.\n",
809 Length
810 );
811 return 0;
812 }
813
814 //
815 // set local variables to suppress incorrect compiler/analyzer warnings
816 //
817 OriginalAttribute = 0;
818 Offset = 0;
819
820 // Increment the Indent
821 gIndent += Indent;
822
823 CopyMem ((VOID *)&BitsData, (VOID *)Ptr, Length);
824 if (Trace && (AsciiName != NULL)) {
825 HighLight = GetColourHighlighting ();
826
827 if (HighLight) {
828 OriginalAttribute = gST->ConOut->Mode->Attribute;
829 gST->ConOut->SetAttribute (
830 gST->ConOut,
831 EFI_TEXT_ATTR (
832 EFI_YELLOW,
833 ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)
834 )
835 );
836 }
837
838 Print (
839 L"%*a%-*a :\n",
840 gIndent,
841 "",
842 (OUTPUT_FIELD_COLUMN_WIDTH - gIndent),
843 AsciiName
844 );
845 if (HighLight) {
846 gST->ConOut->SetAttribute (gST->ConOut, OriginalAttribute);
847 }
848 }
849
850 for (Index = 0; Index < ParserItems; Index++) {
851 if ((Offset + Parser[Index].Length) > (Length * 8)) {
852 // For fields outside the buffer length provided, reset any pointers
853 // which were supposed to be updated by this function call
854 if (Parser[Index].ItemPtr != NULL) {
855 *Parser[Index].ItemPtr = NULL;
856 }
857
858 // We don't parse past the end of the max length specified
859 continue;
860 }
861
862 if (Parser[Index].Length == 0) {
864 // don't parse the bitfield whose length is zero
865 Print (
866 L"\nERROR: %a: Cannot parse this field, Field Length = %d\n",
867 Parser[Index].Length
868 );
869 continue;
870 }
871
872 if (GetConsistencyChecking () &&
873 (Offset != Parser[Index].Offset))
874 {
876 Print (
877 L"\nERROR: %a: Offset Mismatch for %s\n"
878 L"CurrentOffset = %d FieldOffset = %d\n",
879 AsciiName,
880 Parser[Index].NameStr,
881 Offset,
882 Parser[Index].Offset
883 );
884 }
885
886 // extract Bitfield data for the current item
887 Data = RShiftU64 (BitsData, Parser[Index].Offset) & ~(LShiftU64 (~0ULL, Parser[Index].Length));
888
889 if (Trace) {
890 // if there is a Formatter function let the function handle
891 // the printing else if a Format is specified in the table use
892 // the Format for printing
893 PrintFieldName (2, Parser[Index].NameStr);
894 if (Parser[Index].PrintFormatter != NULL) {
895 Parser[Index].PrintFormatter (Parser[Index].Format, (UINT8 *)&Data);
896 } else if (Parser[Index].Format != NULL) {
897 // convert bit length to byte length
898 switch ((Parser[Index].Length + 7) >> 3) {
899 // print the data depends on byte size
900 case 1:
901 DumpUint8 (Parser[Index].Format, (UINT8 *)&Data);
902 break;
903 case 2:
904 DumpUint16 (Parser[Index].Format, (UINT8 *)&Data);
905 break;
906 case 3:
907 case 4:
908 DumpUint32 (Parser[Index].Format, (UINT8 *)&Data);
909 break;
910 case 5:
911 case 6:
912 case 7:
913 case 8:
914 DumpUint64 (Parser[Index].Format, (UINT8 *)&Data);
915 break;
916 default:
917 Print (
918 L"\nERROR: %a: CANNOT PARSE THIS FIELD, Field Length = %d\n",
919 AsciiName,
920 Parser[Index].Length
921 );
922 } // switch
923 }
924
925 // Validating only makes sense if we are tracing
926 // the parsed table entries, to report by table name.
927 if (GetConsistencyChecking () &&
928 (Parser[Index].FieldValidator != NULL))
929 {
930 Parser[Index].FieldValidator ((UINT8 *)&Data, Parser[Index].Context);
931 }
932
933 Print (L"\n");
934 } // if (Trace)
935
936 Offset += Parser[Index].Length;
937 } // for
938
939 // Decrement the Indent
940 gIndent -= Indent;
941 return Offset;
942}
UINT64 UINTN
STATIC CONST ACPI_PARSER AcpiHeaderParser[]
Definition: AcpiParser.c:26
UINT32 EFIAPI ParseAcpiHeader(IN UINT8 *Ptr, OUT CONST UINT32 **Signature, OUT CONST UINT32 **Length, OUT CONST UINT8 **Revision)
Definition: AcpiParser.c:733
VOID EFIAPI Dump4Chars(IN CONST CHAR16 *Format OPTIONAL, IN UINT8 *Ptr)
Definition: AcpiParser.c:349
VOID EFIAPI IncrementWarningCount(VOID)
Definition: AcpiParser.c:95
UINT32 EFIAPI DumpGasStruct(IN UINT8 *Ptr, IN UINT32 Indent, IN UINT32 Length)
Definition: AcpiParser.c:662
VOID ResetWarningCount(VOID)
Definition: AcpiParser.c:58
VOID EFIAPI Dump3Chars(IN CONST CHAR16 *Format OPTIONAL, IN UINT8 *Ptr)
Definition: AcpiParser.c:325
UINT32 GetErrorCount(VOID)
Definition: AcpiParser.c:47
VOID EFIAPI DumpUint16(IN CONST CHAR16 *Format, IN UINT8 *Ptr)
Definition: AcpiParser.c:264
VOID EFIAPI DumpUint64(IN CONST CHAR16 *Format, IN UINT8 *Ptr)
Definition: AcpiParser.c:296
VOID EFIAPI PrintFieldName(IN UINT32 Indent, IN CONST CHAR16 *FieldName)
Definition: AcpiParser.c:466
BOOLEAN EFIAPI VerifyChecksum(IN BOOLEAN Log, IN UINT8 *Ptr, IN UINT32 Length)
Definition: AcpiParser.c:117
VOID ResetErrorCount(VOID)
Definition: AcpiParser.c:34
UINT32 EFIAPI DumpAcpiHeader(IN UINT8 *Ptr)
Definition: AcpiParser.c:704
VOID EFIAPI IncrementErrorCount(VOID)
Definition: AcpiParser.c:83
UINT32 EFIAPI ParseAcpi(IN BOOLEAN Trace, IN UINT32 Indent, IN CONST CHAR8 *AsciiName OPTIONAL, IN UINT8 *Ptr, IN UINT32 Length, IN CONST ACPI_PARSER *Parser, IN UINT32 ParserItems)
Definition: AcpiParser.c:508
VOID EFIAPI Dump12Chars(IN CONST CHAR16 *Format OPTIONAL, IN UINT8 *Ptr)
Definition: AcpiParser.c:430
VOID EFIAPI DumpUint32(IN CONST CHAR16 *Format, IN UINT8 *Ptr)
Definition: AcpiParser.c:280
UINT32 EFIAPI ParseAcpiBitFields(IN BOOLEAN Trace, IN UINT32 Indent, IN CONST CHAR8 *AsciiName OPTIONAL, IN UINT8 *Ptr, IN UINT32 Length, IN CONST ACPI_PARSER *Parser, IN UINT32 ParserItems)
Definition: AcpiParser.c:787
STATIC CONST ACPI_PARSER GasParser[]
Definition: AcpiParser.c:643
UINT32 GetWarningCount(VOID)
Definition: AcpiParser.c:71
VOID EFIAPI Dump6Chars(IN CONST CHAR16 *Format OPTIONAL, IN UINT8 *Ptr)
Definition: AcpiParser.c:374
VOID EFIAPI DumpUint8(IN CONST CHAR16 *Format, IN UINT8 *Ptr)
Definition: AcpiParser.c:248
VOID EFIAPI DumpGas(IN CONST CHAR16 *Format OPTIONAL, IN UINT8 *Ptr)
Definition: AcpiParser.c:687
VOID EFIAPI DumpRaw(IN UINT8 *Ptr, IN UINT32 Length)
Definition: AcpiParser.c:184
VOID EFIAPI Dump8Chars(IN CONST CHAR16 *Format OPTIONAL, IN UINT8 *Ptr)
Definition: AcpiParser.c:401
#define PARSER_PARAMS(Parser)
Definition: AcpiParser.h:421
#define PARSE_ACPI_HEADER(Info)
Definition: AcpiParser.h:428
BOOLEAN EFIAPI GetConsistencyChecking(VOID)
BOOLEAN EFIAPI GetColourHighlighting(VOID)
#define NULL
Definition: Base.h:312
#define CONST
Definition: Base.h:259
#define STATIC
Definition: Base.h:264
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
UINT64 EFIAPI RShiftU64(IN UINT64 Operand, IN UINTN Count)
Definition: RShiftU64.c:28
UINT64 EFIAPI LShiftU64(IN UINT64 Operand, IN UINTN Count)
Definition: LShiftU64.c:28
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
EFI_SYSTEM_TABLE * gST
UINTN EFIAPI Print(IN CONST CHAR16 *Format,...)
Definition: UefiLibPrint.c:109
EFI_SIMPLE_TEXT_OUTPUT_MODE * Mode
UINT32 * Length
Length of the ACPI table.
Definition: AcpiParser.h:321
UINT32 * Signature
ACPI table signature.
Definition: AcpiParser.h:319
UINT8 * Revision
Revision.
Definition: AcpiParser.h:323
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL * ConOut
Definition: UefiSpec.h:2009