1 /*******************************************************************************
2  *
3  * Module Name: rsdump - AML debugger support for resource structures.
4  *
5  ******************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2017, 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 "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 
173         /* Sanity check the length. It must not be zero, or we loop forever */
174 
175         if (!ResourceList->Length)
176         {
177             AcpiOsPrintf (
178                 "Invalid zero length descriptor in resource list\n");
179             return;
180         }
181 
182         /* Dump the resource descriptor */
183 
184         if (Type == ACPI_RESOURCE_TYPE_SERIAL_BUS)
185         {
186             AcpiRsDumpDescriptor (&ResourceList->Data,
187                 AcpiGbl_DumpSerialBusDispatch[
188                     ResourceList->Data.CommonSerialBus.Type]);
189         }
190         else
191         {
192             AcpiRsDumpDescriptor (&ResourceList->Data,
193                 AcpiGbl_DumpResourceDispatch[Type]);
194         }
195 
196         /* Point to the next resource structure */
197 
198         ResourceList = ACPI_NEXT_RESOURCE (ResourceList);
199 
200         /* Exit when END_TAG descriptor is reached */
201 
202     } while (Type != ACPI_RESOURCE_TYPE_END_TAG);
203 }
204 
205 
206 /*******************************************************************************
207  *
208  * FUNCTION:    AcpiRsDumpIrqList
209  *
210  * PARAMETERS:  RouteTable      - Pointer to the routing table to dump.
211  *
212  * RETURN:      None
213  *
214  * DESCRIPTION: Print IRQ routing table
215  *
216  ******************************************************************************/
217 
218 void
219 AcpiRsDumpIrqList (
220     UINT8                   *RouteTable)
221 {
222     ACPI_PCI_ROUTING_TABLE  *PrtElement;
223     UINT8                   Count;
224 
225 
226     ACPI_FUNCTION_ENTRY ();
227 
228 
229     /* Check if debug output enabled */
230 
231     if (!ACPI_IS_DEBUG_ENABLED (ACPI_LV_RESOURCES, _COMPONENT))
232     {
233         return;
234     }
235 
236     PrtElement = ACPI_CAST_PTR (ACPI_PCI_ROUTING_TABLE, RouteTable);
237 
238     /* Dump all table elements, Exit on zero length element */
239 
240     for (Count = 0; PrtElement->Length; Count++)
241     {
242         AcpiOsPrintf ("\n[%02X] PCI IRQ Routing Table Package\n", Count);
243         AcpiRsDumpDescriptor (PrtElement, AcpiRsDumpPrt);
244 
245         PrtElement = ACPI_ADD_PTR (ACPI_PCI_ROUTING_TABLE,
246             PrtElement, PrtElement->Length);
247     }
248 }
249 
250 
251 /*******************************************************************************
252  *
253  * FUNCTION:    AcpiRsDumpDescriptor
254  *
255  * PARAMETERS:  Resource            - Buffer containing the resource
256  *              Table               - Table entry to decode the resource
257  *
258  * RETURN:      None
259  *
260  * DESCRIPTION: Dump a resource descriptor based on a dump table entry.
261  *
262  ******************************************************************************/
263 
264 static void
265 AcpiRsDumpDescriptor (
266     void                    *Resource,
267     ACPI_RSDUMP_INFO        *Table)
268 {
269     UINT8                   *Target = NULL;
270     UINT8                   *PreviousTarget;
271     const char              *Name;
272     UINT8                   Count;
273 
274 
275     /* First table entry must contain the table length (# of table entries) */
276 
277     Count = Table->Offset;
278 
279     while (Count)
280     {
281         PreviousTarget = Target;
282         Target = ACPI_ADD_PTR (UINT8, Resource, Table->Offset);
283         Name = Table->Name;
284 
285         switch (Table->Opcode)
286         {
287         case ACPI_RSD_TITLE:
288             /*
289              * Optional resource title
290              */
291             if (Table->Name)
292             {
293                 AcpiOsPrintf ("%s Resource\n", Name);
294             }
295             break;
296 
297         /* Strings */
298 
299         case ACPI_RSD_LITERAL:
300 
301             AcpiRsOutString (Name, ACPI_CAST_PTR (char, Table->Pointer));
302             break;
303 
304         case ACPI_RSD_STRING:
305 
306             AcpiRsOutString (Name, ACPI_CAST_PTR (char, Target));
307             break;
308 
309         /* Data items, 8/16/32/64 bit */
310 
311         case ACPI_RSD_UINT8:
312 
313             if (Table->Pointer)
314             {
315                 AcpiRsOutString (Name, Table->Pointer [*Target]);
316             }
317             else
318             {
319                 AcpiRsOutInteger8 (Name, ACPI_GET8 (Target));
320             }
321             break;
322 
323         case ACPI_RSD_UINT16:
324 
325             AcpiRsOutInteger16 (Name, ACPI_GET16 (Target));
326             break;
327 
328         case ACPI_RSD_UINT32:
329 
330             AcpiRsOutInteger32 (Name, ACPI_GET32 (Target));
331             break;
332 
333         case ACPI_RSD_UINT64:
334 
335             AcpiRsOutInteger64 (Name, ACPI_GET64 (Target));
336             break;
337 
338         /* Flags: 1-bit and 2-bit flags supported */
339 
340         case ACPI_RSD_1BITFLAG:
341 
342             AcpiRsOutString (Name, Table->Pointer [*Target & 0x01]);
343             break;
344 
345         case ACPI_RSD_2BITFLAG:
346 
347             AcpiRsOutString (Name, Table->Pointer [*Target & 0x03]);
348             break;
349 
350         case ACPI_RSD_3BITFLAG:
351 
352             AcpiRsOutString (Name, Table->Pointer [*Target & 0x07]);
353             break;
354 
355         case ACPI_RSD_SHORTLIST:
356             /*
357              * Short byte list (single line output) for DMA and IRQ resources
358              * Note: The list length is obtained from the previous table entry
359              */
360             if (PreviousTarget)
361             {
362                 AcpiRsOutTitle (Name);
363                 AcpiRsDumpShortByteList (*PreviousTarget, Target);
364             }
365             break;
366 
367         case ACPI_RSD_SHORTLISTX:
368             /*
369              * Short byte list (single line output) for GPIO vendor data
370              * Note: The list length is obtained from the previous table entry
371              */
372             if (PreviousTarget)
373             {
374                 AcpiRsOutTitle (Name);
375                 AcpiRsDumpShortByteList (*PreviousTarget,
376                     *(ACPI_CAST_INDIRECT_PTR (UINT8, Target)));
377             }
378             break;
379 
380         case ACPI_RSD_LONGLIST:
381             /*
382              * Long byte list for Vendor resource data
383              * Note: The list length is obtained from the previous table entry
384              */
385             if (PreviousTarget)
386             {
387                 AcpiRsDumpByteList (ACPI_GET16 (PreviousTarget), Target);
388             }
389             break;
390 
391         case ACPI_RSD_DWORDLIST:
392             /*
393              * Dword list for Extended Interrupt resources
394              * Note: The list length is obtained from the previous table entry
395              */
396             if (PreviousTarget)
397             {
398                 AcpiRsDumpDwordList (*PreviousTarget,
399                     ACPI_CAST_PTR (UINT32, Target));
400             }
401             break;
402 
403         case ACPI_RSD_WORDLIST:
404             /*
405              * Word list for GPIO Pin Table
406              * Note: The list length is obtained from the previous table entry
407              */
408             if (PreviousTarget)
409             {
410                 AcpiRsDumpWordList (*PreviousTarget,
411                     *(ACPI_CAST_INDIRECT_PTR (UINT16, Target)));
412             }
413             break;
414 
415         case ACPI_RSD_ADDRESS:
416             /*
417              * Common flags for all Address resources
418              */
419             AcpiRsDumpAddressCommon (ACPI_CAST_PTR (
420                 ACPI_RESOURCE_DATA, Target));
421             break;
422 
423         case ACPI_RSD_SOURCE:
424             /*
425              * Optional ResourceSource for Address resources
426              */
427             AcpiRsDumpResourceSource (ACPI_CAST_PTR (
428                 ACPI_RESOURCE_SOURCE, Target));
429             break;
430 
431         case ACPI_RSD_LABEL:
432             /*
433              * ResourceLabel
434              */
435             AcpiRsDumpResourceLabel ("Resource Label", ACPI_CAST_PTR (
436                 ACPI_RESOURCE_LABEL, Target));
437             break;
438 
439         case ACPI_RSD_SOURCE_LABEL:
440             /*
441              * ResourceSourceLabel
442              */
443             AcpiRsDumpResourceLabel ("Resource Source Label", ACPI_CAST_PTR (
444                 ACPI_RESOURCE_LABEL, Target));
445             break;
446 
447         default:
448 
449             AcpiOsPrintf ("**** Invalid table opcode [%X] ****\n",
450                 Table->Opcode);
451             return;
452         }
453 
454         Table++;
455         Count--;
456     }
457 }
458 
459 
460 /*******************************************************************************
461  *
462  * FUNCTION:    AcpiRsDumpResourceSource
463  *
464  * PARAMETERS:  ResourceSource      - Pointer to a Resource Source struct
465  *
466  * RETURN:      None
467  *
468  * DESCRIPTION: Common routine for dumping the optional ResourceSource and the
469  *              corresponding ResourceSourceIndex.
470  *
471  ******************************************************************************/
472 
473 static void
474 AcpiRsDumpResourceSource (
475     ACPI_RESOURCE_SOURCE    *ResourceSource)
476 {
477     ACPI_FUNCTION_ENTRY ();
478 
479 
480     if (ResourceSource->Index == 0xFF)
481     {
482         return;
483     }
484 
485     AcpiRsOutInteger8 ("Resource Source Index",
486         ResourceSource->Index);
487 
488     AcpiRsOutString ("Resource Source",
489         ResourceSource->StringPtr ?
490             ResourceSource->StringPtr : "[Not Specified]");
491 }
492 
493 
494 /*******************************************************************************
495  *
496  * FUNCTION:    AcpiRsDumpResourceLabel
497  *
498  * PARAMETERS:  Title              - Title of the dumped resource field
499  *              ResourceLabel      - Pointer to a Resource Label struct
500  *
501  * RETURN:      None
502  *
503  * DESCRIPTION: Common routine for dumping the ResourceLabel
504  *
505  ******************************************************************************/
506 
507 static void
508 AcpiRsDumpResourceLabel (
509     char                   *Title,
510     ACPI_RESOURCE_LABEL    *ResourceLabel)
511 {
512     ACPI_FUNCTION_ENTRY ();
513 
514     AcpiRsOutString (Title,
515         ResourceLabel->StringPtr ?
516             ResourceLabel->StringPtr : "[Not Specified]");
517 }
518 
519 
520 /*******************************************************************************
521  *
522  * FUNCTION:    AcpiRsDumpAddressCommon
523  *
524  * PARAMETERS:  Resource        - Pointer to an internal resource descriptor
525  *
526  * RETURN:      None
527  *
528  * DESCRIPTION: Dump the fields that are common to all Address resource
529  *              descriptors
530  *
531  ******************************************************************************/
532 
533 static void
534 AcpiRsDumpAddressCommon (
535     ACPI_RESOURCE_DATA      *Resource)
536 {
537     ACPI_FUNCTION_ENTRY ();
538 
539 
540    /* Decode the type-specific flags */
541 
542     switch (Resource->Address.ResourceType)
543     {
544     case ACPI_MEMORY_RANGE:
545 
546         AcpiRsDumpDescriptor (Resource, AcpiRsDumpMemoryFlags);
547         break;
548 
549     case ACPI_IO_RANGE:
550 
551         AcpiRsDumpDescriptor (Resource, AcpiRsDumpIoFlags);
552         break;
553 
554     case ACPI_BUS_NUMBER_RANGE:
555 
556         AcpiRsOutString ("Resource Type", "Bus Number Range");
557         break;
558 
559     default:
560 
561         AcpiRsOutInteger8 ("Resource Type",
562             (UINT8) Resource->Address.ResourceType);
563         break;
564     }
565 
566     /* Decode the general flags */
567 
568     AcpiRsDumpDescriptor (Resource, AcpiRsDumpGeneralFlags);
569 }
570 
571 
572 /*******************************************************************************
573  *
574  * FUNCTION:    AcpiRsOut*
575  *
576  * PARAMETERS:  Title       - Name of the resource field
577  *              Value       - Value of the resource field
578  *
579  * RETURN:      None
580  *
581  * DESCRIPTION: Miscellaneous helper functions to consistently format the
582  *              output of the resource dump routines
583  *
584  ******************************************************************************/
585 
586 static void
587 AcpiRsOutString (
588     const char              *Title,
589     const char              *Value)
590 {
591 
592     AcpiOsPrintf ("%27s : %s", Title, Value);
593     if (!*Value)
594     {
595         AcpiOsPrintf ("[NULL NAMESTRING]");
596     }
597     AcpiOsPrintf ("\n");
598 }
599 
600 static void
601 AcpiRsOutInteger8 (
602     const char              *Title,
603     UINT8                   Value)
604 {
605     AcpiOsPrintf ("%27s : %2.2X\n", Title, Value);
606 }
607 
608 static void
609 AcpiRsOutInteger16 (
610     const char              *Title,
611     UINT16                  Value)
612 {
613 
614     AcpiOsPrintf ("%27s : %4.4X\n", Title, Value);
615 }
616 
617 static void
618 AcpiRsOutInteger32 (
619     const char              *Title,
620     UINT32                  Value)
621 {
622 
623     AcpiOsPrintf ("%27s : %8.8X\n", Title, Value);
624 }
625 
626 static void
627 AcpiRsOutInteger64 (
628     const char              *Title,
629     UINT64                  Value)
630 {
631 
632     AcpiOsPrintf ("%27s : %8.8X%8.8X\n", Title,
633         ACPI_FORMAT_UINT64 (Value));
634 }
635 
636 static void
637 AcpiRsOutTitle (
638     const char              *Title)
639 {
640 
641     AcpiOsPrintf ("%27s : ", Title);
642 }
643 
644 
645 /*******************************************************************************
646  *
647  * FUNCTION:    AcpiRsDump*List
648  *
649  * PARAMETERS:  Length      - Number of elements in the list
650  *              Data        - Start of the list
651  *
652  * RETURN:      None
653  *
654  * DESCRIPTION: Miscellaneous functions to dump lists of raw data
655  *
656  ******************************************************************************/
657 
658 static void
659 AcpiRsDumpByteList (
660     UINT16                  Length,
661     UINT8                   *Data)
662 {
663     UINT8                   i;
664 
665 
666     for (i = 0; i < Length; i++)
667     {
668         AcpiOsPrintf ("%25s%2.2X : %2.2X\n", "Byte", i, Data[i]);
669     }
670 }
671 
672 static void
673 AcpiRsDumpShortByteList (
674     UINT8                   Length,
675     UINT8                   *Data)
676 {
677     UINT8                   i;
678 
679 
680     for (i = 0; i < Length; i++)
681     {
682         AcpiOsPrintf ("%X ", Data[i]);
683     }
684 
685     AcpiOsPrintf ("\n");
686 }
687 
688 static void
689 AcpiRsDumpDwordList (
690     UINT8                   Length,
691     UINT32                  *Data)
692 {
693     UINT8                   i;
694 
695 
696     for (i = 0; i < Length; i++)
697     {
698         AcpiOsPrintf ("%25s%2.2X : %8.8X\n", "Dword", i, Data[i]);
699     }
700 }
701 
702 static void
703 AcpiRsDumpWordList (
704     UINT16                  Length,
705     UINT16                  *Data)
706 {
707     UINT16                  i;
708 
709 
710     for (i = 0; i < Length; i++)
711     {
712         AcpiOsPrintf ("%25s%2.2X : %4.4X\n", "Word", i, Data[i]);
713     }
714 }
715