[ACPICA]
[reactos.git] / reactos / drivers / bus / acpi / acpica / namespace / nsparse.c
index 1ff3336..95f6da6 100644 (file)
 #include "acparser.h"
 #include "acdispat.h"
 #include "actables.h"
+#include "acinterp.h"
 
 
 #define _COMPONENT          ACPI_NAMESPACE
         ACPI_MODULE_NAME    ("nsparse")
 
 
+/*******************************************************************************
+ *
+ * FUNCTION:    NsExecuteTable
+ *
+ * PARAMETERS:  TableDesc       - An ACPI table descriptor for table to parse
+ *              StartNode       - Where to enter the table into the namespace
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Load ACPI/AML table by executing the entire table as a
+ *              TermList.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiNsExecuteTable (
+    UINT32                  TableIndex,
+    ACPI_NAMESPACE_NODE     *StartNode)
+{
+    ACPI_STATUS             Status;
+    ACPI_TABLE_HEADER       *Table;
+    ACPI_OWNER_ID           OwnerId;
+    ACPI_EVALUATE_INFO      *Info = NULL;
+    UINT32                  AmlLength;
+    UINT8                   *AmlStart;
+    ACPI_OPERAND_OBJECT     *MethodObj = NULL;
+
+
+    ACPI_FUNCTION_TRACE (NsExecuteTable);
+
+
+    Status = AcpiGetTableByIndex (TableIndex, &Table);
+    if (ACPI_FAILURE (Status))
+    {
+        return_ACPI_STATUS (Status);
+    }
+
+    /* Table must consist of at least a complete header */
+
+    if (Table->Length < sizeof (ACPI_TABLE_HEADER))
+    {
+        return_ACPI_STATUS (AE_BAD_HEADER);
+    }
+
+    AmlStart = (UINT8 *) Table + sizeof (ACPI_TABLE_HEADER);
+    AmlLength = Table->Length - sizeof (ACPI_TABLE_HEADER);
+
+    Status = AcpiTbGetOwnerId (TableIndex, &OwnerId);
+    if (ACPI_FAILURE (Status))
+    {
+        return_ACPI_STATUS (Status);
+    }
+
+    /* Create, initialize, and link a new temporary method object */
+
+    MethodObj = AcpiUtCreateInternalObject (ACPI_TYPE_METHOD);
+    if (!MethodObj)
+    {
+        return_ACPI_STATUS (AE_NO_MEMORY);
+    }
+
+    /* Allocate the evaluation information block */
+
+    Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
+    if (!Info)
+    {
+        Status = AE_NO_MEMORY;
+        goto Cleanup;
+    }
+
+    ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
+        "Create table code block: %p\n", MethodObj));
+
+    MethodObj->Method.AmlStart = AmlStart;
+    MethodObj->Method.AmlLength = AmlLength;
+    MethodObj->Method.OwnerId = OwnerId;
+    MethodObj->Method.InfoFlags |= ACPI_METHOD_MODULE_LEVEL;
+
+    Info->PassNumber = ACPI_IMODE_EXECUTE;
+    Info->Node = StartNode;
+    Info->ObjDesc = MethodObj;
+    Info->NodeFlags = Info->Node->Flags;
+    Info->FullPathname = AcpiNsGetNormalizedPathname (Info->Node, TRUE);
+    if (!Info->FullPathname)
+    {
+        Status = AE_NO_MEMORY;
+        goto Cleanup;
+    }
+
+    Status = AcpiPsExecuteTable (Info);
+
+Cleanup:
+    if (Info)
+    {
+        ACPI_FREE (Info->FullPathname);
+        Info->FullPathname = NULL;
+    }
+    ACPI_FREE (Info);
+    AcpiUtRemoveReference (MethodObj);
+    return_ACPI_STATUS (Status);
+}
+
+
 /*******************************************************************************
  *
  * FUNCTION:    NsOneCompleteParse
@@ -156,7 +260,9 @@ AcpiNsOneCompleteParse (
 
     ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
         "*PARSE* pass %u parse\n", PassNumber));
+    AcpiExEnterInterpreter ();
     Status = AcpiPsParseAml (WalkState);
+    AcpiExExitInterpreter ();
 
 Cleanup:
     AcpiPsDeleteParseTree (ParseRoot);
@@ -188,40 +294,53 @@ AcpiNsParseTable (
     ACPI_FUNCTION_TRACE (NsParseTable);
 
 
-    /*
-     * AML Parse, pass 1
-     *
-     * In this pass, we load most of the namespace. Control methods
-     * are not parsed until later. A parse tree is not created. Instead,
-     * each Parser Op subtree is deleted when it is finished. This saves
-     * a great deal of memory, and allows a small cache of parse objects
-     * to service the entire parse. The second pass of the parse then
-     * performs another complete parse of the AML.
-     */
-    ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "**** Start pass 1\n"));
-
-    Status = AcpiNsOneCompleteParse (ACPI_IMODE_LOAD_PASS1,
-        TableIndex, StartNode);
-    if (ACPI_FAILURE (Status))
+    if (AcpiGbl_ParseTableAsTermList)
     {
-        return_ACPI_STATUS (Status);
-    }
+        ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "**** Start load pass\n"));
 
-    /*
-     * AML Parse, pass 2
-     *
-     * In this pass, we resolve forward references and other things
-     * that could not be completed during the first pass.
-     * Another complete parse of the AML is performed, but the
-     * overhead of this is compensated for by the fact that the
-     * parse objects are all cached.
-     */
-    ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "**** Start pass 2\n"));
-    Status = AcpiNsOneCompleteParse (ACPI_IMODE_LOAD_PASS2,
-        TableIndex, StartNode);
-    if (ACPI_FAILURE (Status))
+        Status = AcpiNsExecuteTable (TableIndex, StartNode);
+        if (ACPI_FAILURE (Status))
+        {
+            return_ACPI_STATUS (Status);
+        }
+    }
+    else
     {
-        return_ACPI_STATUS (Status);
+        /*
+         * AML Parse, pass 1
+         *
+         * In this pass, we load most of the namespace. Control methods
+         * are not parsed until later. A parse tree is not created.
+         * Instead, each Parser Op subtree is deleted when it is finished.
+         * This saves a great deal of memory, and allows a small cache of
+         * parse objects to service the entire parse. The second pass of
+         * the parse then performs another complete parse of the AML.
+         */
+        ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "**** Start pass 1\n"));
+
+        Status = AcpiNsOneCompleteParse (ACPI_IMODE_LOAD_PASS1,
+            TableIndex, StartNode);
+        if (ACPI_FAILURE (Status))
+        {
+            return_ACPI_STATUS (Status);
+        }
+
+        /*
+         * AML Parse, pass 2
+         *
+         * In this pass, we resolve forward references and other things
+         * that could not be completed during the first pass.
+         * Another complete parse of the AML is performed, but the
+         * overhead of this is compensated for by the fact that the
+         * parse objects are all cached.
+         */
+        ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "**** Start pass 2\n"));
+        Status = AcpiNsOneCompleteParse (ACPI_IMODE_LOAD_PASS2,
+            TableIndex, StartNode);
+        if (ACPI_FAILURE (Status))
+        {
+            return_ACPI_STATUS (Status);
+        }
     }
 
     return_ACPI_STATUS (Status);