aslresource.c revision 1.1.1.2 1
2 /******************************************************************************
3 *
4 * Module Name: aslresource - Resource template/descriptor utilities
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 "aslcompiler.h"
47 #include "aslcompiler.y.h"
48 #include "amlcode.h"
49
50
51 #define _COMPONENT ACPI_COMPILER
52 ACPI_MODULE_NAME ("aslresource")
53
54
55 /*******************************************************************************
56 *
57 * FUNCTION: RsSmallAddressCheck
58 *
59 * PARAMETERS: Minimum - Address Min value
60 * Maximum - Address Max value
61 * Length - Address range value
62 * Alignment - Address alignment value
63 * MinOp - Original Op for Address Min
64 * MaxOp - Original Op for Address Max
65 * LengthOp - Original Op for address range
66 * AlignOp - Original Op for address alignment. If
67 * NULL, means "zero value for alignment is
68 * OK, and means 64K alignment" (for
69 * Memory24 descriptor)
70 * Op - Parent Op for entire construct
71 *
72 * RETURN: None. Adds error messages to error log if necessary
73 *
74 * DESCRIPTION: Perform common value checks for "small" address descriptors.
75 * Currently:
76 * Io, Memory24, Memory32
77 *
78 ******************************************************************************/
79
80 void
81 RsSmallAddressCheck (
82 UINT8 Type,
83 UINT32 Minimum,
84 UINT32 Maximum,
85 UINT32 Length,
86 UINT32 Alignment,
87 ACPI_PARSE_OBJECT *MinOp,
88 ACPI_PARSE_OBJECT *MaxOp,
89 ACPI_PARSE_OBJECT *LengthOp,
90 ACPI_PARSE_OBJECT *AlignOp,
91 ACPI_PARSE_OBJECT *Op)
92 {
93
94 if (Gbl_NoResourceChecking)
95 {
96 return;
97 }
98
99 /*
100 * Check for a so-called "null descriptor". These are descriptors that are
101 * created with most fields set to zero. The intent is that the descriptor
102 * will be updated/completed at runtime via a BufferField.
103 *
104 * If the descriptor does NOT have a resource tag, it cannot be referenced
105 * by a BufferField and we will flag this as an error. Conversely, if
106 * the descriptor has a resource tag, we will assume that a BufferField
107 * will be used to dynamically update it, so no error.
108 *
109 * A possible enhancement to this check would be to verify that in fact
110 * a BufferField is created using the resource tag, and perhaps even
111 * verify that a Store is performed to the BufferField.
112 *
113 * Note: for these descriptors, Alignment is allowed to be zero
114 */
115 if (!Minimum && !Maximum && !Length)
116 {
117 if (!Op->Asl.ExternalName)
118 {
119 /* No resource tag. Descriptor is fixed and is also illegal */
120
121 AslError (ASL_ERROR, ASL_MSG_NULL_DESCRIPTOR, Op, NULL);
122 }
123
124 return;
125 }
126
127 /* Special case for Memory24, values are compressed */
128
129 if (Type == ACPI_RESOURCE_NAME_MEMORY24)
130 {
131 if (!Alignment) /* Alignment==0 means 64K - no invalid alignment */
132 {
133 Alignment = ACPI_UINT16_MAX + 1;
134 }
135
136 Minimum <<= 8;
137 Maximum <<= 8;
138 Length *= 256;
139 }
140
141 /* IO descriptor has different definition of min/max, don't check */
142
143 if (Type != ACPI_RESOURCE_NAME_IO)
144 {
145 /* Basic checks on Min/Max/Length */
146
147 if (Minimum > Maximum)
148 {
149 AslError (ASL_ERROR, ASL_MSG_INVALID_MIN_MAX, MinOp, NULL);
150 }
151 else if (Length > (Maximum - Minimum + 1))
152 {
153 AslError (ASL_ERROR, ASL_MSG_INVALID_LENGTH, LengthOp, NULL);
154 }
155 }
156
157 /* Alignment of zero is not in ACPI spec, but is used to mean byte acc */
158
159 if (!Alignment)
160 {
161 Alignment = 1;
162 }
163
164 /* Addresses must be an exact multiple of the alignment value */
165
166 if (Minimum % Alignment)
167 {
168 AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MinOp, NULL);
169 }
170 if (Maximum % Alignment)
171 {
172 AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MaxOp, NULL);
173 }
174 }
175
176
177 /*******************************************************************************
178 *
179 * FUNCTION: RsLargeAddressCheck
180 *
181 * PARAMETERS: Minimum - Address Min value
182 * Maximum - Address Max value
183 * Length - Address range value
184 * Granularity - Address granularity value
185 * Flags - General flags for address descriptors:
186 * _MIF, _MAF, _DEC
187 * MinOp - Original Op for Address Min
188 * MaxOp - Original Op for Address Max
189 * LengthOp - Original Op for address range
190 * GranOp - Original Op for address granularity
191 * Op - Parent Op for entire construct
192 *
193 * RETURN: None. Adds error messages to error log if necessary
194 *
195 * DESCRIPTION: Perform common value checks for "large" address descriptors.
196 * Currently:
197 * WordIo, WordBusNumber, WordSpace
198 * DWordIo, DWordMemory, DWordSpace
199 * QWordIo, QWordMemory, QWordSpace
200 * ExtendedIo, ExtendedMemory, ExtendedSpace
201 *
202 * _MIF flag set means that the minimum address is fixed and is not relocatable
203 * _MAF flag set means that the maximum address is fixed and is not relocatable
204 * Length of zero means that the record size is variable
205 *
206 * This function implements the LEN/MIF/MAF/MIN/MAX/GRA rules within Table 6-40
207 * of the ACPI 4.0a specification. Added 04/2010.
208 *
209 ******************************************************************************/
210
211 void
212 RsLargeAddressCheck (
213 UINT64 Minimum,
214 UINT64 Maximum,
215 UINT64 Length,
216 UINT64 Granularity,
217 UINT8 Flags,
218 ACPI_PARSE_OBJECT *MinOp,
219 ACPI_PARSE_OBJECT *MaxOp,
220 ACPI_PARSE_OBJECT *LengthOp,
221 ACPI_PARSE_OBJECT *GranOp,
222 ACPI_PARSE_OBJECT *Op)
223 {
224
225 if (Gbl_NoResourceChecking)
226 {
227 return;
228 }
229
230 /*
231 * Check for a so-called "null descriptor". These are descriptors that are
232 * created with most fields set to zero. The intent is that the descriptor
233 * will be updated/completed at runtime via a BufferField.
234 *
235 * If the descriptor does NOT have a resource tag, it cannot be referenced
236 * by a BufferField and we will flag this as an error. Conversely, if
237 * the descriptor has a resource tag, we will assume that a BufferField
238 * will be used to dynamically update it, so no error.
239 *
240 * A possible enhancement to this check would be to verify that in fact
241 * a BufferField is created using the resource tag, and perhaps even
242 * verify that a Store is performed to the BufferField.
243 */
244 if (!Minimum && !Maximum && !Length && !Granularity)
245 {
246 if (!Op->Asl.ExternalName)
247 {
248 /* No resource tag. Descriptor is fixed and is also illegal */
249
250 AslError (ASL_ERROR, ASL_MSG_NULL_DESCRIPTOR, Op, NULL);
251 }
252
253 return;
254 }
255
256 /* Basic checks on Min/Max/Length */
257
258 if (Minimum > Maximum)
259 {
260 AslError (ASL_ERROR, ASL_MSG_INVALID_MIN_MAX, MinOp, NULL);
261 return;
262 }
263 else if (Length > (Maximum - Minimum + 1))
264 {
265 AslError (ASL_ERROR, ASL_MSG_INVALID_LENGTH, LengthOp, NULL);
266 return;
267 }
268
269 /* If specified (non-zero), ensure granularity is a power-of-two minus one */
270
271 if (Granularity)
272 {
273 if ((Granularity + 1) &
274 Granularity)
275 {
276 AslError (ASL_ERROR, ASL_MSG_INVALID_GRANULARITY, GranOp, NULL);
277 return;
278 }
279 }
280
281 /*
282 * Check the various combinations of Length, MinFixed, and MaxFixed
283 */
284 if (Length)
285 {
286 /* Fixed non-zero length */
287
288 switch (Flags & (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF))
289 {
290 case 0:
291 /*
292 * Fixed length, variable locations (both _MIN and _MAX).
293 * Length must be a multiple of granularity
294 */
295 if (Granularity & Length)
296 {
297 AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, LengthOp, NULL);
298 }
299 break;
300
301 case (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF):
302
303 /* Fixed length, fixed location. Granularity must be zero */
304
305 if (Granularity != 0)
306 {
307 AslError (ASL_ERROR, ASL_MSG_INVALID_GRAN_FIXED, GranOp, NULL);
308 }
309
310 /* Length must be exactly the size of the min/max window */
311
312 if (Length != (Maximum - Minimum + 1))
313 {
314 AslError (ASL_ERROR, ASL_MSG_INVALID_LENGTH_FIXED, LengthOp, NULL);
315 }
316 break;
317
318 /* All other combinations are invalid */
319
320 case ACPI_RESOURCE_FLAG_MIF:
321 case ACPI_RESOURCE_FLAG_MAF:
322 default:
323 AslError (ASL_ERROR, ASL_MSG_INVALID_ADDR_FLAGS, LengthOp, NULL);
324 }
325 }
326 else
327 {
328 /* Variable length (length==0) */
329
330 switch (Flags & (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF))
331 {
332 case 0:
333 /*
334 * Both _MIN and _MAX are variable.
335 * No additional requirements, just exit
336 */
337 break;
338
339 case ACPI_RESOURCE_FLAG_MIF:
340
341 /* _MIN is fixed. _MIN must be multiple of _GRA */
342
343 /*
344 * The granularity is defined by the ACPI specification to be a
345 * power-of-two minus one, therefore the granularity is a
346 * bitmask which can be used to easily validate the addresses.
347 */
348 if (Granularity & Minimum)
349 {
350 AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MinOp, NULL);
351 }
352 break;
353
354 case ACPI_RESOURCE_FLAG_MAF:
355
356 /* _MAX is fixed. (_MAX + 1) must be multiple of _GRA */
357
358 if (Granularity & (Maximum + 1))
359 {
360 AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MaxOp, "-1");
361 }
362 break;
363
364 /* Both MIF/MAF set is invalid if length is zero */
365
366 case (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF):
367 default:
368 AslError (ASL_ERROR, ASL_MSG_INVALID_ADDR_FLAGS, LengthOp, NULL);
369 }
370 }
371 }
372
373
374 /*******************************************************************************
375 *
376 * FUNCTION: RsGetStringDataLength
377 *
378 * PARAMETERS: InitializerOp - Start of a subtree of init nodes
379 *
380 * RETURN: Valid string length if a string node is found (otherwise 0)
381 *
382 * DESCRIPTION: In a list of peer nodes, find the first one that contains a
383 * string and return the length of the string.
384 *
385 ******************************************************************************/
386
387 UINT16
388 RsGetStringDataLength (
389 ACPI_PARSE_OBJECT *InitializerOp)
390 {
391
392 while (InitializerOp)
393 {
394 if (InitializerOp->Asl.ParseOpcode == PARSEOP_STRING_LITERAL)
395 {
396 return ((UINT16) (strlen (InitializerOp->Asl.Value.String) + 1));
397 }
398 InitializerOp = ASL_GET_PEER_NODE (InitializerOp);
399 }
400
401 return 0;
402 }
403
404
405 /*******************************************************************************
406 *
407 * FUNCTION: RsAllocateResourceNode
408 *
409 * PARAMETERS: Size - Size of node in bytes
410 *
411 * RETURN: The allocated node - aborts on allocation failure
412 *
413 * DESCRIPTION: Allocate a resource description node and the resource
414 * descriptor itself (the nodes are used to link descriptors).
415 *
416 ******************************************************************************/
417
418 ASL_RESOURCE_NODE *
419 RsAllocateResourceNode (
420 UINT32 Size)
421 {
422 ASL_RESOURCE_NODE *Rnode;
423
424
425 /* Allocate the node */
426
427 Rnode = UtLocalCalloc (sizeof (ASL_RESOURCE_NODE));
428
429 /* Allocate the resource descriptor itself */
430
431 Rnode->Buffer = UtLocalCalloc (Size);
432 Rnode->BufferLength = Size;
433
434 return (Rnode);
435 }
436
437
438 /*******************************************************************************
439 *
440 * FUNCTION: RsCreateBitField
441 *
442 * PARAMETERS: Op - Resource field node
443 * Name - Name of the field (Used only to reference
444 * the field in the ASL, not in the AML)
445 * ByteOffset - Offset from the field start
446 * BitOffset - Additional bit offset
447 *
448 * RETURN: None, sets fields within the input node
449 *
450 * DESCRIPTION: Utility function to generate a named bit field within a
451 * resource descriptor. Mark a node as 1) a field in a resource
452 * descriptor, and 2) set the value to be a BIT offset
453 *
454 ******************************************************************************/
455
456 void
457 RsCreateBitField (
458 ACPI_PARSE_OBJECT *Op,
459 char *Name,
460 UINT32 ByteOffset,
461 UINT32 BitOffset)
462 {
463
464 Op->Asl.ExternalName = Name;
465 Op->Asl.Value.Integer = ((UINT64) ByteOffset * 8) + BitOffset;
466 Op->Asl.CompileFlags |= (NODE_IS_RESOURCE_FIELD | NODE_IS_BIT_OFFSET);
467 }
468
469
470 /*******************************************************************************
471 *
472 * FUNCTION: RsCreateByteField
473 *
474 * PARAMETERS: Op - Resource field node
475 * Name - Name of the field (Used only to reference
476 * the field in the ASL, not in the AML)
477 * ByteOffset - Offset from the field start
478 *
479 * RETURN: None, sets fields within the input node
480 *
481 * DESCRIPTION: Utility function to generate a named byte field within a
482 * resource descriptor. Mark a node as 1) a field in a resource
483 * descriptor, and 2) set the value to be a BYTE offset
484 *
485 ******************************************************************************/
486
487 void
488 RsCreateByteField (
489 ACPI_PARSE_OBJECT *Op,
490 char *Name,
491 UINT32 ByteOffset)
492 {
493
494 Op->Asl.ExternalName = Name;
495 Op->Asl.Value.Integer = ByteOffset;
496 Op->Asl.CompileFlags |= NODE_IS_RESOURCE_FIELD;
497 }
498
499
500 /*******************************************************************************
501 *
502 * FUNCTION: RsSetFlagBits
503 *
504 * PARAMETERS: *Flags - Pointer to the flag byte
505 * Op - Flag initialization node
506 * Position - Bit position within the flag byte
507 * Default - Used if the node is DEFAULT.
508 *
509 * RETURN: Sets bits within the *Flags output byte.
510 *
511 * DESCRIPTION: Set a bit in a cumulative flags word from an initialization
512 * node. Will use a default value if the node is DEFAULT, meaning
513 * that no value was specified in the ASL. Used to merge multiple
514 * keywords into a single flags byte.
515 *
516 ******************************************************************************/
517
518 void
519 RsSetFlagBits (
520 UINT8 *Flags,
521 ACPI_PARSE_OBJECT *Op,
522 UINT8 Position,
523 UINT8 DefaultBit)
524 {
525
526 if (Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
527 {
528 /* Use the default bit */
529
530 *Flags |= (DefaultBit << Position);
531 }
532 else
533 {
534 /* Use the bit specified in the initialization node */
535
536 *Flags |= (((UINT8) Op->Asl.Value.Integer) << Position);
537 }
538 }
539
540
541 /*******************************************************************************
542 *
543 * FUNCTION: RsCompleteNodeAndGetNext
544 *
545 * PARAMETERS: Op - Resource node to be completed
546 *
547 * RETURN: The next peer to the input node.
548 *
549 * DESCRIPTION: Mark the current node completed and return the next peer.
550 * The node ParseOpcode is set to DEFAULT_ARG, meaning that
551 * this node is to be ignored from now on.
552 *
553 ******************************************************************************/
554
555 ACPI_PARSE_OBJECT *
556 RsCompleteNodeAndGetNext (
557 ACPI_PARSE_OBJECT *Op)
558 {
559
560 /* Mark this node unused */
561
562 Op->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
563
564 /* Move on to the next peer node in the initializer list */
565
566 return (ASL_GET_PEER_NODE (Op));
567 }
568
569
570 /*******************************************************************************
571 *
572 * FUNCTION: RsCheckListForDuplicates
573 *
574 * PARAMETERS: Op - First op in the initializer list
575 *
576 * RETURN: None
577 *
578 * DESCRIPTION: Check an initializer list for duplicate values. Emits an error
579 * if any duplicates are found.
580 *
581 ******************************************************************************/
582
583 void
584 RsCheckListForDuplicates (
585 ACPI_PARSE_OBJECT *Op)
586 {
587 ACPI_PARSE_OBJECT *NextValueOp = Op;
588 ACPI_PARSE_OBJECT *NextOp;
589 UINT32 Value;
590
591
592 if (!Op)
593 {
594 return;
595 }
596
597 /* Search list once for each value in the list */
598
599 while (NextValueOp)
600 {
601 Value = (UINT32) NextValueOp->Asl.Value.Integer;
602
603 /* Compare this value to all remaining values in the list */
604
605 NextOp = ASL_GET_PEER_NODE (NextValueOp);
606 while (NextOp)
607 {
608 if (NextOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
609 {
610 /* Compare values */
611
612 if (Value == (UINT32) NextOp->Asl.Value.Integer)
613 {
614 /* Emit error only once per duplicate node */
615
616 if (!(NextOp->Asl.CompileFlags & NODE_IS_DUPLICATE))
617 {
618 NextOp->Asl.CompileFlags |= NODE_IS_DUPLICATE;
619 AslError (ASL_ERROR, ASL_MSG_DUPLICATE_ITEM,
620 NextOp, NULL);
621 }
622 }
623 }
624
625 NextOp = ASL_GET_PEER_NODE (NextOp);
626 }
627
628 NextValueOp = ASL_GET_PEER_NODE (NextValueOp);
629 }
630 }
631
632
633 /*******************************************************************************
634 *
635 * FUNCTION: RsDoOneResourceDescriptor
636 *
637 * PARAMETERS: DescriptorTypeOp - Parent parse node of the descriptor
638 * CurrentByteOffset - Offset in the resource descriptor
639 * buffer.
640 *
641 * RETURN: A valid resource node for the descriptor
642 *
643 * DESCRIPTION: Dispatches the processing of one resource descriptor
644 *
645 ******************************************************************************/
646
647 ASL_RESOURCE_NODE *
648 RsDoOneResourceDescriptor (
649 ACPI_PARSE_OBJECT *DescriptorTypeOp,
650 UINT32 CurrentByteOffset,
651 UINT8 *State)
652 {
653 ASL_RESOURCE_NODE *Rnode = NULL;
654
655
656 /* Construct the resource */
657
658 switch (DescriptorTypeOp->Asl.ParseOpcode)
659 {
660 case PARSEOP_DMA:
661 Rnode = RsDoDmaDescriptor (DescriptorTypeOp,
662 CurrentByteOffset);
663 break;
664
665 case PARSEOP_DWORDIO:
666 Rnode = RsDoDwordIoDescriptor (DescriptorTypeOp,
667 CurrentByteOffset);
668 break;
669
670 case PARSEOP_DWORDMEMORY:
671 Rnode = RsDoDwordMemoryDescriptor (DescriptorTypeOp,
672 CurrentByteOffset);
673 break;
674
675 case PARSEOP_DWORDSPACE:
676 Rnode = RsDoDwordSpaceDescriptor (DescriptorTypeOp,
677 CurrentByteOffset);
678 break;
679
680 case PARSEOP_ENDDEPENDENTFN:
681 switch (*State)
682 {
683 case ACPI_RSTATE_NORMAL:
684 AslError (ASL_ERROR, ASL_MSG_MISSING_STARTDEPENDENT,
685 DescriptorTypeOp, NULL);
686 break;
687
688 case ACPI_RSTATE_START_DEPENDENT:
689 AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING,
690 DescriptorTypeOp, NULL);
691 break;
692
693 case ACPI_RSTATE_DEPENDENT_LIST:
694 default:
695 break;
696 }
697
698 *State = ACPI_RSTATE_NORMAL;
699 Rnode = RsDoEndDependentDescriptor (DescriptorTypeOp,
700 CurrentByteOffset);
701 break;
702
703 case PARSEOP_ENDTAG:
704 Rnode = RsDoEndTagDescriptor (DescriptorTypeOp,
705 CurrentByteOffset);
706 break;
707
708 case PARSEOP_EXTENDEDIO:
709 Rnode = RsDoExtendedIoDescriptor (DescriptorTypeOp,
710 CurrentByteOffset);
711 break;
712
713 case PARSEOP_EXTENDEDMEMORY:
714 Rnode = RsDoExtendedMemoryDescriptor (DescriptorTypeOp,
715 CurrentByteOffset);
716 break;
717
718 case PARSEOP_EXTENDEDSPACE:
719 Rnode = RsDoExtendedSpaceDescriptor (DescriptorTypeOp,
720 CurrentByteOffset);
721 break;
722
723 case PARSEOP_FIXEDIO:
724 Rnode = RsDoFixedIoDescriptor (DescriptorTypeOp,
725 CurrentByteOffset);
726 break;
727
728 case PARSEOP_INTERRUPT:
729 Rnode = RsDoInterruptDescriptor (DescriptorTypeOp,
730 CurrentByteOffset);
731 break;
732
733 case PARSEOP_IO:
734 Rnode = RsDoIoDescriptor (DescriptorTypeOp,
735 CurrentByteOffset);
736 break;
737
738 case PARSEOP_IRQ:
739 Rnode = RsDoIrqDescriptor (DescriptorTypeOp,
740 CurrentByteOffset);
741 break;
742
743 case PARSEOP_IRQNOFLAGS:
744 Rnode = RsDoIrqNoFlagsDescriptor (DescriptorTypeOp,
745 CurrentByteOffset);
746 break;
747
748 case PARSEOP_MEMORY24:
749 Rnode = RsDoMemory24Descriptor (DescriptorTypeOp,
750 CurrentByteOffset);
751 break;
752
753 case PARSEOP_MEMORY32:
754 Rnode = RsDoMemory32Descriptor (DescriptorTypeOp,
755 CurrentByteOffset);
756 break;
757
758 case PARSEOP_MEMORY32FIXED:
759 Rnode = RsDoMemory32FixedDescriptor (DescriptorTypeOp,
760 CurrentByteOffset);
761 break;
762
763 case PARSEOP_QWORDIO:
764 Rnode = RsDoQwordIoDescriptor (DescriptorTypeOp,
765 CurrentByteOffset);
766 break;
767
768 case PARSEOP_QWORDMEMORY:
769 Rnode = RsDoQwordMemoryDescriptor (DescriptorTypeOp,
770 CurrentByteOffset);
771 break;
772
773 case PARSEOP_QWORDSPACE:
774 Rnode = RsDoQwordSpaceDescriptor (DescriptorTypeOp,
775 CurrentByteOffset);
776 break;
777
778 case PARSEOP_REGISTER:
779 Rnode = RsDoGeneralRegisterDescriptor (DescriptorTypeOp,
780 CurrentByteOffset);
781 break;
782
783 case PARSEOP_STARTDEPENDENTFN:
784 switch (*State)
785 {
786 case ACPI_RSTATE_START_DEPENDENT:
787 AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING,
788 DescriptorTypeOp, NULL);
789 break;
790
791 case ACPI_RSTATE_NORMAL:
792 case ACPI_RSTATE_DEPENDENT_LIST:
793 default:
794 break;
795 }
796
797 *State = ACPI_RSTATE_START_DEPENDENT;
798 Rnode = RsDoStartDependentDescriptor (DescriptorTypeOp,
799 CurrentByteOffset);
800 *State = ACPI_RSTATE_DEPENDENT_LIST;
801 break;
802
803 case PARSEOP_STARTDEPENDENTFN_NOPRI:
804 switch (*State)
805 {
806 case ACPI_RSTATE_START_DEPENDENT:
807 AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING,
808 DescriptorTypeOp, NULL);
809 break;
810
811 case ACPI_RSTATE_NORMAL:
812 case ACPI_RSTATE_DEPENDENT_LIST:
813 default:
814 break;
815 }
816
817 *State = ACPI_RSTATE_START_DEPENDENT;
818 Rnode = RsDoStartDependentNoPriDescriptor (DescriptorTypeOp,
819 CurrentByteOffset);
820 *State = ACPI_RSTATE_DEPENDENT_LIST;
821 break;
822
823 case PARSEOP_VENDORLONG:
824 Rnode = RsDoVendorLargeDescriptor (DescriptorTypeOp,
825 CurrentByteOffset);
826 break;
827
828 case PARSEOP_VENDORSHORT:
829 Rnode = RsDoVendorSmallDescriptor (DescriptorTypeOp,
830 CurrentByteOffset);
831 break;
832
833 case PARSEOP_WORDBUSNUMBER:
834 Rnode = RsDoWordBusNumberDescriptor (DescriptorTypeOp,
835 CurrentByteOffset);
836 break;
837
838 case PARSEOP_WORDIO:
839 Rnode = RsDoWordIoDescriptor (DescriptorTypeOp,
840 CurrentByteOffset);
841 break;
842
843 case PARSEOP_WORDSPACE:
844 Rnode = RsDoWordSpaceDescriptor (DescriptorTypeOp,
845 CurrentByteOffset);
846 break;
847
848 case PARSEOP_DEFAULT_ARG:
849 /* Just ignore any of these, they are used as fillers/placeholders */
850 break;
851
852 default:
853 printf ("Unknown resource descriptor type [%s]\n",
854 DescriptorTypeOp->Asl.ParseOpName);
855 break;
856 }
857
858 /*
859 * Mark original node as unused, but head of a resource descriptor.
860 * This allows the resource to be installed in the namespace so that
861 * references to the descriptor can be resolved.
862 */
863 DescriptorTypeOp->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
864 DescriptorTypeOp->Asl.CompileFlags = NODE_IS_RESOURCE_DESC;
865 DescriptorTypeOp->Asl.Value.Integer = CurrentByteOffset;
866
867 if (Rnode)
868 {
869 DescriptorTypeOp->Asl.FinalAmlLength = Rnode->BufferLength;
870 }
871
872 return (Rnode);
873 }
874
875
876 /*******************************************************************************
877 *
878 * FUNCTION: RsLinkDescriptorChain
879 *
880 * PARAMETERS: PreviousRnode - Pointer to the node that will be previous
881 * to the linked node, At exit, set to the
882 * last node in the new chain.
883 * Rnode - Resource node to link into the list
884 *
885 * RETURN: Cumulative buffer byte offset of the new segment of chain
886 *
887 * DESCRIPTION: Link a descriptor chain at the end of an existing chain.
888 *
889 ******************************************************************************/
890
891 UINT32
892 RsLinkDescriptorChain (
893 ASL_RESOURCE_NODE **PreviousRnode,
894 ASL_RESOURCE_NODE *Rnode)
895 {
896 ASL_RESOURCE_NODE *LastRnode;
897 UINT32 CurrentByteOffset;
898
899
900 /* Anything to do? */
901
902 if (!Rnode)
903 {
904 return 0;
905 }
906
907 /* Point the previous node to the new node */
908
909 (*PreviousRnode)->Next = Rnode;
910 CurrentByteOffset = Rnode->BufferLength;
911
912 /* Walk to the end of the chain headed by Rnode */
913
914 LastRnode = Rnode;
915 while (LastRnode->Next)
916 {
917 LastRnode = LastRnode->Next;
918 CurrentByteOffset += LastRnode->BufferLength;
919 }
920
921 /* Previous node becomes the last node in the chain */
922
923 *PreviousRnode = LastRnode;
924 return CurrentByteOffset;
925 }
926
927
928 /*******************************************************************************
929 *
930 * FUNCTION: RsDoResourceTemplate
931 *
932 * PARAMETERS: Op - Parent of a resource template list
933 *
934 * RETURN: None. Sets input node to point to a list of AML code
935 *
936 * DESCRIPTION: Merge a list of resource descriptors into a single AML buffer,
937 * in preparation for output to the AML output file.
938 *
939 ******************************************************************************/
940
941 void
942 RsDoResourceTemplate (
943 ACPI_PARSE_OBJECT *Op)
944 {
945 ACPI_PARSE_OBJECT *BufferLengthOp;
946 ACPI_PARSE_OBJECT *BufferOp;
947 ACPI_PARSE_OBJECT *DescriptorTypeOp;
948 ACPI_PARSE_OBJECT *LastOp = NULL;
949 UINT32 CurrentByteOffset = 0;
950 ASL_RESOURCE_NODE HeadRnode;
951 ASL_RESOURCE_NODE *PreviousRnode;
952 ASL_RESOURCE_NODE *Rnode;
953 UINT8 State;
954
955
956 /* Mark parent as containing a resource template */
957
958 if (Op->Asl.Parent)
959 {
960 Op->Asl.Parent->Asl.CompileFlags |= NODE_IS_RESOURCE_DESC;
961 }
962
963 /* ResourceTemplate Opcode is first (Op) */
964 /* Buffer Length node is first child */
965
966 BufferLengthOp = ASL_GET_CHILD_NODE (Op);
967
968 /* Buffer Op is first peer */
969
970 BufferOp = ASL_GET_PEER_NODE (BufferLengthOp);
971
972 /* First Descriptor type is next */
973
974 DescriptorTypeOp = ASL_GET_PEER_NODE (BufferOp);
975
976 /*
977 * Process all resource descriptors in the list
978 * Note: It is assumed that the EndTag node has been automatically
979 * inserted at the end of the template by the parser.
980 */
981 State = ACPI_RSTATE_NORMAL;
982 PreviousRnode = &HeadRnode;
983 while (DescriptorTypeOp)
984 {
985 DescriptorTypeOp->Asl.CompileFlags |= NODE_IS_RESOURCE_DESC;
986 Rnode = RsDoOneResourceDescriptor (DescriptorTypeOp, CurrentByteOffset,
987 &State);
988
989 /*
990 * Update current byte offset to indicate the number of bytes from the
991 * start of the buffer. Buffer can include multiple descriptors, we
992 * must keep track of the offset of not only each descriptor, but each
993 * element (field) within each descriptor as well.
994 */
995 CurrentByteOffset += RsLinkDescriptorChain (&PreviousRnode, Rnode);
996
997 /* Get the next descriptor in the list */
998
999 LastOp = DescriptorTypeOp;
1000 DescriptorTypeOp = ASL_GET_PEER_NODE (DescriptorTypeOp);
1001 }
1002
1003 if (State == ACPI_RSTATE_DEPENDENT_LIST)
1004 {
1005 if (LastOp)
1006 {
1007 LastOp = LastOp->Asl.Parent;
1008 }
1009 AslError (ASL_ERROR, ASL_MSG_MISSING_ENDDEPENDENT, LastOp, NULL);
1010 }
1011
1012 /*
1013 * Transform the nodes into the following
1014 *
1015 * Op -> AML_BUFFER_OP
1016 * First Child -> BufferLength
1017 * Second Child -> Descriptor Buffer (raw byte data)
1018 */
1019 Op->Asl.ParseOpcode = PARSEOP_BUFFER;
1020 Op->Asl.AmlOpcode = AML_BUFFER_OP;
1021 Op->Asl.CompileFlags = NODE_AML_PACKAGE | NODE_IS_RESOURCE_DESC;
1022
1023 BufferLengthOp->Asl.ParseOpcode = PARSEOP_INTEGER;
1024 BufferLengthOp->Asl.Value.Integer = CurrentByteOffset;
1025 (void) OpcSetOptimalIntegerSize (BufferLengthOp);
1026
1027 BufferOp->Asl.ParseOpcode = PARSEOP_RAW_DATA;
1028 BufferOp->Asl.AmlOpcode = AML_RAW_DATA_CHAIN;
1029 BufferOp->Asl.AmlOpcodeLength = 0;
1030 BufferOp->Asl.AmlLength = CurrentByteOffset;
1031 BufferOp->Asl.Value.Buffer = (UINT8 *) HeadRnode.Next;
1032 BufferOp->Asl.CompileFlags |= NODE_IS_RESOURCE_DATA;
1033
1034 return;
1035 }
1036
1037
1038