rscalc.c revision 193341
1177162Sjkoshy/*******************************************************************************
2145256Sjkoshy *
3145256Sjkoshy * Module Name: rscalc - Calculate stream and list lengths
4145256Sjkoshy *
5145256Sjkoshy ******************************************************************************/
6145256Sjkoshy
7145256Sjkoshy/******************************************************************************
8145256Sjkoshy *
9145256Sjkoshy * 1. Copyright Notice
10145256Sjkoshy *
11145256Sjkoshy * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp.
12231871Sbrueffer * All rights reserved.
13231871Sbrueffer *
14231871Sbrueffer * 2. License
15231871Sbrueffer *
16231871Sbrueffer * 2.1. This is your license from Intel Corp. under its intellectual property
17231871Sbrueffer * rights.  You may have additional license terms from the party that provided
18231871Sbrueffer * you this software, covering your right to use that party's intellectual
19231871Sbrueffer * property rights.
20231871Sbrueffer *
21231871Sbrueffer * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22231871Sbrueffer * copy of the source code appearing in this file ("Covered Code") an
23145256Sjkoshy * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24145256Sjkoshy * base code distributed originally by Intel ("Original Intel Code") to copy,
25145256Sjkoshy * make derivatives, distribute, use and display any portion of the Covered
26183595Sjkoshy * Code in any form, with the right to sublicense such rights; and
27206622Suqs *
28145256Sjkoshy * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29145256Sjkoshy * license (with the right to sublicense), under only those claims of Intel
30183084Sjkoshy * patents that are infringed by the Original Intel Code, to make, use, sell,
31183084Sjkoshy * offer to sell, and import the Covered Code and derivative works thereof
32183084Sjkoshy * solely to the minimum extent necessary to exercise the above copyright
33183084Sjkoshy * license, and in no event shall the patent license extend to any additions
34183084Sjkoshy * to or modifications of the Original Intel Code.  No other license or right
35145256Sjkoshy * is granted directly or by implication, estoppel or otherwise;
36145256Sjkoshy *
37145256Sjkoshy * The above copyright and patent license is granted only if the following
38145256Sjkoshy * conditions are met:
39145256Sjkoshy *
40183084Sjkoshy * 3. Conditions
41173900Sjkoshy *
42145256Sjkoshy * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43145256Sjkoshy * Redistribution of source code of any substantial portion of the Covered
44145256Sjkoshy * Code or modification with rights to further distribute source must include
45145256Sjkoshy * the above Copyright Notice, the above License, this list of Conditions,
46145256Sjkoshy * and the following Disclaimer and Export Compliance provision.  In addition,
47147586Sru * Licensee must cause all Covered Code to which Licensee contributes to
48145256Sjkoshy * contain a file documenting the changes Licensee made to create that Covered
49183084Sjkoshy * Code and the date of any change.  Licensee must include in that file the
50183084Sjkoshy * documentation of any changes made by any predecessor Licensee.  Licensee
51183084Sjkoshy * must include a prominent statement that the modification is derived,
52183084Sjkoshy * directly or indirectly, from Original Intel Code.
53183084Sjkoshy *
54183084Sjkoshy * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55183084Sjkoshy * Redistribution of source code of any substantial portion of the Covered
56183084Sjkoshy * Code or modification without rights to further distribute source must
57183084Sjkoshy * include the following Disclaimer and Export Compliance provision in the
58183084Sjkoshy * documentation and/or other materials provided with distribution.  In
59183084Sjkoshy * addition, Licensee may not authorize further sublicense of source of any
60183084Sjkoshy * portion of the Covered Code, and must include terms to the effect that the
61183084Sjkoshy * license from Licensee to its licensee is limited to the intellectual
62183084Sjkoshy * property embodied in the software Licensee provides to its licensee, and
63183084Sjkoshy * not to intellectual property embodied in modifications its licensee may
64183084Sjkoshy * make.
65183084Sjkoshy *
66183084Sjkoshy * 3.3. Redistribution of Executable. Redistribution in executable form of any
67145256Sjkoshy * substantial portion of the Covered Code or modification must reproduce the
68145256Sjkoshy * above Copyright Notice, and the following Disclaimer and Export Compliance
69145256Sjkoshy * provision in the documentation and/or other materials provided with the
70145256Sjkoshy * distribution.
71145256Sjkoshy *
72145256Sjkoshy * 3.4. Intel retains all right, title, and interest in and to the Original
73145256Sjkoshy * Intel Code.
74145256Sjkoshy *
75145256Sjkoshy * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76145256Sjkoshy * Intel shall be used in advertising or otherwise to promote the sale, use or
77145256Sjkoshy * other dealings in products derived from or relating to the Covered Code
78145256Sjkoshy * without prior written authorization from Intel.
79145256Sjkoshy *
80145256Sjkoshy * 4. Disclaimer and Export Compliance
81196446Sjkoshy *
82147586Sru * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83145256Sjkoshy * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84145256Sjkoshy * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
85145256Sjkoshy * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
86147586Sru * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
87145256Sjkoshy * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88145256Sjkoshy * PARTICULAR PURPOSE.
89145256Sjkoshy *
90145256Sjkoshy * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91145256Sjkoshy * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92147586Sru * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93147586Sru * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94145256Sjkoshy * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95147586Sru * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
96145256Sjkoshy * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97145256Sjkoshy * LIMITED REMEDY.
98147586Sru *
99147586Sru * 4.3. Licensee shall not export, either directly or indirectly, any of this
100145256Sjkoshy * software or system incorporating such software without first obtaining any
101147586Sru * required license or other approval from the U. S. Department of Commerce or
102145256Sjkoshy * any other agency or department of the United States Government.  In the
103145256Sjkoshy * event Licensee exports any such software from the United States or
104145256Sjkoshy * re-exports any such software from a foreign destination, Licensee shall
105145256Sjkoshy * ensure that the distribution and export/re-export of the software is in
106145256Sjkoshy * compliance with all laws, regulations, orders, or other restrictions of the
107145256Sjkoshy * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108145256Sjkoshy * any of its subsidiaries will export/re-export any technical data, process,
109145256Sjkoshy * software, or service, directly or indirectly, to any country for which the
110145256Sjkoshy * United States government or any agency thereof requires an export license,
111145256Sjkoshy * other governmental approval, or letter of assurance, without first obtaining
112145256Sjkoshy * such license, approval or letter.
113145256Sjkoshy *
114145256Sjkoshy *****************************************************************************/
115145256Sjkoshy
116145256Sjkoshy#define __RSCALC_C__
117145256Sjkoshy
118145256Sjkoshy#include <contrib/dev/acpica/include/acpi.h>
119145256Sjkoshy#include <contrib/dev/acpica/include/accommon.h>
120145256Sjkoshy#include <contrib/dev/acpica/include/acresrc.h>
121145256Sjkoshy#include <contrib/dev/acpica/include/acnamesp.h>
122145256Sjkoshy
123145256Sjkoshy
124147586Sru#define _COMPONENT          ACPI_RESOURCES
125145256Sjkoshy        ACPI_MODULE_NAME    ("rscalc")
126147586Sru
127145256Sjkoshy
128145256Sjkoshy/* Local prototypes */
129145256Sjkoshy
130145256Sjkoshystatic UINT8
131145256SjkoshyAcpiRsCountSetBits (
132145256Sjkoshy    UINT16                  BitField);
133147586Sru
134145256Sjkoshystatic ACPI_RS_LENGTH
135147586SruAcpiRsStructOptionLength (
136145256Sjkoshy    ACPI_RESOURCE_SOURCE    *ResourceSource);
137147586Sru
138145256Sjkoshystatic UINT32
139183084SjkoshyAcpiRsStreamOptionLength (
140147586Sru    UINT32                  ResourceLength,
141145256Sjkoshy    UINT32                  MinimumTotalLength);
142145256Sjkoshy
143183540Sjkoshy
144145256Sjkoshy/*******************************************************************************
145145256Sjkoshy *
146183540Sjkoshy * FUNCTION:    AcpiRsCountSetBits
147145256Sjkoshy *
148145256Sjkoshy * PARAMETERS:  BitField        - Field in which to count bits
149183540Sjkoshy *
150145256Sjkoshy * RETURN:      Number of bits set within the field
151145256Sjkoshy *
152147586Sru * DESCRIPTION: Count the number of bits set in a resource field. Used for
153145256Sjkoshy *              (Short descriptor) interrupt and DMA lists.
154145256Sjkoshy *
155183540Sjkoshy ******************************************************************************/
156145256Sjkoshy
157145256Sjkoshystatic UINT8
158147586SruAcpiRsCountSetBits (
159145256Sjkoshy    UINT16                  BitField)
160145256Sjkoshy{
161183540Sjkoshy    UINT8                   BitsSet;
162145256Sjkoshy
163145256Sjkoshy
164147586Sru    ACPI_FUNCTION_ENTRY ();
165145256Sjkoshy
166183540Sjkoshy
167183540Sjkoshy    for (BitsSet = 0; BitField; BitsSet++)
168183540Sjkoshy    {
169145256Sjkoshy        /* Zero the least significant bit that is set */
170183540Sjkoshy
171145256Sjkoshy        BitField &= (UINT16) (BitField - 1);
172145256Sjkoshy    }
173183540Sjkoshy
174145256Sjkoshy    return (BitsSet);
175183540Sjkoshy}
176183540Sjkoshy
177183540Sjkoshy
178183540Sjkoshy/*******************************************************************************
179183540Sjkoshy *
180183540Sjkoshy * FUNCTION:    AcpiRsStructOptionLength
181183540Sjkoshy *
182183540Sjkoshy * PARAMETERS:  ResourceSource      - Pointer to optional descriptor field
183183540Sjkoshy *
184183540Sjkoshy * RETURN:      Status
185183540Sjkoshy *
186183540Sjkoshy * DESCRIPTION: Common code to handle optional ResourceSourceIndex and
187183540Sjkoshy *              ResourceSource fields in some Large descriptors. Used during
188183540Sjkoshy *              list-to-stream conversion
189183540Sjkoshy *
190183540Sjkoshy ******************************************************************************/
191183540Sjkoshy
192145256Sjkoshystatic ACPI_RS_LENGTH
193183540SjkoshyAcpiRsStructOptionLength (
194145256Sjkoshy    ACPI_RESOURCE_SOURCE    *ResourceSource)
195145256Sjkoshy{
196183540Sjkoshy    ACPI_FUNCTION_ENTRY ();
197145256Sjkoshy
198183540Sjkoshy
199183540Sjkoshy    /*
200183540Sjkoshy     * If the ResourceSource string is valid, return the size of the string
201145256Sjkoshy     * (StringLength includes the NULL terminator) plus the size of the
202183540Sjkoshy     * ResourceSourceIndex (1).
203145256Sjkoshy     */
204145256Sjkoshy    if (ResourceSource->StringPtr)
205145256Sjkoshy    {
206183540Sjkoshy        return ((ACPI_RS_LENGTH) (ResourceSource->StringLength + 1));
207196446Sjkoshy    }
208183540Sjkoshy
209183540Sjkoshy    return (0);
210183540Sjkoshy}
211183540Sjkoshy
212183540Sjkoshy
213183540Sjkoshy/*******************************************************************************
214183540Sjkoshy *
215183540Sjkoshy * FUNCTION:    AcpiRsStreamOptionLength
216183540Sjkoshy *
217183540Sjkoshy * PARAMETERS:  ResourceLength      - Length from the resource header
218183540Sjkoshy *              MinimumTotalLength  - Minimum length of this resource, before
219183540Sjkoshy *                                    any optional fields. Includes header size
220145256Sjkoshy *
221183540Sjkoshy * RETURN:      Length of optional string (0 if no string present)
222145256Sjkoshy *
223145256Sjkoshy * DESCRIPTION: Common code to handle optional ResourceSourceIndex and
224183540Sjkoshy *              ResourceSource fields in some Large descriptors. Used during
225145256Sjkoshy *              stream-to-list conversion
226145256Sjkoshy *
227183084Sjkoshy ******************************************************************************/
228183084Sjkoshy
229183084Sjkoshystatic UINT32
230183084SjkoshyAcpiRsStreamOptionLength (
231183084Sjkoshy    UINT32                  ResourceLength,
232183084Sjkoshy    UINT32                  MinimumAmlResourceLength)
233183084Sjkoshy{
234183084Sjkoshy    UINT32                  StringLength = 0;
235183084Sjkoshy
236183084Sjkoshy
237183084Sjkoshy    ACPI_FUNCTION_ENTRY ();
238183084Sjkoshy
239183084Sjkoshy
240183084Sjkoshy    /*
241145256Sjkoshy     * The ResourceSourceIndex and ResourceSource are optional elements of some
242145256Sjkoshy     * Large-type resource descriptors.
243183084Sjkoshy     */
244183595Sjkoshy
245183595Sjkoshy    /*
246183595Sjkoshy     * If the length of the actual resource descriptor is greater than the ACPI
247183595Sjkoshy     * spec-defined minimum length, it means that a ResourceSourceIndex exists
248183084Sjkoshy     * and is followed by a (required) null terminated string. The string length
249183084Sjkoshy     * (including the null terminator) is the resource length minus the minimum
250183084Sjkoshy     * length, minus one byte for the ResourceSourceIndex itself.
251183084Sjkoshy     */
252233628Sfabient    if (ResourceLength > MinimumAmlResourceLength)
253183084Sjkoshy    {
254147191Sjkoshy        /* Compute the length of the optional string */
255183084Sjkoshy
256148223Sjkoshy        StringLength = ResourceLength - MinimumAmlResourceLength - 1;
257148223Sjkoshy    }
258152551Sru
259148223Sjkoshy    /*
260148223Sjkoshy     * Round the length up to a multiple of the native word in order to
261173900Sjkoshy     * guarantee that the entire resource descriptor is native word aligned
262173900Sjkoshy     */
263173900Sjkoshy    return ((UINT32) ACPI_ROUND_UP_TO_NATIVE_WORD (StringLength));
264173900Sjkoshy}
265173900Sjkoshy
266173900Sjkoshy
267/*******************************************************************************
268 *
269 * FUNCTION:    AcpiRsGetAmlLength
270 *
271 * PARAMETERS:  Resource            - Pointer to the resource linked list
272 *              SizeNeeded          - Where the required size is returned
273 *
274 * RETURN:      Status
275 *
276 * DESCRIPTION: Takes a linked list of internal resource descriptors and
277 *              calculates the size buffer needed to hold the corresponding
278 *              external resource byte stream.
279 *
280 ******************************************************************************/
281
282ACPI_STATUS
283AcpiRsGetAmlLength (
284    ACPI_RESOURCE           *Resource,
285    ACPI_SIZE               *SizeNeeded)
286{
287    ACPI_SIZE               AmlSizeNeeded = 0;
288    ACPI_RS_LENGTH          TotalSize;
289
290
291    ACPI_FUNCTION_TRACE (RsGetAmlLength);
292
293
294    /* Traverse entire list of internal resource descriptors */
295
296    while (Resource)
297    {
298        /* Validate the descriptor type */
299
300        if (Resource->Type > ACPI_RESOURCE_TYPE_MAX)
301        {
302            return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
303        }
304
305        /* Get the base size of the (external stream) resource descriptor */
306
307        TotalSize = AcpiGbl_AmlResourceSizes [Resource->Type];
308
309        /*
310         * Augment the base size for descriptors with optional and/or
311         * variable-length fields
312         */
313        switch (Resource->Type)
314        {
315        case ACPI_RESOURCE_TYPE_IRQ:
316
317            /* Length can be 3 or 2 */
318
319            if (Resource->Data.Irq.DescriptorLength == 2)
320            {
321                TotalSize--;
322            }
323            break;
324
325
326        case ACPI_RESOURCE_TYPE_START_DEPENDENT:
327
328            /* Length can be 1 or 0 */
329
330            if (Resource->Data.Irq.DescriptorLength == 0)
331            {
332                TotalSize--;
333            }
334            break;
335
336
337        case ACPI_RESOURCE_TYPE_VENDOR:
338            /*
339             * Vendor Defined Resource:
340             * For a Vendor Specific resource, if the Length is between 1 and 7
341             * it will be created as a Small Resource data type, otherwise it
342             * is a Large Resource data type.
343             */
344            if (Resource->Data.Vendor.ByteLength > 7)
345            {
346                /* Base size of a Large resource descriptor */
347
348                TotalSize = sizeof (AML_RESOURCE_LARGE_HEADER);
349            }
350
351            /* Add the size of the vendor-specific data */
352
353            TotalSize = (ACPI_RS_LENGTH)
354                (TotalSize + Resource->Data.Vendor.ByteLength);
355            break;
356
357
358        case ACPI_RESOURCE_TYPE_END_TAG:
359            /*
360             * End Tag:
361             * We are done -- return the accumulated total size.
362             */
363            *SizeNeeded = AmlSizeNeeded + TotalSize;
364
365            /* Normal exit */
366
367            return_ACPI_STATUS (AE_OK);
368
369
370        case ACPI_RESOURCE_TYPE_ADDRESS16:
371            /*
372             * 16-Bit Address Resource:
373             * Add the size of the optional ResourceSource info
374             */
375            TotalSize = (ACPI_RS_LENGTH)
376                (TotalSize + AcpiRsStructOptionLength (
377                                &Resource->Data.Address16.ResourceSource));
378            break;
379
380
381        case ACPI_RESOURCE_TYPE_ADDRESS32:
382            /*
383             * 32-Bit Address Resource:
384             * Add the size of the optional ResourceSource info
385             */
386            TotalSize = (ACPI_RS_LENGTH)
387                (TotalSize + AcpiRsStructOptionLength (
388                                &Resource->Data.Address32.ResourceSource));
389            break;
390
391
392        case ACPI_RESOURCE_TYPE_ADDRESS64:
393            /*
394             * 64-Bit Address Resource:
395             * Add the size of the optional ResourceSource info
396             */
397            TotalSize = (ACPI_RS_LENGTH)
398                (TotalSize + AcpiRsStructOptionLength (
399                                &Resource->Data.Address64.ResourceSource));
400            break;
401
402
403        case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
404            /*
405             * Extended IRQ Resource:
406             * Add the size of each additional optional interrupt beyond the
407             * required 1 (4 bytes for each UINT32 interrupt number)
408             */
409            TotalSize = (ACPI_RS_LENGTH)
410                (TotalSize +
411                ((Resource->Data.ExtendedIrq.InterruptCount - 1) * 4) +
412
413                /* Add the size of the optional ResourceSource info */
414
415                AcpiRsStructOptionLength (
416                    &Resource->Data.ExtendedIrq.ResourceSource));
417            break;
418
419
420        default:
421            break;
422        }
423
424        /* Update the total */
425
426        AmlSizeNeeded += TotalSize;
427
428        /* Point to the next object */
429
430        Resource = ACPI_ADD_PTR (ACPI_RESOURCE, Resource, Resource->Length);
431    }
432
433    /* Did not find an EndTag resource descriptor */
434
435    return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG);
436}
437
438
439/*******************************************************************************
440 *
441 * FUNCTION:    AcpiRsGetListLength
442 *
443 * PARAMETERS:  AmlBuffer           - Pointer to the resource byte stream
444 *              AmlBufferLength     - Size of AmlBuffer
445 *              SizeNeeded          - Where the size needed is returned
446 *
447 * RETURN:      Status
448 *
449 * DESCRIPTION: Takes an external resource byte stream and calculates the size
450 *              buffer needed to hold the corresponding internal resource
451 *              descriptor linked list.
452 *
453 ******************************************************************************/
454
455ACPI_STATUS
456AcpiRsGetListLength (
457    UINT8                   *AmlBuffer,
458    UINT32                  AmlBufferLength,
459    ACPI_SIZE               *SizeNeeded)
460{
461    ACPI_STATUS             Status;
462    UINT8                   *EndAml;
463    UINT8                   *Buffer;
464    UINT32                  BufferSize;
465    UINT16                  Temp16;
466    UINT16                  ResourceLength;
467    UINT32                  ExtraStructBytes;
468    UINT8                   ResourceIndex;
469    UINT8                   MinimumAmlResourceLength;
470
471
472    ACPI_FUNCTION_TRACE (RsGetListLength);
473
474
475    *SizeNeeded = 0;
476    EndAml = AmlBuffer + AmlBufferLength;
477
478    /* Walk the list of AML resource descriptors */
479
480    while (AmlBuffer < EndAml)
481    {
482        /* Validate the Resource Type and Resource Length */
483
484        Status = AcpiUtValidateResource (AmlBuffer, &ResourceIndex);
485        if (ACPI_FAILURE (Status))
486        {
487            return_ACPI_STATUS (Status);
488        }
489
490        /* Get the resource length and base (minimum) AML size */
491
492        ResourceLength = AcpiUtGetResourceLength (AmlBuffer);
493        MinimumAmlResourceLength = AcpiGbl_ResourceAmlSizes[ResourceIndex];
494
495        /*
496         * Augment the size for descriptors with optional
497         * and/or variable length fields
498         */
499        ExtraStructBytes = 0;
500        Buffer = AmlBuffer + AcpiUtGetResourceHeaderLength (AmlBuffer);
501
502        switch (AcpiUtGetResourceType (AmlBuffer))
503        {
504        case ACPI_RESOURCE_NAME_IRQ:
505            /*
506             * IRQ Resource:
507             * Get the number of bits set in the 16-bit IRQ mask
508             */
509            ACPI_MOVE_16_TO_16 (&Temp16, Buffer);
510            ExtraStructBytes = AcpiRsCountSetBits (Temp16);
511            break;
512
513
514        case ACPI_RESOURCE_NAME_DMA:
515            /*
516             * DMA Resource:
517             * Get the number of bits set in the 8-bit DMA mask
518             */
519            ExtraStructBytes = AcpiRsCountSetBits (*Buffer);
520            break;
521
522
523        case ACPI_RESOURCE_NAME_VENDOR_SMALL:
524        case ACPI_RESOURCE_NAME_VENDOR_LARGE:
525            /*
526             * Vendor Resource:
527             * Get the number of vendor data bytes
528             */
529            ExtraStructBytes = ResourceLength;
530            break;
531
532
533        case ACPI_RESOURCE_NAME_END_TAG:
534            /*
535             * End Tag:
536             * This is the normal exit, add size of EndTag
537             */
538            *SizeNeeded += ACPI_RS_SIZE_MIN;
539            return_ACPI_STATUS (AE_OK);
540
541
542        case ACPI_RESOURCE_NAME_ADDRESS32:
543        case ACPI_RESOURCE_NAME_ADDRESS16:
544        case ACPI_RESOURCE_NAME_ADDRESS64:
545            /*
546             * Address Resource:
547             * Add the size of the optional ResourceSource
548             */
549            ExtraStructBytes = AcpiRsStreamOptionLength (
550                ResourceLength, MinimumAmlResourceLength);
551            break;
552
553
554        case ACPI_RESOURCE_NAME_EXTENDED_IRQ:
555            /*
556             * Extended IRQ Resource:
557             * Using the InterruptTableLength, add 4 bytes for each additional
558             * interrupt. Note: at least one interrupt is required and is
559             * included in the minimum descriptor size (reason for the -1)
560             */
561            ExtraStructBytes = (Buffer[1] - 1) * sizeof (UINT32);
562
563            /* Add the size of the optional ResourceSource */
564
565            ExtraStructBytes += AcpiRsStreamOptionLength (
566                ResourceLength - ExtraStructBytes, MinimumAmlResourceLength);
567            break;
568
569
570        default:
571            break;
572        }
573
574        /*
575         * Update the required buffer size for the internal descriptor structs
576         *
577         * Important: Round the size up for the appropriate alignment. This
578         * is a requirement on IA64.
579         */
580        BufferSize = AcpiGbl_ResourceStructSizes[ResourceIndex] +
581                        ExtraStructBytes;
582        BufferSize = (UINT32) ACPI_ROUND_UP_TO_NATIVE_WORD (BufferSize);
583
584        *SizeNeeded += BufferSize;
585
586        ACPI_DEBUG_PRINT ((ACPI_DB_RESOURCES,
587            "Type %.2X, AmlLength %.2X InternalLength %.2X\n",
588            AcpiUtGetResourceType (AmlBuffer),
589            AcpiUtGetDescriptorLength (AmlBuffer), BufferSize));
590
591        /*
592         * Point to the next resource within the AML stream using the length
593         * contained in the resource descriptor header
594         */
595        AmlBuffer += AcpiUtGetDescriptorLength (AmlBuffer);
596    }
597
598    /* Did not find an EndTag resource descriptor */
599
600    return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG);
601}
602
603
604/*******************************************************************************
605 *
606 * FUNCTION:    AcpiRsGetPciRoutingTableLength
607 *
608 * PARAMETERS:  PackageObject           - Pointer to the package object
609 *              BufferSizeNeeded        - UINT32 pointer of the size buffer
610 *                                        needed to properly return the
611 *                                        parsed data
612 *
613 * RETURN:      Status
614 *
615 * DESCRIPTION: Given a package representing a PCI routing table, this
616 *              calculates the size of the corresponding linked list of
617 *              descriptions.
618 *
619 ******************************************************************************/
620
621ACPI_STATUS
622AcpiRsGetPciRoutingTableLength (
623    ACPI_OPERAND_OBJECT     *PackageObject,
624    ACPI_SIZE               *BufferSizeNeeded)
625{
626    UINT32                  NumberOfElements;
627    ACPI_SIZE               TempSizeNeeded = 0;
628    ACPI_OPERAND_OBJECT     **TopObjectList;
629    UINT32                  Index;
630    ACPI_OPERAND_OBJECT     *PackageElement;
631    ACPI_OPERAND_OBJECT     **SubObjectList;
632    BOOLEAN                 NameFound;
633    UINT32                  TableIndex;
634
635
636    ACPI_FUNCTION_TRACE (RsGetPciRoutingTableLength);
637
638
639    NumberOfElements = PackageObject->Package.Count;
640
641    /*
642     * Calculate the size of the return buffer.
643     * The base size is the number of elements * the sizes of the
644     * structures.  Additional space for the strings is added below.
645     * The minus one is to subtract the size of the UINT8 Source[1]
646     * member because it is added below.
647     *
648     * But each PRT_ENTRY structure has a pointer to a string and
649     * the size of that string must be found.
650     */
651    TopObjectList = PackageObject->Package.Elements;
652
653    for (Index = 0; Index < NumberOfElements; Index++)
654    {
655        /* Dereference the sub-package */
656
657        PackageElement = *TopObjectList;
658
659        /* We must have a valid Package object */
660
661        if (!PackageElement ||
662            (PackageElement->Common.Type != ACPI_TYPE_PACKAGE))
663        {
664            return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
665        }
666
667        /*
668         * The SubObjectList will now point to an array of the
669         * four IRQ elements: Address, Pin, Source and SourceIndex
670         */
671        SubObjectList = PackageElement->Package.Elements;
672
673        /* Scan the IrqTableElements for the Source Name String */
674
675        NameFound = FALSE;
676
677        for (TableIndex = 0; TableIndex < 4 && !NameFound; TableIndex++)
678        {
679            if (*SubObjectList && /* Null object allowed */
680
681                ((ACPI_TYPE_STRING ==
682                    (*SubObjectList)->Common.Type) ||
683
684                ((ACPI_TYPE_LOCAL_REFERENCE ==
685                    (*SubObjectList)->Common.Type) &&
686
687                    ((*SubObjectList)->Reference.Class ==
688                        ACPI_REFCLASS_NAME))))
689            {
690                NameFound = TRUE;
691            }
692            else
693            {
694                /* Look at the next element */
695
696                SubObjectList++;
697            }
698        }
699
700        TempSizeNeeded += (sizeof (ACPI_PCI_ROUTING_TABLE) - 4);
701
702        /* Was a String type found? */
703
704        if (NameFound)
705        {
706            if ((*SubObjectList)->Common.Type == ACPI_TYPE_STRING)
707            {
708                /*
709                 * The length String.Length field does not include the
710                 * terminating NULL, add 1
711                 */
712                TempSizeNeeded += ((ACPI_SIZE)
713                    (*SubObjectList)->String.Length + 1);
714            }
715            else
716            {
717                TempSizeNeeded += AcpiNsGetPathnameLength (
718                                    (*SubObjectList)->Reference.Node);
719            }
720        }
721        else
722        {
723            /*
724             * If no name was found, then this is a NULL, which is
725             * translated as a UINT32 zero.
726             */
727            TempSizeNeeded += sizeof (UINT32);
728        }
729
730        /* Round up the size since each element must be aligned */
731
732        TempSizeNeeded = ACPI_ROUND_UP_TO_64BIT (TempSizeNeeded);
733
734        /* Point to the next ACPI_OPERAND_OBJECT */
735
736        TopObjectList++;
737    }
738
739    /*
740     * Add an extra element to the end of the list, essentially a
741     * NULL terminator
742     */
743    *BufferSizeNeeded = TempSizeNeeded + sizeof (ACPI_PCI_ROUTING_TABLE);
744    return_ACPI_STATUS (AE_OK);
745}
746