Beispiel #1
0
ACPI_PARSE_OBJECT*
AcpiPsAllocOp (
    UINT16                  Opcode,
    UINT8                   *Aml)
{
    ACPI_PARSE_OBJECT       *Op;
    const ACPI_OPCODE_INFO  *OpInfo;
    UINT8                   Flags = ACPI_PARSEOP_GENERIC;


    ACPI_FUNCTION_ENTRY ();


    OpInfo = AcpiPsGetOpcodeInfo (Opcode);

    /* Determine type of ParseOp required */

    if (OpInfo->Flags & AML_DEFER)
    {
        Flags = ACPI_PARSEOP_DEFERRED;
    }
    else if (OpInfo->Flags & AML_NAMED)
    {
        Flags = ACPI_PARSEOP_NAMED;
    }
    else if (Opcode == AML_INT_BYTELIST_OP)
    {
        Flags = ACPI_PARSEOP_BYTELIST;
    }

    /* Allocate the minimum required size object */

    if (Flags == ACPI_PARSEOP_GENERIC)
    {
        /* The generic op (default) is by far the most common (16 to 1) */

        Op = AcpiOsAcquireObject (AcpiGbl_PsNodeCache);
    }
    else
    {
        /* Extended parseop */

        Op = AcpiOsAcquireObject (AcpiGbl_PsNodeExtCache);
    }

    /* Initialize the Op */

    if (Op)
    {
        AcpiPsInitOp (Op, Opcode);
        Op->Common.Aml = Aml;
        Op->Common.Flags = Flags;
    }

    return (Op);
}
Beispiel #2
0
static char *
AcpiGetTagPathname (
    ACPI_PARSE_OBJECT       *IndexOp,
    ACPI_NAMESPACE_NODE     *BufferNode,
    ACPI_NAMESPACE_NODE     *ResourceNode,
    UINT32                  BitIndex)
{
    ACPI_STATUS             Status;
    UINT32                  ResourceBitIndex;
    UINT8                   ResourceTableIndex;
    ACPI_SIZE               RequiredSize;
    char                    *Pathname;
    AML_RESOURCE            *Aml;
    ACPI_PARSE_OBJECT       *Op;
    char                    *InternalPath;
    char                    *Tag;


    /* Get the Op that contains the actual buffer data */

    Op = BufferNode->Op->Common.Value.Arg;
    Op = Op->Common.Next;
    if (!Op)
    {
        return (NULL);
    }

    /* Get the individual resource descriptor and validate it */

    Aml = ACPI_CAST_PTR (
        AML_RESOURCE, &Op->Named.Data[ResourceNode->Value]);

    Status = AcpiUtValidateResource (NULL, Aml, &ResourceTableIndex);
    if (ACPI_FAILURE (Status))
    {
        return (NULL);
    }

    /* Get offset into this descriptor (from offset into entire buffer) */

    ResourceBitIndex = BitIndex - ACPI_MUL_8 (ResourceNode->Value);

    /* Get the tag associated with this resource descriptor and offset */

    Tag = AcpiDmGetResourceTag (ResourceBitIndex, Aml, ResourceTableIndex);
    if (!Tag)
    {
        return (NULL);
    }

    /*
     * Now that we know that we have a reference that can be converted to a
     * symbol, change the name of the resource to a unique name.
     */
    AcpiDmUpdateResourceName (ResourceNode);

    /* Get the full pathname to the parent buffer */

    RequiredSize = AcpiNsBuildNormalizedPath (BufferNode, NULL, 0, FALSE);
    if (!RequiredSize)
    {
        return (NULL);
    }

    Pathname = ACPI_ALLOCATE_ZEROED (RequiredSize + ACPI_PATH_SEGMENT_LENGTH);
    if (!Pathname)
    {
        return (NULL);
    }

    (void) AcpiNsBuildNormalizedPath (BufferNode, Pathname,
        RequiredSize, FALSE);

    /*
     * Create the full path to the resource and tag by: remove the buffer name,
     * append the resource descriptor name, append a dot, append the tag name.
     *
     * TBD: Always using the full path is a bit brute force, the path can be
     * often be optimized with carats (if the original buffer namepath is a
     * single nameseg). This doesn't really matter, because these paths do not
     * end up in the final compiled AML, it's just an appearance issue for the
     * disassembled code.
     */
    Pathname[strlen (Pathname) - ACPI_NAME_SIZE] = 0;
    strncat (Pathname, ResourceNode->Name.Ascii, ACPI_NAME_SIZE);
    strcat (Pathname, ".");
    strncat (Pathname, Tag, ACPI_NAME_SIZE);

    /* Internalize the namepath to AML format */

    AcpiNsInternalizeName (Pathname, &InternalPath);
    ACPI_FREE (Pathname);

    /* Update the Op with the symbol */

    AcpiPsInitOp (IndexOp, AML_INT_NAMEPATH_OP);
    IndexOp->Common.Value.String = InternalPath;

    /* We will need the tag later. Cheat by putting it in the Node field */

    IndexOp->Common.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Tag);
    return (InternalPath);
}
Beispiel #3
0
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;
}
Beispiel #4
0
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;
}
Beispiel #5
0
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;
}