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