aslrestype2q.c revision 241973
155714Skris/******************************************************************************
255714Skris *
355714Skris * Module Name: aslrestype2q - Large QWord address resource descriptors
455714Skris *
555714Skris *****************************************************************************/
655714Skris
755714Skris/*
8296341Sdelphij * Copyright (C) 2000 - 2012, Intel Corp.
955714Skris * All rights reserved.
1055714Skris *
1155714Skris * Redistribution and use in source and binary forms, with or without
1255714Skris * modification, are permitted provided that the following conditions
1355714Skris * are met:
1455714Skris * 1. Redistributions of source code must retain the above copyright
15296341Sdelphij *    notice, this list of conditions, and the following disclaimer,
1655714Skris *    without modification.
1755714Skris * 2. Redistributions in binary form must reproduce at minimum a disclaimer
1855714Skris *    substantially similar to the "NO WARRANTY" disclaimer below
1955714Skris *    ("Disclaimer") and any redistribution must be conditioned upon
2055714Skris *    including a substantially similar Disclaimer requirement for further
2155714Skris *    binary redistribution.
22296341Sdelphij * 3. Neither the names of the above-listed copyright holders nor the names
2355714Skris *    of any contributors may be used to endorse or promote products derived
2455714Skris *    from this software without specific prior written permission.
2555714Skris *
2655714Skris * Alternatively, this software may be distributed under the terms of the
2755714Skris * GNU General Public License ("GPL") version 2 as published by the Free
2855714Skris * Software Foundation.
2955714Skris *
3055714Skris * NO WARRANTY
3155714Skris * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
3255714Skris * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3355714Skris * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
3455714Skris * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3555714Skris * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37296341Sdelphij * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
3955714Skris * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40296341Sdelphij * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
4155714Skris * POSSIBILITY OF SUCH DAMAGES.
4255714Skris */
4355714Skris
4455714Skris
4555714Skris#include <contrib/dev/acpica/compiler/aslcompiler.h>
4655714Skris#include "aslcompiler.y.h"
4755714Skris
4855714Skris#define _COMPONENT          ACPI_COMPILER
4955714Skris        ACPI_MODULE_NAME    ("aslrestype2q")
5055714Skris
5155714Skris/*
52296341Sdelphij * This module contains the QWord (64-bit) address space descriptors:
5355714Skris *
5455714Skris * QWordIO
5555714Skris * QWordMemory
5655714Skris * QWordSpace
5755714Skris */
5855714Skris
5959194Skris/*******************************************************************************
60110007Smarkm *
61296341Sdelphij * FUNCTION:    RsDoQwordIoDescriptor
6255714Skris *
6355714Skris * PARAMETERS:  Op                  - Parent resource descriptor parse node
64296341Sdelphij *              CurrentByteOffset   - Offset into the resource template AML
65296341Sdelphij *                                    buffer (to track references to the desc)
66296341Sdelphij *
67296341Sdelphij * RETURN:      Completed resource node
68296341Sdelphij *
69296341Sdelphij * DESCRIPTION: Construct a long "QwordIO" descriptor
7055714Skris *
71296341Sdelphij ******************************************************************************/
72296341Sdelphij
73296341SdelphijASL_RESOURCE_NODE *
74296341SdelphijRsDoQwordIoDescriptor (
75296341Sdelphij    ACPI_PARSE_OBJECT       *Op,
76296341Sdelphij    UINT32                  CurrentByteOffset)
77296341Sdelphij{
7855714Skris    AML_RESOURCE            *Descriptor;
79296341Sdelphij    ACPI_PARSE_OBJECT       *InitializerOp;
80296341Sdelphij    ACPI_PARSE_OBJECT       *MinOp = NULL;
81296341Sdelphij    ACPI_PARSE_OBJECT       *MaxOp = NULL;
82296341Sdelphij    ACPI_PARSE_OBJECT       *LengthOp = NULL;
83167615Ssimon    ACPI_PARSE_OBJECT       *GranOp = NULL;
84296341Sdelphij    ASL_RESOURCE_NODE       *Rnode;
85296341Sdelphij    UINT8                   *OptionalFields;
86296341Sdelphij    UINT16                  StringLength = 0;
87296341Sdelphij    UINT32                  OptionIndex = 0;
88296341Sdelphij    UINT32                  i;
89296341Sdelphij    BOOLEAN                 ResSourceIndex = FALSE;
90167615Ssimon
91296341Sdelphij
92296341Sdelphij    InitializerOp = Op->Asl.Child;
93296341Sdelphij    StringLength = RsGetStringDataLength (InitializerOp);
94296341Sdelphij
95296341Sdelphij    Rnode = RsAllocateResourceNode (
9655714Skris                sizeof (AML_RESOURCE_ADDRESS64) + 1 + StringLength);
97296341Sdelphij
98296341Sdelphij    Descriptor = Rnode->Buffer;
9955714Skris    Descriptor->Address64.DescriptorType  = ACPI_RESOURCE_NAME_ADDRESS64;
100296341Sdelphij    Descriptor->Address64.ResourceType    = ACPI_ADDRESS_TYPE_IO_RANGE;
101296341Sdelphij
102296341Sdelphij    /*
10355714Skris     * Initial descriptor length -- may be enlarged if there are
104296341Sdelphij     * optional fields present
105296341Sdelphij     */
10655714Skris    OptionalFields = ((UINT8 *) Descriptor) + sizeof (AML_RESOURCE_ADDRESS64);
107296341Sdelphij    Descriptor->Address64.ResourceLength = (UINT16)
108296341Sdelphij        (sizeof (AML_RESOURCE_ADDRESS64) -
109296341Sdelphij         sizeof (AML_RESOURCE_LARGE_HEADER));
110296341Sdelphij
111296341Sdelphij    /* Process all child initialization nodes */
112296341Sdelphij
113296341Sdelphij    for (i = 0; InitializerOp; i++)
114296341Sdelphij    {
115296341Sdelphij        switch (i)
116296341Sdelphij        {
117296341Sdelphij        case 0: /* Resource Usage */
118296341Sdelphij
119296341Sdelphij            RsSetFlagBits (&Descriptor->Address64.Flags, InitializerOp, 0, 1);
120296341Sdelphij            break;
12155714Skris
122296341Sdelphij        case 1: /* MinType */
123296341Sdelphij
124296341Sdelphij            RsSetFlagBits (&Descriptor->Address64.Flags, InitializerOp, 2, 0);
125296341Sdelphij            RsCreateBitField (InitializerOp, ACPI_RESTAG_MINTYPE,
126296341Sdelphij                CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.Flags), 2);
127279264Sdelphij            break;
128296341Sdelphij
129296341Sdelphij        case 2: /* MaxType */
130296341Sdelphij
131296341Sdelphij            RsSetFlagBits (&Descriptor->Address64.Flags, InitializerOp, 3, 0);
13255714Skris            RsCreateBitField (InitializerOp, ACPI_RESTAG_MAXTYPE,
133296341Sdelphij                CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.Flags), 3);
134296341Sdelphij            break;
135296341Sdelphij
136296341Sdelphij        case 3: /* DecodeType */
137296341Sdelphij
138296341Sdelphij            RsSetFlagBits (&Descriptor->Address64.Flags, InitializerOp, 1, 0);
139296341Sdelphij            RsCreateBitField (InitializerOp, ACPI_RESTAG_DECODE,
14055714Skris                CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.Flags), 1);
141296341Sdelphij            break;
142296341Sdelphij
143296341Sdelphij        case 4: /* Range Type */
14455714Skris
145296341Sdelphij            RsSetFlagBits (&Descriptor->Address64.SpecificFlags, InitializerOp, 0, 3);
146296341Sdelphij            RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_RANGETYPE,
147296341Sdelphij                CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.SpecificFlags), 0, 2);
148296341Sdelphij            break;
149296341Sdelphij
150296341Sdelphij        case 5: /* Address Granularity */
151296341Sdelphij
15255714Skris            Descriptor->Address64.Granularity = InitializerOp->Asl.Value.Integer;
153296341Sdelphij            RsCreateQwordField (InitializerOp, ACPI_RESTAG_GRANULARITY,
154296341Sdelphij                CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.Granularity));
15555714Skris            GranOp = InitializerOp;
156296341Sdelphij            break;
157296341Sdelphij
158279264Sdelphij        case 6: /* Address Min */
15955714Skris
160296341Sdelphij            Descriptor->Address64.Minimum = InitializerOp->Asl.Value.Integer;
161296341Sdelphij            RsCreateQwordField (InitializerOp, ACPI_RESTAG_MINADDR,
162296341Sdelphij                CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.Minimum));
163296341Sdelphij            MinOp = InitializerOp;
164296341Sdelphij            break;
16555714Skris
166296341Sdelphij        case 7: /* Address Max */
167296341Sdelphij
168296341Sdelphij            Descriptor->Address64.Maximum = InitializerOp->Asl.Value.Integer;
169296341Sdelphij            RsCreateQwordField (InitializerOp, ACPI_RESTAG_MAXADDR,
170296341Sdelphij                CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.Maximum));
171296341Sdelphij            MaxOp = InitializerOp;
172296341Sdelphij            break;
173296341Sdelphij
174296341Sdelphij        case 8: /* Translation Offset */
175296341Sdelphij
176296341Sdelphij            Descriptor->Address64.TranslationOffset = InitializerOp->Asl.Value.Integer;
17755714Skris            RsCreateByteField (InitializerOp, ACPI_RESTAG_TRANSLATION,
178296341Sdelphij                CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.TranslationOffset));
179296341Sdelphij            break;
18055714Skris
181296341Sdelphij        case 9: /* Address Length */
182296341Sdelphij
183296341Sdelphij            Descriptor->Address64.AddressLength = InitializerOp->Asl.Value.Integer;
184296341Sdelphij            RsCreateQwordField (InitializerOp, ACPI_RESTAG_LENGTH,
185296341Sdelphij                CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.AddressLength));
186296341Sdelphij            LengthOp = InitializerOp;
187296341Sdelphij            break;
188296341Sdelphij
189296341Sdelphij        case 10: /* ResSourceIndex [Optional Field - BYTE] */
190296341Sdelphij
191296341Sdelphij            if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
19255714Skris            {
19359194Skris                OptionalFields[0] = (UINT8) InitializerOp->Asl.Value.Integer;
194296341Sdelphij                OptionIndex++;
19559194Skris                Descriptor->Address64.ResourceLength++;
19659194Skris                ResSourceIndex = TRUE;
19755949Skris            }
198            break;
199
200        case 11: /* ResSource [Optional Field - STRING] */
201
202            if ((InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) &&
203                (InitializerOp->Asl.Value.String))
204            {
205                if (StringLength)
206                {
207                    Descriptor->Address64.ResourceLength = (UINT16)
208                        (Descriptor->Address64.ResourceLength + StringLength);
209
210                    strcpy ((char *)
211                        &OptionalFields[OptionIndex],
212                        InitializerOp->Asl.Value.String);
213
214                    /* ResourceSourceIndex must also be valid */
215
216                    if (!ResSourceIndex)
217                    {
218                        AslError (ASL_ERROR, ASL_MSG_RESOURCE_INDEX,
219                            InitializerOp, NULL);
220                    }
221                }
222            }
223
224#if 0
225            /*
226             * Not a valid ResourceSource, ResourceSourceIndex must also
227             * be invalid
228             */
229            else if (ResSourceIndex)
230            {
231                AslError (ASL_ERROR, ASL_MSG_RESOURCE_SOURCE,
232                    InitializerOp, NULL);
233            }
234#endif
235            break;
236
237        case 12: /* ResourceTag */
238
239            UtAttachNamepathToOwner (Op, InitializerOp);
240            break;
241
242        case 13: /* Type */
243
244            RsSetFlagBits (&Descriptor->Address64.SpecificFlags, InitializerOp, 4, 0);
245            RsCreateBitField (InitializerOp, ACPI_RESTAG_TYPE,
246                CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.SpecificFlags), 4);
247            break;
248
249        case 14: /* Translation Type */
250
251            RsSetFlagBits (&Descriptor->Address64.SpecificFlags, InitializerOp, 5, 0);
252            RsCreateBitField (InitializerOp, ACPI_RESTAG_TRANSTYPE,
253                CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.SpecificFlags), 5);
254            break;
255
256        default:
257
258            AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL);
259            break;
260        }
261
262        InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
263    }
264
265    /* Validate the Min/Max/Len/Gran values */
266
267    RsLargeAddressCheck (
268        Descriptor->Address64.Minimum,
269        Descriptor->Address64.Maximum,
270        Descriptor->Address64.AddressLength,
271        Descriptor->Address64.Granularity,
272        Descriptor->Address64.Flags,
273        MinOp, MaxOp, LengthOp, GranOp, Op);
274
275    Rnode->BufferLength = sizeof (AML_RESOURCE_ADDRESS64) +
276                            OptionIndex + StringLength;
277    return (Rnode);
278}
279
280
281/*******************************************************************************
282 *
283 * FUNCTION:    RsDoQwordMemoryDescriptor
284 *
285 * PARAMETERS:  Op                  - Parent resource descriptor parse node
286 *              CurrentByteOffset   - Offset into the resource template AML
287 *                                    buffer (to track references to the desc)
288 *
289 * RETURN:      Completed resource node
290 *
291 * DESCRIPTION: Construct a long "QwordMemory" descriptor
292 *
293 ******************************************************************************/
294
295ASL_RESOURCE_NODE *
296RsDoQwordMemoryDescriptor (
297    ACPI_PARSE_OBJECT       *Op,
298    UINT32                  CurrentByteOffset)
299{
300    AML_RESOURCE            *Descriptor;
301    ACPI_PARSE_OBJECT       *InitializerOp;
302    ACPI_PARSE_OBJECT       *MinOp = NULL;
303    ACPI_PARSE_OBJECT       *MaxOp = NULL;
304    ACPI_PARSE_OBJECT       *LengthOp = NULL;
305    ACPI_PARSE_OBJECT       *GranOp = NULL;
306    ASL_RESOURCE_NODE       *Rnode;
307    UINT8                   *OptionalFields;
308    UINT16                  StringLength = 0;
309    UINT32                  OptionIndex = 0;
310    UINT32                  i;
311    BOOLEAN                 ResSourceIndex = FALSE;
312
313
314    InitializerOp = Op->Asl.Child;
315    StringLength = RsGetStringDataLength (InitializerOp);
316
317    Rnode = RsAllocateResourceNode (
318                sizeof (AML_RESOURCE_ADDRESS64) + 1 + StringLength);
319
320    Descriptor = Rnode->Buffer;
321    Descriptor->Address64.DescriptorType  = ACPI_RESOURCE_NAME_ADDRESS64;
322    Descriptor->Address64.ResourceType    = ACPI_ADDRESS_TYPE_MEMORY_RANGE;
323
324    /*
325     * Initial descriptor length -- may be enlarged if there are
326     * optional fields present
327     */
328    OptionalFields = ((UINT8 *) Descriptor) + sizeof (AML_RESOURCE_ADDRESS64);
329    Descriptor->Address64.ResourceLength = (UINT16)
330        (sizeof (AML_RESOURCE_ADDRESS64) -
331         sizeof (AML_RESOURCE_LARGE_HEADER));
332
333    /* Process all child initialization nodes */
334
335    for (i = 0; InitializerOp; i++)
336    {
337        switch (i)
338        {
339        case 0: /* Resource Usage */
340
341            RsSetFlagBits (&Descriptor->Address64.Flags, InitializerOp, 0, 1);
342            break;
343
344        case 1: /* DecodeType */
345
346            RsSetFlagBits (&Descriptor->Address64.Flags, InitializerOp, 1, 0);
347            RsCreateBitField (InitializerOp, ACPI_RESTAG_DECODE,
348                CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.Flags), 1);
349            break;
350
351        case 2: /* MinType */
352
353            RsSetFlagBits (&Descriptor->Address64.Flags, InitializerOp, 2, 0);
354            RsCreateBitField (InitializerOp, ACPI_RESTAG_MINTYPE,
355                CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.Flags), 2);
356            break;
357
358        case 3: /* MaxType */
359
360            RsSetFlagBits (&Descriptor->Address64.Flags, InitializerOp, 3, 0);
361            RsCreateBitField (InitializerOp, ACPI_RESTAG_MAXTYPE,
362                CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.Flags), 3);
363            break;
364
365        case 4: /* Memory Type */
366
367            RsSetFlagBits (&Descriptor->Address64.SpecificFlags, InitializerOp, 1, 0);
368            RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_MEMTYPE,
369                CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.SpecificFlags), 1, 2);
370            break;
371
372        case 5: /* Read/Write Type */
373
374            RsSetFlagBits (&Descriptor->Address64.SpecificFlags, InitializerOp, 0, 1);
375            RsCreateBitField (InitializerOp, ACPI_RESTAG_READWRITETYPE,
376                CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.SpecificFlags), 0);
377            break;
378
379        case 6: /* Address Granularity */
380
381            Descriptor->Address64.Granularity = InitializerOp->Asl.Value.Integer;
382            RsCreateQwordField (InitializerOp, ACPI_RESTAG_GRANULARITY,
383                CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.Granularity));
384            GranOp = InitializerOp;
385            break;
386
387        case 7: /* Min Address */
388
389            Descriptor->Address64.Minimum = InitializerOp->Asl.Value.Integer;
390            RsCreateQwordField (InitializerOp, ACPI_RESTAG_MINADDR,
391                CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.Minimum));
392            MinOp = InitializerOp;
393            break;
394
395        case 8: /* Max Address */
396
397            Descriptor->Address64.Maximum = InitializerOp->Asl.Value.Integer;
398            RsCreateQwordField (InitializerOp, ACPI_RESTAG_MAXADDR,
399                CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.Maximum));
400            MaxOp = InitializerOp;
401            break;
402
403        case 9: /* Translation Offset */
404
405            Descriptor->Address64.TranslationOffset = InitializerOp->Asl.Value.Integer;
406            RsCreateQwordField (InitializerOp, ACPI_RESTAG_TRANSLATION,
407                CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.TranslationOffset));
408            break;
409
410        case 10: /* Address Length */
411
412            Descriptor->Address64.AddressLength = InitializerOp->Asl.Value.Integer;
413            RsCreateQwordField (InitializerOp, ACPI_RESTAG_LENGTH,
414                CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.AddressLength));
415            LengthOp = InitializerOp;
416            break;
417
418        case 11: /* ResSourceIndex [Optional Field - BYTE] */
419
420            if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
421            {
422                OptionalFields[0] = (UINT8) InitializerOp->Asl.Value.Integer;
423                OptionIndex++;
424                Descriptor->Address64.ResourceLength++;
425                ResSourceIndex = TRUE;
426            }
427            break;
428
429        case 12: /* ResSource [Optional Field - STRING] */
430
431            if ((InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) &&
432                (InitializerOp->Asl.Value.String))
433            {
434                if (StringLength)
435                {
436                    Descriptor->Address64.ResourceLength = (UINT16)
437                        (Descriptor->Address64.ResourceLength + StringLength);
438
439                    strcpy ((char *)
440                        &OptionalFields[OptionIndex],
441                        InitializerOp->Asl.Value.String);
442
443                    /* ResourceSourceIndex must also be valid */
444
445                    if (!ResSourceIndex)
446                    {
447                        AslError (ASL_ERROR, ASL_MSG_RESOURCE_INDEX,
448                            InitializerOp, NULL);
449                    }
450                }
451            }
452
453#if 0
454            /*
455             * Not a valid ResourceSource, ResourceSourceIndex must also
456             * be invalid
457             */
458            else if (ResSourceIndex)
459            {
460                AslError (ASL_ERROR, ASL_MSG_RESOURCE_SOURCE,
461                    InitializerOp, NULL);
462            }
463#endif
464            break;
465
466        case 13: /* ResourceTag */
467
468            UtAttachNamepathToOwner (Op, InitializerOp);
469            break;
470
471
472        case 14: /* Address Range */
473
474            RsSetFlagBits (&Descriptor->Address64.SpecificFlags, InitializerOp, 3, 0);
475            RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_MEMATTRIBUTES,
476                CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.SpecificFlags), 3, 2);
477            break;
478
479        case 15: /* Type */
480
481            RsSetFlagBits (&Descriptor->Address64.SpecificFlags, InitializerOp, 5, 0);
482            RsCreateBitField (InitializerOp, ACPI_RESTAG_TYPE,
483                CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.SpecificFlags), 5);
484            break;
485
486        default:
487
488            AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL);
489            break;
490        }
491
492        InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
493    }
494
495    /* Validate the Min/Max/Len/Gran values */
496
497    RsLargeAddressCheck (
498        Descriptor->Address64.Minimum,
499        Descriptor->Address64.Maximum,
500        Descriptor->Address64.AddressLength,
501        Descriptor->Address64.Granularity,
502        Descriptor->Address64.Flags,
503        MinOp, MaxOp, LengthOp, GranOp, Op);
504
505    Rnode->BufferLength = sizeof (AML_RESOURCE_ADDRESS64) +
506                            OptionIndex + StringLength;
507    return (Rnode);
508}
509
510
511/*******************************************************************************
512 *
513 * FUNCTION:    RsDoQwordSpaceDescriptor
514 *
515 * PARAMETERS:  Op                  - Parent resource descriptor parse node
516 *              CurrentByteOffset   - Offset into the resource template AML
517 *                                    buffer (to track references to the desc)
518 *
519 * RETURN:      Completed resource node
520 *
521 * DESCRIPTION: Construct a long "QwordSpace" descriptor
522 *
523 ******************************************************************************/
524
525ASL_RESOURCE_NODE *
526RsDoQwordSpaceDescriptor (
527    ACPI_PARSE_OBJECT       *Op,
528    UINT32                  CurrentByteOffset)
529{
530    AML_RESOURCE            *Descriptor;
531    ACPI_PARSE_OBJECT       *InitializerOp;
532    ACPI_PARSE_OBJECT       *MinOp = NULL;
533    ACPI_PARSE_OBJECT       *MaxOp = NULL;
534    ACPI_PARSE_OBJECT       *LengthOp = NULL;
535    ACPI_PARSE_OBJECT       *GranOp = NULL;
536    ASL_RESOURCE_NODE       *Rnode;
537    UINT8                   *OptionalFields;
538    UINT16                  StringLength = 0;
539    UINT32                  OptionIndex = 0;
540    UINT32                  i;
541    BOOLEAN                 ResSourceIndex = FALSE;
542
543
544    InitializerOp = Op->Asl.Child;
545    StringLength = RsGetStringDataLength (InitializerOp);
546
547    Rnode = RsAllocateResourceNode (
548                sizeof (AML_RESOURCE_ADDRESS64) + 1 + StringLength);
549
550    Descriptor = Rnode->Buffer;
551    Descriptor->Address64.DescriptorType = ACPI_RESOURCE_NAME_ADDRESS64;
552
553    /*
554     * Initial descriptor length -- may be enlarged if there are
555     * optional fields present
556     */
557    OptionalFields = ((UINT8 *) Descriptor) + sizeof (AML_RESOURCE_ADDRESS64);
558    Descriptor->Address64.ResourceLength = (UINT16)
559        (sizeof (AML_RESOURCE_ADDRESS64) -
560         sizeof (AML_RESOURCE_LARGE_HEADER));
561
562    /* Process all child initialization nodes */
563
564    for (i = 0; InitializerOp; i++)
565    {
566        switch (i)
567        {
568        case 0: /* Resource Type */
569
570            Descriptor->Address64.ResourceType =
571                (UINT8) InitializerOp->Asl.Value.Integer;
572            break;
573
574        case 1: /* Resource Usage */
575
576            RsSetFlagBits (&Descriptor->Address64.Flags, InitializerOp, 0, 1);
577            break;
578
579        case 2: /* DecodeType */
580
581            RsSetFlagBits (&Descriptor->Address64.Flags, InitializerOp, 1, 0);
582            RsCreateBitField (InitializerOp, ACPI_RESTAG_DECODE,
583                CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.Flags), 1);
584            break;
585
586        case 3: /* MinType */
587
588            RsSetFlagBits (&Descriptor->Address64.Flags, InitializerOp, 2, 0);
589            RsCreateBitField (InitializerOp, ACPI_RESTAG_MINTYPE,
590                CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.Flags), 2);
591            break;
592
593        case 4: /* MaxType */
594
595            RsSetFlagBits (&Descriptor->Address64.Flags, InitializerOp, 3, 0);
596            RsCreateBitField (InitializerOp, ACPI_RESTAG_MAXTYPE,
597                CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.Flags), 3);
598            break;
599
600        case 5: /* Type-Specific flags */
601
602            Descriptor->Address64.SpecificFlags =
603                (UINT8) InitializerOp->Asl.Value.Integer;
604            break;
605
606        case 6: /* Address Granularity */
607
608            Descriptor->Address64.Granularity = InitializerOp->Asl.Value.Integer;
609            RsCreateQwordField (InitializerOp, ACPI_RESTAG_GRANULARITY,
610                CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.Granularity));
611            GranOp = InitializerOp;
612            break;
613
614        case 7: /* Min Address */
615
616            Descriptor->Address64.Minimum = InitializerOp->Asl.Value.Integer;
617            RsCreateQwordField (InitializerOp, ACPI_RESTAG_MINADDR,
618                CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.Minimum));
619            MinOp = InitializerOp;
620            break;
621
622        case 8: /* Max Address */
623
624            Descriptor->Address64.Maximum = InitializerOp->Asl.Value.Integer;
625            RsCreateQwordField (InitializerOp, ACPI_RESTAG_MAXADDR,
626                CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.Maximum));
627            MaxOp = InitializerOp;
628            break;
629
630        case 9: /* Translation Offset */
631
632            Descriptor->Address64.TranslationOffset = InitializerOp->Asl.Value.Integer;
633            RsCreateQwordField (InitializerOp, ACPI_RESTAG_TRANSLATION,
634                CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.TranslationOffset));
635            break;
636
637        case 10: /* Address Length */
638
639            Descriptor->Address64.AddressLength = InitializerOp->Asl.Value.Integer;
640            RsCreateQwordField (InitializerOp, ACPI_RESTAG_LENGTH,
641                CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.AddressLength));
642            LengthOp = InitializerOp;
643            break;
644
645        case 11: /* ResSourceIndex [Optional Field - BYTE] */
646
647            if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
648            {
649                OptionalFields[0] = (UINT8) InitializerOp->Asl.Value.Integer;
650                OptionIndex++;
651                Descriptor->Address64.ResourceLength++;
652                ResSourceIndex = TRUE;
653            }
654            break;
655
656        case 12: /* ResSource [Optional Field - STRING] */
657
658            if ((InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) &&
659                (InitializerOp->Asl.Value.String))
660            {
661                if (StringLength)
662                {
663                    Descriptor->Address64.ResourceLength = (UINT16)
664                        (Descriptor->Address64.ResourceLength + StringLength);
665
666                    strcpy ((char *)
667                        &OptionalFields[OptionIndex],
668                        InitializerOp->Asl.Value.String);
669
670                    /* ResourceSourceIndex must also be valid */
671
672                    if (!ResSourceIndex)
673                    {
674                        AslError (ASL_ERROR, ASL_MSG_RESOURCE_INDEX,
675                            InitializerOp, NULL);
676                    }
677                }
678            }
679
680#if 0
681            /*
682             * Not a valid ResourceSource, ResourceSourceIndex must also
683             * be invalid
684             */
685            else if (ResSourceIndex)
686            {
687                AslError (ASL_ERROR, ASL_MSG_RESOURCE_SOURCE,
688                    InitializerOp, NULL);
689            }
690#endif
691            break;
692
693        case 13: /* ResourceTag */
694
695            UtAttachNamepathToOwner (Op, InitializerOp);
696            break;
697
698        default:
699
700            AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL);
701            break;
702        }
703
704        InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
705    }
706
707    /* Validate the Min/Max/Len/Gran values */
708
709    RsLargeAddressCheck (
710        Descriptor->Address64.Minimum,
711        Descriptor->Address64.Maximum,
712        Descriptor->Address64.AddressLength,
713        Descriptor->Address64.Granularity,
714        Descriptor->Address64.Flags,
715        MinOp, MaxOp, LengthOp, GranOp, Op);
716
717    Rnode->BufferLength = sizeof (AML_RESOURCE_ADDRESS64) +
718                            OptionIndex + StringLength;
719    return (Rnode);
720}
721