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