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