GNU Linux-libre 4.19.264-gnu1
[releases.git] / drivers / acpi / acpica / rsdump.c
1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /*******************************************************************************
3  *
4  * Module Name: rsdump - AML debugger support for resource structures.
5  *
6  ******************************************************************************/
7
8 #include <acpi/acpi.h>
9 #include "accommon.h"
10 #include "acresrc.h"
11
12 #define _COMPONENT          ACPI_RESOURCES
13 ACPI_MODULE_NAME("rsdump")
14
15 /*
16  * All functions in this module are used by the AML Debugger only
17  */
18 /* Local prototypes */
19 static void acpi_rs_out_string(const char *title, const char *value);
20
21 static void acpi_rs_out_integer8(const char *title, u8 value);
22
23 static void acpi_rs_out_integer16(const char *title, u16 value);
24
25 static void acpi_rs_out_integer32(const char *title, u32 value);
26
27 static void acpi_rs_out_integer64(const char *title, u64 value);
28
29 static void acpi_rs_out_title(const char *title);
30
31 static void acpi_rs_dump_byte_list(u16 length, u8 *data);
32
33 static void acpi_rs_dump_word_list(u16 length, u16 *data);
34
35 static void acpi_rs_dump_dword_list(u8 length, u32 *data);
36
37 static void acpi_rs_dump_short_byte_list(u8 length, u8 *data);
38
39 static void
40 acpi_rs_dump_resource_source(struct acpi_resource_source *resource_source);
41
42 static void
43 acpi_rs_dump_resource_label(char *title,
44                             struct acpi_resource_label *resource_label);
45
46 static void acpi_rs_dump_address_common(union acpi_resource_data *resource);
47
48 static void
49 acpi_rs_dump_descriptor(void *resource, struct acpi_rsdump_info *table);
50
51 /*******************************************************************************
52  *
53  * FUNCTION:    acpi_rs_dump_resource_list
54  *
55  * PARAMETERS:  resource_list       - Pointer to a resource descriptor list
56  *
57  * RETURN:      None
58  *
59  * DESCRIPTION: Dispatches the structure to the correct dump routine.
60  *
61  ******************************************************************************/
62
63 void acpi_rs_dump_resource_list(struct acpi_resource *resource_list)
64 {
65         u32 count = 0;
66         u32 type;
67
68         ACPI_FUNCTION_ENTRY();
69
70         /* Check if debug output enabled */
71
72         if (!ACPI_IS_DEBUG_ENABLED(ACPI_LV_RESOURCES, _COMPONENT)) {
73                 return;
74         }
75
76         /* Walk list and dump all resource descriptors (END_TAG terminates) */
77
78         do {
79                 acpi_os_printf("\n[%02X] ", count);
80                 count++;
81
82                 /* Validate Type before dispatch */
83
84                 type = resource_list->type;
85                 if (type > ACPI_RESOURCE_TYPE_MAX) {
86                         acpi_os_printf
87                             ("Invalid descriptor type (%X) in resource list\n",
88                              resource_list->type);
89                         return;
90                 }
91
92                 /* Sanity check the length. It must not be zero, or we loop forever */
93
94                 if (!resource_list->length) {
95                         acpi_os_printf
96                             ("Invalid zero length descriptor in resource list\n");
97                         return;
98                 }
99
100                 /* Dump the resource descriptor */
101
102                 if (type == ACPI_RESOURCE_TYPE_SERIAL_BUS) {
103                         acpi_rs_dump_descriptor(&resource_list->data,
104                                                 acpi_gbl_dump_serial_bus_dispatch
105                                                 [resource_list->data.
106                                                  common_serial_bus.type]);
107                 } else {
108                         acpi_rs_dump_descriptor(&resource_list->data,
109                                                 acpi_gbl_dump_resource_dispatch
110                                                 [type]);
111                 }
112
113                 /* Point to the next resource structure */
114
115                 resource_list = ACPI_NEXT_RESOURCE(resource_list);
116
117                 /* Exit when END_TAG descriptor is reached */
118
119         } while (type != ACPI_RESOURCE_TYPE_END_TAG);
120 }
121
122 /*******************************************************************************
123  *
124  * FUNCTION:    acpi_rs_dump_irq_list
125  *
126  * PARAMETERS:  route_table     - Pointer to the routing table to dump.
127  *
128  * RETURN:      None
129  *
130  * DESCRIPTION: Print IRQ routing table
131  *
132  ******************************************************************************/
133
134 void acpi_rs_dump_irq_list(u8 *route_table)
135 {
136         struct acpi_pci_routing_table *prt_element;
137         u8 count;
138
139         ACPI_FUNCTION_ENTRY();
140
141         /* Check if debug output enabled */
142
143         if (!ACPI_IS_DEBUG_ENABLED(ACPI_LV_RESOURCES, _COMPONENT)) {
144                 return;
145         }
146
147         prt_element = ACPI_CAST_PTR(struct acpi_pci_routing_table, route_table);
148
149         /* Dump all table elements, Exit on zero length element */
150
151         for (count = 0; prt_element->length; count++) {
152                 acpi_os_printf("\n[%02X] PCI IRQ Routing Table Package\n",
153                                count);
154                 acpi_rs_dump_descriptor(prt_element, acpi_rs_dump_prt);
155
156                 prt_element = ACPI_ADD_PTR(struct acpi_pci_routing_table,
157                                            prt_element, prt_element->length);
158         }
159 }
160
161 /*******************************************************************************
162  *
163  * FUNCTION:    acpi_rs_dump_descriptor
164  *
165  * PARAMETERS:  resource            - Buffer containing the resource
166  *              table               - Table entry to decode the resource
167  *
168  * RETURN:      None
169  *
170  * DESCRIPTION: Dump a resource descriptor based on a dump table entry.
171  *
172  ******************************************************************************/
173
174 static void
175 acpi_rs_dump_descriptor(void *resource, struct acpi_rsdump_info *table)
176 {
177         u8 *target = NULL;
178         u8 *previous_target;
179         const char *name;
180         u8 count;
181
182         /* First table entry must contain the table length (# of table entries) */
183
184         count = table->offset;
185
186         while (count) {
187                 previous_target = target;
188                 target = ACPI_ADD_PTR(u8, resource, table->offset);
189                 name = table->name;
190
191                 switch (table->opcode) {
192                 case ACPI_RSD_TITLE:
193                         /*
194                          * Optional resource title
195                          */
196                         if (table->name) {
197                                 acpi_os_printf("%s Resource\n", name);
198                         }
199                         break;
200
201                         /* Strings */
202
203                 case ACPI_RSD_LITERAL:
204
205                         acpi_rs_out_string(name,
206                                            ACPI_CAST_PTR(char, table->pointer));
207                         break;
208
209                 case ACPI_RSD_STRING:
210
211                         acpi_rs_out_string(name, ACPI_CAST_PTR(char, target));
212                         break;
213
214                         /* Data items, 8/16/32/64 bit */
215
216                 case ACPI_RSD_UINT8:
217
218                         if (table->pointer) {
219                                 acpi_rs_out_string(name,
220                                                    table->pointer[*target]);
221                         } else {
222                                 acpi_rs_out_integer8(name, ACPI_GET8(target));
223                         }
224                         break;
225
226                 case ACPI_RSD_UINT16:
227
228                         acpi_rs_out_integer16(name, ACPI_GET16(target));
229                         break;
230
231                 case ACPI_RSD_UINT32:
232
233                         acpi_rs_out_integer32(name, ACPI_GET32(target));
234                         break;
235
236                 case ACPI_RSD_UINT64:
237
238                         acpi_rs_out_integer64(name, ACPI_GET64(target));
239                         break;
240
241                         /* Flags: 1-bit and 2-bit flags supported */
242
243                 case ACPI_RSD_1BITFLAG:
244
245                         acpi_rs_out_string(name,
246                                            table->pointer[*target & 0x01]);
247                         break;
248
249                 case ACPI_RSD_2BITFLAG:
250
251                         acpi_rs_out_string(name,
252                                            table->pointer[*target & 0x03]);
253                         break;
254
255                 case ACPI_RSD_3BITFLAG:
256
257                         acpi_rs_out_string(name,
258                                            table->pointer[*target & 0x07]);
259                         break;
260
261                 case ACPI_RSD_SHORTLIST:
262                         /*
263                          * Short byte list (single line output) for DMA and IRQ resources
264                          * Note: The list length is obtained from the previous table entry
265                          */
266                         if (previous_target) {
267                                 acpi_rs_out_title(name);
268                                 acpi_rs_dump_short_byte_list(*previous_target,
269                                                              target);
270                         }
271                         break;
272
273                 case ACPI_RSD_SHORTLISTX:
274                         /*
275                          * Short byte list (single line output) for GPIO vendor data
276                          * Note: The list length is obtained from the previous table entry
277                          */
278                         if (previous_target) {
279                                 acpi_rs_out_title(name);
280                                 acpi_rs_dump_short_byte_list(*previous_target,
281                                                              *
282                                                              (ACPI_CAST_INDIRECT_PTR
283                                                               (u8, target)));
284                         }
285                         break;
286
287                 case ACPI_RSD_LONGLIST:
288                         /*
289                          * Long byte list for Vendor resource data
290                          * Note: The list length is obtained from the previous table entry
291                          */
292                         if (previous_target) {
293                                 acpi_rs_dump_byte_list(ACPI_GET16
294                                                        (previous_target),
295                                                        target);
296                         }
297                         break;
298
299                 case ACPI_RSD_DWORDLIST:
300                         /*
301                          * Dword list for Extended Interrupt resources
302                          * Note: The list length is obtained from the previous table entry
303                          */
304                         if (previous_target) {
305                                 acpi_rs_dump_dword_list(*previous_target,
306                                                         ACPI_CAST_PTR(u32,
307                                                                       target));
308                         }
309                         break;
310
311                 case ACPI_RSD_WORDLIST:
312                         /*
313                          * Word list for GPIO Pin Table
314                          * Note: The list length is obtained from the previous table entry
315                          */
316                         if (previous_target) {
317                                 acpi_rs_dump_word_list(*previous_target,
318                                                        *(ACPI_CAST_INDIRECT_PTR
319                                                          (u16, target)));
320                         }
321                         break;
322
323                 case ACPI_RSD_ADDRESS:
324                         /*
325                          * Common flags for all Address resources
326                          */
327                         acpi_rs_dump_address_common(ACPI_CAST_PTR
328                                                     (union acpi_resource_data,
329                                                      target));
330                         break;
331
332                 case ACPI_RSD_SOURCE:
333                         /*
334                          * Optional resource_source for Address resources
335                          */
336                         acpi_rs_dump_resource_source(ACPI_CAST_PTR
337                                                      (struct
338                                                                    acpi_resource_source,
339                                                                    target));
340                         break;
341
342                 case ACPI_RSD_LABEL:
343                         /*
344                          * resource_label
345                          */
346                         acpi_rs_dump_resource_label("Resource Label",
347                                                     ACPI_CAST_PTR(struct
348                                                                   acpi_resource_label,
349                                                                   target));
350                         break;
351
352                 case ACPI_RSD_SOURCE_LABEL:
353                         /*
354                          * resource_source_label
355                          */
356                         acpi_rs_dump_resource_label("Resource Source Label",
357                                                     ACPI_CAST_PTR(struct
358                                                                   acpi_resource_label,
359                                                                   target));
360                         break;
361
362                 default:
363
364                         acpi_os_printf("**** Invalid table opcode [%X] ****\n",
365                                        table->opcode);
366                         return;
367                 }
368
369                 table++;
370                 count--;
371         }
372 }
373
374 /*******************************************************************************
375  *
376  * FUNCTION:    acpi_rs_dump_resource_source
377  *
378  * PARAMETERS:  resource_source     - Pointer to a Resource Source struct
379  *
380  * RETURN:      None
381  *
382  * DESCRIPTION: Common routine for dumping the optional resource_source and the
383  *              corresponding resource_source_index.
384  *
385  ******************************************************************************/
386
387 static void
388 acpi_rs_dump_resource_source(struct acpi_resource_source *resource_source)
389 {
390         ACPI_FUNCTION_ENTRY();
391
392         if (resource_source->index == 0xFF) {
393                 return;
394         }
395
396         acpi_rs_out_integer8("Resource Source Index", resource_source->index);
397
398         acpi_rs_out_string("Resource Source",
399                            resource_source->string_ptr ?
400                            resource_source->string_ptr : "[Not Specified]");
401 }
402
403 /*******************************************************************************
404  *
405  * FUNCTION:    acpi_rs_dump_resource_label
406  *
407  * PARAMETERS:  title              - Title of the dumped resource field
408  *              resource_label     - Pointer to a Resource Label struct
409  *
410  * RETURN:      None
411  *
412  * DESCRIPTION: Common routine for dumping the resource_label
413  *
414  ******************************************************************************/
415
416 static void
417 acpi_rs_dump_resource_label(char *title,
418                             struct acpi_resource_label *resource_label)
419 {
420         ACPI_FUNCTION_ENTRY();
421
422         acpi_rs_out_string(title,
423                            resource_label->string_ptr ?
424                            resource_label->string_ptr : "[Not Specified]");
425 }
426
427 /*******************************************************************************
428  *
429  * FUNCTION:    acpi_rs_dump_address_common
430  *
431  * PARAMETERS:  resource        - Pointer to an internal resource descriptor
432  *
433  * RETURN:      None
434  *
435  * DESCRIPTION: Dump the fields that are common to all Address resource
436  *              descriptors
437  *
438  ******************************************************************************/
439
440 static void acpi_rs_dump_address_common(union acpi_resource_data *resource)
441 {
442         ACPI_FUNCTION_ENTRY();
443
444         /* Decode the type-specific flags */
445
446         switch (resource->address.resource_type) {
447         case ACPI_MEMORY_RANGE:
448
449                 acpi_rs_dump_descriptor(resource, acpi_rs_dump_memory_flags);
450                 break;
451
452         case ACPI_IO_RANGE:
453
454                 acpi_rs_dump_descriptor(resource, acpi_rs_dump_io_flags);
455                 break;
456
457         case ACPI_BUS_NUMBER_RANGE:
458
459                 acpi_rs_out_string("Resource Type", "Bus Number Range");
460                 break;
461
462         default:
463
464                 acpi_rs_out_integer8("Resource Type",
465                                      (u8) resource->address.resource_type);
466                 break;
467         }
468
469         /* Decode the general flags */
470
471         acpi_rs_dump_descriptor(resource, acpi_rs_dump_general_flags);
472 }
473
474 /*******************************************************************************
475  *
476  * FUNCTION:    acpi_rs_out*
477  *
478  * PARAMETERS:  title       - Name of the resource field
479  *              value       - Value of the resource field
480  *
481  * RETURN:      None
482  *
483  * DESCRIPTION: Miscellaneous helper functions to consistently format the
484  *              output of the resource dump routines
485  *
486  ******************************************************************************/
487
488 static void acpi_rs_out_string(const char *title, const char *value)
489 {
490
491         acpi_os_printf("%27s : %s", title, value);
492         if (!*value) {
493                 acpi_os_printf("[NULL NAMESTRING]");
494         }
495         acpi_os_printf("\n");
496 }
497
498 static void acpi_rs_out_integer8(const char *title, u8 value)
499 {
500         acpi_os_printf("%27s : %2.2X\n", title, value);
501 }
502
503 static void acpi_rs_out_integer16(const char *title, u16 value)
504 {
505
506         acpi_os_printf("%27s : %4.4X\n", title, value);
507 }
508
509 static void acpi_rs_out_integer32(const char *title, u32 value)
510 {
511
512         acpi_os_printf("%27s : %8.8X\n", title, value);
513 }
514
515 static void acpi_rs_out_integer64(const char *title, u64 value)
516 {
517
518         acpi_os_printf("%27s : %8.8X%8.8X\n", title, ACPI_FORMAT_UINT64(value));
519 }
520
521 static void acpi_rs_out_title(const char *title)
522 {
523
524         acpi_os_printf("%27s : ", title);
525 }
526
527 /*******************************************************************************
528  *
529  * FUNCTION:    acpi_rs_dump*List
530  *
531  * PARAMETERS:  length      - Number of elements in the list
532  *              data        - Start of the list
533  *
534  * RETURN:      None
535  *
536  * DESCRIPTION: Miscellaneous functions to dump lists of raw data
537  *
538  ******************************************************************************/
539
540 static void acpi_rs_dump_byte_list(u16 length, u8 * data)
541 {
542         u16 i;
543
544         for (i = 0; i < length; i++) {
545                 acpi_os_printf("%25s%2.2X : %2.2X\n", "Byte", i, data[i]);
546         }
547 }
548
549 static void acpi_rs_dump_short_byte_list(u8 length, u8 * data)
550 {
551         u8 i;
552
553         for (i = 0; i < length; i++) {
554                 acpi_os_printf("%X ", data[i]);
555         }
556
557         acpi_os_printf("\n");
558 }
559
560 static void acpi_rs_dump_dword_list(u8 length, u32 * data)
561 {
562         u8 i;
563
564         for (i = 0; i < length; i++) {
565                 acpi_os_printf("%25s%2.2X : %8.8X\n", "Dword", i, data[i]);
566         }
567 }
568
569 static void acpi_rs_dump_word_list(u16 length, u16 *data)
570 {
571         u16 i;
572
573         for (i = 0; i < length; i++) {
574                 acpi_os_printf("%25s%2.2X : %4.4X\n", "Word", i, data[i]);
575         }
576 }