Fixed compatibility of output.
[AROS.git] / arch / all-pc / acpica / source / compiler / aslresource.c
blobd7f829f0515589bf35c74f688ec6753ac67557bd
1 /******************************************************************************
3 * Module Name: aslresource - Resource template/descriptor utilities
5 *****************************************************************************/
7 /*
8 * Copyright (C) 2000 - 2013, Intel Corp.
9 * All rights reserved.
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.
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.
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 MERCHANTIBILITY 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.
45 #include "aslcompiler.h"
46 #include "aslcompiler.y.h"
47 #include "amlcode.h"
50 #define _COMPONENT ACPI_COMPILER
51 ACPI_MODULE_NAME ("aslresource")
54 /*******************************************************************************
56 * FUNCTION: RsSmallAddressCheck
58 * PARAMETERS: Minimum - Address Min value
59 * Maximum - Address Max value
60 * Length - Address range value
61 * Alignment - Address alignment value
62 * MinOp - Original Op for Address Min
63 * MaxOp - Original Op for Address Max
64 * LengthOp - Original Op for address range
65 * AlignOp - Original Op for address alignment. If
66 * NULL, means "zero value for alignment is
67 * OK, and means 64K alignment" (for
68 * Memory24 descriptor)
69 * Op - Parent Op for entire construct
71 * RETURN: None. Adds error messages to error log if necessary
73 * DESCRIPTION: Perform common value checks for "small" address descriptors.
74 * Currently:
75 * Io, Memory24, Memory32
77 ******************************************************************************/
79 void
80 RsSmallAddressCheck (
81 UINT8 Type,
82 UINT32 Minimum,
83 UINT32 Maximum,
84 UINT32 Length,
85 UINT32 Alignment,
86 ACPI_PARSE_OBJECT *MinOp,
87 ACPI_PARSE_OBJECT *MaxOp,
88 ACPI_PARSE_OBJECT *LengthOp,
89 ACPI_PARSE_OBJECT *AlignOp,
90 ACPI_PARSE_OBJECT *Op)
93 if (Gbl_NoResourceChecking)
95 return;
99 * Check for a so-called "null descriptor". These are descriptors that are
100 * created with most fields set to zero. The intent is that the descriptor
101 * will be updated/completed at runtime via a BufferField.
103 * If the descriptor does NOT have a resource tag, it cannot be referenced
104 * by a BufferField and we will flag this as an error. Conversely, if
105 * the descriptor has a resource tag, we will assume that a BufferField
106 * will be used to dynamically update it, so no error.
108 * A possible enhancement to this check would be to verify that in fact
109 * a BufferField is created using the resource tag, and perhaps even
110 * verify that a Store is performed to the BufferField.
112 * Note: for these descriptors, Alignment is allowed to be zero
114 if (!Minimum && !Maximum && !Length)
116 if (!Op->Asl.ExternalName)
118 /* No resource tag. Descriptor is fixed and is also illegal */
120 AslError (ASL_ERROR, ASL_MSG_NULL_DESCRIPTOR, Op, NULL);
123 return;
126 /* Special case for Memory24, values are compressed */
128 if (Type == ACPI_RESOURCE_NAME_MEMORY24)
130 if (!Alignment) /* Alignment==0 means 64K - no invalid alignment */
132 Alignment = ACPI_UINT16_MAX + 1;
135 Minimum <<= 8;
136 Maximum <<= 8;
137 Length *= 256;
140 /* IO descriptor has different definition of min/max, don't check */
142 if (Type != ACPI_RESOURCE_NAME_IO)
144 /* Basic checks on Min/Max/Length */
146 if (Minimum > Maximum)
148 AslError (ASL_ERROR, ASL_MSG_INVALID_MIN_MAX, MinOp, NULL);
150 else if (Length > (Maximum - Minimum + 1))
152 AslError (ASL_ERROR, ASL_MSG_INVALID_LENGTH, LengthOp, NULL);
156 /* Alignment of zero is not in ACPI spec, but is used to mean byte acc */
158 if (!Alignment)
160 Alignment = 1;
163 /* Addresses must be an exact multiple of the alignment value */
165 if (Minimum % Alignment)
167 AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MinOp, NULL);
169 if (Maximum % Alignment)
171 AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MaxOp, NULL);
176 /*******************************************************************************
178 * FUNCTION: RsLargeAddressCheck
180 * PARAMETERS: Minimum - Address Min value
181 * Maximum - Address Max value
182 * Length - Address range value
183 * Granularity - Address granularity value
184 * Flags - General flags for address descriptors:
185 * _MIF, _MAF, _DEC
186 * MinOp - Original Op for Address Min
187 * MaxOp - Original Op for Address Max
188 * LengthOp - Original Op for address range
189 * GranOp - Original Op for address granularity
190 * Op - Parent Op for entire construct
192 * RETURN: None. Adds error messages to error log if necessary
194 * DESCRIPTION: Perform common value checks for "large" address descriptors.
195 * Currently:
196 * WordIo, WordBusNumber, WordSpace
197 * DWordIo, DWordMemory, DWordSpace
198 * QWordIo, QWordMemory, QWordSpace
199 * ExtendedIo, ExtendedMemory, ExtendedSpace
201 * _MIF flag set means that the minimum address is fixed and is not relocatable
202 * _MAF flag set means that the maximum address is fixed and is not relocatable
203 * Length of zero means that the record size is variable
205 * This function implements the LEN/MIF/MAF/MIN/MAX/GRA rules within Table 6-40
206 * of the ACPI 4.0a specification. Added 04/2010.
208 ******************************************************************************/
210 void
211 RsLargeAddressCheck (
212 UINT64 Minimum,
213 UINT64 Maximum,
214 UINT64 Length,
215 UINT64 Granularity,
216 UINT8 Flags,
217 ACPI_PARSE_OBJECT *MinOp,
218 ACPI_PARSE_OBJECT *MaxOp,
219 ACPI_PARSE_OBJECT *LengthOp,
220 ACPI_PARSE_OBJECT *GranOp,
221 ACPI_PARSE_OBJECT *Op)
224 if (Gbl_NoResourceChecking)
226 return;
230 * Check for a so-called "null descriptor". These are descriptors that are
231 * created with most fields set to zero. The intent is that the descriptor
232 * will be updated/completed at runtime via a BufferField.
234 * If the descriptor does NOT have a resource tag, it cannot be referenced
235 * by a BufferField and we will flag this as an error. Conversely, if
236 * the descriptor has a resource tag, we will assume that a BufferField
237 * will be used to dynamically update it, so no error.
239 * A possible enhancement to this check would be to verify that in fact
240 * a BufferField is created using the resource tag, and perhaps even
241 * verify that a Store is performed to the BufferField.
243 if (!Minimum && !Maximum && !Length && !Granularity)
245 if (!Op->Asl.ExternalName)
247 /* No resource tag. Descriptor is fixed and is also illegal */
249 AslError (ASL_ERROR, ASL_MSG_NULL_DESCRIPTOR, Op, NULL);
252 return;
255 /* Basic checks on Min/Max/Length */
257 if (Minimum > Maximum)
259 AslError (ASL_ERROR, ASL_MSG_INVALID_MIN_MAX, MinOp, NULL);
260 return;
262 else if (Length > (Maximum - Minimum + 1))
264 AslError (ASL_ERROR, ASL_MSG_INVALID_LENGTH, LengthOp, NULL);
265 return;
268 /* If specified (non-zero), ensure granularity is a power-of-two minus one */
270 if (Granularity)
272 if ((Granularity + 1) &
273 Granularity)
275 AslError (ASL_ERROR, ASL_MSG_INVALID_GRANULARITY, GranOp, NULL);
276 return;
281 * Check the various combinations of Length, MinFixed, and MaxFixed
283 if (Length)
285 /* Fixed non-zero length */
287 switch (Flags & (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF))
289 case 0:
291 * Fixed length, variable locations (both _MIN and _MAX).
292 * Length must be a multiple of granularity
294 if (Granularity & Length)
296 AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, LengthOp, NULL);
298 break;
300 case (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF):
302 /* Fixed length, fixed location. Granularity must be zero */
304 if (Granularity != 0)
306 AslError (ASL_ERROR, ASL_MSG_INVALID_GRAN_FIXED, GranOp, NULL);
309 /* Length must be exactly the size of the min/max window */
311 if (Length != (Maximum - Minimum + 1))
313 AslError (ASL_ERROR, ASL_MSG_INVALID_LENGTH_FIXED, LengthOp, NULL);
315 break;
317 /* All other combinations are invalid */
319 case ACPI_RESOURCE_FLAG_MIF:
320 case ACPI_RESOURCE_FLAG_MAF:
321 default:
323 AslError (ASL_ERROR, ASL_MSG_INVALID_ADDR_FLAGS, LengthOp, NULL);
326 else
328 /* Variable length (length==0) */
330 switch (Flags & (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF))
332 case 0:
334 * Both _MIN and _MAX are variable.
335 * No additional requirements, just exit
337 break;
339 case ACPI_RESOURCE_FLAG_MIF:
341 /* _MIN is fixed. _MIN must be multiple of _GRA */
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.
348 if (Granularity & Minimum)
350 AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MinOp, NULL);
352 break;
354 case ACPI_RESOURCE_FLAG_MAF:
356 /* _MAX is fixed. (_MAX + 1) must be multiple of _GRA */
358 if (Granularity & (Maximum + 1))
360 AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MaxOp, "-1");
362 break;
364 /* Both MIF/MAF set is invalid if length is zero */
366 case (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF):
367 default:
369 AslError (ASL_ERROR, ASL_MSG_INVALID_ADDR_FLAGS, LengthOp, NULL);
375 /*******************************************************************************
377 * FUNCTION: RsGetStringDataLength
379 * PARAMETERS: InitializerOp - Start of a subtree of init nodes
381 * RETURN: Valid string length if a string node is found (otherwise 0)
383 * DESCRIPTION: In a list of peer nodes, find the first one that contains a
384 * string and return the length of the string.
386 ******************************************************************************/
388 UINT16
389 RsGetStringDataLength (
390 ACPI_PARSE_OBJECT *InitializerOp)
393 while (InitializerOp)
395 if (InitializerOp->Asl.ParseOpcode == PARSEOP_STRING_LITERAL)
397 return ((UINT16) (strlen (InitializerOp->Asl.Value.String) + 1));
399 InitializerOp = ASL_GET_PEER_NODE (InitializerOp);
402 return (0);
406 /*******************************************************************************
408 * FUNCTION: RsAllocateResourceNode
410 * PARAMETERS: Size - Size of node in bytes
412 * RETURN: The allocated node - aborts on allocation failure
414 * DESCRIPTION: Allocate a resource description node and the resource
415 * descriptor itself (the nodes are used to link descriptors).
417 ******************************************************************************/
419 ASL_RESOURCE_NODE *
420 RsAllocateResourceNode (
421 UINT32 Size)
423 ASL_RESOURCE_NODE *Rnode;
426 /* Allocate the node */
428 Rnode = UtLocalCalloc (sizeof (ASL_RESOURCE_NODE));
430 /* Allocate the resource descriptor itself */
432 Rnode->Buffer = UtLocalCalloc (Size);
433 Rnode->BufferLength = Size;
435 return (Rnode);
439 /*******************************************************************************
441 * FUNCTION: RsCreateResourceField
443 * PARAMETERS: Op - Resource field node
444 * Name - Name of the field (Used only to reference
445 * the field in the ASL, not in the AML)
446 * ByteOffset - Offset from the field start
447 * BitOffset - Additional bit offset
448 * BitLength - Number of bits in the field
450 * RETURN: None, sets fields within the input node
452 * DESCRIPTION: Utility function to generate a named bit field within a
453 * resource descriptor. Mark a node as 1) a field in a resource
454 * descriptor, and 2) set the value to be a BIT offset
456 ******************************************************************************/
458 void
459 RsCreateResourceField (
460 ACPI_PARSE_OBJECT *Op,
461 char *Name,
462 UINT32 ByteOffset,
463 UINT32 BitOffset,
464 UINT32 BitLength)
467 Op->Asl.ExternalName = Name;
468 Op->Asl.CompileFlags |= NODE_IS_RESOURCE_FIELD;
471 Op->Asl.Value.Tag.BitOffset = (ByteOffset * 8) + BitOffset;
472 Op->Asl.Value.Tag.BitLength = BitLength;
476 /*******************************************************************************
478 * FUNCTION: RsSetFlagBits
480 * PARAMETERS: *Flags - Pointer to the flag byte
481 * Op - Flag initialization node
482 * Position - Bit position within the flag byte
483 * Default - Used if the node is DEFAULT.
485 * RETURN: Sets bits within the *Flags output byte.
487 * DESCRIPTION: Set a bit in a cumulative flags word from an initialization
488 * node. Will use a default value if the node is DEFAULT, meaning
489 * that no value was specified in the ASL. Used to merge multiple
490 * keywords into a single flags byte.
492 ******************************************************************************/
494 void
495 RsSetFlagBits (
496 UINT8 *Flags,
497 ACPI_PARSE_OBJECT *Op,
498 UINT8 Position,
499 UINT8 DefaultBit)
502 if (Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
504 /* Use the default bit */
506 *Flags |= (DefaultBit << Position);
508 else
510 /* Use the bit specified in the initialization node */
512 *Flags |= (((UINT8) Op->Asl.Value.Integer) << Position);
517 void
518 RsSetFlagBits16 (
519 UINT16 *Flags,
520 ACPI_PARSE_OBJECT *Op,
521 UINT8 Position,
522 UINT8 DefaultBit)
525 if (Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
527 /* Use the default bit */
529 *Flags |= (DefaultBit << Position);
531 else
533 /* Use the bit specified in the initialization node */
535 *Flags |= (((UINT16) Op->Asl.Value.Integer) << Position);
540 /*******************************************************************************
542 * FUNCTION: RsCompleteNodeAndGetNext
544 * PARAMETERS: Op - Resource node to be completed
546 * RETURN: The next peer to the input node.
548 * DESCRIPTION: Mark the current node completed and return the next peer.
549 * The node ParseOpcode is set to DEFAULT_ARG, meaning that
550 * this node is to be ignored from now on.
552 ******************************************************************************/
554 ACPI_PARSE_OBJECT *
555 RsCompleteNodeAndGetNext (
556 ACPI_PARSE_OBJECT *Op)
559 /* Mark this node unused */
561 Op->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
563 /* Move on to the next peer node in the initializer list */
565 return (ASL_GET_PEER_NODE (Op));
569 /*******************************************************************************
571 * FUNCTION: RsCheckListForDuplicates
573 * PARAMETERS: Op - First op in the initializer list
575 * RETURN: None
577 * DESCRIPTION: Check an initializer list for duplicate values. Emits an error
578 * if any duplicates are found.
580 ******************************************************************************/
582 void
583 RsCheckListForDuplicates (
584 ACPI_PARSE_OBJECT *Op)
586 ACPI_PARSE_OBJECT *NextValueOp = Op;
587 ACPI_PARSE_OBJECT *NextOp;
588 UINT32 Value;
591 if (!Op)
593 return;
596 /* Search list once for each value in the list */
598 while (NextValueOp)
600 Value = (UINT32) NextValueOp->Asl.Value.Integer;
602 /* Compare this value to all remaining values in the list */
604 NextOp = ASL_GET_PEER_NODE (NextValueOp);
605 while (NextOp)
607 if (NextOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
609 /* Compare values */
611 if (Value == (UINT32) NextOp->Asl.Value.Integer)
613 /* Emit error only once per duplicate node */
615 if (!(NextOp->Asl.CompileFlags & NODE_IS_DUPLICATE))
617 NextOp->Asl.CompileFlags |= NODE_IS_DUPLICATE;
618 AslError (ASL_ERROR, ASL_MSG_DUPLICATE_ITEM,
619 NextOp, NULL);
624 NextOp = ASL_GET_PEER_NODE (NextOp);
627 NextValueOp = ASL_GET_PEER_NODE (NextValueOp);
632 /*******************************************************************************
634 * FUNCTION: RsDoOneResourceDescriptor
636 * PARAMETERS: DescriptorTypeOp - Parent parse node of the descriptor
637 * CurrentByteOffset - Offset in the resource descriptor
638 * buffer.
640 * RETURN: A valid resource node for the descriptor
642 * DESCRIPTION: Dispatches the processing of one resource descriptor
644 ******************************************************************************/
646 ASL_RESOURCE_NODE *
647 RsDoOneResourceDescriptor (
648 ACPI_PARSE_OBJECT *DescriptorTypeOp,
649 UINT32 CurrentByteOffset,
650 UINT8 *State)
652 ASL_RESOURCE_NODE *Rnode = NULL;
655 /* Construct the resource */
657 switch (DescriptorTypeOp->Asl.ParseOpcode)
659 case PARSEOP_DMA:
661 Rnode = RsDoDmaDescriptor (DescriptorTypeOp,
662 CurrentByteOffset);
663 break;
665 case PARSEOP_FIXEDDMA:
667 Rnode = RsDoFixedDmaDescriptor (DescriptorTypeOp,
668 CurrentByteOffset);
669 break;
671 case PARSEOP_DWORDIO:
673 Rnode = RsDoDwordIoDescriptor (DescriptorTypeOp,
674 CurrentByteOffset);
675 break;
677 case PARSEOP_DWORDMEMORY:
679 Rnode = RsDoDwordMemoryDescriptor (DescriptorTypeOp,
680 CurrentByteOffset);
681 break;
683 case PARSEOP_DWORDSPACE:
685 Rnode = RsDoDwordSpaceDescriptor (DescriptorTypeOp,
686 CurrentByteOffset);
687 break;
689 case PARSEOP_ENDDEPENDENTFN:
691 switch (*State)
693 case ACPI_RSTATE_NORMAL:
695 AslError (ASL_ERROR, ASL_MSG_MISSING_STARTDEPENDENT,
696 DescriptorTypeOp, NULL);
697 break;
699 case ACPI_RSTATE_START_DEPENDENT:
701 AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING,
702 DescriptorTypeOp, NULL);
703 break;
705 case ACPI_RSTATE_DEPENDENT_LIST:
706 default:
708 break;
711 *State = ACPI_RSTATE_NORMAL;
712 Rnode = RsDoEndDependentDescriptor (DescriptorTypeOp,
713 CurrentByteOffset);
714 break;
716 case PARSEOP_ENDTAG:
718 Rnode = RsDoEndTagDescriptor (DescriptorTypeOp,
719 CurrentByteOffset);
720 break;
722 case PARSEOP_EXTENDEDIO:
724 Rnode = RsDoExtendedIoDescriptor (DescriptorTypeOp,
725 CurrentByteOffset);
726 break;
728 case PARSEOP_EXTENDEDMEMORY:
730 Rnode = RsDoExtendedMemoryDescriptor (DescriptorTypeOp,
731 CurrentByteOffset);
732 break;
734 case PARSEOP_EXTENDEDSPACE:
736 Rnode = RsDoExtendedSpaceDescriptor (DescriptorTypeOp,
737 CurrentByteOffset);
738 break;
740 case PARSEOP_FIXEDIO:
742 Rnode = RsDoFixedIoDescriptor (DescriptorTypeOp,
743 CurrentByteOffset);
744 break;
746 case PARSEOP_INTERRUPT:
748 Rnode = RsDoInterruptDescriptor (DescriptorTypeOp,
749 CurrentByteOffset);
750 break;
752 case PARSEOP_IO:
754 Rnode = RsDoIoDescriptor (DescriptorTypeOp,
755 CurrentByteOffset);
756 break;
758 case PARSEOP_IRQ:
760 Rnode = RsDoIrqDescriptor (DescriptorTypeOp,
761 CurrentByteOffset);
762 break;
764 case PARSEOP_IRQNOFLAGS:
766 Rnode = RsDoIrqNoFlagsDescriptor (DescriptorTypeOp,
767 CurrentByteOffset);
768 break;
770 case PARSEOP_MEMORY24:
772 Rnode = RsDoMemory24Descriptor (DescriptorTypeOp,
773 CurrentByteOffset);
774 break;
776 case PARSEOP_MEMORY32:
778 Rnode = RsDoMemory32Descriptor (DescriptorTypeOp,
779 CurrentByteOffset);
780 break;
782 case PARSEOP_MEMORY32FIXED:
784 Rnode = RsDoMemory32FixedDescriptor (DescriptorTypeOp,
785 CurrentByteOffset);
786 break;
788 case PARSEOP_QWORDIO:
790 Rnode = RsDoQwordIoDescriptor (DescriptorTypeOp,
791 CurrentByteOffset);
792 break;
794 case PARSEOP_QWORDMEMORY:
796 Rnode = RsDoQwordMemoryDescriptor (DescriptorTypeOp,
797 CurrentByteOffset);
798 break;
800 case PARSEOP_QWORDSPACE:
802 Rnode = RsDoQwordSpaceDescriptor (DescriptorTypeOp,
803 CurrentByteOffset);
804 break;
806 case PARSEOP_REGISTER:
808 Rnode = RsDoGeneralRegisterDescriptor (DescriptorTypeOp,
809 CurrentByteOffset);
810 break;
812 case PARSEOP_STARTDEPENDENTFN:
814 switch (*State)
816 case ACPI_RSTATE_START_DEPENDENT:
818 AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING,
819 DescriptorTypeOp, NULL);
820 break;
822 case ACPI_RSTATE_NORMAL:
823 case ACPI_RSTATE_DEPENDENT_LIST:
824 default:
826 break;
829 *State = ACPI_RSTATE_START_DEPENDENT;
830 Rnode = RsDoStartDependentDescriptor (DescriptorTypeOp,
831 CurrentByteOffset);
832 *State = ACPI_RSTATE_DEPENDENT_LIST;
833 break;
835 case PARSEOP_STARTDEPENDENTFN_NOPRI:
837 switch (*State)
839 case ACPI_RSTATE_START_DEPENDENT:
841 AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING,
842 DescriptorTypeOp, NULL);
843 break;
845 case ACPI_RSTATE_NORMAL:
846 case ACPI_RSTATE_DEPENDENT_LIST:
847 default:
849 break;
852 *State = ACPI_RSTATE_START_DEPENDENT;
853 Rnode = RsDoStartDependentNoPriDescriptor (DescriptorTypeOp,
854 CurrentByteOffset);
855 *State = ACPI_RSTATE_DEPENDENT_LIST;
856 break;
858 case PARSEOP_VENDORLONG:
860 Rnode = RsDoVendorLargeDescriptor (DescriptorTypeOp,
861 CurrentByteOffset);
862 break;
864 case PARSEOP_VENDORSHORT:
866 Rnode = RsDoVendorSmallDescriptor (DescriptorTypeOp,
867 CurrentByteOffset);
868 break;
870 case PARSEOP_WORDBUSNUMBER:
872 Rnode = RsDoWordBusNumberDescriptor (DescriptorTypeOp,
873 CurrentByteOffset);
874 break;
876 case PARSEOP_WORDIO:
878 Rnode = RsDoWordIoDescriptor (DescriptorTypeOp,
879 CurrentByteOffset);
880 break;
882 case PARSEOP_WORDSPACE:
884 Rnode = RsDoWordSpaceDescriptor (DescriptorTypeOp,
885 CurrentByteOffset);
886 break;
888 case PARSEOP_GPIO_INT:
890 Rnode = RsDoGpioIntDescriptor (DescriptorTypeOp,
891 CurrentByteOffset);
892 break;
894 case PARSEOP_GPIO_IO:
896 Rnode = RsDoGpioIoDescriptor (DescriptorTypeOp,
897 CurrentByteOffset);
898 break;
900 case PARSEOP_I2C_SERIALBUS:
902 Rnode = RsDoI2cSerialBusDescriptor (DescriptorTypeOp,
903 CurrentByteOffset);
904 break;
906 case PARSEOP_SPI_SERIALBUS:
908 Rnode = RsDoSpiSerialBusDescriptor (DescriptorTypeOp,
909 CurrentByteOffset);
910 break;
912 case PARSEOP_UART_SERIALBUS:
914 Rnode = RsDoUartSerialBusDescriptor (DescriptorTypeOp,
915 CurrentByteOffset);
916 break;
918 case PARSEOP_DEFAULT_ARG:
920 /* Just ignore any of these, they are used as fillers/placeholders */
921 break;
923 default:
925 printf ("Unknown resource descriptor type [%s]\n",
926 DescriptorTypeOp->Asl.ParseOpName);
927 break;
931 * Mark original node as unused, but head of a resource descriptor.
932 * This allows the resource to be installed in the namespace so that
933 * references to the descriptor can be resolved.
935 DescriptorTypeOp->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
936 DescriptorTypeOp->Asl.CompileFlags = NODE_IS_RESOURCE_DESC;
937 DescriptorTypeOp->Asl.Value.Integer = CurrentByteOffset;
939 if (Rnode)
941 DescriptorTypeOp->Asl.FinalAmlLength = Rnode->BufferLength;
942 DescriptorTypeOp->Asl.Extra = ((AML_RESOURCE *) Rnode->Buffer)->DescriptorType;
945 return (Rnode);
949 /*******************************************************************************
951 * FUNCTION: RsLinkDescriptorChain
953 * PARAMETERS: PreviousRnode - Pointer to the node that will be previous
954 * to the linked node, At exit, set to the
955 * last node in the new chain.
956 * Rnode - Resource node to link into the list
958 * RETURN: Cumulative buffer byte offset of the new segment of chain
960 * DESCRIPTION: Link a descriptor chain at the end of an existing chain.
962 ******************************************************************************/
964 UINT32
965 RsLinkDescriptorChain (
966 ASL_RESOURCE_NODE **PreviousRnode,
967 ASL_RESOURCE_NODE *Rnode)
969 ASL_RESOURCE_NODE *LastRnode;
970 UINT32 CurrentByteOffset;
973 /* Anything to do? */
975 if (!Rnode)
977 return (0);
980 /* Point the previous node to the new node */
982 (*PreviousRnode)->Next = Rnode;
983 CurrentByteOffset = Rnode->BufferLength;
985 /* Walk to the end of the chain headed by Rnode */
987 LastRnode = Rnode;
988 while (LastRnode->Next)
990 LastRnode = LastRnode->Next;
991 CurrentByteOffset += LastRnode->BufferLength;
994 /* Previous node becomes the last node in the chain */
996 *PreviousRnode = LastRnode;
997 return (CurrentByteOffset);
1001 /*******************************************************************************
1003 * FUNCTION: RsDoResourceTemplate
1005 * PARAMETERS: Op - Parent of a resource template list
1007 * RETURN: None. Sets input node to point to a list of AML code
1009 * DESCRIPTION: Merge a list of resource descriptors into a single AML buffer,
1010 * in preparation for output to the AML output file.
1012 ******************************************************************************/
1014 void
1015 RsDoResourceTemplate (
1016 ACPI_PARSE_OBJECT *Op)
1018 ACPI_PARSE_OBJECT *BufferLengthOp;
1019 ACPI_PARSE_OBJECT *BufferOp;
1020 ACPI_PARSE_OBJECT *DescriptorTypeOp;
1021 ACPI_PARSE_OBJECT *LastOp = NULL;
1022 UINT32 CurrentByteOffset = 0;
1023 ASL_RESOURCE_NODE HeadRnode;
1024 ASL_RESOURCE_NODE *PreviousRnode;
1025 ASL_RESOURCE_NODE *Rnode;
1026 UINT8 State;
1029 /* Mark parent as containing a resource template */
1031 if (Op->Asl.Parent)
1033 Op->Asl.Parent->Asl.CompileFlags |= NODE_IS_RESOURCE_DESC;
1036 /* ResourceTemplate Opcode is first (Op) */
1037 /* Buffer Length node is first child */
1039 BufferLengthOp = ASL_GET_CHILD_NODE (Op);
1041 /* Buffer Op is first peer */
1043 BufferOp = ASL_GET_PEER_NODE (BufferLengthOp);
1045 /* First Descriptor type is next */
1047 DescriptorTypeOp = ASL_GET_PEER_NODE (BufferOp);
1050 * Process all resource descriptors in the list
1051 * Note: It is assumed that the EndTag node has been automatically
1052 * inserted at the end of the template by the parser.
1054 State = ACPI_RSTATE_NORMAL;
1055 PreviousRnode = &HeadRnode;
1056 while (DescriptorTypeOp)
1058 DescriptorTypeOp->Asl.CompileFlags |= NODE_IS_RESOURCE_DESC;
1059 Rnode = RsDoOneResourceDescriptor (DescriptorTypeOp, CurrentByteOffset,
1060 &State);
1063 * Update current byte offset to indicate the number of bytes from the
1064 * start of the buffer. Buffer can include multiple descriptors, we
1065 * must keep track of the offset of not only each descriptor, but each
1066 * element (field) within each descriptor as well.
1068 CurrentByteOffset += RsLinkDescriptorChain (&PreviousRnode, Rnode);
1070 /* Get the next descriptor in the list */
1072 LastOp = DescriptorTypeOp;
1073 DescriptorTypeOp = ASL_GET_PEER_NODE (DescriptorTypeOp);
1076 if (State == ACPI_RSTATE_DEPENDENT_LIST)
1078 if (LastOp)
1080 LastOp = LastOp->Asl.Parent;
1082 AslError (ASL_ERROR, ASL_MSG_MISSING_ENDDEPENDENT, LastOp, NULL);
1086 * Transform the nodes into the following
1088 * Op -> AML_BUFFER_OP
1089 * First Child -> BufferLength
1090 * Second Child -> Descriptor Buffer (raw byte data)
1092 Op->Asl.ParseOpcode = PARSEOP_BUFFER;
1093 Op->Asl.AmlOpcode = AML_BUFFER_OP;
1094 Op->Asl.CompileFlags = NODE_AML_PACKAGE | NODE_IS_RESOURCE_DESC;
1095 UtSetParseOpName (Op);
1097 BufferLengthOp->Asl.ParseOpcode = PARSEOP_INTEGER;
1098 BufferLengthOp->Asl.Value.Integer = CurrentByteOffset;
1099 (void) OpcSetOptimalIntegerSize (BufferLengthOp);
1100 UtSetParseOpName (BufferLengthOp);
1102 BufferOp->Asl.ParseOpcode = PARSEOP_RAW_DATA;
1103 BufferOp->Asl.AmlOpcode = AML_RAW_DATA_CHAIN;
1104 BufferOp->Asl.AmlOpcodeLength = 0;
1105 BufferOp->Asl.AmlLength = CurrentByteOffset;
1106 BufferOp->Asl.Value.Buffer = (UINT8 *) HeadRnode.Next;
1107 BufferOp->Asl.CompileFlags |= NODE_IS_RESOURCE_DATA;
1108 UtSetParseOpName (BufferOp);
1110 return;