xref: /netbsd-src/sys/external/bsd/acpica/dist/common/dmtbdump1.c (revision e6c7e151de239c49d2e38720a061ed9d1fa99309)
1 /******************************************************************************
2  *
3  * Module Name: dmtbdump1 - Dump ACPI data tables that contain no AML code
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2020, 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    ("dmtbdump1")
53 
54 
55 /*******************************************************************************
56  *
57  * FUNCTION:    AcpiDmDumpAsf
58  *
59  * PARAMETERS:  Table               - A ASF table
60  *
61  * RETURN:      None
62  *
63  * DESCRIPTION: Format the contents of a ASF table
64  *
65  ******************************************************************************/
66 
67 void
68 AcpiDmDumpAsf (
69     ACPI_TABLE_HEADER       *Table)
70 {
71     ACPI_STATUS             Status;
72     UINT32                  Offset = sizeof (ACPI_TABLE_HEADER);
73     ACPI_ASF_INFO           *Subtable;
74     ACPI_DMTABLE_INFO       *InfoTable;
75     ACPI_DMTABLE_INFO       *DataInfoTable = NULL;
76     UINT8                   *DataTable = NULL;
77     UINT32                  DataCount = 0;
78     UINT32                  DataLength = 0;
79     UINT32                  DataOffset = 0;
80     UINT32                  i;
81     UINT8                   Type;
82 
83 
84     /* No main table, only subtables */
85 
86     Subtable = ACPI_ADD_PTR (ACPI_ASF_INFO, Table, Offset);
87     while (Offset < Table->Length)
88     {
89         /* Common subtable header */
90 
91         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
92             Subtable->Header.Length, AcpiDmTableInfoAsfHdr);
93         if (ACPI_FAILURE (Status))
94         {
95             return;
96         }
97 
98         /* The actual type is the lower 7 bits of Type */
99 
100         Type = (UINT8) (Subtable->Header.Type & 0x7F);
101 
102         switch (Type)
103         {
104         case ACPI_ASF_TYPE_INFO:
105 
106             InfoTable = AcpiDmTableInfoAsf0;
107             break;
108 
109         case ACPI_ASF_TYPE_ALERT:
110 
111             InfoTable = AcpiDmTableInfoAsf1;
112             DataInfoTable = AcpiDmTableInfoAsf1a;
113             DataTable = ACPI_ADD_PTR (UINT8, Subtable, sizeof (ACPI_ASF_ALERT));
114             DataCount = ACPI_CAST_PTR (ACPI_ASF_ALERT, Subtable)->Alerts;
115             DataLength = ACPI_CAST_PTR (ACPI_ASF_ALERT, Subtable)->DataLength;
116             DataOffset = Offset + sizeof (ACPI_ASF_ALERT);
117             break;
118 
119         case ACPI_ASF_TYPE_CONTROL:
120 
121             InfoTable = AcpiDmTableInfoAsf2;
122             DataInfoTable = AcpiDmTableInfoAsf2a;
123             DataTable = ACPI_ADD_PTR (UINT8, Subtable, sizeof (ACPI_ASF_REMOTE));
124             DataCount = ACPI_CAST_PTR (ACPI_ASF_REMOTE, Subtable)->Controls;
125             DataLength = ACPI_CAST_PTR (ACPI_ASF_REMOTE, Subtable)->DataLength;
126             DataOffset = Offset + sizeof (ACPI_ASF_REMOTE);
127             break;
128 
129         case ACPI_ASF_TYPE_BOOT:
130 
131             InfoTable = AcpiDmTableInfoAsf3;
132             break;
133 
134         case ACPI_ASF_TYPE_ADDRESS:
135 
136             InfoTable = AcpiDmTableInfoAsf4;
137             DataTable = ACPI_ADD_PTR (UINT8, Subtable, sizeof (ACPI_ASF_ADDRESS));
138             DataLength = ACPI_CAST_PTR (ACPI_ASF_ADDRESS, Subtable)->Devices;
139             DataOffset = Offset + sizeof (ACPI_ASF_ADDRESS);
140             break;
141 
142         default:
143 
144             AcpiOsPrintf ("\n**** Unknown ASF subtable type 0x%X\n",
145                 Subtable->Header.Type);
146             return;
147         }
148 
149         Status = AcpiDmDumpTable (Table->Length, Offset, Subtable,
150             Subtable->Header.Length, InfoTable);
151         if (ACPI_FAILURE (Status))
152         {
153             return;
154         }
155 
156         /* Dump variable-length extra data */
157 
158         switch (Type)
159         {
160         case ACPI_ASF_TYPE_ALERT:
161         case ACPI_ASF_TYPE_CONTROL:
162 
163             for (i = 0; i < DataCount; i++)
164             {
165                 AcpiOsPrintf ("\n");
166                 Status = AcpiDmDumpTable (Table->Length, DataOffset,
167                     DataTable, DataLength, DataInfoTable);
168                 if (ACPI_FAILURE (Status))
169                 {
170                     return;
171                 }
172 
173                 DataTable = ACPI_ADD_PTR (UINT8, DataTable, DataLength);
174                 DataOffset += DataLength;
175             }
176             break;
177 
178         case ACPI_ASF_TYPE_ADDRESS:
179 
180             for (i = 0; i < DataLength; i++)
181             {
182                 if (!(i % 16))
183                 {
184                     AcpiDmLineHeader (DataOffset, 1, "Addresses");
185                 }
186 
187                 AcpiOsPrintf ("%2.2X ", *DataTable);
188                 DataTable++;
189                 DataOffset++;
190 
191                 if (DataOffset > Table->Length)
192                 {
193                     AcpiOsPrintf (
194                         "**** ACPI table terminates in the middle of a "
195                         "data structure! (ASF! table)\n");
196                     return;
197                 }
198             }
199 
200             AcpiOsPrintf ("\n");
201             break;
202 
203         default:
204 
205             break;
206         }
207 
208         AcpiOsPrintf ("\n");
209 
210         /* Point to next subtable */
211 
212         if (!Subtable->Header.Length)
213         {
214             AcpiOsPrintf ("Invalid zero subtable header length\n");
215             return;
216         }
217 
218         Offset += Subtable->Header.Length;
219         Subtable = ACPI_ADD_PTR (ACPI_ASF_INFO, Subtable,
220             Subtable->Header.Length);
221     }
222 }
223 
224 
225 /*******************************************************************************
226  *
227  * FUNCTION:    AcpiDmDumpCpep
228  *
229  * PARAMETERS:  Table               - A CPEP table
230  *
231  * RETURN:      None
232  *
233  * DESCRIPTION: Format the contents of a CPEP. This table type consists
234  *              of an open-ended number of subtables.
235  *
236  ******************************************************************************/
237 
238 void
239 AcpiDmDumpCpep (
240     ACPI_TABLE_HEADER       *Table)
241 {
242     ACPI_STATUS             Status;
243     ACPI_CPEP_POLLING       *Subtable;
244     UINT32                  Length = Table->Length;
245     UINT32                  Offset = sizeof (ACPI_TABLE_CPEP);
246 
247 
248     /* Main table */
249 
250     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoCpep);
251     if (ACPI_FAILURE (Status))
252     {
253         return;
254     }
255 
256     /* Subtables */
257 
258     Subtable = ACPI_ADD_PTR (ACPI_CPEP_POLLING, Table, Offset);
259     while (Offset < Table->Length)
260     {
261         AcpiOsPrintf ("\n");
262         Status = AcpiDmDumpTable (Length, Offset, Subtable,
263             Subtable->Header.Length, AcpiDmTableInfoCpep0);
264         if (ACPI_FAILURE (Status))
265         {
266             return;
267         }
268 
269         /* Point to next subtable */
270 
271         Offset += Subtable->Header.Length;
272         Subtable = ACPI_ADD_PTR (ACPI_CPEP_POLLING, Subtable,
273             Subtable->Header.Length);
274     }
275 }
276 
277 
278 /*******************************************************************************
279  *
280  * FUNCTION:    AcpiDmDumpCsrt
281  *
282  * PARAMETERS:  Table               - A CSRT table
283  *
284  * RETURN:      None
285  *
286  * DESCRIPTION: Format the contents of a CSRT. This table type consists
287  *              of an open-ended number of subtables.
288  *
289  ******************************************************************************/
290 
291 void
292 AcpiDmDumpCsrt (
293     ACPI_TABLE_HEADER       *Table)
294 {
295     ACPI_STATUS             Status;
296     ACPI_CSRT_GROUP         *Subtable;
297     ACPI_CSRT_SHARED_INFO   *SharedInfoTable;
298     ACPI_CSRT_DESCRIPTOR    *SubSubtable;
299     UINT32                  Length = Table->Length;
300     UINT32                  Offset = sizeof (ACPI_TABLE_CSRT);
301     UINT32                  SubOffset;
302     UINT32                  SubSubOffset;
303     UINT32                  InfoLength;
304 
305 
306     /* The main table only contains the ACPI header, thus already handled */
307 
308     /* Subtables (Resource Groups) */
309 
310     Subtable = ACPI_ADD_PTR (ACPI_CSRT_GROUP, Table, Offset);
311     while (Offset < Table->Length)
312     {
313         /* Resource group subtable */
314 
315         AcpiOsPrintf ("\n");
316         Status = AcpiDmDumpTable (Length, Offset, Subtable,
317             Subtable->Length, AcpiDmTableInfoCsrt0);
318         if (ACPI_FAILURE (Status))
319         {
320             return;
321         }
322 
323         /* Shared info subtable (One per resource group) */
324 
325         SubOffset = sizeof (ACPI_CSRT_GROUP);
326         SharedInfoTable = ACPI_ADD_PTR (ACPI_CSRT_SHARED_INFO, Table,
327             Offset + SubOffset);
328 
329         AcpiOsPrintf ("\n");
330         Status = AcpiDmDumpTable (Length, Offset + SubOffset, SharedInfoTable,
331             sizeof (ACPI_CSRT_SHARED_INFO), AcpiDmTableInfoCsrt1);
332         if (ACPI_FAILURE (Status))
333         {
334             return;
335         }
336 
337         SubOffset += Subtable->SharedInfoLength;
338 
339         /* Sub-Subtables (Resource Descriptors) */
340 
341         SubSubtable = ACPI_ADD_PTR (ACPI_CSRT_DESCRIPTOR, Table,
342             Offset + SubOffset);
343 
344         while ((SubOffset < Subtable->Length) &&
345               ((Offset + SubOffset) < Table->Length))
346         {
347             AcpiOsPrintf ("\n");
348             Status = AcpiDmDumpTable (Length, Offset + SubOffset, SubSubtable,
349                 SubSubtable->Length, AcpiDmTableInfoCsrt2);
350             if (ACPI_FAILURE (Status))
351             {
352                 return;
353             }
354 
355             SubSubOffset = sizeof (ACPI_CSRT_DESCRIPTOR);
356 
357             /* Resource-specific info buffer */
358 
359             InfoLength = SubSubtable->Length - SubSubOffset;
360             if (InfoLength)
361             {
362                 Status = AcpiDmDumpTable (Length,
363                     Offset + SubOffset + SubSubOffset, Table,
364                     InfoLength, AcpiDmTableInfoCsrt2a);
365                 if (ACPI_FAILURE (Status))
366                 {
367                     return;
368                 }
369             }
370 
371             /* Point to next sub-subtable */
372 
373             SubOffset += SubSubtable->Length;
374             SubSubtable = ACPI_ADD_PTR (ACPI_CSRT_DESCRIPTOR, SubSubtable,
375                 SubSubtable->Length);
376         }
377 
378         /* Point to next subtable */
379 
380         Offset += Subtable->Length;
381         Subtable = ACPI_ADD_PTR (ACPI_CSRT_GROUP, Subtable,
382             Subtable->Length);
383     }
384 }
385 
386 
387 /*******************************************************************************
388  *
389  * FUNCTION:    AcpiDmDumpDbg2
390  *
391  * PARAMETERS:  Table               - A DBG2 table
392  *
393  * RETURN:      None
394  *
395  * DESCRIPTION: Format the contents of a DBG2. This table type consists
396  *              of an open-ended number of subtables.
397  *
398  ******************************************************************************/
399 
400 void
401 AcpiDmDumpDbg2 (
402     ACPI_TABLE_HEADER       *Table)
403 {
404     ACPI_STATUS             Status;
405     ACPI_DBG2_DEVICE        *Subtable;
406     UINT32                  Length = Table->Length;
407     UINT32                  Offset = sizeof (ACPI_TABLE_DBG2);
408     UINT32                  i;
409     UINT32                  ArrayOffset;
410     UINT32                  AbsoluteOffset;
411     UINT8                   *Array;
412 
413 
414     /* Main table */
415 
416     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoDbg2);
417     if (ACPI_FAILURE (Status))
418     {
419         return;
420     }
421 
422     /* Subtables */
423 
424     Subtable = ACPI_ADD_PTR (ACPI_DBG2_DEVICE, Table, Offset);
425     while (Offset < Table->Length)
426     {
427         AcpiOsPrintf ("\n");
428         Status = AcpiDmDumpTable (Length, Offset, Subtable,
429             Subtable->Length, AcpiDmTableInfoDbg2Device);
430         if (ACPI_FAILURE (Status))
431         {
432             return;
433         }
434 
435         /* Dump the BaseAddress array */
436 
437         for (i = 0; i < Subtable->RegisterCount; i++)
438         {
439             ArrayOffset = Subtable->BaseAddressOffset +
440                 (sizeof (ACPI_GENERIC_ADDRESS) * i);
441             AbsoluteOffset = Offset + ArrayOffset;
442             Array = (UINT8 *) Subtable + ArrayOffset;
443 
444             Status = AcpiDmDumpTable (Length, AbsoluteOffset, Array,
445                 Subtable->Length, AcpiDmTableInfoDbg2Addr);
446             if (ACPI_FAILURE (Status))
447             {
448                 return;
449             }
450         }
451 
452         /* Dump the AddressSize array */
453 
454         for (i = 0; i < Subtable->RegisterCount; i++)
455         {
456             ArrayOffset = Subtable->AddressSizeOffset +
457                 (sizeof (UINT32) * i);
458             AbsoluteOffset = Offset + ArrayOffset;
459             Array = (UINT8 *) Subtable + ArrayOffset;
460 
461             Status = AcpiDmDumpTable (Length, AbsoluteOffset, Array,
462                 Subtable->Length, AcpiDmTableInfoDbg2Size);
463             if (ACPI_FAILURE (Status))
464             {
465                 return;
466             }
467         }
468 
469         /* Dump the Namestring (required) */
470 
471         AcpiOsPrintf ("\n");
472         ArrayOffset = Subtable->NamepathOffset;
473         AbsoluteOffset = Offset + ArrayOffset;
474         Array = (UINT8 *) Subtable + ArrayOffset;
475 
476         Status = AcpiDmDumpTable (Length, AbsoluteOffset, Array,
477             Subtable->Length, AcpiDmTableInfoDbg2Name);
478         if (ACPI_FAILURE (Status))
479         {
480             return;
481         }
482 
483         /* Dump the OemData (optional) */
484 
485         if (Subtable->OemDataOffset)
486         {
487             Status = AcpiDmDumpTable (Length, Offset + Subtable->OemDataOffset,
488                 Table, Subtable->OemDataLength,
489                 AcpiDmTableInfoDbg2OemData);
490             if (ACPI_FAILURE (Status))
491             {
492                 return;
493             }
494         }
495 
496         /* Point to next subtable */
497 
498         Offset += Subtable->Length;
499         Subtable = ACPI_ADD_PTR (ACPI_DBG2_DEVICE, Subtable,
500             Subtable->Length);
501     }
502 }
503 
504 
505 /*******************************************************************************
506  *
507  * FUNCTION:    AcpiDmDumpDmar
508  *
509  * PARAMETERS:  Table               - A DMAR table
510  *
511  * RETURN:      None
512  *
513  * DESCRIPTION: Format the contents of a DMAR. This table type consists
514  *              of an open-ended number of subtables.
515  *
516  ******************************************************************************/
517 
518 void
519 AcpiDmDumpDmar (
520     ACPI_TABLE_HEADER       *Table)
521 {
522     ACPI_STATUS             Status;
523     ACPI_DMAR_HEADER        *Subtable;
524     UINT32                  Length = Table->Length;
525     UINT32                  Offset = sizeof (ACPI_TABLE_DMAR);
526     ACPI_DMTABLE_INFO       *InfoTable;
527     ACPI_DMAR_DEVICE_SCOPE  *ScopeTable;
528     UINT32                  ScopeOffset;
529     UINT8                   *PciPath;
530     UINT32                  PathOffset;
531 
532 
533     /* Main table */
534 
535     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoDmar);
536     if (ACPI_FAILURE (Status))
537     {
538         return;
539     }
540 
541     /* Subtables */
542 
543     Subtable = ACPI_ADD_PTR (ACPI_DMAR_HEADER, Table, Offset);
544     while (Offset < Table->Length)
545     {
546         /* Common subtable header */
547 
548         AcpiOsPrintf ("\n");
549         Status = AcpiDmDumpTable (Length, Offset, Subtable,
550             Subtable->Length, AcpiDmTableInfoDmarHdr);
551         if (ACPI_FAILURE (Status))
552         {
553             return;
554         }
555 
556         AcpiOsPrintf ("\n");
557 
558         switch (Subtable->Type)
559         {
560         case ACPI_DMAR_TYPE_HARDWARE_UNIT:
561 
562             InfoTable = AcpiDmTableInfoDmar0;
563             ScopeOffset = sizeof (ACPI_DMAR_HARDWARE_UNIT);
564             break;
565 
566         case ACPI_DMAR_TYPE_RESERVED_MEMORY:
567 
568             InfoTable = AcpiDmTableInfoDmar1;
569             ScopeOffset = sizeof (ACPI_DMAR_RESERVED_MEMORY);
570             break;
571 
572         case ACPI_DMAR_TYPE_ROOT_ATS:
573 
574             InfoTable = AcpiDmTableInfoDmar2;
575             ScopeOffset = sizeof (ACPI_DMAR_ATSR);
576             break;
577 
578         case ACPI_DMAR_TYPE_HARDWARE_AFFINITY:
579 
580             InfoTable = AcpiDmTableInfoDmar3;
581             ScopeOffset = sizeof (ACPI_DMAR_RHSA);
582             break;
583 
584         case ACPI_DMAR_TYPE_NAMESPACE:
585 
586             InfoTable = AcpiDmTableInfoDmar4;
587             ScopeOffset = sizeof (ACPI_DMAR_ANDD);
588             break;
589 
590         default:
591 
592             AcpiOsPrintf ("\n**** Unknown DMAR subtable type 0x%X\n\n",
593                 Subtable->Type);
594             return;
595         }
596 
597         Status = AcpiDmDumpTable (Length, Offset, Subtable,
598             Subtable->Length, InfoTable);
599         if (ACPI_FAILURE (Status))
600         {
601             return;
602         }
603 
604         /*
605          * Dump the optional device scope entries
606          */
607         if ((Subtable->Type == ACPI_DMAR_TYPE_HARDWARE_AFFINITY) ||
608             (Subtable->Type == ACPI_DMAR_TYPE_NAMESPACE))
609         {
610             /* These types do not support device scopes */
611 
612             goto NextSubtable;
613         }
614 
615         ScopeTable = ACPI_ADD_PTR (ACPI_DMAR_DEVICE_SCOPE, Subtable, ScopeOffset);
616         while (ScopeOffset < Subtable->Length)
617         {
618             AcpiOsPrintf ("\n");
619             Status = AcpiDmDumpTable (Length, Offset + ScopeOffset, ScopeTable,
620                 ScopeTable->Length, AcpiDmTableInfoDmarScope);
621             if (ACPI_FAILURE (Status))
622             {
623                 return;
624             }
625             AcpiOsPrintf ("\n");
626 
627             /* Dump the PCI Path entries for this device scope */
628 
629             PathOffset = sizeof (ACPI_DMAR_DEVICE_SCOPE); /* Path entries start at this offset */
630 
631             PciPath = ACPI_ADD_PTR (UINT8, ScopeTable,
632                 sizeof (ACPI_DMAR_DEVICE_SCOPE));
633 
634             while (PathOffset < ScopeTable->Length)
635             {
636                 AcpiDmLineHeader ((PathOffset + ScopeOffset + Offset), 2,
637                     "PCI Path");
638                 AcpiOsPrintf ("%2.2X,%2.2X\n", PciPath[0], PciPath[1]);
639 
640                 /* Point to next PCI Path entry */
641 
642                 PathOffset += 2;
643                 PciPath += 2;
644                 AcpiOsPrintf ("\n");
645             }
646 
647             /* Point to next device scope entry */
648 
649             ScopeOffset += ScopeTable->Length;
650             ScopeTable = ACPI_ADD_PTR (ACPI_DMAR_DEVICE_SCOPE,
651                 ScopeTable, ScopeTable->Length);
652         }
653 
654 NextSubtable:
655         /* Point to next subtable */
656 
657         Offset += Subtable->Length;
658         Subtable = ACPI_ADD_PTR (ACPI_DMAR_HEADER, Subtable,
659             Subtable->Length);
660     }
661 }
662 
663 
664 /*******************************************************************************
665  *
666  * FUNCTION:    AcpiDmDumpDrtm
667  *
668  * PARAMETERS:  Table               - A DRTM table
669  *
670  * RETURN:      None
671  *
672  * DESCRIPTION: Format the contents of a DRTM.
673  *
674  ******************************************************************************/
675 
676 void
677 AcpiDmDumpDrtm (
678     ACPI_TABLE_HEADER       *Table)
679 {
680     ACPI_STATUS             Status;
681     UINT32                  Offset;
682     ACPI_DRTM_VTABLE_LIST   *DrtmVtl;
683     ACPI_DRTM_RESOURCE_LIST *DrtmRl;
684     ACPI_DRTM_DPS_ID        *DrtmDps;
685     UINT32                  Count;
686 
687 
688     /* Main table */
689 
690     Status = AcpiDmDumpTable (Table->Length, 0, Table, 0,
691         AcpiDmTableInfoDrtm);
692     if (ACPI_FAILURE (Status))
693     {
694         return;
695     }
696 
697     Offset = sizeof (ACPI_TABLE_DRTM);
698 
699     /* Sub-tables */
700 
701     /* Dump ValidatedTable length */
702 
703     DrtmVtl = ACPI_ADD_PTR (ACPI_DRTM_VTABLE_LIST, Table, Offset);
704     AcpiOsPrintf ("\n");
705     Status = AcpiDmDumpTable (Table->Length, Offset,
706         DrtmVtl, ACPI_OFFSET (ACPI_DRTM_VTABLE_LIST, ValidatedTables),
707         AcpiDmTableInfoDrtm0);
708     if (ACPI_FAILURE (Status))
709     {
710             return;
711     }
712 
713     Offset += ACPI_OFFSET (ACPI_DRTM_VTABLE_LIST, ValidatedTables);
714 
715     /* Dump Validated table addresses */
716 
717     Count = 0;
718     while ((Offset < Table->Length) &&
719             (DrtmVtl->ValidatedTableCount > Count))
720     {
721         Status = AcpiDmDumpTable (Table->Length, Offset,
722             ACPI_ADD_PTR (void, Table, Offset), sizeof (UINT64),
723             AcpiDmTableInfoDrtm0a);
724         if (ACPI_FAILURE (Status))
725         {
726             return;
727         }
728 
729         Offset += sizeof (UINT64);
730         Count++;
731     }
732 
733     /* Dump ResourceList length */
734 
735     DrtmRl = ACPI_ADD_PTR (ACPI_DRTM_RESOURCE_LIST, Table, Offset);
736     AcpiOsPrintf ("\n");
737     Status = AcpiDmDumpTable (Table->Length, Offset,
738         DrtmRl, ACPI_OFFSET (ACPI_DRTM_RESOURCE_LIST, Resources),
739         AcpiDmTableInfoDrtm1);
740     if (ACPI_FAILURE (Status))
741     {
742         return;
743     }
744 
745     Offset += ACPI_OFFSET (ACPI_DRTM_RESOURCE_LIST, Resources);
746 
747     /* Dump the Resource List */
748 
749     Count = 0;
750     while ((Offset < Table->Length) &&
751            (DrtmRl->ResourceCount > Count))
752     {
753         Status = AcpiDmDumpTable (Table->Length, Offset,
754             ACPI_ADD_PTR (void, Table, Offset),
755             sizeof (ACPI_DRTM_RESOURCE), AcpiDmTableInfoDrtm1a);
756         if (ACPI_FAILURE (Status))
757         {
758             return;
759         }
760 
761         Offset += sizeof (ACPI_DRTM_RESOURCE);
762         Count++;
763     }
764 
765     /* Dump DPS */
766 
767     DrtmDps = ACPI_ADD_PTR (ACPI_DRTM_DPS_ID, Table, Offset);
768     AcpiOsPrintf ("\n");
769     (void) AcpiDmDumpTable (Table->Length, Offset,
770         DrtmDps, sizeof (ACPI_DRTM_DPS_ID), AcpiDmTableInfoDrtm2);
771 }
772 
773 
774 /*******************************************************************************
775  *
776  * FUNCTION:    AcpiDmDumpEinj
777  *
778  * PARAMETERS:  Table               - A EINJ table
779  *
780  * RETURN:      None
781  *
782  * DESCRIPTION: Format the contents of a EINJ. This table type consists
783  *              of an open-ended number of subtables.
784  *
785  ******************************************************************************/
786 
787 void
788 AcpiDmDumpEinj (
789     ACPI_TABLE_HEADER       *Table)
790 {
791     ACPI_STATUS             Status;
792     ACPI_WHEA_HEADER        *Subtable;
793     UINT32                  Length = Table->Length;
794     UINT32                  Offset = sizeof (ACPI_TABLE_EINJ);
795 
796 
797     /* Main table */
798 
799     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoEinj);
800     if (ACPI_FAILURE (Status))
801     {
802         return;
803     }
804 
805     /* Subtables */
806 
807     Subtable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, Table, Offset);
808     while (Offset < Table->Length)
809     {
810         AcpiOsPrintf ("\n");
811         Status = AcpiDmDumpTable (Length, Offset, Subtable,
812             sizeof (ACPI_WHEA_HEADER), AcpiDmTableInfoEinj0);
813         if (ACPI_FAILURE (Status))
814         {
815             return;
816         }
817 
818         /* Point to next subtable (each subtable is of fixed length) */
819 
820         Offset += sizeof (ACPI_WHEA_HEADER);
821         Subtable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, Subtable,
822             sizeof (ACPI_WHEA_HEADER));
823     }
824 }
825 
826 
827 /*******************************************************************************
828  *
829  * FUNCTION:    AcpiDmDumpErst
830  *
831  * PARAMETERS:  Table               - A ERST table
832  *
833  * RETURN:      None
834  *
835  * DESCRIPTION: Format the contents of a ERST. This table type consists
836  *              of an open-ended number of subtables.
837  *
838  ******************************************************************************/
839 
840 void
841 AcpiDmDumpErst (
842     ACPI_TABLE_HEADER       *Table)
843 {
844     ACPI_STATUS             Status;
845     ACPI_WHEA_HEADER        *Subtable;
846     UINT32                  Length = Table->Length;
847     UINT32                  Offset = sizeof (ACPI_TABLE_ERST);
848 
849 
850     /* Main table */
851 
852     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoErst);
853     if (ACPI_FAILURE (Status))
854     {
855         return;
856     }
857 
858     /* Subtables */
859 
860     Subtable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, Table, Offset);
861     while (Offset < Table->Length)
862     {
863         AcpiOsPrintf ("\n");
864         Status = AcpiDmDumpTable (Length, Offset, Subtable,
865             sizeof (ACPI_WHEA_HEADER), AcpiDmTableInfoErst0);
866         if (ACPI_FAILURE (Status))
867         {
868             return;
869         }
870 
871         /* Point to next subtable (each subtable is of fixed length) */
872 
873         Offset += sizeof (ACPI_WHEA_HEADER);
874         Subtable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, Subtable,
875             sizeof (ACPI_WHEA_HEADER));
876     }
877 }
878 
879 
880 /*******************************************************************************
881  *
882  * FUNCTION:    AcpiDmDumpFpdt
883  *
884  * PARAMETERS:  Table               - A FPDT table
885  *
886  * RETURN:      None
887  *
888  * DESCRIPTION: Format the contents of a FPDT. This table type consists
889  *              of an open-ended number of subtables.
890  *
891  ******************************************************************************/
892 
893 void
894 AcpiDmDumpFpdt (
895     ACPI_TABLE_HEADER       *Table)
896 {
897     ACPI_STATUS             Status;
898     ACPI_FPDT_HEADER        *Subtable;
899     UINT32                  Length = Table->Length;
900     UINT32                  Offset = sizeof (ACPI_TABLE_FPDT);
901     ACPI_DMTABLE_INFO       *InfoTable;
902 
903 
904     /* There is no main table (other than the standard ACPI header) */
905 
906     /* Subtables */
907 
908     Subtable = ACPI_ADD_PTR (ACPI_FPDT_HEADER, Table, Offset);
909     while (Offset < Table->Length)
910     {
911         /* Common subtable header */
912 
913         AcpiOsPrintf ("\n");
914         Status = AcpiDmDumpTable (Length, Offset, Subtable,
915             Subtable->Length, AcpiDmTableInfoFpdtHdr);
916         if (ACPI_FAILURE (Status))
917         {
918             return;
919         }
920 
921         switch (Subtable->Type)
922         {
923         case ACPI_FPDT_TYPE_BOOT:
924 
925             InfoTable = AcpiDmTableInfoFpdt0;
926             break;
927 
928         case ACPI_FPDT_TYPE_S3PERF:
929 
930             InfoTable = AcpiDmTableInfoFpdt1;
931             break;
932 
933         default:
934 
935             AcpiOsPrintf ("\n**** Unknown FPDT subtable type 0x%X\n\n",
936                 Subtable->Type);
937 
938             /* Attempt to continue */
939 
940             if (!Subtable->Length)
941             {
942                 AcpiOsPrintf ("Invalid zero length subtable\n");
943                 return;
944             }
945             goto NextSubtable;
946         }
947 
948         Status = AcpiDmDumpTable (Length, Offset, Subtable,
949             Subtable->Length, InfoTable);
950         if (ACPI_FAILURE (Status))
951         {
952             return;
953         }
954 
955 NextSubtable:
956         /* Point to next subtable */
957 
958         Offset += Subtable->Length;
959         Subtable = ACPI_ADD_PTR (ACPI_FPDT_HEADER, Subtable,
960             Subtable->Length);
961     }
962 }
963 
964 
965 /*******************************************************************************
966  *
967  * FUNCTION:    AcpiDmDumpGtdt
968  *
969  * PARAMETERS:  Table               - A GTDT table
970  *
971  * RETURN:      None
972  *
973  * DESCRIPTION: Format the contents of a GTDT. This table type consists
974  *              of an open-ended number of subtables.
975  *
976  ******************************************************************************/
977 
978 void
979 AcpiDmDumpGtdt (
980     ACPI_TABLE_HEADER       *Table)
981 {
982     ACPI_STATUS             Status;
983     ACPI_GTDT_HEADER        *Subtable;
984     UINT32                  Length = Table->Length;
985     UINT32                  Offset = sizeof (ACPI_TABLE_GTDT);
986     ACPI_DMTABLE_INFO       *InfoTable;
987     UINT32                  SubtableLength;
988     UINT32                  GtCount;
989     ACPI_GTDT_TIMER_ENTRY   *GtxTable;
990 
991 
992     /* Main table */
993 
994     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoGtdt);
995     if (ACPI_FAILURE (Status))
996     {
997         return;
998     }
999 
1000     /* Rev 3 fields */
1001 
1002     Subtable = ACPI_ADD_PTR (ACPI_GTDT_HEADER, Table, Offset);
1003 
1004     if (Table->Revision > 2)
1005     {
1006         SubtableLength = sizeof (ACPI_GTDT_EL2);
1007         Status = AcpiDmDumpTable (Length, Offset, Subtable,
1008             SubtableLength, AcpiDmTableInfoGtdtEl2);
1009         if (ACPI_FAILURE (Status))
1010         {
1011             return;
1012         }
1013         Offset += SubtableLength;
1014     }
1015 
1016     Subtable = ACPI_ADD_PTR (ACPI_GTDT_HEADER, Table, Offset);
1017 
1018     /* Subtables */
1019 
1020     while (Offset < Table->Length)
1021     {
1022         /* Common subtable header */
1023 
1024         AcpiOsPrintf ("\n");
1025         Status = AcpiDmDumpTable (Length, Offset, Subtable,
1026             Subtable->Length, AcpiDmTableInfoGtdtHdr);
1027         if (ACPI_FAILURE (Status))
1028         {
1029             return;
1030         }
1031 
1032         GtCount = 0;
1033         switch (Subtable->Type)
1034         {
1035         case ACPI_GTDT_TYPE_TIMER_BLOCK:
1036 
1037             SubtableLength = sizeof (ACPI_GTDT_TIMER_BLOCK);
1038             GtCount = (ACPI_CAST_PTR (ACPI_GTDT_TIMER_BLOCK,
1039                 Subtable))->TimerCount;
1040 
1041             InfoTable = AcpiDmTableInfoGtdt0;
1042             break;
1043 
1044         case ACPI_GTDT_TYPE_WATCHDOG:
1045 
1046             SubtableLength = sizeof (ACPI_GTDT_WATCHDOG);
1047 
1048             InfoTable = AcpiDmTableInfoGtdt1;
1049             break;
1050 
1051         default:
1052 
1053             /* Cannot continue on unknown type - no length */
1054 
1055             AcpiOsPrintf ("\n**** Unknown GTDT subtable type 0x%X\n",
1056                 Subtable->Type);
1057             return;
1058         }
1059 
1060         Status = AcpiDmDumpTable (Length, Offset, Subtable,
1061             Subtable->Length, InfoTable);
1062         if (ACPI_FAILURE (Status))
1063         {
1064             return;
1065         }
1066 
1067         /* Point to end of current subtable (each subtable above is of fixed length) */
1068 
1069         Offset += SubtableLength;
1070 
1071         /* If there are any Gt Timer Blocks from above, dump them now */
1072 
1073         if (GtCount)
1074         {
1075             GtxTable = ACPI_ADD_PTR (
1076                 ACPI_GTDT_TIMER_ENTRY, Subtable, SubtableLength);
1077             SubtableLength += GtCount * sizeof (ACPI_GTDT_TIMER_ENTRY);
1078 
1079             while (GtCount)
1080             {
1081                 AcpiOsPrintf ("\n");
1082                 Status = AcpiDmDumpTable (Length, Offset, GtxTable,
1083                     sizeof (ACPI_GTDT_TIMER_ENTRY), AcpiDmTableInfoGtdt0a);
1084                 if (ACPI_FAILURE (Status))
1085                 {
1086                     return;
1087                 }
1088                 Offset += sizeof (ACPI_GTDT_TIMER_ENTRY);
1089                 GtxTable++;
1090                 GtCount--;
1091             }
1092         }
1093 
1094         /* Point to next subtable */
1095 
1096         Subtable = ACPI_ADD_PTR (ACPI_GTDT_HEADER, Subtable, SubtableLength);
1097     }
1098 }
1099 
1100 
1101 /*******************************************************************************
1102  *
1103  * FUNCTION:    AcpiDmDumpHest
1104  *
1105  * PARAMETERS:  Table               - A HEST table
1106  *
1107  * RETURN:      None
1108  *
1109  * DESCRIPTION: Format the contents of a HEST. This table type consists
1110  *              of an open-ended number of subtables.
1111  *
1112  ******************************************************************************/
1113 
1114 void
1115 AcpiDmDumpHest (
1116     ACPI_TABLE_HEADER       *Table)
1117 {
1118     ACPI_STATUS             Status;
1119     ACPI_HEST_HEADER        *Subtable;
1120     UINT32                  Length = Table->Length;
1121     UINT32                  Offset = sizeof (ACPI_TABLE_HEST);
1122     ACPI_DMTABLE_INFO       *InfoTable;
1123     UINT32                  SubtableLength;
1124     UINT32                  BankCount;
1125     ACPI_HEST_IA_ERROR_BANK *BankTable;
1126 
1127 
1128     /* Main table */
1129 
1130     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoHest);
1131     if (ACPI_FAILURE (Status))
1132     {
1133         return;
1134     }
1135 
1136     /* Subtables */
1137 
1138     Subtable = ACPI_ADD_PTR (ACPI_HEST_HEADER, Table, Offset);
1139     while (Offset < Table->Length)
1140     {
1141         BankCount = 0;
1142         switch (Subtable->Type)
1143         {
1144         case ACPI_HEST_TYPE_IA32_CHECK:
1145 
1146             InfoTable = AcpiDmTableInfoHest0;
1147             SubtableLength = sizeof (ACPI_HEST_IA_MACHINE_CHECK);
1148             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK,
1149                 Subtable))->NumHardwareBanks;
1150             break;
1151 
1152         case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
1153 
1154             InfoTable = AcpiDmTableInfoHest1;
1155             SubtableLength = sizeof (ACPI_HEST_IA_CORRECTED);
1156             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED,
1157                 Subtable))->NumHardwareBanks;
1158             break;
1159 
1160         case ACPI_HEST_TYPE_IA32_NMI:
1161 
1162             InfoTable = AcpiDmTableInfoHest2;
1163             SubtableLength = sizeof (ACPI_HEST_IA_NMI);
1164             break;
1165 
1166         case ACPI_HEST_TYPE_AER_ROOT_PORT:
1167 
1168             InfoTable = AcpiDmTableInfoHest6;
1169             SubtableLength = sizeof (ACPI_HEST_AER_ROOT);
1170             break;
1171 
1172         case ACPI_HEST_TYPE_AER_ENDPOINT:
1173 
1174             InfoTable = AcpiDmTableInfoHest7;
1175             SubtableLength = sizeof (ACPI_HEST_AER);
1176             break;
1177 
1178         case ACPI_HEST_TYPE_AER_BRIDGE:
1179 
1180             InfoTable = AcpiDmTableInfoHest8;
1181             SubtableLength = sizeof (ACPI_HEST_AER_BRIDGE);
1182             break;
1183 
1184         case ACPI_HEST_TYPE_GENERIC_ERROR:
1185 
1186             InfoTable = AcpiDmTableInfoHest9;
1187             SubtableLength = sizeof (ACPI_HEST_GENERIC);
1188             break;
1189 
1190         case ACPI_HEST_TYPE_GENERIC_ERROR_V2:
1191 
1192             InfoTable = AcpiDmTableInfoHest10;
1193             SubtableLength = sizeof (ACPI_HEST_GENERIC_V2);
1194             break;
1195 
1196         case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK:
1197 
1198             InfoTable = AcpiDmTableInfoHest11;
1199             SubtableLength = sizeof (ACPI_HEST_IA_DEFERRED_CHECK);
1200             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_DEFERRED_CHECK,
1201                 Subtable))->NumHardwareBanks;
1202             break;
1203 
1204         default:
1205 
1206             /* Cannot continue on unknown type - no length */
1207 
1208             AcpiOsPrintf ("\n**** Unknown HEST subtable type 0x%X\n",
1209                 Subtable->Type);
1210             return;
1211         }
1212 
1213         AcpiOsPrintf ("\n");
1214         Status = AcpiDmDumpTable (Length, Offset, Subtable,
1215             SubtableLength, InfoTable);
1216         if (ACPI_FAILURE (Status))
1217         {
1218             return;
1219         }
1220 
1221         /* Point to end of current subtable (each subtable above is of fixed length) */
1222 
1223         Offset += SubtableLength;
1224 
1225         /* If there are any (fixed-length) Error Banks from above, dump them now */
1226 
1227         if (BankCount)
1228         {
1229             BankTable = ACPI_ADD_PTR (ACPI_HEST_IA_ERROR_BANK, Subtable,
1230                 SubtableLength);
1231             SubtableLength += BankCount * sizeof (ACPI_HEST_IA_ERROR_BANK);
1232 
1233             while (BankCount)
1234             {
1235                 AcpiOsPrintf ("\n");
1236                 Status = AcpiDmDumpTable (Length, Offset, BankTable,
1237                     sizeof (ACPI_HEST_IA_ERROR_BANK), AcpiDmTableInfoHestBank);
1238                 if (ACPI_FAILURE (Status))
1239                 {
1240                     return;
1241                 }
1242 
1243                 Offset += sizeof (ACPI_HEST_IA_ERROR_BANK);
1244                 BankTable++;
1245                 BankCount--;
1246             }
1247         }
1248 
1249         /* Point to next subtable */
1250 
1251         Subtable = ACPI_ADD_PTR (ACPI_HEST_HEADER, Subtable, SubtableLength);
1252     }
1253 }
1254 
1255 
1256 /*******************************************************************************
1257  *
1258  * FUNCTION:    AcpiDmDumpHmat
1259  *
1260  * PARAMETERS:  Table               - A HMAT table
1261  *
1262  * RETURN:      None
1263  *
1264  * DESCRIPTION: Format the contents of a HMAT.
1265  *
1266  ******************************************************************************/
1267 
1268 void
1269 AcpiDmDumpHmat (
1270     ACPI_TABLE_HEADER       *Table)
1271 {
1272     ACPI_STATUS             Status;
1273     ACPI_HMAT_STRUCTURE     *HmatStruct;
1274     ACPI_HMAT_LOCALITY      *HmatLocality;
1275     ACPI_HMAT_CACHE         *HmatCache;
1276     UINT32                  Offset;
1277     UINT32                  SubtableOffset;
1278     UINT32                  Length;
1279     ACPI_DMTABLE_INFO       *InfoTable;
1280     UINT32                  i, j;
1281 
1282 
1283     /* Main table */
1284 
1285     Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoHmat);
1286     if (ACPI_FAILURE (Status))
1287     {
1288         return;
1289     }
1290     Offset = sizeof (ACPI_TABLE_HMAT);
1291 
1292     while (Offset < Table->Length)
1293     {
1294         AcpiOsPrintf ("\n");
1295 
1296         /* Dump HMAT structure header */
1297 
1298         HmatStruct = ACPI_ADD_PTR (ACPI_HMAT_STRUCTURE, Table, Offset);
1299         if (HmatStruct->Length < sizeof (ACPI_HMAT_STRUCTURE))
1300         {
1301             AcpiOsPrintf ("Invalid HMAT structure length\n");
1302             return;
1303         }
1304         Status = AcpiDmDumpTable (Table->Length, Offset, HmatStruct,
1305             HmatStruct->Length, AcpiDmTableInfoHmatHdr);
1306         if (ACPI_FAILURE (Status))
1307         {
1308             return;
1309         }
1310 
1311         switch (HmatStruct->Type)
1312         {
1313         case ACPI_HMAT_TYPE_ADDRESS_RANGE:
1314 
1315             InfoTable = AcpiDmTableInfoHmat0;
1316             Length = sizeof (ACPI_HMAT_PROXIMITY_DOMAIN);
1317             break;
1318 
1319         case ACPI_HMAT_TYPE_LOCALITY:
1320 
1321             InfoTable = AcpiDmTableInfoHmat1;
1322             Length = sizeof (ACPI_HMAT_LOCALITY);
1323             break;
1324 
1325         case ACPI_HMAT_TYPE_CACHE:
1326 
1327             InfoTable = AcpiDmTableInfoHmat2;
1328             Length = sizeof (ACPI_HMAT_CACHE);
1329             break;
1330 
1331         default:
1332 
1333             AcpiOsPrintf ("\n**** Unknown HMAT structure type 0x%X\n",
1334                 HmatStruct->Type);
1335 
1336             /* Attempt to continue */
1337 
1338             goto NextSubtable;
1339         }
1340 
1341         /* Dump HMAT structure body */
1342 
1343         if (HmatStruct->Length < Length)
1344         {
1345             AcpiOsPrintf ("Invalid HMAT structure length\n");
1346             return;
1347         }
1348         Status = AcpiDmDumpTable (Table->Length, Offset, HmatStruct,
1349             HmatStruct->Length, InfoTable);
1350         if (ACPI_FAILURE (Status))
1351         {
1352             return;
1353         }
1354 
1355         /* Dump HMAT structure additionals */
1356 
1357         switch (HmatStruct->Type)
1358         {
1359         case ACPI_HMAT_TYPE_LOCALITY:
1360 
1361             HmatLocality = ACPI_CAST_PTR (ACPI_HMAT_LOCALITY, HmatStruct);
1362             SubtableOffset = sizeof (ACPI_HMAT_LOCALITY);
1363 
1364             /* Dump initiator proximity domains */
1365 
1366             if ((UINT32)(HmatStruct->Length - SubtableOffset) <
1367                 (UINT32)(HmatLocality->NumberOfInitiatorPDs * 4))
1368             {
1369                 AcpiOsPrintf ("Invalid initiator proximity domain number\n");
1370                 return;
1371             }
1372             for (i = 0; i < HmatLocality->NumberOfInitiatorPDs; i++)
1373             {
1374                 Status = AcpiDmDumpTable (Table->Length, Offset + SubtableOffset,
1375                     ACPI_ADD_PTR (ACPI_HMAT_STRUCTURE, HmatStruct, SubtableOffset),
1376                     4, AcpiDmTableInfoHmat1a);
1377                 if (ACPI_FAILURE (Status))
1378                 {
1379                     return;
1380                 }
1381 
1382                 SubtableOffset += 4;
1383             }
1384 
1385             /* Dump target proximity domains */
1386 
1387             if ((UINT32)(HmatStruct->Length - SubtableOffset) <
1388                 (UINT32)(HmatLocality->NumberOfTargetPDs * 4))
1389             {
1390                 AcpiOsPrintf ("Invalid target proximity domain number\n");
1391                 return;
1392             }
1393             for (i = 0; i < HmatLocality->NumberOfTargetPDs; i++)
1394             {
1395                 Status = AcpiDmDumpTable (Table->Length, Offset + SubtableOffset,
1396                     ACPI_ADD_PTR (ACPI_HMAT_STRUCTURE, HmatStruct, SubtableOffset),
1397                     4, AcpiDmTableInfoHmat1b);
1398                 if (ACPI_FAILURE (Status))
1399                 {
1400                     return;
1401                 }
1402 
1403                 SubtableOffset += 4;
1404             }
1405 
1406             /* Dump latency/bandwidth entris */
1407 
1408             if ((UINT32)(HmatStruct->Length - SubtableOffset) <
1409                 (UINT32)(HmatLocality->NumberOfInitiatorPDs *
1410                          HmatLocality->NumberOfTargetPDs * 2))
1411             {
1412                 AcpiOsPrintf ("Invalid latency/bandwidth entry number\n");
1413                 return;
1414             }
1415             for (i = 0; i < HmatLocality->NumberOfInitiatorPDs; i++)
1416             {
1417                 for (j = 0; j < HmatLocality->NumberOfTargetPDs; j++)
1418                 {
1419                     Status = AcpiDmDumpTable (Table->Length, Offset + SubtableOffset,
1420                         ACPI_ADD_PTR (ACPI_HMAT_STRUCTURE, HmatStruct, SubtableOffset),
1421                         2, AcpiDmTableInfoHmat1c);
1422                     if (ACPI_FAILURE(Status))
1423                     {
1424                         return;
1425                     }
1426 
1427                     SubtableOffset += 2;
1428                 }
1429             }
1430             break;
1431 
1432         case ACPI_HMAT_TYPE_CACHE:
1433 
1434             HmatCache = ACPI_CAST_PTR (ACPI_HMAT_CACHE, HmatStruct);
1435             SubtableOffset = sizeof (ACPI_HMAT_CACHE);
1436 
1437             /* Dump SMBIOS handles */
1438 
1439             if ((UINT32)(HmatStruct->Length - SubtableOffset) <
1440                 (UINT32)(HmatCache->NumberOfSMBIOSHandles * 2))
1441             {
1442                 AcpiOsPrintf ("Invalid SMBIOS handle number\n");
1443                 return;
1444             }
1445             for (i = 0; i < HmatCache->NumberOfSMBIOSHandles; i++)
1446             {
1447                 Status = AcpiDmDumpTable (Table->Length, Offset + SubtableOffset,
1448                     ACPI_ADD_PTR (ACPI_HMAT_STRUCTURE, HmatStruct, SubtableOffset),
1449                     2, AcpiDmTableInfoHmat2a);
1450                 if (ACPI_FAILURE (Status))
1451                 {
1452                     return;
1453                 }
1454 
1455                 SubtableOffset += 2;
1456             }
1457             break;
1458 
1459         default:
1460 
1461             break;
1462         }
1463 
1464 NextSubtable:
1465         /* Point to next HMAT structure subtable */
1466 
1467         Offset += (HmatStruct->Length);
1468     }
1469 }
1470