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