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 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_PARSE_OBJECT * AcpiPsGetNextField ( ACPI_PARSE_STATE *ParserState) { UINT32 AmlOffset = ParserState->Aml - ParserState->AmlStart; ACPI_PARSE_OBJECT *Field; UINT16 Opcode; UINT32 Name; FUNCTION_TRACE ("PsGetNextField"); /* determine field type */ switch (GET8 (ParserState->Aml)) { default: Opcode = AML_INT_NAMEDFIELD_OP; break; case 0x00: Opcode = AML_INT_RESERVEDFIELD_OP; ParserState->Aml++; break; case 0x01: Opcode = AML_INT_ACCESSFIELD_OP; ParserState->Aml++; break; } /* Allocate a new field op */ Field = AcpiPsAllocOp (Opcode); if (Field) { Field->AmlOffset = AmlOffset; /* Decode the field type */ switch (Opcode) { case AML_INT_NAMEDFIELD_OP: /* Get the 4-character name */ MOVE_UNALIGNED32_TO_32 (&Name, ParserState->Aml); AcpiPsSetName (Field, Name); ParserState->Aml += 4; /* Get the length which is encoded as a package length */ Field->Value.Size = AcpiPsGetNextPackageLength (ParserState); break; case AML_INT_RESERVEDFIELD_OP: /* Get the length which is encoded as a package length */ Field->Value.Size = AcpiPsGetNextPackageLength (ParserState); break; case AML_INT_ACCESSFIELD_OP: /* Get AccessType and AccessAtrib and merge into the field Op */ Field->Value.Integer = ((GET8 (ParserState->Aml) << 8) | GET8 (ParserState->Aml)); ParserState->Aml += 2; break; } } return_PTR (Field); }