ACPI_STATUS AcpiDsAutoSerializeMethod ( ACPI_NAMESPACE_NODE *Node, ACPI_OPERAND_OBJECT *ObjDesc) { ACPI_STATUS Status; ACPI_PARSE_OBJECT *Op = NULL; ACPI_WALK_STATE *WalkState; ACPI_FUNCTION_TRACE_PTR (DsAutoSerializeMethod, Node); ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Method auto-serialization parse [%4.4s] %p\n", AcpiUtGetNodeName (Node), Node)); /* Create/Init a root op for the method parse tree */ Op = AcpiPsAllocOp (AML_METHOD_OP); if (!Op) { return_ACPI_STATUS (AE_NO_MEMORY); } AcpiPsSetName (Op, Node->Name.Integer); Op->Common.Node = Node; /* Create and initialize a new walk state */ WalkState = AcpiDsCreateWalkState (Node->OwnerId, NULL, NULL, NULL); if (!WalkState) { return_ACPI_STATUS (AE_NO_MEMORY); } Status = AcpiDsInitAmlWalk (WalkState, Op, Node, ObjDesc->Method.AmlStart, ObjDesc->Method.AmlLength, NULL, 0); if (ACPI_FAILURE (Status)) { AcpiDsDeleteWalkState (WalkState); return_ACPI_STATUS (Status); } WalkState->DescendingCallback = AcpiDsDetectNamedOpcodes; /* Parse the method, scan for creation of named objects */ Status = AcpiPsParseAml (WalkState); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } AcpiPsDeleteParseTree (Op); 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); } 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 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); }
static ACPI_STATUS AcpiDmDeferredParse ( ACPI_PARSE_OBJECT *Op, UINT8 *Aml, UINT32 AmlLength) { ACPI_WALK_STATE *WalkState; ACPI_STATUS Status; ACPI_PARSE_OBJECT *SearchOp; ACPI_PARSE_OBJECT *StartOp; UINT32 BaseAmlOffset; ACPI_PARSE_OBJECT *NewRootOp; ACPI_PARSE_OBJECT *ExtraOp; ACPI_FUNCTION_TRACE (DmDeferredParse); if (!Aml || !AmlLength) { return_ACPI_STATUS (AE_OK); } ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Parsing deferred opcode %s [%4.4s]\n", Op->Common.AmlOpName, (char *) &Op->Named.Name)); /* Need a new walk state to parse the AML */ WalkState = AcpiDsCreateWalkState (0, Op, NULL, NULL); if (!WalkState) { return_ACPI_STATUS (AE_NO_MEMORY); } Status = AcpiDsInitAmlWalk (WalkState, Op, NULL, Aml, AmlLength, NULL, ACPI_IMODE_LOAD_PASS1); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } /* Parse the AML for this deferred opcode */ WalkState->ParseFlags &= ~ACPI_PARSE_DELETE_TREE; WalkState->ParseFlags |= ACPI_PARSE_DISASSEMBLE; Status = AcpiPsParseAml (WalkState); /* * We need to update all of the AML offsets, since the parser thought * that the method began at offset zero. In reality, it began somewhere * within the ACPI table, at the BaseAmlOffset. Walk the entire tree that * was just created and update the AmlOffset in each Op. */ BaseAmlOffset = (Op->Common.Value.Arg)->Common.AmlOffset + 1; StartOp = (Op->Common.Value.Arg)->Common.Next; SearchOp = StartOp; while (SearchOp) { SearchOp->Common.AmlOffset += BaseAmlOffset; SearchOp = AcpiPsGetDepthNext (StartOp, SearchOp); } /* * For Buffer and Package opcodes, link the newly parsed subtree * into the main parse tree */ switch (Op->Common.AmlOpcode) { case AML_BUFFER_OP: case AML_PACKAGE_OP: case AML_VAR_PACKAGE_OP: switch (Op->Common.AmlOpcode) { case AML_PACKAGE_OP: ExtraOp = Op->Common.Value.Arg; NewRootOp = ExtraOp->Common.Next; ACPI_FREE (ExtraOp); break; case AML_VAR_PACKAGE_OP: case AML_BUFFER_OP: default: NewRootOp = Op->Common.Value.Arg; break; } Op->Common.Value.Arg = NewRootOp->Common.Value.Arg; /* Must point all parents to the main tree */ StartOp = Op; SearchOp = StartOp; while (SearchOp) { if (SearchOp->Common.Parent == NewRootOp) { SearchOp->Common.Parent = Op; } SearchOp = AcpiPsGetDepthNext (StartOp, SearchOp); } ACPI_FREE (NewRootOp); break; default: break; } return_ACPI_STATUS (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); }
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); }
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); }
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_PARSE_OBJECT *Arg; ACPI_FUNCTION_TRACE ("AcpiDsExecuteArguments"); /* * 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 (TABLE_ID_DSDT, NULL, NULL, NULL); if (!WalkState) { return_ACPI_STATUS (AE_NO_MEMORY); } Status = AcpiDsInitAmlWalk (WalkState, Op, NULL, AmlStart, AmlLength, NULL, NULL, 1); if (ACPI_FAILURE (Status)) { AcpiDsDeleteWalkState (WalkState); return_ACPI_STATUS (Status); } WalkState->ParseFlags = ACPI_PARSE_DEFERRED_OP; /* Pass1: Parse the entire declaration */ Status = AcpiPsParseAml (WalkState); if (ACPI_FAILURE (Status)) { AcpiPsDeleteParseTree (Op); return_ACPI_STATUS (Status); } /* Get and init the Op created above */ Arg = Op->Common.Value.Arg; Op->Common.Node = Node; Arg->Common.Node = Node; AcpiPsDeleteParseTree (Op); /* Evaluate the address and length arguments for the Buffer Field */ 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 (TABLE_ID_DSDT, NULL, NULL, NULL); if (!WalkState) { return_ACPI_STATUS (AE_NO_MEMORY); } Status = AcpiDsInitAmlWalk (WalkState, Op, NULL, AmlStart, AmlLength, NULL, NULL, 3); if (ACPI_FAILURE (Status)) { AcpiDsDeleteWalkState (WalkState); return_ACPI_STATUS (Status); } Status = AcpiPsParseAml (WalkState); AcpiPsDeleteParseTree (Op); return_ACPI_STATUS (Status); }