예제 #1
0
파일: psparse.c 프로젝트: MarginC/kame
ACPI_STATUS
AcpiPsFindObject (
    UINT16                  Opcode,
    ACPI_PARSE_OBJECT       *Op,
    ACPI_WALK_STATE         *WalkState,
    ACPI_PARSE_OBJECT       **OutOp)
{
    NATIVE_CHAR             *Path;
    const ACPI_OPCODE_INFO  *OpInfo;


    /* We are only interested in opcodes that have an associated name */

    OpInfo = AcpiPsGetOpcodeInfo (Opcode);
    if (!(OpInfo->Flags & AML_NAMED))
    {
        *OutOp = Op;
        return (AE_OK);
    }

    /* Find the name in the parse tree */

    Path = AcpiPsGetNextNamestring (WalkState->ParserState);

    *OutOp = AcpiPsFind (AcpiPsGetParentScope (WalkState->ParserState),
                 Path, Opcode, 1);

    if (!(*OutOp))
    {
        return (AE_NOT_FOUND);
    }

    return (AE_OK);
}
예제 #2
0
ACPI_STATUS
AcpiDsLoad1BeginOp (
    ACPI_WALK_STATE         *WalkState,
    ACPI_PARSE_OBJECT       **OutOp)
{
    ACPI_PARSE_OBJECT       *Op;
    ACPI_NAMESPACE_NODE     *Node;
    ACPI_STATUS             Status;
    ACPI_OBJECT_TYPE        ObjectType;
    char                    *Path;
    UINT32                  Flags;


    ACPI_FUNCTION_TRACE (DsLoad1BeginOp);


    Op = WalkState->Op;
    ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p State=%p\n", Op, WalkState));

    /* We are only interested in opcodes that have an associated name */

    if (Op)
    {
        if (!(WalkState->OpInfo->Flags & AML_NAMED))
        {
            *OutOp = Op;
            return_ACPI_STATUS (AE_OK);
        }

        /* Check if this object has already been installed in the namespace */

        if (Op->Common.Node)
        {
            *OutOp = Op;
            return_ACPI_STATUS (AE_OK);
        }
    }

    Path = AcpiPsGetNextNamestring (&WalkState->ParserState);

    /* Map the raw opcode into an internal object type */

    ObjectType = WalkState->OpInfo->ObjectType;

    ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
        "State=%p Op=%p [%s]\n", WalkState, Op, AcpiUtGetTypeName (ObjectType)));

    switch (WalkState->Opcode)
    {
    case AML_SCOPE_OP:
        /*
         * The target name of the Scope() operator must exist at this point so
         * that we can actually open the scope to enter new names underneath it.
         * Allow search-to-root for single namesegs.
         */
        Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType,
                        ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, WalkState, &(Node));
#ifdef ACPI_ASL_COMPILER
        if (Status == AE_NOT_FOUND)
        {
            /*
             * Table disassembly:
             * Target of Scope() not found. Generate an External for it, and
             * insert the name into the namespace.
             */
            AcpiDmAddOpToExternalList (Op, Path, ACPI_TYPE_DEVICE, 0, 0);
            Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType,
                       ACPI_IMODE_LOAD_PASS1, ACPI_NS_SEARCH_PARENT,
                       WalkState, &Node);
        }
