xref: /titanic_51/usr/src/uts/intel/io/acpica/resources/rsmisc.c (revision 7ff836697c120cb94bd30d5c2204eb9b74718e4c)
1 /*******************************************************************************
2  *
3  * Module Name: rsmisc - Miscellaneous resource descriptors
4  *
5  ******************************************************************************/
6 
7 /******************************************************************************
8  *
9  * 1. Copyright Notice
10  *
11  * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp.
12  * All rights reserved.
13  *
14  * 2. License
15  *
16  * 2.1. This is your license from Intel Corp. under its intellectual property
17  * rights.  You may have additional license terms from the party that provided
18  * you this software, covering your right to use that party's intellectual
19  * property rights.
20  *
21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22  * copy of the source code appearing in this file ("Covered Code") an
23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24  * base code distributed originally by Intel ("Original Intel Code") to copy,
25  * make derivatives, distribute, use and display any portion of the Covered
26  * Code in any form, with the right to sublicense such rights; and
27  *
28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29  * license (with the right to sublicense), under only those claims of Intel
30  * patents that are infringed by the Original Intel Code, to make, use, sell,
31  * offer to sell, and import the Covered Code and derivative works thereof
32  * solely to the minimum extent necessary to exercise the above copyright
33  * license, and in no event shall the patent license extend to any additions
34  * to or modifications of the Original Intel Code.  No other license or right
35  * is granted directly or by implication, estoppel or otherwise;
36  *
37  * The above copyright and patent license is granted only if the following
38  * conditions are met:
39  *
40  * 3. Conditions
41  *
42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43  * Redistribution of source code of any substantial portion of the Covered
44  * Code or modification with rights to further distribute source must include
45  * the above Copyright Notice, the above License, this list of Conditions,
46  * and the following Disclaimer and Export Compliance provision.  In addition,
47  * Licensee must cause all Covered Code to which Licensee contributes to
48  * contain a file documenting the changes Licensee made to create that Covered
49  * Code and the date of any change.  Licensee must include in that file the
50  * documentation of any changes made by any predecessor Licensee.  Licensee
51  * must include a prominent statement that the modification is derived,
52  * directly or indirectly, from Original Intel Code.
53  *
54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55  * Redistribution of source code of any substantial portion of the Covered
56  * Code or modification without rights to further distribute source must
57  * include the following Disclaimer and Export Compliance provision in the
58  * documentation and/or other materials provided with distribution.  In
59  * addition, Licensee may not authorize further sublicense of source of any
60  * portion of the Covered Code, and must include terms to the effect that the
61  * license from Licensee to its licensee is limited to the intellectual
62  * property embodied in the software Licensee provides to its licensee, and
63  * not to intellectual property embodied in modifications its licensee may
64  * make.
65  *
66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
67  * substantial portion of the Covered Code or modification must reproduce the
68  * above Copyright Notice, and the following Disclaimer and Export Compliance
69  * provision in the documentation and/or other materials provided with the
70  * distribution.
71  *
72  * 3.4. Intel retains all right, title, and interest in and to the Original
73  * Intel Code.
74  *
75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76  * Intel shall be used in advertising or otherwise to promote the sale, use or
77  * other dealings in products derived from or relating to the Covered Code
78  * without prior written authorization from Intel.
79  *
80  * 4. Disclaimer and Export Compliance
81  *
82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
85  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
86  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88  * PARTICULAR PURPOSE.
89  *
90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97  * LIMITED REMEDY.
98  *
99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
100  * software or system incorporating such software without first obtaining any
101  * required license or other approval from the U. S. Department of Commerce or
102  * any other agency or department of the United States Government.  In the
103  * event Licensee exports any such software from the United States or
104  * re-exports any such software from a foreign destination, Licensee shall
105  * ensure that the distribution and export/re-export of the software is in
106  * compliance with all laws, regulations, orders, or other restrictions of the
107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108  * any of its subsidiaries will export/re-export any technical data, process,
109  * software, or service, directly or indirectly, to any country for which the
110  * United States government or any agency thereof requires an export license,
111  * other governmental approval, or letter of assurance, without first obtaining
112  * such license, approval or letter.
113  *
114  *****************************************************************************/
115 
116 #define __RSMISC_C__
117 
118 #include "acpi.h"
119 #include "accommon.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_SIZE) 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         case ACPI_RSC_EXIT_EQ:
614             /*
615              * Control - Exit conversion if equal
616              */
617             if (*ACPI_ADD_PTR (UINT8, Resource,
618                     COMPARE_TARGET (Info)) == COMPARE_VALUE (Info))
619             {
620                 goto Exit;
621             }
622             break;
623 
624 
625         default:
626 
627             ACPI_ERROR ((AE_INFO, "Invalid conversion opcode"));
628             return_ACPI_STATUS (AE_BAD_PARAMETER);
629         }
630 
631         Count--;
632         Info++;
633     }
634 
635 Exit:
636     return_ACPI_STATUS (AE_OK);
637 }
638 
639 
640 #if 0
641 /* Previous resource validations */
642 
643     if (Aml->ExtAddress64.RevisionID != AML_RESOURCE_EXTENDED_ADDRESS_REVISION)
644     {
645         return_ACPI_STATUS (AE_SUPPORT);
646     }
647 
648     if (Resource->Data.StartDpf.PerformanceRobustness >= 3)
649     {
650         return_ACPI_STATUS (AE_AML_BAD_RESOURCE_VALUE);
651     }
652 
653     if (((Aml->Irq.Flags & 0x09) == 0x00) ||
654         ((Aml->Irq.Flags & 0x09) == 0x09))
655     {
656         /*
657          * Only [ActiveHigh, EdgeSensitive] or [ActiveLow, LevelSensitive]
658          * polarity/trigger interrupts are allowed (ACPI spec, section
659          * "IRQ Format"), so 0x00 and 0x09 are illegal.
660          */
661         ACPI_ERROR ((AE_INFO,
662             "Invalid interrupt polarity/trigger in resource list, %X",
663             Aml->Irq.Flags));
664         return_ACPI_STATUS (AE_BAD_DATA);
665     }
666 
667     Resource->Data.ExtendedIrq.InterruptCount = Temp8;
668     if (Temp8 < 1)
669     {
670         /* Must have at least one IRQ */
671 
672         return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH);
673     }
674 
675     if (Resource->Data.Dma.Transfer == 0x03)
676     {
677         ACPI_ERROR ((AE_INFO,
678             "Invalid DMA.Transfer preference (3)"));
679         return_ACPI_STATUS (AE_BAD_DATA);
680     }
681 #endif
682 
683 
684