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); }
ACPI_STATUS AcpiNsOneCompleteParse ( UINT32 PassNumber, ACPI_TABLE_DESC *TableDesc) { ACPI_PARSE_OBJECT *ParseRoot; ACPI_STATUS Status; ACPI_WALK_STATE *WalkState; ACPI_FUNCTION_TRACE ("NsOneCompleteParse"); /* Create and init a Root Node */ ParseRoot = AcpiPsCreateScopeOp (); if (!ParseRoot) { return_ACPI_STATUS (AE_NO_MEMORY); } /* Create and initialize a new walk state */ WalkState = AcpiDsCreateWalkState (TABLE_ID_DSDT, NULL, NULL, NULL); if (!WalkState) { AcpiPsFreeOp (ParseRoot); return_ACPI_STATUS (AE_NO_MEMORY); } Status = AcpiDsInitAmlWalk (WalkState, ParseRoot, NULL, TableDesc->AmlStart, TableDesc->AmlLength, NULL, NULL, PassNumber); if (ACPI_FAILURE (Status)) { AcpiDsDeleteWalkState (WalkState); return_ACPI_STATUS (Status); } /* Parse the AML */ ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "*PARSE* pass %d parse\n", PassNumber)); Status = AcpiPsParseAml (WalkState); AcpiPsDeleteParseTree (ParseRoot); return_ACPI_STATUS (Status); }
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); } if (Method->Type != ACPI_TYPE_METHOD) { ACPI_ERROR ((AE_INFO, "%s (%s): Object must be a control method", Name, AcpiUtGetTypeName (Method->Type))); 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); } Status = AcpiUtAllocateOwnerId (&ObjDesc->Method.OwnerId); WalkState->OwnerId = ObjDesc->Method.OwnerId; /* Push start scope on scope stack and make it current */ Status = AcpiDsScopeStackPush (Method, Method->Type, WalkState); if (ACPI_FAILURE (Status)) { return (Status); } /* Parse the entire method AML including deferred operators */ WalkState->ParseFlags &= ~ACPI_PARSE_DELETE_TREE; WalkState->ParseFlags |= ACPI_PARSE_DISASSEMBLE; Status = AcpiPsParseAml (WalkState); (void) AcpiDmParseDeferredOps (Op); /* Now we can disassemble the method */ AcpiGbl_DbOpt_verbose = FALSE; AcpiDmDisassemble (NULL, Op, 0); AcpiGbl_DbOpt_verbose = TRUE; AcpiPsDeleteParseTree (Op); /* Method cleanup */ AcpiNsDeleteNamespaceSubtree (Method); AcpiNsDeleteNamespaceByOwner (ObjDesc->Method.OwnerId); AcpiUtReleaseOwnerId (&ObjDesc->Method.OwnerId); return (AE_OK); }
ACPI_STATUS AdParseTable ( ACPI_TABLE_HEADER *Table, ACPI_OWNER_ID *OwnerId, BOOLEAN LoadTable, BOOLEAN External) { ACPI_STATUS Status = AE_OK; ACPI_WALK_STATE *WalkState; UINT8 *AmlStart; UINT32 AmlLength; UINT32 TableIndex; if (!Table) { return (AE_NOT_EXIST); } /* Pass 1: Parse everything except control method bodies */ fprintf (stderr, "Pass 1 parse of [%4.4s]\n", (char *) Table->Signature); AmlLength = Table->Length - sizeof (ACPI_TABLE_HEADER); AmlStart = ((UINT8 *) Table + sizeof (ACPI_TABLE_HEADER)); /* Create the root object */ AcpiGbl_ParseOpRoot = AcpiPsCreateScopeOp (); if (!AcpiGbl_ParseOpRoot) { return (AE_NO_MEMORY); } /* Create and initialize a new walk state */ WalkState = AcpiDsCreateWalkState (0, AcpiGbl_ParseOpRoot, NULL, NULL); if (!WalkState) { return (AE_NO_MEMORY); } Status = AcpiDsInitAmlWalk (WalkState, AcpiGbl_ParseOpRoot, NULL, AmlStart, AmlLength, NULL, ACPI_IMODE_LOAD_PASS1); if (ACPI_FAILURE (Status)) { return (Status); } WalkState->ParseFlags &= ~ACPI_PARSE_DELETE_TREE; WalkState->ParseFlags |= ACPI_PARSE_DISASSEMBLE; Status = AcpiPsParseAml (WalkState); if (ACPI_FAILURE (Status)) { return (Status); } /* If LoadTable is FALSE, we are parsing the last loaded table */ TableIndex = AcpiGbl_RootTableList.CurrentTableCount - 1; /* Pass 2 */ if (LoadTable) { Status = AcpiTbStoreTable ((ACPI_PHYSICAL_ADDRESS) Table, Table, Table->Length, ACPI_TABLE_ORIGIN_ALLOCATED, &TableIndex); if (ACPI_FAILURE (Status)) { return (Status); } Status = AcpiTbAllocateOwnerId (TableIndex); if (ACPI_FAILURE (Status)) { return (Status); } if (OwnerId) { Status = AcpiTbGetOwnerId (TableIndex, OwnerId); if (ACPI_FAILURE (Status)) { return (Status); } } } fprintf (stderr, "Pass 2 parse of [%4.4s]\n", (char *) Table->Signature); Status = AcpiNsOneCompleteParse (ACPI_IMODE_LOAD_PASS2, TableIndex, NULL); if (ACPI_FAILURE (Status)) { return (Status); } /* No need to parse control methods of external table */ if (External) { return (AE_OK); } /* Pass 3: Parse control methods and link their parse trees into the main parse tree */ fprintf (stderr, "Parsing Deferred Opcodes (Methods/Buffers/Packages/Regions)\n"); Status = AcpiDmParseDeferredOps (AcpiGbl_ParseOpRoot); fprintf (stderr, "\n"); /* Process Resource Templates */ AcpiDmFindResources (AcpiGbl_ParseOpRoot); fprintf (stderr, "Parsing completed\n"); return (AE_OK); }
ACPI_STATUS AcpiPsxExecute ( ACPI_NAMESPACE_NODE *MethodNode, ACPI_OPERAND_OBJECT **Params, ACPI_OPERAND_OBJECT **ReturnObjDesc) { ACPI_STATUS Status; ACPI_OPERAND_OBJECT *ObjDesc; UINT32 i; ACPI_PARSE_OBJECT *Op; ACPI_WALK_STATE *WalkState; ACPI_FUNCTION_TRACE ("PsxExecute"); /* Validate the Node and get the attached object */ if (!MethodNode) { return_ACPI_STATUS (AE_NULL_ENTRY); } ObjDesc = AcpiNsGetAttachedObject (MethodNode); if (!ObjDesc) { return_ACPI_STATUS (AE_NULL_OBJECT); } /* Init for new method, wait on concurrency semaphore */ Status = AcpiDsBeginMethodExecution (MethodNode, ObjDesc, NULL); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } if (Params) { /* * The caller "owns" the parameters, so give each one an extra * reference */ for (i = 0; Params[i]; i++) { AcpiUtAddReference (Params[i]); } } /* * 1) Perform the first pass parse of the method to enter any * named objects that it creates into the namespace */ ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "**** Begin Method Parse **** Entry=%p obj=%p\n", MethodNode, ObjDesc)); /* Create and init a Root Node */ Op = AcpiPsCreateScopeOp (); if (!Op) { return_ACPI_STATUS (AE_NO_MEMORY); } /* * Get a new OwnerId for objects created by this method. Namespace * objects (such as Operation Regions) can be created during the * first pass parse. */ ObjDesc->Method.OwningId = AcpiUtAllocateOwnerId (ACPI_OWNER_TYPE_METHOD); /* Create and initialize a new walk state */ WalkState = AcpiDsCreateWalkState (ObjDesc->Method.OwningId, NULL, NULL, NULL); if (!WalkState) { return_ACPI_STATUS (AE_NO_MEMORY); } Status = AcpiDsInitAmlWalk (WalkState, Op, MethodNode, ObjDesc->Method.AmlStart, ObjDesc->Method.AmlLength, NULL, NULL, 1); if (ACPI_FAILURE (Status)) { AcpiDsDeleteWalkState (WalkState); return_ACPI_STATUS (Status); } /* Parse the AML */ Status = AcpiPsParseAml (WalkState); AcpiPsDeleteParseTree (Op); /* * 2) Execute the method. Performs second pass parse simultaneously */ ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "**** Begin Method Execution **** Entry=%p obj=%p\n", MethodNode, ObjDesc)); /* Create and init a Root Node */ Op = AcpiPsCreateScopeOp (); if (!Op) { return_ACPI_STATUS (AE_NO_MEMORY); } /* Init new op with the method name and pointer back to the NS node */ AcpiPsSetName (Op, MethodNode->Name.Integer); Op->Common.Node = MethodNode; /* Create and initialize a new walk state */ WalkState = AcpiDsCreateWalkState (TABLE_ID_DSDT, NULL, NULL, NULL); if (!WalkState) { return_ACPI_STATUS (AE_NO_MEMORY); } Status = AcpiDsInitAmlWalk (WalkState, Op, MethodNode, ObjDesc->Method.AmlStart, ObjDesc->Method.AmlLength, Params, ReturnObjDesc, 3); if (ACPI_FAILURE (Status)) { AcpiDsDeleteWalkState (WalkState); return_ACPI_STATUS (Status); } /* * The walk of the parse tree is where we actually execute the method */ Status = AcpiPsParseAml (WalkState); AcpiPsDeleteParseTree (Op); if (Params) { /* Take away the extra reference that we gave the parameters above */ for (i = 0; Params[i]; i++) { /* Ignore errors, just do them all */ (void) AcpiUtUpdateObjectReference (Params[i], REF_DECREMENT); } } /* * If the method has returned an object, signal this to the caller with * a control exception code */ if (*ReturnObjDesc) { ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Method returned ObjDesc=%p\n", *ReturnObjDesc)); ACPI_DUMP_STACK_ENTRY (*ReturnObjDesc); Status = AE_CTRL_RETURN_VALUE; } return_ACPI_STATUS (Status); }
ACPI_STATUS AcpiNsOneCompleteParse ( ACPI_NATIVE_UINT PassNumber, ACPI_NATIVE_UINT TableIndex, ACPI_NAMESPACE_NODE *StartNode) { ACPI_PARSE_OBJECT *ParseRoot; ACPI_STATUS Status; ACPI_NATIVE_UINT AmlLength; UINT8 *AmlStart; ACPI_WALK_STATE *WalkState; ACPI_TABLE_HEADER *Table; ACPI_OWNER_ID OwnerId; ACPI_FUNCTION_TRACE (NsOneCompleteParse); Status = AcpiTbGetOwnerId (TableIndex, &OwnerId); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } /* Create and init a Root Node */ ParseRoot = AcpiPsCreateScopeOp (); if (!ParseRoot) { return_ACPI_STATUS (AE_NO_MEMORY); } /* Create and initialize a new walk state */ WalkState = AcpiDsCreateWalkState (OwnerId, NULL, NULL, NULL); if (!WalkState) { AcpiPsFreeOp (ParseRoot); return_ACPI_STATUS (AE_NO_MEMORY); } Status = AcpiGetTableByIndex (TableIndex, &Table); if (ACPI_FAILURE (Status)) { AcpiDsDeleteWalkState (WalkState); AcpiPsFreeOp (ParseRoot); return_ACPI_STATUS (Status); } /* Table must consist of at least a complete header */ if (Table->Length < sizeof (ACPI_TABLE_HEADER)) { Status = AE_BAD_HEADER; } else { AmlStart = (UINT8 *) Table + sizeof (ACPI_TABLE_HEADER); AmlLength = Table->Length - sizeof (ACPI_TABLE_HEADER); Status = AcpiDsInitAmlWalk (WalkState, ParseRoot, NULL, AmlStart, (UINT32) AmlLength, NULL, (UINT8) PassNumber); } if (ACPI_FAILURE (Status)) { AcpiDsDeleteWalkState (WalkState); goto Cleanup; } /* StartNode is the default location to load the table */ if (StartNode && StartNode != AcpiGbl_RootNode) { Status = AcpiDsScopeStackPush (StartNode, ACPI_TYPE_METHOD, WalkState); if (ACPI_FAILURE (Status)) { AcpiDsDeleteWalkState (WalkState); goto Cleanup; } } /* Parse the AML */ ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "*PARSE* pass %d parse\n", (UINT32) PassNumber)); Status = AcpiPsParseAml (WalkState); Cleanup: AcpiPsDeleteParseTree (ParseRoot); return_ACPI_STATUS (Status); }
ACPI_STATUS AcpiPsExecuteTable ( ACPI_EVALUATE_INFO *Info) { ACPI_STATUS Status; ACPI_PARSE_OBJECT *Op = NULL; ACPI_WALK_STATE *WalkState = NULL; ACPI_FUNCTION_TRACE (PsExecuteTable); /* Create and init a Root Node */ Op = AcpiPsCreateScopeOp (Info->ObjDesc->Method.AmlStart); if (!Op) { Status = AE_NO_MEMORY; goto Cleanup; } /* Create and initialize a new walk state */ WalkState = AcpiDsCreateWalkState ( Info->ObjDesc->Method.OwnerId, NULL, NULL, NULL); if (!WalkState) { Status = AE_NO_MEMORY; goto Cleanup; } Status = AcpiDsInitAmlWalk (WalkState, Op, Info->Node, Info->ObjDesc->Method.AmlStart, Info->ObjDesc->Method.AmlLength, Info, Info->PassNumber); if (ACPI_FAILURE (Status)) { goto Cleanup; } if (Info->ObjDesc->Method.InfoFlags & ACPI_METHOD_MODULE_LEVEL) { WalkState->ParseFlags |= ACPI_PARSE_MODULE_LEVEL; } /* Info->Node is the default location to load the table */ if (Info->Node && Info->Node != AcpiGbl_RootNode) { Status = AcpiDsScopeStackPush ( Info->Node, ACPI_TYPE_METHOD, WalkState); if (ACPI_FAILURE (Status)) { goto Cleanup; } } /* * Parse the AML, WalkState will be deleted by ParseAml */ AcpiExEnterInterpreter (); Status = AcpiPsParseAml (WalkState); AcpiExExitInterpreter (); WalkState = NULL; Cleanup: if (WalkState) { AcpiDsDeleteWalkState (WalkState); } if (Op) { AcpiPsDeleteParseTree (Op); } return_ACPI_STATUS (Status); }
ACPI_STATUS AcpiPsExecuteMethod ( ACPI_EVALUATE_INFO *Info) { ACPI_STATUS Status; ACPI_PARSE_OBJECT *Op; ACPI_WALK_STATE *WalkState; ACPI_FUNCTION_TRACE (PsExecuteMethod); /* Quick validation of DSDT header */ AcpiTbCheckDsdtHeader (); /* Validate the Info and method Node */ if (!Info || !Info->Node) { return_ACPI_STATUS (AE_NULL_ENTRY); } /* Init for new method, wait on concurrency semaphore */ Status = AcpiDsBeginMethodExecution (Info->Node, Info->ObjDesc, NULL); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } /* * The caller "owns" the parameters, so give each one an extra reference */ AcpiPsUpdateParameterList (Info, REF_INCREMENT); /* * Execute the method. Performs parse simultaneously */ ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "**** Begin Method Parse/Execute [%4.4s] **** Node=%p Obj=%p\n", Info->Node->Name.Ascii, Info->Node, Info->ObjDesc)); /* Create and init a Root Node */ Op = AcpiPsCreateScopeOp (Info->ObjDesc->Method.AmlStart); if (!Op) { Status = AE_NO_MEMORY; goto Cleanup; } /* Create and initialize a new walk state */ Info->PassNumber = ACPI_IMODE_EXECUTE; WalkState = AcpiDsCreateWalkState ( Info->ObjDesc->Method.OwnerId, NULL, NULL, NULL); if (!WalkState) { Status = AE_NO_MEMORY; goto Cleanup; } Status = AcpiDsInitAmlWalk (WalkState, Op, Info->Node, Info->ObjDesc->Method.AmlStart, Info->ObjDesc->Method.AmlLength, Info, Info->PassNumber); if (ACPI_FAILURE (Status)) { AcpiDsDeleteWalkState (WalkState); goto Cleanup; } if (Info->ObjDesc->Method.InfoFlags & ACPI_METHOD_MODULE_LEVEL) { WalkState->ParseFlags |= ACPI_PARSE_MODULE_LEVEL; } /* Invoke an internal method if necessary */ if (Info->ObjDesc->Method.InfoFlags & ACPI_METHOD_INTERNAL_ONLY) { Status = Info->ObjDesc->Method.Dispatch.Implementation (WalkState); Info->ReturnObject = WalkState->ReturnDesc; /* Cleanup states */ AcpiDsScopeStackClear (WalkState); AcpiPsCleanupScope (&WalkState->ParserState); AcpiDsTerminateControlMethod (WalkState->MethodDesc, WalkState); AcpiDsDeleteWalkState (WalkState); goto Cleanup; } /* * Start method evaluation with an implicit return of zero. * This is done for Windows compatibility. */ if (AcpiGbl_EnableInterpreterSlack) { WalkState->ImplicitReturnObj = AcpiUtCreateIntegerObject ((UINT64) 0); if (!WalkState->ImplicitReturnObj) { Status = AE_NO_MEMORY; AcpiDsDeleteWalkState (WalkState); goto Cleanup; } } /* Parse the AML */ Status = AcpiPsParseAml (WalkState); /* WalkState was deleted by ParseAml */ Cleanup: AcpiPsDeleteParseTree (Op); /* Take away the extra reference that we gave the parameters above */ AcpiPsUpdateParameterList (Info, REF_DECREMENT); /* Exit now if error above */ if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } /* * If the method has returned an object, signal this to the caller with * a control exception code */ if (Info->ReturnObject) { ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Method returned ObjDesc=%p\n", Info->ReturnObject)); ACPI_DUMP_STACK_ENTRY (Info->ReturnObject); Status = AE_CTRL_RETURN_VALUE; } return_ACPI_STATUS (Status); }
ACPI_STATUS AcpiNsOneCompleteParse ( UINT32 PassNumber, UINT32 TableIndex, ACPI_NAMESPACE_NODE *StartNode) { ACPI_PARSE_OBJECT *ParseRoot; ACPI_STATUS Status; UINT32 AmlLength; UINT8 *AmlStart; ACPI_WALK_STATE *WalkState; ACPI_TABLE_HEADER *Table; ACPI_OWNER_ID OwnerId; ACPI_FUNCTION_TRACE (NsOneCompleteParse); 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 and init a Root Node */ ParseRoot = AcpiPsCreateScopeOp (AmlStart); if (!ParseRoot) { return_ACPI_STATUS (AE_NO_MEMORY); } /* Create and initialize a new walk state */ WalkState = AcpiDsCreateWalkState (OwnerId, NULL, NULL, NULL); if (!WalkState) { AcpiPsFreeOp (ParseRoot); return_ACPI_STATUS (AE_NO_MEMORY); } Status = AcpiDsInitAmlWalk (WalkState, ParseRoot, NULL, AmlStart, AmlLength, NULL, (UINT8) PassNumber); if (ACPI_FAILURE (Status)) { AcpiDsDeleteWalkState (WalkState); goto Cleanup; } /* Found OSDT table, enable the namespace override feature */ if (ACPI_COMPARE_NAME(Table->Signature, ACPI_SIG_OSDT) && PassNumber == ACPI_IMODE_LOAD_PASS1) { WalkState->NamespaceOverride = TRUE; } /* StartNode is the default location to load the table */ if (StartNode && StartNode != AcpiGbl_RootNode) { Status = AcpiDsScopeStackPush ( StartNode, ACPI_TYPE_METHOD, WalkState); if (ACPI_FAILURE (Status)) { AcpiDsDeleteWalkState (WalkState); goto Cleanup; } } /* Parse the AML */ ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "*PARSE* pass %u parse\n", PassNumber)); AcpiExEnterInterpreter (); Status = AcpiPsParseAml (WalkState); AcpiExExitInterpreter (); Cleanup: AcpiPsDeleteParseTree (ParseRoot); return_ACPI_STATUS (Status); }