]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - sys/contrib/dev/acpica/compiler/aslrestype2.c
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / sys / contrib / dev / acpica / compiler / aslrestype2.c
1 /******************************************************************************
2  *
3  * Module Name: aslrestype2 - Miscellaneous Large resource descriptors
4  *
5  *****************************************************************************/
6
7 /*
8  * Copyright (C) 2000 - 2015, 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/compiler/aslcompiler.h>
45 #include "aslcompiler.y.h"
46 #include <contrib/dev/acpica/include/amlcode.h>
47
48 #define _COMPONENT          ACPI_COMPILER
49         ACPI_MODULE_NAME    ("aslrestype2")
50
51 /*
52  * This module contains miscellaneous large resource descriptors:
53  *
54  * Register
55  * Interrupt
56  * VendorLong
57  */
58
59 /*******************************************************************************
60  *
61  * FUNCTION:    RsDoGeneralRegisterDescriptor
62  *
63  * PARAMETERS:  Info                - Parse Op and resource template offset
64  *
65  * RETURN:      Completed resource node
66  *
67  * DESCRIPTION: Construct a long "Register" descriptor
68  *
69  ******************************************************************************/
70
71 ASL_RESOURCE_NODE *
72 RsDoGeneralRegisterDescriptor (
73     ASL_RESOURCE_INFO       *Info)
74 {
75     AML_RESOURCE            *Descriptor;
76     ACPI_PARSE_OBJECT       *InitializerOp;
77     ASL_RESOURCE_NODE       *Rnode;
78     UINT32                  CurrentByteOffset;
79     UINT32                  i;
80
81
82     InitializerOp = Info->DescriptorTypeOp->Asl.Child;
83     CurrentByteOffset = Info->CurrentByteOffset;
84     Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_GENERIC_REGISTER));
85
86     Descriptor = Rnode->Buffer;
87     Descriptor->GenericReg.DescriptorType = ACPI_RESOURCE_NAME_GENERIC_REGISTER;
88     Descriptor->GenericReg.ResourceLength = 12;
89
90     /* Process all child initialization nodes */
91
92     for (i = 0; InitializerOp; i++)
93     {
94         switch (i)
95         {
96         case 0: /* Address space */
97
98             Descriptor->GenericReg.AddressSpaceId = (UINT8) InitializerOp->Asl.Value.Integer;
99             RsCreateByteField (InitializerOp, ACPI_RESTAG_ADDRESSSPACE,
100                 CurrentByteOffset + ASL_RESDESC_OFFSET (GenericReg.AddressSpaceId));
101            break;
102
103         case 1: /* Register Bit Width */
104
105             Descriptor->GenericReg.BitWidth = (UINT8) InitializerOp->Asl.Value.Integer;
106             RsCreateByteField (InitializerOp, ACPI_RESTAG_REGISTERBITWIDTH,
107                 CurrentByteOffset + ASL_RESDESC_OFFSET (GenericReg.BitWidth));
108             break;
109
110         case 2: /* Register Bit Offset */
111
112             Descriptor->GenericReg.BitOffset = (UINT8) InitializerOp->Asl.Value.Integer;
113             RsCreateByteField (InitializerOp, ACPI_RESTAG_REGISTERBITOFFSET,
114                 CurrentByteOffset + ASL_RESDESC_OFFSET (GenericReg.BitOffset));
115             break;
116
117         case 3: /* Register Address */
118
119             Descriptor->GenericReg.Address = InitializerOp->Asl.Value.Integer;
120             RsCreateQwordField (InitializerOp, ACPI_RESTAG_ADDRESS,
121                 CurrentByteOffset + ASL_RESDESC_OFFSET (GenericReg.Address));
122             break;
123
124         case 4: /* Access Size (ACPI 3.0) */
125
126             Descriptor->GenericReg.AccessSize = (UINT8) InitializerOp->Asl.Value.Integer;
127             RsCreateByteField (InitializerOp, ACPI_RESTAG_ACCESSSIZE,
128                 CurrentByteOffset + ASL_RESDESC_OFFSET (GenericReg.AccessSize));
129
130             if (Descriptor->GenericReg.AccessSize > AML_FIELD_ACCESS_QWORD)
131             {
132                 AslError (ASL_ERROR, ASL_MSG_INVALID_ACCESS_SIZE,
133                     InitializerOp, NULL);
134             }
135             break;
136
137         case 5: /* ResourceTag (ACPI 3.0b) */
138
139             UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
140             break;
141
142         default:
143
144             AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL);
145             break;
146         }
147
148         InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
149     }
150     return (Rnode);
151 }
152
153
154 /*******************************************************************************
155  *
156  * FUNCTION:    RsDoInterruptDescriptor
157  *
158  * PARAMETERS:  Info                - Parse Op and resource template offset
159  *
160  * RETURN:      Completed resource node
161  *
162  * DESCRIPTION: Construct a long "Interrupt" descriptor
163  *
164  ******************************************************************************/
165
166 ASL_RESOURCE_NODE *
167 RsDoInterruptDescriptor (
168     ASL_RESOURCE_INFO       *Info)
169 {
170     AML_RESOURCE            *Descriptor;
171     AML_RESOURCE            *Rover = NULL;
172     ACPI_PARSE_OBJECT       *InitializerOp;
173     ASL_RESOURCE_NODE       *Rnode;
174     UINT16                  StringLength = 0;
175     UINT32                  OptionIndex = 0;
176     UINT32                  CurrentByteOffset;
177     UINT32                  i;
178     BOOLEAN                 HasResSourceIndex = FALSE;
179     UINT8                   ResSourceIndex = 0;
180     UINT8                   *ResSourceString = NULL;
181
182
183     InitializerOp = Info->DescriptorTypeOp->Asl.Child;
184     CurrentByteOffset = Info->CurrentByteOffset;
185     StringLength = RsGetStringDataLength (InitializerOp);
186
187     /* Count the interrupt numbers */
188
189     for (i = 0; InitializerOp; i++)
190     {
191         InitializerOp = ASL_GET_PEER_NODE (InitializerOp);
192
193         if (i <= 6)
194         {
195             if (i == 3 &&
196                 InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
197             {
198                 /*
199                  * ResourceSourceIndex was specified, always make room for
200                  * it, even if the ResourceSource was omitted.
201                  */
202                 OptionIndex++;
203             }
204
205             continue;
206         }
207
208         OptionIndex += 4;
209     }
210
211     InitializerOp = Info->DescriptorTypeOp->Asl.Child;
212     Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_EXTENDED_IRQ) +
213         1 + OptionIndex + StringLength);
214
215     Descriptor = Rnode->Buffer;
216     Descriptor->ExtendedIrq.DescriptorType  = ACPI_RESOURCE_NAME_EXTENDED_IRQ;
217
218     /*
219      * Initial descriptor length -- may be enlarged if there are
220      * optional fields present
221      */
222     Descriptor->ExtendedIrq.ResourceLength  = 2;  /* Flags and table length byte */
223     Descriptor->ExtendedIrq.InterruptCount  = 0;
224
225     Rover = ACPI_CAST_PTR (AML_RESOURCE,
226                 (&(Descriptor->ExtendedIrq.Interrupts[0])));
227
228     /* Process all child initialization nodes */
229
230     for (i = 0; InitializerOp; i++)
231     {
232         switch (i)
233         {
234         case 0: /* Resource Usage (Default: consumer (1) */
235
236             RsSetFlagBits (&Descriptor->ExtendedIrq.Flags, InitializerOp, 0, 1);
237             break;
238
239         case 1: /* Interrupt Type (or Mode - edge/level) */
240
241             RsSetFlagBits (&Descriptor->ExtendedIrq.Flags, InitializerOp, 1, 0);
242             RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTTYPE,
243                 CurrentByteOffset + ASL_RESDESC_OFFSET (ExtendedIrq.Flags), 1);
244             break;
245
246         case 2: /* Interrupt Level (or Polarity - Active high/low) */
247
248             RsSetFlagBits (&Descriptor->ExtendedIrq.Flags, InitializerOp, 2, 0);
249             RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTLEVEL,
250                 CurrentByteOffset + ASL_RESDESC_OFFSET (ExtendedIrq.Flags), 2);
251             break;
252
253         case 3: /* Share Type - Default: exclusive (0) */
254
255             RsSetFlagBits (&Descriptor->ExtendedIrq.Flags, InitializerOp, 3, 0);
256             RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE,
257                 CurrentByteOffset + ASL_RESDESC_OFFSET (ExtendedIrq.Flags), 3);
258             break;
259
260         case 4: /* ResSourceIndex [Optional Field - BYTE] */
261
262             if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
263             {
264                 HasResSourceIndex = TRUE;
265                 ResSourceIndex = (UINT8) InitializerOp->Asl.Value.Integer;
266             }
267             break;
268
269         case 5: /* ResSource [Optional Field - STRING] */
270
271             if ((InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) &&
272                 (InitializerOp->Asl.Value.String))
273             {
274                 if (StringLength)
275                 {
276                     ResSourceString = (UINT8 *) InitializerOp->Asl.Value.String;
277                 }
278
279                 /* ResourceSourceIndex must also be valid */
280
281                 if (!HasResSourceIndex)
282                 {
283                     AslError (ASL_ERROR, ASL_MSG_RESOURCE_INDEX,
284                         InitializerOp, NULL);
285                 }
286             }
287
288 #if 0
289             /*
290              * Not a valid ResourceSource, ResourceSourceIndex must also
291              * be invalid
292              */
293             else if (HasResSourceIndex)
294             {
295                 AslError (ASL_ERROR, ASL_MSG_RESOURCE_SOURCE,
296                     InitializerOp, NULL);
297             }
298 #endif
299             break;
300
301         case 6: /* ResourceTag */
302
303             UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
304             break;
305
306         default:
307             /*
308              * Interrupt Numbers come through here, repeatedly
309              */
310
311             /* Maximum 255 interrupts allowed for this descriptor */
312
313             if (Descriptor->ExtendedIrq.InterruptCount == 255)
314             {
315                 AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_LIST,
316                     InitializerOp, NULL);
317                 return (Rnode);
318             }
319
320             /* Each interrupt number must be a 32-bit value */
321
322             if (InitializerOp->Asl.Value.Integer > ACPI_UINT32_MAX)
323             {
324                 AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_NUMBER,
325                     InitializerOp, NULL);
326             }
327
328             /* Save the integer and move pointer to the next one */
329
330             Rover->DwordItem = (UINT32) InitializerOp->Asl.Value.Integer;
331             Rover = ACPI_ADD_PTR (AML_RESOURCE, &(Rover->DwordItem), 4);
332             Descriptor->ExtendedIrq.InterruptCount++;
333             Descriptor->ExtendedIrq.ResourceLength += 4;
334
335             /* Case 7: First interrupt number in list */
336
337             if (i == 7)
338             {
339                 if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
340                 {
341                     /* Must be at least one interrupt */
342
343                     AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_LIST_MIN,
344                         InitializerOp, NULL);
345                 }
346
347                 /* Check now for duplicates in list */
348
349                 RsCheckListForDuplicates (InitializerOp);
350
351                 /* Create a named field at the start of the list */
352
353                 RsCreateDwordField (InitializerOp, ACPI_RESTAG_INTERRUPT,
354                     CurrentByteOffset +
355                     ASL_RESDESC_OFFSET (ExtendedIrq.Interrupts[0]));
356             }
357         }
358
359         InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
360     }
361
362
363     /* Add optional ResSourceIndex if present */
364
365     if (HasResSourceIndex)
366     {
367         Rover->ByteItem = ResSourceIndex;
368         Rover = ACPI_ADD_PTR (AML_RESOURCE, &(Rover->ByteItem), 1);
369         Descriptor->ExtendedIrq.ResourceLength += 1;
370     }
371
372     /* Add optional ResSource string if present */
373
374     if (StringLength && ResSourceString)
375     {
376
377         strcpy ((char *) Rover, (char *) ResSourceString);
378         Rover = ACPI_ADD_PTR (
379                     AML_RESOURCE, &(Rover->ByteItem), StringLength);
380
381         Descriptor->ExtendedIrq.ResourceLength = (UINT16)
382             (Descriptor->ExtendedIrq.ResourceLength + StringLength);
383     }
384
385     Rnode->BufferLength = (ASL_RESDESC_OFFSET (ExtendedIrq.Interrupts[0]) -
386                            ASL_RESDESC_OFFSET (ExtendedIrq.DescriptorType))
387                            + OptionIndex + StringLength;
388     return (Rnode);
389 }
390
391
392 /*******************************************************************************
393  *
394  * FUNCTION:    RsDoVendorLargeDescriptor
395  *
396  * PARAMETERS:  Info                - Parse Op and resource template offset
397  *
398  * RETURN:      Completed resource node
399  *
400  * DESCRIPTION: Construct a long "VendorLong" descriptor
401  *
402  ******************************************************************************/
403
404 ASL_RESOURCE_NODE *
405 RsDoVendorLargeDescriptor (
406     ASL_RESOURCE_INFO       *Info)
407 {
408     AML_RESOURCE            *Descriptor;
409     ACPI_PARSE_OBJECT       *InitializerOp;
410     ASL_RESOURCE_NODE       *Rnode;
411     UINT8                   *VendorData;
412     UINT32                  i;
413
414
415     /* Count the number of data bytes */
416
417     InitializerOp = Info->DescriptorTypeOp->Asl.Child;
418     InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
419
420     for (i = 0; InitializerOp; i++)
421     {
422         if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
423         {
424             break;
425         }
426         InitializerOp = InitializerOp->Asl.Next;
427     }
428
429     InitializerOp = Info->DescriptorTypeOp->Asl.Child;
430     InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
431     Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_VENDOR_LARGE) + i);
432
433     Descriptor = Rnode->Buffer;
434     Descriptor->VendorLarge.DescriptorType  = ACPI_RESOURCE_NAME_VENDOR_LARGE;
435     Descriptor->VendorLarge.ResourceLength = (UINT16) i;
436
437     /* Point to end-of-descriptor for vendor data */
438
439     VendorData = ((UINT8 *) Descriptor) + sizeof (AML_RESOURCE_LARGE_HEADER);
440
441     /* Process all child initialization nodes */
442
443     for (i = 0; InitializerOp; i++)
444     {
445         if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
446         {
447             break;
448         }
449
450         VendorData[i] = (UINT8) InitializerOp->Asl.Value.Integer;
451         InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
452     }
453
454     return (Rnode);
455 }