rscalc.c revision 69450
1/*******************************************************************************
2 *
3 * Module Name: rscalc - AcpiRsCalculateByteStreamLength
4 *                       AcpiRsCalculateListLength
5 *              $Revision: 16 $
6 *
7 ******************************************************************************/
8
9/******************************************************************************
10 *
11 * 1. Copyright Notice
12 *
13 * Some or all of this work - Copyright (c) 1999, Intel Corp.  All rights
14 * reserved.
15 *
16 * 2. License
17 *
18 * 2.1. This is your license from Intel Corp. under its intellectual property
19 * rights.  You may have additional license terms from the party that provided
20 * you this software, covering your right to use that party's intellectual
21 * property rights.
22 *
23 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
24 * copy of the source code appearing in this file ("Covered Code") an
25 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
26 * base code distributed originally by Intel ("Original Intel Code") to copy,
27 * make derivatives, distribute, use and display any portion of the Covered
28 * Code in any form, with the right to sublicense such rights; and
29 *
30 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
31 * license (with the right to sublicense), under only those claims of Intel
32 * patents that are infringed by the Original Intel Code, to make, use, sell,
33 * offer to sell, and import the Covered Code and derivative works thereof
34 * solely to the minimum extent necessary to exercise the above copyright
35 * license, and in no event shall the patent license extend to any additions
36 * to or modifications of the Original Intel Code.  No other license or right
37 * is granted directly or by implication, estoppel or otherwise;
38 *
39 * The above copyright and patent license is granted only if the following
40 * conditions are met:
41 *
42 * 3. Conditions
43 *
44 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
45 * Redistribution of source code of any substantial portion of the Covered
46 * Code or modification with rights to further distribute source must include
47 * the above Copyright Notice, the above License, this list of Conditions,
48 * and the following Disclaimer and Export Compliance provision.  In addition,
49 * Licensee must cause all Covered Code to which Licensee contributes to
50 * contain a file documenting the changes Licensee made to create that Covered
51 * Code and the date of any change.  Licensee must include in that file the
52 * documentation of any changes made by any predecessor Licensee.  Licensee
53 * must include a prominent statement that the modification is derived,
54 * directly or indirectly, from Original Intel Code.
55 *
56 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
57 * Redistribution of source code of any substantial portion of the Covered
58 * Code or modification without rights to further distribute source must
59 * include the following Disclaimer and Export Compliance provision in the
60 * documentation and/or other materials provided with distribution.  In
61 * addition, Licensee may not authorize further sublicense of source of any
62 * portion of the Covered Code, and must include terms to the effect that the
63 * license from Licensee to its licensee is limited to the intellectual
64 * property embodied in the software Licensee provides to its licensee, and
65 * not to intellectual property embodied in modifications its licensee may
66 * make.
67 *
68 * 3.3. Redistribution of Executable. Redistribution in executable form of any
69 * substantial portion of the Covered Code or modification must reproduce the
70 * above Copyright Notice, and the following Disclaimer and Export Compliance
71 * provision in the documentation and/or other materials provided with the
72 * distribution.
73 *
74 * 3.4. Intel retains all right, title, and interest in and to the Original
75 * Intel Code.
76 *
77 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
78 * Intel shall be used in advertising or otherwise to promote the sale, use or
79 * other dealings in products derived from or relating to the Covered Code
80 * without prior written authorization from Intel.
81 *
82 * 4. Disclaimer and Export Compliance
83 *
84 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
85 * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
86 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
87 * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
88 * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
89 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
90 * PARTICULAR PURPOSE.
91 *
92 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
93 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
94 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
95 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
96 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
97 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
98 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
99 * LIMITED REMEDY.
100 *
101 * 4.3. Licensee shall not export, either directly or indirectly, any of this
102 * software or system incorporating such software without first obtaining any
103 * required license or other approval from the U. S. Department of Commerce or
104 * any other agency or department of the United States Government.  In the
105 * event Licensee exports any such software from the United States or
106 * re-exports any such software from a foreign destination, Licensee shall
107 * ensure that the distribution and export/re-export of the software is in
108 * compliance with all laws, regulations, orders, or other restrictions of the
109 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
110 * any of its subsidiaries will export/re-export any technical data, process,
111 * software, or service, directly or indirectly, to any country for which the
112 * United States government or any agency thereof requires an export license,
113 * other governmental approval, or letter of assurance, without first obtaining
114 * such license, approval or letter.
115 *
116 *****************************************************************************/
117
118#define __RSCALC_C__
119
120#include "acpi.h"
121#include "acresrc.h"
122
123#define _COMPONENT          RESOURCE_MANAGER
124        MODULE_NAME         ("rscalc")
125
126
127/*******************************************************************************
128 *
129 * FUNCTION:    AcpiRsCalculateByteStreamLength
130 *
131 * PARAMETERS:  LinkedList          - Pointer to the resource linked list
132 *              SizeNeeded          - UINT32 pointer of the size buffer needed
133 *                                      to properly return the parsed data
134 *
135 * RETURN:      Status  AE_OK if okay, else a valid ACPI_STATUS code
136 *
137 * DESCRIPTION: Takes the resource byte stream and parses it once, calculating
138 *              the size buffer needed to hold the linked list that conveys
139 *              the resource data.
140 *
141 ******************************************************************************/
142
143ACPI_STATUS
144AcpiRsCalculateByteStreamLength (
145    RESOURCE                *LinkedList,
146    UINT32                  *SizeNeeded)
147{
148    UINT32                  ByteStreamSizeNeeded = 0;
149    UINT32                  SegmentSize;
150    EXTENDED_IRQ_RESOURCE   *ExIrq = NULL;
151    BOOLEAN                 Done = FALSE;
152
153
154    FUNCTION_TRACE ("RsCalculateByteStreamLength");
155
156
157    while (!Done)
158    {
159
160        /*
161         * Init the variable that will hold the size to add to the
162         *  total.
163         */
164        SegmentSize = 0;
165
166        switch (LinkedList->Id)
167        {
168        case Irq:
169            /*
170             * IRQ Resource
171             */
172            /*
173             * For an IRQ Resource, Byte 3, although optional, will
174             *  always be created - it holds IRQ information.
175             */
176            SegmentSize = 4;
177            break;
178
179        case Dma:
180            /*
181             * DMA Resource
182             */
183            /*
184             * For this resource the size is static
185             */
186            SegmentSize = 3;
187            break;
188
189        case StartDependentFunctions:
190            /*
191             * Start Dependent Functions Resource
192             */
193            /*
194             * For a StartDependentFunctions Resource, Byte 1,
195             * although optional, will always be created.
196             */
197            SegmentSize = 2;
198            break;
199
200        case EndDependentFunctions:
201            /*
202             * End Dependent Functions Resource
203             */
204            /*
205             * For this resource the size is static
206             */
207            SegmentSize = 1;
208            break;
209
210        case Io:
211            /*
212             * IO Port Resource
213             */
214            /*
215             * For this resource the size is static
216             */
217            SegmentSize = 8;
218            break;
219
220        case FixedIo:
221            /*
222             * Fixed IO Port Resource
223             */
224            /*
225             * For this resource the size is static
226             */
227            SegmentSize = 4;
228            break;
229
230        case VendorSpecific:
231            /*
232             * Vendor Defined Resource
233             */
234            /*
235             * For a Vendor Specific resource, if the Length is
236             *  between 1 and 7 it will be created as a Small
237             *  Resource data type, otherwise it is a Large
238             *  Resource data type.
239             */
240            if(LinkedList->Data.VendorSpecific.Length > 7)
241            {
242                SegmentSize = 3;
243            }
244            else
245            {
246                SegmentSize = 1;
247            }
248            SegmentSize +=
249                LinkedList->Data.VendorSpecific.Length;
250            break;
251
252        case EndTag:
253            /*
254             * End Tag
255             */
256            /*
257             * For this resource the size is static
258             */
259            SegmentSize = 2;
260            Done = TRUE;
261            break;
262
263        case Memory24:
264            /*
265             * 24-Bit Memory Resource
266             */
267            /*
268             * For this resource the size is static
269             */
270            SegmentSize = 12;
271            break;
272
273        case Memory32:
274            /*
275             * 32-Bit Memory Range Resource
276             */
277            /*
278             * For this resource the size is static
279             */
280            SegmentSize = 20;
281            break;
282
283        case FixedMemory32:
284            /*
285             * 32-Bit Fixed Memory Resource
286             */
287            /*
288             * For this resource the size is static
289             */
290            SegmentSize = 12;
291            break;
292
293        case Address16:
294            /*
295             * 16-Bit Address Resource
296             */
297            /*
298             * The base size of this byte stream is 16. If a
299             *  Resource Source string is not NULL, add 1 for
300             *  the Index + the length of the null terminated
301             *  string Resource Source + 1 for the null.
302             */
303            SegmentSize = 16;
304
305            if(NULL != LinkedList->Data.Address16.ResourceSource)
306            {
307                SegmentSize += (1 +
308                    LinkedList->Data.Address16.ResourceSourceStringLength);
309            }
310            break;
311
312        case Address32:
313            /*
314             * 32-Bit Address Resource
315             */
316            /*
317             * The base size of this byte stream is 26. If a Resource
318             *  Source string is not NULL, add 1 for the Index + the
319             *  length of the null terminated string Resource Source +
320             *  1 for the null.
321             */
322            SegmentSize = 26;
323
324            if(NULL != LinkedList->Data.Address16.ResourceSource)
325            {
326                SegmentSize += (1 +
327                    LinkedList->Data.Address16.ResourceSourceStringLength);
328            }
329            break;
330
331        case ExtendedIrq:
332            /*
333             * Extended IRQ Resource
334             */
335            /*
336             * The base size of this byte stream is 9. This is for an
337             *  Interrupt table length of 1.  For each additional
338             *  interrupt, add 4.
339             * If a Resource Source string is not NULL, add 1 for the
340             *  Index + the length of the null terminated string
341             *  Resource Source + 1 for the null.
342             */
343            SegmentSize = 9;
344
345            SegmentSize +=
346                (LinkedList->Data.ExtendedIrq.NumberOfInterrupts -
347                 1) * 4;
348
349            if(NULL != ExIrq->ResourceSource)
350            {
351                SegmentSize += (1 +
352                    LinkedList->Data.ExtendedIrq.ResourceSourceStringLength);
353            }
354            break;
355
356        default:
357            /*
358             * If we get here, everything is out of sync,
359             *  so exit with an error
360             */
361            return_ACPI_STATUS (AE_AML_ERROR);
362            break;
363
364        } /* switch (LinkedList->Id) */
365
366        /*
367         * Update the total
368         */
369        ByteStreamSizeNeeded += SegmentSize;
370
371        /*
372         * Point to the next object
373         */
374        LinkedList = (RESOURCE *) ((NATIVE_UINT) LinkedList +
375                     (NATIVE_UINT) LinkedList->Length);
376    }
377
378    /*
379     * This is the data the caller needs
380     */
381    *SizeNeeded = ByteStreamSizeNeeded;
382
383    return_ACPI_STATUS (AE_OK);
384}
385
386
387/*******************************************************************************
388 *
389 * FUNCTION:    AcpiRsCalculateListLength
390 *
391 * PARAMETERS:  ByteStreamBuffer        - Pointer to the resource byte stream
392 *              ByteStreamBufferLength  - Size of ByteStreamBuffer
393 *              SizeNeeded              - UINT32 pointer of the size buffer
394 *                                          needed to properly return the
395 *                                          parsed data
396 *
397 * RETURN:      Status  AE_OK if okay, else a valid ACPI_STATUS code
398 *
399 * DESCRIPTION: Takes the resource byte stream and parses it once, calculating
400 *              the size buffer needed to hold the linked list that conveys
401 *              the resource data.
402 *
403 ******************************************************************************/
404
405ACPI_STATUS
406AcpiRsCalculateListLength (
407    UINT8                   *ByteStreamBuffer,
408    UINT32                  ByteStreamBufferLength,
409    UINT32                  *SizeNeeded)
410{
411    UINT32                  BufferSize = 0;
412    UINT32                  BytesParsed = 0;
413    UINT8                   NumberOfInterrupts = 0;
414    UINT8                   NumberOfChannels = 0;
415    UINT8                   ResourceType;
416    UINT32                  StructureSize;
417    UINT32                  BytesConsumed;
418    UINT8                   *Buffer;
419    UINT8                   Temp8;
420    UINT16                  Temp16;
421    UINT8                   Index;
422    UINT8                   AdditionalBytes;
423
424
425    FUNCTION_TRACE ("RsCalculateListLength");
426
427
428    while (BytesParsed < ByteStreamBufferLength)
429    {
430        /*
431         * Look at the next byte in the stream
432         */
433        ResourceType = *ByteStreamBuffer;
434
435        /*
436         * See if this is a small or large resource
437         */
438        if(ResourceType & 0x80)
439        {
440            /*
441             * Large Resource Type
442             */
443            switch (ResourceType)
444            {
445            case MEMORY_RANGE_24:
446                /*
447                 * 24-Bit Memory Resource
448                 */
449                BytesConsumed = 12;
450
451                StructureSize = sizeof (MEMORY24_RESOURCE) +
452                                RESOURCE_LENGTH_NO_DATA;
453                break;
454
455            case LARGE_VENDOR_DEFINED:
456                /*
457                 * Vendor Defined Resource
458                 */
459                Buffer = ByteStreamBuffer;
460                ++Buffer;
461
462                MOVE_UNALIGNED16_TO_16 (&Temp16, Buffer);
463                BytesConsumed = Temp16 + 3;
464
465                /*
466                 * Ensure a 32-bit boundary for the structure
467                 */
468                Temp16 = (UINT16) ROUND_UP_TO_32BITS (Temp16);
469
470                StructureSize = sizeof (VENDOR_RESOURCE) +
471                                RESOURCE_LENGTH_NO_DATA +
472                                (Temp16 * sizeof (UINT8));
473                break;
474
475            case MEMORY_RANGE_32:
476                /*
477                 * 32-Bit Memory Range Resource
478                 */
479
480                BytesConsumed = 20;
481
482                StructureSize = sizeof (MEMORY32_RESOURCE) +
483                                RESOURCE_LENGTH_NO_DATA;
484                break;
485
486            case FIXED_MEMORY_RANGE_32:
487                /*
488                 * 32-Bit Fixed Memory Resource
489                 */
490                BytesConsumed = 12;
491
492                StructureSize = sizeof(FIXED_MEMORY32_RESOURCE) +
493                                RESOURCE_LENGTH_NO_DATA;
494                break;
495
496            case DWORD_ADDRESS_SPACE:
497                /*
498                 * 32-Bit Address Resource
499                 */
500                Buffer = ByteStreamBuffer;
501
502                ++Buffer;
503                MOVE_UNALIGNED16_TO_16 (&Temp16, Buffer);
504
505                BytesConsumed = Temp16 + 3;
506
507                /*
508                 * Resource Source Index and Resource Source are
509                 *  optional elements.  Check the length of the
510                 *  Bytestream.  If it is greater than 23, that
511                 *  means that an Index exists and is followed by
512                 *  a null termininated string.  Therefore, set
513                 *  the temp variable to the length minus the minimum
514                 *  byte stream length plus the byte for the Index to
515                 *  determine the size of the NULL terminiated string.
516                 */
517                if (23 < Temp16)
518                {
519                    Temp8 = (UINT8) (Temp16 - 24);
520                }
521                else
522                {
523                    Temp8 = 0;
524                }
525
526                /*
527                 * Ensure a 32-bit boundary for the structure
528                 */
529                Temp8 = (UINT8) ROUND_UP_TO_32BITS (Temp8);
530
531                StructureSize = sizeof (ADDRESS32_RESOURCE) +
532                                RESOURCE_LENGTH_NO_DATA +
533                                (Temp8 * sizeof (UINT8));
534                break;
535
536            case WORD_ADDRESS_SPACE:
537                /*
538                 * 16-Bit Address Resource
539                 */
540                Buffer = ByteStreamBuffer;
541
542                ++Buffer;
543                MOVE_UNALIGNED16_TO_16 (&Temp16, Buffer);
544
545                BytesConsumed = Temp16 + 3;
546
547                /*
548                 * Resource Source Index and Resource Source are
549                 *  optional elements.  Check the length of the
550                 *  Bytestream.  If it is greater than 13, that
551                 *  means that an Index exists and is followed by
552                 *  a null termininated string.  Therefore, set
553                 *  the temp variable to the length minus the minimum
554                 *  byte stream length plus the byte for the Index to
555                 *  determine the size of the NULL terminiated string.
556                 */
557                if (13 < Temp16)
558                {
559                    Temp8 = (UINT8) (Temp16 - 14);
560                }
561                else
562                {
563                    Temp8 = 0;
564                }
565
566                /*
567                 * Ensure a 32-bit boundry for the structure
568                 */
569                Temp8 = (UINT8) ROUND_UP_TO_32BITS (Temp8);
570
571                StructureSize = sizeof (ADDRESS16_RESOURCE) +
572                                RESOURCE_LENGTH_NO_DATA +
573                                (Temp8 * sizeof (UINT8));
574                break;
575
576            case EXTENDED_IRQ:
577                /*
578                 * Extended IRQ
579                 */
580                Buffer = ByteStreamBuffer;
581
582                ++Buffer;
583                MOVE_UNALIGNED16_TO_16 (&Temp16, Buffer);
584
585                BytesConsumed = Temp16 + 3;
586
587                /*
588                 * Point past the length field and the
589                 *  Interrupt vector flags to save off the
590                 *  Interrupt table length to the Temp8 variable.
591                 */
592                Buffer += 3;
593                Temp8 = *Buffer;
594
595                /*
596                 * To compensate for multiple interrupt numbers,
597                 *  Add 4 bytes for each additional interrupts
598                 *  greater than 1
599                 */
600                AdditionalBytes = (UINT8) ((Temp8 - 1) * 4);
601
602                /*
603                 * Resource Source Index and Resource Source are
604                 *  optional elements.  Check the length of the
605                 *  Bytestream.  If it is greater than 9, that
606                 *  means that an Index exists and is followed by
607                 *  a null termininated string.  Therefore, set
608                 *  the temp variable to the length minus the minimum
609                 *  byte stream length plus the byte for the Index to
610                 *  determine the size of the NULL terminiated string.
611                 */
612                if (9 + AdditionalBytes < Temp16)
613                {
614                    Temp8 = (UINT8) (Temp16 - (9 + AdditionalBytes));
615                }
616
617                else
618                {
619                    Temp8 = 0;
620                }
621
622                /*
623                 * Ensure a 32-bit boundry for the structure
624                 */
625                Temp8 = (UINT8) ROUND_UP_TO_32BITS (Temp8);
626
627                StructureSize = sizeof (EXTENDED_IRQ_RESOURCE) +
628                                RESOURCE_LENGTH_NO_DATA +
629                                (AdditionalBytes * sizeof (UINT8)) +
630                                (Temp8 * sizeof (UINT8));
631
632                break;
633
634/* TBD: [Future] 64-bit not currently supported */
635/*
636            case 0x8A:
637                break;
638*/
639
640            default:
641                /*
642                 * If we get here, everything is out of sync,
643                 *  so exit with an error
644                 */
645                return_ACPI_STATUS (AE_AML_ERROR);
646                break;
647            }
648        }
649
650        else
651        {
652            /*
653             * Small Resource Type
654             *  Only bits 7:3 are valid
655             */
656            ResourceType >>= 3;
657
658            switch (ResourceType)
659            {
660            case IRQ_FORMAT:
661                /*
662                 * IRQ Resource
663                 */
664                /*
665                 * Determine if it there are two or three
666                 *  trailing bytes
667                 */
668                Buffer = ByteStreamBuffer;
669                Temp8 = *Buffer;
670
671                if(Temp8 & 0x01)
672                {
673                    BytesConsumed = 4;
674                }
675
676                else
677                {
678                    BytesConsumed = 3;
679                }
680
681                /*
682                 * Point past the descriptor
683                 */
684                ++Buffer;
685
686                /*
687                 * Look at the number of bits set
688                 */
689                MOVE_UNALIGNED16_TO_16 (&Temp16, Buffer);
690
691                for (Index = 0; Index < 16; Index++)
692                {
693                    if (Temp16 & 0x1)
694                    {
695                        ++NumberOfInterrupts;
696                    }
697
698                    Temp16 >>= 1;
699                }
700
701                StructureSize = sizeof (IO_RESOURCE) +
702                                RESOURCE_LENGTH_NO_DATA +
703                                (NumberOfInterrupts * sizeof (UINT32));
704                break;
705
706
707            case DMA_FORMAT:
708
709                /*
710                 * DMA Resource
711                 */
712                Buffer = ByteStreamBuffer;
713
714                BytesConsumed = 3;
715
716                /*
717                 * Point past the descriptor
718                 */
719                ++Buffer;
720
721                /*
722                 * Look at the number of bits set
723                 */
724                Temp8 = *Buffer;
725
726                for(Index = 0; Index < 8; Index++)
727                {
728                    if(Temp8 & 0x1)
729                    {
730                        ++NumberOfChannels;
731                    }
732
733                    Temp8 >>= 1;
734                }
735
736                StructureSize = sizeof (DMA_RESOURCE) +
737                                RESOURCE_LENGTH_NO_DATA +
738                                (NumberOfChannels * sizeof (UINT32));
739                break;
740
741
742            case START_DEPENDENT_TAG:
743
744                /*
745                 * Start Dependent Functions Resource
746                 */
747                /*
748                 * Determine if it there are two or three trailing bytes
749                 */
750                Buffer = ByteStreamBuffer;
751                Temp8 = *Buffer;
752
753                if(Temp8 & 0x01)
754                {
755                    BytesConsumed = 2;
756                }
757                else
758                {
759                    BytesConsumed = 1;
760                }
761
762
763                StructureSize =
764                        sizeof (START_DEPENDENT_FUNCTIONS_RESOURCE) +
765                        RESOURCE_LENGTH_NO_DATA;
766                break;
767
768
769            case END_DEPENDENT_TAG:
770
771                /*
772                 * End Dependent Functions Resource
773                 */
774                BytesConsumed = 1;
775                StructureSize = RESOURCE_LENGTH;
776                break;
777
778
779            case IO_PORT_DESCRIPTOR:
780                /*
781                 * IO Port Resource
782                 */
783                BytesConsumed = 8;
784                StructureSize = sizeof (IO_RESOURCE) +
785                                RESOURCE_LENGTH_NO_DATA;
786                break;
787
788
789            case FIXED_LOCATION_IO_DESCRIPTOR:
790
791                /*
792                 * Fixed IO Port Resource
793                 */
794                BytesConsumed = 4;
795                StructureSize = sizeof (FIXED_IO_RESOURCE) +
796                                RESOURCE_LENGTH_NO_DATA;
797                break;
798
799
800            case SMALL_VENDOR_DEFINED:
801
802                /*
803                 * Vendor Specific Resource
804                 */
805                Buffer = ByteStreamBuffer;
806
807                Temp8 = *Buffer;
808                Temp8 = (UINT8) (Temp8 & 0x7);
809                BytesConsumed = Temp8 + 1;
810
811                /*
812                 * Ensure a 32-bit boundry for the structure
813                 */
814                Temp8 = (UINT8) ROUND_UP_TO_32BITS (Temp8);
815                StructureSize = sizeof (VENDOR_RESOURCE) +
816                                RESOURCE_LENGTH_NO_DATA +
817                                (Temp8 * sizeof (UINT8));
818                break;
819
820
821            case END_TAG:
822
823                /*
824                 * End Tag
825                 */
826                BytesConsumed = 2;
827                StructureSize = RESOURCE_LENGTH;
828                break;
829
830
831            default:
832                /*
833                 * If we get here, everything is out of sync,
834                 *  so exit with an error
835                 */
836                return_ACPI_STATUS (AE_AML_ERROR);
837                break;
838
839            } /* switch */
840
841        }  /* if(ResourceType & 0x80) */
842
843        /*
844         * Update the return value and counter
845         */
846        BufferSize += StructureSize;
847        BytesParsed += BytesConsumed;
848
849        /*
850         * Set the byte stream to point to the next resource
851         */
852        ByteStreamBuffer += BytesConsumed;
853
854    }
855
856    /*
857     * This is the data the caller needs
858     */
859    *SizeNeeded = BufferSize;
860
861    return_ACPI_STATUS (AE_OK);
862}
863
864
865/*******************************************************************************
866 *
867 * FUNCTION:    AcpiRsCalculatePciRoutingTableLength
868 *
869 * PARAMETERS:  PackageObject           - Pointer to the package object
870 *              BufferSizeNeeded        - UINT32 pointer of the size buffer
871 *                                          needed to properly return the
872 *                                          parsed data
873 *
874 * RETURN:      Status  AE_OK
875 *
876 * DESCRIPTION: Given a package representing a PCI routing table, this
877 *                calculates the size of the corresponding linked list of
878 *                descriptions.
879 *
880 ******************************************************************************/
881
882ACPI_STATUS
883AcpiRsCalculatePciRoutingTableLength (
884    ACPI_OPERAND_OBJECT     *PackageObject,
885    UINT32                  *BufferSizeNeeded)
886{
887    UINT32                  NumberOfElements;
888    UINT32                  TempSizeNeeded = 0;
889    ACPI_OPERAND_OBJECT     **TopObjectList;
890    UINT32                  Index;
891    ACPI_OPERAND_OBJECT     *PackageElement;
892    ACPI_OPERAND_OBJECT     **SubObjectList;
893    BOOLEAN                 NameFound;
894    UINT32                  TableIndex;
895
896
897    FUNCTION_TRACE ("AcpiRsCalculatePciRoutingTableLength");
898
899
900    NumberOfElements = PackageObject->Package.Count;
901
902    /*
903     * Calculate the size of the return buffer.
904     * The base size is the number of elements * the sizes of the
905     * structures.  Additional space for the strings is added below.
906     * The minus one is to subtract the size of the UINT8 Source[1]
907     * member because it is added below.
908     *
909     * NOTE: The NumberOfElements is incremented by one to add an end
910     * table structure that is essentially a structure of zeros.
911     */
912
913    /*
914     * But each PRT_ENTRY structure has a pointer to a string and
915     * the size of that string must be found.
916     */
917    TopObjectList = PackageObject->Package.Elements;
918
919    for (Index = 0; Index < NumberOfElements; Index++)
920    {
921        /*
922         * Dereference the sub-package
923         */
924        PackageElement = *TopObjectList;
925
926        /*
927         * The SubObjectList will now point to an array of the
928         * four IRQ elements: Address, Pin, Source and SourceIndex
929         */
930        SubObjectList = PackageElement->Package.Elements;
931
932        /*
933         * Scan the IrqTableElements for the Source Name String
934         */
935        NameFound = FALSE;
936
937        for (TableIndex = 0; TableIndex < 4 && !NameFound; TableIndex++)
938        {
939            if (ACPI_TYPE_STRING == (*SubObjectList)->Common.Type)
940            {
941                NameFound = TRUE;
942            }
943
944            else
945            {
946                /*
947                 * Look at the next element
948                 */
949                SubObjectList++;
950            }
951        }
952
953        TempSizeNeeded += (sizeof (PCI_ROUTING_TABLE) - 1);
954
955        /*
956         * Was a String type found?
957         */
958        if (TRUE == NameFound)
959        {
960            /*
961             * The length String.Length field includes the
962             * terminating NULL
963             */
964            TempSizeNeeded += (*SubObjectList)->String.Length;
965        }
966
967        else
968        {
969            /*
970             * If no name was found, then this is a NULL, which is
971             *  translated as a UINT32 zero.
972             */
973            TempSizeNeeded += sizeof(UINT32);
974        }
975
976
977        /* Round up the size since each element must be aligned */
978
979        TempSizeNeeded = ROUND_UP_TO_64BITS (TempSizeNeeded);
980
981        /*
982         * Point to the next ACPI_OPERAND_OBJECT
983         */
984        TopObjectList++;
985    }
986
987
988    *BufferSizeNeeded = TempSizeNeeded + sizeof (PCI_ROUTING_TABLE);
989
990    return_ACPI_STATUS (AE_OK);
991}
992
993