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