#endif
        if (ACPI_FAILURE (Status))
        {
            ACPI_ERROR_NAMESPACE (Path, Status);
            return_ACPI_STATUS (Status);
        }

        /*
         * Check to make sure that the target is
         * one of the opcodes that actually opens a scope
         */
        switch (Node->Type)
        {
        case ACPI_TYPE_ANY:
        case ACPI_TYPE_LOCAL_SCOPE:         /* Scope  */
        case ACPI_TYPE_DEVICE:
        case ACPI_TYPE_POWER:
        case ACPI_TYPE_PROCESSOR:
        case ACPI_TYPE_THERMAL:

            /* These are acceptable types */
            break;

        case ACPI_TYPE_INTEGER:
        case ACPI_TYPE_STRING:
        case ACPI_TYPE_BUFFER:
            /*
             * These types we will allow, but we will change the type.
             * This enables some existing code of the form:
             *
             *  Name (DEB, 0)
             *  Scope (DEB) { ... }
             *
             * Note: silently change the type here. On the second pass,
             * we will report a warning
             */
            ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
                "Type override - [%4.4s] had invalid type (%s) "
                "for Scope operator, changed to type ANY\n",
                AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Node->Type)));

            Node->Type = ACPI_TYPE_ANY;
            WalkState->ScopeInfo->Common.Value = ACPI_TYPE_ANY;
            break;

        case ACPI_TYPE_METHOD:
            /*
             * Allow scope change to root during execution of module-level
             * code. Root is typed METHOD during this time.
             */
            if ((Node == AcpiGbl_RootNode) &&
                (WalkState->ParseFlags & ACPI_PARSE_MODULE_LEVEL))
            {
                break;
            }

            /*lint -fallthrough */

        default:

            /* All other types are an error */

            ACPI_ERROR ((AE_INFO,
                "Invalid type (%s) for target of "
                "Scope operator [%4.4s] (Cannot override)",
                AcpiUtGetTypeName (Node->Type), AcpiUtGetNodeName (Node)));

            return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
        }
        break;

    default:
        /*
         * For all other named opcodes, we will enter the name into
         * the namespace.
         *
         * Setup the search flags.
         * Since we are entering a name into the namespace, we do not want to
         * enable the search-to-root upsearch.
         *
         * There are only two conditions where it is acceptable that the name
         * already exists:
         *    1) the Scope() operator can reopen a scoping object that was
         *       previously defined (Scope, Method, Device, etc.)
         *    2) Whenever we are parsing a deferred opcode (OpRegion, Buffer,
         *       BufferField, or Package), the name of the object is already
         *       in the namespace.
         */
        if (WalkState->DeferredNode)
        {
            /* This name is already in the namespace, get the node */

            Node = WalkState->DeferredNode;
            Status = AE_OK;
            break;
        }

        /*
         * If we are executing a method, do not create any namespace objects
         * during the load phase, only during execution.
         */
        if (WalkState->MethodNode)
        {
            Node = NULL;
            Status = AE_OK;
            break;
        }

        Flags = ACPI_NS_NO_UPSEARCH;
        if ((WalkState->Opcode != AML_SCOPE_OP) &&
            (!(WalkState->ParseFlags & ACPI_PARSE_DEFERRED_OP)))
        {
            if (WalkState->NamespaceOverride)
            {
                Flags |= ACPI_NS_OVERRIDE_IF_FOUND;
                ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[%s] Override allowed\n",
                        AcpiUtGetTypeName (ObjectType)));
            }
            else
            {
                Flags |= ACPI_NS_ERROR_IF_FOUND;
                ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[%s] Cannot already exist\n",
                        AcpiUtGetTypeName (ObjectType)));
            }
        }
        else
        {
            ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
                "[%s] Both Find or Create allowed\n",
                    AcpiUtGetTypeName (ObjectType)));
        }

        /*
         * Enter the named type into the internal namespace. We enter the name
         * as we go downward in the parse tree. Any necessary subobjects that
         * involve arguments to the opcode must be created as we go back up the
         * parse tree later.
         */
        Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType,
                        ACPI_IMODE_LOAD_PASS1, Flags, WalkState, &Node);
        if (ACPI_FAILURE (Status))
        {
            if (Status == AE_ALREADY_EXISTS)
            {
                /* The name already exists in this scope */

                if (Node->Flags & ANOBJ_IS_EXTERNAL)
                {
                    /*
                     * Allow one create on an object or segment that was
                     * previously declared External
                     */
                    Node->Flags &= ~ANOBJ_IS_EXTERNAL;
                    Node->Type = (UINT8) ObjectType;

                    /* Just retyped a node, probably will need to open a scope */

                    if (AcpiNsOpensScope (ObjectType))
                    {
                        Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState);
                        if (ACPI_FAILURE (Status))
                        {
                            return_ACPI_STATUS (Status);
                        }
                    }

                    Status = AE_OK;
                }
            }

            if (ACPI_FAILURE (Status))
            {
                ACPI_ERROR_NAMESPACE (Path, Status);
                return_ACPI_STATUS (Status);
            }
        }
        break;
    }

    /* Common exit */

    if (!Op)
    {
        /* Create a new op */

        Op = AcpiPsAllocOp (WalkState->Opcode);
        if (!Op)
        {
            return_ACPI_STATUS (AE_NO_MEMORY);
        }
    }

    /* Initialize the op */

#if (defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY))
    Op->Named.Path = ACPI_CAST_PTR (UINT8, Path);
