1 /******************************************************************************
2  *
3  * Module Name: dmtbdump2 - Dump ACPI data tables that contain no AML code
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2022, Intel Corp.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions, and the following disclaimer,
16  *    without modification.
17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18  *    substantially similar to the "NO WARRANTY" disclaimer below
19  *    ("Disclaimer") and any redistribution must be conditioned upon
20  *    including a substantially similar Disclaimer requirement for further
21  *    binary redistribution.
22  * 3. Neither the names of the above-listed copyright holders nor the names
23  *    of any contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * Alternatively, this software may be distributed under the terms of the
27  * GNU General Public License ("GPL") version 2 as published by the Free
28  * Software Foundation.
29  *
30  * NO WARRANTY
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGES.
42  */
43 
44 #include <wchar.h>
45 #include "acpi.h"
46 #include "accommon.h"
47 #include "acdisasm.h"
48 #include "actables.h"
49 #include "aslcompiler.h"
50 
51 /* This module used for application-level code only */
52 
53 #define _COMPONENT          ACPI_CA_DISASSEMBLER
54         ACPI_MODULE_NAME    ("dmtbdump2")
55 
56 
57 /*******************************************************************************
58  *
59  * FUNCTION:    AcpiDmDumpIort
60  *
61  * PARAMETERS:  Table               - A IORT table
62  *
63  * RETURN:      None
64  *
65  * DESCRIPTION: Format the contents of a IORT
66  *
67  ******************************************************************************/
68 
69 void
AcpiDmDumpIort(ACPI_TABLE_HEADER * Table)70 AcpiDmDumpIort (
71     ACPI_TABLE_HEADER       *Table)
72 {
73     ACPI_STATUS             Status;
74     ACPI_TABLE_IORT         *Iort;
75     ACPI_IORT_NODE          *IortNode;
76     ACPI_IORT_ITS_GROUP     *IortItsGroup = NULL;
77     ACPI_IORT_SMMU          *IortSmmu = NULL;
78     ACPI_IORT_RMR           *IortRmr = NULL;
79     UINT32                  Offset;
80     UINT32                  NodeOffset;
81     UINT32                  Length;
82     ACPI_DMTABLE_INFO       *InfoTable;
83     char                    *String;
84     UINT32                  i;
85     UINT32                  MappingByteLength;
86     UINT8                   Revision;
87 
88 
89     /* Main table */
90 
91     Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoIort);
92     if (ACPI_FAILURE (Status))
93     {
94         return;
95     }
96 
97     Revision = Table->Revision;
98 
99     /* IORT Revisions E, E.a and E.c have known issues and are not supported */
100 
101     if (Revision == 1 || Revision == 2 || Revision == 4)
102     {
103         AcpiOsPrintf ("\n**** Unsupported IORT revision 0x%X\n",
104                       Revision);
105         return;
106     }
107 
108     Iort = ACPI_CAST_PTR (ACPI_TABLE_IORT, Table);
109     Offset = sizeof (ACPI_TABLE_IORT);
110 
111     /* Dump the OptionalPadding (optional) */
112 
113     if (Iort->NodeOffset > Offset)
114     {
115         Status = AcpiDmDumpTable (Table->Length, Offset, Table,
116             Iort->NodeOffset - Offset, AcpiDmTableInfoIortPad);
117         if (ACPI_FAILURE (Status))
118         {
119             return;
120         }
121     }
122 
123     Offset = Iort->NodeOffset;
124     while (Offset < Table->Length)
125     {
126         /* Common subtable header */
127 
128         IortNode = ACPI_ADD_PTR (ACPI_IORT_NODE, Table, Offset);
129         AcpiOsPrintf ("\n");
130         Length = ACPI_OFFSET (ACPI_IORT_NODE, NodeData);
131 
132         if (Revision == 0)
133         {
134             Status = AcpiDmDumpTable (Table->Length, Offset,
135                 IortNode, Length, AcpiDmTableInfoIortHdr);
136         }
137         else if (Revision >= 3)
138         {
139             Status = AcpiDmDumpTable (Table->Length, Offset,
140                 IortNode, Length, AcpiDmTableInfoIortHdr3);
141         }
142 
143         if (ACPI_FAILURE (Status))
144         {
145             return;
146         }
147 
148         NodeOffset = Length;
149 
150         switch (IortNode->Type)
151         {
152         case ACPI_IORT_NODE_ITS_GROUP:
153 
154             InfoTable = AcpiDmTableInfoIort0;
155             Length = ACPI_OFFSET (ACPI_IORT_ITS_GROUP, Identifiers);
156             IortItsGroup = ACPI_ADD_PTR (ACPI_IORT_ITS_GROUP, IortNode, NodeOffset);
157             break;
158 
159         case ACPI_IORT_NODE_NAMED_COMPONENT:
160 
161             InfoTable = AcpiDmTableInfoIort1;
162             Length = ACPI_OFFSET (ACPI_IORT_NAMED_COMPONENT, DeviceName);
163             String = ACPI_ADD_PTR (char, IortNode, NodeOffset + Length);
164             Length += strlen (String) + 1;
165             break;
166 
167         case ACPI_IORT_NODE_PCI_ROOT_COMPLEX:
168 
169             InfoTable = AcpiDmTableInfoIort2;
170             Length = IortNode->Length - NodeOffset;
171             break;
172 
173         case ACPI_IORT_NODE_SMMU:
174 
175             InfoTable = AcpiDmTableInfoIort3;
176             Length = ACPI_OFFSET (ACPI_IORT_SMMU, Interrupts);
177             IortSmmu = ACPI_ADD_PTR (ACPI_IORT_SMMU, IortNode, NodeOffset);
178             break;
179 
180         case ACPI_IORT_NODE_SMMU_V3:
181 
182             InfoTable = AcpiDmTableInfoIort4;
183             Length = IortNode->Length - NodeOffset;
184             break;
185 
186         case ACPI_IORT_NODE_PMCG:
187 
188             InfoTable = AcpiDmTableInfoIort5;
189             Length = IortNode->Length - NodeOffset;
190             break;
191 
192         case ACPI_IORT_NODE_RMR:
193 
194             InfoTable = AcpiDmTableInfoIort6;
195             Length = IortNode->Length - NodeOffset;
196             IortRmr = ACPI_ADD_PTR (ACPI_IORT_RMR, IortNode, NodeOffset);
197             break;
198 
199         default:
200 
201             AcpiOsPrintf ("\n**** Unknown IORT node type 0x%X\n",
202                 IortNode->Type);
203 
204             /* Attempt to continue */
205 
206             if (!IortNode->Length)
207             {
208                 AcpiOsPrintf ("Invalid zero length IORT node\n");
209                 return;
210             }
211             goto NextSubtable;
212         }
213 
214         /* Dump the node subtable header */
215 
216         AcpiOsPrintf ("\n");
217         Status = AcpiDmDumpTable (Table->Length, Offset + NodeOffset,
218             ACPI_ADD_PTR (ACPI_IORT_NODE, IortNode, NodeOffset),
219             Length, InfoTable);
220         if (ACPI_FAILURE (Status))
221         {
222             return;
223         }
224 
225         NodeOffset += Length;
226 
227         /* Dump the node specific data */
228 
229         switch (IortNode->Type)
230         {
231         case ACPI_IORT_NODE_ITS_GROUP:
232 
233             /* Validate IortItsGroup to avoid compiler warnings */
234 
235             if (IortItsGroup)
236             {
237                 for (i = 0; i < IortItsGroup->ItsCount; i++)
238                 {
239                     Status = AcpiDmDumpTable (Table->Length, Offset + NodeOffset,
240                         ACPI_ADD_PTR (ACPI_IORT_NODE, IortNode, NodeOffset),
241                         4, AcpiDmTableInfoIort0a);
242                     if (ACPI_FAILURE (Status))
243                     {
244                         return;
245                     }
246 
247                     NodeOffset += 4;
248                 }
249             }
250             break;
251 
252         case ACPI_IORT_NODE_NAMED_COMPONENT:
253 
254             /* Dump the Padding (optional) */
255 
256             if (IortNode->Length > NodeOffset)
257             {
258                 MappingByteLength =
259                     IortNode->MappingCount * sizeof (ACPI_IORT_ID_MAPPING);
260                 Status = AcpiDmDumpTable (Table->Length, Offset + NodeOffset,
261                     Table, IortNode->Length - NodeOffset - MappingByteLength,
262                     AcpiDmTableInfoIort1a);
263                 if (ACPI_FAILURE (Status))
264                 {
265                     return;
266                 }
267             }
268             break;
269 
270         case ACPI_IORT_NODE_SMMU:
271 
272             AcpiOsPrintf ("\n");
273 
274             /* Validate IortSmmu to avoid compiler warnings */
275 
276             if (IortSmmu)
277             {
278                 Length = 2 * sizeof (UINT64);
279                 NodeOffset = IortSmmu->GlobalInterruptOffset;
280                 Status = AcpiDmDumpTable (Table->Length, Offset + NodeOffset,
281                     ACPI_ADD_PTR (ACPI_IORT_NODE, IortNode, NodeOffset),
282                     Length, AcpiDmTableInfoIort3a);
283                 if (ACPI_FAILURE (Status))
284                 {
285                     return;
286                 }
287 
288                 NodeOffset = IortSmmu->ContextInterruptOffset;
289                 for (i = 0; i < IortSmmu->ContextInterruptCount; i++)
290                 {
291                     Status = AcpiDmDumpTable (Table->Length, Offset + NodeOffset,
292                         ACPI_ADD_PTR (ACPI_IORT_NODE, IortNode, NodeOffset),
293                         8, AcpiDmTableInfoIort3b);
294                     if (ACPI_FAILURE (Status))
295                     {
296                         return;
297                     }
298 
299                     NodeOffset += 8;
300                 }
301 
302                 NodeOffset = IortSmmu->PmuInterruptOffset;
303                 for (i = 0; i < IortSmmu->PmuInterruptCount; i++)
304                 {
305                     Status = AcpiDmDumpTable (Table->Length, Offset + NodeOffset,
306                         ACPI_ADD_PTR (ACPI_IORT_NODE, IortNode, NodeOffset),
307                         8, AcpiDmTableInfoIort3c);
308                     if (ACPI_FAILURE (Status))
309                     {
310                         return;
311                     }
312 
313                     NodeOffset += 8;
314                 }
315             }
316             break;
317 
318         case ACPI_IORT_NODE_RMR:
319 
320             /* Validate IortRmr to avoid compiler warnings */
321             if (IortRmr)
322             {
323                 NodeOffset = IortRmr->RmrOffset;
324                 Length = sizeof (ACPI_IORT_RMR_DESC);
325                 for (i = 0; i < IortRmr->RmrCount; i++)
326                 {
327                     AcpiOsPrintf ("\n");
328                     Status = AcpiDmDumpTable (Table->Length, Offset + NodeOffset,
329                         ACPI_ADD_PTR (ACPI_IORT_NODE, IortNode, NodeOffset),
330                         Length, AcpiDmTableInfoIort6a);
331                     if (ACPI_FAILURE (Status))
332                     {
333                         return;
334                     }
335 
336                     NodeOffset += Length;
337                 }
338             }
339             break;
340 
341         default:
342 
343             break;
344         }
345 
346         /* Dump the ID mappings */
347 
348         NodeOffset = IortNode->MappingOffset;
349         for (i = 0; i < IortNode->MappingCount; i++)
350         {
351             AcpiOsPrintf ("\n");
352             Length = sizeof (ACPI_IORT_ID_MAPPING);
353             Status = AcpiDmDumpTable (Table->Length, Offset + NodeOffset,
354                 ACPI_ADD_PTR (ACPI_IORT_NODE, IortNode, NodeOffset),
355                 Length, AcpiDmTableInfoIortMap);
356             if (ACPI_FAILURE (Status))
357             {
358                 return;
359             }
360 
361             NodeOffset += Length;
362         }
363 
364 NextSubtable:
365         /* Point to next node subtable */
366 
367         Offset += IortNode->Length;
368     }
369 }
370 
371 
372 /*******************************************************************************
373  *
374  * FUNCTION:    AcpiDmDumpIvrs
375  *
376  * PARAMETERS:  Table               - A IVRS table
377  *
378  * RETURN:      None
379  *
380  * DESCRIPTION: Format the contents of a IVRS. Notes:
381  *              The IVRS is essentially a flat table, with the following
382  *              structure:
383  *              <Main ACPI Table Header>
384  *              <Main subtable - virtualization info>
385  *              <IVHD>
386  *                  <Device Entries>
387  *              ...
388  *              <IVHD>
389  *                  <Device Entries>
390  *              <IVMD>
391  *              ...
392  *
393  ******************************************************************************/
394 
395 void
AcpiDmDumpIvrs(ACPI_TABLE_HEADER * Table)396 AcpiDmDumpIvrs (
397     ACPI_TABLE_HEADER       *Table)
398 {
399     ACPI_STATUS             Status;
400     UINT32                  Offset = sizeof (ACPI_TABLE_IVRS);
401     UINT32                  EntryOffset;
402     UINT32                  EntryLength;
403     UINT32                  EntryType;
404     ACPI_IVRS_DEVICE_HID    *HidSubtable;
405     ACPI_IVRS_DE_HEADER     *DeviceEntry;
406     ACPI_IVRS_HEADER        *Subtable;
407     ACPI_DMTABLE_INFO       *InfoTable;
408 
409 
410     /* Main table */
411 
412     Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoIvrs);
413     if (ACPI_FAILURE (Status))
414     {
415         return;
416     }
417 
418     /* Subtables */
419 
420     Subtable = ACPI_ADD_PTR (ACPI_IVRS_HEADER, Table, Offset);
421 
422     while (Offset < Table->Length)
423     {
424         switch (Subtable->Type)
425         {
426         /* Type 10h, IVHD (I/O Virtualization Hardware Definition) */
427 
428         case ACPI_IVRS_TYPE_HARDWARE1:
429 
430             AcpiOsPrintf ("\n");
431             InfoTable = AcpiDmTableInfoIvrsHware1;
432             break;
433 
434         /* Types 11h, 40h, IVHD (I/O Virtualization Hardware Definition) */
435 
436         case ACPI_IVRS_TYPE_HARDWARE2:
437         case ACPI_IVRS_TYPE_HARDWARE3:
438 
439             AcpiOsPrintf ("\n");
440             InfoTable = AcpiDmTableInfoIvrsHware23;
441             break;
442 
443         /* Types 20h-22h, IVMD (I/O Virtualization Memory Definition Block) */
444 
445         case ACPI_IVRS_TYPE_MEMORY1:
446         case ACPI_IVRS_TYPE_MEMORY2:
447         case ACPI_IVRS_TYPE_MEMORY3:
448 
449             AcpiOsPrintf ("\n");
450             InfoTable = AcpiDmTableInfoIvrsMemory;
451             break;
452 
453         default:
454 
455             AcpiOsPrintf ("\n**** Unknown IVRS subtable type 0x%X\n",
456                 Subtable->Type);
457 
458             /* Attempt to continue */
459 
460             if (!Subtable->Length)
461             {
462                 AcpiOsPrintf ("Invalid zero length subtable\n");
463                 return;
464             }
465             goto NextSubtable;
466         }
467 
468         /* Dump the subtable */
469 
470         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
471             Subtable->Length, InfoTable);
472         if (ACPI_FAILURE (Status))
473         {
474             return;
475         }
476 
477         /* The hardware subtables (IVHD) can contain multiple device entries */
478 
479         if (Subtable->Type == ACPI_IVRS_TYPE_HARDWARE1 ||
480             Subtable->Type == ACPI_IVRS_TYPE_HARDWARE2 ||
481             Subtable->Type == ACPI_IVRS_TYPE_HARDWARE3)
482         {
483             if (Subtable->Type == ACPI_IVRS_TYPE_HARDWARE1)
484             {
485                 EntryOffset = Offset + sizeof (ACPI_IVRS_HARDWARE1);
486                 DeviceEntry = ACPI_ADD_PTR (ACPI_IVRS_DE_HEADER, Subtable,
487                     sizeof (ACPI_IVRS_HARDWARE1));
488             }
489             else
490             {
491                 /* ACPI_IVRS_TYPE_HARDWARE2, HARDWARE3 subtable types */
492 
493                 EntryOffset = Offset + sizeof (ACPI_IVRS_HARDWARE2);
494                 DeviceEntry = ACPI_ADD_PTR (ACPI_IVRS_DE_HEADER, Subtable,
495                     sizeof (ACPI_IVRS_HARDWARE2));
496             }
497 
498             /* Process all of the Device Entries */
499 
500             while (EntryOffset < (Offset + Subtable->Length))
501             {
502                 AcpiOsPrintf ("\n");
503 
504                 /*
505                  * Upper 2 bits of Type encode the length of the device entry
506                  *
507                  * 00 = 4 byte
508                  * 01 = 8 byte
509                  * 1x = variable length
510                  */
511                 EntryType = DeviceEntry->Type;
512                 EntryLength = EntryType >> 6 == 1 ? 8 : 4;
513 
514                 switch (EntryType)
515                 {
516                 /* 4-byte device entries */
517 
518                 case ACPI_IVRS_TYPE_PAD4:
519                 case ACPI_IVRS_TYPE_ALL:
520                 case ACPI_IVRS_TYPE_SELECT:
521                 case ACPI_IVRS_TYPE_START:
522                 case ACPI_IVRS_TYPE_END:
523 
524                     InfoTable = AcpiDmTableInfoIvrs4;
525                     break;
526 
527                 /* 8-byte entries, type A */
528 
529                 case ACPI_IVRS_TYPE_ALIAS_SELECT:
530                 case ACPI_IVRS_TYPE_ALIAS_START:
531 
532                     InfoTable = AcpiDmTableInfoIvrs8a;
533                     break;
534 
535                 /* 8-byte entries, type B */
536 
537                 case ACPI_IVRS_TYPE_PAD8:
538                 case ACPI_IVRS_TYPE_EXT_SELECT:
539                 case ACPI_IVRS_TYPE_EXT_START:
540 
541                     InfoTable = AcpiDmTableInfoIvrs8b;
542                     break;
543 
544                 /* 8-byte entries, type C */
545 
546                 case ACPI_IVRS_TYPE_SPECIAL:
547 
548                     InfoTable = AcpiDmTableInfoIvrs8c;
549                     break;
550 
551                 /* Variable-length entries */
552 
553                 case ACPI_IVRS_TYPE_HID:
554 
555                     EntryLength = 4;
556                     InfoTable = AcpiDmTableInfoIvrsHid;
557                     break;
558 
559                 default:
560                     InfoTable = AcpiDmTableInfoIvrs4;
561                     AcpiOsPrintf (
562                         "\n**** Unknown IVRS device entry type/length: "
563                         "0x%.2X/0x%X at offset 0x%.4X: (header below)\n",
564                         EntryType, EntryLength, EntryOffset);
565                     break;
566                 }
567 
568                 /* Dump the Device Entry */
569 
570                 Status = AcpiDmDumpTable (Table->Length, EntryOffset,
571                     DeviceEntry, EntryLength, InfoTable);
572                 if (ACPI_FAILURE (Status))
573                 {
574                     return;
575                 }
576 
577                 HidSubtable = ACPI_CAST_PTR (ACPI_IVRS_DEVICE_HID, DeviceEntry);
578                 EntryOffset += EntryLength;
579                 DeviceEntry = ACPI_ADD_PTR (ACPI_IVRS_DE_HEADER, HidSubtable,
580                     EntryLength);
581 
582                 if (EntryType == ACPI_IVRS_TYPE_HID)
583                 {
584                     /*
585                      * Determine if the HID is an integer or a string.
586                      * An integer is defined to be 32 bits, with the upper 32 bits
587                      * set to zero. (from the ACPI Spec): "The HID can be a 32-bit
588                      * integer or a character string. If an integer, the lower
589                      * 4 bytes of the field contain the integer and the upper
590                      * 4 bytes are padded with 0".
591                      */
592                     if (UtIsIdInteger ((UINT8 *) &HidSubtable->AcpiHid))
593                     {
594                         Status = AcpiDmDumpTable (Table->Length, EntryOffset,
595                             &HidSubtable->AcpiHid, 8, AcpiDmTableInfoIvrsHidInteger);
596                     }
597                     else
598                     {
599                         Status = AcpiDmDumpTable (Table->Length, EntryOffset,
600                             &HidSubtable->AcpiHid, 8, AcpiDmTableInfoIvrsHidString);
601                     }
602                     if (ACPI_FAILURE (Status))
603                     {
604                         return;
605                     }
606 
607                     EntryOffset += 8;
608 
609                     /*
610                      * Determine if the CID is an integer or a string. The format
611                      * of the CID is the same as the HID above. From ACPI Spec:
612                      * "If present, CID must be a single Compatible Device ID
613                      * following the same format as the HID field."
614                      */
615                     if (UtIsIdInteger ((UINT8 *) &HidSubtable->AcpiCid))
616                     {
617                         Status = AcpiDmDumpTable (Table->Length, EntryOffset,
618                             &HidSubtable->AcpiCid, 8, AcpiDmTableInfoIvrsCidInteger);
619                     }
620                     else
621                     {
622                         Status = AcpiDmDumpTable (Table->Length, EntryOffset,
623                             &HidSubtable->AcpiCid, 8, AcpiDmTableInfoIvrsCidString);
624                     }
625                     if (ACPI_FAILURE (Status))
626                     {
627                         return;
628                     }
629 
630                     EntryOffset += 8;
631                     EntryLength = HidSubtable->UidLength;
632 
633                     if (EntryLength > ACPI_IVRS_UID_NOT_PRESENT)
634                     {
635                         /* Dump the UID based upon the UidType field (String or Integer) */
636 
637                         if (HidSubtable->UidType == ACPI_IVRS_UID_IS_STRING)
638                         {
639                             Status = AcpiDmDumpTable (Table->Length, EntryOffset,
640                                 &HidSubtable->UidType, EntryLength, AcpiDmTableInfoIvrsUidString);
641                             if (ACPI_FAILURE (Status))
642                             {
643                                 return;
644                             }
645                         }
646                         else /* ACPI_IVRS_UID_IS_INTEGER */
647                         {
648                             Status = AcpiDmDumpTable (Table->Length, EntryOffset,
649                                 &HidSubtable->UidType, EntryLength, AcpiDmTableInfoIvrsUidInteger);
650                             if (ACPI_FAILURE (Status))
651                             {
652                                 return;
653                             }
654                         }
655                     }
656 
657                     EntryOffset += EntryLength+2;
658                     DeviceEntry = ACPI_ADD_PTR (ACPI_IVRS_DE_HEADER,
659                         Table, EntryOffset);
660                 }
661             }
662         }
663 
664 NextSubtable:
665         /* Point to next subtable */
666 
667         Offset += Subtable->Length;
668         Subtable = ACPI_ADD_PTR (ACPI_IVRS_HEADER, Subtable, Subtable->Length);
669     }
670 }
671 
672 
673 /*******************************************************************************
674  *
675  * FUNCTION:    AcpiDmDumpLpit
676  *
677  * PARAMETERS:  Table               - A LPIT table
678  *
679  * RETURN:      None
680  *
681  * DESCRIPTION: Format the contents of a LPIT. This table type consists
682  *              of an open-ended number of subtables. Note: There are no
683  *              entries in the main table. An LPIT consists of the table
684  *              header and then subtables only.
685  *
686  ******************************************************************************/
687 
688 void
AcpiDmDumpLpit(ACPI_TABLE_HEADER * Table)689 AcpiDmDumpLpit (
690     ACPI_TABLE_HEADER       *Table)
691 {
692     ACPI_STATUS             Status;
693     ACPI_LPIT_HEADER        *Subtable;
694     UINT32                  Length = Table->Length;
695     UINT32                  Offset = sizeof (ACPI_TABLE_LPIT);
696     ACPI_DMTABLE_INFO       *InfoTable;
697     UINT32                  SubtableLength;
698 
699 
700     /* Subtables */
701 
702     Subtable = ACPI_ADD_PTR (ACPI_LPIT_HEADER, Table, Offset);
703     while (Offset < Table->Length)
704     {
705         /* Common subtable header */
706 
707         Status = AcpiDmDumpTable (Length, Offset, Subtable,
708             sizeof (ACPI_LPIT_HEADER), AcpiDmTableInfoLpitHdr);
709         if (ACPI_FAILURE (Status))
710         {
711             return;
712         }
713 
714         switch (Subtable->Type)
715         {
716         case ACPI_LPIT_TYPE_NATIVE_CSTATE:
717 
718             InfoTable = AcpiDmTableInfoLpit0;
719             SubtableLength = sizeof (ACPI_LPIT_NATIVE);
720             break;
721 
722         default:
723 
724             /* Cannot continue on unknown type - no length */
725 
726             AcpiOsPrintf ("\n**** Unknown LPIT subtable type 0x%X\n",
727                 Subtable->Type);
728             return;
729         }
730 
731         Status = AcpiDmDumpTable (Length, Offset, Subtable,
732             SubtableLength, InfoTable);
733         if (ACPI_FAILURE (Status))
734         {
735             return;
736         }
737 
738         AcpiOsPrintf ("\n");
739 
740         /* Point to next subtable */
741 
742         Offset += SubtableLength;
743         Subtable = ACPI_ADD_PTR (ACPI_LPIT_HEADER, Subtable, SubtableLength);
744     }
745 }
746 
747 
748 /*******************************************************************************
749  *
750  * FUNCTION:    AcpiDmDumpMadt
751  *
752  * PARAMETERS:  Table               - A MADT table
753  *
754  * RETURN:      None
755  *
756  * DESCRIPTION: Format the contents of a MADT. This table type consists
757  *              of an open-ended number of subtables.
758  *
759  ******************************************************************************/
760 
761 void
AcpiDmDumpMadt(ACPI_TABLE_HEADER * Table)762 AcpiDmDumpMadt (
763     ACPI_TABLE_HEADER       *Table)
764 {
765     ACPI_STATUS             Status;
766     ACPI_SUBTABLE_HEADER    *Subtable;
767     UINT32                  Length = Table->Length;
768     UINT32                  Offset = sizeof (ACPI_TABLE_MADT);
769     ACPI_DMTABLE_INFO       *InfoTable;
770 
771 
772     /* Main table */
773 
774     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoMadt);
775     if (ACPI_FAILURE (Status))
776     {
777         return;
778     }
779 
780     /* Subtables */
781 
782     Subtable = ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, Table, Offset);
783     DbgPrint (ASL_PARSE_OUTPUT, "//0B) Offset %X, from table start: 0x%8.8X%8.8X\n",
784         Offset, ACPI_FORMAT_UINT64 (ACPI_CAST_PTR (char, Subtable) - ACPI_CAST_PTR (char, Table)));
785     while (Offset < Table->Length)
786     {
787         /* Common subtable header */
788 
789         AcpiOsPrintf ("\n");
790         Status = AcpiDmDumpTable (Length, Offset, Subtable,
791             Subtable->Length, AcpiDmTableInfoMadtHdr);
792         if (ACPI_FAILURE (Status))
793         {
794             return;
795         }
796 
797         DbgPrint (ASL_PARSE_OUTPUT, "subtableType: %X\n", Subtable->Type);
798         switch (Subtable->Type)
799         {
800         case ACPI_MADT_TYPE_LOCAL_APIC:
801 
802             InfoTable = AcpiDmTableInfoMadt0;
803             break;
804 
805         case ACPI_MADT_TYPE_IO_APIC:
806 
807             InfoTable = AcpiDmTableInfoMadt1;
808             break;
809 
810         case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
811 
812             InfoTable = AcpiDmTableInfoMadt2;
813             break;
814 
815         case ACPI_MADT_TYPE_NMI_SOURCE:
816 
817             InfoTable = AcpiDmTableInfoMadt3;
818             break;
819 
820         case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
821 
822             InfoTable = AcpiDmTableInfoMadt4;
823             break;
824 
825         case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
826 
827             InfoTable = AcpiDmTableInfoMadt5;
828             break;
829 
830         case ACPI_MADT_TYPE_IO_SAPIC:
831 
832             InfoTable = AcpiDmTableInfoMadt6;
833             break;
834 
835         case ACPI_MADT_TYPE_LOCAL_SAPIC:
836 
837             InfoTable = AcpiDmTableInfoMadt7;
838             break;
839 
840         case ACPI_MADT_TYPE_INTERRUPT_SOURCE:
841 
842             InfoTable = AcpiDmTableInfoMadt8;
843             break;
844 
845         case ACPI_MADT_TYPE_LOCAL_X2APIC:
846 
847             InfoTable = AcpiDmTableInfoMadt9;
848             break;
849 
850         case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
851 
852             InfoTable = AcpiDmTableInfoMadt10;
853             break;
854 
855         case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
856 
857             InfoTable = AcpiDmTableInfoMadt11;
858             break;
859 
860         case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
861 
862             InfoTable = AcpiDmTableInfoMadt12;
863             break;
864 
865         case ACPI_MADT_TYPE_GENERIC_MSI_FRAME:
866 
867             InfoTable = AcpiDmTableInfoMadt13;
868             break;
869 
870         case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR:
871 
872             InfoTable = AcpiDmTableInfoMadt14;
873             break;
874 
875         case ACPI_MADT_TYPE_GENERIC_TRANSLATOR:
876 
877             InfoTable = AcpiDmTableInfoMadt15;
878             break;
879 
880         case ACPI_MADT_TYPE_MULTIPROC_WAKEUP:
881 
882             InfoTable = AcpiDmTableInfoMadt16;
883             break;
884 
885         default:
886 
887             if ((Subtable->Type >= ACPI_MADT_TYPE_RESERVED) &&
888                 (Subtable->Type < ACPI_MADT_TYPE_OEM_RESERVED))
889             {
890                 AcpiOsPrintf ("\n**** Unknown MADT subtable type 0x%X\n\n",
891                     Subtable->Type);
892                 goto NextSubtable;
893             }
894             else if (Subtable->Type >= ACPI_MADT_TYPE_OEM_RESERVED)
895             {
896                 DbgPrint (ASL_PARSE_OUTPUT, "//[Found an OEM structure, type = %0x]\n",
897                     Subtable->Type);
898                 Offset += sizeof (ACPI_SUBTABLE_HEADER);
899                 DbgPrint (ASL_PARSE_OUTPUT, "//[0) Subtable->Length = %X, Subtable = %p, Offset = %X]\n",
900                     Subtable->Length, Subtable, Offset);
901                 DbgPrint (ASL_PARSE_OUTPUT, "//[0A) Offset from table start: 0x%8.8X%8.8X]\n",
902                     ACPI_FORMAT_UINT64 (ACPI_CAST_PTR (char, Subtable) - ACPI_CAST_PTR (char, Table)));
903             }
904 
905             /* Attempt to continue */
906 
907             if (!Subtable->Length)
908             {
909                 AcpiOsPrintf ("Invalid zero length subtable\n");
910                 return;
911             }
912 
913             /* Dump the OEM data */
914 
915             Status = AcpiDmDumpTable (Length, Offset, ACPI_CAST_PTR (UINT8, Table) + Offset,
916                 Subtable->Length - sizeof (ACPI_SUBTABLE_HEADER), AcpiDmTableInfoMadt17);
917             if (ACPI_FAILURE (Status))
918             {
919                 return;
920             }
921 
922             DbgPrint (ASL_PARSE_OUTPUT, "//[1) Subtable->Length = %X, Offset = %X]\n",
923                 Subtable->Length, Offset);
924             Offset -= sizeof (ACPI_SUBTABLE_HEADER);
925 
926             goto NextSubtable;
927         }
928 
929         DbgPrint (ASL_PARSE_OUTPUT, "//[2) Subtable->Length = %X, Offset = %X]\n",
930             Subtable->Length, Offset);
931         Status = AcpiDmDumpTable (Length, Offset, Subtable,
932             Subtable->Length, InfoTable);
933         if (ACPI_FAILURE (Status))
934         {
935             return;
936         }
937 
938 NextSubtable:
939         /* Point to next subtable */
940 
941         DbgPrint (ASL_PARSE_OUTPUT, "//[3) Subtable->Length = %X, Offset = %X]\n",
942             Subtable->Length, Offset);
943         DbgPrint (ASL_PARSE_OUTPUT, "//[4) Offset from table start: 0x%8.8X%8.8X (%p) %p]\n",
944             ACPI_FORMAT_UINT64 (ACPI_CAST_PTR (UINT8, Subtable) - ACPI_CAST_PTR (UINT8, Table)), Subtable, Table);
945         if (Offset > Table->Length)
946         {
947             return;
948         }
949 
950         Subtable = ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, Subtable,
951             Subtable->Length);
952 
953         DbgPrint (ASL_PARSE_OUTPUT, "//[5) Next Subtable %p, length %X]\n",
954             Subtable, Subtable->Length);
955         DbgPrint (ASL_PARSE_OUTPUT, "//[5B) Offset from table start: 0x%8.8X%8.8X (%p)]\n",
956             ACPI_FORMAT_UINT64 (ACPI_CAST_PTR (char, Subtable) - ACPI_CAST_PTR (char, Table)), Subtable);
957 
958         Offset = ACPI_CAST_PTR (char, Subtable) - ACPI_CAST_PTR (char, Table);
959         if (Offset >= Table->Length)
960         {
961             return;
962         }
963     }
964 }
965 
966 
967 /*******************************************************************************
968  *
969  * FUNCTION:    AcpiDmDumpMcfg
970  *
971  * PARAMETERS:  Table               - A MCFG Table
972  *
973  * RETURN:      None
974  *
975  * DESCRIPTION: Format the contents of a MCFG table
976  *
977  ******************************************************************************/
978 
979 void
AcpiDmDumpMcfg(ACPI_TABLE_HEADER * Table)980 AcpiDmDumpMcfg (
981     ACPI_TABLE_HEADER       *Table)
982 {
983     ACPI_STATUS             Status;
984     UINT32                  Offset = sizeof (ACPI_TABLE_MCFG);
985     ACPI_MCFG_ALLOCATION    *Subtable;
986 
987 
988     /* Main table */
989 
990     Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoMcfg);
991     if (ACPI_FAILURE (Status))
992     {
993         return;
994     }
995 
996     /* Subtables */
997 
998     Subtable = ACPI_ADD_PTR (ACPI_MCFG_ALLOCATION, Table, Offset);
999     while (Offset < Table->Length)
1000     {
1001         if (Offset + sizeof (ACPI_MCFG_ALLOCATION) > Table->Length)
1002         {
1003             AcpiOsPrintf ("Warning: there are %u invalid trailing bytes\n",
1004                 (UINT32) sizeof (ACPI_MCFG_ALLOCATION) - (Offset - Table->Length));
1005             return;
1006         }
1007 
1008         AcpiOsPrintf ("\n");
1009         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
1010             sizeof (ACPI_MCFG_ALLOCATION), AcpiDmTableInfoMcfg0);
1011         if (ACPI_FAILURE (Status))
1012         {
1013             return;
1014         }
1015 
1016         /* Point to next subtable (each subtable is of fixed length) */
1017 
1018         Offset += sizeof (ACPI_MCFG_ALLOCATION);
1019         Subtable = ACPI_ADD_PTR (ACPI_MCFG_ALLOCATION, Subtable,
1020             sizeof (ACPI_MCFG_ALLOCATION));
1021     }
1022 }
1023 
1024 
1025 /*******************************************************************************
1026  *
1027  * FUNCTION:    AcpiDmDumpMpst
1028  *
1029  * PARAMETERS:  Table               - A MPST Table
1030  *
1031  * RETURN:      None
1032  *
1033  * DESCRIPTION: Format the contents of a MPST table
1034  *
1035  ******************************************************************************/
1036 
1037 void
AcpiDmDumpMpst(ACPI_TABLE_HEADER * Table)1038 AcpiDmDumpMpst (
1039     ACPI_TABLE_HEADER       *Table)
1040 {
1041     ACPI_STATUS             Status;
1042     UINT32                  Offset = sizeof (ACPI_TABLE_MPST);
1043     ACPI_MPST_POWER_NODE    *Subtable0;
1044     ACPI_MPST_POWER_STATE   *Subtable0A;
1045     ACPI_MPST_COMPONENT     *Subtable0B;
1046     ACPI_MPST_DATA_HDR      *Subtable1;
1047     ACPI_MPST_POWER_DATA    *Subtable2;
1048     UINT16                  SubtableCount;
1049     UINT32                  PowerStateCount;
1050     UINT32                  ComponentCount;
1051 
1052 
1053     /* Main table */
1054 
1055     Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoMpst);
1056     if (ACPI_FAILURE (Status))
1057     {
1058         return;
1059     }
1060 
1061     /* Subtable: Memory Power Node(s) */
1062 
1063     SubtableCount = (ACPI_CAST_PTR (ACPI_TABLE_MPST, Table))->PowerNodeCount;
1064     Subtable0 = ACPI_ADD_PTR (ACPI_MPST_POWER_NODE, Table, Offset);
1065 
1066     while ((Offset < Table->Length) && SubtableCount)
1067     {
1068         AcpiOsPrintf ("\n");
1069         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable0,
1070             sizeof (ACPI_MPST_POWER_NODE), AcpiDmTableInfoMpst0);
1071         if (ACPI_FAILURE (Status))
1072         {
1073             return;
1074         }
1075 
1076         /* Extract the sub-subtable counts */
1077 
1078         PowerStateCount = Subtable0->NumPowerStates;
1079         ComponentCount = Subtable0->NumPhysicalComponents;
1080         Offset += sizeof (ACPI_MPST_POWER_NODE);
1081 
1082         /* Sub-subtables - Memory Power State Structure(s) */
1083 
1084         Subtable0A = ACPI_ADD_PTR (ACPI_MPST_POWER_STATE, Subtable0,
1085             sizeof (ACPI_MPST_POWER_NODE));
1086 
1087         while (PowerStateCount)
1088         {
1089             AcpiOsPrintf ("\n");
1090             Status = AcpiDmDumpTable (Table->Length, Offset, Subtable0A,
1091                 sizeof (ACPI_MPST_POWER_STATE), AcpiDmTableInfoMpst0A);
1092             if (ACPI_FAILURE (Status))
1093             {
1094                 return;
1095             }
1096 
1097             Subtable0A++;
1098             PowerStateCount--;
1099             Offset += sizeof (ACPI_MPST_POWER_STATE);
1100        }
1101 
1102         /* Sub-subtables - Physical Component ID Structure(s) */
1103 
1104         Subtable0B = ACPI_CAST_PTR (ACPI_MPST_COMPONENT, Subtable0A);
1105 
1106         if (ComponentCount)
1107         {
1108             AcpiOsPrintf ("\n");
1109         }
1110 
1111         while (ComponentCount)
1112         {
1113             Status = AcpiDmDumpTable (Table->Length, Offset, Subtable0B,
1114                 sizeof (ACPI_MPST_COMPONENT), AcpiDmTableInfoMpst0B);
1115             if (ACPI_FAILURE (Status))
1116             {
1117                 return;
1118             }
1119 
1120             Subtable0B++;
1121             ComponentCount--;
1122             Offset += sizeof (ACPI_MPST_COMPONENT);
1123         }
1124 
1125         /* Point to next Memory Power Node subtable */
1126 
1127         SubtableCount--;
1128         Subtable0 = ACPI_ADD_PTR (ACPI_MPST_POWER_NODE, Subtable0,
1129             sizeof (ACPI_MPST_POWER_NODE) +
1130             (sizeof (ACPI_MPST_POWER_STATE) * Subtable0->NumPowerStates) +
1131             (sizeof (ACPI_MPST_COMPONENT) * Subtable0->NumPhysicalComponents));
1132     }
1133 
1134     /* Subtable: Count of Memory Power State Characteristic structures */
1135 
1136     AcpiOsPrintf ("\n");
1137     Subtable1 = ACPI_CAST_PTR (ACPI_MPST_DATA_HDR, Subtable0);
1138     Status = AcpiDmDumpTable (Table->Length, Offset, Subtable1,
1139         sizeof (ACPI_MPST_DATA_HDR), AcpiDmTableInfoMpst1);
1140     if (ACPI_FAILURE (Status))
1141     {
1142         return;
1143     }
1144 
1145     SubtableCount = Subtable1->CharacteristicsCount;
1146     Offset += sizeof (ACPI_MPST_DATA_HDR);
1147 
1148     /* Subtable: Memory Power State Characteristics structure(s) */
1149 
1150     Subtable2 = ACPI_ADD_PTR (ACPI_MPST_POWER_DATA, Subtable1,
1151         sizeof (ACPI_MPST_DATA_HDR));
1152 
1153     while ((Offset < Table->Length) && SubtableCount)
1154     {
1155         AcpiOsPrintf ("\n");
1156         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable2,
1157             sizeof (ACPI_MPST_POWER_DATA), AcpiDmTableInfoMpst2);
1158         if (ACPI_FAILURE (Status))
1159         {
1160             return;
1161         }
1162 
1163         Subtable2++;
1164         SubtableCount--;
1165         Offset += sizeof (ACPI_MPST_POWER_DATA);
1166     }
1167 }
1168 
1169 
1170 /*******************************************************************************
1171  *
1172  * FUNCTION:    AcpiDmDumpMsct
1173  *
1174  * PARAMETERS:  Table               - A MSCT table
1175  *
1176  * RETURN:      None
1177  *
1178  * DESCRIPTION: Format the contents of a MSCT
1179  *
1180  ******************************************************************************/
1181 
1182 void
AcpiDmDumpMsct(ACPI_TABLE_HEADER * Table)1183 AcpiDmDumpMsct (
1184     ACPI_TABLE_HEADER       *Table)
1185 {
1186     ACPI_STATUS             Status;
1187     UINT32                  Offset = sizeof (ACPI_TABLE_MSCT);
1188     ACPI_MSCT_PROXIMITY     *Subtable;
1189 
1190 
1191     /* Main table */
1192 
1193     Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoMsct);
1194     if (ACPI_FAILURE (Status))
1195     {
1196         return;
1197     }
1198 
1199     /* Subtables */
1200 
1201     Subtable = ACPI_ADD_PTR (ACPI_MSCT_PROXIMITY, Table, Offset);
1202     while (Offset < Table->Length)
1203     {
1204         /* Common subtable header */
1205 
1206         AcpiOsPrintf ("\n");
1207         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
1208             sizeof (ACPI_MSCT_PROXIMITY), AcpiDmTableInfoMsct0);
1209         if (ACPI_FAILURE (Status))
1210         {
1211             return;
1212         }
1213 
1214         /* Point to next subtable */
1215 
1216         Offset += sizeof (ACPI_MSCT_PROXIMITY);
1217         Subtable = ACPI_ADD_PTR (ACPI_MSCT_PROXIMITY, Subtable,
1218             sizeof (ACPI_MSCT_PROXIMITY));
1219     }
1220 }
1221 
1222 
1223 /*******************************************************************************
1224  *
1225  * FUNCTION:    AcpiDmDumpNfit
1226  *
1227  * PARAMETERS:  Table               - A NFIT table
1228  *
1229  * RETURN:      None
1230  *
1231  * DESCRIPTION: Format the contents of an NFIT.
1232  *
1233  ******************************************************************************/
1234 
1235 void
AcpiDmDumpNfit(ACPI_TABLE_HEADER * Table)1236 AcpiDmDumpNfit (
1237     ACPI_TABLE_HEADER       *Table)
1238 {
1239     ACPI_STATUS             Status;
1240     UINT32                  Offset = sizeof (ACPI_TABLE_NFIT);
1241     UINT32                  FieldOffset = 0;
1242     UINT32                  Length;
1243     ACPI_NFIT_HEADER        *Subtable;
1244     ACPI_DMTABLE_INFO       *InfoTable;
1245     ACPI_NFIT_INTERLEAVE    *Interleave = NULL;
1246     ACPI_NFIT_SMBIOS        *SmbiosInfo = NULL;
1247     ACPI_NFIT_FLUSH_ADDRESS *Hint = NULL;
1248     UINT32                  i;
1249 
1250 
1251     /* Main table */
1252 
1253     Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoNfit);
1254     if (ACPI_FAILURE (Status))
1255     {
1256         return;
1257     }
1258 
1259     /* Subtables */
1260 
1261     Subtable = ACPI_ADD_PTR (ACPI_NFIT_HEADER, Table, Offset);
1262     while (Offset < Table->Length)
1263     {
1264         /* NFIT subtable header */
1265 
1266         AcpiOsPrintf ("\n");
1267         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
1268             Subtable->Length, AcpiDmTableInfoNfitHdr);
1269         if (ACPI_FAILURE (Status))
1270         {
1271             return;
1272         }
1273 
1274         switch (Subtable->Type)
1275         {
1276         case ACPI_NFIT_TYPE_SYSTEM_ADDRESS:
1277 
1278             InfoTable = AcpiDmTableInfoNfit0;
1279             break;
1280 
1281         case ACPI_NFIT_TYPE_MEMORY_MAP:
1282 
1283             InfoTable = AcpiDmTableInfoNfit1;
1284             break;
1285 
1286         case ACPI_NFIT_TYPE_INTERLEAVE:
1287 
1288             /* Has a variable number of 32-bit values at the end */
1289 
1290             InfoTable = AcpiDmTableInfoNfit2;
1291             FieldOffset = sizeof (ACPI_NFIT_INTERLEAVE);
1292             break;
1293 
1294         case ACPI_NFIT_TYPE_SMBIOS:
1295 
1296             SmbiosInfo = ACPI_CAST_PTR (ACPI_NFIT_SMBIOS, Subtable);
1297             InfoTable = AcpiDmTableInfoNfit3;
1298             break;
1299 
1300         case ACPI_NFIT_TYPE_CONTROL_REGION:
1301 
1302             InfoTable = AcpiDmTableInfoNfit4;
1303             break;
1304 
1305         case ACPI_NFIT_TYPE_DATA_REGION:
1306 
1307             InfoTable = AcpiDmTableInfoNfit5;
1308             break;
1309 
1310         case ACPI_NFIT_TYPE_FLUSH_ADDRESS:
1311 
1312             /* Has a variable number of 64-bit addresses at the end */
1313 
1314             InfoTable = AcpiDmTableInfoNfit6;
1315             FieldOffset = sizeof (ACPI_NFIT_FLUSH_ADDRESS) - sizeof (UINT64);
1316             break;
1317 
1318         case ACPI_NFIT_TYPE_CAPABILITIES:    /* ACPI 6.0A */
1319 
1320             InfoTable = AcpiDmTableInfoNfit7;
1321             break;
1322 
1323         default:
1324             AcpiOsPrintf ("\n**** Unknown NFIT subtable type 0x%X\n",
1325                 Subtable->Type);
1326 
1327             /* Attempt to continue */
1328 
1329             if (!Subtable->Length)
1330             {
1331                 AcpiOsPrintf ("Invalid zero length subtable\n");
1332                 return;
1333             }
1334             goto NextSubtable;
1335         }
1336 
1337         AcpiOsPrintf ("\n");
1338         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
1339             Subtable->Length, InfoTable);
1340         if (ACPI_FAILURE (Status))
1341         {
1342             return;
1343         }
1344 
1345         /* Per-subtable variable-length fields */
1346 
1347         switch (Subtable->Type)
1348         {
1349         case ACPI_NFIT_TYPE_INTERLEAVE:
1350 
1351             Interleave = ACPI_CAST_PTR (ACPI_NFIT_INTERLEAVE, Subtable);
1352             for (i = 0; i < Interleave->LineCount; i++)
1353             {
1354                 Status = AcpiDmDumpTable (Table->Length, Offset + FieldOffset,
1355                     &Interleave->LineOffset[i],
1356                     sizeof (UINT32), AcpiDmTableInfoNfit2a);
1357                 if (ACPI_FAILURE (Status))
1358                 {
1359                     return;
1360                 }
1361 
1362                 FieldOffset += sizeof (UINT32);
1363             }
1364             break;
1365 
1366         case ACPI_NFIT_TYPE_SMBIOS:
1367 
1368             Length = Subtable->Length -
1369                 sizeof (ACPI_NFIT_SMBIOS) + sizeof (UINT8);
1370 
1371             if (Length)
1372             {
1373                 Status = AcpiDmDumpTable (Table->Length,
1374                     sizeof (ACPI_NFIT_SMBIOS) - sizeof (UINT8),
1375                     SmbiosInfo,
1376                     Length, AcpiDmTableInfoNfit3a);
1377                 if (ACPI_FAILURE (Status))
1378                 {
1379                     return;
1380                 }
1381             }
1382 
1383             break;
1384 
1385         case ACPI_NFIT_TYPE_FLUSH_ADDRESS:
1386 
1387             Hint = ACPI_CAST_PTR (ACPI_NFIT_FLUSH_ADDRESS, Subtable);
1388             for (i = 0; i < Hint->HintCount; i++)
1389             {
1390                 Status = AcpiDmDumpTable (Table->Length, Offset + FieldOffset,
1391                     &Hint->HintAddress[i],
1392                     sizeof (UINT64), AcpiDmTableInfoNfit6a);
1393                 if (ACPI_FAILURE (Status))
1394                 {
1395                     return;
1396                 }
1397 
1398                 FieldOffset += sizeof (UINT64);
1399             }
1400             break;
1401 
1402         default:
1403             break;
1404         }
1405 
1406 NextSubtable:
1407         /* Point to next subtable */
1408 
1409         Offset += Subtable->Length;
1410         Subtable = ACPI_ADD_PTR (ACPI_NFIT_HEADER, Subtable, Subtable->Length);
1411     }
1412 }
1413 
1414 
1415 /*******************************************************************************
1416  *
1417  * FUNCTION:    AcpiDmDumpNhlt
1418  *
1419  * PARAMETERS:  Table               - A NHLT table
1420  *
1421  * RETURN:      None
1422  *
1423  * DESCRIPTION: Format the contents of an NHLT.
1424  *
1425  ******************************************************************************/
1426 
1427 void
AcpiDmDumpNhlt(ACPI_TABLE_HEADER * Table)1428 AcpiDmDumpNhlt (
1429     ACPI_TABLE_HEADER       *Table)
1430 {
1431     ACPI_STATUS             Status;
1432     UINT32                  Offset;
1433     UINT32                  TableLength = Table->Length;
1434     UINT32                  EndpointCount;
1435     UINT8                   FormatsCount;
1436     ACPI_NHLT_ENDPOINT      *Subtable;
1437     ACPI_NHLT_FORMAT_CONFIG *FormatSubtable;
1438     ACPI_TABLE_NHLT         *InfoTable;
1439     UINT32                  CapabilitiesSize;
1440     UINT32                  i;
1441     UINT32                  j;
1442     UINT32                  EndpointEndOffset;
1443     UINT8                   ConfigType = 0;
1444     UINT8                   ArrayType;
1445     UINT8                   MicrophoneCount;
1446     ACPI_NHLT_VENDOR_MIC_COUNT          *MicCount;
1447     ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_A  *DevSpecific;
1448     ACPI_NHLT_FORMATS_CONFIG            *FormatsConfig;
1449     ACPI_NHLT_DEVICE_INFO_COUNT         *Count;
1450     ACPI_NHLT_DEVICE_INFO               *DeviceInfo;
1451     ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_B  *Capabilities;
1452 
1453 
1454     /* Main table */
1455 
1456     AcpiOsPrintf ("    /* Main table */\n");
1457 
1458     Status = AcpiDmDumpTable (TableLength, 0, Table, 0, AcpiDmTableInfoNhlt);
1459     if (ACPI_FAILURE (Status))
1460     {
1461         return;
1462     }
1463 
1464     /* Get the Endpoint Descriptor Count */
1465 
1466     InfoTable = ACPI_ADD_PTR (ACPI_TABLE_NHLT, Table, 0);
1467     EndpointCount = InfoTable->EndpointCount;
1468 
1469     /* Subtables */
1470 
1471     Offset = sizeof (ACPI_TABLE_NHLT);
1472 
1473     while (Offset < TableLength)
1474     {
1475         /* A variable number of Endpoint Descriptors - process each */
1476 
1477         for (i = 0; i < EndpointCount; i++)
1478         {
1479             /* Do the Endpoint Descriptor table */
1480 
1481             Subtable = ACPI_ADD_PTR (ACPI_NHLT_ENDPOINT, Table, Offset);
1482 
1483             /* Check for endpoint descriptor length beyond end-of-table */
1484 
1485             if (Subtable->DescriptorLength > TableLength)
1486             {
1487                 Offset += 1;
1488                 AcpiOsPrintf ("\n    /* Endpoint Descriptor Length larger than"
1489                     " table size: %X, table %X, adjusting table offset (+1) */\n",
1490                     Subtable->DescriptorLength, TableLength);
1491 
1492                 Subtable = ACPI_ADD_PTR (ACPI_NHLT_ENDPOINT, Table, Offset);
1493             }
1494 
1495             AcpiOsPrintf ("\n    /* Endpoint Descriptor #%u */\n", i+1);
1496             Status = AcpiDmDumpTable (TableLength, Offset, Subtable,
1497                 Subtable->DescriptorLength, AcpiDmTableInfoNhlt0);
1498             if (ACPI_FAILURE (Status))
1499             {
1500                 return;
1501             }
1502 
1503             EndpointEndOffset = Subtable->DescriptorLength + Offset;
1504 
1505             /* Check for endpoint descriptor beyond end-of-table */
1506 
1507             if (Subtable->DescriptorLength > TableLength)
1508             {
1509                 AcpiOsPrintf ("\n    /* Endpoint Descriptor Length larger than table size: %X, table %X */\n",
1510                     Subtable->DescriptorLength, TableLength);
1511             }
1512 
1513             Offset += sizeof (ACPI_NHLT_ENDPOINT);
1514             Subtable = ACPI_ADD_PTR (ACPI_NHLT_ENDPOINT, Table, Offset);
1515 
1516             /* Do the Device Specific table */
1517 
1518             AcpiOsPrintf ("\n    /* Endpoint Device_Specific_Config table */\n");
1519             DevSpecific = ACPI_CAST_PTR (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_A, Subtable);
1520             CapabilitiesSize = DevSpecific->CapabilitiesSize;
1521             Status = AcpiDmDumpTable (TableLength, Offset, DevSpecific,
1522                 sizeof (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_B), AcpiDmTableInfoNhlt5b);
1523             if (ACPI_FAILURE (Status))
1524             {
1525                 return;
1526             }
1527 
1528             ArrayType = 0;
1529 
1530             /* Different subtables based upon capabilities_size */
1531 
1532             switch (CapabilitiesSize)
1533             {
1534             case 0:
1535                 Offset += sizeof (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_B);
1536                 break;
1537 
1538             case 1:
1539                 Status = AcpiDmDumpTable (TableLength, Offset, DevSpecific,
1540                     sizeof (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_C), AcpiDmTableInfoNhlt5c);
1541                 if (ACPI_FAILURE (Status))
1542                 {
1543                     return;
1544                 }
1545                 Offset += sizeof (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_C);
1546                 break;
1547 
1548             case 2:
1549                 Status = AcpiDmDumpTable (TableLength, Offset, DevSpecific,
1550                     sizeof (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG), AcpiDmTableInfoNhlt5);
1551                 if (ACPI_FAILURE (Status))
1552                 {
1553                     return;
1554                 }
1555                 Offset += sizeof (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG);
1556                 break;
1557 
1558             case 3:
1559             default:
1560                 /* Extract the ConfigType and ArrayType */
1561 
1562                 ConfigType = DevSpecific->ConfigType;
1563                 ArrayType = DevSpecific->ArrayType;
1564 
1565                 Status = AcpiDmDumpTable (TableLength, Offset, DevSpecific,
1566                     sizeof (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_A), AcpiDmTableInfoNhlt5a);
1567                 if (ACPI_FAILURE (Status))
1568                 {
1569                     return;
1570                 }
1571 
1572                 /* Capabilities Size == 3 */
1573                 Offset += sizeof (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_A);
1574                 break;
1575 
1576             case 7:
1577                 ConfigType = DevSpecific->ConfigType;
1578                 Subtable = ACPI_ADD_PTR (ACPI_NHLT_ENDPOINT, Table, Offset);
1579                 DevSpecific = ACPI_CAST_PTR (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_A, Subtable);
1580 
1581                 AcpiOsPrintf ("\n    /* Render Feedback Device-Specific table */\n");
1582                 Status = AcpiDmDumpTable (TableLength, Offset, DevSpecific,
1583                     sizeof (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG), AcpiDmTableInfoNhlt5);
1584                 if (ACPI_FAILURE (Status))
1585                 {
1586                     return;
1587                 }
1588 
1589                 /* Capabilities Size = 7 */
1590                 Offset += sizeof (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG);
1591 
1592                 if (ConfigType == ACPI_NHLT_CONFIG_TYPE_RENDER_FEEDBACK)
1593                 {
1594                     Subtable = ACPI_ADD_PTR (ACPI_NHLT_ENDPOINT, Table, Offset);
1595                     DevSpecific = ACPI_CAST_PTR (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_A, Subtable);
1596 
1597                     Status = AcpiDmDumpTable (TableLength, Offset, DevSpecific,
1598                         sizeof (ACPI_NHLT_RENDER_FEEDBACK_DEVICE_SPECIFIC_CONFIG), AcpiDmTableInfoNhlt6b);
1599                     if (ACPI_FAILURE (Status))
1600                     {
1601                         return;
1602                     }
1603                     Offset += sizeof (ACPI_NHLT_RENDER_FEEDBACK_DEVICE_SPECIFIC_CONFIG);
1604                 }
1605                 break;
1606            }
1607 
1608             /* Check for a vendor-defined mic array */
1609 
1610             if (ConfigType == ACPI_NHLT_CONFIG_TYPE_MIC_ARRAY)
1611             {
1612                 if ((ArrayType & ACPI_NHLT_ARRAY_TYPE_MASK) == ACPI_NHLT_VENDOR_DEFINED)
1613                 {
1614                     /* Vendor-defined microphone array; get the microphone count first */
1615 
1616                     AcpiOsPrintf ("\n    /* Vendor-defined microphone count */\n");
1617                     MicCount = ACPI_ADD_PTR (ACPI_NHLT_VENDOR_MIC_COUNT, Table, Offset);
1618                     MicrophoneCount = MicCount->MicrophoneCount;
1619 
1620                     Status = AcpiDmDumpTable (TableLength, Offset, MicCount,
1621                         sizeof (ACPI_NHLT_VENDOR_MIC_COUNT), AcpiDmTableInfoNhlt6a);
1622                     Offset += sizeof (ACPI_NHLT_VENDOR_MIC_COUNT);
1623                     if (ACPI_FAILURE (Status))
1624                     {
1625                         return;
1626                     }
1627 
1628                     /* Get the vendor microphone config structure(s) */
1629 
1630                     for (j = 0; j < MicrophoneCount; j++)
1631                     {
1632                         AcpiOsPrintf ("\n    /* Vendor-defined microphone array #%u*/\n", j+1);
1633                         DevSpecific = ACPI_ADD_PTR (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_A, Table, Offset);
1634 
1635                         Status = AcpiDmDumpTable (TableLength, Offset, DevSpecific,
1636                             sizeof (ACPI_NHLT_VENDOR_MIC_CONFIG), AcpiDmTableInfoNhlt6);
1637                         if (ACPI_FAILURE (Status))
1638                         {
1639                             return;
1640                         }
1641 
1642                         Offset += sizeof (ACPI_NHLT_VENDOR_MIC_CONFIG);
1643                     }
1644 
1645                     /* Check for Microphone SNR and sensitivity extension */
1646 
1647                     if ((ArrayType & ACPI_NHLT_ARRAY_TYPE_EXT_MASK) == ACPI_NHLT_MIC_SNR_SENSITIVITY_EXT)
1648                     {
1649                         AcpiOsPrintf ("\n    /* Microphone SNR and sensitivity array */\n");
1650                         DevSpecific = ACPI_ADD_PTR (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_A, Table, Offset);
1651 
1652                         Status = AcpiDmDumpTable (TableLength, Offset, DevSpecific,
1653                             sizeof (ACPI_NHLT_MIC_SNR_SENSITIVITY_EXTENSION), AcpiDmTableInfoNhlt9);
1654                         if (ACPI_FAILURE (Status))
1655                         {
1656                             return;
1657                         }
1658 
1659                         Offset += sizeof (ACPI_NHLT_MIC_SNR_SENSITIVITY_EXTENSION);
1660                     }
1661                 }
1662             }
1663 
1664             /* Do the Formats_Config table - starts with the FormatsCount field */
1665 
1666             FormatsConfig = ACPI_ADD_PTR (ACPI_NHLT_FORMATS_CONFIG, Table, Offset);
1667             FormatsCount = FormatsConfig->FormatsCount;
1668 
1669             AcpiOsPrintf ("\n    /* Formats_Config table */\n");
1670 
1671             /* Dump the FormatsCount value */
1672 
1673             if (FormatsCount > 0)
1674             {
1675                 Status = AcpiDmDumpTable (TableLength, Offset, FormatsConfig,
1676                     sizeof (ACPI_NHLT_FORMATS_CONFIG), AcpiDmTableInfoNhlt4);
1677                 if (ACPI_FAILURE (Status))
1678                 {
1679                     return;
1680                 }
1681             }
1682             Offset += sizeof (ACPI_NHLT_FORMATS_CONFIG);
1683 
1684             /* A variable number of Format_Config Descriptors - process each */
1685 
1686             for (j = 0; j < FormatsCount; j++)
1687             {
1688                 FormatSubtable = ACPI_ADD_PTR (ACPI_NHLT_FORMAT_CONFIG, Table, Offset);
1689                 CapabilitiesSize = FormatSubtable->CapabilitySize;
1690 
1691                 /* Do the Wave_extensible struct */
1692 
1693                 AcpiOsPrintf ("\n    /* Wave_Format_Extensible table #%u */\n", j+1);
1694                 Status = AcpiDmDumpTable (TableLength, Offset, FormatSubtable,
1695                     sizeof (ACPI_NHLT_FORMAT_CONFIG), AcpiDmTableInfoNhlt3);
1696                 if (ACPI_FAILURE (Status))
1697                 {
1698                     return;
1699                 }
1700 
1701                 Offset += sizeof (ACPI_NHLT_FORMAT_CONFIG);
1702 
1703                 if (CapabilitiesSize > 0)
1704                 {
1705                     UINT8* CapabilitiesBuf = ACPI_ADD_PTR (UINT8, Table, Offset);
1706                     /* Do the Capabilities array (of bytes) */
1707 
1708                     AcpiOsPrintf ("\n    /* Specific_Config table #%u */\n", j+1);
1709 
1710                     Status = AcpiDmDumpTable (TableLength, Offset, CapabilitiesBuf,
1711                         CapabilitiesSize, AcpiDmTableInfoNhlt3a);
1712                     if (ACPI_FAILURE (Status))
1713                     {
1714                         return;
1715                     }
1716 
1717                     Offset += CapabilitiesSize; /* + sizeof (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_B); */
1718                 }
1719 
1720             } /* for (j = 0; j < FormatsCount; j++) */
1721 
1722             /*
1723              * If we are not done with the current Endpoint yet, then there must be
1724              * some non documented structure(s) yet to be processed. First, get
1725              * the count of such structure(s).
1726              */
1727             if (Offset < EndpointEndOffset)
1728             {
1729                 AcpiOsPrintf ("\n    /* Structures that are not part of NHLT spec */\n");
1730                 Count = ACPI_ADD_PTR (ACPI_NHLT_DEVICE_INFO_COUNT, Table, Offset);
1731                 Status = AcpiDmDumpTable (TableLength, Offset, Count,
1732                     sizeof (ACPI_NHLT_DEVICE_INFO_COUNT), AcpiDmTableInfoNhlt7);
1733                 if (ACPI_FAILURE (Status))
1734                 {
1735                     return;
1736                 }
1737                 Offset += sizeof (ACPI_NHLT_DEVICE_INFO_COUNT);
1738 
1739                 /* Variable number of device structures */
1740 
1741                 for (j = 0; j < Count->StructureCount; j++)
1742                 {
1743                     DeviceInfo = ACPI_ADD_PTR (ACPI_NHLT_DEVICE_INFO, Table, Offset);
1744                     AcpiOsPrintf ("\n    /* Device Info structure #%u (not part of NHLT spec) */\n", j+1);
1745 
1746                     /*
1747                      * Dump the following Device Info fields:
1748                      *  1) Device ID
1749                      *  2) Device Instance ID
1750                      *  3) Device Port ID
1751                      */
1752                     Status = AcpiDmDumpTable (TableLength, Offset, DeviceInfo,
1753                         sizeof (ACPI_NHLT_DEVICE_INFO), AcpiDmTableInfoNhlt7a);
1754                     if (ACPI_FAILURE (Status))
1755                     {
1756                         return;
1757                     }
1758 
1759                     Offset += sizeof (ACPI_NHLT_DEVICE_INFO);
1760                 }
1761 
1762                 /*
1763                  * Check that the current offset is not beyond the end of
1764                  * this endpoint descriptor. If it is not, print those
1765                  * undocumented bytes.
1766                  */
1767                 if (Offset < EndpointEndOffset)
1768                 {
1769                     /* Unknown data at the end of the Endpoint */
1770                     UINT32 size = EndpointEndOffset - Offset;
1771                     UINT8* buffer = ACPI_ADD_PTR (UINT8, Table, Offset);
1772                     AcpiOsPrintf ("\n    /* Unknown data at the end of the Endpoint, size: %X */\n", size);
1773                     Status = AcpiDmDumpTable (TableLength, Offset, buffer,
1774                         size, AcpiDmTableInfoNhlt7b);
1775                     Offset = EndpointEndOffset;
1776                 }
1777 
1778                 /* Should be at the end of the Endpoint structure. */
1779             }
1780 
1781         } /* for (i = 0; i < EndpointCount; i++) */
1782 
1783 
1784         /*
1785          * Done with all of the Endpoint Descriptors, Emit the table terminator
1786          * (if such a legacy structure is present -- not in NHLT specification)
1787          */
1788         if (Offset < TableLength)
1789         {
1790             Capabilities = ACPI_ADD_PTR (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_B, Table, Offset);
1791             AcpiOsPrintf ("\n/* Terminating specific config (not part of NHLT spec) */\n");
1792 
1793             Status = AcpiDmDumpTable (TableLength, Offset, Capabilities,
1794                 sizeof (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_B), AcpiDmTableInfoNhlt5b);
1795             if (ACPI_FAILURE (Status))
1796             {
1797                 return;
1798             }
1799             Offset += sizeof (ACPI_NHLT_DEVICE_SPECIFIC_CONFIG_B);
1800 
1801             if (Capabilities->CapabilitiesSize > 0)
1802             {
1803                 UINT32 remainingBytes = TableLength - Offset;
1804                 UINT8* buffer = ACPI_ADD_PTR (UINT8, Table, Offset);
1805 
1806                 if (remainingBytes != Capabilities->CapabilitiesSize)
1807                     AcpiOsPrintf ("\n/* Incorrect config size, should be %X, is %X */\n",
1808                         Capabilities->CapabilitiesSize, remainingBytes);
1809                 Status = AcpiDmDumpTable (TableLength, Offset, buffer,
1810                         remainingBytes, AcpiDmTableInfoNhlt3a);
1811             }
1812         }
1813 
1814         return;
1815     }
1816 }
1817 
1818 
1819 /*******************************************************************************
1820  *
1821  * FUNCTION:    AcpiDmDumpPcct
1822  *
1823  * PARAMETERS:  Table               - A PCCT table
1824  *
1825  * RETURN:      None
1826  *
1827  * DESCRIPTION: Format the contents of a PCCT. This table type consists
1828  *              of an open-ended number of subtables.
1829  *
1830  ******************************************************************************/
1831 
1832 void
AcpiDmDumpPcct(ACPI_TABLE_HEADER * Table)1833 AcpiDmDumpPcct (
1834     ACPI_TABLE_HEADER       *Table)
1835 {
1836     ACPI_STATUS             Status;
1837     ACPI_PCCT_SUBSPACE      *Subtable;
1838     ACPI_DMTABLE_INFO       *InfoTable;
1839     UINT32                  Length = Table->Length;
1840     UINT32                  Offset = sizeof (ACPI_TABLE_PCCT);
1841 
1842 
1843     /* Main table */
1844 
1845     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoPcct);
1846     if (ACPI_FAILURE (Status))
1847     {
1848         return;
1849     }
1850 
1851     /* Subtables */
1852 
1853     Subtable = ACPI_ADD_PTR (ACPI_PCCT_SUBSPACE, Table, Offset);
1854     while (Offset < Table->Length)
1855     {
1856         /* Common subtable header */
1857 
1858         AcpiOsPrintf ("\n");
1859         Status = AcpiDmDumpTable (Length, Offset, Subtable,
1860             Subtable->Header.Length, AcpiDmTableInfoPcctHdr);
1861         if (ACPI_FAILURE (Status))
1862         {
1863             return;
1864         }
1865 
1866         switch (Subtable->Header.Type)
1867         {
1868         case ACPI_PCCT_TYPE_GENERIC_SUBSPACE:
1869 
1870             InfoTable = AcpiDmTableInfoPcct0;
1871             break;
1872 
1873         case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE:
1874 
1875             InfoTable = AcpiDmTableInfoPcct1;
1876             break;
1877 
1878         case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2:
1879 
1880             InfoTable = AcpiDmTableInfoPcct2;
1881             break;
1882 
1883         case ACPI_PCCT_TYPE_EXT_PCC_MASTER_SUBSPACE:
1884 
1885             InfoTable = AcpiDmTableInfoPcct3;
1886             break;
1887 
1888         case ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE:
1889 
1890             InfoTable = AcpiDmTableInfoPcct4;
1891             break;
1892 
1893         case ACPI_PCCT_TYPE_HW_REG_COMM_SUBSPACE:
1894 
1895             InfoTable = AcpiDmTableInfoPcct5;
1896             break;
1897 
1898         default:
1899 
1900             AcpiOsPrintf (
1901                 "\n**** Unexpected or unknown PCCT subtable type 0x%X\n\n",
1902                 Subtable->Header.Type);
1903             return;
1904         }
1905 
1906         AcpiOsPrintf ("\n");
1907         Status = AcpiDmDumpTable (Length, Offset, Subtable,
1908             Subtable->Header.Length, InfoTable);
1909         if (ACPI_FAILURE (Status))
1910         {
1911             return;
1912         }
1913 
1914         /* Point to next subtable */
1915 
1916         Offset += Subtable->Header.Length;
1917         Subtable = ACPI_ADD_PTR (ACPI_PCCT_SUBSPACE, Subtable,
1918             Subtable->Header.Length);
1919     }
1920 }
1921 
1922 
1923 /*******************************************************************************
1924  *
1925  * FUNCTION:    AcpiDmDumpPdtt
1926  *
1927  * PARAMETERS:  Table               - A PDTT table
1928  *
1929  * RETURN:      None
1930  *
1931  * DESCRIPTION: Format the contents of a Pdtt. This is a variable-length
1932  *              table that contains an open-ended number of IDs
1933  *              at the end of the table.
1934  *
1935  ******************************************************************************/
1936 
1937 void
AcpiDmDumpPdtt(ACPI_TABLE_HEADER * Table)1938 AcpiDmDumpPdtt (
1939     ACPI_TABLE_HEADER       *Table)
1940 {
1941     ACPI_STATUS             Status;
1942     ACPI_PDTT_CHANNEL       *Subtable;
1943     UINT32                  Length = Table->Length;
1944     UINT32                  Offset = sizeof (ACPI_TABLE_PDTT);
1945 
1946 
1947     /* Main table */
1948 
1949     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoPdtt);
1950     if (ACPI_FAILURE (Status))
1951     {
1952         return;
1953     }
1954 
1955     /* Subtables. Currently there is only one type, but can be multiples */
1956 
1957     Subtable = ACPI_ADD_PTR (ACPI_PDTT_CHANNEL, Table, Offset);
1958     while (Offset < Table->Length)
1959     {
1960         AcpiOsPrintf ("\n");
1961         Status = AcpiDmDumpTable (Length, Offset, Subtable,
1962             sizeof (ACPI_PDTT_CHANNEL), AcpiDmTableInfoPdtt0);
1963         if (ACPI_FAILURE (Status))
1964         {
1965             return;
1966         }
1967 
1968         /* Point to next subtable */
1969 
1970         Offset += sizeof (ACPI_PDTT_CHANNEL);
1971         Subtable = ACPI_ADD_PTR (ACPI_PDTT_CHANNEL, Subtable,
1972             sizeof (ACPI_PDTT_CHANNEL));
1973     }
1974 }
1975 
1976 
1977 /*******************************************************************************
1978  *
1979  * FUNCTION:    AcpiDmDumpPhat
1980  *
1981  * PARAMETERS:  Table               - A PHAT table
1982  *
1983  * RETURN:      None
1984  *
1985  * DESCRIPTION: Format the contents of a PHAT.
1986  *
1987  ******************************************************************************/
1988 
1989 void
AcpiDmDumpPhat(ACPI_TABLE_HEADER * Table)1990 AcpiDmDumpPhat (
1991     ACPI_TABLE_HEADER       *Table)
1992 {
1993     ACPI_STATUS             Status;
1994     ACPI_DMTABLE_INFO       *InfoTable;
1995     ACPI_PHAT_HEADER        *Subtable;
1996     ACPI_PHAT_VERSION_DATA  *VersionData;
1997     UINT32                  RecordCount;
1998     UINT32                  Length = Table->Length;
1999     UINT32                  Offset = sizeof (ACPI_TABLE_PHAT);
2000     UINT32                  OriginalOffset;
2001     UINT32                  SubtableLength;
2002     UINT32                  PathLength;
2003     UINT32                  VendorLength;
2004     UINT16                  RecordType;
2005     const wchar_t           *WideString;
2006 
2007 
2008     Subtable = ACPI_ADD_PTR (ACPI_PHAT_HEADER, Table, sizeof (ACPI_TABLE_PHAT));
2009 
2010     while (Offset < Table->Length)
2011     {
2012         /* Common subtable header */
2013 
2014         AcpiOsPrintf ("\n");
2015         Status = AcpiDmDumpTable (Length, Offset, Subtable,
2016             sizeof (ACPI_PHAT_HEADER), AcpiDmTableInfoPhatHdr);
2017         if (ACPI_FAILURE (Status))
2018         {
2019             return;
2020         }
2021 
2022         DbgPrint (ASL_DEBUG_OUTPUT, "\n/* %u, Subtable->Type %X */\n",
2023             __LINE__, Subtable->Type);
2024 
2025         switch (Subtable->Type)
2026         {
2027         case ACPI_PHAT_TYPE_FW_VERSION_DATA:
2028 
2029             InfoTable = AcpiDmTableInfoPhat0;
2030             SubtableLength = Offset += sizeof (ACPI_PHAT_VERSION_DATA);
2031             break;
2032 
2033         case ACPI_PHAT_TYPE_FW_HEALTH_DATA:
2034 
2035             InfoTable = AcpiDmTableInfoPhat1;
2036             SubtableLength = Offset += sizeof (ACPI_PHAT_TYPE_FW_HEALTH_DATA);
2037             break;
2038 
2039         default:
2040 
2041             DbgPrint (ASL_DEBUG_OUTPUT, "\n**** Unknown PHAT subtable type 0x%X\n\n",
2042                 Subtable->Type);
2043 
2044             return;
2045         }
2046 
2047         Status = AcpiDmDumpTable (Length, SubtableLength, Subtable,
2048             SubtableLength, InfoTable);
2049         if (ACPI_FAILURE (Status))
2050         {
2051             return;
2052         }
2053 
2054         OriginalOffset = Offset;
2055         switch (Subtable->Type)
2056         {
2057         case ACPI_PHAT_TYPE_FW_VERSION_DATA:
2058 
2059             VersionData = ACPI_CAST_PTR (ACPI_PHAT_VERSION_DATA, Subtable);
2060             RecordCount = VersionData->ElementCount;
2061             RecordType = *ACPI_CAST_PTR (UINT8, Subtable);
2062 
2063             /*
2064              * Skip past a zero-valued block (not part of the ACPI PHAT specification).
2065              * First, check for a zero length record and a zero element count
2066              */
2067             if (!VersionData->Header.Length && !VersionData->ElementCount)
2068             {
2069                 while (RecordType == 0)
2070                 {
2071                     Subtable = ACPI_ADD_PTR (ACPI_PHAT_HEADER, Table, Offset);
2072                     RecordType = *ACPI_CAST_PTR (UINT8, Subtable);
2073                     RecordCount = VersionData->ElementCount;
2074                     Offset += 1;
2075                 }
2076 
2077                 Offset -= 1;
2078                 AcpiOsPrintf ("\n/* Warning: Block of zeros found above starting at Offset %X Length %X */\n"
2079                     "/* (not compliant to PHAT specification -- ignoring block) */\n",
2080                     OriginalOffset - 12, Offset - OriginalOffset + 12);
2081             }
2082 
2083             DbgPrint (ASL_DEBUG_OUTPUT, "/* %u, RecordCount: %X, Offset %X, SubtableLength %X */\n",
2084                 __LINE__, RecordCount, Offset, SubtableLength);
2085 
2086             /* Emit each of the version elements */
2087 
2088             while (RecordCount && VersionData->Header.Length)
2089             {
2090                 AcpiOsPrintf ("\n/* Version Element #%Xh Offset %Xh */\n\n",
2091                     VersionData->ElementCount - RecordCount + 1, Offset);
2092 
2093                 Subtable = ACPI_ADD_PTR (ACPI_PHAT_HEADER, Table, Offset);
2094                 Status = AcpiDmDumpTable (Length, Offset, Subtable,
2095                     sizeof (ACPI_PHAT_VERSION_ELEMENT), AcpiDmTableInfoPhat0a);
2096                 if (ACPI_FAILURE (Status))
2097                 {
2098                     return;
2099                 }
2100 
2101                 Offset += sizeof (ACPI_PHAT_VERSION_ELEMENT);
2102                 RecordCount--;
2103             }
2104 
2105             break;
2106 
2107         case ACPI_PHAT_TYPE_FW_HEALTH_DATA:
2108 
2109             /*
2110              * Get the length of the Device Path (UEFI wide string).
2111              * Include the wide null terminator (+2),
2112              */
2113             WideString = ACPI_ADD_PTR (wchar_t, Subtable,
2114                 sizeof (ACPI_PHAT_HEALTH_DATA));
2115 
2116             PathLength = (wcslen (WideString) * 2) + 2;
2117             DbgPrint (ASL_DEBUG_OUTPUT, "/* %u, PathLength %X, Offset %X, Table->Length %X */\n",
2118                 __LINE__, PathLength, Offset, Length);
2119 
2120             Status = AcpiDmDumpTable (Length, Offset,
2121                 ACPI_ADD_PTR (ACPI_PHAT_HEADER, Subtable, sizeof (ACPI_PHAT_HEALTH_DATA)),
2122                 PathLength, AcpiDmTableInfoPhat1a);
2123             Offset += PathLength;
2124             if (ACPI_FAILURE (Status))
2125             {
2126                 return;
2127             }
2128 
2129             /* Get Device-Specific Data - length of which is the remaining subtable length. */
2130 
2131             VendorLength =
2132                 Subtable->Length - sizeof (ACPI_PHAT_HEALTH_DATA) - PathLength;
2133             DbgPrint (ASL_DEBUG_OUTPUT, "%u, Subtable->Length %X, VendorLength %X, Offset %X PathLength: %X\n",
2134                 __LINE__, Subtable->Length, VendorLength, Offset, PathLength);
2135 
2136             if (VendorLength)
2137             {
2138                 /* Point past the Device Path, Compile the Device-Specific Data */
2139 
2140                 Status = AcpiDmDumpTable (Length, Offset,
2141                     ACPI_ADD_PTR (ACPI_PHAT_HEADER, Subtable, sizeof (ACPI_PHAT_HEALTH_DATA) + PathLength),
2142                     VendorLength, AcpiDmTableInfoPhat1b);
2143                 if (ACPI_FAILURE (Status))
2144                 {
2145                     return;
2146                 }
2147 
2148                 Offset += VendorLength;
2149             }
2150 
2151             if (ACPI_FAILURE (Status))
2152             {
2153                 return;
2154             }
2155             break;
2156 
2157         default:
2158 
2159             AcpiOsPrintf ("\n**** Unknown PHAT subtable type 0x%X\n\n",
2160                 Subtable->Type);
2161             return;
2162         }
2163 
2164         /* Next subtable */
2165 
2166         DbgPrint (ASL_DEBUG_OUTPUT, "/* %u, Bottom of main loop: Offset %X, "
2167             "Subtable->Length %X, Table->Length %X */\n",
2168             __LINE__, Offset, Subtable->Length, Table->Length);
2169 
2170         Subtable = ACPI_ADD_PTR (ACPI_PHAT_HEADER, Table,
2171             Offset);
2172     }
2173 }
2174 
2175 
2176 /*******************************************************************************
2177  *
2178  * FUNCTION:    AcpiDmDumpPmtt
2179  *
2180  * PARAMETERS:  Table               - A PMTT table
2181  *
2182  * RETURN:      None
2183  *
2184  * DESCRIPTION: Format the contents of a PMTT. This table type consists
2185  *              of an open-ended number of subtables.
2186  *
2187  ******************************************************************************/
2188 
2189 void
AcpiDmDumpPmtt(ACPI_TABLE_HEADER * Table)2190 AcpiDmDumpPmtt (
2191     ACPI_TABLE_HEADER       *Table)
2192 {
2193     ACPI_STATUS             Status;
2194     ACPI_PMTT_HEADER        *Subtable;
2195     UINT32                  Length = Table->Length;
2196     UINT32                  Offset = sizeof (ACPI_TABLE_PMTT);
2197 
2198 
2199     /* Main table */
2200 
2201     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoPmtt);
2202     if (ACPI_FAILURE (Status))
2203     {
2204         return;
2205     }
2206 
2207     /* Subtables */
2208 
2209     Subtable = ACPI_ADD_PTR (ACPI_PMTT_HEADER, Table, Offset);
2210     while (Offset < Table->Length)
2211     {
2212         /* Each of the types below contain the common subtable header */
2213 
2214         AcpiOsPrintf ("\n");
2215         switch (Subtable->Type)
2216         {
2217         case ACPI_PMTT_TYPE_SOCKET:
2218 
2219             Status = AcpiDmDumpTable (Length, Offset, Subtable,
2220                 Subtable->Length, AcpiDmTableInfoPmtt0);
2221             if (ACPI_FAILURE (Status))
2222             {
2223                 return;
2224             }
2225             break;
2226 
2227         case ACPI_PMTT_TYPE_CONTROLLER:
2228             Status = AcpiDmDumpTable (Length, Offset, Subtable,
2229                 Subtable->Length, AcpiDmTableInfoPmtt1);
2230             if (ACPI_FAILURE (Status))
2231             {
2232                 return;
2233             }
2234             break;
2235 
2236        case ACPI_PMTT_TYPE_DIMM:
2237             Status = AcpiDmDumpTable (Length, Offset, Subtable,
2238                 Subtable->Length, AcpiDmTableInfoPmtt2);
2239             if (ACPI_FAILURE (Status))
2240             {
2241                 return;
2242             }
2243             break;
2244 
2245         case ACPI_PMTT_TYPE_VENDOR:
2246             Status = AcpiDmDumpTable (Length, Offset, Subtable,
2247                 Subtable->Length, AcpiDmTableInfoPmttVendor);
2248             if (ACPI_FAILURE (Status))
2249             {
2250                 return;
2251             }
2252             break;
2253 
2254         default:
2255             AcpiOsPrintf (
2256                 "\n**** Unexpected or unknown PMTT subtable type 0x%X\n\n",
2257                 Subtable->Type);
2258             return;
2259         }
2260 
2261         /* Point to next subtable */
2262 
2263         Offset += Subtable->Length;
2264         Subtable = ACPI_ADD_PTR (ACPI_PMTT_HEADER,
2265             Subtable, Subtable->Length);
2266     }
2267 }
2268 
2269 
2270 /*******************************************************************************
2271  *
2272  * FUNCTION:    AcpiDmDumpPptt
2273  *
2274  * PARAMETERS:  Table               - A PMTT table
2275  *
2276  * RETURN:      None
2277  *
2278  * DESCRIPTION: Format the contents of a PPTT. This table type consists
2279  *              of an open-ended number of subtables.
2280  *
2281  ******************************************************************************/
2282 
2283 void
AcpiDmDumpPptt(ACPI_TABLE_HEADER * Table)2284 AcpiDmDumpPptt (
2285     ACPI_TABLE_HEADER       *Table)
2286 {
2287     ACPI_STATUS             Status;
2288     ACPI_SUBTABLE_HEADER    *Subtable;
2289     ACPI_PPTT_PROCESSOR     *PpttProcessor;
2290     UINT8                   Length;
2291     UINT8                   SubtableOffset;
2292     UINT32                  Offset = sizeof (ACPI_TABLE_FPDT);
2293     ACPI_DMTABLE_INFO       *InfoTable;
2294     UINT32                  i;
2295 
2296 
2297     /* There is no main table (other than the standard ACPI header) */
2298 
2299     /* Subtables */
2300 
2301     Offset = sizeof (ACPI_TABLE_HEADER);
2302     while (Offset < Table->Length)
2303     {
2304         AcpiOsPrintf ("\n");
2305 
2306         /* Common subtable header */
2307 
2308         Subtable = ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, Table, Offset);
2309         if (Subtable->Length < sizeof (ACPI_SUBTABLE_HEADER))
2310         {
2311             AcpiOsPrintf ("Invalid subtable length\n");
2312             return;
2313         }
2314         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
2315             Subtable->Length, AcpiDmTableInfoPpttHdr);
2316         if (ACPI_FAILURE (Status))
2317         {
2318             return;
2319         }
2320 
2321         switch (Subtable->Type)
2322         {
2323         case ACPI_PPTT_TYPE_PROCESSOR:
2324 
2325             InfoTable = AcpiDmTableInfoPptt0;
2326             Length = sizeof (ACPI_PPTT_PROCESSOR);
2327             break;
2328 
2329         case ACPI_PPTT_TYPE_CACHE:
2330 
2331             InfoTable = AcpiDmTableInfoPptt1;
2332             Length = sizeof (ACPI_PPTT_CACHE);
2333             break;
2334 
2335         case ACPI_PPTT_TYPE_ID:
2336 
2337             InfoTable = AcpiDmTableInfoPptt2;
2338             Length = sizeof (ACPI_PPTT_ID);
2339             break;
2340 
2341         default:
2342 
2343             AcpiOsPrintf ("\n**** Unknown PPTT subtable type 0x%X\n\n",
2344                 Subtable->Type);
2345 
2346             /* Attempt to continue */
2347 
2348             goto NextSubtable;
2349         }
2350 
2351         if (Subtable->Length < Length)
2352         {
2353             AcpiOsPrintf ("Invalid subtable length\n");
2354             return;
2355         }
2356         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
2357             Subtable->Length, InfoTable);
2358         if (ACPI_FAILURE (Status))
2359         {
2360             return;
2361         }
2362         SubtableOffset = Length;
2363 
2364         switch (Subtable->Type)
2365         {
2366         case ACPI_PPTT_TYPE_PROCESSOR:
2367 
2368             PpttProcessor = ACPI_CAST_PTR (ACPI_PPTT_PROCESSOR, Subtable);
2369 
2370             /* Dump SMBIOS handles */
2371 
2372             if ((UINT8)(Subtable->Length - SubtableOffset) <
2373                 (UINT8)(PpttProcessor->NumberOfPrivResources * 4))
2374             {
2375                 AcpiOsPrintf ("Invalid private resource number\n");
2376                 return;
2377             }
2378             for (i = 0; i < PpttProcessor->NumberOfPrivResources; i++)
2379             {
2380                 Status = AcpiDmDumpTable (Table->Length, Offset + SubtableOffset,
2381                     ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, Subtable, SubtableOffset),
2382                     4, AcpiDmTableInfoPptt0a);
2383                 if (ACPI_FAILURE (Status))
2384                 {
2385                     return;
2386                 }
2387 
2388                 SubtableOffset += 4;
2389             }
2390             break;
2391 
2392         case ACPI_PPTT_TYPE_CACHE:
2393 
2394             if (Table->Revision < 3)
2395             {
2396                 break;
2397             }
2398             Status = AcpiDmDumpTable (Table->Length, Offset + SubtableOffset,
2399                 ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, Subtable, SubtableOffset),
2400                 sizeof (ACPI_PPTT_CACHE_V1), AcpiDmTableInfoPptt1a);
2401             if (ACPI_FAILURE (Status))
2402             {
2403                 return;
2404             }
2405             break;
2406 
2407         default:
2408 
2409             break;
2410         }
2411 
2412 NextSubtable:
2413         /* Point to next subtable */
2414 
2415         Offset += Subtable->Length;
2416     }
2417 }
2418 
2419 
2420 /*******************************************************************************
2421  *
2422  * FUNCTION:    AcpiDmDumpPrmt
2423  *
2424  * PARAMETERS:  Table               - A PRMT table
2425  *
2426  * RETURN:      None
2427  *
2428  * DESCRIPTION: Format the contents of a PRMT. This table type consists
2429  *              of an open-ended number of subtables.
2430  *
2431  ******************************************************************************/
2432 
2433 void
AcpiDmDumpPrmt(ACPI_TABLE_HEADER * Table)2434 AcpiDmDumpPrmt (
2435     ACPI_TABLE_HEADER       *Table)
2436 {
2437     UINT32                  CurrentOffset = sizeof (ACPI_TABLE_HEADER);
2438     ACPI_TABLE_PRMT_HEADER  *PrmtHeader;
2439     ACPI_PRMT_MODULE_INFO   *PrmtModuleInfo;
2440     ACPI_PRMT_HANDLER_INFO  *PrmtHandlerInfo;
2441     ACPI_STATUS             Status;
2442     UINT32                  i, j;
2443 
2444 
2445     /* Main table header */
2446 
2447     PrmtHeader = ACPI_ADD_PTR (ACPI_TABLE_PRMT_HEADER, Table, CurrentOffset);
2448     Status = AcpiDmDumpTable (Table->Length, CurrentOffset, PrmtHeader,
2449         sizeof (ACPI_TABLE_PRMT_HEADER), AcpiDmTableInfoPrmtHdr);
2450     if (ACPI_FAILURE (Status))
2451     {
2452         AcpiOsPrintf ("Invalid PRMT header\n");
2453         return;
2454     }
2455 
2456     CurrentOffset += sizeof (ACPI_TABLE_PRMT_HEADER);
2457 
2458     /* PRM Module Information Structure array */
2459 
2460     for (i = 0; i < PrmtHeader->ModuleInfoCount; ++i)
2461     {
2462         PrmtModuleInfo = ACPI_ADD_PTR (ACPI_PRMT_MODULE_INFO, Table, CurrentOffset);
2463         Status = AcpiDmDumpTable (Table->Length, CurrentOffset, PrmtModuleInfo,
2464             sizeof (ACPI_PRMT_MODULE_INFO), AcpiDmTableInfoPrmtModule);
2465 
2466         CurrentOffset += sizeof (ACPI_PRMT_MODULE_INFO);
2467 
2468         /* PRM handler information structure array */
2469 
2470         for (j = 0; j < PrmtModuleInfo->HandlerInfoCount; ++j)
2471         {
2472             PrmtHandlerInfo = ACPI_ADD_PTR (ACPI_PRMT_HANDLER_INFO, Table, CurrentOffset);
2473             Status = AcpiDmDumpTable (Table->Length, CurrentOffset, PrmtHandlerInfo,
2474                 sizeof (ACPI_PRMT_HANDLER_INFO), AcpiDmTableInfoPrmtHandler);
2475 
2476             CurrentOffset += sizeof (ACPI_PRMT_HANDLER_INFO);
2477         }
2478     }
2479 }
2480 
2481 
2482 /*******************************************************************************
2483  *
2484  * FUNCTION:    AcpiDmDumpRgrt
2485  *
2486  * PARAMETERS:  Table               - A RGRT table
2487  *
2488  * RETURN:      None
2489  *
2490  * DESCRIPTION: Format the contents of a RGRT
2491  *
2492  ******************************************************************************/
2493 
2494 void
AcpiDmDumpRgrt(ACPI_TABLE_HEADER * Table)2495 AcpiDmDumpRgrt (
2496     ACPI_TABLE_HEADER       *Table)
2497 {
2498     ACPI_STATUS             Status;
2499     ACPI_TABLE_RGRT         *Subtable = ACPI_CAST_PTR (ACPI_TABLE_RGRT, Table);
2500     UINT32                  Offset = sizeof (ACPI_TABLE_RGRT);
2501 
2502 
2503     /* Main table */
2504 
2505     Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoRgrt);
2506     if (ACPI_FAILURE (Status))
2507     {
2508         return;
2509     }
2510 
2511     /* Dump the binary image as a subtable */
2512 
2513     Status = AcpiDmDumpTable (Table->Length, Offset, &Subtable->Image,
2514         Table->Length - Offset, AcpiDmTableInfoRgrt0);
2515     if (ACPI_FAILURE (Status))
2516     {
2517         return;
2518     }
2519 }
2520 
2521 
2522 /*******************************************************************************
2523  *
2524  * FUNCTION:    AcpiDmDumpS3pt
2525  *
2526  * PARAMETERS:  Table               - A S3PT table
2527  *
2528  * RETURN:      Length of the table
2529  *
2530  * DESCRIPTION: Format the contents of a S3PT
2531  *
2532  ******************************************************************************/
2533 
2534 UINT32
AcpiDmDumpS3pt(ACPI_TABLE_HEADER * Tables)2535 AcpiDmDumpS3pt (
2536     ACPI_TABLE_HEADER       *Tables)
2537 {
2538     ACPI_STATUS             Status;
2539     UINT32                  Offset = sizeof (ACPI_TABLE_S3PT);
2540     ACPI_FPDT_HEADER        *Subtable;
2541     ACPI_DMTABLE_INFO       *InfoTable;
2542     ACPI_TABLE_S3PT         *S3ptTable = ACPI_CAST_PTR (ACPI_TABLE_S3PT, Tables);
2543 
2544 
2545     /* Main table */
2546 
2547     Status = AcpiDmDumpTable (Offset, 0, S3ptTable, 0, AcpiDmTableInfoS3pt);
2548     if (ACPI_FAILURE (Status))
2549     {
2550         return 0;
2551     }
2552 
2553     Subtable = ACPI_ADD_PTR (ACPI_FPDT_HEADER, S3ptTable, Offset);
2554     while (Offset < S3ptTable->Length)
2555     {
2556         /* Common subtable header */
2557 
2558         AcpiOsPrintf ("\n");
2559         Status = AcpiDmDumpTable (S3ptTable->Length, Offset, Subtable,
2560             Subtable->Length, AcpiDmTableInfoS3ptHdr);
2561         if (ACPI_FAILURE (Status))
2562         {
2563             return 0;
2564         }
2565 
2566         switch (Subtable->Type)
2567         {
2568         case ACPI_S3PT_TYPE_RESUME:
2569 
2570             InfoTable = AcpiDmTableInfoS3pt0;
2571             break;
2572 
2573         case ACPI_S3PT_TYPE_SUSPEND:
2574 
2575             InfoTable = AcpiDmTableInfoS3pt1;
2576             break;
2577 
2578         default:
2579 
2580             AcpiOsPrintf ("\n**** Unknown S3PT subtable type 0x%X\n",
2581                 Subtable->Type);
2582 
2583             /* Attempt to continue */
2584 
2585             if (!Subtable->Length)
2586             {
2587                 AcpiOsPrintf ("Invalid zero length subtable\n");
2588                 return 0;
2589             }
2590             goto NextSubtable;
2591         }
2592 
2593         AcpiOsPrintf ("\n");
2594         Status = AcpiDmDumpTable (S3ptTable->Length, Offset, Subtable,
2595             Subtable->Length, InfoTable);
2596         if (ACPI_FAILURE (Status))
2597         {
2598             return 0;
2599         }
2600 
2601 NextSubtable:
2602         /* Point to next subtable */
2603 
2604         Offset += Subtable->Length;
2605         Subtable = ACPI_ADD_PTR (ACPI_FPDT_HEADER, Subtable, Subtable->Length);
2606     }
2607 
2608     return (S3ptTable->Length);
2609 }
2610 
2611 
2612 /*******************************************************************************
2613  *
2614  * FUNCTION:    AcpiDmDumpSdev
2615  *
2616  * PARAMETERS:  Table               - A SDEV table
2617  *
2618  * RETURN:      None
2619  *
2620  * DESCRIPTION: Format the contents of a SDEV. This is a variable-length
2621  *              table that contains variable strings and vendor data.
2622  *
2623  ******************************************************************************/
2624 
2625 void
AcpiDmDumpSdev(ACPI_TABLE_HEADER * Table)2626 AcpiDmDumpSdev (
2627     ACPI_TABLE_HEADER       *Table)
2628 {
2629     ACPI_STATUS                 Status;
2630     ACPI_SDEV_HEADER            *Subtable;
2631     ACPI_SDEV_PCIE              *Pcie;
2632     ACPI_SDEV_NAMESPACE         *Namesp;
2633     ACPI_DMTABLE_INFO           *InfoTable;
2634     ACPI_DMTABLE_INFO           *SecureComponentInfoTable;
2635     UINT32                      Length = Table->Length;
2636     UINT32                      Offset = sizeof (ACPI_TABLE_SDEV);
2637     UINT16                      PathOffset;
2638     UINT16                      PathLength;
2639     UINT16                      VendorDataOffset;
2640     UINT16                      VendorDataLength;
2641     ACPI_SDEV_SECURE_COMPONENT  *SecureComponent = NULL;
2642     UINT32                      CurrentOffset = 0;
2643 
2644 
2645     /* Main table */
2646 
2647     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoSdev);
2648     if (ACPI_FAILURE (Status))
2649     {
2650         return;
2651     }
2652 
2653     /* Subtables */
2654 
2655     Subtable = ACPI_ADD_PTR (ACPI_SDEV_HEADER, Table, Offset);
2656     while (Offset < Table->Length)
2657     {
2658         /* Common subtable header */
2659 
2660         AcpiOsPrintf ("\n");
2661         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
2662             Subtable->Length, AcpiDmTableInfoSdevHdr);
2663         if (ACPI_FAILURE (Status))
2664         {
2665             return;
2666         }
2667 
2668         switch (Subtable->Type)
2669         {
2670         case ACPI_SDEV_TYPE_NAMESPACE_DEVICE:
2671 
2672             InfoTable = AcpiDmTableInfoSdev0;
2673             break;
2674 
2675         case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE:
2676 
2677             InfoTable = AcpiDmTableInfoSdev1;
2678             break;
2679 
2680         default:
2681             goto NextSubtable;
2682         }
2683 
2684         AcpiOsPrintf ("\n");
2685         Status = AcpiDmDumpTable (Table->Length, 0, Subtable,
2686             Subtable->Length, InfoTable);
2687         if (ACPI_FAILURE (Status))
2688         {
2689             return;
2690         }
2691 
2692         switch (Subtable->Type)
2693         {
2694         case ACPI_SDEV_TYPE_NAMESPACE_DEVICE:
2695 
2696             CurrentOffset = sizeof (ACPI_SDEV_NAMESPACE);
2697             if (Subtable->Flags & ACPI_SDEV_SECURE_COMPONENTS_PRESENT)
2698             {
2699                 SecureComponent = ACPI_CAST_PTR (ACPI_SDEV_SECURE_COMPONENT,
2700                     ACPI_ADD_PTR (UINT8, Subtable, sizeof (ACPI_SDEV_NAMESPACE)));
2701 
2702                 Status = AcpiDmDumpTable (Table->Length, CurrentOffset,
2703                     ACPI_ADD_PTR(UINT8, Subtable, sizeof (ACPI_SDEV_NAMESPACE)),
2704                     sizeof (ACPI_SDEV_SECURE_COMPONENT), AcpiDmTableInfoSdev0b);
2705                 if (ACPI_FAILURE (Status))
2706                 {
2707                     return;
2708                 }
2709                 CurrentOffset += sizeof (ACPI_SDEV_SECURE_COMPONENT);
2710 
2711                 Status = AcpiDmDumpTable (Table->Length, CurrentOffset,
2712                     ACPI_ADD_PTR(UINT8, Subtable, SecureComponent->SecureComponentOffset),
2713                     sizeof (ACPI_SDEV_HEADER), AcpiDmTableInfoSdevSecCompHdr);
2714                 if (ACPI_FAILURE (Status))
2715                 {
2716                     return;
2717                 }
2718                 CurrentOffset += sizeof (ACPI_SDEV_HEADER);
2719 
2720                 switch (Subtable->Type)
2721                 {
2722                 case ACPI_SDEV_TYPE_ID_COMPONENT:
2723 
2724                     SecureComponentInfoTable = AcpiDmTableInfoSdevSecCompId;
2725                     break;
2726 
2727                 case ACPI_SDEV_TYPE_MEM_COMPONENT:
2728 
2729                     SecureComponentInfoTable = AcpiDmTableInfoSdevSecCompMem;
2730                     break;
2731 
2732                 default:
2733                     goto NextSubtable;
2734                 }
2735 
2736                 Status = AcpiDmDumpTable (Table->Length, CurrentOffset,
2737                     ACPI_ADD_PTR(UINT8, Subtable, SecureComponent->SecureComponentOffset),
2738                     SecureComponent->SecureComponentLength, SecureComponentInfoTable);
2739                 CurrentOffset += SecureComponent->SecureComponentLength;
2740             }
2741 
2742             /* Dump the PCIe device ID(s) */
2743 
2744             Namesp = ACPI_CAST_PTR (ACPI_SDEV_NAMESPACE, Subtable);
2745             PathOffset = Namesp->DeviceIdOffset;
2746             PathLength = Namesp->DeviceIdLength;
2747 
2748             if (PathLength)
2749             {
2750                 Status = AcpiDmDumpTable (Table->Length, CurrentOffset,
2751                     ACPI_ADD_PTR (UINT8, Namesp, PathOffset),
2752                     PathLength, AcpiDmTableInfoSdev0a);
2753                 if (ACPI_FAILURE (Status))
2754                 {
2755                     return;
2756                 }
2757                 CurrentOffset += PathLength;
2758             }
2759 
2760             /* Dump the vendor-specific data */
2761 
2762             VendorDataLength =
2763                 Namesp->VendorDataLength;
2764             VendorDataOffset =
2765                 Namesp->DeviceIdOffset + Namesp->DeviceIdLength;
2766 
2767             if (VendorDataLength)
2768             {
2769                 Status = AcpiDmDumpTable (Table->Length, 0,
2770                     ACPI_ADD_PTR (UINT8, Namesp, VendorDataOffset),
2771                     VendorDataLength, AcpiDmTableInfoSdev1b);
2772                 if (ACPI_FAILURE (Status))
2773                 {
2774                     return;
2775                 }
2776             }
2777             break;
2778 
2779         case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE:
2780 
2781             /* PCI path substructures */
2782 
2783             Pcie = ACPI_CAST_PTR (ACPI_SDEV_PCIE, Subtable);
2784             PathOffset = Pcie->PathOffset;
2785             PathLength = Pcie->PathLength;
2786 
2787             while (PathLength)
2788             {
2789                 Status = AcpiDmDumpTable (Table->Length,
2790                     PathOffset + Offset,
2791                     ACPI_ADD_PTR (UINT8, Pcie, PathOffset),
2792                     sizeof (ACPI_SDEV_PCIE_PATH), AcpiDmTableInfoSdev1a);
2793                 if (ACPI_FAILURE (Status))
2794                 {
2795                     return;
2796                 }
2797 
2798                 PathOffset += sizeof (ACPI_SDEV_PCIE_PATH);
2799                 PathLength -= sizeof (ACPI_SDEV_PCIE_PATH);
2800             }
2801 
2802             /* VendorData */
2803 
2804             VendorDataLength = Pcie->VendorDataLength;
2805             VendorDataOffset = Pcie->PathOffset + Pcie->PathLength;
2806 
2807             if (VendorDataLength)
2808             {
2809                 Status = AcpiDmDumpTable (Table->Length, 0,
2810                     ACPI_ADD_PTR (UINT8, Pcie, VendorDataOffset),
2811                     VendorDataLength, AcpiDmTableInfoSdev1b);
2812                 if (ACPI_FAILURE (Status))
2813                 {
2814                     return;
2815                 }
2816             }
2817             break;
2818 
2819         default:
2820             goto NextSubtable;
2821         }
2822 
2823 NextSubtable:
2824         /* Point to next subtable */
2825 
2826         Offset += Subtable->Length;
2827         Subtable = ACPI_ADD_PTR (ACPI_SDEV_HEADER, Subtable,
2828             Subtable->Length);
2829     }
2830 }
2831