Пример #1
0
UINT32
AcpiUtCheckAddressRange (
    ACPI_ADR_SPACE_TYPE     SpaceId,
    ACPI_PHYSICAL_ADDRESS   Address,
    UINT32                  Length,
    BOOLEAN                 Warn)
{
    ACPI_ADDRESS_RANGE      *RangeInfo;
    ACPI_PHYSICAL_ADDRESS   EndAddress;
    char                    *Pathname;
    UINT32                  OverlapCount = 0;


    ACPI_FUNCTION_TRACE (UtCheckAddressRange);


    if ((SpaceId != ACPI_ADR_SPACE_SYSTEM_MEMORY) &&
        (SpaceId != ACPI_ADR_SPACE_SYSTEM_IO))
    {
        return_UINT32 (0);
    }

    RangeInfo = AcpiGbl_AddressRangeList[SpaceId];
    EndAddress = Address + Length - 1;

    /* Check entire list for all possible conflicts */

    while (RangeInfo)
    {
        /*
         * Check if the requested address/length overlaps this
         * address range. There are four cases to consider:
         *
         * 1) Input address/length is contained completely in the
         *    address range
         * 2) Input address/length overlaps range at the range start
         * 3) Input address/length overlaps range at the range end
         * 4) Input address/length completely encompasses the range
         */
        if ((Address <= RangeInfo->EndAddress) &&
            (EndAddress >= RangeInfo->StartAddress))
        {
            /* Found an address range overlap */

            OverlapCount++;
            if (Warn)   /* Optional warning message */
            {
                Pathname = AcpiNsGetNormalizedPathname (RangeInfo->RegionNode, TRUE);

                ACPI_WARNING ((AE_INFO,
                    "%s range 0x%8.8X%8.8X-0x%8.8X%8.8X conflicts with OpRegion 0x%8.8X%8.8X-0x%8.8X%8.8X (%s)",
                    AcpiUtGetRegionName (SpaceId),
                    ACPI_FORMAT_UINT64 (Address),
                    ACPI_FORMAT_UINT64 (EndAddress),
                    ACPI_FORMAT_UINT64 (RangeInfo->StartAddress),
                    ACPI_FORMAT_UINT64 (RangeInfo->EndAddress),
                    Pathname));
                ACPI_FREE (Pathname);
            }
        }

        RangeInfo = RangeInfo->Next;
    }

    return_UINT32 (OverlapCount);
}
Пример #2
0
ACPI_STATUS
AcpiNsExecuteTable (
    UINT32                  TableIndex,
    ACPI_NAMESPACE_NODE     *StartNode)
{
    ACPI_STATUS             Status;
    ACPI_TABLE_HEADER       *Table;
    ACPI_OWNER_ID           OwnerId;
    ACPI_EVALUATE_INFO      *Info = NULL;
    UINT32                  AmlLength;
    UINT8                   *AmlStart;
    ACPI_OPERAND_OBJECT     *MethodObj = NULL;


    ACPI_FUNCTION_TRACE (NsExecuteTable);


    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, initialize, and link a new temporary method object */

    MethodObj = AcpiUtCreateInternalObject (ACPI_TYPE_METHOD);
    if (!MethodObj)
    {
        return_ACPI_STATUS (AE_NO_MEMORY);
    }

    /* Allocate the evaluation information block */

    Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
    if (!Info)
    {
        Status = AE_NO_MEMORY;
        goto Cleanup;
    }

    ACPI_DEBUG_PRINT_RAW ((ACPI_DB_PARSE,
        "%s: Create table pseudo-method for [%4.4s] @%p, method %p\n",
        ACPI_GET_FUNCTION_NAME, Table->Signature, Table, MethodObj));

    MethodObj->Method.AmlStart = AmlStart;
    MethodObj->Method.AmlLength = AmlLength;
    MethodObj->Method.OwnerId = OwnerId;
    MethodObj->Method.InfoFlags |= ACPI_METHOD_MODULE_LEVEL;

    Info->PassNumber = ACPI_IMODE_EXECUTE;
    Info->Node = StartNode;
    Info->ObjDesc = MethodObj;
    Info->NodeFlags = Info->Node->Flags;
    Info->FullPathname = AcpiNsGetNormalizedPathname (Info->Node, TRUE);
    if (!Info->FullPathname)
    {
        Status = AE_NO_MEMORY;
        goto Cleanup;
    }

    Status = AcpiPsExecuteTable (Info);

Cleanup:
    if (Info)
    {
        ACPI_FREE (Info->FullPathname);
        Info->FullPathname = NULL;
    }
    ACPI_FREE (Info);
    AcpiUtRemoveReference (MethodObj);
    return_ACPI_STATUS (Status);
}
Пример #3
0
static ACPI_STATUS
AcpiNsInitOneDevice (
    ACPI_HANDLE             ObjHandle,
    UINT32                  NestingLevel,
    void                    *Context,
    void                    **ReturnValue)
{
    ACPI_DEVICE_WALK_INFO   *WalkInfo = ACPI_CAST_PTR (ACPI_DEVICE_WALK_INFO, Context);
    ACPI_EVALUATE_INFO      *Info = WalkInfo->EvaluateInfo;
    UINT32                  Flags;
    ACPI_STATUS             Status;
    ACPI_NAMESPACE_NODE     *DeviceNode;


    ACPI_FUNCTION_TRACE (NsInitOneDevice);


    /* We are interested in Devices, Processors and ThermalZones only */

    DeviceNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle);
    if ((DeviceNode->Type != ACPI_TYPE_DEVICE)    &&
        (DeviceNode->Type != ACPI_TYPE_PROCESSOR) &&
        (DeviceNode->Type != ACPI_TYPE_THERMAL))
    {
        return_ACPI_STATUS (AE_OK);
    }

    /*
     * Because of an earlier namespace analysis, all subtrees that contain an
     * _INI method are tagged.
     *
     * If this device subtree does not contain any _INI methods, we
     * can exit now and stop traversing this entire subtree.
     */
    if (!(DeviceNode->Flags & ANOBJ_SUBTREE_HAS_INI))
    {
        return_ACPI_STATUS (AE_CTRL_DEPTH);
    }

    /*
     * Run _STA to determine if this device is present and functioning. We
     * must know this information for two important reasons (from ACPI spec):
     *
     * 1) We can only run _INI if the device is present.
     * 2) We must abort the device tree walk on this subtree if the device is
     *    not present and is not functional (we will not examine the children)
     *
     * The _STA method is not required to be present under the device, we
     * assume the device is present if _STA does not exist.
     */
    ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname (
        ACPI_TYPE_METHOD, DeviceNode, METHOD_NAME__STA));

    Status = AcpiUtExecute_STA (DeviceNode, &Flags);
    if (ACPI_FAILURE (Status))
    {
        /* Ignore error and move on to next device */

        return_ACPI_STATUS (AE_OK);
    }

    /*
     * Flags == -1 means that _STA was not found. In this case, we assume that
     * the device is both present and functional.
     *
     * From the ACPI spec, description of _STA:
     *
     * "If a device object (including the processor object) does not have an
     * _STA object, then OSPM assumes that all of the above bits are set (in
     * other words, the device is present, ..., and functioning)"
     */
    if (Flags != ACPI_UINT32_MAX)
    {
        WalkInfo->Num_STA++;
    }

    /*
     * Examine the PRESENT and FUNCTIONING status bits
     *
     * Note: ACPI spec does not seem to specify behavior for the present but
     * not functioning case, so we assume functioning if present.
     */
    if (!(Flags & ACPI_STA_DEVICE_PRESENT))
    {
        /* Device is not present, we must examine the Functioning bit */

        if (Flags & ACPI_STA_DEVICE_FUNCTIONING)
        {
            /*
             * Device is not present but is "functioning". In this case,
             * we will not run _INI, but we continue to examine the children
             * of this device.
             *
             * From the ACPI spec, description of _STA: (Note - no mention
             * of whether to run _INI or not on the device in question)
             *
             * "_STA may return bit 0 clear (not present) with bit 3 set
             * (device is functional). This case is used to indicate a valid
             * device for which no device driver should be loaded (for example,
             * a bridge device.) Children of this device may be present and
             * valid. OSPM should continue enumeration below a device whose
             * _STA returns this bit combination"
             */
            return_ACPI_STATUS (AE_OK);
        }
        else
        {
            /*
             * Device is not present and is not functioning. We must abort the
             * walk of this subtree immediately -- don't look at the children
             * of such a device.
             *
             * From the ACPI spec, description of _INI:
             *
             * "If the _STA method indicates that the device is not present,
             * OSPM will not run the _INI and will not examine the children
             * of the device for _INI methods"
             */
            return_ACPI_STATUS (AE_CTRL_DEPTH);
        }
    }

    /*
     * The device is present or is assumed present if no _STA exists.
     * Run the _INI if it exists (not required to exist)
     *
     * Note: We know there is an _INI within this subtree, but it may not be
     * under this particular device, it may be lower in the branch.
     */
    if (!ACPI_COMPARE_NAME (DeviceNode->Name.Ascii, "_SB_") ||
        DeviceNode->Parent != AcpiGbl_RootNode)
    {
        ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname (
            ACPI_TYPE_METHOD, DeviceNode, METHOD_NAME__INI));

        memset (Info, 0, sizeof (ACPI_EVALUATE_INFO));
        Info->PrefixNode = DeviceNode;
        Info->RelativePathname = METHOD_NAME__INI;
        Info->Parameters = NULL;
        Info->Flags = ACPI_IGNORE_RETURN_VALUE;

        Status = AcpiNsEvaluate (Info);
        if (ACPI_SUCCESS (Status))
        {
            WalkInfo->Num_INI++;
        }

