Esempio n. 1
0
void
AcpiDmResourceTemplate (
    ACPI_OP_WALK_INFO       *Info,
    ACPI_PARSE_OBJECT       *Op,
    UINT8                   *ByteData,
    UINT32                  ByteCount)
{
    ACPI_STATUS             Status;
    UINT32                  CurrentByteOffset;
    UINT8                   ResourceType;
    UINT32                  ResourceLength;
    void                    *Aml;
    UINT32                  Level;
    BOOLEAN                 DependentFns = FALSE;
    UINT8                   ResourceIndex;
    ACPI_NAMESPACE_NODE     *Node;


    if (Op->Asl.AmlOpcode != AML_FIELD_OP)
    {
        Info->MappingOp = Op;
    }

    Level = Info->Level;
    ResourceName = ACPI_DEFAULT_RESNAME;
    Node = Op->Common.Node;
    if (Node)
    {
        Node = Node->Child;
    }

    for (CurrentByteOffset = 0; CurrentByteOffset < ByteCount;)
    {
        Aml = &ByteData[CurrentByteOffset];

        /* Get the descriptor type and length */

        ResourceType = AcpiUtGetResourceType (Aml);
        ResourceLength = AcpiUtGetResourceLength (Aml);

        /* Validate the Resource Type and Resource Length */

        Status = AcpiUtValidateResource (NULL, Aml, &ResourceIndex);
        if (ACPI_FAILURE (Status))
        {
            AcpiOsPrintf ("/*** Could not validate Resource, type (%X) %s***/\n",
                ResourceType, AcpiFormatException (Status));
            return;
        }

        /* Point to next descriptor */

        CurrentByteOffset += AcpiUtGetDescriptorLength (Aml);

        /* Descriptor pre-processing */

        switch (ResourceType)
        {
        case ACPI_RESOURCE_NAME_START_DEPENDENT:

            /* Finish a previous StartDependentFns */

            if (DependentFns)
            {
                Level--;
                AcpiDmIndent (Level);
                AcpiOsPrintf ("}\n");
            }
            break;

        case ACPI_RESOURCE_NAME_END_DEPENDENT:

            Level--;
            DependentFns = FALSE;
            break;

        case ACPI_RESOURCE_NAME_END_TAG:

            /* Normal exit, the resource list is finished */

            if (DependentFns)
            {
                /*
                 * Close an open StartDependentDescriptor. This indicates a
                 * missing EndDependentDescriptor.
                 */
                Level--;
                DependentFns = FALSE;

                /* Go ahead and insert EndDependentFn() */

                AcpiDmEndDependentDescriptor (Info, Aml, ResourceLength, Level);

                AcpiDmIndent (Level);
                AcpiOsPrintf (
                    "/*** Disassembler: inserted missing EndDependentFn () ***/\n");
            }
            return;

        default:

            break;
        }

        /* Disassemble the resource structure */

        if (Node)
        {
            ResourceName = Node->Name.Integer;
            Node = Node->Peer;
        }

        AcpiGbl_DmResourceDispatch [ResourceIndex] (
            Info, Aml, ResourceLength, Level);

        /* Descriptor post-processing */

        if (ResourceType == ACPI_RESOURCE_NAME_START_DEPENDENT)
        {
            DependentFns = TRUE;
            Level++;
        }
    }
}
Esempio n. 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);
}
Esempio n. 3
0
ACPI_STATUS
AcpiRsGetListLength (
    UINT8                   *AmlBuffer,
    UINT32                  AmlBufferLength,
    ACPI_SIZE               *SizeNeeded)
{
    ACPI_STATUS             Status;
    UINT8                   *EndAml;
    UINT8                   *Buffer;
    UINT32                  BufferSize;
    UINT16                  Temp16;
    UINT16                  ResourceLength;
    UINT32                  ExtraStructBytes;
    UINT8                   ResourceIndex;
    UINT8                   MinimumAmlResourceLength;
    AML_RESOURCE            *AmlResource;


    ACPI_FUNCTION_TRACE (RsGetListLength);


    *SizeNeeded = ACPI_RS_SIZE_MIN;         /* Minimum size is one EndTag */
    EndAml = AmlBuffer + AmlBufferLength;

    /* Walk the list of AML resource descriptors */

    while (AmlBuffer < EndAml)
    {
        /* Validate the Resource Type and Resource Length */

        Status = AcpiUtValidateResource (NULL, AmlBuffer, &ResourceIndex);
        if (ACPI_FAILURE (Status))
        {
            /*
             * Exit on failure. Cannot continue because the descriptor length
             * may be bogus also.
             */
            return_ACPI_STATUS (Status);
        }

        AmlResource = (void *) AmlBuffer;

        /* Get the resource length and base (minimum) AML size */

        ResourceLength = AcpiUtGetResourceLength (AmlBuffer);
        MinimumAmlResourceLength = AcpiGbl_ResourceAmlSizes[ResourceIndex];

        /*
         * Augment the size for descriptors with optional
         * and/or variable length fields
         */
        ExtraStructBytes = 0;
        Buffer = AmlBuffer + AcpiUtGetResourceHeaderLength (AmlBuffer);

        switch (AcpiUtGetResourceType (AmlBuffer))
        {
        case ACPI_RESOURCE_NAME_IRQ:
            /*
             * IRQ Resource:
             * Get the number of bits set in the 16-bit IRQ mask
             */
            ACPI_MOVE_16_TO_16 (&Temp16, Buffer);
            ExtraStructBytes = AcpiRsCountSetBits (Temp16);
            break;


        case ACPI_RESOURCE_NAME_DMA:
            /*
             * DMA Resource:
             * Get the number of bits set in the 8-bit DMA mask
             */
            ExtraStructBytes = AcpiRsCountSetBits (*Buffer);
            break;


        case ACPI_RESOURCE_NAME_VENDOR_SMALL:
        case ACPI_RESOURCE_NAME_VENDOR_LARGE:
            /*
             * Vendor Resource:
             * Get the number of vendor data bytes
             */
            ExtraStructBytes = ResourceLength;

            /*
             * There is already one byte included in the minimum
             * descriptor size. If there are extra struct bytes,
             * subtract one from the count.
             */
            if (ExtraStructBytes)
            {
                ExtraStructBytes--;
            }
            break;


        case ACPI_RESOURCE_NAME_END_TAG:
            /*
             * End Tag: This is the normal exit
             */
            return_ACPI_STATUS (AE_OK);


        case ACPI_RESOURCE_NAME_ADDRESS32:
        case ACPI_RESOURCE_NAME_ADDRESS16:
        case ACPI_RESOURCE_NAME_ADDRESS64:
            /*
             * Address Resource:
             * Add the size of the optional ResourceSource
             */
            ExtraStructBytes = AcpiRsStreamOptionLength (
                ResourceLength, MinimumAmlResourceLength);
            break;


        case ACPI_RESOURCE_NAME_EXTENDED_IRQ:
            /*
             * Extended IRQ Resource:
             * Using the InterruptTableLength, add 4 bytes for each additional
             * interrupt. Note: at least one interrupt is required and is
             * included in the minimum descriptor size (reason for the -1)
             */
            ExtraStructBytes = (Buffer[1] - 1) * sizeof (UINT32);

            /* Add the size of the optional ResourceSource */

            ExtraStructBytes += AcpiRsStreamOptionLength (
                ResourceLength - ExtraStructBytes, MinimumAmlResourceLength);
            break;

        case ACPI_RESOURCE_NAME_GPIO:

            /* Vendor data is optional */

            if (AmlResource->Gpio.VendorLength)
            {
                ExtraStructBytes += AmlResource->Gpio.VendorOffset -
                    AmlResource->Gpio.PinTableOffset + AmlResource->Gpio.VendorLength;
            }
            else
            {
                ExtraStructBytes += AmlResource->LargeHeader.ResourceLength +
                    sizeof (AML_RESOURCE_LARGE_HEADER) -
                    AmlResource->Gpio.PinTableOffset;
            }
            break;

        case ACPI_RESOURCE_NAME_SERIAL_BUS:

            MinimumAmlResourceLength = AcpiGbl_ResourceAmlSerialBusSizes[
                AmlResource->CommonSerialBus.Type];
            ExtraStructBytes += AmlResource->CommonSerialBus.ResourceLength -
                MinimumAmlResourceLength;
            break;

        default:

            break;
        }

        /*
         * Update the required buffer size for the internal descriptor structs
         *
         * Important: Round the size up for the appropriate alignment. This
         * is a requirement on IA64.
         */
        if (AcpiUtGetResourceType (AmlBuffer) == ACPI_RESOURCE_NAME_SERIAL_BUS)
        {
            BufferSize = AcpiGbl_ResourceStructSerialBusSizes[
                AmlResource->CommonSerialBus.Type] + ExtraStructBytes;
        }
        else
        {
            BufferSize = AcpiGbl_ResourceStructSizes[ResourceIndex] +
                        ExtraStructBytes;
        }
        BufferSize = (UINT32) ACPI_ROUND_UP_TO_NATIVE_WORD (BufferSize);

        *SizeNeeded += BufferSize;

        ACPI_DEBUG_PRINT ((ACPI_DB_RESOURCES,
            "Type %.2X, AmlLength %.2X InternalLength %.2X\n",
            AcpiUtGetResourceType (AmlBuffer),
            AcpiUtGetDescriptorLength (AmlBuffer), BufferSize));

        /*
         * Point to the next resource within the AML stream using the length
         * contained in the resource descriptor header
         */
        AmlBuffer += AcpiUtGetDescriptorLength (AmlBuffer);
    }

    /* Did not find an EndTag resource descriptor */

    return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG);
}
Esempio n. 4
0
ACPI_STATUS
AcpiRsConvertResourcesToAml (
    ACPI_RESOURCE           *Resource,
    ACPI_SIZE               AmlSizeNeeded,
    UINT8                   *OutputBuffer)
{
    UINT8                   *Aml = OutputBuffer;
    UINT8                   *EndAml = OutputBuffer + AmlSizeNeeded;
    ACPI_RSCONVERT_INFO     *ConversionTable;
    ACPI_STATUS             Status;


    ACPI_FUNCTION_TRACE (RsConvertResourcesToAml);


    /* Walk the resource descriptor list, convert each descriptor */

    while (Aml < EndAml)
    {
        /* Validate the (internal) Resource Type */

        if (Resource->Type > ACPI_RESOURCE_TYPE_MAX)
        {
            ACPI_ERROR ((AE_INFO,
                "Invalid descriptor type (0x%X) in resource list",
                Resource->Type));
            return_ACPI_STATUS (AE_BAD_DATA);
        }

        /* Sanity check the length. It must not be zero, or we loop forever */

        if (!Resource->Length)
        {
            ACPI_ERROR ((AE_INFO,
                "Invalid zero length descriptor in resource list\n"));
            return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH);
        }

        /* Perform the conversion */

        if (Resource->Type == ACPI_RESOURCE_TYPE_SERIAL_BUS)
        {
            if (Resource->Data.CommonSerialBus.Type > AML_RESOURCE_MAX_SERIALBUSTYPE)
            {
                ConversionTable = NULL;
            }
            else
            {
                /* This is an I2C, SPI, or UART SerialBus descriptor */

                ConversionTable = AcpiGbl_ConvertResourceSerialBusDispatch[
                    Resource->Data.CommonSerialBus.Type];
            }
        }
        else
        {
            ConversionTable = AcpiGbl_SetResourceDispatch[Resource->Type];
        }

        if (!ConversionTable)
        {
            ACPI_ERROR ((AE_INFO,
                "Invalid/unsupported resource descriptor: Type 0x%2.2X",
                Resource->Type));
            return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
        }

        Status = AcpiRsConvertResourceToAml (Resource,
                ACPI_CAST_PTR (AML_RESOURCE, Aml),
                ConversionTable);
        if (ACPI_FAILURE (Status))
        {
            ACPI_EXCEPTION ((AE_INFO, Status,
                "Could not convert resource (type 0x%X) to AML",
                Resource->Type));
            return_ACPI_STATUS (Status);
        }

        /* Perform final sanity check on the new AML resource descriptor */

        Status = AcpiUtValidateResource (NULL,
                    ACPI_CAST_PTR (AML_RESOURCE, Aml), NULL);
        if (ACPI_FAILURE (Status))
        {
            return_ACPI_STATUS (Status);
        }

        /* Check for end-of-list, normal exit */

        if (Resource->Type == ACPI_RESOURCE_TYPE_END_TAG)
        {
            /* An End Tag indicates the end of the input Resource Template */

            return_ACPI_STATUS (AE_OK);
        }

        /*
         * Extract the total length of the new descriptor and set the
         * Aml to point to the next (output) resource descriptor
         */
        Aml += AcpiUtGetDescriptorLength (Aml);

        /* Point to the next input resource descriptor */

        Resource = ACPI_NEXT_RESOURCE (Resource);
    }

    /* Completed buffer, but did not find an EndTag resource descriptor */

    return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG);
}
Esempio n. 5
0
ACPI_STATUS
AcpiRsConvertResourcesToAml (
    ACPI_RESOURCE           *Resource,
    ACPI_SIZE               AmlSizeNeeded,
    UINT8                   *OutputBuffer)
{
    UINT8                   *Aml = OutputBuffer;
    UINT8                   *EndAml = OutputBuffer + AmlSizeNeeded;
    ACPI_STATUS             Status;


    ACPI_FUNCTION_TRACE (RsConvertResourcesToAml);


    /* Walk the resource descriptor list, convert each descriptor */

    while (Aml < EndAml)
    {
        /* Validate the (internal) Resource Type */

        if (Resource->Type > ACPI_RESOURCE_TYPE_MAX)
        {
            ACPI_ERROR ((AE_INFO,
                "Invalid descriptor type (0x%X) in resource list",
                Resource->Type));
            return_ACPI_STATUS (AE_BAD_DATA);
        }

        /* Perform the conversion */

        Status = AcpiRsConvertResourceToAml (Resource,
                    ACPI_CAST_PTR (AML_RESOURCE, Aml),
                    AcpiGbl_SetResourceDispatch[Resource->Type]);
        if (ACPI_FAILURE (Status))
        {
            ACPI_EXCEPTION ((AE_INFO, Status,
                "Could not convert resource (type 0x%X) to AML",
                Resource->Type));
            return_ACPI_STATUS (Status);
        }

        /* Perform final sanity check on the new AML resource descriptor */

        Status = AcpiUtValidateResource (
                    ACPI_CAST_PTR (AML_RESOURCE, Aml), NULL);
        if (ACPI_FAILURE (Status))
        {
            return_ACPI_STATUS (Status);
        }

        /* Check for end-of-list, normal exit */

        if (Resource->Type == ACPI_RESOURCE_TYPE_END_TAG)
        {
            /* An End Tag indicates the end of the input Resource Template */

            return_ACPI_STATUS (AE_OK);
        }

        /*
         * Extract the total length of the new descriptor and set the
         * Aml to point to the next (output) resource descriptor
         */
        Aml += AcpiUtGetDescriptorLength (Aml);

        /* Point to the next input resource descriptor */

        Resource = ACPI_ADD_PTR (ACPI_RESOURCE, Resource, Resource->Length);
    }

    /* Completed buffer, but did not find an EndTag resource descriptor */

    return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG);
}
Esempio n. 6
0
ACPI_STATUS
AcpiRsGetListLength (
    UINT8                   *AmlBuffer,
    UINT32                  AmlBufferLength,
    ACPI_SIZE               *SizeNeeded)
{
    ACPI_STATUS             Status;
    UINT8                   *EndAml;
    UINT8                   *Buffer;
    UINT32                  BufferSize;
    UINT16                  Temp16;
    UINT16                  ResourceLength;
    UINT32                  ExtraStructBytes;
    UINT8                   ResourceIndex;
    UINT8                   MinimumAmlResourceLength;


    ACPI_FUNCTION_TRACE (RsGetListLength);


    *SizeNeeded = 0;
    EndAml = AmlBuffer + AmlBufferLength;

    /* Walk the list of AML resource descriptors */

    while (AmlBuffer < EndAml)
    {
        /* Validate the Resource Type and Resource Length */

        Status = AcpiUtValidateResource (AmlBuffer, &ResourceIndex);
        if (ACPI_FAILURE (Status))
        {
            return_ACPI_STATUS (Status);
        }

        /* Get the resource length and base (minimum) AML size */

        ResourceLength = AcpiUtGetResourceLength (AmlBuffer);
        MinimumAmlResourceLength = AcpiGbl_ResourceAmlSizes[ResourceIndex];

        /*
         * Augment the size for descriptors with optional
         * and/or variable length fields
         */
        ExtraStructBytes = 0;
        Buffer = AmlBuffer + AcpiUtGetResourceHeaderLength (AmlBuffer);

        switch (AcpiUtGetResourceType (AmlBuffer))
        {
        case ACPI_RESOURCE_NAME_IRQ:
            /*
             * IRQ Resource:
             * Get the number of bits set in the 16-bit IRQ mask
             */
            ACPI_MOVE_16_TO_16 (&Temp16, Buffer);
            ExtraStructBytes = AcpiRsCountSetBits (Temp16);
            break;


        case ACPI_RESOURCE_NAME_DMA:
            /*
             * DMA Resource:
             * Get the number of bits set in the 8-bit DMA mask
             */
            ExtraStructBytes = AcpiRsCountSetBits (*Buffer);
            break;


        case ACPI_RESOURCE_NAME_VENDOR_SMALL:
        case ACPI_RESOURCE_NAME_VENDOR_LARGE:
            /*
             * Vendor Resource:
             * Get the number of vendor data bytes
             */
            ExtraStructBytes = ResourceLength;
            break;


        case ACPI_RESOURCE_NAME_END_TAG:
            /*
             * End Tag:
             * This is the normal exit, add size of EndTag
             */
            *SizeNeeded += ACPI_RS_SIZE_MIN;
            return_ACPI_STATUS (AE_OK);


        case ACPI_RESOURCE_NAME_ADDRESS32:
        case ACPI_RESOURCE_NAME_ADDRESS16:
        case ACPI_RESOURCE_NAME_ADDRESS64:
            /*
             * Address Resource:
             * Add the size of the optional ResourceSource
             */
            ExtraStructBytes = AcpiRsStreamOptionLength (
                ResourceLength, MinimumAmlResourceLength);
            break;


        case ACPI_RESOURCE_NAME_EXTENDED_IRQ:
            /*
             * Extended IRQ Resource:
             * Using the InterruptTableLength, add 4 bytes for each additional
             * interrupt. Note: at least one interrupt is required and is
             * included in the minimum descriptor size (reason for the -1)
             */
            ExtraStructBytes = (Buffer[1] - 1) * sizeof (UINT32);

            /* Add the size of the optional ResourceSource */

            ExtraStructBytes += AcpiRsStreamOptionLength (
                ResourceLength - ExtraStructBytes, MinimumAmlResourceLength);
            break;


        default:
            break;
        }

        /*
         * Update the required buffer size for the internal descriptor structs
         *
         * Important: Round the size up for the appropriate alignment. This
         * is a requirement on IA64.
         */
        BufferSize = AcpiGbl_ResourceStructSizes[ResourceIndex] +
                        ExtraStructBytes;
        BufferSize = (UINT32) ACPI_ROUND_UP_TO_NATIVE_WORD (BufferSize);

        *SizeNeeded += BufferSize;

        ACPI_DEBUG_PRINT ((ACPI_DB_RESOURCES,
            "Type %.2X, AmlLength %.2X InternalLength %.2X\n",
            AcpiUtGetResourceType (AmlBuffer),
            AcpiUtGetDescriptorLength (AmlBuffer), BufferSize));

        /*
         * Point to the next resource within the AML stream using the length
         * contained in the resource descriptor header
         */
        AmlBuffer += AcpiUtGetDescriptorLength (AmlBuffer);
    }

    /* Did not find an EndTag resource descriptor */

    return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG);
}