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