2 /******************************************************************************
4 * Module Name: aslresource - Resource template/descriptor utilities
6 *****************************************************************************/
9 * Copyright (C) 2000 - 2012, Intel Corp.
10 * All rights reserved.
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
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.
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.
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.
46 #include <contrib/dev/acpica/compiler/aslcompiler.h>
47 #include "aslcompiler.y.h"
48 #include <contrib/dev/acpica/include/amlcode.h>
51 #define _COMPONENT ACPI_COMPILER
52 ACPI_MODULE_NAME ("aslresource")
55 /*******************************************************************************
57 * FUNCTION: RsSmallAddressCheck
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
72 * RETURN: None. Adds error messages to error log if necessary
74 * DESCRIPTION: Perform common value checks for "small" address descriptors.
76 * Io, Memory24, Memory32
78 ******************************************************************************/
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)
94 if (Gbl_NoResourceChecking)
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.
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.
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.
113 * Note: for these descriptors, Alignment is allowed to be zero
115 if (!Minimum && !Maximum && !Length)
117 if (!Op->Asl.ExternalName)
119 /* No resource tag. Descriptor is fixed and is also illegal */
121 AslError (ASL_ERROR, ASL_MSG_NULL_DESCRIPTOR, Op, NULL);
127 /* Special case for Memory24, values are compressed */
129 if (Type == ACPI_RESOURCE_NAME_MEMORY24)
131 if (!Alignment) /* Alignment==0 means 64K - no invalid alignment */
133 Alignment = ACPI_UINT16_MAX + 1;
141 /* IO descriptor has different definition of min/max, don't check */
143 if (Type != ACPI_RESOURCE_NAME_IO)
145 /* Basic checks on Min/Max/Length */
147 if (Minimum > Maximum)
149 AslError (ASL_ERROR, ASL_MSG_INVALID_MIN_MAX, MinOp, NULL);
151 else if (Length > (Maximum - Minimum + 1))
153 AslError (ASL_ERROR, ASL_MSG_INVALID_LENGTH, LengthOp, NULL);
157 /* Alignment of zero is not in ACPI spec, but is used to mean byte acc */
164 /* Addresses must be an exact multiple of the alignment value */
166 if (Minimum % Alignment)
168 AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MinOp, NULL);
170 if (Maximum % Alignment)
172 AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MaxOp, NULL);
177 /*******************************************************************************
179 * FUNCTION: RsLargeAddressCheck
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:
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
193 * RETURN: None. Adds error messages to error log if necessary
195 * DESCRIPTION: Perform common value checks for "large" address descriptors.
197 * WordIo, WordBusNumber, WordSpace
198 * DWordIo, DWordMemory, DWordSpace
199 * QWordIo, QWordMemory, QWordSpace
200 * ExtendedIo, ExtendedMemory, ExtendedSpace
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
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.
209 ******************************************************************************/
212 RsLargeAddressCheck (
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)
225 if (Gbl_NoResourceChecking)
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.
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.
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.
244 if (!Minimum && !Maximum && !Length && !Granularity)
246 if (!Op->Asl.ExternalName)
248 /* No resource tag. Descriptor is fixed and is also illegal */
250 AslError (ASL_ERROR, ASL_MSG_NULL_DESCRIPTOR, Op, NULL);
256 /* Basic checks on Min/Max/Length */
258 if (Minimum > Maximum)
260 AslError (ASL_ERROR, ASL_MSG_INVALID_MIN_MAX, MinOp, NULL);
263 else if (Length > (Maximum - Minimum + 1))
265 AslError (ASL_ERROR, ASL_MSG_INVALID_LENGTH, LengthOp, NULL);
269 /* If specified (non-zero), ensure granularity is a power-of-two minus one */
273 if ((Granularity + 1) &
276 AslError (ASL_ERROR, ASL_MSG_INVALID_GRANULARITY, GranOp, NULL);
282 * Check the various combinations of Length, MinFixed, and MaxFixed
286 /* Fixed non-zero length */
288 switch (Flags & (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF))
292 * Fixed length, variable locations (both _MIN and _MAX).
293 * Length must be a multiple of granularity
295 if (Granularity & Length)
297 AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, LengthOp, NULL);
301 case (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF):
303 /* Fixed length, fixed location. Granularity must be zero */
305 if (Granularity != 0)
307 AslError (ASL_ERROR, ASL_MSG_INVALID_GRAN_FIXED, GranOp, NULL);
310 /* Length must be exactly the size of the min/max window */
312 if (Length != (Maximum - Minimum + 1))
314 AslError (ASL_ERROR, ASL_MSG_INVALID_LENGTH_FIXED, LengthOp, NULL);
318 /* All other combinations are invalid */
320 case ACPI_RESOURCE_FLAG_MIF:
321 case ACPI_RESOURCE_FLAG_MAF:
323 AslError (ASL_ERROR, ASL_MSG_INVALID_ADDR_FLAGS, LengthOp, NULL);
328 /* Variable length (length==0) */
330 switch (Flags & (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF))
334 * Both _MIN and _MAX are variable.
335 * No additional requirements, just exit
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);
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");
364 /* Both MIF/MAF set is invalid if length is zero */
366 case (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF):
368 AslError (ASL_ERROR, ASL_MSG_INVALID_ADDR_FLAGS, LengthOp, NULL);
374 /*******************************************************************************
376 * FUNCTION: RsGetStringDataLength
378 * PARAMETERS: InitializerOp - Start of a subtree of init nodes
380 * RETURN: Valid string length if a string node is found (otherwise 0)
382 * DESCRIPTION: In a list of peer nodes, find the first one that contains a
383 * string and return the length of the string.
385 ******************************************************************************/
388 RsGetStringDataLength (
389 ACPI_PARSE_OBJECT *InitializerOp)
392 while (InitializerOp)
394 if (InitializerOp->Asl.ParseOpcode == PARSEOP_STRING_LITERAL)
396 return ((UINT16) (strlen (InitializerOp->Asl.Value.String) + 1));
398 InitializerOp = ASL_GET_PEER_NODE (InitializerOp);
405 /*******************************************************************************
407 * FUNCTION: RsAllocateResourceNode
409 * PARAMETERS: Size - Size of node in bytes
411 * RETURN: The allocated node - aborts on allocation failure
413 * DESCRIPTION: Allocate a resource description node and the resource
414 * descriptor itself (the nodes are used to link descriptors).
416 ******************************************************************************/
419 RsAllocateResourceNode (
422 ASL_RESOURCE_NODE *Rnode;
425 /* Allocate the node */
427 Rnode = UtLocalCalloc (sizeof (ASL_RESOURCE_NODE));
429 /* Allocate the resource descriptor itself */
431 Rnode->Buffer = UtLocalCalloc (Size);
432 Rnode->BufferLength = Size;
438 /*******************************************************************************
440 * FUNCTION: RsCreateResourceField
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 * BitLength - Number of bits in the field
449 * RETURN: None, sets fields within the input node
451 * DESCRIPTION: Utility function to generate a named bit field within a
452 * resource descriptor. Mark a node as 1) a field in a resource
453 * descriptor, and 2) set the value to be a BIT offset
455 ******************************************************************************/
458 RsCreateResourceField (
459 ACPI_PARSE_OBJECT *Op,
466 Op->Asl.ExternalName = Name;
467 Op->Asl.CompileFlags |= NODE_IS_RESOURCE_FIELD;
470 Op->Asl.Value.Tag.BitOffset = (ByteOffset * 8) + BitOffset;
471 Op->Asl.Value.Tag.BitLength = BitLength;
475 /*******************************************************************************
477 * FUNCTION: RsSetFlagBits
479 * PARAMETERS: *Flags - Pointer to the flag byte
480 * Op - Flag initialization node
481 * Position - Bit position within the flag byte
482 * Default - Used if the node is DEFAULT.
484 * RETURN: Sets bits within the *Flags output byte.
486 * DESCRIPTION: Set a bit in a cumulative flags word from an initialization
487 * node. Will use a default value if the node is DEFAULT, meaning
488 * that no value was specified in the ASL. Used to merge multiple
489 * keywords into a single flags byte.
491 ******************************************************************************/
496 ACPI_PARSE_OBJECT *Op,
501 if (Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
503 /* Use the default bit */
505 *Flags |= (DefaultBit << Position);
509 /* Use the bit specified in the initialization node */
511 *Flags |= (((UINT8) Op->Asl.Value.Integer) << Position);
519 ACPI_PARSE_OBJECT *Op,
524 if (Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
526 /* Use the default bit */
528 *Flags |= (DefaultBit << Position);
532 /* Use the bit specified in the initialization node */
534 *Flags |= (((UINT16) Op->Asl.Value.Integer) << Position);
539 /*******************************************************************************
541 * FUNCTION: RsCompleteNodeAndGetNext
543 * PARAMETERS: Op - Resource node to be completed
545 * RETURN: The next peer to the input node.
547 * DESCRIPTION: Mark the current node completed and return the next peer.
548 * The node ParseOpcode is set to DEFAULT_ARG, meaning that
549 * this node is to be ignored from now on.
551 ******************************************************************************/
554 RsCompleteNodeAndGetNext (
555 ACPI_PARSE_OBJECT *Op)
558 /* Mark this node unused */
560 Op->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
562 /* Move on to the next peer node in the initializer list */
564 return (ASL_GET_PEER_NODE (Op));
568 /*******************************************************************************
570 * FUNCTION: RsCheckListForDuplicates
572 * PARAMETERS: Op - First op in the initializer list
576 * DESCRIPTION: Check an initializer list for duplicate values. Emits an error
577 * if any duplicates are found.
579 ******************************************************************************/
582 RsCheckListForDuplicates (
583 ACPI_PARSE_OBJECT *Op)
585 ACPI_PARSE_OBJECT *NextValueOp = Op;
586 ACPI_PARSE_OBJECT *NextOp;
595 /* Search list once for each value in the list */
599 Value = (UINT32) NextValueOp->Asl.Value.Integer;
601 /* Compare this value to all remaining values in the list */
603 NextOp = ASL_GET_PEER_NODE (NextValueOp);
606 if (NextOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)
610 if (Value == (UINT32) NextOp->Asl.Value.Integer)
612 /* Emit error only once per duplicate node */
614 if (!(NextOp->Asl.CompileFlags & NODE_IS_DUPLICATE))
616 NextOp->Asl.CompileFlags |= NODE_IS_DUPLICATE;
617 AslError (ASL_ERROR, ASL_MSG_DUPLICATE_ITEM,
623 NextOp = ASL_GET_PEER_NODE (NextOp);
626 NextValueOp = ASL_GET_PEER_NODE (NextValueOp);
631 /*******************************************************************************
633 * FUNCTION: RsDoOneResourceDescriptor
635 * PARAMETERS: DescriptorTypeOp - Parent parse node of the descriptor
636 * CurrentByteOffset - Offset in the resource descriptor
639 * RETURN: A valid resource node for the descriptor
641 * DESCRIPTION: Dispatches the processing of one resource descriptor
643 ******************************************************************************/
646 RsDoOneResourceDescriptor (
647 ACPI_PARSE_OBJECT *DescriptorTypeOp,
648 UINT32 CurrentByteOffset,
651 ASL_RESOURCE_NODE *Rnode = NULL;
654 /* Construct the resource */
656 switch (DescriptorTypeOp->Asl.ParseOpcode)
659 Rnode = RsDoDmaDescriptor (DescriptorTypeOp,
663 case PARSEOP_FIXEDDMA:
664 Rnode = RsDoFixedDmaDescriptor (DescriptorTypeOp,
668 case PARSEOP_DWORDIO:
669 Rnode = RsDoDwordIoDescriptor (DescriptorTypeOp,
673 case PARSEOP_DWORDMEMORY:
674 Rnode = RsDoDwordMemoryDescriptor (DescriptorTypeOp,
678 case PARSEOP_DWORDSPACE:
679 Rnode = RsDoDwordSpaceDescriptor (DescriptorTypeOp,
683 case PARSEOP_ENDDEPENDENTFN:
686 case ACPI_RSTATE_NORMAL:
687 AslError (ASL_ERROR, ASL_MSG_MISSING_STARTDEPENDENT,
688 DescriptorTypeOp, NULL);
691 case ACPI_RSTATE_START_DEPENDENT:
692 AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING,
693 DescriptorTypeOp, NULL);
696 case ACPI_RSTATE_DEPENDENT_LIST:
701 *State = ACPI_RSTATE_NORMAL;
702 Rnode = RsDoEndDependentDescriptor (DescriptorTypeOp,
707 Rnode = RsDoEndTagDescriptor (DescriptorTypeOp,
711 case PARSEOP_EXTENDEDIO:
712 Rnode = RsDoExtendedIoDescriptor (DescriptorTypeOp,
716 case PARSEOP_EXTENDEDMEMORY:
717 Rnode = RsDoExtendedMemoryDescriptor (DescriptorTypeOp,
721 case PARSEOP_EXTENDEDSPACE:
722 Rnode = RsDoExtendedSpaceDescriptor (DescriptorTypeOp,
726 case PARSEOP_FIXEDIO:
727 Rnode = RsDoFixedIoDescriptor (DescriptorTypeOp,
731 case PARSEOP_INTERRUPT:
732 Rnode = RsDoInterruptDescriptor (DescriptorTypeOp,
737 Rnode = RsDoIoDescriptor (DescriptorTypeOp,
742 Rnode = RsDoIrqDescriptor (DescriptorTypeOp,
746 case PARSEOP_IRQNOFLAGS:
747 Rnode = RsDoIrqNoFlagsDescriptor (DescriptorTypeOp,
751 case PARSEOP_MEMORY24:
752 Rnode = RsDoMemory24Descriptor (DescriptorTypeOp,
756 case PARSEOP_MEMORY32:
757 Rnode = RsDoMemory32Descriptor (DescriptorTypeOp,
761 case PARSEOP_MEMORY32FIXED:
762 Rnode = RsDoMemory32FixedDescriptor (DescriptorTypeOp,
766 case PARSEOP_QWORDIO:
767 Rnode = RsDoQwordIoDescriptor (DescriptorTypeOp,
771 case PARSEOP_QWORDMEMORY:
772 Rnode = RsDoQwordMemoryDescriptor (DescriptorTypeOp,
776 case PARSEOP_QWORDSPACE:
777 Rnode = RsDoQwordSpaceDescriptor (DescriptorTypeOp,
781 case PARSEOP_REGISTER:
782 Rnode = RsDoGeneralRegisterDescriptor (DescriptorTypeOp,
786 case PARSEOP_STARTDEPENDENTFN:
789 case ACPI_RSTATE_START_DEPENDENT:
790 AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING,
791 DescriptorTypeOp, NULL);
794 case ACPI_RSTATE_NORMAL:
795 case ACPI_RSTATE_DEPENDENT_LIST:
800 *State = ACPI_RSTATE_START_DEPENDENT;
801 Rnode = RsDoStartDependentDescriptor (DescriptorTypeOp,
803 *State = ACPI_RSTATE_DEPENDENT_LIST;
806 case PARSEOP_STARTDEPENDENTFN_NOPRI:
809 case ACPI_RSTATE_START_DEPENDENT:
810 AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING,
811 DescriptorTypeOp, NULL);
814 case ACPI_RSTATE_NORMAL:
815 case ACPI_RSTATE_DEPENDENT_LIST:
820 *State = ACPI_RSTATE_START_DEPENDENT;
821 Rnode = RsDoStartDependentNoPriDescriptor (DescriptorTypeOp,
823 *State = ACPI_RSTATE_DEPENDENT_LIST;
826 case PARSEOP_VENDORLONG:
827 Rnode = RsDoVendorLargeDescriptor (DescriptorTypeOp,
831 case PARSEOP_VENDORSHORT:
832 Rnode = RsDoVendorSmallDescriptor (DescriptorTypeOp,
836 case PARSEOP_WORDBUSNUMBER:
837 Rnode = RsDoWordBusNumberDescriptor (DescriptorTypeOp,
842 Rnode = RsDoWordIoDescriptor (DescriptorTypeOp,
846 case PARSEOP_WORDSPACE:
847 Rnode = RsDoWordSpaceDescriptor (DescriptorTypeOp,
851 case PARSEOP_GPIO_INT:
852 Rnode = RsDoGpioIntDescriptor (DescriptorTypeOp,
856 case PARSEOP_GPIO_IO:
857 Rnode = RsDoGpioIoDescriptor (DescriptorTypeOp,
861 case PARSEOP_I2C_SERIALBUS:
862 Rnode = RsDoI2cSerialBusDescriptor (DescriptorTypeOp,
866 case PARSEOP_SPI_SERIALBUS:
867 Rnode = RsDoSpiSerialBusDescriptor (DescriptorTypeOp,
871 case PARSEOP_UART_SERIALBUS:
872 Rnode = RsDoUartSerialBusDescriptor (DescriptorTypeOp,
876 case PARSEOP_DEFAULT_ARG:
877 /* Just ignore any of these, they are used as fillers/placeholders */
881 printf ("Unknown resource descriptor type [%s]\n",
882 DescriptorTypeOp->Asl.ParseOpName);
887 * Mark original node as unused, but head of a resource descriptor.
888 * This allows the resource to be installed in the namespace so that
889 * references to the descriptor can be resolved.
891 DescriptorTypeOp->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
892 DescriptorTypeOp->Asl.CompileFlags = NODE_IS_RESOURCE_DESC;
893 DescriptorTypeOp->Asl.Value.Integer = CurrentByteOffset;
897 DescriptorTypeOp->Asl.FinalAmlLength = Rnode->BufferLength;
904 /*******************************************************************************
906 * FUNCTION: RsLinkDescriptorChain
908 * PARAMETERS: PreviousRnode - Pointer to the node that will be previous
909 * to the linked node, At exit, set to the
910 * last node in the new chain.
911 * Rnode - Resource node to link into the list
913 * RETURN: Cumulative buffer byte offset of the new segment of chain
915 * DESCRIPTION: Link a descriptor chain at the end of an existing chain.
917 ******************************************************************************/
920 RsLinkDescriptorChain (
921 ASL_RESOURCE_NODE **PreviousRnode,
922 ASL_RESOURCE_NODE *Rnode)
924 ASL_RESOURCE_NODE *LastRnode;
925 UINT32 CurrentByteOffset;
928 /* Anything to do? */
935 /* Point the previous node to the new node */
937 (*PreviousRnode)->Next = Rnode;
938 CurrentByteOffset = Rnode->BufferLength;
940 /* Walk to the end of the chain headed by Rnode */
943 while (LastRnode->Next)
945 LastRnode = LastRnode->Next;
946 CurrentByteOffset += LastRnode->BufferLength;
949 /* Previous node becomes the last node in the chain */
951 *PreviousRnode = LastRnode;
952 return CurrentByteOffset;
956 /*******************************************************************************
958 * FUNCTION: RsDoResourceTemplate
960 * PARAMETERS: Op - Parent of a resource template list
962 * RETURN: None. Sets input node to point to a list of AML code
964 * DESCRIPTION: Merge a list of resource descriptors into a single AML buffer,
965 * in preparation for output to the AML output file.
967 ******************************************************************************/
970 RsDoResourceTemplate (
971 ACPI_PARSE_OBJECT *Op)
973 ACPI_PARSE_OBJECT *BufferLengthOp;
974 ACPI_PARSE_OBJECT *BufferOp;
975 ACPI_PARSE_OBJECT *DescriptorTypeOp;
976 ACPI_PARSE_OBJECT *LastOp = NULL;
977 UINT32 CurrentByteOffset = 0;
978 ASL_RESOURCE_NODE HeadRnode;
979 ASL_RESOURCE_NODE *PreviousRnode;
980 ASL_RESOURCE_NODE *Rnode;
984 /* Mark parent as containing a resource template */
988 Op->Asl.Parent->Asl.CompileFlags |= NODE_IS_RESOURCE_DESC;
991 /* ResourceTemplate Opcode is first (Op) */
992 /* Buffer Length node is first child */
994 BufferLengthOp = ASL_GET_CHILD_NODE (Op);
996 /* Buffer Op is first peer */
998 BufferOp = ASL_GET_PEER_NODE (BufferLengthOp);
1000 /* First Descriptor type is next */
1002 DescriptorTypeOp = ASL_GET_PEER_NODE (BufferOp);
1005 * Process all resource descriptors in the list
1006 * Note: It is assumed that the EndTag node has been automatically
1007 * inserted at the end of the template by the parser.
1009 State = ACPI_RSTATE_NORMAL;
1010 PreviousRnode = &HeadRnode;
1011 while (DescriptorTypeOp)
1013 DescriptorTypeOp->Asl.CompileFlags |= NODE_IS_RESOURCE_DESC;
1014 Rnode = RsDoOneResourceDescriptor (DescriptorTypeOp, CurrentByteOffset,
1018 * Update current byte offset to indicate the number of bytes from the
1019 * start of the buffer. Buffer can include multiple descriptors, we
1020 * must keep track of the offset of not only each descriptor, but each
1021 * element (field) within each descriptor as well.
1023 CurrentByteOffset += RsLinkDescriptorChain (&PreviousRnode, Rnode);
1025 /* Get the next descriptor in the list */
1027 LastOp = DescriptorTypeOp;
1028 DescriptorTypeOp = ASL_GET_PEER_NODE (DescriptorTypeOp);
1031 if (State == ACPI_RSTATE_DEPENDENT_LIST)
1035 LastOp = LastOp->Asl.Parent;
1037 AslError (ASL_ERROR, ASL_MSG_MISSING_ENDDEPENDENT, LastOp, NULL);
1041 * Transform the nodes into the following
1043 * Op -> AML_BUFFER_OP
1044 * First Child -> BufferLength
1045 * Second Child -> Descriptor Buffer (raw byte data)
1047 Op->Asl.ParseOpcode = PARSEOP_BUFFER;
1048 Op->Asl.AmlOpcode = AML_BUFFER_OP;
1049 Op->Asl.CompileFlags = NODE_AML_PACKAGE | NODE_IS_RESOURCE_DESC;
1050 UtSetParseOpName (Op);
1052 BufferLengthOp->Asl.ParseOpcode = PARSEOP_INTEGER;
1053 BufferLengthOp->Asl.Value.Integer = CurrentByteOffset;
1054 (void) OpcSetOptimalIntegerSize (BufferLengthOp);
1055 UtSetParseOpName (BufferLengthOp);
1057 BufferOp->Asl.ParseOpcode = PARSEOP_RAW_DATA;
1058 BufferOp->Asl.AmlOpcode = AML_RAW_DATA_CHAIN;
1059 BufferOp->Asl.AmlOpcodeLength = 0;
1060 BufferOp->Asl.AmlLength = CurrentByteOffset;
1061 BufferOp->Asl.Value.Buffer = (UINT8 *) HeadRnode.Next;
1062 BufferOp->Asl.CompileFlags |= NODE_IS_RESOURCE_DATA;
1063 UtSetParseOpName (BufferOp);