#ifdef ACPI_DEBUG_OUTPUT
        else if (Status != AE_NOT_FOUND)
        {
            /* Ignore error and move on to next device */

            char *ScopeName = AcpiNsGetNormalizedPathname (DeviceNode, TRUE);

            ACPI_EXCEPTION ((AE_INFO, Status, "during %s._INI execution",
                ScopeName));
            ACPI_FREE (ScopeName);
        }
#endif
    }

    /* Ignore errors from above */

    Status = AE_OK;

    /*
     * The _INI method has been run if present; call the Global Initialization
     * Handler for this device.
     */
    if (AcpiGbl_InitHandler)
    {
        Status = AcpiGbl_InitHandler (DeviceNode, ACPI_INIT_DEVICE_INI);
    }

    return_ACPI_STATUS (Status);
}
Пример #4
0
ACPI_STATUS
AcpiDsCallControlMethod (
    ACPI_THREAD_STATE       *Thread,
    ACPI_WALK_STATE         *ThisWalkState,
    ACPI_PARSE_OBJECT       *Op)
{
    ACPI_STATUS             Status;
    ACPI_NAMESPACE_NODE     *MethodNode;
    ACPI_WALK_STATE         *NextWalkState = NULL;
    ACPI_OPERAND_OBJECT     *ObjDesc;
    ACPI_EVALUATE_INFO      *Info;
    UINT32                  i;


    ACPI_FUNCTION_TRACE_PTR (DsCallControlMethod, ThisWalkState);

    ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
        "Calling method %p, currentstate=%p\n",
        ThisWalkState->PrevOp, ThisWalkState));

    /*
     * Get the namespace entry for the control method we are about to call
     */
    MethodNode = ThisWalkState->MethodCallNode;
    if (!MethodNode)
    {
        return_ACPI_STATUS (AE_NULL_ENTRY);
    }

    ObjDesc = AcpiNsGetAttachedObject (MethodNode);
    if (!ObjDesc)
    {
        return_ACPI_STATUS (AE_NULL_OBJECT);
    }

    /* Init for new method, possibly wait on method mutex */

    Status = AcpiDsBeginMethodExecution (
        MethodNode, ObjDesc, ThisWalkState);
    if (ACPI_FAILURE (Status))
    {
        return_ACPI_STATUS (Status);
    }

    /* Begin method parse/execution. Create a new walk state */

    NextWalkState = AcpiDsCreateWalkState (
        ObjDesc->Method.OwnerId, NULL, ObjDesc, Thread);
    if (!NextWalkState)
    {
        Status = AE_NO_MEMORY;
        goto Cleanup;
    }

    /*
     * The resolved arguments were put on the previous walk state's operand
     * stack. Operands on the previous walk state stack always
     * start at index 0. Also, null terminate the list of arguments
     */
    ThisWalkState->Operands [ThisWalkState->NumOperands] = NULL;

    /*
     * Allocate and initialize the evaluation information block
     * TBD: this is somewhat inefficient, should change interface to
     * DsInitAmlWalk. For now, keeps this struct off the CPU stack
     */
    Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
    if (!Info)
    {
        Status = AE_NO_MEMORY;
        goto Cleanup;
    }

    Info->Parameters = &ThisWalkState->Operands[0];

    Status = AcpiDsInitAmlWalk (NextWalkState, NULL, MethodNode,
        ObjDesc->Method.AmlStart, ObjDesc->Method.AmlLength,
        Info, ACPI_IMODE_EXECUTE);

    ACPI_FREE (Info);
    if (ACPI_FAILURE (Status))
    {
        goto Cleanup;
    }

    NextWalkState->MethodNestingDepth = ThisWalkState->MethodNestingDepth + 1;

    /*
     * Delete the operands on the previous walkstate operand stack
     * (they were copied to new objects)
     */
    for (i = 0; i < ObjDesc->Method.ParamCount; i++)
    {
        AcpiUtRemoveReference (ThisWalkState->Operands [i]);
        ThisWalkState->Operands [i] = NULL;
    }

    /* Clear the operand stack */

    ThisWalkState->NumOperands = 0;

    ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
        "**** Begin nested execution of [%4.4s] **** WalkState=%p\n",
        MethodNode->Name.Ascii, NextWalkState));

    ThisWalkState->MethodPathname = AcpiNsGetNormalizedPathname (MethodNode, TRUE);
    ThisWalkState->MethodIsNested = TRUE;

    /* Optional object evaluation log */

    ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EVALUATION,
        "%-26s:  %*s%s\n", "   Nested method call",
        NextWalkState->MethodNestingDepth * 3, " ",
        &ThisWalkState->MethodPathname[1]));

    /* Invoke an internal method if necessary */

    if (ObjDesc->Method.InfoFlags & ACPI_METHOD_INTERNAL_ONLY)
    {
        Status = ObjDesc->Method.Dispatch.Implementation (NextWalkState);
        if (Status == AE_OK)
        {
            Status = AE_CTRL_TERMINATE;
        }
    }

    return_ACPI_STATUS (Status);


