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