1/*******************************************************************************
2 *
3 * Module Name: rsmisc - Miscellaneous resource descriptors
4 *
5 ******************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2016, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 *    notice, this list of conditions, and the following disclaimer,
16 *    without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 *    substantially similar to the "NO WARRANTY" disclaimer below
19 *    ("Disclaimer") and any redistribution must be conditioned upon
20 *    including a substantially similar Disclaimer requirement for further
21 *    binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 *    of any contributors may be used to endorse or promote products derived
24 *    from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44#include <contrib/dev/acpica/include/acpi.h>
45#include <contrib/dev/acpica/include/accommon.h>
46#include <contrib/dev/acpica/include/acresrc.h>
47
48#define _COMPONENT          ACPI_RESOURCES
49        ACPI_MODULE_NAME    ("rsmisc")
50
51
52#define INIT_RESOURCE_TYPE(i)       i->ResourceOffset
53#define INIT_RESOURCE_LENGTH(i)     i->AmlOffset
54#define INIT_TABLE_LENGTH(i)        i->Value
55
56#define COMPARE_OPCODE(i)           i->ResourceOffset
57#define COMPARE_TARGET(i)           i->AmlOffset
58#define COMPARE_VALUE(i)            i->Value
59
60
61/*******************************************************************************
62 *
63 * FUNCTION:    AcpiRsConvertAmlToResource
64 *
65 * PARAMETERS:  Resource            - Pointer to the resource descriptor
66 *              Aml                 - Where the AML descriptor is returned
67 *              Info                - Pointer to appropriate conversion table
68 *
69 * RETURN:      Status
70 *
71 * DESCRIPTION: Convert an external AML resource descriptor to the corresponding
72 *              internal resource descriptor
73 *
74 ******************************************************************************/
75
76ACPI_STATUS
77AcpiRsConvertAmlToResource (
78    ACPI_RESOURCE           *Resource,
79    AML_RESOURCE            *Aml,
80    ACPI_RSCONVERT_INFO     *Info)
81{
82    ACPI_RS_LENGTH          AmlResourceLength;
83    void                    *Source;
84    void                    *Destination;
85    char                    *Target;
86    UINT8                   Count;
87    UINT8                   FlagsMode = FALSE;
88    UINT16                  ItemCount = 0;
89    UINT16                  Temp16 = 0;
90
91
92    ACPI_FUNCTION_TRACE (RsConvertAmlToResource);
93
94
95    if (!Info)
96    {
97        return_ACPI_STATUS (AE_BAD_PARAMETER);
98    }
99
100    if (((ACPI_SIZE) Resource) & 0x3)
101    {
102        /* Each internal resource struct is expected to be 32-bit aligned */
103
104        ACPI_WARNING ((AE_INFO,
105            "Misaligned resource pointer (get): %p Type 0x%2.2X Length %u",
106            Resource, Resource->Type, Resource->Length));
107    }
108
109    /* Extract the resource Length field (does not include header length) */
110
111    AmlResourceLength = AcpiUtGetResourceLength (Aml);
112
113    /*
114     * First table entry must be ACPI_RSC_INITxxx and must contain the
115     * table length (# of table entries)
116     */
117    Count = INIT_TABLE_LENGTH (Info);
118    while (Count)
119    {
120        /*
121         * Source is the external AML byte stream buffer,
122         * destination is the internal resource descriptor
123         */
124        Source = ACPI_ADD_PTR (void, Aml, Info->AmlOffset);
125        Destination = ACPI_ADD_PTR (void, Resource, Info->ResourceOffset);
126
127        switch (Info->Opcode)
128        {
129        case ACPI_RSC_INITGET:
130            /*
131             * Get the resource type and the initial (minimum) length
132             */
133            memset (Resource, 0, INIT_RESOURCE_LENGTH (Info));
134            Resource->Type = INIT_RESOURCE_TYPE (Info);
135            Resource->Length = INIT_RESOURCE_LENGTH (Info);
136            break;
137
138        case ACPI_RSC_INITSET:
139            break;
140
141        case ACPI_RSC_FLAGINIT:
142
143            FlagsMode = TRUE;
144            break;
145
146        case ACPI_RSC_1BITFLAG:
147            /*
148             * Mask and shift the flag bit
149             */
150            ACPI_SET8 (Destination,
151                ((ACPI_GET8 (Source) >> Info->Value) & 0x01));
152            break;
153
154        case ACPI_RSC_2BITFLAG:
155            /*
156             * Mask and shift the flag bits
157             */
158            ACPI_SET8 (Destination,
159                ((ACPI_GET8 (Source) >> Info->Value) & 0x03));
160            break;
161
162        case ACPI_RSC_3BITFLAG:
163            /*
164             * Mask and shift the flag bits
165             */
166            ACPI_SET8 (Destination,
167                ((ACPI_GET8 (Source) >> Info->Value) & 0x07));
168            break;
169
170        case ACPI_RSC_COUNT:
171
172            ItemCount = ACPI_GET8 (Source);
173            ACPI_SET8 (Destination, ItemCount);
174
175            Resource->Length = Resource->Length +
176                (Info->Value * (ItemCount - 1));
177            break;
178
179        case ACPI_RSC_COUNT16:
180
181            ItemCount = AmlResourceLength;
182            ACPI_SET16 (Destination, ItemCount);
183
184            Resource->Length = Resource->Length +
185                (Info->Value * (ItemCount - 1));
186            break;
187
188        case ACPI_RSC_COUNT_GPIO_PIN:
189
190            Target = ACPI_ADD_PTR (void, Aml, Info->Value);
191            ItemCount = ACPI_GET16 (Target) - ACPI_GET16 (Source);
192
193            Resource->Length = Resource->Length + ItemCount;
194            ItemCount = ItemCount / 2;
195            ACPI_SET16 (Destination, ItemCount);
196            break;
197
198        case ACPI_RSC_COUNT_GPIO_VEN:
199
200            ItemCount = ACPI_GET8 (Source);
201            ACPI_SET8 (Destination, ItemCount);
202
203            Resource->Length = Resource->Length + (Info->Value * ItemCount);
204            break;
205
206        case ACPI_RSC_COUNT_GPIO_RES:
207            /*
208             * Vendor data is optional (length/offset may both be zero)
209             * Examine vendor data length field first
210             */
211            Target = ACPI_ADD_PTR (void, Aml, (Info->Value + 2));
212            if (ACPI_GET16 (Target))
213            {
214                /* Use vendor offset to get resource source length */
215
216                Target = ACPI_ADD_PTR (void, Aml, Info->Value);
217                ItemCount = ACPI_GET16 (Target) - ACPI_GET16 (Source);
218            }
219            else
220            {
221                /* No vendor data to worry about */
222
223                ItemCount = Aml->LargeHeader.ResourceLength +
224                    sizeof (AML_RESOURCE_LARGE_HEADER) -
225                    ACPI_GET16 (Source);
226            }
227
228            Resource->Length = Resource->Length + ItemCount;
229            ACPI_SET16 (Destination, ItemCount);
230            break;
231
232        case ACPI_RSC_COUNT_SERIAL_VEN:
233
234            ItemCount = ACPI_GET16 (Source) - Info->Value;
235
236            Resource->Length = Resource->Length + ItemCount;
237            ACPI_SET16 (Destination, ItemCount);
238            break;
239
240        case ACPI_RSC_COUNT_SERIAL_RES:
241
242            ItemCount = (AmlResourceLength +
243                sizeof (AML_RESOURCE_LARGE_HEADER)) -
244                ACPI_GET16 (Source) - Info->Value;
245
246            Resource->Length = Resource->Length + ItemCount;
247            ACPI_SET16 (Destination, ItemCount);
248            break;
249
250        case ACPI_RSC_LENGTH:
251
252            Resource->Length = Resource->Length + Info->Value;
253            break;
254
255        case ACPI_RSC_MOVE8:
256        case ACPI_RSC_MOVE16:
257        case ACPI_RSC_MOVE32:
258        case ACPI_RSC_MOVE64:
259            /*
260             * Raw data move. Use the Info value field unless ItemCount has
261             * been previously initialized via a COUNT opcode
262             */
263            if (Info->Value)
264            {
265                ItemCount = Info->Value;
266            }
267            AcpiRsMoveData (Destination, Source, ItemCount, Info->Opcode);
268            break;
269
270        case ACPI_RSC_MOVE_GPIO_PIN:
271
272            /* Generate and set the PIN data pointer */
273
274            Target = (char *) ACPI_ADD_PTR (void, Resource,
275                (Resource->Length - ItemCount * 2));
276            *(UINT16 **) Destination = ACPI_CAST_PTR (UINT16, Target);
277
278            /* Copy the PIN data */
279
280            Source = ACPI_ADD_PTR (void, Aml, ACPI_GET16 (Source));
281            AcpiRsMoveData (Target, Source, ItemCount, Info->Opcode);
282            break;
283
284        case ACPI_RSC_MOVE_GPIO_RES:
285
286            /* Generate and set the ResourceSource string pointer */
287
288            Target = (char *) ACPI_ADD_PTR (void, Resource,
289                (Resource->Length - ItemCount));
290            *(UINT8 **) Destination = ACPI_CAST_PTR (UINT8, Target);
291
292            /* Copy the ResourceSource string */
293
294            Source = ACPI_ADD_PTR (void, Aml, ACPI_GET16 (Source));
295            AcpiRsMoveData (Target, Source, ItemCount, Info->Opcode);
296            break;
297
298        case ACPI_RSC_MOVE_SERIAL_VEN:
299
300            /* Generate and set the Vendor Data pointer */
301
302            Target = (char *) ACPI_ADD_PTR (void, Resource,
303                (Resource->Length - ItemCount));
304            *(UINT8 **) Destination = ACPI_CAST_PTR (UINT8, Target);
305
306            /* Copy the Vendor Data */
307
308            Source = ACPI_ADD_PTR (void, Aml, Info->Value);
309            AcpiRsMoveData (Target, Source, ItemCount, Info->Opcode);
310            break;
311
312        case ACPI_RSC_MOVE_SERIAL_RES:
313
314            /* Generate and set the ResourceSource string pointer */
315
316            Target = (char *) ACPI_ADD_PTR (void, Resource,
317                (Resource->Length - ItemCount));
318            *(UINT8 **) Destination = ACPI_CAST_PTR (UINT8, Target);
319
320            /* Copy the ResourceSource string */
321
322            Source = ACPI_ADD_PTR (
323                void, Aml, (ACPI_GET16 (Source) + Info->Value));
324            AcpiRsMoveData (Target, Source, ItemCount, Info->Opcode);
325            break;
326
327        case ACPI_RSC_SET8:
328
329            memset (Destination, Info->AmlOffset, Info->Value);
330            break;
331
332        case ACPI_RSC_DATA8:
333
334            Target = ACPI_ADD_PTR (char, Resource, Info->Value);
335            memcpy (Destination, Source,  ACPI_GET16 (Target));
336            break;
337
338        case ACPI_RSC_ADDRESS:
339            /*
340             * Common handler for address descriptor flags
341             */
342            if (!AcpiRsGetAddressCommon (Resource, Aml))
343            {
344                return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
345            }
346            break;
347
348        case ACPI_RSC_SOURCE:
349            /*
350             * Optional ResourceSource (Index and String)
351             */
352            Resource->Length +=
353                AcpiRsGetResourceSource (AmlResourceLength, Info->Value,
354                    Destination, Aml, NULL);
355            break;
356
357        case ACPI_RSC_SOURCEX:
358            /*
359             * Optional ResourceSource (Index and String). This is the more
360             * complicated case used by the Interrupt() macro
361             */
362            Target = ACPI_ADD_PTR (char, Resource,
363                Info->AmlOffset + (ItemCount * 4));
364
365            Resource->Length +=
366                AcpiRsGetResourceSource (AmlResourceLength, (ACPI_RS_LENGTH)
367                    (((ItemCount - 1) * sizeof (UINT32)) + Info->Value),
368                    Destination, Aml, Target);
369            break;
370
371        case ACPI_RSC_BITMASK:
372            /*
373             * 8-bit encoded bitmask (DMA macro)
374             */
375            ItemCount = AcpiRsDecodeBitmask (ACPI_GET8 (Source), Destination);
376            if (ItemCount)
377            {
378                Resource->Length += (ItemCount - 1);
379            }
380
381            Target = ACPI_ADD_PTR (char, Resource, Info->Value);
382            ACPI_SET8 (Target, ItemCount);
383            break;
384
385        case ACPI_RSC_BITMASK16:
386            /*
387             * 16-bit encoded bitmask (IRQ macro)
388             */
389            ACPI_MOVE_16_TO_16 (&Temp16, Source);
390
391            ItemCount = AcpiRsDecodeBitmask (Temp16, Destination);
392            if (ItemCount)
393            {
394                Resource->Length += (ItemCount - 1);
395            }
396
397            Target = ACPI_ADD_PTR (char, Resource, Info->Value);
398            ACPI_SET8 (Target, ItemCount);
399            break;
400
401        case ACPI_RSC_EXIT_NE:
402            /*
403             * Control - Exit conversion if not equal
404             */
405            switch (Info->ResourceOffset)
406            {
407            case ACPI_RSC_COMPARE_AML_LENGTH:
408
409                if (AmlResourceLength != Info->Value)
410                {
411                    goto Exit;
412                }
413                break;
414
415            case ACPI_RSC_COMPARE_VALUE:
416
417                if (ACPI_GET8 (Source) != Info->Value)
418                {
419                    goto Exit;
420                }
421                break;
422
423            default:
424
425                ACPI_ERROR ((AE_INFO, "Invalid conversion sub-opcode"));
426                return_ACPI_STATUS (AE_BAD_PARAMETER);
427            }
428            break;
429
430        default:
431
432            ACPI_ERROR ((AE_INFO, "Invalid conversion opcode"));
433            return_ACPI_STATUS (AE_BAD_PARAMETER);
434        }
435
436        Count--;
437        Info++;
438    }
439
440Exit:
441    if (!FlagsMode)
442    {
443        /* Round the resource struct length up to the next boundary (32 or 64) */
444
445        Resource->Length = (UINT32)
446            ACPI_ROUND_UP_TO_NATIVE_WORD (Resource->Length);
447    }
448    return_ACPI_STATUS (AE_OK);
449}
450
451
452/*******************************************************************************
453 *
454 * FUNCTION:    AcpiRsConvertResourceToAml
455 *
456 * PARAMETERS:  Resource            - Pointer to the resource descriptor
457 *              Aml                 - Where the AML descriptor is returned
458 *              Info                - Pointer to appropriate conversion table
459 *
460 * RETURN:      Status
461 *
462 * DESCRIPTION: Convert an internal resource descriptor to the corresponding
463 *              external AML resource descriptor.
464 *
465 ******************************************************************************/
466
467ACPI_STATUS
468AcpiRsConvertResourceToAml (
469    ACPI_RESOURCE           *Resource,
470    AML_RESOURCE            *Aml,
471    ACPI_RSCONVERT_INFO     *Info)
472{
473    void                    *Source = NULL;
474    void                    *Destination;
475    char                    *Target;
476    ACPI_RSDESC_SIZE        AmlLength = 0;
477    UINT8                   Count;
478    UINT16                  Temp16 = 0;
479    UINT16                  ItemCount = 0;
480
481
482    ACPI_FUNCTION_TRACE (RsConvertResourceToAml);
483
484
485    if (!Info)
486    {
487        return_ACPI_STATUS (AE_BAD_PARAMETER);
488    }
489
490    /*
491     * First table entry must be ACPI_RSC_INITxxx and must contain the
492     * table length (# of table entries)
493     */
494    Count = INIT_TABLE_LENGTH (Info);
495
496    while (Count)
497    {
498        /*
499         * Source is the internal resource descriptor,
500         * destination is the external AML byte stream buffer
501         */
502        Source = ACPI_ADD_PTR (void, Resource, Info->ResourceOffset);
503        Destination = ACPI_ADD_PTR (void, Aml, Info->AmlOffset);
504
505        switch (Info->Opcode)
506        {
507        case ACPI_RSC_INITSET:
508
509            memset (Aml, 0, INIT_RESOURCE_LENGTH (Info));
510            AmlLength = INIT_RESOURCE_LENGTH (Info);
511            AcpiRsSetResourceHeader (
512                INIT_RESOURCE_TYPE (Info), AmlLength, Aml);
513            break;
514
515        case ACPI_RSC_INITGET:
516            break;
517
518        case ACPI_RSC_FLAGINIT:
519            /*
520             * Clear the flag byte
521             */
522            ACPI_SET8 (Destination, 0);
523            break;
524
525        case ACPI_RSC_1BITFLAG:
526            /*
527             * Mask and shift the flag bit
528             */
529            ACPI_SET_BIT (*ACPI_CAST8 (Destination), (UINT8)
530                ((ACPI_GET8 (Source) & 0x01) << Info->Value));
531            break;
532
533        case ACPI_RSC_2BITFLAG:
534            /*
535             * Mask and shift the flag bits
536             */
537            ACPI_SET_BIT (*ACPI_CAST8 (Destination), (UINT8)
538                ((ACPI_GET8 (Source) & 0x03) << Info->Value));
539            break;
540
541        case ACPI_RSC_3BITFLAG:
542            /*
543             * Mask and shift the flag bits
544             */
545            ACPI_SET_BIT (*ACPI_CAST8 (Destination), (UINT8)
546                ((ACPI_GET8 (Source) & 0x07) << Info->Value));
547            break;
548
549        case ACPI_RSC_COUNT:
550
551            ItemCount = ACPI_GET8 (Source);
552            ACPI_SET8 (Destination, ItemCount);
553
554            AmlLength = (UINT16)
555                (AmlLength + (Info->Value * (ItemCount - 1)));
556            break;
557
558        case ACPI_RSC_COUNT16:
559
560            ItemCount = ACPI_GET16 (Source);
561            AmlLength = (UINT16) (AmlLength + ItemCount);
562            AcpiRsSetResourceLength (AmlLength, Aml);
563            break;
564
565        case ACPI_RSC_COUNT_GPIO_PIN:
566
567            ItemCount = ACPI_GET16 (Source);
568            ACPI_SET16 (Destination, AmlLength);
569
570            AmlLength = (UINT16) (AmlLength + ItemCount * 2);
571            Target = ACPI_ADD_PTR (void, Aml, Info->Value);
572            ACPI_SET16 (Target, AmlLength);
573            AcpiRsSetResourceLength (AmlLength, Aml);
574            break;
575
576        case ACPI_RSC_COUNT_GPIO_VEN:
577
578            ItemCount = ACPI_GET16 (Source);
579            ACPI_SET16 (Destination, ItemCount);
580
581            AmlLength = (UINT16) (
582                AmlLength + (Info->Value * ItemCount));
583            AcpiRsSetResourceLength (AmlLength, Aml);
584            break;
585
586        case ACPI_RSC_COUNT_GPIO_RES:
587
588            /* Set resource source string length */
589
590            ItemCount = ACPI_GET16 (Source);
591            ACPI_SET16 (Destination, AmlLength);
592
593            /* Compute offset for the Vendor Data */
594
595            AmlLength = (UINT16) (AmlLength + ItemCount);
596            Target = ACPI_ADD_PTR (void, Aml, Info->Value);
597
598            /* Set vendor offset only if there is vendor data */
599
600            if (Resource->Data.Gpio.VendorLength)
601            {
602                ACPI_SET16 (Target, AmlLength);
603            }
604
605            AcpiRsSetResourceLength (AmlLength, Aml);
606            break;
607
608        case ACPI_RSC_COUNT_SERIAL_VEN:
609
610            ItemCount = ACPI_GET16 (Source);
611            ACPI_SET16 (Destination, ItemCount + Info->Value);
612            AmlLength = (UINT16) (AmlLength + ItemCount);
613            AcpiRsSetResourceLength (AmlLength, Aml);
614            break;
615
616        case ACPI_RSC_COUNT_SERIAL_RES:
617
618            ItemCount = ACPI_GET16 (Source);
619            AmlLength = (UINT16) (AmlLength + ItemCount);
620            AcpiRsSetResourceLength (AmlLength, Aml);
621            break;
622
623        case ACPI_RSC_LENGTH:
624
625            AcpiRsSetResourceLength (Info->Value, Aml);
626            break;
627
628        case ACPI_RSC_MOVE8:
629        case ACPI_RSC_MOVE16:
630        case ACPI_RSC_MOVE32:
631        case ACPI_RSC_MOVE64:
632
633            if (Info->Value)
634            {
635                ItemCount = Info->Value;
636            }
637            AcpiRsMoveData (Destination, Source, ItemCount, Info->Opcode);
638            break;
639
640        case ACPI_RSC_MOVE_GPIO_PIN:
641
642            Destination = (char *) ACPI_ADD_PTR (void, Aml,
643                ACPI_GET16 (Destination));
644            Source = * (UINT16 **) Source;
645            AcpiRsMoveData (Destination, Source, ItemCount, Info->Opcode);
646            break;
647
648        case ACPI_RSC_MOVE_GPIO_RES:
649
650            /* Used for both ResourceSource string and VendorData */
651
652            Destination = (char *) ACPI_ADD_PTR (void, Aml,
653                ACPI_GET16 (Destination));
654            Source = * (UINT8 **) Source;
655            AcpiRsMoveData (Destination, Source, ItemCount, Info->Opcode);
656            break;
657
658        case ACPI_RSC_MOVE_SERIAL_VEN:
659
660            Destination = (char *) ACPI_ADD_PTR (void, Aml,
661                (AmlLength - ItemCount));
662            Source = * (UINT8 **) Source;
663            AcpiRsMoveData (Destination, Source, ItemCount, Info->Opcode);
664            break;
665
666        case ACPI_RSC_MOVE_SERIAL_RES:
667
668            Destination = (char *) ACPI_ADD_PTR (void, Aml,
669                (AmlLength - ItemCount));
670            Source = * (UINT8 **) Source;
671            AcpiRsMoveData (Destination, Source, ItemCount, Info->Opcode);
672            break;
673
674        case ACPI_RSC_ADDRESS:
675
676            /* Set the Resource Type, General Flags, and Type-Specific Flags */
677
678            AcpiRsSetAddressCommon (Aml, Resource);
679            break;
680
681        case ACPI_RSC_SOURCEX:
682            /*
683             * Optional ResourceSource (Index and String)
684             */
685            AmlLength = AcpiRsSetResourceSource (
686                Aml, (ACPI_RS_LENGTH) AmlLength, Source);
687            AcpiRsSetResourceLength (AmlLength, Aml);
688            break;
689
690        case ACPI_RSC_SOURCE:
691            /*
692             * Optional ResourceSource (Index and String). This is the more
693             * complicated case used by the Interrupt() macro
694             */
695            AmlLength = AcpiRsSetResourceSource (Aml, Info->Value, Source);
696            AcpiRsSetResourceLength (AmlLength, Aml);
697            break;
698
699        case ACPI_RSC_BITMASK:
700            /*
701             * 8-bit encoded bitmask (DMA macro)
702             */
703            ACPI_SET8 (Destination,
704                AcpiRsEncodeBitmask (Source,
705                    *ACPI_ADD_PTR (UINT8, Resource, Info->Value)));
706            break;
707
708        case ACPI_RSC_BITMASK16:
709            /*
710             * 16-bit encoded bitmask (IRQ macro)
711             */
712            Temp16 = AcpiRsEncodeBitmask (
713                Source, *ACPI_ADD_PTR (UINT8, Resource, Info->Value));
714            ACPI_MOVE_16_TO_16 (Destination, &Temp16);
715            break;
716
717        case ACPI_RSC_EXIT_LE:
718            /*
719             * Control - Exit conversion if less than or equal
720             */
721            if (ItemCount <= Info->Value)
722            {
723                goto Exit;
724            }
725            break;
726
727        case ACPI_RSC_EXIT_NE:
728            /*
729             * Control - Exit conversion if not equal
730             */
731            switch (COMPARE_OPCODE (Info))
732            {
733            case ACPI_RSC_COMPARE_VALUE:
734
735                if (*ACPI_ADD_PTR (UINT8, Resource,
736                    COMPARE_TARGET (Info)) != COMPARE_VALUE (Info))
737                {
738                    goto Exit;
739                }
740                break;
741
742            default:
743
744                ACPI_ERROR ((AE_INFO, "Invalid conversion sub-opcode"));
745                return_ACPI_STATUS (AE_BAD_PARAMETER);
746            }
747            break;
748
749        case ACPI_RSC_EXIT_EQ:
750            /*
751             * Control - Exit conversion if equal
752             */
753            if (*ACPI_ADD_PTR (UINT8, Resource,
754                COMPARE_TARGET (Info)) == COMPARE_VALUE (Info))
755            {
756                goto Exit;
757            }
758            break;
759
760        default:
761
762            ACPI_ERROR ((AE_INFO, "Invalid conversion opcode"));
763            return_ACPI_STATUS (AE_BAD_PARAMETER);
764        }
765
766        Count--;
767        Info++;
768    }
769
770Exit:
771    return_ACPI_STATUS (AE_OK);
772}
773
774
775#if 0
776/* Previous resource validations */
777
778    if (Aml->ExtAddress64.RevisionID !=
779        AML_RESOURCE_EXTENDED_ADDRESS_REVISION)
780    {
781        return_ACPI_STATUS (AE_SUPPORT);
782    }
783
784    if (Resource->Data.StartDpf.PerformanceRobustness >= 3)
785    {
786        return_ACPI_STATUS (AE_AML_BAD_RESOURCE_VALUE);
787    }
788
789    if (((Aml->Irq.Flags & 0x09) == 0x00) ||
790        ((Aml->Irq.Flags & 0x09) == 0x09))
791    {
792        /*
793         * Only [ActiveHigh, EdgeSensitive] or [ActiveLow, LevelSensitive]
794         * polarity/trigger interrupts are allowed (ACPI spec, section
795         * "IRQ Format"), so 0x00 and 0x09 are illegal.
796         */
797        ACPI_ERROR ((AE_INFO,
798            "Invalid interrupt polarity/trigger in resource list, 0x%X",
799            Aml->Irq.Flags));
800        return_ACPI_STATUS (AE_BAD_DATA);
801    }
802
803    Resource->Data.ExtendedIrq.InterruptCount = Temp8;
804    if (Temp8 < 1)
805    {
806        /* Must have at least one IRQ */
807
808        return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH);
809    }
810
811    if (Resource->Data.Dma.Transfer == 0x03)
812    {
813        ACPI_ERROR ((AE_INFO,
814            "Invalid DMA.Transfer preference (3)"));
815        return_ACPI_STATUS (AE_BAD_DATA);
816    }
817#endif
818