Cleanup:

    /* On error, we must terminate the method properly */

    AcpiDsTerminateControlMethod (ObjDesc, NextWalkState);
    AcpiDsDeleteWalkState (NextWalkState);

    return_ACPI_STATUS (Status);
}
Пример #5
0
ACPI_STATUS
AcpiNsEvaluate (
    ACPI_EVALUATE_INFO      *Info)
{
    ACPI_STATUS             Status;


    ACPI_FUNCTION_TRACE (NsEvaluate);


    if (!Info)
    {
        return_ACPI_STATUS (AE_BAD_PARAMETER);
    }

    if (!Info->Node)
    {
        /*
         * Get the actual namespace node for the target object if we
         * need to. Handles these cases:
         *
         * 1) Null node, valid pathname from root (absolute path)
         * 2) Node and valid pathname (path relative to Node)
         * 3) Node, Null pathname
         */
        Status = AcpiNsGetNode (Info->PrefixNode, Info->RelativePathname,
            ACPI_NS_NO_UPSEARCH, &Info->Node);
        if (ACPI_FAILURE (Status))
        {
            return_ACPI_STATUS (Status);
        }
    }

    /*
     * For a method alias, we must grab the actual method node so that
     * proper scoping context will be established before execution.
     */
    if (AcpiNsGetType (Info->Node) == ACPI_TYPE_LOCAL_METHOD_ALIAS)
    {
        Info->Node = ACPI_CAST_PTR (
            ACPI_NAMESPACE_NODE, Info->Node->Object);
    }

    /* Complete the info block initialization */

    Info->ReturnObject = NULL;
    Info->NodeFlags = Info->Node->Flags;
    Info->ObjDesc = AcpiNsGetAttachedObject (Info->Node);

    ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%s [%p] Value %p\n",
        Info->RelativePathname, Info->Node,
        AcpiNsGetAttachedObject (Info->Node)));

    /* Get info if we have a predefined name (_HID, etc.) */

    Info->Predefined = AcpiUtMatchPredefinedMethod (Info->Node->Name.Ascii);

    /* Get the full pathname to the object, for use in warning messages */

    Info->FullPathname = AcpiNsGetNormalizedPathname (Info->Node, TRUE);
    if (!Info->FullPathname)
    {
        return_ACPI_STATUS (AE_NO_MEMORY);
    }

    /* Optional object evaluation log */

    ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EVALUATION,
        "%-26s:  %s (%s)\n", "   Enter evaluation",
        &Info->FullPathname[1], AcpiUtGetTypeName (Info->Node->Type)));

    /* Count the number of arguments being passed in */

    Info->ParamCount = 0;
    if (Info->Parameters)
    {
        while (Info->Parameters[Info->ParamCount])
        {
            Info->ParamCount++;
        }

        /* Warn on impossible argument count */

        if (Info->ParamCount > ACPI_METHOD_NUM_ARGS)
        {
            ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, ACPI_WARN_ALWAYS,
                "Excess arguments (%u) - using only %u",
                Info->ParamCount, ACPI_METHOD_NUM_ARGS));

            Info->ParamCount = ACPI_METHOD_NUM_ARGS;
        }
    }

    /*
     * For predefined names: Check that the declared argument count
     * matches the ACPI spec -- otherwise this is a BIOS error.
     */
    AcpiNsCheckAcpiCompliance (Info->FullPathname, Info->Node,
        Info->Predefined);

    /*
     * For all names: Check that the incoming argument count for
     * this method/object matches the actual ASL/AML definition.
     */
    AcpiNsCheckArgumentCount (Info->FullPathname, Info->Node,
        Info->ParamCount, Info->Predefined);

    /* For predefined names: Typecheck all incoming arguments */

    AcpiNsCheckArgumentTypes (Info);

    /*
     * Three major evaluation cases:
     *
     * 1) Object types that cannot be evaluated by definition
     * 2) The object is a control method -- execute it
     * 3) The object is not a method -- just return it's current value
     */
    switch (AcpiNsGetType (Info->Node))
    {
    case ACPI_TYPE_ANY:
    case ACPI_TYPE_DEVICE:
    case ACPI_TYPE_EVENT:
    case ACPI_TYPE_MUTEX:
    case ACPI_TYPE_REGION:
    case ACPI_TYPE_THERMAL:
    case ACPI_TYPE_LOCAL_SCOPE:
        /*
         * 1) Disallow evaluation of these object types. For these,
         *    object evaluation is undefined.
         */
        ACPI_ERROR ((AE_INFO,
            "%s: This object type [%s] "
            "never contains data and cannot be evaluated",
            Info->FullPathname, AcpiUtGetTypeName (Info->Node->Type)));

        Status = AE_TYPE;
        goto Cleanup;

    case ACPI_TYPE_METHOD:
        /*
         * 2) Object is a control method - execute it
         */

        /* Verify that there is a method object associated with this node */

        if (!Info->ObjDesc)
        {
            ACPI_ERROR ((AE_INFO, "%s: Method has no attached sub-object",
                Info->FullPathname));
            Status = AE_NULL_OBJECT;
            goto Cleanup;
        }

        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
            "**** Execute method [%s] at AML address %p length %X\n",
            Info->FullPathname,
            Info->ObjDesc->Method.AmlStart + 1,
            Info->ObjDesc->Method.AmlLength - 1));

        /*
         * Any namespace deletion must acquire both the namespace and
         * interpreter locks to ensure that no thread is using the portion of
         * the namespace that is being deleted.
         *
         * Execute the method via the interpreter. The interpreter is locked
         * here before calling into the AML parser
         */
        AcpiExEnterInterpreter ();
        Status = AcpiPsExecuteMethod (Info);
        AcpiExExitInterpreter ();
        break;

    default:
        /*
         * 3) All other non-method objects -- get the current object value
         */

        /*
         * Some objects require additional resolution steps (e.g., the Node
         * may be a field that must be read, etc.) -- we can't just grab
         * the object out of the node.
         *
         * Use ResolveNodeToValue() to get the associated value.
         *
         * NOTE: we can get away with passing in NULL for a walk state because
         * the Node is guaranteed to not be a reference to either a method
         * local or a method argument (because this interface is never called
         * from a running method.)
         *
         * Even though we do not directly invoke the interpreter for object
         * resolution, we must lock it because we could access an OpRegion.
         * The OpRegion access code assumes that the interpreter is locked.
         */
        AcpiExEnterInterpreter ();

        /* TBD: ResolveNodeToValue has a strange interface, fix */

        Info->ReturnObject = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Info->Node);

        Status = AcpiExResolveNodeToValue (ACPI_CAST_INDIRECT_PTR (
            ACPI_NAMESPACE_NODE, &Info->ReturnObject), NULL);
        AcpiExExitInterpreter ();

        if (ACPI_FAILURE (Status))
        {
            Info->ReturnObject = NULL;
            goto Cleanup;
        }

        ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Returned object %p [%s]\n",
            Info->ReturnObject,
            AcpiUtGetObjectTypeName (Info->ReturnObject)));

        Status = AE_CTRL_RETURN_VALUE; /* Always has a "return value" */
        break;
    }

    /*
     * For predefined names, check the return value against the ACPI
     * specification. Some incorrect return value types are repaired.
     */
    (void) AcpiNsCheckReturnValue (Info->Node, Info, Info->ParamCount,
        Status, &Info->ReturnObject);

    /* Check if there is a return value that must be dealt with */

    if (Status == AE_CTRL_RETURN_VALUE)
    {
        /* If caller does not want the return value, delete it */

        if (Info->Flags & ACPI_IGNORE_RETURN_VALUE)
        {
            AcpiUtRemoveReference (Info->ReturnObject);
            Info->ReturnObject = NULL;
        }

        /* Map AE_CTRL_RETURN_VALUE to AE_OK, we are done with it */

        Status = AE_OK;
    }
    else if (ACPI_FAILURE(Status))
    {
        /* If ReturnObject exists, delete it */

        if (Info->ReturnObject)
        {
            AcpiUtRemoveReference (Info->ReturnObject);
            Info->ReturnObject = NULL;
        }
    }

    ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
        "*** Completed evaluation of object %s ***\n",
        Info->RelativePathname));

