xref: /netbsd-src/sys/external/bsd/acpica/dist/common/dmtbdump1.c (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
1 /******************************************************************************
2  *
3  * Module Name: dmtbdump1 - 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    ("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                 SubSubOffset += InfoLength;
370             }
371 
372             /* Point to next sub-subtable */
373 
374             SubOffset += SubSubtable->Length;
375             SubSubtable = ACPI_ADD_PTR (ACPI_CSRT_DESCRIPTOR, SubSubtable,
376                 SubSubtable->Length);
377         }
378 
379         /* Point to next subtable */
380 
381         Offset += Subtable->Length;
382         Subtable = ACPI_ADD_PTR (ACPI_CSRT_GROUP, Subtable,
383             Subtable->Length);
384     }
385 }
386 
387 
388 /*******************************************************************************
389  *
390  * FUNCTION:    AcpiDmDumpDbg2
391  *
392  * PARAMETERS:  Table               - A DBG2 table
393  *
394  * RETURN:      None
395  *
396  * DESCRIPTION: Format the contents of a DBG2. This table type consists
397  *              of an open-ended number of subtables.
398  *
399  ******************************************************************************/
400 
401 void
402 AcpiDmDumpDbg2 (
403     ACPI_TABLE_HEADER       *Table)
404 {
405     ACPI_STATUS             Status;
406     ACPI_DBG2_DEVICE        *Subtable;
407     UINT32                  Length = Table->Length;
408     UINT32                  Offset = sizeof (ACPI_TABLE_DBG2);
409     UINT32                  i;
410     UINT32                  ArrayOffset;
411     UINT32                  AbsoluteOffset;
412     UINT8                   *Array;
413 
414 
415     /* Main table */
416 
417     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoDbg2);
418     if (ACPI_FAILURE (Status))
419     {
420         return;
421     }
422 
423     /* Subtables */
424 
425     Subtable = ACPI_ADD_PTR (ACPI_DBG2_DEVICE, Table, Offset);
426     while (Offset < Table->Length)
427     {
428         AcpiOsPrintf ("\n");
429         Status = AcpiDmDumpTable (Length, Offset, Subtable,
430             Subtable->Length, AcpiDmTableInfoDbg2Device);
431         if (ACPI_FAILURE (Status))
432         {
433             return;
434         }
435 
436         /* Dump the BaseAddress array */
437 
438         for (i = 0; i < Subtable->RegisterCount; i++)
439         {
440             ArrayOffset = Subtable->BaseAddressOffset +
441                 (sizeof (ACPI_GENERIC_ADDRESS) * i);
442             AbsoluteOffset = Offset + ArrayOffset;
443             Array = (UINT8 *) Subtable + ArrayOffset;
444 
445             Status = AcpiDmDumpTable (Length, AbsoluteOffset, Array,
446                 Subtable->Length, AcpiDmTableInfoDbg2Addr);
447             if (ACPI_FAILURE (Status))
448             {
449                 return;
450             }
451         }
452 
453         /* Dump the AddressSize array */
454 
455         for (i = 0; i < Subtable->RegisterCount; i++)
456         {
457             ArrayOffset = Subtable->AddressSizeOffset +
458                 (sizeof (UINT32) * i);
459             AbsoluteOffset = Offset + ArrayOffset;
460             Array = (UINT8 *) Subtable + ArrayOffset;
461 
462             Status = AcpiDmDumpTable (Length, AbsoluteOffset, Array,
463                 Subtable->Length, AcpiDmTableInfoDbg2Size);
464             if (ACPI_FAILURE (Status))
465             {
466                 return;
467             }
468         }
469 
470         /* Dump the Namestring (required) */
471 
472         AcpiOsPrintf ("\n");
473         ArrayOffset = Subtable->NamepathOffset;
474         AbsoluteOffset = Offset + ArrayOffset;
475         Array = (UINT8 *) Subtable + ArrayOffset;
476 
477         Status = AcpiDmDumpTable (Length, AbsoluteOffset, Array,
478             Subtable->Length, AcpiDmTableInfoDbg2Name);
479         if (ACPI_FAILURE (Status))
480         {
481             return;
482         }
483 
484         /* Dump the OemData (optional) */
485 
486         if (Subtable->OemDataOffset)
487         {
488             Status = AcpiDmDumpTable (Length, Offset + Subtable->OemDataOffset,
489                 Table, Subtable->OemDataLength,
490                 AcpiDmTableInfoDbg2OemData);
491             if (ACPI_FAILURE (Status))
492             {
493                 return;
494             }
495         }
496 
497         /* Point to next subtable */
498 
499         Offset += Subtable->Length;
500         Subtable = ACPI_ADD_PTR (ACPI_DBG2_DEVICE, Subtable,
501             Subtable->Length);
502     }
503 }
504 
505 
506 /*******************************************************************************
507  *
508  * FUNCTION:    AcpiDmDumpDmar
509  *
510  * PARAMETERS:  Table               - A DMAR table
511  *
512  * RETURN:      None
513  *
514  * DESCRIPTION: Format the contents of a DMAR. This table type consists
515  *              of an open-ended number of subtables.
516  *
517  ******************************************************************************/
518 
519 void
520 AcpiDmDumpDmar (
521     ACPI_TABLE_HEADER       *Table)
522 {
523     ACPI_STATUS             Status;
524     ACPI_DMAR_HEADER        *Subtable;
525     UINT32                  Length = Table->Length;
526     UINT32                  Offset = sizeof (ACPI_TABLE_DMAR);
527     ACPI_DMTABLE_INFO       *InfoTable;
528     ACPI_DMAR_DEVICE_SCOPE  *ScopeTable;
529     UINT32                  ScopeOffset;
530     UINT8                   *PciPath;
531     UINT32                  PathOffset;
532 
533 
534     /* Main table */
535 
536     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoDmar);
537     if (ACPI_FAILURE (Status))
538     {
539         return;
540     }
541 
542     /* Subtables */
543 
544     Subtable = ACPI_ADD_PTR (ACPI_DMAR_HEADER, Table, Offset);
545     while (Offset < Table->Length)
546     {
547         /* Common subtable header */
548 
549         AcpiOsPrintf ("\n");
550         Status = AcpiDmDumpTable (Length, Offset, Subtable,
551             Subtable->Length, AcpiDmTableInfoDmarHdr);
552         if (ACPI_FAILURE (Status))
553         {
554             return;
555         }
556 
557         AcpiOsPrintf ("\n");
558 
559         switch (Subtable->Type)
560         {
561         case ACPI_DMAR_TYPE_HARDWARE_UNIT:
562 
563             InfoTable = AcpiDmTableInfoDmar0;
564             ScopeOffset = sizeof (ACPI_DMAR_HARDWARE_UNIT);
565             break;
566 
567         case ACPI_DMAR_TYPE_RESERVED_MEMORY:
568 
569             InfoTable = AcpiDmTableInfoDmar1;
570             ScopeOffset = sizeof (ACPI_DMAR_RESERVED_MEMORY);
571             break;
572 
573         case ACPI_DMAR_TYPE_ROOT_ATS:
574 
575             InfoTable = AcpiDmTableInfoDmar2;
576             ScopeOffset = sizeof (ACPI_DMAR_ATSR);
577             break;
578 
579         case ACPI_DMAR_TYPE_HARDWARE_AFFINITY:
580 
581             InfoTable = AcpiDmTableInfoDmar3;
582             ScopeOffset = sizeof (ACPI_DMAR_RHSA);
583             break;
584 
585         case ACPI_DMAR_TYPE_NAMESPACE:
586 
587             InfoTable = AcpiDmTableInfoDmar4;
588             ScopeOffset = sizeof (ACPI_DMAR_ANDD);
589             break;
590 
591         default:
592 
593             AcpiOsPrintf ("\n**** Unknown DMAR subtable type 0x%X\n\n",
594                 Subtable->Type);
595             return;
596         }
597 
598         Status = AcpiDmDumpTable (Length, Offset, Subtable,
599             Subtable->Length, InfoTable);
600         if (ACPI_FAILURE (Status))
601         {
602             return;
603         }
604 
605         /*
606          * Dump the optional device scope entries
607          */
608         if ((Subtable->Type == ACPI_DMAR_TYPE_HARDWARE_AFFINITY) ||
609             (Subtable->Type == ACPI_DMAR_TYPE_NAMESPACE))
610         {
611             /* These types do not support device scopes */
612 
613             goto NextSubtable;
614         }
615 
616         ScopeTable = ACPI_ADD_PTR (ACPI_DMAR_DEVICE_SCOPE, Subtable, ScopeOffset);
617         while (ScopeOffset < Subtable->Length)
618         {
619             AcpiOsPrintf ("\n");
620             Status = AcpiDmDumpTable (Length, Offset + ScopeOffset, ScopeTable,
621                 ScopeTable->Length, AcpiDmTableInfoDmarScope);
622             if (ACPI_FAILURE (Status))
623             {
624                 return;
625             }
626             AcpiOsPrintf ("\n");
627 
628             /* Dump the PCI Path entries for this device scope */
629 
630             PathOffset = sizeof (ACPI_DMAR_DEVICE_SCOPE); /* Path entries start at this offset */
631 
632             PciPath = ACPI_ADD_PTR (UINT8, ScopeTable,
633                 sizeof (ACPI_DMAR_DEVICE_SCOPE));
634 
635             while (PathOffset < ScopeTable->Length)
636             {
637                 AcpiDmLineHeader ((PathOffset + ScopeOffset + Offset), 2,
638                     "PCI Path");
639                 AcpiOsPrintf ("%2.2X,%2.2X\n", PciPath[0], PciPath[1]);
640 
641                 /* Point to next PCI Path entry */
642 
643                 PathOffset += 2;
644                 PciPath += 2;
645                 AcpiOsPrintf ("\n");
646             }
647 
648             /* Point to next device scope entry */
649 
650             ScopeOffset += ScopeTable->Length;
651             ScopeTable = ACPI_ADD_PTR (ACPI_DMAR_DEVICE_SCOPE,
652                 ScopeTable, ScopeTable->Length);
653         }
654 
655 NextSubtable:
656         /* Point to next subtable */
657 
658         Offset += Subtable->Length;
659         Subtable = ACPI_ADD_PTR (ACPI_DMAR_HEADER, Subtable,
660             Subtable->Length);
661     }
662 }
663 
664 
665 /*******************************************************************************
666  *
667  * FUNCTION:    AcpiDmDumpDrtm
668  *
669  * PARAMETERS:  Table               - A DRTM table
670  *
671  * RETURN:      None
672  *
673  * DESCRIPTION: Format the contents of a DRTM.
674  *
675  ******************************************************************************/
676 
677 void
678 AcpiDmDumpDrtm (
679     ACPI_TABLE_HEADER       *Table)
680 {
681     ACPI_STATUS             Status;
682     UINT32                  Offset;
683     ACPI_DRTM_VTABLE_LIST   *DrtmVtl;
684     ACPI_DRTM_RESOURCE_LIST *DrtmRl;
685     ACPI_DRTM_DPS_ID        *DrtmDps;
686     UINT32                  Count;
687 
688 
689     /* Main table */
690 
691     Status = AcpiDmDumpTable (Table->Length, 0, Table, 0,
692         AcpiDmTableInfoDrtm);
693     if (ACPI_FAILURE (Status))
694     {
695         return;
696     }
697 
698     Offset = sizeof (ACPI_TABLE_DRTM);
699 
700     /* Sub-tables */
701 
702     /* Dump ValidatedTable length */
703 
704     DrtmVtl = ACPI_ADD_PTR (ACPI_DRTM_VTABLE_LIST, Table, Offset);
705     AcpiOsPrintf ("\n");
706     Status = AcpiDmDumpTable (Table->Length, Offset,
707         DrtmVtl, ACPI_OFFSET (ACPI_DRTM_VTABLE_LIST, ValidatedTables),
708         AcpiDmTableInfoDrtm0);
709     if (ACPI_FAILURE (Status))
710     {
711             return;
712     }
713 
714     Offset += ACPI_OFFSET (ACPI_DRTM_VTABLE_LIST, ValidatedTables);
715 
716     /* Dump Validated table addresses */
717 
718     Count = 0;
719     while ((Offset < Table->Length) &&
720             (DrtmVtl->ValidatedTableCount > Count))
721     {
722         Status = AcpiDmDumpTable (Table->Length, Offset,
723             ACPI_ADD_PTR (void, Table, Offset), sizeof (UINT64),
724             AcpiDmTableInfoDrtm0a);
725         if (ACPI_FAILURE (Status))
726         {
727             return;
728         }
729 
730         Offset += sizeof (UINT64);
731         Count++;
732     }
733 
734     /* Dump ResourceList length */
735 
736     DrtmRl = ACPI_ADD_PTR (ACPI_DRTM_RESOURCE_LIST, Table, Offset);
737     AcpiOsPrintf ("\n");
738     Status = AcpiDmDumpTable (Table->Length, Offset,
739         DrtmRl, ACPI_OFFSET (ACPI_DRTM_RESOURCE_LIST, Resources),
740         AcpiDmTableInfoDrtm1);
741     if (ACPI_FAILURE (Status))
742     {
743         return;
744     }
745 
746     Offset += ACPI_OFFSET (ACPI_DRTM_RESOURCE_LIST, Resources);
747 
748     /* Dump the Resource List */
749 
750     Count = 0;
751     while ((Offset < Table->Length) &&
752            (DrtmRl->ResourceCount > Count))
753     {
754         Status = AcpiDmDumpTable (Table->Length, Offset,
755             ACPI_ADD_PTR (void, Table, Offset),
756             sizeof (ACPI_DRTM_RESOURCE), AcpiDmTableInfoDrtm1a);
757         if (ACPI_FAILURE (Status))
758         {
759             return;
760         }
761 
762         Offset += sizeof (ACPI_DRTM_RESOURCE);
763         Count++;
764     }
765 
766     /* Dump DPS */
767 
768     DrtmDps = ACPI_ADD_PTR (ACPI_DRTM_DPS_ID, Table, Offset);
769     AcpiOsPrintf ("\n");
770     (void) AcpiDmDumpTable (Table->Length, Offset,
771         DrtmDps, sizeof (ACPI_DRTM_DPS_ID), AcpiDmTableInfoDrtm2);
772 }
773 
774 
775 /*******************************************************************************
776  *
777  * FUNCTION:    AcpiDmDumpEinj
778  *
779  * PARAMETERS:  Table               - A EINJ table
780  *
781  * RETURN:      None
782  *
783  * DESCRIPTION: Format the contents of a EINJ. This table type consists
784  *              of an open-ended number of subtables.
785  *
786  ******************************************************************************/
787 
788 void
789 AcpiDmDumpEinj (
790     ACPI_TABLE_HEADER       *Table)
791 {
792     ACPI_STATUS             Status;
793     ACPI_WHEA_HEADER        *Subtable;
794     UINT32                  Length = Table->Length;
795     UINT32                  Offset = sizeof (ACPI_TABLE_EINJ);
796 
797 
798     /* Main table */
799 
800     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoEinj);
801     if (ACPI_FAILURE (Status))
802     {
803         return;
804     }
805 
806     /* Subtables */
807 
808     Subtable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, Table, Offset);
809     while (Offset < Table->Length)
810     {
811         AcpiOsPrintf ("\n");
812         Status = AcpiDmDumpTable (Length, Offset, Subtable,
813             sizeof (ACPI_WHEA_HEADER), AcpiDmTableInfoEinj0);
814         if (ACPI_FAILURE (Status))
815         {
816             return;
817         }
818 
819         /* Point to next subtable (each subtable is of fixed length) */
820 
821         Offset += sizeof (ACPI_WHEA_HEADER);
822         Subtable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, Subtable,
823             sizeof (ACPI_WHEA_HEADER));
824     }
825 }
826 
827 
828 /*******************************************************************************
829  *
830  * FUNCTION:    AcpiDmDumpErst
831  *
832  * PARAMETERS:  Table               - A ERST table
833  *
834  * RETURN:      None
835  *
836  * DESCRIPTION: Format the contents of a ERST. This table type consists
837  *              of an open-ended number of subtables.
838  *
839  ******************************************************************************/
840 
841 void
842 AcpiDmDumpErst (
843     ACPI_TABLE_HEADER       *Table)
844 {
845     ACPI_STATUS             Status;
846     ACPI_WHEA_HEADER        *Subtable;
847     UINT32                  Length = Table->Length;
848     UINT32                  Offset = sizeof (ACPI_TABLE_ERST);
849 
850 
851     /* Main table */
852 
853     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoErst);
854     if (ACPI_FAILURE (Status))
855     {
856         return;
857     }
858 
859     /* Subtables */
860 
861     Subtable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, Table, Offset);
862     while (Offset < Table->Length)
863     {
864         AcpiOsPrintf ("\n");
865         Status = AcpiDmDumpTable (Length, Offset, Subtable,
866             sizeof (ACPI_WHEA_HEADER), AcpiDmTableInfoErst0);
867         if (ACPI_FAILURE (Status))
868         {
869             return;
870         }
871 
872         /* Point to next subtable (each subtable is of fixed length) */
873 
874         Offset += sizeof (ACPI_WHEA_HEADER);
875         Subtable = ACPI_ADD_PTR (ACPI_WHEA_HEADER, Subtable,
876             sizeof (ACPI_WHEA_HEADER));
877     }
878 }
879 
880 
881 /*******************************************************************************
882  *
883  * FUNCTION:    AcpiDmDumpFpdt
884  *
885  * PARAMETERS:  Table               - A FPDT table
886  *
887  * RETURN:      None
888  *
889  * DESCRIPTION: Format the contents of a FPDT. This table type consists
890  *              of an open-ended number of subtables.
891  *
892  ******************************************************************************/
893 
894 void
895 AcpiDmDumpFpdt (
896     ACPI_TABLE_HEADER       *Table)
897 {
898     ACPI_STATUS             Status;
899     ACPI_FPDT_HEADER        *Subtable;
900     UINT32                  Length = Table->Length;
901     UINT32                  Offset = sizeof (ACPI_TABLE_FPDT);
902     ACPI_DMTABLE_INFO       *InfoTable;
903 
904 
905     /* There is no main table (other than the standard ACPI header) */
906 
907     /* Subtables */
908 
909     Subtable = ACPI_ADD_PTR (ACPI_FPDT_HEADER, Table, Offset);
910     while (Offset < Table->Length)
911     {
912         /* Common subtable header */
913 
914         AcpiOsPrintf ("\n");
915         Status = AcpiDmDumpTable (Length, Offset, Subtable,
916             Subtable->Length, AcpiDmTableInfoFpdtHdr);
917         if (ACPI_FAILURE (Status))
918         {
919             return;
920         }
921 
922         switch (Subtable->Type)
923         {
924         case ACPI_FPDT_TYPE_BOOT:
925 
926             InfoTable = AcpiDmTableInfoFpdt0;
927             break;
928 
929         case ACPI_FPDT_TYPE_S3PERF:
930 
931             InfoTable = AcpiDmTableInfoFpdt1;
932             break;
933 
934         default:
935 
936             AcpiOsPrintf ("\n**** Unknown FPDT subtable type 0x%X\n\n",
937                 Subtable->Type);
938 
939             /* Attempt to continue */
940 
941             if (!Subtable->Length)
942             {
943                 AcpiOsPrintf ("Invalid zero length subtable\n");
944                 return;
945             }
946             goto NextSubtable;
947         }
948 
949         Status = AcpiDmDumpTable (Length, Offset, Subtable,
950             Subtable->Length, InfoTable);
951         if (ACPI_FAILURE (Status))
952         {
953             return;
954         }
955 
956 NextSubtable:
957         /* Point to next subtable */
958 
959         Offset += Subtable->Length;
960         Subtable = ACPI_ADD_PTR (ACPI_FPDT_HEADER, Subtable,
961             Subtable->Length);
962     }
963 }
964 
965 
966 /*******************************************************************************
967  *
968  * FUNCTION:    AcpiDmDumpGtdt
969  *
970  * PARAMETERS:  Table               - A GTDT table
971  *
972  * RETURN:      None
973  *
974  * DESCRIPTION: Format the contents of a GTDT. This table type consists
975  *              of an open-ended number of subtables.
976  *
977  ******************************************************************************/
978 
979 void
980 AcpiDmDumpGtdt (
981     ACPI_TABLE_HEADER       *Table)
982 {
983     ACPI_STATUS             Status;
984     ACPI_GTDT_HEADER        *Subtable;
985     UINT32                  Length = Table->Length;
986     UINT32                  Offset = sizeof (ACPI_TABLE_GTDT);
987     ACPI_DMTABLE_INFO       *InfoTable;
988     UINT32                  SubtableLength;
989     UINT32                  GtCount;
990     ACPI_GTDT_TIMER_ENTRY   *GtxTable;
991 
992 
993     /* Main table */
994 
995     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoGtdt);
996     if (ACPI_FAILURE (Status))
997     {
998         return;
999     }
1000 
1001     /* Subtables */
1002 
1003     Subtable = ACPI_ADD_PTR (ACPI_GTDT_HEADER, Table, Offset);
1004     while (Offset < Table->Length)
1005     {
1006         /* Common subtable header */
1007 
1008         AcpiOsPrintf ("\n");
1009         Status = AcpiDmDumpTable (Length, Offset, Subtable,
1010             Subtable->Length, AcpiDmTableInfoGtdtHdr);
1011         if (ACPI_FAILURE (Status))
1012         {
1013             return;
1014         }
1015 
1016         GtCount = 0;
1017         switch (Subtable->Type)
1018         {
1019         case ACPI_GTDT_TYPE_TIMER_BLOCK:
1020 
1021             SubtableLength = sizeof (ACPI_GTDT_TIMER_BLOCK);
1022             GtCount = (ACPI_CAST_PTR (ACPI_GTDT_TIMER_BLOCK,
1023                 Subtable))->TimerCount;
1024 
1025             InfoTable = AcpiDmTableInfoGtdt0;
1026             break;
1027 
1028         case ACPI_GTDT_TYPE_WATCHDOG:
1029 
1030             SubtableLength = sizeof (ACPI_GTDT_WATCHDOG);
1031 
1032             InfoTable = AcpiDmTableInfoGtdt1;
1033             break;
1034 
1035         default:
1036 
1037             /* Cannot continue on unknown type - no length */
1038 
1039             AcpiOsPrintf ("\n**** Unknown GTDT subtable type 0x%X\n",
1040                 Subtable->Type);
1041             return;
1042         }
1043 
1044         Status = AcpiDmDumpTable (Length, Offset, Subtable,
1045             Subtable->Length, InfoTable);
1046         if (ACPI_FAILURE (Status))
1047         {
1048             return;
1049         }
1050 
1051         /* Point to end of current subtable (each subtable above is of fixed length) */
1052 
1053         Offset += SubtableLength;
1054 
1055         /* If there are any Gt Timer Blocks from above, dump them now */
1056 
1057         if (GtCount)
1058         {
1059             GtxTable = ACPI_ADD_PTR (
1060                 ACPI_GTDT_TIMER_ENTRY, Subtable, SubtableLength);
1061             SubtableLength += GtCount * sizeof (ACPI_GTDT_TIMER_ENTRY);
1062 
1063             while (GtCount)
1064             {
1065                 AcpiOsPrintf ("\n");
1066                 Status = AcpiDmDumpTable (Length, Offset, GtxTable,
1067                     sizeof (ACPI_GTDT_TIMER_ENTRY), AcpiDmTableInfoGtdt0a);
1068                 if (ACPI_FAILURE (Status))
1069                 {
1070                     return;
1071                 }
1072                 Offset += sizeof (ACPI_GTDT_TIMER_ENTRY);
1073                 GtxTable++;
1074                 GtCount--;
1075             }
1076         }
1077 
1078         /* Point to next subtable */
1079 
1080         Subtable = ACPI_ADD_PTR (ACPI_GTDT_HEADER, Subtable, SubtableLength);
1081     }
1082 }
1083 
1084 
1085 /*******************************************************************************
1086  *
1087  * FUNCTION:    AcpiDmDumpHest
1088  *
1089  * PARAMETERS:  Table               - A HEST table
1090  *
1091  * RETURN:      None
1092  *
1093  * DESCRIPTION: Format the contents of a HEST. This table type consists
1094  *              of an open-ended number of subtables.
1095  *
1096  ******************************************************************************/
1097 
1098 void
1099 AcpiDmDumpHest (
1100     ACPI_TABLE_HEADER       *Table)
1101 {
1102     ACPI_STATUS             Status;
1103     ACPI_HEST_HEADER        *Subtable;
1104     UINT32                  Length = Table->Length;
1105     UINT32                  Offset = sizeof (ACPI_TABLE_HEST);
1106     ACPI_DMTABLE_INFO       *InfoTable;
1107     UINT32                  SubtableLength;
1108     UINT32                  BankCount;
1109     ACPI_HEST_IA_ERROR_BANK *BankTable;
1110 
1111 
1112     /* Main table */
1113 
1114     Status = AcpiDmDumpTable (Length, 0, Table, 0, AcpiDmTableInfoHest);
1115     if (ACPI_FAILURE (Status))
1116     {
1117         return;
1118     }
1119 
1120     /* Subtables */
1121 
1122     Subtable = ACPI_ADD_PTR (ACPI_HEST_HEADER, Table, Offset);
1123     while (Offset < Table->Length)
1124     {
1125         BankCount = 0;
1126         switch (Subtable->Type)
1127         {
1128         case ACPI_HEST_TYPE_IA32_CHECK:
1129 
1130             InfoTable = AcpiDmTableInfoHest0;
1131             SubtableLength = sizeof (ACPI_HEST_IA_MACHINE_CHECK);
1132             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_MACHINE_CHECK,
1133                 Subtable))->NumHardwareBanks;
1134             break;
1135 
1136         case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
1137 
1138             InfoTable = AcpiDmTableInfoHest1;
1139             SubtableLength = sizeof (ACPI_HEST_IA_CORRECTED);
1140             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_CORRECTED,
1141                 Subtable))->NumHardwareBanks;
1142             break;
1143 
1144         case ACPI_HEST_TYPE_IA32_NMI:
1145 
1146             InfoTable = AcpiDmTableInfoHest2;
1147             SubtableLength = sizeof (ACPI_HEST_IA_NMI);
1148             break;
1149 
1150         case ACPI_HEST_TYPE_AER_ROOT_PORT:
1151 
1152             InfoTable = AcpiDmTableInfoHest6;
1153             SubtableLength = sizeof (ACPI_HEST_AER_ROOT);
1154             break;
1155 
1156         case ACPI_HEST_TYPE_AER_ENDPOINT:
1157 
1158             InfoTable = AcpiDmTableInfoHest7;
1159             SubtableLength = sizeof (ACPI_HEST_AER);
1160             break;
1161 
1162         case ACPI_HEST_TYPE_AER_BRIDGE:
1163 
1164             InfoTable = AcpiDmTableInfoHest8;
1165             SubtableLength = sizeof (ACPI_HEST_AER_BRIDGE);
1166             break;
1167 
1168         case ACPI_HEST_TYPE_GENERIC_ERROR:
1169 
1170             InfoTable = AcpiDmTableInfoHest9;
1171             SubtableLength = sizeof (ACPI_HEST_GENERIC);
1172             break;
1173 
1174         case ACPI_HEST_TYPE_GENERIC_ERROR_V2:
1175 
1176             InfoTable = AcpiDmTableInfoHest10;
1177             SubtableLength = sizeof (ACPI_HEST_GENERIC_V2);
1178             break;
1179 
1180         case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK:
1181 
1182             InfoTable = AcpiDmTableInfoHest11;
1183             SubtableLength = sizeof (ACPI_HEST_IA_DEFERRED_CHECK);
1184             BankCount = (ACPI_CAST_PTR (ACPI_HEST_IA_DEFERRED_CHECK,
1185                 Subtable))->NumHardwareBanks;
1186             break;
1187 
1188         default:
1189 
1190             /* Cannot continue on unknown type - no length */
1191 
1192             AcpiOsPrintf ("\n**** Unknown HEST subtable type 0x%X\n",
1193                 Subtable->Type);
1194             return;
1195         }
1196 
1197         AcpiOsPrintf ("\n");
1198         Status = AcpiDmDumpTable (Length, Offset, Subtable,
1199             SubtableLength, InfoTable);
1200         if (ACPI_FAILURE (Status))
1201         {
1202             return;
1203         }
1204 
1205         /* Point to end of current subtable (each subtable above is of fixed length) */
1206 
1207         Offset += SubtableLength;
1208 
1209         /* If there are any (fixed-length) Error Banks from above, dump them now */
1210 
1211         if (BankCount)
1212         {
1213             BankTable = ACPI_ADD_PTR (ACPI_HEST_IA_ERROR_BANK, Subtable,
1214                 SubtableLength);
1215             SubtableLength += BankCount * sizeof (ACPI_HEST_IA_ERROR_BANK);
1216 
1217             while (BankCount)
1218             {
1219                 AcpiOsPrintf ("\n");
1220                 Status = AcpiDmDumpTable (Length, Offset, BankTable,
1221                     sizeof (ACPI_HEST_IA_ERROR_BANK), AcpiDmTableInfoHestBank);
1222                 if (ACPI_FAILURE (Status))
1223                 {
1224                     return;
1225                 }
1226 
1227                 Offset += sizeof (ACPI_HEST_IA_ERROR_BANK);
1228                 BankTable++;
1229                 BankCount--;
1230             }
1231         }
1232 
1233         /* Point to next subtable */
1234 
1235         Subtable = ACPI_ADD_PTR (ACPI_HEST_HEADER, Subtable, SubtableLength);
1236     }
1237 }
1238 
1239 
1240 /*******************************************************************************
1241  *
1242  * FUNCTION:    AcpiDmDumpHmat
1243  *
1244  * PARAMETERS:  Table               - A HMAT table
1245  *
1246  * RETURN:      None
1247  *
1248  * DESCRIPTION: Format the contents of a HMAT.
1249  *
1250  ******************************************************************************/
1251 
1252 void
1253 AcpiDmDumpHmat (
1254     ACPI_TABLE_HEADER       *Table)
1255 {
1256     ACPI_STATUS             Status;
1257     ACPI_HMAT_STRUCTURE     *HmatStruct;
1258     ACPI_HMAT_LOCALITY      *HmatLocality;
1259     ACPI_HMAT_CACHE         *HmatCache;
1260     UINT32                  Offset;
1261     UINT32                  SubtableOffset;
1262     UINT32                  Length;
1263     ACPI_DMTABLE_INFO       *InfoTable;
1264     UINT32                  i, j;
1265 
1266 
1267     /* Main table */
1268 
1269     Status = AcpiDmDumpTable (Table->Length, 0, Table, 0, AcpiDmTableInfoHmat);
1270     if (ACPI_FAILURE (Status))
1271     {
1272         return;
1273     }
1274     Offset = sizeof (ACPI_TABLE_HMAT);
1275 
1276     while (Offset < Table->Length)
1277     {
1278         AcpiOsPrintf ("\n");
1279         SubtableOffset = 0;
1280 
1281         /* Dump HMAT structure header */
1282 
1283         HmatStruct = ACPI_ADD_PTR (ACPI_HMAT_STRUCTURE, Table, Offset);
1284         if (HmatStruct->Length < sizeof (ACPI_HMAT_STRUCTURE))
1285         {
1286             AcpiOsPrintf ("Invalid HMAT structure length\n");
1287             return;
1288         }
1289         Status = AcpiDmDumpTable (Table->Length, Offset, HmatStruct,
1290             HmatStruct->Length, AcpiDmTableInfoHmatHdr);
1291         if (ACPI_FAILURE (Status))
1292         {
1293             return;
1294         }
1295 
1296         switch (HmatStruct->Type)
1297         {
1298         case ACPI_HMAT_TYPE_ADDRESS_RANGE:
1299 
1300             InfoTable = AcpiDmTableInfoHmat0;
1301             Length = sizeof (ACPI_HMAT_ADDRESS_RANGE);
1302             break;
1303 
1304         case ACPI_HMAT_TYPE_LOCALITY:
1305 
1306             InfoTable = AcpiDmTableInfoHmat1;
1307             Length = sizeof (ACPI_HMAT_LOCALITY);
1308             break;
1309 
1310         case ACPI_HMAT_TYPE_CACHE:
1311 
1312             InfoTable = AcpiDmTableInfoHmat2;
1313             Length = sizeof (ACPI_HMAT_CACHE);
1314             break;
1315 
1316         default:
1317 
1318             AcpiOsPrintf ("\n**** Unknown HMAT structure type 0x%X\n",
1319                 HmatStruct->Type);
1320 
1321             /* Attempt to continue */
1322 
1323             goto NextSubtable;
1324         }
1325 
1326         /* Dump HMAT structure body */
1327 
1328         if (HmatStruct->Length < Length)
1329         {
1330             AcpiOsPrintf ("Invalid HMAT structure length\n");
1331             return;
1332         }
1333         Status = AcpiDmDumpTable (Table->Length, Offset, HmatStruct,
1334             HmatStruct->Length, InfoTable);
1335         if (ACPI_FAILURE (Status))
1336         {
1337             return;
1338         }
1339 
1340         /* Dump HMAT structure additionals */
1341 
1342         switch (HmatStruct->Type)
1343         {
1344         case ACPI_HMAT_TYPE_LOCALITY:
1345 
1346             HmatLocality = ACPI_CAST_PTR (ACPI_HMAT_LOCALITY, HmatStruct);
1347             SubtableOffset = sizeof (ACPI_HMAT_LOCALITY);
1348 
1349             /* Dump initiator proximity domains */
1350 
1351             if ((UINT32)(HmatStruct->Length - SubtableOffset) <
1352                 (UINT32)(HmatLocality->NumberOfInitiatorPDs * 4))
1353             {
1354                 AcpiOsPrintf ("Invalid initiator proximity domain number\n");
1355                 return;
1356             }
1357             for (i = 0; i < HmatLocality->NumberOfInitiatorPDs; i++)
1358             {
1359                 Status = AcpiDmDumpTable (Table->Length, Offset + SubtableOffset,
1360                     ACPI_ADD_PTR (ACPI_HMAT_STRUCTURE, HmatStruct, SubtableOffset),
1361                     4, AcpiDmTableInfoHmat1a);
1362                 SubtableOffset += 4;
1363             }
1364 
1365             /* Dump target proximity domains */
1366 
1367             if ((UINT32)(HmatStruct->Length - SubtableOffset) <
1368                 (UINT32)(HmatLocality->NumberOfTargetPDs * 4))
1369             {
1370                 AcpiOsPrintf ("Invalid target proximity domain number\n");
1371                 return;
1372             }
1373             for (i = 0; i < HmatLocality->NumberOfTargetPDs; i++)
1374             {
1375                 Status = AcpiDmDumpTable (Table->Length, Offset + SubtableOffset,
1376                     ACPI_ADD_PTR (ACPI_HMAT_STRUCTURE, HmatStruct, SubtableOffset),
1377                     4, AcpiDmTableInfoHmat1b);
1378                 SubtableOffset += 4;
1379             }
1380 
1381             /* Dump latency/bandwidth entris */
1382 
1383             if ((UINT32)(HmatStruct->Length - SubtableOffset) <
1384                 (UINT32)(HmatLocality->NumberOfInitiatorPDs *
1385                          HmatLocality->NumberOfTargetPDs * 2))
1386             {
1387                 AcpiOsPrintf ("Invalid latency/bandwidth entry number\n");
1388                 return;
1389             }
1390             for (i = 0; i < HmatLocality->NumberOfInitiatorPDs; i++)
1391             {
1392                 for (j = 0; j < HmatLocality->NumberOfTargetPDs; j++)
1393                 {
1394                     Status = AcpiDmDumpTable (Table->Length, Offset + SubtableOffset,
1395                         ACPI_ADD_PTR (ACPI_HMAT_STRUCTURE, HmatStruct, SubtableOffset),
1396                         2, AcpiDmTableInfoHmat1c);
1397                     SubtableOffset += 2;
1398                 }
1399             }
1400             break;
1401 
1402         case ACPI_HMAT_TYPE_CACHE:
1403 
1404             HmatCache = ACPI_CAST_PTR (ACPI_HMAT_CACHE, HmatStruct);
1405             SubtableOffset = sizeof (ACPI_HMAT_CACHE);
1406 
1407             /* Dump SMBIOS handles */
1408 
1409             if ((UINT32)(HmatStruct->Length - SubtableOffset) <
1410                 (UINT32)(HmatCache->NumberOfSMBIOSHandles * 2))
1411             {
1412                 AcpiOsPrintf ("Invalid SMBIOS handle number\n");
1413                 return;
1414             }
1415             for (i = 0; i < HmatCache->NumberOfSMBIOSHandles; i++)
1416             {
1417                 Status = AcpiDmDumpTable (Table->Length, Offset + SubtableOffset,
1418                     ACPI_ADD_PTR (ACPI_HMAT_STRUCTURE, HmatStruct, SubtableOffset),
1419                     2, AcpiDmTableInfoHmat2a);
1420                 SubtableOffset += 2;
1421             }
1422             break;
1423 
1424         default:
1425 
1426             break;
1427         }
1428 
1429 NextSubtable:
1430         /* Point to next HMAT structure subtable */
1431 
1432         Offset += (HmatStruct->Length);
1433     }
1434 }
1435