aboutsummaryrefslogtreecommitdiff
path: root/source/components
diff options
context:
space:
mode:
authorJung-uk Kim <jkim@FreeBSD.org>2012-02-16 00:24:10 +0000
committerJung-uk Kim <jkim@FreeBSD.org>2012-02-16 00:24:10 +0000
commit5437485bdb98c4b00f15969e013c454426e9c862 (patch)
tree71526afe7e3c45a4c88ba7b5d8d57d1e469feec2 /source/components
parent234358d94982312d34c80b868fea481307fb3a48 (diff)
downloadsrc-5437485bdb98c4b00f15969e013c454426e9c862.tar.gz
src-5437485bdb98c4b00f15969e013c454426e9c862.zip
Import ACPICA 20120215.vendor/acpica/20120215
Notes
Notes: svn path=/vendor-sys/acpica/dist/; revision=231798 svn path=/vendor-sys/acpica/20120215/; revision=231799; tag=vendor/acpica/20120215
Diffstat (limited to 'source/components')
-rw-r--r--source/components/debugger/dbcmds.c1084
-rw-r--r--source/components/debugger/dbdisply.c1057
-rw-r--r--source/components/debugger/dbexec.c1105
-rw-r--r--source/components/debugger/dbfileio.c578
-rw-r--r--source/components/debugger/dbhistry.c220
-rw-r--r--source/components/debugger/dbinput.c1091
-rw-r--r--source/components/debugger/dbmethod.c525
-rw-r--r--source/components/debugger/dbnames.c934
-rw-r--r--source/components/debugger/dbstats.c549
-rw-r--r--source/components/debugger/dbutils.c526
-rw-r--r--source/components/debugger/dbxface.c536
-rw-r--r--source/components/disassembler/dmbuffer.c542
-rw-r--r--source/components/disassembler/dmnames.c453
-rw-r--r--source/components/disassembler/dmobject.c589
-rw-r--r--source/components/disassembler/dmopcode.c607
-rw-r--r--source/components/disassembler/dmresrc.c434
-rw-r--r--source/components/disassembler/dmresrcl.c1052
-rw-r--r--source/components/disassembler/dmresrcl2.c700
-rw-r--r--source/components/disassembler/dmresrcs.c358
-rw-r--r--source/components/disassembler/dmutils.c321
-rw-r--r--source/components/disassembler/dmwalk.c935
-rw-r--r--source/components/dispatcher/dsargs.c438
-rw-r--r--source/components/dispatcher/dscontrol.c424
-rw-r--r--source/components/dispatcher/dsfield.c748
-rw-r--r--source/components/dispatcher/dsinit.c238
-rw-r--r--source/components/dispatcher/dsmethod.c726
-rw-r--r--source/components/dispatcher/dsmthdat.c772
-rw-r--r--source/components/dispatcher/dsobject.c867
-rw-r--r--source/components/dispatcher/dsopcode.c809
-rw-r--r--source/components/dispatcher/dsutils.c937
-rw-r--r--source/components/dispatcher/dswexec.c797
-rw-r--r--source/components/dispatcher/dswload.c551
-rw-r--r--source/components/dispatcher/dswload2.c747
-rw-r--r--source/components/dispatcher/dswscope.c239
-rw-r--r--source/components/dispatcher/dswstate.c846
-rw-r--r--source/components/events/evevent.c336
-rw-r--r--source/components/events/evglock.c377
-rw-r--r--source/components/events/evgpe.c831
-rw-r--r--source/components/events/evgpeblk.c550
-rw-r--r--source/components/events/evgpeinit.c462
-rw-r--r--source/components/events/evgpeutil.c425
-rw-r--r--source/components/events/evmisc.c377
-rw-r--r--source/components/events/evregion.c1366
-rw-r--r--source/components/events/evrgnini.c732
-rw-r--r--source/components/events/evsci.c209
-rw-r--r--source/components/events/evxface.c979
-rw-r--r--source/components/events/evxfevnt.c381
-rw-r--r--source/components/events/evxfgpe.c903
-rw-r--r--source/components/events/evxfregn.c313
-rw-r--r--source/components/executer/exconfig.c688
-rw-r--r--source/components/executer/exconvrt.c754
-rw-r--r--source/components/executer/excreate.c574
-rw-r--r--source/components/executer/exdebug.c278
-rw-r--r--source/components/executer/exdump.c1124
-rw-r--r--source/components/executer/exfield.c406
-rw-r--r--source/components/executer/exfldio.c1055
-rw-r--r--source/components/executer/exmisc.c800
-rw-r--r--source/components/executer/exmutex.c554
-rw-r--r--source/components/executer/exnames.c488
-rw-r--r--source/components/executer/exoparg1.c1111
-rw-r--r--source/components/executer/exoparg2.c642
-rw-r--r--source/components/executer/exoparg3.c304
-rw-r--r--source/components/executer/exoparg6.c365
-rw-r--r--source/components/executer/exprep.c648
-rw-r--r--source/components/executer/exregion.c565
-rw-r--r--source/components/executer/exresnte.c302
-rw-r--r--source/components/executer/exresolv.c580
-rw-r--r--source/components/executer/exresop.c738
-rw-r--r--source/components/executer/exstore.c531
-rw-r--r--source/components/executer/exstoren.c314
-rw-r--r--source/components/executer/exstorob.c244
-rw-r--r--source/components/executer/exsystem.c355
-rw-r--r--source/components/executer/exutils.c532
-rw-r--r--source/components/hardware/hwacpi.c209
-rw-r--r--source/components/hardware/hwesleep.c263
-rw-r--r--source/components/hardware/hwgpe.c543
-rw-r--r--source/components/hardware/hwpci.c459
-rw-r--r--source/components/hardware/hwregs.c741
-rw-r--r--source/components/hardware/hwsleep.c384
-rw-r--r--source/components/hardware/hwtimer.c218
-rw-r--r--source/components/hardware/hwvalid.c368
-rw-r--r--source/components/hardware/hwxface.c617
-rw-r--r--source/components/hardware/hwxfsleep.c474
-rw-r--r--source/components/namespace/nsaccess.c700
-rw-r--r--source/components/namespace/nsalloc.c588
-rw-r--r--source/components/namespace/nsdump.c769
-rw-r--r--source/components/namespace/nsdumpdv.c161
-rw-r--r--source/components/namespace/nseval.c485
-rw-r--r--source/components/namespace/nsinit.c665
-rw-r--r--source/components/namespace/nsload.c356
-rw-r--r--source/components/namespace/nsnames.c303
-rw-r--r--source/components/namespace/nsobject.c505
-rw-r--r--source/components/namespace/nsparse.c225
-rw-r--r--source/components/namespace/nspredef.c1243
-rw-r--r--source/components/namespace/nsrepair.c802
-rw-r--r--source/components/namespace/nsrepair2.c827
-rw-r--r--source/components/namespace/nssearch.c424
-rw-r--r--source/components/namespace/nsutils.c875
-rw-r--r--source/components/namespace/nswalk.c386
-rw-r--r--source/components/namespace/nsxfeval.c960
-rw-r--r--source/components/namespace/nsxfname.c702
-rw-r--r--source/components/namespace/nsxfobj.c285
-rw-r--r--source/components/parser/psargs.c940
-rw-r--r--source/components/parser/psloop.c1268
-rw-r--r--source/components/parser/psopcode.c522
-rw-r--r--source/components/parser/psparse.c711
-rw-r--r--source/components/parser/psscope.c302
-rw-r--r--source/components/parser/pstree.c360
-rw-r--r--source/components/parser/psutils.c290
-rw-r--r--source/components/parser/pswalk.c121
-rw-r--r--source/components/parser/psxface.c442
-rw-r--r--source/components/resources/rsaddr.c407
-rw-r--r--source/components/resources/rscalc.c730
-rw-r--r--source/components/resources/rscreate.c534
-rw-r--r--source/components/resources/rsdump.c946
-rw-r--r--source/components/resources/rsinfo.c265
-rw-r--r--source/components/resources/rsio.c304
-rw-r--r--source/components/resources/rsirq.c308
-rw-r--r--source/components/resources/rslist.c275
-rw-r--r--source/components/resources/rsmemory.c251
-rw-r--r--source/components/resources/rsmisc.c869
-rw-r--r--source/components/resources/rsserial.c425
-rw-r--r--source/components/resources/rsutils.c861
-rw-r--r--source/components/resources/rsxface.c689
-rw-r--r--source/components/tables/tbfadt.c704
-rw-r--r--source/components/tables/tbfind.c143
-rw-r--r--source/components/tables/tbinstal.c806
-rw-r--r--source/components/tables/tbutils.c760
-rw-r--r--source/components/tables/tbxface.c712
-rw-r--r--source/components/tables/tbxfroot.c299
-rw-r--r--source/components/utilities/utaddress.c322
-rw-r--r--source/components/utilities/utalloc.c416
-rw-r--r--source/components/utilities/utcache.c361
-rw-r--r--source/components/utilities/utclib.c889
-rw-r--r--source/components/utilities/utcopy.c1078
-rw-r--r--source/components/utilities/utdebug.c741
-rw-r--r--source/components/utilities/utdecode.c637
-rw-r--r--source/components/utilities/utdelete.c766
-rw-r--r--source/components/utilities/uteval.c370
-rw-r--r--source/components/utilities/utglobal.c365
-rw-r--r--source/components/utilities/utids.c380
-rw-r--r--source/components/utilities/utinit.c192
-rw-r--r--source/components/utilities/utlock.c205
-rw-r--r--source/components/utilities/utmath.c379
-rw-r--r--source/components/utilities/utmisc.c1299
-rw-r--r--source/components/utilities/utmutex.c397
-rw-r--r--source/components/utilities/utobject.c787
-rw-r--r--source/components/utilities/utosi.c422
-rw-r--r--source/components/utilities/utresrc.c923
-rw-r--r--source/components/utilities/utstate.c398
-rw-r--r--source/components/utilities/uttrack.c711
-rw-r--r--source/components/utilities/utxface.c837
-rw-r--r--source/components/utilities/utxferror.c478
-rw-r--r--source/components/utilities/utxfmutex.c213
154 files changed, 89875 insertions, 0 deletions
diff --git a/source/components/debugger/dbcmds.c b/source/components/debugger/dbcmds.c
new file mode 100644
index 000000000000..cf214a161c07
--- /dev/null
+++ b/source/components/debugger/dbcmds.c
@@ -0,0 +1,1084 @@
+/*******************************************************************************
+ *
+ * Module Name: dbcmds - Miscellaneous debug commands and output routines
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2012, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include "acpi.h"
+#include "accommon.h"
+#include "acevents.h"
+#include "acdebug.h"
+#include "acnamesp.h"
+#include "acresrc.h"
+#include "actables.h"
+
+#ifdef ACPI_DEBUGGER
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("dbcmds")
+
+
+/* Local prototypes */
+
+static void
+AcpiDmCompareAmlResources (
+ UINT8 *Aml1Buffer,
+ ACPI_RSDESC_SIZE Aml1BufferLength,
+ UINT8 *Aml2Buffer,
+ ACPI_RSDESC_SIZE Aml2BufferLength);
+
+static ACPI_STATUS
+AcpiDmTestResourceConversion (
+ ACPI_NAMESPACE_NODE *Node,
+ char *Name);
+
+static ACPI_STATUS
+AcpiDbResourceCallback (
+ ACPI_RESOURCE *Resource,
+ void *Context);
+
+static ACPI_STATUS
+AcpiDbDeviceResources (
+ ACPI_HANDLE ObjHandle,
+ UINT32 NestingLevel,
+ void *Context,
+ void **ReturnValue);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbConvertToNode
+ *
+ * PARAMETERS: InString - String to convert
+ *
+ * RETURN: Pointer to a NS node
+ *
+ * DESCRIPTION: Convert a string to a valid NS pointer. Handles numeric or
+ * alpha strings.
+ *
+ ******************************************************************************/
+
+ACPI_NAMESPACE_NODE *
+AcpiDbConvertToNode (
+ char *InString)
+{
+ ACPI_NAMESPACE_NODE *Node;
+
+
+ if ((*InString >= 0x30) && (*InString <= 0x39))
+ {
+ /* Numeric argument, convert */
+
+ Node = ACPI_TO_POINTER (ACPI_STRTOUL (InString, NULL, 16));
+ if (!AcpiOsReadable (Node, sizeof (ACPI_NAMESPACE_NODE)))
+ {
+ AcpiOsPrintf ("Address %p is invalid in this address space\n",
+ Node);
+ return (NULL);
+ }
+
+ /* Make sure pointer is valid NS node */
+
+ if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED)
+ {
+ AcpiOsPrintf ("Address %p is not a valid NS node [%s]\n",
+ Node, AcpiUtGetDescriptorName (Node));
+ return (NULL);
+ }
+ }
+ else
+ {
+ /* Alpha argument */
+ /* The parameter is a name string that must be resolved to a
+ * Named obj
+ */
+ Node = AcpiDbLocalNsLookup (InString);
+ if (!Node)
+ {
+ Node = AcpiGbl_RootNode;
+ }
+ }
+
+ return (Node);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbSleep
+ *
+ * PARAMETERS: ObjectArg - Desired sleep state (0-5)
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Simulate a sleep/wake sequence
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDbSleep (
+ char *ObjectArg)
+{
+ ACPI_STATUS Status;
+ UINT8 SleepState;
+
+
+ ACPI_FUNCTION_TRACE (AcpiDbSleep);
+
+
+ SleepState = (UINT8) ACPI_STRTOUL (ObjectArg, NULL, 0);
+
+ AcpiOsPrintf ("**** Prepare to sleep ****\n");
+ Status = AcpiEnterSleepStatePrep (SleepState);
+ if (ACPI_FAILURE (Status))
+ {
+ goto ErrorExit;
+ }
+
+ AcpiOsPrintf ("**** Going to sleep ****\n");
+ Status = AcpiEnterSleepState (SleepState);
+ if (ACPI_FAILURE (Status))
+ {
+ goto ErrorExit;
+ }
+
+ AcpiOsPrintf ("**** Prepare to return from sleep ****\n");
+ Status = AcpiLeaveSleepStatePrep (SleepState);
+ if (ACPI_FAILURE (Status))
+ {
+ goto ErrorExit;
+ }
+
+ AcpiOsPrintf ("**** Returning from sleep ****\n");
+ Status = AcpiLeaveSleepState (SleepState);
+ if (ACPI_FAILURE (Status))
+ {
+ goto ErrorExit;
+ }
+
+ return (Status);
+
+
+ErrorExit:
+
+ ACPI_EXCEPTION ((AE_INFO, Status, "During sleep test"));
+ return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDisplayLocks
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Display information about internal mutexes.
+ *
+ ******************************************************************************/
+
+void
+AcpiDbDisplayLocks (
+ void)
+{
+ UINT32 i;
+
+
+ for (i = 0; i < ACPI_MAX_MUTEX; i++)
+ {
+ AcpiOsPrintf ("%26s : %s\n", AcpiUtGetMutexName (i),
+ AcpiGbl_MutexInfo[i].ThreadId == ACPI_MUTEX_NOT_ACQUIRED
+ ? "Locked" : "Unlocked");
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDisplayTableInfo
+ *
+ * PARAMETERS: TableArg - String with name of table to be displayed
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Display information about loaded tables. Current
+ * implementation displays all loaded tables.
+ *
+ ******************************************************************************/
+
+void
+AcpiDbDisplayTableInfo (
+ char *TableArg)
+{
+ UINT32 i;
+ ACPI_TABLE_DESC *TableDesc;
+ ACPI_STATUS Status;
+
+
+ /* Walk the entire root table list */
+
+ for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
+ {
+ TableDesc = &AcpiGbl_RootTableList.Tables[i];
+ AcpiOsPrintf ("%u ", i);
+
+ /* Make sure that the table is mapped */
+
+ Status = AcpiTbVerifyTable (TableDesc);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+
+ /* Dump the table header */
+
+ if (TableDesc->Pointer)
+ {
+ AcpiTbPrintTableHeader (TableDesc->Address, TableDesc->Pointer);
+ }
+ else
+ {
+ /* If the pointer is null, the table has been unloaded */
+
+ ACPI_INFO ((AE_INFO, "%4.4s - Table has been unloaded",
+ TableDesc->Signature.Ascii));
+ }
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbUnloadAcpiTable
+ *
+ * PARAMETERS: TableArg - Name of the table to be unloaded
+ * InstanceArg - Which instance of the table to unload (if
+ * there are multiple tables of the same type)
+ *
+ * RETURN: Nonde
+ *
+ * DESCRIPTION: Unload an ACPI table.
+ * Instance is not implemented
+ *
+ ******************************************************************************/
+
+void
+AcpiDbUnloadAcpiTable (
+ char *TableArg,
+ char *InstanceArg)
+{
+/* TBD: Need to reimplement for new data structures */
+
+#if 0
+ UINT32 i;
+ ACPI_STATUS Status;
+
+
+ /* Search all tables for the target type */
+
+ for (i = 0; i < (ACPI_TABLE_ID_MAX+1); i++)
+ {
+ if (!ACPI_STRNCMP (TableArg, AcpiGbl_TableData[i].Signature,
+ AcpiGbl_TableData[i].SigLength))
+ {
+ /* Found the table, unload it */
+
+ Status = AcpiUnloadTable (i);
+ if (ACPI_SUCCESS (Status))
+ {
+ AcpiOsPrintf ("[%s] unloaded and uninstalled\n", TableArg);
+ }
+ else
+ {
+ AcpiOsPrintf ("%s, while unloading [%s]\n",
+ AcpiFormatException (Status), TableArg);
+ }
+
+ return;
+ }
+ }
+
+ AcpiOsPrintf ("Unknown table type [%s]\n", TableArg);
+#endif
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbSendNotify
+ *
+ * PARAMETERS: Name - Name of ACPI object to send the notify to
+ * Value - Value of the notify to send.
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Send an ACPI notification. The value specified is sent to the
+ * named object as an ACPI notify.
+ *
+ ******************************************************************************/
+
+void
+AcpiDbSendNotify (
+ char *Name,
+ UINT32 Value)
+{
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_STATUS Status;
+
+
+ /* Translate name to an Named object */
+
+ Node = AcpiDbConvertToNode (Name);
+ if (!Node)
+ {
+ return;
+ }
+
+ /* Decode Named object type */
+
+ switch (Node->Type)
+ {
+ case ACPI_TYPE_DEVICE:
+ case ACPI_TYPE_THERMAL:
+
+ /* Send the notify */
+
+ Status = AcpiEvQueueNotifyRequest (Node, Value);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Could not queue notify\n");
+ }
+ break;
+
+ default:
+ AcpiOsPrintf ("Named object is not a device or a thermal object\n");
+ break;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDisplayInterfaces
+ *
+ * PARAMETERS: ActionArg - Null, "install", or "remove"
+ * InterfaceNameArg - Name for install/remove options
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Display or modify the global _OSI interface list
+ *
+ ******************************************************************************/
+
+void
+AcpiDbDisplayInterfaces (
+ char *ActionArg,
+ char *InterfaceNameArg)
+{
+ ACPI_INTERFACE_INFO *NextInterface;
+ char *SubString;
+ ACPI_STATUS Status;
+
+
+ /* If no arguments, just display current interface list */
+
+ if (!ActionArg)
+ {
+ (void) AcpiOsAcquireMutex (AcpiGbl_OsiMutex,
+ ACPI_WAIT_FOREVER);
+
+ NextInterface = AcpiGbl_SupportedInterfaces;
+
+ while (NextInterface)
+ {
+ if (!(NextInterface->Flags & ACPI_OSI_INVALID))
+ {
+ AcpiOsPrintf ("%s\n", NextInterface->Name);
+ }
+ NextInterface = NextInterface->Next;
+ }
+
+ AcpiOsReleaseMutex (AcpiGbl_OsiMutex);
+ return;
+ }
+
+ /* If ActionArg exists, so must InterfaceNameArg */
+
+ if (!InterfaceNameArg)
+ {
+ AcpiOsPrintf ("Missing Interface Name argument\n");
+ return;
+ }
+
+ /* Uppercase the action for match below */
+
+ AcpiUtStrupr (ActionArg);
+
+ /* Install - install an interface */
+
+ SubString = ACPI_STRSTR ("INSTALL", ActionArg);
+ if (SubString)
+ {
+ Status = AcpiInstallInterface (InterfaceNameArg);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("%s, while installing \"%s\"\n",
+ AcpiFormatException (Status), InterfaceNameArg);
+ }
+ return;
+ }
+
+ /* Remove - remove an interface */
+
+ SubString = ACPI_STRSTR ("REMOVE", ActionArg);
+ if (SubString)
+ {
+ Status = AcpiRemoveInterface (InterfaceNameArg);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("%s, while removing \"%s\"\n",
+ AcpiFormatException (Status), InterfaceNameArg);
+ }
+ return;
+ }
+
+ /* Invalid ActionArg */
+
+ AcpiOsPrintf ("Invalid action argument: %s\n", ActionArg);
+ return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDisplayTemplate
+ *
+ * PARAMETERS: BufferArg - Buffer name or addrss
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump a buffer that contains a resource template
+ *
+ ******************************************************************************/
+
+void
+AcpiDbDisplayTemplate (
+ char *BufferArg)
+{
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_STATUS Status;
+ ACPI_BUFFER ReturnObj;
+
+
+ /* Translate BufferArg to an Named object */
+
+ Node = AcpiDbConvertToNode (BufferArg);
+ if (!Node || (Node == AcpiGbl_RootNode))
+ {
+ AcpiOsPrintf ("Invalid argument: %s\n", BufferArg);
+ return;
+ }
+
+ /* We must have a buffer object */
+
+ if (Node->Type != ACPI_TYPE_BUFFER)
+ {
+ AcpiOsPrintf ("Not a Buffer object, cannot be a template: %s\n",
+ BufferArg);
+ return;
+ }
+
+ ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE;
+ ReturnObj.Pointer = AcpiGbl_DbBuffer;
+
+ /* Attempt to convert the raw buffer to a resource list */
+
+ Status = AcpiRsCreateResourceList (Node->Object, &ReturnObj);
+
+ AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
+ AcpiDbgLevel |= ACPI_LV_RESOURCES;
+
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Could not convert Buffer to a resource list: %s, %s\n",
+ BufferArg, AcpiFormatException (Status));
+ goto DumpBuffer;
+ }
+
+ /* Now we can dump the resource list */
+
+ AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE,
+ ReturnObj.Pointer));
+
+DumpBuffer:
+ AcpiOsPrintf ("\nRaw data buffer:\n");
+ AcpiUtDumpBuffer ((UINT8 *) Node->Object->Buffer.Pointer,
+ Node->Object->Buffer.Length,
+ DB_BYTE_DISPLAY, ACPI_UINT32_MAX);
+
+ AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
+ return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmCompareAmlResources
+ *
+ * PARAMETERS: Aml1Buffer - Contains first resource list
+ * Aml1BufferLength - Length of first resource list
+ * Aml2Buffer - Contains second resource list
+ * Aml2BufferLength - Length of second resource list
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Compare two AML resource lists, descriptor by descriptor (in
+ * order to isolate a miscompare to an individual resource)
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmCompareAmlResources (
+ UINT8 *Aml1Buffer,
+ ACPI_RSDESC_SIZE Aml1BufferLength,
+ UINT8 *Aml2Buffer,
+ ACPI_RSDESC_SIZE Aml2BufferLength)
+{
+ UINT8 *Aml1;
+ UINT8 *Aml2;
+ UINT8 *Aml1End;
+ UINT8 *Aml2End;
+ ACPI_RSDESC_SIZE Aml1Length;
+ ACPI_RSDESC_SIZE Aml2Length;
+ ACPI_RSDESC_SIZE Offset = 0;
+ UINT8 ResourceType;
+ UINT32 Count = 0;
+ UINT32 i;
+
+
+ /* Compare overall buffer sizes (may be different due to size rounding) */
+
+ if (Aml1BufferLength != Aml2BufferLength)
+ {
+ AcpiOsPrintf (
+ "**** Buffer length mismatch in converted AML: Original %X, New %X ****\n",
+ Aml1BufferLength, Aml2BufferLength);
+ }
+
+ Aml1 = Aml1Buffer;
+ Aml2 = Aml2Buffer;
+ Aml1End = Aml1Buffer + Aml1BufferLength;
+ Aml2End = Aml2Buffer + Aml2BufferLength;
+
+ /* Walk the descriptor lists, comparing each descriptor */
+
+ while ((Aml1 < Aml1End) && (Aml2 < Aml2End))
+ {
+ /* Get the lengths of each descriptor */
+
+ Aml1Length = AcpiUtGetDescriptorLength (Aml1);
+ Aml2Length = AcpiUtGetDescriptorLength (Aml2);
+ ResourceType = AcpiUtGetResourceType (Aml1);
+
+ /* Check for descriptor length match */
+
+ if (Aml1Length != Aml2Length)
+ {
+ AcpiOsPrintf (
+ "**** Length mismatch in descriptor [%.2X] type %2.2X, Offset %8.8X Len1 %X, Len2 %X ****\n",
+ Count, ResourceType, Offset, Aml1Length, Aml2Length);
+ }
+
+ /* Check for descriptor byte match */
+
+ else if (ACPI_MEMCMP (Aml1, Aml2, Aml1Length))
+ {
+ AcpiOsPrintf (
+ "**** Data mismatch in descriptor [%.2X] type %2.2X, Offset %8.8X ****\n",
+ Count, ResourceType, Offset);
+
+ for (i = 0; i < Aml1Length; i++)
+ {
+ if (Aml1[i] != Aml2[i])
+ {
+ AcpiOsPrintf ("Mismatch at byte offset %.2X: is %2.2X, should be %2.2X\n",
+ i, Aml2[i], Aml1[i]);
+ }
+ }
+ }
+
+ /* Exit on EndTag descriptor */
+
+ if (ResourceType == ACPI_RESOURCE_NAME_END_TAG)
+ {
+ return;
+ }
+
+ /* Point to next descriptor in each buffer */
+
+ Count++;
+ Offset += Aml1Length;
+ Aml1 += Aml1Length;
+ Aml2 += Aml2Length;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmTestResourceConversion
+ *
+ * PARAMETERS: Node - Parent device node
+ * Name - resource method name (_CRS)
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Compare the original AML with a conversion of the AML to
+ * internal resource list, then back to AML.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDmTestResourceConversion (
+ ACPI_NAMESPACE_NODE *Node,
+ char *Name)
+{
+ ACPI_STATUS Status;
+ ACPI_BUFFER ReturnObj;
+ ACPI_BUFFER ResourceObj;
+ ACPI_BUFFER NewAml;
+ ACPI_OBJECT *OriginalAml;
+
+
+ AcpiOsPrintf ("Resource Conversion Comparison:\n");
+
+ NewAml.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
+ ReturnObj.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
+ ResourceObj.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
+
+ /* Get the original _CRS AML resource template */
+
+ Status = AcpiEvaluateObject (Node, Name, NULL, &ReturnObj);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Could not obtain %s: %s\n",
+ Name, AcpiFormatException (Status));
+ return (Status);
+ }
+
+ /* Get the AML resource template, converted to internal resource structs */
+
+ Status = AcpiGetCurrentResources (Node, &ResourceObj);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n",
+ AcpiFormatException (Status));
+ goto Exit1;
+ }
+
+ /* Convert internal resource list to external AML resource template */
+
+ Status = AcpiRsCreateAmlResources (ResourceObj.Pointer, &NewAml);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("AcpiRsCreateAmlResources failed: %s\n",
+ AcpiFormatException (Status));
+ goto Exit2;
+ }
+
+ /* Compare original AML to the newly created AML resource list */
+
+ OriginalAml = ReturnObj.Pointer;
+
+ AcpiDmCompareAmlResources (
+ OriginalAml->Buffer.Pointer, (ACPI_RSDESC_SIZE) OriginalAml->Buffer.Length,
+ NewAml.Pointer, (ACPI_RSDESC_SIZE) NewAml.Length);
+
+ /* Cleanup and exit */
+
+ ACPI_FREE (NewAml.Pointer);
+Exit2:
+ ACPI_FREE (ResourceObj.Pointer);
+Exit1:
+ ACPI_FREE (ReturnObj.Pointer);
+ return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbResourceCallback
+ *
+ * PARAMETERS: ACPI_WALK_RESOURCE_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Simple callback to exercise AcpiWalkResources
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDbResourceCallback (
+ ACPI_RESOURCE *Resource,
+ void *Context)
+{
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDeviceResources
+ *
+ * PARAMETERS: ACPI_WALK_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Display the _PRT/_CRS/_PRS resources for a device object.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDbDeviceResources (
+ ACPI_HANDLE ObjHandle,
+ UINT32 NestingLevel,
+ void *Context,
+ void **ReturnValue)
+{
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_NAMESPACE_NODE *PrtNode = NULL;
+ ACPI_NAMESPACE_NODE *CrsNode = NULL;
+ ACPI_NAMESPACE_NODE *PrsNode = NULL;
+ ACPI_NAMESPACE_NODE *AeiNode = NULL;
+ char *ParentPath;
+ ACPI_BUFFER ReturnObj;
+ ACPI_STATUS Status;
+
+
+ Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle);
+ ParentPath = AcpiNsGetExternalPathname (Node);
+ if (!ParentPath)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ /* Get handles to the resource methods for this device */
+
+ (void) AcpiGetHandle (Node, METHOD_NAME__PRT, ACPI_CAST_PTR (ACPI_HANDLE, &PrtNode));
+ (void) AcpiGetHandle (Node, METHOD_NAME__CRS, ACPI_CAST_PTR (ACPI_HANDLE, &CrsNode));
+ (void) AcpiGetHandle (Node, METHOD_NAME__PRS, ACPI_CAST_PTR (ACPI_HANDLE, &PrsNode));
+ (void) AcpiGetHandle (Node, METHOD_NAME__AEI, ACPI_CAST_PTR (ACPI_HANDLE, &AeiNode));
+ if (!PrtNode && !CrsNode && !PrsNode && !AeiNode)
+ {
+ goto Cleanup; /* Nothing to do */
+ }
+
+ AcpiOsPrintf ("\nDevice: %s\n", ParentPath);
+
+ /* Prepare for a return object of arbitrary size */
+
+ ReturnObj.Pointer = AcpiGbl_DbBuffer;
+ ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE;
+
+
+ /* _PRT */
+
+ if (PrtNode)
+ {
+ AcpiOsPrintf ("Evaluating _PRT\n");
+
+ Status = AcpiEvaluateObject (PrtNode, NULL, NULL, &ReturnObj);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Could not evaluate _PRT: %s\n",
+ AcpiFormatException (Status));
+ goto GetCrs;
+ }
+
+ ReturnObj.Pointer = AcpiGbl_DbBuffer;
+ ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE;
+
+ Status = AcpiGetIrqRoutingTable (Node, &ReturnObj);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("GetIrqRoutingTable failed: %s\n",
+ AcpiFormatException (Status));
+ goto GetCrs;
+ }
+
+ AcpiRsDumpIrqList (ACPI_CAST_PTR (UINT8, AcpiGbl_DbBuffer));
+ }
+
+
+ /* _CRS */
+
+GetCrs:
+ if (CrsNode)
+ {
+ AcpiOsPrintf ("Evaluating _CRS\n");
+
+ ReturnObj.Pointer = AcpiGbl_DbBuffer;
+ ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE;
+
+ Status = AcpiEvaluateObject (CrsNode, NULL, NULL, &ReturnObj);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Could not evaluate _CRS: %s\n",
+ AcpiFormatException (Status));
+ goto GetPrs;
+ }
+
+ /* This code is here to exercise the AcpiWalkResources interface */
+
+ Status = AcpiWalkResources (Node, METHOD_NAME__CRS,
+ AcpiDbResourceCallback, NULL);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("AcpiWalkResources failed: %s\n",
+ AcpiFormatException (Status));
+ goto GetPrs;
+ }
+
+ /* Get the _CRS resource list */
+
+ ReturnObj.Pointer = AcpiGbl_DbBuffer;
+ ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE;
+
+ Status = AcpiGetCurrentResources (Node, &ReturnObj);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n",
+ AcpiFormatException (Status));
+ goto GetPrs;
+ }
+
+ /* Dump the _CRS resource list */
+
+ AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE,
+ ReturnObj.Pointer));
+
+ /*
+ * Perform comparison of original AML to newly created AML. This tests both
+ * the AML->Resource conversion and the Resource->Aml conversion.
+ */
+ Status = AcpiDmTestResourceConversion (Node, METHOD_NAME__CRS);
+
+ /* Execute _SRS with the resource list */
+
+ Status = AcpiSetCurrentResources (Node, &ReturnObj);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("AcpiSetCurrentResources failed: %s\n",
+ AcpiFormatException (Status));
+ goto GetPrs;
+ }
+ }
+
+
+ /* _PRS */
+
+GetPrs:
+ if (PrsNode)
+ {
+ AcpiOsPrintf ("Evaluating _PRS\n");
+
+ ReturnObj.Pointer = AcpiGbl_DbBuffer;
+ ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE;
+
+ Status = AcpiEvaluateObject (PrsNode, NULL, NULL, &ReturnObj);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Could not evaluate _PRS: %s\n",
+ AcpiFormatException (Status));
+ goto GetAei;
+ }
+
+ ReturnObj.Pointer = AcpiGbl_DbBuffer;
+ ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE;
+
+ Status = AcpiGetPossibleResources (Node, &ReturnObj);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("AcpiGetPossibleResources failed: %s\n",
+ AcpiFormatException (Status));
+ goto GetAei;
+ }
+
+ AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE, AcpiGbl_DbBuffer));
+ }
+
+
+ /* _AEI */
+
+GetAei:
+ if (AeiNode)
+ {
+ AcpiOsPrintf ("Evaluating _AEI\n");
+
+ ReturnObj.Pointer = AcpiGbl_DbBuffer;
+ ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE;
+
+ Status = AcpiEvaluateObject (AeiNode, NULL, NULL, &ReturnObj);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Could not evaluate _AEI: %s\n",
+ AcpiFormatException (Status));
+ goto Cleanup;
+ }
+
+ ReturnObj.Pointer = AcpiGbl_DbBuffer;
+ ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE;
+
+ Status = AcpiGetEventResources (Node, &ReturnObj);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("AcpiGetEventResources failed: %s\n",
+ AcpiFormatException (Status));
+ goto Cleanup;
+ }
+
+ AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE, AcpiGbl_DbBuffer));
+ }
+
+
+Cleanup:
+ ACPI_FREE (ParentPath);
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDisplayResources
+ *
+ * PARAMETERS: ObjectArg - String object name or object pointer.
+ * "*" means "display resources for all devices"
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Display the resource objects associated with a device.
+ *
+ ******************************************************************************/
+
+void
+AcpiDbDisplayResources (
+ char *ObjectArg)
+{
+ ACPI_NAMESPACE_NODE *Node;
+
+
+ AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
+ AcpiDbgLevel |= ACPI_LV_RESOURCES;
+
+ /* Asterisk means "display resources for all devices" */
+
+ if (!ACPI_STRCMP (ObjectArg, "*"))
+ {
+ (void) AcpiWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+ ACPI_UINT32_MAX, AcpiDbDeviceResources, NULL, NULL, NULL);
+ }
+ else
+ {
+ /* Convert string to object pointer */
+
+ Node = AcpiDbConvertToNode (ObjectArg);
+ if (Node)
+ {
+ if (Node->Type != ACPI_TYPE_DEVICE)
+ {
+ AcpiOsPrintf ("%4.4s: Name is not a device object (%s)\n",
+ Node->Name.Ascii, AcpiUtGetTypeName (Node->Type));
+ }
+ else
+ {
+ (void) AcpiDbDeviceResources (Node, 0, NULL, NULL);
+ }
+ }
+ }
+
+ AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
+}
+
+
+#if (!ACPI_REDUCED_HARDWARE)
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbGenerateGpe
+ *
+ * PARAMETERS: GpeArg - Raw GPE number, ascii string
+ * BlockArg - GPE block number, ascii string
+ * 0 or 1 for FADT GPE blocks
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Generate a GPE
+ *
+ ******************************************************************************/
+
+void
+AcpiDbGenerateGpe (
+ char *GpeArg,
+ char *BlockArg)
+{
+ UINT32 BlockNumber;
+ UINT32 GpeNumber;
+ ACPI_GPE_EVENT_INFO *GpeEventInfo;
+
+
+ GpeNumber = ACPI_STRTOUL (GpeArg, NULL, 0);
+ BlockNumber = ACPI_STRTOUL (BlockArg, NULL, 0);
+
+
+ GpeEventInfo = AcpiEvGetGpeEventInfo (ACPI_TO_POINTER (BlockNumber),
+ GpeNumber);
+ if (!GpeEventInfo)
+ {
+ AcpiOsPrintf ("Invalid GPE\n");
+ return;
+ }
+
+ (void) AcpiEvGpeDispatch (NULL, GpeEventInfo, GpeNumber);
+}
+#endif /* !ACPI_REDUCED_HARDWARE */
+
+#endif /* ACPI_DEBUGGER */
diff --git a/source/components/debugger/dbdisply.c b/source/components/debugger/dbdisply.c
new file mode 100644
index 000000000000..fa943e7fa996
--- /dev/null
+++ b/source/components/debugger/dbdisply.c
@@ -0,0 +1,1057 @@
+/*******************************************************************************
+ *
+ * Module Name: dbdisply - debug display commands
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2012, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include "acpi.h"
+#include "accommon.h"
+#include "amlcode.h"
+#include "acdispat.h"
+#include "acnamesp.h"
+#include "acparser.h"
+#include "acinterp.h"
+#include "acdebug.h"
+#include "acdisasm.h"
+
+
+#ifdef ACPI_DEBUGGER
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("dbdisply")
+
+/* Local prototypes */
+
+static void
+AcpiDbDumpParserDescriptor (
+ ACPI_PARSE_OBJECT *Op);
+
+static void *
+AcpiDbGetPointer (
+ void *Target);
+
+
+/*
+ * System handler information.
+ * Used for Handlers command, in AcpiDbDisplayHandlers.
+ */
+#define ACPI_PREDEFINED_PREFIX "%25s (%.2X) : "
+#define ACPI_HANDLER_NAME_STRING "%30s : "
+#define ACPI_HANDLER_PRESENT_STRING "%-9s (%p)\n"
+#define ACPI_HANDLER_NOT_PRESENT_STRING "%-9s\n"
+
+/* All predefined Address Space IDs */
+
+static ACPI_ADR_SPACE_TYPE AcpiGbl_SpaceIdList[] =
+{
+ ACPI_ADR_SPACE_SYSTEM_MEMORY,
+ ACPI_ADR_SPACE_SYSTEM_IO,
+ ACPI_ADR_SPACE_PCI_CONFIG,
+ ACPI_ADR_SPACE_EC,
+ ACPI_ADR_SPACE_SMBUS,
+ ACPI_ADR_SPACE_CMOS,
+ ACPI_ADR_SPACE_PCI_BAR_TARGET,
+ ACPI_ADR_SPACE_IPMI,
+ ACPI_ADR_SPACE_GPIO,
+ ACPI_ADR_SPACE_GSBUS,
+ ACPI_ADR_SPACE_DATA_TABLE,
+ ACPI_ADR_SPACE_FIXED_HARDWARE
+};
+
+/* Global handler information */
+
+typedef struct acpi_handler_info
+{
+ void *Handler;
+ char *Name;
+
+} ACPI_HANDLER_INFO;
+
+static ACPI_HANDLER_INFO AcpiGbl_HandlerList[] =
+{
+ {&AcpiGbl_SystemNotify.Handler, "System Notifications"},
+ {&AcpiGbl_DeviceNotify.Handler, "Device Notifications"},
+ {&AcpiGbl_TableHandler, "ACPI Table Events"},
+ {&AcpiGbl_ExceptionHandler, "Control Method Exceptions"},
+ {&AcpiGbl_InterfaceHandler, "OSI Invocations"}
+};
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbGetPointer
+ *
+ * PARAMETERS: Target - Pointer to string to be converted
+ *
+ * RETURN: Converted pointer
+ *
+ * DESCRIPTION: Convert an ascii pointer value to a real value
+ *
+ ******************************************************************************/
+
+static void *
+AcpiDbGetPointer (
+ void *Target)
+{
+ void *ObjPtr;
+
+
+ ObjPtr = ACPI_TO_POINTER (ACPI_STRTOUL (Target, NULL, 16));
+ return (ObjPtr);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDumpParserDescriptor
+ *
+ * PARAMETERS: Op - A parser Op descriptor
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Display a formatted parser object
+ *
+ ******************************************************************************/
+
+static void
+AcpiDbDumpParserDescriptor (
+ ACPI_PARSE_OBJECT *Op)
+{
+ const ACPI_OPCODE_INFO *Info;
+
+
+ Info = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
+
+ AcpiOsPrintf ("Parser Op Descriptor:\n");
+ AcpiOsPrintf ("%20.20s : %4.4X\n", "Opcode", Op->Common.AmlOpcode);
+
+ ACPI_DEBUG_ONLY_MEMBERS (AcpiOsPrintf ("%20.20s : %s\n", "Opcode Name",
+ Info->Name));
+
+ AcpiOsPrintf ("%20.20s : %p\n", "Value/ArgList", Op->Common.Value.Arg);
+ AcpiOsPrintf ("%20.20s : %p\n", "Parent", Op->Common.Parent);
+ AcpiOsPrintf ("%20.20s : %p\n", "NextOp", Op->Common.Next);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDecodeAndDisplayObject
+ *
+ * PARAMETERS: Target - String with object to be displayed. Names
+ * and hex pointers are supported.
+ * OutputType - Byte, Word, Dword, or Qword (B|W|D|Q)
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Display a formatted ACPI object
+ *
+ ******************************************************************************/
+
+void
+AcpiDbDecodeAndDisplayObject (
+ char *Target,
+ char *OutputType)
+{
+ void *ObjPtr;
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ UINT32 Display = DB_BYTE_DISPLAY;
+ char Buffer[80];
+ ACPI_BUFFER RetBuf;
+ ACPI_STATUS Status;
+ UINT32 Size;
+
+
+ if (!Target)
+ {
+ return;
+ }
+
+ /* Decode the output type */
+
+ if (OutputType)
+ {
+ AcpiUtStrupr (OutputType);
+ if (OutputType[0] == 'W')
+ {
+ Display = DB_WORD_DISPLAY;
+ }
+ else if (OutputType[0] == 'D')
+ {
+ Display = DB_DWORD_DISPLAY;
+ }
+ else if (OutputType[0] == 'Q')
+ {
+ Display = DB_QWORD_DISPLAY;
+ }
+ }
+
+ RetBuf.Length = sizeof (Buffer);
+ RetBuf.Pointer = Buffer;
+
+ /* Differentiate between a number and a name */
+
+ if ((Target[0] >= 0x30) && (Target[0] <= 0x39))
+ {
+ ObjPtr = AcpiDbGetPointer (Target);
+ if (!AcpiOsReadable (ObjPtr, 16))
+ {
+ AcpiOsPrintf ("Address %p is invalid in this address space\n",
+ ObjPtr);
+ return;
+ }
+
+ /* Decode the object type */
+
+ switch (ACPI_GET_DESCRIPTOR_TYPE (ObjPtr))
+ {
+ case ACPI_DESC_TYPE_NAMED:
+
+ /* This is a namespace Node */
+
+ if (!AcpiOsReadable (ObjPtr, sizeof (ACPI_NAMESPACE_NODE)))
+ {
+ AcpiOsPrintf (
+ "Cannot read entire Named object at address %p\n", ObjPtr);
+ return;
+ }
+
+ Node = ObjPtr;
+ goto DumpNode;
+
+
+ case ACPI_DESC_TYPE_OPERAND:
+
+ /* This is a ACPI OPERAND OBJECT */
+
+ if (!AcpiOsReadable (ObjPtr, sizeof (ACPI_OPERAND_OBJECT)))
+ {
+ AcpiOsPrintf ("Cannot read entire ACPI object at address %p\n",
+ ObjPtr);
+ return;
+ }
+
+ AcpiUtDumpBuffer (ObjPtr, sizeof (ACPI_OPERAND_OBJECT), Display,
+ ACPI_UINT32_MAX);
+ AcpiExDumpObjectDescriptor (ObjPtr, 1);
+ break;
+
+
+ case ACPI_DESC_TYPE_PARSER:
+
+ /* This is a Parser Op object */
+
+ if (!AcpiOsReadable (ObjPtr, sizeof (ACPI_PARSE_OBJECT)))
+ {
+ AcpiOsPrintf (
+ "Cannot read entire Parser object at address %p\n", ObjPtr);
+ return;
+ }
+
+ AcpiUtDumpBuffer (ObjPtr, sizeof (ACPI_PARSE_OBJECT), Display,
+ ACPI_UINT32_MAX);
+ AcpiDbDumpParserDescriptor ((ACPI_PARSE_OBJECT *) ObjPtr);
+ break;
+
+
+ default:
+
+ /* Is not a recognizeable object */
+
+ Size = 16;
+ if (AcpiOsReadable (ObjPtr, 64))
+ {
+ Size = 64;
+ }
+
+ /* Just dump some memory */
+
+ AcpiUtDumpBuffer (ObjPtr, Size, Display, ACPI_UINT32_MAX);
+ break;
+ }
+
+ return;
+ }
+
+ /* The parameter is a name string that must be resolved to a Named obj */
+
+ Node = AcpiDbLocalNsLookup (Target);
+ if (!Node)
+ {
+ return;
+ }
+
+
+DumpNode:
+ /* Now dump the NS node */
+
+ Status = AcpiGetName (Node, ACPI_FULL_PATHNAME, &RetBuf);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Could not convert name to pathname\n");
+ }
+
+ else
+ {
+ AcpiOsPrintf ("Object (%p) Pathname: %s\n",
+ Node, (char *) RetBuf.Pointer);
+ }
+
+ if (!AcpiOsReadable (Node, sizeof (ACPI_NAMESPACE_NODE)))
+ {
+ AcpiOsPrintf ("Invalid Named object at address %p\n", Node);
+ return;
+ }
+
+ AcpiUtDumpBuffer ((void *) Node, sizeof (ACPI_NAMESPACE_NODE),
+ Display, ACPI_UINT32_MAX);
+ AcpiExDumpNamespaceNode (Node, 1);
+
+ ObjDesc = AcpiNsGetAttachedObject (Node);
+ if (ObjDesc)
+ {
+ AcpiOsPrintf ("\nAttached Object (%p):\n", ObjDesc);
+ if (!AcpiOsReadable (ObjDesc, sizeof (ACPI_OPERAND_OBJECT)))
+ {
+ AcpiOsPrintf ("Invalid internal ACPI Object at address %p\n",
+ ObjDesc);
+ return;
+ }
+
+ AcpiUtDumpBuffer ((void *) ObjDesc, sizeof (ACPI_OPERAND_OBJECT),
+ Display, ACPI_UINT32_MAX);
+ AcpiExDumpObjectDescriptor (ObjDesc, 1);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDisplayMethodInfo
+ *
+ * PARAMETERS: StartOp - Root of the control method parse tree
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Display information about the current method
+ *
+ ******************************************************************************/
+
+void
+AcpiDbDisplayMethodInfo (
+ ACPI_PARSE_OBJECT *StartOp)
+{
+ ACPI_WALK_STATE *WalkState;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_PARSE_OBJECT *RootOp;
+ ACPI_PARSE_OBJECT *Op;
+ const ACPI_OPCODE_INFO *OpInfo;
+ UINT32 NumOps = 0;
+ UINT32 NumOperands = 0;
+ UINT32 NumOperators = 0;
+ UINT32 NumRemainingOps = 0;
+ UINT32 NumRemainingOperands = 0;
+ UINT32 NumRemainingOperators = 0;
+ BOOLEAN CountRemaining = FALSE;
+
+
+ WalkState = AcpiDsGetCurrentWalkState (AcpiGbl_CurrentWalkList);
+ if (!WalkState)
+ {
+ AcpiOsPrintf ("There is no method currently executing\n");
+ return;
+ }
+
+ ObjDesc = WalkState->MethodDesc;
+ Node = WalkState->MethodNode;
+
+ AcpiOsPrintf ("Currently executing control method is [%4.4s]\n",
+ AcpiUtGetNodeName (Node));
+ AcpiOsPrintf ("%X Arguments, SyncLevel = %X\n",
+ (UINT32) ObjDesc->Method.ParamCount,
+ (UINT32) ObjDesc->Method.SyncLevel);
+
+
+ RootOp = StartOp;
+ while (RootOp->Common.Parent)
+ {
+ RootOp = RootOp->Common.Parent;
+ }
+
+ Op = RootOp;
+
+ while (Op)
+ {
+ if (Op == StartOp)
+ {
+ CountRemaining = TRUE;
+ }
+
+ NumOps++;
+ if (CountRemaining)
+ {
+ NumRemainingOps++;
+ }
+
+ /* Decode the opcode */
+
+ OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
+ switch (OpInfo->Class)
+ {
+ case AML_CLASS_ARGUMENT:
+ if (CountRemaining)
+ {
+ NumRemainingOperands++;
+ }
+
+ NumOperands++;
+ break;
+
+ case AML_CLASS_UNKNOWN:
+ /* Bad opcode or ASCII character */
+
+ continue;
+
+ default:
+ if (CountRemaining)
+ {
+ NumRemainingOperators++;
+ }
+
+ NumOperators++;
+ break;
+ }
+
+ Op = AcpiPsGetDepthNext (StartOp, Op);
+ }
+
+ AcpiOsPrintf (
+ "Method contains: %X AML Opcodes - %X Operators, %X Operands\n",
+ NumOps, NumOperators, NumOperands);
+
+ AcpiOsPrintf (
+ "Remaining to execute: %X AML Opcodes - %X Operators, %X Operands\n",
+ NumRemainingOps, NumRemainingOperators, NumRemainingOperands);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDisplayLocals
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Display all locals for the currently running control method
+ *
+ ******************************************************************************/
+
+void
+AcpiDbDisplayLocals (
+ void)
+{
+ ACPI_WALK_STATE *WalkState;
+
+
+ WalkState = AcpiDsGetCurrentWalkState (AcpiGbl_CurrentWalkList);
+ if (!WalkState)
+ {
+ AcpiOsPrintf ("There is no method currently executing\n");
+ return;
+ }
+
+ AcpiDmDisplayLocals (WalkState);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDisplayArguments
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Display all arguments for the currently running control method
+ *
+ ******************************************************************************/
+
+void
+AcpiDbDisplayArguments (
+ void)
+{
+ ACPI_WALK_STATE *WalkState;
+
+
+ WalkState = AcpiDsGetCurrentWalkState (AcpiGbl_CurrentWalkList);
+ if (!WalkState)
+ {
+ AcpiOsPrintf ("There is no method currently executing\n");
+ return;
+ }
+
+ AcpiDmDisplayArguments (WalkState);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDisplayResults
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Display current contents of a method result stack
+ *
+ ******************************************************************************/
+
+void
+AcpiDbDisplayResults (
+ void)
+{
+ UINT32 i;
+ ACPI_WALK_STATE *WalkState;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ UINT32 ResultCount = 0;
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_GENERIC_STATE *Frame;
+ UINT32 Index; /* Index onto current frame */
+
+
+ WalkState = AcpiDsGetCurrentWalkState (AcpiGbl_CurrentWalkList);
+ if (!WalkState)
+ {
+ AcpiOsPrintf ("There is no method currently executing\n");
+ return;
+ }
+
+ ObjDesc = WalkState->MethodDesc;
+ Node = WalkState->MethodNode;
+
+ if (WalkState->Results)
+ {
+ ResultCount = WalkState->ResultCount;
+ }
+
+ AcpiOsPrintf ("Method [%4.4s] has %X stacked result objects\n",
+ AcpiUtGetNodeName (Node), ResultCount);
+
+ /* From the top element of result stack */
+
+ Frame = WalkState->Results;
+ Index = (ResultCount - 1) % ACPI_RESULTS_FRAME_OBJ_NUM;
+
+ for (i = 0; i < ResultCount; i++)
+ {
+ ObjDesc = Frame->Results.ObjDesc[Index];
+ AcpiOsPrintf ("Result%u: ", i);
+ AcpiDmDisplayInternalObject (ObjDesc, WalkState);
+ if (Index == 0)
+ {
+ Frame = Frame->Results.Next;
+ Index = ACPI_RESULTS_FRAME_OBJ_NUM;
+ }
+ Index--;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDisplayCallingTree
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Display current calling tree of nested control methods
+ *
+ ******************************************************************************/
+
+void
+AcpiDbDisplayCallingTree (
+ void)
+{
+ ACPI_WALK_STATE *WalkState;
+ ACPI_NAMESPACE_NODE *Node;
+
+
+ WalkState = AcpiDsGetCurrentWalkState (AcpiGbl_CurrentWalkList);
+ if (!WalkState)
+ {
+ AcpiOsPrintf ("There is no method currently executing\n");
+ return;
+ }
+
+ Node = WalkState->MethodNode;
+ AcpiOsPrintf ("Current Control Method Call Tree\n");
+
+ while (WalkState)
+ {
+ Node = WalkState->MethodNode;
+
+ AcpiOsPrintf (" [%4.4s]\n", AcpiUtGetNodeName (Node));
+
+ WalkState = WalkState->Next;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDisplayObjectType
+ *
+ * PARAMETERS: ObjectArg - User entered NS node handle
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Display type of an arbitrary NS node
+ *
+ ******************************************************************************/
+
+void
+AcpiDbDisplayObjectType (
+ char *ObjectArg)
+{
+ ACPI_HANDLE Handle;
+ ACPI_DEVICE_INFO *Info;
+ ACPI_STATUS Status;
+ UINT32 i;
+
+
+ Handle = ACPI_TO_POINTER (ACPI_STRTOUL (ObjectArg, NULL, 16));
+
+ Status = AcpiGetObjectInfo (Handle, &Info);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Could not get object info, %s\n",
+ AcpiFormatException (Status));
+ return;
+ }
+
+ AcpiOsPrintf ("ADR: %8.8X%8.8X, STA: %8.8X, Flags: %X\n",
+ ACPI_FORMAT_UINT64 (Info->Address),
+ Info->CurrentStatus, Info->Flags);
+
+ AcpiOsPrintf ("S1D-%2.2X S2D-%2.2X S3D-%2.2X S4D-%2.2X\n",
+ Info->HighestDstates[0], Info->HighestDstates[1],
+ Info->HighestDstates[2], Info->HighestDstates[3]);
+
+ AcpiOsPrintf ("S0W-%2.2X S1W-%2.2X S2W-%2.2X S3W-%2.2X S4W-%2.2X\n",
+ Info->LowestDstates[0], Info->LowestDstates[1],
+ Info->LowestDstates[2], Info->LowestDstates[3],
+ Info->LowestDstates[4]);
+
+ if (Info->Valid & ACPI_VALID_HID)
+ {
+ AcpiOsPrintf ("HID: %s\n", Info->HardwareId.String);
+ }
+ if (Info->Valid & ACPI_VALID_UID)
+ {
+ AcpiOsPrintf ("UID: %s\n", Info->UniqueId.String);
+ }
+ if (Info->Valid & ACPI_VALID_CID)
+ {
+ for (i = 0; i < Info->CompatibleIdList.Count; i++)
+ {
+ AcpiOsPrintf ("CID %u: %s\n", i,
+ Info->CompatibleIdList.Ids[i].String);
+ }
+ }
+
+ ACPI_FREE (Info);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDisplayResultObject
+ *
+ * PARAMETERS: ObjDesc - Object to be displayed
+ * WalkState - Current walk state
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Display the result of an AML opcode
+ *
+ * Note: Curently only displays the result object if we are single stepping.
+ * However, this output may be useful in other contexts and could be enabled
+ * to do so if needed.
+ *
+ ******************************************************************************/
+
+void
+AcpiDbDisplayResultObject (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ ACPI_WALK_STATE *WalkState)
+{
+
+ /* Only display if single stepping */
+
+ if (!AcpiGbl_CmSingleStep)
+ {
+ return;
+ }
+
+ AcpiOsPrintf ("ResultObj: ");
+ AcpiDmDisplayInternalObject (ObjDesc, WalkState);
+ AcpiOsPrintf ("\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDisplayArgumentObject
+ *
+ * PARAMETERS: ObjDesc - Object to be displayed
+ * WalkState - Current walk state
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Display the result of an AML opcode
+ *
+ ******************************************************************************/
+
+void
+AcpiDbDisplayArgumentObject (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ ACPI_WALK_STATE *WalkState)
+{
+
+ if (!AcpiGbl_CmSingleStep)
+ {
+ return;
+ }
+
+ AcpiOsPrintf ("ArgObj: ");
+ AcpiDmDisplayInternalObject (ObjDesc, WalkState);
+}
+
+
+#if (!ACPI_REDUCED_HARDWARE)
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDisplayGpes
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Display the current GPE structures
+ *
+ ******************************************************************************/
+
+void
+AcpiDbDisplayGpes (
+ void)
+{
+ ACPI_GPE_BLOCK_INFO *GpeBlock;
+ ACPI_GPE_XRUPT_INFO *GpeXruptInfo;
+ ACPI_GPE_EVENT_INFO *GpeEventInfo;
+ ACPI_GPE_REGISTER_INFO *GpeRegisterInfo;
+ char *GpeType;
+ UINT32 GpeIndex;
+ UINT32 Block = 0;
+ UINT32 i;
+ UINT32 j;
+ char Buffer[80];
+ ACPI_BUFFER RetBuf;
+ ACPI_STATUS Status;
+
+
+ RetBuf.Length = sizeof (Buffer);
+ RetBuf.Pointer = Buffer;
+
+ Block = 0;
+
+ /* Walk the GPE lists */
+
+ GpeXruptInfo = AcpiGbl_GpeXruptListHead;
+ while (GpeXruptInfo)
+ {
+ GpeBlock = GpeXruptInfo->GpeBlockListHead;
+ while (GpeBlock)
+ {
+ Status = AcpiGetName (GpeBlock->Node, ACPI_FULL_PATHNAME, &RetBuf);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Could not convert name to pathname\n");
+ }
+
+ if (GpeBlock->Node == AcpiGbl_FadtGpeDevice)
+ {
+ GpeType = "FADT-defined GPE block";
+ }
+ else
+ {
+ GpeType = "GPE Block Device";
+ }
+
+ AcpiOsPrintf ("\nBlock %u - Info %p DeviceNode %p [%s] - %s\n",
+ Block, GpeBlock, GpeBlock->Node, Buffer, GpeType);
+
+ AcpiOsPrintf (" Registers: %u (%u GPEs)\n",
+ GpeBlock->RegisterCount, GpeBlock->GpeCount);
+
+ AcpiOsPrintf (" GPE range: 0x%X to 0x%X on interrupt %u\n",
+ GpeBlock->BlockBaseNumber,
+ GpeBlock->BlockBaseNumber + (GpeBlock->GpeCount - 1),
+ GpeXruptInfo->InterruptNumber);
+
+ AcpiOsPrintf (
+ " RegisterInfo: %p Status %8.8X%8.8X Enable %8.8X%8.8X\n",
+ GpeBlock->RegisterInfo,
+ ACPI_FORMAT_UINT64 (GpeBlock->RegisterInfo->StatusAddress.Address),
+ ACPI_FORMAT_UINT64 (GpeBlock->RegisterInfo->EnableAddress.Address));
+
+ AcpiOsPrintf (" EventInfo: %p\n", GpeBlock->EventInfo);
+
+ /* Examine each GPE Register within the block */
+
+ for (i = 0; i < GpeBlock->RegisterCount; i++)
+ {
+ GpeRegisterInfo = &GpeBlock->RegisterInfo[i];
+
+ AcpiOsPrintf (
+ " Reg %u: (GPE %.2X-%.2X) RunEnable %2.2X WakeEnable %2.2X"
+ " Status %8.8X%8.8X Enable %8.8X%8.8X\n",
+ i, GpeRegisterInfo->BaseGpeNumber,
+ GpeRegisterInfo->BaseGpeNumber + (ACPI_GPE_REGISTER_WIDTH - 1),
+ GpeRegisterInfo->EnableForRun,
+ GpeRegisterInfo->EnableForWake,
+ ACPI_FORMAT_UINT64 (GpeRegisterInfo->StatusAddress.Address),
+ ACPI_FORMAT_UINT64 (GpeRegisterInfo->EnableAddress.Address));
+
+ /* Now look at the individual GPEs in this byte register */
+
+ for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++)
+ {
+ GpeIndex = (i * ACPI_GPE_REGISTER_WIDTH) + j;
+ GpeEventInfo = &GpeBlock->EventInfo[GpeIndex];
+
+ if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) ==
+ ACPI_GPE_DISPATCH_NONE)
+ {
+ /* This GPE is not used (no method or handler), ignore it */
+
+ continue;
+ }
+
+ AcpiOsPrintf (
+ " GPE %.2X: %p RunRefs %2.2X Flags %2.2X (",
+ GpeBlock->BlockBaseNumber + GpeIndex, GpeEventInfo,
+ GpeEventInfo->RuntimeCount, GpeEventInfo->Flags);
+
+ /* Decode the flags byte */
+
+ if (GpeEventInfo->Flags & ACPI_GPE_LEVEL_TRIGGERED)
+ {
+ AcpiOsPrintf ("Level, ");
+ }
+ else
+ {
+ AcpiOsPrintf ("Edge, ");
+ }
+
+ if (GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE)
+ {
+ AcpiOsPrintf ("CanWake, ");
+ }
+ else
+ {
+ AcpiOsPrintf ("RunOnly, ");
+ }
+
+ switch (GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK)
+ {
+ case ACPI_GPE_DISPATCH_NONE:
+ AcpiOsPrintf ("NotUsed");
+ break;
+ case ACPI_GPE_DISPATCH_METHOD:
+ AcpiOsPrintf ("Method");
+ break;
+ case ACPI_GPE_DISPATCH_HANDLER:
+ AcpiOsPrintf ("Handler");
+ break;
+ case ACPI_GPE_DISPATCH_NOTIFY:
+ AcpiOsPrintf ("Notify");
+ break;
+ default:
+ AcpiOsPrintf ("UNKNOWN: %X",
+ GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK);
+ break;
+ }
+
+ AcpiOsPrintf (")\n");
+ }
+ }
+ Block++;
+ GpeBlock = GpeBlock->Next;
+ }
+ GpeXruptInfo = GpeXruptInfo->Next;
+ }
+}
+#endif /* !ACPI_REDUCED_HARDWARE */
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDisplayHandlers
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Display the currently installed global handlers
+ *
+ ******************************************************************************/
+
+void
+AcpiDbDisplayHandlers (
+ void)
+{
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_OPERAND_OBJECT *HandlerObj;
+ ACPI_ADR_SPACE_TYPE SpaceId;
+ UINT32 i;
+
+
+ /* Operation region handlers */
+
+ AcpiOsPrintf ("\nOperation Region Handlers:\n");
+
+ ObjDesc = AcpiNsGetAttachedObject (AcpiGbl_RootNode);
+ if (ObjDesc)
+ {
+ for (i = 0; i < ACPI_ARRAY_LENGTH (AcpiGbl_SpaceIdList); i++)
+ {
+ SpaceId = AcpiGbl_SpaceIdList[i];
+ HandlerObj = ObjDesc->Device.Handler;
+
+ AcpiOsPrintf (ACPI_PREDEFINED_PREFIX,
+ AcpiUtGetRegionName ((UINT8) SpaceId), SpaceId);
+
+ while (HandlerObj)
+ {
+ if (AcpiGbl_SpaceIdList[i] == HandlerObj->AddressSpace.SpaceId)
+ {
+ AcpiOsPrintf (ACPI_HANDLER_PRESENT_STRING,
+ (HandlerObj->AddressSpace.HandlerFlags &
+ ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) ? "Default" : "User",
+ HandlerObj->AddressSpace.Handler);
+ goto FoundHandler;
+ }
+
+ HandlerObj = HandlerObj->AddressSpace.Next;
+ }
+
+ /* There is no handler for this SpaceId */
+
+ AcpiOsPrintf ("None\n");
+
+ FoundHandler:;
+ }
+
+ /* Find all handlers for user-defined SpaceIDs */
+
+ HandlerObj = ObjDesc->Device.Handler;
+ while (HandlerObj)
+ {
+ if (HandlerObj->AddressSpace.SpaceId >= ACPI_USER_REGION_BEGIN)
+ {
+ AcpiOsPrintf (ACPI_PREDEFINED_PREFIX,
+ "User-defined ID", HandlerObj->AddressSpace.SpaceId);
+ AcpiOsPrintf (ACPI_HANDLER_PRESENT_STRING,
+ (HandlerObj->AddressSpace.HandlerFlags &
+ ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) ? "Default" : "User",
+ HandlerObj->AddressSpace.Handler);
+ }
+
+ HandlerObj = HandlerObj->AddressSpace.Next;
+ }
+ }
+
+#if (!ACPI_REDUCED_HARDWARE)
+
+ /* Fixed event handlers */
+
+ AcpiOsPrintf ("\nFixed Event Handlers:\n");
+
+ for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++)
+ {
+ AcpiOsPrintf (ACPI_PREDEFINED_PREFIX, AcpiUtGetEventName (i), i);
+ if (AcpiGbl_FixedEventHandlers[i].Handler)
+ {
+ AcpiOsPrintf (ACPI_HANDLER_PRESENT_STRING, "User",
+ AcpiGbl_FixedEventHandlers[i].Handler);
+ }
+ else
+ {
+ AcpiOsPrintf (ACPI_HANDLER_NOT_PRESENT_STRING, "None");
+ }
+ }
+
+#endif /* !ACPI_REDUCED_HARDWARE */
+
+ /* Miscellaneous global handlers */
+
+ AcpiOsPrintf ("\nMiscellaneous Global Handlers:\n");
+
+ for (i = 0; i < ACPI_ARRAY_LENGTH (AcpiGbl_HandlerList); i++)
+ {
+ AcpiOsPrintf (ACPI_HANDLER_NAME_STRING, AcpiGbl_HandlerList[i].Name);
+ if (AcpiGbl_HandlerList[i].Handler)
+ {
+ AcpiOsPrintf (ACPI_HANDLER_PRESENT_STRING, "User",
+ AcpiGbl_HandlerList[i].Handler);
+ }
+ else
+ {
+ AcpiOsPrintf (ACPI_HANDLER_NOT_PRESENT_STRING, "None");
+ }
+ }
+}
+
+#endif /* ACPI_DEBUGGER */
diff --git a/source/components/debugger/dbexec.c b/source/components/debugger/dbexec.c
new file mode 100644
index 000000000000..7818c9ddbef8
--- /dev/null
+++ b/source/components/debugger/dbexec.c
@@ -0,0 +1,1105 @@
+/*******************************************************************************
+ *
+ * Module Name: dbexec - debugger control method execution
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2012, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include "acpi.h"
+#include "accommon.h"
+#include "acdebug.h"
+#include "acnamesp.h"
+
+#ifdef ACPI_DEBUGGER
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("dbexec")
+
+
+static ACPI_DB_METHOD_INFO AcpiGbl_DbMethodInfo;
+#define DB_DEFAULT_PKG_ELEMENTS 33
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiDbExecuteMethod (
+ ACPI_DB_METHOD_INFO *Info,
+ ACPI_BUFFER *ReturnObj);
+
+static void
+AcpiDbExecuteSetup (
+ ACPI_DB_METHOD_INFO *Info);
+
+static UINT32
+AcpiDbGetOutstandingAllocations (
+ void);
+
+static void ACPI_SYSTEM_XFACE
+AcpiDbMethodThread (
+ void *Context);
+
+static ACPI_STATUS
+AcpiDbExecutionWalk (
+ ACPI_HANDLE ObjHandle,
+ UINT32 NestingLevel,
+ void *Context,
+ void **ReturnValue);
+
+static ACPI_STATUS
+AcpiDbHexCharToValue (
+ int HexChar,
+ UINT8 *ReturnValue);
+
+static ACPI_STATUS
+AcpiDbConvertToPackage (
+ char *String,
+ ACPI_OBJECT *Object);
+
+static ACPI_STATUS
+AcpiDbConvertToObject (
+ ACPI_OBJECT_TYPE Type,
+ char *String,
+ ACPI_OBJECT *Object);
+
+static void
+AcpiDbDeleteObjects (
+ UINT32 Count,
+ ACPI_OBJECT *Objects);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbHexCharToValue
+ *
+ * PARAMETERS: HexChar - Ascii Hex digit, 0-9|a-f|A-F
+ * ReturnValue - Where the converted value is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Convert a single hex character to a 4-bit number (0-16).
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDbHexCharToValue (
+ int HexChar,
+ UINT8 *ReturnValue)
+{
+ UINT8 Value;
+
+
+ /* Digit must be ascii [0-9a-fA-F] */
+
+ if (!ACPI_IS_XDIGIT (HexChar))
+ {
+ return (AE_BAD_HEX_CONSTANT);
+ }
+
+ if (HexChar <= 0x39)
+ {
+ Value = (UINT8) (HexChar - 0x30);
+ }
+ else
+ {
+ Value = (UINT8) (ACPI_TOUPPER (HexChar) - 0x37);
+ }
+
+ *ReturnValue = Value;
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbHexByteToBinary
+ *
+ * PARAMETERS: HexByte - Double hex digit (0x00 - 0xFF) in format:
+ * HiByte then LoByte.
+ * ReturnValue - Where the converted value is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Convert two hex characters to an 8 bit number (0 - 255).
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDbHexByteToBinary (
+ char *HexByte,
+ UINT8 *ReturnValue)
+{
+ UINT8 Local0;
+ UINT8 Local1;
+ ACPI_STATUS Status;
+
+
+ /* High byte */
+
+ Status = AcpiDbHexCharToValue (HexByte[0], &Local0);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /* Low byte */
+
+ Status = AcpiDbHexCharToValue (HexByte[1], &Local1);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ *ReturnValue = (UINT8) ((Local0 << 4) | Local1);
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbConvertToBuffer
+ *
+ * PARAMETERS: String - Input string to be converted
+ * Object - Where the buffer object is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Convert a string to a buffer object. String is treated a list
+ * of buffer elements, each separated by a space or comma.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDbConvertToBuffer (
+ char *String,
+ ACPI_OBJECT *Object)
+{
+ UINT32 i;
+ UINT32 j;
+ UINT32 Length;
+ UINT8 *Buffer;
+ ACPI_STATUS Status;
+
+
+ /* Generate the final buffer length */
+
+ for (i = 0, Length = 0; String[i];)
+ {
+ i+=2;
+ Length++;
+
+ while (String[i] &&
+ ((String[i] == ',') || (String[i] == ' ')))
+ {
+ i++;
+ }
+ }
+
+ Buffer = ACPI_ALLOCATE (Length);
+ if (!Buffer)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ /* Convert the command line bytes to the buffer */
+
+ for (i = 0, j = 0; String[i];)
+ {
+ Status = AcpiDbHexByteToBinary (&String[i], &Buffer[j]);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_FREE (Buffer);
+ return (Status);
+ }
+
+ j++;
+ i+=2;
+ while (String[i] &&
+ ((String[i] == ',') || (String[i] == ' ')))
+ {
+ i++;
+ }
+ }
+
+ Object->Type = ACPI_TYPE_BUFFER;
+ Object->Buffer.Pointer = Buffer;
+ Object->Buffer.Length = Length;
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbConvertToPackage
+ *
+ * PARAMETERS: String - Input string to be converted
+ * Object - Where the package object is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Convert a string to a package object. Handles nested packages
+ * via recursion with AcpiDbConvertToObject.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDbConvertToPackage (
+ char *String,
+ ACPI_OBJECT *Object)
+{
+ char *This;
+ char *Next;
+ UINT32 i;
+ ACPI_OBJECT_TYPE Type;
+ ACPI_OBJECT *Elements;
+ ACPI_STATUS Status;
+
+
+ Elements = ACPI_ALLOCATE_ZEROED (
+ DB_DEFAULT_PKG_ELEMENTS * sizeof (ACPI_OBJECT));
+
+ This = String;
+ for (i = 0; i < (DB_DEFAULT_PKG_ELEMENTS - 1); i++)
+ {
+ This = AcpiDbGetNextToken (This, &Next, &Type);
+ if (!This)
+ {
+ break;
+ }
+
+ /* Recursive call to convert each package element */
+
+ Status = AcpiDbConvertToObject (Type, This, &Elements[i]);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiDbDeleteObjects (i + 1, Elements);
+ ACPI_FREE (Elements);
+ return (Status);
+ }
+
+ This = Next;
+ }
+
+ Object->Type = ACPI_TYPE_PACKAGE;
+ Object->Package.Count = i;
+ Object->Package.Elements = Elements;
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbConvertToObject
+ *
+ * PARAMETERS: Type - Object type as determined by parser
+ * String - Input string to be converted
+ * Object - Where the new object is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Convert a typed and tokenized string to an ACPI_OBJECT. Typing:
+ * 1) String objects were surrounded by quotes.
+ * 2) Buffer objects were surrounded by parentheses.
+ * 3) Package objects were surrounded by brackets "[]".
+ * 4) All standalone tokens are treated as integers.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDbConvertToObject (
+ ACPI_OBJECT_TYPE Type,
+ char *String,
+ ACPI_OBJECT *Object)
+{
+ ACPI_STATUS Status = AE_OK;
+
+
+ switch (Type)
+ {
+ case ACPI_TYPE_STRING:
+ Object->Type = ACPI_TYPE_STRING;
+ Object->String.Pointer = String;
+ Object->String.Length = (UINT32) ACPI_STRLEN (String);
+ break;
+
+ case ACPI_TYPE_BUFFER:
+ Status = AcpiDbConvertToBuffer (String, Object);
+ break;
+
+ case ACPI_TYPE_PACKAGE:
+ Status = AcpiDbConvertToPackage (String, Object);
+ break;
+
+ default:
+ Object->Type = ACPI_TYPE_INTEGER;
+ Status = AcpiUtStrtoul64 (String, 16, &Object->Integer.Value);
+ break;
+ }
+
+ return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDeleteObjects
+ *
+ * PARAMETERS: Count - Count of objects in the list
+ * Objects - Array of ACPI_OBJECTs to be deleted
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Delete a list of ACPI_OBJECTS. Handles packages and nested
+ * packages via recursion.
+ *
+ ******************************************************************************/
+
+static void
+AcpiDbDeleteObjects (
+ UINT32 Count,
+ ACPI_OBJECT *Objects)
+{
+ UINT32 i;
+
+
+ for (i = 0; i < Count; i++)
+ {
+ switch (Objects[i].Type)
+ {
+ case ACPI_TYPE_BUFFER:
+ ACPI_FREE (Objects[i].Buffer.Pointer);
+ break;
+
+ case ACPI_TYPE_PACKAGE:
+
+ /* Recursive call to delete package elements */
+
+ AcpiDbDeleteObjects (Objects[i].Package.Count,
+ Objects[i].Package.Elements);
+
+ /* Free the elements array */
+
+ ACPI_FREE (Objects[i].Package.Elements);
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbExecuteMethod
+ *
+ * PARAMETERS: Info - Valid info segment
+ * ReturnObj - Where to put return object
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Execute a control method.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDbExecuteMethod (
+ ACPI_DB_METHOD_INFO *Info,
+ ACPI_BUFFER *ReturnObj)
+{
+ ACPI_STATUS Status;
+ ACPI_OBJECT_LIST ParamObjects;
+ ACPI_OBJECT Params[ACPI_METHOD_NUM_ARGS];
+ ACPI_HANDLE Handle;
+ ACPI_DEVICE_INFO *ObjInfo;
+ UINT32 i;
+
+
+ ACPI_FUNCTION_TRACE (DbExecuteMethod);
+
+
+ if (AcpiGbl_DbOutputToFile && !AcpiDbgLevel)
+ {
+ AcpiOsPrintf ("Warning: debug output is not enabled!\n");
+ }
+
+ /* Get the NS node, determines existence also */
+
+ Status = AcpiGetHandle (NULL, Info->Pathname, &Handle);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Get the object info for number of method parameters */
+
+ Status = AcpiGetObjectInfo (Handle, &ObjInfo);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ ParamObjects.Pointer = NULL;
+ ParamObjects.Count = 0;
+
+ if (ObjInfo->Type == ACPI_TYPE_METHOD)
+ {
+ /* Are there arguments to the method? */
+
+ i = 0;
+ if (Info->Args && Info->Args[0])
+ {
+ /* Get arguments passed on the command line */
+
+ for (; Info->Args[i] &&
+ (i < ACPI_METHOD_NUM_ARGS) &&
+ (i < ObjInfo->ParamCount);
+ i++)
+ {
+ /* Convert input string (token) to an actual ACPI_OBJECT */
+
+ Status = AcpiDbConvertToObject (Info->Types[i],
+ Info->Args[i], &Params[i]);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status,
+ "While parsing method arguments"));
+ goto Cleanup;
+ }
+ }
+ }
+
+ /* Create additional "default" parameters as needed */
+
+ if (i < ObjInfo->ParamCount)
+ {
+ AcpiOsPrintf ("Adding %u arguments containing default values\n",
+ ObjInfo->ParamCount - i);
+
+ for (; i < ObjInfo->ParamCount; i++)
+ {
+ switch (i)
+ {
+ case 0:
+
+ Params[0].Type = ACPI_TYPE_INTEGER;
+ Params[0].Integer.Value = 0x01020304;
+ break;
+
+ case 1:
+
+ Params[1].Type = ACPI_TYPE_STRING;
+ Params[1].String.Length = 12;
+ Params[1].String.Pointer = "AML Debugger";
+ break;
+
+ default:
+
+ Params[i].Type = ACPI_TYPE_INTEGER;
+ Params[i].Integer.Value = i * (UINT64) 0x1000;
+ break;
+ }
+ }
+ }
+
+ ParamObjects.Count = ObjInfo->ParamCount;
+ ParamObjects.Pointer = Params;
+ }
+
+ /* Prepare for a return object of arbitrary size */
+
+ ReturnObj->Pointer = AcpiGbl_DbBuffer;
+ ReturnObj->Length = ACPI_DEBUG_BUFFER_SIZE;
+
+ /* Do the actual method execution */
+
+ AcpiGbl_MethodExecuting = TRUE;
+ Status = AcpiEvaluateObject (NULL,
+ Info->Pathname, &ParamObjects, ReturnObj);
+
+ AcpiGbl_CmSingleStep = FALSE;
+ AcpiGbl_MethodExecuting = FALSE;
+
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status,
+ "while executing %s from debugger", Info->Pathname));
+
+ if (Status == AE_BUFFER_OVERFLOW)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Possible overflow of internal debugger buffer (size 0x%X needed 0x%X)",
+ ACPI_DEBUG_BUFFER_SIZE, (UINT32) ReturnObj->Length));
+ }
+ }
+
+Cleanup:
+ AcpiDbDeleteObjects (ObjInfo->ParamCount, Params);
+ ACPI_FREE (ObjInfo);
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbExecuteSetup
+ *
+ * PARAMETERS: Info - Valid method info
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Setup info segment prior to method execution
+ *
+ ******************************************************************************/
+
+static void
+AcpiDbExecuteSetup (
+ ACPI_DB_METHOD_INFO *Info)
+{
+
+ /* Catenate the current scope to the supplied name */
+
+ Info->Pathname[0] = 0;
+ if ((Info->Name[0] != '\\') &&
+ (Info->Name[0] != '/'))
+ {
+ ACPI_STRCAT (Info->Pathname, AcpiGbl_DbScopeBuf);
+ }
+
+ ACPI_STRCAT (Info->Pathname, Info->Name);
+ AcpiDbPrepNamestring (Info->Pathname);
+
+ AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
+ AcpiOsPrintf ("Executing %s\n", Info->Pathname);
+
+ if (Info->Flags & EX_SINGLE_STEP)
+ {
+ AcpiGbl_CmSingleStep = TRUE;
+ AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
+ }
+
+ else
+ {
+ /* No single step, allow redirection to a file */
+
+ AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
+ }
+}
+
+
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+UINT32
+AcpiDbGetCacheInfo (
+ ACPI_MEMORY_LIST *Cache)
+{
+
+ return (Cache->TotalAllocated - Cache->TotalFreed - Cache->CurrentDepth);
+}
+#endif
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbGetOutstandingAllocations
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Current global allocation count minus cache entries
+ *
+ * DESCRIPTION: Determine the current number of "outstanding" allocations --
+ * those allocations that have not been freed and also are not
+ * in one of the various object caches.
+ *
+ ******************************************************************************/
+
+static UINT32
+AcpiDbGetOutstandingAllocations (
+ void)
+{
+ UINT32 Outstanding = 0;
+
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+
+ Outstanding += AcpiDbGetCacheInfo (AcpiGbl_StateCache);
+ Outstanding += AcpiDbGetCacheInfo (AcpiGbl_PsNodeCache);
+ Outstanding += AcpiDbGetCacheInfo (AcpiGbl_PsNodeExtCache);
+ Outstanding += AcpiDbGetCacheInfo (AcpiGbl_OperandCache);
+#endif
+
+ return (Outstanding);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbExecutionWalk
+ *
+ * PARAMETERS: WALK_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Execute a control method. Name is relative to the current
+ * scope.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDbExecutionWalk (
+ ACPI_HANDLE ObjHandle,
+ UINT32 NestingLevel,
+ void *Context,
+ void **ReturnValue)
+{
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
+ ACPI_BUFFER ReturnObj;
+ ACPI_STATUS Status;
+
+
+ ObjDesc = AcpiNsGetAttachedObject (Node);
+ if (ObjDesc->Method.ParamCount)
+ {
+ return (AE_OK);
+ }
+
+ ReturnObj.Pointer = NULL;
+ ReturnObj.Length = ACPI_ALLOCATE_BUFFER;
+
+ AcpiNsPrintNodePathname (Node, "Execute");
+
+ /* Do the actual method execution */
+
+ AcpiOsPrintf ("\n");
+ AcpiGbl_MethodExecuting = TRUE;
+
+ Status = AcpiEvaluateObject (Node, NULL, NULL, &ReturnObj);
+
+ AcpiOsPrintf ("[%4.4s] returned %s\n", AcpiUtGetNodeName (Node),
+ AcpiFormatException (Status));
+ AcpiGbl_MethodExecuting = FALSE;
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbExecute
+ *
+ * PARAMETERS: Name - Name of method to execute
+ * Args - Parameters to the method
+ * Flags - single step/no single step
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Execute a control method. Name is relative to the current
+ * scope.
+ *
+ ******************************************************************************/
+
+void
+AcpiDbExecute (
+ char *Name,
+ char **Args,
+ ACPI_OBJECT_TYPE *Types,
+ UINT32 Flags)
+{
+ ACPI_STATUS Status;
+ ACPI_BUFFER ReturnObj;
+ char *NameString;
+
+
+#ifdef ACPI_DEBUG_OUTPUT
+ UINT32 PreviousAllocations;
+ UINT32 Allocations;
+
+
+ /* Memory allocation tracking */
+
+ PreviousAllocations = AcpiDbGetOutstandingAllocations ();
+#endif
+
+ if (*Name == '*')
+ {
+ (void) AcpiWalkNamespace (ACPI_TYPE_METHOD, ACPI_ROOT_OBJECT,
+ ACPI_UINT32_MAX, AcpiDbExecutionWalk, NULL, NULL, NULL);
+ return;
+ }
+ else
+ {
+ NameString = ACPI_ALLOCATE (ACPI_STRLEN (Name) + 1);
+ if (!NameString)
+ {
+ return;
+ }
+
+ ACPI_MEMSET (&AcpiGbl_DbMethodInfo, 0, sizeof (ACPI_DB_METHOD_INFO));
+
+ ACPI_STRCPY (NameString, Name);
+ AcpiUtStrupr (NameString);
+ AcpiGbl_DbMethodInfo.Name = NameString;
+ AcpiGbl_DbMethodInfo.Args = Args;
+ AcpiGbl_DbMethodInfo.Types = Types;
+ AcpiGbl_DbMethodInfo.Flags = Flags;
+
+ ReturnObj.Pointer = NULL;
+ ReturnObj.Length = ACPI_ALLOCATE_BUFFER;
+
+ AcpiDbExecuteSetup (&AcpiGbl_DbMethodInfo);
+ Status = AcpiDbExecuteMethod (&AcpiGbl_DbMethodInfo, &ReturnObj);
+ ACPI_FREE (NameString);
+ }
+
+ /*
+ * Allow any handlers in separate threads to complete.
+ * (Such as Notify handlers invoked from AML executed above).
+ */
+ AcpiOsSleep ((UINT64) 10);
+
+
+#ifdef ACPI_DEBUG_OUTPUT
+
+ /* Memory allocation tracking */
+
+ Allocations = AcpiDbGetOutstandingAllocations () - PreviousAllocations;
+
+ AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
+
+ if (Allocations > 0)
+ {
+ AcpiOsPrintf ("Outstanding: 0x%X allocations after execution\n",
+ Allocations);
+ }
+#endif
+
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Execution of %s failed with status %s\n",
+ AcpiGbl_DbMethodInfo.Pathname, AcpiFormatException (Status));
+ }
+ else
+ {
+ /* Display a return object, if any */
+
+ if (ReturnObj.Length)
+ {
+ AcpiOsPrintf ("Execution of %s returned object %p Buflen %X\n",
+ AcpiGbl_DbMethodInfo.Pathname, ReturnObj.Pointer,
+ (UINT32) ReturnObj.Length);
+ AcpiDbDumpExternalObject (ReturnObj.Pointer, 1);
+ }
+ else
+ {
+ AcpiOsPrintf ("No return object from execution of %s\n",
+ AcpiGbl_DbMethodInfo.Pathname);
+ }
+ }
+
+ AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbMethodThread
+ *
+ * PARAMETERS: Context - Execution info segment
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Debugger execute thread. Waits for a command line, then
+ * simply dispatches it.
+ *
+ ******************************************************************************/
+
+static void ACPI_SYSTEM_XFACE
+AcpiDbMethodThread (
+ void *Context)
+{
+ ACPI_STATUS Status;
+ ACPI_DB_METHOD_INFO *Info = Context;
+ ACPI_DB_METHOD_INFO LocalInfo;
+ UINT32 i;
+ UINT8 Allow;
+ ACPI_BUFFER ReturnObj;
+
+
+ /*
+ * AcpiGbl_DbMethodInfo.Arguments will be passed as method arguments.
+ * Prevent AcpiGbl_DbMethodInfo from being modified by multiple threads
+ * concurrently.
+ *
+ * Note: The arguments we are passing are used by the ASL test suite
+ * (aslts). Do not change them without updating the tests.
+ */
+ (void) AcpiOsWaitSemaphore (Info->InfoGate, 1, ACPI_WAIT_FOREVER);
+
+ if (Info->InitArgs)
+ {
+ AcpiDbUInt32ToHexString (Info->NumCreated, Info->IndexOfThreadStr);
+ AcpiDbUInt32ToHexString ((UINT32) AcpiOsGetThreadId (), Info->IdOfThreadStr);
+ }
+
+ if (Info->Threads && (Info->NumCreated < Info->NumThreads))
+ {
+ Info->Threads[Info->NumCreated++] = AcpiOsGetThreadId();
+ }
+
+ LocalInfo = *Info;
+ LocalInfo.Args = LocalInfo.Arguments;
+ LocalInfo.Arguments[0] = LocalInfo.NumThreadsStr;
+ LocalInfo.Arguments[1] = LocalInfo.IdOfThreadStr;
+ LocalInfo.Arguments[2] = LocalInfo.IndexOfThreadStr;
+ LocalInfo.Arguments[3] = NULL;
+
+ LocalInfo.Types = LocalInfo.ArgTypes;
+
+ (void) AcpiOsSignalSemaphore (Info->InfoGate, 1);
+
+ for (i = 0; i < Info->NumLoops; i++)
+ {
+ Status = AcpiDbExecuteMethod (&LocalInfo, &ReturnObj);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("%s During execution of %s at iteration %X\n",
+ AcpiFormatException (Status), Info->Pathname, i);
+ if (Status == AE_ABORT_METHOD)
+ {
+ break;
+ }
+ }
+
+#if 0
+ if ((i % 100) == 0)
+ {
+ AcpiOsPrintf ("%u executions, Thread 0x%x\n", i, AcpiOsGetThreadId ());
+ }
+
+ if (ReturnObj.Length)
+ {
+ AcpiOsPrintf ("Execution of %s returned object %p Buflen %X\n",
+ Info->Pathname, ReturnObj.Pointer, (UINT32) ReturnObj.Length);
+ AcpiDbDumpExternalObject (ReturnObj.Pointer, 1);
+ }
+#endif
+ }
+
+ /* Signal our completion */
+
+ Allow = 0;
+ (void) AcpiOsWaitSemaphore (Info->ThreadCompleteGate, 1, ACPI_WAIT_FOREVER);
+ Info->NumCompleted++;
+
+ if (Info->NumCompleted == Info->NumThreads)
+ {
+ /* Do signal for main thread once only */
+ Allow = 1;
+ }
+
+ (void) AcpiOsSignalSemaphore (Info->ThreadCompleteGate, 1);
+
+ if (Allow)
+ {
+ Status = AcpiOsSignalSemaphore (Info->MainThreadGate, 1);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Could not signal debugger thread sync semaphore, %s\n",
+ AcpiFormatException (Status));
+ }
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbCreateExecutionThreads
+ *
+ * PARAMETERS: NumThreadsArg - Number of threads to create
+ * NumLoopsArg - Loop count for the thread(s)
+ * MethodNameArg - Control method to execute
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Create threads to execute method(s)
+ *
+ ******************************************************************************/
+
+void
+AcpiDbCreateExecutionThreads (
+ char *NumThreadsArg,
+ char *NumLoopsArg,
+ char *MethodNameArg)
+{
+ ACPI_STATUS Status;
+ UINT32 NumThreads;
+ UINT32 NumLoops;
+ UINT32 i;
+ UINT32 Size;
+ ACPI_MUTEX MainThreadGate;
+ ACPI_MUTEX ThreadCompleteGate;
+ ACPI_MUTEX InfoGate;
+
+
+ /* Get the arguments */
+
+ NumThreads = ACPI_STRTOUL (NumThreadsArg, NULL, 0);
+ NumLoops = ACPI_STRTOUL (NumLoopsArg, NULL, 0);
+
+ if (!NumThreads || !NumLoops)
+ {
+ AcpiOsPrintf ("Bad argument: Threads %X, Loops %X\n",
+ NumThreads, NumLoops);
+ return;
+ }
+
+ /*
+ * Create the semaphore for synchronization of
+ * the created threads with the main thread.
+ */
+ Status = AcpiOsCreateSemaphore (1, 0, &MainThreadGate);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Could not create semaphore for synchronization with the main thread, %s\n",
+ AcpiFormatException (Status));
+ return;
+ }
+
+ /*
+ * Create the semaphore for synchronization
+ * between the created threads.
+ */
+ Status = AcpiOsCreateSemaphore (1, 1, &ThreadCompleteGate);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Could not create semaphore for synchronization between the created threads, %s\n",
+ AcpiFormatException (Status));
+ (void) AcpiOsDeleteSemaphore (MainThreadGate);
+ return;
+ }
+
+ Status = AcpiOsCreateSemaphore (1, 1, &InfoGate);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Could not create semaphore for synchronization of AcpiGbl_DbMethodInfo, %s\n",
+ AcpiFormatException (Status));
+ (void) AcpiOsDeleteSemaphore (ThreadCompleteGate);
+ (void) AcpiOsDeleteSemaphore (MainThreadGate);
+ return;
+ }
+
+ ACPI_MEMSET (&AcpiGbl_DbMethodInfo, 0, sizeof (ACPI_DB_METHOD_INFO));
+
+ /* Array to store IDs of threads */
+
+ AcpiGbl_DbMethodInfo.NumThreads = NumThreads;
+ Size = sizeof (ACPI_THREAD_ID) * AcpiGbl_DbMethodInfo.NumThreads;
+ AcpiGbl_DbMethodInfo.Threads = AcpiOsAllocate (Size);
+ if (AcpiGbl_DbMethodInfo.Threads == NULL)
+ {
+ AcpiOsPrintf ("No memory for thread IDs array\n");
+ (void) AcpiOsDeleteSemaphore (MainThreadGate);
+ (void) AcpiOsDeleteSemaphore (ThreadCompleteGate);
+ (void) AcpiOsDeleteSemaphore (InfoGate);
+ return;
+ }
+ ACPI_MEMSET (AcpiGbl_DbMethodInfo.Threads, 0, Size);
+
+ /* Setup the context to be passed to each thread */
+
+ AcpiGbl_DbMethodInfo.Name = MethodNameArg;
+ AcpiGbl_DbMethodInfo.Flags = 0;
+ AcpiGbl_DbMethodInfo.NumLoops = NumLoops;
+ AcpiGbl_DbMethodInfo.MainThreadGate = MainThreadGate;
+ AcpiGbl_DbMethodInfo.ThreadCompleteGate = ThreadCompleteGate;
+ AcpiGbl_DbMethodInfo.InfoGate = InfoGate;
+
+ /* Init arguments to be passed to method */
+
+ AcpiGbl_DbMethodInfo.InitArgs = 1;
+ AcpiGbl_DbMethodInfo.Args = AcpiGbl_DbMethodInfo.Arguments;
+ AcpiGbl_DbMethodInfo.Arguments[0] = AcpiGbl_DbMethodInfo.NumThreadsStr;
+ AcpiGbl_DbMethodInfo.Arguments[1] = AcpiGbl_DbMethodInfo.IdOfThreadStr;
+ AcpiGbl_DbMethodInfo.Arguments[2] = AcpiGbl_DbMethodInfo.IndexOfThreadStr;
+ AcpiGbl_DbMethodInfo.Arguments[3] = NULL;
+
+ AcpiGbl_DbMethodInfo.Types = AcpiGbl_DbMethodInfo.ArgTypes;
+ AcpiGbl_DbMethodInfo.ArgTypes[0] = ACPI_TYPE_INTEGER;
+ AcpiGbl_DbMethodInfo.ArgTypes[1] = ACPI_TYPE_INTEGER;
+ AcpiGbl_DbMethodInfo.ArgTypes[2] = ACPI_TYPE_INTEGER;
+
+ AcpiDbUInt32ToHexString (NumThreads, AcpiGbl_DbMethodInfo.NumThreadsStr);
+
+ AcpiDbExecuteSetup (&AcpiGbl_DbMethodInfo);
+
+ /* Create the threads */
+
+ AcpiOsPrintf ("Creating %X threads to execute %X times each\n",
+ NumThreads, NumLoops);
+
+ for (i = 0; i < (NumThreads); i++)
+ {
+ Status = AcpiOsExecute (OSL_DEBUGGER_THREAD, AcpiDbMethodThread,
+ &AcpiGbl_DbMethodInfo);
+ if (ACPI_FAILURE (Status))
+ {
+ break;
+ }
+ }
+
+ /* Wait for all threads to complete */
+
+ (void) AcpiOsWaitSemaphore (MainThreadGate, 1, ACPI_WAIT_FOREVER);
+
+ AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
+ AcpiOsPrintf ("All threads (%X) have completed\n", NumThreads);
+ AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
+
+ /* Cleanup and exit */
+
+ (void) AcpiOsDeleteSemaphore (MainThreadGate);
+ (void) AcpiOsDeleteSemaphore (ThreadCompleteGate);
+ (void) AcpiOsDeleteSemaphore (InfoGate);
+
+ AcpiOsFree (AcpiGbl_DbMethodInfo.Threads);
+ AcpiGbl_DbMethodInfo.Threads = NULL;
+}
+
+#endif /* ACPI_DEBUGGER */
+
+
diff --git a/source/components/debugger/dbfileio.c b/source/components/debugger/dbfileio.c
new file mode 100644
index 000000000000..ef9b7fef5379
--- /dev/null
+++ b/source/components/debugger/dbfileio.c
@@ -0,0 +1,578 @@
+/*******************************************************************************
+ *
+ * Module Name: dbfileio - Debugger file I/O commands. These can't usually
+ * be used when running the debugger in Ring 0 (Kernel mode)
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2012, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include "acpi.h"
+#include "accommon.h"
+#include "acdebug.h"
+
+#ifdef ACPI_APPLICATION
+#include "actables.h"
+#endif
+
+#if (defined ACPI_DEBUGGER || defined ACPI_DISASSEMBLER)
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("dbfileio")
+
+/*
+ * NOTE: this is here for lack of a better place. It is used in all
+ * flavors of the debugger, need LCD file
+ */
+#ifdef ACPI_APPLICATION
+#include <stdio.h>
+FILE *AcpiGbl_DebugFile = NULL;
+#endif
+
+
+#ifdef ACPI_DEBUGGER
+
+/* Local prototypes */
+
+#ifdef ACPI_APPLICATION
+
+static ACPI_STATUS
+AcpiDbCheckTextModeCorruption (
+ UINT8 *Table,
+ UINT32 TableLength,
+ UINT32 FileLength);
+
+#endif
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbCloseDebugFile
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: If open, close the current debug output file
+ *
+ ******************************************************************************/
+
+void
+AcpiDbCloseDebugFile (
+ void)
+{
+
+#ifdef ACPI_APPLICATION
+
+ if (AcpiGbl_DebugFile)
+ {
+ fclose (AcpiGbl_DebugFile);
+ AcpiGbl_DebugFile = NULL;
+ AcpiGbl_DbOutputToFile = FALSE;
+ AcpiOsPrintf ("Debug output file %s closed\n", AcpiGbl_DbDebugFilename);
+ }
+#endif
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbOpenDebugFile
+ *
+ * PARAMETERS: Name - Filename to open
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Open a file where debug output will be directed.
+ *
+ ******************************************************************************/
+
+void
+AcpiDbOpenDebugFile (
+ char *Name)
+{
+
+#ifdef ACPI_APPLICATION
+
+ AcpiDbCloseDebugFile ();
+ AcpiGbl_DebugFile = fopen (Name, "w+");
+ if (AcpiGbl_DebugFile)
+ {
+ AcpiOsPrintf ("Debug output file %s opened\n", Name);
+ ACPI_STRCPY (AcpiGbl_DbDebugFilename, Name);
+ AcpiGbl_DbOutputToFile = TRUE;
+ }
+ else
+ {
+ AcpiOsPrintf ("Could not open debug file %s\n", Name);
+ }
+
+#endif
+}
+#endif
+
+
+#ifdef ACPI_APPLICATION
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbCheckTextModeCorruption
+ *
+ * PARAMETERS: Table - Table buffer
+ * TableLength - Length of table from the table header
+ * FileLength - Length of the file that contains the table
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Check table for text mode file corruption where all linefeed
+ * characters (LF) have been replaced by carriage return linefeed
+ * pairs (CR/LF).
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDbCheckTextModeCorruption (
+ UINT8 *Table,
+ UINT32 TableLength,
+ UINT32 FileLength)
+{
+ UINT32 i;
+ UINT32 Pairs = 0;
+
+
+ if (TableLength != FileLength)
+ {
+ ACPI_WARNING ((AE_INFO,
+ "File length (0x%X) is not the same as the table length (0x%X)",
+ FileLength, TableLength));
+ }
+
+ /* Scan entire table to determine if each LF has been prefixed with a CR */
+
+ for (i = 1; i < FileLength; i++)
+ {
+ if (Table[i] == 0x0A)
+ {
+ if (Table[i - 1] != 0x0D)
+ {
+ /* The LF does not have a preceding CR, table not corrupted */
+
+ return (AE_OK);
+ }
+ else
+ {
+ /* Found a CR/LF pair */
+
+ Pairs++;
+ }
+ i++;
+ }
+ }
+
+ if (!Pairs)
+ {
+ return (AE_OK);
+ }
+
+ /*
+ * Entire table scanned, each CR is part of a CR/LF pair --
+ * meaning that the table was treated as a text file somewhere.
+ *
+ * NOTE: We can't "fix" the table, because any existing CR/LF pairs in the
+ * original table are left untouched by the text conversion process --
+ * meaning that we cannot simply replace CR/LF pairs with LFs.
+ */
+ AcpiOsPrintf ("Table has been corrupted by text mode conversion\n");
+ AcpiOsPrintf ("All LFs (%u) were changed to CR/LF pairs\n", Pairs);
+ AcpiOsPrintf ("Table cannot be repaired!\n");
+ return (AE_BAD_VALUE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbReadTable
+ *
+ * PARAMETERS: fp - File that contains table
+ * Table - Return value, buffer with table
+ * TableLength - Return value, length of table
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Load the DSDT from the file pointer
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDbReadTable (
+ FILE *fp,
+ ACPI_TABLE_HEADER **Table,
+ UINT32 *TableLength)
+{
+ ACPI_TABLE_HEADER TableHeader;
+ UINT32 Actual;
+ ACPI_STATUS Status;
+ UINT32 FileSize;
+ BOOLEAN StandardHeader = TRUE;
+
+
+ /* Get the file size */
+
+ fseek (fp, 0, SEEK_END);
+ FileSize = (UINT32) ftell (fp);
+ fseek (fp, 0, SEEK_SET);
+
+ if (FileSize < 4)
+ {
+ return (AE_BAD_HEADER);
+ }
+
+ /* Read the signature */
+
+ if (fread (&TableHeader, 1, 4, fp) != 4)
+ {
+ AcpiOsPrintf ("Could not read the table signature\n");
+ return (AE_BAD_HEADER);
+ }
+
+ fseek (fp, 0, SEEK_SET);
+
+ /* The RSDT, FACS and S3PT tables do not have standard ACPI headers */
+
+ if (ACPI_COMPARE_NAME (TableHeader.Signature, "RSD ") ||
+ ACPI_COMPARE_NAME (TableHeader.Signature, "FACS") ||
+ ACPI_COMPARE_NAME (TableHeader.Signature, "S3PT"))
+ {
+ *TableLength = FileSize;
+ StandardHeader = FALSE;
+ }
+ else
+ {
+ /* Read the table header */
+
+ if (fread (&TableHeader, 1, sizeof (TableHeader), fp) !=
+ sizeof (ACPI_TABLE_HEADER))
+ {
+ AcpiOsPrintf ("Could not read the table header\n");
+ return (AE_BAD_HEADER);
+ }
+
+#if 0
+ /* Validate the table header/length */
+
+ Status = AcpiTbValidateTableHeader (&TableHeader);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Table header is invalid!\n");
+ return (Status);
+ }
+#endif
+
+ /* File size must be at least as long as the Header-specified length */
+
+ if (TableHeader.Length > FileSize)
+ {
+ AcpiOsPrintf (
+ "TableHeader length [0x%X] greater than the input file size [0x%X]\n",
+ TableHeader.Length, FileSize);
+ return (AE_BAD_HEADER);
+ }
+
+#ifdef ACPI_OBSOLETE_CODE
+ /* We only support a limited number of table types */
+
+ if (ACPI_STRNCMP ((char *) TableHeader.Signature, DSDT_SIG, 4) &&
+ ACPI_STRNCMP ((char *) TableHeader.Signature, PSDT_SIG, 4) &&
+ ACPI_STRNCMP ((char *) TableHeader.Signature, SSDT_SIG, 4))
+ {
+ AcpiOsPrintf ("Table signature [%4.4s] is invalid or not supported\n",
+ (char *) TableHeader.Signature);
+ ACPI_DUMP_BUFFER (&TableHeader, sizeof (ACPI_TABLE_HEADER));
+ return (AE_ERROR);
+ }
+#endif
+
+ *TableLength = TableHeader.Length;
+ }
+
+ /* Allocate a buffer for the table */
+
+ *Table = AcpiOsAllocate ((size_t) FileSize);
+ if (!*Table)
+ {
+ AcpiOsPrintf (
+ "Could not allocate memory for ACPI table %4.4s (size=0x%X)\n",
+ TableHeader.Signature, *TableLength);
+ return (AE_NO_MEMORY);
+ }
+
+ /* Get the rest of the table */
+
+ fseek (fp, 0, SEEK_SET);
+ Actual = fread (*Table, 1, (size_t) FileSize, fp);
+ if (Actual == FileSize)
+ {
+ if (StandardHeader)
+ {
+ /* Now validate the checksum */
+
+ Status = AcpiTbVerifyChecksum ((void *) *Table,
+ ACPI_CAST_PTR (ACPI_TABLE_HEADER, *Table)->Length);
+
+ if (Status == AE_BAD_CHECKSUM)
+ {
+ Status = AcpiDbCheckTextModeCorruption ((UINT8 *) *Table,
+ FileSize, (*Table)->Length);
+ return (Status);
+ }
+ }
+ return (AE_OK);
+ }
+
+ if (Actual > 0)
+ {
+ AcpiOsPrintf ("Warning - reading table, asked for %X got %X\n",
+ FileSize, Actual);
+ return (AE_OK);
+ }
+
+ AcpiOsPrintf ("Error - could not read the table file\n");
+ AcpiOsFree (*Table);
+ *Table = NULL;
+ *TableLength = 0;
+
+ return (AE_ERROR);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AeLocalLoadTable
+ *
+ * PARAMETERS: Table - pointer to a buffer containing the entire
+ * table to be loaded
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: This function is called to load a table from the caller's
+ * buffer. The buffer must contain an entire ACPI Table including
+ * a valid header. The header fields will be verified, and if it
+ * is determined that the table is invalid, the call will fail.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AeLocalLoadTable (
+ ACPI_TABLE_HEADER *Table)
+{
+ ACPI_STATUS Status = AE_OK;
+/* ACPI_TABLE_DESC TableInfo; */
+
+
+ ACPI_FUNCTION_TRACE (AeLocalLoadTable);
+#if 0
+
+
+ if (!Table)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ TableInfo.Pointer = Table;
+ Status = AcpiTbRecognizeTable (&TableInfo, ACPI_TABLE_ALL);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Install the new table into the local data structures */
+
+ Status = AcpiTbInstallTable (&TableInfo);
+ if (ACPI_FAILURE (Status))
+ {
+ if (Status == AE_ALREADY_EXISTS)
+ {
+ /* Table already exists, no error */
+
+ Status = AE_OK;
+ }
+
+ /* Free table allocated by AcpiTbGetTable */
+
+ AcpiTbDeleteSingleTable (&TableInfo);
+ return_ACPI_STATUS (Status);
+ }
+
+#if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY))
+
+ Status = AcpiNsLoadTable (TableInfo.InstalledDesc, AcpiGbl_RootNode);
+ if (ACPI_FAILURE (Status))
+ {
+ /* Uninstall table and free the buffer */
+
+ AcpiTbDeleteTablesByType (ACPI_TABLE_ID_DSDT);
+ return_ACPI_STATUS (Status);
+ }
+#endif
+#endif
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbReadTableFromFile
+ *
+ * PARAMETERS: Filename - File where table is located
+ * Table - Where a pointer to the table is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Get an ACPI table from a file
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDbReadTableFromFile (
+ char *Filename,
+ ACPI_TABLE_HEADER **Table)
+{
+ FILE *fp;
+ UINT32 TableLength;
+ ACPI_STATUS Status;
+
+
+ /* Open the file */
+
+ fp = fopen (Filename, "rb");
+ if (!fp)
+ {
+ AcpiOsPrintf ("Could not open input file %s\n", Filename);
+ return (AE_ERROR);
+ }
+
+ /* Get the entire file */
+
+ fprintf (stderr, "Loading Acpi table from file %s\n", Filename);
+ Status = AcpiDbReadTable (fp, Table, &TableLength);
+ fclose(fp);
+
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Could not get table from the file\n");
+ return (Status);
+ }
+
+ return (AE_OK);
+ }
+#endif
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbGetTableFromFile
+ *
+ * PARAMETERS: Filename - File where table is located
+ * ReturnTable - Where a pointer to the table is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Load an ACPI table from a file
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDbGetTableFromFile (
+ char *Filename,
+ ACPI_TABLE_HEADER **ReturnTable)
+{
+#ifdef ACPI_APPLICATION
+ ACPI_STATUS Status;
+ ACPI_TABLE_HEADER *Table;
+ BOOLEAN IsAmlTable = TRUE;
+
+
+ Status = AcpiDbReadTableFromFile (Filename, &Table);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+#ifdef ACPI_DATA_TABLE_DISASSEMBLY
+ IsAmlTable = AcpiUtIsAmlTable (Table);
+#endif
+
+ if (IsAmlTable)
+ {
+ /* Attempt to recognize and install the table */
+
+ Status = AeLocalLoadTable (Table);
+ if (ACPI_FAILURE (Status))
+ {
+ if (Status == AE_ALREADY_EXISTS)
+ {
+ AcpiOsPrintf ("Table %4.4s is already installed\n",
+ Table->Signature);
+ }
+ else
+ {
+ AcpiOsPrintf ("Could not install table, %s\n",
+ AcpiFormatException (Status));
+ }
+
+ return (Status);
+ }
+
+ fprintf (stderr,
+ "Acpi table [%4.4s] successfully installed and loaded\n",
+ Table->Signature);
+ }
+
+ AcpiGbl_AcpiHardwarePresent = FALSE;
+ if (ReturnTable)
+ {
+ *ReturnTable = Table;
+ }
+
+
+#endif /* ACPI_APPLICATION */
+ return (AE_OK);
+}
+
+#endif /* ACPI_DEBUGGER */
+
diff --git a/source/components/debugger/dbhistry.c b/source/components/debugger/dbhistry.c
new file mode 100644
index 000000000000..536b69cdfaab
--- /dev/null
+++ b/source/components/debugger/dbhistry.c
@@ -0,0 +1,220 @@
+/******************************************************************************
+ *
+ * Module Name: dbhistry - debugger HISTORY command
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2012, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include "acpi.h"
+#include "accommon.h"
+#include "acdebug.h"
+
+#ifdef ACPI_DEBUGGER
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("dbhistry")
+
+
+#define HI_NO_HISTORY 0
+#define HI_RECORD_HISTORY 1
+#define HISTORY_SIZE 20
+
+
+typedef struct HistoryInfo
+{
+ char Command[80];
+ UINT32 CmdNum;
+
+} HISTORY_INFO;
+
+
+static HISTORY_INFO AcpiGbl_HistoryBuffer[HISTORY_SIZE];
+static UINT16 AcpiGbl_LoHistory = 0;
+static UINT16 AcpiGbl_NumHistory = 0;
+static UINT16 AcpiGbl_NextHistoryIndex = 0;
+static UINT32 AcpiGbl_NextCmdNum = 1;
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbAddToHistory
+ *
+ * PARAMETERS: CommandLine - Command to add
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Add a command line to the history buffer.
+ *
+ ******************************************************************************/
+
+void
+AcpiDbAddToHistory (
+ char *CommandLine)
+{
+
+ /* Put command into the next available slot */
+
+ ACPI_STRCPY (AcpiGbl_HistoryBuffer[AcpiGbl_NextHistoryIndex].Command,
+ CommandLine);
+
+ AcpiGbl_HistoryBuffer[AcpiGbl_NextHistoryIndex].CmdNum = AcpiGbl_NextCmdNum;
+
+ /* Adjust indexes */
+
+ if ((AcpiGbl_NumHistory == HISTORY_SIZE) &&
+ (AcpiGbl_NextHistoryIndex == AcpiGbl_LoHistory))
+ {
+ AcpiGbl_LoHistory++;
+ if (AcpiGbl_LoHistory >= HISTORY_SIZE)
+ {
+ AcpiGbl_LoHistory = 0;
+ }
+ }
+
+ AcpiGbl_NextHistoryIndex++;
+ if (AcpiGbl_NextHistoryIndex >= HISTORY_SIZE)
+ {
+ AcpiGbl_NextHistoryIndex = 0;
+ }
+
+ AcpiGbl_NextCmdNum++;
+ if (AcpiGbl_NumHistory < HISTORY_SIZE)
+ {
+ AcpiGbl_NumHistory++;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDisplayHistory
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Display the contents of the history buffer
+ *
+ ******************************************************************************/
+
+void
+AcpiDbDisplayHistory (
+ void)
+{
+ UINT32 i;
+ UINT16 HistoryIndex;
+
+
+ HistoryIndex = AcpiGbl_LoHistory;
+
+ /* Dump entire history buffer */
+
+ for (i = 0; i < AcpiGbl_NumHistory; i++)
+ {
+ AcpiOsPrintf ("%ld %s\n", AcpiGbl_HistoryBuffer[HistoryIndex].CmdNum,
+ AcpiGbl_HistoryBuffer[HistoryIndex].Command);
+
+ HistoryIndex++;
+ if (HistoryIndex >= HISTORY_SIZE)
+ {
+ HistoryIndex = 0;
+ }
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbGetFromHistory
+ *
+ * PARAMETERS: CommandNumArg - String containing the number of the
+ * command to be retrieved
+ *
+ * RETURN: Pointer to the retrieved command. Null on error.
+ *
+ * DESCRIPTION: Get a command from the history buffer
+ *
+ ******************************************************************************/
+
+char *
+AcpiDbGetFromHistory (
+ char *CommandNumArg)
+{
+ UINT32 i;
+ UINT16 HistoryIndex;
+ UINT32 CmdNum;
+
+
+ if (CommandNumArg == NULL)
+ {
+ CmdNum = AcpiGbl_NextCmdNum - 1;
+ }
+
+ else
+ {
+ CmdNum = ACPI_STRTOUL (CommandNumArg, NULL, 0);
+ }
+
+ /* Search history buffer */
+
+ HistoryIndex = AcpiGbl_LoHistory;
+ for (i = 0; i < AcpiGbl_NumHistory; i++)
+ {
+ if (AcpiGbl_HistoryBuffer[HistoryIndex].CmdNum == CmdNum)
+ {
+ /* Found the commnad, return it */
+
+ return (AcpiGbl_HistoryBuffer[HistoryIndex].Command);
+ }
+
+
+ HistoryIndex++;
+ if (HistoryIndex >= HISTORY_SIZE)
+ {
+ HistoryIndex = 0;
+ }
+ }
+
+ AcpiOsPrintf ("Invalid history number: %u\n", HistoryIndex);
+ return (NULL);
+}
+
+#endif /* ACPI_DEBUGGER */
+
diff --git a/source/components/debugger/dbinput.c b/source/components/debugger/dbinput.c
new file mode 100644
index 000000000000..0ae313934b40
--- /dev/null
+++ b/source/components/debugger/dbinput.c
@@ -0,0 +1,1091 @@
+/*******************************************************************************
+ *
+ * Module Name: dbinput - user front-end to the AML debugger
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2012, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include "acpi.h"
+#include "accommon.h"
+#include "acdebug.h"
+
+
+#ifdef ACPI_DEBUGGER
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("dbinput")
+
+/* Local prototypes */
+
+static UINT32
+AcpiDbGetLine (
+ char *InputBuffer);
+
+static UINT32
+AcpiDbMatchCommand (
+ char *UserCommand);
+
+static void
+AcpiDbSingleThread (
+ void);
+
+static void
+AcpiDbDisplayHelp (
+ void);
+
+
+/*
+ * Top-level debugger commands.
+ *
+ * This list of commands must match the string table below it
+ */
+enum AcpiExDebuggerCommands
+{
+ CMD_NOT_FOUND = 0,
+ CMD_NULL,
+ CMD_ALLOCATIONS,
+ CMD_ARGS,
+ CMD_ARGUMENTS,
+ CMD_BATCH,
+ CMD_BREAKPOINT,
+ CMD_BUSINFO,
+ CMD_CALL,
+ CMD_CLOSE,
+ CMD_DEBUG,
+ CMD_DISASSEMBLE,
+ CMD_DUMP,
+ CMD_ENABLEACPI,
+ CMD_EVENT,
+ CMD_EXECUTE,
+ CMD_EXIT,
+ CMD_FIND,
+ CMD_GO,
+ CMD_GPE,
+ CMD_GPES,
+ CMD_HANDLERS,
+ CMD_HELP,
+ CMD_HELP2,
+ CMD_HISTORY,
+ CMD_HISTORY_EXE,
+ CMD_HISTORY_LAST,
+ CMD_INFORMATION,
+ CMD_INTEGRITY,
+ CMD_INTO,
+ CMD_LEVEL,
+ CMD_LIST,
+ CMD_LOAD,
+ CMD_LOCALS,
+ CMD_LOCKS,
+ CMD_METHODS,
+ CMD_NAMESPACE,
+ CMD_NOTIFY,
+ CMD_OBJECT,
+ CMD_OPEN,
+ CMD_OSI,
+ CMD_OWNER,
+ CMD_PREDEFINED,
+ CMD_PREFIX,
+ CMD_QUIT,
+ CMD_REFERENCES,
+ CMD_RESOURCES,
+ CMD_RESULTS,
+ CMD_SET,
+ CMD_SLEEP,
+ CMD_STATS,
+ CMD_STOP,
+ CMD_TABLES,
+ CMD_TEMPLATE,
+ CMD_TERMINATE,
+ CMD_THREADS,
+ CMD_TRACE,
+ CMD_TREE,
+ CMD_TYPE,
+ CMD_UNLOAD
+};
+
+#define CMD_FIRST_VALID 2
+
+
+/* Second parameter is the required argument count */
+
+static const COMMAND_INFO AcpiGbl_DbCommands[] =
+{
+ {"<NOT FOUND>", 0},
+ {"<NULL>", 0},
+ {"ALLOCATIONS", 0},
+ {"ARGS", 0},
+ {"ARGUMENTS", 0},
+ {"BATCH", 0},
+ {"BREAKPOINT", 1},
+ {"BUSINFO", 0},
+ {"CALL", 0},
+ {"CLOSE", 0},
+ {"DEBUG", 1},
+ {"DISASSEMBLE", 1},
+ {"DUMP", 1},
+ {"ENABLEACPI", 0},
+ {"EVENT", 1},
+ {"EXECUTE", 1},
+ {"EXIT", 0},
+ {"FIND", 1},
+ {"GO", 0},
+ {"GPE", 2},
+ {"GPES", 0},
+ {"HANDLERS", 0},
+ {"HELP", 0},
+ {"?", 0},
+ {"HISTORY", 0},
+ {"!", 1},
+ {"!!", 0},
+ {"INFORMATION", 0},
+ {"INTEGRITY", 0},
+ {"INTO", 0},
+ {"LEVEL", 0},
+ {"LIST", 0},
+ {"LOAD", 1},
+ {"LOCALS", 0},
+ {"LOCKS", 0},
+ {"METHODS", 0},
+ {"NAMESPACE", 0},
+ {"NOTIFY", 2},
+ {"OBJECT", 1},
+ {"OPEN", 1},
+ {"OSI", 0},
+ {"OWNER", 1},
+ {"PREDEFINED", 0},
+ {"PREFIX", 0},
+ {"QUIT", 0},
+ {"REFERENCES", 1},
+ {"RESOURCES", 1},
+ {"RESULTS", 0},
+ {"SET", 3},
+ {"SLEEP", 1},
+ {"STATS", 0},
+ {"STOP", 0},
+ {"TABLES", 0},
+ {"TEMPLATE", 1},
+ {"TERMINATE", 0},
+ {"THREADS", 3},
+ {"TRACE", 1},
+ {"TREE", 0},
+ {"TYPE", 1},
+ {"UNLOAD", 1},
+ {NULL, 0}
+};
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDisplayHelp
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Print a usage message.
+ *
+ ******************************************************************************/
+
+static void
+AcpiDbDisplayHelp (
+ void)
+{
+
+ AcpiOsPrintf ("\nGeneral-Purpose Commands:\n");
+ AcpiOsPrintf (" Allocations Display list of current memory allocations\n");
+ AcpiOsPrintf (" Dump <Address>|<Namepath>\n");
+ AcpiOsPrintf (" [Byte|Word|Dword|Qword] Display ACPI objects or memory\n");
+ AcpiOsPrintf (" EnableAcpi Enable ACPI (hardware) mode\n");
+ AcpiOsPrintf (" Handlers Info about global handlers\n");
+ AcpiOsPrintf (" Help This help screen\n");
+ AcpiOsPrintf (" History Display command history buffer\n");
+ AcpiOsPrintf (" Level [<DebugLevel>] [console] Get/Set debug level for file or console\n");
+ AcpiOsPrintf (" Locks Current status of internal mutexes\n");
+ AcpiOsPrintf (" Osi [Install|Remove <name>] Display or modify global _OSI list\n");
+ AcpiOsPrintf (" Quit or Exit Exit this command\n");
+ AcpiOsPrintf (" Stats [Allocations|Memory|Misc|\n");
+ AcpiOsPrintf (" Objects|Sizes|Stack|Tables] Display namespace and memory statistics\n");
+ AcpiOsPrintf (" Allocations Display list of current memory allocations\n");
+ AcpiOsPrintf (" Memory Dump internal memory lists\n");
+ AcpiOsPrintf (" Misc Namespace search and mutex stats\n");
+ AcpiOsPrintf (" Objects Summary of namespace objects\n");
+ AcpiOsPrintf (" Sizes Sizes for each of the internal objects\n");
+ AcpiOsPrintf (" Stack Display CPU stack usage\n");
+ AcpiOsPrintf (" Tables Info about current ACPI table(s)\n");
+ AcpiOsPrintf (" Tables Display info about loaded ACPI tables\n");
+ AcpiOsPrintf (" Unload <TableSig> [Instance] Unload an ACPI table\n");
+ AcpiOsPrintf (" ! <CommandNumber> Execute command from history buffer\n");
+ AcpiOsPrintf (" !! Execute last command again\n");
+
+ AcpiOsPrintf ("\nNamespace Access Commands:\n");
+ AcpiOsPrintf (" Businfo Display system bus info\n");
+ AcpiOsPrintf (" Disassemble <Method> Disassemble a control method\n");
+ AcpiOsPrintf (" Event <F|G> <Value> Generate AcpiEvent (Fixed/GPE)\n");
+ AcpiOsPrintf (" Find <AcpiName> (? is wildcard) Find ACPI name(s) with wildcards\n");
+ AcpiOsPrintf (" Gpe <GpeNum> <GpeBlock> Simulate a GPE\n");
+ AcpiOsPrintf (" Gpes Display info on all GPEs\n");
+ AcpiOsPrintf (" Integrity Validate namespace integrity\n");
+ AcpiOsPrintf (" Methods Display list of loaded control methods\n");
+ AcpiOsPrintf (" Namespace [Object] [Depth] Display loaded namespace tree/subtree\n");
+ AcpiOsPrintf (" Notify <Object> <Value> Send a notification on Object\n");
+ AcpiOsPrintf (" Objects <ObjectType> Display all objects of the given type\n");
+ AcpiOsPrintf (" Owner <OwnerId> [Depth] Display loaded namespace by object owner\n");
+ AcpiOsPrintf (" Predefined Check all predefined names\n");
+ AcpiOsPrintf (" Prefix [<NamePath>] Set or Get current execution prefix\n");
+ AcpiOsPrintf (" References <Addr> Find all references to object at addr\n");
+ AcpiOsPrintf (" Resources <DeviceName | *> Display Device resources (* = all devices)\n");
+ AcpiOsPrintf (" Set N <NamedObject> <Value> Set value for named integer\n");
+ AcpiOsPrintf (" Sleep <SleepState> Simulate sleep/wake sequence\n");
+ AcpiOsPrintf (" Template <Object> Format/dump a Buffer/ResourceTemplate\n");
+ AcpiOsPrintf (" Terminate Delete namespace and all internal objects\n");
+ AcpiOsPrintf (" Type <Object> Display object type\n");
+
+ AcpiOsPrintf ("\nControl Method Execution Commands:\n");
+ AcpiOsPrintf (" Arguments (or Args) Display method arguments\n");
+ AcpiOsPrintf (" Breakpoint <AmlOffset> Set an AML execution breakpoint\n");
+ AcpiOsPrintf (" Call Run to next control method invocation\n");
+ AcpiOsPrintf (" Debug <Namepath> [Arguments] Single Step a control method\n");
+ AcpiOsPrintf (" Execute <Namepath> [Arguments] Execute control method\n");
+ AcpiOsPrintf (" Hex Integer Integer method argument\n");
+ AcpiOsPrintf (" \"Ascii String\" String method argument\n");
+ AcpiOsPrintf (" (Byte List) Buffer method argument\n");
+ AcpiOsPrintf (" [Package Element List] Package method argument\n");
+ AcpiOsPrintf (" Go Allow method to run to completion\n");
+ AcpiOsPrintf (" Information Display info about the current method\n");
+ AcpiOsPrintf (" Into Step into (not over) a method call\n");
+ AcpiOsPrintf (" List [# of Aml Opcodes] Display method ASL statements\n");
+ AcpiOsPrintf (" Locals Display method local variables\n");
+ AcpiOsPrintf (" Results Display method result stack\n");
+ AcpiOsPrintf (" Set <A|L> <#> <Value> Set method data (Arguments/Locals)\n");
+ AcpiOsPrintf (" Stop Terminate control method\n");
+ AcpiOsPrintf (" Thread <Threads><Loops><NamePath> Spawn threads to execute method(s)\n");
+ AcpiOsPrintf (" Trace <method name> Trace method execution\n");
+ AcpiOsPrintf (" Tree Display control method calling tree\n");
+ AcpiOsPrintf (" <Enter> Single step next AML opcode (over calls)\n");
+
+ AcpiOsPrintf ("\nFile I/O Commands:\n");
+ AcpiOsPrintf (" Close Close debug output file\n");
+ AcpiOsPrintf (" Load <Input Filename> Load ACPI table from a file\n");
+ AcpiOsPrintf (" Open <Output Filename> Open a file for debug output\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbGetNextToken
+ *
+ * PARAMETERS: String - Command buffer
+ * Next - Return value, end of next token
+ *
+ * RETURN: Pointer to the start of the next token.
+ *
+ * DESCRIPTION: Command line parsing. Get the next token on the command line
+ *
+ ******************************************************************************/
+
+char *
+AcpiDbGetNextToken (
+ char *String,
+ char **Next,
+ ACPI_OBJECT_TYPE *ReturnType)
+{
+ char *Start;
+ UINT32 Depth;
+ ACPI_OBJECT_TYPE Type = ACPI_TYPE_INTEGER;
+
+
+ /* At end of buffer? */
+
+ if (!String || !(*String))
+ {
+ return (NULL);
+ }
+
+ /* Remove any spaces at the beginning */
+
+ if (*String == ' ')
+ {
+ while (*String && (*String == ' '))
+ {
+ String++;
+ }
+
+ if (!(*String))
+ {
+ return (NULL);
+ }
+ }
+
+ switch (*String)
+ {
+ case '"':
+
+ /* This is a quoted string, scan until closing quote */
+
+ String++;
+ Start = String;
+ Type = ACPI_TYPE_STRING;
+
+ /* Find end of string */
+
+ while (*String && (*String != '"'))
+ {
+ String++;
+ }
+ break;
+
+ case '(':
+
+ /* This is the start of a buffer, scan until closing paren */
+
+ String++;
+ Start = String;
+ Type = ACPI_TYPE_BUFFER;
+
+ /* Find end of buffer */
+
+ while (*String && (*String != ')'))
+ {
+ String++;
+ }
+ break;
+
+ case '[':
+
+ /* This is the start of a package, scan until closing bracket */
+
+ String++;
+ Depth = 1;
+ Start = String;
+ Type = ACPI_TYPE_PACKAGE;
+
+ /* Find end of package (closing bracket) */
+
+ while (*String)
+ {
+ /* Handle String package elements */
+
+ if (*String == '"')
+ {
+ /* Find end of string */
+
+ String++;
+ while (*String && (*String != '"'))
+ {
+ String++;
+ }
+ if (!(*String))
+ {
+ break;
+ }
+ }
+ else if (*String == '[')
+ {
+ Depth++; /* A nested package declaration */
+ }
+ else if (*String == ']')
+ {
+ Depth--;
+ if (Depth == 0) /* Found final package closing bracket */
+ {
+ break;
+ }
+ }
+
+ String++;
+ }
+ break;
+
+ default:
+
+ Start = String;
+
+ /* Find end of token */
+
+ while (*String && (*String != ' '))
+ {
+ String++;
+ }
+ break;
+ }
+
+ if (!(*String))
+ {
+ *Next = NULL;
+ }
+ else
+ {
+ *String = 0;
+ *Next = String + 1;
+ }
+
+ *ReturnType = Type;
+ return (Start);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbGetLine
+ *
+ * PARAMETERS: InputBuffer - Command line buffer
+ *
+ * RETURN: Count of arguments to the command
+ *
+ * DESCRIPTION: Get the next command line from the user. Gets entire line
+ * up to the next newline
+ *
+ ******************************************************************************/
+
+static UINT32
+AcpiDbGetLine (
+ char *InputBuffer)
+{
+ UINT32 i;
+ UINT32 Count;
+ char *Next;
+ char *This;
+
+
+ ACPI_STRCPY (AcpiGbl_DbParsedBuf, InputBuffer);
+
+ This = AcpiGbl_DbParsedBuf;
+ for (i = 0; i < ACPI_DEBUGGER_MAX_ARGS; i++)
+ {
+ AcpiGbl_DbArgs[i] = AcpiDbGetNextToken (This, &Next,
+ &AcpiGbl_DbArgTypes[i]);
+ if (!AcpiGbl_DbArgs[i])
+ {
+ break;
+ }
+
+ This = Next;
+ }
+
+ /* Uppercase the actual command */
+
+ if (AcpiGbl_DbArgs[0])
+ {
+ AcpiUtStrupr (AcpiGbl_DbArgs[0]);
+ }
+
+ Count = i;
+ if (Count)
+ {
+ Count--; /* Number of args only */
+ }
+
+ return (Count);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbMatchCommand
+ *
+ * PARAMETERS: UserCommand - User command line
+ *
+ * RETURN: Index into command array, -1 if not found
+ *
+ * DESCRIPTION: Search command array for a command match
+ *
+ ******************************************************************************/
+
+static UINT32
+AcpiDbMatchCommand (
+ char *UserCommand)
+{
+ UINT32 i;
+
+
+ if (!UserCommand || UserCommand[0] == 0)
+ {
+ return (CMD_NULL);
+ }
+
+ for (i = CMD_FIRST_VALID; AcpiGbl_DbCommands[i].Name; i++)
+ {
+ if (ACPI_STRSTR (AcpiGbl_DbCommands[i].Name, UserCommand) ==
+ AcpiGbl_DbCommands[i].Name)
+ {
+ return (i);
+ }
+ }
+
+ /* Command not recognized */
+
+ return (CMD_NOT_FOUND);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbCommandDispatch
+ *
+ * PARAMETERS: InputBuffer - Command line buffer
+ * WalkState - Current walk
+ * Op - Current (executing) parse op
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Command dispatcher.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDbCommandDispatch (
+ char *InputBuffer,
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op)
+{
+ UINT32 Temp;
+ UINT32 CommandIndex;
+ UINT32 ParamCount;
+ char *CommandLine;
+ ACPI_STATUS Status = AE_CTRL_TRUE;
+
+
+ /* If AcpiTerminate has been called, terminate this thread */
+
+ if (AcpiGbl_DbTerminateThreads)
+ {
+ return (AE_CTRL_TERMINATE);
+ }
+
+ ParamCount = AcpiDbGetLine (InputBuffer);
+ CommandIndex = AcpiDbMatchCommand (AcpiGbl_DbArgs[0]);
+ Temp = 0;
+
+ /* Verify that we have the minimum number of params */
+
+ if (ParamCount < AcpiGbl_DbCommands[CommandIndex].MinArgs)
+ {
+ AcpiOsPrintf ("%u parameters entered, [%s] requires %u parameters\n",
+ ParamCount, AcpiGbl_DbCommands[CommandIndex].Name,
+ AcpiGbl_DbCommands[CommandIndex].MinArgs);
+
+ return (AE_CTRL_TRUE);
+ }
+
+ /* Decode and dispatch the command */
+
+ switch (CommandIndex)
+ {
+ case CMD_NULL:
+ if (Op)
+ {
+ return (AE_OK);
+ }
+ break;
+
+ case CMD_ALLOCATIONS:
+
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+ AcpiUtDumpAllocations ((UINT32) -1, NULL);
+#endif
+ break;
+
+ case CMD_ARGS:
+ case CMD_ARGUMENTS:
+ AcpiDbDisplayArguments ();
+ break;
+
+ case CMD_BATCH:
+ AcpiDbBatchExecute (AcpiGbl_DbArgs[1]);
+ break;
+
+ case CMD_BREAKPOINT:
+ AcpiDbSetMethodBreakpoint (AcpiGbl_DbArgs[1], WalkState, Op);
+ break;
+
+ case CMD_BUSINFO:
+ AcpiDbGetBusInfo ();
+ break;
+
+ case CMD_CALL:
+ AcpiDbSetMethodCallBreakpoint (Op);
+ Status = AE_OK;
+ break;
+
+ case CMD_CLOSE:
+ AcpiDbCloseDebugFile ();
+ break;
+
+ case CMD_DEBUG:
+ AcpiDbExecute (AcpiGbl_DbArgs[1],
+ &AcpiGbl_DbArgs[2], &AcpiGbl_DbArgTypes[2], EX_SINGLE_STEP);
+ break;
+
+ case CMD_DISASSEMBLE:
+ (void) AcpiDbDisassembleMethod (AcpiGbl_DbArgs[1]);
+ break;
+
+ case CMD_DUMP:
+ AcpiDbDecodeAndDisplayObject (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
+ break;
+
+ case CMD_ENABLEACPI:
+#if (!ACPI_REDUCED_HARDWARE)
+
+ Status = AcpiEnable();
+ if (ACPI_FAILURE(Status))
+ {
+ AcpiOsPrintf("AcpiEnable failed (Status=%X)\n", Status);
+ return (Status);
+ }
+#endif /* !ACPI_REDUCED_HARDWARE */
+ break;
+
+ case CMD_EVENT:
+ AcpiOsPrintf ("Event command not implemented\n");
+ break;
+
+ case CMD_EXECUTE:
+ AcpiDbExecute (AcpiGbl_DbArgs[1],
+ &AcpiGbl_DbArgs[2], &AcpiGbl_DbArgTypes[2], EX_NO_SINGLE_STEP);
+ break;
+
+ case CMD_FIND:
+ Status = AcpiDbFindNameInNamespace (AcpiGbl_DbArgs[1]);
+ break;
+
+ case CMD_GO:
+ AcpiGbl_CmSingleStep = FALSE;
+ return (AE_OK);
+
+ case CMD_GPE:
+ AcpiDbGenerateGpe (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
+ break;
+
+ case CMD_GPES:
+ AcpiDbDisplayGpes ();
+ break;
+
+ case CMD_HANDLERS:
+ AcpiDbDisplayHandlers ();
+ break;
+
+ case CMD_HELP:
+ case CMD_HELP2:
+ AcpiDbDisplayHelp ();
+ break;
+
+ case CMD_HISTORY:
+ AcpiDbDisplayHistory ();
+ break;
+
+ case CMD_HISTORY_EXE:
+ CommandLine = AcpiDbGetFromHistory (AcpiGbl_DbArgs[1]);
+ if (!CommandLine)
+ {
+ return (AE_CTRL_TRUE);
+ }
+
+ Status = AcpiDbCommandDispatch (CommandLine, WalkState, Op);
+ return (Status);
+
+ case CMD_HISTORY_LAST:
+ CommandLine = AcpiDbGetFromHistory (NULL);
+ if (!CommandLine)
+ {
+ return (AE_CTRL_TRUE);
+ }
+
+ Status = AcpiDbCommandDispatch (CommandLine, WalkState, Op);
+ return (Status);
+
+ case CMD_INFORMATION:
+ AcpiDbDisplayMethodInfo (Op);
+ break;
+
+ case CMD_INTEGRITY:
+ AcpiDbCheckIntegrity ();
+ break;
+
+ case CMD_INTO:
+ if (Op)
+ {
+ AcpiGbl_CmSingleStep = TRUE;
+ return (AE_OK);
+ }
+ break;
+
+ case CMD_LEVEL:
+ if (ParamCount == 0)
+ {
+ AcpiOsPrintf ("Current debug level for file output is: %8.8lX\n",
+ AcpiGbl_DbDebugLevel);
+ AcpiOsPrintf ("Current debug level for console output is: %8.8lX\n",
+ AcpiGbl_DbConsoleDebugLevel);
+ }
+ else if (ParamCount == 2)
+ {
+ Temp = AcpiGbl_DbConsoleDebugLevel;
+ AcpiGbl_DbConsoleDebugLevel = ACPI_STRTOUL (AcpiGbl_DbArgs[1],
+ NULL, 16);
+ AcpiOsPrintf (
+ "Debug Level for console output was %8.8lX, now %8.8lX\n",
+ Temp, AcpiGbl_DbConsoleDebugLevel);
+ }
+ else
+ {
+ Temp = AcpiGbl_DbDebugLevel;
+ AcpiGbl_DbDebugLevel = ACPI_STRTOUL (AcpiGbl_DbArgs[1], NULL, 16);
+ AcpiOsPrintf (
+ "Debug Level for file output was %8.8lX, now %8.8lX\n",
+ Temp, AcpiGbl_DbDebugLevel);
+ }
+ break;
+
+ case CMD_LIST:
+ AcpiDbDisassembleAml (AcpiGbl_DbArgs[1], Op);
+ break;
+
+ case CMD_LOAD:
+ Status = AcpiDbGetTableFromFile (AcpiGbl_DbArgs[1], NULL);
+ break;
+
+ case CMD_LOCKS:
+ AcpiDbDisplayLocks ();
+ break;
+
+ case CMD_LOCALS:
+ AcpiDbDisplayLocals ();
+ break;
+
+ case CMD_METHODS:
+ Status = AcpiDbDisplayObjects ("METHOD", AcpiGbl_DbArgs[1]);
+ break;
+
+ case CMD_NAMESPACE:
+ AcpiDbDumpNamespace (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
+ break;
+
+ case CMD_NOTIFY:
+ Temp = ACPI_STRTOUL (AcpiGbl_DbArgs[2], NULL, 0);
+ AcpiDbSendNotify (AcpiGbl_DbArgs[1], Temp);
+ break;
+
+ case CMD_OBJECT:
+ AcpiUtStrupr (AcpiGbl_DbArgs[1]);
+ Status = AcpiDbDisplayObjects (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
+ break;
+
+ case CMD_OPEN:
+ AcpiDbOpenDebugFile (AcpiGbl_DbArgs[1]);
+ break;
+
+ case CMD_OSI:
+ AcpiDbDisplayInterfaces (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
+ break;
+
+ case CMD_OWNER:
+ AcpiDbDumpNamespaceByOwner (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
+ break;
+
+ case CMD_PREDEFINED:
+ AcpiDbCheckPredefinedNames ();
+ break;
+
+ case CMD_PREFIX:
+ AcpiDbSetScope (AcpiGbl_DbArgs[1]);
+ break;
+
+ case CMD_REFERENCES:
+ AcpiDbFindReferences (AcpiGbl_DbArgs[1]);
+ break;
+
+ case CMD_RESOURCES:
+ AcpiDbDisplayResources (AcpiGbl_DbArgs[1]);
+ break;
+
+ case CMD_RESULTS:
+ AcpiDbDisplayResults ();
+ break;
+
+ case CMD_SET:
+ AcpiDbSetMethodData (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2],
+ AcpiGbl_DbArgs[3]);
+ break;
+
+ case CMD_SLEEP:
+ Status = AcpiDbSleep (AcpiGbl_DbArgs[1]);
+ break;
+
+ case CMD_STATS:
+ Status = AcpiDbDisplayStatistics (AcpiGbl_DbArgs[1]);
+ break;
+
+ case CMD_STOP:
+ return (AE_NOT_IMPLEMENTED);
+
+ case CMD_TABLES:
+ AcpiDbDisplayTableInfo (AcpiGbl_DbArgs[1]);
+ break;
+
+ case CMD_TEMPLATE:
+ AcpiDbDisplayTemplate (AcpiGbl_DbArgs[1]);
+ break;
+
+ case CMD_TERMINATE:
+ AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
+ AcpiUtSubsystemShutdown ();
+
+ /*
+ * TBD: [Restructure] Need some way to re-initialize without
+ * re-creating the semaphores!
+ */
+
+ /* AcpiInitialize (NULL); */
+ break;
+
+ case CMD_THREADS:
+ AcpiDbCreateExecutionThreads (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2],
+ AcpiGbl_DbArgs[3]);
+ break;
+
+ case CMD_TRACE:
+ (void) AcpiDebugTrace (AcpiGbl_DbArgs[1],0,0,1);
+ break;
+
+ case CMD_TREE:
+ AcpiDbDisplayCallingTree ();
+ break;
+
+ case CMD_TYPE:
+ AcpiDbDisplayObjectType (AcpiGbl_DbArgs[1]);
+ break;
+
+ case CMD_UNLOAD:
+ AcpiDbUnloadAcpiTable (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
+ break;
+
+ case CMD_EXIT:
+ case CMD_QUIT:
+ if (Op)
+ {
+ AcpiOsPrintf ("Method execution terminated\n");
+ return (AE_CTRL_TERMINATE);
+ }
+
+ if (!AcpiGbl_DbOutputToFile)
+ {
+ AcpiDbgLevel = ACPI_DEBUG_DEFAULT;
+ }
+
+ AcpiDbCloseDebugFile ();
+ AcpiGbl_DbTerminateThreads = TRUE;
+ return (AE_CTRL_TERMINATE);
+
+ case CMD_NOT_FOUND:
+ default:
+ AcpiOsPrintf ("Unknown Command\n");
+ return (AE_CTRL_TRUE);
+ }
+
+ if (ACPI_SUCCESS (Status))
+ {
+ Status = AE_CTRL_TRUE;
+ }
+
+ /* Add all commands that come here to the history buffer */
+
+ AcpiDbAddToHistory (InputBuffer);
+ return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbExecuteThread
+ *
+ * PARAMETERS: Context - Not used
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Debugger execute thread. Waits for a command line, then
+ * simply dispatches it.
+ *
+ ******************************************************************************/
+
+void ACPI_SYSTEM_XFACE
+AcpiDbExecuteThread (
+ void *Context)
+{
+ ACPI_STATUS Status = AE_OK;
+ ACPI_STATUS MStatus;
+
+
+ while (Status != AE_CTRL_TERMINATE)
+ {
+ AcpiGbl_MethodExecuting = FALSE;
+ AcpiGbl_StepToNextCall = FALSE;
+
+ MStatus = AcpiUtAcquireMutex (ACPI_MTX_DEBUG_CMD_READY);
+ if (ACPI_FAILURE (MStatus))
+ {
+ return;
+ }
+
+ Status = AcpiDbCommandDispatch (AcpiGbl_DbLineBuf, NULL, NULL);
+
+ MStatus = AcpiUtReleaseMutex (ACPI_MTX_DEBUG_CMD_COMPLETE);
+ if (ACPI_FAILURE (MStatus))
+ {
+ return;
+ }
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbSingleThread
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Debugger execute thread. Waits for a command line, then
+ * simply dispatches it.
+ *
+ ******************************************************************************/
+
+static void
+AcpiDbSingleThread (
+ void)
+{
+
+ AcpiGbl_MethodExecuting = FALSE;
+ AcpiGbl_StepToNextCall = FALSE;
+
+ (void) AcpiDbCommandDispatch (AcpiGbl_DbLineBuf, NULL, NULL);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbUserCommands
+ *
+ * PARAMETERS: Prompt - User prompt (depends on mode)
+ * Op - Current executing parse op
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Command line execution for the AML debugger. Commands are
+ * matched and dispatched here.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDbUserCommands (
+ char Prompt,
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_STATUS Status = AE_OK;
+
+
+ /* TBD: [Restructure] Need a separate command line buffer for step mode */
+
+ while (!AcpiGbl_DbTerminateThreads)
+ {
+ /* Force output to console until a command is entered */
+
+ AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
+
+ /* Different prompt if method is executing */
+
+ if (!AcpiGbl_MethodExecuting)
+ {
+ AcpiOsPrintf ("%1c ", ACPI_DEBUGGER_COMMAND_PROMPT);
+ }
+ else
+ {
+ AcpiOsPrintf ("%1c ", ACPI_DEBUGGER_EXECUTE_PROMPT);
+ }
+
+ /* Get the user input line */
+
+ Status = AcpiOsGetLine (AcpiGbl_DbLineBuf,
+ ACPI_DB_LINE_BUFFER_SIZE, NULL);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status, "While parsing command line"));
+ return (Status);
+ }
+
+ /* Check for single or multithreaded debug */
+
+ if (AcpiGbl_DebuggerConfiguration & DEBUGGER_MULTI_THREADED)
+ {
+ /*
+ * Signal the debug thread that we have a command to execute,
+ * and wait for the command to complete.
+ */
+ Status = AcpiUtReleaseMutex (ACPI_MTX_DEBUG_CMD_READY);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_DEBUG_CMD_COMPLETE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ }
+ else
+ {
+ /* Just call to the command line interpreter */
+
+ AcpiDbSingleThread ();
+ }
+ }
+
+ /*
+ * Only this thread (the original thread) should actually terminate the
+ * subsystem, because all the semaphores are deleted during termination
+ */
+ Status = AcpiTerminate ();
+ return (Status);
+}
+
+#endif /* ACPI_DEBUGGER */
+
diff --git a/source/components/debugger/dbmethod.c b/source/components/debugger/dbmethod.c
new file mode 100644
index 000000000000..0d45d68150b4
--- /dev/null
+++ b/source/components/debugger/dbmethod.c
@@ -0,0 +1,525 @@
+/*******************************************************************************
+ *
+ * Module Name: dbmethod - Debug commands for control methods
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2012, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include "acpi.h"
+#include "accommon.h"
+#include "acdispat.h"
+#include "acnamesp.h"
+#include "acdebug.h"
+#include "acdisasm.h"
+#include "acparser.h"
+
+
+#ifdef ACPI_DEBUGGER
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("dbmethod")
+
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiDbWalkForExecute (
+ ACPI_HANDLE ObjHandle,
+ UINT32 NestingLevel,
+ void *Context,
+ void **ReturnValue);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbSetMethodBreakpoint
+ *
+ * PARAMETERS: Location - AML offset of breakpoint
+ * WalkState - Current walk info
+ * Op - Current Op (from parse walk)
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Set a breakpoint in a control method at the specified
+ * AML offset
+ *
+ ******************************************************************************/
+
+void
+AcpiDbSetMethodBreakpoint (
+ char *Location,
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op)
+{
+ UINT32 Address;
+
+
+ if (!Op)
+ {
+ AcpiOsPrintf ("There is no method currently executing\n");
+ return;
+ }
+
+ /* Get and verify the breakpoint address */
+
+ Address = ACPI_STRTOUL (Location, NULL, 16);
+ if (Address <= Op->Common.AmlOffset)
+ {
+ AcpiOsPrintf ("Breakpoint %X is beyond current address %X\n",
+ Address, Op->Common.AmlOffset);
+ }
+
+ /* Save breakpoint in current walk */
+
+ WalkState->UserBreakpoint = Address;
+ AcpiOsPrintf ("Breakpoint set at AML offset %X\n", Address);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbSetMethodCallBreakpoint
+ *
+ * PARAMETERS: Op - Current Op (from parse walk)
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Set a breakpoint in a control method at the specified
+ * AML offset
+ *
+ ******************************************************************************/
+
+void
+AcpiDbSetMethodCallBreakpoint (
+ ACPI_PARSE_OBJECT *Op)
+{
+
+
+ if (!Op)
+ {
+ AcpiOsPrintf ("There is no method currently executing\n");
+ return;
+ }
+
+ AcpiGbl_StepToNextCall = TRUE;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbSetMethodData
+ *
+ * PARAMETERS: TypeArg - L for local, A for argument
+ * IndexArg - which one
+ * ValueArg - Value to set.
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Set a local or argument for the running control method.
+ * NOTE: only object supported is Number.
+ *
+ ******************************************************************************/
+
+void
+AcpiDbSetMethodData (
+ char *TypeArg,
+ char *IndexArg,
+ char *ValueArg)
+{
+ char Type;
+ UINT32 Index;
+ UINT32 Value;
+ ACPI_WALK_STATE *WalkState;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_STATUS Status;
+ ACPI_NAMESPACE_NODE *Node;
+
+
+ /* Validate TypeArg */
+
+ AcpiUtStrupr (TypeArg);
+ Type = TypeArg[0];
+ if ((Type != 'L') &&
+ (Type != 'A') &&
+ (Type != 'N'))
+ {
+ AcpiOsPrintf ("Invalid SET operand: %s\n", TypeArg);
+ return;
+ }
+
+ Value = ACPI_STRTOUL (ValueArg, NULL, 16);
+
+ if (Type == 'N')
+ {
+ Node = AcpiDbConvertToNode (IndexArg);
+ if (Node->Type != ACPI_TYPE_INTEGER)
+ {
+ AcpiOsPrintf ("Can only set Integer nodes\n");
+ return;
+ }
+ ObjDesc = Node->Object;
+ ObjDesc->Integer.Value = Value;
+ return;
+ }
+
+ /* Get the index and value */
+
+ Index = ACPI_STRTOUL (IndexArg, NULL, 16);
+
+ WalkState = AcpiDsGetCurrentWalkState (AcpiGbl_CurrentWalkList);
+ if (!WalkState)
+ {
+ AcpiOsPrintf ("There is no method currently executing\n");
+ return;
+ }
+
+ /* Create and initialize the new object */
+
+ ObjDesc = AcpiUtCreateIntegerObject ((UINT64) Value);
+ if (!ObjDesc)
+ {
+ AcpiOsPrintf ("Could not create an internal object\n");
+ return;
+ }
+
+ /* Store the new object into the target */
+
+ switch (Type)
+ {
+ case 'A':
+
+ /* Set a method argument */
+
+ if (Index > ACPI_METHOD_MAX_ARG)
+ {
+ AcpiOsPrintf ("Arg%u - Invalid argument name\n", Index);
+ goto Cleanup;
+ }
+
+ Status = AcpiDsStoreObjectToLocal (ACPI_REFCLASS_ARG, Index, ObjDesc,
+ WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Cleanup;
+ }
+
+ ObjDesc = WalkState->Arguments[Index].Object;
+
+ AcpiOsPrintf ("Arg%u: ", Index);
+ AcpiDmDisplayInternalObject (ObjDesc, WalkState);
+ break;
+
+ case 'L':
+
+ /* Set a method local */
+
+ if (Index > ACPI_METHOD_MAX_LOCAL)
+ {
+ AcpiOsPrintf ("Local%u - Invalid local variable name\n", Index);
+ goto Cleanup;
+ }
+
+ Status = AcpiDsStoreObjectToLocal (ACPI_REFCLASS_LOCAL, Index, ObjDesc,
+ WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Cleanup;
+ }
+
+ ObjDesc = WalkState->LocalVariables[Index].Object;
+
+ AcpiOsPrintf ("Local%u: ", Index);
+ AcpiDmDisplayInternalObject (ObjDesc, WalkState);
+ break;
+
+ default:
+ break;
+ }
+
+Cleanup:
+ AcpiUtRemoveReference (ObjDesc);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDisassembleAml
+ *
+ * PARAMETERS: Statements - Number of statements to disassemble
+ * Op - Current Op (from parse walk)
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Display disassembled AML (ASL) starting from Op for the number
+ * of statements specified.
+ *
+ ******************************************************************************/
+
+void
+AcpiDbDisassembleAml (
+ char *Statements,
+ ACPI_PARSE_OBJECT *Op)
+{
+ UINT32 NumStatements = 8;
+
+
+ if (!Op)
+ {
+ AcpiOsPrintf ("There is no method currently executing\n");
+ return;
+ }
+
+ if (Statements)
+ {
+ NumStatements = ACPI_STRTOUL (Statements, NULL, 0);
+ }
+
+ AcpiDmDisassemble (NULL, Op, NumStatements);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDisassembleMethod
+ *
+ * PARAMETERS: Name - Name of control method
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Display disassembled AML (ASL) starting from Op for the number
+ * of statements specified.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDbDisassembleMethod (
+ char *Name)
+{
+ ACPI_STATUS Status;
+ ACPI_PARSE_OBJECT *Op;
+ ACPI_WALK_STATE *WalkState;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_NAMESPACE_NODE *Method;
+
+
+ Method = AcpiDbConvertToNode (Name);
+ if (!Method)
+ {
+ return (AE_BAD_PARAMETER);
+ }
+
+ ObjDesc = Method->Object;
+
+ Op = AcpiPsCreateScopeOp ();
+ if (!Op)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ /* Create and initialize a new walk state */
+
+ WalkState = AcpiDsCreateWalkState (0, Op, NULL, NULL);
+ if (!WalkState)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ Status = AcpiDsInitAmlWalk (WalkState, Op, NULL,
+ ObjDesc->Method.AmlStart,
+ ObjDesc->Method.AmlLength, NULL, ACPI_IMODE_LOAD_PASS1);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /* Parse the AML */
+
+ WalkState->ParseFlags &= ~ACPI_PARSE_DELETE_TREE;
+ WalkState->ParseFlags |= ACPI_PARSE_DISASSEMBLE;
+ Status = AcpiPsParseAml (WalkState);
+
+ AcpiDmDisassemble (NULL, Op, 0);
+ AcpiPsDeleteParseTree (Op);
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbWalkForExecute
+ *
+ * PARAMETERS: Callback from WalkNamespace
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Batch execution module. Currently only executes predefined
+ * ACPI names.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDbWalkForExecute (
+ ACPI_HANDLE ObjHandle,
+ UINT32 NestingLevel,
+ void *Context,
+ void **ReturnValue)
+{
+ ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
+ ACPI_EXECUTE_WALK *Info = (ACPI_EXECUTE_WALK *) Context;
+ ACPI_BUFFER ReturnObj;
+ ACPI_STATUS Status;
+ char *Pathname;
+ UINT32 i;
+ ACPI_DEVICE_INFO *ObjInfo;
+ ACPI_OBJECT_LIST ParamObjects;
+ ACPI_OBJECT Params[ACPI_METHOD_NUM_ARGS];
+ const ACPI_PREDEFINED_INFO *Predefined;
+
+
+ Predefined = AcpiNsCheckForPredefinedName (Node);
+ if (!Predefined)
+ {
+ return (AE_OK);
+ }
+
+ if (Node->Type == ACPI_TYPE_LOCAL_SCOPE)
+ {
+ return (AE_OK);
+ }
+
+ Pathname = AcpiNsGetExternalPathname (Node);
+ if (!Pathname)
+ {
+ return (AE_OK);
+ }
+
+ /* Get the object info for number of method parameters */
+
+ Status = AcpiGetObjectInfo (ObjHandle, &ObjInfo);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ ParamObjects.Pointer = NULL;
+ ParamObjects.Count = 0;
+
+ if (ObjInfo->Type == ACPI_TYPE_METHOD)
+ {
+ /* Setup default parameters */
+
+ for (i = 0; i < ObjInfo->ParamCount; i++)
+ {
+ Params[i].Type = ACPI_TYPE_INTEGER;
+ Params[i].Integer.Value = 1;
+ }
+
+ ParamObjects.Pointer = Params;
+ ParamObjects.Count = ObjInfo->ParamCount;
+ }
+
+ ACPI_FREE (ObjInfo);
+ ReturnObj.Pointer = NULL;
+ ReturnObj.Length = ACPI_ALLOCATE_BUFFER;
+
+ /* Do the actual method execution */
+
+ AcpiGbl_MethodExecuting = TRUE;
+
+ Status = AcpiEvaluateObject (Node, NULL, &ParamObjects, &ReturnObj);
+
+ AcpiOsPrintf ("%-32s returned %s\n", Pathname, AcpiFormatException (Status));
+ AcpiGbl_MethodExecuting = FALSE;
+ ACPI_FREE (Pathname);
+
+ /* Ignore status from method execution */
+
+ Status = AE_OK;
+
+ /* Update count, check if we have executed enough methods */
+
+ Info->Count++;
+ if (Info->Count >= Info->MaxCount)
+ {
+ Status = AE_CTRL_TERMINATE;
+ }
+
+ return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbBatchExecute
+ *
+ * PARAMETERS: CountArg - Max number of methods to execute
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Namespace batch execution. Execute predefined names in the
+ * namespace, up to the max count, if specified.
+ *
+ ******************************************************************************/
+
+void
+AcpiDbBatchExecute (
+ char *CountArg)
+{
+ ACPI_EXECUTE_WALK Info;
+
+
+ Info.Count = 0;
+ Info.MaxCount = ACPI_UINT32_MAX;
+
+ if (CountArg)
+ {
+ Info.MaxCount = ACPI_STRTOUL (CountArg, NULL, 0);
+ }
+
+
+ /* Search all nodes in namespace */
+
+ (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
+ AcpiDbWalkForExecute, NULL, (void *) &Info, NULL);
+
+ AcpiOsPrintf ("Executed %u predefined names in the namespace\n", Info.Count);
+}
+
+#endif /* ACPI_DEBUGGER */
diff --git a/source/components/debugger/dbnames.c b/source/components/debugger/dbnames.c
new file mode 100644
index 000000000000..be326c5390a7
--- /dev/null
+++ b/source/components/debugger/dbnames.c
@@ -0,0 +1,934 @@
+/*******************************************************************************
+ *
+ * Module Name: dbnames - Debugger commands for the acpi namespace
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2012, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include "acpi.h"
+#include "accommon.h"
+#include "acnamesp.h"
+#include "acdebug.h"
+
+
+#ifdef ACPI_DEBUGGER
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("dbnames")
+
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiDbWalkAndMatchName (
+ ACPI_HANDLE ObjHandle,
+ UINT32 NestingLevel,
+ void *Context,
+ void **ReturnValue);
+
+static ACPI_STATUS
+AcpiDbWalkForPredefinedNames (
+ ACPI_HANDLE ObjHandle,
+ UINT32 NestingLevel,
+ void *Context,
+ void **ReturnValue);
+
+static ACPI_STATUS
+AcpiDbWalkForSpecificObjects (
+ ACPI_HANDLE ObjHandle,
+ UINT32 NestingLevel,
+ void *Context,
+ void **ReturnValue);
+
+static ACPI_STATUS
+AcpiDbIntegrityWalk (
+ ACPI_HANDLE ObjHandle,
+ UINT32 NestingLevel,
+ void *Context,
+ void **ReturnValue);
+
+static ACPI_STATUS
+AcpiDbWalkForReferences (
+ ACPI_HANDLE ObjHandle,
+ UINT32 NestingLevel,
+ void *Context,
+ void **ReturnValue);
+
+static ACPI_STATUS
+AcpiDbBusWalk (
+ ACPI_HANDLE ObjHandle,
+ UINT32 NestingLevel,
+ void *Context,
+ void **ReturnValue);
+
+/*
+ * Arguments for the Objects command
+ * These object types map directly to the ACPI_TYPES
+ */
+static ARGUMENT_INFO AcpiDbObjectTypes [] =
+{
+ {"ANY"},
+ {"INTEGERS"},
+ {"STRINGS"},
+ {"BUFFERS"},
+ {"PACKAGES"},
+ {"FIELDS"},
+ {"DEVICES"},
+ {"EVENTS"},
+ {"METHODS"},
+ {"MUTEXES"},
+ {"REGIONS"},
+ {"POWERRESOURCES"},
+ {"PROCESSORS"},
+ {"THERMALZONES"},
+ {"BUFFERFIELDS"},
+ {"DDBHANDLES"},
+ {"DEBUG"},
+ {"REGIONFIELDS"},
+ {"BANKFIELDS"},
+ {"INDEXFIELDS"},
+ {"REFERENCES"},
+ {"ALIAS"},
+ {NULL} /* Must be null terminated */
+};
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbSetScope
+ *
+ * PARAMETERS: Name - New scope path
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Set the "current scope" as maintained by this utility.
+ * The scope is used as a prefix to ACPI paths.
+ *
+ ******************************************************************************/
+
+void
+AcpiDbSetScope (
+ char *Name)
+{
+ ACPI_STATUS Status;
+ ACPI_NAMESPACE_NODE *Node;
+
+
+ if (!Name || Name[0] == 0)
+ {
+ AcpiOsPrintf ("Current scope: %s\n", AcpiGbl_DbScopeBuf);
+ return;
+ }
+
+ AcpiDbPrepNamestring (Name);
+
+ if (Name[0] == '\\')
+ {
+ /* Validate new scope from the root */
+
+ Status = AcpiNsGetNode (AcpiGbl_RootNode, Name, ACPI_NS_NO_UPSEARCH,
+ &Node);
+ if (ACPI_FAILURE (Status))
+ {
+ goto ErrorExit;
+ }
+
+ ACPI_STRCPY (AcpiGbl_DbScopeBuf, Name);
+ ACPI_STRCAT (AcpiGbl_DbScopeBuf, "\\");
+ }
+ else
+ {
+ /* Validate new scope relative to old scope */
+
+ Status = AcpiNsGetNode (AcpiGbl_DbScopeNode, Name, ACPI_NS_NO_UPSEARCH,
+ &Node);
+ if (ACPI_FAILURE (Status))
+ {
+ goto ErrorExit;
+ }
+
+ ACPI_STRCAT (AcpiGbl_DbScopeBuf, Name);
+ ACPI_STRCAT (AcpiGbl_DbScopeBuf, "\\");
+ }
+
+ AcpiGbl_DbScopeNode = Node;
+ AcpiOsPrintf ("New scope: %s\n", AcpiGbl_DbScopeBuf);
+ return;
+
+ErrorExit:
+
+ AcpiOsPrintf ("Could not attach scope: %s, %s\n",
+ Name, AcpiFormatException (Status));
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDumpNamespace
+ *
+ * PARAMETERS: StartArg - Node to begin namespace dump
+ * DepthArg - Maximum tree depth to be dumped
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump entire namespace or a subtree. Each node is displayed
+ * with type and other information.
+ *
+ ******************************************************************************/
+
+void
+AcpiDbDumpNamespace (
+ char *StartArg,
+ char *DepthArg)
+{
+ ACPI_HANDLE SubtreeEntry = AcpiGbl_RootNode;
+ UINT32 MaxDepth = ACPI_UINT32_MAX;
+
+
+ /* No argument given, just start at the root and dump entire namespace */
+
+ if (StartArg)
+ {
+ SubtreeEntry = AcpiDbConvertToNode (StartArg);
+ if (!SubtreeEntry)
+ {
+ return;
+ }
+
+ /* Now we can check for the depth argument */
+
+ if (DepthArg)
+ {
+ MaxDepth = ACPI_STRTOUL (DepthArg, NULL, 0);
+ }
+ }
+
+ AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
+ AcpiOsPrintf ("ACPI Namespace (from %4.4s (%p) subtree):\n",
+ ((ACPI_NAMESPACE_NODE *) SubtreeEntry)->Name.Ascii, SubtreeEntry);
+
+ /* Display the subtree */
+
+ AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
+ AcpiNsDumpObjects (ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, MaxDepth,
+ ACPI_OWNER_ID_MAX, SubtreeEntry);
+ AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDumpNamespaceByOwner
+ *
+ * PARAMETERS: OwnerArg - Owner ID whose nodes will be displayed
+ * DepthArg - Maximum tree depth to be dumped
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump elements of the namespace that are owned by the OwnerId.
+ *
+ ******************************************************************************/
+
+void
+AcpiDbDumpNamespaceByOwner (
+ char *OwnerArg,
+ char *DepthArg)
+{
+ ACPI_HANDLE SubtreeEntry = AcpiGbl_RootNode;
+ UINT32 MaxDepth = ACPI_UINT32_MAX;
+ ACPI_OWNER_ID OwnerId;
+
+
+ OwnerId = (ACPI_OWNER_ID) ACPI_STRTOUL (OwnerArg, NULL, 0);
+
+ /* Now we can check for the depth argument */
+
+ if (DepthArg)
+ {
+ MaxDepth = ACPI_STRTOUL (DepthArg, NULL, 0);
+ }
+
+ AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
+ AcpiOsPrintf ("ACPI Namespace by owner %X:\n", OwnerId);
+
+ /* Display the subtree */
+
+ AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
+ AcpiNsDumpObjects (ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, MaxDepth, OwnerId,
+ SubtreeEntry);
+ AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbWalkAndMatchName
+ *
+ * PARAMETERS: Callback from WalkNamespace
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Find a particular name/names within the namespace. Wildcards
+ * are supported -- '?' matches any character.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDbWalkAndMatchName (
+ ACPI_HANDLE ObjHandle,
+ UINT32 NestingLevel,
+ void *Context,
+ void **ReturnValue)
+{
+ ACPI_STATUS Status;
+ char *RequestedName = (char *) Context;
+ UINT32 i;
+ ACPI_BUFFER Buffer;
+ ACPI_WALK_INFO Info;
+
+
+ /* Check for a name match */
+
+ for (i = 0; i < 4; i++)
+ {
+ /* Wildcard support */
+
+ if ((RequestedName[i] != '?') &&
+ (RequestedName[i] != ((ACPI_NAMESPACE_NODE *) ObjHandle)->Name.Ascii[i]))
+ {
+ /* No match, just exit */
+
+ return (AE_OK);
+ }
+ }
+
+ /* Get the full pathname to this object */
+
+ Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
+ Status = AcpiNsHandleToPathname (ObjHandle, &Buffer);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle);
+ }
+ else
+ {
+ Info.OwnerId = ACPI_OWNER_ID_MAX;
+ Info.DebugLevel = ACPI_UINT32_MAX;
+ Info.DisplayType = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
+
+ AcpiOsPrintf ("%32s", (char *) Buffer.Pointer);
+ (void) AcpiNsDumpOneObject (ObjHandle, NestingLevel, &Info, NULL);
+ ACPI_FREE (Buffer.Pointer);
+ }
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbFindNameInNamespace
+ *
+ * PARAMETERS: NameArg - The 4-character ACPI name to find.
+ * wildcards are supported.
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Search the namespace for a given name (with wildcards)
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDbFindNameInNamespace (
+ char *NameArg)
+{
+ char AcpiName[5] = "____";
+ char *AcpiNamePtr = AcpiName;
+
+
+ if (ACPI_STRLEN (NameArg) > 4)
+ {
+ AcpiOsPrintf ("Name must be no longer than 4 characters\n");
+ return (AE_OK);
+ }
+
+ /* Pad out name with underscores as necessary to create a 4-char name */
+
+ AcpiUtStrupr (NameArg);
+ while (*NameArg)
+ {
+ *AcpiNamePtr = *NameArg;
+ AcpiNamePtr++;
+ NameArg++;
+ }
+
+ /* Walk the namespace from the root */
+
+ (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
+ AcpiDbWalkAndMatchName, NULL, AcpiName, NULL);
+
+ AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbWalkForPredefinedNames
+ *
+ * PARAMETERS: Callback from WalkNamespace
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Detect and display predefined ACPI names (names that start with
+ * an underscore)
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDbWalkForPredefinedNames (
+ ACPI_HANDLE ObjHandle,
+ UINT32 NestingLevel,
+ void *Context,
+ void **ReturnValue)
+{
+ ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
+ UINT32 *Count = (UINT32 *) Context;
+ const ACPI_PREDEFINED_INFO *Predefined;
+ const ACPI_PREDEFINED_INFO *Package = NULL;
+ char *Pathname;
+
+
+ Predefined = AcpiNsCheckForPredefinedName (Node);
+ if (!Predefined)
+ {
+ return (AE_OK);
+ }
+
+ Pathname = AcpiNsGetExternalPathname (Node);
+ if (!Pathname)
+ {
+ return (AE_OK);
+ }
+
+ /* If method returns a package, the info is in the next table entry */
+
+ if (Predefined->Info.ExpectedBtypes & ACPI_BTYPE_PACKAGE)
+ {
+ Package = Predefined + 1;
+ }
+
+ AcpiOsPrintf ("%-32s arg %X ret %2.2X", Pathname,
+ Predefined->Info.ParamCount, Predefined->Info.ExpectedBtypes);
+
+ if (Package)
+ {
+ AcpiOsPrintf (" PkgType %2.2X ObjType %2.2X Count %2.2X",
+ Package->RetInfo.Type, Package->RetInfo.ObjectType1,
+ Package->RetInfo.Count1);
+ }
+
+ AcpiOsPrintf("\n");
+
+ AcpiNsCheckParameterCount (Pathname, Node, ACPI_UINT32_MAX, Predefined);
+ ACPI_FREE (Pathname);
+ (*Count)++;
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbCheckPredefinedNames
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Validate all predefined names in the namespace
+ *
+ ******************************************************************************/
+
+void
+AcpiDbCheckPredefinedNames (
+ void)
+{
+ UINT32 Count = 0;
+
+
+ /* Search all nodes in namespace */
+
+ (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
+ AcpiDbWalkForPredefinedNames, NULL, (void *) &Count, NULL);
+
+ AcpiOsPrintf ("Found %u predefined names in the namespace\n", Count);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbWalkForSpecificObjects
+ *
+ * PARAMETERS: Callback from WalkNamespace
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Display short info about objects in the namespace
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDbWalkForSpecificObjects (
+ ACPI_HANDLE ObjHandle,
+ UINT32 NestingLevel,
+ void *Context,
+ void **ReturnValue)
+{
+ ACPI_WALK_INFO *Info = (ACPI_WALK_INFO *) Context;
+ ACPI_BUFFER Buffer;
+ ACPI_STATUS Status;
+
+
+ Info->Count++;
+
+ /* Get and display the full pathname to this object */
+
+ Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
+ Status = AcpiNsHandleToPathname (ObjHandle, &Buffer);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle);
+ return (AE_OK);
+ }
+
+ AcpiOsPrintf ("%32s", (char *) Buffer.Pointer);
+ ACPI_FREE (Buffer.Pointer);
+
+ /* Dump short info about the object */
+
+ (void) AcpiNsDumpOneObject (ObjHandle, NestingLevel, Info, NULL);
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDisplayObjects
+ *
+ * PARAMETERS: ObjTypeArg - Type of object to display
+ * DisplayCountArg - Max depth to display
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Display objects in the namespace of the requested type
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDbDisplayObjects (
+ char *ObjTypeArg,
+ char *DisplayCountArg)
+{
+ ACPI_WALK_INFO Info;
+ ACPI_OBJECT_TYPE Type;
+
+
+ /* Get the object type */
+
+ Type = AcpiDbMatchArgument (ObjTypeArg, AcpiDbObjectTypes);
+ if (Type == ACPI_TYPE_NOT_FOUND)
+ {
+ AcpiOsPrintf ("Invalid or unsupported argument\n");
+ return (AE_OK);
+ }
+
+ AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
+ AcpiOsPrintf (
+ "Objects of type [%s] defined in the current ACPI Namespace:\n",
+ AcpiUtGetTypeName (Type));
+
+ AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
+
+ Info.Count = 0;
+ Info.OwnerId = ACPI_OWNER_ID_MAX;
+ Info.DebugLevel = ACPI_UINT32_MAX;
+ Info.DisplayType = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
+
+ /* Walk the namespace from the root */
+
+ (void) AcpiWalkNamespace (Type, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
+ AcpiDbWalkForSpecificObjects, NULL, (void *) &Info, NULL);
+
+ AcpiOsPrintf (
+ "\nFound %u objects of type [%s] in the current ACPI Namespace\n",
+ Info.Count, AcpiUtGetTypeName (Type));
+
+ AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbIntegrityWalk
+ *
+ * PARAMETERS: Callback from WalkNamespace
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Examine one NS node for valid values.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDbIntegrityWalk (
+ ACPI_HANDLE ObjHandle,
+ UINT32 NestingLevel,
+ void *Context,
+ void **ReturnValue)
+{
+ ACPI_INTEGRITY_INFO *Info = (ACPI_INTEGRITY_INFO *) Context;
+ ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
+ ACPI_OPERAND_OBJECT *Object;
+ BOOLEAN Alias = TRUE;
+
+
+ Info->Nodes++;
+
+ /* Verify the NS node, and dereference aliases */
+
+ while (Alias)
+ {
+ if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED)
+ {
+ AcpiOsPrintf ("Invalid Descriptor Type for Node %p [%s] - is %2.2X should be %2.2X\n",
+ Node, AcpiUtGetDescriptorName (Node), ACPI_GET_DESCRIPTOR_TYPE (Node),
+ ACPI_DESC_TYPE_NAMED);
+ return (AE_OK);
+ }
+
+ if ((Node->Type == ACPI_TYPE_LOCAL_ALIAS) ||
+ (Node->Type == ACPI_TYPE_LOCAL_METHOD_ALIAS))
+ {
+ Node = (ACPI_NAMESPACE_NODE *) Node->Object;
+ }
+ else
+ {
+ Alias = FALSE;
+ }
+ }
+
+ if (Node->Type > ACPI_TYPE_LOCAL_MAX)
+ {
+ AcpiOsPrintf ("Invalid Object Type for Node %p, Type = %X\n",
+ Node, Node->Type);
+ return (AE_OK);
+ }
+
+ if (!AcpiUtValidAcpiName (Node->Name.Integer))
+ {
+ AcpiOsPrintf ("Invalid AcpiName for Node %p\n", Node);
+ return (AE_OK);
+ }
+
+ Object = AcpiNsGetAttachedObject (Node);
+ if (Object)
+ {
+ Info->Objects++;
+ if (ACPI_GET_DESCRIPTOR_TYPE (Object) != ACPI_DESC_TYPE_OPERAND)
+ {
+ AcpiOsPrintf ("Invalid Descriptor Type for Object %p [%s]\n",
+ Object, AcpiUtGetDescriptorName (Object));
+ }
+ }
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbCheckIntegrity
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Check entire namespace for data structure integrity
+ *
+ ******************************************************************************/
+
+void
+AcpiDbCheckIntegrity (
+ void)
+{
+ ACPI_INTEGRITY_INFO Info = {0,0};
+
+ /* Search all nodes in namespace */
+
+ (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
+ AcpiDbIntegrityWalk, NULL, (void *) &Info, NULL);
+
+ AcpiOsPrintf ("Verified %u namespace nodes with %u Objects\n",
+ Info.Nodes, Info.Objects);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbWalkForReferences
+ *
+ * PARAMETERS: Callback from WalkNamespace
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Check if this namespace object refers to the target object
+ * that is passed in as the context value.
+ *
+ * Note: Currently doesn't check subobjects within the Node's object
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDbWalkForReferences (
+ ACPI_HANDLE ObjHandle,
+ UINT32 NestingLevel,
+ void *Context,
+ void **ReturnValue)
+{
+ ACPI_OPERAND_OBJECT *ObjDesc = (ACPI_OPERAND_OBJECT *) Context;
+ ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
+
+
+ /* Check for match against the namespace node itself */
+
+ if (Node == (void *) ObjDesc)
+ {
+ AcpiOsPrintf ("Object is a Node [%4.4s]\n",
+ AcpiUtGetNodeName (Node));
+ }
+
+ /* Check for match against the object attached to the node */
+
+ if (AcpiNsGetAttachedObject (Node) == ObjDesc)
+ {
+ AcpiOsPrintf ("Reference at Node->Object %p [%4.4s]\n",
+ Node, AcpiUtGetNodeName (Node));
+ }
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbFindReferences
+ *
+ * PARAMETERS: ObjectArg - String with hex value of the object
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Search namespace for all references to the input object
+ *
+ ******************************************************************************/
+
+void
+AcpiDbFindReferences (
+ char *ObjectArg)
+{
+ ACPI_OPERAND_OBJECT *ObjDesc;
+
+
+ /* Convert string to object pointer */
+
+ ObjDesc = ACPI_TO_POINTER (ACPI_STRTOUL (ObjectArg, NULL, 16));
+
+ /* Search all nodes in namespace */
+
+ (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
+ AcpiDbWalkForReferences, NULL, (void *) ObjDesc, NULL);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbBusWalk
+ *
+ * PARAMETERS: Callback from WalkNamespace
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Display info about device objects that have a corresponding
+ * _PRT method.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDbBusWalk (
+ ACPI_HANDLE ObjHandle,
+ UINT32 NestingLevel,
+ void *Context,
+ void **ReturnValue)
+{
+ ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
+ ACPI_STATUS Status;
+ ACPI_BUFFER Buffer;
+ ACPI_NAMESPACE_NODE *TempNode;
+ ACPI_DEVICE_INFO *Info;
+ UINT32 i;
+
+
+ if ((Node->Type != ACPI_TYPE_DEVICE) &&
+ (Node->Type != ACPI_TYPE_PROCESSOR))
+ {
+ return (AE_OK);
+ }
+
+ /* Exit if there is no _PRT under this device */
+
+ Status = AcpiGetHandle (Node, METHOD_NAME__PRT,
+ ACPI_CAST_PTR (ACPI_HANDLE, &TempNode));
+ if (ACPI_FAILURE (Status))
+ {
+ return (AE_OK);
+ }
+
+ /* Get the full path to this device object */
+
+ Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
+ Status = AcpiNsHandleToPathname (ObjHandle, &Buffer);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle);
+ return (AE_OK);
+ }
+
+ Status = AcpiGetObjectInfo (ObjHandle, &Info);
+ if (ACPI_FAILURE (Status))
+ {
+ return (AE_OK);
+ }
+
+ /* Display the full path */
+
+ AcpiOsPrintf ("%-32s Type %X", (char *) Buffer.Pointer, Node->Type);
+ ACPI_FREE (Buffer.Pointer);
+
+ if (Info->Flags & ACPI_PCI_ROOT_BRIDGE)
+ {
+ AcpiOsPrintf (" - Is PCI Root Bridge");
+ }
+ AcpiOsPrintf ("\n");
+
+ /* _PRT info */
+
+ AcpiOsPrintf ("_PRT: %p\n", TempNode);
+
+ /* Dump _ADR, _HID, _UID, _CID */
+
+ if (Info->Valid & ACPI_VALID_ADR)
+ {
+ AcpiOsPrintf ("_ADR: %8.8X%8.8X\n", ACPI_FORMAT_UINT64 (Info->Address));
+ }
+ else
+ {
+ AcpiOsPrintf ("_ADR: <Not Present>\n");
+ }
+
+ if (Info->Valid & ACPI_VALID_HID)
+ {
+ AcpiOsPrintf ("_HID: %s\n", Info->HardwareId.String);
+ }
+ else
+ {
+ AcpiOsPrintf ("_HID: <Not Present>\n");
+ }
+
+ if (Info->Valid & ACPI_VALID_UID)
+ {
+ AcpiOsPrintf ("_UID: %s\n", Info->UniqueId.String);
+ }
+ else
+ {
+ AcpiOsPrintf ("_UID: <Not Present>\n");
+ }
+
+ if (Info->Valid & ACPI_VALID_CID)
+ {
+ for (i = 0; i < Info->CompatibleIdList.Count; i++)
+ {
+ AcpiOsPrintf ("_CID: %s\n",
+ Info->CompatibleIdList.Ids[i].String);
+ }
+ }
+ else
+ {
+ AcpiOsPrintf ("_CID: <Not Present>\n");
+ }
+
+ ACPI_FREE (Info);
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbGetBusInfo
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Display info about system busses.
+ *
+ ******************************************************************************/
+
+void
+AcpiDbGetBusInfo (
+ void)
+{
+ /* Search all nodes in namespace */
+
+ (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
+ AcpiDbBusWalk, NULL, NULL, NULL);
+}
+
+#endif /* ACPI_DEBUGGER */
diff --git a/source/components/debugger/dbstats.c b/source/components/debugger/dbstats.c
new file mode 100644
index 000000000000..379493515a61
--- /dev/null
+++ b/source/components/debugger/dbstats.c
@@ -0,0 +1,549 @@
+/*******************************************************************************
+ *
+ * Module Name: dbstats - Generation and display of ACPI table statistics
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2012, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include "acpi.h"
+#include "accommon.h"
+#include "acdebug.h"
+#include "acnamesp.h"
+
+#ifdef ACPI_DEBUGGER
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("dbstats")
+
+/* Local prototypes */
+
+static void
+AcpiDbCountNamespaceObjects (
+ void);
+
+static void
+AcpiDbEnumerateObject (
+ ACPI_OPERAND_OBJECT *ObjDesc);
+
+static ACPI_STATUS
+AcpiDbClassifyOneObject (
+ ACPI_HANDLE ObjHandle,
+ UINT32 NestingLevel,
+ void *Context,
+ void **ReturnValue);
+
+#if defined ACPI_DBG_TRACK_ALLOCATIONS || defined ACPI_USE_LOCAL_CACHE
+static void
+AcpiDbListInfo (
+ ACPI_MEMORY_LIST *List);
+#endif
+
+
+/*
+ * Statistics subcommands
+ */
+static ARGUMENT_INFO AcpiDbStatTypes [] =
+{
+ {"ALLOCATIONS"},
+ {"OBJECTS"},
+ {"MEMORY"},
+ {"MISC"},
+ {"TABLES"},
+ {"SIZES"},
+ {"STACK"},
+ {NULL} /* Must be null terminated */
+};
+
+#define CMD_STAT_ALLOCATIONS 0
+#define CMD_STAT_OBJECTS 1
+#define CMD_STAT_MEMORY 2
+#define CMD_STAT_MISC 3
+#define CMD_STAT_TABLES 4
+#define CMD_STAT_SIZES 5
+#define CMD_STAT_STACK 6
+
+
+#if defined ACPI_DBG_TRACK_ALLOCATIONS || defined ACPI_USE_LOCAL_CACHE
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbListInfo
+ *
+ * PARAMETERS: List - Memory list/cache to be displayed
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Display information about the input memory list or cache.
+ *
+ ******************************************************************************/
+
+static void
+AcpiDbListInfo (
+ ACPI_MEMORY_LIST *List)
+{
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+ UINT32 Outstanding;
+#endif
+
+ AcpiOsPrintf ("\n%s\n", List->ListName);
+
+ /* MaxDepth > 0 indicates a cache object */
+
+ if (List->MaxDepth > 0)
+ {
+ AcpiOsPrintf (
+ " Cache: [Depth MaxD Avail Size] %8.2X %8.2X %8.2X %8.2X\n",
+ List->CurrentDepth,
+ List->MaxDepth,
+ List->MaxDepth - List->CurrentDepth,
+ (List->CurrentDepth * List->ObjectSize));
+ }
+
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+ if (List->MaxDepth > 0)
+ {
+ AcpiOsPrintf (
+ " Cache: [Requests Hits Misses ObjSize] %8.2X %8.2X %8.2X %8.2X\n",
+ List->Requests,
+ List->Hits,
+ List->Requests - List->Hits,
+ List->ObjectSize);
+ }
+
+ Outstanding = AcpiDbGetCacheInfo (List);
+
+ if (List->ObjectSize)
+ {
+ AcpiOsPrintf (
+ " Mem: [Alloc Free Max CurSize Outstanding] %8.2X %8.2X %8.2X %8.2X %8.2X\n",
+ List->TotalAllocated,
+ List->TotalFreed,
+ List->MaxOccupied,
+ Outstanding * List->ObjectSize,
+ Outstanding);
+ }
+ else
+ {
+ AcpiOsPrintf (
+ " Mem: [Alloc Free Max CurSize Outstanding Total] %8.2X %8.2X %8.2X %8.2X %8.2X %8.2X\n",
+ List->TotalAllocated,
+ List->TotalFreed,
+ List->MaxOccupied,
+ List->CurrentTotalSize,
+ Outstanding,
+ List->TotalSize);
+ }
+#endif
+}
+#endif
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbEnumerateObject
+ *
+ * PARAMETERS: ObjDesc - Object to be counted
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Add this object to the global counts, by object type.
+ * Limited recursion handles subobjects and packages, and this
+ * is probably acceptable within the AML debugger only.
+ *
+ ******************************************************************************/
+
+static void
+AcpiDbEnumerateObject (
+ ACPI_OPERAND_OBJECT *ObjDesc)
+{
+ UINT32 i;
+
+
+ if (!ObjDesc)
+ {
+ return;
+ }
+
+ /* Enumerate this object first */
+
+ AcpiGbl_NumObjects++;
+
+ if (ObjDesc->Common.Type > ACPI_TYPE_NS_NODE_MAX)
+ {
+ AcpiGbl_ObjTypeCountMisc++;
+ }
+ else
+ {
+ AcpiGbl_ObjTypeCount [ObjDesc->Common.Type]++;
+ }
+
+ /* Count the sub-objects */
+
+ switch (ObjDesc->Common.Type)
+ {
+ case ACPI_TYPE_PACKAGE:
+
+ for (i = 0; i < ObjDesc->Package.Count; i++)
+ {
+ AcpiDbEnumerateObject (ObjDesc->Package.Elements[i]);
+ }
+ break;
+
+ case ACPI_TYPE_DEVICE:
+
+ AcpiDbEnumerateObject (ObjDesc->Device.SystemNotify);
+ AcpiDbEnumerateObject (ObjDesc->Device.DeviceNotify);
+ AcpiDbEnumerateObject (ObjDesc->Device.Handler);
+ break;
+
+ case ACPI_TYPE_BUFFER_FIELD:
+
+ if (AcpiNsGetSecondaryObject (ObjDesc))
+ {
+ AcpiGbl_ObjTypeCount [ACPI_TYPE_BUFFER_FIELD]++;
+ }
+ break;
+
+ case ACPI_TYPE_REGION:
+
+ AcpiGbl_ObjTypeCount [ACPI_TYPE_LOCAL_REGION_FIELD ]++;
+ AcpiDbEnumerateObject (ObjDesc->Region.Handler);
+ break;
+
+ case ACPI_TYPE_POWER:
+
+ AcpiDbEnumerateObject (ObjDesc->PowerResource.SystemNotify);
+ AcpiDbEnumerateObject (ObjDesc->PowerResource.DeviceNotify);
+ break;
+
+ case ACPI_TYPE_PROCESSOR:
+
+ AcpiDbEnumerateObject (ObjDesc->Processor.SystemNotify);
+ AcpiDbEnumerateObject (ObjDesc->Processor.DeviceNotify);
+ AcpiDbEnumerateObject (ObjDesc->Processor.Handler);
+ break;
+
+ case ACPI_TYPE_THERMAL:
+
+ AcpiDbEnumerateObject (ObjDesc->ThermalZone.SystemNotify);
+ AcpiDbEnumerateObject (ObjDesc->ThermalZone.DeviceNotify);
+ AcpiDbEnumerateObject (ObjDesc->ThermalZone.Handler);
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbClassifyOneObject
+ *
+ * PARAMETERS: Callback for WalkNamespace
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Enumerate both the object descriptor (including subobjects) and
+ * the parent namespace node.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDbClassifyOneObject (
+ ACPI_HANDLE ObjHandle,
+ UINT32 NestingLevel,
+ void *Context,
+ void **ReturnValue)
+{
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ UINT32 Type;
+
+
+ AcpiGbl_NumNodes++;
+
+ Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
+ ObjDesc = AcpiNsGetAttachedObject (Node);
+
+ AcpiDbEnumerateObject (ObjDesc);
+
+ Type = Node->Type;
+ if (Type > ACPI_TYPE_NS_NODE_MAX)
+ {
+ AcpiGbl_NodeTypeCountMisc++;
+ }
+ else
+ {
+ AcpiGbl_NodeTypeCount [Type]++;
+ }
+
+ return AE_OK;
+
+
+#ifdef ACPI_FUTURE_IMPLEMENTATION
+
+ /* TBD: These need to be counted during the initial parsing phase */
+
+ if (AcpiPsIsNamedOp (Op->Opcode))
+ {
+ NumNodes++;
+ }
+
+ if (IsMethod)
+ {
+ NumMethodElements++;
+ }
+
+ NumGrammarElements++;
+ Op = AcpiPsGetDepthNext (Root, Op);
+
+ SizeOfParseTree = (NumGrammarElements - NumMethodElements) *
+ (UINT32) sizeof (ACPI_PARSE_OBJECT);
+ SizeOfMethodTrees = NumMethodElements * (UINT32) sizeof (ACPI_PARSE_OBJECT);
+ SizeOfNodeEntries = NumNodes * (UINT32) sizeof (ACPI_NAMESPACE_NODE);
+ SizeOfAcpiObjects = NumNodes * (UINT32) sizeof (ACPI_OPERAND_OBJECT);
+#endif
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbCountNamespaceObjects
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Count and classify the entire namespace, including all
+ * namespace nodes and attached objects.
+ *
+ ******************************************************************************/
+
+static void
+AcpiDbCountNamespaceObjects (
+ void)
+{
+ UINT32 i;
+
+
+ AcpiGbl_NumNodes = 0;
+ AcpiGbl_NumObjects = 0;
+
+ AcpiGbl_ObjTypeCountMisc = 0;
+ for (i = 0; i < (ACPI_TYPE_NS_NODE_MAX -1); i++)
+ {
+ AcpiGbl_ObjTypeCount [i] = 0;
+ AcpiGbl_NodeTypeCount [i] = 0;
+ }
+
+ (void) AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
+ ACPI_UINT32_MAX, FALSE, AcpiDbClassifyOneObject, NULL, NULL, NULL);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDisplayStatistics
+ *
+ * PARAMETERS: TypeArg - Subcommand
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Display various statistics
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDbDisplayStatistics (
+ char *TypeArg)
+{
+ UINT32 i;
+ UINT32 Temp;
+
+
+ if (!TypeArg)
+ {
+ AcpiOsPrintf ("The following subcommands are available:\n ALLOCATIONS, OBJECTS, MEMORY, MISC, SIZES, TABLES\n");
+ return (AE_OK);
+ }
+
+ AcpiUtStrupr (TypeArg);
+ Temp = AcpiDbMatchArgument (TypeArg, AcpiDbStatTypes);
+ if (Temp == (UINT32) -1)
+ {
+ AcpiOsPrintf ("Invalid or unsupported argument\n");
+ return (AE_OK);
+ }
+
+
+ switch (Temp)
+ {
+ case CMD_STAT_ALLOCATIONS:
+
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+ AcpiUtDumpAllocationInfo ();
+#endif
+ break;
+
+ case CMD_STAT_TABLES:
+
+ AcpiOsPrintf ("ACPI Table Information (not implemented):\n\n");
+ break;
+
+ case CMD_STAT_OBJECTS:
+
+ AcpiDbCountNamespaceObjects ();
+
+ AcpiOsPrintf ("\nObjects defined in the current namespace:\n\n");
+
+ AcpiOsPrintf ("%16.16s %10.10s %10.10s\n",
+ "ACPI_TYPE", "NODES", "OBJECTS");
+
+ for (i = 0; i < ACPI_TYPE_NS_NODE_MAX; i++)
+ {
+ AcpiOsPrintf ("%16.16s % 10ld% 10ld\n", AcpiUtGetTypeName (i),
+ AcpiGbl_NodeTypeCount [i], AcpiGbl_ObjTypeCount [i]);
+ }
+ AcpiOsPrintf ("%16.16s % 10ld% 10ld\n", "Misc/Unknown",
+ AcpiGbl_NodeTypeCountMisc, AcpiGbl_ObjTypeCountMisc);
+
+ AcpiOsPrintf ("%16.16s % 10ld% 10ld\n", "TOTALS:",
+ AcpiGbl_NumNodes, AcpiGbl_NumObjects);
+ break;
+
+ case CMD_STAT_MEMORY:
+
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+ AcpiOsPrintf ("\n----Object Statistics (all in hex)---------\n");
+
+ AcpiDbListInfo (AcpiGbl_GlobalList);
+ AcpiDbListInfo (AcpiGbl_NsNodeList);
+#endif
+
+#ifdef ACPI_USE_LOCAL_CACHE
+ AcpiOsPrintf ("\n----Cache Statistics (all in hex)---------\n");
+ AcpiDbListInfo (AcpiGbl_OperandCache);
+ AcpiDbListInfo (AcpiGbl_PsNodeCache);
+ AcpiDbListInfo (AcpiGbl_PsNodeExtCache);
+ AcpiDbListInfo (AcpiGbl_StateCache);
+#endif
+
+ break;
+
+ case CMD_STAT_MISC:
+
+ AcpiOsPrintf ("\nMiscellaneous Statistics:\n\n");
+ AcpiOsPrintf ("Calls to AcpiPsFind:.. ........% 7ld\n",
+ AcpiGbl_PsFindCount);
+ AcpiOsPrintf ("Calls to AcpiNsLookup:..........% 7ld\n",
+ AcpiGbl_NsLookupCount);
+
+ AcpiOsPrintf ("\n");
+
+ AcpiOsPrintf ("Mutex usage:\n\n");
+ for (i = 0; i < ACPI_NUM_MUTEX; i++)
+ {
+ AcpiOsPrintf ("%-28s: % 7ld\n",
+ AcpiUtGetMutexName (i), AcpiGbl_MutexInfo[i].UseCount);
+ }
+ break;
+
+
+ case CMD_STAT_SIZES:
+
+ AcpiOsPrintf ("\nInternal object sizes:\n\n");
+
+ AcpiOsPrintf ("Common %3d\n", sizeof (ACPI_OBJECT_COMMON));
+ AcpiOsPrintf ("Number %3d\n", sizeof (ACPI_OBJECT_INTEGER));
+ AcpiOsPrintf ("String %3d\n", sizeof (ACPI_OBJECT_STRING));
+ AcpiOsPrintf ("Buffer %3d\n", sizeof (ACPI_OBJECT_BUFFER));
+ AcpiOsPrintf ("Package %3d\n", sizeof (ACPI_OBJECT_PACKAGE));
+ AcpiOsPrintf ("BufferField %3d\n", sizeof (ACPI_OBJECT_BUFFER_FIELD));
+ AcpiOsPrintf ("Device %3d\n", sizeof (ACPI_OBJECT_DEVICE));
+ AcpiOsPrintf ("Event %3d\n", sizeof (ACPI_OBJECT_EVENT));
+ AcpiOsPrintf ("Method %3d\n", sizeof (ACPI_OBJECT_METHOD));
+ AcpiOsPrintf ("Mutex %3d\n", sizeof (ACPI_OBJECT_MUTEX));
+ AcpiOsPrintf ("Region %3d\n", sizeof (ACPI_OBJECT_REGION));
+ AcpiOsPrintf ("PowerResource %3d\n", sizeof (ACPI_OBJECT_POWER_RESOURCE));
+ AcpiOsPrintf ("Processor %3d\n", sizeof (ACPI_OBJECT_PROCESSOR));
+ AcpiOsPrintf ("ThermalZone %3d\n", sizeof (ACPI_OBJECT_THERMAL_ZONE));
+ AcpiOsPrintf ("RegionField %3d\n", sizeof (ACPI_OBJECT_REGION_FIELD));
+ AcpiOsPrintf ("BankField %3d\n", sizeof (ACPI_OBJECT_BANK_FIELD));
+ AcpiOsPrintf ("IndexField %3d\n", sizeof (ACPI_OBJECT_INDEX_FIELD));
+ AcpiOsPrintf ("Reference %3d\n", sizeof (ACPI_OBJECT_REFERENCE));
+ AcpiOsPrintf ("Notify %3d\n", sizeof (ACPI_OBJECT_NOTIFY_HANDLER));
+ AcpiOsPrintf ("AddressSpace %3d\n", sizeof (ACPI_OBJECT_ADDR_HANDLER));
+ AcpiOsPrintf ("Extra %3d\n", sizeof (ACPI_OBJECT_EXTRA));
+ AcpiOsPrintf ("Data %3d\n", sizeof (ACPI_OBJECT_DATA));
+
+ AcpiOsPrintf ("\n");
+
+ AcpiOsPrintf ("ParseObject %3d\n", sizeof (ACPI_PARSE_OBJ_COMMON));
+ AcpiOsPrintf ("ParseObjectNamed %3d\n", sizeof (ACPI_PARSE_OBJ_NAMED));
+ AcpiOsPrintf ("ParseObjectAsl %3d\n", sizeof (ACPI_PARSE_OBJ_ASL));
+ AcpiOsPrintf ("OperandObject %3d\n", sizeof (ACPI_OPERAND_OBJECT));
+ AcpiOsPrintf ("NamespaceNode %3d\n", sizeof (ACPI_NAMESPACE_NODE));
+ AcpiOsPrintf ("AcpiObject %3d\n", sizeof (ACPI_OBJECT));
+
+ break;
+
+
+ case CMD_STAT_STACK:
+#if defined(ACPI_DEBUG_OUTPUT)
+
+ Temp = (UINT32) ACPI_PTR_DIFF (AcpiGbl_EntryStackPointer, AcpiGbl_LowestStackPointer);
+
+ AcpiOsPrintf ("\nSubsystem Stack Usage:\n\n");
+ AcpiOsPrintf ("Entry Stack Pointer %p\n", AcpiGbl_EntryStackPointer);
+ AcpiOsPrintf ("Lowest Stack Pointer %p\n", AcpiGbl_LowestStackPointer);
+ AcpiOsPrintf ("Stack Use %X (%u)\n", Temp, Temp);
+ AcpiOsPrintf ("Deepest Procedure Nesting %u\n", AcpiGbl_DeepestNesting);
+#endif
+ break;
+
+ default:
+ break;
+ }
+
+ AcpiOsPrintf ("\n");
+ return (AE_OK);
+}
+
+#endif /* ACPI_DEBUGGER */
diff --git a/source/components/debugger/dbutils.c b/source/components/debugger/dbutils.c
new file mode 100644
index 000000000000..c44ff2efa906
--- /dev/null
+++ b/source/components/debugger/dbutils.c
@@ -0,0 +1,526 @@
+/*******************************************************************************
+ *
+ * Module Name: dbutils - AML debugger utilities
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2012, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include "acpi.h"
+#include "accommon.h"
+#include "acnamesp.h"
+#include "acdebug.h"
+#include "acdisasm.h"
+
+
+#ifdef ACPI_DEBUGGER
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("dbutils")
+
+/* Local prototypes */
+
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+ACPI_STATUS
+AcpiDbSecondPassParse (
+ ACPI_PARSE_OBJECT *Root);
+
+void
+AcpiDbDumpBuffer (
+ UINT32 Address);
+#endif
+
+static char *Converter = "0123456789ABCDEF";
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbMatchArgument
+ *
+ * PARAMETERS: UserArgument - User command line
+ * Arguments - Array of commands to match against
+ *
+ * RETURN: Index into command array or ACPI_TYPE_NOT_FOUND if not found
+ *
+ * DESCRIPTION: Search command array for a command match
+ *
+ ******************************************************************************/
+
+ACPI_OBJECT_TYPE
+AcpiDbMatchArgument (
+ char *UserArgument,
+ ARGUMENT_INFO *Arguments)
+{
+ UINT32 i;
+
+
+ if (!UserArgument || UserArgument[0] == 0)
+ {
+ return (ACPI_TYPE_NOT_FOUND);
+ }
+
+ for (i = 0; Arguments[i].Name; i++)
+ {
+ if (ACPI_STRSTR (Arguments[i].Name, UserArgument) == Arguments[i].Name)
+ {
+ return (i);
+ }
+ }
+
+ /* Argument not recognized */
+
+ return (ACPI_TYPE_NOT_FOUND);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbSetOutputDestination
+ *
+ * PARAMETERS: OutputFlags - Current flags word
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Set the current destination for debugger output. Also sets
+ * the debug output level accordingly.
+ *
+ ******************************************************************************/
+
+void
+AcpiDbSetOutputDestination (
+ UINT32 OutputFlags)
+{
+
+ AcpiGbl_DbOutputFlags = (UINT8) OutputFlags;
+
+ if ((OutputFlags & ACPI_DB_REDIRECTABLE_OUTPUT) && AcpiGbl_DbOutputToFile)
+ {
+ AcpiDbgLevel = AcpiGbl_DbDebugLevel;
+ }
+ else
+ {
+ AcpiDbgLevel = AcpiGbl_DbConsoleDebugLevel;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDumpExternalObject
+ *
+ * PARAMETERS: ObjDesc - External ACPI object to dump
+ * Level - Nesting level.
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump the contents of an ACPI external object
+ *
+ ******************************************************************************/
+
+void
+AcpiDbDumpExternalObject (
+ ACPI_OBJECT *ObjDesc,
+ UINT32 Level)
+{
+ UINT32 i;
+
+
+ if (!ObjDesc)
+ {
+ AcpiOsPrintf ("[Null Object]\n");
+ return;
+ }
+
+ for (i = 0; i < Level; i++)
+ {
+ AcpiOsPrintf (" ");
+ }
+
+ switch (ObjDesc->Type)
+ {
+ case ACPI_TYPE_ANY:
+
+ AcpiOsPrintf ("[Null Object] (Type=0)\n");
+ break;
+
+
+ case ACPI_TYPE_INTEGER:
+
+ AcpiOsPrintf ("[Integer] = %8.8X%8.8X\n",
+ ACPI_FORMAT_UINT64 (ObjDesc->Integer.Value));
+ break;
+
+
+ case ACPI_TYPE_STRING:
+
+ AcpiOsPrintf ("[String] Length %.2X = ", ObjDesc->String.Length);
+ for (i = 0; i < ObjDesc->String.Length; i++)
+ {
+ AcpiOsPrintf ("%c", ObjDesc->String.Pointer[i]);
+ }
+ AcpiOsPrintf ("\n");
+ break;
+
+
+ case ACPI_TYPE_BUFFER:
+
+ AcpiOsPrintf ("[Buffer] Length %.2X = ", ObjDesc->Buffer.Length);
+ if (ObjDesc->Buffer.Length)
+ {
+ if (ObjDesc->Buffer.Length > 16)
+ {
+ AcpiOsPrintf ("\n");
+ }
+ AcpiUtDumpBuffer (ACPI_CAST_PTR (UINT8, ObjDesc->Buffer.Pointer),
+ ObjDesc->Buffer.Length, DB_BYTE_DISPLAY, _COMPONENT);
+ }
+ else
+ {
+ AcpiOsPrintf ("\n");
+ }
+ break;
+
+
+ case ACPI_TYPE_PACKAGE:
+
+ AcpiOsPrintf ("[Package] Contains %u Elements:\n",
+ ObjDesc->Package.Count);
+
+ for (i = 0; i < ObjDesc->Package.Count; i++)
+ {
+ AcpiDbDumpExternalObject (&ObjDesc->Package.Elements[i], Level+1);
+ }
+ break;
+
+
+ case ACPI_TYPE_LOCAL_REFERENCE:
+
+ AcpiOsPrintf ("[Object Reference] = ");
+ AcpiDmDisplayInternalObject (ObjDesc->Reference.Handle, NULL);
+ break;
+
+
+ case ACPI_TYPE_PROCESSOR:
+
+ AcpiOsPrintf ("[Processor]\n");
+ break;
+
+
+ case ACPI_TYPE_POWER:
+
+ AcpiOsPrintf ("[Power Resource]\n");
+ break;
+
+
+ default:
+
+ AcpiOsPrintf ("[Unknown Type] %X\n", ObjDesc->Type);
+ break;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbPrepNamestring
+ *
+ * PARAMETERS: Name - String to prepare
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Translate all forward slashes and dots to backslashes.
+ *
+ ******************************************************************************/
+
+void
+AcpiDbPrepNamestring (
+ char *Name)
+{
+
+ if (!Name)
+ {
+ return;
+ }
+
+ AcpiUtStrupr (Name);
+
+ /* Convert a leading forward slash to a backslash */
+
+ if (*Name == '/')
+ {
+ *Name = '\\';
+ }
+
+ /* Ignore a leading backslash, this is the root prefix */
+
+ if (*Name == '\\')
+ {
+ Name++;
+ }
+
+ /* Convert all slash path separators to dots */
+
+ while (*Name)
+ {
+ if ((*Name == '/') ||
+ (*Name == '\\'))
+ {
+ *Name = '.';
+ }
+
+ Name++;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbLocalNsLookup
+ *
+ * PARAMETERS: Name - Name to lookup
+ *
+ * RETURN: Pointer to a namespace node, null on failure
+ *
+ * DESCRIPTION: Lookup a name in the ACPI namespace
+ *
+ * Note: Currently begins search from the root. Could be enhanced to use
+ * the current prefix (scope) node as the search beginning point.
+ *
+ ******************************************************************************/
+
+ACPI_NAMESPACE_NODE *
+AcpiDbLocalNsLookup (
+ char *Name)
+{
+ char *InternalPath;
+ ACPI_STATUS Status;
+ ACPI_NAMESPACE_NODE *Node = NULL;
+
+
+ AcpiDbPrepNamestring (Name);
+
+ /* Build an internal namestring */
+
+ Status = AcpiNsInternalizeName (Name, &InternalPath);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Invalid namestring: %s\n", Name);
+ return (NULL);
+ }
+
+ /*
+ * Lookup the name.
+ * (Uses root node as the search starting point)
+ */
+ Status = AcpiNsLookup (NULL, InternalPath, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
+ ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE, NULL, &Node);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Could not locate name: %s, %s\n",
+ Name, AcpiFormatException (Status));
+ }
+
+ ACPI_FREE (InternalPath);
+ return (Node);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbUInt32ToHexString
+ *
+ * PARAMETERS: Value - The value to be converted to string
+ * Buffer - Buffer for result (not less than 11 bytes)
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Convert the unsigned 32-bit value to the hexadecimal image
+ *
+ * NOTE: It is the caller's responsibility to ensure that the length of buffer
+ * is sufficient.
+ *
+ ******************************************************************************/
+
+void
+AcpiDbUInt32ToHexString (
+ UINT32 Value,
+ char *Buffer)
+{
+ int i;
+
+
+ if (Value == 0)
+ {
+ ACPI_STRCPY (Buffer, "0");
+ return;
+ }
+
+ Buffer[8] = '\0';
+
+ for (i = 7; i >= 0; i--)
+ {
+ Buffer[i] = Converter [Value & 0x0F];
+ Value = Value >> 4;
+ }
+}
+
+
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbSecondPassParse
+ *
+ * PARAMETERS: Root - Root of the parse tree
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Second pass parse of the ACPI tables. We need to wait until
+ * second pass to parse the control methods
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDbSecondPassParse (
+ ACPI_PARSE_OBJECT *Root)
+{
+ ACPI_PARSE_OBJECT *Op = Root;
+ ACPI_PARSE_OBJECT *Method;
+ ACPI_PARSE_OBJECT *SearchOp;
+ ACPI_PARSE_OBJECT *StartOp;
+ ACPI_STATUS Status = AE_OK;
+ UINT32 BaseAmlOffset;
+ ACPI_WALK_STATE *WalkState;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ AcpiOsPrintf ("Pass two parse ....\n");
+
+ while (Op)
+ {
+ if (Op->Common.AmlOpcode == AML_METHOD_OP)
+ {
+ Method = Op;
+
+ /* Create a new walk state for the parse */
+
+ WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
+ if (!WalkState)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ /* Init the Walk State */
+
+ WalkState->ParserState.Aml =
+ WalkState->ParserState.AmlStart = Method->Named.Data;
+ WalkState->ParserState.AmlEnd =
+ WalkState->ParserState.PkgEnd = Method->Named.Data +
+ Method->Named.Length;
+ WalkState->ParserState.StartScope = Op;
+
+ WalkState->DescendingCallback = AcpiDsLoad1BeginOp;
+ WalkState->AscendingCallback = AcpiDsLoad1EndOp;
+
+ /* Perform the AML parse */
+
+ Status = AcpiPsParseAml (WalkState);
+
+ BaseAmlOffset = (Method->Common.Value.Arg)->Common.AmlOffset + 1;
+ StartOp = (Method->Common.Value.Arg)->Common.Next;
+ SearchOp = StartOp;
+
+ while (SearchOp)
+ {
+ SearchOp->Common.AmlOffset += BaseAmlOffset;
+ SearchOp = AcpiPsGetDepthNext (StartOp, SearchOp);
+ }
+ }
+
+ if (Op->Common.AmlOpcode == AML_REGION_OP)
+ {
+ /* TBD: [Investigate] this isn't quite the right thing to do! */
+ /*
+ *
+ * Method = (ACPI_DEFERRED_OP *) Op;
+ * Status = AcpiPsParseAml (Op, Method->Body, Method->BodyLength);
+ */
+ }
+
+ if (ACPI_FAILURE (Status))
+ {
+ break;
+ }
+
+ Op = AcpiPsGetDepthNext (Root, Op);
+ }
+
+ return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbDumpBuffer
+ *
+ * PARAMETERS: Address - Pointer to the buffer
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Print a portion of a buffer
+ *
+ ******************************************************************************/
+
+void
+AcpiDbDumpBuffer (
+ UINT32 Address)
+{
+
+ AcpiOsPrintf ("\nLocation %X:\n", Address);
+
+ AcpiDbgLevel |= ACPI_LV_TABLES;
+ AcpiUtDumpBuffer (ACPI_TO_POINTER (Address), 64, DB_BYTE_DISPLAY,
+ ACPI_UINT32_MAX);
+}
+#endif
+
+#endif /* ACPI_DEBUGGER */
+
+
diff --git a/source/components/debugger/dbxface.c b/source/components/debugger/dbxface.c
new file mode 100644
index 000000000000..cd3027343459
--- /dev/null
+++ b/source/components/debugger/dbxface.c
@@ -0,0 +1,536 @@
+/*******************************************************************************
+ *
+ * Module Name: dbxface - AML Debugger external interfaces
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2012, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include "acpi.h"
+#include "accommon.h"
+#include "amlcode.h"
+#include "acdebug.h"
+#include "acdisasm.h"
+
+
+#ifdef ACPI_DEBUGGER
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("dbxface")
+
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiDbStartCommand (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op);
+
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+void
+AcpiDbMethodEnd (
+ ACPI_WALK_STATE *WalkState);
+#endif
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbStartCommand
+ *
+ * PARAMETERS: WalkState - Current walk
+ * Op - Current executing Op, from AML interpreter
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Enter debugger command loop
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDbStartCommand (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_STATUS Status;
+
+
+ /* TBD: [Investigate] are there namespace locking issues here? */
+
+ /* AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); */
+
+ /* Go into the command loop and await next user command */
+
+
+ AcpiGbl_MethodExecuting = TRUE;
+ Status = AE_CTRL_TRUE;
+ while (Status == AE_CTRL_TRUE)
+ {
+ if (AcpiGbl_DebuggerConfiguration == DEBUGGER_MULTI_THREADED)
+ {
+ /* Handshake with the front-end that gets user command lines */
+
+ Status = AcpiUtReleaseMutex (ACPI_MTX_DEBUG_CMD_COMPLETE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ Status = AcpiUtAcquireMutex (ACPI_MTX_DEBUG_CMD_READY);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ }
+ else
+ {
+ /* Single threaded, we must get a command line ourselves */
+
+ /* Force output to console until a command is entered */
+
+ AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
+
+ /* Different prompt if method is executing */
+
+ if (!AcpiGbl_MethodExecuting)
+ {
+ AcpiOsPrintf ("%1c ", ACPI_DEBUGGER_COMMAND_PROMPT);
+ }
+ else
+ {
+ AcpiOsPrintf ("%1c ", ACPI_DEBUGGER_EXECUTE_PROMPT);
+ }
+
+ /* Get the user input line */
+
+ Status = AcpiOsGetLine (AcpiGbl_DbLineBuf,
+ ACPI_DB_LINE_BUFFER_SIZE, NULL);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status, "While parsing command line"));
+ return (Status);
+ }
+ }
+
+ Status = AcpiDbCommandDispatch (AcpiGbl_DbLineBuf, WalkState, Op);
+ }
+
+ /* AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); */
+
+ return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbSingleStep
+ *
+ * PARAMETERS: WalkState - Current walk
+ * Op - Current executing op (from aml interpreter)
+ * OpcodeClass - Class of the current AML Opcode
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Called just before execution of an AML opcode.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDbSingleStep (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 OpcodeClass)
+{
+ ACPI_PARSE_OBJECT *Next;
+ ACPI_STATUS Status = AE_OK;
+ UINT32 OriginalDebugLevel;
+ ACPI_PARSE_OBJECT *DisplayOp;
+ ACPI_PARSE_OBJECT *ParentOp;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /* Check the abort flag */
+
+ if (AcpiGbl_AbortMethod)
+ {
+ AcpiGbl_AbortMethod = FALSE;
+ return (AE_ABORT_METHOD);
+ }
+
+ /* Check for single-step breakpoint */
+
+ if (WalkState->MethodBreakpoint &&
+ (WalkState->MethodBreakpoint <= Op->Common.AmlOffset))
+ {
+ /* Check if the breakpoint has been reached or passed */
+ /* Hit the breakpoint, resume single step, reset breakpoint */
+
+ AcpiOsPrintf ("***Break*** at AML offset %X\n", Op->Common.AmlOffset);
+ AcpiGbl_CmSingleStep = TRUE;
+ AcpiGbl_StepToNextCall = FALSE;
+ WalkState->MethodBreakpoint = 0;
+ }
+
+ /* Check for user breakpoint (Must be on exact Aml offset) */
+
+ else if (WalkState->UserBreakpoint &&
+ (WalkState->UserBreakpoint == Op->Common.AmlOffset))
+ {
+ AcpiOsPrintf ("***UserBreakpoint*** at AML offset %X\n",
+ Op->Common.AmlOffset);
+ AcpiGbl_CmSingleStep = TRUE;
+ AcpiGbl_StepToNextCall = FALSE;
+ WalkState->MethodBreakpoint = 0;
+ }
+
+ /*
+ * Check if this is an opcode that we are interested in --
+ * namely, opcodes that have arguments
+ */
+ if (Op->Common.AmlOpcode == AML_INT_NAMEDFIELD_OP)
+ {
+ return (AE_OK);
+ }
+
+ switch (OpcodeClass)
+ {
+ case AML_CLASS_UNKNOWN:
+ case AML_CLASS_ARGUMENT: /* constants, literals, etc. do nothing */
+ return (AE_OK);
+
+ default:
+ /* All other opcodes -- continue */
+ break;
+ }
+
+ /*
+ * Under certain debug conditions, display this opcode and its operands
+ */
+ if ((AcpiGbl_DbOutputToFile) ||
+ (AcpiGbl_CmSingleStep) ||
+ (AcpiDbgLevel & ACPI_LV_PARSE))
+ {
+ if ((AcpiGbl_DbOutputToFile) ||
+ (AcpiDbgLevel & ACPI_LV_PARSE))
+ {
+ AcpiOsPrintf ("\n[AmlDebug] Next AML Opcode to execute:\n");
+ }
+
+ /*
+ * Display this op (and only this op - zero out the NEXT field
+ * temporarily, and disable parser trace output for the duration of
+ * the display because we don't want the extraneous debug output)
+ */
+ OriginalDebugLevel = AcpiDbgLevel;
+ AcpiDbgLevel &= ~(ACPI_LV_PARSE | ACPI_LV_FUNCTIONS);
+ Next = Op->Common.Next;
+ Op->Common.Next = NULL;
+
+
+ DisplayOp = Op;
+ ParentOp = Op->Common.Parent;
+ if (ParentOp)
+ {
+ if ((WalkState->ControlState) &&
+ (WalkState->ControlState->Common.State ==
+ ACPI_CONTROL_PREDICATE_EXECUTING))
+ {
+ /*
+ * We are executing the predicate of an IF or WHILE statement
+ * Search upwards for the containing IF or WHILE so that the
+ * entire predicate can be displayed.
+ */
+ while (ParentOp)
+ {
+ if ((ParentOp->Common.AmlOpcode == AML_IF_OP) ||
+ (ParentOp->Common.AmlOpcode == AML_WHILE_OP))
+ {
+ DisplayOp = ParentOp;
+ break;
+ }
+ ParentOp = ParentOp->Common.Parent;
+ }
+ }
+ else
+ {
+ while (ParentOp)
+ {
+ if ((ParentOp->Common.AmlOpcode == AML_IF_OP) ||
+ (ParentOp->Common.AmlOpcode == AML_ELSE_OP) ||
+ (ParentOp->Common.AmlOpcode == AML_SCOPE_OP) ||
+ (ParentOp->Common.AmlOpcode == AML_METHOD_OP) ||
+ (ParentOp->Common.AmlOpcode == AML_WHILE_OP))
+ {
+ break;
+ }
+ DisplayOp = ParentOp;
+ ParentOp = ParentOp->Common.Parent;
+ }
+ }
+ }
+
+ /* Now we can display it */
+
+ AcpiDmDisassemble (WalkState, DisplayOp, ACPI_UINT32_MAX);
+
+ if ((Op->Common.AmlOpcode == AML_IF_OP) ||
+ (Op->Common.AmlOpcode == AML_WHILE_OP))
+ {
+ if (WalkState->ControlState->Common.Value)
+ {
+ AcpiOsPrintf ("Predicate = [True], IF block was executed\n");
+ }
+ else
+ {
+ AcpiOsPrintf ("Predicate = [False], Skipping IF block\n");
+ }
+ }
+ else if (Op->Common.AmlOpcode == AML_ELSE_OP)
+ {
+ AcpiOsPrintf ("Predicate = [False], ELSE block was executed\n");
+ }
+
+ /* Restore everything */
+
+ Op->Common.Next = Next;
+ AcpiOsPrintf ("\n");
+ if ((AcpiGbl_DbOutputToFile) ||
+ (AcpiDbgLevel & ACPI_LV_PARSE))
+ {
+ AcpiOsPrintf ("\n");
+ }
+ AcpiDbgLevel = OriginalDebugLevel;
+ }
+
+ /* If we are not single stepping, just continue executing the method */
+
+ if (!AcpiGbl_CmSingleStep)
+ {
+ return (AE_OK);
+ }
+
+ /*
+ * If we are executing a step-to-call command,
+ * Check if this is a method call.
+ */
+ if (AcpiGbl_StepToNextCall)
+ {
+ if (Op->Common.AmlOpcode != AML_INT_METHODCALL_OP)
+ {
+ /* Not a method call, just keep executing */
+
+ return (AE_OK);
+ }
+
+ /* Found a method call, stop executing */
+
+ AcpiGbl_StepToNextCall = FALSE;
+ }
+
+ /*
+ * If the next opcode is a method call, we will "step over" it
+ * by default.
+ */
+ if (Op->Common.AmlOpcode == AML_INT_METHODCALL_OP)
+ {
+ /* Force no more single stepping while executing called method */
+
+ AcpiGbl_CmSingleStep = FALSE;
+
+ /*
+ * Set the breakpoint on/before the call, it will stop execution
+ * as soon as we return
+ */
+ WalkState->MethodBreakpoint = 1; /* Must be non-zero! */
+ }
+
+
+ Status = AcpiDbStartCommand (WalkState, Op);
+
+ /* User commands complete, continue execution of the interrupted method */
+
+ return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbInitialize
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Init and start debugger
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDbInitialize (
+ void)
+{
+ ACPI_STATUS Status;
+
+
+ /* Init globals */
+
+ AcpiGbl_DbBuffer = NULL;
+ AcpiGbl_DbFilename = NULL;
+ AcpiGbl_DbOutputToFile = FALSE;
+
+ AcpiGbl_DbDebugLevel = ACPI_LV_VERBOSITY2;
+ AcpiGbl_DbConsoleDebugLevel = ACPI_NORMAL_DEFAULT | ACPI_LV_TABLES;
+ AcpiGbl_DbOutputFlags = ACPI_DB_CONSOLE_OUTPUT;
+
+ AcpiGbl_DbOpt_tables = FALSE;
+ AcpiGbl_DbOpt_disasm = FALSE;
+ AcpiGbl_DbOpt_stats = FALSE;
+ AcpiGbl_DbOpt_verbose = TRUE;
+ AcpiGbl_DbOpt_ini_methods = TRUE;
+
+ AcpiGbl_DbBuffer = AcpiOsAllocate (ACPI_DEBUG_BUFFER_SIZE);
+ if (!AcpiGbl_DbBuffer)
+ {
+ return (AE_NO_MEMORY);
+ }
+ ACPI_MEMSET (AcpiGbl_DbBuffer, 0, ACPI_DEBUG_BUFFER_SIZE);
+
+ /* Initial scope is the root */
+
+ AcpiGbl_DbScopeBuf [0] = '\\';
+ AcpiGbl_DbScopeBuf [1] = 0;
+ AcpiGbl_DbScopeNode = AcpiGbl_RootNode;
+
+ /*
+ * If configured for multi-thread support, the debug executor runs in
+ * a separate thread so that the front end can be in another address
+ * space, environment, or even another machine.
+ */
+ if (AcpiGbl_DebuggerConfiguration & DEBUGGER_MULTI_THREADED)
+ {
+ /* These were created with one unit, grab it */
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_DEBUG_CMD_COMPLETE);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Could not get debugger mutex\n");
+ return (Status);
+ }
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_DEBUG_CMD_READY);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Could not get debugger mutex\n");
+ return (Status);
+ }
+
+ /* Create the debug execution thread to execute commands */
+
+ Status = AcpiOsExecute (OSL_DEBUGGER_THREAD, AcpiDbExecuteThread, NULL);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("Could not start debugger thread\n");
+ return (Status);
+ }
+ }
+
+ if (!AcpiGbl_DbOpt_verbose)
+ {
+ AcpiGbl_DbOpt_disasm = TRUE;
+ AcpiGbl_DbOpt_stats = FALSE;
+ }
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbTerminate
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Stop debugger
+ *
+ ******************************************************************************/
+
+void
+AcpiDbTerminate (
+ void)
+{
+
+ if (AcpiGbl_DbBuffer)
+ {
+ AcpiOsFree (AcpiGbl_DbBuffer);
+ }
+}
+
+
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDbMethodEnd
+ *
+ * PARAMETERS: WalkState - Current walk
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Called at method termination
+ *
+ ******************************************************************************/
+
+void
+AcpiDbMethodEnd (
+ ACPI_WALK_STATE *WalkState)
+{
+
+ if (!AcpiGbl_CmSingleStep)
+ {
+ return;
+ }
+
+ AcpiOsPrintf ("<Method Terminating>\n");
+
+ AcpiDbStartCommand (WalkState, NULL);
+}
+#endif
+
+#endif /* ACPI_DEBUGGER */
diff --git a/source/components/disassembler/dmbuffer.c b/source/components/disassembler/dmbuffer.c
new file mode 100644
index 000000000000..9f49f92e4743
--- /dev/null
+++ b/source/components/disassembler/dmbuffer.c
@@ -0,0 +1,542 @@
+/*******************************************************************************
+ *
+ * Module Name: dmbuffer - AML disassembler, buffer and string support
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2012, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include "acpi.h"
+#include "accommon.h"
+#include "acdisasm.h"
+#include "acparser.h"
+#include "amlcode.h"
+
+
+#ifdef ACPI_DISASSEMBLER
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("dmbuffer")
+
+/* Local prototypes */
+
+static void
+AcpiDmUnicode (
+ ACPI_PARSE_OBJECT *Op);
+
+static void
+AcpiDmIsEisaIdElement (
+ ACPI_PARSE_OBJECT *Op);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDisasmByteList
+ *
+ * PARAMETERS: Level - Current source code indentation level
+ * ByteData - Pointer to the byte list
+ * ByteCount - Length of the byte list
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump an AML "ByteList" in Hex format. 8 bytes per line, prefixed
+ * with the hex buffer offset.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDisasmByteList (
+ UINT32 Level,
+ UINT8 *ByteData,
+ UINT32 ByteCount)
+{
+ UINT32 i;
+
+
+ if (!ByteCount)
+ {
+ return;
+ }
+
+ /* Dump the byte list */
+
+ for (i = 0; i < ByteCount; i++)
+ {
+ /* New line every 8 bytes */
+
+ if (((i % 8) == 0) && (i < ByteCount))
+ {
+ if (i > 0)
+ {
+ AcpiOsPrintf ("\n");
+ }
+
+ AcpiDmIndent (Level);
+ if (ByteCount > 8)
+ {
+ AcpiOsPrintf ("/* %04X */ ", i);
+ }
+ }
+
+ AcpiOsPrintf (" 0x%2.2X", (UINT32) ByteData[i]);
+
+ /* Add comma if there are more bytes to display */
+
+ if (i < (ByteCount -1))
+ {
+ AcpiOsPrintf (",");
+ }
+ }
+
+ if (Level)
+ {
+ AcpiOsPrintf ("\n");
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmByteList
+ *
+ * PARAMETERS: Info - Parse tree walk info
+ * Op - Byte list op
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump a buffer byte list, handling the various types of buffers.
+ * Buffer type must be already set in the Op DisasmOpcode.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmByteList (
+ ACPI_OP_WALK_INFO *Info,
+ ACPI_PARSE_OBJECT *Op)
+{
+ UINT8 *ByteData;
+ UINT32 ByteCount;
+
+
+ ByteData = Op->Named.Data;
+ ByteCount = (UINT32) Op->Common.Value.Integer;
+
+ /*
+ * The byte list belongs to a buffer, and can be produced by either
+ * a ResourceTemplate, Unicode, quoted string, or a plain byte list.
+ */
+ switch (Op->Common.Parent->Common.DisasmOpcode)
+ {
+ case ACPI_DASM_RESOURCE:
+
+ AcpiDmResourceTemplate (Info, Op->Common.Parent, ByteData, ByteCount);
+ break;
+
+ case ACPI_DASM_STRING:
+
+ AcpiDmIndent (Info->Level);
+ AcpiUtPrintString ((char *) ByteData, ACPI_UINT8_MAX);
+ AcpiOsPrintf ("\n");
+ break;
+
+ case ACPI_DASM_UNICODE:
+
+ AcpiDmUnicode (Op);
+ break;
+
+ case ACPI_DASM_BUFFER:
+ default:
+
+ /*
+ * Not a resource, string, or unicode string.
+ * Just dump the buffer
+ */
+ AcpiDmDisasmByteList (Info->Level, ByteData, ByteCount);
+ break;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmIsUnicodeBuffer
+ *
+ * PARAMETERS: Op - Buffer Object to be examined
+ *
+ * RETURN: TRUE if buffer contains a UNICODE string
+ *
+ * DESCRIPTION: Determine if a buffer Op contains a Unicode string
+ *
+ ******************************************************************************/
+
+BOOLEAN
+AcpiDmIsUnicodeBuffer (
+ ACPI_PARSE_OBJECT *Op)
+{
+ UINT8 *ByteData;
+ UINT32 ByteCount;
+ UINT32 WordCount;
+ ACPI_PARSE_OBJECT *SizeOp;
+ ACPI_PARSE_OBJECT *NextOp;
+ UINT32 i;
+
+
+ /* Buffer size is the buffer argument */
+
+ SizeOp = Op->Common.Value.Arg;
+
+ /* Next, the initializer byte list to examine */
+
+ NextOp = SizeOp->Common.Next;
+ if (!NextOp)
+ {
+ return (FALSE);
+ }
+
+ /* Extract the byte list info */
+
+ ByteData = NextOp->Named.Data;
+ ByteCount = (UINT32) NextOp->Common.Value.Integer;
+ WordCount = ACPI_DIV_2 (ByteCount);
+
+ /*
+ * Unicode string must have an even number of bytes and last
+ * word must be zero
+ */
+ if ((!ByteCount) ||
+ (ByteCount < 4) ||
+ (ByteCount & 1) ||
+ ((UINT16 *) (void *) ByteData)[WordCount - 1] != 0)
+ {
+ return (FALSE);
+ }
+
+ /* For each word, 1st byte must be ascii, 2nd byte must be zero */
+
+ for (i = 0; i < (ByteCount - 2); i += 2)
+ {
+ if ((!ACPI_IS_PRINT (ByteData[i])) ||
+ (ByteData[(ACPI_SIZE) i + 1] != 0))
+ {
+ return (FALSE);
+ }
+ }
+
+ /* Ignore the Size argument in the disassembly of this buffer op */
+
+ SizeOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
+ return (TRUE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmIsStringBuffer
+ *
+ * PARAMETERS: Op - Buffer Object to be examined
+ *
+ * RETURN: TRUE if buffer contains a ASCII string, FALSE otherwise
+ *
+ * DESCRIPTION: Determine if a buffer Op contains a ASCII string
+ *
+ ******************************************************************************/
+
+BOOLEAN
+AcpiDmIsStringBuffer (
+ ACPI_PARSE_OBJECT *Op)
+{
+ UINT8 *ByteData;
+ UINT32 ByteCount;
+ ACPI_PARSE_OBJECT *SizeOp;
+ ACPI_PARSE_OBJECT *NextOp;
+ UINT32 i;
+
+
+ /* Buffer size is the buffer argument */
+
+ SizeOp = Op->Common.Value.Arg;
+
+ /* Next, the initializer byte list to examine */
+
+ NextOp = SizeOp->Common.Next;
+ if (!NextOp)
+ {
+ return (FALSE);
+ }
+
+ /* Extract the byte list info */
+
+ ByteData = NextOp->Named.Data;
+ ByteCount = (UINT32) NextOp->Common.Value.Integer;
+
+ /* Last byte must be the null terminator */
+
+ if ((!ByteCount) ||
+ (ByteCount < 2) ||
+ (ByteData[ByteCount-1] != 0))
+ {
+ return (FALSE);
+ }
+
+ for (i = 0; i < (ByteCount - 1); i++)
+ {
+ /* TBD: allow some escapes (non-ascii chars).
+ * they will be handled in the string output routine
+ */
+
+ if (!ACPI_IS_PRINT (ByteData[i]))
+ {
+ return (FALSE);
+ }
+ }
+
+ return (TRUE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmUnicode
+ *
+ * PARAMETERS: Op - Byte List op containing Unicode string
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump Unicode string as a standard ASCII string. (Remove
+ * the extra zero bytes).
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmUnicode (
+ ACPI_PARSE_OBJECT *Op)
+{
+ UINT16 *WordData;
+ UINT32 WordCount;
+ UINT32 i;
+
+
+ /* Extract the buffer info as a WORD buffer */
+
+ WordData = ACPI_CAST_PTR (UINT16, Op->Named.Data);
+ WordCount = ACPI_DIV_2 (((UINT32) Op->Common.Value.Integer));
+
+
+ AcpiOsPrintf ("\"");
+
+ /* Write every other byte as an ASCII character */
+
+ for (i = 0; i < (WordCount - 1); i++)
+ {
+ AcpiOsPrintf ("%c", (int) WordData[i]);
+ }
+
+ AcpiOsPrintf ("\")");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmIsEisaIdElement
+ *
+ * PARAMETERS: Op - Op to be examined
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Determine if an Op (argument to _HID or _CID) can be converted
+ * to an EISA ID.
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmIsEisaIdElement (
+ ACPI_PARSE_OBJECT *Op)
+{
+ UINT32 BigEndianId;
+ UINT32 Prefix[3];
+ UINT32 i;
+
+
+ /* The parameter must be either a word or a dword */
+
+ if ((Op->Common.AmlOpcode != AML_DWORD_OP) &&
+ (Op->Common.AmlOpcode != AML_WORD_OP))
+ {
+ return;
+ }
+
+ /* Swap from little-endian to big-endian to simplify conversion */
+
+ BigEndianId = AcpiUtDwordByteSwap ((UINT32) Op->Common.Value.Integer);
+
+ /* Create the 3 leading ASCII letters */
+
+ Prefix[0] = ((BigEndianId >> 26) & 0x1F) + 0x40;
+ Prefix[1] = ((BigEndianId >> 21) & 0x1F) + 0x40;
+ Prefix[2] = ((BigEndianId >> 16) & 0x1F) + 0x40;
+
+ /* Verify that all 3 are ascii and alpha */
+
+ for (i = 0; i < 3; i++)
+ {
+ if (!ACPI_IS_ASCII (Prefix[i]) ||
+ !ACPI_IS_ALPHA (Prefix[i]))
+ {
+ return;
+ }
+ }
+
+ /* OK - mark this node as convertable to an EISA ID */
+
+ Op->Common.DisasmOpcode = ACPI_DASM_EISAID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmIsEisaId
+ *
+ * PARAMETERS: Op - Op to be examined
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Determine if a Name() Op can be converted to an EisaId.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmIsEisaId (
+ ACPI_PARSE_OBJECT *Op)
+{
+ UINT32 Name;
+ ACPI_PARSE_OBJECT *NextOp;
+
+
+ /* Get the NameSegment */
+
+ Name = AcpiPsGetName (Op);
+ if (!Name)
+ {
+ return;
+ }
+
+ NextOp = AcpiPsGetDepthNext (NULL, Op);
+ if (!NextOp)
+ {
+ return;
+ }
+
+ /* Check for _HID - has one argument */
+
+ if (ACPI_COMPARE_NAME (&Name, METHOD_NAME__HID))
+ {
+ AcpiDmIsEisaIdElement (NextOp);
+ return;
+ }
+
+ /* Exit if not _CID */
+
+ if (!ACPI_COMPARE_NAME (&Name, METHOD_NAME__CID))
+ {
+ return;
+ }
+
+ /* _CID can contain a single argument or a package */
+
+ if (NextOp->Common.AmlOpcode != AML_PACKAGE_OP)
+ {
+ AcpiDmIsEisaIdElement (NextOp);
+ return;
+ }
+
+ /* _CID with Package: get the package length */
+
+ NextOp = AcpiPsGetDepthNext (NULL, NextOp);
+
+ /* Don't need to use the length, just walk the peer list */
+
+ NextOp = NextOp->Common.Next;
+ while (NextOp)
+ {
+ AcpiDmIsEisaIdElement (NextOp);
+ NextOp = NextOp->Common.Next;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmEisaId
+ *
+ * PARAMETERS: EncodedId - Raw encoded EISA ID.
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Convert an encoded EISAID back to the original ASCII String.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmEisaId (
+ UINT32 EncodedId)
+{
+ UINT32 BigEndianId;
+
+
+ /* Swap from little-endian to big-endian to simplify conversion */
+
+ BigEndianId = AcpiUtDwordByteSwap (EncodedId);
+
+
+ /* Split to form "AAANNNN" string */
+
+ AcpiOsPrintf ("EisaId (\"%c%c%c%4.4X\")",
+
+ /* Three Alpha characters (AAA), 5 bits each */
+
+ (int) ((BigEndianId >> 26) & 0x1F) + 0x40,
+ (int) ((BigEndianId >> 21) & 0x1F) + 0x40,
+ (int) ((BigEndianId >> 16) & 0x1F) + 0x40,
+
+ /* Numeric part (NNNN) is simply the lower 16 bits */
+
+ (UINT32) (BigEndianId & 0xFFFF));
+}
+
+#endif
diff --git a/source/components/disassembler/dmnames.c b/source/components/disassembler/dmnames.c
new file mode 100644
index 000000000000..92e67c2e0a8c
--- /dev/null
+++ b/source/components/disassembler/dmnames.c
@@ -0,0 +1,453 @@
+/*******************************************************************************
+ *
+ * Module Name: dmnames - AML disassembler, names, namestrings, pathnames
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2012, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include "acpi.h"
+#include "accommon.h"
+#include "acparser.h"
+#include "amlcode.h"
+#include "acnamesp.h"
+#include "acdisasm.h"
+
+
+#ifdef ACPI_DISASSEMBLER
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("dmnames")
+
+/* Local prototypes */
+
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+void
+AcpiDmDisplayPath (
+ ACPI_PARSE_OBJECT *Op);
+#endif
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDumpName
+ *
+ * PARAMETERS: Name - 4 character ACPI name
+ *
+ * RETURN: Final length of name
+ *
+ * DESCRIPTION: Dump an ACPI name, minus any trailing underscores.
+ *
+ ******************************************************************************/
+
+UINT32
+AcpiDmDumpName (
+ UINT32 Name)
+{
+ UINT32 i;
+ UINT32 Length;
+ char NewName[4];
+
+
+ /* Copy name locally in case the original name is not writeable */
+
+ *ACPI_CAST_PTR (UINT32, &NewName[0]) = Name;
+
+ /* Ensure that the name is printable, even if we have to fix it */
+
+ AcpiUtRepairName (NewName);
+
+ /* Remove all trailing underscores from the name */
+
+ Length = ACPI_NAME_SIZE;
+ for (i = (ACPI_NAME_SIZE - 1); i != 0; i--)
+ {
+ if (NewName[i] == '_')
+ {
+ Length--;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ /* Dump the name, up to the start of the trailing underscores */
+
+ for (i = 0; i < Length; i++)
+ {
+ AcpiOsPrintf ("%c", NewName[i]);
+ }
+
+ return (Length);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiPsDisplayObjectPathname
+ *
+ * PARAMETERS: WalkState - Current walk state
+ * Op - Object whose pathname is to be obtained
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Diplay the pathname associated with a named object. Two
+ * versions. One searches the parse tree (for parser-only
+ * applications suchas AcpiDump), and the other searches the
+ * ACPI namespace (the parse tree is probably deleted)
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiPsDisplayObjectPathname (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_STATUS Status;
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_BUFFER Buffer;
+ UINT32 DebugLevel;
+
+
+ /* Save current debug level so we don't get extraneous debug output */
+
+ DebugLevel = AcpiDbgLevel;
+ AcpiDbgLevel = 0;
+
+ /* Just get the Node out of the Op object */
+
+ Node = Op->Common.Node;
+ if (!Node)
+ {
+ /* Node not defined in this scope, look it up */
+
+ Status = AcpiNsLookup (WalkState->ScopeInfo, Op->Common.Value.String,
+ ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
+ WalkState, &(Node));
+
+ if (ACPI_FAILURE (Status))
+ {
+ /*
+ * We can't get the pathname since the object
+ * is not in the namespace. This can happen during single
+ * stepping where a dynamic named object is *about* to be created.
+ */
+ AcpiOsPrintf (" [Path not found]");
+ goto Exit;
+ }
+
+ /* Save it for next time. */
+
+ Op->Common.Node = Node;
+ }
+
+ /* Convert NamedDesc/handle to a full pathname */
+
+ Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
+ Status = AcpiNsHandleToPathname (Node, &Buffer);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("****Could not get pathname****)");
+ goto Exit;
+ }
+
+ AcpiOsPrintf (" (Path %s)", (char *) Buffer.Pointer);
+ ACPI_FREE (Buffer.Pointer);
+
+
+Exit:
+ /* Restore the debug level */
+
+ AcpiDbgLevel = DebugLevel;
+ return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmNamestring
+ *
+ * PARAMETERS: Name - ACPI Name string to store
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode and dump an ACPI namestring. Handles prefix characters
+ *
+ ******************************************************************************/
+
+void
+AcpiDmNamestring (
+ char *Name)
+{
+ UINT32 SegCount;
+
+
+ if (!Name)
+ {
+ return;
+ }
+
+ /* Handle all Scope Prefix operators */
+
+ while (AcpiPsIsPrefixChar (ACPI_GET8 (Name)))
+ {
+ /* Append prefix character */
+
+ AcpiOsPrintf ("%1c", ACPI_GET8 (Name));
+ Name++;
+ }
+
+ switch (ACPI_GET8 (Name))
+ {
+ case 0:
+ SegCount = 0;
+ break;
+
+ case AML_DUAL_NAME_PREFIX:
+ SegCount = 2;
+ Name++;
+ break;
+
+ case AML_MULTI_NAME_PREFIX_OP:
+ SegCount = (UINT32) ACPI_GET8 (Name + 1);
+ Name += 2;
+ break;
+
+ default:
+ SegCount = 1;
+ break;
+ }
+
+ while (SegCount)
+ {
+ /* Append Name segment */
+
+ AcpiDmDumpName (*ACPI_CAST_PTR (UINT32, Name));
+
+ SegCount--;
+ if (SegCount)
+ {
+ /* Not last name, append dot separator */
+
+ AcpiOsPrintf (".");
+ }
+ Name += ACPI_NAME_SIZE;
+ }
+}
+
+
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDisplayPath
+ *
+ * PARAMETERS: Op - Named Op whose path is to be constructed
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Walk backwards from current scope and display the name
+ * of each previous level of scope up to the root scope
+ * (like "pwd" does with file systems)
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDisplayPath (
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_PARSE_OBJECT *Prev;
+ ACPI_PARSE_OBJECT *Search;
+ UINT32 Name;
+ BOOLEAN DoDot = FALSE;
+ ACPI_PARSE_OBJECT *NamePath;
+ const ACPI_OPCODE_INFO *OpInfo;
+
+
+ /* We are only interested in named objects */
+
+ OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
+ if (!(OpInfo->Flags & AML_NSNODE))
+ {
+ return;
+ }
+
+ if (OpInfo->Flags & AML_CREATE)
+ {
+ /* Field creation - check for a fully qualified namepath */
+
+ if (Op->Common.AmlOpcode == AML_CREATE_FIELD_OP)
+ {
+ NamePath = AcpiPsGetArg (Op, 3);
+ }
+ else
+ {
+ NamePath = AcpiPsGetArg (Op, 2);
+ }
+
+ if ((NamePath) &&
+ (NamePath->Common.Value.String) &&
+ (NamePath->Common.Value.String[0] == '\\'))
+ {
+ AcpiDmNamestring (NamePath->Common.Value.String);
+ return;
+ }
+ }
+
+ Prev = NULL; /* Start with Root Node */
+
+ while (Prev != Op)
+ {
+ /* Search upwards in the tree to find scope with "prev" as its parent */
+
+ Search = Op;
+ for (; ;)
+ {
+ if (Search->Common.Parent == Prev)
+ {
+ break;
+ }
+
+ /* Go up one level */
+
+ Search = Search->Common.Parent;
+ }
+
+ if (Prev)
+ {
+ OpInfo = AcpiPsGetOpcodeInfo (Search->Common.AmlOpcode);
+ if (!(OpInfo->Flags & AML_FIELD))
+ {
+ /* Below root scope, append scope name */
+
+ if (DoDot)
+ {
+ /* Append dot */
+
+ AcpiOsPrintf (".");
+ }
+
+ if (OpInfo->Flags & AML_CREATE)
+ {
+ if (Op->Common.AmlOpcode == AML_CREATE_FIELD_OP)
+ {
+ NamePath = AcpiPsGetArg (Op, 3);
+ }
+ else
+ {
+ NamePath = AcpiPsGetArg (Op, 2);
+ }
+
+ if ((NamePath) &&
+ (NamePath->Common.Value.String))
+ {
+ AcpiDmDumpName (NamePath->Common.Value.String);
+ }
+ }
+ else
+ {
+ Name = AcpiPsGetName (Search);
+ AcpiDmDumpName ((char *) &Name);
+ }
+
+ DoDot = TRUE;
+ }
+ }
+ Prev = Search;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmValidateName
+ *
+ * PARAMETERS: Name - 4 character ACPI name
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Lookup the name
+ *
+ ******************************************************************************/
+
+void
+AcpiDmValidateName (
+ char *Name,
+ ACPI_PARSE_OBJECT *Op)
+{
+
+ if ((!Name) ||
+ (!Op->Common.Parent))
+ {
+ return;
+ }
+
+ if (!Op->Common.Node)
+ {
+ AcpiOsPrintf (
+ " /**** Name not found or not accessible from this scope ****/ ");
+ }
+
+ ACPI_PARSE_OBJECT *TargetOp;
+
+
+ if ((!Name) ||
+ (!Op->Common.Parent))
+ {
+ return;
+ }
+
+ TargetOp = AcpiPsFind (Op, Name, 0, 0);
+ if (!TargetOp)
+ {
+ /*
+ * Didn't find the name in the parse tree. This may be
+ * a problem, or it may simply be one of the predefined names
+ * (such as _OS_). Rather than worry about looking up all
+ * the predefined names, just display the name as given
+ */
+ AcpiOsPrintf (
+ " /**** Name not found or not accessible from this scope ****/ ");
+ }
+}
+#endif
+
+#endif
+
+
diff --git a/source/components/disassembler/dmobject.c b/source/components/disassembler/dmobject.c
new file mode 100644
index 000000000000..cb515e94279d
--- /dev/null
+++ b/source/components/disassembler/dmobject.c
@@ -0,0 +1,589 @@
+/*******************************************************************************
+ *
+ * Module Name: dmobject - ACPI object decode and display
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2012, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include "acpi.h"
+#include "accommon.h"
+#include "acnamesp.h"
+#include "acdisasm.h"
+
+
+#ifdef ACPI_DISASSEMBLER
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("dmnames")
+
+/* Local prototypes */
+
+static void
+AcpiDmDecodeNode (
+ ACPI_NAMESPACE_NODE *Node);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDumpMethodInfo
+ *
+ * PARAMETERS: Status - Method execution status
+ * WalkState - Current state of the parse tree walk
+ * Op - Executing parse op
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Called when a method has been aborted because of an error.
+ * Dumps the method execution stack, and the method locals/args,
+ * and disassembles the AML opcode that failed.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDumpMethodInfo (
+ ACPI_STATUS Status,
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_PARSE_OBJECT *Next;
+ ACPI_THREAD_STATE *Thread;
+ ACPI_WALK_STATE *NextWalkState;
+ ACPI_NAMESPACE_NODE *PreviousMethod = NULL;
+
+
+ /* Ignore control codes, they are not errors */
+
+ if ((Status & AE_CODE_MASK) == AE_CODE_CONTROL)
+ {
+ return;
+ }
+
+ /* We may be executing a deferred opcode */
+
+ if (WalkState->DeferredNode)
+ {
+ AcpiOsPrintf ("Executing subtree for Buffer/Package/Region\n");
+ return;
+ }
+
+ /*
+ * If there is no Thread, we are not actually executing a method.
+ * This can happen when the iASL compiler calls the interpreter
+ * to perform constant folding.
+ */
+ Thread = WalkState->Thread;
+ if (!Thread)
+ {
+ return;
+ }
+
+ /* Display exception and method name */
+
+ AcpiOsPrintf ("\n**** Exception %s during execution of method ",
+ AcpiFormatException (Status));
+ AcpiNsPrintNodePathname (WalkState->MethodNode, NULL);
+
+ /* Display stack of executing methods */
+
+ AcpiOsPrintf ("\n\nMethod Execution Stack:\n");
+ NextWalkState = Thread->WalkStateList;
+
+ /* Walk list of linked walk states */
+
+ while (NextWalkState)
+ {
+ AcpiOsPrintf (" Method [%4.4s] executing: ",
+ AcpiUtGetNodeName (NextWalkState->MethodNode));
+
+ /* First method is the currently executing method */
+
+ if (NextWalkState == WalkState)
+ {
+ if (Op)
+ {
+ /* Display currently executing ASL statement */
+
+ Next = Op->Common.Next;
+ Op->Common.Next = NULL;
+
+ AcpiDmDisassemble (NextWalkState, Op, ACPI_UINT32_MAX);
+ Op->Common.Next = Next;
+ }
+ }
+ else
+ {
+ /*
+ * This method has called another method
+ * NOTE: the method call parse subtree is already deleted at this
+ * point, so we cannot disassemble the method invocation.
+ */
+ AcpiOsPrintf ("Call to method ");
+ AcpiNsPrintNodePathname (PreviousMethod, NULL);
+ }
+
+ PreviousMethod = NextWalkState->MethodNode;
+ NextWalkState = NextWalkState->Next;
+ AcpiOsPrintf ("\n");
+ }
+
+ /* Display the method locals and arguments */
+
+ AcpiOsPrintf ("\n");
+ AcpiDmDisplayLocals (WalkState);
+ AcpiOsPrintf ("\n");
+ AcpiDmDisplayArguments (WalkState);
+ AcpiOsPrintf ("\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDecodeInternalObject
+ *
+ * PARAMETERS: ObjDesc - Object to be displayed
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Short display of an internal object. Numbers/Strings/Buffers.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDecodeInternalObject (
+ ACPI_OPERAND_OBJECT *ObjDesc)
+{
+ UINT32 i;
+
+
+ if (!ObjDesc)
+ {
+ AcpiOsPrintf (" Uninitialized");
+ return;
+ }
+
+ if (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc) != ACPI_DESC_TYPE_OPERAND)
+ {
+ AcpiOsPrintf (" %p [%s]", ObjDesc, AcpiUtGetDescriptorName (ObjDesc));
+ return;
+ }
+
+ AcpiOsPrintf (" %s", AcpiUtGetObjectTypeName (ObjDesc));
+
+ switch (ObjDesc->Common.Type)
+ {
+ case ACPI_TYPE_INTEGER:
+
+ AcpiOsPrintf (" %8.8X%8.8X",
+ ACPI_FORMAT_UINT64 (ObjDesc->Integer.Value));
+ break;
+
+
+ case ACPI_TYPE_STRING:
+
+ AcpiOsPrintf ("(%u) \"%.24s",
+ ObjDesc->String.Length, ObjDesc->String.Pointer);
+
+ if (ObjDesc->String.Length > 24)
+ {
+ AcpiOsPrintf ("...");
+ }
+ else
+ {
+ AcpiOsPrintf ("\"");
+ }
+ break;
+
+
+ case ACPI_TYPE_BUFFER:
+
+ AcpiOsPrintf ("(%u)", ObjDesc->Buffer.Length);
+ for (i = 0; (i < 8) && (i < ObjDesc->Buffer.Length); i++)
+ {
+ AcpiOsPrintf (" %2.2X", ObjDesc->Buffer.Pointer[i]);
+ }
+ break;
+
+
+ default:
+
+ AcpiOsPrintf (" %p", ObjDesc);
+ break;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDecodeNode
+ *
+ * PARAMETERS: Node - Object to be displayed
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Short display of a namespace node
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmDecodeNode (
+ ACPI_NAMESPACE_NODE *Node)
+{
+
+ AcpiOsPrintf ("<Node> Name %4.4s",
+ AcpiUtGetNodeName (Node));
+
+ if (Node->Flags & ANOBJ_METHOD_ARG)
+ {
+ AcpiOsPrintf (" [Method Arg]");
+ }
+ if (Node->Flags & ANOBJ_METHOD_LOCAL)
+ {
+ AcpiOsPrintf (" [Method Local]");
+ }
+
+ switch (Node->Type)
+ {
+ /* These types have no attached object */
+
+ case ACPI_TYPE_DEVICE:
+ AcpiOsPrintf (" Device");
+ break;
+
+ case ACPI_TYPE_THERMAL:
+ AcpiOsPrintf (" Thermal Zone");
+ break;
+
+ default:
+ AcpiDmDecodeInternalObject (AcpiNsGetAttachedObject (Node));
+ break;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDisplayInternalObject
+ *
+ * PARAMETERS: ObjDesc - Object to be displayed
+ * WalkState - Current walk state
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Short display of an internal object
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDisplayInternalObject (
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ ACPI_WALK_STATE *WalkState)
+{
+ UINT8 Type;
+
+
+ AcpiOsPrintf ("%p ", ObjDesc);
+
+ if (!ObjDesc)
+ {
+ AcpiOsPrintf ("<Null Object>\n");
+ return;
+ }
+
+ /* Decode the object type */
+
+ switch (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc))
+ {
+ case ACPI_DESC_TYPE_PARSER:
+
+ AcpiOsPrintf ("<Parser> ");
+ break;
+
+
+ case ACPI_DESC_TYPE_NAMED:
+
+ AcpiDmDecodeNode ((ACPI_NAMESPACE_NODE *) ObjDesc);
+ break;
+
+
+ case ACPI_DESC_TYPE_OPERAND:
+
+ Type = ObjDesc->Common.Type;
+ if (Type > ACPI_TYPE_LOCAL_MAX)
+ {
+ AcpiOsPrintf (" Type %X [Invalid Type]", (UINT32) Type);
+ return;
+ }
+
+ /* Decode the ACPI object type */
+
+ switch (ObjDesc->Common.Type)
+ {
+ case ACPI_TYPE_LOCAL_REFERENCE:
+
+ AcpiOsPrintf ("[%s] ", AcpiUtGetReferenceName (ObjDesc));
+
+ /* Decode the refererence */
+
+ switch (ObjDesc->Reference.Class)
+ {
+ case ACPI_REFCLASS_LOCAL:
+
+ AcpiOsPrintf ("%X ", ObjDesc->Reference.Value);
+ if (WalkState)
+ {
+ ObjDesc = WalkState->LocalVariables
+ [ObjDesc->Reference.Value].Object;
+ AcpiOsPrintf ("%p", ObjDesc);
+ AcpiDmDecodeInternalObject (ObjDesc);
+ }
+ break;
+
+
+ case ACPI_REFCLASS_ARG:
+
+ AcpiOsPrintf ("%X ", ObjDesc->Reference.Value);
+ if (WalkState)
+ {
+ ObjDesc = WalkState->Arguments
+ [ObjDesc->Reference.Value].Object;
+ AcpiOsPrintf ("%p", ObjDesc);
+ AcpiDmDecodeInternalObject (ObjDesc);
+ }
+ break;
+
+
+ case ACPI_REFCLASS_INDEX:
+
+ switch (ObjDesc->Reference.TargetType)
+ {
+ case ACPI_TYPE_BUFFER_FIELD:
+
+ AcpiOsPrintf ("%p", ObjDesc->Reference.Object);
+ AcpiDmDecodeInternalObject (ObjDesc->Reference.Object);
+ break;
+
+ case ACPI_TYPE_PACKAGE:
+
+ AcpiOsPrintf ("%p", ObjDesc->Reference.Where);
+ if (!ObjDesc->Reference.Where)
+ {
+ AcpiOsPrintf (" Uninitialized WHERE pointer");
+ }
+ else
+ {
+ AcpiDmDecodeInternalObject (
+ *(ObjDesc->Reference.Where));
+ }
+ break;
+
+ default:
+
+ AcpiOsPrintf ("Unknown index target type");
+ break;
+ }
+ break;
+
+
+ case ACPI_REFCLASS_REFOF:
+
+ if (!ObjDesc->Reference.Object)
+ {
+ AcpiOsPrintf ("Uninitialized reference subobject pointer");
+ break;
+ }
+
+ /* Reference can be to a Node or an Operand object */
+
+ switch (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc->Reference.Object))
+ {
+ case ACPI_DESC_TYPE_NAMED:
+ AcpiDmDecodeNode (ObjDesc->Reference.Object);
+ break;
+
+ case ACPI_DESC_TYPE_OPERAND:
+ AcpiDmDecodeInternalObject (ObjDesc->Reference.Object);
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+
+ case ACPI_REFCLASS_NAME:
+
+ AcpiDmDecodeNode (ObjDesc->Reference.Node);
+ break;
+
+
+ case ACPI_REFCLASS_DEBUG:
+ case ACPI_REFCLASS_TABLE:
+
+ AcpiOsPrintf ("\n");
+ break;
+
+
+ default: /* Unknown reference class */
+
+ AcpiOsPrintf ("%2.2X\n", ObjDesc->Reference.Class);
+ break;
+ }
+ break;
+
+
+ default:
+
+ AcpiOsPrintf ("<Obj> ");
+ AcpiDmDecodeInternalObject (ObjDesc);
+ break;
+ }
+ break;
+
+
+ default:
+
+ AcpiOsPrintf ("<Not a valid ACPI Object Descriptor> [%s]",
+ AcpiUtGetDescriptorName (ObjDesc));
+ break;
+ }
+
+ AcpiOsPrintf ("\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDisplayLocals
+ *
+ * PARAMETERS: WalkState - State for current method
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Display all locals for the currently running control method
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDisplayLocals (
+ ACPI_WALK_STATE *WalkState)
+{
+ UINT32 i;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_NAMESPACE_NODE *Node;
+
+
+ ObjDesc = WalkState->MethodDesc;
+ Node = WalkState->MethodNode;
+ if (!Node)
+ {
+ AcpiOsPrintf (
+ "No method node (Executing subtree for buffer or opregion)\n");
+ return;
+ }
+
+ if (Node->Type != ACPI_TYPE_METHOD)
+ {
+ AcpiOsPrintf ("Executing subtree for Buffer/Package/Region\n");
+ return;
+ }
+
+ AcpiOsPrintf ("Local Variables for method [%4.4s]:\n",
+ AcpiUtGetNodeName (Node));
+
+ for (i = 0; i < ACPI_METHOD_NUM_LOCALS; i++)
+ {
+ ObjDesc = WalkState->LocalVariables[i].Object;
+ AcpiOsPrintf (" Local%X: ", i);
+ AcpiDmDisplayInternalObject (ObjDesc, WalkState);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDisplayArguments
+ *
+ * PARAMETERS: WalkState - State for current method
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Display all arguments for the currently running control method
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDisplayArguments (
+ ACPI_WALK_STATE *WalkState)
+{
+ UINT32 i;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_NAMESPACE_NODE *Node;
+
+
+ ObjDesc = WalkState->MethodDesc;
+ Node = WalkState->MethodNode;
+ if (!Node)
+ {
+ AcpiOsPrintf (
+ "No method node (Executing subtree for buffer or opregion)\n");
+ return;
+ }
+
+ if (Node->Type != ACPI_TYPE_METHOD)
+ {
+ AcpiOsPrintf ("Executing subtree for Buffer/Package/Region\n");
+ return;
+ }
+
+ AcpiOsPrintf (
+ "Arguments for Method [%4.4s]: (%X arguments defined, max concurrency = %X)\n",
+ AcpiUtGetNodeName (Node), ObjDesc->Method.ParamCount, ObjDesc->Method.SyncLevel);
+
+ for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++)
+ {
+ ObjDesc = WalkState->Arguments[i].Object;
+ AcpiOsPrintf (" Arg%u: ", i);
+ AcpiDmDisplayInternalObject (ObjDesc, WalkState);
+ }
+}
+
+#endif
+
+
diff --git a/source/components/disassembler/dmopcode.c b/source/components/disassembler/dmopcode.c
new file mode 100644
index 000000000000..6d2c3e1ecf55
--- /dev/null
+++ b/source/components/disassembler/dmopcode.c
@@ -0,0 +1,607 @@
+/*******************************************************************************
+ *
+ * Module Name: dmopcode - AML disassembler, specific AML opcodes
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2012, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include "acpi.h"
+#include "accommon.h"
+#include "acparser.h"
+#include "amlcode.h"
+#include "acdisasm.h"
+
+#ifdef ACPI_DISASSEMBLER
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("dmopcode")
+
+/* Local prototypes */
+
+static void
+AcpiDmMatchKeyword (
+ ACPI_PARSE_OBJECT *Op);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmMethodFlags
+ *
+ * PARAMETERS: Op - Method Object to be examined
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode control method flags
+ *
+ ******************************************************************************/
+
+void
+AcpiDmMethodFlags (
+ ACPI_PARSE_OBJECT *Op)
+{
+ UINT32 Flags;
+ UINT32 Args;
+
+
+ /* The next Op contains the flags */
+
+ Op = AcpiPsGetDepthNext (NULL, Op);
+ Flags = (UINT8) Op->Common.Value.Integer;
+ Args = Flags & 0x07;
+
+ /* Mark the Op as completed */
+
+ Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
+
+ /* 1) Method argument count */
+
+ AcpiOsPrintf (", %u, ", Args);
+
+ /* 2) Serialize rule */
+
+ if (!(Flags & 0x08))
+ {
+ AcpiOsPrintf ("Not");
+ }
+
+ AcpiOsPrintf ("Serialized");
+
+ /* 3) SyncLevel */
+
+ if (Flags & 0xF0)
+ {
+ AcpiOsPrintf (", %u", Flags >> 4);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmFieldFlags
+ *
+ * PARAMETERS: Op - Field Object to be examined
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode Field definition flags
+ *
+ ******************************************************************************/
+
+void
+AcpiDmFieldFlags (
+ ACPI_PARSE_OBJECT *Op)
+{
+ UINT32 Flags;
+
+
+ Op = Op->Common.Next;
+ Flags = (UINT8) Op->Common.Value.Integer;
+
+ /* Mark the Op as completed */
+
+ Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
+
+ AcpiOsPrintf ("%s, ", AcpiGbl_AccessTypes [Flags & 0x07]);
+ AcpiOsPrintf ("%s, ", AcpiGbl_LockRule [(Flags & 0x10) >> 4]);
+ AcpiOsPrintf ("%s)", AcpiGbl_UpdateRules [(Flags & 0x60) >> 5]);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmAddressSpace
+ *
+ * PARAMETERS: SpaceId - ID to be translated
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a SpaceId to an AddressSpaceKeyword
+ *
+ ******************************************************************************/
+
+void
+AcpiDmAddressSpace (
+ UINT8 SpaceId)
+{
+
+ if (SpaceId >= ACPI_NUM_PREDEFINED_REGIONS)
+ {
+ if (SpaceId == 0x7F)
+ {
+ AcpiOsPrintf ("FFixedHW, ");
+ }
+ else
+ {
+ AcpiOsPrintf ("0x%.2X, ", SpaceId);
+ }
+ }
+ else
+ {
+ AcpiOsPrintf ("%s, ", AcpiGbl_RegionTypes [SpaceId]);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmRegionFlags
+ *
+ * PARAMETERS: Op - Object to be examined
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode OperationRegion flags
+ *
+ ******************************************************************************/
+
+void
+AcpiDmRegionFlags (
+ ACPI_PARSE_OBJECT *Op)
+{
+
+
+ /* The next Op contains the SpaceId */
+
+ Op = AcpiPsGetDepthNext (NULL, Op);
+
+ /* Mark the Op as completed */
+
+ Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
+
+ AcpiOsPrintf (", ");
+ AcpiDmAddressSpace ((UINT8) Op->Common.Value.Integer);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmMatchOp
+ *
+ * PARAMETERS: Op - Match Object to be examined
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode Match opcode operands
+ *
+ ******************************************************************************/
+
+void
+AcpiDmMatchOp (
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_PARSE_OBJECT *NextOp;
+
+
+ NextOp = AcpiPsGetDepthNext (NULL, Op);
+ NextOp = NextOp->Common.Next;
+
+ if (!NextOp)
+ {
+ /* Handle partial tree during single-step */
+
+ return;
+ }
+
+ /* Mark the two nodes that contain the encoding for the match keywords */
+
+ NextOp->Common.DisasmOpcode = ACPI_DASM_MATCHOP;
+
+ NextOp = NextOp->Common.Next;
+ NextOp = NextOp->Common.Next;
+ NextOp->Common.DisasmOpcode = ACPI_DASM_MATCHOP;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmMatchKeyword
+ *
+ * PARAMETERS: Op - Match Object to be examined
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode Match opcode operands
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmMatchKeyword (
+ ACPI_PARSE_OBJECT *Op)
+{
+
+
+ if (((UINT32) Op->Common.Value.Integer) > ACPI_MAX_MATCH_OPCODE)
+ {
+ AcpiOsPrintf ("/* Unknown Match Keyword encoding */");
+ }
+ else
+ {
+ AcpiOsPrintf ("%s", ACPI_CAST_PTR (char,
+ AcpiGbl_MatchOps[(ACPI_SIZE) Op->Common.Value.Integer]));
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDisassembleOneOp
+ *
+ * PARAMETERS: WalkState - Current walk info
+ * Info - Parse tree walk info
+ * Op - Op that is to be printed
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Disassemble a single AML opcode
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDisassembleOneOp (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_OP_WALK_INFO *Info,
+ ACPI_PARSE_OBJECT *Op)
+{
+ const ACPI_OPCODE_INFO *OpInfo = NULL;
+ UINT32 Offset;
+ UINT32 Length;
+ ACPI_PARSE_OBJECT *Child;
+ ACPI_STATUS Status;
+ UINT8 *Aml;
+
+
+ if (!Op)
+ {
+ AcpiOsPrintf ("<NULL OP PTR>");
+ return;
+ }
+
+ switch (Op->Common.DisasmOpcode)
+ {
+ case ACPI_DASM_MATCHOP:
+
+ AcpiDmMatchKeyword (Op);
+ return;
+
+ case ACPI_DASM_LNOT_SUFFIX:
+ switch (Op->Common.AmlOpcode)
+ {
+ case AML_LEQUAL_OP:
+ AcpiOsPrintf ("LNotEqual");
+ break;
+
+ case AML_LGREATER_OP:
+ AcpiOsPrintf ("LLessEqual");
+ break;
+
+ case AML_LLESS_OP:
+ AcpiOsPrintf ("LGreaterEqual");
+ break;
+
+ default:
+ break;
+ }
+ Op->Common.DisasmOpcode = 0;
+ Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
+ return;
+
+ default:
+ break;
+ }
+
+
+ OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
+
+ /* The op and arguments */
+
+ switch (Op->Common.AmlOpcode)
+ {
+ case AML_LNOT_OP:
+
+ Child = Op->Common.Value.Arg;
+ if ((Child->Common.AmlOpcode == AML_LEQUAL_OP) ||
+ (Child->Common.AmlOpcode == AML_LGREATER_OP) ||
+ (Child->Common.AmlOpcode == AML_LLESS_OP))
+ {
+ Child->Common.DisasmOpcode = ACPI_DASM_LNOT_SUFFIX;
+ Op->Common.DisasmOpcode = ACPI_DASM_LNOT_PREFIX;
+ }
+ else
+ {
+ AcpiOsPrintf ("%s", OpInfo->Name);
+ }
+ break;
+
+ case AML_BYTE_OP:
+
+ AcpiOsPrintf ("0x%2.2X", (UINT32) Op->Common.Value.Integer);
+ break;
+
+
+ case AML_WORD_OP:
+
+ if (Op->Common.DisasmOpcode == ACPI_DASM_EISAID)
+ {
+ AcpiDmEisaId ((UINT32) Op->Common.Value.Integer);
+ }
+ else
+ {
+ AcpiOsPrintf ("0x%4.4X", (UINT32) Op->Common.Value.Integer);
+ }
+ break;
+
+
+ case AML_DWORD_OP:
+
+ if (Op->Common.DisasmOpcode == ACPI_DASM_EISAID)
+ {
+ AcpiDmEisaId ((UINT32) Op->Common.Value.Integer);
+ }
+ else
+ {
+ AcpiOsPrintf ("0x%8.8X", (UINT32) Op->Common.Value.Integer);
+ }
+ break;
+
+
+ case AML_QWORD_OP:
+
+ AcpiOsPrintf ("0x%8.8X%8.8X",
+ ACPI_FORMAT_UINT64 (Op->Common.Value.Integer));
+ break;
+
+
+ case AML_STRING_OP:
+
+ AcpiUtPrintString (Op->Common.Value.String, ACPI_UINT8_MAX);
+ break;
+
+
+ case AML_BUFFER_OP:
+
+ /*
+ * Determine the type of buffer. We can have one of the following:
+ *
+ * 1) ResourceTemplate containing Resource Descriptors.
+ * 2) Unicode String buffer
+ * 3) ASCII String buffer
+ * 4) Raw data buffer (if none of the above)
+ *
+ * Since there are no special AML opcodes to differentiate these
+ * types of buffers, we have to closely look at the data in the
+ * buffer to determine the type.
+ */
+ if (!AcpiGbl_NoResourceDisassembly)
+ {
+ Status = AcpiDmIsResourceTemplate (Op);
+ if (ACPI_SUCCESS (Status))
+ {
+ Op->Common.DisasmOpcode = ACPI_DASM_RESOURCE;
+ AcpiOsPrintf ("ResourceTemplate");
+ break;
+ }
+ else if (Status == AE_AML_NO_RESOURCE_END_TAG)
+ {
+ AcpiOsPrintf ("/**** Is ResourceTemplate, but EndTag not at buffer end ****/ ");
+ }
+ }
+
+ if (AcpiDmIsUnicodeBuffer (Op))
+ {
+ Op->Common.DisasmOpcode = ACPI_DASM_UNICODE;
+ AcpiOsPrintf ("Unicode (");
+ }
+ else if (AcpiDmIsStringBuffer (Op))
+ {
+ Op->Common.DisasmOpcode = ACPI_DASM_STRING;
+ AcpiOsPrintf ("Buffer");
+ }
+ else
+ {
+ Op->Common.DisasmOpcode = ACPI_DASM_BUFFER;
+ AcpiOsPrintf ("Buffer");
+ }
+ break;
+
+
+ case AML_INT_STATICSTRING_OP:
+
+ if (Op->Common.Value.String)
+ {
+ AcpiOsPrintf ("%s", Op->Common.Value.String);
+ }
+ else
+ {
+ AcpiOsPrintf ("\"<NULL STATIC STRING PTR>\"");
+ }
+ break;
+
+
+ case AML_INT_NAMEPATH_OP:
+
+ AcpiDmNamestring (Op->Common.Value.Name);
+ break;
+
+
+ case AML_INT_NAMEDFIELD_OP:
+
+ Length = AcpiDmDumpName (Op->Named.Name);
+ AcpiOsPrintf (",%*.s %u", (unsigned) (5 - Length), " ",
+ (UINT32) Op->Common.Value.Integer);
+ AcpiDmCommaIfFieldMember (Op);
+
+ Info->BitOffset += (UINT32) Op->Common.Value.Integer;
+ break;
+
+
+ case AML_INT_RESERVEDFIELD_OP:
+
+ /* Offset() -- Must account for previous offsets */
+
+ Offset = (UINT32) Op->Common.Value.Integer;
+ Info->BitOffset += Offset;
+
+ if (Info->BitOffset % 8 == 0)
+ {
+ AcpiOsPrintf ("Offset (0x%.2X)", ACPI_DIV_8 (Info->BitOffset));
+ }
+ else
+ {
+ AcpiOsPrintf (" , %u", Offset);
+ }
+
+ AcpiDmCommaIfFieldMember (Op);
+ break;
+
+
+ case AML_INT_ACCESSFIELD_OP:
+ case AML_INT_EXTACCESSFIELD_OP:
+
+ AcpiOsPrintf ("AccessAs (%s, ",
+ AcpiGbl_AccessTypes [(UINT32) (Op->Common.Value.Integer & 0x7)]);
+
+ AcpiDmDecodeAttribute ((UINT8) (Op->Common.Value.Integer >> 8));
+
+ if (Op->Common.AmlOpcode == AML_INT_EXTACCESSFIELD_OP)
+ {
+ AcpiOsPrintf (" (0x%2.2X)", (unsigned) ((Op->Common.Value.Integer >> 16) & 0xFF));
+ }
+
+ AcpiOsPrintf (")");
+ AcpiDmCommaIfFieldMember (Op);
+ break;
+
+
+ case AML_INT_CONNECTION_OP:
+
+ /*
+ * Two types of Connection() - one with a buffer object, the
+ * other with a namestring that points to a buffer object.
+ */
+ AcpiOsPrintf ("Connection (");
+ Child = Op->Common.Value.Arg;
+
+ if (Child->Common.AmlOpcode == AML_INT_BYTELIST_OP)
+ {
+ AcpiOsPrintf ("\n");
+
+ Aml = Child->Named.Data;
+ Length = (UINT32) Child->Common.Value.Integer;
+
+ Info->Level += 1;
+ Op->Common.DisasmOpcode = ACPI_DASM_RESOURCE;
+ AcpiDmResourceTemplate (Info, Op->Common.Parent, Aml, Length);
+
+ Info->Level -= 1;
+ AcpiDmIndent (Info->Level);
+ }
+ else
+ {
+ AcpiDmNamestring (Child->Common.Value.Name);
+ }
+
+ AcpiOsPrintf (")");
+ AcpiDmCommaIfFieldMember (Op);
+ AcpiOsPrintf ("\n");
+
+ Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; /* for now, ignore in AcpiDmAscendingOp */
+ Child->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
+ break;
+
+ case AML_INT_BYTELIST_OP:
+
+ AcpiDmByteList (Info, Op);
+ break;
+
+
+ case AML_INT_METHODCALL_OP:
+
+ Op = AcpiPsGetDepthNext (NULL, Op);
+ Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
+
+ AcpiDmNamestring (Op->Common.Value.Name);
+ break;
+
+
+ default:
+
+ /* Just get the opcode name and print it */
+
+ AcpiOsPrintf ("%s", OpInfo->Name);
+
+
+#ifdef ACPI_DEBUGGER
+
+ if ((Op->Common.AmlOpcode == AML_INT_RETURN_VALUE_OP) &&
+ (WalkState) &&
+ (WalkState->Results) &&
+ (WalkState->ResultCount))
+ {
+ AcpiDmDecodeInternalObject (
+ WalkState->Results->Results.ObjDesc [
+ (WalkState->ResultCount - 1) %
+ ACPI_RESULTS_FRAME_OBJ_NUM]);
+ }
+#endif
+
+ break;
+ }
+}
+
+#endif /* ACPI_DISASSEMBLER */
diff --git a/source/components/disassembler/dmresrc.c b/source/components/disassembler/dmresrc.c
new file mode 100644
index 000000000000..9c07bf7e9462
--- /dev/null
+++ b/source/components/disassembler/dmresrc.c
@@ -0,0 +1,434 @@
+/*******************************************************************************
+ *
+ * Module Name: dmresrc.c - Resource Descriptor disassembly
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2012, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include "acpi.h"
+#include "accommon.h"
+#include "amlcode.h"
+#include "acdisasm.h"
+
+#ifdef ACPI_DISASSEMBLER
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("dbresrc")
+
+
+/* Dispatch tables for Resource disassembly functions */
+
+static ACPI_RESOURCE_HANDLER AcpiGbl_DmResourceDispatch [] =
+{
+ /* Small descriptors */
+
+ NULL, /* 0x00, Reserved */
+ NULL, /* 0x01, Reserved */
+ NULL, /* 0x02, Reserved */
+ NULL, /* 0x03, Reserved */
+ AcpiDmIrqDescriptor, /* 0x04, ACPI_RESOURCE_NAME_IRQ_FORMAT */
+ AcpiDmDmaDescriptor, /* 0x05, ACPI_RESOURCE_NAME_DMA_FORMAT */
+ AcpiDmStartDependentDescriptor, /* 0x06, ACPI_RESOURCE_NAME_START_DEPENDENT */
+ AcpiDmEndDependentDescriptor, /* 0x07, ACPI_RESOURCE_NAME_END_DEPENDENT */
+ AcpiDmIoDescriptor, /* 0x08, ACPI_RESOURCE_NAME_IO_PORT */
+ AcpiDmFixedIoDescriptor, /* 0x09, ACPI_RESOURCE_NAME_FIXED_IO_PORT */
+ AcpiDmFixedDmaDescriptor, /* 0x0A, ACPI_RESOURCE_NAME_FIXED_DMA */
+ NULL, /* 0x0B, Reserved */
+ NULL, /* 0x0C, Reserved */
+ NULL, /* 0x0D, Reserved */
+ AcpiDmVendorSmallDescriptor, /* 0x0E, ACPI_RESOURCE_NAME_SMALL_VENDOR */
+ NULL, /* 0x0F, ACPI_RESOURCE_NAME_END_TAG (not used) */
+
+ /* Large descriptors */
+
+ NULL, /* 0x00, Reserved */
+ AcpiDmMemory24Descriptor, /* 0x01, ACPI_RESOURCE_NAME_MEMORY_24 */
+ AcpiDmGenericRegisterDescriptor,/* 0x02, ACPI_RESOURCE_NAME_GENERIC_REGISTER */
+ NULL, /* 0x03, Reserved */
+ AcpiDmVendorLargeDescriptor, /* 0x04, ACPI_RESOURCE_NAME_LARGE_VENDOR */
+ AcpiDmMemory32Descriptor, /* 0x05, ACPI_RESOURCE_NAME_MEMORY_32 */
+ AcpiDmFixedMemory32Descriptor, /* 0x06, ACPI_RESOURCE_NAME_FIXED_MEMORY_32 */
+ AcpiDmDwordDescriptor, /* 0x07, ACPI_RESOURCE_NAME_DWORD_ADDRESS_SPACE */
+ AcpiDmWordDescriptor, /* 0x08, ACPI_RESOURCE_NAME_WORD_ADDRESS_SPACE */
+ AcpiDmInterruptDescriptor, /* 0x09, ACPI_RESOURCE_NAME_EXTENDED_XRUPT */
+ AcpiDmQwordDescriptor, /* 0x0A, ACPI_RESOURCE_NAME_QWORD_ADDRESS_SPACE */
+ AcpiDmExtendedDescriptor, /* 0x0B, ACPI_RESOURCE_NAME_EXTENDED_ADDRESS_SPACE */
+ AcpiDmGpioDescriptor, /* 0x0C, ACPI_RESOURCE_NAME_GPIO */
+ NULL, /* 0x0D, Reserved */
+ AcpiDmSerialBusDescriptor /* 0x0E, ACPI_RESOURCE_NAME_SERIAL_BUS */
+};
+
+
+/* Only used for single-threaded applications */
+/* TBD: remove when name is passed as parameter to the dump functions */
+
+static UINT32 ResourceName;
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDescriptorName
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Emit a name for the descriptor if one is present (indicated
+ * by the name being changed from the default name.) A name is only
+ * emitted if a reference to the descriptor has been made somewhere
+ * in the original ASL code.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDescriptorName (
+ void)
+{
+
+ if (ResourceName == ACPI_DEFAULT_RESNAME)
+ {
+ return;
+ }
+
+ AcpiOsPrintf ("%4.4s", (char *) &ResourceName);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDumpInteger*
+ *
+ * PARAMETERS: Value - Value to emit
+ * Name - Associated name (emitted as a comment)
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Integer output helper functions
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDumpInteger8 (
+ UINT8 Value,
+ char *Name)
+{
+ AcpiOsPrintf ("0x%2.2X, // %s\n", Value, Name);
+}
+
+void
+AcpiDmDumpInteger16 (
+ UINT16 Value,
+ char *Name)
+{
+ AcpiOsPrintf ("0x%4.4X, // %s\n", Value, Name);
+}
+
+void
+AcpiDmDumpInteger32 (
+ UINT32 Value,
+ char *Name)
+{
+ AcpiOsPrintf ("0x%8.8X, // %s\n", Value, Name);
+}
+
+void
+AcpiDmDumpInteger64 (
+ UINT64 Value,
+ char *Name)
+{
+ AcpiOsPrintf ("0x%8.8X%8.8X, // %s\n", ACPI_FORMAT_UINT64 (Value), Name);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmBitList
+ *
+ * PARAMETERS: Mask - 16-bit value corresponding to 16 interrupt
+ * or DMA values
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump a bit mask as a list of individual interrupt/DMA levels.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmBitList (
+ UINT16 Mask)
+{
+ UINT32 i;
+ BOOLEAN Previous = FALSE;
+
+
+ /* Open the initializer list */
+
+ AcpiOsPrintf ("{");
+
+ /* Examine each bit */
+
+ for (i = 0; i < 16; i++)
+ {
+ /* Only interested in bits that are set to 1 */
+
+ if (Mask & 1)
+ {
+ if (Previous)
+ {
+ AcpiOsPrintf (",");
+ }
+ Previous = TRUE;
+ AcpiOsPrintf ("%u", i);
+ }
+
+ Mask >>= 1;
+ }
+
+ /* Close list */
+
+ AcpiOsPrintf ("}\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmResourceTemplate
+ *
+ * PARAMETERS: Info - Curent parse tree walk info
+ * ByteData - Pointer to the byte list data
+ * ByteCount - Length of the byte list
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump the contents of a Resource Template containing a set of
+ * Resource Descriptors.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmResourceTemplate (
+ ACPI_OP_WALK_INFO *Info,
+ ACPI_PARSE_OBJECT *Op,
+ UINT8 *ByteData,
+ UINT32 ByteCount)
+{
+ ACPI_STATUS Status;
+ UINT32 CurrentByteOffset;
+ UINT8 ResourceType;
+ UINT32 ResourceLength;
+ void *Aml;
+ UINT32 Level;
+ BOOLEAN DependentFns = FALSE;
+ UINT8 ResourceIndex;
+ ACPI_NAMESPACE_NODE *Node;
+
+
+ Level = Info->Level;
+ ResourceName = ACPI_DEFAULT_RESNAME;
+ Node = Op->Common.Node;
+ if (Node)
+ {
+ Node = Node->Child;
+ }
+
+ for (CurrentByteOffset = 0; CurrentByteOffset < ByteCount;)
+ {
+ Aml = &ByteData[CurrentByteOffset];
+
+ /* Get the descriptor type and length */
+
+ ResourceType = AcpiUtGetResourceType (Aml);
+ ResourceLength = AcpiUtGetResourceLength (Aml);
+
+ /* Validate the Resource Type and Resource Length */
+
+ Status = AcpiUtValidateResource (Aml, &ResourceIndex);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsPrintf ("/*** Could not validate Resource, type (%X) %s***/\n",
+ ResourceType, AcpiFormatException (Status));
+ return;
+ }
+
+ /* Point to next descriptor */
+
+ CurrentByteOffset += AcpiUtGetDescriptorLength (Aml);
+
+ /* Descriptor pre-processing */
+
+ switch (ResourceType)
+ {
+ case ACPI_RESOURCE_NAME_START_DEPENDENT:
+
+ /* Finish a previous StartDependentFns */
+
+ if (DependentFns)
+ {
+ Level--;
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("}\n");
+ }
+ break;
+
+ case ACPI_RESOURCE_NAME_END_DEPENDENT:
+
+ Level--;
+ DependentFns = FALSE;
+ break;
+
+ case ACPI_RESOURCE_NAME_END_TAG:
+
+ /* Normal exit, the resource list is finished */
+
+ if (DependentFns)
+ {
+ /*
+ * Close an open StartDependentDescriptor. This indicates a
+ * missing EndDependentDescriptor.
+ */
+ Level--;
+ DependentFns = FALSE;
+
+ /* Go ahead and insert EndDependentFn() */
+
+ AcpiDmEndDependentDescriptor (Aml, ResourceLength, Level);
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf (
+ "/*** Disassembler: inserted missing EndDependentFn () ***/\n");
+ }
+ return;
+
+ default:
+ break;
+ }
+
+ /* Disassemble the resource structure */
+
+ if (Node)
+ {
+ ResourceName = Node->Name.Integer;
+ Node = Node->Peer;
+ }
+
+ AcpiGbl_DmResourceDispatch [ResourceIndex] (
+ Aml, ResourceLength, Level);
+
+ /* Descriptor post-processing */
+
+ if (ResourceType == ACPI_RESOURCE_NAME_START_DEPENDENT)
+ {
+ DependentFns = TRUE;
+ Level++;
+ }
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmIsResourceTemplate
+ *
+ * PARAMETERS: Op - Buffer Op to be examined
+ *
+ * RETURN: Status. AE_OK if valid template
+ *
+ * DESCRIPTION: Walk a byte list to determine if it consists of a valid set
+ * of resource descriptors. Nothing is output.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDmIsResourceTemplate (
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_STATUS Status;
+ ACPI_PARSE_OBJECT *NextOp;
+ UINT8 *Aml;
+ UINT8 *EndAml;
+ ACPI_SIZE Length;
+
+
+ /* This op must be a buffer */
+
+ if (Op->Common.AmlOpcode != AML_BUFFER_OP)
+ {
+ return (AE_TYPE);
+ }
+
+ /* Get the ByteData list and length */
+
+ NextOp = Op->Common.Value.Arg;
+ NextOp = NextOp->Common.Next;
+ if (!NextOp)
+ {
+ return (AE_TYPE);
+ }
+
+ Aml = NextOp->Named.Data;
+ Length = (ACPI_SIZE) NextOp->Common.Value.Integer;
+
+ /* Walk the byte list, abort on any invalid descriptor type or length */
+
+ Status = AcpiUtWalkAmlResources (Aml, Length, NULL, &EndAml);
+ if (ACPI_FAILURE (Status))
+ {
+ return (AE_TYPE);
+ }
+
+ /*
+ * For the resource template to be valid, one EndTag must appear
+ * at the very end of the ByteList, not before. (For proper disassembly
+ * of a ResourceTemplate, the buffer must not have any extra data after
+ * the EndTag.)
+ */
+ if ((Aml + Length - sizeof (AML_RESOURCE_END_TAG)) != EndAml)
+ {
+ return (AE_AML_NO_RESOURCE_END_TAG);
+ }
+
+ /*
+ * All resource descriptors are valid, therefore this list appears
+ * to be a valid resource template
+ */
+ return (AE_OK);
+}
+
+#endif
diff --git a/source/components/disassembler/dmresrcl.c b/source/components/disassembler/dmresrcl.c
new file mode 100644
index 000000000000..ed78b31c707b
--- /dev/null
+++ b/source/components/disassembler/dmresrcl.c
@@ -0,0 +1,1052 @@
+/*******************************************************************************
+ *
+ * Module Name: dmresrcl.c - "Large" Resource Descriptor disassembly
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2012, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include "acpi.h"
+#include "accommon.h"
+#include "acdisasm.h"
+
+
+#ifdef ACPI_DISASSEMBLER
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("dbresrcl")
+
+
+/* Common names for address and memory descriptors */
+
+static char *AcpiDmAddressNames[] =
+{
+ "Granularity",
+ "Range Minimum",
+ "Range Maximum",
+ "Translation Offset",
+ "Length"
+};
+
+static char *AcpiDmMemoryNames[] =
+{
+ "Range Minimum",
+ "Range Maximum",
+ "Alignment",
+ "Length"
+};
+
+
+/* Local prototypes */
+
+static void
+AcpiDmSpaceFlags (
+ UINT8 Flags);
+
+static void
+AcpiDmIoFlags (
+ UINT8 Flags);
+
+static void
+AcpiDmIoFlags2 (
+ UINT8 SpecificFlags);
+
+static void
+AcpiDmMemoryFlags (
+ UINT8 Flags,
+ UINT8 SpecificFlags);
+
+static void
+AcpiDmMemoryFlags2 (
+ UINT8 SpecificFlags);
+
+static void
+AcpiDmResourceSource (
+ AML_RESOURCE *Resource,
+ ACPI_SIZE MinimumLength,
+ UINT32 Length);
+
+static void
+AcpiDmAddressFields (
+ void *Source,
+ UINT8 Type,
+ UINT32 Level);
+
+static void
+AcpiDmAddressPrefix (
+ UINT8 Type);
+
+static void
+AcpiDmAddressCommon (
+ AML_RESOURCE *Resource,
+ UINT8 Type,
+ UINT32 Level);
+
+static void
+AcpiDmAddressFlags (
+ AML_RESOURCE *Resource);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmMemoryFields
+ *
+ * PARAMETERS: Source - Pointer to the contiguous data fields
+ * Type - 16 or 32 (bit)
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode fields common to Memory24 and Memory32 descriptors
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmMemoryFields (
+ void *Source,
+ UINT8 Type,
+ UINT32 Level)
+{
+ UINT32 i;
+
+
+ for (i = 0; i < 4; i++)
+ {
+ AcpiDmIndent (Level + 1);
+
+ switch (Type)
+ {
+ case 16:
+ AcpiDmDumpInteger16 (ACPI_CAST_PTR (UINT16, Source)[i],
+ AcpiDmMemoryNames[i]);
+ break;
+
+ case 32:
+ AcpiDmDumpInteger32 (ACPI_CAST_PTR (UINT32, Source)[i],
+ AcpiDmMemoryNames[i]);
+ break;
+
+ default:
+ return;
+ }
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmAddressFields
+ *
+ * PARAMETERS: Source - Pointer to the contiguous data fields
+ * Type - 16, 32, or 64 (bit)
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode fields common to address descriptors
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmAddressFields (
+ void *Source,
+ UINT8 Type,
+ UINT32 Level)
+{
+ UINT32 i;
+
+
+ AcpiOsPrintf ("\n");
+
+ for (i = 0; i < 5; i++)
+ {
+ AcpiDmIndent (Level + 1);
+
+ switch (Type)
+ {
+ case 16:
+ AcpiDmDumpInteger16 (ACPI_CAST_PTR (UINT16, Source)[i],
+ AcpiDmAddressNames[i]);
+ break;
+
+ case 32:
+ AcpiDmDumpInteger32 (ACPI_CAST_PTR (UINT32, Source)[i],
+ AcpiDmAddressNames[i]);
+ break;
+
+ case 64:
+ AcpiDmDumpInteger64 (ACPI_CAST_PTR (UINT64, Source)[i],
+ AcpiDmAddressNames[i]);
+ break;
+
+ default:
+ return;
+ }
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmAddressPrefix
+ *
+ * PARAMETERS: Type - Descriptor type
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Emit name prefix representing the address descriptor type
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmAddressPrefix (
+ UINT8 Type)
+{
+
+ switch (Type)
+ {
+ case ACPI_RESOURCE_TYPE_ADDRESS16:
+ AcpiOsPrintf ("Word");
+ break;
+
+ case ACPI_RESOURCE_TYPE_ADDRESS32:
+ AcpiOsPrintf ("DWord");
+ break;
+
+ case ACPI_RESOURCE_TYPE_ADDRESS64:
+ AcpiOsPrintf ("QWord");
+ break;
+
+ case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
+ AcpiOsPrintf ("Extended");
+ break;
+
+ default:
+ return;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmAddressCommon
+ *
+ * PARAMETERS: Resource - Raw AML descriptor
+ * Type - Descriptor type
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Emit common name and flag fields common to address descriptors
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmAddressCommon (
+ AML_RESOURCE *Resource,
+ UINT8 Type,
+ UINT32 Level)
+{
+ UINT8 ResourceType;
+ UINT8 SpecificFlags;
+ UINT8 Flags;
+
+
+ ResourceType = Resource->Address.ResourceType;
+ SpecificFlags = Resource->Address.SpecificFlags;
+ Flags = Resource->Address.Flags;
+
+ AcpiDmIndent (Level);
+
+ /* Validate ResourceType */
+
+ if ((ResourceType > 2) && (ResourceType < 0xC0))
+ {
+ AcpiOsPrintf ("/**** Invalid Resource Type: 0x%X ****/", ResourceType);
+ return;
+ }
+
+ /* Prefix is either Word, DWord, QWord, or Extended */
+
+ AcpiDmAddressPrefix (Type);
+
+ /* Resource Types above 0xC0 are vendor-defined */
+
+ if (ResourceType > 2)
+ {
+ AcpiOsPrintf ("Space (0x%2.2X, ", ResourceType);
+ AcpiDmSpaceFlags (Flags);
+ AcpiOsPrintf (" 0x%2.2X,", SpecificFlags);
+ return;
+ }
+
+ /* This is either a Memory, IO, or BusNumber descriptor (0,1,2) */
+
+ AcpiOsPrintf ("%s (", AcpiGbl_WordDecode [ResourceType & 0x3]);
+
+ /* Decode the general and type-specific flags */
+
+ if (ResourceType == ACPI_MEMORY_RANGE)
+ {
+ AcpiDmMemoryFlags (Flags, SpecificFlags);
+ }
+ else /* IO range or BusNumberRange */
+ {
+ AcpiDmIoFlags (Flags);
+ if (ResourceType == ACPI_IO_RANGE)
+ {
+ AcpiOsPrintf (" %s,", AcpiGbl_RngDecode [SpecificFlags & 0x3]);
+ }
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmAddressFlags
+ *
+ * PARAMETERS: Resource - Raw AML descriptor
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Emit flags common to address descriptors
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmAddressFlags (
+ AML_RESOURCE *Resource)
+{
+
+ if (Resource->Address.ResourceType == ACPI_IO_RANGE)
+ {
+ AcpiDmIoFlags2 (Resource->Address.SpecificFlags);
+ }
+ else if (Resource->Address.ResourceType == ACPI_MEMORY_RANGE)
+ {
+ AcpiDmMemoryFlags2 (Resource->Address.SpecificFlags);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmSpaceFlags
+ *
+ * PARAMETERS: Flags - Flag byte to be decoded
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode the flags specific to Space Address space descriptors
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmSpaceFlags (
+ UINT8 Flags)
+{
+
+ AcpiOsPrintf ("%s, %s, %s, %s,",
+ AcpiGbl_ConsumeDecode [(Flags & 1)],
+ AcpiGbl_DecDecode [(Flags & 0x2) >> 1],
+ AcpiGbl_MinDecode [(Flags & 0x4) >> 2],
+ AcpiGbl_MaxDecode [(Flags & 0x8) >> 3]);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmIoFlags
+ *
+ * PARAMETERS: Flags - Flag byte to be decoded
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode the flags specific to IO Address space descriptors
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmIoFlags (
+ UINT8 Flags)
+{
+ AcpiOsPrintf ("%s, %s, %s, %s,",
+ AcpiGbl_ConsumeDecode [(Flags & 1)],
+ AcpiGbl_MinDecode [(Flags & 0x4) >> 2],
+ AcpiGbl_MaxDecode [(Flags & 0x8) >> 3],
+ AcpiGbl_DecDecode [(Flags & 0x2) >> 1]);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmIoFlags2
+ *
+ * PARAMETERS: SpecificFlags - "Specific" flag byte to be decoded
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode the flags specific to IO Address space descriptors
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmIoFlags2 (
+ UINT8 SpecificFlags)
+{
+
+ AcpiOsPrintf (", %s",
+ AcpiGbl_TtpDecode [(SpecificFlags & 0x10) >> 4]);
+
+ /* TRS is only used if TTP is TypeTranslation */
+
+ if (SpecificFlags & 0x10)
+ {
+ AcpiOsPrintf (", %s",
+ AcpiGbl_TrsDecode [(SpecificFlags & 0x20) >> 5]);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmMemoryFlags
+ *
+ * PARAMETERS: Flags - Flag byte to be decoded
+ * SpecificFlags - "Specific" flag byte to be decoded
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode flags specific to Memory Address Space descriptors
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmMemoryFlags (
+ UINT8 Flags,
+ UINT8 SpecificFlags)
+{
+
+ AcpiOsPrintf ("%s, %s, %s, %s, %s, %s,",
+ AcpiGbl_ConsumeDecode [(Flags & 1)],
+ AcpiGbl_DecDecode [(Flags & 0x2) >> 1],
+ AcpiGbl_MinDecode [(Flags & 0x4) >> 2],
+ AcpiGbl_MaxDecode [(Flags & 0x8) >> 3],
+ AcpiGbl_MemDecode [(SpecificFlags & 0x6) >> 1],
+ AcpiGbl_RwDecode [(SpecificFlags & 0x1)]);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmMemoryFlags2
+ *
+ * PARAMETERS: SpecificFlags - "Specific" flag byte to be decoded
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode flags specific to Memory Address Space descriptors
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmMemoryFlags2 (
+ UINT8 SpecificFlags)
+{
+
+ AcpiOsPrintf (", %s, %s",
+ AcpiGbl_MtpDecode [(SpecificFlags & 0x18) >> 3],
+ AcpiGbl_TtpDecode [(SpecificFlags & 0x20) >> 5]);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmResourceSource
+ *
+ * PARAMETERS: Resource - Raw AML descriptor
+ * MinimumLength - descriptor length without optional fields
+ * ResourceLength
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump optional ResourceSource fields of an address descriptor
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmResourceSource (
+ AML_RESOURCE *Resource,
+ ACPI_SIZE MinimumTotalLength,
+ UINT32 ResourceLength)
+{
+ UINT8 *AmlResourceSource;
+ UINT32 TotalLength;
+
+
+ TotalLength = ResourceLength + sizeof (AML_RESOURCE_LARGE_HEADER);
+
+ /* Check if the optional ResourceSource fields are present */
+
+ if (TotalLength <= MinimumTotalLength)
+ {
+ /* The two optional fields are not used */
+
+ AcpiOsPrintf (",, ");
+ return;
+ }
+
+ /* Get a pointer to the ResourceSource */
+
+ AmlResourceSource = ACPI_ADD_PTR (UINT8, Resource, MinimumTotalLength);
+
+ /*
+ * Always emit the ResourceSourceIndex (Byte)
+ *
+ * NOTE: Some ASL compilers always create a 0 byte (in the AML) for the
+ * Index even if the String does not exist. Although this is in violation
+ * of the ACPI specification, it is very important to emit ASL code that
+ * can be compiled back to the identical AML. There may be fields and/or
+ * indexes into the resource template buffer that are compiled to absolute
+ * offsets, and these will be broken if the AML length is changed.
+ */
+ AcpiOsPrintf ("0x%2.2X,", (UINT32) AmlResourceSource[0]);
+
+ /* Make sure that the ResourceSource string exists before dumping it */
+
+ if (TotalLength > (MinimumTotalLength + 1))
+ {
+ AcpiOsPrintf (" ");
+ AcpiUtPrintString ((char *) &AmlResourceSource[1], ACPI_UINT8_MAX);
+ }
+
+ AcpiOsPrintf (", ");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmWordDescriptor
+ *
+ * PARAMETERS: Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a Word Address Space descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmWordDescriptor (
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ /* Dump resource name and flags */
+
+ AcpiDmAddressCommon (Resource, ACPI_RESOURCE_TYPE_ADDRESS16, Level);
+
+ /* Dump the 5 contiguous WORD values */
+
+ AcpiDmAddressFields (&Resource->Address16.Granularity, 16, Level);
+
+ /* The ResourceSource fields are optional */
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmResourceSource (Resource, sizeof (AML_RESOURCE_ADDRESS16), Length);
+
+ /* Insert a descriptor name */
+
+ AcpiDmDescriptorName ();
+
+ /* Type-specific flags */
+
+ AcpiDmAddressFlags (Resource);
+ AcpiOsPrintf (")\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDwordDescriptor
+ *
+ * PARAMETERS: Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a DWord Address Space descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDwordDescriptor (
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ /* Dump resource name and flags */
+
+ AcpiDmAddressCommon (Resource, ACPI_RESOURCE_TYPE_ADDRESS32, Level);
+
+ /* Dump the 5 contiguous DWORD values */
+
+ AcpiDmAddressFields (&Resource->Address32.Granularity, 32, Level);
+
+ /* The ResourceSource fields are optional */
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmResourceSource (Resource, sizeof (AML_RESOURCE_ADDRESS32), Length);
+
+ /* Insert a descriptor name */
+
+ AcpiDmDescriptorName ();
+
+ /* Type-specific flags */
+
+ AcpiDmAddressFlags (Resource);
+ AcpiOsPrintf (")\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmQwordDescriptor
+ *
+ * PARAMETERS: Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a QWord Address Space descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmQwordDescriptor (
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ /* Dump resource name and flags */
+
+ AcpiDmAddressCommon (Resource, ACPI_RESOURCE_TYPE_ADDRESS64, Level);
+
+ /* Dump the 5 contiguous QWORD values */
+
+ AcpiDmAddressFields (&Resource->Address64.Granularity, 64, Level);
+
+ /* The ResourceSource fields are optional */
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmResourceSource (Resource, sizeof (AML_RESOURCE_ADDRESS64), Length);
+
+ /* Insert a descriptor name */
+
+ AcpiDmDescriptorName ();
+
+ /* Type-specific flags */
+
+ AcpiDmAddressFlags (Resource);
+ AcpiOsPrintf (")\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmExtendedDescriptor
+ *
+ * PARAMETERS: Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a Extended Address Space descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmExtendedDescriptor (
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ /* Dump resource name and flags */
+
+ AcpiDmAddressCommon (Resource, ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64, Level);
+
+ /* Dump the 5 contiguous QWORD values */
+
+ AcpiDmAddressFields (&Resource->ExtAddress64.Granularity, 64, Level);
+
+ /* Extra field for this descriptor only */
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDumpInteger64 (Resource->ExtAddress64.TypeSpecific,
+ "Type-Specific Attributes");
+
+ /* Insert a descriptor name */
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDescriptorName ();
+
+ /* Type-specific flags */
+
+ AcpiDmAddressFlags (Resource);
+ AcpiOsPrintf (")\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmMemory24Descriptor
+ *
+ * PARAMETERS: Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a Memory24 descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmMemory24Descriptor (
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ /* Dump name and read/write flag */
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("Memory24 (%s,\n",
+ AcpiGbl_RwDecode [Resource->Memory24.Flags & 1]);
+
+ /* Dump the 4 contiguous WORD values */
+
+ AcpiDmMemoryFields (&Resource->Memory24.Minimum, 16, Level);
+
+ /* Insert a descriptor name */
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDescriptorName ();
+ AcpiOsPrintf (")\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmMemory32Descriptor
+ *
+ * PARAMETERS: Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a Memory32 descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmMemory32Descriptor (
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ /* Dump name and read/write flag */
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("Memory32 (%s,\n",
+ AcpiGbl_RwDecode [Resource->Memory32.Flags & 1]);
+
+ /* Dump the 4 contiguous DWORD values */
+
+ AcpiDmMemoryFields (&Resource->Memory32.Minimum, 32, Level);
+
+ /* Insert a descriptor name */
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDescriptorName ();
+ AcpiOsPrintf (")\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmFixedMemory32Descriptor
+ *
+ * PARAMETERS: Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a Fixed Memory32 descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmFixedMemory32Descriptor (
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ /* Dump name and read/write flag */
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("Memory32Fixed (%s,\n",
+ AcpiGbl_RwDecode [Resource->FixedMemory32.Flags & 1]);
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDumpInteger32 (Resource->FixedMemory32.Address, "Address Base");
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDumpInteger32 (Resource->FixedMemory32.AddressLength, "Address Length");
+
+ /* Insert a descriptor name */
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDescriptorName ();
+ AcpiOsPrintf (")\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmGenericRegisterDescriptor
+ *
+ * PARAMETERS: Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a Generic Register descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmGenericRegisterDescriptor (
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("Register (");
+ AcpiDmAddressSpace (Resource->GenericReg.AddressSpaceId);
+ AcpiOsPrintf ("\n");
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDumpInteger8 (Resource->GenericReg.BitWidth, "Bit Width");
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDumpInteger8 (Resource->GenericReg.BitOffset, "Bit Offset");
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDumpInteger64 (Resource->GenericReg.Address, "Address");
+
+ /* Optional field for ACPI 3.0 */
+
+ AcpiDmIndent (Level + 1);
+ if (Resource->GenericReg.AccessSize)
+ {
+ AcpiOsPrintf ("0x%2.2X, // %s\n",
+ Resource->GenericReg.AccessSize, "Access Size");
+ AcpiDmIndent (Level + 1);
+ }
+ else
+ {
+ AcpiOsPrintf (",");
+ }
+
+ /* DescriptorName was added for ACPI 3.0+ */
+
+ AcpiDmDescriptorName ();
+ AcpiOsPrintf (")\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmInterruptDescriptor
+ *
+ * PARAMETERS: Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a extended Interrupt descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmInterruptDescriptor (
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+ UINT32 i;
+
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("Interrupt (%s, %s, %s, %s, ",
+ AcpiGbl_ConsumeDecode [(Resource->ExtendedIrq.Flags & 1)],
+ AcpiGbl_HeDecode [(Resource->ExtendedIrq.Flags >> 1) & 1],
+ AcpiGbl_LlDecode [(Resource->ExtendedIrq.Flags >> 2) & 1],
+ AcpiGbl_ShrDecode [(Resource->ExtendedIrq.Flags >> 3) & 1]);
+
+ /*
+ * The ResourceSource fields are optional and appear after the interrupt
+ * list. Must compute length based on length of the list. First xrupt
+ * is included in the struct (reason for -1 below)
+ */
+ AcpiDmResourceSource (Resource,
+ sizeof (AML_RESOURCE_EXTENDED_IRQ) +
+ ((UINT32) Resource->ExtendedIrq.InterruptCount - 1) * sizeof (UINT32),
+ Resource->ExtendedIrq.ResourceLength);
+
+ /* Insert a descriptor name */
+
+ AcpiDmDescriptorName ();
+ AcpiOsPrintf (")\n");
+
+ /* Dump the interrupt list */
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("{\n");
+ for (i = 0; i < Resource->ExtendedIrq.InterruptCount; i++)
+ {
+ AcpiDmIndent (Level + 1);
+ AcpiOsPrintf ("0x%8.8X,\n",
+ (UINT32) Resource->ExtendedIrq.Interrupts[i]);
+ }
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("}\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmVendorCommon
+ *
+ * PARAMETERS: Name - Descriptor name suffix
+ * ByteData - Pointer to the vendor byte data
+ * Length - Length of the byte data
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a Vendor descriptor, both Large and Small
+ *
+ ******************************************************************************/
+
+void
+AcpiDmVendorCommon (
+ char *Name,
+ UINT8 *ByteData,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ /* Dump macro name */
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("Vendor%s (", Name);
+
+ /* Insert a descriptor name */
+
+ AcpiDmDescriptorName ();
+ AcpiOsPrintf (") // Length = 0x%.2X\n", Length);
+
+ /* Dump the vendor bytes */
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("{\n");
+
+ AcpiDmDisasmByteList (Level + 1, ByteData, Length);
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("}\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmVendorLargeDescriptor
+ *
+ * PARAMETERS: Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a Vendor Large descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmVendorLargeDescriptor (
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ AcpiDmVendorCommon ("Long ",
+ ACPI_ADD_PTR (UINT8, Resource, sizeof (AML_RESOURCE_LARGE_HEADER)),
+ Length, Level);
+}
+
+#endif
diff --git a/source/components/disassembler/dmresrcl2.c b/source/components/disassembler/dmresrcl2.c
new file mode 100644
index 000000000000..e79307ee72d0
--- /dev/null
+++ b/source/components/disassembler/dmresrcl2.c
@@ -0,0 +1,700 @@
+/*******************************************************************************
+ *
+ * Module Name: dmresrcl2.c - "Large" Resource Descriptor disassembly (#2)
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2012, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include "acpi.h"
+#include "accommon.h"
+#include "acdisasm.h"
+
+
+#ifdef ACPI_DISASSEMBLER
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("dbresrcl2")
+
+/* Local prototypes */
+
+static void
+AcpiDmI2cSerialBusDescriptor (
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level);
+
+static void
+AcpiDmSpiSerialBusDescriptor (
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level);
+
+static void
+AcpiDmUartSerialBusDescriptor (
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level);
+
+static void
+AcpiDmGpioCommon (
+ AML_RESOURCE *Resource,
+ UINT32 Level);
+
+static void
+AcpiDmDumpRawDataBuffer (
+ UINT8 *Buffer,
+ UINT32 Length,
+ UINT32 Level);
+
+
+/* Dispatch table for the serial bus descriptors */
+
+static ACPI_RESOURCE_HANDLER SerialBusResourceDispatch [] =
+{
+ NULL,
+ AcpiDmI2cSerialBusDescriptor,
+ AcpiDmSpiSerialBusDescriptor,
+ AcpiDmUartSerialBusDescriptor
+};
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDumpRawDataBuffer
+ *
+ * PARAMETERS: Buffer - Pointer to the data bytes
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump a data buffer as a RawDataBuffer() object. Used for
+ * vendor data bytes.
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmDumpRawDataBuffer (
+ UINT8 *Buffer,
+ UINT32 Length,
+ UINT32 Level)
+{
+ UINT32 Index;
+ UINT32 i;
+ UINT32 j;
+
+
+ if (!Length)
+ {
+ return;
+ }
+
+ AcpiOsPrintf ("RawDataBuffer (0x%.2X) // Vendor Data", Length);
+
+ AcpiOsPrintf ("\n");
+ AcpiDmIndent (Level + 1);
+ AcpiOsPrintf ("{\n");
+ AcpiDmIndent (Level + 2);
+
+ for (i = 0; i < Length;)
+ {
+ for (j = 0; j < 8; j++)
+ {
+ Index = i + j;
+ if (Index >= Length)
+ {
+ goto Finish;
+ }
+
+ AcpiOsPrintf ("0x%2.2X", Buffer[Index]);
+ if ((Index + 1) >= Length)
+ {
+ goto Finish;
+ }
+
+ AcpiOsPrintf (", ");
+ }
+ AcpiOsPrintf ("\n");
+ AcpiDmIndent (Level + 2);
+
+ i += 8;
+ }
+
+Finish:
+ AcpiOsPrintf ("\n");
+ AcpiDmIndent (Level + 1);
+ AcpiOsPrintf ("}");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmGpioCommon
+ *
+ * PARAMETERS: Resource - Pointer to the resource descriptor
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode common parts of a GPIO Interrupt descriptor
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmGpioCommon (
+ AML_RESOURCE *Resource,
+ UINT32 Level)
+{
+ UINT32 PinCount;
+ UINT16 *PinList;
+ UINT8 *VendorData;
+ UINT32 i;
+
+
+ /* ResourceSource, ResourceSourceIndex, ResourceType */
+
+ AcpiDmIndent (Level + 1);
+ if (Resource->Gpio.ResSourceOffset)
+ {
+ AcpiUtPrintString (
+ ACPI_ADD_PTR (char, Resource, Resource->Gpio.ResSourceOffset),
+ ACPI_UINT8_MAX);
+ }
+
+ AcpiOsPrintf (", ");
+ AcpiOsPrintf ("0x%2.2X, ", Resource->Gpio.ResSourceIndex);
+ AcpiOsPrintf ("%s, ",
+ AcpiGbl_ConsumeDecode [(Resource->Gpio.Flags & 1)]);
+
+ /* Insert a descriptor name */
+
+ AcpiDmDescriptorName ();
+ AcpiOsPrintf (",");
+
+ /* Dump the vendor data */
+
+ if (Resource->Gpio.VendorOffset)
+ {
+ AcpiOsPrintf ("\n");
+ AcpiDmIndent (Level + 1);
+ VendorData = ACPI_ADD_PTR (UINT8, Resource,
+ Resource->Gpio.VendorOffset);
+
+ AcpiDmDumpRawDataBuffer (VendorData,
+ Resource->Gpio.VendorLength, Level);
+ }
+
+ AcpiOsPrintf (")\n");
+
+ /* Dump the interrupt list */
+
+ AcpiDmIndent (Level + 1);
+ AcpiOsPrintf ("{ // Pin list\n");
+
+ PinCount = ((UINT32) (Resource->Gpio.ResSourceOffset -
+ Resource->Gpio.PinTableOffset)) /
+ sizeof (UINT16);
+
+ PinList = (UINT16 *) ACPI_ADD_PTR (char, Resource,
+ Resource->Gpio.PinTableOffset);
+
+ for (i = 0; i < PinCount; i++)
+ {
+ AcpiDmIndent (Level + 2);
+ AcpiOsPrintf ("0x%4.4X%s\n", PinList[i], ((i + 1) < PinCount) ? "," : "");
+ }
+
+ AcpiDmIndent (Level + 1);
+ AcpiOsPrintf ("}\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmGpioIntDescriptor
+ *
+ * PARAMETERS: Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a GPIO Interrupt descriptor
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmGpioIntDescriptor (
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ /* Dump the GpioInt-specific portion of the descriptor */
+
+ /* EdgeLevel, ActiveLevel, Shared */
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("GpioInt (%s, %s, %s, ",
+ AcpiGbl_HeDecode [(Resource->Gpio.IntFlags & 1)],
+ AcpiGbl_LlDecode [(Resource->Gpio.IntFlags >> 1) & 1],
+ AcpiGbl_ShrDecode [(Resource->Gpio.IntFlags >> 3) & 1]);
+
+ /* PinConfig, DebounceTimeout */
+
+ if (Resource->Gpio.PinConfig <= 3)
+ {
+ AcpiOsPrintf ("%s, ",
+ AcpiGbl_PpcDecode[Resource->Gpio.PinConfig]);
+ }
+ else
+ {
+ AcpiOsPrintf ("0x%2.2X, ", Resource->Gpio.PinConfig);
+ }
+ AcpiOsPrintf ("0x%4.4X,\n", Resource->Gpio.DebounceTimeout);
+
+ /* Dump the GpioInt/GpioIo common portion of the descriptor */
+
+ AcpiDmGpioCommon (Resource, Level);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmGpioIoDescriptor
+ *
+ * PARAMETERS: Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a GPIO Interrupt descriptor
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmGpioIoDescriptor (
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ /* Dump the GpioIo-specific portion of the descriptor */
+
+ /* Shared, PinConfig */
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("GpioIo (%s, ",
+ AcpiGbl_ShrDecode [(Resource->Gpio.IntFlags >> 3) & 1]);
+
+ if (Resource->Gpio.PinConfig <= 3)
+ {
+ AcpiOsPrintf ("%s, ",
+ AcpiGbl_PpcDecode[Resource->Gpio.PinConfig]);
+ }
+ else
+ {
+ AcpiOsPrintf ("0x%2.2X, ", Resource->Gpio.PinConfig);
+ }
+
+ /* DebounceTimeout, DriveStrength, IoRestriction */
+
+ AcpiOsPrintf ("0x%4.4X, ", Resource->Gpio.DebounceTimeout);
+ AcpiOsPrintf ("0x%4.4X, ", Resource->Gpio.DriveStrength);
+ AcpiOsPrintf ("%s,\n",
+ AcpiGbl_IorDecode [Resource->Gpio.IntFlags & 3]);
+
+ /* Dump the GpioInt/GpioIo common portion of the descriptor */
+
+ AcpiDmGpioCommon (Resource, Level);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmGpioDescriptor
+ *
+ * PARAMETERS: Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a GpioInt/GpioIo GPIO Interrupt/IO descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmGpioDescriptor (
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+ UINT8 ConnectionType;
+
+
+ ConnectionType = Resource->Gpio.ConnectionType;
+
+ switch (ConnectionType)
+ {
+ case AML_RESOURCE_GPIO_TYPE_INT:
+ AcpiDmGpioIntDescriptor (Resource, Length, Level);
+ break;
+
+ case AML_RESOURCE_GPIO_TYPE_IO:
+ AcpiDmGpioIoDescriptor (Resource, Length, Level);
+ break;
+
+ default:
+ AcpiOsPrintf ("Unknown GPIO type\n");
+ break;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDumpSerialBusVendorData
+ *
+ * PARAMETERS: Resource - Pointer to the resource descriptor
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Dump optional serial bus vendor data
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmDumpSerialBusVendorData (
+ AML_RESOURCE *Resource,
+ UINT32 Level)
+{
+ UINT8 *VendorData;
+ UINT32 VendorLength;
+
+
+ /* Get the (optional) vendor data and length */
+
+ switch (Resource->CommonSerialBus.Type)
+ {
+ case AML_RESOURCE_I2C_SERIALBUSTYPE:
+
+ VendorLength = Resource->CommonSerialBus.TypeDataLength -
+ AML_RESOURCE_I2C_MIN_DATA_LEN;
+
+ VendorData = ACPI_ADD_PTR (UINT8, Resource,
+ sizeof (AML_RESOURCE_I2C_SERIALBUS));
+ break;
+
+ case AML_RESOURCE_SPI_SERIALBUSTYPE:
+
+ VendorLength = Resource->CommonSerialBus.TypeDataLength -
+ AML_RESOURCE_SPI_MIN_DATA_LEN;
+
+ VendorData = ACPI_ADD_PTR (UINT8, Resource,
+ sizeof (AML_RESOURCE_SPI_SERIALBUS));
+ break;
+
+ case AML_RESOURCE_UART_SERIALBUSTYPE:
+
+ VendorLength = Resource->CommonSerialBus.TypeDataLength -
+ AML_RESOURCE_UART_MIN_DATA_LEN;
+
+ VendorData = ACPI_ADD_PTR (UINT8, Resource,
+ sizeof (AML_RESOURCE_UART_SERIALBUS));
+ break;
+
+ default:
+ return;
+ }
+
+ /* Dump the vendor bytes as a RawDataBuffer object */
+
+ AcpiDmDumpRawDataBuffer (VendorData, VendorLength, Level);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmI2cSerialBusDescriptor
+ *
+ * PARAMETERS: Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a I2C serial bus descriptor
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmI2cSerialBusDescriptor (
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+ UINT32 ResourceSourceOffset;
+
+
+ /* SlaveAddress, SlaveMode, ConnectionSpeed, AddressingMode */
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("I2cSerialBus (0x%4.4X, %s, 0x%8.8X,\n",
+ Resource->I2cSerialBus.SlaveAddress,
+ AcpiGbl_SmDecode [(Resource->I2cSerialBus.Flags & 1)],
+ Resource->I2cSerialBus.ConnectionSpeed);
+
+ AcpiDmIndent (Level + 1);
+ AcpiOsPrintf ("%s, ",
+ AcpiGbl_AmDecode [(Resource->I2cSerialBus.TypeSpecificFlags & 1)]);
+
+ /* ResourceSource is a required field */
+
+ ResourceSourceOffset = sizeof (AML_RESOURCE_COMMON_SERIALBUS) +
+ Resource->CommonSerialBus.TypeDataLength;
+
+ AcpiUtPrintString (
+ ACPI_ADD_PTR (char, Resource, ResourceSourceOffset),
+ ACPI_UINT8_MAX);
+
+ /* ResourceSourceIndex, ResourceUsage */
+
+ AcpiOsPrintf (",\n");
+ AcpiDmIndent (Level + 1);
+ AcpiOsPrintf ("0x%2.2X, ", Resource->I2cSerialBus.ResSourceIndex);
+
+ AcpiOsPrintf ("%s, ",
+ AcpiGbl_ConsumeDecode [(Resource->I2cSerialBus.Flags >> 1) & 1]);
+
+ /* Insert a descriptor name */
+
+ AcpiDmDescriptorName ();
+ AcpiOsPrintf (",\n");
+
+ /* Dump the vendor data */
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDumpSerialBusVendorData (Resource, Level);
+ AcpiOsPrintf (")\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmSpiSerialBusDescriptor
+ *
+ * PARAMETERS: Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a SPI serial bus descriptor
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmSpiSerialBusDescriptor (
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+ UINT32 ResourceSourceOffset;
+
+
+ /* DeviceSelection, DeviceSelectionPolarity, WireMode, DataBitLength */
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("SpiSerialBus (0x%4.4X, %s, %s, 0x%2.2X,\n",
+ Resource->SpiSerialBus.DeviceSelection,
+ AcpiGbl_DpDecode [(Resource->SpiSerialBus.TypeSpecificFlags >> 1) & 1],
+ AcpiGbl_WmDecode [(Resource->SpiSerialBus.TypeSpecificFlags & 1)],
+ Resource->SpiSerialBus.DataBitLength);
+
+ /* SlaveMode, ConnectionSpeed, ClockPolarity, ClockPhase */
+
+ AcpiDmIndent (Level + 1);
+ AcpiOsPrintf ("%s, 0x%8.8X, %s,\n",
+ AcpiGbl_SmDecode [(Resource->SpiSerialBus.Flags & 1)],
+ Resource->SpiSerialBus.ConnectionSpeed,
+ AcpiGbl_CpoDecode [(Resource->SpiSerialBus.ClockPolarity & 1)]);
+
+ AcpiDmIndent (Level + 1);
+ AcpiOsPrintf ("%s, ",
+ AcpiGbl_CphDecode [(Resource->SpiSerialBus.ClockPhase & 1)]);
+
+ /* ResourceSource is a required field */
+
+ ResourceSourceOffset = sizeof (AML_RESOURCE_COMMON_SERIALBUS) +
+ Resource->CommonSerialBus.TypeDataLength;
+
+ AcpiUtPrintString (
+ ACPI_ADD_PTR (char, Resource, ResourceSourceOffset),
+ ACPI_UINT8_MAX);
+
+ /* ResourceSourceIndex, ResourceUsage */
+
+ AcpiOsPrintf (",\n");
+ AcpiDmIndent (Level + 1);
+ AcpiOsPrintf ("0x%2.2X, ", Resource->SpiSerialBus.ResSourceIndex);
+
+ AcpiOsPrintf ("%s, ",
+ AcpiGbl_ConsumeDecode [(Resource->SpiSerialBus.Flags >> 1) & 1]);
+
+ /* Insert a descriptor name */
+
+ AcpiDmDescriptorName ();
+ AcpiOsPrintf (",\n");
+
+ /* Dump the vendor data */
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDumpSerialBusVendorData (Resource, Level);
+ AcpiOsPrintf (")\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmUartSerialBusDescriptor
+ *
+ * PARAMETERS: Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a UART serial bus descriptor
+ *
+ ******************************************************************************/
+
+static void
+AcpiDmUartSerialBusDescriptor (
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+ UINT32 ResourceSourceOffset;
+
+
+ /* ConnectionSpeed, BitsPerByte, StopBits */
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("UartSerialBus (0x%8.8X, %s, %s,\n",
+ Resource->UartSerialBus.DefaultBaudRate,
+ AcpiGbl_BpbDecode [(Resource->UartSerialBus.TypeSpecificFlags >> 4) & 3],
+ AcpiGbl_SbDecode [(Resource->UartSerialBus.TypeSpecificFlags >> 2) & 3]);
+
+ /* LinesInUse, IsBigEndian, Parity, FlowControl */
+
+ AcpiDmIndent (Level + 1);
+ AcpiOsPrintf ("0x%2.2X, %s, %s, %s,\n",
+ Resource->UartSerialBus.LinesEnabled,
+ AcpiGbl_EdDecode [(Resource->UartSerialBus.TypeSpecificFlags >> 7) & 1],
+ AcpiGbl_PtDecode [Resource->UartSerialBus.Parity & 7],
+ AcpiGbl_FcDecode [Resource->UartSerialBus.TypeSpecificFlags & 3]);
+
+ /* ReceiveBufferSize, TransmitBufferSize */
+
+ AcpiDmIndent (Level + 1);
+ AcpiOsPrintf ("0x%4.4X, 0x%4.4X, ",
+ Resource->UartSerialBus.RxFifoSize,
+ Resource->UartSerialBus.TxFifoSize);
+
+ /* ResourceSource is a required field */
+
+ ResourceSourceOffset = sizeof (AML_RESOURCE_COMMON_SERIALBUS) +
+ Resource->CommonSerialBus.TypeDataLength;
+
+ AcpiUtPrintString (
+ ACPI_ADD_PTR (char, Resource, ResourceSourceOffset),
+ ACPI_UINT8_MAX);
+
+ /* ResourceSourceIndex, ResourceUsage */
+
+ AcpiOsPrintf (",\n");
+ AcpiDmIndent (Level + 1);
+ AcpiOsPrintf ("0x%2.2X, ", Resource->UartSerialBus.ResSourceIndex);
+
+ AcpiOsPrintf ("%s, ",
+ AcpiGbl_ConsumeDecode [(Resource->UartSerialBus.Flags >> 1) & 1]);
+
+ /* Insert a descriptor name */
+
+ AcpiDmDescriptorName ();
+ AcpiOsPrintf (",\n");
+
+ /* Dump the vendor data */
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDumpSerialBusVendorData (Resource, Level);
+ AcpiOsPrintf (")\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmSerialBusDescriptor
+ *
+ * PARAMETERS: Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a I2C/SPI/UART serial bus descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmSerialBusDescriptor (
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ SerialBusResourceDispatch [Resource->CommonSerialBus.Type] (
+ Resource, Length, Level);
+}
+
+#endif
+
diff --git a/source/components/disassembler/dmresrcs.c b/source/components/disassembler/dmresrcs.c
new file mode 100644
index 000000000000..32759d991bb5
--- /dev/null
+++ b/source/components/disassembler/dmresrcs.c
@@ -0,0 +1,358 @@
+/*******************************************************************************
+ *
+ * Module Name: dmresrcs.c - "Small" Resource Descriptor disassembly
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2012, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include "acpi.h"
+#include "accommon.h"
+#include "acdisasm.h"
+
+
+#ifdef ACPI_DISASSEMBLER
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("dbresrcs")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmIrqDescriptor
+ *
+ * PARAMETERS: Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a IRQ descriptor, either Irq() or IrqNoFlags()
+ *
+ ******************************************************************************/
+
+void
+AcpiDmIrqDescriptor (
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("%s (",
+ AcpiGbl_IrqDecode [Length & 1]);
+
+ /* Decode flags byte if present */
+
+ if (Length & 1)
+ {
+ AcpiOsPrintf ("%s, %s, %s, ",
+ AcpiGbl_HeDecode [Resource->Irq.Flags & 1],
+ AcpiGbl_LlDecode [(Resource->Irq.Flags >> 3) & 1],
+ AcpiGbl_ShrDecode [(Resource->Irq.Flags >> 4) & 1]);
+ }
+
+ /* Insert a descriptor name */
+
+ AcpiDmDescriptorName ();
+ AcpiOsPrintf (")\n");
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmBitList (Resource->Irq.IrqMask);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDmaDescriptor
+ *
+ * PARAMETERS: Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a DMA descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDmaDescriptor (
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("DMA (%s, %s, %s, ",
+ AcpiGbl_TypDecode [(Resource->Dma.Flags >> 5) & 3],
+ AcpiGbl_BmDecode [(Resource->Dma.Flags >> 2) & 1],
+ AcpiGbl_SizDecode [(Resource->Dma.Flags >> 0) & 3]);
+
+ /* Insert a descriptor name */
+
+ AcpiDmDescriptorName ();
+ AcpiOsPrintf (")\n");
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmBitList (Resource->Dma.DmaChannelMask);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmFixedDmaDescriptor
+ *
+ * PARAMETERS: Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a FixedDMA descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmFixedDmaDescriptor (
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("FixedDMA (0x%4.4X, 0x%4.4X, ",
+ Resource->FixedDma.RequestLines,
+ Resource->FixedDma.Channels);
+
+ if (Resource->FixedDma.Width <= 5)
+ {
+ AcpiOsPrintf ("%s, ",
+ AcpiGbl_DtsDecode [Resource->FixedDma.Width]);
+ }
+ else
+ {
+ AcpiOsPrintf ("%X /* INVALID DMA WIDTH */, ", Resource->FixedDma.Width);
+ }
+
+ /* Insert a descriptor name */
+
+ AcpiDmDescriptorName ();
+ AcpiOsPrintf (")\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmIoDescriptor
+ *
+ * PARAMETERS: Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode an IO descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmIoDescriptor (
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("IO (%s,\n",
+ AcpiGbl_IoDecode [(Resource->Io.Flags & 1)]);
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDumpInteger16 (Resource->Io.Minimum, "Range Minimum");
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDumpInteger16 (Resource->Io.Maximum, "Range Maximum");
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDumpInteger8 (Resource->Io.Alignment, "Alignment");
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDumpInteger8 (Resource->Io.AddressLength, "Length");
+
+ /* Insert a descriptor name */
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDescriptorName ();
+ AcpiOsPrintf (")\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmFixedIoDescriptor
+ *
+ * PARAMETERS: Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a Fixed IO descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmFixedIoDescriptor (
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("FixedIO (\n");
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDumpInteger16 (Resource->FixedIo.Address, "Address");
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDumpInteger8 (Resource->FixedIo.AddressLength, "Length");
+
+ /* Insert a descriptor name */
+
+ AcpiDmIndent (Level + 1);
+ AcpiDmDescriptorName ();
+ AcpiOsPrintf (")\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmStartDependentDescriptor
+ *
+ * PARAMETERS: Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a Start Dependendent functions descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmStartDependentDescriptor (
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ AcpiDmIndent (Level);
+
+ if (Length & 1)
+ {
+ AcpiOsPrintf ("StartDependentFn (0x%2.2X, 0x%2.2X)\n",
+ (UINT32) Resource->StartDpf.Flags & 3,
+ (UINT32) (Resource->StartDpf.Flags >> 2) & 3);
+ }
+ else
+ {
+ AcpiOsPrintf ("StartDependentFnNoPri ()\n");
+ }
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("{\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmEndDependentDescriptor
+ *
+ * PARAMETERS: Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode an End Dependent functions descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmEndDependentDescriptor (
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("}\n");
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("EndDependentFn ()\n");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmVendorSmallDescriptor
+ *
+ * PARAMETERS: Resource - Pointer to the resource descriptor
+ * Length - Length of the descriptor in bytes
+ * Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode a Vendor Small Descriptor
+ *
+ ******************************************************************************/
+
+void
+AcpiDmVendorSmallDescriptor (
+ AML_RESOURCE *Resource,
+ UINT32 Length,
+ UINT32 Level)
+{
+
+ AcpiDmVendorCommon ("Short",
+ ACPI_ADD_PTR (UINT8, Resource, sizeof (AML_RESOURCE_SMALL_HEADER)),
+ Length, Level);
+}
+
+#endif
+
diff --git a/source/components/disassembler/dmutils.c b/source/components/disassembler/dmutils.c
new file mode 100644
index 000000000000..ce3443ec3fc1
--- /dev/null
+++ b/source/components/disassembler/dmutils.c
@@ -0,0 +1,321 @@
+/*******************************************************************************
+ *
+ * Module Name: dmutils - AML disassembler utilities
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2012, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include "acpi.h"
+#include "accommon.h"
+#include "amlcode.h"
+#include "acdisasm.h"
+
+#ifdef ACPI_ASL_COMPILER
+#include <acnamesp.h>
+#endif
+
+#ifdef ACPI_DISASSEMBLER
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("dmutils")
+
+
+/* Data used in keeping track of fields */
+#if 0
+const char *AcpiGbl_FENames[] =
+{
+ "skip",
+ "?access?"
+}; /* FE = Field Element */
+#endif
+
+/* Operators for Match() */
+
+const char *AcpiGbl_MatchOps[] =
+{
+ "MTR",
+ "MEQ",
+ "MLE",
+ "MLT",
+ "MGE",
+ "MGT"
+};
+
+/* Access type decoding */
+
+const char *AcpiGbl_AccessTypes[] =
+{
+ "AnyAcc",
+ "ByteAcc",
+ "WordAcc",
+ "DWordAcc",
+ "QWordAcc",
+ "BufferAcc",
+ "InvalidAccType",
+ "InvalidAccType"
+};
+
+/* Lock rule decoding */
+
+const char *AcpiGbl_LockRule[] =
+{
+ "NoLock",
+ "Lock"
+};
+
+/* Update rule decoding */
+
+const char *AcpiGbl_UpdateRules[] =
+{
+ "Preserve",
+ "WriteAsOnes",
+ "WriteAsZeros",
+ "InvalidUpdateRule"
+};
+
+/* Strings used to decode resource descriptors */
+
+const char *AcpiGbl_WordDecode[] =
+{
+ "Memory",
+ "IO",
+ "BusNumber",
+ "UnknownResourceType"
+};
+
+const char *AcpiGbl_IrqDecode[] =
+{
+ "IRQNoFlags",
+ "IRQ"
+};
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDecodeAttribute
+ *
+ * PARAMETERS: Attribute - Attribute field of AccessAs keyword
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decode the AccessAs attribute byte. (Mostly SMBus and
+ * GenericSerialBus stuff.)
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDecodeAttribute (
+ UINT8 Attribute)
+{
+
+ switch (Attribute)
+ {
+ case AML_FIELD_ATTRIB_QUICK:
+
+ AcpiOsPrintf ("AttribQuick");
+ break;
+
+ case AML_FIELD_ATTRIB_SEND_RCV:
+
+ AcpiOsPrintf ("AttribSendReceive");
+ break;
+
+ case AML_FIELD_ATTRIB_BYTE:
+
+ AcpiOsPrintf ("AttribByte");
+ break;
+
+ case AML_FIELD_ATTRIB_WORD:
+
+ AcpiOsPrintf ("AttribWord");
+ break;
+
+ case AML_FIELD_ATTRIB_BLOCK:
+
+ AcpiOsPrintf ("AttribBlock");
+ break;
+
+ case AML_FIELD_ATTRIB_MULTIBYTE:
+
+ AcpiOsPrintf ("AttribBytes");
+ break;
+
+ case AML_FIELD_ATTRIB_WORD_CALL:
+
+ AcpiOsPrintf ("AttribProcessCall");
+ break;
+
+ case AML_FIELD_ATTRIB_BLOCK_CALL:
+
+ AcpiOsPrintf ("AttribBlockProcessCall");
+ break;
+
+ case AML_FIELD_ATTRIB_RAW_BYTES:
+
+ AcpiOsPrintf ("AttribRawBytes");
+ break;
+
+ case AML_FIELD_ATTRIB_RAW_PROCESS:
+
+ AcpiOsPrintf ("AttribRawProcessBytes");
+ break;
+
+ default:
+
+ /* A ByteConst is allowed by the grammar */
+
+ AcpiOsPrintf ("0x%2.2X", Attribute);
+ break;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmIndent
+ *
+ * PARAMETERS: Level - Current source code indentation level
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Indent 4 spaces per indentation level.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmIndent (
+ UINT32 Level)
+{
+
+ if (!Level)
+ {
+ return;
+ }
+
+ AcpiOsPrintf ("%*.s", ACPI_MUL_4 (Level), " ");
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmCommaIfListMember
+ *
+ * PARAMETERS: Op - Current operator/operand
+ *
+ * RETURN: TRUE if a comma was inserted
+ *
+ * DESCRIPTION: Insert a comma if this Op is a member of an argument list.
+ *
+ ******************************************************************************/
+
+BOOLEAN
+AcpiDmCommaIfListMember (
+ ACPI_PARSE_OBJECT *Op)
+{
+
+ if (!Op->Common.Next)
+ {
+ return FALSE;
+ }
+
+ if (AcpiDmListType (Op->Common.Parent) & BLOCK_COMMA_LIST)
+ {
+ /* Check for a NULL target operand */
+
+ if ((Op->Common.Next->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&
+ (!Op->Common.Next->Common.Value.String))
+ {
+ /*
+ * To handle the Divide() case where there are two optional
+ * targets, look ahead one more op. If null, this null target
+ * is the one and only target -- no comma needed. Otherwise,
+ * we need a comma to prepare for the next target.
+ */
+ if (!Op->Common.Next->Common.Next)
+ {
+ return FALSE;
+ }
+ }
+
+ if ((Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST) &&
+ (!(Op->Common.Next->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)))
+ {
+ return FALSE;
+ }
+
+ AcpiOsPrintf (", ");
+ return (TRUE);
+ }
+
+ else if ((Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST) &&
+ (Op->Common.Next->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST))
+ {
+ AcpiOsPrintf (", ");
+ return (TRUE);
+ }
+
+ return (FALSE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmCommaIfFieldMember
+ *
+ * PARAMETERS: Op - Current operator/operand
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Insert a comma if this Op is a member of a Field argument list.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmCommaIfFieldMember (
+ ACPI_PARSE_OBJECT *Op)
+{
+
+ if (Op->Common.Next)
+ {
+ AcpiOsPrintf (", ");
+ }
+}
+
+#endif
diff --git a/source/components/disassembler/dmwalk.c b/source/components/disassembler/dmwalk.c
new file mode 100644
index 000000000000..dd3ee002557b
--- /dev/null
+++ b/source/components/disassembler/dmwalk.c
@@ -0,0 +1,935 @@
+/*******************************************************************************
+ *
+ * Module Name: dmwalk - AML disassembly tree walk
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2012, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include "acpi.h"
+#include "accommon.h"
+#include "acparser.h"
+#include "amlcode.h"
+#include "acdisasm.h"
+#include "acdebug.h"
+
+
+#ifdef ACPI_DISASSEMBLER
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ ACPI_MODULE_NAME ("dmwalk")
+
+
+#define DB_FULL_OP_INFO "[%4.4s] @%5.5X #%4.4X: "
+
+/* Stub for non-compiler code */
+
+#ifndef ACPI_ASL_COMPILER
+void
+AcpiDmEmitExternals (
+ void)
+{
+ return;
+}
+#endif
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiDmDescendingOp (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context);
+
+static ACPI_STATUS
+AcpiDmAscendingOp (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context);
+
+static UINT32
+AcpiDmBlockType (
+ ACPI_PARSE_OBJECT *Op);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDisassemble
+ *
+ * PARAMETERS: WalkState - Current state
+ * Origin - Starting object
+ * NumOpcodes - Max number of opcodes to be displayed
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Disassemble parser object and its children. This is the
+ * main entry point of the disassembler.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmDisassemble (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Origin,
+ UINT32 NumOpcodes)
+{
+ ACPI_PARSE_OBJECT *Op = Origin;
+ ACPI_OP_WALK_INFO Info;
+
+
+ if (!Op)
+ {
+ return;
+ }
+
+ Info.Flags = 0;
+ Info.Level = 0;
+ Info.Count = 0;
+ Info.WalkState = WalkState;
+ AcpiDmWalkParseTree (Op, AcpiDmDescendingOp, AcpiDmAscendingOp, &Info);
+ return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmWalkParseTree
+ *
+ * PARAMETERS: Op - Root Op object
+ * DescendingCallback - Called during tree descent
+ * AscendingCallback - Called during tree ascent
+ * Context - To be passed to the callbacks
+ *
+ * RETURN: Status from callback(s)
+ *
+ * DESCRIPTION: Walk the entire parse tree.
+ *
+ ******************************************************************************/
+
+void
+AcpiDmWalkParseTree (
+ ACPI_PARSE_OBJECT *Op,
+ ASL_WALK_CALLBACK DescendingCallback,
+ ASL_WALK_CALLBACK AscendingCallback,
+ void *Context)
+{
+ BOOLEAN NodePreviouslyVisited;
+ ACPI_PARSE_OBJECT *StartOp = Op;
+ ACPI_STATUS Status;
+ ACPI_PARSE_OBJECT *Next;
+ ACPI_OP_WALK_INFO *Info = Context;
+
+
+ Info->Level = 0;
+ NodePreviouslyVisited = FALSE;
+
+ while (Op)
+ {
+ if (NodePreviouslyVisited)
+ {
+ if (AscendingCallback)
+ {
+ Status = AscendingCallback (Op, Info->Level, Context);
+ if (ACPI_FAILURE (Status))
+ {
+ return;
+ }
+ }
+ }
+ else
+ {
+ /* Let the callback process the node */
+
+ Status = DescendingCallback (Op, Info->Level, Context);
+ if (ACPI_SUCCESS (Status))
+ {
+ /* Visit children first, once */
+
+ Next = AcpiPsGetArg (Op, 0);
+ if (Next)
+ {
+ Info->Level++;
+ Op = Next;
+ continue;
+ }
+ }
+ else if (Status != AE_CTRL_DEPTH)
+ {
+ /* Exit immediately on any error */
+
+ return;
+ }
+ }
+
+ /* Terminate walk at start op */
+
+ if (Op == StartOp)
+ {
+ break;
+ }
+
+ /* No more children, re-visit this node */
+
+ if (!NodePreviouslyVisited)
+ {
+ NodePreviouslyVisited = TRUE;
+ continue;
+ }
+
+ /* No more children, visit peers */
+
+ if (Op->Common.Next)
+ {
+ Op = Op->Common.Next;
+ NodePreviouslyVisited = FALSE;
+ }
+ else
+ {
+ /* No peers, re-visit parent */
+
+ if (Info->Level != 0 )
+ {
+ Info->Level--;
+ }
+
+ Op = Op->Common.Parent;
+ NodePreviouslyVisited = TRUE;
+ }
+ }
+
+ /* If we get here, the walk completed with no errors */
+
+ return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmBlockType
+ *
+ * PARAMETERS: Op - Object to be examined
+ *
+ * RETURN: BlockType - not a block, parens, braces, or even both.
+ *
+ * DESCRIPTION: Type of block for this op (parens or braces)
+ *
+ ******************************************************************************/
+
+static UINT32
+AcpiDmBlockType (
+ ACPI_PARSE_OBJECT *Op)
+{
+ const ACPI_OPCODE_INFO *OpInfo;
+
+
+ if (!Op)
+ {
+ return (BLOCK_NONE);
+ }
+
+ switch (Op->Common.AmlOpcode)
+ {
+ case AML_ELSE_OP:
+
+ return (BLOCK_BRACE);
+
+ case AML_METHOD_OP:
+ case AML_DEVICE_OP:
+ case AML_SCOPE_OP:
+ case AML_PROCESSOR_OP:
+ case AML_POWER_RES_OP:
+ case AML_THERMAL_ZONE_OP:
+ case AML_IF_OP:
+ case AML_WHILE_OP:
+ case AML_FIELD_OP:
+ case AML_INDEX_FIELD_OP:
+ case AML_BANK_FIELD_OP:
+
+ return (BLOCK_PAREN | BLOCK_BRACE);
+
+ case AML_BUFFER_OP:
+
+ if (Op->Common.DisasmOpcode == ACPI_DASM_UNICODE)
+ {
+ return (BLOCK_NONE);
+ }
+
+ /*lint -fallthrough */
+
+ case AML_PACKAGE_OP:
+ case AML_VAR_PACKAGE_OP:
+
+ return (BLOCK_PAREN | BLOCK_BRACE);
+
+ case AML_EVENT_OP:
+
+ return (BLOCK_PAREN);
+
+ default:
+
+ OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
+ if (OpInfo->Flags & AML_HAS_ARGS)
+ {
+ return (BLOCK_PAREN);
+ }
+
+ return (BLOCK_NONE);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmListType
+ *
+ * PARAMETERS: Op - Object to be examined
+ *
+ * RETURN: ListType - has commas or not.
+ *
+ * DESCRIPTION: Type of block for this op (parens or braces)
+ *
+ ******************************************************************************/
+
+UINT32
+AcpiDmListType (
+ ACPI_PARSE_OBJECT *Op)
+{
+ const ACPI_OPCODE_INFO *OpInfo;
+
+
+ if (!Op)
+ {
+ return (BLOCK_NONE);
+ }
+
+ switch (Op->Common.AmlOpcode)
+ {
+
+ case AML_ELSE_OP:
+ case AML_METHOD_OP:
+ case AML_DEVICE_OP:
+ case AML_SCOPE_OP:
+ case AML_POWER_RES_OP:
+ case AML_PROCESSOR_OP:
+ case AML_THERMAL_ZONE_OP:
+ case AML_IF_OP:
+ case AML_WHILE_OP:
+ case AML_FIELD_OP:
+ case AML_INDEX_FIELD_OP:
+ case AML_BANK_FIELD_OP:
+
+ return (BLOCK_NONE);
+
+ case AML_BUFFER_OP:
+ case AML_PACKAGE_OP:
+ case AML_VAR_PACKAGE_OP:
+
+ return (BLOCK_COMMA_LIST);
+
+ default:
+
+ OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
+ if (OpInfo->Flags & AML_HAS_ARGS)
+ {
+ return (BLOCK_COMMA_LIST);
+ }
+
+ return (BLOCK_NONE);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmDescendingOp
+ *
+ * PARAMETERS: ASL_WALK_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: First visitation of a parse object during tree descent.
+ * Decode opcode name and begin parameter list(s), if any.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDmDescendingOp (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context)
+{
+ ACPI_OP_WALK_INFO *Info = Context;
+ const ACPI_OPCODE_INFO *OpInfo;
+ UINT32 Name;
+ ACPI_PARSE_OBJECT *NextOp;
+
+
+ if (Op->Common.DisasmFlags & ACPI_PARSEOP_IGNORE)
+ {
+ /* Ignore this op -- it was handled elsewhere */
+
+ return (AE_CTRL_DEPTH);
+ }
+
+ /* Level 0 is at the Definition Block level */
+
+ if (Level == 0)
+ {
+ /* In verbose mode, print the AML offset, opcode and depth count */
+
+ if (Info->WalkState)
+ {
+ VERBOSE_PRINT ((DB_FULL_OP_INFO,
+ (Info->WalkState->MethodNode ?
+ Info->WalkState->MethodNode->Name.Ascii : " "),
+ Op->Common.AmlOffset, (UINT32) Op->Common.AmlOpcode));
+ }
+
+ if (Op->Common.AmlOpcode == AML_SCOPE_OP)
+ {
+ /* This is the beginning of the Definition Block */
+
+ AcpiOsPrintf ("{\n");
+
+ /* Emit all External() declarations here */
+
+ AcpiDmEmitExternals ();
+ return (AE_OK);
+ }
+ }
+ else if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
+ (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) &&
+ (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP))
+ {
+ /*
+ * This is a first-level element of a term list,
+ * indent a new line
+ */
+ AcpiDmIndent (Level);
+ Info->LastLevel = Level;
+ Info->Count = 0;
+ }
+
+ /*
+ * This is an inexpensive mechanism to try and keep lines from getting
+ * too long. When the limit is hit, start a new line at the previous
+ * indent plus one. A better but more expensive mechanism would be to
+ * keep track of the current column.
+ */
+ Info->Count++;
+ if (Info->Count /*+Info->LastLevel*/ > 10)
+ {
+ Info->Count = 0;
+ AcpiOsPrintf ("\n");
+ AcpiDmIndent (Info->LastLevel + 1);
+ }
+
+ /* Print the opcode name */
+
+ AcpiDmDisassembleOneOp (NULL, Info, Op);
+
+ if ((Op->Common.DisasmOpcode == ACPI_DASM_LNOT_PREFIX) ||
+ (Op->Common.AmlOpcode == AML_INT_CONNECTION_OP))
+ {
+ return (AE_OK);
+ }
+
+ if ((Op->Common.AmlOpcode == AML_NAME_OP) ||
+ (Op->Common.AmlOpcode == AML_RETURN_OP))
+ {
+ Info->Level--;
+ }
+
+ /* Start the opcode argument list if necessary */
+
+ OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
+
+ if ((OpInfo->Flags & AML_HAS_ARGS) ||
+ (Op->Common.AmlOpcode == AML_EVENT_OP))
+ {
+ /* This opcode has an argument list */
+
+ if (AcpiDmBlockType (Op) & BLOCK_PAREN)
+ {
+ AcpiOsPrintf (" (");
+ }
+
+ /* If this is a named opcode, print the associated name value */
+
+ if (OpInfo->Flags & AML_NAMED)
+ {
+ switch (Op->Common.AmlOpcode)
+ {
+ case AML_ALIAS_OP:
+
+ NextOp = AcpiPsGetDepthNext (NULL, Op);
+ NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
+ AcpiDmNamestring (NextOp->Common.Value.Name);
+ AcpiOsPrintf (", ");
+
+ /*lint -fallthrough */
+
+ default:
+
+ Name = AcpiPsGetName (Op);
+ if (Op->Named.Path)
+ {
+ AcpiDmNamestring ((char *) Op->Named.Path);
+ }
+ else
+ {
+ AcpiDmDumpName (Name);
+ }
+
+ if (Op->Common.AmlOpcode != AML_INT_NAMEDFIELD_OP)
+ {
+ if (AcpiGbl_DbOpt_verbose)
+ {
+ (void) AcpiPsDisplayObjectPathname (NULL, Op);
+ }
+ }
+ break;
+ }
+
+ switch (Op->Common.AmlOpcode)
+ {
+ case AML_METHOD_OP:
+
+ AcpiDmMethodFlags (Op);
+ AcpiOsPrintf (")");
+ break;
+
+
+ case AML_NAME_OP:
+
+ /* Check for _HID and related EISAID() */
+
+ AcpiDmIsEisaId (Op);
+ AcpiOsPrintf (", ");
+ break;
+
+
+ case AML_REGION_OP:
+
+ AcpiDmRegionFlags (Op);
+ break;
+
+
+ case AML_POWER_RES_OP:
+
+ /* Mark the next two Ops as part of the parameter list */
+
+ AcpiOsPrintf (", ");
+ NextOp = AcpiPsGetDepthNext (NULL, Op);
+ NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
+
+ NextOp = NextOp->Common.Next;
+ NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
+ return (AE_OK);
+
+
+ case AML_PROCESSOR_OP:
+
+ /* Mark the next three Ops as part of the parameter list */
+
+ AcpiOsPrintf (", ");
+ NextOp = AcpiPsGetDepthNext (NULL, Op);
+ NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
+
+ NextOp = NextOp->Common.Next;
+ NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
+
+ NextOp = NextOp->Common.Next;
+ NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
+ return (AE_OK);
+
+
+ case AML_MUTEX_OP:
+ case AML_DATA_REGION_OP:
+
+ AcpiOsPrintf (", ");
+ return (AE_OK);
+
+
+ case AML_EVENT_OP:
+ case AML_ALIAS_OP:
+
+ return (AE_OK);
+
+
+ case AML_SCOPE_OP:
+ case AML_DEVICE_OP:
+ case AML_THERMAL_ZONE_OP:
+
+ AcpiOsPrintf (")");
+ break;
+
+
+ default:
+
+ AcpiOsPrintf ("*** Unhandled named opcode %X\n", Op->Common.AmlOpcode);
+ break;
+ }
+ }
+
+ else switch (Op->Common.AmlOpcode)
+ {
+ case AML_FIELD_OP:
+ case AML_BANK_FIELD_OP:
+ case AML_INDEX_FIELD_OP:
+
+ Info->BitOffset = 0;
+
+ /* Name of the parent OperationRegion */
+
+ NextOp = AcpiPsGetDepthNext (NULL, Op);
+ AcpiDmNamestring (NextOp->Common.Value.Name);
+ AcpiOsPrintf (", ");
+ NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
+
+ switch (Op->Common.AmlOpcode)
+ {
+ case AML_BANK_FIELD_OP:
+
+ /* Namestring - Bank Name */
+
+ NextOp = AcpiPsGetDepthNext (NULL, NextOp);
+ AcpiDmNamestring (NextOp->Common.Value.Name);
+ NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
+ AcpiOsPrintf (", ");
+
+ /*
+ * Bank Value. This is a TermArg in the middle of the parameter
+ * list, must handle it here.
+ *
+ * Disassemble the TermArg parse tree. ACPI_PARSEOP_PARAMLIST
+ * eliminates newline in the output.
+ */
+ NextOp = NextOp->Common.Next;
+
+ Info->Flags = ACPI_PARSEOP_PARAMLIST;
+ AcpiDmWalkParseTree (NextOp, AcpiDmDescendingOp, AcpiDmAscendingOp, Info);
+ Info->Flags = 0;
+ Info->Level = Level;
+
+ NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
+ AcpiOsPrintf (", ");
+ break;
+
+ case AML_INDEX_FIELD_OP:
+
+ /* Namestring - Data Name */
+
+ NextOp = AcpiPsGetDepthNext (NULL, NextOp);
+ AcpiDmNamestring (NextOp->Common.Value.Name);
+ AcpiOsPrintf (", ");
+ NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
+ break;
+
+ default:
+
+ break;
+ }
+
+ AcpiDmFieldFlags (NextOp);
+ break;
+
+
+ case AML_BUFFER_OP:
+
+ /* The next op is the size parameter */
+
+ NextOp = AcpiPsGetDepthNext (NULL, Op);
+ if (!NextOp)
+ {
+ /* Single-step support */
+
+ return (AE_OK);
+ }
+
+ if (Op->Common.DisasmOpcode == ACPI_DASM_RESOURCE)
+ {
+ /*
+ * We have a resource list. Don't need to output
+ * the buffer size Op. Open up a new block
+ */
+ NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
+ NextOp = NextOp->Common.Next;
+ AcpiOsPrintf (")\n");
+ AcpiDmIndent (Info->Level);
+ AcpiOsPrintf ("{\n");
+ return (AE_OK);
+ }
+
+ /* Normal Buffer, mark size as in the parameter list */
+
+ NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
+ return (AE_OK);
+
+
+ case AML_VAR_PACKAGE_OP:
+ case AML_IF_OP:
+ case AML_WHILE_OP:
+
+ /* The next op is the size or predicate parameter */
+
+ NextOp = AcpiPsGetDepthNext (NULL, Op);
+ if (NextOp)
+ {
+ NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
+ }
+ return (AE_OK);
+
+
+ case AML_PACKAGE_OP:
+
+ /* The next op is the size or predicate parameter */
+
+ NextOp = AcpiPsGetDepthNext (NULL, Op);
+ if (NextOp)
+ {
+ NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST;
+ }
+ return (AE_OK);
+
+
+ case AML_MATCH_OP:
+
+ AcpiDmMatchOp (Op);
+ break;
+
+
+ default:
+
+ break;
+ }
+
+ if (AcpiDmBlockType (Op) & BLOCK_BRACE)
+ {
+ AcpiOsPrintf ("\n");
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("{\n");
+ }
+ }
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDmAscendingOp
+ *
+ * PARAMETERS: ASL_WALK_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Second visitation of a parse object, during ascent of parse
+ * tree. Close out any parameter lists and complete the opcode.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDmAscendingOp (
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 Level,
+ void *Context)
+{
+ ACPI_OP_WALK_INFO *Info = Context;
+
+
+ if (Op->Common.DisasmFlags & ACPI_PARSEOP_IGNORE)
+ {
+ /* Ignore this op -- it was handled elsewhere */
+
+ return (AE_OK);
+ }
+
+ if ((Level == 0) && (Op->Common.AmlOpcode == AML_SCOPE_OP))
+ {
+ /* Indicates the end of the current descriptor block (table) */
+
+ AcpiOsPrintf ("}\n\n");
+ return (AE_OK);
+ }
+
+ switch (AcpiDmBlockType (Op))
+ {
+ case BLOCK_PAREN:
+
+ /* Completed an op that has arguments, add closing paren */
+
+ AcpiOsPrintf (")");
+
+ /* Could be a nested operator, check if comma required */
+
+ if (!AcpiDmCommaIfListMember (Op))
+ {
+ if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
+ (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) &&
+ (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP))
+ {
+ /*
+ * This is a first-level element of a term list
+ * start a new line
+ */
+ if (!(Info->Flags & ACPI_PARSEOP_PARAMLIST))
+ {
+ AcpiOsPrintf ("\n");
+ }
+ }
+ }
+ break;
+
+
+ case BLOCK_BRACE:
+ case (BLOCK_BRACE | BLOCK_PAREN):
+
+ /* Completed an op that has a term list, add closing brace */
+
+ if (Op->Common.DisasmFlags & ACPI_PARSEOP_EMPTY_TERMLIST)
+ {
+ AcpiOsPrintf ("}");
+ }
+ else
+ {
+ AcpiDmIndent (Level);
+ AcpiOsPrintf ("}");
+ }
+
+ AcpiDmCommaIfListMember (Op);
+
+ if (AcpiDmBlockType (Op->Common.Parent) != BLOCK_PAREN)
+ {
+ AcpiOsPrintf ("\n");
+ if (!(Op->Common.DisasmFlags & ACPI_PARSEOP_EMPTY_TERMLIST))
+ {
+ if ((Op->Common.AmlOpcode == AML_IF_OP) &&
+ (Op->Common.Next) &&
+ (Op->Common.Next->Common.AmlOpcode == AML_ELSE_OP))
+ {
+ break;
+ }
+
+ if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
+ (!Op->Common.Next))
+ {
+ break;
+ }
+ AcpiOsPrintf ("\n");
+ }
+ }
+ break;
+
+
+ case BLOCK_NONE:
+ default:
+
+ /* Could be a nested operator, check if comma required */
+
+ if (!AcpiDmCommaIfListMember (Op))
+ {
+ if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&
+ (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) &&
+ (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP))
+ {
+ /*
+ * This is a first-level element of a term list
+ * start a new line
+ */
+ AcpiOsPrintf ("\n");
+ }
+ }
+ else if (Op->Common.Parent)
+ {
+ switch (Op->Common.Parent->Common.AmlOpcode)
+ {
+ case AML_PACKAGE_OP:
+ case AML_VAR_PACKAGE_OP:
+
+ if (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST))
+ {
+ AcpiOsPrintf ("\n");
+ }
+ break;
+
+ default:
+
+ break;
+ }
+ }
+ break;
+ }
+
+ if (Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)
+ {
+ if ((Op->Common.Next) &&
+ (Op->Common.Next->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST))
+ {
+ return (AE_OK);
+ }
+
+ /*
+ * Just completed a parameter node for something like "Buffer (param)".
+ * Close the paren and open up the term list block with a brace
+ */
+ if (Op->Common.Next)
+ {
+ AcpiOsPrintf (")\n");
+ AcpiDmIndent (Level - 1);
+ AcpiOsPrintf ("{\n");
+ }
+ else
+ {
+ Op->Common.Parent->Common.DisasmFlags |=
+ ACPI_PARSEOP_EMPTY_TERMLIST;
+ AcpiOsPrintf (") {");
+ }
+ }
+
+ if ((Op->Common.AmlOpcode == AML_NAME_OP) ||
+ (Op->Common.AmlOpcode == AML_RETURN_OP))
+ {
+ Info->Level++;
+ }
+ return (AE_OK);
+}
+
+
+#endif /* ACPI_DISASSEMBLER */
diff --git a/source/components/dispatcher/dsargs.c b/source/components/dispatcher/dsargs.c
new file mode 100644
index 000000000000..ea0d7bee88f7
--- /dev/null
+++ b/source/components/dispatcher/dsargs.c
@@ -0,0 +1,438 @@
+/******************************************************************************
+ *
+ * Module Name: dsargs - Support for execution of dynamic arguments for static
+ * objects (regions, fields, buffer fields, etc.)
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2012, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#define __DSARGS_C__
+
+#include "acpi.h"
+#include "accommon.h"
+#include "acparser.h"
+#include "amlcode.h"
+#include "acdispat.h"
+#include "acnamesp.h"
+
+#define _COMPONENT ACPI_DISPATCHER
+ ACPI_MODULE_NAME ("dsargs")
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiDsExecuteArguments (
+ ACPI_NAMESPACE_NODE *Node,
+ ACPI_NAMESPACE_NODE *ScopeNode,
+ UINT32 AmlLength,
+ UINT8 *AmlStart);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsExecuteArguments
+ *
+ * PARAMETERS: Node - Object NS node
+ * ScopeNode - Parent NS node
+ * AmlLength - Length of executable AML
+ * AmlStart - Pointer to the AML
+ *
+ * RETURN: Status.
+ *
+ * DESCRIPTION: Late (deferred) execution of region or field arguments
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDsExecuteArguments (
+ ACPI_NAMESPACE_NODE *Node,
+ ACPI_NAMESPACE_NODE *ScopeNode,
+ UINT32 AmlLength,
+ UINT8 *AmlStart)
+{
+ ACPI_STATUS Status;
+ ACPI_PARSE_OBJECT *Op;
+ ACPI_WALK_STATE *WalkState;
+
+
+ ACPI_FUNCTION_TRACE (DsExecuteArguments);
+
+
+ /* Allocate a new parser op to be the root of the parsed tree */
+
+ Op = AcpiPsAllocOp (AML_INT_EVAL_SUBTREE_OP);
+ if (!Op)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ /* Save the Node for use in AcpiPsParseAml */
+
+ Op->Common.Node = ScopeNode;
+
+ /* Create and initialize a new parser state */
+
+ WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
+ if (!WalkState)
+ {
+ Status = AE_NO_MEMORY;
+ goto Cleanup;
+ }
+
+ Status = AcpiDsInitAmlWalk (WalkState, Op, NULL, AmlStart,
+ AmlLength, NULL, ACPI_IMODE_LOAD_PASS1);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiDsDeleteWalkState (WalkState);
+ goto Cleanup;
+ }
+
+ /* Mark this parse as a deferred opcode */
+
+ WalkState->ParseFlags = ACPI_PARSE_DEFERRED_OP;
+ WalkState->DeferredNode = Node;
+
+ /* Pass1: Parse the entire declaration */
+
+ Status = AcpiPsParseAml (WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Cleanup;
+ }
+
+ /* Get and init the Op created above */
+
+ Op->Common.Node = Node;
+ AcpiPsDeleteParseTree (Op);
+
+ /* Evaluate the deferred arguments */
+
+ Op = AcpiPsAllocOp (AML_INT_EVAL_SUBTREE_OP);
+ if (!Op)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ Op->Common.Node = ScopeNode;
+
+ /* Create and initialize a new parser state */
+
+ WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
+ if (!WalkState)
+ {
+ Status = AE_NO_MEMORY;
+ goto Cleanup;
+ }
+
+ /* Execute the opcode and arguments */
+
+ Status = AcpiDsInitAmlWalk (WalkState, Op, NULL, AmlStart,
+ AmlLength, NULL, ACPI_IMODE_EXECUTE);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiDsDeleteWalkState (WalkState);
+ goto Cleanup;
+ }
+
+ /* Mark this execution as a deferred opcode */
+
+ WalkState->DeferredNode = Node;
+ Status = AcpiPsParseAml (WalkState);
+
+Cleanup:
+ AcpiPsDeleteParseTree (Op);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsGetBufferFieldArguments
+ *
+ * PARAMETERS: ObjDesc - A valid BufferField object
+ *
+ * RETURN: Status.
+ *
+ * DESCRIPTION: Get BufferField Buffer and Index. This implements the late
+ * evaluation of these field attributes.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsGetBufferFieldArguments (
+ ACPI_OPERAND_OBJECT *ObjDesc)
+{
+ ACPI_OPERAND_OBJECT *ExtraDesc;
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE_PTR (DsGetBufferFieldArguments, ObjDesc);
+
+
+ if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
+ {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* Get the AML pointer (method object) and BufferField node */
+
+ ExtraDesc = AcpiNsGetSecondaryObject (ObjDesc);
+ Node = ObjDesc->BufferField.Node;
+
+ ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname (ACPI_TYPE_BUFFER_FIELD,
+ Node, NULL));
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] BufferField Arg Init\n",
+ AcpiUtGetNodeName (Node)));
+
+ /* Execute the AML code for the TermArg arguments */
+
+ Status = AcpiDsExecuteArguments (Node, Node->Parent,
+ ExtraDesc->Extra.AmlLength, ExtraDesc->Extra.AmlStart);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsGetBankFieldArguments
+ *
+ * PARAMETERS: ObjDesc - A valid BankField object
+ *
+ * RETURN: Status.
+ *
+ * DESCRIPTION: Get BankField BankValue. This implements the late
+ * evaluation of these field attributes.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsGetBankFieldArguments (
+ ACPI_OPERAND_OBJECT *ObjDesc)
+{
+ ACPI_OPERAND_OBJECT *ExtraDesc;
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE_PTR (DsGetBankFieldArguments, ObjDesc);
+
+
+ if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
+ {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* Get the AML pointer (method object) and BankField node */
+
+ ExtraDesc = AcpiNsGetSecondaryObject (ObjDesc);
+ Node = ObjDesc->BankField.Node;
+
+ ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname (ACPI_TYPE_LOCAL_BANK_FIELD,
+ Node, NULL));
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] BankField Arg Init\n",
+ AcpiUtGetNodeName (Node)));
+
+ /* Execute the AML code for the TermArg arguments */
+
+ Status = AcpiDsExecuteArguments (Node, Node->Parent,
+ ExtraDesc->Extra.AmlLength, ExtraDesc->Extra.AmlStart);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsGetBufferArguments
+ *
+ * PARAMETERS: ObjDesc - A valid Buffer object
+ *
+ * RETURN: Status.
+ *
+ * DESCRIPTION: Get Buffer length and initializer byte list. This implements
+ * the late evaluation of these attributes.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsGetBufferArguments (
+ ACPI_OPERAND_OBJECT *ObjDesc)
+{
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE_PTR (DsGetBufferArguments, ObjDesc);
+
+
+ if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
+ {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* Get the Buffer node */
+
+ Node = ObjDesc->Buffer.Node;
+ if (!Node)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "No pointer back to namespace node in buffer object %p", ObjDesc));
+ return_ACPI_STATUS (AE_AML_INTERNAL);
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Buffer Arg Init\n"));
+
+ /* Execute the AML code for the TermArg arguments */
+
+ Status = AcpiDsExecuteArguments (Node, Node,
+ ObjDesc->Buffer.AmlLength, ObjDesc->Buffer.AmlStart);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsGetPackageArguments
+ *
+ * PARAMETERS: ObjDesc - A valid Package object
+ *
+ * RETURN: Status.
+ *
+ * DESCRIPTION: Get Package length and initializer byte list. This implements
+ * the late evaluation of these attributes.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsGetPackageArguments (
+ ACPI_OPERAND_OBJECT *ObjDesc)
+{
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE_PTR (DsGetPackageArguments, ObjDesc);
+
+
+ if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
+ {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* Get the Package node */
+
+ Node = ObjDesc->Package.Node;
+ if (!Node)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "No pointer back to namespace node in package %p", ObjDesc));
+ return_ACPI_STATUS (AE_AML_INTERNAL);
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Package Arg Init\n"));
+
+ /* Execute the AML code for the TermArg arguments */
+
+ Status = AcpiDsExecuteArguments (Node, Node,
+ ObjDesc->Package.AmlLength, ObjDesc->Package.AmlStart);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsGetRegionArguments
+ *
+ * PARAMETERS: ObjDesc - A valid region object
+ *
+ * RETURN: Status.
+ *
+ * DESCRIPTION: Get region address and length. This implements the late
+ * evaluation of these region attributes.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsGetRegionArguments (
+ ACPI_OPERAND_OBJECT *ObjDesc)
+{
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_STATUS Status;
+ ACPI_OPERAND_OBJECT *ExtraDesc;
+
+
+ ACPI_FUNCTION_TRACE_PTR (DsGetRegionArguments, ObjDesc);
+
+
+ if (ObjDesc->Region.Flags & AOPOBJ_DATA_VALID)
+ {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ ExtraDesc = AcpiNsGetSecondaryObject (ObjDesc);
+ if (!ExtraDesc)
+ {
+ return_ACPI_STATUS (AE_NOT_EXIST);
+ }
+
+ /* Get the Region node */
+
+ Node = ObjDesc->Region.Node;
+
+ ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname (ACPI_TYPE_REGION, Node, NULL));
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] OpRegion Arg Init at AML %p\n",
+ AcpiUtGetNodeName (Node), ExtraDesc->Extra.AmlStart));
+
+ /* Execute the argument AML */
+
+ Status = AcpiDsExecuteArguments (Node, ExtraDesc->Extra.ScopeNode,
+ ExtraDesc->Extra.AmlLength, ExtraDesc->Extra.AmlStart);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ Status = AcpiUtAddAddressRange (ObjDesc->Region.SpaceId,
+ ObjDesc->Region.Address, ObjDesc->Region.Length,
+ Node);
+ return_ACPI_STATUS (Status);
+}
diff --git a/source/components/dispatcher/dscontrol.c b/source/components/dispatcher/dscontrol.c
new file mode 100644
index 000000000000..5c5c51a573e6
--- /dev/null
+++ b/source/components/dispatcher/dscontrol.c
@@ -0,0 +1,424 @@
+/******************************************************************************
+ *
+ * Module Name: dscontrol - Support for execution control opcodes -
+ * if/else/while/return
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2012, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#define __DSCONTROL_C__
+
+#include "acpi.h"
+#include "accommon.h"
+#include "amlcode.h"
+#include "acdispat.h"
+#include "acinterp.h"
+
+#define _COMPONENT ACPI_DISPATCHER
+ ACPI_MODULE_NAME ("dscontrol")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsExecBeginControlOp
+ *
+ * PARAMETERS: WalkList - The list that owns the walk stack
+ * Op - The control Op
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Handles all control ops encountered during control method
+ * execution.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsExecBeginControlOp (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_STATUS Status = AE_OK;
+ ACPI_GENERIC_STATE *ControlState;
+
+
+ ACPI_FUNCTION_NAME (DsExecBeginControlOp);
+
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p Opcode=%2.2X State=%p\n",
+ Op, Op->Common.AmlOpcode, WalkState));
+
+ switch (Op->Common.AmlOpcode)
+ {
+ case AML_WHILE_OP:
+
+ /*
+ * If this is an additional iteration of a while loop, continue.
+ * There is no need to allocate a new control state.
+ */
+ if (WalkState->ControlState)
+ {
+ if (WalkState->ControlState->Control.AmlPredicateStart ==
+ (WalkState->ParserState.Aml - 1))
+ {
+ /* Reset the state to start-of-loop */
+
+ WalkState->ControlState->Common.State =
+ ACPI_CONTROL_CONDITIONAL_EXECUTING;
+ break;
+ }
+ }
+
+ /*lint -fallthrough */
+
+ case AML_IF_OP:
+
+ /*
+ * IF/WHILE: Create a new control state to manage these
+ * constructs. We need to manage these as a stack, in order
+ * to handle nesting.
+ */
+ ControlState = AcpiUtCreateControlState ();
+ if (!ControlState)
+ {
+ Status = AE_NO_MEMORY;
+ break;
+ }
+ /*
+ * Save a pointer to the predicate for multiple executions
+ * of a loop
+ */
+ ControlState->Control.AmlPredicateStart = WalkState->ParserState.Aml - 1;
+ ControlState->Control.PackageEnd = WalkState->ParserState.PkgEnd;
+ ControlState->Control.Opcode = Op->Common.AmlOpcode;
+
+
+ /* Push the control state on this walk's control stack */
+
+ AcpiUtPushGenericState (&WalkState->ControlState, ControlState);
+ break;
+
+ case AML_ELSE_OP:
+
+ /* Predicate is in the state object */
+ /* If predicate is true, the IF was executed, ignore ELSE part */
+
+ if (WalkState->LastPredicate)
+ {
+ Status = AE_CTRL_TRUE;
+ }
+
+ break;
+
+ case AML_RETURN_OP:
+
+ break;
+
+ default:
+ break;
+ }
+
+ return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsExecEndControlOp
+ *
+ * PARAMETERS: WalkList - The list that owns the walk stack
+ * Op - The control Op
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Handles all control ops encountered during control method
+ * execution.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsExecEndControlOp (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_STATUS Status = AE_OK;
+ ACPI_GENERIC_STATE *ControlState;
+
+
+ ACPI_FUNCTION_NAME (DsExecEndControlOp);
+
+
+ switch (Op->Common.AmlOpcode)
+ {
+ case AML_IF_OP:
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[IF_OP] Op=%p\n", Op));
+
+ /*
+ * Save the result of the predicate in case there is an
+ * ELSE to come
+ */
+ WalkState->LastPredicate =
+ (BOOLEAN) WalkState->ControlState->Common.Value;
+
+ /*
+ * Pop the control state that was created at the start
+ * of the IF and free it
+ */
+ ControlState = AcpiUtPopGenericState (&WalkState->ControlState);
+ AcpiUtDeleteGenericState (ControlState);
+ break;
+
+
+ case AML_ELSE_OP:
+
+ break;
+
+
+ case AML_WHILE_OP:
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[WHILE_OP] Op=%p\n", Op));
+
+ ControlState = WalkState->ControlState;
+ if (ControlState->Common.Value)
+ {
+ /* Predicate was true, the body of the loop was just executed */
+
+ /*
+ * This loop counter mechanism allows the interpreter to escape
+ * possibly infinite loops. This can occur in poorly written AML
+ * when the hardware does not respond within a while loop and the
+ * loop does not implement a timeout.
+ */
+ ControlState->Control.LoopCount++;
+ if (ControlState->Control.LoopCount > ACPI_MAX_LOOP_ITERATIONS)
+ {
+ Status = AE_AML_INFINITE_LOOP;
+ break;
+ }
+
+ /*
+ * Go back and evaluate the predicate and maybe execute the loop
+ * another time
+ */
+ Status = AE_CTRL_PENDING;
+ WalkState->AmlLastWhile = ControlState->Control.AmlPredicateStart;
+ break;
+ }
+
+ /* Predicate was false, terminate this while loop */
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "[WHILE_OP] termination! Op=%p\n",Op));
+
+ /* Pop this control state and free it */
+
+ ControlState = AcpiUtPopGenericState (&WalkState->ControlState);
+ AcpiUtDeleteGenericState (ControlState);
+ break;
+
+
+ case AML_RETURN_OP:
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "[RETURN_OP] Op=%p Arg=%p\n",Op, Op->Common.Value.Arg));
+
+ /*
+ * One optional operand -- the return value
+ * It can be either an immediate operand or a result that
+ * has been bubbled up the tree
+ */
+ if (Op->Common.Value.Arg)
+ {
+ /* Since we have a real Return(), delete any implicit return */
+
+ AcpiDsClearImplicitReturn (WalkState);
+
+ /* Return statement has an immediate operand */
+
+ Status = AcpiDsCreateOperands (WalkState, Op->Common.Value.Arg);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /*
+ * If value being returned is a Reference (such as
+ * an arg or local), resolve it now because it may
+ * cease to exist at the end of the method.
+ */
+ Status = AcpiExResolveToValue (&WalkState->Operands [0], WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ /*
+ * Get the return value and save as the last result
+ * value. This is the only place where WalkState->ReturnDesc
+ * is set to anything other than zero!
+ */
+ WalkState->ReturnDesc = WalkState->Operands[0];
+ }
+ else if (WalkState->ResultCount)
+ {
+ /* Since we have a real Return(), delete any implicit return */
+
+ AcpiDsClearImplicitReturn (WalkState);
+
+ /*
+ * The return value has come from a previous calculation.
+ *
+ * If value being returned is a Reference (such as
+ * an arg or local), resolve it now because it may
+ * cease to exist at the end of the method.
+ *
+ * Allow references created by the Index operator to return
+ * unchanged.
+ */
+ if ((ACPI_GET_DESCRIPTOR_TYPE (WalkState->Results->Results.ObjDesc[0]) == ACPI_DESC_TYPE_OPERAND) &&
+ ((WalkState->Results->Results.ObjDesc [0])->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) &&
+ ((WalkState->Results->Results.ObjDesc [0])->Reference.Class != ACPI_REFCLASS_INDEX))
+ {
+ Status = AcpiExResolveToValue (&WalkState->Results->Results.ObjDesc [0], WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ }
+
+ WalkState->ReturnDesc = WalkState->Results->Results.ObjDesc [0];
+ }
+ else
+ {
+ /* No return operand */
+
+ if (WalkState->NumOperands)
+ {
+ AcpiUtRemoveReference (WalkState->Operands [0]);
+ }
+
+ WalkState->Operands [0] = NULL;
+ WalkState->NumOperands = 0;
+ WalkState->ReturnDesc = NULL;
+ }
+
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "Completed RETURN_OP State=%p, RetVal=%p\n",
+ WalkState, WalkState->ReturnDesc));
+
+ /* End the control method execution right now */
+
+ Status = AE_CTRL_TERMINATE;
+ break;
+
+
+ case AML_NOOP_OP:
+
+ /* Just do nothing! */
+ break;
+
+
+ case AML_BREAK_POINT_OP:
+
+ /*
+ * Set the single-step flag. This will cause the debugger (if present)
+ * to break to the console within the AML debugger at the start of the
+ * next AML instruction.
+ */
+ ACPI_DEBUGGER_EXEC (
+ AcpiGbl_CmSingleStep = TRUE);
+ ACPI_DEBUGGER_EXEC (
+ AcpiOsPrintf ("**break** Executed AML BreakPoint opcode\n"));
+
+ /* Call to the OSL in case OS wants a piece of the action */
+
+ Status = AcpiOsSignal (ACPI_SIGNAL_BREAKPOINT,
+ "Executed AML Breakpoint opcode");
+ break;
+
+
+ case AML_BREAK_OP:
+ case AML_CONTINUE_OP: /* ACPI 2.0 */
+
+
+ /* Pop and delete control states until we find a while */
+
+ while (WalkState->ControlState &&
+ (WalkState->ControlState->Control.Opcode != AML_WHILE_OP))
+ {
+ ControlState = AcpiUtPopGenericState (&WalkState->ControlState);
+ AcpiUtDeleteGenericState (ControlState);
+ }
+
+ /* No while found? */
+
+ if (!WalkState->ControlState)
+ {
+ return (AE_AML_NO_WHILE);
+ }
+
+ /* Was: WalkState->AmlLastWhile = WalkState->ControlState->Control.AmlPredicateStart; */
+
+ WalkState->AmlLastWhile = WalkState->ControlState->Control.PackageEnd;
+
+ /* Return status depending on opcode */
+
+ if (Op->Common.AmlOpcode == AML_BREAK_OP)
+ {
+ Status = AE_CTRL_BREAK;
+ }
+ else
+ {
+ Status = AE_CTRL_CONTINUE;
+ }
+ break;
+
+
+ default:
+
+ ACPI_ERROR ((AE_INFO, "Unknown control opcode=0x%X Op=%p",
+ Op->Common.AmlOpcode, Op));
+
+ Status = AE_AML_BAD_OPCODE;
+ break;
+ }
+
+ return (Status);
+}
diff --git a/source/components/dispatcher/dsfield.c b/source/components/dispatcher/dsfield.c
new file mode 100644
index 000000000000..1c3c523720cf
--- /dev/null
+++ b/source/components/dispatcher/dsfield.c
@@ -0,0 +1,748 @@
+/******************************************************************************
+ *
+ * Module Name: dsfield - Dispatcher field routines
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2012, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#define __DSFIELD_C__
+
+#include "acpi.h"
+#include "accommon.h"
+#include "amlcode.h"
+#include "acdispat.h"
+#include "acinterp.h"
+#include "acnamesp.h"
+#include "acparser.h"
+
+
+#define _COMPONENT ACPI_DISPATCHER
+ ACPI_MODULE_NAME ("dsfield")
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiDsGetFieldNames (
+ ACPI_CREATE_FIELD_INFO *Info,
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Arg);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsCreateBufferField
+ *
+ * PARAMETERS: Op - Current parse op (CreateXXField)
+ * WalkState - Current state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Execute the CreateField operators:
+ * CreateBitFieldOp,
+ * CreateByteFieldOp,
+ * CreateWordFieldOp,
+ * CreateDWordFieldOp,
+ * CreateQWordFieldOp,
+ * CreateFieldOp (all of which define a field in a buffer)
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsCreateBufferField (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_PARSE_OBJECT *Arg;
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_STATUS Status;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_OPERAND_OBJECT *SecondDesc = NULL;
+ UINT32 Flags;
+
+
+ ACPI_FUNCTION_TRACE (DsCreateBufferField);
+
+
+ /*
+ * Get the NameString argument (name of the new BufferField)
+ */
+ if (Op->Common.AmlOpcode == AML_CREATE_FIELD_OP)
+ {
+ /* For CreateField, name is the 4th argument */
+
+ Arg = AcpiPsGetArg (Op, 3);
+ }
+ else
+ {
+ /* For all other CreateXXXField operators, name is the 3rd argument */
+
+ Arg = AcpiPsGetArg (Op, 2);
+ }
+
+ if (!Arg)
+ {
+ return_ACPI_STATUS (AE_AML_NO_OPERAND);
+ }
+
+ if (WalkState->DeferredNode)
+ {
+ Node = WalkState->DeferredNode;
+ Status = AE_OK;
+ }
+ else
+ {
+ /* Execute flag should always be set when this function is entered */
+
+ if (!(WalkState->ParseFlags & ACPI_PARSE_EXECUTE))
+ {
+ return_ACPI_STATUS (AE_AML_INTERNAL);
+ }
+
+ /* Creating new namespace node, should not already exist */
+
+ Flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
+ ACPI_NS_ERROR_IF_FOUND;
+
+ /*
+ * Mark node temporary if we are executing a normal control
+ * method. (Don't mark if this is a module-level code method)
+ */
+ if (WalkState->MethodNode &&
+ !(WalkState->ParseFlags & ACPI_PARSE_MODULE_LEVEL))
+ {
+ Flags |= ACPI_NS_TEMPORARY;
+ }
+
+ /* Enter the NameString into the namespace */
+
+ Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String,
+ ACPI_TYPE_ANY, ACPI_IMODE_LOAD_PASS1,
+ Flags, WalkState, &Node);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status);
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+ /*
+ * We could put the returned object (Node) on the object stack for later,
+ * but for now, we will put it in the "op" object that the parser uses,
+ * so we can get it again at the end of this scope.
+ */
+ Op->Common.Node = Node;
+
+ /*
+ * If there is no object attached to the node, this node was just created
+ * and we need to create the field object. Otherwise, this was a lookup
+ * of an existing node and we don't want to create the field object again.
+ */
+ ObjDesc = AcpiNsGetAttachedObject (Node);
+ if (ObjDesc)
+ {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /*
+ * The Field definition is not fully parsed at this time.
+ * (We must save the address of the AML for the buffer and index operands)
+ */
+
+ /* Create the buffer field object */
+
+ ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_BUFFER_FIELD);
+ if (!ObjDesc)
+ {
+ Status = AE_NO_MEMORY;
+ goto Cleanup;
+ }
+
+ /*
+ * Remember location in AML stream of the field unit opcode and operands --
+ * since the buffer and index operands must be evaluated.
+ */
+ SecondDesc = ObjDesc->Common.NextObject;
+ SecondDesc->Extra.AmlStart = Op->Named.Data;
+ SecondDesc->Extra.AmlLength = Op->Named.Length;
+ ObjDesc->BufferField.Node = Node;
+
+ /* Attach constructed field descriptors to parent node */
+
+ Status = AcpiNsAttachObject (Node, ObjDesc, ACPI_TYPE_BUFFER_FIELD);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Cleanup;
+ }
+
+
+Cleanup:
+
+ /* Remove local reference to the object */
+
+ AcpiUtRemoveReference (ObjDesc);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsGetFieldNames
+ *
+ * PARAMETERS: Info - CreateField info structure
+ * ` WalkState - Current method state
+ * Arg - First parser arg for the field name list
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Process all named fields in a field declaration. Names are
+ * entered into the namespace.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDsGetFieldNames (
+ ACPI_CREATE_FIELD_INFO *Info,
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Arg)
+{
+ ACPI_STATUS Status;
+ UINT64 Position;
+ ACPI_PARSE_OBJECT *Child;
+
+
+ ACPI_FUNCTION_TRACE_PTR (DsGetFieldNames, Info);
+
+
+ /* First field starts at bit zero */
+
+ Info->FieldBitPosition = 0;
+
+ /* Process all elements in the field list (of parse nodes) */
+
+ while (Arg)
+ {
+ /*
+ * Four types of field elements are handled:
+ * 1) Name - Enters a new named field into the namespace
+ * 2) Offset - specifies a bit offset
+ * 3) AccessAs - changes the access mode/attributes
+ * 4) Connection - Associate a resource template with the field
+ */
+ switch (Arg->Common.AmlOpcode)
+ {
+ case AML_INT_RESERVEDFIELD_OP:
+
+ Position = (UINT64) Info->FieldBitPosition
+ + (UINT64) Arg->Common.Value.Size;
+
+ if (Position > ACPI_UINT32_MAX)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Bit offset within field too large (> 0xFFFFFFFF)"));
+ return_ACPI_STATUS (AE_SUPPORT);
+ }
+
+ Info->FieldBitPosition = (UINT32) Position;
+ break;
+
+ case AML_INT_ACCESSFIELD_OP:
+ case AML_INT_EXTACCESSFIELD_OP:
+ /*
+ * Get new AccessType, AccessAttribute, and AccessLength fields
+ * -- to be used for all field units that follow, until the
+ * end-of-field or another AccessAs keyword is encountered.
+ * NOTE. These three bytes are encoded in the integer value
+ * of the parseop for convenience.
+ *
+ * In FieldFlags, preserve the flag bits other than the
+ * ACCESS_TYPE bits.
+ */
+
+ /* AccessType (ByteAcc, WordAcc, etc.) */
+
+ Info->FieldFlags = (UINT8)
+ ((Info->FieldFlags & ~(AML_FIELD_ACCESS_TYPE_MASK)) |
+ ((UINT8) ((UINT32) (Arg->Common.Value.Integer & 0x07))));
+
+ /* AccessAttribute (AttribQuick, AttribByte, etc.) */
+
+ Info->Attribute = (UINT8) ((Arg->Common.Value.Integer >> 8) & 0xFF);
+
+ /* AccessLength (for serial/buffer protocols) */
+
+ Info->AccessLength = (UINT8) ((Arg->Common.Value.Integer >> 16) & 0xFF);
+ break;
+
+ case AML_INT_CONNECTION_OP:
+ /*
+ * Clear any previous connection. New connection is used for all
+ * fields that follow, similar to AccessAs
+ */
+ Info->ResourceBuffer = NULL;
+ Info->ConnectionNode = NULL;
+
+ /*
+ * A Connection() is either an actual resource descriptor (buffer)
+ * or a named reference to a resource template
+ */
+ Child = Arg->Common.Value.Arg;
+ if (Child->Common.AmlOpcode == AML_INT_BYTELIST_OP)
+ {
+ Info->ResourceBuffer = Child->Named.Data;
+ Info->ResourceLength = (UINT16) Child->Named.Value.Integer;
+ }
+ else
+ {
+ /* Lookup the Connection() namepath, it should already exist */
+
+ Status = AcpiNsLookup (WalkState->ScopeInfo,
+ Child->Common.Value.Name, ACPI_TYPE_ANY,
+ ACPI_IMODE_EXECUTE, ACPI_NS_DONT_OPEN_SCOPE,
+ WalkState, &Info->ConnectionNode);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_ERROR_NAMESPACE (Child->Common.Value.Name, Status);
+ return_ACPI_STATUS (Status);
+ }
+ }
+ break;
+
+ case AML_INT_NAMEDFIELD_OP:
+
+ /* Lookup the name, it should already exist */
+
+ Status = AcpiNsLookup (WalkState->ScopeInfo,
+ (char *) &Arg->Named.Name, Info->FieldType,
+ ACPI_IMODE_EXECUTE, ACPI_NS_DONT_OPEN_SCOPE,
+ WalkState, &Info->FieldNode);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_ERROR_NAMESPACE ((char *) &Arg->Named.Name, Status);
+ return_ACPI_STATUS (Status);
+ }
+ else
+ {
+ Arg->Common.Node = Info->FieldNode;
+ Info->FieldBitLength = Arg->Common.Value.Size;
+
+ /*
+ * If there is no object attached to the node, this node was
+ * just created and we need to create the field object.
+ * Otherwise, this was a lookup of an existing node and we
+ * don't want to create the field object again.
+ */
+ if (!AcpiNsGetAttachedObject (Info->FieldNode))
+ {
+ Status = AcpiExPrepFieldValue (Info);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
+ }
+
+ /* Keep track of bit position for the next field */
+
+ Position = (UINT64) Info->FieldBitPosition
+ + (UINT64) Arg->Common.Value.Size;
+
+ if (Position > ACPI_UINT32_MAX)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Field [%4.4s] bit offset too large (> 0xFFFFFFFF)",
+ ACPI_CAST_PTR (char, &Info->FieldNode->Name)));
+ return_ACPI_STATUS (AE_SUPPORT);
+ }
+
+ Info->FieldBitPosition += Info->FieldBitLength;
+ break;
+
+ default:
+
+ ACPI_ERROR ((AE_INFO,
+ "Invalid opcode in field list: 0x%X", Arg->Common.AmlOpcode));
+ return_ACPI_STATUS (AE_AML_BAD_OPCODE);
+ }
+
+ Arg = Arg->Common.Next;
+ }
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsCreateField
+ *
+ * PARAMETERS: Op - Op containing the Field definition and args
+ * RegionNode - Object for the containing Operation Region
+ * ` WalkState - Current method state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Create a new field in the specified operation region
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsCreateField (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_NAMESPACE_NODE *RegionNode,
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_STATUS Status;
+ ACPI_PARSE_OBJECT *Arg;
+ ACPI_CREATE_FIELD_INFO Info;
+
+
+ ACPI_FUNCTION_TRACE_PTR (DsCreateField, Op);
+
+
+ /* First arg is the name of the parent OpRegion (must already exist) */
+
+ Arg = Op->Common.Value.Arg;
+ if (!RegionNode)
+ {
+ Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.Name,
+ ACPI_TYPE_REGION, ACPI_IMODE_EXECUTE,
+ ACPI_NS_SEARCH_PARENT, WalkState, &RegionNode);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_ERROR_NAMESPACE (Arg->Common.Value.Name, Status);
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+ ACPI_MEMSET (&Info, 0, sizeof (ACPI_CREATE_FIELD_INFO));
+
+ /* Second arg is the field flags */
+
+ Arg = Arg->Common.Next;
+ Info.FieldFlags = (UINT8) Arg->Common.Value.Integer;
+ Info.Attribute = 0;
+
+ /* Each remaining arg is a Named Field */
+
+ Info.FieldType = ACPI_TYPE_LOCAL_REGION_FIELD;
+ Info.RegionNode = RegionNode;
+
+ Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Common.Next);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsInitFieldObjects
+ *
+ * PARAMETERS: Op - Op containing the Field definition and args
+ * ` WalkState - Current method state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: For each "Field Unit" name in the argument list that is
+ * part of the field declaration, enter the name into the
+ * namespace.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsInitFieldObjects (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_STATUS Status;
+ ACPI_PARSE_OBJECT *Arg = NULL;
+ ACPI_NAMESPACE_NODE *Node;
+ UINT8 Type = 0;
+ UINT32 Flags;
+
+
+ ACPI_FUNCTION_TRACE_PTR (DsInitFieldObjects, Op);
+
+
+ /* Execute flag should always be set when this function is entered */
+
+ if (!(WalkState->ParseFlags & ACPI_PARSE_EXECUTE))
+ {
+ if (WalkState->ParseFlags & ACPI_PARSE_DEFERRED_OP)
+ {
+ /* BankField Op is deferred, just return OK */
+
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ return_ACPI_STATUS (AE_AML_INTERNAL);
+ }
+
+ /*
+ * Get the FieldList argument for this opcode. This is the start of the
+ * list of field elements.
+ */
+ switch (WalkState->Opcode)
+ {
+ case AML_FIELD_OP:
+ Arg = AcpiPsGetArg (Op, 2);
+ Type = ACPI_TYPE_LOCAL_REGION_FIELD;
+ break;
+
+ case AML_BANK_FIELD_OP:
+ Arg = AcpiPsGetArg (Op, 4);
+ Type = ACPI_TYPE_LOCAL_BANK_FIELD;
+ break;
+
+ case AML_INDEX_FIELD_OP:
+ Arg = AcpiPsGetArg (Op, 3);
+ Type = ACPI_TYPE_LOCAL_INDEX_FIELD;
+ break;
+
+ default:
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ /* Creating new namespace node(s), should not already exist */
+
+ Flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
+ ACPI_NS_ERROR_IF_FOUND;
+
+ /*
+ * Mark node(s) temporary if we are executing a normal control
+ * method. (Don't mark if this is a module-level code method)
+ */
+ if (WalkState->MethodNode &&
+ !(WalkState->ParseFlags & ACPI_PARSE_MODULE_LEVEL))
+ {
+ Flags |= ACPI_NS_TEMPORARY;
+ }
+
+ /*
+ * Walk the list of entries in the FieldList
+ * Note: FieldList can be of zero length. In this case, Arg will be NULL.
+ */
+ while (Arg)
+ {
+ /*
+ * Ignore OFFSET/ACCESSAS/CONNECTION terms here; we are only interested
+ * in the field names in order to enter them into the namespace.
+ */
+ if (Arg->Common.AmlOpcode == AML_INT_NAMEDFIELD_OP)
+ {
+ Status = AcpiNsLookup (WalkState->ScopeInfo,
+ (char *) &Arg->Named.Name, Type, ACPI_IMODE_LOAD_PASS1,
+ Flags, WalkState, &Node);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_ERROR_NAMESPACE ((char *) &Arg->Named.Name, Status);
+ if (Status != AE_ALREADY_EXISTS)
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Name already exists, just ignore this error */
+
+ Status = AE_OK;
+ }
+
+ Arg->Common.Node = Node;
+ }
+
+ /* Get the next field element in the list */
+
+ Arg = Arg->Common.Next;
+ }
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsCreateBankField
+ *
+ * PARAMETERS: Op - Op containing the Field definition and args
+ * RegionNode - Object for the containing Operation Region
+ * WalkState - Current method state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Create a new bank field in the specified operation region
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsCreateBankField (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_NAMESPACE_NODE *RegionNode,
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_STATUS Status;
+ ACPI_PARSE_OBJECT *Arg;
+ ACPI_CREATE_FIELD_INFO Info;
+
+
+ ACPI_FUNCTION_TRACE_PTR (DsCreateBankField, Op);
+
+
+ /* First arg is the name of the parent OpRegion (must already exist) */
+
+ Arg = Op->Common.Value.Arg;
+ if (!RegionNode)
+ {
+ Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.Name,
+ ACPI_TYPE_REGION, ACPI_IMODE_EXECUTE,
+ ACPI_NS_SEARCH_PARENT, WalkState, &RegionNode);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_ERROR_NAMESPACE (Arg->Common.Value.Name, Status);
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+ /* Second arg is the Bank Register (Field) (must already exist) */
+
+ Arg = Arg->Common.Next;
+ Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String,
+ ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
+ ACPI_NS_SEARCH_PARENT, WalkState, &Info.RegisterNode);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status);
+ return_ACPI_STATUS (Status);
+ }
+
+ /*
+ * Third arg is the BankValue
+ * This arg is a TermArg, not a constant
+ * It will be evaluated later, by AcpiDsEvalBankFieldOperands
+ */
+ Arg = Arg->Common.Next;
+
+ /* Fourth arg is the field flags */
+
+ Arg = Arg->Common.Next;
+ Info.FieldFlags = (UINT8) Arg->Common.Value.Integer;
+
+ /* Each remaining arg is a Named Field */
+
+ Info.FieldType = ACPI_TYPE_LOCAL_BANK_FIELD;
+ Info.RegionNode = RegionNode;
+
+ /*
+ * Use Info.DataRegisterNode to store BankField Op
+ * It's safe because DataRegisterNode will never be used when create bank field
+ * We store AmlStart and AmlLength in the BankField Op for late evaluation
+ * Used in AcpiExPrepFieldValue(Info)
+ *
+ * TBD: Or, should we add a field in ACPI_CREATE_FIELD_INFO, like "void *ParentOp"?
+ */
+ Info.DataRegisterNode = (ACPI_NAMESPACE_NODE*) Op;
+
+ Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Common.Next);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsCreateIndexField
+ *
+ * PARAMETERS: Op - Op containing the Field definition and args
+ * RegionNode - Object for the containing Operation Region
+ * ` WalkState - Current method state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Create a new index field in the specified operation region
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsCreateIndexField (
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_NAMESPACE_NODE *RegionNode,
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_STATUS Status;
+ ACPI_PARSE_OBJECT *Arg;
+ ACPI_CREATE_FIELD_INFO Info;
+
+
+ ACPI_FUNCTION_TRACE_PTR (DsCreateIndexField, Op);
+
+
+ /* First arg is the name of the Index register (must already exist) */
+
+ Arg = Op->Common.Value.Arg;
+ Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String,
+ ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
+ ACPI_NS_SEARCH_PARENT, WalkState, &Info.RegisterNode);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status);
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Second arg is the data register (must already exist) */
+
+ Arg = Arg->Common.Next;
+ Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String,
+ ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
+ ACPI_NS_SEARCH_PARENT, WalkState, &Info.DataRegisterNode);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status);
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Next arg is the field flags */
+
+ Arg = Arg->Common.Next;
+ Info.FieldFlags = (UINT8) Arg->Common.Value.Integer;
+
+ /* Each remaining arg is a Named Field */
+
+ Info.FieldType = ACPI_TYPE_LOCAL_INDEX_FIELD;
+ Info.RegionNode = RegionNode;
+
+ Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Common.Next);
+ return_ACPI_STATUS (Status);
+}
+
+
diff --git a/source/components/dispatcher/dsinit.c b/source/components/dispatcher/dsinit.c
new file mode 100644
index 000000000000..1c7ad8849258
--- /dev/null
+++ b/source/components/dispatcher/dsinit.c
@@ -0,0 +1,238 @@
+/******************************************************************************
+ *
+ * Module Name: dsinit - Object initialization namespace walk
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2012, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#define __DSINIT_C__
+
+#include "acpi.h"
+#include "accommon.h"
+#include "acdispat.h"
+#include "acnamesp.h"
+#include "actables.h"
+
+#define _COMPONENT ACPI_DISPATCHER
+ ACPI_MODULE_NAME ("dsinit")
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiDsInitOneObject (
+ ACPI_HANDLE ObjHandle,
+ UINT32 Level,
+ void *Context,
+ void **ReturnValue);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsInitOneObject
+ *
+ * PARAMETERS: ObjHandle - Node for the object
+ * Level - Current nesting level
+ * Context - Points to a init info struct
+ * ReturnValue - Not used
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Callback from AcpiWalkNamespace. Invoked for every object
+ * within the namespace.
+ *
+ * Currently, the only objects that require initialization are:
+ * 1) Methods
+ * 2) Operation Regions
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDsInitOneObject (
+ ACPI_HANDLE ObjHandle,
+ UINT32 Level,
+ void *Context,
+ void **ReturnValue)
+{
+ ACPI_INIT_WALK_INFO *Info = (ACPI_INIT_WALK_INFO *) Context;
+ ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
+ ACPI_OBJECT_TYPE Type;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /*
+ * We are only interested in NS nodes owned by the table that
+ * was just loaded
+ */
+ if (Node->OwnerId != Info->OwnerId)
+ {
+ return (AE_OK);
+ }
+
+ Info->ObjectCount++;
+
+ /* And even then, we are only interested in a few object types */
+
+ Type = AcpiNsGetType (ObjHandle);
+
+ switch (Type)
+ {
+ case ACPI_TYPE_REGION:
+
+ Status = AcpiDsInitializeRegion (ObjHandle);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status,
+ "During Region initialization %p [%4.4s]",
+ ObjHandle, AcpiUtGetNodeName (ObjHandle)));
+ }
+
+ Info->OpRegionCount++;
+ break;
+
+
+ case ACPI_TYPE_METHOD:
+
+ Info->MethodCount++;
+ break;
+
+
+ case ACPI_TYPE_DEVICE:
+
+ Info->DeviceCount++;
+ break;
+
+
+ default:
+ break;
+ }
+
+ /*
+ * We ignore errors from above, and always return OK, since
+ * we don't want to abort the walk on a single error.
+ */
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsInitializeObjects
+ *
+ * PARAMETERS: TableDesc - Descriptor for parent ACPI table
+ * StartNode - Root of subtree to be initialized.
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Walk the namespace starting at "StartNode" and perform any
+ * necessary initialization on the objects found therein
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsInitializeObjects (
+ UINT32 TableIndex,
+ ACPI_NAMESPACE_NODE *StartNode)
+{
+ ACPI_STATUS Status;
+ ACPI_INIT_WALK_INFO Info;
+ ACPI_TABLE_HEADER *Table;
+ ACPI_OWNER_ID OwnerId;
+
+
+ ACPI_FUNCTION_TRACE (DsInitializeObjects);
+
+
+ Status = AcpiTbGetOwnerId (TableIndex, &OwnerId);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "**** Starting initialization of namespace objects ****\n"));
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, "Parsing all Control Methods:"));
+
+ /* Set all init info to zero */
+
+ ACPI_MEMSET (&Info, 0, sizeof (ACPI_INIT_WALK_INFO));
+
+ Info.OwnerId = OwnerId;
+ Info.TableIndex = TableIndex;
+
+ /* Walk entire namespace from the supplied root */
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /*
+ * We don't use AcpiWalkNamespace since we do not want to acquire
+ * the namespace reader lock.
+ */
+ Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, StartNode, ACPI_UINT32_MAX,
+ ACPI_NS_WALK_UNLOCK, AcpiDsInitOneObject, NULL, &Info, NULL);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status, "During WalkNamespace"));
+ }
+ (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
+
+ Status = AcpiGetTableByIndex (TableIndex, &Table);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
+ "\nTable [%4.4s](id %4.4X) - %u Objects with %u Devices %u Methods %u Regions\n",
+ Table->Signature, OwnerId, Info.ObjectCount,
+ Info.DeviceCount, Info.MethodCount, Info.OpRegionCount));
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "%u Methods, %u Regions\n", Info.MethodCount, Info.OpRegionCount));
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+
diff --git a/source/components/dispatcher/dsmethod.c b/source/components/dispatcher/dsmethod.c
new file mode 100644
index 000000000000..670382ac9bfb
--- /dev/null
+++ b/source/components/dispatcher/dsmethod.c
@@ -0,0 +1,726 @@
+/******************************************************************************
+ *
+ * Module Name: dsmethod - Parser/Interpreter interface - control method parsing
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2012, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#define __DSMETHOD_C__
+
+#include "acpi.h"
+#include "accommon.h"
+#include "acdispat.h"
+#include "acinterp.h"
+#include "acnamesp.h"
+#include "acdisasm.h"
+
+
+#define _COMPONENT ACPI_DISPATCHER
+ ACPI_MODULE_NAME ("dsmethod")
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiDsCreateMethodMutex (
+ ACPI_OPERAND_OBJECT *MethodDesc);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsMethodError
+ *
+ * PARAMETERS: Status - Execution status
+ * WalkState - Current state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Called on method error. Invoke the global exception handler if
+ * present, dump the method data if the disassembler is configured
+ *
+ * Note: Allows the exception handler to change the status code
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsMethodError (
+ ACPI_STATUS Status,
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /* Ignore AE_OK and control exception codes */
+
+ if (ACPI_SUCCESS (Status) ||
+ (Status & AE_CODE_CONTROL))
+ {
+ return (Status);
+ }
+
+ /* Invoke the global exception handler */
+
+ if (AcpiGbl_ExceptionHandler)
+ {
+ /* Exit the interpreter, allow handler to execute methods */
+
+ AcpiExExitInterpreter ();
+
+ /*
+ * Handler can map the exception code to anything it wants, including
+ * AE_OK, in which case the executing method will not be aborted.
+ */
+ Status = AcpiGbl_ExceptionHandler (Status,
+ WalkState->MethodNode ?
+ WalkState->MethodNode->Name.Integer : 0,
+ WalkState->Opcode, WalkState->AmlOffset, NULL);
+ AcpiExEnterInterpreter ();
+ }
+
+ AcpiDsClearImplicitReturn (WalkState);
+
+#ifdef ACPI_DISASSEMBLER
+ if (ACPI_FAILURE (Status))
+ {
+ /* Display method locals/args if disassembler is present */
+
+ AcpiDmDumpMethodInfo (Status, WalkState, WalkState->Op);
+ }
+#endif
+
+ return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsCreateMethodMutex
+ *
+ * PARAMETERS: ObjDesc - The method object
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Create a mutex object for a serialized control method
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDsCreateMethodMutex (
+ ACPI_OPERAND_OBJECT *MethodDesc)
+{
+ ACPI_OPERAND_OBJECT *MutexDesc;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (DsCreateMethodMutex);
+
+
+ /* Create the new mutex object */
+
+ MutexDesc = AcpiUtCreateInternalObject (ACPI_TYPE_MUTEX);
+ if (!MutexDesc)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ /* Create the actual OS Mutex */
+
+ Status = AcpiOsCreateMutex (&MutexDesc->Mutex.OsMutex);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ MutexDesc->Mutex.SyncLevel = MethodDesc->Method.SyncLevel;
+ MethodDesc->Method.Mutex = MutexDesc;
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsBeginMethodExecution
+ *
+ * PARAMETERS: MethodNode - Node of the method
+ * ObjDesc - The method object
+ * WalkState - current state, NULL if not yet executing
+ * a method.
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Prepare a method for execution. Parses the method if necessary,
+ * increments the thread count, and waits at the method semaphore
+ * for clearance to execute.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsBeginMethodExecution (
+ ACPI_NAMESPACE_NODE *MethodNode,
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_STATUS Status = AE_OK;
+
+
+ ACPI_FUNCTION_TRACE_PTR (DsBeginMethodExecution, MethodNode);
+
+
+ if (!MethodNode)
+ {
+ return_ACPI_STATUS (AE_NULL_ENTRY);
+ }
+
+ /* Prevent wraparound of thread count */
+
+ if (ObjDesc->Method.ThreadCount == ACPI_UINT8_MAX)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Method reached maximum reentrancy limit (255)"));
+ return_ACPI_STATUS (AE_AML_METHOD_LIMIT);
+ }
+
+ /*
+ * If this method is serialized, we need to acquire the method mutex.
+ */
+ if (ObjDesc->Method.InfoFlags & ACPI_METHOD_SERIALIZED)
+ {
+ /*
+ * Create a mutex for the method if it is defined to be Serialized
+ * and a mutex has not already been created. We defer the mutex creation
+ * until a method is actually executed, to minimize the object count
+ */
+ if (!ObjDesc->Method.Mutex)
+ {
+ Status = AcpiDsCreateMethodMutex (ObjDesc);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+ /*
+ * The CurrentSyncLevel (per-thread) must be less than or equal to
+ * the sync level of the method. This mechanism provides some
+ * deadlock prevention
+ *
+ * Top-level method invocation has no walk state at this point
+ */
+ if (WalkState &&
+ (WalkState->Thread->CurrentSyncLevel > ObjDesc->Method.Mutex->Mutex.SyncLevel))
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Cannot acquire Mutex for method [%4.4s], current SyncLevel is too large (%u)",
+ AcpiUtGetNodeName (MethodNode),
+ WalkState->Thread->CurrentSyncLevel));
+
+ return_ACPI_STATUS (AE_AML_MUTEX_ORDER);
+ }
+
+ /*
+ * Obtain the method mutex if necessary. Do not acquire mutex for a
+ * recursive call.
+ */
+ if (!WalkState ||
+ !ObjDesc->Method.Mutex->Mutex.ThreadId ||
+ (WalkState->Thread->ThreadId != ObjDesc->Method.Mutex->Mutex.ThreadId))
+ {
+ /*
+ * Acquire the method mutex. This releases the interpreter if we
+ * block (and reacquires it before it returns)
+ */
+ Status = AcpiExSystemWaitMutex (ObjDesc->Method.Mutex->Mutex.OsMutex,
+ ACPI_WAIT_FOREVER);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Update the mutex and walk info and save the original SyncLevel */
+
+ if (WalkState)
+ {
+ ObjDesc->Method.Mutex->Mutex.OriginalSyncLevel =
+ WalkState->Thread->CurrentSyncLevel;
+
+ ObjDesc->Method.Mutex->Mutex.ThreadId = WalkState->Thread->ThreadId;
+ WalkState->Thread->CurrentSyncLevel = ObjDesc->Method.SyncLevel;
+ }
+ else
+ {
+ ObjDesc->Method.Mutex->Mutex.OriginalSyncLevel =
+ ObjDesc->Method.Mutex->Mutex.SyncLevel;
+ }
+ }
+
+ /* Always increase acquisition depth */
+
+ ObjDesc->Method.Mutex->Mutex.AcquisitionDepth++;
+ }
+
+ /*
+ * Allocate an Owner ID for this method, only if this is the first thread
+ * to begin concurrent execution. We only need one OwnerId, even if the
+ * method is invoked recursively.
+ */
+ if (!ObjDesc->Method.OwnerId)
+ {
+ Status = AcpiUtAllocateOwnerId (&ObjDesc->Method.OwnerId);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Cleanup;
+ }
+ }
+
+ /*
+ * Increment the method parse tree thread count since it has been
+ * reentered one more time (even if it is the same thread)
+ */
+ ObjDesc->Method.ThreadCount++;
+ AcpiMethodCount++;
+ return_ACPI_STATUS (Status);
+
+
+Cleanup:
+ /* On error, must release the method mutex (if present) */
+
+ if (ObjDesc->Method.Mutex)
+ {
+ AcpiOsReleaseMutex (ObjDesc->Method.Mutex->Mutex.OsMutex);
+ }
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsCallControlMethod
+ *
+ * PARAMETERS: Thread - Info for this thread
+ * ThisWalkState - Current walk state
+ * Op - Current Op to be walked
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Transfer execution to a called control method
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsCallControlMethod (
+ ACPI_THREAD_STATE *Thread,
+ ACPI_WALK_STATE *ThisWalkState,
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_STATUS Status;
+ ACPI_NAMESPACE_NODE *MethodNode;
+ ACPI_WALK_STATE *NextWalkState = NULL;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_EVALUATE_INFO *Info;
+ UINT32 i;
+
+
+ ACPI_FUNCTION_TRACE_PTR (DsCallControlMethod, ThisWalkState);
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Calling method %p, currentstate=%p\n",
+ ThisWalkState->PrevOp, ThisWalkState));
+
+ /*
+ * Get the namespace entry for the control method we are about to call
+ */
+ MethodNode = ThisWalkState->MethodCallNode;
+ if (!MethodNode)
+ {
+ return_ACPI_STATUS (AE_NULL_ENTRY);
+ }
+
+ ObjDesc = AcpiNsGetAttachedObject (MethodNode);
+ if (!ObjDesc)
+ {
+ return_ACPI_STATUS (AE_NULL_OBJECT);
+ }
+
+ /* Init for new method, possibly wait on method mutex */
+
+ Status = AcpiDsBeginMethodExecution (MethodNode, ObjDesc,
+ ThisWalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Begin method parse/execution. Create a new walk state */
+
+ NextWalkState = AcpiDsCreateWalkState (ObjDesc->Method.OwnerId,
+ NULL, ObjDesc, Thread);
+ if (!NextWalkState)
+ {
+ Status = AE_NO_MEMORY;
+ goto Cleanup;
+ }
+
+ /*
+ * The resolved arguments were put on the previous walk state's operand
+ * stack. Operands on the previous walk state stack always
+ * start at index 0. Also, null terminate the list of arguments
+ */
+ ThisWalkState->Operands [ThisWalkState->NumOperands] = NULL;
+
+ /*
+ * Allocate and initialize the evaluation information block
+ * TBD: this is somewhat inefficient, should change interface to
+ * DsInitAmlWalk. For now, keeps this struct off the CPU stack
+ */
+ Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
+ if (!Info)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ Info->Parameters = &ThisWalkState->Operands[0];
+
+ Status = AcpiDsInitAmlWalk (NextWalkState, NULL, MethodNode,
+ ObjDesc->Method.AmlStart, ObjDesc->Method.AmlLength,
+ Info, ACPI_IMODE_EXECUTE);
+
+ ACPI_FREE (Info);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Cleanup;
+ }
+
+ /*
+ * Delete the operands on the previous walkstate operand stack
+ * (they were copied to new objects)
+ */
+ for (i = 0; i < ObjDesc->Method.ParamCount; i++)
+ {
+ AcpiUtRemoveReference (ThisWalkState->Operands [i]);
+ ThisWalkState->Operands [i] = NULL;
+ }
+
+ /* Clear the operand stack */
+
+ ThisWalkState->NumOperands = 0;
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "**** Begin nested execution of [%4.4s] **** WalkState=%p\n",
+ MethodNode->Name.Ascii, NextWalkState));
+
+ /* Invoke an internal method if necessary */
+
+ if (ObjDesc->Method.InfoFlags & ACPI_METHOD_INTERNAL_ONLY)
+ {
+ Status = ObjDesc->Method.Dispatch.Implementation (NextWalkState);
+ if (Status == AE_OK)
+ {
+ Status = AE_CTRL_TERMINATE;
+ }
+ }
+
+ return_ACPI_STATUS (Status);
+
+
+Cleanup:
+
+ /* On error, we must terminate the method properly */
+
+ AcpiDsTerminateControlMethod (ObjDesc, NextWalkState);
+ if (NextWalkState)
+ {
+ AcpiDsDeleteWalkState (NextWalkState);
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsRestartControlMethod
+ *
+ * PARAMETERS: WalkState - State for preempted method (caller)
+ * ReturnDesc - Return value from the called method
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Restart a method that was preempted by another (nested) method
+ * invocation. Handle the return value (if any) from the callee.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsRestartControlMethod (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_OPERAND_OBJECT *ReturnDesc)
+{
+ ACPI_STATUS Status;
+ int SameAsImplicitReturn;
+
+
+ ACPI_FUNCTION_TRACE_PTR (DsRestartControlMethod, WalkState);
+
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "****Restart [%4.4s] Op %p ReturnValueFromCallee %p\n",
+ AcpiUtGetNodeName (WalkState->MethodNode),
+ WalkState->MethodCallOp, ReturnDesc));
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ " ReturnFromThisMethodUsed?=%X ResStack %p Walk %p\n",
+ WalkState->ReturnUsed,
+ WalkState->Results, WalkState));
+
+ /* Did the called method return a value? */
+
+ if (ReturnDesc)
+ {
+ /* Is the implicit return object the same as the return desc? */
+
+ SameAsImplicitReturn = (WalkState->ImplicitReturnObj == ReturnDesc);
+
+ /* Are we actually going to use the return value? */
+
+ if (WalkState->ReturnUsed)
+ {
+ /* Save the return value from the previous method */
+
+ Status = AcpiDsResultPush (ReturnDesc, WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiUtRemoveReference (ReturnDesc);
+ return_ACPI_STATUS (Status);
+ }
+
+ /*
+ * Save as THIS method's return value in case it is returned
+ * immediately to yet another method
+ */
+ WalkState->ReturnDesc = ReturnDesc;
+ }
+
+ /*
+ * The following code is the optional support for the so-called
+ * "implicit return". Some AML code assumes that the last value of the
+ * method is "implicitly" returned to the caller, in the absence of an
+ * explicit return value.
+ *
+ * Just save the last result of the method as the return value.
+ *
+ * NOTE: this is optional because the ASL language does not actually
+ * support this behavior.
+ */
+ else if (!AcpiDsDoImplicitReturn (ReturnDesc, WalkState, FALSE) ||
+ SameAsImplicitReturn)
+ {
+ /*
+ * Delete the return value if it will not be used by the
+ * calling method or remove one reference if the explicit return
+ * is the same as the implicit return value.
+ */
+ AcpiUtRemoveReference (ReturnDesc);
+ }
+ }
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsTerminateControlMethod
+ *
+ * PARAMETERS: MethodDesc - Method object
+ * WalkState - State associated with the method
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Terminate a control method. Delete everything that the method
+ * created, delete all locals and arguments, and delete the parse
+ * tree if requested.
+ *
+ * MUTEX: Interpreter is locked
+ *
+ ******************************************************************************/
+
+void
+AcpiDsTerminateControlMethod (
+ ACPI_OPERAND_OBJECT *MethodDesc,
+ ACPI_WALK_STATE *WalkState)
+{
+
+ ACPI_FUNCTION_TRACE_PTR (DsTerminateControlMethod, WalkState);
+
+
+ /* MethodDesc is required, WalkState is optional */
+
+ if (!MethodDesc)
+ {
+ return_VOID;
+ }
+
+ if (WalkState)
+ {
+ /* Delete all arguments and locals */
+
+ AcpiDsMethodDataDeleteAll (WalkState);
+
+ /*
+ * If method is serialized, release the mutex and restore the
+ * current sync level for this thread
+ */
+ if (MethodDesc->Method.Mutex)
+ {
+ /* Acquisition Depth handles recursive calls */
+
+ MethodDesc->Method.Mutex->Mutex.AcquisitionDepth--;
+ if (!MethodDesc->Method.Mutex->Mutex.AcquisitionDepth)
+ {
+ WalkState->Thread->CurrentSyncLevel =
+ MethodDesc->Method.Mutex->Mutex.OriginalSyncLevel;
+
+ AcpiOsReleaseMutex (MethodDesc->Method.Mutex->Mutex.OsMutex);
+ MethodDesc->Method.Mutex->Mutex.ThreadId = 0;
+ }
+ }
+
+ /*
+ * Delete any namespace objects created anywhere within the
+ * namespace by the execution of this method. Unless:
+ * 1) This method is a module-level executable code method, in which
+ * case we want make the objects permanent.
+ * 2) There are other threads executing the method, in which case we
+ * will wait until the last thread has completed.
+ */
+ if (!(MethodDesc->Method.InfoFlags & ACPI_METHOD_MODULE_LEVEL) &&
+ (MethodDesc->Method.ThreadCount == 1))
+ {
+ /* Delete any direct children of (created by) this method */
+
+ AcpiNsDeleteNamespaceSubtree (WalkState->MethodNode);
+
+ /*
+ * Delete any objects that were created by this method
+ * elsewhere in the namespace (if any were created).
+ * Use of the ACPI_METHOD_MODIFIED_NAMESPACE optimizes the
+ * deletion such that we don't have to perform an entire
+ * namespace walk for every control method execution.
+ */
+ if (MethodDesc->Method.InfoFlags & ACPI_METHOD_MODIFIED_NAMESPACE)
+ {
+ AcpiNsDeleteNamespaceByOwner (MethodDesc->Method.OwnerId);
+ MethodDesc->Method.InfoFlags &= ~ACPI_METHOD_MODIFIED_NAMESPACE;
+ }
+ }
+ }
+
+ /* Decrement the thread count on the method */
+
+ if (MethodDesc->Method.ThreadCount)
+ {
+ MethodDesc->Method.ThreadCount--;
+ }
+ else
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Invalid zero thread count in method"));
+ }
+
+ /* Are there any other threads currently executing this method? */
+
+ if (MethodDesc->Method.ThreadCount)
+ {
+ /*
+ * Additional threads. Do not release the OwnerId in this case,
+ * we immediately reuse it for the next thread executing this method
+ */
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "*** Completed execution of one thread, %u threads remaining\n",
+ MethodDesc->Method.ThreadCount));
+ }
+ else
+ {
+ /* This is the only executing thread for this method */
+
+ /*
+ * Support to dynamically change a method from NotSerialized to
+ * Serialized if it appears that the method is incorrectly written and
+ * does not support multiple thread execution. The best example of this
+ * is if such a method creates namespace objects and blocks. A second
+ * thread will fail with an AE_ALREADY_EXISTS exception.
+ *
+ * This code is here because we must wait until the last thread exits
+ * before marking the method as serialized.
+ */
+ if (MethodDesc->Method.InfoFlags & ACPI_METHOD_SERIALIZED_PENDING)
+ {
+ if (WalkState)
+ {
+ ACPI_INFO ((AE_INFO,
+ "Marking method %4.4s as Serialized because of AE_ALREADY_EXISTS error",
+ WalkState->MethodNode->Name.Ascii));
+ }
+
+ /*
+ * Method tried to create an object twice and was marked as
+ * "pending serialized". The probable cause is that the method
+ * cannot handle reentrancy.
+ *
+ * The method was created as NotSerialized, but it tried to create
+ * a named object and then blocked, causing the second thread
+ * entrance to begin and then fail. Workaround this problem by
+ * marking the method permanently as Serialized when the last
+ * thread exits here.
+ */
+ MethodDesc->Method.InfoFlags &= ~ACPI_METHOD_SERIALIZED_PENDING;
+ MethodDesc->Method.InfoFlags |= ACPI_METHOD_SERIALIZED;
+ MethodDesc->Method.SyncLevel = 0;
+ }
+
+ /* No more threads, we can free the OwnerId */
+
+ if (!(MethodDesc->Method.InfoFlags & ACPI_METHOD_MODULE_LEVEL))
+ {
+ AcpiUtReleaseOwnerId (&MethodDesc->Method.OwnerId);
+ }
+ }
+
+ return_VOID;
+}
+
+
diff --git a/source/components/dispatcher/dsmthdat.c b/source/components/dispatcher/dsmthdat.c
new file mode 100644
index 000000000000..b4509e771021
--- /dev/null
+++ b/source/components/dispatcher/dsmthdat.c
@@ -0,0 +1,772 @@
+/*******************************************************************************
+ *
+ * Module Name: dsmthdat - control method arguments and local variables
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2012, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#define __DSMTHDAT_C__
+
+#include "acpi.h"
+#include "accommon.h"
+#include "acdispat.h"
+#include "acnamesp.h"
+#include "acinterp.h"
+
+
+#define _COMPONENT ACPI_DISPATCHER
+ ACPI_MODULE_NAME ("dsmthdat")
+
+/* Local prototypes */
+
+static void
+AcpiDsMethodDataDeleteValue (
+ UINT8 Type,
+ UINT32 Index,
+ ACPI_WALK_STATE *WalkState);
+
+static ACPI_STATUS
+AcpiDsMethodDataSetValue (
+ UINT8 Type,
+ UINT32 Index,
+ ACPI_OPERAND_OBJECT *Object,
+ ACPI_WALK_STATE *WalkState);
+
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+ACPI_OBJECT_TYPE
+AcpiDsMethodDataGetType (
+ UINT16 Opcode,
+ UINT32 Index,
+ ACPI_WALK_STATE *WalkState);
+#endif
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsMethodDataInit
+ *
+ * PARAMETERS: WalkState - Current walk state object
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Initialize the data structures that hold the method's arguments
+ * and locals. The data struct is an array of namespace nodes for
+ * each - this allows RefOf and DeRefOf to work properly for these
+ * special data types.
+ *
+ * NOTES: WalkState fields are initialized to zero by the
+ * ACPI_ALLOCATE_ZEROED().
+ *
+ * A pseudo-Namespace Node is assigned to each argument and local
+ * so that RefOf() can return a pointer to the Node.
+ *
+ ******************************************************************************/
+
+void
+AcpiDsMethodDataInit (
+ ACPI_WALK_STATE *WalkState)
+{
+ UINT32 i;
+
+
+ ACPI_FUNCTION_TRACE (DsMethodDataInit);
+
+
+ /* Init the method arguments */
+
+ for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++)
+ {
+ ACPI_MOVE_32_TO_32 (&WalkState->Arguments[i].Name, NAMEOF_ARG_NTE);
+ WalkState->Arguments[i].Name.Integer |= (i << 24);
+ WalkState->Arguments[i].DescriptorType = ACPI_DESC_TYPE_NAMED;
+ WalkState->Arguments[i].Type = ACPI_TYPE_ANY;
+ WalkState->Arguments[i].Flags = ANOBJ_METHOD_ARG;
+ }
+
+ /* Init the method locals */
+
+ for (i = 0; i < ACPI_METHOD_NUM_LOCALS; i++)
+ {
+ ACPI_MOVE_32_TO_32 (&WalkState->LocalVariables[i].Name, NAMEOF_LOCAL_NTE);
+
+ WalkState->LocalVariables[i].Name.Integer |= (i << 24);
+ WalkState->LocalVariables[i].DescriptorType = ACPI_DESC_TYPE_NAMED;
+ WalkState->LocalVariables[i].Type = ACPI_TYPE_ANY;
+ WalkState->LocalVariables[i].Flags = ANOBJ_METHOD_LOCAL;
+ }
+
+ return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsMethodDataDeleteAll
+ *
+ * PARAMETERS: WalkState - Current walk state object
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Delete method locals and arguments. Arguments are only
+ * deleted if this method was called from another method.
+ *
+ ******************************************************************************/
+
+void
+AcpiDsMethodDataDeleteAll (
+ ACPI_WALK_STATE *WalkState)
+{
+ UINT32 Index;
+
+
+ ACPI_FUNCTION_TRACE (DsMethodDataDeleteAll);
+
+
+ /* Detach the locals */
+
+ for (Index = 0; Index < ACPI_METHOD_NUM_LOCALS; Index++)
+ {
+ if (WalkState->LocalVariables[Index].Object)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Deleting Local%u=%p\n",
+ Index, WalkState->LocalVariables[Index].Object));
+
+ /* Detach object (if present) and remove a reference */
+
+ AcpiNsDetachObject (&WalkState->LocalVariables[Index]);
+ }
+ }
+
+ /* Detach the arguments */
+
+ for (Index = 0; Index < ACPI_METHOD_NUM_ARGS; Index++)
+ {
+ if (WalkState->Arguments[Index].Object)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Deleting Arg%u=%p\n",
+ Index, WalkState->Arguments[Index].Object));
+
+ /* Detach object (if present) and remove a reference */
+
+ AcpiNsDetachObject (&WalkState->Arguments[Index]);
+ }
+ }
+
+ return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsMethodDataInitArgs
+ *
+ * PARAMETERS: *Params - Pointer to a parameter list for the method
+ * MaxParamCount - The arg count for this method
+ * WalkState - Current walk state object
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Initialize arguments for a method. The parameter list is a list
+ * of ACPI operand objects, either null terminated or whose length
+ * is defined by MaxParamCount.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsMethodDataInitArgs (
+ ACPI_OPERAND_OBJECT **Params,
+ UINT32 MaxParamCount,
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_STATUS Status;
+ UINT32 Index = 0;
+
+
+ ACPI_FUNCTION_TRACE_PTR (DsMethodDataInitArgs, Params);
+
+
+ if (!Params)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "No param list passed to method\n"));
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* Copy passed parameters into the new method stack frame */
+
+ while ((Index < ACPI_METHOD_NUM_ARGS) &&
+ (Index < MaxParamCount) &&
+ Params[Index])
+ {
+ /*
+ * A valid parameter.
+ * Store the argument in the method/walk descriptor.
+ * Do not copy the arg in order to implement call by reference
+ */
+ Status = AcpiDsMethodDataSetValue (ACPI_REFCLASS_ARG, Index,
+ Params[Index], WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ Index++;
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%u args passed to method\n", Index));
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsMethodDataGetNode
+ *
+ * PARAMETERS: Type - Either ACPI_REFCLASS_LOCAL or
+ * ACPI_REFCLASS_ARG
+ * Index - Which Local or Arg whose type to get
+ * WalkState - Current walk state object
+ * Node - Where the node is returned.
+ *
+ * RETURN: Status and node
+ *
+ * DESCRIPTION: Get the Node associated with a local or arg.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsMethodDataGetNode (
+ UINT8 Type,
+ UINT32 Index,
+ ACPI_WALK_STATE *WalkState,
+ ACPI_NAMESPACE_NODE **Node)
+{
+ ACPI_FUNCTION_TRACE (DsMethodDataGetNode);
+
+
+ /*
+ * Method Locals and Arguments are supported
+ */
+ switch (Type)
+ {
+ case ACPI_REFCLASS_LOCAL:
+
+ if (Index > ACPI_METHOD_MAX_LOCAL)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Local index %u is invalid (max %u)",
+ Index, ACPI_METHOD_MAX_LOCAL));
+ return_ACPI_STATUS (AE_AML_INVALID_INDEX);
+ }
+
+ /* Return a pointer to the pseudo-node */
+
+ *Node = &WalkState->LocalVariables[Index];
+ break;
+
+ case ACPI_REFCLASS_ARG:
+
+ if (Index > ACPI_METHOD_MAX_ARG)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Arg index %u is invalid (max %u)",
+ Index, ACPI_METHOD_MAX_ARG));
+ return_ACPI_STATUS (AE_AML_INVALID_INDEX);
+ }
+
+ /* Return a pointer to the pseudo-node */
+
+ *Node = &WalkState->Arguments[Index];
+ break;
+
+ default:
+ ACPI_ERROR ((AE_INFO, "Type %u is invalid", Type));
+ return_ACPI_STATUS (AE_TYPE);
+ }
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsMethodDataSetValue
+ *
+ * PARAMETERS: Type - Either ACPI_REFCLASS_LOCAL or
+ * ACPI_REFCLASS_ARG
+ * Index - Which Local or Arg to get
+ * Object - Object to be inserted into the stack entry
+ * WalkState - Current walk state object
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Insert an object onto the method stack at entry Opcode:Index.
+ * Note: There is no "implicit conversion" for locals.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDsMethodDataSetValue (
+ UINT8 Type,
+ UINT32 Index,
+ ACPI_OPERAND_OBJECT *Object,
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_STATUS Status;
+ ACPI_NAMESPACE_NODE *Node;
+
+
+ ACPI_FUNCTION_TRACE (DsMethodDataSetValue);
+
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "NewObj %p Type %2.2X, Refs=%u [%s]\n", Object,
+ Type, Object->Common.ReferenceCount,
+ AcpiUtGetTypeName (Object->Common.Type)));
+
+ /* Get the namespace node for the arg/local */
+
+ Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /*
+ * Increment ref count so object can't be deleted while installed.
+ * NOTE: We do not copy the object in order to preserve the call by
+ * reference semantics of ACPI Control Method invocation.
+ * (See ACPI Specification 2.0C)
+ */
+ AcpiUtAddReference (Object);
+
+ /* Install the object */
+
+ Node->Object = Object;
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsMethodDataGetValue
+ *
+ * PARAMETERS: Type - Either ACPI_REFCLASS_LOCAL or
+ * ACPI_REFCLASS_ARG
+ * Index - Which localVar or argument to get
+ * WalkState - Current walk state object
+ * DestDesc - Where Arg or Local value is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Retrieve value of selected Arg or Local for this method
+ * Used only in AcpiExResolveToValue().
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsMethodDataGetValue (
+ UINT8 Type,
+ UINT32 Index,
+ ACPI_WALK_STATE *WalkState,
+ ACPI_OPERAND_OBJECT **DestDesc)
+{
+ ACPI_STATUS Status;
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_OPERAND_OBJECT *Object;
+
+
+ ACPI_FUNCTION_TRACE (DsMethodDataGetValue);
+
+
+ /* Validate the object descriptor */
+
+ if (!DestDesc)
+ {
+ ACPI_ERROR ((AE_INFO, "Null object descriptor pointer"));
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ /* Get the namespace node for the arg/local */
+
+ Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Get the object from the node */
+
+ Object = Node->Object;
+
+ /* Examine the returned object, it must be valid. */
+
+ if (!Object)
+ {
+ /*
+ * Index points to uninitialized object.
+ * This means that either 1) The expected argument was
+ * not passed to the method, or 2) A local variable
+ * was referenced by the method (via the ASL)
+ * before it was initialized. Either case is an error.
+ */
+
+ /* If slack enabled, init the LocalX/ArgX to an Integer of value zero */
+
+ if (AcpiGbl_EnableInterpreterSlack)
+ {
+ Object = AcpiUtCreateIntegerObject ((UINT64) 0);
+ if (!Object)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ Node->Object = Object;
+ }
+
+ /* Otherwise, return the error */
+
+ else switch (Type)
+ {
+ case ACPI_REFCLASS_ARG:
+
+ ACPI_ERROR ((AE_INFO,
+ "Uninitialized Arg[%u] at node %p",
+ Index, Node));
+
+ return_ACPI_STATUS (AE_AML_UNINITIALIZED_ARG);
+
+ case ACPI_REFCLASS_LOCAL:
+
+ /*
+ * No error message for this case, will be trapped again later to
+ * detect and ignore cases of Store(LocalX,LocalX)
+ */
+ return_ACPI_STATUS (AE_AML_UNINITIALIZED_LOCAL);
+
+ default:
+
+ ACPI_ERROR ((AE_INFO, "Not a Arg/Local opcode: 0x%X", Type));
+ return_ACPI_STATUS (AE_AML_INTERNAL);
+ }
+ }
+
+ /*
+ * The Index points to an initialized and valid object.
+ * Return an additional reference to the object
+ */
+ *DestDesc = Object;
+ AcpiUtAddReference (Object);
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsMethodDataDeleteValue
+ *
+ * PARAMETERS: Type - Either ACPI_REFCLASS_LOCAL or
+ * ACPI_REFCLASS_ARG
+ * Index - Which localVar or argument to delete
+ * WalkState - Current walk state object
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Delete the entry at Opcode:Index. Inserts
+ * a null into the stack slot after the object is deleted.
+ *
+ ******************************************************************************/
+
+static void
+AcpiDsMethodDataDeleteValue (
+ UINT8 Type,
+ UINT32 Index,
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_STATUS Status;
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_OPERAND_OBJECT *Object;
+
+
+ ACPI_FUNCTION_TRACE (DsMethodDataDeleteValue);
+
+
+ /* Get the namespace node for the arg/local */
+
+ Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node);
+ if (ACPI_FAILURE (Status))
+ {
+ return_VOID;
+ }
+
+ /* Get the associated object */
+
+ Object = AcpiNsGetAttachedObject (Node);
+
+ /*
+ * Undefine the Arg or Local by setting its descriptor
+ * pointer to NULL. Locals/Args can contain both
+ * ACPI_OPERAND_OBJECTS and ACPI_NAMESPACE_NODEs
+ */
+ Node->Object = NULL;
+
+ if ((Object) &&
+ (ACPI_GET_DESCRIPTOR_TYPE (Object) == ACPI_DESC_TYPE_OPERAND))
+ {
+ /*
+ * There is a valid object.
+ * Decrement the reference count by one to balance the
+ * increment when the object was stored.
+ */
+ AcpiUtRemoveReference (Object);
+ }
+
+ return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsStoreObjectToLocal
+ *
+ * PARAMETERS: Type - Either ACPI_REFCLASS_LOCAL or
+ * ACPI_REFCLASS_ARG
+ * Index - Which Local or Arg to set
+ * ObjDesc - Value to be stored
+ * WalkState - Current walk state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Store a value in an Arg or Local. The ObjDesc is installed
+ * as the new value for the Arg or Local and the reference count
+ * for ObjDesc is incremented.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsStoreObjectToLocal (
+ UINT8 Type,
+ UINT32 Index,
+ ACPI_OPERAND_OBJECT *ObjDesc,
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_STATUS Status;
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_OPERAND_OBJECT *CurrentObjDesc;
+ ACPI_OPERAND_OBJECT *NewObjDesc;
+
+
+ ACPI_FUNCTION_TRACE (DsStoreObjectToLocal);
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Type=%2.2X Index=%u Obj=%p\n",
+ Type, Index, ObjDesc));
+
+ /* Parameter validation */
+
+ if (!ObjDesc)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ /* Get the namespace node for the arg/local */
+
+ Status = AcpiDsMethodDataGetNode (Type, Index, WalkState, &Node);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ CurrentObjDesc = AcpiNsGetAttachedObject (Node);
+ if (CurrentObjDesc == ObjDesc)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p already installed!\n",
+ ObjDesc));
+ return_ACPI_STATUS (Status);
+ }
+
+ /*
+ * If the reference count on the object is more than one, we must
+ * take a copy of the object before we store. A reference count
+ * of exactly 1 means that the object was just created during the
+ * evaluation of an expression, and we can safely use it since it
+ * is not used anywhere else.
+ */
+ NewObjDesc = ObjDesc;
+ if (ObjDesc->Common.ReferenceCount > 1)
+ {
+ Status = AcpiUtCopyIobjectToIobject (ObjDesc, &NewObjDesc, WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+ /*
+ * If there is an object already in this slot, we either
+ * have to delete it, or if this is an argument and there
+ * is an object reference stored there, we have to do
+ * an indirect store!
+ */
+ if (CurrentObjDesc)
+ {
+ /*
+ * Check for an indirect store if an argument
+ * contains an object reference (stored as an Node).
+ * We don't allow this automatic dereferencing for
+ * locals, since a store to a local should overwrite
+ * anything there, including an object reference.
+ *
+ * If both Arg0 and Local0 contain RefOf (Local4):
+ *
+ * Store (1, Arg0) - Causes indirect store to local4
+ * Store (1, Local0) - Stores 1 in local0, overwriting
+ * the reference to local4
+ * Store (1, DeRefof (Local0)) - Causes indirect store to local4
+ *
+ * Weird, but true.
+ */
+ if (Type == ACPI_REFCLASS_ARG)
+ {
+ /*
+ * If we have a valid reference object that came from RefOf(),
+ * do the indirect store
+ */
+ if ((ACPI_GET_DESCRIPTOR_TYPE (CurrentObjDesc) == ACPI_DESC_TYPE_OPERAND) &&
+ (CurrentObjDesc->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) &&
+ (CurrentObjDesc->Reference.Class == ACPI_REFCLASS_REFOF))
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "Arg (%p) is an ObjRef(Node), storing in node %p\n",
+ NewObjDesc, CurrentObjDesc));
+
+ /*
+ * Store this object to the Node (perform the indirect store)
+ * NOTE: No implicit conversion is performed, as per the ACPI
+ * specification rules on storing to Locals/Args.
+ */
+ Status = AcpiExStoreObjectToNode (NewObjDesc,
+ CurrentObjDesc->Reference.Object, WalkState,
+ ACPI_NO_IMPLICIT_CONVERSION);
+
+ /* Remove local reference if we copied the object above */
+
+ if (NewObjDesc != ObjDesc)
+ {
+ AcpiUtRemoveReference (NewObjDesc);
+ }
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+ /* Delete the existing object before storing the new one */
+
+ AcpiDsMethodDataDeleteValue (Type, Index, WalkState);
+ }
+
+ /*
+ * Install the Obj descriptor (*NewObjDesc) into
+ * the descriptor for the Arg or Local.
+ * (increments the object reference count by one)
+ */
+ Status = AcpiDsMethodDataSetValue (Type, Index, NewObjDesc, WalkState);
+
+ /* Remove local reference if we copied the object above */
+
+ if (NewObjDesc != ObjDesc)
+ {
+ AcpiUtRemoveReference (NewObjDesc);
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsMethodDataGetType
+ *
+ * PARAMETERS: Opcode - Either AML_LOCAL_OP or AML_ARG_OP
+ * Index - Which Local or Arg whose type to get
+ * WalkState - Current walk state object
+ *
+ * RETURN: Data type of current value of the selected Arg or Local
+ *
+ * DESCRIPTION: Get the type of the object stored in the Local or Arg
+ *
+ ******************************************************************************/
+
+ACPI_OBJECT_TYPE
+AcpiDsMethodDataGetType (
+ UINT16 Opcode,
+ UINT32 Index,
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_STATUS Status;
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_OPERAND_OBJECT *Object;
+
+
+ ACPI_FUNCTION_TRACE (DsMethodDataGetType);
+
+
+ /* Get the namespace node for the arg/local */
+
+ Status = AcpiDsMethodDataGetNode (Opcode, Index, WalkState, &Node);
+ if (ACPI_FAILURE (Status))
+ {
+ return_VALUE ((ACPI_TYPE_NOT_FOUND));
+ }
+
+ /* Get the object */
+
+ Object = AcpiNsGetAttachedObject (Node);
+ if (!Object)
+ {
+ /* Uninitialized local/arg, return TYPE_ANY */
+
+ return_VALUE (ACPI_TYPE_ANY);
+ }
+
+ /* Get the object type */
+
+ return_VALUE (Object->Type);
+}
+#endif
+
+
diff --git a/source/components/dispatcher/dsobject.c b/source/components/dispatcher/dsobject.c
new file mode 100644
index 000000000000..b3567766a2db
--- /dev/null
+++ b/source/components/dispatcher/dsobject.c
@@ -0,0 +1,867 @@
+/******************************************************************************
+ *
+ * Module Name: dsobject - Dispatcher object management routines
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2012, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#define __DSOBJECT_C__
+
+#include "acpi.h"
+#include "accommon.h"
+#include "acparser.h"
+#include "amlcode.h"
+#include "acdispat.h"
+#include "acnamesp.h"
+#include "acinterp.h"
+
+#define _COMPONENT ACPI_DISPATCHER
+ ACPI_MODULE_NAME ("dsobject")
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiDsBuildInternalObject (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_OPERAND_OBJECT **ObjDescPtr);
+
+
+#ifndef ACPI_NO_METHOD_EXECUTION
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsBuildInternalObject
+ *
+ * PARAMETERS: WalkState - Current walk state
+ * Op - Parser object to be translated
+ * ObjDescPtr - Where the ACPI internal object is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Translate a parser Op object to the equivalent namespace object
+ * Simple objects are any objects other than a package object!
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiDsBuildInternalObject (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_OPERAND_OBJECT **ObjDescPtr)
+{
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_STATUS Status;
+ ACPI_OBJECT_TYPE Type;
+
+
+ ACPI_FUNCTION_TRACE (DsBuildInternalObject);
+
+
+ *ObjDescPtr = NULL;
+ if (Op->Common.AmlOpcode == AML_INT_NAMEPATH_OP)
+ {
+ /*
+ * This is a named object reference. If this name was
+ * previously looked up in the namespace, it was stored in this op.
+ * Otherwise, go ahead and look it up now
+ */
+ if (!Op->Common.Node)
+ {
+ Status = AcpiNsLookup (WalkState->ScopeInfo,
+ Op->Common.Value.String,
+ ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
+ ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL,
+ ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, &(Op->Common.Node)));
+ if (ACPI_FAILURE (Status))
+ {
+ /* Check if we are resolving a named reference within a package */
+
+ if ((Status == AE_NOT_FOUND) && (AcpiGbl_EnableInterpreterSlack) &&
+
+ ((Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||
+ (Op->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP)))
+ {
+ /*
+ * We didn't find the target and we are populating elements
+ * of a package - ignore if slack enabled. Some ASL code
+ * contains dangling invalid references in packages and
+ * expects that no exception will be issued. Leave the
+ * element as a null element. It cannot be used, but it
+ * can be overwritten by subsequent ASL code - this is
+ * typically the case.
+ */
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+ "Ignoring unresolved reference in package [%4.4s]\n",
+ WalkState->ScopeInfo->Scope.Node->Name.Ascii));
+
+ return_ACPI_STATUS (AE_OK);
+ }
+ else
+ {
+ ACPI_ERROR_NAMESPACE (Op->Common.Value.String, Status);
+ }
+
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+ /* Special object resolution for elements of a package */
+
+ if ((Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||
+ (Op->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP))
+ {
+ /*
+ * Attempt to resolve the node to a value before we insert it into
+ * the package. If this is a reference to a common data type,
+ * resolve it immediately. According to the ACPI spec, package
+ * elements can only be "data objects" or method references.
+ * Attempt to resolve to an Integer, Buffer, String or Package.
+ * If cannot, return the named reference (for things like Devices,
+ * Methods, etc.) Buffer Fields and Fields will resolve to simple
+ * objects (int/buf/str/pkg).
+ *
+ * NOTE: References to things like Devices, Methods, Mutexes, etc.
+ * will remain as named references. This behavior is not described
+ * in the ACPI spec, but it appears to be an oversight.
+ */
+ ObjDesc = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Op->Common.Node);
+
+ Status = AcpiExResolveNodeToValue (
+ ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, &ObjDesc),
+ WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /*
+ * Special handling for Alias objects. We need to setup the type
+ * and the Op->Common.Node to point to the Alias target. Note,
+ * Alias has at most one level of indirection internally.
+ */
+ Type = Op->Common.Node->Type;
+ if (Type == ACPI_TYPE_LOCAL_ALIAS)
+ {
+ Type = ObjDesc->Common.Type;
+ Op->Common.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE,
+ Op->Common.Node->Object);
+ }
+
+ switch (Type)
+ {
+ /*
+ * For these types, we need the actual node, not the subobject.
+ * However, the subobject did not get an extra reference count above.
+ *
+ * TBD: should ExResolveNodeToValue be changed to fix this?
+ */
+ case ACPI_TYPE_DEVICE:
+ case ACPI_TYPE_THERMAL:
+
+ AcpiUtAddReference (Op->Common.Node->Object);
+
+ /*lint -fallthrough */
+ /*
+ * For these types, we need the actual node, not the subobject.
+ * The subobject got an extra reference count in ExResolveNodeToValue.
+ */
+ case ACPI_TYPE_MUTEX:
+ case ACPI_TYPE_METHOD:
+ case ACPI_TYPE_POWER:
+ case ACPI_TYPE_PROCESSOR:
+ case ACPI_TYPE_EVENT:
+ case ACPI_TYPE_REGION:
+
+ /* We will create a reference object for these types below */
+ break;
+
+ default:
+ /*
+ * All other types - the node was resolved to an actual
+ * object, we are done.
+ */
+ goto Exit;
+ }
+ }
+ }
+
+ /* Create and init a new internal ACPI object */
+
+ ObjDesc = AcpiUtCreateInternalObject (
+ (AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode))->ObjectType);
+ if (!ObjDesc)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ Status = AcpiDsInitObjectFromOp (WalkState, Op, Op->Common.AmlOpcode,
+ &ObjDesc);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiUtRemoveReference (ObjDesc);
+ return_ACPI_STATUS (Status);
+ }
+
+Exit:
+ *ObjDescPtr = ObjDesc;
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsBuildInternalBufferObj
+ *
+ * PARAMETERS: WalkState - Current walk state
+ * Op - Parser object to be translated
+ * BufferLength - Length of the buffer
+ * ObjDescPtr - Where the ACPI internal object is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Translate a parser Op package object to the equivalent
+ * namespace object
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsBuildInternalBufferObj (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 BufferLength,
+ ACPI_OPERAND_OBJECT **ObjDescPtr)
+{
+ ACPI_PARSE_OBJECT *Arg;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_PARSE_OBJECT *ByteList;
+ UINT32 ByteListLength = 0;
+
+
+ ACPI_FUNCTION_TRACE (DsBuildInternalBufferObj);
+
+
+ /*
+ * If we are evaluating a Named buffer object "Name (xxxx, Buffer)".
+ * The buffer object already exists (from the NS node), otherwise it must
+ * be created.
+ */
+ ObjDesc = *ObjDescPtr;
+ if (!ObjDesc)
+ {
+ /* Create a new buffer object */
+
+ ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_BUFFER);
+ *ObjDescPtr = ObjDesc;
+ if (!ObjDesc)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+ }
+
+ /*
+ * Second arg is the buffer data (optional) ByteList can be either
+ * individual bytes or a string initializer. In either case, a
+ * ByteList appears in the AML.
+ */
+ Arg = Op->Common.Value.Arg; /* skip first arg */
+
+ ByteList = Arg->Named.Next;
+ if (ByteList)
+ {
+ if (ByteList->Common.AmlOpcode != AML_INT_BYTELIST_OP)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Expecting bytelist, found AML opcode 0x%X in op %p",
+ ByteList->Common.AmlOpcode, ByteList));
+
+ AcpiUtRemoveReference (ObjDesc);
+ return (AE_TYPE);
+ }
+
+ ByteListLength = (UINT32) ByteList->Common.Value.Integer;
+ }
+
+ /*
+ * The buffer length (number of bytes) will be the larger of:
+ * 1) The specified buffer length and
+ * 2) The length of the initializer byte list
+ */
+ ObjDesc->Buffer.Length = BufferLength;
+ if (ByteListLength > BufferLength)
+ {
+ ObjDesc->Buffer.Length = ByteListLength;
+ }
+
+ /* Allocate the buffer */
+
+ if (ObjDesc->Buffer.Length == 0)
+ {
+ ObjDesc->Buffer.Pointer = NULL;
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+ "Buffer defined with zero length in AML, creating\n"));
+ }
+ else
+ {
+ ObjDesc->Buffer.Pointer = ACPI_ALLOCATE_ZEROED (
+ ObjDesc->Buffer.Length);
+ if (!ObjDesc->Buffer.Pointer)
+ {
+ AcpiUtDeleteObjectDesc (ObjDesc);
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ /* Initialize buffer from the ByteList (if present) */
+
+ if (ByteList)
+ {
+ ACPI_MEMCPY (ObjDesc->Buffer.Pointer, ByteList->Named.Data,
+ ByteListLength);
+ }
+ }
+
+ ObjDesc->Buffer.Flags |= AOPOBJ_DATA_VALID;
+ Op->Common.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjDesc);
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsBuildInternalPackageObj
+ *
+ * PARAMETERS: WalkState - Current walk state
+ * Op - Parser object to be translated
+ * ElementCount - Number of elements in the package - this is
+ * the NumElements argument to Package()
+ * ObjDescPtr - Where the ACPI internal object is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Translate a parser Op package object to the equivalent
+ * namespace object
+ *
+ * NOTE: The number of elements in the package will be always be the NumElements
+ * count, regardless of the number of elements in the package list. If
+ * NumElements is smaller, only that many package list elements are used.
+ * if NumElements is larger, the Package object is padded out with
+ * objects of type Uninitialized (as per ACPI spec.)
+ *
+ * Even though the ASL compilers do not allow NumElements to be smaller
+ * than the Package list length (for the fixed length package opcode), some
+ * BIOS code modifies the AML on the fly to adjust the NumElements, and
+ * this code compensates for that. This also provides compatibility with
+ * other AML interpreters.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsBuildInternalPackageObj (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op,
+ UINT32 ElementCount,
+ ACPI_OPERAND_OBJECT **ObjDescPtr)
+{
+ ACPI_PARSE_OBJECT *Arg;
+ ACPI_PARSE_OBJECT *Parent;
+ ACPI_OPERAND_OBJECT *ObjDesc = NULL;
+ ACPI_STATUS Status = AE_OK;
+ UINT32 i;
+ UINT16 Index;
+ UINT16 ReferenceCount;
+
+
+ ACPI_FUNCTION_TRACE (DsBuildInternalPackageObj);
+
+
+ /* Find the parent of a possibly nested package */
+
+ Parent = Op->Common.Parent;
+ while ((Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||
+ (Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP))
+ {
+ Parent = Parent->Common.Parent;
+ }
+
+ /*
+ * If we are evaluating a Named package object "Name (xxxx, Package)",
+ * the package object already exists, otherwise it must be created.
+ */
+ ObjDesc = *ObjDescPtr;
+ if (!ObjDesc)
+ {
+ ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_PACKAGE);
+ *ObjDescPtr = ObjDesc;
+ if (!ObjDesc)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ ObjDesc->Package.Node = Parent->Common.Node;
+ }
+
+ /*
+ * Allocate the element array (array of pointers to the individual
+ * objects) based on the NumElements parameter. Add an extra pointer slot
+ * so that the list is always null terminated.
+ */
+ ObjDesc->Package.Elements = ACPI_ALLOCATE_ZEROED (
+ ((ACPI_SIZE) ElementCount + 1) * sizeof (void *));
+
+ if (!ObjDesc->Package.Elements)
+ {
+ AcpiUtDeleteObjectDesc (ObjDesc);
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ ObjDesc->Package.Count = ElementCount;
+
+ /*
+ * Initialize the elements of the package, up to the NumElements count.
+ * Package is automatically padded with uninitialized (NULL) elements
+ * if NumElements is greater than the package list length. Likewise,
+ * Package is truncated if NumElements is less than the list length.
+ */
+ Arg = Op->Common.Value.Arg;
+ Arg = Arg->Common.Next;
+ for (i = 0; Arg && (i < ElementCount); i++)
+ {
+ if (Arg->Common.AmlOpcode == AML_INT_RETURN_VALUE_OP)
+ {
+ if (Arg->Common.Node->Type == ACPI_TYPE_METHOD)
+ {
+ /*
+ * A method reference "looks" to the parser to be a method
+ * invocation, so we special case it here
+ */
+ Arg->Common.AmlOpcode = AML_INT_NAMEPATH_OP;
+ Status = AcpiDsBuildInternalObject (WalkState, Arg,
+ &ObjDesc->Package.Elements[i]);
+ }
+ else
+ {
+ /* This package element is already built, just get it */
+
+ ObjDesc->Package.Elements[i] =
+ ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Arg->Common.Node);
+ }
+ }
+ else
+ {
+ Status = AcpiDsBuildInternalObject (WalkState, Arg,
+ &ObjDesc->Package.Elements[i]);
+ }
+
+ if (*ObjDescPtr)
+ {
+ /* Existing package, get existing reference count */
+
+ ReferenceCount = (*ObjDescPtr)->Common.ReferenceCount;
+ if (ReferenceCount > 1)
+ {
+ /* Make new element ref count match original ref count */
+
+ for (Index = 0; Index < (ReferenceCount - 1); Index++)
+ {
+ AcpiUtAddReference ((ObjDesc->Package.Elements[i]));
+ }
+ }
+ }
+
+ Arg = Arg->Common.Next;
+ }
+
+ /* Check for match between NumElements and actual length of PackageList */
+
+ if (Arg)
+ {
+ /*
+ * NumElements was exhausted, but there are remaining elements in the
+ * PackageList. Truncate the package to NumElements.
+ *
+ * Note: technically, this is an error, from ACPI spec: "It is an error
+ * for NumElements to be less than the number of elements in the
+ * PackageList". However, we just print a message and
+ * no exception is returned. This provides Windows compatibility. Some
+ * BIOSs will alter the NumElements on the fly, creating this type
+ * of ill-formed package object.
+ */
+ while (Arg)
+ {
+ /*
+ * We must delete any package elements that were created earlier
+ * and are not going to be used because of the package truncation.
+ */
+ if (Arg->Common.Node)
+ {
+ AcpiUtRemoveReference (
+ ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Arg->Common.Node));
+ Arg->Common.Node = NULL;
+ }
+
+ /* Find out how many elements there really are */
+
+ i++;
+ Arg = Arg->Common.Next;
+ }
+
+ ACPI_INFO ((AE_INFO,
+ "Actual Package length (%u) is larger than NumElements field (%u), truncated\n",
+ i, ElementCount));
+ }
+ else if (i < ElementCount)
+ {
+ /*
+ * Arg list (elements) was exhausted, but we did not reach NumElements count.
+ * Note: this is not an error, the package is padded out with NULLs.
+ */
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+ "Package List length (%u) smaller than NumElements count (%u), padded with null elements\n",
+ i, ElementCount));
+ }
+
+ ObjDesc->Package.Flags |= AOPOBJ_DATA_VALID;
+ Op->Common.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjDesc);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsCreateNode
+ *
+ * PARAMETERS: WalkState - Current walk state
+ * Node - NS Node to be initialized
+ * Op - Parser object to be translated
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Create the object to be associated with a namespace node
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsCreateNode (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_NAMESPACE_NODE *Node,
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_STATUS Status;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+
+
+ ACPI_FUNCTION_TRACE_PTR (DsCreateNode, Op);
+
+
+ /*
+ * Because of the execution pass through the non-control-method
+ * parts of the table, we can arrive here twice. Only init
+ * the named object node the first time through
+ */
+ if (AcpiNsGetAttachedObject (Node))
+ {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ if (!Op->Common.Value.Arg)
+ {
+ /* No arguments, there is nothing to do */
+
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* Build an internal object for the argument(s) */
+
+ Status = AcpiDsBuildInternalObject (WalkState, Op->Common.Value.Arg,
+ &ObjDesc);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Re-type the object according to its argument */
+
+ Node->Type = ObjDesc->Common.Type;
+
+ /* Attach obj to node */
+
+ Status = AcpiNsAttachObject (Node, ObjDesc, Node->Type);
+
+ /* Remove local reference to the object */
+
+ AcpiUtRemoveReference (ObjDesc);
+ return_ACPI_STATUS (Status);
+}
+
+#endif /* ACPI_NO_METHOD_EXECUTION */
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsInitObjectFromOp
+ *
+ * PARAMETERS: WalkState - Current walk state
+ * Op - Parser op used to init the internal object
+ * Opcode - AML opcode associated with the object
+ * RetObjDesc - Namespace object to be initialized
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Initialize a namespace object from a parser Op and its
+ * associated arguments. The namespace object is a more compact
+ * representation of the Op and its arguments.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDsInitObjectFromOp (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op,
+ UINT16 Opcode,
+ ACPI_OPERAND_OBJECT **RetObjDesc)
+{
+ const ACPI_OPCODE_INFO *OpInfo;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_STATUS Status = AE_OK;
+
+
+ ACPI_FUNCTION_TRACE (DsInitObjectFromOp);
+
+
+ ObjDesc = *RetObjDesc;
+ OpInfo = AcpiPsGetOpcodeInfo (Opcode);
+ if (OpInfo->Class == AML_CLASS_UNKNOWN)
+ {
+ /* Unknown opcode */
+
+ return_ACPI_STATUS (AE_TYPE);
+ }
+
+ /* Perform per-object initialization */
+
+ switch (ObjDesc->Common.Type)
+ {
+ case ACPI_TYPE_BUFFER:
+
+ /*
+ * Defer evaluation of Buffer TermArg operand
+ */
+ ObjDesc->Buffer.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE,