587 lines · c
1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.02/*******************************************************************************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_RESOURCES13ACPI_MODULE_NAME("rsdump")14 15/*16 * All functions in this module are used by the AML Debugger only17 */18/* Local prototypes */19static void acpi_rs_out_string(const char *title, const char *value);20 21static void acpi_rs_out_integer8(const char *title, u8 value);22 23static void acpi_rs_out_integer16(const char *title, u16 value);24 25static void acpi_rs_out_integer32(const char *title, u32 value);26 27static void acpi_rs_out_integer64(const char *title, u64 value);28 29static void acpi_rs_out_title(const char *title);30 31static void acpi_rs_dump_byte_list(u16 length, u8 *data);32 33static void acpi_rs_dump_word_list(u16 length, u16 *data);34 35static void acpi_rs_dump_dword_list(u8 length, u32 *data);36 37static void acpi_rs_dump_short_byte_list(u8 length, u8 *data);38 39static void40acpi_rs_dump_resource_source(struct acpi_resource_source *resource_source);41 42static void43acpi_rs_dump_resource_label(char *title,44 struct acpi_resource_label *resource_label);45 46static void acpi_rs_dump_address_common(union acpi_resource_data *resource);47 48static void49acpi_rs_dump_descriptor(void *resource, struct acpi_rsdump_info *table);50 51#ifdef ACPI_DEBUGGER52/*******************************************************************************53 *54 * FUNCTION: acpi_rs_dump_resource_list55 *56 * PARAMETERS: resource_list - Pointer to a resource descriptor list57 *58 * RETURN: None59 *60 * DESCRIPTION: Dispatches the structure to the correct dump routine.61 *62 ******************************************************************************/63 64void acpi_rs_dump_resource_list(struct acpi_resource *resource_list)65{66 u32 count = 0;67 u32 type;68 69 ACPI_FUNCTION_ENTRY();70 71 /* Check if debug output enabled */72 73 if (!ACPI_IS_DEBUG_ENABLED(ACPI_LV_RESOURCES, _COMPONENT)) {74 return;75 }76 77 /* Walk list and dump all resource descriptors (END_TAG terminates) */78 79 do {80 acpi_os_printf("\n[%02X] ", count);81 count++;82 83 /* Validate Type before dispatch */84 85 type = resource_list->type;86 if (type > ACPI_RESOURCE_TYPE_MAX) {87 acpi_os_printf88 ("Invalid descriptor type (%X) in resource list\n",89 resource_list->type);90 return;91 } else if (!resource_list->type) {92 ACPI_ERROR((AE_INFO, "Invalid Zero Resource Type"));93 return;94 }95 96 /* Sanity check the length. It must not be zero, or we loop forever */97 98 if (!resource_list->length) {99 acpi_os_printf100 ("Invalid zero length descriptor in resource list\n");101 return;102 }103 104 /* Dump the resource descriptor */105 106 if (type == ACPI_RESOURCE_TYPE_SERIAL_BUS) {107 acpi_rs_dump_descriptor(&resource_list->data,108 acpi_gbl_dump_serial_bus_dispatch109 [resource_list->data.110 common_serial_bus.type]);111 } else {112 acpi_rs_dump_descriptor(&resource_list->data,113 acpi_gbl_dump_resource_dispatch114 [type]);115 }116 117 /* Point to the next resource structure */118 119 resource_list = ACPI_NEXT_RESOURCE(resource_list);120 121 /* Exit when END_TAG descriptor is reached */122 123 } while (type != ACPI_RESOURCE_TYPE_END_TAG);124}125 126/*******************************************************************************127 *128 * FUNCTION: acpi_rs_dump_irq_list129 *130 * PARAMETERS: route_table - Pointer to the routing table to dump.131 *132 * RETURN: None133 *134 * DESCRIPTION: Print IRQ routing table135 *136 ******************************************************************************/137 138void acpi_rs_dump_irq_list(u8 *route_table)139{140 struct acpi_pci_routing_table *prt_element;141 u8 count;142 143 ACPI_FUNCTION_ENTRY();144 145 /* Check if debug output enabled */146 147 if (!ACPI_IS_DEBUG_ENABLED(ACPI_LV_RESOURCES, _COMPONENT)) {148 return;149 }150 151 prt_element = ACPI_CAST_PTR(struct acpi_pci_routing_table, route_table);152 153 /* Dump all table elements, Exit on zero length element */154 155 for (count = 0; prt_element->length; count++) {156 acpi_os_printf("\n[%02X] PCI IRQ Routing Table Package\n",157 count);158 acpi_rs_dump_descriptor(prt_element, acpi_rs_dump_prt);159 160 prt_element = ACPI_ADD_PTR(struct acpi_pci_routing_table,161 prt_element, prt_element->length);162 }163}164#endif165 166/*******************************************************************************167 *168 * FUNCTION: acpi_rs_dump_descriptor169 *170 * PARAMETERS: resource - Buffer containing the resource171 * table - Table entry to decode the resource172 *173 * RETURN: None174 *175 * DESCRIPTION: Dump a resource descriptor based on a dump table entry.176 *177 ******************************************************************************/178 179static void180acpi_rs_dump_descriptor(void *resource, struct acpi_rsdump_info *table)181{182 u8 *target = NULL;183 u8 *previous_target;184 const char *name;185 u8 count;186 187 /* First table entry must contain the table length (# of table entries) */188 189 count = table->offset;190 191 while (count) {192 previous_target = target;193 target = ACPI_ADD_PTR(u8, resource, table->offset);194 name = table->name;195 196 switch (table->opcode) {197 case ACPI_RSD_TITLE:198 /*199 * Optional resource title200 */201 if (table->name) {202 acpi_os_printf("%s Resource\n", name);203 }204 break;205 206 /* Strings */207 208 case ACPI_RSD_LITERAL:209 210 acpi_rs_out_string(name,211 ACPI_CAST_PTR(char, table->pointer));212 break;213 214 case ACPI_RSD_STRING:215 216 acpi_rs_out_string(name, ACPI_CAST_PTR(char, target));217 break;218 219 /* Data items, 8/16/32/64 bit */220 221 case ACPI_RSD_UINT8:222 223 if (table->pointer) {224 acpi_rs_out_string(name,225 table->pointer[*target]);226 } else {227 acpi_rs_out_integer8(name, ACPI_GET8(target));228 }229 break;230 231 case ACPI_RSD_UINT16:232 233 acpi_rs_out_integer16(name, ACPI_GET16(target));234 break;235 236 case ACPI_RSD_UINT32:237 238 acpi_rs_out_integer32(name, ACPI_GET32(target));239 break;240 241 case ACPI_RSD_UINT64:242 243 acpi_rs_out_integer64(name, ACPI_GET64(target));244 break;245 246 /* Flags: 1-bit and 2-bit flags supported */247 248 case ACPI_RSD_1BITFLAG:249 250 acpi_rs_out_string(name,251 table->pointer[*target & 0x01]);252 break;253 254 case ACPI_RSD_2BITFLAG:255 256 acpi_rs_out_string(name,257 table->pointer[*target & 0x03]);258 break;259 260 case ACPI_RSD_3BITFLAG:261 262 acpi_rs_out_string(name,263 table->pointer[*target & 0x07]);264 break;265 266 case ACPI_RSD_6BITFLAG:267 268 acpi_rs_out_integer8(name, (ACPI_GET8(target) & 0x3F));269 break;270 271 case ACPI_RSD_SHORTLIST:272 /*273 * Short byte list (single line output) for DMA and IRQ resources274 * Note: The list length is obtained from the previous table entry275 */276 if (previous_target) {277 acpi_rs_out_title(name);278 acpi_rs_dump_short_byte_list(*previous_target,279 target);280 }281 break;282 283 case ACPI_RSD_SHORTLISTX:284 /*285 * Short byte list (single line output) for GPIO vendor data286 * Note: The list length is obtained from the previous table entry287 */288 if (previous_target) {289 acpi_rs_out_title(name);290 acpi_rs_dump_short_byte_list(*previous_target,291 *292 (ACPI_CAST_INDIRECT_PTR293 (u8, target)));294 }295 break;296 297 case ACPI_RSD_LONGLIST:298 /*299 * Long byte list for Vendor resource data300 * Note: The list length is obtained from the previous table entry301 */302 if (previous_target) {303 acpi_rs_dump_byte_list(ACPI_GET16304 (previous_target),305 target);306 }307 break;308 309 case ACPI_RSD_DWORDLIST:310 /*311 * Dword list for Extended Interrupt resources312 * Note: The list length is obtained from the previous table entry313 */314 if (previous_target) {315 acpi_rs_dump_dword_list(*previous_target,316 ACPI_CAST_PTR(u32,317 target));318 }319 break;320 321 case ACPI_RSD_WORDLIST:322 /*323 * Word list for GPIO Pin Table324 * Note: The list length is obtained from the previous table entry325 */326 if (previous_target) {327 acpi_rs_dump_word_list(*previous_target,328 *(ACPI_CAST_INDIRECT_PTR329 (u16, target)));330 }331 break;332 333 case ACPI_RSD_ADDRESS:334 /*335 * Common flags for all Address resources336 */337 acpi_rs_dump_address_common(ACPI_CAST_PTR338 (union acpi_resource_data,339 target));340 break;341 342 case ACPI_RSD_SOURCE:343 /*344 * Optional resource_source for Address resources345 */346 acpi_rs_dump_resource_source(ACPI_CAST_PTR347 (struct348 acpi_resource_source,349 target));350 break;351 352 case ACPI_RSD_LABEL:353 /*354 * resource_label355 */356 acpi_rs_dump_resource_label("Resource Label",357 ACPI_CAST_PTR(struct358 acpi_resource_label,359 target));360 break;361 362 case ACPI_RSD_SOURCE_LABEL:363 /*364 * resource_source_label365 */366 acpi_rs_dump_resource_label("Resource Source Label",367 ACPI_CAST_PTR(struct368 acpi_resource_label,369 target));370 break;371 372 default:373 374 acpi_os_printf("**** Invalid table opcode [%X] ****\n",375 table->opcode);376 return;377 }378 379 table++;380 count--;381 }382}383 384/*******************************************************************************385 *386 * FUNCTION: acpi_rs_dump_resource_source387 *388 * PARAMETERS: resource_source - Pointer to a Resource Source struct389 *390 * RETURN: None391 *392 * DESCRIPTION: Common routine for dumping the optional resource_source and the393 * corresponding resource_source_index.394 *395 ******************************************************************************/396 397static void398acpi_rs_dump_resource_source(struct acpi_resource_source *resource_source)399{400 ACPI_FUNCTION_ENTRY();401 402 if (resource_source->index == 0xFF) {403 return;404 }405 406 acpi_rs_out_integer8("Resource Source Index", resource_source->index);407 408 acpi_rs_out_string("Resource Source",409 resource_source->string_ptr ?410 resource_source->string_ptr : "[Not Specified]");411}412 413/*******************************************************************************414 *415 * FUNCTION: acpi_rs_dump_resource_label416 *417 * PARAMETERS: title - Title of the dumped resource field418 * resource_label - Pointer to a Resource Label struct419 *420 * RETURN: None421 *422 * DESCRIPTION: Common routine for dumping the resource_label423 *424 ******************************************************************************/425 426static void427acpi_rs_dump_resource_label(char *title,428 struct acpi_resource_label *resource_label)429{430 ACPI_FUNCTION_ENTRY();431 432 acpi_rs_out_string(title,433 resource_label->string_ptr ?434 resource_label->string_ptr : "[Not Specified]");435}436 437/*******************************************************************************438 *439 * FUNCTION: acpi_rs_dump_address_common440 *441 * PARAMETERS: resource - Pointer to an internal resource descriptor442 *443 * RETURN: None444 *445 * DESCRIPTION: Dump the fields that are common to all Address resource446 * descriptors447 *448 ******************************************************************************/449 450static void acpi_rs_dump_address_common(union acpi_resource_data *resource)451{452 ACPI_FUNCTION_ENTRY();453 454 /* Decode the type-specific flags */455 456 switch (resource->address.resource_type) {457 case ACPI_MEMORY_RANGE:458 459 acpi_rs_dump_descriptor(resource, acpi_rs_dump_memory_flags);460 break;461 462 case ACPI_IO_RANGE:463 464 acpi_rs_dump_descriptor(resource, acpi_rs_dump_io_flags);465 break;466 467 case ACPI_BUS_NUMBER_RANGE:468 469 acpi_rs_out_string("Resource Type", "Bus Number Range");470 break;471 472 default:473 474 acpi_rs_out_integer8("Resource Type",475 (u8) resource->address.resource_type);476 break;477 }478 479 /* Decode the general flags */480 481 acpi_rs_dump_descriptor(resource, acpi_rs_dump_general_flags);482}483 484/*******************************************************************************485 *486 * FUNCTION: acpi_rs_out*487 *488 * PARAMETERS: title - Name of the resource field489 * value - Value of the resource field490 *491 * RETURN: None492 *493 * DESCRIPTION: Miscellaneous helper functions to consistently format the494 * output of the resource dump routines495 *496 ******************************************************************************/497 498static void acpi_rs_out_string(const char *title, const char *value)499{500 501 acpi_os_printf("%27s : %s", title, value);502 if (!*value) {503 acpi_os_printf("[NULL NAMESTRING]");504 }505 acpi_os_printf("\n");506}507 508static void acpi_rs_out_integer8(const char *title, u8 value)509{510 acpi_os_printf("%27s : %2.2X\n", title, value);511}512 513static void acpi_rs_out_integer16(const char *title, u16 value)514{515 516 acpi_os_printf("%27s : %4.4X\n", title, value);517}518 519static void acpi_rs_out_integer32(const char *title, u32 value)520{521 522 acpi_os_printf("%27s : %8.8X\n", title, value);523}524 525static void acpi_rs_out_integer64(const char *title, u64 value)526{527 528 acpi_os_printf("%27s : %8.8X%8.8X\n", title, ACPI_FORMAT_UINT64(value));529}530 531static void acpi_rs_out_title(const char *title)532{533 534 acpi_os_printf("%27s : ", title);535}536 537/*******************************************************************************538 *539 * FUNCTION: acpi_rs_dump*List540 *541 * PARAMETERS: length - Number of elements in the list542 * data - Start of the list543 *544 * RETURN: None545 *546 * DESCRIPTION: Miscellaneous functions to dump lists of raw data547 *548 ******************************************************************************/549 550static void acpi_rs_dump_byte_list(u16 length, u8 * data)551{552 u16 i;553 554 for (i = 0; i < length; i++) {555 acpi_os_printf("%25s%2.2X : %2.2X\n", "Byte", i, data[i]);556 }557}558 559static void acpi_rs_dump_short_byte_list(u8 length, u8 * data)560{561 u8 i;562 563 for (i = 0; i < length; i++) {564 acpi_os_printf("%X ", data[i]);565 }566 567 acpi_os_printf("\n");568}569 570static void acpi_rs_dump_dword_list(u8 length, u32 * data)571{572 u8 i;573 574 for (i = 0; i < length; i++) {575 acpi_os_printf("%25s%2.2X : %8.8X\n", "Dword", i, data[i]);576 }577}578 579static void acpi_rs_dump_word_list(u16 length, u16 *data)580{581 u16 i;582 583 for (i = 0; i < length; i++) {584 acpi_os_printf("%25s%2.2X : %4.4X\n", "Word", i, data[i]);585 }586}587