]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - sys/contrib/dev/acpica/compiler/aslrestype1i.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / sys / contrib / dev / acpica / compiler / aslrestype1i.c
1
2 /******************************************************************************
3  *
4  * Module Name: aslrestype1i - Small I/O-related resource descriptors
5  *
6  *****************************************************************************/
7
8 /*
9  * Copyright (C) 2000 - 2011, Intel Corp.
10  * All rights reserved.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions, and the following disclaimer,
17  *    without modification.
18  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19  *    substantially similar to the "NO WARRANTY" disclaimer below
20  *    ("Disclaimer") and any redistribution must be conditioned upon
21  *    including a substantially similar Disclaimer requirement for further
22  *    binary redistribution.
23  * 3. Neither the names of the above-listed copyright holders nor the names
24  *    of any contributors may be used to endorse or promote products derived
25  *    from this software without specific prior written permission.
26  *
27  * Alternatively, this software may be distributed under the terms of the
28  * GNU General Public License ("GPL") version 2 as published by the Free
29  * Software Foundation.
30  *
31  * NO WARRANTY
32  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42  * POSSIBILITY OF SUCH DAMAGES.
43  */
44
45
46 #include <contrib/dev/acpica/compiler/aslcompiler.h>
47 #include "aslcompiler.y.h"
48
49 #define _COMPONENT          ACPI_COMPILER
50         ACPI_MODULE_NAME    ("aslrestype1i")
51
52 /*
53  * This module contains the I/O-related small resource descriptors:
54  *
55  * DMA
56  * FixedIO
57  * IO
58  * IRQ
59  * IRQNoFlags
60  */
61
62 /*******************************************************************************
63  *
64  * FUNCTION:    RsDoDmaDescriptor
65  *
66  * PARAMETERS:  Op                  - Parent resource descriptor parse node
67  *              CurrentByteOffset   - Offset into the resource template AML
68  *                                    buffer (to track references to the desc)
69  *
70  * RETURN:      Completed resource node
71  *
72  * DESCRIPTION: Construct a short "DMA" descriptor
73  *
74  ******************************************************************************/
75
76 ASL_RESOURCE_NODE *
77 RsDoDmaDescriptor (
78     ACPI_PARSE_OBJECT       *Op,
79     UINT32                  CurrentByteOffset)
80 {
81     AML_RESOURCE            *Descriptor;
82     ACPI_PARSE_OBJECT       *InitializerOp;
83     ASL_RESOURCE_NODE       *Rnode;
84     UINT32                  i;
85     UINT8                   DmaChannelMask = 0;
86     UINT8                   DmaChannels = 0;
87
88
89     InitializerOp = Op->Asl.Child;
90     Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_DMA));
91
92     Descriptor = Rnode->Buffer;
93     Descriptor->Dma.DescriptorType  = ACPI_RESOURCE_NAME_DMA |
94                                         ASL_RDESC_DMA_SIZE;
95
96     /* Process all child initialization nodes */
97
98     for (i = 0; InitializerOp; i++)
99     {
100         switch (i)
101         {
102         case 0: /* DMA type */
103
104             RsSetFlagBits (&Descriptor->Dma.Flags, InitializerOp, 5, 0);
105             RsCreateBitField (InitializerOp, ACPI_RESTAG_DMATYPE,
106                 CurrentByteOffset + ASL_RESDESC_OFFSET (Dma.Flags), 5);
107             break;
108
109         case 1: /* Bus Master */
110
111             RsSetFlagBits (&Descriptor->Dma.Flags, InitializerOp, 2, 0);
112             RsCreateBitField (InitializerOp, ACPI_RESTAG_BUSMASTER,
113                 CurrentByteOffset + ASL_RESDESC_OFFSET (Dma.Flags), 2);
114             break;
115
116         case 2: /* Xfer Type (transfer width) */
117
118             RsSetFlagBits (&Descriptor->Dma.Flags, InitializerOp, 0, 0);
119             RsCreateBitField (InitializerOp, ACPI_RESTAG_XFERTYPE,
120                 CurrentByteOffset + ASL_RESDESC_OFFSET (Dma.Flags), 0);
121             break;
122
123         case 3: /* Name */
124
125             UtAttachNamepathToOwner (Op, InitializerOp);
126             break;
127
128         default:
129
130             /* All DMA channel bytes are handled here, after flags and name */
131
132             if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
133             {
134                 /* Up to 8 channels can be specified in the list */
135
136                 DmaChannels++;
137                 if (DmaChannels > 8)
138                 {
139                     AslError (ASL_ERROR, ASL_MSG_DMA_LIST,
140                         InitializerOp, NULL);
141                     return (Rnode);
142                 }
143
144                 /* Only DMA channels 0-7 are allowed (mask is 8 bits) */
145
146                 if (InitializerOp->Asl.Value.Integer > 7)
147                 {
148                     AslError (ASL_ERROR, ASL_MSG_DMA_CHANNEL,
149                         InitializerOp, NULL);
150                 }
151
152                 /* Build the mask */
153
154                 DmaChannelMask |=
155                     (1 << ((UINT8) InitializerOp->Asl.Value.Integer));
156             }
157
158             if (i == 4) /* case 4: First DMA byte */
159             {
160                 /* Check now for duplicates in list */
161
162                 RsCheckListForDuplicates (InitializerOp);
163
164                 /* Create a named field at the start of the list */
165
166                 RsCreateByteField (InitializerOp, ACPI_RESTAG_DMA,
167                     CurrentByteOffset +
168                     ASL_RESDESC_OFFSET (Dma.DmaChannelMask));
169             }
170             break;
171         }
172
173         InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
174     }
175
176     /* Now we can set the channel mask */
177
178     Descriptor->Dma.DmaChannelMask = DmaChannelMask;
179     return (Rnode);
180 }
181
182
183 /*******************************************************************************
184  *
185  * FUNCTION:    RsDoFixedIoDescriptor
186  *
187  * PARAMETERS:  Op                  - Parent resource descriptor parse node
188  *              CurrentByteOffset   - Offset into the resource template AML
189  *                                    buffer (to track references to the desc)
190  *
191  * RETURN:      Completed resource node
192  *
193  * DESCRIPTION: Construct a short "FixedIO" descriptor
194  *
195  ******************************************************************************/
196
197 ASL_RESOURCE_NODE *
198 RsDoFixedIoDescriptor (
199     ACPI_PARSE_OBJECT       *Op,
200     UINT32                  CurrentByteOffset)
201 {
202     AML_RESOURCE            *Descriptor;
203     ACPI_PARSE_OBJECT       *InitializerOp;
204     ACPI_PARSE_OBJECT       *AddressOp = NULL;
205     ASL_RESOURCE_NODE       *Rnode;
206     UINT32                  i;
207
208
209     InitializerOp = Op->Asl.Child;
210     Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_FIXED_IO));
211
212     Descriptor = Rnode->Buffer;
213     Descriptor->Io.DescriptorType  = ACPI_RESOURCE_NAME_FIXED_IO |
214                                       ASL_RDESC_FIXED_IO_SIZE;
215
216     /* Process all child initialization nodes */
217
218     for (i = 0; InitializerOp; i++)
219     {
220         switch (i)
221         {
222         case 0: /* Base Address */
223
224             Descriptor->FixedIo.Address =
225                 (UINT16) InitializerOp->Asl.Value.Integer;
226             RsCreateByteField (InitializerOp, ACPI_RESTAG_BASEADDRESS,
227                 CurrentByteOffset + ASL_RESDESC_OFFSET (FixedIo.Address));
228             AddressOp = InitializerOp;
229             break;
230
231         case 1: /* Length */
232
233             Descriptor->FixedIo.AddressLength =
234                 (UINT8) InitializerOp->Asl.Value.Integer;
235             RsCreateByteField (InitializerOp, ACPI_RESTAG_LENGTH,
236                 CurrentByteOffset + ASL_RESDESC_OFFSET (FixedIo.AddressLength));
237             break;
238
239         case 2: /* Name */
240
241             UtAttachNamepathToOwner (Op, InitializerOp);
242             break;
243
244         default:
245
246             AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL);
247             break;
248         }
249
250         InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
251     }
252
253     /* Error checks */
254
255     if (Descriptor->FixedIo.Address > 0x03FF)
256     {
257         AslError (ASL_WARNING, ASL_MSG_ISA_ADDRESS, AddressOp, NULL);
258     }
259
260     return (Rnode);
261 }
262
263
264 /*******************************************************************************
265  *
266  * FUNCTION:    RsDoIoDescriptor
267  *
268  * PARAMETERS:  Op                  - Parent resource descriptor parse node
269  *              CurrentByteOffset   - Offset into the resource template AML
270  *                                    buffer (to track references to the desc)
271  *
272  * RETURN:      Completed resource node
273  *
274  * DESCRIPTION: Construct a short "IO" descriptor
275  *
276  ******************************************************************************/
277
278 ASL_RESOURCE_NODE *
279 RsDoIoDescriptor (
280     ACPI_PARSE_OBJECT       *Op,
281     UINT32                  CurrentByteOffset)
282 {
283     AML_RESOURCE            *Descriptor;
284     ACPI_PARSE_OBJECT       *InitializerOp;
285     ACPI_PARSE_OBJECT       *MinOp = NULL;
286     ACPI_PARSE_OBJECT       *MaxOp = NULL;
287     ACPI_PARSE_OBJECT       *LengthOp = NULL;
288     ACPI_PARSE_OBJECT       *AlignOp = NULL;
289     ASL_RESOURCE_NODE       *Rnode;
290     UINT32                  i;
291
292
293     InitializerOp = Op->Asl.Child;
294     Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_IO));
295
296     Descriptor = Rnode->Buffer;
297     Descriptor->Io.DescriptorType  = ACPI_RESOURCE_NAME_IO |
298                                       ASL_RDESC_IO_SIZE;
299
300     /* Process all child initialization nodes */
301
302     for (i = 0; InitializerOp; i++)
303     {
304         switch (i)
305         {
306         case 0: /* Decode size */
307
308             RsSetFlagBits (&Descriptor->Io.Flags, InitializerOp, 0, 1);
309             RsCreateBitField (InitializerOp, ACPI_RESTAG_DECODE,
310                 CurrentByteOffset + ASL_RESDESC_OFFSET (Io.Flags), 0);
311             break;
312
313         case 1:  /* Min Address */
314
315             Descriptor->Io.Minimum =
316                 (UINT16) InitializerOp->Asl.Value.Integer;
317             RsCreateByteField (InitializerOp, ACPI_RESTAG_MINADDR,
318                 CurrentByteOffset + ASL_RESDESC_OFFSET (Io.Minimum));
319             MinOp = InitializerOp;
320             break;
321
322         case 2: /* Max Address */
323
324             Descriptor->Io.Maximum =
325                 (UINT16) InitializerOp->Asl.Value.Integer;
326             RsCreateByteField (InitializerOp, ACPI_RESTAG_MAXADDR,
327                 CurrentByteOffset + ASL_RESDESC_OFFSET (Io.Maximum));
328             MaxOp = InitializerOp;
329             break;
330
331         case 3: /* Alignment */
332
333             Descriptor->Io.Alignment =
334                 (UINT8) InitializerOp->Asl.Value.Integer;
335             RsCreateByteField (InitializerOp, ACPI_RESTAG_ALIGNMENT,
336                 CurrentByteOffset + ASL_RESDESC_OFFSET (Io.Alignment));
337             AlignOp = InitializerOp;
338             break;
339
340         case 4: /* Length */
341
342             Descriptor->Io.AddressLength =
343                 (UINT8) InitializerOp->Asl.Value.Integer;
344             RsCreateByteField (InitializerOp, ACPI_RESTAG_LENGTH,
345                 CurrentByteOffset + ASL_RESDESC_OFFSET (Io.AddressLength));
346             LengthOp = InitializerOp;
347             break;
348
349         case 5: /* Name */
350
351             UtAttachNamepathToOwner (Op, InitializerOp);
352             break;
353
354         default:
355
356             AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL);
357             break;
358         }
359
360         InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
361     }
362
363     /* Validate the Min/Max/Len/Align values */
364
365     RsSmallAddressCheck (ACPI_RESOURCE_NAME_IO,
366         Descriptor->Io.Minimum,
367         Descriptor->Io.Maximum,
368         Descriptor->Io.AddressLength,
369         Descriptor->Io.Alignment,
370         MinOp, MaxOp, LengthOp, AlignOp, Op);
371
372     return (Rnode);
373 }
374
375
376 /*******************************************************************************
377  *
378  * FUNCTION:    RsDoIrqDescriptor
379  *
380  * PARAMETERS:  Op                  - Parent resource descriptor parse node
381  *              CurrentByteOffset   - Offset into the resource template AML
382  *                                    buffer (to track references to the desc)
383  *
384  * RETURN:      Completed resource node
385  *
386  * DESCRIPTION: Construct a short "IRQ" descriptor
387  *
388  ******************************************************************************/
389
390 ASL_RESOURCE_NODE *
391 RsDoIrqDescriptor (
392     ACPI_PARSE_OBJECT       *Op,
393     UINT32                  CurrentByteOffset)
394 {
395     AML_RESOURCE            *Descriptor;
396     ACPI_PARSE_OBJECT       *InitializerOp;
397     ASL_RESOURCE_NODE       *Rnode;
398     UINT32                  Interrupts = 0;
399     UINT16                  IrqMask = 0;
400     UINT32                  i;
401
402
403     InitializerOp = Op->Asl.Child;
404     Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_IRQ));
405
406     /* Length = 3 (with flag byte) */
407
408     Descriptor = Rnode->Buffer;
409     Descriptor->Irq.DescriptorType  = ACPI_RESOURCE_NAME_IRQ |
410                                       (ASL_RDESC_IRQ_SIZE + 0x01);
411
412     /* Process all child initialization nodes */
413
414     for (i = 0; InitializerOp; i++)
415     {
416         switch (i)
417         {
418         case 0: /* Interrupt Type (or Mode - edge/level) */
419
420             RsSetFlagBits (&Descriptor->Irq.Flags, InitializerOp, 0, 1);
421             RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTTYPE,
422                 CurrentByteOffset + ASL_RESDESC_OFFSET (Irq.Flags), 0);
423             break;
424
425         case 1: /* Interrupt Level (or Polarity - Active high/low) */
426
427             RsSetFlagBits (&Descriptor->Irq.Flags, InitializerOp, 3, 0);
428             RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTLEVEL,
429                 CurrentByteOffset + ASL_RESDESC_OFFSET (Irq.Flags), 3);
430             break;
431
432         case 2: /* Share Type - Default: exclusive (0) */
433
434             RsSetFlagBits (&Descriptor->Irq.Flags, InitializerOp, 4, 0);
435             RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE,
436                 CurrentByteOffset + ASL_RESDESC_OFFSET (Irq.Flags), 4);
437             break;
438
439         case 3: /* Name */
440
441             UtAttachNamepathToOwner (Op, InitializerOp);
442             break;
443
444         default:
445
446             /* All IRQ bytes are handled here, after the flags and name */
447
448             if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
449             {
450                 /* Up to 16 interrupts can be specified in the list */
451
452                 Interrupts++;
453                 if (Interrupts > 16)
454                 {
455                     AslError (ASL_ERROR, ASL_MSG_INTERRUPT_LIST,
456                         InitializerOp, NULL);
457                     return (Rnode);
458                 }
459
460                 /* Only interrupts 0-15 are allowed (mask is 16 bits) */
461
462                 if (InitializerOp->Asl.Value.Integer > 15)
463                 {
464                     AslError (ASL_ERROR, ASL_MSG_INTERRUPT_NUMBER,
465                         InitializerOp, NULL);
466                 }
467                 else
468                 {
469                     IrqMask |= (1 << (UINT8) InitializerOp->Asl.Value.Integer);
470                 }
471             }
472
473             /* Case 4: First IRQ value in list */
474
475             if (i == 4)
476             {
477                 /* Check now for duplicates in list */
478
479                 RsCheckListForDuplicates (InitializerOp);
480
481                 /* Create a named field at the start of the list */
482
483                 RsCreateByteField (InitializerOp, ACPI_RESTAG_INTERRUPT,
484                     CurrentByteOffset + ASL_RESDESC_OFFSET (Irq.IrqMask));
485             }
486             break;
487         }
488
489         InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
490     }
491
492     /* Now we can set the channel mask */
493
494     Descriptor->Irq.IrqMask = IrqMask;
495     return (Rnode);
496 }
497
498
499 /*******************************************************************************
500  *
501  * FUNCTION:    RsDoIrqNoFlagsDescriptor
502  *
503  * PARAMETERS:  Op                  - Parent resource descriptor parse node
504  *              CurrentByteOffset   - Offset into the resource template AML
505  *                                    buffer (to track references to the desc)
506  *
507  * RETURN:      Completed resource node
508  *
509  * DESCRIPTION: Construct a short "IRQNoFlags" descriptor
510  *
511  ******************************************************************************/
512
513 ASL_RESOURCE_NODE *
514 RsDoIrqNoFlagsDescriptor (
515     ACPI_PARSE_OBJECT       *Op,
516     UINT32                  CurrentByteOffset)
517 {
518     AML_RESOURCE            *Descriptor;
519     ACPI_PARSE_OBJECT       *InitializerOp;
520     ASL_RESOURCE_NODE       *Rnode;
521     UINT16                  IrqMask = 0;
522     UINT32                  Interrupts = 0;
523     UINT32                  i;
524
525
526     InitializerOp = Op->Asl.Child;
527     Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_IRQ_NOFLAGS));
528
529     Descriptor = Rnode->Buffer;
530     Descriptor->Irq.DescriptorType  = ACPI_RESOURCE_NAME_IRQ |
531                                       ASL_RDESC_IRQ_SIZE;
532
533     /* Process all child initialization nodes */
534
535     for (i = 0; InitializerOp; i++)
536     {
537         switch (i)
538         {
539         case 0: /* Name */
540
541             UtAttachNamepathToOwner (Op, InitializerOp);
542             break;
543
544         default:
545
546             /* IRQ bytes are handled here, after the flags and name */
547
548             if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
549             {
550                 /* Up to 16 interrupts can be specified in the list */
551
552                 Interrupts++;
553                 if (Interrupts > 16)
554                 {
555                     AslError (ASL_ERROR, ASL_MSG_INTERRUPT_LIST,
556                         InitializerOp, NULL);
557                     return (Rnode);
558                 }
559
560                 /* Only interrupts 0-15 are allowed (mask is 16 bits) */
561
562                 if (InitializerOp->Asl.Value.Integer > 15)
563                 {
564                     AslError (ASL_ERROR, ASL_MSG_INTERRUPT_NUMBER,
565                         InitializerOp, NULL);
566                 }
567                 else
568                 {
569                     IrqMask |= (1 << ((UINT8) InitializerOp->Asl.Value.Integer));
570                 }
571             }
572
573             /* Case 1: First IRQ value in list */
574
575             if (i == 1)
576             {
577                 /* Check now for duplicates in list */
578
579                 RsCheckListForDuplicates (InitializerOp);
580
581                 /* Create a named field at the start of the list */
582
583                 RsCreateByteField (InitializerOp, ACPI_RESTAG_INTERRUPT,
584                     CurrentByteOffset + ASL_RESDESC_OFFSET (Irq.IrqMask));
585             }
586             break;
587         }
588
589         InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
590     }
591
592     /* Now we can set the interrupt mask */
593
594     Descriptor->Irq.IrqMask = IrqMask;
595     return (Rnode);
596 }