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); 178 if (ACPI_FAILURE (Status)) 179 { 180 goto ErrorExit; 181 } 182 183 AcpiOsPrintf ("**** Prepare to return from sleep ****\n"); 184 Status = AcpiLeaveSleepStatePrep (SleepState); 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_ACPI_STATUS (Status); 198 199 200 ErrorExit: 201 202 ACPI_EXCEPTION ((AE_INFO, Status, "During sleep test")); 203 return_ACPI_STATUS (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 /* Header */ 258 259 AcpiOsPrintf ("Idx ID Status Type Sig Address Len Header\n"); 260 261 /* Walk the entire root table list */ 262 263 for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++) 264 { 265 TableDesc = &AcpiGbl_RootTableList.Tables[i]; 266 267 /* Index and Table ID */ 268 269 AcpiOsPrintf ("%3u %.2u ", i, TableDesc->OwnerId); 270 271 /* Decode the table flags */ 272 273 if (!(TableDesc->Flags & ACPI_TABLE_IS_LOADED)) 274 { 275 AcpiOsPrintf ("NotLoaded "); 276 } 277 else 278 { 279 AcpiOsPrintf (" Loaded "); 280 } 281 282 switch (TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK) 283 { 284 case ACPI_TABLE_ORIGIN_UNKNOWN: 285 AcpiOsPrintf ("Unknown "); 286 break; 287 288 case ACPI_TABLE_ORIGIN_MAPPED: 289 AcpiOsPrintf ("Mapped "); 290 break; 291 292 case ACPI_TABLE_ORIGIN_ALLOCATED: 293 AcpiOsPrintf ("Allocated "); 294 break; 295 296 case ACPI_TABLE_ORIGIN_OVERRIDE: 297 AcpiOsPrintf ("Override "); 298 break; 299 300 default: 301 AcpiOsPrintf ("INVALID "); 302 break; 303 } 304 305 /* Make sure that the table is mapped */ 306 307 Status = AcpiTbVerifyTable (TableDesc); 308 if (ACPI_FAILURE (Status)) 309 { 310 return; 311 } 312 313 /* Dump the table header */ 314 315 if (TableDesc->Pointer) 316 { 317 AcpiTbPrintTableHeader (TableDesc->Address, TableDesc->Pointer); 318 } 319 else 320 { 321 /* If the pointer is null, the table has been unloaded */ 322 323 ACPI_INFO ((AE_INFO, "%4.4s - Table has been unloaded", 324 TableDesc->Signature.Ascii)); 325 } 326 } 327 } 328 329 330 /******************************************************************************* 331 * 332 * FUNCTION: AcpiDbUnloadAcpiTable 333 * 334 * PARAMETERS: ObjectName - Namespace pathname for an object that 335 * is owned by the table to be unloaded 336 * 337 * RETURN: None 338 * 339 * DESCRIPTION: Unload an ACPI table, via any namespace node that is owned 340 * by the table. 341 * 342 ******************************************************************************/ 343 344 void 345 AcpiDbUnloadAcpiTable ( 346 char *ObjectName) 347 { 348 ACPI_NAMESPACE_NODE *Node; 349 ACPI_STATUS Status; 350 351 352 /* Translate name to an Named object */ 353 354 Node = AcpiDbConvertToNode (ObjectName); 355 if (!Node) 356 { 357 AcpiOsPrintf ("Could not find [%s] in namespace\n", 358 ObjectName); 359 return; 360 } 361 362 Status = AcpiUnloadParentTable (ACPI_CAST_PTR (ACPI_HANDLE, Node)); 363 if (ACPI_SUCCESS (Status)) 364 { 365 AcpiOsPrintf ("Parent of [%s] (%p) unloaded and uninstalled\n", 366 ObjectName, Node); 367 } 368 else 369 { 370 AcpiOsPrintf ("%s, while unloading parent table of [%s]\n", 371 AcpiFormatException (Status), ObjectName); 372 } 373 } 374 375 376 /******************************************************************************* 377 * 378 * FUNCTION: AcpiDbSendNotify 379 * 380 * PARAMETERS: Name - Name of ACPI object to send the notify to 381 * Value - Value of the notify to send. 382 * 383 * RETURN: None 384 * 385 * DESCRIPTION: Send an ACPI notification. The value specified is sent to the 386 * named object as an ACPI notify. 387 * 388 ******************************************************************************/ 389 390 void 391 AcpiDbSendNotify ( 392 char *Name, 393 UINT32 Value) 394 { 395 ACPI_NAMESPACE_NODE *Node; 396 ACPI_STATUS Status; 397 398 399 /* Translate name to an Named object */ 400 401 Node = AcpiDbConvertToNode (Name); 402 if (!Node) 403 { 404 return; 405 } 406 407 /* Dispatch the notify if legal */ 408 409 if (AcpiEvIsNotifyObject (Node)) 410 { 411 Status = AcpiEvQueueNotifyRequest (Node, Value); 412 if (ACPI_FAILURE (Status)) 413 { 414 AcpiOsPrintf ("Could not queue notify\n"); 415 } 416 } 417 else 418 { 419 AcpiOsPrintf ("Named object [%4.4s] Type %s, must be Device/Thermal/Processor type\n", 420 AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Node->Type)); 421 } 422 } 423 424 425 /******************************************************************************* 426 * 427 * FUNCTION: AcpiDbDisplayInterfaces 428 * 429 * PARAMETERS: ActionArg - Null, "install", or "remove" 430 * InterfaceNameArg - Name for install/remove options 431 * 432 * RETURN: None 433 * 434 * DESCRIPTION: Display or modify the global _OSI interface list 435 * 436 ******************************************************************************/ 437 438 void 439 AcpiDbDisplayInterfaces ( 440 char *ActionArg, 441 char *InterfaceNameArg) 442 { 443 ACPI_INTERFACE_INFO *NextInterface; 444 char *SubString; 445 ACPI_STATUS Status; 446 447 448 /* If no arguments, just display current interface list */ 449 450 if (!ActionArg) 451 { 452 (void) AcpiOsAcquireMutex (AcpiGbl_OsiMutex, 453 ACPI_WAIT_FOREVER); 454 455 NextInterface = AcpiGbl_SupportedInterfaces; 456 457 while (NextInterface) 458 { 459 if (!(NextInterface->Flags & ACPI_OSI_INVALID)) 460 { 461 AcpiOsPrintf ("%s\n", NextInterface->Name); 462 } 463 NextInterface = NextInterface->Next; 464 } 465 466 AcpiOsReleaseMutex (AcpiGbl_OsiMutex); 467 return; 468 } 469 470 /* If ActionArg exists, so must InterfaceNameArg */ 471 472 if (!InterfaceNameArg) 473 { 474 AcpiOsPrintf ("Missing Interface Name argument\n"); 475 return; 476 } 477 478 /* Uppercase the action for match below */ 479 480 AcpiUtStrupr (ActionArg); 481 482 /* Install - install an interface */ 483 484 SubString = ACPI_STRSTR ("INSTALL", ActionArg); 485 if (SubString) 486 { 487 Status = AcpiInstallInterface (InterfaceNameArg); 488 if (ACPI_FAILURE (Status)) 489 { 490 AcpiOsPrintf ("%s, while installing \"%s\"\n", 491 AcpiFormatException (Status), InterfaceNameArg); 492 } 493 return; 494 } 495 496 /* Remove - remove an interface */ 497 498 SubString = ACPI_STRSTR ("REMOVE", ActionArg); 499 if (SubString) 500 { 501 Status = AcpiRemoveInterface (InterfaceNameArg); 502 if (ACPI_FAILURE (Status)) 503 { 504 AcpiOsPrintf ("%s, while removing \"%s\"\n", 505 AcpiFormatException (Status), InterfaceNameArg); 506 } 507 return; 508 } 509 510 /* Invalid ActionArg */ 511 512 AcpiOsPrintf ("Invalid action argument: %s\n", ActionArg); 513 return; 514 } 515 516 517 /******************************************************************************* 518 * 519 * FUNCTION: AcpiDbDisplayTemplate 520 * 521 * PARAMETERS: BufferArg - Buffer name or addrss 522 * 523 * RETURN: None 524 * 525 * DESCRIPTION: Dump a buffer that contains a resource template 526 * 527 ******************************************************************************/ 528 529 void 530 AcpiDbDisplayTemplate ( 531 char *BufferArg) 532 { 533 ACPI_NAMESPACE_NODE *Node; 534 ACPI_STATUS Status; 535 ACPI_BUFFER ReturnObj; 536 537 538 /* Translate BufferArg to an Named object */ 539 540 Node = AcpiDbConvertToNode (BufferArg); 541 if (!Node || (Node == AcpiGbl_RootNode)) 542 { 543 AcpiOsPrintf ("Invalid argument: %s\n", BufferArg); 544 return; 545 } 546 547 /* We must have a buffer object */ 548 549 if (Node->Type != ACPI_TYPE_BUFFER) 550 { 551 AcpiOsPrintf ("Not a Buffer object, cannot be a template: %s\n", 552 BufferArg); 553 return; 554 } 555 556 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE; 557 ReturnObj.Pointer = AcpiGbl_DbBuffer; 558 559 /* Attempt to convert the raw buffer to a resource list */ 560 561 Status = AcpiRsCreateResourceList (Node->Object, &ReturnObj); 562 563 AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT); 564 AcpiDbgLevel |= ACPI_LV_RESOURCES; 565 566 if (ACPI_FAILURE (Status)) 567 { 568 AcpiOsPrintf ("Could not convert Buffer to a resource list: %s, %s\n", 569 BufferArg, AcpiFormatException (Status)); 570 goto DumpBuffer; 571 } 572 573 /* Now we can dump the resource list */ 574 575 AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE, 576 ReturnObj.Pointer)); 577 578 DumpBuffer: 579 AcpiOsPrintf ("\nRaw data buffer:\n"); 580 AcpiUtDebugDumpBuffer ((UINT8 *) Node->Object->Buffer.Pointer, 581 Node->Object->Buffer.Length, 582 DB_BYTE_DISPLAY, ACPI_UINT32_MAX); 583 584 AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); 585 return; 586 } 587 588 589 /******************************************************************************* 590 * 591 * FUNCTION: AcpiDmCompareAmlResources 592 * 593 * PARAMETERS: Aml1Buffer - Contains first resource list 594 * Aml1BufferLength - Length of first resource list 595 * Aml2Buffer - Contains second resource list 596 * Aml2BufferLength - Length of second resource list 597 * 598 * RETURN: None 599 * 600 * DESCRIPTION: Compare two AML resource lists, descriptor by descriptor (in 601 * order to isolate a miscompare to an individual resource) 602 * 603 ******************************************************************************/ 604 605 static void 606 AcpiDmCompareAmlResources ( 607 UINT8 *Aml1Buffer, 608 ACPI_RSDESC_SIZE Aml1BufferLength, 609 UINT8 *Aml2Buffer, 610 ACPI_RSDESC_SIZE Aml2BufferLength) 611 { 612 UINT8 *Aml1; 613 UINT8 *Aml2; 614 UINT8 *Aml1End; 615 UINT8 *Aml2End; 616 ACPI_RSDESC_SIZE Aml1Length; 617 ACPI_RSDESC_SIZE Aml2Length; 618 ACPI_RSDESC_SIZE Offset = 0; 619 UINT8 ResourceType; 620 UINT32 Count = 0; 621 UINT32 i; 622 623 624 /* Compare overall buffer sizes (may be different due to size rounding) */ 625 626 if (Aml1BufferLength != Aml2BufferLength) 627 { 628 AcpiOsPrintf ( 629 "**** Buffer length mismatch in converted AML: Original %X, New %X ****\n", 630 Aml1BufferLength, Aml2BufferLength); 631 } 632 633 Aml1 = Aml1Buffer; 634 Aml2 = Aml2Buffer; 635 Aml1End = Aml1Buffer + Aml1BufferLength; 636 Aml2End = Aml2Buffer + Aml2BufferLength; 637 638 /* Walk the descriptor lists, comparing each descriptor */ 639 640 while ((Aml1 < Aml1End) && (Aml2 < Aml2End)) 641 { 642 /* Get the lengths of each descriptor */ 643 644 Aml1Length = AcpiUtGetDescriptorLength (Aml1); 645 Aml2Length = AcpiUtGetDescriptorLength (Aml2); 646 ResourceType = AcpiUtGetResourceType (Aml1); 647 648 /* Check for descriptor length match */ 649 650 if (Aml1Length != Aml2Length) 651 { 652 AcpiOsPrintf ( 653 "**** Length mismatch in descriptor [%.2X] type %2.2X, Offset %8.8X Len1 %X, Len2 %X ****\n", 654 Count, ResourceType, Offset, Aml1Length, Aml2Length); 655 } 656 657 /* Check for descriptor byte match */ 658 659 else if (ACPI_MEMCMP (Aml1, Aml2, Aml1Length)) 660 { 661 AcpiOsPrintf ( 662 "**** Data mismatch in descriptor [%.2X] type %2.2X, Offset %8.8X ****\n", 663 Count, ResourceType, Offset); 664 665 for (i = 0; i < Aml1Length; i++) 666 { 667 if (Aml1[i] != Aml2[i]) 668 { 669 AcpiOsPrintf ("Mismatch at byte offset %.2X: is %2.2X, should be %2.2X\n", 670 i, Aml2[i], Aml1[i]); 671 } 672 } 673 } 674 675 /* Exit on EndTag descriptor */ 676 677 if (ResourceType == ACPI_RESOURCE_NAME_END_TAG) 678 { 679 return; 680 } 681 682 /* Point to next descriptor in each buffer */ 683 684 Count++; 685 Offset += Aml1Length; 686 Aml1 += Aml1Length; 687 Aml2 += Aml2Length; 688 } 689 } 690 691 692 /******************************************************************************* 693 * 694 * FUNCTION: AcpiDmTestResourceConversion 695 * 696 * PARAMETERS: Node - Parent device node 697 * Name - resource method name (_CRS) 698 * 699 * RETURN: Status 700 * 701 * DESCRIPTION: Compare the original AML with a conversion of the AML to 702 * internal resource list, then back to AML. 703 * 704 ******************************************************************************/ 705 706 static ACPI_STATUS 707 AcpiDmTestResourceConversion ( 708 ACPI_NAMESPACE_NODE *Node, 709 char *Name) 710 { 711 ACPI_STATUS Status; 712 ACPI_BUFFER ReturnObj; 713 ACPI_BUFFER ResourceObj; 714 ACPI_BUFFER NewAml; 715 ACPI_OBJECT *OriginalAml; 716 717 718 AcpiOsPrintf ("Resource Conversion Comparison:\n"); 719 720 NewAml.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 721 ReturnObj.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 722 ResourceObj.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 723 724 /* Get the original _CRS AML resource template */ 725 726 Status = AcpiEvaluateObject (Node, Name, NULL, &ReturnObj); 727 if (ACPI_FAILURE (Status)) 728 { 729 AcpiOsPrintf ("Could not obtain %s: %s\n", 730 Name, AcpiFormatException (Status)); 731 return (Status); 732 } 733 734 /* Get the AML resource template, converted to internal resource structs */ 735 736 Status = AcpiGetCurrentResources (Node, &ResourceObj); 737 if (ACPI_FAILURE (Status)) 738 { 739 AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n", 740 AcpiFormatException (Status)); 741 goto Exit1; 742 } 743 744 /* Convert internal resource list to external AML resource template */ 745 746 Status = AcpiRsCreateAmlResources (ResourceObj.Pointer, &NewAml); 747 if (ACPI_FAILURE (Status)) 748 { 749 AcpiOsPrintf ("AcpiRsCreateAmlResources failed: %s\n", 750 AcpiFormatException (Status)); 751 goto Exit2; 752 } 753 754 /* Compare original AML to the newly created AML resource list */ 755 756 OriginalAml = ReturnObj.Pointer; 757 758 AcpiDmCompareAmlResources ( 759 OriginalAml->Buffer.Pointer, (ACPI_RSDESC_SIZE) OriginalAml->Buffer.Length, 760 NewAml.Pointer, (ACPI_RSDESC_SIZE) NewAml.Length); 761 762 /* Cleanup and exit */ 763 764 ACPI_FREE (NewAml.Pointer); 765 Exit2: 766 ACPI_FREE (ResourceObj.Pointer); 767 Exit1: 768 ACPI_FREE (ReturnObj.Pointer); 769 return (Status); 770 } 771 772 773 /******************************************************************************* 774 * 775 * FUNCTION: AcpiDbResourceCallback 776 * 777 * PARAMETERS: ACPI_WALK_RESOURCE_CALLBACK 778 * 779 * RETURN: Status 780 * 781 * DESCRIPTION: Simple callback to exercise AcpiWalkResources 782 * 783 ******************************************************************************/ 784 785 static ACPI_STATUS 786 AcpiDbResourceCallback ( 787 ACPI_RESOURCE *Resource, 788 void *Context) 789 { 790 791 return (AE_OK); 792 } 793 794 795 /******************************************************************************* 796 * 797 * FUNCTION: AcpiDbDeviceResources 798 * 799 * PARAMETERS: ACPI_WALK_CALLBACK 800 * 801 * RETURN: Status 802 * 803 * DESCRIPTION: Display the _PRT/_CRS/_PRS resources for a device object. 804 * 805 ******************************************************************************/ 806 807 static ACPI_STATUS 808 AcpiDbDeviceResources ( 809 ACPI_HANDLE ObjHandle, 810 UINT32 NestingLevel, 811 void *Context, 812 void **ReturnValue) 813 { 814 ACPI_NAMESPACE_NODE *Node; 815 ACPI_NAMESPACE_NODE *PrtNode = NULL; 816 ACPI_NAMESPACE_NODE *CrsNode = NULL; 817 ACPI_NAMESPACE_NODE *PrsNode = NULL; 818 ACPI_NAMESPACE_NODE *AeiNode = NULL; 819 char *ParentPath; 820 ACPI_BUFFER ReturnObj; 821 ACPI_STATUS Status; 822 823 824 Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle); 825 ParentPath = AcpiNsGetExternalPathname (Node); 826 if (!ParentPath) 827 { 828 return (AE_NO_MEMORY); 829 } 830 831 /* Get handles to the resource methods for this device */ 832 833 (void) AcpiGetHandle (Node, METHOD_NAME__PRT, ACPI_CAST_PTR (ACPI_HANDLE, &PrtNode)); 834 (void) AcpiGetHandle (Node, METHOD_NAME__CRS, ACPI_CAST_PTR (ACPI_HANDLE, &CrsNode)); 835 (void) AcpiGetHandle (Node, METHOD_NAME__PRS, ACPI_CAST_PTR (ACPI_HANDLE, &PrsNode)); 836 (void) AcpiGetHandle (Node, METHOD_NAME__AEI, ACPI_CAST_PTR (ACPI_HANDLE, &AeiNode)); 837 if (!PrtNode && !CrsNode && !PrsNode && !AeiNode) 838 { 839 goto Cleanup; /* Nothing to do */ 840 } 841 842 AcpiOsPrintf ("\nDevice: %s\n", ParentPath); 843 844 /* Prepare for a return object of arbitrary size */ 845 846 ReturnObj.Pointer = AcpiGbl_DbBuffer; 847 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE; 848 849 850 /* _PRT */ 851 852 if (PrtNode) 853 { 854 AcpiOsPrintf ("Evaluating _PRT\n"); 855 856 Status = AcpiEvaluateObject (PrtNode, NULL, NULL, &ReturnObj); 857 if (ACPI_FAILURE (Status)) 858 { 859 AcpiOsPrintf ("Could not evaluate _PRT: %s\n", 860 AcpiFormatException (Status)); 861 goto GetCrs; 862 } 863 864 ReturnObj.Pointer = AcpiGbl_DbBuffer; 865 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE; 866 867 Status = AcpiGetIrqRoutingTable (Node, &ReturnObj); 868 if (ACPI_FAILURE (Status)) 869 { 870 AcpiOsPrintf ("GetIrqRoutingTable failed: %s\n", 871 AcpiFormatException (Status)); 872 goto GetCrs; 873 } 874 875 AcpiRsDumpIrqList (ACPI_CAST_PTR (UINT8, AcpiGbl_DbBuffer)); 876 } 877 878 879 /* _CRS */ 880 881 GetCrs: 882 if (CrsNode) 883 { 884 AcpiOsPrintf ("Evaluating _CRS\n"); 885 886 ReturnObj.Pointer = AcpiGbl_DbBuffer; 887 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE; 888 889 Status = AcpiEvaluateObject (CrsNode, NULL, NULL, &ReturnObj); 890 if (ACPI_FAILURE (Status)) 891 { 892 AcpiOsPrintf ("Could not evaluate _CRS: %s\n", 893 AcpiFormatException (Status)); 894 goto GetPrs; 895 } 896 897 /* This code is here to exercise the AcpiWalkResources interface */ 898 899 Status = AcpiWalkResources (Node, METHOD_NAME__CRS, 900 AcpiDbResourceCallback, NULL); 901 if (ACPI_FAILURE (Status)) 902 { 903 AcpiOsPrintf ("AcpiWalkResources failed: %s\n", 904 AcpiFormatException (Status)); 905 goto GetPrs; 906 } 907 908 /* Get the _CRS resource list */ 909 910 ReturnObj.Pointer = AcpiGbl_DbBuffer; 911 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE; 912 913 Status = AcpiGetCurrentResources (Node, &ReturnObj); 914 if (ACPI_FAILURE (Status)) 915 { 916 AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n", 917 AcpiFormatException (Status)); 918 goto GetPrs; 919 } 920 921 /* Dump the _CRS resource list */ 922 923 AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE, 924 ReturnObj.Pointer)); 925 926 /* 927 * Perform comparison of original AML to newly created AML. This tests both 928 * the AML->Resource conversion and the Resource->Aml conversion. 929 */ 930 Status = AcpiDmTestResourceConversion (Node, METHOD_NAME__CRS); 931 932 /* Execute _SRS with the resource list */ 933 934 Status = AcpiSetCurrentResources (Node, &ReturnObj); 935 if (ACPI_FAILURE (Status)) 936 { 937 AcpiOsPrintf ("AcpiSetCurrentResources failed: %s\n", 938 AcpiFormatException (Status)); 939 goto GetPrs; 940 } 941 } 942 943 944 /* _PRS */ 945 946 GetPrs: 947 if (PrsNode) 948 { 949 AcpiOsPrintf ("Evaluating _PRS\n"); 950 951 ReturnObj.Pointer = AcpiGbl_DbBuffer; 952 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE; 953 954 Status = AcpiEvaluateObject (PrsNode, NULL, NULL, &ReturnObj); 955 if (ACPI_FAILURE (Status)) 956 { 957 AcpiOsPrintf ("Could not evaluate _PRS: %s\n", 958 AcpiFormatException (Status)); 959 goto GetAei; 960 } 961 962 ReturnObj.Pointer = AcpiGbl_DbBuffer; 963 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE; 964 965 Status = AcpiGetPossibleResources (Node, &ReturnObj); 966 if (ACPI_FAILURE (Status)) 967 { 968 AcpiOsPrintf ("AcpiGetPossibleResources failed: %s\n", 969 AcpiFormatException (Status)); 970 goto GetAei; 971 } 972 973 AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE, AcpiGbl_DbBuffer)); 974 } 975 976 977 /* _AEI */ 978 979 GetAei: 980 if (AeiNode) 981 { 982 AcpiOsPrintf ("Evaluating _AEI\n"); 983 984 ReturnObj.Pointer = AcpiGbl_DbBuffer; 985 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE; 986 987 Status = AcpiEvaluateObject (AeiNode, NULL, NULL, &ReturnObj); 988 if (ACPI_FAILURE (Status)) 989 { 990 AcpiOsPrintf ("Could not evaluate _AEI: %s\n", 991 AcpiFormatException (Status)); 992 goto Cleanup; 993 } 994 995 ReturnObj.Pointer = AcpiGbl_DbBuffer; 996 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE; 997 998 Status = AcpiGetEventResources (Node, &ReturnObj); 999 if (ACPI_FAILURE (Status)) 1000 { 1001 AcpiOsPrintf ("AcpiGetEventResources failed: %s\n", 1002 AcpiFormatException (Status)); 1003 goto Cleanup; 1004 } 1005 1006 AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE, AcpiGbl_DbBuffer)); 1007 } 1008 1009 1010 Cleanup: 1011 ACPI_FREE (ParentPath); 1012 return (AE_OK); 1013 } 1014 1015 1016 /******************************************************************************* 1017 * 1018 * FUNCTION: AcpiDbDisplayResources 1019 * 1020 * PARAMETERS: ObjectArg - String object name or object pointer. 1021 * "*" means "display resources for all devices" 1022 * 1023 * RETURN: None 1024 * 1025 * DESCRIPTION: Display the resource objects associated with a device. 1026 * 1027 ******************************************************************************/ 1028 1029 void 1030 AcpiDbDisplayResources ( 1031 char *ObjectArg) 1032 { 1033 ACPI_NAMESPACE_NODE *Node; 1034 1035 1036 AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT); 1037 AcpiDbgLevel |= ACPI_LV_RESOURCES; 1038 1039 /* Asterisk means "display resources for all devices" */ 1040 1041 if (!ACPI_STRCMP (ObjectArg, "*")) 1042 { 1043 (void) AcpiWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 1044 ACPI_UINT32_MAX, AcpiDbDeviceResources, NULL, NULL, NULL); 1045 } 1046 else 1047 { 1048 /* Convert string to object pointer */ 1049 1050 Node = AcpiDbConvertToNode (ObjectArg); 1051 if (Node) 1052 { 1053 if (Node->Type != ACPI_TYPE_DEVICE) 1054 { 1055 AcpiOsPrintf ("%4.4s: Name is not a device object (%s)\n", 1056 Node->Name.Ascii, AcpiUtGetTypeName (Node->Type)); 1057 } 1058 else 1059 { 1060 (void) AcpiDbDeviceResources (Node, 0, NULL, NULL); 1061 } 1062 } 1063 } 1064 1065 AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); 1066 } 1067 1068 1069 #if (!ACPI_REDUCED_HARDWARE) 1070 /******************************************************************************* 1071 * 1072 * FUNCTION: AcpiDbGenerateGpe 1073 * 1074 * PARAMETERS: GpeArg - Raw GPE number, ascii string 1075 * BlockArg - GPE block number, ascii string 1076 * 0 or 1 for FADT GPE blocks 1077 * 1078 * RETURN: None 1079 * 1080 * DESCRIPTION: Generate a GPE 1081 * 1082 ******************************************************************************/ 1083 1084 void 1085 AcpiDbGenerateGpe ( 1086 char *GpeArg, 1087 char *BlockArg) 1088 { 1089 UINT32 BlockNumber; 1090 UINT32 GpeNumber; 1091 ACPI_GPE_EVENT_INFO *GpeEventInfo; 1092 1093 1094 GpeNumber = ACPI_STRTOUL (GpeArg, NULL, 0); 1095 BlockNumber = ACPI_STRTOUL (BlockArg, NULL, 0); 1096 1097 1098 GpeEventInfo = AcpiEvGetGpeEventInfo (ACPI_TO_POINTER (BlockNumber), 1099 GpeNumber); 1100 if (!GpeEventInfo) 1101 { 1102 AcpiOsPrintf ("Invalid GPE\n"); 1103 return; 1104 } 1105 1106 (void) AcpiEvGpeDispatch (NULL, GpeEventInfo, GpeNumber); 1107 } 1108 #endif /* !ACPI_REDUCED_HARDWARE */ 1109 1110 #endif /* ACPI_DEBUGGER */ 1111