Import acpica-unix-20061109 from Intel.
[dragonfly.git] / sys / contrib / dev / acpica-unix-20061109 / resources / rsmisc.c
1 /*******************************************************************************
2  *
3  * Module Name: rsmisc - Miscellaneous resource descriptors
4  *              $Revision: 1.45 $
5  *
6  ******************************************************************************/
7
8 /******************************************************************************
9  *
10  * 1. Copyright Notice
11  *
12  * Some or all of this work - Copyright (c) 1999 - 2006, Intel Corp.
13  * All rights reserved.
14  *
15  * 2. License
16  *
17  * 2.1. This is your license from Intel Corp. under its intellectual property
18  * rights.  You may have additional license terms from the party that provided
19  * you this software, covering your right to use that party's intellectual
20  * property rights.
21  *
22  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
23  * copy of the source code appearing in this file ("Covered Code") an
24  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
25  * base code distributed originally by Intel ("Original Intel Code") to copy,
26  * make derivatives, distribute, use and display any portion of the Covered
27  * Code in any form, with the right to sublicense such rights; and
28  *
29  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
30  * license (with the right to sublicense), under only those claims of Intel
31  * patents that are infringed by the Original Intel Code, to make, use, sell,
32  * offer to sell, and import the Covered Code and derivative works thereof
33  * solely to the minimum extent necessary to exercise the above copyright
34  * license, and in no event shall the patent license extend to any additions
35  * to or modifications of the Original Intel Code.  No other license or right
36  * is granted directly or by implication, estoppel or otherwise;
37  *
38  * The above copyright and patent license is granted only if the following
39  * conditions are met:
40  *
41  * 3. Conditions
42  *
43  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
44  * Redistribution of source code of any substantial portion of the Covered
45  * Code or modification with rights to further distribute source must include
46  * the above Copyright Notice, the above License, this list of Conditions,
47  * and the following Disclaimer and Export Compliance provision.  In addition,
48  * Licensee must cause all Covered Code to which Licensee contributes to
49  * contain a file documenting the changes Licensee made to create that Covered
50  * Code and the date of any change.  Licensee must include in that file the
51  * documentation of any changes made by any predecessor Licensee.  Licensee
52  * must include a prominent statement that the modification is derived,
53  * directly or indirectly, from Original Intel Code.
54  *
55  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
56  * Redistribution of source code of any substantial portion of the Covered
57  * Code or modification without rights to further distribute source must
58  * include the following Disclaimer and Export Compliance provision in the
59  * documentation and/or other materials provided with distribution.  In
60  * addition, Licensee may not authorize further sublicense of source of any
61  * portion of the Covered Code, and must include terms to the effect that the
62  * license from Licensee to its licensee is limited to the intellectual
63  * property embodied in the software Licensee provides to its licensee, and
64  * not to intellectual property embodied in modifications its licensee may
65  * make.
66  *
67  * 3.3. Redistribution of Executable. Redistribution in executable form of any
68  * substantial portion of the Covered Code or modification must reproduce the
69  * above Copyright Notice, and the following Disclaimer and Export Compliance
70  * provision in the documentation and/or other materials provided with the
71  * distribution.
72  *
73  * 3.4. Intel retains all right, title, and interest in and to the Original
74  * Intel Code.
75  *
76  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
77  * Intel shall be used in advertising or otherwise to promote the sale, use or
78  * other dealings in products derived from or relating to the Covered Code
79  * without prior written authorization from Intel.
80  *
81  * 4. Disclaimer and Export Compliance
82  *
83  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
84  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
85  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
86  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
87  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
88  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
89  * PARTICULAR PURPOSE.
90  *
91  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
92  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
93  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
94  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
95  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
96  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
97  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
98  * LIMITED REMEDY.
99  *
100  * 4.3. Licensee shall not export, either directly or indirectly, any of this
101  * software or system incorporating such software without first obtaining any
102  * required license or other approval from the U. S. Department of Commerce or
103  * any other agency or department of the United States Government.  In the
104  * event Licensee exports any such software from the United States or
105  * re-exports any such software from a foreign destination, Licensee shall
106  * ensure that the distribution and export/re-export of the software is in
107  * compliance with all laws, regulations, orders, or other restrictions of the
108  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
109  * any of its subsidiaries will export/re-export any technical data, process,
110  * software, or service, directly or indirectly, to any country for which the
111  * United States government or any agency thereof requires an export license,
112  * other governmental approval, or letter of assurance, without first obtaining
113  * such license, approval or letter.
114  *
115  *****************************************************************************/
116
117 #define __RSMISC_C__
118
119 #include "acpi.h"
120 #include "acresrc.h"
121
122 #define _COMPONENT          ACPI_RESOURCES
123         ACPI_MODULE_NAME    ("rsmisc")
124
125
126 #define INIT_RESOURCE_TYPE(i)       i->ResourceOffset
127 #define INIT_RESOURCE_LENGTH(i)     i->AmlOffset
128 #define INIT_TABLE_LENGTH(i)        i->Value
129
130 #define COMPARE_OPCODE(i)           i->ResourceOffset
131 #define COMPARE_TARGET(i)           i->AmlOffset
132 #define COMPARE_VALUE(i)            i->Value
133
134
135 /*******************************************************************************
136  *
137  * FUNCTION:    AcpiRsConvertAmlToResource
138  *
139  * PARAMETERS:  Resource            - Pointer to the resource descriptor
140  *              Aml                 - Where the AML descriptor is returned
141  *              Info                - Pointer to appropriate conversion table
142  *
143  * RETURN:      Status
144  *
145  * DESCRIPTION: Convert an external AML resource descriptor to the corresponding
146  *              internal resource descriptor
147  *
148  ******************************************************************************/
149
150 ACPI_STATUS
151 AcpiRsConvertAmlToResource (
152     ACPI_RESOURCE           *Resource,
153     AML_RESOURCE            *Aml,
154     ACPI_RSCONVERT_INFO     *Info)
155 {
156     ACPI_RS_LENGTH          AmlResourceLength;
157     void                    *Source;
158     void                    *Destination;
159     char                    *Target;
160     UINT8                   Count;
161     UINT8                   FlagsMode = FALSE;
162     UINT16                  ItemCount = 0;
163     UINT16                  Temp16 = 0;
164
165
166     ACPI_FUNCTION_TRACE (RsConvertAmlToResource);
167
168
169     if (((ACPI_NATIVE_UINT) Resource) & 0x3)
170     {
171         /* Each internal resource struct is expected to be 32-bit aligned */
172
173         ACPI_WARNING ((AE_INFO,
174             "Misaligned resource pointer (get): %p Type %2.2X Len %X",
175             Resource, Resource->Type, Resource->Length));
176     }
177
178     /* Extract the resource Length field (does not include header length) */
179
180     AmlResourceLength = AcpiUtGetResourceLength (Aml);
181
182     /*
183      * First table entry must be ACPI_RSC_INITxxx and must contain the
184      * table length (# of table entries)
185      */
186     Count = INIT_TABLE_LENGTH (Info);
187
188     while (Count)
189     {
190         /*
191          * Source is the external AML byte stream buffer,
192          * destination is the internal resource descriptor
193          */
194         Source      = ACPI_ADD_PTR (void, Aml, Info->AmlOffset);
195         Destination = ACPI_ADD_PTR (void, Resource, Info->ResourceOffset);
196
197         switch (Info->Opcode)
198         {
199         case ACPI_RSC_INITGET:
200             /*
201              * Get the resource type and the initial (minimum) length
202              */
203             ACPI_MEMSET (Resource, 0, INIT_RESOURCE_LENGTH (Info));
204             Resource->Type = INIT_RESOURCE_TYPE (Info);
205             Resource->Length = INIT_RESOURCE_LENGTH (Info);
206             break;
207
208
209         case ACPI_RSC_INITSET:
210             break;
211
212
213         case ACPI_RSC_FLAGINIT:
214
215             FlagsMode = TRUE;
216             break;
217
218
219         case ACPI_RSC_1BITFLAG:
220             /*
221              * Mask and shift the flag bit
222              */
223             ACPI_SET8 (Destination) = (UINT8)
224                 ((ACPI_GET8 (Source) >> Info->Value) & 0x01);
225             break;
226
227
228         case ACPI_RSC_2BITFLAG:
229             /*
230              * Mask and shift the flag bits
231              */
232             ACPI_SET8 (Destination) = (UINT8)
233                 ((ACPI_GET8 (Source) >> Info->Value) & 0x03);
234             break;
235
236
237         case ACPI_RSC_COUNT:
238
239             ItemCount = ACPI_GET8 (Source);
240             ACPI_SET8 (Destination) = (UINT8) ItemCount;
241
242             Resource->Length = Resource->Length +
243                 (Info->Value * (ItemCount - 1));
244             break;
245
246
247         case ACPI_RSC_COUNT16:
248
249             ItemCount = AmlResourceLength;
250             ACPI_SET16 (Destination) = ItemCount;
251
252             Resource->Length = Resource->Length +
253                 (Info->Value * (ItemCount - 1));
254             break;
255
256
257         case ACPI_RSC_LENGTH:
258
259             Resource->Length = Resource->Length + Info->Value;
260             break;
261
262
263         case ACPI_RSC_MOVE8:
264         case ACPI_RSC_MOVE16:
265         case ACPI_RSC_MOVE32:
266         case ACPI_RSC_MOVE64:
267             /*
268              * Raw data move. Use the Info value field unless ItemCount has
269              * been previously initialized via a COUNT opcode
270              */
271             if (Info->Value)
272             {
273                 ItemCount = Info->Value;
274             }
275             AcpiRsMoveData (Destination, Source, ItemCount, Info->Opcode);
276             break;
277
278
279         case ACPI_RSC_SET8:
280
281             ACPI_MEMSET (Destination, Info->AmlOffset, Info->Value);
282             break;
283
284
285         case ACPI_RSC_DATA8:
286
287             Target = ACPI_ADD_PTR (char, Resource, Info->Value);
288             ACPI_MEMCPY (Destination, Source,  ACPI_GET16 (Target));
289             break;
290
291
292         case ACPI_RSC_ADDRESS:
293             /*
294              * Common handler for address descriptor flags
295              */
296             if (!AcpiRsGetAddressCommon (Resource, Aml))
297             {
298                 return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
299             }
300             break;
301
302
303         case ACPI_RSC_SOURCE:
304             /*
305              * Optional ResourceSource (Index and String)
306              */
307             Resource->Length +=
308                 AcpiRsGetResourceSource (AmlResourceLength, Info->Value,
309                     Destination, Aml, NULL);
310             break;
311
312
313         case ACPI_RSC_SOURCEX:
314             /*
315              * Optional ResourceSource (Index and String). This is the more
316              * complicated case used by the Interrupt() macro
317              */
318             Target = ACPI_ADD_PTR (char, Resource, Info->AmlOffset + (ItemCount * 4));
319
320             Resource->Length +=
321                 AcpiRsGetResourceSource (AmlResourceLength,
322                     (ACPI_RS_LENGTH) (((ItemCount - 1) * sizeof (UINT32)) + Info->Value),
323                     Destination, Aml, Target);
324             break;
325
326
327         case ACPI_RSC_BITMASK:
328             /*
329              * 8-bit encoded bitmask (DMA macro)
330              */
331             ItemCount = AcpiRsDecodeBitmask (ACPI_GET8 (Source), Destination);
332             if (ItemCount)
333             {
334                 Resource->Length += (ItemCount - 1);
335             }
336
337             Target = ACPI_ADD_PTR (char, Resource, Info->Value);
338             ACPI_SET8 (Target) = (UINT8) ItemCount;
339             break;
340
341
342         case ACPI_RSC_BITMASK16:
343             /*
344              * 16-bit encoded bitmask (IRQ macro)
345              */
346             ACPI_MOVE_16_TO_16 (&Temp16, Source);
347
348             ItemCount = AcpiRsDecodeBitmask (Temp16, Destination);
349             if (ItemCount)
350             {
351                 Resource->Length += (ItemCount - 1);
352             }
353
354             Target = ACPI_ADD_PTR (char, Resource, Info->Value);
355             ACPI_SET8 (Target) = (UINT8) ItemCount;
356             break;
357
358
359         case ACPI_RSC_EXIT_NE:
360             /*
361              * Control - Exit conversion if not equal
362              */
363             switch (Info->ResourceOffset)
364             {
365             case ACPI_RSC_COMPARE_AML_LENGTH:
366                 if (AmlResourceLength != Info->Value)
367                 {
368                     goto Exit;
369                 }
370                 break;
371
372             case ACPI_RSC_COMPARE_VALUE:
373                 if (ACPI_GET8 (Source) != Info->Value)
374                 {
375                     goto Exit;
376                 }
377                 break;
378
379             default:
380
381                 ACPI_ERROR ((AE_INFO, "Invalid conversion sub-opcode"));
382                 return_ACPI_STATUS (AE_BAD_PARAMETER);
383             }
384             break;
385
386
387         default:
388
389             ACPI_ERROR ((AE_INFO, "Invalid conversion opcode"));
390             return_ACPI_STATUS (AE_BAD_PARAMETER);
391         }
392
393         Count--;
394         Info++;
395     }
396
397 Exit:
398     if (!FlagsMode)
399     {
400         /* Round the resource struct length up to the next boundary (32 or 64) */
401
402         Resource->Length = (UINT32) ACPI_ROUND_UP_TO_NATIVE_WORD (Resource->Length);
403     }
404     return_ACPI_STATUS (AE_OK);
405 }
406
407
408 /*******************************************************************************
409  *
410  * FUNCTION:    AcpiRsConvertResourceToAml
411  *
412  * PARAMETERS:  Resource            - Pointer to the resource descriptor
413  *              Aml                 - Where the AML descriptor is returned
414  *              Info                - Pointer to appropriate conversion table
415  *
416  * RETURN:      Status
417  *
418  * DESCRIPTION: Convert an internal resource descriptor to the corresponding
419  *              external AML resource descriptor.
420  *
421  ******************************************************************************/
422
423 ACPI_STATUS
424 AcpiRsConvertResourceToAml (
425     ACPI_RESOURCE           *Resource,
426     AML_RESOURCE            *Aml,
427     ACPI_RSCONVERT_INFO     *Info)
428 {
429     void                    *Source = NULL;
430     void                    *Destination;
431     ACPI_RSDESC_SIZE        AmlLength = 0;
432     UINT8                   Count;
433     UINT16                  Temp16 = 0;
434     UINT16                  ItemCount = 0;
435
436
437     ACPI_FUNCTION_TRACE (RsConvertResourceToAml);
438
439
440     /*
441      * First table entry must be ACPI_RSC_INITxxx and must contain the
442      * table length (# of table entries)
443      */
444     Count = INIT_TABLE_LENGTH (Info);
445
446     while (Count)
447     {
448         /*
449          * Source is the internal resource descriptor,
450          * destination is the external AML byte stream buffer
451          */
452         Source      = ACPI_ADD_PTR (void, Resource, Info->ResourceOffset);
453         Destination = ACPI_ADD_PTR (void, Aml, Info->AmlOffset);
454
455         switch (Info->Opcode)
456         {
457         case ACPI_RSC_INITSET:
458
459             ACPI_MEMSET (Aml, 0, INIT_RESOURCE_LENGTH (Info));
460             AmlLength = INIT_RESOURCE_LENGTH (Info);
461             AcpiRsSetResourceHeader (INIT_RESOURCE_TYPE (Info), AmlLength, Aml);
462             break;
463
464
465         case ACPI_RSC_INITGET:
466             break;
467
468
469         case ACPI_RSC_FLAGINIT:
470             /*
471              * Clear the flag byte
472              */
473             ACPI_SET8 (Destination) = 0;
474             break;
475
476
477         case ACPI_RSC_1BITFLAG:
478             /*
479              * Mask and shift the flag bit
480              */
481             ACPI_SET8 (Destination) |= (UINT8)
482                 ((ACPI_GET8 (Source) & 0x01) << Info->Value);
483             break;
484
485
486         case ACPI_RSC_2BITFLAG:
487             /*
488              * Mask and shift the flag bits
489              */
490             ACPI_SET8 (Destination) |= (UINT8)
491                 ((ACPI_GET8 (Source) & 0x03) << Info->Value);
492             break;
493
494
495         case ACPI_RSC_COUNT:
496
497             ItemCount = ACPI_GET8 (Source);
498             ACPI_SET8 (Destination) = (UINT8) ItemCount;
499
500             AmlLength = (UINT16) (AmlLength + (Info->Value * (ItemCount - 1)));
501             break;
502
503
504         case ACPI_RSC_COUNT16:
505
506             ItemCount = ACPI_GET16 (Source);
507             AmlLength = (UINT16) (AmlLength + ItemCount);
508             AcpiRsSetResourceLength (AmlLength, Aml);
509             break;
510
511
512         case ACPI_RSC_LENGTH:
513
514             AcpiRsSetResourceLength (Info->Value, Aml);
515             break;
516
517
518         case ACPI_RSC_MOVE8:
519         case ACPI_RSC_MOVE16:
520         case ACPI_RSC_MOVE32:
521         case ACPI_RSC_MOVE64:
522
523             if (Info->Value)
524             {
525                 ItemCount = Info->Value;
526             }
527             AcpiRsMoveData (Destination, Source, ItemCount, Info->Opcode);
528             break;
529
530
531         case ACPI_RSC_ADDRESS:
532
533             /* Set the Resource Type, General Flags, and Type-Specific Flags */
534
535             AcpiRsSetAddressCommon (Aml, Resource);
536             break;
537
538
539         case ACPI_RSC_SOURCEX:
540             /*
541              * Optional ResourceSource (Index and String)
542              */
543             AmlLength = AcpiRsSetResourceSource (
544                             Aml, (ACPI_RS_LENGTH) AmlLength, Source);
545             AcpiRsSetResourceLength (AmlLength, Aml);
546             break;
547
548
549         case ACPI_RSC_SOURCE:
550             /*
551              * Optional ResourceSource (Index and String). This is the more
552              * complicated case used by the Interrupt() macro
553              */
554             AmlLength = AcpiRsSetResourceSource (Aml, Info->Value, Source);
555             AcpiRsSetResourceLength (AmlLength, Aml);
556             break;
557
558
559         case ACPI_RSC_BITMASK:
560             /*
561              * 8-bit encoded bitmask (DMA macro)
562              */
563             ACPI_SET8 (Destination) = (UINT8)
564                 AcpiRsEncodeBitmask (Source,
565                     *ACPI_ADD_PTR (UINT8, Resource, Info->Value));
566             break;
567
568
569         case ACPI_RSC_BITMASK16:
570             /*
571              * 16-bit encoded bitmask (IRQ macro)
572              */
573             Temp16 = AcpiRsEncodeBitmask (Source,
574                         *ACPI_ADD_PTR (UINT8, Resource, Info->Value));
575             ACPI_MOVE_16_TO_16 (Destination, &Temp16);
576             break;
577
578
579         case ACPI_RSC_EXIT_LE:
580             /*
581              * Control - Exit conversion if less than or equal
582              */
583             if (ItemCount <= Info->Value)
584             {
585                 goto Exit;
586             }
587             break;
588
589
590         case ACPI_RSC_EXIT_NE:
591             /*
592              * Control - Exit conversion if not equal
593              */
594             switch (COMPARE_OPCODE (Info))
595             {
596             case ACPI_RSC_COMPARE_VALUE:
597
598                 if (*ACPI_ADD_PTR (UINT8, Resource,
599                         COMPARE_TARGET (Info)) != COMPARE_VALUE (Info))
600                 {
601                     goto Exit;
602                 }
603                 break;
604
605             default:
606
607                 ACPI_ERROR ((AE_INFO, "Invalid conversion sub-opcode"));
608                 return_ACPI_STATUS (AE_BAD_PARAMETER);
609             }
610             break;
611
612
613         default:
614
615             ACPI_ERROR ((AE_INFO, "Invalid conversion opcode"));
616             return_ACPI_STATUS (AE_BAD_PARAMETER);
617         }
618
619         Count--;
620         Info++;
621     }
622
623 Exit:
624     return_ACPI_STATUS (AE_OK);
625 }
626
627
628 #if 0
629 /* Previous resource validations */
630
631     if (Aml->ExtAddress64.RevisionID != AML_RESOURCE_EXTENDED_ADDRESS_REVISION)
632     {
633         return_ACPI_STATUS (AE_SUPPORT);
634     }
635
636     if (Resource->Data.StartDpf.PerformanceRobustness >= 3)
637     {
638         return_ACPI_STATUS (AE_AML_BAD_RESOURCE_VALUE);
639     }
640
641     if (((Aml->Irq.Flags & 0x09) == 0x00) ||
642         ((Aml->Irq.Flags & 0x09) == 0x09))
643     {
644         /*
645          * Only [ActiveHigh, EdgeSensitive] or [ActiveLow, LevelSensitive]
646          * polarity/trigger interrupts are allowed (ACPI spec, section
647          * "IRQ Format"), so 0x00 and 0x09 are illegal.
648          */
649         ACPI_ERROR ((AE_INFO,
650             "Invalid interrupt polarity/trigger in resource list, %X",
651             Aml->Irq.Flags));
652         return_ACPI_STATUS (AE_BAD_DATA);
653     }
654
655     Resource->Data.ExtendedIrq.InterruptCount = Temp8;
656     if (Temp8 < 1)
657     {
658         /* Must have at least one IRQ */
659
660         return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH);
661     }
662
663     if (Resource->Data.Dma.Transfer == 0x03)
664     {
665         ACPI_ERROR ((AE_INFO,
666             "Invalid DMA.Transfer preference (3)"));
667         return_ACPI_STATUS (AE_BAD_DATA);
668     }
669 #endif
670
671