rscalc.c revision 281075
1/*******************************************************************************
2 *
3 * Module Name: rscalc - Calculate stream and list lengths
4 *
5 ******************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2015, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 *    notice, this list of conditions, and the following disclaimer,
16 *    without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 *    substantially similar to the "NO WARRANTY" disclaimer below
19 *    ("Disclaimer") and any redistribution must be conditioned upon
20 *    including a substantially similar Disclaimer requirement for further
21 *    binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 *    of any contributors may be used to endorse or promote products derived
24 *    from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44#include <contrib/dev/acpica/include/acpi.h>
45#include <contrib/dev/acpica/include/accommon.h>
46#include <contrib/dev/acpica/include/acresrc.h>
47#include <contrib/dev/acpica/include/acnamesp.h>
48
49
50#define _COMPONENT          ACPI_RESOURCES
51        ACPI_MODULE_NAME    ("rscalc")
52
53
54/* Local prototypes */
55
56static UINT8
57AcpiRsCountSetBits (
58    UINT16                  BitField);
59
60static ACPI_RS_LENGTH
61AcpiRsStructOptionLength (
62    ACPI_RESOURCE_SOURCE    *ResourceSource);
63
64static UINT32
65AcpiRsStreamOptionLength (
66    UINT32                  ResourceLength,
67    UINT32                  MinimumTotalLength);
68
69
70/*******************************************************************************
71 *
72 * FUNCTION:    AcpiRsCountSetBits
73 *
74 * PARAMETERS:  BitField        - Field in which to count bits
75 *
76 * RETURN:      Number of bits set within the field
77 *
78 * DESCRIPTION: Count the number of bits set in a resource field. Used for
79 *              (Short descriptor) interrupt and DMA lists.
80 *
81 ******************************************************************************/
82
83static UINT8
84AcpiRsCountSetBits (
85    UINT16                  BitField)
86{
87    UINT8                   BitsSet;
88
89
90    ACPI_FUNCTION_ENTRY ();
91
92
93    for (BitsSet = 0; BitField; BitsSet++)
94    {
95        /* Zero the least significant bit that is set */
96
97        BitField &= (UINT16) (BitField - 1);
98    }
99
100    return (BitsSet);
101}
102
103
104/*******************************************************************************
105 *
106 * FUNCTION:    AcpiRsStructOptionLength
107 *
108 * PARAMETERS:  ResourceSource      - Pointer to optional descriptor field
109 *
110 * RETURN:      Status
111 *
112 * DESCRIPTION: Common code to handle optional ResourceSourceIndex and
113 *              ResourceSource fields in some Large descriptors. Used during
114 *              list-to-stream conversion
115 *
116 ******************************************************************************/
117
118static ACPI_RS_LENGTH
119AcpiRsStructOptionLength (
120    ACPI_RESOURCE_SOURCE    *ResourceSource)
121{
122    ACPI_FUNCTION_ENTRY ();
123
124
125    /*
126     * If the ResourceSource string is valid, return the size of the string
127     * (StringLength includes the NULL terminator) plus the size of the
128     * ResourceSourceIndex (1).
129     */
130    if (ResourceSource->StringPtr)
131    {
132        return ((ACPI_RS_LENGTH) (ResourceSource->StringLength + 1));
133    }
134
135    return (0);
136}
137
138
139/*******************************************************************************
140 *
141 * FUNCTION:    AcpiRsStreamOptionLength
142 *
143 * PARAMETERS:  ResourceLength      - Length from the resource header
144 *              MinimumTotalLength  - Minimum length of this resource, before
145 *                                    any optional fields. Includes header size
146 *
147 * RETURN:      Length of optional string (0 if no string present)
148 *
149 * DESCRIPTION: Common code to handle optional ResourceSourceIndex and
150 *              ResourceSource fields in some Large descriptors. Used during
151 *              stream-to-list conversion
152 *
153 ******************************************************************************/
154
155static UINT32
156AcpiRsStreamOptionLength (
157    UINT32                  ResourceLength,
158    UINT32                  MinimumAmlResourceLength)
159{
160    UINT32                  StringLength = 0;
161
162
163    ACPI_FUNCTION_ENTRY ();
164
165
166    /*
167     * The ResourceSourceIndex and ResourceSource are optional elements of some
168     * Large-type resource descriptors.
169     */
170
171    /*
172     * If the length of the actual resource descriptor is greater than the ACPI
173     * spec-defined minimum length, it means that a ResourceSourceIndex exists
174     * and is followed by a (required) null terminated string. The string length
175     * (including the null terminator) is the resource length minus the minimum
176     * length, minus one byte for the ResourceSourceIndex itself.
177     */
178    if (ResourceLength > MinimumAmlResourceLength)
179    {
180        /* Compute the length of the optional string */
181
182        StringLength = ResourceLength - MinimumAmlResourceLength - 1;
183    }
184
185    /*
186     * Round the length up to a multiple of the native word in order to
187     * guarantee that the entire resource descriptor is native word aligned
188     */
189    return ((UINT32) ACPI_ROUND_UP_TO_NATIVE_WORD (StringLength));
190}
191
192
193/*******************************************************************************
194 *
195 * FUNCTION:    AcpiRsGetAmlLength
196 *
197 * PARAMETERS:  Resource            - Pointer to the resource linked list
198 *              ResourceListSize    - Size of the resource linked list
199 *              SizeNeeded          - Where the required size is returned
200 *
201 * RETURN:      Status
202 *
203 * DESCRIPTION: Takes a linked list of internal resource descriptors and
204 *              calculates the size buffer needed to hold the corresponding
205 *              external resource byte stream.
206 *
207 ******************************************************************************/
208
209ACPI_STATUS
210AcpiRsGetAmlLength (
211    ACPI_RESOURCE           *Resource,
212    ACPI_SIZE               ResourceListSize,
213    ACPI_SIZE               *SizeNeeded)
214{
215    ACPI_SIZE               AmlSizeNeeded = 0;
216    ACPI_RESOURCE           *ResourceEnd;
217    ACPI_RS_LENGTH          TotalSize;
218
219
220    ACPI_FUNCTION_TRACE (RsGetAmlLength);
221
222
223    /* Traverse entire list of internal resource descriptors */
224
225    ResourceEnd = ACPI_ADD_PTR (ACPI_RESOURCE, Resource, ResourceListSize);
226    while (Resource < ResourceEnd)
227    {
228        /* Validate the descriptor type */
229
230        if (Resource->Type > ACPI_RESOURCE_TYPE_MAX)
231        {
232            return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
233        }
234
235        /* Sanity check the length. It must not be zero, or we loop forever */
236
237        if (!Resource->Length)
238        {
239            return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH);
240        }
241
242        /* Get the base size of the (external stream) resource descriptor */
243
244        TotalSize = AcpiGbl_AmlResourceSizes [Resource->Type];
245
246        /*
247         * Augment the base size for descriptors with optional and/or
248         * variable-length fields
249         */
250        switch (Resource->Type)
251        {
252        case ACPI_RESOURCE_TYPE_IRQ:
253
254            /* Length can be 3 or 2 */
255
256            if (Resource->Data.Irq.DescriptorLength == 2)
257            {
258                TotalSize--;
259            }
260            break;
261
262
263        case ACPI_RESOURCE_TYPE_START_DEPENDENT:
264
265            /* Length can be 1 or 0 */
266
267            if (Resource->Data.Irq.DescriptorLength == 0)
268            {
269                TotalSize--;
270            }
271            break;
272
273
274        case ACPI_RESOURCE_TYPE_VENDOR:
275            /*
276             * Vendor Defined Resource:
277             * For a Vendor Specific resource, if the Length is between 1 and 7
278             * it will be created as a Small Resource data type, otherwise it
279             * is a Large Resource data type.
280             */
281            if (Resource->Data.Vendor.ByteLength > 7)
282            {
283                /* Base size of a Large resource descriptor */
284
285                TotalSize = sizeof (AML_RESOURCE_LARGE_HEADER);
286            }
287
288            /* Add the size of the vendor-specific data */
289
290            TotalSize = (ACPI_RS_LENGTH)
291                (TotalSize + Resource->Data.Vendor.ByteLength);
292            break;
293
294
295        case ACPI_RESOURCE_TYPE_END_TAG:
296            /*
297             * End Tag:
298             * We are done -- return the accumulated total size.
299             */
300            *SizeNeeded = AmlSizeNeeded + TotalSize;
301
302            /* Normal exit */
303
304            return_ACPI_STATUS (AE_OK);
305
306
307        case ACPI_RESOURCE_TYPE_ADDRESS16:
308            /*
309             * 16-Bit Address Resource:
310             * Add the size of the optional ResourceSource info
311             */
312            TotalSize = (ACPI_RS_LENGTH)
313                (TotalSize + AcpiRsStructOptionLength (
314                                &Resource->Data.Address16.ResourceSource));
315            break;
316
317
318        case ACPI_RESOURCE_TYPE_ADDRESS32:
319            /*
320             * 32-Bit Address Resource:
321             * Add the size of the optional ResourceSource info
322             */
323            TotalSize = (ACPI_RS_LENGTH)
324                (TotalSize + AcpiRsStructOptionLength (
325                                &Resource->Data.Address32.ResourceSource));
326            break;
327
328
329        case ACPI_RESOURCE_TYPE_ADDRESS64:
330            /*
331             * 64-Bit Address Resource:
332             * Add the size of the optional ResourceSource info
333             */
334            TotalSize = (ACPI_RS_LENGTH)
335                (TotalSize + AcpiRsStructOptionLength (
336                                &Resource->Data.Address64.ResourceSource));
337            break;
338
339
340        case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
341            /*
342             * Extended IRQ Resource:
343             * Add the size of each additional optional interrupt beyond the
344             * required 1 (4 bytes for each UINT32 interrupt number)
345             */
346            TotalSize = (ACPI_RS_LENGTH)
347                (TotalSize +
348                ((Resource->Data.ExtendedIrq.InterruptCount - 1) * 4) +
349
350                /* Add the size of the optional ResourceSource info */
351
352                AcpiRsStructOptionLength (
353                    &Resource->Data.ExtendedIrq.ResourceSource));
354            break;
355
356
357        case ACPI_RESOURCE_TYPE_GPIO:
358
359            TotalSize = (ACPI_RS_LENGTH) (TotalSize + (Resource->Data.Gpio.PinTableLength * 2) +
360                Resource->Data.Gpio.ResourceSource.StringLength +
361                Resource->Data.Gpio.VendorLength);
362
363            break;
364
365
366        case ACPI_RESOURCE_TYPE_SERIAL_BUS:
367
368            TotalSize = AcpiGbl_AmlResourceSerialBusSizes [Resource->Data.CommonSerialBus.Type];
369
370            TotalSize = (ACPI_RS_LENGTH) (TotalSize +
371                Resource->Data.I2cSerialBus.ResourceSource.StringLength +
372                Resource->Data.I2cSerialBus.VendorLength);
373
374            break;
375
376        default:
377
378            break;
379        }
380
381        /* Update the total */
382
383        AmlSizeNeeded += TotalSize;
384
385        /* Point to the next object */
386
387        Resource = ACPI_ADD_PTR (ACPI_RESOURCE, Resource, Resource->Length);
388    }
389
390    /* Did not find an EndTag resource descriptor */
391
392    return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG);
393}
394
395
396/*******************************************************************************
397 *
398 * FUNCTION:    AcpiRsGetListLength
399 *
400 * PARAMETERS:  AmlBuffer           - Pointer to the resource byte stream
401 *              AmlBufferLength     - Size of AmlBuffer
402 *              SizeNeeded          - Where the size needed is returned
403 *
404 * RETURN:      Status
405 *
406 * DESCRIPTION: Takes an external resource byte stream and calculates the size
407 *              buffer needed to hold the corresponding internal resource
408 *              descriptor linked list.
409 *
410 ******************************************************************************/
411
412ACPI_STATUS
413AcpiRsGetListLength (
414    UINT8                   *AmlBuffer,
415    UINT32                  AmlBufferLength,
416    ACPI_SIZE               *SizeNeeded)
417{
418    ACPI_STATUS             Status;
419    UINT8                   *EndAml;
420    UINT8                   *Buffer;
421    UINT32                  BufferSize;
422    UINT16                  Temp16;
423    UINT16                  ResourceLength;
424    UINT32                  ExtraStructBytes;
425    UINT8                   ResourceIndex;
426    UINT8                   MinimumAmlResourceLength;
427    AML_RESOURCE            *AmlResource;
428
429
430    ACPI_FUNCTION_TRACE (RsGetListLength);
431
432
433    *SizeNeeded = ACPI_RS_SIZE_MIN;         /* Minimum size is one EndTag */
434    EndAml = AmlBuffer + AmlBufferLength;
435
436    /* Walk the list of AML resource descriptors */
437
438    while (AmlBuffer < EndAml)
439    {
440        /* Validate the Resource Type and Resource Length */
441
442        Status = AcpiUtValidateResource (NULL, AmlBuffer, &ResourceIndex);
443        if (ACPI_FAILURE (Status))
444        {
445            /*
446             * Exit on failure. Cannot continue because the descriptor length
447             * may be bogus also.
448             */
449            return_ACPI_STATUS (Status);
450        }
451
452        AmlResource = (void *) AmlBuffer;
453
454        /* Get the resource length and base (minimum) AML size */
455
456        ResourceLength = AcpiUtGetResourceLength (AmlBuffer);
457        MinimumAmlResourceLength = AcpiGbl_ResourceAmlSizes[ResourceIndex];
458
459        /*
460         * Augment the size for descriptors with optional
461         * and/or variable length fields
462         */
463        ExtraStructBytes = 0;
464        Buffer = AmlBuffer + AcpiUtGetResourceHeaderLength (AmlBuffer);
465
466        switch (AcpiUtGetResourceType (AmlBuffer))
467        {
468        case ACPI_RESOURCE_NAME_IRQ:
469            /*
470             * IRQ Resource:
471             * Get the number of bits set in the 16-bit IRQ mask
472             */
473            ACPI_MOVE_16_TO_16 (&Temp16, Buffer);
474            ExtraStructBytes = AcpiRsCountSetBits (Temp16);
475            break;
476
477
478        case ACPI_RESOURCE_NAME_DMA:
479            /*
480             * DMA Resource:
481             * Get the number of bits set in the 8-bit DMA mask
482             */
483            ExtraStructBytes = AcpiRsCountSetBits (*Buffer);
484            break;
485
486
487        case ACPI_RESOURCE_NAME_VENDOR_SMALL:
488        case ACPI_RESOURCE_NAME_VENDOR_LARGE:
489            /*
490             * Vendor Resource:
491             * Get the number of vendor data bytes
492             */
493            ExtraStructBytes = ResourceLength;
494
495            /*
496             * There is already one byte included in the minimum
497             * descriptor size. If there are extra struct bytes,
498             * subtract one from the count.
499             */
500            if (ExtraStructBytes)
501            {
502                ExtraStructBytes--;
503            }
504            break;
505
506
507        case ACPI_RESOURCE_NAME_END_TAG:
508            /*
509             * End Tag: This is the normal exit
510             */
511            return_ACPI_STATUS (AE_OK);
512
513
514        case ACPI_RESOURCE_NAME_ADDRESS32:
515        case ACPI_RESOURCE_NAME_ADDRESS16:
516        case ACPI_RESOURCE_NAME_ADDRESS64:
517            /*
518             * Address Resource:
519             * Add the size of the optional ResourceSource
520             */
521            ExtraStructBytes = AcpiRsStreamOptionLength (
522                ResourceLength, MinimumAmlResourceLength);
523            break;
524
525
526        case ACPI_RESOURCE_NAME_EXTENDED_IRQ:
527            /*
528             * Extended IRQ Resource:
529             * Using the InterruptTableLength, add 4 bytes for each additional
530             * interrupt. Note: at least one interrupt is required and is
531             * included in the minimum descriptor size (reason for the -1)
532             */
533            ExtraStructBytes = (Buffer[1] - 1) * sizeof (UINT32);
534
535            /* Add the size of the optional ResourceSource */
536
537            ExtraStructBytes += AcpiRsStreamOptionLength (
538                ResourceLength - ExtraStructBytes, MinimumAmlResourceLength);
539            break;
540
541        case ACPI_RESOURCE_NAME_GPIO:
542
543            /* Vendor data is optional */
544
545            if (AmlResource->Gpio.VendorLength)
546            {
547                ExtraStructBytes += AmlResource->Gpio.VendorOffset -
548                    AmlResource->Gpio.PinTableOffset + AmlResource->Gpio.VendorLength;
549            }
550            else
551            {
552                ExtraStructBytes += AmlResource->LargeHeader.ResourceLength +
553                    sizeof (AML_RESOURCE_LARGE_HEADER) -
554                    AmlResource->Gpio.PinTableOffset;
555            }
556            break;
557
558        case ACPI_RESOURCE_NAME_SERIAL_BUS:
559
560            MinimumAmlResourceLength = AcpiGbl_ResourceAmlSerialBusSizes[
561                AmlResource->CommonSerialBus.Type];
562            ExtraStructBytes += AmlResource->CommonSerialBus.ResourceLength -
563                MinimumAmlResourceLength;
564            break;
565
566        default:
567
568            break;
569        }
570
571        /*
572         * Update the required buffer size for the internal descriptor structs
573         *
574         * Important: Round the size up for the appropriate alignment. This
575         * is a requirement on IA64.
576         */
577        if (AcpiUtGetResourceType (AmlBuffer) == ACPI_RESOURCE_NAME_SERIAL_BUS)
578        {
579            BufferSize = AcpiGbl_ResourceStructSerialBusSizes[
580                AmlResource->CommonSerialBus.Type] + ExtraStructBytes;
581        }
582        else
583        {
584            BufferSize = AcpiGbl_ResourceStructSizes[ResourceIndex] +
585                        ExtraStructBytes;
586        }
587        BufferSize = (UINT32) ACPI_ROUND_UP_TO_NATIVE_WORD (BufferSize);
588
589        *SizeNeeded += BufferSize;
590
591        ACPI_DEBUG_PRINT ((ACPI_DB_RESOURCES,
592            "Type %.2X, AmlLength %.2X InternalLength %.2X\n",
593            AcpiUtGetResourceType (AmlBuffer),
594            AcpiUtGetDescriptorLength (AmlBuffer), BufferSize));
595
596        /*
597         * Point to the next resource within the AML stream using the length
598         * contained in the resource descriptor header
599         */
600        AmlBuffer += AcpiUtGetDescriptorLength (AmlBuffer);
601    }
602
603    /* Did not find an EndTag resource descriptor */
604
605    return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG);
606}
607
608
609/*******************************************************************************
610 *
611 * FUNCTION:    AcpiRsGetPciRoutingTableLength
612 *
613 * PARAMETERS:  PackageObject           - Pointer to the package object
614 *              BufferSizeNeeded        - UINT32 pointer of the size buffer
615 *                                        needed to properly return the
616 *                                        parsed data
617 *
618 * RETURN:      Status
619 *
620 * DESCRIPTION: Given a package representing a PCI routing table, this
621 *              calculates the size of the corresponding linked list of
622 *              descriptions.
623 *
624 ******************************************************************************/
625
626ACPI_STATUS
627AcpiRsGetPciRoutingTableLength (
628    ACPI_OPERAND_OBJECT     *PackageObject,
629    ACPI_SIZE               *BufferSizeNeeded)
630{
631    UINT32                  NumberOfElements;
632    ACPI_SIZE               TempSizeNeeded = 0;
633    ACPI_OPERAND_OBJECT     **TopObjectList;
634    UINT32                  Index;
635    ACPI_OPERAND_OBJECT     *PackageElement;
636    ACPI_OPERAND_OBJECT     **SubObjectList;
637    BOOLEAN                 NameFound;
638    UINT32                  TableIndex;
639
640
641    ACPI_FUNCTION_TRACE (RsGetPciRoutingTableLength);
642
643
644    NumberOfElements = PackageObject->Package.Count;
645
646    /*
647     * Calculate the size of the return buffer.
648     * The base size is the number of elements * the sizes of the
649     * structures. Additional space for the strings is added below.
650     * The minus one is to subtract the size of the UINT8 Source[1]
651     * member because it is added below.
652     *
653     * But each PRT_ENTRY structure has a pointer to a string and
654     * the size of that string must be found.
655     */
656    TopObjectList = PackageObject->Package.Elements;
657
658    for (Index = 0; Index < NumberOfElements; Index++)
659    {
660        /* Dereference the subpackage */
661
662        PackageElement = *TopObjectList;
663
664        /* We must have a valid Package object */
665
666        if (!PackageElement ||
667            (PackageElement->Common.Type != ACPI_TYPE_PACKAGE))
668        {
669            return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
670        }
671
672        /*
673         * The SubObjectList will now point to an array of the
674         * four IRQ elements: Address, Pin, Source and SourceIndex
675         */
676        SubObjectList = PackageElement->Package.Elements;
677
678        /* Scan the IrqTableElements for the Source Name String */
679
680        NameFound = FALSE;
681
682        for (TableIndex = 0;
683             TableIndex < PackageElement->Package.Count && !NameFound;
684             TableIndex++)
685        {
686            if (*SubObjectList && /* Null object allowed */
687
688                ((ACPI_TYPE_STRING ==
689                    (*SubObjectList)->Common.Type) ||
690
691                ((ACPI_TYPE_LOCAL_REFERENCE ==
692                    (*SubObjectList)->Common.Type) &&
693
694                    ((*SubObjectList)->Reference.Class ==
695                        ACPI_REFCLASS_NAME))))
696            {
697                NameFound = TRUE;
698            }
699            else
700            {
701                /* Look at the next element */
702
703                SubObjectList++;
704            }
705        }
706
707        TempSizeNeeded += (sizeof (ACPI_PCI_ROUTING_TABLE) - 4);
708
709        /* Was a String type found? */
710
711        if (NameFound)
712        {
713            if ((*SubObjectList)->Common.Type == ACPI_TYPE_STRING)
714            {
715                /*
716                 * The length String.Length field does not include the
717                 * terminating NULL, add 1
718                 */
719                TempSizeNeeded += ((ACPI_SIZE)
720                    (*SubObjectList)->String.Length + 1);
721            }
722            else
723            {
724                TempSizeNeeded += AcpiNsGetPathnameLength (
725                                    (*SubObjectList)->Reference.Node);
726            }
727        }
728        else
729        {
730            /*
731             * If no name was found, then this is a NULL, which is
732             * translated as a UINT32 zero.
733             */
734            TempSizeNeeded += sizeof (UINT32);
735        }
736
737        /* Round up the size since each element must be aligned */
738
739        TempSizeNeeded = ACPI_ROUND_UP_TO_64BIT (TempSizeNeeded);
740
741        /* Point to the next ACPI_OPERAND_OBJECT */
742
743        TopObjectList++;
744    }
745
746    /*
747     * Add an extra element to the end of the list, essentially a
748     * NULL terminator
749     */
750    *BufferSizeNeeded = TempSizeNeeded + sizeof (ACPI_PCI_ROUTING_TABLE);
751    return_ACPI_STATUS (AE_OK);
752}
753