rscalc.c revision 77424
167754Smsmith/*******************************************************************************
267754Smsmith *
377424Smsmith * Module Name: rscalc - Calculate stream and list lengths
477424Smsmith *              $Revision: 30 $
567754Smsmith *
667754Smsmith ******************************************************************************/
767754Smsmith
867754Smsmith/******************************************************************************
967754Smsmith *
1067754Smsmith * 1. Copyright Notice
1167754Smsmith *
1271867Smsmith * Some or all of this work - Copyright (c) 1999, 2000, 2001, Intel Corp.
1370243Smsmith * All rights reserved.
1467754Smsmith *
1567754Smsmith * 2. License
1667754Smsmith *
1767754Smsmith * 2.1. This is your license from Intel Corp. under its intellectual property
1867754Smsmith * rights.  You may have additional license terms from the party that provided
1967754Smsmith * you this software, covering your right to use that party's intellectual
2067754Smsmith * property rights.
2167754Smsmith *
2267754Smsmith * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
2367754Smsmith * copy of the source code appearing in this file ("Covered Code") an
2467754Smsmith * irrevocable, perpetual, worldwide license under Intel's copyrights in the
2567754Smsmith * base code distributed originally by Intel ("Original Intel Code") to copy,
2667754Smsmith * make derivatives, distribute, use and display any portion of the Covered
2767754Smsmith * Code in any form, with the right to sublicense such rights; and
2867754Smsmith *
2967754Smsmith * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
3067754Smsmith * license (with the right to sublicense), under only those claims of Intel
3167754Smsmith * patents that are infringed by the Original Intel Code, to make, use, sell,
3267754Smsmith * offer to sell, and import the Covered Code and derivative works thereof
3367754Smsmith * solely to the minimum extent necessary to exercise the above copyright
3467754Smsmith * license, and in no event shall the patent license extend to any additions
3567754Smsmith * to or modifications of the Original Intel Code.  No other license or right
3667754Smsmith * is granted directly or by implication, estoppel or otherwise;
3767754Smsmith *
3867754Smsmith * The above copyright and patent license is granted only if the following
3967754Smsmith * conditions are met:
4067754Smsmith *
4167754Smsmith * 3. Conditions
4267754Smsmith *
4367754Smsmith * 3.1. Redistribution of Source with Rights to Further Distribute Source.
4467754Smsmith * Redistribution of source code of any substantial portion of the Covered
4567754Smsmith * Code or modification with rights to further distribute source must include
4667754Smsmith * the above Copyright Notice, the above License, this list of Conditions,
4767754Smsmith * and the following Disclaimer and Export Compliance provision.  In addition,
4867754Smsmith * Licensee must cause all Covered Code to which Licensee contributes to
4967754Smsmith * contain a file documenting the changes Licensee made to create that Covered
5067754Smsmith * Code and the date of any change.  Licensee must include in that file the
5167754Smsmith * documentation of any changes made by any predecessor Licensee.  Licensee
5267754Smsmith * must include a prominent statement that the modification is derived,
5367754Smsmith * directly or indirectly, from Original Intel Code.
5467754Smsmith *
5567754Smsmith * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
5667754Smsmith * Redistribution of source code of any substantial portion of the Covered
5767754Smsmith * Code or modification without rights to further distribute source must
5867754Smsmith * include the following Disclaimer and Export Compliance provision in the
5967754Smsmith * documentation and/or other materials provided with distribution.  In
6067754Smsmith * addition, Licensee may not authorize further sublicense of source of any
6167754Smsmith * portion of the Covered Code, and must include terms to the effect that the
6267754Smsmith * license from Licensee to its licensee is limited to the intellectual
6367754Smsmith * property embodied in the software Licensee provides to its licensee, and
6467754Smsmith * not to intellectual property embodied in modifications its licensee may
6567754Smsmith * make.
6667754Smsmith *
6767754Smsmith * 3.3. Redistribution of Executable. Redistribution in executable form of any
6867754Smsmith * substantial portion of the Covered Code or modification must reproduce the
6967754Smsmith * above Copyright Notice, and the following Disclaimer and Export Compliance
7067754Smsmith * provision in the documentation and/or other materials provided with the
7167754Smsmith * distribution.
7267754Smsmith *
7367754Smsmith * 3.4. Intel retains all right, title, and interest in and to the Original
7467754Smsmith * Intel Code.
7567754Smsmith *
7667754Smsmith * 3.5. Neither the name Intel nor any other trademark owned or controlled by
7767754Smsmith * Intel shall be used in advertising or otherwise to promote the sale, use or
7867754Smsmith * other dealings in products derived from or relating to the Covered Code
7967754Smsmith * without prior written authorization from Intel.
8067754Smsmith *
8167754Smsmith * 4. Disclaimer and Export Compliance
8267754Smsmith *
8367754Smsmith * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
8467754Smsmith * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
8567754Smsmith * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
8667754Smsmith * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
8767754Smsmith * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
8867754Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
8967754Smsmith * PARTICULAR PURPOSE.
9067754Smsmith *
9167754Smsmith * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
9267754Smsmith * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
9367754Smsmith * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
9467754Smsmith * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
9567754Smsmith * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
9667754Smsmith * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
9767754Smsmith * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
9867754Smsmith * LIMITED REMEDY.
9967754Smsmith *
10067754Smsmith * 4.3. Licensee shall not export, either directly or indirectly, any of this
10167754Smsmith * software or system incorporating such software without first obtaining any
10267754Smsmith * required license or other approval from the U. S. Department of Commerce or
10367754Smsmith * any other agency or department of the United States Government.  In the
10467754Smsmith * event Licensee exports any such software from the United States or
10567754Smsmith * re-exports any such software from a foreign destination, Licensee shall
10667754Smsmith * ensure that the distribution and export/re-export of the software is in
10767754Smsmith * compliance with all laws, regulations, orders, or other restrictions of the
10867754Smsmith * U.S. Export Administration Regulations. Licensee agrees that neither it nor
10967754Smsmith * any of its subsidiaries will export/re-export any technical data, process,
11067754Smsmith * software, or service, directly or indirectly, to any country for which the
11167754Smsmith * United States government or any agency thereof requires an export license,
11267754Smsmith * other governmental approval, or letter of assurance, without first obtaining
11367754Smsmith * such license, approval or letter.
11467754Smsmith *
11567754Smsmith *****************************************************************************/
11667754Smsmith
11767754Smsmith#define __RSCALC_C__
11867754Smsmith
11967754Smsmith#include "acpi.h"
12069450Smsmith#include "acresrc.h"
12173561Smsmith#include "amlcode.h"
12273561Smsmith#include "acnamesp.h"
12367754Smsmith
12477424Smsmith#define _COMPONENT          ACPI_RESOURCES
12567754Smsmith        MODULE_NAME         ("rscalc")
12667754Smsmith
12767754Smsmith
12867754Smsmith/*******************************************************************************
12967754Smsmith *
13067754Smsmith * FUNCTION:    AcpiRsCalculateByteStreamLength
13167754Smsmith *
13267754Smsmith * PARAMETERS:  LinkedList          - Pointer to the resource linked list
13367754Smsmith *              SizeNeeded          - UINT32 pointer of the size buffer needed
13477424Smsmith *                                    to properly return the parsed data
13567754Smsmith *
13677424Smsmith * RETURN:      Status
13767754Smsmith *
13867754Smsmith * DESCRIPTION: Takes the resource byte stream and parses it once, calculating
13967754Smsmith *              the size buffer needed to hold the linked list that conveys
14067754Smsmith *              the resource data.
14167754Smsmith *
14267754Smsmith ******************************************************************************/
14367754Smsmith
14467754SmsmithACPI_STATUS
14567754SmsmithAcpiRsCalculateByteStreamLength (
14677424Smsmith    ACPI_RESOURCE           *LinkedList,
14767754Smsmith    UINT32                  *SizeNeeded)
14867754Smsmith{
14967754Smsmith    UINT32                  ByteStreamSizeNeeded = 0;
15067754Smsmith    UINT32                  SegmentSize;
15177424Smsmith    ACPI_RESOURCE_EXT_IRQ   *ExIrq = NULL;
15267754Smsmith    BOOLEAN                 Done = FALSE;
15367754Smsmith
15467754Smsmith
15567754Smsmith    FUNCTION_TRACE ("RsCalculateByteStreamLength");
15667754Smsmith
15767754Smsmith
15867754Smsmith    while (!Done)
15967754Smsmith    {
16067754Smsmith        /*
16177424Smsmith         * Init the variable that will hold the size to add to the total.
16267754Smsmith         */
16367754Smsmith        SegmentSize = 0;
16467754Smsmith
16567754Smsmith        switch (LinkedList->Id)
16667754Smsmith        {
16777424Smsmith        case ACPI_RSTYPE_IRQ:
16867754Smsmith            /*
16967754Smsmith             * IRQ Resource
17067754Smsmith             * For an IRQ Resource, Byte 3, although optional, will
17177424Smsmith             * always be created - it holds IRQ information.
17267754Smsmith             */
17367754Smsmith            SegmentSize = 4;
17467754Smsmith            break;
17567754Smsmith
17677424Smsmith        case ACPI_RSTYPE_DMA:
17767754Smsmith            /*
17867754Smsmith             * DMA Resource
17967754Smsmith             * For this resource the size is static
18067754Smsmith             */
18167754Smsmith            SegmentSize = 3;
18267754Smsmith            break;
18367754Smsmith
18477424Smsmith        case ACPI_RSTYPE_START_DPF:
18567754Smsmith            /*
18667754Smsmith             * Start Dependent Functions Resource
18767754Smsmith             * For a StartDependentFunctions Resource, Byte 1,
18867754Smsmith             * although optional, will always be created.
18967754Smsmith             */
19067754Smsmith            SegmentSize = 2;
19167754Smsmith            break;
19267754Smsmith
19377424Smsmith        case ACPI_RSTYPE_END_DPF:
19467754Smsmith            /*
19567754Smsmith             * End Dependent Functions Resource
19667754Smsmith             * For this resource the size is static
19767754Smsmith             */
19867754Smsmith            SegmentSize = 1;
19967754Smsmith            break;
20067754Smsmith
20177424Smsmith        case ACPI_RSTYPE_IO:
20267754Smsmith            /*
20367754Smsmith             * IO Port Resource
20467754Smsmith             * For this resource the size is static
20567754Smsmith             */
20667754Smsmith            SegmentSize = 8;
20767754Smsmith            break;
20867754Smsmith
20977424Smsmith        case ACPI_RSTYPE_FIXED_IO:
21067754Smsmith            /*
21167754Smsmith             * Fixed IO Port Resource
21267754Smsmith             * For this resource the size is static
21367754Smsmith             */
21467754Smsmith            SegmentSize = 4;
21567754Smsmith            break;
21667754Smsmith
21777424Smsmith        case ACPI_RSTYPE_VENDOR:
21867754Smsmith            /*
21967754Smsmith             * Vendor Defined Resource
22067754Smsmith             * For a Vendor Specific resource, if the Length is
22177424Smsmith             * between 1 and 7 it will be created as a Small
22277424Smsmith             * Resource data type, otherwise it is a Large
22377424Smsmith             * Resource data type.
22467754Smsmith             */
22577424Smsmith            if (LinkedList->Data.VendorSpecific.Length > 7)
22667754Smsmith            {
22767754Smsmith                SegmentSize = 3;
22867754Smsmith            }
22967754Smsmith            else
23067754Smsmith            {
23167754Smsmith                SegmentSize = 1;
23267754Smsmith            }
23377424Smsmith            SegmentSize += LinkedList->Data.VendorSpecific.Length;
23467754Smsmith            break;
23567754Smsmith
23677424Smsmith        case ACPI_RSTYPE_END_TAG:
23767754Smsmith            /*
23867754Smsmith             * End Tag
23967754Smsmith             * For this resource the size is static
24067754Smsmith             */
24167754Smsmith            SegmentSize = 2;
24267754Smsmith            Done = TRUE;
24367754Smsmith            break;
24467754Smsmith
24577424Smsmith        case ACPI_RSTYPE_MEM24:
24667754Smsmith            /*
24767754Smsmith             * 24-Bit Memory Resource
24867754Smsmith             * For this resource the size is static
24967754Smsmith             */
25067754Smsmith            SegmentSize = 12;
25167754Smsmith            break;
25267754Smsmith
25377424Smsmith        case ACPI_RSTYPE_MEM32:
25467754Smsmith            /*
25567754Smsmith             * 32-Bit Memory Range Resource
25667754Smsmith             * For this resource the size is static
25767754Smsmith             */
25867754Smsmith            SegmentSize = 20;
25967754Smsmith            break;
26067754Smsmith
26177424Smsmith        case ACPI_RSTYPE_FIXED_MEM32:
26267754Smsmith            /*
26367754Smsmith             * 32-Bit Fixed Memory Resource
26467754Smsmith             * For this resource the size is static
26567754Smsmith             */
26667754Smsmith            SegmentSize = 12;
26767754Smsmith            break;
26867754Smsmith
26977424Smsmith        case ACPI_RSTYPE_ADDRESS16:
27067754Smsmith            /*
27167754Smsmith             * 16-Bit Address Resource
27267754Smsmith             * The base size of this byte stream is 16. If a
27377424Smsmith             * Resource Source string is not NULL, add 1 for
27477424Smsmith             * the Index + the length of the null terminated
27577424Smsmith             * string Resource Source + 1 for the null.
27667754Smsmith             */
27767754Smsmith            SegmentSize = 16;
27867754Smsmith
27977424Smsmith            if (NULL != LinkedList->Data.Address16.ResourceSource.StringPtr)
28067754Smsmith            {
28167754Smsmith                SegmentSize += (1 +
28277424Smsmith                    LinkedList->Data.Address16.ResourceSource.StringLength);
28367754Smsmith            }
28467754Smsmith            break;
28567754Smsmith
28677424Smsmith        case ACPI_RSTYPE_ADDRESS32:
28767754Smsmith            /*
28867754Smsmith             * 32-Bit Address Resource
28967754Smsmith             * The base size of this byte stream is 26. If a Resource
29077424Smsmith             * Source string is not NULL, add 1 for the Index + the
29177424Smsmith             * length of the null terminated string Resource Source +
29277424Smsmith             * 1 for the null.
29367754Smsmith             */
29467754Smsmith            SegmentSize = 26;
29567754Smsmith
29677424Smsmith            if (NULL != LinkedList->Data.Address32.ResourceSource.StringPtr)
29767754Smsmith            {
29867754Smsmith                SegmentSize += (1 +
29977424Smsmith                    LinkedList->Data.Address32.ResourceSource.StringLength);
30067754Smsmith            }
30167754Smsmith            break;
30267754Smsmith
30377424Smsmith        case ACPI_RSTYPE_ADDRESS64:
30467754Smsmith            /*
30577424Smsmith             * 64-Bit Address Resource
30677424Smsmith             * The base size of this byte stream is 46. If a Resource
30777424Smsmith             * Source string is not NULL, add 1 for the Index + the
30877424Smsmith             * length of the null terminated string Resource Source +
30977424Smsmith             * 1 for the null.
31067754Smsmith             */
31177424Smsmith            SegmentSize = 46;
31277424Smsmith
31377424Smsmith            if (NULL != LinkedList->Data.Address64.ResourceSource.StringPtr)
31477424Smsmith            {
31577424Smsmith                SegmentSize += (1 +
31677424Smsmith                    LinkedList->Data.Address64.ResourceSource.StringLength);
31777424Smsmith            }
31877424Smsmith            break;
31977424Smsmith
32077424Smsmith        case ACPI_RSTYPE_EXT_IRQ:
32167754Smsmith            /*
32277424Smsmith             * Extended IRQ Resource
32367754Smsmith             * The base size of this byte stream is 9. This is for an
32477424Smsmith             * Interrupt table length of 1.  For each additional
32577424Smsmith             * interrupt, add 4.
32667754Smsmith             * If a Resource Source string is not NULL, add 1 for the
32777424Smsmith             * Index + the length of the null terminated string
32877424Smsmith             * Resource Source + 1 for the null.
32967754Smsmith             */
33077424Smsmith            SegmentSize = 9 +
33177424Smsmith                ((LinkedList->Data.ExtendedIrq.NumberOfInterrupts - 1) * 4);
33267754Smsmith
33377424Smsmith            if (NULL != ExIrq->ResourceSource.StringPtr)
33467754Smsmith            {
33567754Smsmith                SegmentSize += (1 +
33677424Smsmith                    LinkedList->Data.ExtendedIrq.ResourceSource.StringLength);
33767754Smsmith            }
33867754Smsmith            break;
33967754Smsmith
34067754Smsmith        default:
34167754Smsmith            /*
34267754Smsmith             * If we get here, everything is out of sync,
34377424Smsmith             * so exit with an error
34467754Smsmith             */
34577424Smsmith            return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
34667754Smsmith            break;
34767754Smsmith
34867754Smsmith        } /* switch (LinkedList->Id) */
34967754Smsmith
35067754Smsmith        /*
35167754Smsmith         * Update the total
35267754Smsmith         */
35367754Smsmith        ByteStreamSizeNeeded += SegmentSize;
35467754Smsmith
35567754Smsmith        /*
35667754Smsmith         * Point to the next object
35767754Smsmith         */
35877424Smsmith        LinkedList = POINTER_ADD (ACPI_RESOURCE,
35977424Smsmith                        LinkedList, LinkedList->Length);
36067754Smsmith    }
36167754Smsmith
36267754Smsmith    /*
36367754Smsmith     * This is the data the caller needs
36467754Smsmith     */
36567754Smsmith    *SizeNeeded = ByteStreamSizeNeeded;
36667754Smsmith    return_ACPI_STATUS (AE_OK);
36767754Smsmith}
36867754Smsmith
36967754Smsmith
37067754Smsmith/*******************************************************************************
37167754Smsmith *
37267754Smsmith * FUNCTION:    AcpiRsCalculateListLength
37367754Smsmith *
37467754Smsmith * PARAMETERS:  ByteStreamBuffer        - Pointer to the resource byte stream
37567754Smsmith *              ByteStreamBufferLength  - Size of ByteStreamBuffer
37667754Smsmith *              SizeNeeded              - UINT32 pointer of the size buffer
37777424Smsmith *                                        needed to properly return the
37877424Smsmith *                                        parsed data
37967754Smsmith *
38077424Smsmith * RETURN:      Status
38167754Smsmith *
38267754Smsmith * DESCRIPTION: Takes the resource byte stream and parses it once, calculating
38367754Smsmith *              the size buffer needed to hold the linked list that conveys
38467754Smsmith *              the resource data.
38567754Smsmith *
38667754Smsmith ******************************************************************************/
38767754Smsmith
38867754SmsmithACPI_STATUS
38967754SmsmithAcpiRsCalculateListLength (
39067754Smsmith    UINT8                   *ByteStreamBuffer,
39167754Smsmith    UINT32                  ByteStreamBufferLength,
39267754Smsmith    UINT32                  *SizeNeeded)
39367754Smsmith{
39467754Smsmith    UINT32                  BufferSize = 0;
39567754Smsmith    UINT32                  BytesParsed = 0;
39667754Smsmith    UINT8                   NumberOfInterrupts = 0;
39767754Smsmith    UINT8                   NumberOfChannels = 0;
39867754Smsmith    UINT8                   ResourceType;
39967754Smsmith    UINT32                  StructureSize;
40067754Smsmith    UINT32                  BytesConsumed;
40167754Smsmith    UINT8                   *Buffer;
40267754Smsmith    UINT8                   Temp8;
40367754Smsmith    UINT16                  Temp16;
40467754Smsmith    UINT8                   Index;
40567754Smsmith    UINT8                   AdditionalBytes;
40667754Smsmith
40767754Smsmith
40867754Smsmith    FUNCTION_TRACE ("RsCalculateListLength");
40967754Smsmith
41067754Smsmith
41167754Smsmith    while (BytesParsed < ByteStreamBufferLength)
41267754Smsmith    {
41367754Smsmith        /*
41477424Smsmith         * The next byte in the stream is the resource type
41567754Smsmith         */
41677424Smsmith        ResourceType = AcpiRsGetResourceType (*ByteStreamBuffer);
41767754Smsmith
41877424Smsmith        switch (ResourceType)
41967754Smsmith        {
42077424Smsmith        case RESOURCE_DESC_MEMORY_24:
42167754Smsmith            /*
42277424Smsmith             * 24-Bit Memory Resource
42367754Smsmith             */
42477424Smsmith            BytesConsumed = 12;
42567754Smsmith
42677424Smsmith            StructureSize = SIZEOF_RESOURCE (ACPI_RESOURCE_MEM24);
42777424Smsmith            break;
42867754Smsmith
42967754Smsmith
43077424Smsmith        case RESOURCE_DESC_LARGE_VENDOR:
43177424Smsmith            /*
43277424Smsmith             * Vendor Defined Resource
43377424Smsmith             */
43477424Smsmith            Buffer = ByteStreamBuffer;
43577424Smsmith            ++Buffer;
43667754Smsmith
43777424Smsmith            MOVE_UNALIGNED16_TO_16 (&Temp16, Buffer);
43877424Smsmith            BytesConsumed = Temp16 + 3;
43967754Smsmith
44077424Smsmith            /*
44177424Smsmith             * Ensure a 32-bit boundary for the structure
44277424Smsmith             */
44377424Smsmith            Temp16 = (UINT16) ROUND_UP_TO_32BITS (Temp16);
44477424Smsmith
44577424Smsmith            StructureSize = SIZEOF_RESOURCE (ACPI_RESOURCE_VENDOR) +
44667754Smsmith                                (Temp16 * sizeof (UINT8));
44777424Smsmith            break;
44867754Smsmith
44967754Smsmith
45077424Smsmith        case RESOURCE_DESC_MEMORY_32:
45177424Smsmith            /*
45277424Smsmith             * 32-Bit Memory Range Resource
45377424Smsmith             */
45467754Smsmith
45577424Smsmith            BytesConsumed = 20;
45667754Smsmith
45777424Smsmith            StructureSize = SIZEOF_RESOURCE (ACPI_RESOURCE_MEM32);
45877424Smsmith            break;
45967754Smsmith
46067754Smsmith
46177424Smsmith        case RESOURCE_DESC_FIXED_MEMORY_32:
46277424Smsmith            /*
46377424Smsmith             * 32-Bit Fixed Memory Resource
46477424Smsmith             */
46577424Smsmith            BytesConsumed = 12;
46667754Smsmith
46777424Smsmith            StructureSize = SIZEOF_RESOURCE (ACPI_RESOURCE_FIXED_MEM32);
46877424Smsmith            break;
46967754Smsmith
47067754Smsmith
47177424Smsmith        case RESOURCE_DESC_QWORD_ADDRESS_SPACE:
47277424Smsmith            /*
47377424Smsmith             * 64-Bit Address Resource
47477424Smsmith             */
47577424Smsmith            Buffer = ByteStreamBuffer;
47667754Smsmith
47777424Smsmith            ++Buffer;
47877424Smsmith            MOVE_UNALIGNED16_TO_16 (&Temp16, Buffer);
47967754Smsmith
48077424Smsmith            BytesConsumed = Temp16 + 3;
48167754Smsmith
48277424Smsmith            /*
48377424Smsmith             * Resource Source Index and Resource Source are
48477424Smsmith             * optional elements.  Check the length of the
48577424Smsmith             * Bytestream.  If it is greater than 43, that
48677424Smsmith             * means that an Index exists and is followed by
48777424Smsmith             * a null termininated string.  Therefore, set
48877424Smsmith             * the temp variable to the length minus the minimum
48977424Smsmith             * byte stream length plus the byte for the Index to
49077424Smsmith             * determine the size of the NULL terminiated string.
49177424Smsmith             */
49277424Smsmith            if (43 < Temp16)
49377424Smsmith            {
49477424Smsmith                Temp8 = (UINT8) (Temp16 - 44);
49577424Smsmith            }
49677424Smsmith            else
49777424Smsmith            {
49877424Smsmith                Temp8 = 0;
49977424Smsmith            }
50067754Smsmith
50177424Smsmith            /*
50277424Smsmith             * Ensure a 64-bit boundary for the structure
50377424Smsmith             */
50477424Smsmith            Temp8 = (UINT8) ROUND_UP_TO_64BITS (Temp8);
50567754Smsmith
50677424Smsmith            StructureSize = SIZEOF_RESOURCE (ACPI_RESOURCE_ADDRESS64) +
50777424Smsmith                                (Temp8 * sizeof (UINT8));
50877424Smsmith            break;
50967754Smsmith
51067754Smsmith
51177424Smsmith        case RESOURCE_DESC_DWORD_ADDRESS_SPACE:
51277424Smsmith            /*
51377424Smsmith             * 32-Bit Address Resource
51477424Smsmith             */
51577424Smsmith            Buffer = ByteStreamBuffer;
51667754Smsmith
51777424Smsmith            ++Buffer;
51877424Smsmith            MOVE_UNALIGNED16_TO_16 (&Temp16, Buffer);
51967754Smsmith
52077424Smsmith            BytesConsumed = Temp16 + 3;
52167754Smsmith
52277424Smsmith            /*
52377424Smsmith             * Resource Source Index and Resource Source are
52477424Smsmith             * optional elements.  Check the length of the
52577424Smsmith             * Bytestream.  If it is greater than 23, that
52677424Smsmith             * means that an Index exists and is followed by
52777424Smsmith             * a null termininated string.  Therefore, set
52877424Smsmith             * the temp variable to the length minus the minimum
52977424Smsmith             * byte stream length plus the byte for the Index to
53077424Smsmith             * determine the size of the NULL terminiated string.
53177424Smsmith             */
53277424Smsmith            if (23 < Temp16)
53377424Smsmith            {
53477424Smsmith                Temp8 = (UINT8) (Temp16 - 24);
53577424Smsmith            }
53677424Smsmith            else
53777424Smsmith            {
53877424Smsmith                Temp8 = 0;
53977424Smsmith            }
54067754Smsmith
54177424Smsmith            /*
54277424Smsmith             * Ensure a 32-bit boundary for the structure
54377424Smsmith             */
54477424Smsmith            Temp8 = (UINT8) ROUND_UP_TO_32BITS (Temp8);
54567754Smsmith
54677424Smsmith            StructureSize = SIZEOF_RESOURCE (ACPI_RESOURCE_ADDRESS32) +
54777424Smsmith                                (Temp8 * sizeof (UINT8));
54877424Smsmith            break;
54967754Smsmith
55067754Smsmith
55177424Smsmith        case RESOURCE_DESC_WORD_ADDRESS_SPACE:
55277424Smsmith            /*
55377424Smsmith             * 16-Bit Address Resource
55477424Smsmith             */
55577424Smsmith            Buffer = ByteStreamBuffer;
55667754Smsmith
55777424Smsmith            ++Buffer;
55877424Smsmith            MOVE_UNALIGNED16_TO_16 (&Temp16, Buffer);
55967754Smsmith
56077424Smsmith            BytesConsumed = Temp16 + 3;
56167754Smsmith
56277424Smsmith            /*
56377424Smsmith             * Resource Source Index and Resource Source are
56477424Smsmith             * optional elements.  Check the length of the
56577424Smsmith             * Bytestream.  If it is greater than 13, that
56677424Smsmith             * means that an Index exists and is followed by
56777424Smsmith             * a null termininated string.  Therefore, set
56877424Smsmith             * the temp variable to the length minus the minimum
56977424Smsmith             * byte stream length plus the byte for the Index to
57077424Smsmith             * determine the size of the NULL terminiated string.
57177424Smsmith             */
57277424Smsmith            if (13 < Temp16)
57377424Smsmith            {
57477424Smsmith                Temp8 = (UINT8) (Temp16 - 14);
57577424Smsmith            }
57677424Smsmith            else
57777424Smsmith            {
57877424Smsmith                Temp8 = 0;
57977424Smsmith            }
58067754Smsmith
58177424Smsmith            /*
58277424Smsmith             * Ensure a 32-bit boundary for the structure
58377424Smsmith             */
58477424Smsmith            Temp8 = (UINT8) ROUND_UP_TO_32BITS (Temp8);
58567754Smsmith
58677424Smsmith            StructureSize = SIZEOF_RESOURCE (ACPI_RESOURCE_ADDRESS16) +
58777424Smsmith                                (Temp8 * sizeof (UINT8));
58877424Smsmith            break;
58967754Smsmith
59067754Smsmith
59177424Smsmith        case RESOURCE_DESC_EXTENDED_XRUPT:
59267754Smsmith            /*
59377424Smsmith             * Extended IRQ
59467754Smsmith             */
59577424Smsmith            Buffer = ByteStreamBuffer;
59667754Smsmith
59777424Smsmith            ++Buffer;
59877424Smsmith            MOVE_UNALIGNED16_TO_16 (&Temp16, Buffer);
59967754Smsmith
60077424Smsmith            BytesConsumed = Temp16 + 3;
60167754Smsmith
60277424Smsmith            /*
60377424Smsmith             * Point past the length field and the
60477424Smsmith             * Interrupt vector flags to save off the
60577424Smsmith             * Interrupt table length to the Temp8 variable.
60677424Smsmith             */
60777424Smsmith            Buffer += 3;
60877424Smsmith            Temp8 = *Buffer;
60967754Smsmith
61077424Smsmith            /*
61177424Smsmith             * To compensate for multiple interrupt numbers, add 4 bytes for
61277424Smsmith             * each additional interrupts greater than 1
61377424Smsmith             */
61477424Smsmith            AdditionalBytes = (UINT8) ((Temp8 - 1) * 4);
61567754Smsmith
61677424Smsmith            /*
61777424Smsmith             * Resource Source Index and Resource Source are
61877424Smsmith             * optional elements.  Check the length of the
61977424Smsmith             * Bytestream.  If it is greater than 9, that
62077424Smsmith             * means that an Index exists and is followed by
62177424Smsmith             * a null termininated string.  Therefore, set
62277424Smsmith             * the temp variable to the length minus the minimum
62377424Smsmith             * byte stream length plus the byte for the Index to
62477424Smsmith             * determine the size of the NULL terminiated string.
62577424Smsmith             */
62677424Smsmith            if (9 + AdditionalBytes < Temp16)
62777424Smsmith            {
62877424Smsmith                Temp8 = (UINT8) (Temp16 - (9 + AdditionalBytes));
62977424Smsmith            }
63067754Smsmith
63177424Smsmith            else
63277424Smsmith            {
63377424Smsmith                Temp8 = 0;
63477424Smsmith            }
63567754Smsmith
63677424Smsmith            /*
63777424Smsmith             * Ensure a 32-bit boundary for the structure
63877424Smsmith             */
63977424Smsmith            Temp8 = (UINT8) ROUND_UP_TO_32BITS (Temp8);
64067754Smsmith
64177424Smsmith            StructureSize = SIZEOF_RESOURCE (ACPI_RESOURCE_EXT_IRQ) +
64277424Smsmith                                (AdditionalBytes * sizeof (UINT8)) +
64377424Smsmith                                (Temp8 * sizeof (UINT8));
64477424Smsmith            break;
64567754Smsmith
64667754Smsmith
64777424Smsmith        case RESOURCE_DESC_IRQ_FORMAT:
64877424Smsmith            /*
64977424Smsmith             * IRQ Resource.
65077424Smsmith             * Determine if it there are two or three trailing bytes
65177424Smsmith             */
65277424Smsmith            Buffer = ByteStreamBuffer;
65377424Smsmith            Temp8 = *Buffer;
65467754Smsmith
65577424Smsmith            if(Temp8 & 0x01)
65677424Smsmith            {
65777424Smsmith                BytesConsumed = 4;
65877424Smsmith            }
65967754Smsmith
66077424Smsmith            else
66177424Smsmith            {
66267754Smsmith                BytesConsumed = 3;
66377424Smsmith            }
66467754Smsmith
66577424Smsmith            /*
66677424Smsmith             * Point past the descriptor
66777424Smsmith             */
66877424Smsmith            ++Buffer;
66967754Smsmith
67077424Smsmith            /*
67177424Smsmith             * Look at the number of bits set
67277424Smsmith             */
67377424Smsmith            MOVE_UNALIGNED16_TO_16 (&Temp16, Buffer);
67467754Smsmith
67577424Smsmith            for (Index = 0; Index < 16; Index++)
67677424Smsmith            {
67777424Smsmith                if (Temp16 & 0x1)
67867754Smsmith                {
67977424Smsmith                    ++NumberOfInterrupts;
68067754Smsmith                }
68167754Smsmith
68277424Smsmith                Temp16 >>= 1;
68377424Smsmith            }
68467754Smsmith
68577424Smsmith            StructureSize = SIZEOF_RESOURCE (ACPI_RESOURCE_IO) +
68677424Smsmith                                (NumberOfInterrupts * sizeof (UINT32));
68777424Smsmith            break;
68867754Smsmith
68967754Smsmith
69077424Smsmith        case RESOURCE_DESC_DMA_FORMAT:
69177424Smsmith            /*
69277424Smsmith             * DMA Resource
69377424Smsmith             */
69477424Smsmith            Buffer = ByteStreamBuffer;
69577424Smsmith            BytesConsumed = 3;
69667754Smsmith
69777424Smsmith            /*
69877424Smsmith             * Point past the descriptor
69977424Smsmith             */
70077424Smsmith            ++Buffer;
70177424Smsmith
70277424Smsmith            /*
70377424Smsmith             * Look at the number of bits set
70477424Smsmith             */
70577424Smsmith            Temp8 = *Buffer;
70677424Smsmith
70777424Smsmith            for(Index = 0; Index < 8; Index++)
70877424Smsmith            {
70977424Smsmith                if(Temp8 & 0x1)
71067754Smsmith                {
71177424Smsmith                    ++NumberOfChannels;
71267754Smsmith                }
71367754Smsmith
71477424Smsmith                Temp8 >>= 1;
71577424Smsmith            }
71667754Smsmith
71777424Smsmith            StructureSize = SIZEOF_RESOURCE (ACPI_RESOURCE_DMA) +
71877424Smsmith                                (NumberOfChannels * sizeof (UINT32));
71977424Smsmith            break;
72067754Smsmith
72167754Smsmith
72277424Smsmith        case RESOURCE_DESC_START_DEPENDENT:
72377424Smsmith            /*
72477424Smsmith             * Start Dependent Functions Resource
72577424Smsmith             * Determine if it there are two or three trailing bytes
72677424Smsmith             */
72777424Smsmith            Buffer = ByteStreamBuffer;
72877424Smsmith            Temp8 = *Buffer;
72967754Smsmith
73077424Smsmith            if(Temp8 & 0x01)
73177424Smsmith            {
73277424Smsmith                BytesConsumed = 2;
73377424Smsmith            }
73477424Smsmith            else
73577424Smsmith            {
73667754Smsmith                BytesConsumed = 1;
73777424Smsmith            }
73867754Smsmith
73977424Smsmith            StructureSize = SIZEOF_RESOURCE (ACPI_RESOURCE_START_DPF);
74077424Smsmith            break;
74167754Smsmith
74267754Smsmith
74377424Smsmith        case RESOURCE_DESC_END_DEPENDENT:
74477424Smsmith            /*
74577424Smsmith             * End Dependent Functions Resource
74677424Smsmith             */
74777424Smsmith            BytesConsumed = 1;
74877424Smsmith            StructureSize = ACPI_RESOURCE_LENGTH;
74977424Smsmith            break;
75067754Smsmith
75167754Smsmith
75277424Smsmith        case RESOURCE_DESC_IO_PORT:
75377424Smsmith            /*
75477424Smsmith             * IO Port Resource
75577424Smsmith             */
75677424Smsmith            BytesConsumed = 8;
75777424Smsmith            StructureSize = SIZEOF_RESOURCE (ACPI_RESOURCE_IO);
75877424Smsmith            break;
75967754Smsmith
76067754Smsmith
76177424Smsmith        case RESOURCE_DESC_FIXED_IO_PORT:
76277424Smsmith            /*
76377424Smsmith             * Fixed IO Port Resource
76477424Smsmith             */
76577424Smsmith            BytesConsumed = 4;
76677424Smsmith            StructureSize = SIZEOF_RESOURCE (ACPI_RESOURCE_FIXED_IO);
76777424Smsmith            break;
76867754Smsmith
76967754Smsmith
77077424Smsmith        case RESOURCE_DESC_SMALL_VENDOR:
77177424Smsmith            /*
77277424Smsmith             * Vendor Specific Resource
77377424Smsmith             */
77477424Smsmith            Buffer = ByteStreamBuffer;
77567754Smsmith
77677424Smsmith            Temp8 = *Buffer;
77777424Smsmith            Temp8 = (UINT8) (Temp8 & 0x7);
77877424Smsmith            BytesConsumed = Temp8 + 1;
77977424Smsmith
78077424Smsmith            /*
78177424Smsmith             * Ensure a 32-bit boundary for the structure
78277424Smsmith             */
78377424Smsmith            Temp8 = (UINT8) ROUND_UP_TO_32BITS (Temp8);
78477424Smsmith            StructureSize = SIZEOF_RESOURCE (ACPI_RESOURCE_VENDOR) +
78567754Smsmith                                (Temp8 * sizeof (UINT8));
78677424Smsmith            break;
78767754Smsmith
78867754Smsmith
78977424Smsmith        case RESOURCE_DESC_END_TAG:
79077424Smsmith            /*
79177424Smsmith             * End Tag
79277424Smsmith             */
79377424Smsmith            BytesConsumed = 2;
79477424Smsmith            StructureSize = ACPI_RESOURCE_LENGTH;
79577424Smsmith            ByteStreamBufferLength = BytesParsed;
79677424Smsmith            break;
79767754Smsmith
79867754Smsmith
79977424Smsmith        default:
80077424Smsmith            /*
80177424Smsmith             * If we get here, everything is out of sync,
80277424Smsmith             *  so exit with an error
80377424Smsmith             */
80477424Smsmith            return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
80577424Smsmith            break;
80677424Smsmith        }
80767754Smsmith
80867754Smsmith
80967754Smsmith        /*
81067754Smsmith         * Update the return value and counter
81167754Smsmith         */
81267754Smsmith        BufferSize += StructureSize;
81367754Smsmith        BytesParsed += BytesConsumed;
81467754Smsmith
81567754Smsmith        /*
81667754Smsmith         * Set the byte stream to point to the next resource
81767754Smsmith         */
81867754Smsmith        ByteStreamBuffer += BytesConsumed;
81967754Smsmith    }
82067754Smsmith
82177424Smsmith
82267754Smsmith    /*
82367754Smsmith     * This is the data the caller needs
82467754Smsmith     */
82567754Smsmith    *SizeNeeded = BufferSize;
82667754Smsmith    return_ACPI_STATUS (AE_OK);
82767754Smsmith}
82867754Smsmith
82967754Smsmith
83067754Smsmith/*******************************************************************************
83167754Smsmith *
83267754Smsmith * FUNCTION:    AcpiRsCalculatePciRoutingTableLength
83367754Smsmith *
83467754Smsmith * PARAMETERS:  PackageObject           - Pointer to the package object
83567754Smsmith *              BufferSizeNeeded        - UINT32 pointer of the size buffer
83677424Smsmith *                                        needed to properly return the
83777424Smsmith *                                        parsed data
83867754Smsmith *
83977424Smsmith * RETURN:      Status
84067754Smsmith *
84167754Smsmith * DESCRIPTION: Given a package representing a PCI routing table, this
84277424Smsmith *              calculates the size of the corresponding linked list of
84377424Smsmith *              descriptions.
84467754Smsmith *
84567754Smsmith ******************************************************************************/
84667754Smsmith
84767754SmsmithACPI_STATUS
84867754SmsmithAcpiRsCalculatePciRoutingTableLength (
84967754Smsmith    ACPI_OPERAND_OBJECT     *PackageObject,
85067754Smsmith    UINT32                  *BufferSizeNeeded)
85167754Smsmith{
85267754Smsmith    UINT32                  NumberOfElements;
85369450Smsmith    UINT32                  TempSizeNeeded = 0;
85467754Smsmith    ACPI_OPERAND_OBJECT     **TopObjectList;
85567754Smsmith    UINT32                  Index;
85667754Smsmith    ACPI_OPERAND_OBJECT     *PackageElement;
85767754Smsmith    ACPI_OPERAND_OBJECT     **SubObjectList;
85867754Smsmith    BOOLEAN                 NameFound;
85967754Smsmith    UINT32                  TableIndex;
86067754Smsmith
86167754Smsmith
86267754Smsmith    FUNCTION_TRACE ("AcpiRsCalculatePciRoutingTableLength");
86367754Smsmith
86467754Smsmith
86567754Smsmith    NumberOfElements = PackageObject->Package.Count;
86667754Smsmith
86767754Smsmith    /*
86867754Smsmith     * Calculate the size of the return buffer.
86967754Smsmith     * The base size is the number of elements * the sizes of the
87067754Smsmith     * structures.  Additional space for the strings is added below.
87167754Smsmith     * The minus one is to subtract the size of the UINT8 Source[1]
87267754Smsmith     * member because it is added below.
87367754Smsmith     *
87467754Smsmith     * But each PRT_ENTRY structure has a pointer to a string and
87567754Smsmith     * the size of that string must be found.
87667754Smsmith     */
87767754Smsmith    TopObjectList = PackageObject->Package.Elements;
87867754Smsmith
87967754Smsmith    for (Index = 0; Index < NumberOfElements; Index++)
88067754Smsmith    {
88167754Smsmith        /*
88267754Smsmith         * Dereference the sub-package
88367754Smsmith         */
88467754Smsmith        PackageElement = *TopObjectList;
88567754Smsmith
88667754Smsmith        /*
88767754Smsmith         * The SubObjectList will now point to an array of the
88867754Smsmith         * four IRQ elements: Address, Pin, Source and SourceIndex
88967754Smsmith         */
89067754Smsmith        SubObjectList = PackageElement->Package.Elements;
89167754Smsmith
89267754Smsmith        /*
89367754Smsmith         * Scan the IrqTableElements for the Source Name String
89467754Smsmith         */
89567754Smsmith        NameFound = FALSE;
89667754Smsmith
89767754Smsmith        for (TableIndex = 0; TableIndex < 4 && !NameFound; TableIndex++)
89867754Smsmith        {
89973561Smsmith            if ((ACPI_TYPE_STRING == (*SubObjectList)->Common.Type) ||
90073561Smsmith                ((INTERNAL_TYPE_REFERENCE == (*SubObjectList)->Common.Type) &&
90177424Smsmith                    ((*SubObjectList)->Reference.Opcode == AML_INT_NAMEPATH_OP)))
90267754Smsmith            {
90367754Smsmith                NameFound = TRUE;
90467754Smsmith            }
90567754Smsmith
90667754Smsmith            else
90767754Smsmith            {
90867754Smsmith                /*
90967754Smsmith                 * Look at the next element
91067754Smsmith                 */
91167754Smsmith                SubObjectList++;
91267754Smsmith            }
91367754Smsmith        }
91467754Smsmith
91573561Smsmith        TempSizeNeeded += (sizeof (PCI_ROUTING_TABLE) - 4);
91669450Smsmith
91767754Smsmith        /*
91867754Smsmith         * Was a String type found?
91967754Smsmith         */
92067754Smsmith        if (TRUE == NameFound)
92167754Smsmith        {
92273561Smsmith            if (ACPI_TYPE_STRING == (*SubObjectList)->Common.Type)
92373561Smsmith            {
92473561Smsmith                /*
92573561Smsmith                 * The length String.Length field includes the
92673561Smsmith                 * terminating NULL
92773561Smsmith                 */
92873561Smsmith                TempSizeNeeded += (*SubObjectList)->String.Length;
92973561Smsmith            }
93077424Smsmith
93173561Smsmith            else
93273561Smsmith            {
93377424Smsmith                TempSizeNeeded += AcpiNsGetPathnameLength (
93477424Smsmith                                    (*SubObjectList)->Reference.Node);
93573561Smsmith            }
93667754Smsmith        }
93767754Smsmith
93867754Smsmith        else
93967754Smsmith        {
94067754Smsmith            /*
94167754Smsmith             * If no name was found, then this is a NULL, which is
94277424Smsmith             * translated as a UINT32 zero.
94367754Smsmith             */
94477424Smsmith            TempSizeNeeded += sizeof (UINT32);
94567754Smsmith        }
94667754Smsmith
94769450Smsmith        /* Round up the size since each element must be aligned */
94869450Smsmith
94969450Smsmith        TempSizeNeeded = ROUND_UP_TO_64BITS (TempSizeNeeded);
95069450Smsmith
95167754Smsmith        /*
95267754Smsmith         * Point to the next ACPI_OPERAND_OBJECT
95367754Smsmith         */
95467754Smsmith        TopObjectList++;
95567754Smsmith    }
95667754Smsmith
95767754Smsmith
95877424Smsmith    /*
95977424Smsmith     * Adding an extra element to the end of the list, essentially a NULL terminator
96077424Smsmith     */
96177424Smsmith    *BufferSizeNeeded = TempSizeNeeded + sizeof (PCI_ROUTING_TABLE);
96267754Smsmith    return_ACPI_STATUS (AE_OK);
96369450Smsmith}
964