1 /******************************************************************************* 2 * 3 * Module Name: dbcmds - Miscellaneous debug commands and output routines 4 * 5 ******************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2015, 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 #include <contrib/dev/acpica/include/acpi.h> 45 #include <contrib/dev/acpica/include/accommon.h> 46 #include <contrib/dev/acpica/include/acevents.h> 47 #include <contrib/dev/acpica/include/acdebug.h> 48 #include <contrib/dev/acpica/include/acnamesp.h> 49 #include <contrib/dev/acpica/include/acresrc.h> 50 #include <contrib/dev/acpica/include/actables.h> 51 52 53 #define _COMPONENT ACPI_CA_DEBUGGER 54 ACPI_MODULE_NAME ("dbcmds") 55 56 57 /* Local prototypes */ 58 59 static void 60 AcpiDmCompareAmlResources ( 61 UINT8 *Aml1Buffer, 62 ACPI_RSDESC_SIZE Aml1BufferLength, 63 UINT8 *Aml2Buffer, 64 ACPI_RSDESC_SIZE Aml2BufferLength); 65 66 static ACPI_STATUS 67 AcpiDmTestResourceConversion ( 68 ACPI_NAMESPACE_NODE *Node, 69 char *Name); 70 71 static ACPI_STATUS 72 AcpiDbResourceCallback ( 73 ACPI_RESOURCE *Resource, 74 void *Context); 75 76 static ACPI_STATUS 77 AcpiDbDeviceResources ( 78 ACPI_HANDLE ObjHandle, 79 UINT32 NestingLevel, 80 void *Context, 81 void **ReturnValue); 82 83 static void 84 AcpiDbDoOneSleepState ( 85 UINT8 SleepState); 86 87 88 static char *AcpiDbTraceMethodName = NULL; 89 90 91 /******************************************************************************* 92 * 93 * FUNCTION: AcpiDbConvertToNode 94 * 95 * PARAMETERS: InString - String to convert 96 * 97 * RETURN: Pointer to a NS node 98 * 99 * DESCRIPTION: Convert a string to a valid NS pointer. Handles numeric or 100 * alphanumeric strings. 101 * 102 ******************************************************************************/ 103 104 ACPI_NAMESPACE_NODE * 105 AcpiDbConvertToNode ( 106 char *InString) 107 { 108 ACPI_NAMESPACE_NODE *Node; 109 ACPI_SIZE Address; 110 111 112 if ((*InString >= 0x30) && (*InString <= 0x39)) 113 { 114 /* Numeric argument, convert */ 115 116 Address = strtoul (InString, NULL, 16); 117 Node = ACPI_TO_POINTER (Address); 118 if (!AcpiOsReadable (Node, sizeof (ACPI_NAMESPACE_NODE))) 119 { 120 AcpiOsPrintf ("Address %p is invalid", 121 Node); 122 return (NULL); 123 } 124 125 /* Make sure pointer is valid NS node */ 126 127 if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED) 128 { 129 AcpiOsPrintf ("Address %p is not a valid namespace node [%s]\n", 130 Node, AcpiUtGetDescriptorName (Node)); 131 return (NULL); 132 } 133 } 134 else 135 { 136 /* 137 * Alpha argument: The parameter is a name string that must be 138 * resolved to a Namespace object. 139 */ 140 Node = AcpiDbLocalNsLookup (InString); 141 if (!Node) 142 { 143 AcpiOsPrintf ( 144 "Could not find [%s] in namespace, defaulting to root node\n", 145 InString); 146 Node = AcpiGbl_RootNode; 147 } 148 } 149 150 return (Node); 151 } 152 153 154 /******************************************************************************* 155 * 156 * FUNCTION: AcpiDbSleep 157 * 158 * PARAMETERS: ObjectArg - Desired sleep state (0-5). NULL means 159 * invoke all possible sleep states. 160 * 161 * RETURN: Status 162 * 163 * DESCRIPTION: Simulate sleep/wake sequences 164 * 165 ******************************************************************************/ 166 167 ACPI_STATUS 168 AcpiDbSleep ( 169 char *ObjectArg) 170 { 171 UINT8 SleepState; 172 UINT32 i; 173 174 175 ACPI_FUNCTION_TRACE (AcpiDbSleep); 176 177 178 /* Null input (no arguments) means to invoke all sleep states */ 179 180 if (!ObjectArg) 181 { 182 AcpiOsPrintf ("Invoking all possible sleep states, 0-%d\n", 183 ACPI_S_STATES_MAX); 184 185 for (i = 0; i <= ACPI_S_STATES_MAX; i++) 186 { 187 AcpiDbDoOneSleepState ((UINT8) i); 188 } 189 190 return_ACPI_STATUS (AE_OK); 191 } 192 193 /* Convert argument to binary and invoke the sleep state */ 194 195 SleepState = (UINT8) strtoul (ObjectArg, NULL, 0); 196 AcpiDbDoOneSleepState (SleepState); 197 return_ACPI_STATUS (AE_OK); 198 } 199 200 201 /******************************************************************************* 202 * 203 * FUNCTION: AcpiDbDoOneSleepState 204 * 205 * PARAMETERS: SleepState - Desired sleep state (0-5) 206 * 207 * RETURN: None 208 * 209 * DESCRIPTION: Simulate a sleep/wake sequence 210 * 211 ******************************************************************************/ 212 213 static void 214 AcpiDbDoOneSleepState ( 215 UINT8 SleepState) 216 { 217 ACPI_STATUS Status; 218 UINT8 SleepTypeA; 219 UINT8 SleepTypeB; 220 221 222 /* Validate parameter */ 223 224 if (SleepState > ACPI_S_STATES_MAX) 225 { 226 AcpiOsPrintf ("Sleep state %d out of range (%d max)\n", 227 SleepState, ACPI_S_STATES_MAX); 228 return; 229 } 230 231 AcpiOsPrintf ("\n---- Invoking sleep state S%d (%s):\n", 232 SleepState, AcpiGbl_SleepStateNames[SleepState]); 233 234 /* Get the values for the sleep type registers (for display only) */ 235 236 Status = AcpiGetSleepTypeData (SleepState, &SleepTypeA, &SleepTypeB); 237 if (ACPI_FAILURE (Status)) 238 { 239 AcpiOsPrintf ("Could not evaluate [%s] method, %s\n", 240 AcpiGbl_SleepStateNames[SleepState], 241 AcpiFormatException (Status)); 242 return; 243 } 244 245 AcpiOsPrintf ( 246 "Register values for sleep state S%d: Sleep-A: %.2X, Sleep-B: %.2X\n", 247 SleepState, SleepTypeA, SleepTypeB); 248 249 /* Invoke the various sleep/wake interfaces */ 250 251 AcpiOsPrintf ("**** Sleep: Prepare to sleep (S%d) ****\n", 252 SleepState); 253 Status = AcpiEnterSleepStatePrep (SleepState); 254 if (ACPI_FAILURE (Status)) 255 { 256 goto ErrorExit; 257 } 258 259 AcpiOsPrintf ("**** Sleep: Going to sleep (S%d) ****\n", 260 SleepState); 261 Status = AcpiEnterSleepState (SleepState); 262 if (ACPI_FAILURE (Status)) 263 { 264 goto ErrorExit; 265 } 266 267 AcpiOsPrintf ("**** Wake: Prepare to return from sleep (S%d) ****\n", 268 SleepState); 269 Status = AcpiLeaveSleepStatePrep (SleepState); 270 if (ACPI_FAILURE (Status)) 271 { 272 goto ErrorExit; 273 } 274 275 AcpiOsPrintf ("**** Wake: Return from sleep (S%d) ****\n", 276 SleepState); 277 Status = AcpiLeaveSleepState (SleepState); 278 if (ACPI_FAILURE (Status)) 279 { 280 goto ErrorExit; 281 } 282 283 return; 284 285 286 ErrorExit: 287 ACPI_EXCEPTION ((AE_INFO, Status, "During invocation of sleep state S%d", 288 SleepState)); 289 } 290 291 292 /******************************************************************************* 293 * 294 * FUNCTION: AcpiDbDisplayLocks 295 * 296 * PARAMETERS: None 297 * 298 * RETURN: None 299 * 300 * DESCRIPTION: Display information about internal mutexes. 301 * 302 ******************************************************************************/ 303 304 void 305 AcpiDbDisplayLocks ( 306 void) 307 { 308 UINT32 i; 309 310 311 for (i = 0; i < ACPI_MAX_MUTEX; i++) 312 { 313 AcpiOsPrintf ("%26s : %s\n", AcpiUtGetMutexName (i), 314 AcpiGbl_MutexInfo[i].ThreadId == ACPI_MUTEX_NOT_ACQUIRED 315 ? "Locked" : "Unlocked"); 316 } 317 } 318 319 320 /******************************************************************************* 321 * 322 * FUNCTION: AcpiDbDisplayTableInfo 323 * 324 * PARAMETERS: TableArg - Name of table to be displayed 325 * 326 * RETURN: None 327 * 328 * DESCRIPTION: Display information about loaded tables. Current 329 * implementation displays all loaded tables. 330 * 331 ******************************************************************************/ 332 333 void 334 AcpiDbDisplayTableInfo ( 335 char *TableArg) 336 { 337 UINT32 i; 338 ACPI_TABLE_DESC *TableDesc; 339 ACPI_STATUS Status; 340 341 342 /* Header */ 343 344 AcpiOsPrintf ("Idx ID Status Type " 345 "TableHeader (Sig, Address, Length, Misc)\n"); 346 347 /* Walk the entire root table list */ 348 349 for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++) 350 { 351 TableDesc = &AcpiGbl_RootTableList.Tables[i]; 352 353 /* Index and Table ID */ 354 355 AcpiOsPrintf ("%3u %.2u ", i, TableDesc->OwnerId); 356 357 /* Decode the table flags */ 358 359 if (!(TableDesc->Flags & ACPI_TABLE_IS_LOADED)) 360 { 361 AcpiOsPrintf ("NotLoaded "); 362 } 363 else 364 { 365 AcpiOsPrintf (" Loaded "); 366 } 367 368 switch (TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK) 369 { 370 case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL: 371 372 AcpiOsPrintf ("External/virtual "); 373 break; 374 375 case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL: 376 377 AcpiOsPrintf ("Internal/physical "); 378 break; 379 380 case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL: 381 382 AcpiOsPrintf ("Internal/virtual "); 383 break; 384 385 default: 386 387 AcpiOsPrintf ("INVALID TYPE "); 388 break; 389 } 390 391 /* Make sure that the table is mapped */ 392 393 Status = AcpiTbValidateTable (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 return; 444 } 445 446 Status = AcpiUnloadParentTable (ACPI_CAST_PTR (ACPI_HANDLE, Node)); 447 if (ACPI_SUCCESS (Status)) 448 { 449 AcpiOsPrintf ("Parent of [%s] (%p) unloaded and uninstalled\n", 450 ObjectName, Node); 451 } 452 else 453 { 454 AcpiOsPrintf ("%s, while unloading parent table of [%s]\n", 455 AcpiFormatException (Status), ObjectName); 456 } 457 } 458 459 460 /******************************************************************************* 461 * 462 * FUNCTION: AcpiDbSendNotify 463 * 464 * PARAMETERS: Name - Name of ACPI object where to send notify 465 * Value - Value of the notify to send. 466 * 467 * RETURN: None 468 * 469 * DESCRIPTION: Send an ACPI notification. The value specified is sent to the 470 * named object as an ACPI notify. 471 * 472 ******************************************************************************/ 473 474 void 475 AcpiDbSendNotify ( 476 char *Name, 477 UINT32 Value) 478 { 479 ACPI_NAMESPACE_NODE *Node; 480 ACPI_STATUS Status; 481 482 483 /* Translate name to an Named object */ 484 485 Node = AcpiDbConvertToNode (Name); 486 if (!Node) 487 { 488 return; 489 } 490 491 /* Dispatch the notify if legal */ 492 493 if (AcpiEvIsNotifyObject (Node)) 494 { 495 Status = AcpiEvQueueNotifyRequest (Node, Value); 496 if (ACPI_FAILURE (Status)) 497 { 498 AcpiOsPrintf ("Could not queue notify\n"); 499 } 500 } 501 else 502 { 503 AcpiOsPrintf ( 504 "Named object [%4.4s] Type %s, " 505 "must be Device/Thermal/Processor type\n", 506 AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Node->Type)); 507 } 508 } 509 510 511 /******************************************************************************* 512 * 513 * FUNCTION: AcpiDbDisplayInterfaces 514 * 515 * PARAMETERS: ActionArg - Null, "install", or "remove" 516 * InterfaceNameArg - Name for install/remove options 517 * 518 * RETURN: None 519 * 520 * DESCRIPTION: Display or modify the global _OSI interface list 521 * 522 ******************************************************************************/ 523 524 void 525 AcpiDbDisplayInterfaces ( 526 char *ActionArg, 527 char *InterfaceNameArg) 528 { 529 ACPI_INTERFACE_INFO *NextInterface; 530 char *SubString; 531 ACPI_STATUS Status; 532 533 534 /* If no arguments, just display current interface list */ 535 536 if (!ActionArg) 537 { 538 (void) AcpiOsAcquireMutex (AcpiGbl_OsiMutex, ACPI_WAIT_FOREVER); 539 540 NextInterface = AcpiGbl_SupportedInterfaces; 541 while (NextInterface) 542 { 543 if (!(NextInterface->Flags & ACPI_OSI_INVALID)) 544 { 545 AcpiOsPrintf ("%s\n", NextInterface->Name); 546 } 547 548 NextInterface = NextInterface->Next; 549 } 550 551 AcpiOsReleaseMutex (AcpiGbl_OsiMutex); 552 return; 553 } 554 555 /* If ActionArg exists, so must InterfaceNameArg */ 556 557 if (!InterfaceNameArg) 558 { 559 AcpiOsPrintf ("Missing Interface Name argument\n"); 560 return; 561 } 562 563 /* Uppercase the action for match below */ 564 565 AcpiUtStrupr (ActionArg); 566 567 /* Install - install an interface */ 568 569 SubString = strstr ("INSTALL", ActionArg); 570 if (SubString) 571 { 572 Status = AcpiInstallInterface (InterfaceNameArg); 573 if (ACPI_FAILURE (Status)) 574 { 575 AcpiOsPrintf ("%s, while installing \"%s\"\n", 576 AcpiFormatException (Status), InterfaceNameArg); 577 } 578 return; 579 } 580 581 /* Remove - remove an interface */ 582 583 SubString = strstr ("REMOVE", ActionArg); 584 if (SubString) 585 { 586 Status = AcpiRemoveInterface (InterfaceNameArg); 587 if (ACPI_FAILURE (Status)) 588 { 589 AcpiOsPrintf ("%s, while removing \"%s\"\n", 590 AcpiFormatException (Status), InterfaceNameArg); 591 } 592 return; 593 } 594 595 /* Invalid ActionArg */ 596 597 AcpiOsPrintf ("Invalid action argument: %s\n", ActionArg); 598 return; 599 } 600 601 602 /******************************************************************************* 603 * 604 * FUNCTION: AcpiDbDisplayTemplate 605 * 606 * PARAMETERS: BufferArg - Buffer name or address 607 * 608 * RETURN: None 609 * 610 * DESCRIPTION: Dump a buffer that contains a resource template 611 * 612 ******************************************************************************/ 613 614 void 615 AcpiDbDisplayTemplate ( 616 char *BufferArg) 617 { 618 ACPI_NAMESPACE_NODE *Node; 619 ACPI_STATUS Status; 620 ACPI_BUFFER ReturnBuffer; 621 622 623 /* Translate BufferArg to an Named object */ 624 625 Node = AcpiDbConvertToNode (BufferArg); 626 if (!Node || (Node == AcpiGbl_RootNode)) 627 { 628 AcpiOsPrintf ("Invalid argument: %s\n", BufferArg); 629 return; 630 } 631 632 /* We must have a buffer object */ 633 634 if (Node->Type != ACPI_TYPE_BUFFER) 635 { 636 AcpiOsPrintf ("Not a Buffer object, cannot be a template: %s\n", 637 BufferArg); 638 return; 639 } 640 641 ReturnBuffer.Length = ACPI_DEBUG_BUFFER_SIZE; 642 ReturnBuffer.Pointer = AcpiGbl_DbBuffer; 643 644 /* Attempt to convert the raw buffer to a resource list */ 645 646 Status = AcpiRsCreateResourceList (Node->Object, &ReturnBuffer); 647 648 AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT); 649 AcpiDbgLevel |= ACPI_LV_RESOURCES; 650 651 if (ACPI_FAILURE (Status)) 652 { 653 AcpiOsPrintf ( 654 "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 " 716 "AML: Original %X, New %X ****\n", 717 Aml1BufferLength, Aml2BufferLength); 718 } 719 720 Aml1 = Aml1Buffer; 721 Aml2 = Aml2Buffer; 722 Aml1End = Aml1Buffer + Aml1BufferLength; 723 Aml2End = Aml2Buffer + Aml2BufferLength; 724 725 /* Walk the descriptor lists, comparing each descriptor */ 726 727 while ((Aml1 < Aml1End) && (Aml2 < Aml2End)) 728 { 729 /* Get the lengths of each descriptor */ 730 731 Aml1Length = AcpiUtGetDescriptorLength (Aml1); 732 Aml2Length = AcpiUtGetDescriptorLength (Aml2); 733 ResourceType = AcpiUtGetResourceType (Aml1); 734 735 /* Check for descriptor length match */ 736 737 if (Aml1Length != Aml2Length) 738 { 739 AcpiOsPrintf ( 740 "**** Length mismatch in descriptor [%.2X] type %2.2X, " 741 "Offset %8.8X Len1 %X, Len2 %X ****\n", 742 Count, ResourceType, Offset, Aml1Length, Aml2Length); 743 } 744 745 /* Check for descriptor byte match */ 746 747 else if (memcmp (Aml1, Aml2, Aml1Length)) 748 { 749 AcpiOsPrintf ( 750 "**** Data mismatch in descriptor [%.2X] type %2.2X, " 751 "Offset %8.8X ****\n", 752 Count, ResourceType, Offset); 753 754 for (i = 0; i < Aml1Length; i++) 755 { 756 if (Aml1[i] != Aml2[i]) 757 { 758 AcpiOsPrintf ( 759 "Mismatch at byte offset %.2X: is %2.2X, " 760 "should be %2.2X\n", 761 i, Aml2[i], Aml1[i]); 762 } 763 } 764 } 765 766 /* Exit on EndTag descriptor */ 767 768 if (ResourceType == ACPI_RESOURCE_NAME_END_TAG) 769 { 770 return; 771 } 772 773 /* Point to next descriptor in each buffer */ 774 775 Count++; 776 Offset += Aml1Length; 777 Aml1 += Aml1Length; 778 Aml2 += Aml2Length; 779 } 780 } 781 782 783 /******************************************************************************* 784 * 785 * FUNCTION: AcpiDmTestResourceConversion 786 * 787 * PARAMETERS: Node - Parent device node 788 * Name - resource method name (_CRS) 789 * 790 * RETURN: Status 791 * 792 * DESCRIPTION: Compare the original AML with a conversion of the AML to 793 * internal resource list, then back to AML. 794 * 795 ******************************************************************************/ 796 797 static ACPI_STATUS 798 AcpiDmTestResourceConversion ( 799 ACPI_NAMESPACE_NODE *Node, 800 char *Name) 801 { 802 ACPI_STATUS Status; 803 ACPI_BUFFER ReturnBuffer; 804 ACPI_BUFFER ResourceBuffer; 805 ACPI_BUFFER NewAml; 806 ACPI_OBJECT *OriginalAml; 807 808 809 AcpiOsPrintf ("Resource Conversion Comparison:\n"); 810 811 NewAml.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 812 ReturnBuffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 813 ResourceBuffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 814 815 /* Get the original _CRS AML resource template */ 816 817 Status = AcpiEvaluateObject (Node, Name, NULL, &ReturnBuffer); 818 if (ACPI_FAILURE (Status)) 819 { 820 AcpiOsPrintf ("Could not obtain %s: %s\n", 821 Name, AcpiFormatException (Status)); 822 return (Status); 823 } 824 825 /* Get the AML resource template, converted to internal resource structs */ 826 827 Status = AcpiGetCurrentResources (Node, &ResourceBuffer); 828 if (ACPI_FAILURE (Status)) 829 { 830 AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n", 831 AcpiFormatException (Status)); 832 goto Exit1; 833 } 834 835 /* Convert internal resource list to external AML resource template */ 836 837 Status = AcpiRsCreateAmlResources (&ResourceBuffer, &NewAml); 838 if (ACPI_FAILURE (Status)) 839 { 840 AcpiOsPrintf ("AcpiRsCreateAmlResources failed: %s\n", 841 AcpiFormatException (Status)); 842 goto Exit2; 843 } 844 845 /* Compare original AML to the newly created AML resource list */ 846 847 OriginalAml = ReturnBuffer.Pointer; 848 849 AcpiDmCompareAmlResources (OriginalAml->Buffer.Pointer, 850 (ACPI_RSDESC_SIZE) OriginalAml->Buffer.Length, 851 NewAml.Pointer, (ACPI_RSDESC_SIZE) NewAml.Length); 852 853 /* Cleanup and exit */ 854 855 ACPI_FREE (NewAml.Pointer); 856 Exit2: 857 ACPI_FREE (ResourceBuffer.Pointer); 858 Exit1: 859 ACPI_FREE (ReturnBuffer.Pointer); 860 return (Status); 861 } 862 863 864 /******************************************************************************* 865 * 866 * FUNCTION: AcpiDbResourceCallback 867 * 868 * PARAMETERS: ACPI_WALK_RESOURCE_CALLBACK 869 * 870 * RETURN: Status 871 * 872 * DESCRIPTION: Simple callback to exercise AcpiWalkResources and 873 * AcpiWalkResourceBuffer. 874 * 875 ******************************************************************************/ 876 877 static ACPI_STATUS 878 AcpiDbResourceCallback ( 879 ACPI_RESOURCE *Resource, 880 void *Context) 881 { 882 883 return (AE_OK); 884 } 885 886 887 /******************************************************************************* 888 * 889 * FUNCTION: AcpiDbDeviceResources 890 * 891 * PARAMETERS: ACPI_WALK_CALLBACK 892 * 893 * RETURN: Status 894 * 895 * DESCRIPTION: Display the _PRT/_CRS/_PRS resources for a device object. 896 * 897 ******************************************************************************/ 898 899 static ACPI_STATUS 900 AcpiDbDeviceResources ( 901 ACPI_HANDLE ObjHandle, 902 UINT32 NestingLevel, 903 void *Context, 904 void **ReturnValue) 905 { 906 ACPI_NAMESPACE_NODE *Node; 907 ACPI_NAMESPACE_NODE *PrtNode = NULL; 908 ACPI_NAMESPACE_NODE *CrsNode = NULL; 909 ACPI_NAMESPACE_NODE *PrsNode = NULL; 910 ACPI_NAMESPACE_NODE *AeiNode = NULL; 911 char *ParentPath; 912 ACPI_BUFFER ReturnBuffer; 913 ACPI_STATUS Status; 914 915 916 Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle); 917 ParentPath = AcpiNsGetExternalPathname (Node); 918 if (!ParentPath) 919 { 920 return (AE_NO_MEMORY); 921 } 922 923 /* Get handles to the resource methods for this device */ 924 925 (void) AcpiGetHandle (Node, METHOD_NAME__PRT, 926 ACPI_CAST_PTR (ACPI_HANDLE, &PrtNode)); 927 (void) AcpiGetHandle (Node, METHOD_NAME__CRS, 928 ACPI_CAST_PTR (ACPI_HANDLE, &CrsNode)); 929 (void) AcpiGetHandle (Node, METHOD_NAME__PRS, 930 ACPI_CAST_PTR (ACPI_HANDLE, &PrsNode)); 931 (void) AcpiGetHandle (Node, METHOD_NAME__AEI, 932 ACPI_CAST_PTR (ACPI_HANDLE, &AeiNode)); 933 934 if (!PrtNode && !CrsNode && !PrsNode && !AeiNode) 935 { 936 goto Cleanup; /* Nothing to do */ 937 } 938 939 AcpiOsPrintf ("\nDevice: %s\n", ParentPath); 940 941 /* Prepare for a return object of arbitrary size */ 942 943 ReturnBuffer.Pointer = AcpiGbl_DbBuffer; 944 ReturnBuffer.Length = ACPI_DEBUG_BUFFER_SIZE; 945 946 947 /* _PRT */ 948 949 if (PrtNode) 950 { 951 AcpiOsPrintf ("Evaluating _PRT\n"); 952 953 Status = AcpiEvaluateObject (PrtNode, NULL, NULL, &ReturnBuffer); 954 if (ACPI_FAILURE (Status)) 955 { 956 AcpiOsPrintf ("Could not evaluate _PRT: %s\n", 957 AcpiFormatException (Status)); 958 goto GetCrs; 959 } 960 961 ReturnBuffer.Pointer = AcpiGbl_DbBuffer; 962 ReturnBuffer.Length = ACPI_DEBUG_BUFFER_SIZE; 963 964 Status = AcpiGetIrqRoutingTable (Node, &ReturnBuffer); 965 if (ACPI_FAILURE (Status)) 966 { 967 AcpiOsPrintf ("GetIrqRoutingTable failed: %s\n", 968 AcpiFormatException (Status)); 969 goto GetCrs; 970 } 971 972 AcpiRsDumpIrqList (ACPI_CAST_PTR (UINT8, AcpiGbl_DbBuffer)); 973 } 974 975 976 /* _CRS */ 977 978 GetCrs: 979 if (CrsNode) 980 { 981 AcpiOsPrintf ("Evaluating _CRS\n"); 982 983 ReturnBuffer.Pointer = AcpiGbl_DbBuffer; 984 ReturnBuffer.Length = ACPI_DEBUG_BUFFER_SIZE; 985 986 Status = AcpiEvaluateObject (CrsNode, NULL, NULL, &ReturnBuffer); 987 if (ACPI_FAILURE (Status)) 988 { 989 AcpiOsPrintf ("Could not evaluate _CRS: %s\n", 990 AcpiFormatException (Status)); 991 goto GetPrs; 992 } 993 994 /* This code exercises the AcpiWalkResources interface */ 995 996 Status = AcpiWalkResources (Node, METHOD_NAME__CRS, 997 AcpiDbResourceCallback, NULL); 998 if (ACPI_FAILURE (Status)) 999 { 1000 AcpiOsPrintf ("AcpiWalkResources failed: %s\n", 1001 AcpiFormatException (Status)); 1002 goto GetPrs; 1003 } 1004 1005 /* Get the _CRS resource list (test ALLOCATE buffer) */ 1006 1007 ReturnBuffer.Pointer = NULL; 1008 ReturnBuffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 1009 1010 Status = AcpiGetCurrentResources (Node, &ReturnBuffer); 1011 if (ACPI_FAILURE (Status)) 1012 { 1013 AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n", 1014 AcpiFormatException (Status)); 1015 goto GetPrs; 1016 } 1017 1018 /* This code exercises the AcpiWalkResourceBuffer interface */ 1019 1020 Status = AcpiWalkResourceBuffer (&ReturnBuffer, 1021 AcpiDbResourceCallback, NULL); 1022 if (ACPI_FAILURE (Status)) 1023 { 1024 AcpiOsPrintf ("AcpiWalkResourceBuffer failed: %s\n", 1025 AcpiFormatException (Status)); 1026 goto EndCrs; 1027 } 1028 1029 /* Dump the _CRS resource list */ 1030 1031 AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE, 1032 ReturnBuffer.Pointer)); 1033 1034 /* 1035 * Perform comparison of original AML to newly created AML. This 1036 * tests both the AML->Resource conversion and the Resource->AML 1037 * conversion. 1038 */ 1039 (void) AcpiDmTestResourceConversion (Node, METHOD_NAME__CRS); 1040 1041 /* Execute _SRS with the resource list */ 1042 1043 AcpiOsPrintf ("Evaluating _SRS\n"); 1044 1045 Status = AcpiSetCurrentResources (Node, &ReturnBuffer); 1046 if (ACPI_FAILURE (Status)) 1047 { 1048 AcpiOsPrintf ("AcpiSetCurrentResources failed: %s\n", 1049 AcpiFormatException (Status)); 1050 goto EndCrs; 1051 } 1052 1053 EndCrs: 1054 ACPI_FREE (ReturnBuffer.Pointer); 1055 } 1056 1057 1058 /* _PRS */ 1059 1060 GetPrs: 1061 if (PrsNode) 1062 { 1063 AcpiOsPrintf ("Evaluating _PRS\n"); 1064 1065 ReturnBuffer.Pointer = AcpiGbl_DbBuffer; 1066 ReturnBuffer.Length = ACPI_DEBUG_BUFFER_SIZE; 1067 1068 Status = AcpiEvaluateObject (PrsNode, NULL, NULL, &ReturnBuffer); 1069 if (ACPI_FAILURE (Status)) 1070 { 1071 AcpiOsPrintf ("Could not evaluate _PRS: %s\n", 1072 AcpiFormatException (Status)); 1073 goto GetAei; 1074 } 1075 1076 ReturnBuffer.Pointer = AcpiGbl_DbBuffer; 1077 ReturnBuffer.Length = ACPI_DEBUG_BUFFER_SIZE; 1078 1079 Status = AcpiGetPossibleResources (Node, &ReturnBuffer); 1080 if (ACPI_FAILURE (Status)) 1081 { 1082 AcpiOsPrintf ("AcpiGetPossibleResources failed: %s\n", 1083 AcpiFormatException (Status)); 1084 goto GetAei; 1085 } 1086 1087 AcpiRsDumpResourceList (ACPI_CAST_PTR ( 1088 ACPI_RESOURCE, AcpiGbl_DbBuffer)); 1089 } 1090 1091 1092 /* _AEI */ 1093 1094 GetAei: 1095 if (AeiNode) 1096 { 1097 AcpiOsPrintf ("Evaluating _AEI\n"); 1098 1099 ReturnBuffer.Pointer = AcpiGbl_DbBuffer; 1100 ReturnBuffer.Length = ACPI_DEBUG_BUFFER_SIZE; 1101 1102 Status = AcpiEvaluateObject (AeiNode, NULL, NULL, &ReturnBuffer); 1103 if (ACPI_FAILURE (Status)) 1104 { 1105 AcpiOsPrintf ("Could not evaluate _AEI: %s\n", 1106 AcpiFormatException (Status)); 1107 goto Cleanup; 1108 } 1109 1110 ReturnBuffer.Pointer = AcpiGbl_DbBuffer; 1111 ReturnBuffer.Length = ACPI_DEBUG_BUFFER_SIZE; 1112 1113 Status = AcpiGetEventResources (Node, &ReturnBuffer); 1114 if (ACPI_FAILURE (Status)) 1115 { 1116 AcpiOsPrintf ("AcpiGetEventResources failed: %s\n", 1117 AcpiFormatException (Status)); 1118 goto Cleanup; 1119 } 1120 1121 AcpiRsDumpResourceList (ACPI_CAST_PTR ( 1122 ACPI_RESOURCE, AcpiGbl_DbBuffer)); 1123 } 1124 1125 1126 Cleanup: 1127 ACPI_FREE (ParentPath); 1128 return (AE_OK); 1129 } 1130 1131 1132 /******************************************************************************* 1133 * 1134 * FUNCTION: AcpiDbDisplayResources 1135 * 1136 * PARAMETERS: ObjectArg - String object name or object pointer. 1137 * NULL or "*" means "display resources for 1138 * all devices" 1139 * 1140 * RETURN: None 1141 * 1142 * DESCRIPTION: Display the resource objects associated with a device. 1143 * 1144 ******************************************************************************/ 1145 1146 void 1147 AcpiDbDisplayResources ( 1148 char *ObjectArg) 1149 { 1150 ACPI_NAMESPACE_NODE *Node; 1151 1152 1153 AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT); 1154 AcpiDbgLevel |= ACPI_LV_RESOURCES; 1155 1156 /* Asterisk means "display resources for all devices" */ 1157 1158 if (!ObjectArg || (!strcmp (ObjectArg, "*"))) 1159 { 1160 (void) AcpiWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 1161 ACPI_UINT32_MAX, AcpiDbDeviceResources, NULL, NULL, NULL); 1162 } 1163 else 1164 { 1165 /* Convert string to object pointer */ 1166 1167 Node = AcpiDbConvertToNode (ObjectArg); 1168 if (Node) 1169 { 1170 if (Node->Type != ACPI_TYPE_DEVICE) 1171 { 1172 AcpiOsPrintf ( 1173 "%4.4s: Name is not a device object (%s)\n", 1174 Node->Name.Ascii, AcpiUtGetTypeName (Node->Type)); 1175 } 1176 else 1177 { 1178 (void) AcpiDbDeviceResources (Node, 0, NULL, NULL); 1179 } 1180 } 1181 } 1182 1183 AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); 1184 } 1185 1186 1187 #if (!ACPI_REDUCED_HARDWARE) 1188 /******************************************************************************* 1189 * 1190 * FUNCTION: AcpiDbGenerateGpe 1191 * 1192 * PARAMETERS: GpeArg - Raw GPE number, ascii string 1193 * BlockArg - GPE block number, ascii string 1194 * 0 or 1 for FADT GPE blocks 1195 * 1196 * RETURN: None 1197 * 1198 * DESCRIPTION: Simulate firing of a GPE 1199 * 1200 ******************************************************************************/ 1201 1202 void 1203 AcpiDbGenerateGpe ( 1204 char *GpeArg, 1205 char *BlockArg) 1206 { 1207 UINT32 BlockNumber = 0; 1208 UINT32 GpeNumber; 1209 ACPI_GPE_EVENT_INFO *GpeEventInfo; 1210 1211 1212 GpeNumber = strtoul (GpeArg, NULL, 0); 1213 1214 /* 1215 * If no block arg, or block arg == 0 or 1, use the FADT-defined 1216 * GPE blocks. 1217 */ 1218 if (BlockArg) 1219 { 1220 BlockNumber = strtoul (BlockArg, NULL, 0); 1221 if (BlockNumber == 1) 1222 { 1223 BlockNumber = 0; 1224 } 1225 } 1226 1227 GpeEventInfo = AcpiEvGetGpeEventInfo (ACPI_TO_POINTER (BlockNumber), 1228 GpeNumber); 1229 if (!GpeEventInfo) 1230 { 1231 AcpiOsPrintf ("Invalid GPE\n"); 1232 return; 1233 } 1234 1235 (void) AcpiEvGpeDispatch (NULL, GpeEventInfo, GpeNumber); 1236 } 1237 1238 1239 /******************************************************************************* 1240 * 1241 * FUNCTION: AcpiDbGenerateSci 1242 * 1243 * PARAMETERS: None 1244 * 1245 * RETURN: None 1246 * 1247 * DESCRIPTION: Simulate an SCI -- just call the SCI dispatch. 1248 * 1249 ******************************************************************************/ 1250 1251 void 1252 AcpiDbGenerateSci ( 1253 void) 1254 { 1255 AcpiEvSciDispatch (); 1256 } 1257 1258 #endif /* !ACPI_REDUCED_HARDWARE */ 1259 1260 1261 /******************************************************************************* 1262 * 1263 * FUNCTION: AcpiDbTrace 1264 * 1265 * PARAMETERS: EnableArg - ENABLE/AML to enable tracer 1266 * DISABLE to disable tracer 1267 * MethodArg - Method to trace 1268 * OnceArg - Whether trace once 1269 * 1270 * RETURN: None 1271 * 1272 * DESCRIPTION: Control method tracing facility 1273 * 1274 ******************************************************************************/ 1275 1276 void 1277 AcpiDbTrace ( 1278 char *EnableArg, 1279 char *MethodArg, 1280 char *OnceArg) 1281 { 1282 UINT32 DebugLevel = 0; 1283 UINT32 DebugLayer = 0; 1284 UINT32 Flags = 0; 1285 1286 1287 if (EnableArg) 1288 { 1289 AcpiUtStrupr (EnableArg); 1290 } 1291 1292 if (OnceArg) 1293 { 1294 AcpiUtStrupr (OnceArg); 1295 } 1296 1297 if (MethodArg) 1298 { 1299 if (AcpiDbTraceMethodName) 1300 { 1301 ACPI_FREE (AcpiDbTraceMethodName); 1302 AcpiDbTraceMethodName = NULL; 1303 } 1304 1305 AcpiDbTraceMethodName = ACPI_ALLOCATE (strlen (MethodArg) + 1); 1306 if (!AcpiDbTraceMethodName) 1307 { 1308 AcpiOsPrintf ("Failed to allocate method name (%s)\n", 1309 MethodArg); 1310 return; 1311 } 1312 1313 strcpy (AcpiDbTraceMethodName, MethodArg); 1314 } 1315 1316 if (!strcmp (EnableArg, "ENABLE") || 1317 !strcmp (EnableArg, "METHOD") || 1318 !strcmp (EnableArg, "OPCODE")) 1319 { 1320 if (!strcmp (EnableArg, "ENABLE")) 1321 { 1322 /* Inherit current console settings */ 1323 1324 DebugLevel = AcpiGbl_DbConsoleDebugLevel; 1325 DebugLayer = AcpiDbgLayer; 1326 } 1327 else 1328 { 1329 /* Restrict console output to trace points only */ 1330 1331 DebugLevel = ACPI_LV_TRACE_POINT; 1332 DebugLayer = ACPI_EXECUTER; 1333 } 1334 1335 Flags = ACPI_TRACE_ENABLED; 1336 1337 if (!strcmp (EnableArg, "OPCODE")) 1338 { 1339 Flags |= ACPI_TRACE_OPCODE; 1340 } 1341 1342 if (OnceArg && !strcmp (OnceArg, "ONCE")) 1343 { 1344 Flags |= ACPI_TRACE_ONESHOT; 1345 } 1346 } 1347 1348 (void) AcpiDebugTrace (AcpiDbTraceMethodName, 1349 DebugLevel, DebugLayer, Flags); 1350 } 1351