1 /*******************************************************************************
3 * Module Name: dbcmds - Miscellaneous debug commands and output routines
5 ******************************************************************************/
8 * Copyright (C) 2000 - 2011, Intel Corp.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
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.
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.
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.
45 #include <contrib/dev/acpica/include/acpi.h>
46 #include <contrib/dev/acpica/include/accommon.h>
47 #include <contrib/dev/acpica/include/acevents.h>
48 #include <contrib/dev/acpica/include/acdebug.h>
49 #include <contrib/dev/acpica/include/acresrc.h>
50 #include <contrib/dev/acpica/include/actables.h>
54 #define _COMPONENT ACPI_CA_DEBUGGER
55 ACPI_MODULE_NAME ("dbcmds")
58 /* Local prototypes */
61 AcpiDmCompareAmlResources (
63 ACPI_RSDESC_SIZE Aml1BufferLength,
65 ACPI_RSDESC_SIZE Aml2BufferLength);
68 AcpiDmTestResourceConversion (
69 ACPI_NAMESPACE_NODE *Node,
73 /*******************************************************************************
75 * FUNCTION: AcpiDbConvertToNode
77 * PARAMETERS: InString - String to convert
79 * RETURN: Pointer to a NS node
81 * DESCRIPTION: Convert a string to a valid NS pointer. Handles numeric or
84 ******************************************************************************/
90 ACPI_NAMESPACE_NODE *Node;
93 if ((*InString >= 0x30) && (*InString <= 0x39))
95 /* Numeric argument, convert */
97 Node = ACPI_TO_POINTER (ACPI_STRTOUL (InString, NULL, 16));
98 if (!AcpiOsReadable (Node, sizeof (ACPI_NAMESPACE_NODE)))
100 AcpiOsPrintf ("Address %p is invalid in this address space\n",
105 /* Make sure pointer is valid NS node */
107 if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED)
109 AcpiOsPrintf ("Address %p is not a valid NS node [%s]\n",
110 Node, AcpiUtGetDescriptorName (Node));
117 /* The parameter is a name string that must be resolved to a
120 Node = AcpiDbLocalNsLookup (InString);
123 Node = AcpiGbl_RootNode;
131 /*******************************************************************************
133 * FUNCTION: AcpiDbSleep
135 * PARAMETERS: ObjectArg - Desired sleep state (0-5)
139 * DESCRIPTION: Simulate a sleep/wake sequence
141 ******************************************************************************/
151 SleepState = (UINT8) ACPI_STRTOUL (ObjectArg, NULL, 0);
153 AcpiOsPrintf ("**** Prepare to sleep ****\n");
154 Status = AcpiEnterSleepStatePrep (SleepState);
155 if (ACPI_FAILURE (Status))
160 AcpiOsPrintf ("**** Going to sleep ****\n");
161 Status = AcpiEnterSleepState (SleepState);
162 if (ACPI_FAILURE (Status))
167 AcpiOsPrintf ("**** returning from sleep ****\n");
168 Status = AcpiLeaveSleepState (SleepState);
173 /*******************************************************************************
175 * FUNCTION: AcpiDbDisplayLocks
181 * DESCRIPTION: Display information about internal mutexes.
183 ******************************************************************************/
192 for (i = 0; i < ACPI_MAX_MUTEX; i++)
194 AcpiOsPrintf ("%26s : %s\n", AcpiUtGetMutexName (i),
195 AcpiGbl_MutexInfo[i].ThreadId == ACPI_MUTEX_NOT_ACQUIRED
196 ? "Locked" : "Unlocked");
201 /*******************************************************************************
203 * FUNCTION: AcpiDbDisplayTableInfo
205 * PARAMETERS: TableArg - String with name of table to be displayed
209 * DESCRIPTION: Display information about loaded tables. Current
210 * implementation displays all loaded tables.
212 ******************************************************************************/
215 AcpiDbDisplayTableInfo (
219 ACPI_TABLE_DESC *TableDesc;
223 /* Walk the entire root table list */
225 for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
227 TableDesc = &AcpiGbl_RootTableList.Tables[i];
228 AcpiOsPrintf ("%u ", i);
230 /* Make sure that the table is mapped */
232 Status = AcpiTbVerifyTable (TableDesc);
233 if (ACPI_FAILURE (Status))
238 /* Dump the table header */
240 if (TableDesc->Pointer)
242 AcpiTbPrintTableHeader (TableDesc->Address, TableDesc->Pointer);
246 /* If the pointer is null, the table has been unloaded */
248 ACPI_INFO ((AE_INFO, "%4.4s - Table has been unloaded",
249 TableDesc->Signature.Ascii));
255 /*******************************************************************************
257 * FUNCTION: AcpiDbUnloadAcpiTable
259 * PARAMETERS: TableArg - Name of the table to be unloaded
260 * InstanceArg - Which instance of the table to unload (if
261 * there are multiple tables of the same type)
265 * DESCRIPTION: Unload an ACPI table.
266 * Instance is not implemented
268 ******************************************************************************/
271 AcpiDbUnloadAcpiTable (
275 /* TBD: Need to reimplement for new data structures */
282 /* Search all tables for the target type */
284 for (i = 0; i < (ACPI_TABLE_ID_MAX+1); i++)
286 if (!ACPI_STRNCMP (TableArg, AcpiGbl_TableData[i].Signature,
287 AcpiGbl_TableData[i].SigLength))
289 /* Found the table, unload it */
291 Status = AcpiUnloadTable (i);
292 if (ACPI_SUCCESS (Status))
294 AcpiOsPrintf ("[%s] unloaded and uninstalled\n", TableArg);
298 AcpiOsPrintf ("%s, while unloading [%s]\n",
299 AcpiFormatException (Status), TableArg);
306 AcpiOsPrintf ("Unknown table type [%s]\n", TableArg);
311 /*******************************************************************************
313 * FUNCTION: AcpiDbSendNotify
315 * PARAMETERS: Name - Name of ACPI object to send the notify to
316 * Value - Value of the notify to send.
320 * DESCRIPTION: Send an ACPI notification. The value specified is sent to the
321 * named object as an ACPI notify.
323 ******************************************************************************/
330 ACPI_NAMESPACE_NODE *Node;
334 /* Translate name to an Named object */
336 Node = AcpiDbConvertToNode (Name);
342 /* Decode Named object type */
346 case ACPI_TYPE_DEVICE:
347 case ACPI_TYPE_THERMAL:
349 /* Send the notify */
351 Status = AcpiEvQueueNotifyRequest (Node, Value);
352 if (ACPI_FAILURE (Status))
354 AcpiOsPrintf ("Could not queue notify\n");
359 AcpiOsPrintf ("Named object is not a device or a thermal object\n");
365 /*******************************************************************************
367 * FUNCTION: AcpiDbDisplayInterfaces
369 * PARAMETERS: ActionArg - Null, "install", or "remove"
370 * InterfaceNameArg - Name for install/remove options
374 * DESCRIPTION: Display or modify the global _OSI interface list
376 ******************************************************************************/
379 AcpiDbDisplayInterfaces (
381 char *InterfaceNameArg)
383 ACPI_INTERFACE_INFO *NextInterface;
388 /* If no arguments, just display current interface list */
392 (void) AcpiOsAcquireMutex (AcpiGbl_OsiMutex,
395 NextInterface = AcpiGbl_SupportedInterfaces;
397 while (NextInterface)
399 if (!(NextInterface->Flags & ACPI_OSI_INVALID))
401 AcpiOsPrintf ("%s\n", NextInterface->Name);
403 NextInterface = NextInterface->Next;
406 AcpiOsReleaseMutex (AcpiGbl_OsiMutex);
410 /* If ActionArg exists, so must InterfaceNameArg */
412 if (!InterfaceNameArg)
414 AcpiOsPrintf ("Missing Interface Name argument\n");
418 /* Uppercase the action for match below */
420 AcpiUtStrupr (ActionArg);
422 /* Install - install an interface */
424 SubString = ACPI_STRSTR ("INSTALL", ActionArg);
427 Status = AcpiInstallInterface (InterfaceNameArg);
428 if (ACPI_FAILURE (Status))
430 AcpiOsPrintf ("%s, while installing \"%s\"\n",
431 AcpiFormatException (Status), InterfaceNameArg);
436 /* Remove - remove an interface */
438 SubString = ACPI_STRSTR ("REMOVE", ActionArg);
441 Status = AcpiRemoveInterface (InterfaceNameArg);
442 if (ACPI_FAILURE (Status))
444 AcpiOsPrintf ("%s, while removing \"%s\"\n",
445 AcpiFormatException (Status), InterfaceNameArg);
450 /* Invalid ActionArg */
452 AcpiOsPrintf ("Invalid action argument: %s\n", ActionArg);
457 /*******************************************************************************
459 * FUNCTION: AcpiDmCompareAmlResources
461 * PARAMETERS: Aml1Buffer - Contains first resource list
462 * Aml1BufferLength - Length of first resource list
463 * Aml2Buffer - Contains second resource list
464 * Aml2BufferLength - Length of second resource list
468 * DESCRIPTION: Compare two AML resource lists, descriptor by descriptor (in
469 * order to isolate a miscompare to an individual resource)
471 ******************************************************************************/
474 AcpiDmCompareAmlResources (
476 ACPI_RSDESC_SIZE Aml1BufferLength,
478 ACPI_RSDESC_SIZE Aml2BufferLength)
482 ACPI_RSDESC_SIZE Aml1Length;
483 ACPI_RSDESC_SIZE Aml2Length;
484 ACPI_RSDESC_SIZE Offset = 0;
489 /* Compare overall buffer sizes (may be different due to size rounding) */
491 if (Aml1BufferLength != Aml2BufferLength)
494 "**** Buffer length mismatch in converted AML: original %X new %X ****\n",
495 Aml1BufferLength, Aml2BufferLength);
501 /* Walk the descriptor lists, comparing each descriptor */
503 while (Aml1 < (Aml1Buffer + Aml1BufferLength))
505 /* Get the lengths of each descriptor */
507 Aml1Length = AcpiUtGetDescriptorLength (Aml1);
508 Aml2Length = AcpiUtGetDescriptorLength (Aml2);
509 ResourceType = AcpiUtGetResourceType (Aml1);
511 /* Check for descriptor length match */
513 if (Aml1Length != Aml2Length)
516 "**** Length mismatch in descriptor [%.2X] type %2.2X, Offset %8.8X L1 %X L2 %X ****\n",
517 Count, ResourceType, Offset, Aml1Length, Aml2Length);
520 /* Check for descriptor byte match */
522 else if (ACPI_MEMCMP (Aml1, Aml2, Aml1Length))
525 "**** Data mismatch in descriptor [%.2X] type %2.2X, Offset %8.8X ****\n",
526 Count, ResourceType, Offset);
529 /* Exit on EndTag descriptor */
531 if (ResourceType == ACPI_RESOURCE_NAME_END_TAG)
536 /* Point to next descriptor in each buffer */
539 Offset += Aml1Length;
546 /*******************************************************************************
548 * FUNCTION: AcpiDmTestResourceConversion
550 * PARAMETERS: Node - Parent device node
551 * Name - resource method name (_CRS)
555 * DESCRIPTION: Compare the original AML with a conversion of the AML to
556 * internal resource list, then back to AML.
558 ******************************************************************************/
561 AcpiDmTestResourceConversion (
562 ACPI_NAMESPACE_NODE *Node,
566 ACPI_BUFFER ReturnObj;
567 ACPI_BUFFER ResourceObj;
569 ACPI_OBJECT *OriginalAml;
572 AcpiOsPrintf ("Resource Conversion Comparison:\n");
574 NewAml.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
575 ReturnObj.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
576 ResourceObj.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
578 /* Get the original _CRS AML resource template */
580 Status = AcpiEvaluateObject (Node, Name, NULL, &ReturnObj);
581 if (ACPI_FAILURE (Status))
583 AcpiOsPrintf ("Could not obtain %s: %s\n",
584 Name, AcpiFormatException (Status));
588 /* Get the AML resource template, converted to internal resource structs */
590 Status = AcpiGetCurrentResources (Node, &ResourceObj);
591 if (ACPI_FAILURE (Status))
593 AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n",
594 AcpiFormatException (Status));
598 /* Convert internal resource list to external AML resource template */
600 Status = AcpiRsCreateAmlResources (ResourceObj.Pointer, &NewAml);
601 if (ACPI_FAILURE (Status))
603 AcpiOsPrintf ("AcpiRsCreateAmlResources failed: %s\n",
604 AcpiFormatException (Status));
608 /* Compare original AML to the newly created AML resource list */
610 OriginalAml = ReturnObj.Pointer;
612 AcpiDmCompareAmlResources (
613 OriginalAml->Buffer.Pointer, (ACPI_RSDESC_SIZE) OriginalAml->Buffer.Length,
614 NewAml.Pointer, (ACPI_RSDESC_SIZE) NewAml.Length);
616 /* Cleanup and exit */
618 ACPI_FREE (NewAml.Pointer);
620 ACPI_FREE (ResourceObj.Pointer);
622 ACPI_FREE (ReturnObj.Pointer);
627 /*******************************************************************************
629 * FUNCTION: AcpiDbDisplayResources
631 * PARAMETERS: ObjectArg - String with hex value of the object
635 * DESCRIPTION: Display the resource objects associated with a device.
637 ******************************************************************************/
640 AcpiDbDisplayResources (
643 ACPI_NAMESPACE_NODE *Node;
645 ACPI_BUFFER ReturnObj;
648 AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
649 AcpiDbgLevel |= ACPI_LV_RESOURCES;
651 /* Convert string to object pointer */
653 Node = AcpiDbConvertToNode (ObjectArg);
659 /* Prepare for a return object of arbitrary size */
661 ReturnObj.Pointer = AcpiGbl_DbBuffer;
662 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE;
666 AcpiOsPrintf ("Evaluating _PRT\n");
668 /* Check if _PRT exists */
670 Status = AcpiEvaluateObject (Node, METHOD_NAME__PRT, NULL, &ReturnObj);
671 if (ACPI_FAILURE (Status))
673 AcpiOsPrintf ("Could not obtain _PRT: %s\n",
674 AcpiFormatException (Status));
678 ReturnObj.Pointer = AcpiGbl_DbBuffer;
679 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE;
681 Status = AcpiGetIrqRoutingTable (Node, &ReturnObj);
682 if (ACPI_FAILURE (Status))
684 AcpiOsPrintf ("GetIrqRoutingTable failed: %s\n",
685 AcpiFormatException (Status));
689 AcpiRsDumpIrqList (ACPI_CAST_PTR (UINT8, AcpiGbl_DbBuffer));
695 AcpiOsPrintf ("Evaluating _CRS\n");
697 ReturnObj.Pointer = AcpiGbl_DbBuffer;
698 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE;
700 /* Check if _CRS exists */
702 Status = AcpiEvaluateObject (Node, METHOD_NAME__CRS, NULL, &ReturnObj);
703 if (ACPI_FAILURE (Status))
705 AcpiOsPrintf ("Could not obtain _CRS: %s\n",
706 AcpiFormatException (Status));
710 /* Get the _CRS resource list */
712 ReturnObj.Pointer = AcpiGbl_DbBuffer;
713 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE;
715 Status = AcpiGetCurrentResources (Node, &ReturnObj);
716 if (ACPI_FAILURE (Status))
718 AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n",
719 AcpiFormatException (Status));
723 /* Dump the _CRS resource list */
725 AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE,
729 * Perform comparison of original AML to newly created AML. This tests both
730 * the AML->Resource conversion and the Resource->Aml conversion.
732 Status = AcpiDmTestResourceConversion (Node, METHOD_NAME__CRS);
734 /* Execute _SRS with the resource list */
736 Status = AcpiSetCurrentResources (Node, &ReturnObj);
737 if (ACPI_FAILURE (Status))
739 AcpiOsPrintf ("AcpiSetCurrentResources failed: %s\n",
740 AcpiFormatException (Status));
748 AcpiOsPrintf ("Evaluating _PRS\n");
750 ReturnObj.Pointer = AcpiGbl_DbBuffer;
751 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE;
753 /* Check if _PRS exists */
755 Status = AcpiEvaluateObject (Node, METHOD_NAME__PRS, NULL, &ReturnObj);
756 if (ACPI_FAILURE (Status))
758 AcpiOsPrintf ("Could not obtain _PRS: %s\n",
759 AcpiFormatException (Status));
763 ReturnObj.Pointer = AcpiGbl_DbBuffer;
764 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE;
766 Status = AcpiGetPossibleResources (Node, &ReturnObj);
767 if (ACPI_FAILURE (Status))
769 AcpiOsPrintf ("AcpiGetPossibleResources failed: %s\n",
770 AcpiFormatException (Status));
774 AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE, AcpiGbl_DbBuffer));
778 AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
783 /*******************************************************************************
785 * FUNCTION: AcpiDbGenerateGpe
787 * PARAMETERS: GpeArg - Raw GPE number, ascii string
788 * BlockArg - GPE block number, ascii string
789 * 0 or 1 for FADT GPE blocks
793 * DESCRIPTION: Generate a GPE
795 ******************************************************************************/
804 ACPI_GPE_EVENT_INFO *GpeEventInfo;
807 GpeNumber = ACPI_STRTOUL (GpeArg, NULL, 0);
808 BlockNumber = ACPI_STRTOUL (BlockArg, NULL, 0);
811 GpeEventInfo = AcpiEvGetGpeEventInfo (ACPI_TO_POINTER (BlockNumber),
815 AcpiOsPrintf ("Invalid GPE\n");
819 (void) AcpiEvGpeDispatch (NULL, GpeEventInfo, GpeNumber);
822 #endif /* ACPI_DEBUGGER */