167754Smsmith/*******************************************************************************
267754Smsmith *
377424Smsmith * Module Name: rslist - Linked list utilities
467754Smsmith *
567754Smsmith ******************************************************************************/
667754Smsmith
7217365Sjkim/*
8306536Sjkim * Copyright (C) 2000 - 2016, Intel Corp.
970243Smsmith * All rights reserved.
1067754Smsmith *
11217365Sjkim * Redistribution and use in source and binary forms, with or without
12217365Sjkim * modification, are permitted provided that the following conditions
13217365Sjkim * are met:
14217365Sjkim * 1. Redistributions of source code must retain the above copyright
15217365Sjkim *    notice, this list of conditions, and the following disclaimer,
16217365Sjkim *    without modification.
17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18217365Sjkim *    substantially similar to the "NO WARRANTY" disclaimer below
19217365Sjkim *    ("Disclaimer") and any redistribution must be conditioned upon
20217365Sjkim *    including a substantially similar Disclaimer requirement for further
21217365Sjkim *    binary redistribution.
22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names
23217365Sjkim *    of any contributors may be used to endorse or promote products derived
24217365Sjkim *    from this software without specific prior written permission.
2567754Smsmith *
26217365Sjkim * Alternatively, this software may be distributed under the terms of the
27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free
28217365Sjkim * Software Foundation.
2967754Smsmith *
30217365Sjkim * NO WARRANTY
31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41217365Sjkim * POSSIBILITY OF SUCH DAMAGES.
42217365Sjkim */
4367754Smsmith
44193341Sjkim#include <contrib/dev/acpica/include/acpi.h>
45193341Sjkim#include <contrib/dev/acpica/include/accommon.h>
46193341Sjkim#include <contrib/dev/acpica/include/acresrc.h>
4767754Smsmith
4877424Smsmith#define _COMPONENT          ACPI_RESOURCES
4991116Smsmith        ACPI_MODULE_NAME    ("rslist")
5067754Smsmith
5167754Smsmith
5267754Smsmith/*******************************************************************************
5367754Smsmith *
54151937Sjkim * FUNCTION:    AcpiRsConvertAmlToResources
55151937Sjkim *
56167802Sjkim * PARAMETERS:  ACPI_WALK_AML_CALLBACK
57167802Sjkim *              ResourcePtr             - Pointer to the buffer that will
58167802Sjkim *                                        contain the output structures
59151937Sjkim *
60151937Sjkim * RETURN:      Status
61151937Sjkim *
62167802Sjkim * DESCRIPTION: Convert an AML resource to an internal representation of the
63167802Sjkim *              resource that is aligned and easier to access.
64151937Sjkim *
65151937Sjkim ******************************************************************************/
6667754Smsmith
67151937SjkimACPI_STATUS
68151937SjkimAcpiRsConvertAmlToResources (
69167802Sjkim    UINT8                   *Aml,
70167802Sjkim    UINT32                  Length,
71167802Sjkim    UINT32                  Offset,
72167802Sjkim    UINT8                   ResourceIndex,
73245582Sjkim    void                    **Context)
74151937Sjkim{
75167802Sjkim    ACPI_RESOURCE           **ResourcePtr = ACPI_CAST_INDIRECT_PTR (
76167802Sjkim                                ACPI_RESOURCE, Context);
77167802Sjkim    ACPI_RESOURCE           *Resource;
78228110Sjkim    AML_RESOURCE            *AmlResource;
79228110Sjkim    ACPI_RSCONVERT_INFO     *ConversionTable;
80151937Sjkim    ACPI_STATUS             Status;
8167754Smsmith
8267754Smsmith
83167802Sjkim    ACPI_FUNCTION_TRACE (RsConvertAmlToResources);
8467754Smsmith
8567754Smsmith
86167802Sjkim    /*
87167802Sjkim     * Check that the input buffer and all subsequent pointers into it
88167802Sjkim     * are aligned on a native word boundary. Most important on IA64
89167802Sjkim     */
90167802Sjkim    Resource = *ResourcePtr;
91167802Sjkim    if (ACPI_IS_MISALIGNED (Resource))
92151937Sjkim    {
93167802Sjkim        ACPI_WARNING ((AE_INFO,
94167802Sjkim            "Misaligned resource pointer %p", Resource));
95167802Sjkim    }
9667754Smsmith
97228110Sjkim    /* Get the appropriate conversion info table */
9867754Smsmith
99228110Sjkim    AmlResource = ACPI_CAST_PTR (AML_RESOURCE, Aml);
100306536Sjkim
101306536Sjkim    if (AcpiUtGetResourceType (Aml) ==
102306536Sjkim        ACPI_RESOURCE_NAME_SERIAL_BUS)
103228110Sjkim    {
104306536Sjkim        if (AmlResource->CommonSerialBus.Type >
105306536Sjkim            AML_RESOURCE_MAX_SERIALBUSTYPE)
106228110Sjkim        {
107228110Sjkim            ConversionTable = NULL;
108228110Sjkim        }
109228110Sjkim        else
110228110Sjkim        {
111228110Sjkim            /* This is an I2C, SPI, or UART SerialBus descriptor */
112228110Sjkim
113306536Sjkim            ConversionTable = AcpiGbl_ConvertResourceSerialBusDispatch [
114306536Sjkim                AmlResource->CommonSerialBus.Type];
115228110Sjkim        }
116228110Sjkim    }
117228110Sjkim    else
118228110Sjkim    {
119306536Sjkim        ConversionTable = AcpiGbl_GetResourceDispatch[ResourceIndex];
120228110Sjkim    }
121228110Sjkim
122228110Sjkim    if (!ConversionTable)
123228110Sjkim    {
124228110Sjkim        ACPI_ERROR ((AE_INFO,
125228110Sjkim            "Invalid/unsupported resource descriptor: Type 0x%2.2X",
126228110Sjkim            ResourceIndex));
127241973Sjkim        return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
128228110Sjkim    }
129228110Sjkim
130228110Sjkim     /* Convert the AML byte stream resource to a local resource struct */
131228110Sjkim
132167802Sjkim    Status = AcpiRsConvertAmlToResource (
133228110Sjkim        Resource, AmlResource, ConversionTable);
134167802Sjkim    if (ACPI_FAILURE (Status))
135167802Sjkim    {
136167802Sjkim        ACPI_EXCEPTION ((AE_INFO, Status,
137204773Sjkim            "Could not convert AML resource (Type 0x%X)", *Aml));
138167802Sjkim        return_ACPI_STATUS (Status);
139167802Sjkim    }
14067754Smsmith
141167802Sjkim    ACPI_DEBUG_PRINT ((ACPI_DB_RESOURCES,
142167802Sjkim        "Type %.2X, AmlLength %.2X InternalLength %.2X\n",
143167802Sjkim        AcpiUtGetResourceType (Aml), Length,
144167802Sjkim        Resource->Length));
14567754Smsmith
146167802Sjkim    /* Point to the next structure in the output buffer */
14767754Smsmith
148228110Sjkim    *ResourcePtr = ACPI_NEXT_RESOURCE (Resource);
149167802Sjkim    return_ACPI_STATUS (AE_OK);
15067754Smsmith}
15167754Smsmith
15267754Smsmith
15367754Smsmith/*******************************************************************************
15467754Smsmith *
155151937Sjkim * FUNCTION:    AcpiRsConvertResourcesToAml
15667754Smsmith *
157151937Sjkim * PARAMETERS:  Resource            - Pointer to the resource linked list
158151937Sjkim *              AmlSizeNeeded       - Calculated size of the byte stream
159151937Sjkim *                                    needed from calling AcpiRsGetAmlLength()
160151937Sjkim *                                    The size of the OutputBuffer is
161151937Sjkim *                                    guaranteed to be >= AmlSizeNeeded
162151937Sjkim *              OutputBuffer        - Pointer to the buffer that will
163151937Sjkim *                                    contain the byte stream
16467754Smsmith *
16577424Smsmith * RETURN:      Status
16667754Smsmith *
16767754Smsmith * DESCRIPTION: Takes the resource linked list and parses it, creating a
16867754Smsmith *              byte stream of resources in the caller's output buffer
16967754Smsmith *
17067754Smsmith ******************************************************************************/
17167754Smsmith
17267754SmsmithACPI_STATUS
173151937SjkimAcpiRsConvertResourcesToAml (
174151937Sjkim    ACPI_RESOURCE           *Resource,
175151937Sjkim    ACPI_SIZE               AmlSizeNeeded,
17691116Smsmith    UINT8                   *OutputBuffer)
17767754Smsmith{
178167802Sjkim    UINT8                   *Aml = OutputBuffer;
179167802Sjkim    UINT8                   *EndAml = OutputBuffer + AmlSizeNeeded;
180228110Sjkim    ACPI_RSCONVERT_INFO     *ConversionTable;
18167754Smsmith    ACPI_STATUS             Status;
18267754Smsmith
18367754Smsmith
184167802Sjkim    ACPI_FUNCTION_TRACE (RsConvertResourcesToAml);
18567754Smsmith
18683174Smsmith
187151937Sjkim    /* Walk the resource descriptor list, convert each descriptor */
188151937Sjkim
189167802Sjkim    while (Aml < EndAml)
19067754Smsmith    {
191167802Sjkim        /* Validate the (internal) Resource Type */
192151937Sjkim
193151937Sjkim        if (Resource->Type > ACPI_RESOURCE_TYPE_MAX)
19467754Smsmith        {
195167802Sjkim            ACPI_ERROR ((AE_INFO,
196204773Sjkim                "Invalid descriptor type (0x%X) in resource list",
197151937Sjkim                Resource->Type));
198151937Sjkim            return_ACPI_STATUS (AE_BAD_DATA);
199151937Sjkim        }
20067754Smsmith
201246849Sjkim        /* Sanity check the length. It must not be zero, or we loop forever */
202246849Sjkim
203246849Sjkim        if (!Resource->Length)
204246849Sjkim        {
205246849Sjkim            ACPI_ERROR ((AE_INFO,
206246849Sjkim                "Invalid zero length descriptor in resource list\n"));
207246849Sjkim            return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH);
208246849Sjkim        }
209246849Sjkim
210151937Sjkim        /* Perform the conversion */
21167754Smsmith
212228110Sjkim        if (Resource->Type == ACPI_RESOURCE_TYPE_SERIAL_BUS)
213228110Sjkim        {
214306536Sjkim            if (Resource->Data.CommonSerialBus.Type >
215306536Sjkim                AML_RESOURCE_MAX_SERIALBUSTYPE)
216228110Sjkim            {
217228110Sjkim                ConversionTable = NULL;
218228110Sjkim            }
219228110Sjkim            else
220228110Sjkim            {
221228110Sjkim                /* This is an I2C, SPI, or UART SerialBus descriptor */
222228110Sjkim
223228110Sjkim                ConversionTable = AcpiGbl_ConvertResourceSerialBusDispatch[
224228110Sjkim                    Resource->Data.CommonSerialBus.Type];
225228110Sjkim            }
226228110Sjkim        }
227228110Sjkim        else
228228110Sjkim        {
229228110Sjkim            ConversionTable = AcpiGbl_SetResourceDispatch[Resource->Type];
230228110Sjkim        }
231228110Sjkim
232228110Sjkim        if (!ConversionTable)
233228110Sjkim        {
234228110Sjkim            ACPI_ERROR ((AE_INFO,
235228110Sjkim                "Invalid/unsupported resource descriptor: Type 0x%2.2X",
236228110Sjkim                Resource->Type));
237241973Sjkim            return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
238228110Sjkim        }
239228110Sjkim
240151937Sjkim        Status = AcpiRsConvertResourceToAml (Resource,
241306536Sjkim            ACPI_CAST_PTR (AML_RESOURCE, Aml), ConversionTable);
242151937Sjkim        if (ACPI_FAILURE (Status))
243151937Sjkim        {
244167802Sjkim            ACPI_EXCEPTION ((AE_INFO, Status,
245204773Sjkim                "Could not convert resource (type 0x%X) to AML",
246167802Sjkim                Resource->Type));
247151937Sjkim            return_ACPI_STATUS (Status);
248151937Sjkim        }
24967754Smsmith
250151937Sjkim        /* Perform final sanity check on the new AML resource descriptor */
25167754Smsmith
252306536Sjkim        Status = AcpiUtValidateResource (
253306536Sjkim            NULL, ACPI_CAST_PTR (AML_RESOURCE, Aml), NULL);
254151937Sjkim        if (ACPI_FAILURE (Status))
255151937Sjkim        {
256151937Sjkim            return_ACPI_STATUS (Status);
257151937Sjkim        }
25867754Smsmith
259151937Sjkim        /* Check for end-of-list, normal exit */
26067754Smsmith
261151937Sjkim        if (Resource->Type == ACPI_RESOURCE_TYPE_END_TAG)
262151937Sjkim        {
263151937Sjkim            /* An End Tag indicates the end of the input Resource Template */
26467754Smsmith
265151937Sjkim            return_ACPI_STATUS (AE_OK);
266151937Sjkim        }
26767754Smsmith
268151937Sjkim        /*
269151937Sjkim         * Extract the total length of the new descriptor and set the
270167802Sjkim         * Aml to point to the next (output) resource descriptor
271151937Sjkim         */
272167802Sjkim        Aml += AcpiUtGetDescriptorLength (Aml);
27367754Smsmith
274151937Sjkim        /* Point to the next input resource descriptor */
27567754Smsmith
276228110Sjkim        Resource = ACPI_NEXT_RESOURCE (Resource);
277151937Sjkim    }
27867754Smsmith
279151937Sjkim    /* Completed buffer, but did not find an EndTag resource descriptor */
28067754Smsmith
281151937Sjkim    return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG);
28267754Smsmith}
283