Cleanup:
    /* Optional object evaluation log */

    ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EVALUATION,
        "%-26s:  %s\n", "   Exit evaluation",
        &Info->FullPathname[1]));

    /*
     * Namespace was unlocked by the handling AcpiNs* function, so we
     * just free the pathname and return
     */
    ACPI_FREE (Info->FullPathname);
    Info->FullPathname = NULL;
    return_ACPI_STATUS (Status);
}
Пример #6
0
static void
ExMoveExternals (
    ACPI_PARSE_OBJECT       *DefinitionBlockOp)
{
    ACPI_PARSE_OBJECT       *ParentOp;
    ACPI_PARSE_OBJECT       *ExternalOp;
    ACPI_PARSE_OBJECT       *PredicateOp;
    ACPI_PARSE_OBJECT       *NextOp;
    ACPI_PARSE_OBJECT       *Prev;
    ACPI_PARSE_OBJECT       *Next;
    char                    *ExternalName;
    ACPI_OBJECT_TYPE        ObjType;
    ACPI_STATUS             Status;
    UINT32                  i;


    if (!AslGbl_ExternalsListHead)
    {
        return;
    }

    /* Remove the External nodes from the tree */

    NextOp = AslGbl_ExternalsListHead;
    while (NextOp)
    {
        /*
         * The External is stored in child pointer of each node in the
         * list
         */
        ExternalOp = NextOp->Asl.Child;

        /* Get/set the fully qualified name */

        ExternalName = AcpiNsGetNormalizedPathname (ExternalOp->Asl.Node, TRUE);
        ExternalOp->Asl.ExternalName = ExternalName;
        ExternalOp->Asl.Namepath = ExternalName;

        /* Set line numbers (for listings, etc.) */

        ExternalOp->Asl.LineNumber = 0;
        ExternalOp->Asl.LogicalLineNumber = 0;

        Next = ExternalOp->Asl.Child;
        Next->Asl.LineNumber = 0;
        Next->Asl.LogicalLineNumber = 0;

        if (Next->Asl.ParseOpcode == PARSEOP_NAMESEG)
        {
            Next->Asl.ParseOpcode = PARSEOP_NAMESTRING;
        }

        Next->Asl.ExternalName = ExternalName;
        Status = UtInternalizeName (ExternalName, &Next->Asl.Value.String);
        if (ACPI_FAILURE (Status))
        {
            AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL,
                Next, "Could not internalize namestring");
            return;
        }

        Next->Asl.AmlLength = strlen (Next->Asl.Value.String);

        Next = Next->Asl.Next;
        Next->Asl.LineNumber = 0;
        Next->Asl.LogicalLineNumber = 0;

        Next = Next->Asl.Next;
        Next->Asl.LineNumber = 0;
        Next->Asl.LogicalLineNumber = 0;

        Next = Next->Asl.Next;
        Next->Asl.LineNumber = 0;
        Next->Asl.LogicalLineNumber = 0;

        ParentOp = ExternalOp->Asl.Parent;
        Prev = Next = ParentOp->Asl.Child;

        /* Now find the External node's position in parse tree */

        while (Next != ExternalOp)
        {
            Prev = Next;
            Next = Next->Asl.Next;
        }

        /* Remove the External from the parse tree */

        if (Prev == ExternalOp)
        {
            /* External was the first child node */

            ParentOp->Asl.Child = ExternalOp->Asl.Next;
        }

        Prev->Asl.Next = ExternalOp->Asl.Next;
        ExternalOp->Asl.Next = NULL;
        ExternalOp->Asl.Parent = AslGbl_ExternalsListHead;

        /* Point the External to the next in the list */

        if (NextOp->Asl.Next)
        {
            ExternalOp->Asl.Next = NextOp->Asl.Next->Asl.Child;
        }

        NextOp = NextOp->Asl.Next;
    }

    /*
     * Loop again to remove MethodObj Externals for which
     * a MethodCall was not found (dead external reference)
     */
    Prev = AslGbl_ExternalsListHead->Asl.Child;
    Next = Prev;
    while (Next)
    {
        ObjType = (ACPI_OBJECT_TYPE)
            Next->Asl.Child->Asl.Next->Asl.Value.Integer;

        if (ObjType == ACPI_TYPE_METHOD &&
            !(Next->Asl.CompileFlags & OP_VISITED))
        {
            if (Next == Prev)
            {
                AslGbl_ExternalsListHead->Asl.Child = Next->Asl.Next;
                Next->Asl.Next = NULL;
                Prev = AslGbl_ExternalsListHead->Asl.Child;
                Next = Prev;
                continue;
            }
            else
            {
                Prev->Asl.Next = Next->Asl.Next;
                Next->Asl.Next = NULL;
                Next = Prev->Asl.Next;
                continue;
            }
        }

        Prev = Next;
        Next = Next->Asl.Next;
    }

    /* If list is now empty, don't bother to make If (0) block */

    if (!AslGbl_ExternalsListHead->Asl.Child)
    {
        return;
    }

    /* Convert Gbl_ExternalsListHead parent to If(). */

    AslGbl_ExternalsListHead->Asl.ParseOpcode = PARSEOP_IF;
    AslGbl_ExternalsListHead->Asl.AmlOpcode = AML_IF_OP;
    AslGbl_ExternalsListHead->Asl.CompileFlags = OP_AML_PACKAGE;
    UtSetParseOpName (AslGbl_ExternalsListHead);

    /* Create a Zero op for the If predicate */

    PredicateOp = TrAllocateOp (PARSEOP_ZERO);
    PredicateOp->Asl.AmlOpcode = AML_ZERO_OP;

    PredicateOp->Asl.Parent = AslGbl_ExternalsListHead;
    PredicateOp->Asl.Child = NULL;
    PredicateOp->Asl.Next = AslGbl_ExternalsListHead->Asl.Child;
    AslGbl_ExternalsListHead->Asl.Child = PredicateOp;

    /* Set line numbers (for listings, etc.) */

    AslGbl_ExternalsListHead->Asl.LineNumber = 0;
    AslGbl_ExternalsListHead->Asl.LogicalLineNumber = 0;

    PredicateOp->Asl.LineNumber = 0;
    PredicateOp->Asl.LogicalLineNumber = 0;

    /* Insert block back in the list */

    Prev = DefinitionBlockOp->Asl.Child;
    Next = Prev;

    /* Find last default arg */

    for (i = 0; i < 6; i++)
    {
        Prev = Next;
        Next = Prev->Asl.Next;
    }

    if (Next)
    {
        /* Definition Block is not empty */

        AslGbl_ExternalsListHead->Asl.Next = Next;
    }
    else
    {
        /* Definition Block is empty. */

        AslGbl_ExternalsListHead->Asl.Next = NULL;
    }

    Prev->Asl.Next = AslGbl_ExternalsListHead;
    AslGbl_ExternalsListHead->Asl.Parent = Prev->Asl.Parent;
}
Пример #7
0
static void
ExInsertArgCount (
    ACPI_PARSE_OBJECT       *Op)
{
    ACPI_PARSE_OBJECT       *Next;
    ACPI_PARSE_OBJECT       *NameOp;
    ACPI_PARSE_OBJECT       *Child;
    ACPI_PARSE_OBJECT       *ArgCountOp;
    char *                  ExternalName;
    char *                  CallName;
    UINT16                  ArgCount = 0;
    ACPI_STATUS             Status;


    CallName = AcpiNsGetNormalizedPathname (Op->Asl.Node, TRUE);

    Next = AslGbl_ExternalsListHead;
    while (Next)
    {
        ArgCount = 0;

        /* Skip if External node already handled */

        if (Next->Asl.Child->Asl.CompileFlags & OP_VISITED)
        {
            Next = Next->Asl.Next;
            continue;
        }

        NameOp = Next->Asl.Child->Asl.Child;
        ExternalName = AcpiNsGetNormalizedPathname (NameOp->Asl.Node, TRUE);

        if (strcmp (CallName, ExternalName))
        {
            ACPI_FREE (ExternalName);
            Next = Next->Asl.Next;
            continue;
        }

        Next->Asl.Child->Asl.CompileFlags |= OP_VISITED;

        /*
         * Since we will reposition Externals to the Root, set Namepath
         * to the fully qualified name and recalculate the aml length
         */
        Status = UtInternalizeName (ExternalName,
            &NameOp->Asl.Value.String);

        ACPI_FREE (ExternalName);
        if (ACPI_FAILURE (Status))
        {
            AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL,
                NULL, "- Could not Internalize External");
            break;
        }

        NameOp->Asl.AmlLength = strlen (NameOp->Asl.Value.String);

        /* Get argument count */

        Child = Op->Asl.Child;
        while (Child)
        {
            ArgCount++;
            Child = Child->Asl.Next;
        }

        /* Setup ArgCount operand */

        ArgCountOp = Next->Asl.Child->Asl.Child->Asl.Next->Asl.Next;
        ArgCountOp->Asl.Value.Integer = ArgCount;
        break;
    }

    ACPI_FREE (CallName);
}
Пример #8
0
void
AcpiExStopTraceMethod (
    ACPI_NAMESPACE_NODE     *MethodNode,
    ACPI_OPERAND_OBJECT     *ObjDesc,
    ACPI_WALK_STATE         *WalkState)
{
    ACPI_STATUS             Status;
    char                    *Pathname = NULL;
    BOOLEAN                 Enabled;


    ACPI_FUNCTION_NAME (ExStopTraceMethod);


    if (MethodNode)
    {
        Pathname = AcpiNsGetNormalizedPathname (MethodNode, TRUE);
    }

    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
    if (ACPI_FAILURE (Status))
    {
        goto ExitPath;
    }

    Enabled = AcpiExInterpreterTraceEnabled (NULL);

    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);

    if (Enabled)
    {
        ACPI_TRACE_POINT (ACPI_TRACE_AML_METHOD, FALSE,
            ObjDesc ? ObjDesc->Method.AmlStart : NULL, Pathname);
    }

    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
    if (ACPI_FAILURE (Status))
    {
        goto ExitPath;
    }

    /* Check whether the tracer should be stopped */

    if (AcpiGbl_TraceMethodObject == ObjDesc)
    {
        /* Disable further tracing if type is one-shot */

        if (AcpiGbl_TraceFlags & ACPI_TRACE_ONESHOT)
        {
            AcpiGbl_TraceMethodName = NULL;
        }

        AcpiDbgLevel = AcpiGbl_OriginalDbgLevel;
        AcpiDbgLayer = AcpiGbl_OriginalDbgLayer;
        AcpiGbl_TraceMethodObject = NULL;
    }

    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);

