1/*******************************************************************************
2 *
3 * Module Name: rsdump - AML debugger support for resource structures.
4 *
5 ******************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2023, 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
57static void
58AcpiRsOutString (
59    const char              *Title,
60    const char              *Value);
61
62static void
63AcpiRsOutInteger8 (
64    const char              *Title,
65    UINT8                   Value);
66
67static void
68AcpiRsOutInteger16 (
69    const char              *Title,
70    UINT16                  Value);
71
72static void
73AcpiRsOutInteger32 (
74    const char              *Title,
75    UINT32                  Value);
76
77static void
78AcpiRsOutInteger64 (
79    const char              *Title,
80    UINT64                  Value);
81
82static void
83AcpiRsOutTitle (
84    const char              *Title);
85
86static void
87AcpiRsDumpByteList (
88    UINT16                  Length,
89    UINT8                   *Data);
90
91static void
92AcpiRsDumpWordList (
93    UINT16                  Length,
94    UINT16                  *Data);
95
96static void
97AcpiRsDumpDwordList (
98    UINT8                   Length,
99    UINT32                  *Data);
100
101static void
102AcpiRsDumpShortByteList (
103    UINT8                   Length,
104    UINT8                   *Data);
105
106static void
107AcpiRsDumpResourceSource (
108    ACPI_RESOURCE_SOURCE    *ResourceSource);
109
110static void
111AcpiRsDumpResourceLabel (
112    const char             *Title,
113    ACPI_RESOURCE_LABEL    *ResourceLabel);
114
115static void
116AcpiRsDumpAddressCommon (
117    ACPI_RESOURCE_DATA      *Resource);
118
119static void
120AcpiRsDumpDescriptor (
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
137void
138AcpiRsDumpResourceList (
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
223void
224AcpiRsDumpIrqList (
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
269static void
270AcpiRsDumpDescriptor (
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
483static void
484AcpiRsDumpResourceSource (
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
517static void
518AcpiRsDumpResourceLabel (
519    const 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
543static void
544AcpiRsDumpAddressCommon (
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
596static void
597AcpiRsOutString (
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
610static void
611AcpiRsOutInteger8 (
612    const char              *Title,
613    UINT8                   Value)
614{
615    AcpiOsPrintf ("%27s : %2.2X\n", Title, Value);
616}
617
618static void
619AcpiRsOutInteger16 (
620    const char              *Title,
621    UINT16                  Value)
622{
623
624    AcpiOsPrintf ("%27s : %4.4X\n", Title, Value);
625}
626
627static void
628AcpiRsOutInteger32 (
629    const char              *Title,
630    UINT32                  Value)
631{
632
633    AcpiOsPrintf ("%27s : %8.8X\n", Title, Value);
634}
635
636static void
637AcpiRsOutInteger64 (
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
646static void
647AcpiRsOutTitle (
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
668static void
669AcpiRsDumpByteList (
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
682static void
683AcpiRsDumpShortByteList (
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
698static void
699AcpiRsDumpDwordList (
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
712static void
713AcpiRsDumpWordList (
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