1 /*******************************************************************************
3 * Module Name: rscalc - Calculate stream and list lengths
6 ******************************************************************************/
8 /******************************************************************************
12 * Some or all of this work - Copyright (c) 1999 - 2005, Intel Corp.
13 * All rights reserved.
17 * 2.1. This is your license from Intel Corp. under its intellectual property
18 * rights. You may have additional license terms from the party that provided
19 * you this software, covering your right to use that party's intellectual
22 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
23 * copy of the source code appearing in this file ("Covered Code") an
24 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
25 * base code distributed originally by Intel ("Original Intel Code") to copy,
26 * make derivatives, distribute, use and display any portion of the Covered
27 * Code in any form, with the right to sublicense such rights; and
29 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
30 * license (with the right to sublicense), under only those claims of Intel
31 * patents that are infringed by the Original Intel Code, to make, use, sell,
32 * offer to sell, and import the Covered Code and derivative works thereof
33 * solely to the minimum extent necessary to exercise the above copyright
34 * license, and in no event shall the patent license extend to any additions
35 * to or modifications of the Original Intel Code. No other license or right
36 * is granted directly or by implication, estoppel or otherwise;
38 * The above copyright and patent license is granted only if the following
43 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
44 * Redistribution of source code of any substantial portion of the Covered
45 * Code or modification with rights to further distribute source must include
46 * the above Copyright Notice, the above License, this list of Conditions,
47 * and the following Disclaimer and Export Compliance provision. In addition,
48 * Licensee must cause all Covered Code to which Licensee contributes to
49 * contain a file documenting the changes Licensee made to create that Covered
50 * Code and the date of any change. Licensee must include in that file the
51 * documentation of any changes made by any predecessor Licensee. Licensee
52 * must include a prominent statement that the modification is derived,
53 * directly or indirectly, from Original Intel Code.
55 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
56 * Redistribution of source code of any substantial portion of the Covered
57 * Code or modification without rights to further distribute source must
58 * include the following Disclaimer and Export Compliance provision in the
59 * documentation and/or other materials provided with distribution. In
60 * addition, Licensee may not authorize further sublicense of source of any
61 * portion of the Covered Code, and must include terms to the effect that the
62 * license from Licensee to its licensee is limited to the intellectual
63 * property embodied in the software Licensee provides to its licensee, and
64 * not to intellectual property embodied in modifications its licensee may
67 * 3.3. Redistribution of Executable. Redistribution in executable form of any
68 * substantial portion of the Covered Code or modification must reproduce the
69 * above Copyright Notice, and the following Disclaimer and Export Compliance
70 * provision in the documentation and/or other materials provided with the
73 * 3.4. Intel retains all right, title, and interest in and to the Original
76 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
77 * Intel shall be used in advertising or otherwise to promote the sale, use or
78 * other dealings in products derived from or relating to the Covered Code
79 * without prior written authorization from Intel.
81 * 4. Disclaimer and Export Compliance
83 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
84 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
85 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
86 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
87 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
88 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
91 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
92 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
93 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
94 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
95 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
96 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
97 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
100 * 4.3. Licensee shall not export, either directly or indirectly, any of this
101 * software or system incorporating such software without first obtaining any
102 * required license or other approval from the U. S. Department of Commerce or
103 * any other agency or department of the United States Government. In the
104 * event Licensee exports any such software from the United States or
105 * re-exports any such software from a foreign destination, Licensee shall
106 * ensure that the distribution and export/re-export of the software is in
107 * compliance with all laws, regulations, orders, or other restrictions of the
108 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
109 * any of its subsidiaries will export/re-export any technical data, process,
110 * software, or service, directly or indirectly, to any country for which the
111 * United States government or any agency thereof requires an export license,
112 * other governmental approval, or letter of assurance, without first obtaining
113 * such license, approval or letter.
115 *****************************************************************************/
122 #include "acnamesp.h"
124 #define _COMPONENT ACPI_RESOURCES
125 ACPI_MODULE_NAME ("rscalc")
128 /*******************************************************************************
130 * FUNCTION: AcpiRsGetByteStreamLength
132 * PARAMETERS: LinkedList - Pointer to the resource linked list
133 * SizeNeeded - UINT32 pointer of the size buffer needed
134 * to properly return the parsed data
138 * DESCRIPTION: Takes the resource byte stream and parses it once, calculating
139 * the size buffer needed to hold the linked list that conveys
142 ******************************************************************************/
145 AcpiRsGetByteStreamLength (
146 ACPI_RESOURCE *LinkedList,
147 ACPI_SIZE *SizeNeeded)
149 ACPI_SIZE ByteStreamSizeNeeded = 0;
150 ACPI_SIZE SegmentSize;
151 BOOLEAN Done = FALSE;
154 ACPI_FUNCTION_TRACE ("RsGetByteStreamLength");
160 * Init the variable that will hold the size to add to the total.
164 switch (LinkedList->Id)
166 case ACPI_RSTYPE_IRQ:
169 * For an IRQ Resource, Byte 3, although optional, will always be
170 * created - it holds IRQ information.
175 case ACPI_RSTYPE_DMA:
178 * For this resource the size is static
183 case ACPI_RSTYPE_START_DPF:
185 * Start Dependent Functions Resource
186 * For a StartDependentFunctions Resource, Byte 1, although
187 * optional, will always be created.
192 case ACPI_RSTYPE_END_DPF:
194 * End Dependent Functions Resource
195 * For this resource the size is static
203 * For this resource the size is static
208 case ACPI_RSTYPE_FIXED_IO:
210 * Fixed IO Port Resource
211 * For this resource the size is static
216 case ACPI_RSTYPE_VENDOR:
218 * Vendor Defined Resource
219 * For a Vendor Specific resource, if the Length is between 1 and 7
220 * it will be created as a Small Resource data type, otherwise it
221 * is a Large Resource data type.
223 if (LinkedList->Data.VendorSpecific.Length > 7)
231 SegmentSize += LinkedList->Data.VendorSpecific.Length;
234 case ACPI_RSTYPE_END_TAG:
237 * For this resource the size is static
243 case ACPI_RSTYPE_MEM24:
245 * 24-Bit Memory Resource
246 * For this resource the size is static
251 case ACPI_RSTYPE_MEM32:
253 * 32-Bit Memory Range Resource
254 * For this resource the size is static
259 case ACPI_RSTYPE_FIXED_MEM32:
261 * 32-Bit Fixed Memory Resource
262 * For this resource the size is static
267 case ACPI_RSTYPE_ADDRESS16:
269 * 16-Bit Address Resource
270 * The base size of this byte stream is 16. If a Resource Source
271 * string is not NULL, add 1 for the Index + the length of the null
272 * terminated string Resource Source + 1 for the null.
276 if (LinkedList->Data.Address16.ResourceSource.StringPtr)
278 SegmentSize += LinkedList->Data.Address16.ResourceSource.StringLength;
283 case ACPI_RSTYPE_ADDRESS32:
285 * 32-Bit Address Resource
286 * The base size of this byte stream is 26. If a Resource
287 * Source string is not NULL, add 1 for the Index + the
288 * length of the null terminated string Resource Source +
293 if (LinkedList->Data.Address32.ResourceSource.StringPtr)
295 SegmentSize += LinkedList->Data.Address32.ResourceSource.StringLength;
300 case ACPI_RSTYPE_ADDRESS64:
302 * 64-Bit Address Resource
303 * The base size of this byte stream is 46. If a ResourceSource
304 * string is not NULL, add 1 for the Index + the length of the null
305 * terminated string Resource Source + 1 for the null.
309 if (LinkedList->Data.Address64.ResourceSource.StringPtr)
311 SegmentSize += LinkedList->Data.Address64.ResourceSource.StringLength;
316 case ACPI_RSTYPE_EXT_IRQ:
318 * Extended IRQ Resource
319 * The base size of this byte stream is 9. This is for an Interrupt
320 * table length of 1. For each additional interrupt, add 4.
321 * If a Resource Source string is not NULL, add 1 for the
322 * Index + the length of the null terminated string
323 * Resource Source + 1 for the null.
326 (((ACPI_SIZE) LinkedList->Data.ExtendedIrq.NumberOfInterrupts - 1) * 4);
328 if (LinkedList->Data.ExtendedIrq.ResourceSource.StringPtr)
330 SegmentSize += LinkedList->Data.ExtendedIrq.ResourceSource.StringLength;
337 * If we get here, everything is out of sync, exit with error
339 return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
341 } /* switch (LinkedList->Id) */
346 ByteStreamSizeNeeded += SegmentSize;
349 * Point to the next object
351 LinkedList = ACPI_PTR_ADD (ACPI_RESOURCE,
352 LinkedList, LinkedList->Length);
356 * This is the data the caller needs
358 *SizeNeeded = ByteStreamSizeNeeded;
359 return_ACPI_STATUS (AE_OK);
363 /*******************************************************************************
365 * FUNCTION: AcpiRsGetListLength
367 * PARAMETERS: ByteStreamBuffer - Pointer to the resource byte stream
368 * ByteStreamBufferLength - Size of ByteStreamBuffer
369 * SizeNeeded - UINT32 pointer of the size buffer
370 * needed to properly return the
375 * DESCRIPTION: Takes the resource byte stream and parses it once, calculating
376 * the size buffer needed to hold the linked list that conveys
379 ******************************************************************************/
382 AcpiRsGetListLength (
383 UINT8 *ByteStreamBuffer,
384 UINT32 ByteStreamBufferLength,
385 ACPI_SIZE *SizeNeeded)
387 UINT32 BufferSize = 0;
388 UINT32 BytesParsed = 0;
389 UINT8 NumberOfInterrupts = 0;
390 UINT8 NumberOfChannels = 0;
392 UINT32 StructureSize;
393 UINT32 BytesConsumed;
398 UINT8 AdditionalBytes;
401 ACPI_FUNCTION_TRACE ("RsGetListLength");
404 while (BytesParsed < ByteStreamBufferLength)
407 * The next byte in the stream is the resource type
409 ResourceType = AcpiRsGetResourceType (*ByteStreamBuffer);
411 switch (ResourceType)
413 case ACPI_RDESC_TYPE_MEMORY_24:
415 * 24-Bit Memory Resource
419 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_MEM24);
423 case ACPI_RDESC_TYPE_LARGE_VENDOR:
425 * Vendor Defined Resource
427 Buffer = ByteStreamBuffer;
430 ACPI_MOVE_16_TO_16 (&Temp16, Buffer);
431 BytesConsumed = Temp16 + 3;
434 * Ensure a 32-bit boundary for the structure
436 Temp16 = (UINT16) ACPI_ROUND_UP_TO_32BITS (Temp16);
438 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_VENDOR) +
439 (Temp16 * sizeof (UINT8));
443 case ACPI_RDESC_TYPE_MEMORY_32:
445 * 32-Bit Memory Range Resource
449 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_MEM32);
453 case ACPI_RDESC_TYPE_FIXED_MEMORY_32:
455 * 32-Bit Fixed Memory Resource
459 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_FIXED_MEM32);
463 case ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE:
465 * 64-Bit Address Resource
467 Buffer = ByteStreamBuffer;
470 ACPI_MOVE_16_TO_16 (&Temp16, Buffer);
472 BytesConsumed = Temp16 + 3;
475 * Resource Source Index and Resource Source are optional elements.
476 * Check the length of the Bytestream. If it is greater than 43,
477 * that means that an Index exists and is followed by a null
478 * terminated string. Therefore, set the temp variable to the
479 * length minus the minimum byte stream length plus the byte for
480 * the Index to determine the size of the NULL terminated string.
484 Temp8 = (UINT8) (Temp16 - 44);
492 * Ensure a 64-bit boundary for the structure
494 Temp8 = (UINT8) ACPI_ROUND_UP_TO_64BITS (Temp8);
496 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_ADDRESS64) +
497 (Temp8 * sizeof (UINT8));
501 case ACPI_RDESC_TYPE_DWORD_ADDRESS_SPACE:
503 * 32-Bit Address Resource
505 Buffer = ByteStreamBuffer;
508 ACPI_MOVE_16_TO_16 (&Temp16, Buffer);
510 BytesConsumed = Temp16 + 3;
513 * Resource Source Index and Resource Source are optional elements.
514 * Check the length of the Bytestream. If it is greater than 23,
515 * that means that an Index exists and is followed by a null
516 * terminated string. Therefore, set the temp variable to the
517 * length minus the minimum byte stream length plus the byte for
518 * the Index to determine the size of the NULL terminated string.
522 Temp8 = (UINT8) (Temp16 - 24);
530 * Ensure a 32-bit boundary for the structure
532 Temp8 = (UINT8) ACPI_ROUND_UP_TO_32BITS (Temp8);
534 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_ADDRESS32) +
535 (Temp8 * sizeof (UINT8));
539 case ACPI_RDESC_TYPE_WORD_ADDRESS_SPACE:
541 * 16-Bit Address Resource
543 Buffer = ByteStreamBuffer;
546 ACPI_MOVE_16_TO_16 (&Temp16, Buffer);
548 BytesConsumed = Temp16 + 3;
551 * Resource Source Index and Resource Source are optional elements.
552 * Check the length of the Bytestream. If it is greater than 13,
553 * that means that an Index exists and is followed by a null
554 * terminated string. Therefore, set the temp variable to the
555 * length minus the minimum byte stream length plus the byte for
556 * the Index to determine the size of the NULL terminated string.
560 Temp8 = (UINT8) (Temp16 - 14);
568 * Ensure a 32-bit boundary for the structure
570 Temp8 = (UINT8) ACPI_ROUND_UP_TO_32BITS (Temp8);
572 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_ADDRESS16) +
573 (Temp8 * sizeof (UINT8));
577 case ACPI_RDESC_TYPE_EXTENDED_XRUPT:
581 Buffer = ByteStreamBuffer;
584 ACPI_MOVE_16_TO_16 (&Temp16, Buffer);
586 BytesConsumed = Temp16 + 3;
589 * Point past the length field and the Interrupt vector flags to
590 * save off the Interrupt table length to the Temp8 variable.
596 * To compensate for multiple interrupt numbers, add 4 bytes for
597 * each additional interrupts greater than 1
599 AdditionalBytes = (UINT8) ((Temp8 - 1) * 4);
602 * Resource Source Index and Resource Source are optional elements.
603 * Check the length of the Bytestream. If it is greater than 9,
604 * that means that an Index exists and is followed by a null
605 * terminated string. Therefore, set the temp variable to the
606 * length minus the minimum byte stream length plus the byte for
607 * the Index to determine the size of the NULL terminated string.
609 if (9 + AdditionalBytes < Temp16)
611 Temp8 = (UINT8) (Temp16 - (9 + AdditionalBytes));
619 * Ensure a 32-bit boundary for the structure
621 Temp8 = (UINT8) ACPI_ROUND_UP_TO_32BITS (Temp8);
623 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_EXT_IRQ) +
624 (AdditionalBytes * sizeof (UINT8)) +
625 (Temp8 * sizeof (UINT8));
629 case ACPI_RDESC_TYPE_IRQ_FORMAT:
632 * Determine if it there are two or three trailing bytes
634 Buffer = ByteStreamBuffer;
646 /* Point past the descriptor */
651 * Look at the number of bits set
653 ACPI_MOVE_16_TO_16 (&Temp16, Buffer);
655 for (Index = 0; Index < 16; Index++)
659 ++NumberOfInterrupts;
665 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_IO) +
666 (NumberOfInterrupts * sizeof (UINT32));
670 case ACPI_RDESC_TYPE_DMA_FORMAT:
674 Buffer = ByteStreamBuffer;
677 /* Point past the descriptor */
682 * Look at the number of bits set
686 for(Index = 0; Index < 8; Index++)
696 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_DMA) +
697 (NumberOfChannels * sizeof (UINT32));
701 case ACPI_RDESC_TYPE_START_DEPENDENT:
703 * Start Dependent Functions Resource
704 * Determine if it there are two or three trailing bytes
706 Buffer = ByteStreamBuffer;
718 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_START_DPF);
722 case ACPI_RDESC_TYPE_END_DEPENDENT:
724 * End Dependent Functions Resource
727 StructureSize = ACPI_RESOURCE_LENGTH;
731 case ACPI_RDESC_TYPE_IO_PORT:
736 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_IO);
740 case ACPI_RDESC_TYPE_FIXED_IO_PORT:
742 * Fixed IO Port Resource
745 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_FIXED_IO);
749 case ACPI_RDESC_TYPE_SMALL_VENDOR:
751 * Vendor Specific Resource
753 Buffer = ByteStreamBuffer;
756 Temp8 = (UINT8) (Temp8 & 0x7);
757 BytesConsumed = Temp8 + 1;
760 * Ensure a 32-bit boundary for the structure
762 Temp8 = (UINT8) ACPI_ROUND_UP_TO_32BITS (Temp8);
763 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_VENDOR) +
764 (Temp8 * sizeof (UINT8));
768 case ACPI_RDESC_TYPE_END_TAG:
773 StructureSize = ACPI_RESOURCE_LENGTH;
774 ByteStreamBufferLength = BytesParsed;
780 * If we get here, everything is out of sync,
783 return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
787 * Update the return value and counter
789 BufferSize += (UINT32) ACPI_ALIGN_RESOURCE_SIZE (StructureSize);
790 BytesParsed += BytesConsumed;
793 * Set the byte stream to point to the next resource
795 ByteStreamBuffer += BytesConsumed;
799 * This is the data the caller needs
801 *SizeNeeded = BufferSize;
802 return_ACPI_STATUS (AE_OK);
806 /*******************************************************************************
808 * FUNCTION: AcpiRsGetPciRoutingTableLength
810 * PARAMETERS: PackageObject - Pointer to the package object
811 * BufferSizeNeeded - UINT32 pointer of the size buffer
812 * needed to properly return the
817 * DESCRIPTION: Given a package representing a PCI routing table, this
818 * calculates the size of the corresponding linked list of
821 ******************************************************************************/
824 AcpiRsGetPciRoutingTableLength (
825 ACPI_OPERAND_OBJECT *PackageObject,
826 ACPI_SIZE *BufferSizeNeeded)
828 UINT32 NumberOfElements;
829 ACPI_SIZE TempSizeNeeded = 0;
830 ACPI_OPERAND_OBJECT **TopObjectList;
832 ACPI_OPERAND_OBJECT *PackageElement;
833 ACPI_OPERAND_OBJECT **SubObjectList;
838 ACPI_FUNCTION_TRACE ("RsGetPciRoutingTableLength");
841 NumberOfElements = PackageObject->Package.Count;
844 * Calculate the size of the return buffer.
845 * The base size is the number of elements * the sizes of the
846 * structures. Additional space for the strings is added below.
847 * The minus one is to subtract the size of the UINT8 Source[1]
848 * member because it is added below.
850 * But each PRT_ENTRY structure has a pointer to a string and
851 * the size of that string must be found.
853 TopObjectList = PackageObject->Package.Elements;
855 for (Index = 0; Index < NumberOfElements; Index++)
858 * Dereference the sub-package
860 PackageElement = *TopObjectList;
863 * The SubObjectList will now point to an array of the
864 * four IRQ elements: Address, Pin, Source and SourceIndex
866 SubObjectList = PackageElement->Package.Elements;
869 * Scan the IrqTableElements for the Source Name String
873 for (TableIndex = 0; TableIndex < 4 && !NameFound; TableIndex++)
875 if ((ACPI_TYPE_STRING == ACPI_GET_OBJECT_TYPE (*SubObjectList)) ||
876 ((ACPI_TYPE_LOCAL_REFERENCE == ACPI_GET_OBJECT_TYPE (*SubObjectList)) &&
877 ((*SubObjectList)->Reference.Opcode == AML_INT_NAMEPATH_OP)))
884 * Look at the next element
890 TempSizeNeeded += (sizeof (ACPI_PCI_ROUTING_TABLE) - 4);
893 * Was a String type found?
897 if (ACPI_GET_OBJECT_TYPE (*SubObjectList) == ACPI_TYPE_STRING)
900 * The length String.Length field does not include the
901 * terminating NULL, add 1
903 TempSizeNeeded += ((ACPI_SIZE) (*SubObjectList)->String.Length + 1);
907 TempSizeNeeded += AcpiNsGetPathnameLength (
908 (*SubObjectList)->Reference.Node);
914 * If no name was found, then this is a NULL, which is
915 * translated as a UINT32 zero.
917 TempSizeNeeded += sizeof (UINT32);
920 /* Round up the size since each element must be aligned */
922 TempSizeNeeded = ACPI_ROUND_UP_TO_64BITS (TempSizeNeeded);
925 * Point to the next ACPI_OPERAND_OBJECT
931 * Adding an extra element to the end of the list, essentially a NULL terminator
933 *BufferSizeNeeded = TempSizeNeeded + sizeof (ACPI_PCI_ROUTING_TABLE);
934 return_ACPI_STATUS (AE_OK);