gdb - Local mods (compile)
[dragonfly.git] / sys / contrib / dev / acpica / source / 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 "aslcompiler.h"
45 #include "aslcompiler.y.h"
46 #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
151     return (Rnode);
152 }
153
154
155 /*******************************************************************************
156  *
157  * FUNCTION:    RsDoInterruptDescriptor
158  *
159  * PARAMETERS:  Info                - Parse Op and resource template offset
160  *
161  * RETURN:      Completed resource node
162  *
163  * DESCRIPTION: Construct a long "Interrupt" descriptor
164  *
165  ******************************************************************************/
166
167 ASL_RESOURCE_NODE *
168 RsDoInterruptDescriptor (
169     ASL_RESOURCE_INFO       *Info)
170 {
171     AML_RESOURCE            *Descriptor;
172     AML_RESOURCE            *Rover = NULL;
173     ACPI_PARSE_OBJECT       *InitializerOp;
174     ASL_RESOURCE_NODE       *Rnode;
175     UINT16                  StringLength = 0;
176     UINT32                  OptionIndex = 0;
177     UINT32                  CurrentByteOffset;
178     UINT32                  i;
179     BOOLEAN                 HasResSourceIndex = FALSE;
180     UINT8                   ResSourceIndex = 0;
181     UINT8                   *ResSourceString = NULL;
182
183
184     InitializerOp = Info->DescriptorTypeOp->Asl.Child;
185     CurrentByteOffset = Info->CurrentByteOffset;
186     StringLength = RsGetStringDataLength (InitializerOp);
187
188     /* Count the interrupt numbers */
189
190     for (i = 0; InitializerOp; i++)
191     {
192         InitializerOp = ASL_GET_PEER_NODE (InitializerOp);
193
194         if (i <= 6)
195         {
196             if (i == 3 &&
197                 InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
198             {
199                 /*
200                  * ResourceSourceIndex was specified, always make room for
201                  * it, even if the ResourceSource was omitted.
202                  */
203                 OptionIndex++;
204             }
205
206             continue;
207         }
208
209         OptionIndex += 4;
210     }
211
212     InitializerOp = Info->DescriptorTypeOp->Asl.Child;
213     Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_EXTENDED_IRQ) +
214         1 + OptionIndex + StringLength);
215
216     Descriptor = Rnode->Buffer;
217     Descriptor->ExtendedIrq.DescriptorType = ACPI_RESOURCE_NAME_EXTENDED_IRQ;
218
219     /*
220      * Initial descriptor length -- may be enlarged if there are
221      * optional fields present
222      */
223     Descriptor->ExtendedIrq.ResourceLength  = 2;  /* Flags and table length byte */
224     Descriptor->ExtendedIrq.InterruptCount  = 0;
225
226     Rover = ACPI_CAST_PTR (AML_RESOURCE,
227         (&(Descriptor->ExtendedIrq.Interrupts[0])));
228
229     /* Process all child initialization nodes */
230
231     for (i = 0; InitializerOp; i++)
232     {
233         switch (i)
234         {
235         case 0: /* Resource Usage (Default: consumer (1) */
236
237             RsSetFlagBits (&Descriptor->ExtendedIrq.Flags, InitializerOp, 0, 1);
238             break;
239
240         case 1: /* Interrupt Type (or Mode - edge/level) */
241
242             RsSetFlagBits (&Descriptor->ExtendedIrq.Flags, InitializerOp, 1, 0);
243             RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTTYPE,
244                 CurrentByteOffset + ASL_RESDESC_OFFSET (ExtendedIrq.Flags), 1);
245             break;
246
247         case 2: /* Interrupt Level (or Polarity - Active high/low) */
248
249             RsSetFlagBits (&Descriptor->ExtendedIrq.Flags, InitializerOp, 2, 0);
250             RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTLEVEL,
251                 CurrentByteOffset + ASL_RESDESC_OFFSET (ExtendedIrq.Flags), 2);
252             break;
253
254         case 3: /* Share Type - Default: exclusive (0) */
255
256             RsSetFlagBits (&Descriptor->ExtendedIrq.Flags, InitializerOp, 3, 0);
257             RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE,
258                 CurrentByteOffset + ASL_RESDESC_OFFSET (ExtendedIrq.Flags), 3);
259             break;
260
261         case 4: /* ResSourceIndex [Optional Field - BYTE] */
262
263             if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
264             {
265                 HasResSourceIndex = TRUE;
266                 ResSourceIndex = (UINT8) InitializerOp->Asl.Value.Integer;
267             }
268             break;
269
270         case 5: /* ResSource [Optional Field - STRING] */
271
272             if ((InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) &&
273                 (InitializerOp->Asl.Value.String))
274             {
275                 if (StringLength)
276                 {
277                     ResSourceString = (UINT8 *) InitializerOp->Asl.Value.String;
278                 }
279
280                 /* ResourceSourceIndex must also be valid */
281
282                 if (!HasResSourceIndex)
283                 {
284                     AslError (ASL_ERROR, ASL_MSG_RESOURCE_INDEX,
285                         InitializerOp, NULL);
286                 }
287             }
288
289 #if 0
290             /*
291              * Not a valid ResourceSource, ResourceSourceIndex must also
292              * be invalid
293              */
294             else if (HasResSourceIndex)
295             {
296                 AslError (ASL_ERROR, ASL_MSG_RESOURCE_SOURCE,
297                     InitializerOp, NULL);
298             }
299 #endif
300             break;
301
302         case 6: /* ResourceTag */
303
304             UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
305             break;
306
307         default:
308             /*
309              * Interrupt Numbers come through here, repeatedly
310              */
311
312             /* Maximum 255 interrupts allowed for this descriptor */
313
314             if (Descriptor->ExtendedIrq.InterruptCount == 255)
315             {
316                 AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_LIST,
317                     InitializerOp, NULL);
318                 return (Rnode);
319             }
320
321             /* Each interrupt number must be a 32-bit value */
322
323             if (InitializerOp->Asl.Value.Integer > ACPI_UINT32_MAX)
324             {
325                 AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_NUMBER,
326                     InitializerOp, NULL);
327             }
328
329             /* Save the integer and move pointer to the next one */
330
331             Rover->DwordItem = (UINT32) InitializerOp->Asl.Value.Integer;
332             Rover = ACPI_ADD_PTR (AML_RESOURCE, &(Rover->DwordItem), 4);
333             Descriptor->ExtendedIrq.InterruptCount++;
334             Descriptor->ExtendedIrq.ResourceLength += 4;
335
336             /* Case 7: First interrupt number in list */
337
338             if (i == 7)
339             {
340                 if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
341                 {
342                     /* Must be at least one interrupt */
343
344                     AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_LIST_MIN,
345                         InitializerOp, NULL);
346                 }
347
348                 /* Check now for duplicates in list */
349
350                 RsCheckListForDuplicates (InitializerOp);
351
352                 /* Create a named field at the start of the list */
353
354                 RsCreateDwordField (InitializerOp, ACPI_RESTAG_INTERRUPT,
355                     CurrentByteOffset +
356                     ASL_RESDESC_OFFSET (ExtendedIrq.Interrupts[0]));
357             }
358         }
359
360         InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
361     }
362
363
364     /* Add optional ResSourceIndex if present */
365
366     if (HasResSourceIndex)
367     {
368         Rover->ByteItem = ResSourceIndex;
369         Rover = ACPI_ADD_PTR (AML_RESOURCE, &(Rover->ByteItem), 1);
370         Descriptor->ExtendedIrq.ResourceLength += 1;
371     }
372
373     /* Add optional ResSource string if present */
374
375     if (StringLength && ResSourceString)
376     {
377
378         strcpy ((char *) Rover, (char *) ResSourceString);
379         Rover = ACPI_ADD_PTR (
380                     AML_RESOURCE, &(Rover->ByteItem), StringLength);
381
382         Descriptor->ExtendedIrq.ResourceLength = (UINT16)
383             (Descriptor->ExtendedIrq.ResourceLength + StringLength);
384     }
385
386     Rnode->BufferLength =
387         (ASL_RESDESC_OFFSET (ExtendedIrq.Interrupts[0]) -
388         ASL_RESDESC_OFFSET (ExtendedIrq.DescriptorType))
389         + OptionIndex + StringLength;
390     return (Rnode);
391 }
392
393
394 /*******************************************************************************
395  *
396  * FUNCTION:    RsDoVendorLargeDescriptor
397  *
398  * PARAMETERS:  Info                - Parse Op and resource template offset
399  *
400  * RETURN:      Completed resource node
401  *
402  * DESCRIPTION: Construct a long "VendorLong" descriptor
403  *
404  ******************************************************************************/
405
406 ASL_RESOURCE_NODE *
407 RsDoVendorLargeDescriptor (
408     ASL_RESOURCE_INFO       *Info)
409 {
410     AML_RESOURCE            *Descriptor;
411     ACPI_PARSE_OBJECT       *InitializerOp;
412     ASL_RESOURCE_NODE       *Rnode;
413     UINT8                   *VendorData;
414     UINT32                  i;
415
416
417     /* Count the number of data bytes */
418
419     InitializerOp = Info->DescriptorTypeOp->Asl.Child;
420     InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
421
422     for (i = 0; InitializerOp; i++)
423     {
424         if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
425         {
426             break;
427         }
428         InitializerOp = InitializerOp->Asl.Next;
429     }
430
431     InitializerOp = Info->DescriptorTypeOp->Asl.Child;
432     InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
433     Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_VENDOR_LARGE) + i);
434
435     Descriptor = Rnode->Buffer;
436     Descriptor->VendorLarge.DescriptorType = ACPI_RESOURCE_NAME_VENDOR_LARGE;
437     Descriptor->VendorLarge.ResourceLength = (UINT16) i;
438
439     /* Point to end-of-descriptor for vendor data */
440
441     VendorData = ((UINT8 *) Descriptor) + sizeof (AML_RESOURCE_LARGE_HEADER);
442
443     /* Process all child initialization nodes */
444
445     for (i = 0; InitializerOp; i++)
446     {
447         if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
448         {
449             break;
450         }
451
452         VendorData[i] = (UINT8) InitializerOp->Asl.Value.Integer;
453         InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
454     }
455
456     return (Rnode);
457 }