1 /*******************************************************************************
3 * Module Name: rscalc - Calculate stream and list lengths
6 ******************************************************************************/
8 /******************************************************************************
12 * Some or all of this work - Copyright (c) 1999 - 2003, 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 *****************************************************************************/
116 /* $DragonFly: src/sys/contrib/dev/acpica/Attic/rscalc.c,v 1.1 2003/09/24 03:32:16 drhodus Exp $ */
123 #include "acnamesp.h"
125 #define _COMPONENT ACPI_RESOURCES
126 ACPI_MODULE_NAME ("rscalc")
129 /*******************************************************************************
131 * FUNCTION: AcpiRsGetByteStreamLength
133 * PARAMETERS: LinkedList - Pointer to the resource linked list
134 * SizeNeeded - UINT32 pointer of the size buffer needed
135 * to properly return the parsed data
139 * DESCRIPTION: Takes the resource byte stream and parses it once, calculating
140 * the size buffer needed to hold the linked list that conveys
143 ******************************************************************************/
146 AcpiRsGetByteStreamLength (
147 ACPI_RESOURCE *LinkedList,
148 ACPI_SIZE *SizeNeeded)
150 ACPI_SIZE ByteStreamSizeNeeded = 0;
151 ACPI_SIZE SegmentSize;
152 ACPI_RESOURCE_EXT_IRQ *ExIrq = NULL;
153 BOOLEAN Done = FALSE;
156 ACPI_FUNCTION_TRACE ("RsGetByteStreamLength");
162 * Init the variable that will hold the size to add to the total.
166 switch (LinkedList->Id)
168 case ACPI_RSTYPE_IRQ:
171 * For an IRQ Resource, Byte 3, although optional, will
172 * always be created - it holds IRQ information.
177 case ACPI_RSTYPE_DMA:
180 * For this resource the size is static
185 case ACPI_RSTYPE_START_DPF:
187 * Start Dependent Functions Resource
188 * For a StartDependentFunctions Resource, Byte 1,
189 * although optional, will always be created.
194 case ACPI_RSTYPE_END_DPF:
196 * End Dependent Functions Resource
197 * For this resource the size is static
205 * For this resource the size is static
210 case ACPI_RSTYPE_FIXED_IO:
212 * Fixed IO Port Resource
213 * For this resource the size is static
218 case ACPI_RSTYPE_VENDOR:
220 * Vendor Defined Resource
221 * For a Vendor Specific resource, if the Length is
222 * between 1 and 7 it will be created as a Small
223 * Resource data type, otherwise it is a Large
224 * Resource data type.
226 if (LinkedList->Data.VendorSpecific.Length > 7)
234 SegmentSize += LinkedList->Data.VendorSpecific.Length;
237 case ACPI_RSTYPE_END_TAG:
240 * For this resource the size is static
246 case ACPI_RSTYPE_MEM24:
248 * 24-Bit Memory Resource
249 * For this resource the size is static
254 case ACPI_RSTYPE_MEM32:
256 * 32-Bit Memory Range Resource
257 * For this resource the size is static
262 case ACPI_RSTYPE_FIXED_MEM32:
264 * 32-Bit Fixed Memory Resource
265 * For this resource the size is static
270 case ACPI_RSTYPE_ADDRESS16:
272 * 16-Bit Address Resource
273 * The base size of this byte stream is 16. If a
274 * Resource Source string is not NULL, add 1 for
275 * the Index + the length of the null terminated
276 * string Resource Source + 1 for the null.
280 if (LinkedList->Data.Address16.ResourceSource.StringPtr)
282 SegmentSize += LinkedList->Data.Address16.ResourceSource.StringLength;
287 case ACPI_RSTYPE_ADDRESS32:
289 * 32-Bit Address Resource
290 * The base size of this byte stream is 26. If a Resource
291 * Source string is not NULL, add 1 for the Index + the
292 * length of the null terminated string Resource Source +
297 if (LinkedList->Data.Address32.ResourceSource.StringPtr)
299 SegmentSize += LinkedList->Data.Address32.ResourceSource.StringLength;
304 case ACPI_RSTYPE_ADDRESS64:
306 * 64-Bit Address Resource
307 * The base size of this byte stream is 46. If a Resource
308 * Source string is not NULL, add 1 for the Index + the
309 * length of the null terminated string Resource Source +
314 if (LinkedList->Data.Address64.ResourceSource.StringPtr)
316 SegmentSize += LinkedList->Data.Address64.ResourceSource.StringLength;
321 case ACPI_RSTYPE_EXT_IRQ:
323 * Extended IRQ Resource
324 * The base size of this byte stream is 9. This is for an
325 * Interrupt table length of 1. For each additional
327 * If a Resource Source string is not NULL, add 1 for the
328 * Index + the length of the null terminated string
329 * Resource Source + 1 for the null.
332 (((ACPI_SIZE) LinkedList->Data.ExtendedIrq.NumberOfInterrupts - 1) * 4);
334 if (ExIrq && ExIrq->ResourceSource.StringPtr)
336 SegmentSize += LinkedList->Data.ExtendedIrq.ResourceSource.StringLength;
343 * If we get here, everything is out of sync,
344 * so exit with an error
346 return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
348 } /* switch (LinkedList->Id) */
353 ByteStreamSizeNeeded += SegmentSize;
356 * Point to the next object
358 LinkedList = ACPI_PTR_ADD (ACPI_RESOURCE,
359 LinkedList, LinkedList->Length);
363 * This is the data the caller needs
365 *SizeNeeded = ByteStreamSizeNeeded;
366 return_ACPI_STATUS (AE_OK);
370 /*******************************************************************************
372 * FUNCTION: AcpiRsGetListLength
374 * PARAMETERS: ByteStreamBuffer - Pointer to the resource byte stream
375 * ByteStreamBufferLength - Size of ByteStreamBuffer
376 * SizeNeeded - UINT32 pointer of the size buffer
377 * needed to properly return the
382 * DESCRIPTION: Takes the resource byte stream and parses it once, calculating
383 * the size buffer needed to hold the linked list that conveys
386 ******************************************************************************/
389 AcpiRsGetListLength (
390 UINT8 *ByteStreamBuffer,
391 UINT32 ByteStreamBufferLength,
392 ACPI_SIZE *SizeNeeded)
394 UINT32 BufferSize = 0;
395 UINT32 BytesParsed = 0;
396 UINT8 NumberOfInterrupts = 0;
397 UINT8 NumberOfChannels = 0;
399 UINT32 StructureSize;
400 UINT32 BytesConsumed;
405 UINT8 AdditionalBytes;
408 ACPI_FUNCTION_TRACE ("RsGetListLength");
411 while (BytesParsed < ByteStreamBufferLength)
414 * The next byte in the stream is the resource type
416 ResourceType = AcpiRsGetResourceType (*ByteStreamBuffer);
418 switch (ResourceType)
420 case ACPI_RDESC_TYPE_MEMORY_24:
422 * 24-Bit Memory Resource
426 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_MEM24);
430 case ACPI_RDESC_TYPE_LARGE_VENDOR:
432 * Vendor Defined Resource
434 Buffer = ByteStreamBuffer;
437 ACPI_MOVE_UNALIGNED16_TO_16 (&Temp16, Buffer);
438 BytesConsumed = Temp16 + 3;
441 * Ensure a 32-bit boundary for the structure
443 Temp16 = (UINT16) ACPI_ROUND_UP_TO_32BITS (Temp16);
445 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_VENDOR) +
446 (Temp16 * sizeof (UINT8));
450 case ACPI_RDESC_TYPE_MEMORY_32:
452 * 32-Bit Memory Range Resource
457 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_MEM32);
461 case ACPI_RDESC_TYPE_FIXED_MEMORY_32:
463 * 32-Bit Fixed Memory Resource
467 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_FIXED_MEM32);
471 case ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE:
473 * 64-Bit Address Resource
475 Buffer = ByteStreamBuffer;
478 ACPI_MOVE_UNALIGNED16_TO_16 (&Temp16, Buffer);
480 BytesConsumed = Temp16 + 3;
483 * Resource Source Index and Resource Source are
484 * optional elements. Check the length of the
485 * Bytestream. If it is greater than 43, that
486 * means that an Index exists and is followed by
487 * a null termininated string. Therefore, set
488 * the temp variable to the length minus the minimum
489 * byte stream length plus the byte for the Index to
490 * determine the size of the NULL terminiated string.
494 Temp8 = (UINT8) (Temp16 - 44);
502 * Ensure a 64-bit boundary for the structure
504 Temp8 = (UINT8) ACPI_ROUND_UP_TO_64BITS (Temp8);
506 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_ADDRESS64) +
507 (Temp8 * sizeof (UINT8));
511 case ACPI_RDESC_TYPE_DWORD_ADDRESS_SPACE:
513 * 32-Bit Address Resource
515 Buffer = ByteStreamBuffer;
518 ACPI_MOVE_UNALIGNED16_TO_16 (&Temp16, Buffer);
520 BytesConsumed = Temp16 + 3;
523 * Resource Source Index and Resource Source are
524 * optional elements. Check the length of the
525 * Bytestream. If it is greater than 23, that
526 * means that an Index exists and is followed by
527 * a null termininated string. Therefore, set
528 * the temp variable to the length minus the minimum
529 * byte stream length plus the byte for the Index to
530 * determine the size of the NULL terminiated string.
534 Temp8 = (UINT8) (Temp16 - 24);
542 * Ensure a 32-bit boundary for the structure
544 Temp8 = (UINT8) ACPI_ROUND_UP_TO_32BITS (Temp8);
546 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_ADDRESS32) +
547 (Temp8 * sizeof (UINT8));
551 case ACPI_RDESC_TYPE_WORD_ADDRESS_SPACE:
553 * 16-Bit Address Resource
555 Buffer = ByteStreamBuffer;
558 ACPI_MOVE_UNALIGNED16_TO_16 (&Temp16, Buffer);
560 BytesConsumed = Temp16 + 3;
563 * Resource Source Index and Resource Source are
564 * optional elements. Check the length of the
565 * Bytestream. If it is greater than 13, that
566 * means that an Index exists and is followed by
567 * a null termininated string. Therefore, set
568 * the temp variable to the length minus the minimum
569 * byte stream length plus the byte for the Index to
570 * determine the size of the NULL terminiated string.
574 Temp8 = (UINT8) (Temp16 - 14);
582 * Ensure a 32-bit boundary for the structure
584 Temp8 = (UINT8) ACPI_ROUND_UP_TO_32BITS (Temp8);
586 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_ADDRESS16) +
587 (Temp8 * sizeof (UINT8));
591 case ACPI_RDESC_TYPE_EXTENDED_XRUPT:
595 Buffer = ByteStreamBuffer;
598 ACPI_MOVE_UNALIGNED16_TO_16 (&Temp16, Buffer);
600 BytesConsumed = Temp16 + 3;
603 * Point past the length field and the
604 * Interrupt vector flags to save off the
605 * Interrupt table length to the Temp8 variable.
611 * To compensate for multiple interrupt numbers, add 4 bytes for
612 * each additional interrupts greater than 1
614 AdditionalBytes = (UINT8) ((Temp8 - 1) * 4);
617 * Resource Source Index and Resource Source are
618 * optional elements. Check the length of the
619 * Bytestream. If it is greater than 9, that
620 * means that an Index exists and is followed by
621 * a null termininated string. Therefore, set
622 * the temp variable to the length minus the minimum
623 * byte stream length plus the byte for the Index to
624 * determine the size of the NULL terminiated string.
626 if (9 + AdditionalBytes < Temp16)
628 Temp8 = (UINT8) (Temp16 - (9 + AdditionalBytes));
636 * Ensure a 32-bit boundary for the structure
638 Temp8 = (UINT8) ACPI_ROUND_UP_TO_32BITS (Temp8);
640 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_EXT_IRQ) +
641 (AdditionalBytes * sizeof (UINT8)) +
642 (Temp8 * sizeof (UINT8));
646 case ACPI_RDESC_TYPE_IRQ_FORMAT:
649 * Determine if it there are two or three trailing bytes
651 Buffer = ByteStreamBuffer;
664 * Point past the descriptor
669 * Look at the number of bits set
671 ACPI_MOVE_UNALIGNED16_TO_16 (&Temp16, Buffer);
673 for (Index = 0; Index < 16; Index++)
677 ++NumberOfInterrupts;
683 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_IO) +
684 (NumberOfInterrupts * sizeof (UINT32));
688 case ACPI_RDESC_TYPE_DMA_FORMAT:
692 Buffer = ByteStreamBuffer;
696 * Point past the descriptor
701 * Look at the number of bits set
705 for(Index = 0; Index < 8; Index++)
715 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_DMA) +
716 (NumberOfChannels * sizeof (UINT32));
720 case ACPI_RDESC_TYPE_START_DEPENDENT:
722 * Start Dependent Functions Resource
723 * Determine if it there are two or three trailing bytes
725 Buffer = ByteStreamBuffer;
737 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_START_DPF);
741 case ACPI_RDESC_TYPE_END_DEPENDENT:
743 * End Dependent Functions Resource
746 StructureSize = ACPI_RESOURCE_LENGTH;
750 case ACPI_RDESC_TYPE_IO_PORT:
755 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_IO);
759 case ACPI_RDESC_TYPE_FIXED_IO_PORT:
761 * Fixed IO Port Resource
764 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_FIXED_IO);
768 case ACPI_RDESC_TYPE_SMALL_VENDOR:
770 * Vendor Specific Resource
772 Buffer = ByteStreamBuffer;
775 Temp8 = (UINT8) (Temp8 & 0x7);
776 BytesConsumed = Temp8 + 1;
779 * Ensure a 32-bit boundary for the structure
781 Temp8 = (UINT8) ACPI_ROUND_UP_TO_32BITS (Temp8);
782 StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_VENDOR) +
783 (Temp8 * sizeof (UINT8));
787 case ACPI_RDESC_TYPE_END_TAG:
792 StructureSize = ACPI_RESOURCE_LENGTH;
793 ByteStreamBufferLength = BytesParsed;
799 * If we get here, everything is out of sync,
800 * so exit with an error
802 return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
806 * Update the return value and counter
808 BufferSize += ACPI_ALIGN_RESOURCE_SIZE(StructureSize);
809 BytesParsed += BytesConsumed;
812 * Set the byte stream to point to the next resource
814 ByteStreamBuffer += BytesConsumed;
818 * This is the data the caller needs
820 *SizeNeeded = BufferSize;
821 return_ACPI_STATUS (AE_OK);
825 /*******************************************************************************
827 * FUNCTION: AcpiRsGetPciRoutingTableLength
829 * PARAMETERS: PackageObject - Pointer to the package object
830 * BufferSizeNeeded - UINT32 pointer of the size buffer
831 * needed to properly return the
836 * DESCRIPTION: Given a package representing a PCI routing table, this
837 * calculates the size of the corresponding linked list of
840 ******************************************************************************/
843 AcpiRsGetPciRoutingTableLength (
844 ACPI_OPERAND_OBJECT *PackageObject,
845 ACPI_SIZE *BufferSizeNeeded)
847 UINT32 NumberOfElements;
848 ACPI_SIZE TempSizeNeeded = 0;
849 ACPI_OPERAND_OBJECT **TopObjectList;
851 ACPI_OPERAND_OBJECT *PackageElement;
852 ACPI_OPERAND_OBJECT **SubObjectList;
857 ACPI_FUNCTION_TRACE ("RsGetPciRoutingTableLength");
860 NumberOfElements = PackageObject->Package.Count;
863 * Calculate the size of the return buffer.
864 * The base size is the number of elements * the sizes of the
865 * structures. Additional space for the strings is added below.
866 * The minus one is to subtract the size of the UINT8 Source[1]
867 * member because it is added below.
869 * But each PRT_ENTRY structure has a pointer to a string and
870 * the size of that string must be found.
872 TopObjectList = PackageObject->Package.Elements;
874 for (Index = 0; Index < NumberOfElements; Index++)
877 * Dereference the sub-package
879 PackageElement = *TopObjectList;
882 * The SubObjectList will now point to an array of the
883 * four IRQ elements: Address, Pin, Source and SourceIndex
885 SubObjectList = PackageElement->Package.Elements;
888 * Scan the IrqTableElements for the Source Name String
892 for (TableIndex = 0; TableIndex < 4 && !NameFound; TableIndex++)
894 if ((ACPI_TYPE_STRING == ACPI_GET_OBJECT_TYPE (*SubObjectList)) ||
895 ((ACPI_TYPE_LOCAL_REFERENCE == ACPI_GET_OBJECT_TYPE (*SubObjectList)) &&
896 ((*SubObjectList)->Reference.Opcode == AML_INT_NAMEPATH_OP)))
903 * Look at the next element
909 TempSizeNeeded += (sizeof (ACPI_PCI_ROUTING_TABLE) - 4);
912 * Was a String type found?
916 if (ACPI_GET_OBJECT_TYPE (*SubObjectList) == ACPI_TYPE_STRING)
919 * The length String.Length field does not include the
920 * terminating NULL, add 1
922 TempSizeNeeded += ((ACPI_SIZE) (*SubObjectList)->String.Length + 1);
926 TempSizeNeeded += AcpiNsGetPathnameLength (
927 (*SubObjectList)->Reference.Node);
933 * If no name was found, then this is a NULL, which is
934 * translated as a UINT32 zero.
936 TempSizeNeeded += sizeof (UINT32);
939 /* Round up the size since each element must be aligned */
941 TempSizeNeeded = ACPI_ROUND_UP_TO_64BITS (TempSizeNeeded);
944 * Point to the next ACPI_OPERAND_OBJECT
950 * Adding an extra element to the end of the list, essentially a NULL terminator
952 *BufferSizeNeeded = TempSizeNeeded + sizeof (ACPI_PCI_ROUTING_TABLE);
953 return_ACPI_STATUS (AE_OK);