1 /******************************************************************************* 2 * 3 * Module Name: dbcmds - Miscellaneous debug commands and output routines 4 * 5 ******************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2012, 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 45 #include <contrib/dev/acpica/include/acpi.h> 46 #include <contrib/dev/acpica/include/accommon.h> 47 #include <contrib/dev/acpica/include/acevents.h> 48 #include <contrib/dev/acpica/include/acdebug.h> 49 #include <contrib/dev/acpica/include/acnamesp.h> 50 #include <contrib/dev/acpica/include/acresrc.h> 51 #include <contrib/dev/acpica/include/actables.h> 52 53 #ifdef ACPI_DEBUGGER 54 55 #define _COMPONENT ACPI_CA_DEBUGGER 56 ACPI_MODULE_NAME ("dbcmds") 57 58 59 /* Local prototypes */ 60 61 static void 62 AcpiDmCompareAmlResources ( 63 UINT8 *Aml1Buffer, 64 ACPI_RSDESC_SIZE Aml1BufferLength, 65 UINT8 *Aml2Buffer, 66 ACPI_RSDESC_SIZE Aml2BufferLength); 67 68 static ACPI_STATUS 69 AcpiDmTestResourceConversion ( 70 ACPI_NAMESPACE_NODE *Node, 71 char *Name); 72 73 static ACPI_STATUS 74 AcpiDbResourceCallback ( 75 ACPI_RESOURCE *Resource, 76 void *Context); 77 78 static ACPI_STATUS 79 AcpiDbDeviceResources ( 80 ACPI_HANDLE ObjHandle, 81 UINT32 NestingLevel, 82 void *Context, 83 void **ReturnValue); 84 85 86 /******************************************************************************* 87 * 88 * FUNCTION: AcpiDbConvertToNode 89 * 90 * PARAMETERS: InString - String to convert 91 * 92 * RETURN: Pointer to a NS node 93 * 94 * DESCRIPTION: Convert a string to a valid NS pointer. Handles numeric or 95 * alpha strings. 96 * 97 ******************************************************************************/ 98 99 ACPI_NAMESPACE_NODE * 100 AcpiDbConvertToNode ( 101 char *InString) 102 { 103 ACPI_NAMESPACE_NODE *Node; 104 105 106 if ((*InString >= 0x30) && (*InString <= 0x39)) 107 { 108 /* Numeric argument, convert */ 109 110 Node = ACPI_TO_POINTER (ACPI_STRTOUL (InString, NULL, 16)); 111 if (!AcpiOsReadable (Node, sizeof (ACPI_NAMESPACE_NODE))) 112 { 113 AcpiOsPrintf ("Address %p is invalid in this address space\n", 114 Node); 115 return (NULL); 116 } 117 118 /* Make sure pointer is valid NS node */ 119 120 if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED) 121 { 122 AcpiOsPrintf ("Address %p is not a valid NS node [%s]\n", 123 Node, AcpiUtGetDescriptorName (Node)); 124 return (NULL); 125 } 126 } 127 else 128 { 129 /* Alpha argument */ 130 /* The parameter is a name string that must be resolved to a 131 * Named obj 132 */ 133 Node = AcpiDbLocalNsLookup (InString); 134 if (!Node) 135 { 136 Node = AcpiGbl_RootNode; 137 } 138 } 139 140 return (Node); 141 } 142 143 144 /******************************************************************************* 145 * 146 * FUNCTION: AcpiDbSleep 147 * 148 * PARAMETERS: ObjectArg - Desired sleep state (0-5) 149 * 150 * RETURN: Status 151 * 152 * DESCRIPTION: Simulate a sleep/wake sequence 153 * 154 ******************************************************************************/ 155 156 ACPI_STATUS 157 AcpiDbSleep ( 158 char *ObjectArg) 159 { 160 ACPI_STATUS Status; 161 UINT8 SleepState; 162 163 164 ACPI_FUNCTION_TRACE (AcpiDbSleep); 165 166 167 SleepState = (UINT8) ACPI_STRTOUL (ObjectArg, NULL, 0); 168 169 AcpiOsPrintf ("**** Prepare to sleep ****\n"); 170 Status = AcpiEnterSleepStatePrep (SleepState); 171 if (ACPI_FAILURE (Status)) 172 { 173 goto ErrorExit; 174 } 175 176 AcpiOsPrintf ("**** Going to sleep ****\n"); 177 Status = AcpiEnterSleepState (SleepState, ACPI_NO_OPTIONAL_METHODS); 178 if (ACPI_FAILURE (Status)) 179 { 180 goto ErrorExit; 181 } 182 183 AcpiOsPrintf ("**** Prepare to return from sleep ****\n"); 184 Status = AcpiLeaveSleepStatePrep (SleepState, ACPI_NO_OPTIONAL_METHODS); 185 if (ACPI_FAILURE (Status)) 186 { 187 goto ErrorExit; 188 } 189 190 AcpiOsPrintf ("**** Returning from sleep ****\n"); 191 Status = AcpiLeaveSleepState (SleepState); 192 if (ACPI_FAILURE (Status)) 193 { 194 goto ErrorExit; 195 } 196 197 return (Status); 198 199 200 ErrorExit: 201 202 ACPI_EXCEPTION ((AE_INFO, Status, "During sleep test")); 203 return (Status); 204 } 205 206 207 /******************************************************************************* 208 * 209 * FUNCTION: AcpiDbDisplayLocks 210 * 211 * PARAMETERS: None 212 * 213 * RETURN: None 214 * 215 * DESCRIPTION: Display information about internal mutexes. 216 * 217 ******************************************************************************/ 218 219 void 220 AcpiDbDisplayLocks ( 221 void) 222 { 223 UINT32 i; 224 225 226 for (i = 0; i < ACPI_MAX_MUTEX; i++) 227 { 228 AcpiOsPrintf ("%26s : %s\n", AcpiUtGetMutexName (i), 229 AcpiGbl_MutexInfo[i].ThreadId == ACPI_MUTEX_NOT_ACQUIRED 230 ? "Locked" : "Unlocked"); 231 } 232 } 233 234 235 /******************************************************************************* 236 * 237 * FUNCTION: AcpiDbDisplayTableInfo 238 * 239 * PARAMETERS: TableArg - String with name of table to be displayed 240 * 241 * RETURN: None 242 * 243 * DESCRIPTION: Display information about loaded tables. Current 244 * implementation displays all loaded tables. 245 * 246 ******************************************************************************/ 247 248 void 249 AcpiDbDisplayTableInfo ( 250 char *TableArg) 251 { 252 UINT32 i; 253 ACPI_TABLE_DESC *TableDesc; 254 ACPI_STATUS Status; 255 256 257 /* Walk the entire root table list */ 258 259 for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++) 260 { 261 TableDesc = &AcpiGbl_RootTableList.Tables[i]; 262 AcpiOsPrintf ("%u ", i); 263 264 /* Make sure that the table is mapped */ 265 266 Status = AcpiTbVerifyTable (TableDesc); 267 if (ACPI_FAILURE (Status)) 268 { 269 return; 270 } 271 272 /* Dump the table header */ 273 274 if (TableDesc->Pointer) 275 { 276 AcpiTbPrintTableHeader (TableDesc->Address, TableDesc->Pointer); 277 } 278 else 279 { 280 /* If the pointer is null, the table has been unloaded */ 281 282 ACPI_INFO ((AE_INFO, "%4.4s - Table has been unloaded", 283 TableDesc->Signature.Ascii)); 284 } 285 } 286 } 287 288 289 /******************************************************************************* 290 * 291 * FUNCTION: AcpiDbUnloadAcpiTable 292 * 293 * PARAMETERS: TableArg - Name of the table to be unloaded 294 * InstanceArg - Which instance of the table to unload (if 295 * there are multiple tables of the same type) 296 * 297 * RETURN: Nonde 298 * 299 * DESCRIPTION: Unload an ACPI table. 300 * Instance is not implemented 301 * 302 ******************************************************************************/ 303 304 void 305 AcpiDbUnloadAcpiTable ( 306 char *TableArg, 307 char *InstanceArg) 308 { 309 /* TBD: Need to reimplement for new data structures */ 310 311 #if 0 312 UINT32 i; 313 ACPI_STATUS Status; 314 315 316 /* Search all tables for the target type */ 317 318 for (i = 0; i < (ACPI_TABLE_ID_MAX+1); i++) 319 { 320 if (!ACPI_STRNCMP (TableArg, AcpiGbl_TableData[i].Signature, 321 AcpiGbl_TableData[i].SigLength)) 322 { 323 /* Found the table, unload it */ 324 325 Status = AcpiUnloadTable (i); 326 if (ACPI_SUCCESS (Status)) 327 { 328 AcpiOsPrintf ("[%s] unloaded and uninstalled\n", TableArg); 329 } 330 else 331 { 332 AcpiOsPrintf ("%s, while unloading [%s]\n", 333 AcpiFormatException (Status), TableArg); 334 } 335 336 return; 337 } 338 } 339 340 AcpiOsPrintf ("Unknown table type [%s]\n", TableArg); 341 #endif 342 } 343 344 345 /******************************************************************************* 346 * 347 * FUNCTION: AcpiDbSendNotify 348 * 349 * PARAMETERS: Name - Name of ACPI object to send the notify to 350 * Value - Value of the notify to send. 351 * 352 * RETURN: None 353 * 354 * DESCRIPTION: Send an ACPI notification. The value specified is sent to the 355 * named object as an ACPI notify. 356 * 357 ******************************************************************************/ 358 359 void 360 AcpiDbSendNotify ( 361 char *Name, 362 UINT32 Value) 363 { 364 ACPI_NAMESPACE_NODE *Node; 365 ACPI_STATUS Status; 366 367 368 /* Translate name to an Named object */ 369 370 Node = AcpiDbConvertToNode (Name); 371 if (!Node) 372 { 373 return; 374 } 375 376 /* Dispatch the notify if legal */ 377 378 if (AcpiEvIsNotifyObject (Node)) 379 { 380 Status = AcpiEvQueueNotifyRequest (Node, Value); 381 if (ACPI_FAILURE (Status)) 382 { 383 AcpiOsPrintf ("Could not queue notify\n"); 384 } 385 } 386 else 387 { 388 AcpiOsPrintf ("Named object [%4.4s] Type %s, must be Device/Thermal/Processor type\n", 389 AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Node->Type)); 390 } 391 } 392 393 394 /******************************************************************************* 395 * 396 * FUNCTION: AcpiDbDisplayInterfaces 397 * 398 * PARAMETERS: ActionArg - Null, "install", or "remove" 399 * InterfaceNameArg - Name for install/remove options 400 * 401 * RETURN: None 402 * 403 * DESCRIPTION: Display or modify the global _OSI interface list 404 * 405 ******************************************************************************/ 406 407 void 408 AcpiDbDisplayInterfaces ( 409 char *ActionArg, 410 char *InterfaceNameArg) 411 { 412 ACPI_INTERFACE_INFO *NextInterface; 413 char *SubString; 414 ACPI_STATUS Status; 415 416 417 /* If no arguments, just display current interface list */ 418 419 if (!ActionArg) 420 { 421 (void) AcpiOsAcquireMutex (AcpiGbl_OsiMutex, 422 ACPI_WAIT_FOREVER); 423 424 NextInterface = AcpiGbl_SupportedInterfaces; 425 426 while (NextInterface) 427 { 428 if (!(NextInterface->Flags & ACPI_OSI_INVALID)) 429 { 430 AcpiOsPrintf ("%s\n", NextInterface->Name); 431 } 432 NextInterface = NextInterface->Next; 433 } 434 435 AcpiOsReleaseMutex (AcpiGbl_OsiMutex); 436 return; 437 } 438 439 /* If ActionArg exists, so must InterfaceNameArg */ 440 441 if (!InterfaceNameArg) 442 { 443 AcpiOsPrintf ("Missing Interface Name argument\n"); 444 return; 445 } 446 447 /* Uppercase the action for match below */ 448 449 AcpiUtStrupr (ActionArg); 450 451 /* Install - install an interface */ 452 453 SubString = ACPI_STRSTR ("INSTALL", ActionArg); 454 if (SubString) 455 { 456 Status = AcpiInstallInterface (InterfaceNameArg); 457 if (ACPI_FAILURE (Status)) 458 { 459 AcpiOsPrintf ("%s, while installing \"%s\"\n", 460 AcpiFormatException (Status), InterfaceNameArg); 461 } 462 return; 463 } 464 465 /* Remove - remove an interface */ 466 467 SubString = ACPI_STRSTR ("REMOVE", ActionArg); 468 if (SubString) 469 { 470 Status = AcpiRemoveInterface (InterfaceNameArg); 471 if (ACPI_FAILURE (Status)) 472 { 473 AcpiOsPrintf ("%s, while removing \"%s\"\n", 474 AcpiFormatException (Status), InterfaceNameArg); 475 } 476 return; 477 } 478 479 /* Invalid ActionArg */ 480 481 AcpiOsPrintf ("Invalid action argument: %s\n", ActionArg); 482 return; 483 } 484 485 486 /******************************************************************************* 487 * 488 * FUNCTION: AcpiDbDisplayTemplate 489 * 490 * PARAMETERS: BufferArg - Buffer name or addrss 491 * 492 * RETURN: None 493 * 494 * DESCRIPTION: Dump a buffer that contains a resource template 495 * 496 ******************************************************************************/ 497 498 void 499 AcpiDbDisplayTemplate ( 500 char *BufferArg) 501 { 502 ACPI_NAMESPACE_NODE *Node; 503 ACPI_STATUS Status; 504 ACPI_BUFFER ReturnObj; 505 506 507 /* Translate BufferArg to an Named object */ 508 509 Node = AcpiDbConvertToNode (BufferArg); 510 if (!Node || (Node == AcpiGbl_RootNode)) 511 { 512 AcpiOsPrintf ("Invalid argument: %s\n", BufferArg); 513 return; 514 } 515 516 /* We must have a buffer object */ 517 518 if (Node->Type != ACPI_TYPE_BUFFER) 519 { 520 AcpiOsPrintf ("Not a Buffer object, cannot be a template: %s\n", 521 BufferArg); 522 return; 523 } 524 525 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE; 526 ReturnObj.Pointer = AcpiGbl_DbBuffer; 527 528 /* Attempt to convert the raw buffer to a resource list */ 529 530 Status = AcpiRsCreateResourceList (Node->Object, &ReturnObj); 531 532 AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT); 533 AcpiDbgLevel |= ACPI_LV_RESOURCES; 534 535 if (ACPI_FAILURE (Status)) 536 { 537 AcpiOsPrintf ("Could not convert Buffer to a resource list: %s, %s\n", 538 BufferArg, AcpiFormatException (Status)); 539 goto DumpBuffer; 540 } 541 542 /* Now we can dump the resource list */ 543 544 AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE, 545 ReturnObj.Pointer)); 546 547 DumpBuffer: 548 AcpiOsPrintf ("\nRaw data buffer:\n"); 549 AcpiUtDumpBuffer ((UINT8 *) Node->Object->Buffer.Pointer, 550 Node->Object->Buffer.Length, 551 DB_BYTE_DISPLAY, ACPI_UINT32_MAX); 552 553 AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); 554 return; 555 } 556 557 558 /******************************************************************************* 559 * 560 * FUNCTION: AcpiDmCompareAmlResources 561 * 562 * PARAMETERS: Aml1Buffer - Contains first resource list 563 * Aml1BufferLength - Length of first resource list 564 * Aml2Buffer - Contains second resource list 565 * Aml2BufferLength - Length of second resource list 566 * 567 * RETURN: None 568 * 569 * DESCRIPTION: Compare two AML resource lists, descriptor by descriptor (in 570 * order to isolate a miscompare to an individual resource) 571 * 572 ******************************************************************************/ 573 574 static void 575 AcpiDmCompareAmlResources ( 576 UINT8 *Aml1Buffer, 577 ACPI_RSDESC_SIZE Aml1BufferLength, 578 UINT8 *Aml2Buffer, 579 ACPI_RSDESC_SIZE Aml2BufferLength) 580 { 581 UINT8 *Aml1; 582 UINT8 *Aml2; 583 UINT8 *Aml1End; 584 UINT8 *Aml2End; 585 ACPI_RSDESC_SIZE Aml1Length; 586 ACPI_RSDESC_SIZE Aml2Length; 587 ACPI_RSDESC_SIZE Offset = 0; 588 UINT8 ResourceType; 589 UINT32 Count = 0; 590 UINT32 i; 591 592 593 /* Compare overall buffer sizes (may be different due to size rounding) */ 594 595 if (Aml1BufferLength != Aml2BufferLength) 596 { 597 AcpiOsPrintf ( 598 "**** Buffer length mismatch in converted AML: Original %X, New %X ****\n", 599 Aml1BufferLength, Aml2BufferLength); 600 } 601 602 Aml1 = Aml1Buffer; 603 Aml2 = Aml2Buffer; 604 Aml1End = Aml1Buffer + Aml1BufferLength; 605 Aml2End = Aml2Buffer + Aml2BufferLength; 606 607 /* Walk the descriptor lists, comparing each descriptor */ 608 609 while ((Aml1 < Aml1End) && (Aml2 < Aml2End)) 610 { 611 /* Get the lengths of each descriptor */ 612 613 Aml1Length = AcpiUtGetDescriptorLength (Aml1); 614 Aml2Length = AcpiUtGetDescriptorLength (Aml2); 615 ResourceType = AcpiUtGetResourceType (Aml1); 616 617 /* Check for descriptor length match */ 618 619 if (Aml1Length != Aml2Length) 620 { 621 AcpiOsPrintf ( 622 "**** Length mismatch in descriptor [%.2X] type %2.2X, Offset %8.8X Len1 %X, Len2 %X ****\n", 623 Count, ResourceType, Offset, Aml1Length, Aml2Length); 624 } 625 626 /* Check for descriptor byte match */ 627 628 else if (ACPI_MEMCMP (Aml1, Aml2, Aml1Length)) 629 { 630 AcpiOsPrintf ( 631 "**** Data mismatch in descriptor [%.2X] type %2.2X, Offset %8.8X ****\n", 632 Count, ResourceType, Offset); 633 634 for (i = 0; i < Aml1Length; i++) 635 { 636 if (Aml1[i] != Aml2[i]) 637 { 638 AcpiOsPrintf ("Mismatch at byte offset %.2X: is %2.2X, should be %2.2X\n", 639 i, Aml2[i], Aml1[i]); 640 } 641 } 642 } 643 644 /* Exit on EndTag descriptor */ 645 646 if (ResourceType == ACPI_RESOURCE_NAME_END_TAG) 647 { 648 return; 649 } 650 651 /* Point to next descriptor in each buffer */ 652 653 Count++; 654 Offset += Aml1Length; 655 Aml1 += Aml1Length; 656 Aml2 += Aml2Length; 657 } 658 } 659 660 661 /******************************************************************************* 662 * 663 * FUNCTION: AcpiDmTestResourceConversion 664 * 665 * PARAMETERS: Node - Parent device node 666 * Name - resource method name (_CRS) 667 * 668 * RETURN: Status 669 * 670 * DESCRIPTION: Compare the original AML with a conversion of the AML to 671 * internal resource list, then back to AML. 672 * 673 ******************************************************************************/ 674 675 static ACPI_STATUS 676 AcpiDmTestResourceConversion ( 677 ACPI_NAMESPACE_NODE *Node, 678 char *Name) 679 { 680 ACPI_STATUS Status; 681 ACPI_BUFFER ReturnObj; 682 ACPI_BUFFER ResourceObj; 683 ACPI_BUFFER NewAml; 684 ACPI_OBJECT *OriginalAml; 685 686 687 AcpiOsPrintf ("Resource Conversion Comparison:\n"); 688 689 NewAml.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 690 ReturnObj.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 691 ResourceObj.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 692 693 /* Get the original _CRS AML resource template */ 694 695 Status = AcpiEvaluateObject (Node, Name, NULL, &ReturnObj); 696 if (ACPI_FAILURE (Status)) 697 { 698 AcpiOsPrintf ("Could not obtain %s: %s\n", 699 Name, AcpiFormatException (Status)); 700 return (Status); 701 } 702 703 /* Get the AML resource template, converted to internal resource structs */ 704 705 Status = AcpiGetCurrentResources (Node, &ResourceObj); 706 if (ACPI_FAILURE (Status)) 707 { 708 AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n", 709 AcpiFormatException (Status)); 710 goto Exit1; 711 } 712 713 /* Convert internal resource list to external AML resource template */ 714 715 Status = AcpiRsCreateAmlResources (ResourceObj.Pointer, &NewAml); 716 if (ACPI_FAILURE (Status)) 717 { 718 AcpiOsPrintf ("AcpiRsCreateAmlResources failed: %s\n", 719 AcpiFormatException (Status)); 720 goto Exit2; 721 } 722 723 /* Compare original AML to the newly created AML resource list */ 724 725 OriginalAml = ReturnObj.Pointer; 726 727 AcpiDmCompareAmlResources ( 728 OriginalAml->Buffer.Pointer, (ACPI_RSDESC_SIZE) OriginalAml->Buffer.Length, 729 NewAml.Pointer, (ACPI_RSDESC_SIZE) NewAml.Length); 730 731 /* Cleanup and exit */ 732 733 ACPI_FREE (NewAml.Pointer); 734 Exit2: 735 ACPI_FREE (ResourceObj.Pointer); 736 Exit1: 737 ACPI_FREE (ReturnObj.Pointer); 738 return (Status); 739 } 740 741 742 /******************************************************************************* 743 * 744 * FUNCTION: AcpiDbResourceCallback 745 * 746 * PARAMETERS: ACPI_WALK_RESOURCE_CALLBACK 747 * 748 * RETURN: Status 749 * 750 * DESCRIPTION: Simple callback to exercise AcpiWalkResources 751 * 752 ******************************************************************************/ 753 754 static ACPI_STATUS 755 AcpiDbResourceCallback ( 756 ACPI_RESOURCE *Resource, 757 void *Context) 758 { 759 760 return (AE_OK); 761 } 762 763 764 /******************************************************************************* 765 * 766 * FUNCTION: AcpiDbDeviceResources 767 * 768 * PARAMETERS: ACPI_WALK_CALLBACK 769 * 770 * RETURN: Status 771 * 772 * DESCRIPTION: Display the _PRT/_CRS/_PRS resources for a device object. 773 * 774 ******************************************************************************/ 775 776 static ACPI_STATUS 777 AcpiDbDeviceResources ( 778 ACPI_HANDLE ObjHandle, 779 UINT32 NestingLevel, 780 void *Context, 781 void **ReturnValue) 782 { 783 ACPI_NAMESPACE_NODE *Node; 784 ACPI_NAMESPACE_NODE *PrtNode = NULL; 785 ACPI_NAMESPACE_NODE *CrsNode = NULL; 786 ACPI_NAMESPACE_NODE *PrsNode = NULL; 787 ACPI_NAMESPACE_NODE *AeiNode = NULL; 788 char *ParentPath; 789 ACPI_BUFFER ReturnObj; 790 ACPI_STATUS Status; 791 792 793 Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle); 794 ParentPath = AcpiNsGetExternalPathname (Node); 795 if (!ParentPath) 796 { 797 return (AE_NO_MEMORY); 798 } 799 800 /* Get handles to the resource methods for this device */ 801 802 (void) AcpiGetHandle (Node, METHOD_NAME__PRT, ACPI_CAST_PTR (ACPI_HANDLE, &PrtNode)); 803 (void) AcpiGetHandle (Node, METHOD_NAME__CRS, ACPI_CAST_PTR (ACPI_HANDLE, &CrsNode)); 804 (void) AcpiGetHandle (Node, METHOD_NAME__PRS, ACPI_CAST_PTR (ACPI_HANDLE, &PrsNode)); 805 (void) AcpiGetHandle (Node, METHOD_NAME__AEI, ACPI_CAST_PTR (ACPI_HANDLE, &AeiNode)); 806 if (!PrtNode && !CrsNode && !PrsNode && !AeiNode) 807 { 808 goto Cleanup; /* Nothing to do */ 809 } 810 811 AcpiOsPrintf ("\nDevice: %s\n", ParentPath); 812 813 /* Prepare for a return object of arbitrary size */ 814 815 ReturnObj.Pointer = AcpiGbl_DbBuffer; 816 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE; 817 818 819 /* _PRT */ 820 821 if (PrtNode) 822 { 823 AcpiOsPrintf ("Evaluating _PRT\n"); 824 825 Status = AcpiEvaluateObject (PrtNode, NULL, NULL, &ReturnObj); 826 if (ACPI_FAILURE (Status)) 827 { 828 AcpiOsPrintf ("Could not evaluate _PRT: %s\n", 829 AcpiFormatException (Status)); 830 goto GetCrs; 831 } 832 833 ReturnObj.Pointer = AcpiGbl_DbBuffer; 834 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE; 835 836 Status = AcpiGetIrqRoutingTable (Node, &ReturnObj); 837 if (ACPI_FAILURE (Status)) 838 { 839 AcpiOsPrintf ("GetIrqRoutingTable failed: %s\n", 840 AcpiFormatException (Status)); 841 goto GetCrs; 842 } 843 844 AcpiRsDumpIrqList (ACPI_CAST_PTR (UINT8, AcpiGbl_DbBuffer)); 845 } 846 847 848 /* _CRS */ 849 850 GetCrs: 851 if (CrsNode) 852 { 853 AcpiOsPrintf ("Evaluating _CRS\n"); 854 855 ReturnObj.Pointer = AcpiGbl_DbBuffer; 856 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE; 857 858 Status = AcpiEvaluateObject (CrsNode, NULL, NULL, &ReturnObj); 859 if (ACPI_FAILURE (Status)) 860 { 861 AcpiOsPrintf ("Could not evaluate _CRS: %s\n", 862 AcpiFormatException (Status)); 863 goto GetPrs; 864 } 865 866 /* This code is here to exercise the AcpiWalkResources interface */ 867 868 Status = AcpiWalkResources (Node, METHOD_NAME__CRS, 869 AcpiDbResourceCallback, NULL); 870 if (ACPI_FAILURE (Status)) 871 { 872 AcpiOsPrintf ("AcpiWalkResources failed: %s\n", 873 AcpiFormatException (Status)); 874 goto GetPrs; 875 } 876 877 /* Get the _CRS resource list */ 878 879 ReturnObj.Pointer = AcpiGbl_DbBuffer; 880 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE; 881 882 Status = AcpiGetCurrentResources (Node, &ReturnObj); 883 if (ACPI_FAILURE (Status)) 884 { 885 AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n", 886 AcpiFormatException (Status)); 887 goto GetPrs; 888 } 889 890 /* Dump the _CRS resource list */ 891 892 AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE, 893 ReturnObj.Pointer)); 894 895 /* 896 * Perform comparison of original AML to newly created AML. This tests both 897 * the AML->Resource conversion and the Resource->Aml conversion. 898 */ 899 Status = AcpiDmTestResourceConversion (Node, METHOD_NAME__CRS); 900 901 /* Execute _SRS with the resource list */ 902 903 Status = AcpiSetCurrentResources (Node, &ReturnObj); 904 if (ACPI_FAILURE (Status)) 905 { 906 AcpiOsPrintf ("AcpiSetCurrentResources failed: %s\n", 907 AcpiFormatException (Status)); 908 goto GetPrs; 909 } 910 } 911 912 913 /* _PRS */ 914 915 GetPrs: 916 if (PrsNode) 917 { 918 AcpiOsPrintf ("Evaluating _PRS\n"); 919 920 ReturnObj.Pointer = AcpiGbl_DbBuffer; 921 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE; 922 923 Status = AcpiEvaluateObject (PrsNode, NULL, NULL, &ReturnObj); 924 if (ACPI_FAILURE (Status)) 925 { 926 AcpiOsPrintf ("Could not evaluate _PRS: %s\n", 927 AcpiFormatException (Status)); 928 goto GetAei; 929 } 930 931 ReturnObj.Pointer = AcpiGbl_DbBuffer; 932 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE; 933 934 Status = AcpiGetPossibleResources (Node, &ReturnObj); 935 if (ACPI_FAILURE (Status)) 936 { 937 AcpiOsPrintf ("AcpiGetPossibleResources failed: %s\n", 938 AcpiFormatException (Status)); 939 goto GetAei; 940 } 941 942 AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE, AcpiGbl_DbBuffer)); 943 } 944 945 946 /* _AEI */ 947 948 GetAei: 949 if (AeiNode) 950 { 951 AcpiOsPrintf ("Evaluating _AEI\n"); 952 953 ReturnObj.Pointer = AcpiGbl_DbBuffer; 954 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE; 955 956 Status = AcpiEvaluateObject (AeiNode, NULL, NULL, &ReturnObj); 957 if (ACPI_FAILURE (Status)) 958 { 959 AcpiOsPrintf ("Could not evaluate _AEI: %s\n", 960 AcpiFormatException (Status)); 961 goto Cleanup; 962 } 963 964 ReturnObj.Pointer = AcpiGbl_DbBuffer; 965 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE; 966 967 Status = AcpiGetEventResources (Node, &ReturnObj); 968 if (ACPI_FAILURE (Status)) 969 { 970 AcpiOsPrintf ("AcpiGetEventResources failed: %s\n", 971 AcpiFormatException (Status)); 972 goto Cleanup; 973 } 974 975 AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE, AcpiGbl_DbBuffer)); 976 } 977 978 979 Cleanup: 980 ACPI_FREE (ParentPath); 981 return (AE_OK); 982 } 983 984 985 /******************************************************************************* 986 * 987 * FUNCTION: AcpiDbDisplayResources 988 * 989 * PARAMETERS: ObjectArg - String object name or object pointer. 990 * "*" means "display resources for all devices" 991 * 992 * RETURN: None 993 * 994 * DESCRIPTION: Display the resource objects associated with a device. 995 * 996 ******************************************************************************/ 997 998 void 999 AcpiDbDisplayResources ( 1000 char *ObjectArg) 1001 { 1002 ACPI_NAMESPACE_NODE *Node; 1003 1004 1005 AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT); 1006 AcpiDbgLevel |= ACPI_LV_RESOURCES; 1007 1008 /* Asterisk means "display resources for all devices" */ 1009 1010 if (!ACPI_STRCMP (ObjectArg, "*")) 1011 { 1012 (void) AcpiWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 1013 ACPI_UINT32_MAX, AcpiDbDeviceResources, NULL, NULL, NULL); 1014 } 1015 else 1016 { 1017 /* Convert string to object pointer */ 1018 1019 Node = AcpiDbConvertToNode (ObjectArg); 1020 if (Node) 1021 { 1022 if (Node->Type != ACPI_TYPE_DEVICE) 1023 { 1024 AcpiOsPrintf ("%4.4s: Name is not a device object (%s)\n", 1025 Node->Name.Ascii, AcpiUtGetTypeName (Node->Type)); 1026 } 1027 else 1028 { 1029 (void) AcpiDbDeviceResources (Node, 0, NULL, NULL); 1030 } 1031 } 1032 } 1033 1034 AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); 1035 } 1036 1037 1038 #if (!ACPI_REDUCED_HARDWARE) 1039 /******************************************************************************* 1040 * 1041 * FUNCTION: AcpiDbGenerateGpe 1042 * 1043 * PARAMETERS: GpeArg - Raw GPE number, ascii string 1044 * BlockArg - GPE block number, ascii string 1045 * 0 or 1 for FADT GPE blocks 1046 * 1047 * RETURN: None 1048 * 1049 * DESCRIPTION: Generate a GPE 1050 * 1051 ******************************************************************************/ 1052 1053 void 1054 AcpiDbGenerateGpe ( 1055 char *GpeArg, 1056 char *BlockArg) 1057 { 1058 UINT32 BlockNumber; 1059 UINT32 GpeNumber; 1060 ACPI_GPE_EVENT_INFO *GpeEventInfo; 1061 1062 1063 GpeNumber = ACPI_STRTOUL (GpeArg, NULL, 0); 1064 BlockNumber = ACPI_STRTOUL (BlockArg, NULL, 0); 1065 1066 1067 GpeEventInfo = AcpiEvGetGpeEventInfo (ACPI_TO_POINTER (BlockNumber), 1068 GpeNumber); 1069 if (!GpeEventInfo) 1070 { 1071 AcpiOsPrintf ("Invalid GPE\n"); 1072 return; 1073 } 1074 1075 (void) AcpiEvGpeDispatch (NULL, GpeEventInfo, GpeNumber); 1076 } 1077 #endif /* !ACPI_REDUCED_HARDWARE */ 1078 1079 #endif /* ACPI_DEBUGGER */ 1080