xref: /netbsd-src/sys/external/bsd/acpica/dist/compiler/aslrestype2w.c (revision c7960b37466ae0fd417c32e6acbb4b956ac7a121)
1 /******************************************************************************
2  *
3  * Module Name: aslrestype2w - Large Word address resource descriptors
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2023, 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 MERCHANTABILITY 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 
47 #define _COMPONENT          ACPI_COMPILER
48         ACPI_MODULE_NAME    ("aslrestype2w")
49 
50 /*
51  * This module contains the Word (16-bit) address space descriptors:
52  *
53  * WordIO
54  * WordMemory
55  * WordPcc
56  * WordSpace
57  */
58 
59 /*******************************************************************************
60  *
61  * FUNCTION:    RsDoWordIoDescriptor
62  *
63  * PARAMETERS:  Info                - Parse Op and resource template offset
64  *
65  * RETURN:      Completed resource node
66  *
67  * DESCRIPTION: Construct a long "WordIO" descriptor
68  *
69  ******************************************************************************/
70 
71 ASL_RESOURCE_NODE *
72 RsDoWordIoDescriptor (
73     ASL_RESOURCE_INFO       *Info)
74 {
75     AML_RESOURCE            *Descriptor;
76     ACPI_PARSE_OBJECT       *InitializerOp;
77     ACPI_PARSE_OBJECT       *MinOp = NULL;
78     ACPI_PARSE_OBJECT       *MaxOp = NULL;
79     ACPI_PARSE_OBJECT       *LengthOp = NULL;
80     ACPI_PARSE_OBJECT       *GranOp = NULL;
81     ASL_RESOURCE_NODE       *Rnode;
82     UINT8                   *OptionalFields;
83     UINT16                  StringLength = 0;
84     UINT32                  OptionIndex = 0;
85     UINT32                  CurrentByteOffset;
86     UINT32                  i;
87     BOOLEAN                 ResSourceIndex = FALSE;
88 
89 
90     InitializerOp = Info->DescriptorTypeOp->Asl.Child;
91     StringLength = RsGetStringDataLength (InitializerOp);
92     CurrentByteOffset = Info->CurrentByteOffset;
93 
94     Rnode = RsAllocateResourceNode (
95         sizeof (AML_RESOURCE_ADDRESS16) + 1 + StringLength);
96 
97     Descriptor = Rnode->Buffer;
98     Descriptor->Address16.DescriptorType = ACPI_RESOURCE_NAME_ADDRESS16;
99     Descriptor->Address16.ResourceType = ACPI_ADDRESS_TYPE_IO_RANGE;
100 
101     /*
102      * Initial descriptor length -- may be enlarged if there are
103      * optional fields present
104      */
105     OptionalFields = ((UINT8 *) Descriptor) + sizeof (AML_RESOURCE_ADDRESS16);
106     Descriptor->Address16.ResourceLength = (UINT16)
107         (sizeof (AML_RESOURCE_ADDRESS16) -
108          sizeof (AML_RESOURCE_LARGE_HEADER));
109 
110     /* Process all child initialization nodes */
111 
112     for (i = 0; InitializerOp; i++)
113     {
114         switch (i)
115         {
116         case 0: /* Resource Usage */
117 
118             RsSetFlagBits (&Descriptor->Address16.Flags, InitializerOp, 0, 1);
119             break;
120 
121         case 1: /* MinType */
122 
123             RsSetFlagBits (&Descriptor->Address16.Flags, InitializerOp, 2, 0);
124             RsCreateBitField (InitializerOp, ACPI_RESTAG_MINTYPE,
125                 CurrentByteOffset + ASL_RESDESC_OFFSET (Address16.Flags), 2);
126             break;
127 
128         case 2: /* MaxType */
129 
130             RsSetFlagBits (&Descriptor->Address16.Flags, InitializerOp, 3, 0);
131             RsCreateBitField (InitializerOp, ACPI_RESTAG_MAXTYPE,
132                 CurrentByteOffset + ASL_RESDESC_OFFSET (Address16.Flags), 3);
133             break;
134 
135         case 3: /* DecodeType */
136 
137             RsSetFlagBits (&Descriptor->Address16.Flags, InitializerOp, 1, 0);
138             RsCreateBitField (InitializerOp, ACPI_RESTAG_DECODE,
139                 CurrentByteOffset + ASL_RESDESC_OFFSET (Address16.Flags), 1);
140             break;
141 
142         case 4: /* Range Type */
143 
144             RsSetFlagBits (&Descriptor->Address16.SpecificFlags, InitializerOp, 0, 3);
145             RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_RANGETYPE,
146                 CurrentByteOffset + ASL_RESDESC_OFFSET (Address16.SpecificFlags), 0, 2);
147             break;
148 
149         case 5: /* Address Granularity */
150 
151             Descriptor->Address16.Granularity = (UINT16) InitializerOp->Asl.Value.Integer;
152             RsCreateWordField (InitializerOp, ACPI_RESTAG_GRANULARITY,
153                 CurrentByteOffset + ASL_RESDESC_OFFSET (Address16.Granularity));
154             GranOp = InitializerOp;
155             break;
156 
157         case 6: /* Address Min */
158 
159             Descriptor->Address16.Minimum = (UINT16) InitializerOp->Asl.Value.Integer;
160             RsCreateWordField (InitializerOp, ACPI_RESTAG_MINADDR,
161                 CurrentByteOffset + ASL_RESDESC_OFFSET (Address16.Minimum));
162             MinOp = InitializerOp;
163             break;
164 
165         case 7: /* Address Max */
166 
167             Descriptor->Address16.Maximum = (UINT16) InitializerOp->Asl.Value.Integer;
168             RsCreateWordField (InitializerOp, ACPI_RESTAG_MAXADDR,
169                 CurrentByteOffset + ASL_RESDESC_OFFSET (Address16.Maximum));
170             MaxOp = InitializerOp;
171             break;
172 
173         case 8: /* Translation Offset */
174 
175             Descriptor->Address16.TranslationOffset = (UINT16) InitializerOp->Asl.Value.Integer;
176             RsCreateWordField (InitializerOp, ACPI_RESTAG_TRANSLATION,
177                 CurrentByteOffset + ASL_RESDESC_OFFSET (Address16.TranslationOffset));
178             break;
179 
180         case 9: /* Address Length */
181 
182             Descriptor->Address16.AddressLength = (UINT16) InitializerOp->Asl.Value.Integer;
183             RsCreateWordField (InitializerOp, ACPI_RESTAG_LENGTH,
184                  CurrentByteOffset + ASL_RESDESC_OFFSET (Address16.AddressLength));
185             LengthOp = InitializerOp;
186             break;
187 
188         case 10: /* ResSourceIndex [Optional Field - BYTE] */
189 
190             if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
191             {
192                 OptionalFields[0] = (UINT8) InitializerOp->Asl.Value.Integer;
193                 OptionIndex++;
194                 Descriptor->Address16.ResourceLength++;
195                 ResSourceIndex = TRUE;
196             }
197             break;
198 
199         case 11: /* ResSource [Optional Field - STRING] */
200 
201             if ((InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) &&
202                 (InitializerOp->Asl.Value.String))
203             {
204                 if (StringLength)
205                 {
206                     Descriptor->Address16.ResourceLength = (UINT16)
207                         (Descriptor->Address16.ResourceLength + StringLength);
208 
209                     strcpy ((char *)
210                         &OptionalFields[OptionIndex],
211                         InitializerOp->Asl.Value.String);
212 
213                     /* ResourceSourceIndex must also be valid */
214 
215                     if (!ResSourceIndex)
216                     {
217                         AslError (ASL_ERROR, ASL_MSG_RESOURCE_INDEX,
218                             InitializerOp, NULL);
219                     }
220                 }
221             }
222 
223 #if 0
224             /*
225              * Not a valid ResourceSource, ResourceSourceIndex must also
226              * be invalid
227              */
228             else if (ResSourceIndex)
229             {
230                 AslError (ASL_ERROR, ASL_MSG_RESOURCE_SOURCE,
231                     InitializerOp, NULL);
232             }
233 #endif
234             break;
235 
236         case 12: /* ResourceTag */
237 
238             UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
239             break;
240 
241         case 13: /* Type */
242 
243             RsSetFlagBits (&Descriptor->Address16.SpecificFlags, InitializerOp, 4, 0);
244             RsCreateBitField (InitializerOp, ACPI_RESTAG_TYPE,
245                 CurrentByteOffset + ASL_RESDESC_OFFSET (Address16.SpecificFlags), 4);
246             break;
247 
248         case 14: /* Translation Type */
249 
250             RsSetFlagBits (&Descriptor->Address16.SpecificFlags, InitializerOp, 5, 0);
251             RsCreateBitField (InitializerOp, ACPI_RESTAG_TRANSTYPE,
252                 CurrentByteOffset + ASL_RESDESC_OFFSET (Address16.SpecificFlags), 5);
253             break;
254 
255         default:
256 
257             AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL);
258             break;
259         }
260 
261         InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
262     }
263 
264     /* Validate the Min/Max/Len/Gran values */
265 
266     RsLargeAddressCheck (
267         (UINT64) Descriptor->Address16.Minimum,
268         (UINT64) Descriptor->Address16.Maximum,
269         (UINT64) Descriptor->Address16.AddressLength,
270         (UINT64) Descriptor->Address16.Granularity,
271         Descriptor->Address16.Flags,
272         MinOp, MaxOp, LengthOp, GranOp, Info->DescriptorTypeOp);
273 
274     Rnode->BufferLength = sizeof (AML_RESOURCE_ADDRESS16) +
275         OptionIndex + StringLength;
276     return (Rnode);
277 }
278 
279 
280 /*******************************************************************************
281  *
282  * FUNCTION:    RsDoWordBusNumberDescriptor
283  *
284  * PARAMETERS:  Info                - Parse Op and resource template offset
285  *
286  * RETURN:      Completed resource node
287  *
288  * DESCRIPTION: Construct a long "WordBusNumber" descriptor
289  *
290  ******************************************************************************/
291 
292 ASL_RESOURCE_NODE *
293 RsDoWordBusNumberDescriptor (
294     ASL_RESOURCE_INFO       *Info)
295 {
296     AML_RESOURCE            *Descriptor;
297     ACPI_PARSE_OBJECT       *InitializerOp;
298     ACPI_PARSE_OBJECT       *MinOp = NULL;
299     ACPI_PARSE_OBJECT       *MaxOp = NULL;
300     ACPI_PARSE_OBJECT       *LengthOp = NULL;
301     ACPI_PARSE_OBJECT       *GranOp = NULL;
302     ASL_RESOURCE_NODE       *Rnode;
303     UINT8                   *OptionalFields;
304     UINT16                  StringLength = 0;
305     UINT32                  OptionIndex = 0;
306     UINT32                  CurrentByteOffset;
307     UINT32                  i;
308     BOOLEAN                 ResSourceIndex = FALSE;
309 
310 
311     InitializerOp = Info->DescriptorTypeOp->Asl.Child;
312     StringLength = RsGetStringDataLength (InitializerOp);
313     CurrentByteOffset = Info->CurrentByteOffset;
314 
315     Rnode = RsAllocateResourceNode (
316         sizeof (AML_RESOURCE_ADDRESS16) + 1 + StringLength);
317 
318     Descriptor = Rnode->Buffer;
319     Descriptor->Address16.DescriptorType = ACPI_RESOURCE_NAME_ADDRESS16;
320     Descriptor->Address16.ResourceType = ACPI_ADDRESS_TYPE_BUS_NUMBER_RANGE;
321 
322     /*
323      * Initial descriptor length -- may be enlarged if there are
324      * optional fields present
325      */
326     OptionalFields = ((UINT8 *) Descriptor) + sizeof (AML_RESOURCE_ADDRESS16);
327     Descriptor->Address16.ResourceLength = (UINT16)
328         (sizeof (AML_RESOURCE_ADDRESS16) -
329          sizeof (AML_RESOURCE_LARGE_HEADER));
330 
331     /* Process all child initialization nodes */
332 
333     for (i = 0; InitializerOp; i++)
334     {
335         switch (i)
336         {
337         case 0: /* Resource Usage */
338 
339             RsSetFlagBits (&Descriptor->Address16.Flags, InitializerOp, 0, 1);
340             break;
341 
342         case 1: /* MinType */
343 
344             RsSetFlagBits (&Descriptor->Address16.Flags, InitializerOp, 2, 0);
345             RsCreateBitField (InitializerOp, ACPI_RESTAG_MINTYPE,
346                 CurrentByteOffset + ASL_RESDESC_OFFSET (Address16.Flags), 2);
347             break;
348 
349         case 2: /* MaxType */
350 
351             RsSetFlagBits (&Descriptor->Address16.Flags, InitializerOp, 3, 0);
352             RsCreateBitField (InitializerOp, ACPI_RESTAG_MAXTYPE,
353                 CurrentByteOffset + ASL_RESDESC_OFFSET (Address16.Flags), 3);
354             break;
355 
356         case 3: /* DecodeType */
357 
358             RsSetFlagBits (&Descriptor->Address16.Flags, InitializerOp, 1, 0);
359             RsCreateBitField (InitializerOp, ACPI_RESTAG_DECODE,
360                 CurrentByteOffset + ASL_RESDESC_OFFSET (Address16.Flags), 1);
361             break;
362 
363         case 4: /* Address Granularity */
364 
365             Descriptor->Address16.Granularity =
366                 (UINT16) InitializerOp->Asl.Value.Integer;
367             RsCreateWordField (InitializerOp, ACPI_RESTAG_GRANULARITY,
368                 CurrentByteOffset + ASL_RESDESC_OFFSET (Address16.Granularity));
369             GranOp = InitializerOp;
370             break;
371 
372         case 5: /* Min Address */
373 
374             Descriptor->Address16.Minimum =
375                 (UINT16) InitializerOp->Asl.Value.Integer;
376             RsCreateWordField (InitializerOp, ACPI_RESTAG_MINADDR,
377                 CurrentByteOffset + ASL_RESDESC_OFFSET (Address16.Minimum));
378             MinOp = InitializerOp;
379             break;
380 
381         case 6: /* Max Address */
382 
383             Descriptor->Address16.Maximum =
384                 (UINT16) InitializerOp->Asl.Value.Integer;
385             RsCreateWordField (InitializerOp, ACPI_RESTAG_MAXADDR,
386                 CurrentByteOffset + ASL_RESDESC_OFFSET (Address16.Maximum));
387             MaxOp = InitializerOp;
388             break;
389 
390         case 7: /* Translation Offset */
391 
392             Descriptor->Address16.TranslationOffset =
393                 (UINT16) InitializerOp->Asl.Value.Integer;
394             RsCreateWordField (InitializerOp, ACPI_RESTAG_TRANSLATION,
395                 CurrentByteOffset + ASL_RESDESC_OFFSET (Address16.TranslationOffset));
396             break;
397 
398         case 8: /* Address Length */
399 
400             Descriptor->Address16.AddressLength =
401                 (UINT16) InitializerOp->Asl.Value.Integer;
402             RsCreateWordField (InitializerOp, ACPI_RESTAG_LENGTH,
403                  CurrentByteOffset + ASL_RESDESC_OFFSET (Address16.AddressLength));
404             LengthOp = InitializerOp;
405             break;
406 
407         case 9: /* ResSourceIndex [Optional Field - BYTE] */
408 
409             if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
410             {
411                 OptionalFields[0] = (UINT8) InitializerOp->Asl.Value.Integer;
412                 OptionIndex++;
413                 Descriptor->Address16.ResourceLength++;
414                 ResSourceIndex = TRUE;
415             }
416             break;
417 
418         case 10: /* ResSource [Optional Field - STRING] */
419 
420             if ((InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) &&
421                 (InitializerOp->Asl.Value.String))
422             {
423                 if (StringLength)
424                 {
425                     Descriptor->Address16.ResourceLength = (UINT16)
426                         (Descriptor->Address16.ResourceLength + StringLength);
427 
428                     strcpy ((char *)
429                         &OptionalFields[OptionIndex],
430                         InitializerOp->Asl.Value.String);
431 
432                     /* ResourceSourceIndex must also be valid */
433 
434                     if (!ResSourceIndex)
435                     {
436                         AslError (ASL_ERROR, ASL_MSG_RESOURCE_INDEX,
437                             InitializerOp, NULL);
438                     }
439                 }
440             }
441 
442 #if 0
443             /*
444              * Not a valid ResourceSource, ResourceSourceIndex must also
445              * be invalid
446              */
447             else if (ResSourceIndex)
448             {
449                 AslError (ASL_ERROR, ASL_MSG_RESOURCE_SOURCE,
450                     InitializerOp, NULL);
451             }
452 #endif
453             break;
454 
455         case 11: /* ResourceTag */
456 
457             UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
458             break;
459 
460         default:
461 
462             AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL);
463             break;
464         }
465 
466         InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
467     }
468 
469     /* Validate the Min/Max/Len/Gran values */
470 
471     RsLargeAddressCheck (
472         (UINT64) Descriptor->Address16.Minimum,
473         (UINT64) Descriptor->Address16.Maximum,
474         (UINT64) Descriptor->Address16.AddressLength,
475         (UINT64) Descriptor->Address16.Granularity,
476         Descriptor->Address16.Flags,
477         MinOp, MaxOp, LengthOp, GranOp, Info->DescriptorTypeOp);
478 
479     Rnode->BufferLength = sizeof (AML_RESOURCE_ADDRESS16) +
480         OptionIndex + StringLength;
481     return (Rnode);
482 }
483 
484 
485 /*******************************************************************************
486  *
487  * FUNCTION:    RsDoWordPccDescriptor
488  *
489  * PARAMETERS:  Info                - Parse Op and resource template offset
490  *
491  * RETURN:      Completed resource node
492  *
493  * DESCRIPTION: Construct a long "WordPcc" descriptor
494  *
495  ******************************************************************************/
496 
497 ASL_RESOURCE_NODE *
498 RsDoWordPccDescriptor (
499     ASL_RESOURCE_INFO       *Info)
500 {
501     AML_RESOURCE            *Descriptor;
502     ACPI_PARSE_OBJECT       *InitializerOp;
503     ACPI_PARSE_OBJECT       *MinOp = NULL;
504     ACPI_PARSE_OBJECT       *MaxOp = NULL;
505     ACPI_PARSE_OBJECT       *LengthOp = NULL;
506     ACPI_PARSE_OBJECT       *GranOp = NULL;
507     ASL_RESOURCE_NODE       *Rnode;
508     UINT16                  StringLength = 0;
509     UINT32                  OptionIndex = 0;
510     UINT8                   *OptionalFields;
511     UINT32                  i;
512     BOOLEAN                 ResSourceIndex = FALSE;
513 
514 
515     InitializerOp = Info->DescriptorTypeOp->Asl.Child;
516     StringLength = RsGetStringDataLength (InitializerOp);
517 
518     Rnode = RsAllocateResourceNode (
519         sizeof (AML_RESOURCE_ADDRESS32) + 1 + StringLength);
520 
521     Descriptor = Rnode->Buffer;
522     Descriptor->Address32.DescriptorType = ACPI_RESOURCE_NAME_ADDRESS32;
523     Descriptor->Address32.ResourceType  = ACPI_ADDRESS_TYPE_PCC_NUMBER;
524 
525     /*
526      * Initial descriptor length -- may be enlarged if there are
527      * optional fields present
528      */
529     OptionalFields = ((UINT8 *) Descriptor) + sizeof (AML_RESOURCE_ADDRESS32);
530     Descriptor->Address32.ResourceLength = (UINT16)
531         (sizeof (AML_RESOURCE_ADDRESS32) -
532          sizeof (AML_RESOURCE_LARGE_HEADER));
533 
534 
535     /*
536     * Bit [3] Max Address Fixed, _MAF: 1 (max address is fixed)
537     * Bit [2] Min Address Fixed,_MIF: 1 (min address is fixed)
538     * Bit [1] Decode Type, _DEC: 0 (do not care)
539     * BIT [0] Ignored (must be zero)
540     */
541     Descriptor->Address32.Flags = 0b1100;
542 
543     // No type specific flags. Set to 0.
544     Descriptor->Address32.SpecificFlags = 0;
545 
546     // must be set to zero if _MAX == _MIN.
547     Descriptor->Address32.Granularity = 0x0;
548     /* Process all child initialization nodes */
549 
550     // No translation offset.
551     Descriptor->Address32.TranslationOffset = 0;
552 
553     // Pcc is unique address.
554     Descriptor->Address32.AddressLength = 1;
555 
556     for (i = 0; InitializerOp; i++)
557     {
558         switch (i)
559         {
560 
561         case 0: /* Address Min = Max */
562 
563             Descriptor->Address32.Minimum =
564                 (UINT32) InitializerOp->Asl.Value.Integer;
565             Descriptor->Address32.Maximum =
566                 (UINT32) InitializerOp->Asl.Value.Integer;
567 
568             break;
569 
570         case 1: /* ResSourceIndex [Optional Field - BYTE] */
571 
572             if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
573             {
574                 /* Found a valid ResourceSourceIndex */
575 
576                 OptionalFields[0] = (UINT8) InitializerOp->Asl.Value.Integer;
577                 OptionIndex++;
578                 Descriptor->Address32.ResourceLength++;
579                 ResSourceIndex = TRUE;
580             }
581             break;
582 
583         case 2: /* ResSource [Optional Field - STRING] */
584 
585             if ((InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) &&
586                 (InitializerOp->Asl.Value.String))
587             {
588                 if (StringLength)
589                 {
590                     /* Found a valid ResourceSource */
591 
592                     Descriptor->Address32.ResourceLength = (UINT16)
593                         (Descriptor->Address32.ResourceLength + StringLength);
594 
595                     strcpy ((char *)
596                         &OptionalFields[OptionIndex],
597                         InitializerOp->Asl.Value.String);
598 
599                     /* ResourceSourceIndex must also be valid */
600 
601                     if (!ResSourceIndex)
602                     {
603                         AslError (ASL_ERROR, ASL_MSG_RESOURCE_INDEX,
604                             InitializerOp, NULL);
605                     }
606                 }
607             }
608 
609             break;
610 
611         case 3: // DescriptorName
612             UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
613             break;
614 
615         default:
616 
617             AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL);
618             break;
619         }
620 
621         InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
622     }
623 
624     /* Validate the Min/Max/Len/Gran values */
625 
626     RsLargeAddressCheck (
627         (UINT64) Descriptor->Address32.Minimum,
628         (UINT64) Descriptor->Address32.Maximum,
629         (UINT64) Descriptor->Address32.AddressLength,
630         (UINT64) Descriptor->Address32.Granularity,
631         Descriptor->Address32.Flags,
632         MinOp, MaxOp, LengthOp, GranOp, Info->DescriptorTypeOp);
633 
634     Rnode->BufferLength = sizeof (AML_RESOURCE_ADDRESS32) +
635         OptionIndex + StringLength;
636     return (Rnode);
637 }
638 
639 
640 /*******************************************************************************
641  *
642  * FUNCTION:    RsDoWordSpaceDescriptor
643  *
644  * PARAMETERS:  Info                - Parse Op and resource template offset
645  *
646  * RETURN:      Completed resource node
647  *
648  * DESCRIPTION: Construct a long "WordSpace" descriptor
649  *
650  ******************************************************************************/
651 
652 ASL_RESOURCE_NODE *
653 RsDoWordSpaceDescriptor (
654     ASL_RESOURCE_INFO       *Info)
655 {
656     AML_RESOURCE            *Descriptor;
657     ACPI_PARSE_OBJECT       *InitializerOp;
658     ACPI_PARSE_OBJECT       *MinOp = NULL;
659     ACPI_PARSE_OBJECT       *MaxOp = NULL;
660     ACPI_PARSE_OBJECT       *LengthOp = NULL;
661     ACPI_PARSE_OBJECT       *GranOp = NULL;
662     ASL_RESOURCE_NODE       *Rnode;
663     UINT8                   *OptionalFields;
664     UINT16                  StringLength = 0;
665     UINT32                  OptionIndex = 0;
666     UINT32                  CurrentByteOffset;
667     UINT32                  i;
668     BOOLEAN                 ResSourceIndex = FALSE;
669 
670 
671     InitializerOp = Info->DescriptorTypeOp->Asl.Child;
672     StringLength = RsGetStringDataLength (InitializerOp);
673     CurrentByteOffset = Info->CurrentByteOffset;
674 
675     Rnode = RsAllocateResourceNode (
676         sizeof (AML_RESOURCE_ADDRESS16) + 1 + StringLength);
677 
678     Descriptor = Rnode->Buffer;
679     Descriptor->Address16.DescriptorType = ACPI_RESOURCE_NAME_ADDRESS16;
680 
681     /*
682      * Initial descriptor length -- may be enlarged if there are
683      * optional fields present
684      */
685     OptionalFields = ((UINT8 *) Descriptor) + sizeof (AML_RESOURCE_ADDRESS16);
686     Descriptor->Address16.ResourceLength = (UINT16)
687         (sizeof (AML_RESOURCE_ADDRESS16) -
688          sizeof (AML_RESOURCE_LARGE_HEADER));
689 
690     /* Process all child initialization nodes */
691 
692     for (i = 0; InitializerOp; i++)
693     {
694         switch (i)
695         {
696         case 0: /* Resource Type */
697 
698             Descriptor->Address16.ResourceType =
699                 (UINT8) InitializerOp->Asl.Value.Integer;
700             break;
701 
702         case 1: /* Resource Usage */
703 
704             RsSetFlagBits (&Descriptor->Address16.Flags, InitializerOp, 0, 1);
705             break;
706 
707         case 2: /* DecodeType */
708 
709             RsSetFlagBits (&Descriptor->Address16.Flags, InitializerOp, 1, 0);
710             RsCreateBitField (InitializerOp, ACPI_RESTAG_DECODE,
711                 CurrentByteOffset + ASL_RESDESC_OFFSET (Address16.Flags), 1);
712             break;
713 
714         case 3: /* MinType */
715 
716             RsSetFlagBits (&Descriptor->Address16.Flags, InitializerOp, 2, 0);
717             RsCreateBitField (InitializerOp, ACPI_RESTAG_MINTYPE,
718                 CurrentByteOffset + ASL_RESDESC_OFFSET (Address16.Flags), 2);
719             break;
720 
721         case 4: /* MaxType */
722 
723             RsSetFlagBits (&Descriptor->Address16.Flags, InitializerOp, 3, 0);
724             RsCreateBitField (InitializerOp, ACPI_RESTAG_MAXTYPE,
725                 CurrentByteOffset + ASL_RESDESC_OFFSET (Address16.Flags), 3);
726             break;
727 
728         case 5: /* Type-Specific flags */
729 
730             Descriptor->Address16.SpecificFlags =
731                 (UINT8) InitializerOp->Asl.Value.Integer;
732             break;
733 
734         case 6: /* Address Granularity */
735 
736             Descriptor->Address16.Granularity =
737                 (UINT16) InitializerOp->Asl.Value.Integer;
738             RsCreateWordField (InitializerOp, ACPI_RESTAG_GRANULARITY,
739                 CurrentByteOffset + ASL_RESDESC_OFFSET (Address16.Granularity));
740             GranOp = InitializerOp;
741             break;
742 
743         case 7: /* Min Address */
744 
745             Descriptor->Address16.Minimum =
746                 (UINT16) InitializerOp->Asl.Value.Integer;
747             RsCreateWordField (InitializerOp, ACPI_RESTAG_MINADDR,
748                 CurrentByteOffset + ASL_RESDESC_OFFSET (Address16.Minimum));
749             MinOp = InitializerOp;
750             break;
751 
752         case 8: /* Max Address */
753 
754             Descriptor->Address16.Maximum =
755                 (UINT16) InitializerOp->Asl.Value.Integer;
756             RsCreateWordField (InitializerOp, ACPI_RESTAG_MAXADDR,
757                 CurrentByteOffset + ASL_RESDESC_OFFSET (Address16.Maximum));
758             MaxOp = InitializerOp;
759             break;
760 
761         case 9: /* Translation Offset */
762 
763             Descriptor->Address16.TranslationOffset =
764                 (UINT16) InitializerOp->Asl.Value.Integer;
765             RsCreateWordField (InitializerOp, ACPI_RESTAG_TRANSLATION,
766                 CurrentByteOffset + ASL_RESDESC_OFFSET (Address16.TranslationOffset));
767             break;
768 
769         case 10: /* Address Length */
770 
771             Descriptor->Address16.AddressLength =
772                 (UINT16) InitializerOp->Asl.Value.Integer;
773             RsCreateWordField (InitializerOp, ACPI_RESTAG_LENGTH,
774                 CurrentByteOffset + ASL_RESDESC_OFFSET (Address16.AddressLength));
775             LengthOp = InitializerOp;
776             break;
777 
778         case 11: /* ResSourceIndex [Optional Field - BYTE] */
779 
780             if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
781             {
782                 OptionalFields[0] = (UINT8) InitializerOp->Asl.Value.Integer;
783                 OptionIndex++;
784                 Descriptor->Address16.ResourceLength++;
785                 ResSourceIndex = TRUE;
786             }
787             break;
788 
789         case 12: /* ResSource [Optional Field - STRING] */
790 
791             if ((InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) &&
792                 (InitializerOp->Asl.Value.String))
793             {
794                 if (StringLength)
795                 {
796                     Descriptor->Address16.ResourceLength = (UINT16)
797                         (Descriptor->Address16.ResourceLength + StringLength);
798 
799                     strcpy ((char *)
800                         &OptionalFields[OptionIndex],
801                         InitializerOp->Asl.Value.String);
802 
803                     /* ResourceSourceIndex must also be valid */
804 
805                     if (!ResSourceIndex)
806                     {
807                         AslError (ASL_ERROR, ASL_MSG_RESOURCE_INDEX,
808                             InitializerOp, NULL);
809                     }
810                 }
811             }
812 
813 #if 0
814             /*
815              * Not a valid ResourceSource, ResourceSourceIndex must also
816              * be invalid
817              */
818             else if (ResSourceIndex)
819             {
820                 AslError (ASL_ERROR, ASL_MSG_RESOURCE_SOURCE,
821                     InitializerOp, NULL);
822             }
823 #endif
824             break;
825 
826         case 13: /* ResourceTag */
827 
828             UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp);
829             break;
830 
831         default:
832 
833             AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL);
834             break;
835         }
836 
837         InitializerOp = RsCompleteNodeAndGetNext (InitializerOp);
838     }
839 
840     /* Validate the Min/Max/Len/Gran values */
841 
842     RsLargeAddressCheck (
843         (UINT64) Descriptor->Address16.Minimum,
844         (UINT64) Descriptor->Address16.Maximum,
845         (UINT64) Descriptor->Address16.AddressLength,
846         (UINT64) Descriptor->Address16.Granularity,
847         Descriptor->Address16.Flags,
848         MinOp, MaxOp, LengthOp, GranOp, Info->DescriptorTypeOp);
849 
850     Rnode->BufferLength = sizeof (AML_RESOURCE_ADDRESS16) +
851         OptionIndex + StringLength;
852     return (Rnode);
853 }
854