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