1 /******************************************************************************
3 * Module Name: aslresource - Resource template/descriptor utilities
5 *****************************************************************************/
8 * Copyright (C) 2000 - 2013, Intel Corp.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
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.
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"
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.
75 * Io, Memory24, Memory32
77 ******************************************************************************/
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
)
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
);
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;
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 */
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:
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.
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 ******************************************************************************/
211 RsLargeAddressCheck (
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
)
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
);
255 /* Basic checks on Min/Max/Length */
257 if (Minimum
> Maximum
)
259 AslError (ASL_ERROR
, ASL_MSG_INVALID_MIN_MAX
, MinOp
, NULL
);
262 else if (Length
> (Maximum
- Minimum
+ 1))
264 AslError (ASL_ERROR
, ASL_MSG_INVALID_LENGTH
, LengthOp
, NULL
);
268 /* If specified (non-zero), ensure granularity is a power-of-two minus one */
272 if ((Granularity
+ 1) &
275 AslError (ASL_ERROR
, ASL_MSG_INVALID_GRANULARITY
, GranOp
, NULL
);
281 * Check the various combinations of Length, MinFixed, and MaxFixed
285 /* Fixed non-zero length */
287 switch (Flags
& (ACPI_RESOURCE_FLAG_MIF
| ACPI_RESOURCE_FLAG_MAF
))
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
);
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
);
317 /* All other combinations are invalid */
319 case ACPI_RESOURCE_FLAG_MIF
:
320 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
):
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 ******************************************************************************/
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
);
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 ******************************************************************************/
420 RsAllocateResourceNode (
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
;
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 ******************************************************************************/
459 RsCreateResourceField (
460 ACPI_PARSE_OBJECT
*Op
,
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 ******************************************************************************/
497 ACPI_PARSE_OBJECT
*Op
,
502 if (Op
->Asl
.ParseOpcode
== PARSEOP_DEFAULT_ARG
)
504 /* Use the default bit */
506 *Flags
|= (DefaultBit
<< Position
);
510 /* Use the bit specified in the initialization node */
512 *Flags
|= (((UINT8
) Op
->Asl
.Value
.Integer
) << Position
);
520 ACPI_PARSE_OBJECT
*Op
,
525 if (Op
->Asl
.ParseOpcode
== PARSEOP_DEFAULT_ARG
)
527 /* Use the default bit */
529 *Flags
|= (DefaultBit
<< Position
);
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 ******************************************************************************/
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
577 * DESCRIPTION: Check an initializer list for duplicate values. Emits an error
578 * if any duplicates are found.
580 ******************************************************************************/
583 RsCheckListForDuplicates (
584 ACPI_PARSE_OBJECT
*Op
)
586 ACPI_PARSE_OBJECT
*NextValueOp
= Op
;
587 ACPI_PARSE_OBJECT
*NextOp
;
596 /* Search list once for each value in the list */
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
);
607 if (NextOp
->Asl
.ParseOpcode
!= PARSEOP_DEFAULT_ARG
)
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
,
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
640 * RETURN: A valid resource node for the descriptor
642 * DESCRIPTION: Dispatches the processing of one resource descriptor
644 ******************************************************************************/
647 RsDoOneResourceDescriptor (
648 ACPI_PARSE_OBJECT
*DescriptorTypeOp
,
649 UINT32 CurrentByteOffset
,
652 ASL_RESOURCE_NODE
*Rnode
= NULL
;
655 /* Construct the resource */
657 switch (DescriptorTypeOp
->Asl
.ParseOpcode
)
661 Rnode
= RsDoDmaDescriptor (DescriptorTypeOp
,
665 case PARSEOP_FIXEDDMA
:
667 Rnode
= RsDoFixedDmaDescriptor (DescriptorTypeOp
,
671 case PARSEOP_DWORDIO
:
673 Rnode
= RsDoDwordIoDescriptor (DescriptorTypeOp
,
677 case PARSEOP_DWORDMEMORY
:
679 Rnode
= RsDoDwordMemoryDescriptor (DescriptorTypeOp
,
683 case PARSEOP_DWORDSPACE
:
685 Rnode
= RsDoDwordSpaceDescriptor (DescriptorTypeOp
,
689 case PARSEOP_ENDDEPENDENTFN
:
693 case ACPI_RSTATE_NORMAL
:
695 AslError (ASL_ERROR
, ASL_MSG_MISSING_STARTDEPENDENT
,
696 DescriptorTypeOp
, NULL
);
699 case ACPI_RSTATE_START_DEPENDENT
:
701 AslError (ASL_ERROR
, ASL_MSG_DEPENDENT_NESTING
,
702 DescriptorTypeOp
, NULL
);
705 case ACPI_RSTATE_DEPENDENT_LIST
:
711 *State
= ACPI_RSTATE_NORMAL
;
712 Rnode
= RsDoEndDependentDescriptor (DescriptorTypeOp
,
718 Rnode
= RsDoEndTagDescriptor (DescriptorTypeOp
,
722 case PARSEOP_EXTENDEDIO
:
724 Rnode
= RsDoExtendedIoDescriptor (DescriptorTypeOp
,
728 case PARSEOP_EXTENDEDMEMORY
:
730 Rnode
= RsDoExtendedMemoryDescriptor (DescriptorTypeOp
,
734 case PARSEOP_EXTENDEDSPACE
:
736 Rnode
= RsDoExtendedSpaceDescriptor (DescriptorTypeOp
,
740 case PARSEOP_FIXEDIO
:
742 Rnode
= RsDoFixedIoDescriptor (DescriptorTypeOp
,
746 case PARSEOP_INTERRUPT
:
748 Rnode
= RsDoInterruptDescriptor (DescriptorTypeOp
,
754 Rnode
= RsDoIoDescriptor (DescriptorTypeOp
,
760 Rnode
= RsDoIrqDescriptor (DescriptorTypeOp
,
764 case PARSEOP_IRQNOFLAGS
:
766 Rnode
= RsDoIrqNoFlagsDescriptor (DescriptorTypeOp
,
770 case PARSEOP_MEMORY24
:
772 Rnode
= RsDoMemory24Descriptor (DescriptorTypeOp
,
776 case PARSEOP_MEMORY32
:
778 Rnode
= RsDoMemory32Descriptor (DescriptorTypeOp
,
782 case PARSEOP_MEMORY32FIXED
:
784 Rnode
= RsDoMemory32FixedDescriptor (DescriptorTypeOp
,
788 case PARSEOP_QWORDIO
:
790 Rnode
= RsDoQwordIoDescriptor (DescriptorTypeOp
,
794 case PARSEOP_QWORDMEMORY
:
796 Rnode
= RsDoQwordMemoryDescriptor (DescriptorTypeOp
,
800 case PARSEOP_QWORDSPACE
:
802 Rnode
= RsDoQwordSpaceDescriptor (DescriptorTypeOp
,
806 case PARSEOP_REGISTER
:
808 Rnode
= RsDoGeneralRegisterDescriptor (DescriptorTypeOp
,
812 case PARSEOP_STARTDEPENDENTFN
:
816 case ACPI_RSTATE_START_DEPENDENT
:
818 AslError (ASL_ERROR
, ASL_MSG_DEPENDENT_NESTING
,
819 DescriptorTypeOp
, NULL
);
822 case ACPI_RSTATE_NORMAL
:
823 case ACPI_RSTATE_DEPENDENT_LIST
:
829 *State
= ACPI_RSTATE_START_DEPENDENT
;
830 Rnode
= RsDoStartDependentDescriptor (DescriptorTypeOp
,
832 *State
= ACPI_RSTATE_DEPENDENT_LIST
;
835 case PARSEOP_STARTDEPENDENTFN_NOPRI
:
839 case ACPI_RSTATE_START_DEPENDENT
:
841 AslError (ASL_ERROR
, ASL_MSG_DEPENDENT_NESTING
,
842 DescriptorTypeOp
, NULL
);
845 case ACPI_RSTATE_NORMAL
:
846 case ACPI_RSTATE_DEPENDENT_LIST
:
852 *State
= ACPI_RSTATE_START_DEPENDENT
;
853 Rnode
= RsDoStartDependentNoPriDescriptor (DescriptorTypeOp
,
855 *State
= ACPI_RSTATE_DEPENDENT_LIST
;
858 case PARSEOP_VENDORLONG
:
860 Rnode
= RsDoVendorLargeDescriptor (DescriptorTypeOp
,
864 case PARSEOP_VENDORSHORT
:
866 Rnode
= RsDoVendorSmallDescriptor (DescriptorTypeOp
,
870 case PARSEOP_WORDBUSNUMBER
:
872 Rnode
= RsDoWordBusNumberDescriptor (DescriptorTypeOp
,
878 Rnode
= RsDoWordIoDescriptor (DescriptorTypeOp
,
882 case PARSEOP_WORDSPACE
:
884 Rnode
= RsDoWordSpaceDescriptor (DescriptorTypeOp
,
888 case PARSEOP_GPIO_INT
:
890 Rnode
= RsDoGpioIntDescriptor (DescriptorTypeOp
,
894 case PARSEOP_GPIO_IO
:
896 Rnode
= RsDoGpioIoDescriptor (DescriptorTypeOp
,
900 case PARSEOP_I2C_SERIALBUS
:
902 Rnode
= RsDoI2cSerialBusDescriptor (DescriptorTypeOp
,
906 case PARSEOP_SPI_SERIALBUS
:
908 Rnode
= RsDoSpiSerialBusDescriptor (DescriptorTypeOp
,
912 case PARSEOP_UART_SERIALBUS
:
914 Rnode
= RsDoUartSerialBusDescriptor (DescriptorTypeOp
,
918 case PARSEOP_DEFAULT_ARG
:
920 /* Just ignore any of these, they are used as fillers/placeholders */
925 printf ("Unknown resource descriptor type [%s]\n",
926 DescriptorTypeOp
->Asl
.ParseOpName
);
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
;
941 DescriptorTypeOp
->Asl
.FinalAmlLength
= Rnode
->BufferLength
;
942 DescriptorTypeOp
->Asl
.Extra
= ((AML_RESOURCE
*) Rnode
->Buffer
)->DescriptorType
;
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 ******************************************************************************/
965 RsLinkDescriptorChain (
966 ASL_RESOURCE_NODE
**PreviousRnode
,
967 ASL_RESOURCE_NODE
*Rnode
)
969 ASL_RESOURCE_NODE
*LastRnode
;
970 UINT32 CurrentByteOffset
;
973 /* Anything to do? */
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 */
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 ******************************************************************************/
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
;
1029 /* Mark parent as containing a resource template */
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
,
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
)
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
);