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