ExitPath:
    if (Pathname)
    {
        ACPI_FREE (Pathname);
    }
}
Пример #9
0
static ACPI_STATUS
AcpiDbEvaluateOnePredefinedName (
    ACPI_HANDLE             ObjHandle,
    UINT32                  NestingLevel,
    void                    *Context,
    void                    **ReturnValue)
{
    ACPI_NAMESPACE_NODE         *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
    ACPI_DB_EXECUTE_WALK        *Info = (ACPI_DB_EXECUTE_WALK *) Context;
    char                        *Pathname;
    const ACPI_PREDEFINED_INFO  *Predefined;
    ACPI_DEVICE_INFO            *ObjInfo;
    ACPI_OBJECT_LIST            ParamObjects;
    ACPI_OBJECT                 Params[ACPI_METHOD_NUM_ARGS];
    ACPI_OBJECT                 *ThisParam;
    ACPI_BUFFER                 ReturnObj;
    ACPI_STATUS                 Status;
    UINT16                      ArgTypeList;
    UINT8                       ArgCount;
    UINT8                       ArgType;
    UINT32                      i;


    /* The name must be a predefined ACPI name */

    Predefined = AcpiUtMatchPredefinedMethod (Node->Name.Ascii);
    if (!Predefined)
    {
        return (AE_OK);
    }

    if (Node->Type == ACPI_TYPE_LOCAL_SCOPE)
    {
        return (AE_OK);
    }

    Pathname = AcpiNsGetNormalizedPathname (Node, TRUE);
    if (!Pathname)
    {
        return (AE_OK);
    }

    /* Get the object info for number of method parameters */

    Status = AcpiGetObjectInfo (ObjHandle, &ObjInfo);
    if (ACPI_FAILURE (Status))
    {
        ACPI_FREE (Pathname);
        return (Status);
    }

    ParamObjects.Count = 0;
    ParamObjects.Pointer = NULL;

    if (ObjInfo->Type == ACPI_TYPE_METHOD)
    {
        /* Setup default parameters (with proper types) */

        ArgTypeList = Predefined->Info.ArgumentList;
        ArgCount = METHOD_GET_ARG_COUNT (ArgTypeList);

        /*
         * Setup the ACPI-required number of arguments, regardless of what
         * the actual method defines. If there is a difference, then the
         * method is wrong and a warning will be issued during execution.
         */
        ThisParam = Params;
        for (i = 0; i < ArgCount; i++)
        {
            ArgType = METHOD_GET_NEXT_TYPE (ArgTypeList);
            ThisParam->Type = ArgType;

            switch (ArgType)
            {
            case ACPI_TYPE_INTEGER:

                ThisParam->Integer.Value = 1;
                break;

            case ACPI_TYPE_STRING:

                ThisParam->String.Pointer =
                    "This is the default argument string";
                ThisParam->String.Length =
                    strlen (ThisParam->String.Pointer);
                break;

            case ACPI_TYPE_BUFFER:

                ThisParam->Buffer.Pointer = (UINT8 *) Params; /* just a garbage buffer */
                ThisParam->Buffer.Length = 48;
                break;

             case ACPI_TYPE_PACKAGE:

                ThisParam->Package.Elements = NULL;
                ThisParam->Package.Count = 0;
                break;

           default:

                AcpiOsPrintf ("%s: Unsupported argument type: %u\n",
                    Pathname, ArgType);
                break;
            }

            ThisParam++;
        }

        ParamObjects.Count = ArgCount;
        ParamObjects.Pointer = Params;
    }

    ACPI_FREE (ObjInfo);
    ReturnObj.Pointer = NULL;
    ReturnObj.Length = ACPI_ALLOCATE_BUFFER;

    /* Do the actual method execution */

    AcpiGbl_MethodExecuting = TRUE;

    Status = AcpiEvaluateObject (Node, NULL, &ParamObjects, &ReturnObj);

    AcpiOsPrintf ("%-32s returned %s\n",
        Pathname, AcpiFormatException (Status));
    AcpiGbl_MethodExecuting = FALSE;
    ACPI_FREE (Pathname);

    /* Ignore status from method execution */

    Status = AE_OK;

    /* Update count, check if we have executed enough methods */

    Info->Count++;
    if (Info->Count >= Info->MaxCount)
    {
        Status = AE_CTRL_TERMINATE;
    }

    return (Status);
}
Пример #10
0
char *
AcpiNsBuildPrefixedPathname (
    ACPI_GENERIC_STATE      *PrefixScope,
    const char              *InternalPath)
{
    ACPI_STATUS             Status;
    char                    *FullPath = NULL;
    char                    *ExternalPath = NULL;
    char                    *PrefixPath = NULL;
    UINT32                  PrefixPathLength = 0;


    /* If there is a prefix, get the pathname to it */

    if (PrefixScope && PrefixScope->Scope.Node)
    {
        PrefixPath = AcpiNsGetNormalizedPathname (PrefixScope->Scope.Node, TRUE);
        if (PrefixPath)
        {
            PrefixPathLength = strlen (PrefixPath);
        }
    }

    Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, InternalPath,
        NULL, &ExternalPath);
    if (ACPI_FAILURE (Status))
    {
        goto Cleanup;
    }

    /* Merge the prefix path and the path. 2 is for one dot and trailing null */

    FullPath = ACPI_ALLOCATE_ZEROED (
        PrefixPathLength + strlen (ExternalPath) + 2);
    if (!FullPath)
    {
        goto Cleanup;
    }

    /* Don't merge if the External path is already fully qualified */

    if (PrefixPath &&
        (*ExternalPath != '\\') &&
        (*ExternalPath != '^'))
    {
        strcat (FullPath, PrefixPath);
        if (PrefixPath[1])
        {
            strcat (FullPath, ".");
        }
    }

    AcpiNsNormalizePathname (ExternalPath);
    strcat (FullPath, ExternalPath);

Cleanup:
    if (PrefixPath)
    {
        ACPI_FREE (PrefixPath);
    }
    if (ExternalPath)
    {
        ACPI_FREE (ExternalPath);
    }

    return (FullPath);
}