#endif

    if (Node)
    {
        /*
         * Put the Node in the "op" object that the parser uses, so we
         * can get it again quickly when this scope is closed
         */
        Op->Common.Node = Node;
        Op->Named.Name = Node->Name.Integer;
    }

    AcpiPsAppendArg (AcpiPsGetParentScope (&WalkState->ParserState), Op);
    *OutOp = Op;
    return_ACPI_STATUS (Status);
}
예제 #3
0
                return_ACPI_STATUS (AE_OK);
            }
        }
        else
        {
            /* Get name from the op */

            BufferPtr = ACPI_CAST_PTR (char, &Op->Named.Name);
        }
    }
    else
    {
        /* Get the namestring from the raw AML */

        BufferPtr = AcpiPsGetNextNamestring (&WalkState->ParserState);
    }

    /* Map the opcode into an internal object type */

    ObjectType = WalkState->OpInfo->ObjectType;

    ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
        "State=%p Op=%p Type=%X\n", WalkState, Op, ObjectType));

    switch (WalkState->Opcode)
    {
    case AML_FIELD_OP:
    case AML_BANK_FIELD_OP:
    case AML_INDEX_FIELD_OP:
예제 #4
0
파일: psargs.c 프로젝트: MarginC/kame
void
AcpiPsGetNextSimpleArg (
    ACPI_PARSE_STATE        *ParserState,
    UINT32                  ArgType,
    ACPI_PARSE_OBJECT       *Arg)
{

    FUNCTION_TRACE_U32 ("PsGetNextSimpleArg", ArgType);


    switch (ArgType)
    {

    case ARGP_BYTEDATA:

        AcpiPsInitOp (Arg, AML_BYTE_OP);
        Arg->Value.Integer = (UINT32) GET8 (ParserState->Aml);
        ParserState->Aml++;
        break;


    case ARGP_WORDDATA:

        AcpiPsInitOp (Arg, AML_WORD_OP);

        /* Get 2 bytes from the AML stream */

        MOVE_UNALIGNED16_TO_32 (&Arg->Value.Integer, ParserState->Aml);
        ParserState->Aml += 2;
        break;


    case ARGP_DWORDDATA:

        AcpiPsInitOp (Arg, AML_DWORD_OP);

        /* Get 4 bytes from the AML stream */

        MOVE_UNALIGNED32_TO_32 (&Arg->Value.Integer, ParserState->Aml);
        ParserState->Aml += 4;
        break;


    case ARGP_QWORDDATA:

        AcpiPsInitOp (Arg, AML_QWORD_OP);

        /* Get 8 bytes from the AML stream */

        MOVE_UNALIGNED64_TO_64 (&Arg->Value.Integer, ParserState->Aml);
        ParserState->Aml += 8;
        break;


    case ARGP_CHARLIST:

        AcpiPsInitOp (Arg, AML_STRING_OP);
        Arg->Value.String = (char*) ParserState->Aml;

        while (GET8 (ParserState->Aml) != '\0')
        {
            ParserState->Aml++;
        }
        ParserState->Aml++;
        break;


    case ARGP_NAME:
    case ARGP_NAMESTRING:

        AcpiPsInitOp (Arg, AML_INT_NAMEPATH_OP);
        Arg->Value.Name = AcpiPsGetNextNamestring (ParserState);
        break;
    }

    return_VOID;
}
예제 #5
0
파일: psargs.c 프로젝트: MarginC/kame
void
AcpiPsGetNextNamepath (
    ACPI_PARSE_STATE        *ParserState,
    ACPI_PARSE_OBJECT       *Arg,
    UINT32                  *ArgCount,
    BOOLEAN                 MethodCall)
{
    NATIVE_CHAR             *Path;
    ACPI_PARSE_OBJECT       *NameOp;
    ACPI_STATUS             Status;
    ACPI_NAMESPACE_NODE     *MethodNode = NULL;
    ACPI_NAMESPACE_NODE     *Node;
    ACPI_GENERIC_STATE      ScopeInfo;


    FUNCTION_TRACE ("PsGetNextNamepath");


    Path = AcpiPsGetNextNamestring (ParserState);
    if (!Path || !MethodCall)
    {
        /* Null name case, create a null namepath object */

        AcpiPsInitOp (Arg, AML_INT_NAMEPATH_OP);
        Arg->Value.Name = Path;
        return_VOID;
    }


    if (MethodCall)
    {
        /*
         * Lookup the name in the internal namespace
         */
        ScopeInfo.Scope.Node = NULL;
        Node = ParserState->StartNode;
        if (Node)
        {
            ScopeInfo.Scope.Node = Node;
        }

        /*
         * Lookup object.  We don't want to add anything new to the namespace
         * here, however.  So we use MODE_EXECUTE.  Allow searching of the
         * parent tree, but don't open a new scope -- we just want to lookup the
         * object  (MUST BE mode EXECUTE to perform upsearch)
         */
        Status = AcpiNsLookup (&ScopeInfo, Path, ACPI_TYPE_ANY, IMODE_EXECUTE,
                                NS_SEARCH_PARENT | NS_DONT_OPEN_SCOPE, NULL,
                                &Node);
        if (ACPI_SUCCESS (Status))
        {
            if (Node->Type == ACPI_TYPE_METHOD)
            {
                MethodNode = Node;
                ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "method - %p Path=%p\n",
                    MethodNode, Path));

                NameOp = AcpiPsAllocOp (AML_INT_NAMEPATH_OP);
                if (NameOp)
                {
                    /* Change arg into a METHOD CALL and attach name to it */

                    AcpiPsInitOp (Arg, AML_INT_METHODCALL_OP);

                    NameOp->Value.Name = Path;

                    /* Point METHODCALL/NAME to the METHOD Node */

                    NameOp->Node = MethodNode;
                    AcpiPsAppendArg (Arg, NameOp);

                    if (!(ACPI_OPERAND_OBJECT  *) MethodNode->Object)
                    {
                        return_VOID;
                    }

                    *ArgCount = ((ACPI_OPERAND_OBJECT  *) MethodNode->Object)->Method.ParamCount;
                }

                return_VOID;
            }

            /*
             * Else this is normal named object reference.
             * Just init the NAMEPATH object with the pathname.
             * (See code below)
             */
        }
    }

    /*
     * Either we didn't find the object in the namespace, or the object is
     * something other than a control method.  Just initialize the Op with the
     * pathname.
     */
    AcpiPsInitOp (Arg, AML_INT_NAMEPATH_OP);
    Arg->Value.Name = Path;


    return_VOID;
}
예제 #6
0
파일: psargs.c 프로젝트: MarginC/kame
void
AcpiPsGetNextNamepath (
    ACPI_PARSE_STATE        *ParserState,
    ACPI_PARSE_OBJECT       *Arg,
    UINT32                  *ArgCount,
    BOOLEAN                 MethodCall)
{
    NATIVE_CHAR             *Path;
    ACPI_PARSE_OBJECT       *NameOp;
    ACPI_PARSE_OBJECT       *Op;
    ACPI_PARSE_OBJECT       *Count;


    FUNCTION_TRACE ("PsGetNextNamepath");


    Path = AcpiPsGetNextNamestring (ParserState);
    if (!Path || !MethodCall)
    {
        /* Null name case, create a null namepath object */

        AcpiPsInitOp (Arg, AML_INT_NAMEPATH_OP);
        Arg->Value.Name = Path;
        return_VOID;
    }


    if (AcpiGbl_ParsedNamespaceRoot)
    {
        /*
         * Lookup the name in the parsed namespace
         */
        Op = NULL;
        if (MethodCall)
        {
            Op = AcpiPsFind (AcpiPsGetParentScope (ParserState),
                                Path, AML_METHOD_OP, 0);
        }

        if (Op)
        {
            if (Op->Opcode == AML_METHOD_OP)
            {
                /*
                 * The name refers to a control method, so this namepath is a
                 * method invocation.  We need to 1) Get the number of arguments
                 * associated with this method, and 2) Change the NAMEPATH
                 * object into a METHODCALL object.
                 */
                Count = AcpiPsGetArg (Op, 0);
                if (Count && Count->Opcode == AML_BYTE_OP)
                {
                    NameOp = AcpiPsAllocOp (AML_INT_NAMEPATH_OP);
                    if (NameOp)
                    {
                        /* Change arg into a METHOD CALL and attach the name */

                        AcpiPsInitOp (Arg, AML_INT_METHODCALL_OP);

                        NameOp->Value.Name = Path;

                        /* Point METHODCALL/NAME to the METHOD Node */

                        NameOp->Node = (ACPI_NAMESPACE_NODE *) Op;
                        AcpiPsAppendArg (Arg, NameOp);

                        *ArgCount = (UINT32) Count->Value.Integer &
                                    METHOD_FLAGS_ARG_COUNT;
                    }
                }

                return_VOID;
            }

            /*
             * Else this is normal named object reference.
             * Just init the NAMEPATH object with the pathname.
             * (See code below)
             */
        }
    }

    /*
     * Either we didn't find the object in the namespace, or the object is
     * something other than a control method.  Just initialize the Op with the
     * pathname
     */
    AcpiPsInitOp (Arg, AML_INT_NAMEPATH_OP);
    Arg->Value.Name = Path;


    return_VOID;
}