1 /*******************************************************************************
2  *
3  * Module Name: rsdump - AML debugger support for resource structures.
4  *
5  ******************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2022, Intel Corp.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions, and the following disclaimer,
16  *    without modification.
17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18  *    substantially similar to the "NO WARRANTY" disclaimer below
19  *    ("Disclaimer") and any redistribution must be conditioned upon
20  *    including a substantially similar Disclaimer requirement for further
21  *    binary redistribution.
22  * 3. Neither the names of the above-listed copyright holders nor the names
23  *    of any contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * Alternatively, this software may be distributed under the terms of the
27  * GNU General Public License ("GPL") version 2 as published by the Free
28  * Software Foundation.
29  *
30  * NO WARRANTY
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGES.
42  */
43 
44 #include "acpi.h"
45 #include "accommon.h"
46 #include "acresrc.h"
47 
48 #define _COMPONENT          ACPI_RESOURCES
49         ACPI_MODULE_NAME    ("rsdump")
50 
51 /*
52  * All functions in this module are used by the AML Debugger only
53  */
54 
55 /* Local prototypes */
56 
57 static void
58 AcpiRsOutString (
59     const char              *Title,
60     const char              *Value);
61 
62 static void
63 AcpiRsOutInteger8 (
64     const char              *Title,
65     UINT8                   Value);
66 
67 static void
68 AcpiRsOutInteger16 (
69     const char              *Title,
70     UINT16                  Value);
71 
72 static void
73 AcpiRsOutInteger32 (
74     const char              *Title,
75     UINT32                  Value);
76 
77 static void
78 AcpiRsOutInteger64 (
79     const char              *Title,
80     UINT64                  Value);
81 
82 static void
83 AcpiRsOutTitle (
84     const char              *Title);
85 
86 static void
87 AcpiRsDumpByteList (
88     UINT16                  Length,
89     UINT8                   *Data);
90 
91 static void
92 AcpiRsDumpWordList (
93     UINT16                  Length,
94     UINT16                  *Data);
95 
96 static void
97 AcpiRsDumpDwordList (
98     UINT8                   Length,
99     UINT32                  *Data);
100 
101 static void
102 AcpiRsDumpShortByteList (
103     UINT8                   Length,
104     UINT8                   *Data);
105 
106 static void
107 AcpiRsDumpResourceSource (
108     ACPI_RESOURCE_SOURCE    *ResourceSource);
109 
110 static void
111 AcpiRsDumpResourceLabel (
112     char                   *Title,
113     ACPI_RESOURCE_LABEL    *ResourceLabel);
114 
115 static void
116 AcpiRsDumpAddressCommon (
117     ACPI_RESOURCE_DATA      *Resource);
118 
119 static void
120 AcpiRsDumpDescriptor (
121     void                    *Resource,
122     ACPI_RSDUMP_INFO        *Table);
123 
124 
125 /*******************************************************************************
126  *
127  * FUNCTION:    AcpiRsDumpResourceList
128  *
129  * PARAMETERS:  ResourceList        - Pointer to a resource descriptor list
130  *
131  * RETURN:      None
132  *
133  * DESCRIPTION: Dispatches the structure to the correct dump routine.
134  *
135  ******************************************************************************/
136 
137 void
138 AcpiRsDumpResourceList (
139     ACPI_RESOURCE           *ResourceList)
140 {
141     UINT32                  Count = 0;
142     UINT32                  Type;
143 
144 
145     ACPI_FUNCTION_ENTRY ();
146 
147 
148     /* Check if debug output enabled */
149 
150     if (!ACPI_IS_DEBUG_ENABLED (ACPI_LV_RESOURCES, _COMPONENT))
151     {
152         return;
153     }
154 
155     /* Walk list and dump all resource descriptors (END_TAG terminates) */
156 
157     do
158     {
159         AcpiOsPrintf ("\n[%02X] ", Count);
160         Count++;
161 
162         /* Validate Type before dispatch */
163 
164         Type = ResourceList->Type;
165         if (Type > ACPI_RESOURCE_TYPE_MAX)
166         {
167             AcpiOsPrintf (
168                 "Invalid descriptor type (%X) in resource list\n",
169                 ResourceList->Type);
170             return;
171         }
172         else if (!ResourceList->Type)
173         {
174             ACPI_ERROR ((AE_INFO, "Invalid Zero Resource Type"));
175             return;
176         }
177 
178         /* Sanity check the length. It must not be zero, or we loop forever */
179 
180         if (!ResourceList->Length)
181         {
182             AcpiOsPrintf (
183                 "Invalid zero length descriptor in resource list\n");
184             return;
185         }
186 
187         /* Dump the resource descriptor */
188 
189         if (Type == ACPI_RESOURCE_TYPE_SERIAL_BUS)
190         {
191             AcpiRsDumpDescriptor (&ResourceList->Data,
192                 AcpiGbl_DumpSerialBusDispatch[
193                     ResourceList->Data.CommonSerialBus.Type]);
194         }
195         else
196         {
197             AcpiRsDumpDescriptor (&ResourceList->Data,
198                 AcpiGbl_DumpResourceDispatch[Type]);
199         }
200 
201         /* Point to the next resource structure */
202 
203         ResourceList = ACPI_NEXT_RESOURCE (ResourceList);
204 
205         /* Exit when END_TAG descriptor is reached */
206 
207     } while (Type != ACPI_RESOURCE_TYPE_END_TAG);
208 }
209 
210 
211 /*******************************************************************************
212  *
213  * FUNCTION:    AcpiRsDumpIrqList
214  *
215  * PARAMETERS:  RouteTable      - Pointer to the routing table to dump.
216  *
217  * RETURN:      None
218  *
219  * DESCRIPTION: Print IRQ routing table
220  *
221  ******************************************************************************/
222 
223 void
224 AcpiRsDumpIrqList (
225     UINT8                   *RouteTable)
226 {
227     ACPI_PCI_ROUTING_TABLE  *PrtElement;
228     UINT8                   Count;
229 
230 
231     ACPI_FUNCTION_ENTRY ();
232 
233 
234     /* Check if debug output enabled */
235 
236     if (!ACPI_IS_DEBUG_ENABLED (ACPI_LV_RESOURCES, _COMPONENT))
237     {
238         return;
239     }
240 
241     PrtElement = ACPI_CAST_PTR (ACPI_PCI_ROUTING_TABLE, RouteTable);
242 
243     /* Dump all table elements, Exit on zero length element */
244 
245     for (Count = 0; PrtElement->Length; Count++)
246     {
247         AcpiOsPrintf ("\n[%02X] PCI IRQ Routing Table Package\n", Count);
248         AcpiRsDumpDescriptor (PrtElement, AcpiRsDumpPrt);
249 
250         PrtElement = ACPI_ADD_PTR (ACPI_PCI_ROUTING_TABLE,
251             PrtElement, PrtElement->Length);
252     }
253 }
254 
255 
256 /*******************************************************************************
257  *
258  * FUNCTION:    AcpiRsDumpDescriptor
259  *
260  * PARAMETERS:  Resource            - Buffer containing the resource
261  *              Table               - Table entry to decode the resource
262  *
263  * RETURN:      None
264  *
265  * DESCRIPTION: Dump a resource descriptor based on a dump table entry.
266  *
267  ******************************************************************************/
268 
269 static void
270 AcpiRsDumpDescriptor (
271     void                    *Resource,
272     ACPI_RSDUMP_INFO        *Table)
273 {
274     UINT8                   *Target = NULL;
275     UINT8                   *PreviousTarget;
276     const char              *Name;
277     UINT8                   Count;
278 
279 
280     /* First table entry must contain the table length (# of table entries) */
281 
282     Count = Table->Offset;
283 
284     while (Count)
285     {
286         PreviousTarget = Target;
287         Target = ACPI_ADD_PTR (UINT8, Resource, Table->Offset);
288         Name = Table->Name;
289 
290         switch (Table->Opcode)
291         {
292         case ACPI_RSD_TITLE:
293             /*
294              * Optional resource title
295              */
296             if (Table->Name)
297             {
298                 AcpiOsPrintf ("%s Resource\n", Name);
299             }
300             break;
301 
302         /* Strings */
303 
304         case ACPI_RSD_LITERAL:
305 
306             AcpiRsOutString (Name, ACPI_CAST_PTR (char, Table->Pointer));
307             break;
308 
309         case ACPI_RSD_STRING:
310 
311             AcpiRsOutString (Name, ACPI_CAST_PTR (char, Target));
312             break;
313 
314         /* Data items, 8/16/32/64 bit */
315 
316         case ACPI_RSD_UINT8:
317 
318             if (Table->Pointer)
319             {
320                 AcpiRsOutString (Name, Table->Pointer [*Target]);
321             }
322             else
323             {
324                 AcpiRsOutInteger8 (Name, ACPI_GET8 (Target));
325             }
326             break;
327 
328         case ACPI_RSD_UINT16:
329 
330             AcpiRsOutInteger16 (Name, ACPI_GET16 (Target));
331             break;
332 
333         case ACPI_RSD_UINT32:
334 
335             AcpiRsOutInteger32 (Name, ACPI_GET32 (Target));
336             break;
337 
338         case ACPI_RSD_UINT64:
339 
340             AcpiRsOutInteger64 (Name, ACPI_GET64 (Target));
341             break;
342 
343         /* Flags: 1-bit and 2-bit flags supported */
344 
345         case ACPI_RSD_1BITFLAG:
346 
347             AcpiRsOutString (Name, Table->Pointer [*Target & 0x01]);
348             break;
349 
350         case ACPI_RSD_2BITFLAG:
351 
352             AcpiRsOutString (Name, Table->Pointer [*Target & 0x03]);
353             break;
354 
355         case ACPI_RSD_3BITFLAG:
356 
357             AcpiRsOutString (Name, Table->Pointer [*Target & 0x07]);
358             break;
359 
360         case ACPI_RSD_6BITFLAG:
361 
362             AcpiRsOutInteger8 (Name, (ACPI_GET8 (Target) & 0x3F));
363             break;
364 
365         case ACPI_RSD_SHORTLIST:
366             /*
367              * Short byte list (single line output) for DMA and IRQ resources
368              * Note: The list length is obtained from the previous table entry
369              */
370             if (PreviousTarget)
371             {
372                 AcpiRsOutTitle (Name);
373                 AcpiRsDumpShortByteList (*PreviousTarget, Target);
374             }
375             break;
376 
377         case ACPI_RSD_SHORTLISTX:
378             /*
379              * Short byte list (single line output) for GPIO vendor data
380              * Note: The list length is obtained from the previous table entry
381              */
382             if (PreviousTarget)
383             {
384                 AcpiRsOutTitle (Name);
385                 AcpiRsDumpShortByteList (*PreviousTarget,
386                     *(ACPI_CAST_INDIRECT_PTR (UINT8, Target)));
387             }
388             break;
389 
390         case ACPI_RSD_LONGLIST:
391             /*
392              * Long byte list for Vendor resource data
393              * Note: The list length is obtained from the previous table entry
394              */
395             if (PreviousTarget)
396             {
397                 AcpiRsDumpByteList (ACPI_GET16 (PreviousTarget), Target);
398             }
399             break;
400 
401         case ACPI_RSD_DWORDLIST:
402             /*
403              * Dword list for Extended Interrupt resources
404              * Note: The list length is obtained from the previous table entry
405              */
406             if (PreviousTarget)
407             {
408                 AcpiRsDumpDwordList (*PreviousTarget,
409                     ACPI_CAST_PTR (UINT32, Target));
410             }
411             break;
412 
413         case ACPI_RSD_WORDLIST:
414             /*
415              * Word list for GPIO Pin Table
416              * Note: The list length is obtained from the previous table entry
417              */
418             if (PreviousTarget)
419             {
420                 AcpiRsDumpWordList (*PreviousTarget,
421                     *(ACPI_CAST_INDIRECT_PTR (UINT16, Target)));
422             }
423             break;
424 
425         case ACPI_RSD_ADDRESS:
426             /*
427              * Common flags for all Address resources
428              */
429             AcpiRsDumpAddressCommon (ACPI_CAST_PTR (
430                 ACPI_RESOURCE_DATA, Target));
431             break;
432 
433         case ACPI_RSD_SOURCE:
434             /*
435              * Optional ResourceSource for Address resources
436              */
437             AcpiRsDumpResourceSource (ACPI_CAST_PTR (
438                 ACPI_RESOURCE_SOURCE, Target));
439             break;
440 
441         case ACPI_RSD_LABEL:
442             /*
443              * ResourceLabel
444              */
445             AcpiRsDumpResourceLabel ("Resource Label", ACPI_CAST_PTR (
446                 ACPI_RESOURCE_LABEL, Target));
447             break;
448 
449         case ACPI_RSD_SOURCE_LABEL:
450             /*
451              * ResourceSourceLabel
452              */
453             AcpiRsDumpResourceLabel ("Resource Source Label", ACPI_CAST_PTR (
454                 ACPI_RESOURCE_LABEL, Target));
455             break;
456 
457         default:
458 
459             AcpiOsPrintf ("**** Invalid table opcode [%X] ****\n",
460                 Table->Opcode);
461             return;
462         }
463 
464         Table++;
465         Count--;
466     }
467 }
468 
469 
470 /*******************************************************************************
471  *
472  * FUNCTION:    AcpiRsDumpResourceSource
473  *
474  * PARAMETERS:  ResourceSource      - Pointer to a Resource Source struct
475  *
476  * RETURN:      None
477  *
478  * DESCRIPTION: Common routine for dumping the optional ResourceSource and the
479  *              corresponding ResourceSourceIndex.
480  *
481  ******************************************************************************/
482 
483 static void
484 AcpiRsDumpResourceSource (
485     ACPI_RESOURCE_SOURCE    *ResourceSource)
486 {
487     ACPI_FUNCTION_ENTRY ();
488 
489 
490     if (ResourceSource->Index == 0xFF)
491     {
492         return;
493     }
494 
495     AcpiRsOutInteger8 ("Resource Source Index",
496         ResourceSource->Index);
497 
498     AcpiRsOutString ("Resource Source",
499         ResourceSource->StringPtr ?
500             ResourceSource->StringPtr : "[Not Specified]");
501 }
502 
503 
504 /*******************************************************************************
505  *
506  * FUNCTION:    AcpiRsDumpResourceLabel
507  *
508  * PARAMETERS:  Title              - Title of the dumped resource field
509  *              ResourceLabel      - Pointer to a Resource Label struct
510  *
511  * RETURN:      None
512  *
513  * DESCRIPTION: Common routine for dumping the ResourceLabel
514  *
515  ******************************************************************************/
516 
517 static void
518 AcpiRsDumpResourceLabel (
519     char                   *Title,
520     ACPI_RESOURCE_LABEL    *ResourceLabel)
521 {
522     ACPI_FUNCTION_ENTRY ();
523 
524     AcpiRsOutString (Title,
525         ResourceLabel->StringPtr ?
526             ResourceLabel->StringPtr : "[Not Specified]");
527 }
528 
529 
530 /*******************************************************************************
531  *
532  * FUNCTION:    AcpiRsDumpAddressCommon
533  *
534  * PARAMETERS:  Resource        - Pointer to an internal resource descriptor
535  *
536  * RETURN:      None
537  *
538  * DESCRIPTION: Dump the fields that are common to all Address resource
539  *              descriptors
540  *
541  ******************************************************************************/
542 
543 static void
544 AcpiRsDumpAddressCommon (
545     ACPI_RESOURCE_DATA      *Resource)
546 {
547     ACPI_FUNCTION_ENTRY ();
548 
549 
550    /* Decode the type-specific flags */
551 
552     switch (Resource->Address.ResourceType)
553     {
554     case ACPI_MEMORY_RANGE:
555 
556         AcpiRsDumpDescriptor (Resource, AcpiRsDumpMemoryFlags);
557         break;
558 
559     case ACPI_IO_RANGE:
560 
561         AcpiRsDumpDescriptor (Resource, AcpiRsDumpIoFlags);
562         break;
563 
564     case ACPI_BUS_NUMBER_RANGE:
565 
566         AcpiRsOutString ("Resource Type", "Bus Number Range");
567         break;
568 
569     default:
570 
571         AcpiRsOutInteger8 ("Resource Type",
572             (UINT8) Resource->Address.ResourceType);
573         break;
574     }
575 
576     /* Decode the general flags */
577 
578     AcpiRsDumpDescriptor (Resource, AcpiRsDumpGeneralFlags);
579 }
580 
581 
582 /*******************************************************************************
583  *
584  * FUNCTION:    AcpiRsOut*
585  *
586  * PARAMETERS:  Title       - Name of the resource field
587  *              Value       - Value of the resource field
588  *
589  * RETURN:      None
590  *
591  * DESCRIPTION: Miscellaneous helper functions to consistently format the
592  *              output of the resource dump routines
593  *
594  ******************************************************************************/
595 
596 static void
597 AcpiRsOutString (
598     const char              *Title,
599     const char              *Value)
600 {
601 
602     AcpiOsPrintf ("%27s : %s", Title, Value);
603     if (!*Value)
604     {
605         AcpiOsPrintf ("[NULL NAMESTRING]");
606     }
607     AcpiOsPrintf ("\n");
608 }
609 
610 static void
611 AcpiRsOutInteger8 (
612     const char              *Title,
613     UINT8                   Value)
614 {
615     AcpiOsPrintf ("%27s : %2.2X\n", Title, Value);
616 }
617 
618 static void
619 AcpiRsOutInteger16 (
620     const char              *Title,
621     UINT16                  Value)
622 {
623 
624     AcpiOsPrintf ("%27s : %4.4X\n", Title, Value);
625 }
626 
627 static void
628 AcpiRsOutInteger32 (
629     const char              *Title,
630     UINT32                  Value)
631 {
632 
633     AcpiOsPrintf ("%27s : %8.8X\n", Title, Value);
634 }
635 
636 static void
637 AcpiRsOutInteger64 (
638     const char              *Title,
639     UINT64                  Value)
640 {
641 
642     AcpiOsPrintf ("%27s : %8.8X%8.8X\n", Title,
643         ACPI_FORMAT_UINT64 (Value));
644 }
645 
646 static void
647 AcpiRsOutTitle (
648     const char              *Title)
649 {
650 
651     AcpiOsPrintf ("%27s : ", Title);
652 }
653 
654 
655 /*******************************************************************************
656  *
657  * FUNCTION:    AcpiRsDump*List
658  *
659  * PARAMETERS:  Length      - Number of elements in the list
660  *              Data        - Start of the list
661  *
662  * RETURN:      None
663  *
664  * DESCRIPTION: Miscellaneous functions to dump lists of raw data
665  *
666  ******************************************************************************/
667 
668 static void
669 AcpiRsDumpByteList (
670     UINT16                  Length,
671     UINT8                   *Data)
672 {
673     UINT16                  i;
674 
675 
676     for (i = 0; i < Length; i++)
677     {
678         AcpiOsPrintf ("%25s%2.2X : %2.2X\n", "Byte", i, Data[i]);
679     }
680 }
681 
682 static void
683 AcpiRsDumpShortByteList (
684     UINT8                   Length,
685     UINT8                   *Data)
686 {
687     UINT8                   i;
688 
689 
690     for (i = 0; i < Length; i++)
691     {
692         AcpiOsPrintf ("%X ", Data[i]);
693     }
694 
695     AcpiOsPrintf ("\n");
696 }
697 
698 static void
699 AcpiRsDumpDwordList (
700     UINT8                   Length,
701     UINT32                  *Data)
702 {
703     UINT8                   i;
704 
705 
706     for (i = 0; i < Length; i++)
707     {
708         AcpiOsPrintf ("%25s%2.2X : %8.8X\n", "Dword", i, Data[i]);
709     }
710 }
711 
712 static void
713 AcpiRsDumpWordList (
714     UINT16                  Length,
715     UINT16                  *Data)
716 {
717     UINT16                  i;
718 
719 
720     for (i = 0; i < Length; i++)
721     {
722         AcpiOsPrintf ("%25s%2.2X : %4.4X\n", "Word", i, Data[i]);
723     }
724 }
725