Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
0002 /*******************************************************************************
0003  *
0004  * Module Name: rsdump - AML debugger support for resource structures.
0005  *
0006  ******************************************************************************/
0007 
0008 #include <acpi/acpi.h>
0009 #include "accommon.h"
0010 #include "acresrc.h"
0011 
0012 #define _COMPONENT          ACPI_RESOURCES
0013 ACPI_MODULE_NAME("rsdump")
0014 
0015 /*
0016  * All functions in this module are used by the AML Debugger only
0017  */
0018 /* Local prototypes */
0019 static void acpi_rs_out_string(const char *title, const char *value);
0020 
0021 static void acpi_rs_out_integer8(const char *title, u8 value);
0022 
0023 static void acpi_rs_out_integer16(const char *title, u16 value);
0024 
0025 static void acpi_rs_out_integer32(const char *title, u32 value);
0026 
0027 static void acpi_rs_out_integer64(const char *title, u64 value);
0028 
0029 static void acpi_rs_out_title(const char *title);
0030 
0031 static void acpi_rs_dump_byte_list(u16 length, u8 *data);
0032 
0033 static void acpi_rs_dump_word_list(u16 length, u16 *data);
0034 
0035 static void acpi_rs_dump_dword_list(u8 length, u32 *data);
0036 
0037 static void acpi_rs_dump_short_byte_list(u8 length, u8 *data);
0038 
0039 static void
0040 acpi_rs_dump_resource_source(struct acpi_resource_source *resource_source);
0041 
0042 static void
0043 acpi_rs_dump_resource_label(char *title,
0044                 struct acpi_resource_label *resource_label);
0045 
0046 static void acpi_rs_dump_address_common(union acpi_resource_data *resource);
0047 
0048 static void
0049 acpi_rs_dump_descriptor(void *resource, struct acpi_rsdump_info *table);
0050 
0051 /*******************************************************************************
0052  *
0053  * FUNCTION:    acpi_rs_dump_resource_list
0054  *
0055  * PARAMETERS:  resource_list       - Pointer to a resource descriptor list
0056  *
0057  * RETURN:      None
0058  *
0059  * DESCRIPTION: Dispatches the structure to the correct dump routine.
0060  *
0061  ******************************************************************************/
0062 
0063 void acpi_rs_dump_resource_list(struct acpi_resource *resource_list)
0064 {
0065     u32 count = 0;
0066     u32 type;
0067 
0068     ACPI_FUNCTION_ENTRY();
0069 
0070     /* Check if debug output enabled */
0071 
0072     if (!ACPI_IS_DEBUG_ENABLED(ACPI_LV_RESOURCES, _COMPONENT)) {
0073         return;
0074     }
0075 
0076     /* Walk list and dump all resource descriptors (END_TAG terminates) */
0077 
0078     do {
0079         acpi_os_printf("\n[%02X] ", count);
0080         count++;
0081 
0082         /* Validate Type before dispatch */
0083 
0084         type = resource_list->type;
0085         if (type > ACPI_RESOURCE_TYPE_MAX) {
0086             acpi_os_printf
0087                 ("Invalid descriptor type (%X) in resource list\n",
0088                  resource_list->type);
0089             return;
0090         } else if (!resource_list->type) {
0091             ACPI_ERROR((AE_INFO, "Invalid Zero Resource Type"));
0092             return;
0093         }
0094 
0095         /* Sanity check the length. It must not be zero, or we loop forever */
0096 
0097         if (!resource_list->length) {
0098             acpi_os_printf
0099                 ("Invalid zero length descriptor in resource list\n");
0100             return;
0101         }
0102 
0103         /* Dump the resource descriptor */
0104 
0105         if (type == ACPI_RESOURCE_TYPE_SERIAL_BUS) {
0106             acpi_rs_dump_descriptor(&resource_list->data,
0107                         acpi_gbl_dump_serial_bus_dispatch
0108                         [resource_list->data.
0109                          common_serial_bus.type]);
0110         } else {
0111             acpi_rs_dump_descriptor(&resource_list->data,
0112                         acpi_gbl_dump_resource_dispatch
0113                         [type]);
0114         }
0115 
0116         /* Point to the next resource structure */
0117 
0118         resource_list = ACPI_NEXT_RESOURCE(resource_list);
0119 
0120         /* Exit when END_TAG descriptor is reached */
0121 
0122     } while (type != ACPI_RESOURCE_TYPE_END_TAG);
0123 }
0124 
0125 /*******************************************************************************
0126  *
0127  * FUNCTION:    acpi_rs_dump_irq_list
0128  *
0129  * PARAMETERS:  route_table     - Pointer to the routing table to dump.
0130  *
0131  * RETURN:      None
0132  *
0133  * DESCRIPTION: Print IRQ routing table
0134  *
0135  ******************************************************************************/
0136 
0137 void acpi_rs_dump_irq_list(u8 *route_table)
0138 {
0139     struct acpi_pci_routing_table *prt_element;
0140     u8 count;
0141 
0142     ACPI_FUNCTION_ENTRY();
0143 
0144     /* Check if debug output enabled */
0145 
0146     if (!ACPI_IS_DEBUG_ENABLED(ACPI_LV_RESOURCES, _COMPONENT)) {
0147         return;
0148     }
0149 
0150     prt_element = ACPI_CAST_PTR(struct acpi_pci_routing_table, route_table);
0151 
0152     /* Dump all table elements, Exit on zero length element */
0153 
0154     for (count = 0; prt_element->length; count++) {
0155         acpi_os_printf("\n[%02X] PCI IRQ Routing Table Package\n",
0156                    count);
0157         acpi_rs_dump_descriptor(prt_element, acpi_rs_dump_prt);
0158 
0159         prt_element = ACPI_ADD_PTR(struct acpi_pci_routing_table,
0160                        prt_element, prt_element->length);
0161     }
0162 }
0163 
0164 /*******************************************************************************
0165  *
0166  * FUNCTION:    acpi_rs_dump_descriptor
0167  *
0168  * PARAMETERS:  resource            - Buffer containing the resource
0169  *              table               - Table entry to decode the resource
0170  *
0171  * RETURN:      None
0172  *
0173  * DESCRIPTION: Dump a resource descriptor based on a dump table entry.
0174  *
0175  ******************************************************************************/
0176 
0177 static void
0178 acpi_rs_dump_descriptor(void *resource, struct acpi_rsdump_info *table)
0179 {
0180     u8 *target = NULL;
0181     u8 *previous_target;
0182     const char *name;
0183     u8 count;
0184 
0185     /* First table entry must contain the table length (# of table entries) */
0186 
0187     count = table->offset;
0188 
0189     while (count) {
0190         previous_target = target;
0191         target = ACPI_ADD_PTR(u8, resource, table->offset);
0192         name = table->name;
0193 
0194         switch (table->opcode) {
0195         case ACPI_RSD_TITLE:
0196             /*
0197              * Optional resource title
0198              */
0199             if (table->name) {
0200                 acpi_os_printf("%s Resource\n", name);
0201             }
0202             break;
0203 
0204             /* Strings */
0205 
0206         case ACPI_RSD_LITERAL:
0207 
0208             acpi_rs_out_string(name,
0209                        ACPI_CAST_PTR(char, table->pointer));
0210             break;
0211 
0212         case ACPI_RSD_STRING:
0213 
0214             acpi_rs_out_string(name, ACPI_CAST_PTR(char, target));
0215             break;
0216 
0217             /* Data items, 8/16/32/64 bit */
0218 
0219         case ACPI_RSD_UINT8:
0220 
0221             if (table->pointer) {
0222                 acpi_rs_out_string(name,
0223                            table->pointer[*target]);
0224             } else {
0225                 acpi_rs_out_integer8(name, ACPI_GET8(target));
0226             }
0227             break;
0228 
0229         case ACPI_RSD_UINT16:
0230 
0231             acpi_rs_out_integer16(name, ACPI_GET16(target));
0232             break;
0233 
0234         case ACPI_RSD_UINT32:
0235 
0236             acpi_rs_out_integer32(name, ACPI_GET32(target));
0237             break;
0238 
0239         case ACPI_RSD_UINT64:
0240 
0241             acpi_rs_out_integer64(name, ACPI_GET64(target));
0242             break;
0243 
0244             /* Flags: 1-bit and 2-bit flags supported */
0245 
0246         case ACPI_RSD_1BITFLAG:
0247 
0248             acpi_rs_out_string(name,
0249                        table->pointer[*target & 0x01]);
0250             break;
0251 
0252         case ACPI_RSD_2BITFLAG:
0253 
0254             acpi_rs_out_string(name,
0255                        table->pointer[*target & 0x03]);
0256             break;
0257 
0258         case ACPI_RSD_3BITFLAG:
0259 
0260             acpi_rs_out_string(name,
0261                        table->pointer[*target & 0x07]);
0262             break;
0263 
0264         case ACPI_RSD_6BITFLAG:
0265 
0266             acpi_rs_out_integer8(name, (ACPI_GET8(target) & 0x3F));
0267             break;
0268 
0269         case ACPI_RSD_SHORTLIST:
0270             /*
0271              * Short byte list (single line output) for DMA and IRQ resources
0272              * Note: The list length is obtained from the previous table entry
0273              */
0274             if (previous_target) {
0275                 acpi_rs_out_title(name);
0276                 acpi_rs_dump_short_byte_list(*previous_target,
0277                                  target);
0278             }
0279             break;
0280 
0281         case ACPI_RSD_SHORTLISTX:
0282             /*
0283              * Short byte list (single line output) for GPIO vendor data
0284              * Note: The list length is obtained from the previous table entry
0285              */
0286             if (previous_target) {
0287                 acpi_rs_out_title(name);
0288                 acpi_rs_dump_short_byte_list(*previous_target,
0289                                  *
0290                                  (ACPI_CAST_INDIRECT_PTR
0291                                   (u8, target)));
0292             }
0293             break;
0294 
0295         case ACPI_RSD_LONGLIST:
0296             /*
0297              * Long byte list for Vendor resource data
0298              * Note: The list length is obtained from the previous table entry
0299              */
0300             if (previous_target) {
0301                 acpi_rs_dump_byte_list(ACPI_GET16
0302                                (previous_target),
0303                                target);
0304             }
0305             break;
0306 
0307         case ACPI_RSD_DWORDLIST:
0308             /*
0309              * Dword list for Extended Interrupt resources
0310              * Note: The list length is obtained from the previous table entry
0311              */
0312             if (previous_target) {
0313                 acpi_rs_dump_dword_list(*previous_target,
0314                             ACPI_CAST_PTR(u32,
0315                                       target));
0316             }
0317             break;
0318 
0319         case ACPI_RSD_WORDLIST:
0320             /*
0321              * Word list for GPIO Pin Table
0322              * Note: The list length is obtained from the previous table entry
0323              */
0324             if (previous_target) {
0325                 acpi_rs_dump_word_list(*previous_target,
0326                                *(ACPI_CAST_INDIRECT_PTR
0327                              (u16, target)));
0328             }
0329             break;
0330 
0331         case ACPI_RSD_ADDRESS:
0332             /*
0333              * Common flags for all Address resources
0334              */
0335             acpi_rs_dump_address_common(ACPI_CAST_PTR
0336                             (union acpi_resource_data,
0337                              target));
0338             break;
0339 
0340         case ACPI_RSD_SOURCE:
0341             /*
0342              * Optional resource_source for Address resources
0343              */
0344             acpi_rs_dump_resource_source(ACPI_CAST_PTR
0345                              (struct
0346                                    acpi_resource_source,
0347                                    target));
0348             break;
0349 
0350         case ACPI_RSD_LABEL:
0351             /*
0352              * resource_label
0353              */
0354             acpi_rs_dump_resource_label("Resource Label",
0355                             ACPI_CAST_PTR(struct
0356                                   acpi_resource_label,
0357                                   target));
0358             break;
0359 
0360         case ACPI_RSD_SOURCE_LABEL:
0361             /*
0362              * resource_source_label
0363              */
0364             acpi_rs_dump_resource_label("Resource Source Label",
0365                             ACPI_CAST_PTR(struct
0366                                   acpi_resource_label,
0367                                   target));
0368             break;
0369 
0370         default:
0371 
0372             acpi_os_printf("**** Invalid table opcode [%X] ****\n",
0373                        table->opcode);
0374             return;
0375         }
0376 
0377         table++;
0378         count--;
0379     }
0380 }
0381 
0382 /*******************************************************************************
0383  *
0384  * FUNCTION:    acpi_rs_dump_resource_source
0385  *
0386  * PARAMETERS:  resource_source     - Pointer to a Resource Source struct
0387  *
0388  * RETURN:      None
0389  *
0390  * DESCRIPTION: Common routine for dumping the optional resource_source and the
0391  *              corresponding resource_source_index.
0392  *
0393  ******************************************************************************/
0394 
0395 static void
0396 acpi_rs_dump_resource_source(struct acpi_resource_source *resource_source)
0397 {
0398     ACPI_FUNCTION_ENTRY();
0399 
0400     if (resource_source->index == 0xFF) {
0401         return;
0402     }
0403 
0404     acpi_rs_out_integer8("Resource Source Index", resource_source->index);
0405 
0406     acpi_rs_out_string("Resource Source",
0407                resource_source->string_ptr ?
0408                resource_source->string_ptr : "[Not Specified]");
0409 }
0410 
0411 /*******************************************************************************
0412  *
0413  * FUNCTION:    acpi_rs_dump_resource_label
0414  *
0415  * PARAMETERS:  title              - Title of the dumped resource field
0416  *              resource_label     - Pointer to a Resource Label struct
0417  *
0418  * RETURN:      None
0419  *
0420  * DESCRIPTION: Common routine for dumping the resource_label
0421  *
0422  ******************************************************************************/
0423 
0424 static void
0425 acpi_rs_dump_resource_label(char *title,
0426                 struct acpi_resource_label *resource_label)
0427 {
0428     ACPI_FUNCTION_ENTRY();
0429 
0430     acpi_rs_out_string(title,
0431                resource_label->string_ptr ?
0432                resource_label->string_ptr : "[Not Specified]");
0433 }
0434 
0435 /*******************************************************************************
0436  *
0437  * FUNCTION:    acpi_rs_dump_address_common
0438  *
0439  * PARAMETERS:  resource        - Pointer to an internal resource descriptor
0440  *
0441  * RETURN:      None
0442  *
0443  * DESCRIPTION: Dump the fields that are common to all Address resource
0444  *              descriptors
0445  *
0446  ******************************************************************************/
0447 
0448 static void acpi_rs_dump_address_common(union acpi_resource_data *resource)
0449 {
0450     ACPI_FUNCTION_ENTRY();
0451 
0452     /* Decode the type-specific flags */
0453 
0454     switch (resource->address.resource_type) {
0455     case ACPI_MEMORY_RANGE:
0456 
0457         acpi_rs_dump_descriptor(resource, acpi_rs_dump_memory_flags);
0458         break;
0459 
0460     case ACPI_IO_RANGE:
0461 
0462         acpi_rs_dump_descriptor(resource, acpi_rs_dump_io_flags);
0463         break;
0464 
0465     case ACPI_BUS_NUMBER_RANGE:
0466 
0467         acpi_rs_out_string("Resource Type", "Bus Number Range");
0468         break;
0469 
0470     default:
0471 
0472         acpi_rs_out_integer8("Resource Type",
0473                      (u8) resource->address.resource_type);
0474         break;
0475     }
0476 
0477     /* Decode the general flags */
0478 
0479     acpi_rs_dump_descriptor(resource, acpi_rs_dump_general_flags);
0480 }
0481 
0482 /*******************************************************************************
0483  *
0484  * FUNCTION:    acpi_rs_out*
0485  *
0486  * PARAMETERS:  title       - Name of the resource field
0487  *              value       - Value of the resource field
0488  *
0489  * RETURN:      None
0490  *
0491  * DESCRIPTION: Miscellaneous helper functions to consistently format the
0492  *              output of the resource dump routines
0493  *
0494  ******************************************************************************/
0495 
0496 static void acpi_rs_out_string(const char *title, const char *value)
0497 {
0498 
0499     acpi_os_printf("%27s : %s", title, value);
0500     if (!*value) {
0501         acpi_os_printf("[NULL NAMESTRING]");
0502     }
0503     acpi_os_printf("\n");
0504 }
0505 
0506 static void acpi_rs_out_integer8(const char *title, u8 value)
0507 {
0508     acpi_os_printf("%27s : %2.2X\n", title, value);
0509 }
0510 
0511 static void acpi_rs_out_integer16(const char *title, u16 value)
0512 {
0513 
0514     acpi_os_printf("%27s : %4.4X\n", title, value);
0515 }
0516 
0517 static void acpi_rs_out_integer32(const char *title, u32 value)
0518 {
0519 
0520     acpi_os_printf("%27s : %8.8X\n", title, value);
0521 }
0522 
0523 static void acpi_rs_out_integer64(const char *title, u64 value)
0524 {
0525 
0526     acpi_os_printf("%27s : %8.8X%8.8X\n", title, ACPI_FORMAT_UINT64(value));
0527 }
0528 
0529 static void acpi_rs_out_title(const char *title)
0530 {
0531 
0532     acpi_os_printf("%27s : ", title);
0533 }
0534 
0535 /*******************************************************************************
0536  *
0537  * FUNCTION:    acpi_rs_dump*List
0538  *
0539  * PARAMETERS:  length      - Number of elements in the list
0540  *              data        - Start of the list
0541  *
0542  * RETURN:      None
0543  *
0544  * DESCRIPTION: Miscellaneous functions to dump lists of raw data
0545  *
0546  ******************************************************************************/
0547 
0548 static void acpi_rs_dump_byte_list(u16 length, u8 * data)
0549 {
0550     u16 i;
0551 
0552     for (i = 0; i < length; i++) {
0553         acpi_os_printf("%25s%2.2X : %2.2X\n", "Byte", i, data[i]);
0554     }
0555 }
0556 
0557 static void acpi_rs_dump_short_byte_list(u8 length, u8 * data)
0558 {
0559     u8 i;
0560 
0561     for (i = 0; i < length; i++) {
0562         acpi_os_printf("%X ", data[i]);
0563     }
0564 
0565     acpi_os_printf("\n");
0566 }
0567 
0568 static void acpi_rs_dump_dword_list(u8 length, u32 * data)
0569 {
0570     u8 i;
0571 
0572     for (i = 0; i < length; i++) {
0573         acpi_os_printf("%25s%2.2X : %8.8X\n", "Dword", i, data[i]);
0574     }
0575 }
0576 
0577 static void acpi_rs_dump_word_list(u16 length, u16 *data)
0578 {
0579     u16 i;
0580 
0581     for (i = 0; i < length; i++) {
0582         acpi_os_printf("%25s%2.2X : %4.4X\n", "Word", i, data[i]);
0583     }
0584 }