Home | History | Annotate | Line # | Download | only in common
dmtbdump2.c revision 1.1.1.1
      1 /******************************************************************************
      2  *
      3  * Module Name: dmtbdump2 - Dump ACPI data tables that contain no AML code
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2018, 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 MERCHANTIBILITY 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 "acpi.h"
     45 #include "accommon.h"
     46 #include "acdisasm.h"
     47 #include "actables.h"
     48 
     49 /* This module used for application-level code only */
     50 
     51 #define _COMPONENT          ACPI_CA_DISASSEMBLER
     52         ACPI_MODULE_NAME    ("dmtbdump2")
     53 
     54 
     55 /*******************************************************************************
     56  *
     57  * FUNCTION:    AcpiDmDumpIort
     58  *
     59  * PARAMETERS:  Table               - A IORT table
     60  *
     61  * RETURN:      None
     62  *
     63  * DESCRIPTION: Format the contents of a IORT
     64  *
     65  ******************************************************************************/
     66 
     67 void
     68 AcpiDmDumpIort (
     69     ACPI_TABLE_HEADER       *Table)
     70 {
     71     ACPI_STATUS             Status;
     72     ACPI_TABLE_IORT         *Iort;
     73     ACPI_IORT_NODE          *IortNode;
     74     ACPI_IORT_ITS_GROUP     *IortItsGroup = NULL;
     75     ACPI_IORT_SMMU          *IortSmmu = NULL;
     76     UINT32                  Offset;
     77     UINT32                  NodeOffset;
     78     UINT32                  Length;
     79     ACPI_DMTABLE_INFO       *InfoTable;
     80     char                    *String;
     81     UINT32                  i;
     82 
     83 
     84     /* Main table */
     85 
     86     Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoIort);
     87     if (ACPI_FAILURE (Status))
     88     {
     89         return;
     90     }
     91 
     92     Iort = ACPI_CAST_PTR (ACPI_TABLE_IORT, Table);
     93     Offset = sizeof (ACPI_TABLE_IORT);
     94 
     95     /* Dump the OptionalPadding (optional) */
     96 
     97     if (Iort->NodeOffset > Offset)
     98     {
     99         Status = AcpiDmDumpTable (Table->Length, Offset, Table,
    100             Iort->NodeOffset - Offset, AcpiDmTableInfoIortPad);
    101         if (ACPI_FAILURE (Status))
    102         {
    103             return;
    104         }
    105     }
    106 
    107     Offset = Iort->NodeOffset;
    108     while (Offset < Table->Length)
    109     {
    110         /* Common subtable header */
    111 
    112         IortNode = ACPI_ADD_PTR (ACPI_IORT_NODE, Table, Offset);
    113         AcpiOsPrintf ("\n");
    114         Length = ACPI_OFFSET (ACPI_IORT_NODE, NodeData);
    115         Status = AcpiDmDumpTable (Table->Length, Offset,
    116             IortNode, Length, AcpiDmTableInfoIortHdr);
    117         if (ACPI_FAILURE (Status))
    118         {
    119             return;
    120         }
    121 
    122         NodeOffset = Length;
    123 
    124         switch (IortNode->Type)
    125         {
    126         case ACPI_IORT_NODE_ITS_GROUP:
    127 
    128             InfoTable = AcpiDmTableInfoIort0;
    129             Length = ACPI_OFFSET (ACPI_IORT_ITS_GROUP, Identifiers);
    130             IortItsGroup = ACPI_ADD_PTR (ACPI_IORT_ITS_GROUP, IortNode, NodeOffset);
    131             break;
    132 
    133         case ACPI_IORT_NODE_NAMED_COMPONENT:
    134 
    135             InfoTable = AcpiDmTableInfoIort1;
    136             Length = ACPI_OFFSET (ACPI_IORT_NAMED_COMPONENT, DeviceName);
    137             String = ACPI_ADD_PTR (char, IortNode, NodeOffset + Length);
    138             Length += strlen (String) + 1;
    139             break;
    140 
    141         case ACPI_IORT_NODE_PCI_ROOT_COMPLEX:
    142 
    143             InfoTable = AcpiDmTableInfoIort2;
    144             Length = IortNode->Length - NodeOffset;
    145             break;
    146 
    147         case ACPI_IORT_NODE_SMMU:
    148 
    149             InfoTable = AcpiDmTableInfoIort3;
    150             Length = ACPI_OFFSET (ACPI_IORT_SMMU, Interrupts);
    151             IortSmmu = ACPI_ADD_PTR (ACPI_IORT_SMMU, IortNode, NodeOffset);
    152             break;
    153 
    154         case ACPI_IORT_NODE_SMMU_V3:
    155 
    156             InfoTable = AcpiDmTableInfoIort4;
    157             Length = IortNode->Length - NodeOffset;
    158             break;
    159 
    160         default:
    161 
    162             AcpiOsPrintf ("\n**** Unknown IORT node type 0x%X\n",
    163                 IortNode->Type);
    164 
    165             /* Attempt to continue */
    166 
    167             if (!IortNode->Length)
    168             {
    169                 AcpiOsPrintf ("Invalid zero length IORT node\n");
    170                 return;
    171             }
    172             goto NextSubtable;
    173         }
    174 
    175         /* Dump the node subtable header */
    176 
    177         AcpiOsPrintf ("\n");
    178         Status = AcpiDmDumpTable (Table->Length, Offset + NodeOffset,
    179             ACPI_ADD_PTR (ACPI_IORT_NODE, IortNode, NodeOffset),
    180             Length, InfoTable);
    181         if (ACPI_FAILURE (Status))
    182         {
    183             return;
    184         }
    185 
    186         NodeOffset += Length;
    187 
    188         /* Dump the node specific data */
    189 
    190         switch (IortNode->Type)
    191         {
    192         case ACPI_IORT_NODE_ITS_GROUP:
    193 
    194             /* Validate IortItsGroup to avoid compiler warnings */
    195 
    196             if (IortItsGroup)
    197             {
    198                 for (i = 0; i < IortItsGroup->ItsCount; i++)
    199                 {
    200                     Status = AcpiDmDumpTable (Table->Length, Offset + NodeOffset,
    201                         ACPI_ADD_PTR (ACPI_IORT_NODE, IortNode, NodeOffset),
    202                         4, AcpiDmTableInfoIort0a);
    203                     NodeOffset += 4;
    204                 }
    205             }
    206             break;
    207 
    208         case ACPI_IORT_NODE_NAMED_COMPONENT:
    209 
    210             /* Dump the Padding (optional) */
    211 
    212             if (IortNode->Length > NodeOffset)
    213             {
    214                 Status = AcpiDmDumpTable (Table->Length, Offset + NodeOffset,
    215                     Table, IortNode->Length - NodeOffset,
    216                     AcpiDmTableInfoIort1a);
    217                 if (ACPI_FAILURE (Status))
    218                 {
    219                     return;
    220                 }
    221             }
    222             break;
    223 
    224         case ACPI_IORT_NODE_SMMU:
    225 
    226             AcpiOsPrintf ("\n");
    227 
    228             /* Validate IortSmmu to avoid compiler warnings */
    229 
    230             if (IortSmmu)
    231             {
    232                 Length = 2 * sizeof (UINT64);
    233                 NodeOffset = IortSmmu->GlobalInterruptOffset;
    234                 Status = AcpiDmDumpTable (Table->Length, Offset + NodeOffset,
    235                     ACPI_ADD_PTR (ACPI_IORT_NODE, IortNode, NodeOffset),
    236                     Length, AcpiDmTableInfoIort3a);
    237                 if (ACPI_FAILURE (Status))
    238                 {
    239                     return;
    240                 }
    241 
    242                 NodeOffset = IortSmmu->ContextInterruptOffset;
    243                 for (i = 0; i < IortSmmu->ContextInterruptCount; i++)
    244                 {
    245                     Status = AcpiDmDumpTable (Table->Length, Offset + NodeOffset,
    246                         ACPI_ADD_PTR (ACPI_IORT_NODE, IortNode, NodeOffset),
    247                         8, AcpiDmTableInfoIort3b);
    248                     if (ACPI_FAILURE (Status))
    249                     {
    250                         return;
    251                     }
    252 
    253                     NodeOffset += 8;
    254                 }
    255 
    256                 NodeOffset = IortSmmu->PmuInterruptOffset;
    257                 for (i = 0; i < IortSmmu->PmuInterruptCount; i++)
    258                 {
    259                     Status = AcpiDmDumpTable (Table->Length, Offset + NodeOffset,
    260                         ACPI_ADD_PTR (ACPI_IORT_NODE, IortNode, NodeOffset),
    261                         8, AcpiDmTableInfoIort3c);
    262                     if (ACPI_FAILURE (Status))
    263                     {
    264                         return;
    265                     }
    266 
    267                     NodeOffset += 8;
    268                 }
    269             }
    270             break;
    271 
    272         default:
    273 
    274             break;
    275         }
    276 
    277         /* Dump the ID mappings */
    278 
    279         NodeOffset = IortNode->MappingOffset;
    280         for (i = 0; i < IortNode->MappingCount; i++)
    281         {
    282             AcpiOsPrintf ("\n");
    283             Length = sizeof (ACPI_IORT_ID_MAPPING);
    284             Status = AcpiDmDumpTable (Table->Length, Offset + NodeOffset,
    285                 ACPI_ADD_PTR (ACPI_IORT_NODE, IortNode, NodeOffset),
    286                 Length, AcpiDmTableInfoIortMap);
    287             if (ACPI_FAILURE (Status))
    288             {
    289                 return;
    290             }
    291 
    292             NodeOffset += Length;
    293         }
    294 
    295 NextSubtable:
    296         /* Point to next node subtable */
    297 
    298         Offset += IortNode->Length;
    299         IortNode = ACPI_ADD_PTR (ACPI_IORT_NODE, IortNode, IortNode->Length);
    300     }
    301 }
    302 
    303 
    304 /*******************************************************************************
    305  *
    306  * FUNCTION:    AcpiDmDumpIvrs
    307  *
    308  * PARAMETERS:  Table               - A IVRS table
    309  *
    310  * RETURN:      None
    311  *
    312  * DESCRIPTION: Format the contents of a IVRS
    313  *
    314  ******************************************************************************/
    315 
    316 static UINT8 EntrySizes[] = {4,8,16,32};
    317 
    318 void
    319 AcpiDmDumpIvrs (
    320     ACPI_TABLE_HEADER       *Table)
    321 {
    322     ACPI_STATUS             Status;
    323     UINT32                  Offset = sizeof (ACPI_TABLE_IVRS);
    324     UINT32                  EntryOffset;
    325     UINT32                  EntryLength;
    326     UINT32                  EntryType;
    327     ACPI_IVRS_DE_HEADER     *DeviceEntry;
    328     ACPI_IVRS_HEADER        *Subtable;
    329     ACPI_DMTABLE_INFO       *InfoTable;
    330 
    331 
    332     /* Main table */
    333 
    334     Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoIvrs);
    335     if (ACPI_FAILURE (Status))
    336     {
    337         return;
    338     }
    339 
    340     /* Subtables */
    341 
    342     Subtable = ACPI_ADD_PTR (ACPI_IVRS_HEADER, Table, Offset);
    343     while (Offset < Table->Length)
    344     {
    345         /* Common subtable header */
    346 
    347         AcpiOsPrintf ("\n");
    348         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
    349             Subtable->Length, AcpiDmTableInfoIvrsHdr);
    350         if (ACPI_FAILURE (Status))
    351         {
    352             return;
    353         }
    354 
    355         switch (Subtable->Type)
    356         {
    357         case ACPI_IVRS_TYPE_HARDWARE:
    358 
    359             InfoTable = AcpiDmTableInfoIvrs0;
    360             break;
    361 
    362         case ACPI_IVRS_TYPE_MEMORY1:
    363         case ACPI_IVRS_TYPE_MEMORY2:
    364         case ACPI_IVRS_TYPE_MEMORY3:
    365 
    366             InfoTable = AcpiDmTableInfoIvrs1;
    367             break;
    368 
    369         default:
    370 
    371             AcpiOsPrintf ("\n**** Unknown IVRS subtable type 0x%X\n",
    372                 Subtable->Type);
    373 
    374             /* Attempt to continue */
    375 
    376             if (!Subtable->Length)
    377             {
    378                 AcpiOsPrintf ("Invalid zero length subtable\n");
    379                 return;
    380             }
    381             goto NextSubtable;
    382         }
    383 
    384         /* Dump the subtable */
    385 
    386         AcpiOsPrintf ("\n");
    387         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
    388             Subtable->Length, InfoTable);
    389         if (ACPI_FAILURE (Status))
    390         {
    391             return;
    392         }
    393 
    394         /* The hardware subtable can contain multiple device entries */
    395 
    396         if (Subtable->Type == ACPI_IVRS_TYPE_HARDWARE)
    397         {
    398             EntryOffset = Offset + sizeof (ACPI_IVRS_HARDWARE);
    399             DeviceEntry = ACPI_ADD_PTR (ACPI_IVRS_DE_HEADER, Subtable,
    400                 sizeof (ACPI_IVRS_HARDWARE));
    401 
    402             while (EntryOffset < (Offset + Subtable->Length))
    403             {
    404                 AcpiOsPrintf ("\n");
    405                 /*
    406                  * Upper 2 bits of Type encode the length of the device entry
    407                  *
    408                  * 00 = 4 byte
    409                  * 01 = 8 byte
    410                  * 10 = 16 byte - currently no entries defined
    411                  * 11 = 32 byte - currently no entries defined
    412                  */
    413                 EntryType = DeviceEntry->Type;
    414                 EntryLength = EntrySizes [EntryType >> 6];
    415 
    416                 switch (EntryType)
    417                 {
    418                 /* 4-byte device entries */
    419 
    420                 case ACPI_IVRS_TYPE_PAD4:
    421                 case ACPI_IVRS_TYPE_ALL:
    422                 case ACPI_IVRS_TYPE_SELECT:
    423                 case ACPI_IVRS_TYPE_START:
    424                 case ACPI_IVRS_TYPE_END:
    425 
    426                     InfoTable = AcpiDmTableInfoIvrs4;
    427                     break;
    428 
    429                 /* 8-byte entries, type A */
    430 
    431                 case ACPI_IVRS_TYPE_ALIAS_SELECT:
    432                 case ACPI_IVRS_TYPE_ALIAS_START:
    433 
    434                     InfoTable = AcpiDmTableInfoIvrs8a;
    435                     break;
    436 
    437                 /* 8-byte entries, type B */
    438 
    439                 case ACPI_IVRS_TYPE_PAD8:
    440                 case ACPI_IVRS_TYPE_EXT_SELECT:
    441                 case ACPI_IVRS_TYPE_EXT_START:
    442 
    443                     InfoTable = AcpiDmTableInfoIvrs8b;
    444                     break;
    445 
    446                 /* 8-byte entries, type C */
    447 
    448                 case ACPI_IVRS_TYPE_SPECIAL:
    449 
    450                     InfoTable = AcpiDmTableInfoIvrs8c;
    451                     break;
    452 
    453                 default:
    454                     InfoTable = AcpiDmTableInfoIvrs4;
    455                     AcpiOsPrintf (
    456                         "\n**** Unknown IVRS device entry type/length: "
    457                         "0x%.2X/0x%X at offset 0x%.4X: (header below)\n",
    458                         EntryType, EntryLength, EntryOffset);
    459                     break;
    460                 }
    461 
    462                 /* Dump the Device Entry */
    463 
    464                 Status = AcpiDmDumpTable (Table->Length, EntryOffset,
    465                     DeviceEntry, EntryLength, InfoTable);
    466                 if (ACPI_FAILURE (Status))
    467                 {
    468                     return;
    469                 }
    470 
    471                 EntryOffset += EntryLength;
    472                 DeviceEntry = ACPI_ADD_PTR (ACPI_IVRS_DE_HEADER, DeviceEntry,
    473                     EntryLength);
    474             }
    475         }
    476 
    477 NextSubtable:
    478         /* Point to next subtable */
    479 
    480         Offset += Subtable->Length;
    481         Subtable = ACPI_ADD_PTR (ACPI_IVRS_HEADER, Subtable, Subtable->Length);
    482     }
    483 }
    484 
    485 
    486 /*******************************************************************************
    487  *
    488  * FUNCTION:    AcpiDmDumpLpit
    489  *
    490  * PARAMETERS:  Table               - A LPIT table
    491  *
    492  * RETURN:      None
    493  *
    494  * DESCRIPTION: Format the contents of a LPIT. This table type consists
    495  *              of an open-ended number of subtables. Note: There are no
    496  *              entries in the main table. An LPIT consists of the table
    497  *              header and then subtables only.
    498  *
    499  ******************************************************************************/
    500 
    501 void
    502 AcpiDmDumpLpit (
    503     ACPI_TABLE_HEADER       *Table)
    504 {
    505     ACPI_STATUS             Status;
    506     ACPI_LPIT_HEADER        *Subtable;
    507     UINT32                  Length = Table->Length;
    508     UINT32                  Offset = sizeof (ACPI_TABLE_LPIT);
    509     ACPI_DMTABLE_INFO       *InfoTable;
    510     UINT32                  SubtableLength;
    511 
    512 
    513     /* Subtables */
    514 
    515     Subtable = ACPI_ADD_PTR (ACPI_LPIT_HEADER, Table, Offset);
    516     while (Offset < Table->Length)
    517     {
    518         /* Common subtable header */
    519 
    520         Status = AcpiDmDumpTable (Length, Offset, Subtable,
    521             sizeof (ACPI_LPIT_HEADER), AcpiDmTableInfoLpitHdr);
    522         if (ACPI_FAILURE (Status))
    523         {
    524             return;
    525         }
    526 
    527         switch (Subtable->Type)
    528         {
    529         case ACPI_LPIT_TYPE_NATIVE_CSTATE:
    530 
    531             InfoTable = AcpiDmTableInfoLpit0;
    532             SubtableLength = sizeof (ACPI_LPIT_NATIVE);
    533             break;
    534 
    535         default:
    536 
    537             /* Cannot continue on unknown type - no length */
    538 
    539             AcpiOsPrintf ("\n**** Unknown LPIT subtable type 0x%X\n",
    540                 Subtable->Type);
    541             return;
    542         }
    543 
    544         Status = AcpiDmDumpTable (Length, Offset, Subtable,
    545             SubtableLength, InfoTable);
    546         if (ACPI_FAILURE (Status))
    547         {
    548             return;
    549         }
    550 
    551         AcpiOsPrintf ("\n");
    552 
    553         /* Point to next subtable */
    554 
    555         Offset += SubtableLength;
    556         Subtable = ACPI_ADD_PTR (ACPI_LPIT_HEADER, Subtable, SubtableLength);
    557     }
    558 }
    559 
    560 
    561 /*******************************************************************************
    562  *
    563  * FUNCTION:    AcpiDmDumpMadt
    564  *
    565  * PARAMETERS:  Table               - A MADT table
    566  *
    567  * RETURN:      None
    568  *
    569  * DESCRIPTION: Format the contents of a MADT. This table type consists
    570  *              of an open-ended number of subtables.
    571  *
    572  ******************************************************************************/
    573 
    574 void
    575 AcpiDmDumpMadt (
    576     ACPI_TABLE_HEADER       *Table)
    577 {
    578     ACPI_STATUS             Status;
    579     ACPI_SUBTABLE_HEADER    *Subtable;
    580     UINT32                  Length = Table->Length;
    581     UINT32                  Offset = sizeof (ACPI_TABLE_MADT);
    582     ACPI_DMTABLE_INFO       *InfoTable;
    583 
    584 
    585     /* Main table */
    586 
    587     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoMadt);
    588     if (ACPI_FAILURE (Status))
    589     {
    590         return;
    591     }
    592 
    593     /* Subtables */
    594 
    595     Subtable = ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, Table, Offset);
    596     while (Offset < Table->Length)
    597     {
    598         /* Common subtable header */
    599 
    600         AcpiOsPrintf ("\n");
    601         Status = AcpiDmDumpTable (Length, Offset, Subtable,
    602             Subtable->Length, AcpiDmTableInfoMadtHdr);
    603         if (ACPI_FAILURE (Status))
    604         {
    605             return;
    606         }
    607 
    608         switch (Subtable->Type)
    609         {
    610         case ACPI_MADT_TYPE_LOCAL_APIC:
    611 
    612             InfoTable = AcpiDmTableInfoMadt0;
    613             break;
    614 
    615         case ACPI_MADT_TYPE_IO_APIC:
    616 
    617             InfoTable = AcpiDmTableInfoMadt1;
    618             break;
    619 
    620         case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
    621 
    622             InfoTable = AcpiDmTableInfoMadt2;
    623             break;
    624 
    625         case ACPI_MADT_TYPE_NMI_SOURCE:
    626 
    627             InfoTable = AcpiDmTableInfoMadt3;
    628             break;
    629 
    630         case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
    631 
    632             InfoTable = AcpiDmTableInfoMadt4;
    633             break;
    634 
    635         case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
    636 
    637             InfoTable = AcpiDmTableInfoMadt5;
    638             break;
    639 
    640         case ACPI_MADT_TYPE_IO_SAPIC:
    641 
    642             InfoTable = AcpiDmTableInfoMadt6;
    643             break;
    644 
    645         case ACPI_MADT_TYPE_LOCAL_SAPIC:
    646 
    647             InfoTable = AcpiDmTableInfoMadt7;
    648             break;
    649 
    650         case ACPI_MADT_TYPE_INTERRUPT_SOURCE:
    651 
    652             InfoTable = AcpiDmTableInfoMadt8;
    653             break;
    654 
    655         case ACPI_MADT_TYPE_LOCAL_X2APIC:
    656 
    657             InfoTable = AcpiDmTableInfoMadt9;
    658             break;
    659 
    660         case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
    661 
    662             InfoTable = AcpiDmTableInfoMadt10;
    663             break;
    664 
    665         case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
    666 
    667             InfoTable = AcpiDmTableInfoMadt11;
    668             break;
    669 
    670         case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
    671 
    672             InfoTable = AcpiDmTableInfoMadt12;
    673             break;
    674 
    675         case ACPI_MADT_TYPE_GENERIC_MSI_FRAME:
    676 
    677             InfoTable = AcpiDmTableInfoMadt13;
    678             break;
    679 
    680         case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR:
    681 
    682             InfoTable = AcpiDmTableInfoMadt14;
    683             break;
    684 
    685         case ACPI_MADT_TYPE_GENERIC_TRANSLATOR:
    686 
    687             InfoTable = AcpiDmTableInfoMadt15;
    688             break;
    689 
    690         default:
    691 
    692             AcpiOsPrintf ("\n**** Unknown MADT subtable type 0x%X\n\n",
    693                 Subtable->Type);
    694 
    695             /* Attempt to continue */
    696 
    697             if (!Subtable->Length)
    698             {
    699                 AcpiOsPrintf ("Invalid zero length subtable\n");
    700                 return;
    701             }
    702 
    703             goto NextSubtable;
    704         }
    705 
    706         Status = AcpiDmDumpTable (Length, Offset, Subtable,
    707             Subtable->Length, InfoTable);
    708         if (ACPI_FAILURE (Status))
    709         {
    710             return;
    711         }
    712 
    713 NextSubtable:
    714         /* Point to next subtable */
    715 
    716         Offset += Subtable->Length;
    717         Subtable = ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, Subtable,
    718             Subtable->Length);
    719     }
    720 }
    721 
    722 
    723 /*******************************************************************************
    724  *
    725  * FUNCTION:    AcpiDmDumpMcfg
    726  *
    727  * PARAMETERS:  Table               - A MCFG Table
    728  *
    729  * RETURN:      None
    730  *
    731  * DESCRIPTION: Format the contents of a MCFG table
    732  *
    733  ******************************************************************************/
    734 
    735 void
    736 AcpiDmDumpMcfg (
    737     ACPI_TABLE_HEADER       *Table)
    738 {
    739     ACPI_STATUS             Status;
    740     UINT32                  Offset = sizeof (ACPI_TABLE_MCFG);
    741     ACPI_MCFG_ALLOCATION    *Subtable;
    742 
    743 
    744     /* Main table */
    745 
    746     Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoMcfg);
    747     if (ACPI_FAILURE (Status))
    748     {
    749         return;
    750     }
    751 
    752     /* Subtables */
    753 
    754     Subtable = ACPI_ADD_PTR (ACPI_MCFG_ALLOCATION, Table, Offset);
    755     while (Offset < Table->Length)
    756     {
    757         if (Offset + sizeof (ACPI_MCFG_ALLOCATION) > Table->Length)
    758         {
    759             AcpiOsPrintf ("Warning: there are %u invalid trailing bytes\n",
    760                 sizeof (ACPI_MCFG_ALLOCATION) - (Offset - Table->Length));
    761             return;
    762         }
    763 
    764         AcpiOsPrintf ("\n");
    765         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
    766             sizeof (ACPI_MCFG_ALLOCATION), AcpiDmTableInfoMcfg0);
    767         if (ACPI_FAILURE (Status))
    768         {
    769             return;
    770         }
    771 
    772         /* Point to next subtable (each subtable is of fixed length) */
    773 
    774         Offset += sizeof (ACPI_MCFG_ALLOCATION);
    775         Subtable = ACPI_ADD_PTR (ACPI_MCFG_ALLOCATION, Subtable,
    776             sizeof (ACPI_MCFG_ALLOCATION));
    777     }
    778 }
    779 
    780 
    781 /*******************************************************************************
    782  *
    783  * FUNCTION:    AcpiDmDumpMpst
    784  *
    785  * PARAMETERS:  Table               - A MPST Table
    786  *
    787  * RETURN:      None
    788  *
    789  * DESCRIPTION: Format the contents of a MPST table
    790  *
    791  ******************************************************************************/
    792 
    793 void
    794 AcpiDmDumpMpst (
    795     ACPI_TABLE_HEADER       *Table)
    796 {
    797     ACPI_STATUS             Status;
    798     UINT32                  Offset = sizeof (ACPI_TABLE_MPST);
    799     ACPI_MPST_POWER_NODE    *Subtable0;
    800     ACPI_MPST_POWER_STATE   *Subtable0A;
    801     ACPI_MPST_COMPONENT     *Subtable0B;
    802     ACPI_MPST_DATA_HDR      *Subtable1;
    803     ACPI_MPST_POWER_DATA    *Subtable2;
    804     UINT16                  SubtableCount;
    805     UINT32                  PowerStateCount;
    806     UINT32                  ComponentCount;
    807 
    808 
    809     /* Main table */
    810 
    811     Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoMpst);
    812     if (ACPI_FAILURE (Status))
    813     {
    814         return;
    815     }
    816 
    817     /* Subtable: Memory Power Node(s) */
    818 
    819     SubtableCount = (ACPI_CAST_PTR (ACPI_TABLE_MPST, Table))->PowerNodeCount;
    820     Subtable0 = ACPI_ADD_PTR (ACPI_MPST_POWER_NODE, Table, Offset);
    821 
    822     while ((Offset < Table->Length) && SubtableCount)
    823     {
    824         AcpiOsPrintf ("\n");
    825         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable0,
    826             sizeof (ACPI_MPST_POWER_NODE), AcpiDmTableInfoMpst0);
    827         if (ACPI_FAILURE (Status))
    828         {
    829             return;
    830         }
    831 
    832         /* Extract the sub-subtable counts */
    833 
    834         PowerStateCount = Subtable0->NumPowerStates;
    835         ComponentCount = Subtable0->NumPhysicalComponents;
    836         Offset += sizeof (ACPI_MPST_POWER_NODE);
    837 
    838         /* Sub-subtables - Memory Power State Structure(s) */
    839 
    840         Subtable0A = ACPI_ADD_PTR (ACPI_MPST_POWER_STATE, Subtable0,
    841             sizeof (ACPI_MPST_POWER_NODE));
    842 
    843         while (PowerStateCount)
    844         {
    845             AcpiOsPrintf ("\n");
    846             Status = AcpiDmDumpTable (Table->Length, Offset, Subtable0A,
    847                 sizeof (ACPI_MPST_POWER_STATE), AcpiDmTableInfoMpst0A);
    848             if (ACPI_FAILURE (Status))
    849             {
    850                 return;
    851             }
    852 
    853             Subtable0A++;
    854             PowerStateCount--;
    855             Offset += sizeof (ACPI_MPST_POWER_STATE);
    856        }
    857 
    858         /* Sub-subtables - Physical Component ID Structure(s) */
    859 
    860         Subtable0B = ACPI_CAST_PTR (ACPI_MPST_COMPONENT, Subtable0A);
    861 
    862         if (ComponentCount)
    863         {
    864             AcpiOsPrintf ("\n");
    865         }
    866 
    867         while (ComponentCount)
    868         {
    869             Status = AcpiDmDumpTable (Table->Length, Offset, Subtable0B,
    870                 sizeof (ACPI_MPST_COMPONENT), AcpiDmTableInfoMpst0B);
    871             if (ACPI_FAILURE (Status))
    872             {
    873                 return;
    874             }
    875 
    876             Subtable0B++;
    877             ComponentCount--;
    878             Offset += sizeof (ACPI_MPST_COMPONENT);
    879         }
    880 
    881         /* Point to next Memory Power Node subtable */
    882 
    883         SubtableCount--;
    884         Subtable0 = ACPI_ADD_PTR (ACPI_MPST_POWER_NODE, Subtable0,
    885             sizeof (ACPI_MPST_POWER_NODE) +
    886             (sizeof (ACPI_MPST_POWER_STATE) * Subtable0->NumPowerStates) +
    887             (sizeof (ACPI_MPST_COMPONENT) * Subtable0->NumPhysicalComponents));
    888     }
    889 
    890     /* Subtable: Count of Memory Power State Characteristic structures */
    891 
    892     AcpiOsPrintf ("\n");
    893     Subtable1 = ACPI_CAST_PTR (ACPI_MPST_DATA_HDR, Subtable0);
    894     Status = AcpiDmDumpTable (Table->Length, Offset, Subtable1,
    895         sizeof (ACPI_MPST_DATA_HDR), AcpiDmTableInfoMpst1);
    896     if (ACPI_FAILURE (Status))
    897     {
    898         return;
    899     }
    900 
    901     SubtableCount = Subtable1->CharacteristicsCount;
    902     Offset += sizeof (ACPI_MPST_DATA_HDR);
    903 
    904     /* Subtable: Memory Power State Characteristics structure(s) */
    905 
    906     Subtable2 = ACPI_ADD_PTR (ACPI_MPST_POWER_DATA, Subtable1,
    907         sizeof (ACPI_MPST_DATA_HDR));
    908 
    909     while ((Offset < Table->Length) && SubtableCount)
    910     {
    911         AcpiOsPrintf ("\n");
    912         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable2,
    913             sizeof (ACPI_MPST_POWER_DATA), AcpiDmTableInfoMpst2);
    914         if (ACPI_FAILURE (Status))
    915         {
    916             return;
    917         }
    918 
    919         Subtable2++;
    920         SubtableCount--;
    921         Offset += sizeof (ACPI_MPST_POWER_DATA);
    922     }
    923 }
    924 
    925 
    926 /*******************************************************************************
    927  *
    928  * FUNCTION:    AcpiDmDumpMsct
    929  *
    930  * PARAMETERS:  Table               - A MSCT table
    931  *
    932  * RETURN:      None
    933  *
    934  * DESCRIPTION: Format the contents of a MSCT
    935  *
    936  ******************************************************************************/
    937 
    938 void
    939 AcpiDmDumpMsct (
    940     ACPI_TABLE_HEADER       *Table)
    941 {
    942     ACPI_STATUS             Status;
    943     UINT32                  Offset = sizeof (ACPI_TABLE_MSCT);
    944     ACPI_MSCT_PROXIMITY     *Subtable;
    945 
    946 
    947     /* Main table */
    948 
    949     Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoMsct);
    950     if (ACPI_FAILURE (Status))
    951     {
    952         return;
    953     }
    954 
    955     /* Subtables */
    956 
    957     Subtable = ACPI_ADD_PTR (ACPI_MSCT_PROXIMITY, Table, Offset);
    958     while (Offset < Table->Length)
    959     {
    960         /* Common subtable header */
    961 
    962         AcpiOsPrintf ("\n");
    963         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
    964             sizeof (ACPI_MSCT_PROXIMITY), AcpiDmTableInfoMsct0);
    965         if (ACPI_FAILURE (Status))
    966         {
    967             return;
    968         }
    969 
    970         /* Point to next subtable */
    971 
    972         Offset += sizeof (ACPI_MSCT_PROXIMITY);
    973         Subtable = ACPI_ADD_PTR (ACPI_MSCT_PROXIMITY, Subtable,
    974             sizeof (ACPI_MSCT_PROXIMITY));
    975     }
    976 }
    977 
    978 
    979 /*******************************************************************************
    980  *
    981  * FUNCTION:    AcpiDmDumpMtmr
    982  *
    983  * PARAMETERS:  Table               - A MTMR table
    984  *
    985  * RETURN:      None
    986  *
    987  * DESCRIPTION: Format the contents of a MTMR
    988  *
    989  ******************************************************************************/
    990 
    991 void
    992 AcpiDmDumpMtmr (
    993     ACPI_TABLE_HEADER       *Table)
    994 {
    995     ACPI_STATUS             Status;
    996     UINT32                  Offset = sizeof (ACPI_TABLE_MTMR);
    997     ACPI_MTMR_ENTRY         *Subtable;
    998 
    999 
   1000     /* Main table */
   1001 
   1002     Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoMtmr);
   1003     if (ACPI_FAILURE (Status))
   1004     {
   1005         return;
   1006     }
   1007 
   1008     /* Subtables */
   1009 
   1010     Subtable = ACPI_ADD_PTR (ACPI_MTMR_ENTRY, Table, Offset);
   1011     while (Offset < Table->Length)
   1012     {
   1013         /* Common subtable header */
   1014 
   1015         AcpiOsPrintf ("\n");
   1016         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
   1017             sizeof (ACPI_MTMR_ENTRY), AcpiDmTableInfoMtmr0);
   1018         if (ACPI_FAILURE (Status))
   1019         {
   1020             return;
   1021         }
   1022 
   1023         /* Point to next subtable */
   1024 
   1025         Offset += sizeof (ACPI_MTMR_ENTRY);
   1026         Subtable = ACPI_ADD_PTR (ACPI_MTMR_ENTRY, Subtable,
   1027             sizeof (ACPI_MTMR_ENTRY));
   1028     }
   1029 }
   1030 
   1031 
   1032 /*******************************************************************************
   1033  *
   1034  * FUNCTION:    AcpiDmDumpNfit
   1035  *
   1036  * PARAMETERS:  Table               - A NFIT table
   1037  *
   1038  * RETURN:      None
   1039  *
   1040  * DESCRIPTION: Format the contents of an NFIT.
   1041  *
   1042  ******************************************************************************/
   1043 
   1044 void
   1045 AcpiDmDumpNfit (
   1046     ACPI_TABLE_HEADER       *Table)
   1047 {
   1048     ACPI_STATUS             Status;
   1049     UINT32                  Offset = sizeof (ACPI_TABLE_NFIT);
   1050     UINT32                  FieldOffset = 0;
   1051     UINT32                  Length;
   1052     ACPI_NFIT_HEADER        *Subtable;
   1053     ACPI_DMTABLE_INFO       *InfoTable;
   1054     ACPI_NFIT_INTERLEAVE    *Interleave = NULL;
   1055     ACPI_NFIT_SMBIOS        *SmbiosInfo = NULL;
   1056     ACPI_NFIT_FLUSH_ADDRESS *Hint = NULL;
   1057     UINT32                  i;
   1058 
   1059 
   1060     /* Main table */
   1061 
   1062     Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoNfit);
   1063     if (ACPI_FAILURE (Status))
   1064     {
   1065         return;
   1066     }
   1067 
   1068     /* Subtables */
   1069 
   1070     Subtable = ACPI_ADD_PTR (ACPI_NFIT_HEADER, Table, Offset);
   1071     while (Offset < Table->Length)
   1072     {
   1073         /* NFIT subtable header */
   1074 
   1075         AcpiOsPrintf ("\n");
   1076         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
   1077             Subtable->Length, AcpiDmTableInfoNfitHdr);
   1078         if (ACPI_FAILURE (Status))
   1079         {
   1080             return;
   1081         }
   1082 
   1083         switch (Subtable->Type)
   1084         {
   1085         case ACPI_NFIT_TYPE_SYSTEM_ADDRESS:
   1086 
   1087             InfoTable = AcpiDmTableInfoNfit0;
   1088             break;
   1089 
   1090         case ACPI_NFIT_TYPE_MEMORY_MAP:
   1091 
   1092             InfoTable = AcpiDmTableInfoNfit1;
   1093             break;
   1094 
   1095         case ACPI_NFIT_TYPE_INTERLEAVE:
   1096 
   1097             /* Has a variable number of 32-bit values at the end */
   1098 
   1099             InfoTable = AcpiDmTableInfoNfit2;
   1100             Interleave = ACPI_CAST_PTR (ACPI_NFIT_INTERLEAVE, Subtable);
   1101             FieldOffset = sizeof (ACPI_NFIT_INTERLEAVE);
   1102             break;
   1103 
   1104         case ACPI_NFIT_TYPE_SMBIOS:
   1105 
   1106             SmbiosInfo = ACPI_CAST_PTR (ACPI_NFIT_SMBIOS, Subtable);
   1107             InfoTable = AcpiDmTableInfoNfit3;
   1108             break;
   1109 
   1110         case ACPI_NFIT_TYPE_CONTROL_REGION:
   1111 
   1112             InfoTable = AcpiDmTableInfoNfit4;
   1113             break;
   1114 
   1115         case ACPI_NFIT_TYPE_DATA_REGION:
   1116 
   1117             InfoTable = AcpiDmTableInfoNfit5;
   1118             break;
   1119 
   1120         case ACPI_NFIT_TYPE_FLUSH_ADDRESS:
   1121 
   1122             /* Has a variable number of 64-bit addresses at the end */
   1123 
   1124             InfoTable = AcpiDmTableInfoNfit6;
   1125             Hint = ACPI_CAST_PTR (ACPI_NFIT_FLUSH_ADDRESS, Subtable);
   1126             FieldOffset = sizeof (ACPI_NFIT_FLUSH_ADDRESS) - sizeof (UINT64);
   1127             break;
   1128 
   1129         case ACPI_NFIT_TYPE_CAPABILITIES:    /* ACPI 6.0A */
   1130 
   1131             InfoTable = AcpiDmTableInfoNfit7;
   1132             break;
   1133 
   1134         default:
   1135             AcpiOsPrintf ("\n**** Unknown NFIT subtable type 0x%X\n",
   1136                 Subtable->Type);
   1137 
   1138             /* Attempt to continue */
   1139 
   1140             if (!Subtable->Length)
   1141             {
   1142                 AcpiOsPrintf ("Invalid zero length subtable\n");
   1143                 return;
   1144             }
   1145             goto NextSubtable;
   1146         }
   1147 
   1148         AcpiOsPrintf ("\n");
   1149         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
   1150             Subtable->Length, InfoTable);
   1151         if (ACPI_FAILURE (Status))
   1152         {
   1153             return;
   1154         }
   1155 
   1156         /* Per-subtable variable-length fields */
   1157 
   1158         switch (Subtable->Type)
   1159         {
   1160         case ACPI_NFIT_TYPE_INTERLEAVE:
   1161 
   1162             for (i = 0; i < Interleave->LineCount; i++)
   1163             {
   1164                 Status = AcpiDmDumpTable (Table->Length, Offset + FieldOffset,
   1165                     &Interleave->LineOffset[i],
   1166                     sizeof (UINT32), AcpiDmTableInfoNfit2a);
   1167                 if (ACPI_FAILURE (Status))
   1168                 {
   1169                     return;
   1170                 }
   1171 
   1172                 FieldOffset += sizeof (UINT32);
   1173             }
   1174             break;
   1175 
   1176         case ACPI_NFIT_TYPE_SMBIOS:
   1177 
   1178             Length = Subtable->Length -
   1179                 sizeof (ACPI_NFIT_SMBIOS) + sizeof (UINT8);
   1180 
   1181             if (Length)
   1182             {
   1183                 Status = AcpiDmDumpTable (Table->Length,
   1184                     sizeof (ACPI_NFIT_SMBIOS) - sizeof (UINT8),
   1185                     SmbiosInfo,
   1186                     Length, AcpiDmTableInfoNfit3a);
   1187                 if (ACPI_FAILURE (Status))
   1188                 {
   1189                     return;
   1190                 }
   1191             }
   1192 
   1193             break;
   1194 
   1195         case ACPI_NFIT_TYPE_FLUSH_ADDRESS:
   1196 
   1197             for (i = 0; i < Hint->HintCount; i++)
   1198             {
   1199                 Status = AcpiDmDumpTable (Table->Length, Offset + FieldOffset,
   1200                     &Hint->HintAddress[i],
   1201                     sizeof (UINT64), AcpiDmTableInfoNfit6a);
   1202                 if (ACPI_FAILURE (Status))
   1203                 {
   1204                     return;
   1205                 }
   1206 
   1207                 FieldOffset += sizeof (UINT64);
   1208             }
   1209             break;
   1210 
   1211         default:
   1212             break;
   1213         }
   1214 
   1215 NextSubtable:
   1216         /* Point to next subtable */
   1217 
   1218         Offset += Subtable->Length;
   1219         Subtable = ACPI_ADD_PTR (ACPI_NFIT_HEADER, Subtable, Subtable->Length);
   1220     }
   1221 }
   1222 
   1223 
   1224 /*******************************************************************************
   1225  *
   1226  * FUNCTION:    AcpiDmDumpPcct
   1227  *
   1228  * PARAMETERS:  Table               - A PCCT table
   1229  *
   1230  * RETURN:      None
   1231  *
   1232  * DESCRIPTION: Format the contents of a PCCT. This table type consists
   1233  *              of an open-ended number of subtables.
   1234  *
   1235  ******************************************************************************/
   1236 
   1237 void
   1238 AcpiDmDumpPcct (
   1239     ACPI_TABLE_HEADER       *Table)
   1240 {
   1241     ACPI_STATUS             Status;
   1242     ACPI_PCCT_SUBSPACE      *Subtable;
   1243     ACPI_DMTABLE_INFO       *InfoTable;
   1244     UINT32                  Length = Table->Length;
   1245     UINT32                  Offset = sizeof (ACPI_TABLE_PCCT);
   1246 
   1247 
   1248     /* Main table */
   1249 
   1250     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoPcct);
   1251     if (ACPI_FAILURE (Status))
   1252     {
   1253         return;
   1254     }
   1255 
   1256     /* Subtables */
   1257 
   1258     Subtable = ACPI_ADD_PTR (ACPI_PCCT_SUBSPACE, Table, Offset);
   1259     while (Offset < Table->Length)
   1260     {
   1261         /* Common subtable header */
   1262 
   1263         AcpiOsPrintf ("\n");
   1264         Status = AcpiDmDumpTable (Length, Offset, Subtable,
   1265             Subtable->Header.Length, AcpiDmTableInfoPcctHdr);
   1266         if (ACPI_FAILURE (Status))
   1267         {
   1268             return;
   1269         }
   1270 
   1271         switch (Subtable->Header.Type)
   1272         {
   1273         case ACPI_PCCT_TYPE_GENERIC_SUBSPACE:
   1274 
   1275             InfoTable = AcpiDmTableInfoPcct0;
   1276             break;
   1277 
   1278         case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE:
   1279 
   1280             InfoTable = AcpiDmTableInfoPcct1;
   1281             break;
   1282 
   1283         case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2:
   1284 
   1285             InfoTable = AcpiDmTableInfoPcct2;
   1286             break;
   1287 
   1288         case ACPI_PCCT_TYPE_EXT_PCC_MASTER_SUBSPACE:
   1289 
   1290             InfoTable = AcpiDmTableInfoPcct3;
   1291             break;
   1292 
   1293         case ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE:
   1294 
   1295             InfoTable = AcpiDmTableInfoPcct4;
   1296             break;
   1297 
   1298         default:
   1299 
   1300             AcpiOsPrintf (
   1301                 "\n**** Unexpected or unknown PCCT subtable type 0x%X\n\n",
   1302                 Subtable->Header.Type);
   1303             return;
   1304         }
   1305 
   1306         AcpiOsPrintf ("\n");
   1307         Status = AcpiDmDumpTable (Length, Offset, Subtable,
   1308             Subtable->Header.Length, InfoTable);
   1309         if (ACPI_FAILURE (Status))
   1310         {
   1311             return;
   1312         }
   1313 
   1314         /* Point to next subtable */
   1315 
   1316         Offset += Subtable->Header.Length;
   1317         Subtable = ACPI_ADD_PTR (ACPI_PCCT_SUBSPACE, Subtable,
   1318             Subtable->Header.Length);
   1319     }
   1320 }
   1321 
   1322 
   1323 /*******************************************************************************
   1324  *
   1325  * FUNCTION:    AcpiDmDumpPdtt
   1326  *
   1327  * PARAMETERS:  Table               - A PDTT table
   1328  *
   1329  * RETURN:      None
   1330  *
   1331  * DESCRIPTION: Format the contents of a Pdtt. This is a variable-length
   1332  *              table that contains an open-ended number of IDs
   1333  *              at the end of the table.
   1334  *
   1335  ******************************************************************************/
   1336 
   1337 void
   1338 AcpiDmDumpPdtt (
   1339     ACPI_TABLE_HEADER       *Table)
   1340 {
   1341     ACPI_STATUS             Status;
   1342     ACPI_PDTT_CHANNEL       *Subtable;
   1343     UINT32                  Length = Table->Length;
   1344     UINT32                  Offset = sizeof (ACPI_TABLE_PDTT);
   1345 
   1346 
   1347     /* Main table */
   1348 
   1349     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoPdtt);
   1350     if (ACPI_FAILURE (Status))
   1351     {
   1352         return;
   1353     }
   1354 
   1355     /* Subtables. Currently there is only one type, but can be multiples */
   1356 
   1357     Subtable = ACPI_ADD_PTR (ACPI_PDTT_CHANNEL, Table, Offset);
   1358     while (Offset < Table->Length)
   1359     {
   1360         AcpiOsPrintf ("\n");
   1361         Status = AcpiDmDumpTable (Length, Offset, Subtable,
   1362             sizeof (ACPI_PDTT_CHANNEL), AcpiDmTableInfoPdtt0);
   1363         if (ACPI_FAILURE (Status))
   1364         {
   1365             return;
   1366         }
   1367 
   1368         /* Point to next subtable */
   1369 
   1370         Offset += sizeof (ACPI_PDTT_CHANNEL);
   1371         Subtable = ACPI_ADD_PTR (ACPI_PDTT_CHANNEL, Subtable,
   1372             sizeof (ACPI_PDTT_CHANNEL));
   1373     }
   1374 }
   1375 
   1376 
   1377 /*******************************************************************************
   1378  *
   1379  * FUNCTION:    AcpiDmDumpPmtt
   1380  *
   1381  * PARAMETERS:  Table               - A PMTT table
   1382  *
   1383  * RETURN:      None
   1384  *
   1385  * DESCRIPTION: Format the contents of a PMTT. This table type consists
   1386  *              of an open-ended number of subtables.
   1387  *
   1388  ******************************************************************************/
   1389 
   1390 void
   1391 AcpiDmDumpPmtt (
   1392     ACPI_TABLE_HEADER       *Table)
   1393 {
   1394     ACPI_STATUS             Status;
   1395     ACPI_PMTT_HEADER        *Subtable;
   1396     ACPI_PMTT_HEADER        *MemSubtable;
   1397     ACPI_PMTT_HEADER        *DimmSubtable;
   1398     ACPI_PMTT_DOMAIN        *DomainArray;
   1399     UINT32                  Length = Table->Length;
   1400     UINT32                  Offset = sizeof (ACPI_TABLE_PMTT);
   1401     UINT32                  MemOffset;
   1402     UINT32                  DimmOffset;
   1403     UINT32                  DomainOffset;
   1404     UINT32                  DomainCount;
   1405 
   1406 
   1407     /* Main table */
   1408 
   1409     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoPmtt);
   1410     if (ACPI_FAILURE (Status))
   1411     {
   1412         return;
   1413     }
   1414 
   1415     /* Subtables */
   1416 
   1417     Subtable = ACPI_ADD_PTR (ACPI_PMTT_HEADER, Table, Offset);
   1418     while (Offset < Table->Length)
   1419     {
   1420         /* Common subtable header */
   1421 
   1422         AcpiOsPrintf ("\n");
   1423         Status = AcpiDmDumpTable (Length, Offset, Subtable,
   1424             Subtable->Length, AcpiDmTableInfoPmttHdr);
   1425         if (ACPI_FAILURE (Status))
   1426         {
   1427             return;
   1428         }
   1429 
   1430         /* Only Socket subtables are expected at this level */
   1431 
   1432         if (Subtable->Type != ACPI_PMTT_TYPE_SOCKET)
   1433         {
   1434             AcpiOsPrintf (
   1435                 "\n**** Unexpected or unknown PMTT subtable type 0x%X\n\n",
   1436                 Subtable->Type);
   1437             return;
   1438         }
   1439 
   1440         /* Dump the fixed-length portion of the subtable */
   1441 
   1442         Status = AcpiDmDumpTable (Length, Offset, Subtable,
   1443             Subtable->Length, AcpiDmTableInfoPmtt0);
   1444         if (ACPI_FAILURE (Status))
   1445         {
   1446             return;
   1447         }
   1448 
   1449         /* Walk the memory controller subtables */
   1450 
   1451         MemOffset = sizeof (ACPI_PMTT_SOCKET);
   1452         MemSubtable = ACPI_ADD_PTR (ACPI_PMTT_HEADER, Subtable,
   1453             sizeof (ACPI_PMTT_SOCKET));
   1454 
   1455         while (((Offset + MemOffset) < Table->Length) &&
   1456             (MemOffset < Subtable->Length))
   1457         {
   1458             /* Common subtable header */
   1459 
   1460             AcpiOsPrintf ("\n");
   1461             Status = AcpiDmDumpTable (Length,
   1462                 Offset + MemOffset, MemSubtable,
   1463                 MemSubtable->Length, AcpiDmTableInfoPmttHdr);
   1464             if (ACPI_FAILURE (Status))
   1465             {
   1466                 return;
   1467             }
   1468 
   1469             /* Only memory controller subtables are expected at this level */
   1470 
   1471             if (MemSubtable->Type != ACPI_PMTT_TYPE_CONTROLLER)
   1472             {
   1473                 AcpiOsPrintf (
   1474                     "\n**** Unexpected or unknown PMTT subtable type 0x%X\n\n",
   1475                     MemSubtable->Type);
   1476                 return;
   1477             }
   1478 
   1479             /* Dump the fixed-length portion of the controller subtable */
   1480 
   1481             Status = AcpiDmDumpTable (Length,
   1482                 Offset + MemOffset, MemSubtable,
   1483                 MemSubtable->Length, AcpiDmTableInfoPmtt1);
   1484             if (ACPI_FAILURE (Status))
   1485             {
   1486                 return;
   1487             }
   1488 
   1489             /* Walk the variable count of proximity domains */
   1490 
   1491             DomainCount = ((ACPI_PMTT_CONTROLLER *) MemSubtable)->DomainCount;
   1492             DomainOffset = sizeof (ACPI_PMTT_CONTROLLER);
   1493             DomainArray = ACPI_ADD_PTR (ACPI_PMTT_DOMAIN, MemSubtable,
   1494                 sizeof (ACPI_PMTT_CONTROLLER));
   1495 
   1496             while (((Offset + MemOffset + DomainOffset) < Table->Length) &&
   1497                 ((MemOffset + DomainOffset) < Subtable->Length) &&
   1498                 DomainCount)
   1499             {
   1500                 Status = AcpiDmDumpTable (Length,
   1501                     Offset + MemOffset + DomainOffset, DomainArray,
   1502                     sizeof (ACPI_PMTT_DOMAIN), AcpiDmTableInfoPmtt1a);
   1503                 if (ACPI_FAILURE (Status))
   1504                 {
   1505                     return;
   1506                 }
   1507 
   1508                 DomainOffset += sizeof (ACPI_PMTT_DOMAIN);
   1509                 DomainArray++;
   1510                 DomainCount--;
   1511             }
   1512 
   1513             if (DomainCount)
   1514             {
   1515                 AcpiOsPrintf (
   1516                     "\n**** DomainCount exceeds subtable length\n\n");
   1517             }
   1518 
   1519             /* Walk the physical component (DIMM) subtables */
   1520 
   1521             DimmOffset = DomainOffset;
   1522             DimmSubtable = ACPI_ADD_PTR (ACPI_PMTT_HEADER, MemSubtable,
   1523                 DomainOffset);
   1524 
   1525             while (((Offset + MemOffset + DimmOffset) < Table->Length) &&
   1526                 (DimmOffset < MemSubtable->Length))
   1527             {
   1528                 /* Common subtable header */
   1529 
   1530                 AcpiOsPrintf ("\n");
   1531                 Status = AcpiDmDumpTable (Length,
   1532                     Offset + MemOffset + DimmOffset, DimmSubtable,
   1533                     DimmSubtable->Length, AcpiDmTableInfoPmttHdr);
   1534                 if (ACPI_FAILURE (Status))
   1535                 {
   1536                     return;
   1537                 }
   1538 
   1539                 /* Only DIMM subtables are expected at this level */
   1540 
   1541                 if (DimmSubtable->Type != ACPI_PMTT_TYPE_DIMM)
   1542                 {
   1543                     AcpiOsPrintf (
   1544                         "\n**** Unexpected or unknown PMTT subtable type 0x%X\n\n",
   1545                         DimmSubtable->Type);
   1546                     return;
   1547                 }
   1548 
   1549                 /* Dump the fixed-length DIMM subtable */
   1550 
   1551                 Status = AcpiDmDumpTable (Length,
   1552                     Offset + MemOffset + DimmOffset, DimmSubtable,
   1553                     DimmSubtable->Length, AcpiDmTableInfoPmtt2);
   1554                 if (ACPI_FAILURE (Status))
   1555                 {
   1556                     return;
   1557                 }
   1558 
   1559                 /* Point to next DIMM subtable */
   1560 
   1561                 DimmOffset += DimmSubtable->Length;
   1562                 DimmSubtable = ACPI_ADD_PTR (ACPI_PMTT_HEADER,
   1563                     DimmSubtable, DimmSubtable->Length);
   1564             }
   1565 
   1566             /* Point to next Controller subtable */
   1567 
   1568             MemOffset += MemSubtable->Length;
   1569             MemSubtable = ACPI_ADD_PTR (ACPI_PMTT_HEADER,
   1570                 MemSubtable, MemSubtable->Length);
   1571         }
   1572 
   1573         /* Point to next Socket subtable */
   1574 
   1575         Offset += Subtable->Length;
   1576         Subtable = ACPI_ADD_PTR (ACPI_PMTT_HEADER,
   1577             Subtable, Subtable->Length);
   1578     }
   1579 }
   1580 
   1581 
   1582 /*******************************************************************************
   1583  *
   1584  * FUNCTION:    AcpiDmDumpPptt
   1585  *
   1586  * PARAMETERS:  Table               - A PMTT table
   1587  *
   1588  * RETURN:      None
   1589  *
   1590  * DESCRIPTION: Format the contents of a PPTT. This table type consists
   1591  *              of an open-ended number of subtables.
   1592  *
   1593  ******************************************************************************/
   1594 
   1595 void
   1596 AcpiDmDumpPptt (
   1597     ACPI_TABLE_HEADER       *Table)
   1598 {
   1599     ACPI_STATUS             Status;
   1600     ACPI_SUBTABLE_HEADER    *Subtable;
   1601     ACPI_PPTT_PROCESSOR     *PpttProcessor;
   1602     UINT8                   Length;
   1603     UINT8                   SubtableOffset;
   1604     UINT32                  Offset = sizeof (ACPI_TABLE_FPDT);
   1605     ACPI_DMTABLE_INFO       *InfoTable;
   1606     UINT32                  i;
   1607 
   1608 
   1609     /* There is no main table (other than the standard ACPI header) */
   1610 
   1611     /* Subtables */
   1612 
   1613     Offset = sizeof (ACPI_TABLE_HEADER);
   1614     while (Offset < Table->Length)
   1615     {
   1616         AcpiOsPrintf ("\n");
   1617 
   1618         /* Common subtable header */
   1619 
   1620         Subtable = ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, Table, Offset);
   1621         if (Subtable->Length < sizeof (ACPI_SUBTABLE_HEADER))
   1622         {
   1623             AcpiOsPrintf ("Invalid subtable length\n");
   1624             return;
   1625         }
   1626         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
   1627             Subtable->Length, AcpiDmTableInfoPpttHdr);
   1628         if (ACPI_FAILURE (Status))
   1629         {
   1630             return;
   1631         }
   1632 
   1633         switch (Subtable->Type)
   1634         {
   1635         case ACPI_PPTT_TYPE_PROCESSOR:
   1636 
   1637             InfoTable = AcpiDmTableInfoPptt0;
   1638             Length = sizeof (ACPI_PPTT_PROCESSOR);
   1639             break;
   1640 
   1641         case ACPI_PPTT_TYPE_CACHE:
   1642 
   1643             InfoTable = AcpiDmTableInfoPptt1;
   1644             Length = sizeof (ACPI_PPTT_CACHE);
   1645             break;
   1646 
   1647         case ACPI_PPTT_TYPE_ID:
   1648 
   1649             InfoTable = AcpiDmTableInfoPptt2;
   1650             Length = sizeof (ACPI_PPTT_ID);
   1651             break;
   1652 
   1653         default:
   1654 
   1655             AcpiOsPrintf ("\n**** Unknown PPTT subtable type 0x%X\n\n",
   1656                 Subtable->Type);
   1657 
   1658             /* Attempt to continue */
   1659 
   1660             goto NextSubtable;
   1661         }
   1662 
   1663         if (Subtable->Length < Length)
   1664         {
   1665             AcpiOsPrintf ("Invalid subtable length\n");
   1666             return;
   1667         }
   1668         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
   1669             Subtable->Length, InfoTable);
   1670         if (ACPI_FAILURE (Status))
   1671         {
   1672             return;
   1673         }
   1674         SubtableOffset = Length;
   1675 
   1676         switch (Subtable->Type)
   1677         {
   1678         case ACPI_PPTT_TYPE_PROCESSOR:
   1679 
   1680             PpttProcessor = ACPI_CAST_PTR (ACPI_PPTT_PROCESSOR, Subtable);
   1681 
   1682             /* Dump SMBIOS handles */
   1683 
   1684             if ((UINT8)(Subtable->Length - SubtableOffset) <
   1685                 (UINT8)(PpttProcessor->NumberOfPrivResources * 4))
   1686             {
   1687                 AcpiOsPrintf ("Invalid private resource number\n");
   1688                 return;
   1689             }
   1690             for (i = 0; i < PpttProcessor->NumberOfPrivResources; i++)
   1691             {
   1692                 Status = AcpiDmDumpTable (Table->Length, Offset + SubtableOffset,
   1693                     ACPI_ADD_PTR (ACPI_SUBTABLE_HEADER, Subtable, SubtableOffset),
   1694                     4, AcpiDmTableInfoPptt0a);
   1695                 SubtableOffset += 4;
   1696             }
   1697             break;
   1698 
   1699         default:
   1700 
   1701             break;
   1702         }
   1703 
   1704 NextSubtable:
   1705         /* Point to next subtable */
   1706 
   1707         Offset += Subtable->Length;
   1708     }
   1709 }
   1710 
   1711 
   1712 /*******************************************************************************
   1713  *
   1714  * FUNCTION:    AcpiDmDumpS3pt
   1715  *
   1716  * PARAMETERS:  Table               - A S3PT table
   1717  *
   1718  * RETURN:      Length of the table
   1719  *
   1720  * DESCRIPTION: Format the contents of a S3PT
   1721  *
   1722  ******************************************************************************/
   1723 
   1724 UINT32
   1725 AcpiDmDumpS3pt (
   1726     ACPI_TABLE_HEADER       *Tables)
   1727 {
   1728     ACPI_STATUS             Status;
   1729     UINT32                  Offset = sizeof (ACPI_TABLE_S3PT);
   1730     ACPI_FPDT_HEADER        *Subtable;
   1731     ACPI_DMTABLE_INFO       *InfoTable;
   1732     ACPI_TABLE_S3PT         *S3ptTable = ACPI_CAST_PTR (ACPI_TABLE_S3PT, Tables);
   1733 
   1734 
   1735     /* Main table */
   1736 
   1737     Status = AcpiDmDumpTable (Offset, 0, S3ptTable, 0, AcpiDmTableInfoS3pt);
   1738     if (ACPI_FAILURE (Status))
   1739     {
   1740         return 0;
   1741     }
   1742 
   1743     Subtable = ACPI_ADD_PTR (ACPI_FPDT_HEADER, S3ptTable, Offset);
   1744     while (Offset < S3ptTable->Length)
   1745     {
   1746         /* Common subtable header */
   1747 
   1748         AcpiOsPrintf ("\n");
   1749         Status = AcpiDmDumpTable (S3ptTable->Length, Offset, Subtable,
   1750             Subtable->Length, AcpiDmTableInfoS3ptHdr);
   1751         if (ACPI_FAILURE (Status))
   1752         {
   1753             return 0;
   1754         }
   1755 
   1756         switch (Subtable->Type)
   1757         {
   1758         case ACPI_S3PT_TYPE_RESUME:
   1759 
   1760             InfoTable = AcpiDmTableInfoS3pt0;
   1761             break;
   1762 
   1763         case ACPI_S3PT_TYPE_SUSPEND:
   1764 
   1765             InfoTable = AcpiDmTableInfoS3pt1;
   1766             break;
   1767 
   1768         default:
   1769 
   1770             AcpiOsPrintf ("\n**** Unknown S3PT subtable type 0x%X\n",
   1771                 Subtable->Type);
   1772 
   1773             /* Attempt to continue */
   1774 
   1775             if (!Subtable->Length)
   1776             {
   1777                 AcpiOsPrintf ("Invalid zero length subtable\n");
   1778                 return 0;
   1779             }
   1780             goto NextSubtable;
   1781         }
   1782 
   1783         AcpiOsPrintf ("\n");
   1784         Status = AcpiDmDumpTable (S3ptTable->Length, Offset, Subtable,
   1785             Subtable->Length, InfoTable);
   1786         if (ACPI_FAILURE (Status))
   1787         {
   1788             return 0;
   1789         }
   1790 
   1791 NextSubtable:
   1792         /* Point to next subtable */
   1793 
   1794         Offset += Subtable->Length;
   1795         Subtable = ACPI_ADD_PTR (ACPI_FPDT_HEADER, Subtable, Subtable->Length);
   1796     }
   1797 
   1798     return (S3ptTable->Length);
   1799 }
   1800 
   1801 
   1802 /*******************************************************************************
   1803  *
   1804  * FUNCTION:    AcpiDmDumpSdev
   1805  *
   1806  * PARAMETERS:  Table               - A SDEV table
   1807  *
   1808  * RETURN:      None
   1809  *
   1810  * DESCRIPTION: Format the contents of a SDEV. This is a variable-length
   1811  *              table that contains variable strings and vendor data.
   1812  *
   1813  ******************************************************************************/
   1814 
   1815 void
   1816 AcpiDmDumpSdev (
   1817     ACPI_TABLE_HEADER       *Table)
   1818 {
   1819     ACPI_STATUS             Status;
   1820     ACPI_SDEV_HEADER        *Subtable;
   1821     ACPI_SDEV_PCIE          *Pcie;
   1822     ACPI_SDEV_NAMESPACE     *Namesp;
   1823     ACPI_DMTABLE_INFO       *InfoTable;
   1824     UINT32                  Length = Table->Length;
   1825     UINT32                  Offset = sizeof (ACPI_TABLE_SDEV);
   1826     UINT16                  PathOffset;
   1827     UINT16                  PathLength;
   1828     UINT16                  VendorDataOffset;
   1829     UINT16                  VendorDataLength;
   1830 
   1831 
   1832     /* Main table */
   1833 
   1834     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoSdev);
   1835     if (ACPI_FAILURE (Status))
   1836     {
   1837         return;
   1838     }
   1839 
   1840     /* Subtables */
   1841 
   1842     Subtable = ACPI_ADD_PTR (ACPI_SDEV_HEADER, Table, Offset);
   1843     while (Offset < Table->Length)
   1844     {
   1845         /* Common subtable header */
   1846 
   1847         AcpiOsPrintf ("\n");
   1848         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
   1849             Subtable->Length, AcpiDmTableInfoSdevHdr);
   1850         if (ACPI_FAILURE (Status))
   1851         {
   1852             return;
   1853         }
   1854 
   1855         switch (Subtable->Type)
   1856         {
   1857         case ACPI_SDEV_TYPE_NAMESPACE_DEVICE:
   1858 
   1859             InfoTable = AcpiDmTableInfoSdev0;
   1860             break;
   1861 
   1862         case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE:
   1863 
   1864             InfoTable = AcpiDmTableInfoSdev1;
   1865             break;
   1866 
   1867         default:
   1868             goto NextSubtable;
   1869         }
   1870 
   1871         AcpiOsPrintf ("\n");
   1872         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
   1873             Subtable->Length, InfoTable);
   1874         if (ACPI_FAILURE (Status))
   1875         {
   1876             return;
   1877         }
   1878 
   1879         switch (Subtable->Type)
   1880         {
   1881         case ACPI_SDEV_TYPE_NAMESPACE_DEVICE:
   1882 
   1883             /* Dump the PCIe device ID(s) */
   1884 
   1885             Namesp = ACPI_CAST_PTR (ACPI_SDEV_NAMESPACE, Subtable);
   1886             PathOffset = Namesp->DeviceIdOffset;
   1887             PathLength = Namesp->DeviceIdLength;
   1888 
   1889             if (PathLength)
   1890             {
   1891                 Status = AcpiDmDumpTable (Table->Length, 0,
   1892                     ACPI_ADD_PTR (UINT8, Namesp, PathOffset),
   1893                     PathLength, AcpiDmTableInfoSdev0a);
   1894                 if (ACPI_FAILURE (Status))
   1895                 {
   1896                     return;
   1897                 }
   1898             }
   1899 
   1900             /* Dump the vendor-specific data */
   1901 
   1902             VendorDataLength =
   1903                 Namesp->VendorDataLength;
   1904             VendorDataOffset =
   1905                 Namesp->DeviceIdOffset + Namesp->DeviceIdLength;
   1906 
   1907             if (VendorDataLength)
   1908             {
   1909                 Status = AcpiDmDumpTable (Table->Length, 0,
   1910                     ACPI_ADD_PTR (UINT8, Namesp, VendorDataOffset),
   1911                     VendorDataLength, AcpiDmTableInfoSdev1b);
   1912                 if (ACPI_FAILURE (Status))
   1913                 {
   1914                     return;
   1915                 }
   1916             }
   1917             break;
   1918 
   1919         case ACPI_SDEV_TYPE_PCIE_ENDPOINT_DEVICE:
   1920 
   1921             /* PCI path substructures */
   1922 
   1923             Pcie = ACPI_CAST_PTR (ACPI_SDEV_PCIE, Subtable);
   1924             PathOffset = Pcie->PathOffset;
   1925             PathLength = Pcie->PathLength;
   1926 
   1927             while (PathLength)
   1928             {
   1929                 Status = AcpiDmDumpTable (Table->Length,
   1930                     PathOffset + Offset,
   1931                     ACPI_ADD_PTR (UINT8, Pcie, PathOffset),
   1932                     sizeof (ACPI_SDEV_PCIE_PATH), AcpiDmTableInfoSdev1a);
   1933                 if (ACPI_FAILURE (Status))
   1934                 {
   1935                     return;
   1936                 }
   1937 
   1938                 PathOffset += sizeof (ACPI_SDEV_PCIE_PATH);
   1939                 PathLength -= sizeof (ACPI_SDEV_PCIE_PATH);
   1940             }
   1941 
   1942             /* VendorData */
   1943 
   1944             VendorDataLength = Pcie->VendorDataLength;
   1945             VendorDataOffset = Pcie->PathOffset + Pcie->PathLength;
   1946 
   1947             if (VendorDataLength)
   1948             {
   1949                 Status = AcpiDmDumpTable (Table->Length, 0,
   1950                     ACPI_ADD_PTR (UINT8, Pcie, VendorDataOffset),
   1951                     VendorDataLength, AcpiDmTableInfoSdev1b);
   1952             }
   1953             break;
   1954 
   1955         default:
   1956             goto NextSubtable;
   1957         }
   1958 
   1959 NextSubtable:
   1960         /* Point to next subtable */
   1961 
   1962         Offset += Subtable->Length;
   1963         Subtable = ACPI_ADD_PTR (ACPI_SDEV_HEADER, Subtable,
   1964             Subtable->Length);
   1965     }
   1966 }
   1967