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