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