167754Smsmith/*******************************************************************************
267754Smsmith *
377424Smsmith * Module Name: rsmisc - Miscellaneous resource descriptors
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    ("rsmisc")
5067754Smsmith
5167754Smsmith
52151937Sjkim#define INIT_RESOURCE_TYPE(i)       i->ResourceOffset
53151937Sjkim#define INIT_RESOURCE_LENGTH(i)     i->AmlOffset
54151937Sjkim#define INIT_TABLE_LENGTH(i)        i->Value
55151937Sjkim
56151937Sjkim#define COMPARE_OPCODE(i)           i->ResourceOffset
57151937Sjkim#define COMPARE_TARGET(i)           i->AmlOffset
58151937Sjkim#define COMPARE_VALUE(i)            i->Value
59151937Sjkim
60151937Sjkim
6167754Smsmith/*******************************************************************************
6267754Smsmith *
63151937Sjkim * FUNCTION:    AcpiRsConvertAmlToResource
6467754Smsmith *
65151937Sjkim * PARAMETERS:  Resource            - Pointer to the resource descriptor
66151937Sjkim *              Aml                 - Where the AML descriptor is returned
67151937Sjkim *              Info                - Pointer to appropriate conversion table
6867754Smsmith *
6977424Smsmith * RETURN:      Status
7067754Smsmith *
71151937Sjkim * DESCRIPTION: Convert an external AML resource descriptor to the corresponding
72151937Sjkim *              internal resource descriptor
7367754Smsmith *
7467754Smsmith ******************************************************************************/
7567754Smsmith
7667754SmsmithACPI_STATUS
77151937SjkimAcpiRsConvertAmlToResource (
78151937Sjkim    ACPI_RESOURCE           *Resource,
79151937Sjkim    AML_RESOURCE            *Aml,
80151937Sjkim    ACPI_RSCONVERT_INFO     *Info)
8167754Smsmith{
82151937Sjkim    ACPI_RS_LENGTH          AmlResourceLength;
83151937Sjkim    void                    *Source;
84151937Sjkim    void                    *Destination;
85151937Sjkim    char                    *Target;
86151937Sjkim    UINT8                   Count;
87151937Sjkim    UINT8                   FlagsMode = FALSE;
88151937Sjkim    UINT16                  ItemCount = 0;
89151937Sjkim    UINT16                  Temp16 = 0;
9067754Smsmith
9167754Smsmith
92167802Sjkim    ACPI_FUNCTION_TRACE (RsConvertAmlToResource);
9367754Smsmith
9477424Smsmith
95228110Sjkim    if (!Info)
96228110Sjkim    {
97228110Sjkim        return_ACPI_STATUS (AE_BAD_PARAMETER);
98228110Sjkim    }
99228110Sjkim
100193267Sjkim    if (((ACPI_SIZE) Resource) & 0x3)
101151937Sjkim    {
102167802Sjkim        /* Each internal resource struct is expected to be 32-bit aligned */
103167802Sjkim
104167802Sjkim        ACPI_WARNING ((AE_INFO,
105204773Sjkim            "Misaligned resource pointer (get): %p Type 0x%2.2X Length %u",
106167802Sjkim            Resource, Resource->Type, Resource->Length));
107151937Sjkim    }
10867754Smsmith
109151937Sjkim    /* Extract the resource Length field (does not include header length) */
11067754Smsmith
111151937Sjkim    AmlResourceLength = AcpiUtGetResourceLength (Aml);
11267754Smsmith
11367754Smsmith    /*
114151937Sjkim     * First table entry must be ACPI_RSC_INITxxx and must contain the
115151937Sjkim     * table length (# of table entries)
11667754Smsmith     */
117151937Sjkim    Count = INIT_TABLE_LENGTH (Info);
118151937Sjkim    while (Count)
119151937Sjkim    {
120151937Sjkim        /*
121151937Sjkim         * Source is the external AML byte stream buffer,
122151937Sjkim         * destination is the internal resource descriptor
123151937Sjkim         */
124306536Sjkim        Source = ACPI_ADD_PTR (void, Aml, Info->AmlOffset);
125167802Sjkim        Destination = ACPI_ADD_PTR (void, Resource, Info->ResourceOffset);
12667754Smsmith
127151937Sjkim        switch (Info->Opcode)
128151937Sjkim        {
129151937Sjkim        case ACPI_RSC_INITGET:
130151937Sjkim            /*
131151937Sjkim             * Get the resource type and the initial (minimum) length
132151937Sjkim             */
133306536Sjkim            memset (Resource, 0, INIT_RESOURCE_LENGTH (Info));
134151937Sjkim            Resource->Type = INIT_RESOURCE_TYPE (Info);
135151937Sjkim            Resource->Length = INIT_RESOURCE_LENGTH (Info);
136151937Sjkim            break;
13767754Smsmith
138151937Sjkim        case ACPI_RSC_INITSET:
139151937Sjkim            break;
14067754Smsmith
141151937Sjkim        case ACPI_RSC_FLAGINIT:
14277424Smsmith
143151937Sjkim            FlagsMode = TRUE;
144151937Sjkim            break;
14567754Smsmith
146151937Sjkim        case ACPI_RSC_1BITFLAG:
147151937Sjkim            /*
148151937Sjkim             * Mask and shift the flag bit
149151937Sjkim             */
150243347Sjkim            ACPI_SET8 (Destination,
151243347Sjkim                ((ACPI_GET8 (Source) >> Info->Value) & 0x01));
152151937Sjkim            break;
15367754Smsmith
154151937Sjkim        case ACPI_RSC_2BITFLAG:
155151937Sjkim            /*
156151937Sjkim             * Mask and shift the flag bits
157151937Sjkim             */
158243347Sjkim            ACPI_SET8 (Destination,
159243347Sjkim                ((ACPI_GET8 (Source) >> Info->Value) & 0x03));
160151937Sjkim            break;
16167754Smsmith
162228110Sjkim        case ACPI_RSC_3BITFLAG:
163228110Sjkim            /*
164228110Sjkim             * Mask and shift the flag bits
165228110Sjkim             */
166243347Sjkim            ACPI_SET8 (Destination,
167243347Sjkim                ((ACPI_GET8 (Source) >> Info->Value) & 0x07));
168228110Sjkim            break;
169228110Sjkim
170151937Sjkim        case ACPI_RSC_COUNT:
17167754Smsmith
172167802Sjkim            ItemCount = ACPI_GET8 (Source);
173243347Sjkim            ACPI_SET8 (Destination, ItemCount);
17467754Smsmith
175151937Sjkim            Resource->Length = Resource->Length +
176151937Sjkim                (Info->Value * (ItemCount - 1));
177151937Sjkim            break;
17867754Smsmith
179151937Sjkim        case ACPI_RSC_COUNT16:
18067754Smsmith
181151937Sjkim            ItemCount = AmlResourceLength;
182243347Sjkim            ACPI_SET16 (Destination, ItemCount);
18367754Smsmith
184151937Sjkim            Resource->Length = Resource->Length +
185151937Sjkim                (Info->Value * (ItemCount - 1));
186151937Sjkim            break;
18767754Smsmith
188228110Sjkim        case ACPI_RSC_COUNT_GPIO_PIN:
189228110Sjkim
190228110Sjkim            Target = ACPI_ADD_PTR (void, Aml, Info->Value);
191228110Sjkim            ItemCount = ACPI_GET16 (Target) - ACPI_GET16 (Source);
192228110Sjkim
193228110Sjkim            Resource->Length = Resource->Length + ItemCount;
194228110Sjkim            ItemCount = ItemCount / 2;
195243347Sjkim            ACPI_SET16 (Destination, ItemCount);
196228110Sjkim            break;
197228110Sjkim
198228110Sjkim        case ACPI_RSC_COUNT_GPIO_VEN:
199228110Sjkim
200228110Sjkim            ItemCount = ACPI_GET8 (Source);
201243347Sjkim            ACPI_SET8 (Destination, ItemCount);
202228110Sjkim
203306536Sjkim            Resource->Length = Resource->Length + (Info->Value * ItemCount);
204228110Sjkim            break;
205228110Sjkim
206228110Sjkim        case ACPI_RSC_COUNT_GPIO_RES:
207228110Sjkim            /*
208228110Sjkim             * Vendor data is optional (length/offset may both be zero)
209228110Sjkim             * Examine vendor data length field first
210228110Sjkim             */
211228110Sjkim            Target = ACPI_ADD_PTR (void, Aml, (Info->Value + 2));
212228110Sjkim            if (ACPI_GET16 (Target))
213228110Sjkim            {
214228110Sjkim                /* Use vendor offset to get resource source length */
215228110Sjkim
216228110Sjkim                Target = ACPI_ADD_PTR (void, Aml, Info->Value);
217228110Sjkim                ItemCount = ACPI_GET16 (Target) - ACPI_GET16 (Source);
218228110Sjkim            }
219228110Sjkim            else
220228110Sjkim            {
221228110Sjkim                /* No vendor data to worry about */
222228110Sjkim
223228110Sjkim                ItemCount = Aml->LargeHeader.ResourceLength +
224228110Sjkim                    sizeof (AML_RESOURCE_LARGE_HEADER) -
225228110Sjkim                    ACPI_GET16 (Source);
226228110Sjkim            }
227228110Sjkim
228228110Sjkim            Resource->Length = Resource->Length + ItemCount;
229243347Sjkim            ACPI_SET16 (Destination, ItemCount);
230228110Sjkim            break;
231228110Sjkim
232228110Sjkim        case ACPI_RSC_COUNT_SERIAL_VEN:
233228110Sjkim
234228110Sjkim            ItemCount = ACPI_GET16 (Source) - Info->Value;
235228110Sjkim
236228110Sjkim            Resource->Length = Resource->Length + ItemCount;
237243347Sjkim            ACPI_SET16 (Destination, ItemCount);
238228110Sjkim            break;
239228110Sjkim
240228110Sjkim        case ACPI_RSC_COUNT_SERIAL_RES:
241228110Sjkim
242228110Sjkim            ItemCount = (AmlResourceLength +
243228110Sjkim                sizeof (AML_RESOURCE_LARGE_HEADER)) -
244228110Sjkim                ACPI_GET16 (Source) - Info->Value;
245228110Sjkim
246228110Sjkim            Resource->Length = Resource->Length + ItemCount;
247243347Sjkim            ACPI_SET16 (Destination, ItemCount);
248228110Sjkim            break;
249228110Sjkim
250151937Sjkim        case ACPI_RSC_LENGTH:
25167754Smsmith
252151937Sjkim            Resource->Length = Resource->Length + Info->Value;
253151937Sjkim            break;
25467754Smsmith
255151937Sjkim        case ACPI_RSC_MOVE8:
256151937Sjkim        case ACPI_RSC_MOVE16:
257151937Sjkim        case ACPI_RSC_MOVE32:
258151937Sjkim        case ACPI_RSC_MOVE64:
259151937Sjkim            /*
260151937Sjkim             * Raw data move. Use the Info value field unless ItemCount has
261151937Sjkim             * been previously initialized via a COUNT opcode
262151937Sjkim             */
263151937Sjkim            if (Info->Value)
264151937Sjkim            {
265151937Sjkim                ItemCount = Info->Value;
266151937Sjkim            }
267167802Sjkim            AcpiRsMoveData (Destination, Source, ItemCount, Info->Opcode);
268151937Sjkim            break;
26967754Smsmith
270228110Sjkim        case ACPI_RSC_MOVE_GPIO_PIN:
271228110Sjkim
272228110Sjkim            /* Generate and set the PIN data pointer */
273228110Sjkim
274228110Sjkim            Target = (char *) ACPI_ADD_PTR (void, Resource,
275306536Sjkim                (Resource->Length - ItemCount * 2));
276228110Sjkim            *(UINT16 **) Destination = ACPI_CAST_PTR (UINT16, Target);
277228110Sjkim
278228110Sjkim            /* Copy the PIN data */
279228110Sjkim
280228110Sjkim            Source = ACPI_ADD_PTR (void, Aml, ACPI_GET16 (Source));
281228110Sjkim            AcpiRsMoveData (Target, Source, ItemCount, Info->Opcode);
282228110Sjkim            break;
283228110Sjkim
284228110Sjkim        case ACPI_RSC_MOVE_GPIO_RES:
285228110Sjkim
286228110Sjkim            /* Generate and set the ResourceSource string pointer */
287228110Sjkim
288228110Sjkim            Target = (char *) ACPI_ADD_PTR (void, Resource,
289306536Sjkim                (Resource->Length - ItemCount));
290228110Sjkim            *(UINT8 **) Destination = ACPI_CAST_PTR (UINT8, Target);
291228110Sjkim
292228110Sjkim            /* Copy the ResourceSource string */
293228110Sjkim
294228110Sjkim            Source = ACPI_ADD_PTR (void, Aml, ACPI_GET16 (Source));
295228110Sjkim            AcpiRsMoveData (Target, Source, ItemCount, Info->Opcode);
296228110Sjkim            break;
297228110Sjkim
298228110Sjkim        case ACPI_RSC_MOVE_SERIAL_VEN:
299228110Sjkim
300228110Sjkim            /* Generate and set the Vendor Data pointer */
301228110Sjkim
302228110Sjkim            Target = (char *) ACPI_ADD_PTR (void, Resource,
303306536Sjkim                (Resource->Length - ItemCount));
304228110Sjkim            *(UINT8 **) Destination = ACPI_CAST_PTR (UINT8, Target);
305228110Sjkim
306228110Sjkim            /* Copy the Vendor Data */
307228110Sjkim
308228110Sjkim            Source = ACPI_ADD_PTR (void, Aml, Info->Value);
309228110Sjkim            AcpiRsMoveData (Target, Source, ItemCount, Info->Opcode);
310228110Sjkim            break;
311228110Sjkim
312228110Sjkim        case ACPI_RSC_MOVE_SERIAL_RES:
313228110Sjkim
314228110Sjkim            /* Generate and set the ResourceSource string pointer */
315228110Sjkim
316228110Sjkim            Target = (char *) ACPI_ADD_PTR (void, Resource,
317306536Sjkim                (Resource->Length - ItemCount));
318228110Sjkim            *(UINT8 **) Destination = ACPI_CAST_PTR (UINT8, Target);
319228110Sjkim
320228110Sjkim            /* Copy the ResourceSource string */
321228110Sjkim
322306536Sjkim            Source = ACPI_ADD_PTR (
323306536Sjkim                void, Aml, (ACPI_GET16 (Source) + Info->Value));
324228110Sjkim            AcpiRsMoveData (Target, Source, ItemCount, Info->Opcode);
325228110Sjkim            break;
326228110Sjkim
327151937Sjkim        case ACPI_RSC_SET8:
32867754Smsmith
329306536Sjkim            memset (Destination, Info->AmlOffset, Info->Value);
330151937Sjkim            break;
33167754Smsmith
332151937Sjkim        case ACPI_RSC_DATA8:
33367754Smsmith
334167802Sjkim            Target = ACPI_ADD_PTR (char, Resource, Info->Value);
335306536Sjkim            memcpy (Destination, Source,  ACPI_GET16 (Target));
336151937Sjkim            break;
33767754Smsmith
338151937Sjkim        case ACPI_RSC_ADDRESS:
339151937Sjkim            /*
340151937Sjkim             * Common handler for address descriptor flags
341151937Sjkim             */
342151937Sjkim            if (!AcpiRsGetAddressCommon (Resource, Aml))
343151937Sjkim            {
344151937Sjkim                return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
345151937Sjkim            }
346151937Sjkim            break;
34767754Smsmith
348151937Sjkim        case ACPI_RSC_SOURCE:
349151937Sjkim            /*
350151937Sjkim             * Optional ResourceSource (Index and String)
351151937Sjkim             */
352151937Sjkim            Resource->Length +=
353151937Sjkim                AcpiRsGetResourceSource (AmlResourceLength, Info->Value,
354151937Sjkim                    Destination, Aml, NULL);
355151937Sjkim            break;
35667754Smsmith
357151937Sjkim        case ACPI_RSC_SOURCEX:
358151937Sjkim            /*
359151937Sjkim             * Optional ResourceSource (Index and String). This is the more
360151937Sjkim             * complicated case used by the Interrupt() macro
361151937Sjkim             */
362228110Sjkim            Target = ACPI_ADD_PTR (char, Resource,
363228110Sjkim                Info->AmlOffset + (ItemCount * 4));
36467754Smsmith
365151937Sjkim            Resource->Length +=
366228110Sjkim                AcpiRsGetResourceSource (AmlResourceLength, (ACPI_RS_LENGTH)
367228110Sjkim                    (((ItemCount - 1) * sizeof (UINT32)) + Info->Value),
368151937Sjkim                    Destination, Aml, Target);
369151937Sjkim            break;
37067754Smsmith
371151937Sjkim        case ACPI_RSC_BITMASK:
372151937Sjkim            /*
373151937Sjkim             * 8-bit encoded bitmask (DMA macro)
374151937Sjkim             */
375167802Sjkim            ItemCount = AcpiRsDecodeBitmask (ACPI_GET8 (Source), Destination);
376151937Sjkim            if (ItemCount)
377151937Sjkim            {
378152069Sjkim                Resource->Length += (ItemCount - 1);
379151937Sjkim            }
38077424Smsmith
381167802Sjkim            Target = ACPI_ADD_PTR (char, Resource, Info->Value);
382243347Sjkim            ACPI_SET8 (Target, ItemCount);
383151937Sjkim            break;
38467754Smsmith
385151937Sjkim        case ACPI_RSC_BITMASK16:
386151937Sjkim            /*
387151937Sjkim             * 16-bit encoded bitmask (IRQ macro)
388151937Sjkim             */
389151937Sjkim            ACPI_MOVE_16_TO_16 (&Temp16, Source);
39067754Smsmith
391151937Sjkim            ItemCount = AcpiRsDecodeBitmask (Temp16, Destination);
392151937Sjkim            if (ItemCount)
393151937Sjkim            {
394152069Sjkim                Resource->Length += (ItemCount - 1);
395151937Sjkim            }
396151937Sjkim
397167802Sjkim            Target = ACPI_ADD_PTR (char, Resource, Info->Value);
398243347Sjkim            ACPI_SET8 (Target, ItemCount);
399151937Sjkim            break;
400151937Sjkim
401151937Sjkim        case ACPI_RSC_EXIT_NE:
402151937Sjkim            /*
403151937Sjkim             * Control - Exit conversion if not equal
404151937Sjkim             */
405151937Sjkim            switch (Info->ResourceOffset)
406151937Sjkim            {
407151937Sjkim            case ACPI_RSC_COMPARE_AML_LENGTH:
408250838Sjkim
409151937Sjkim                if (AmlResourceLength != Info->Value)
410151937Sjkim                {
411151937Sjkim                    goto Exit;
412151937Sjkim                }
413151937Sjkim                break;
414151937Sjkim
415151937Sjkim            case ACPI_RSC_COMPARE_VALUE:
416250838Sjkim
417167802Sjkim                if (ACPI_GET8 (Source) != Info->Value)
418151937Sjkim                {
419151937Sjkim                    goto Exit;
420151937Sjkim                }
421151937Sjkim                break;
422151937Sjkim
423151937Sjkim            default:
424167802Sjkim
425167802Sjkim                ACPI_ERROR ((AE_INFO, "Invalid conversion sub-opcode"));
426151937Sjkim                return_ACPI_STATUS (AE_BAD_PARAMETER);
427151937Sjkim            }
428151937Sjkim            break;
429151937Sjkim
430151937Sjkim        default:
431151937Sjkim
432167802Sjkim            ACPI_ERROR ((AE_INFO, "Invalid conversion opcode"));
433151937Sjkim            return_ACPI_STATUS (AE_BAD_PARAMETER);
434151937Sjkim        }
435151937Sjkim
436151937Sjkim        Count--;
437151937Sjkim        Info++;
43867754Smsmith    }
43967754Smsmith
440151937SjkimExit:
441151937Sjkim    if (!FlagsMode)
44267754Smsmith    {
443167802Sjkim        /* Round the resource struct length up to the next boundary (32 or 64) */
44467754Smsmith
445306536Sjkim        Resource->Length = (UINT32)
446306536Sjkim            ACPI_ROUND_UP_TO_NATIVE_WORD (Resource->Length);
44767754Smsmith    }
44867754Smsmith    return_ACPI_STATUS (AE_OK);
44967754Smsmith}
45067754Smsmith
45167754Smsmith
45267754Smsmith/*******************************************************************************
45367754Smsmith *
454151937Sjkim * FUNCTION:    AcpiRsConvertResourceToAml
45567754Smsmith *
456151937Sjkim * PARAMETERS:  Resource            - Pointer to the resource descriptor
457151937Sjkim *              Aml                 - Where the AML descriptor is returned
458151937Sjkim *              Info                - Pointer to appropriate conversion table
45967754Smsmith *
46077424Smsmith * RETURN:      Status
46167754Smsmith *
462151937Sjkim * DESCRIPTION: Convert an internal resource descriptor to the corresponding
463151937Sjkim *              external AML resource descriptor.
46467754Smsmith *
46567754Smsmith ******************************************************************************/
46667754Smsmith
46767754SmsmithACPI_STATUS
468151937SjkimAcpiRsConvertResourceToAml (
469151937Sjkim    ACPI_RESOURCE           *Resource,
470151937Sjkim    AML_RESOURCE            *Aml,
471151937Sjkim    ACPI_RSCONVERT_INFO     *Info)
47267754Smsmith{
473151937Sjkim    void                    *Source = NULL;
474151937Sjkim    void                    *Destination;
475228110Sjkim    char                    *Target;
476151937Sjkim    ACPI_RSDESC_SIZE        AmlLength = 0;
477151937Sjkim    UINT8                   Count;
478151937Sjkim    UINT16                  Temp16 = 0;
479151937Sjkim    UINT16                  ItemCount = 0;
48067754Smsmith
48167754Smsmith
482167802Sjkim    ACPI_FUNCTION_TRACE (RsConvertResourceToAml);
48367754Smsmith
48477424Smsmith
485228110Sjkim    if (!Info)
486228110Sjkim    {
487228110Sjkim        return_ACPI_STATUS (AE_BAD_PARAMETER);
488228110Sjkim    }
489228110Sjkim
49067754Smsmith    /*
491151937Sjkim     * First table entry must be ACPI_RSC_INITxxx and must contain the
492151937Sjkim     * table length (# of table entries)
49367754Smsmith     */
494151937Sjkim    Count = INIT_TABLE_LENGTH (Info);
495151937Sjkim
496151937Sjkim    while (Count)
49767754Smsmith    {
49867754Smsmith        /*
499151937Sjkim         * Source is the internal resource descriptor,
500151937Sjkim         * destination is the external AML byte stream buffer
50167754Smsmith         */
502306536Sjkim        Source = ACPI_ADD_PTR (void, Resource, Info->ResourceOffset);
503167802Sjkim        Destination = ACPI_ADD_PTR (void, Aml, Info->AmlOffset);
50467754Smsmith
505151937Sjkim        switch (Info->Opcode)
50667754Smsmith        {
507151937Sjkim        case ACPI_RSC_INITSET:
50867754Smsmith
509306536Sjkim            memset (Aml, 0, INIT_RESOURCE_LENGTH (Info));
510151937Sjkim            AmlLength = INIT_RESOURCE_LENGTH (Info);
511306536Sjkim            AcpiRsSetResourceHeader (
512306536Sjkim                INIT_RESOURCE_TYPE (Info), AmlLength, Aml);
513151937Sjkim            break;
51467754Smsmith
515151937Sjkim        case ACPI_RSC_INITGET:
516151937Sjkim            break;
51767754Smsmith
518151937Sjkim        case ACPI_RSC_FLAGINIT:
519151937Sjkim            /*
520151937Sjkim             * Clear the flag byte
521151937Sjkim             */
522243347Sjkim            ACPI_SET8 (Destination, 0);
523151937Sjkim            break;
52467754Smsmith
525151937Sjkim        case ACPI_RSC_1BITFLAG:
526151937Sjkim            /*
527151937Sjkim             * Mask and shift the flag bit
528151937Sjkim             */
529243347Sjkim            ACPI_SET_BIT (*ACPI_CAST8 (Destination), (UINT8)
530243347Sjkim                ((ACPI_GET8 (Source) & 0x01) << Info->Value));
531151937Sjkim            break;
53267754Smsmith
533151937Sjkim        case ACPI_RSC_2BITFLAG:
534151937Sjkim            /*
535151937Sjkim             * Mask and shift the flag bits
536151937Sjkim             */
537243347Sjkim            ACPI_SET_BIT (*ACPI_CAST8 (Destination), (UINT8)
538243347Sjkim                ((ACPI_GET8 (Source) & 0x03) << Info->Value));
539151937Sjkim            break;
54067754Smsmith
541228110Sjkim        case ACPI_RSC_3BITFLAG:
542228110Sjkim            /*
543228110Sjkim             * Mask and shift the flag bits
544228110Sjkim             */
545243347Sjkim            ACPI_SET_BIT (*ACPI_CAST8 (Destination), (UINT8)
546243347Sjkim                ((ACPI_GET8 (Source) & 0x07) << Info->Value));
547228110Sjkim            break;
548228110Sjkim
549151937Sjkim        case ACPI_RSC_COUNT:
55077424Smsmith
551167802Sjkim            ItemCount = ACPI_GET8 (Source);
552243347Sjkim            ACPI_SET8 (Destination, ItemCount);
55367754Smsmith
554306536Sjkim            AmlLength = (UINT16)
555306536Sjkim                (AmlLength + (Info->Value * (ItemCount - 1)));
556151937Sjkim            break;
55767754Smsmith
558151937Sjkim        case ACPI_RSC_COUNT16:
55967754Smsmith
560167802Sjkim            ItemCount = ACPI_GET16 (Source);
561151937Sjkim            AmlLength = (UINT16) (AmlLength + ItemCount);
562151937Sjkim            AcpiRsSetResourceLength (AmlLength, Aml);
563151937Sjkim            break;
56467754Smsmith
565228110Sjkim        case ACPI_RSC_COUNT_GPIO_PIN:
566228110Sjkim
567228110Sjkim            ItemCount = ACPI_GET16 (Source);
568243347Sjkim            ACPI_SET16 (Destination, AmlLength);
569228110Sjkim
570228110Sjkim            AmlLength = (UINT16) (AmlLength + ItemCount * 2);
571228110Sjkim            Target = ACPI_ADD_PTR (void, Aml, Info->Value);
572243347Sjkim            ACPI_SET16 (Target, AmlLength);
573228110Sjkim            AcpiRsSetResourceLength (AmlLength, Aml);
574228110Sjkim            break;
575228110Sjkim
576228110Sjkim        case ACPI_RSC_COUNT_GPIO_VEN:
577228110Sjkim
578228110Sjkim            ItemCount = ACPI_GET16 (Source);
579243347Sjkim            ACPI_SET16 (Destination, ItemCount);
580228110Sjkim
581306536Sjkim            AmlLength = (UINT16) (
582306536Sjkim                AmlLength + (Info->Value * ItemCount));
583228110Sjkim            AcpiRsSetResourceLength (AmlLength, Aml);
584228110Sjkim            break;
585228110Sjkim
586228110Sjkim        case ACPI_RSC_COUNT_GPIO_RES:
587228110Sjkim
588228110Sjkim            /* Set resource source string length */
589228110Sjkim
590228110Sjkim            ItemCount = ACPI_GET16 (Source);
591243347Sjkim            ACPI_SET16 (Destination, AmlLength);
592228110Sjkim
593228110Sjkim            /* Compute offset for the Vendor Data */
594228110Sjkim
595228110Sjkim            AmlLength = (UINT16) (AmlLength + ItemCount);
596228110Sjkim            Target = ACPI_ADD_PTR (void, Aml, Info->Value);
597228110Sjkim
598228110Sjkim            /* Set vendor offset only if there is vendor data */
599228110Sjkim
600228110Sjkim            if (Resource->Data.Gpio.VendorLength)
601228110Sjkim            {
602243347Sjkim                ACPI_SET16 (Target, AmlLength);
603228110Sjkim            }
604228110Sjkim
605228110Sjkim            AcpiRsSetResourceLength (AmlLength, Aml);
606228110Sjkim            break;
607228110Sjkim
608228110Sjkim        case ACPI_RSC_COUNT_SERIAL_VEN:
609228110Sjkim
610228110Sjkim            ItemCount = ACPI_GET16 (Source);
611243347Sjkim            ACPI_SET16 (Destination, ItemCount + Info->Value);
612228110Sjkim            AmlLength = (UINT16) (AmlLength + ItemCount);
613228110Sjkim            AcpiRsSetResourceLength (AmlLength, Aml);
614228110Sjkim            break;
615228110Sjkim
616228110Sjkim        case ACPI_RSC_COUNT_SERIAL_RES:
617228110Sjkim
618228110Sjkim            ItemCount = ACPI_GET16 (Source);
619228110Sjkim            AmlLength = (UINT16) (AmlLength + ItemCount);
620228110Sjkim            AcpiRsSetResourceLength (AmlLength, Aml);
621228110Sjkim            break;
622228110Sjkim
623151937Sjkim        case ACPI_RSC_LENGTH:
62467754Smsmith
625151937Sjkim            AcpiRsSetResourceLength (Info->Value, Aml);
626151937Sjkim            break;
62767754Smsmith
628151937Sjkim        case ACPI_RSC_MOVE8:
629151937Sjkim        case ACPI_RSC_MOVE16:
630151937Sjkim        case ACPI_RSC_MOVE32:
631151937Sjkim        case ACPI_RSC_MOVE64:
63277424Smsmith
633151937Sjkim            if (Info->Value)
634151937Sjkim            {
635151937Sjkim                ItemCount = Info->Value;
636151937Sjkim            }
637151937Sjkim            AcpiRsMoveData (Destination, Source, ItemCount, Info->Opcode);
638151937Sjkim            break;
63967754Smsmith
640228110Sjkim        case ACPI_RSC_MOVE_GPIO_PIN:
641228110Sjkim
642228110Sjkim            Destination = (char *) ACPI_ADD_PTR (void, Aml,
643306536Sjkim                ACPI_GET16 (Destination));
644228110Sjkim            Source = * (UINT16 **) Source;
645228110Sjkim            AcpiRsMoveData (Destination, Source, ItemCount, Info->Opcode);
646228110Sjkim            break;
647228110Sjkim
648228110Sjkim        case ACPI_RSC_MOVE_GPIO_RES:
649228110Sjkim
650228110Sjkim            /* Used for both ResourceSource string and VendorData */
651228110Sjkim
652228110Sjkim            Destination = (char *) ACPI_ADD_PTR (void, Aml,
653306536Sjkim                ACPI_GET16 (Destination));
654228110Sjkim            Source = * (UINT8 **) Source;
655228110Sjkim            AcpiRsMoveData (Destination, Source, ItemCount, Info->Opcode);
656228110Sjkim            break;
657228110Sjkim
658228110Sjkim        case ACPI_RSC_MOVE_SERIAL_VEN:
659228110Sjkim
660228110Sjkim            Destination = (char *) ACPI_ADD_PTR (void, Aml,
661306536Sjkim                (AmlLength - ItemCount));
662228110Sjkim            Source = * (UINT8 **) Source;
663228110Sjkim            AcpiRsMoveData (Destination, Source, ItemCount, Info->Opcode);
664228110Sjkim            break;
665228110Sjkim
666228110Sjkim        case ACPI_RSC_MOVE_SERIAL_RES:
667228110Sjkim
668228110Sjkim            Destination = (char *) ACPI_ADD_PTR (void, Aml,
669306536Sjkim                (AmlLength - ItemCount));
670228110Sjkim            Source = * (UINT8 **) Source;
671228110Sjkim            AcpiRsMoveData (Destination, Source, ItemCount, Info->Opcode);
672228110Sjkim            break;
673228110Sjkim
674151937Sjkim        case ACPI_RSC_ADDRESS:
67567754Smsmith
676151937Sjkim            /* Set the Resource Type, General Flags, and Type-Specific Flags */
67767754Smsmith
678151937Sjkim            AcpiRsSetAddressCommon (Aml, Resource);
679151937Sjkim            break;
68067754Smsmith
681151937Sjkim        case ACPI_RSC_SOURCEX:
682151937Sjkim            /*
683151937Sjkim             * Optional ResourceSource (Index and String)
684151937Sjkim             */
685151937Sjkim            AmlLength = AcpiRsSetResourceSource (
686306536Sjkim                Aml, (ACPI_RS_LENGTH) AmlLength, Source);
687151937Sjkim            AcpiRsSetResourceLength (AmlLength, Aml);
688151937Sjkim            break;
68967754Smsmith
690151937Sjkim        case ACPI_RSC_SOURCE:
691151937Sjkim            /*
692151937Sjkim             * Optional ResourceSource (Index and String). This is the more
693151937Sjkim             * complicated case used by the Interrupt() macro
694151937Sjkim             */
695151937Sjkim            AmlLength = AcpiRsSetResourceSource (Aml, Info->Value, Source);
696151937Sjkim            AcpiRsSetResourceLength (AmlLength, Aml);
697151937Sjkim            break;
69867754Smsmith
699151937Sjkim        case ACPI_RSC_BITMASK:
700151937Sjkim            /*
701151937Sjkim             * 8-bit encoded bitmask (DMA macro)
702151937Sjkim             */
703243347Sjkim            ACPI_SET8 (Destination,
704167802Sjkim                AcpiRsEncodeBitmask (Source,
705243347Sjkim                    *ACPI_ADD_PTR (UINT8, Resource, Info->Value)));
706151937Sjkim            break;
70767754Smsmith
708151937Sjkim        case ACPI_RSC_BITMASK16:
709151937Sjkim            /*
710151937Sjkim             * 16-bit encoded bitmask (IRQ macro)
711151937Sjkim             */
712306536Sjkim            Temp16 = AcpiRsEncodeBitmask (
713306536Sjkim                Source, *ACPI_ADD_PTR (UINT8, Resource, Info->Value));
714151937Sjkim            ACPI_MOVE_16_TO_16 (Destination, &Temp16);
715151937Sjkim            break;
716151937Sjkim
717151937Sjkim        case ACPI_RSC_EXIT_LE:
718151937Sjkim            /*
719151937Sjkim             * Control - Exit conversion if less than or equal
720151937Sjkim             */
721151937Sjkim            if (ItemCount <= Info->Value)
722151937Sjkim            {
723151937Sjkim                goto Exit;
724151937Sjkim            }
725151937Sjkim            break;
726151937Sjkim
727151937Sjkim        case ACPI_RSC_EXIT_NE:
728151937Sjkim            /*
729151937Sjkim             * Control - Exit conversion if not equal
730151937Sjkim             */
731151937Sjkim            switch (COMPARE_OPCODE (Info))
732151937Sjkim            {
733151937Sjkim            case ACPI_RSC_COMPARE_VALUE:
734167802Sjkim
735167802Sjkim                if (*ACPI_ADD_PTR (UINT8, Resource,
736306536Sjkim                    COMPARE_TARGET (Info)) != COMPARE_VALUE (Info))
737151937Sjkim                {
738151937Sjkim                    goto Exit;
739151937Sjkim                }
740151937Sjkim                break;
741151937Sjkim
742151937Sjkim            default:
743167802Sjkim
744167802Sjkim                ACPI_ERROR ((AE_INFO, "Invalid conversion sub-opcode"));
745151937Sjkim                return_ACPI_STATUS (AE_BAD_PARAMETER);
746151937Sjkim            }
747151937Sjkim            break;
748151937Sjkim
749193267Sjkim        case ACPI_RSC_EXIT_EQ:
750193267Sjkim            /*
751193267Sjkim             * Control - Exit conversion if equal
752193267Sjkim             */
753193267Sjkim            if (*ACPI_ADD_PTR (UINT8, Resource,
754306536Sjkim                COMPARE_TARGET (Info)) == COMPARE_VALUE (Info))
755193267Sjkim            {
756193267Sjkim                goto Exit;
757193267Sjkim            }
758193267Sjkim            break;
759193267Sjkim
760151937Sjkim        default:
761151937Sjkim
762167802Sjkim            ACPI_ERROR ((AE_INFO, "Invalid conversion opcode"));
763151937Sjkim            return_ACPI_STATUS (AE_BAD_PARAMETER);
764151937Sjkim        }
765151937Sjkim
766151937Sjkim        Count--;
767151937Sjkim        Info++;
768151937Sjkim    }
769151937Sjkim
770151937SjkimExit:
77167754Smsmith    return_ACPI_STATUS (AE_OK);
77267754Smsmith}
77367754Smsmith
774151937Sjkim
775151937Sjkim#if 0
776151937Sjkim/* Previous resource validations */
777151937Sjkim
778306536Sjkim    if (Aml->ExtAddress64.RevisionID !=
779306536Sjkim        AML_RESOURCE_EXTENDED_ADDRESS_REVISION)
780151937Sjkim    {
781151937Sjkim        return_ACPI_STATUS (AE_SUPPORT);
782151937Sjkim    }
783151937Sjkim
784151937Sjkim    if (Resource->Data.StartDpf.PerformanceRobustness >= 3)
785151937Sjkim    {
786151937Sjkim        return_ACPI_STATUS (AE_AML_BAD_RESOURCE_VALUE);
787151937Sjkim    }
788151937Sjkim
789151937Sjkim    if (((Aml->Irq.Flags & 0x09) == 0x00) ||
790151937Sjkim        ((Aml->Irq.Flags & 0x09) == 0x09))
791151937Sjkim    {
792151937Sjkim        /*
793151937Sjkim         * Only [ActiveHigh, EdgeSensitive] or [ActiveLow, LevelSensitive]
794151937Sjkim         * polarity/trigger interrupts are allowed (ACPI spec, section
795151937Sjkim         * "IRQ Format"), so 0x00 and 0x09 are illegal.
796151937Sjkim         */
797167802Sjkim        ACPI_ERROR ((AE_INFO,
798204773Sjkim            "Invalid interrupt polarity/trigger in resource list, 0x%X",
799151937Sjkim            Aml->Irq.Flags));
800151937Sjkim        return_ACPI_STATUS (AE_BAD_DATA);
801151937Sjkim    }
802151937Sjkim
803151937Sjkim    Resource->Data.ExtendedIrq.InterruptCount = Temp8;
804151937Sjkim    if (Temp8 < 1)
805151937Sjkim    {
806151937Sjkim        /* Must have at least one IRQ */
807151937Sjkim
808151937Sjkim        return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH);
809151937Sjkim    }
810151937Sjkim
811151937Sjkim    if (Resource->Data.Dma.Transfer == 0x03)
812151937Sjkim    {
813167802Sjkim        ACPI_ERROR ((AE_INFO,
814167802Sjkim            "Invalid DMA.Transfer preference (3)"));
815151937Sjkim        return_ACPI_STATUS (AE_BAD_DATA);
816151937Sjkim    }
817151937Sjkim#endif
818