Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/contrib/dev/acpica/components/resources/rscalc.c
48406 views
1
/*******************************************************************************
2
*
3
* Module Name: rscalc - Calculate stream and list lengths
4
*
5
******************************************************************************/
6
7
/******************************************************************************
8
*
9
* 1. Copyright Notice
10
*
11
* Some or all of this work - Copyright (c) 1999 - 2025, Intel Corp.
12
* All rights reserved.
13
*
14
* 2. License
15
*
16
* 2.1. This is your license from Intel Corp. under its intellectual property
17
* rights. You may have additional license terms from the party that provided
18
* you this software, covering your right to use that party's intellectual
19
* property rights.
20
*
21
* 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22
* copy of the source code appearing in this file ("Covered Code") an
23
* irrevocable, perpetual, worldwide license under Intel's copyrights in the
24
* base code distributed originally by Intel ("Original Intel Code") to copy,
25
* make derivatives, distribute, use and display any portion of the Covered
26
* Code in any form, with the right to sublicense such rights; and
27
*
28
* 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29
* license (with the right to sublicense), under only those claims of Intel
30
* patents that are infringed by the Original Intel Code, to make, use, sell,
31
* offer to sell, and import the Covered Code and derivative works thereof
32
* solely to the minimum extent necessary to exercise the above copyright
33
* license, and in no event shall the patent license extend to any additions
34
* to or modifications of the Original Intel Code. No other license or right
35
* is granted directly or by implication, estoppel or otherwise;
36
*
37
* The above copyright and patent license is granted only if the following
38
* conditions are met:
39
*
40
* 3. Conditions
41
*
42
* 3.1. Redistribution of Source with Rights to Further Distribute Source.
43
* Redistribution of source code of any substantial portion of the Covered
44
* Code or modification with rights to further distribute source must include
45
* the above Copyright Notice, the above License, this list of Conditions,
46
* and the following Disclaimer and Export Compliance provision. In addition,
47
* Licensee must cause all Covered Code to which Licensee contributes to
48
* contain a file documenting the changes Licensee made to create that Covered
49
* Code and the date of any change. Licensee must include in that file the
50
* documentation of any changes made by any predecessor Licensee. Licensee
51
* must include a prominent statement that the modification is derived,
52
* directly or indirectly, from Original Intel Code.
53
*
54
* 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55
* Redistribution of source code of any substantial portion of the Covered
56
* Code or modification without rights to further distribute source must
57
* include the following Disclaimer and Export Compliance provision in the
58
* documentation and/or other materials provided with distribution. In
59
* addition, Licensee may not authorize further sublicense of source of any
60
* portion of the Covered Code, and must include terms to the effect that the
61
* license from Licensee to its licensee is limited to the intellectual
62
* property embodied in the software Licensee provides to its licensee, and
63
* not to intellectual property embodied in modifications its licensee may
64
* make.
65
*
66
* 3.3. Redistribution of Executable. Redistribution in executable form of any
67
* substantial portion of the Covered Code or modification must reproduce the
68
* above Copyright Notice, and the following Disclaimer and Export Compliance
69
* provision in the documentation and/or other materials provided with the
70
* distribution.
71
*
72
* 3.4. Intel retains all right, title, and interest in and to the Original
73
* Intel Code.
74
*
75
* 3.5. Neither the name Intel nor any other trademark owned or controlled by
76
* Intel shall be used in advertising or otherwise to promote the sale, use or
77
* other dealings in products derived from or relating to the Covered Code
78
* without prior written authorization from Intel.
79
*
80
* 4. Disclaimer and Export Compliance
81
*
82
* 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83
* HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84
* IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85
* INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86
* UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87
* IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88
* PARTICULAR PURPOSE.
89
*
90
* 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91
* OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92
* COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93
* SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94
* CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95
* HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96
* SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97
* LIMITED REMEDY.
98
*
99
* 4.3. Licensee shall not export, either directly or indirectly, any of this
100
* software or system incorporating such software without first obtaining any
101
* required license or other approval from the U. S. Department of Commerce or
102
* any other agency or department of the United States Government. In the
103
* event Licensee exports any such software from the United States or
104
* re-exports any such software from a foreign destination, Licensee shall
105
* ensure that the distribution and export/re-export of the software is in
106
* compliance with all laws, regulations, orders, or other restrictions of the
107
* U.S. Export Administration Regulations. Licensee agrees that neither it nor
108
* any of its subsidiaries will export/re-export any technical data, process,
109
* software, or service, directly or indirectly, to any country for which the
110
* United States government or any agency thereof requires an export license,
111
* other governmental approval, or letter of assurance, without first obtaining
112
* such license, approval or letter.
113
*
114
*****************************************************************************
115
*
116
* Alternatively, you may choose to be licensed under the terms of the
117
* following license:
118
*
119
* Redistribution and use in source and binary forms, with or without
120
* modification, are permitted provided that the following conditions
121
* are met:
122
* 1. Redistributions of source code must retain the above copyright
123
* notice, this list of conditions, and the following disclaimer,
124
* without modification.
125
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
126
* substantially similar to the "NO WARRANTY" disclaimer below
127
* ("Disclaimer") and any redistribution must be conditioned upon
128
* including a substantially similar Disclaimer requirement for further
129
* binary redistribution.
130
* 3. Neither the names of the above-listed copyright holders nor the names
131
* of any contributors may be used to endorse or promote products derived
132
* from this software without specific prior written permission.
133
*
134
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145
*
146
* Alternatively, you may choose to be licensed under the terms of the
147
* GNU General Public License ("GPL") version 2 as published by the Free
148
* Software Foundation.
149
*
150
*****************************************************************************/
151
152
#include <contrib/dev/acpica/include/acpi.h>
153
#include <contrib/dev/acpica/include/accommon.h>
154
#include <contrib/dev/acpica/include/acresrc.h>
155
#include <contrib/dev/acpica/include/acnamesp.h>
156
157
158
#define _COMPONENT ACPI_RESOURCES
159
ACPI_MODULE_NAME ("rscalc")
160
161
162
/* Local prototypes */
163
164
static UINT8
165
AcpiRsCountSetBits (
166
UINT16 BitField);
167
168
static ACPI_RS_LENGTH
169
AcpiRsStructOptionLength (
170
ACPI_RESOURCE_SOURCE *ResourceSource);
171
172
static UINT32
173
AcpiRsStreamOptionLength (
174
UINT32 ResourceLength,
175
UINT32 MinimumTotalLength);
176
177
178
/*******************************************************************************
179
*
180
* FUNCTION: AcpiRsCountSetBits
181
*
182
* PARAMETERS: BitField - Field in which to count bits
183
*
184
* RETURN: Number of bits set within the field
185
*
186
* DESCRIPTION: Count the number of bits set in a resource field. Used for
187
* (Short descriptor) interrupt and DMA lists.
188
*
189
******************************************************************************/
190
191
static UINT8
192
AcpiRsCountSetBits (
193
UINT16 BitField)
194
{
195
UINT8 BitsSet;
196
197
198
ACPI_FUNCTION_ENTRY ();
199
200
201
for (BitsSet = 0; BitField; BitsSet++)
202
{
203
/* Zero the least significant bit that is set */
204
205
BitField &= (UINT16) (BitField - 1);
206
}
207
208
return (BitsSet);
209
}
210
211
212
/*******************************************************************************
213
*
214
* FUNCTION: AcpiRsStructOptionLength
215
*
216
* PARAMETERS: ResourceSource - Pointer to optional descriptor field
217
*
218
* RETURN: Status
219
*
220
* DESCRIPTION: Common code to handle optional ResourceSourceIndex and
221
* ResourceSource fields in some Large descriptors. Used during
222
* list-to-stream conversion
223
*
224
******************************************************************************/
225
226
static ACPI_RS_LENGTH
227
AcpiRsStructOptionLength (
228
ACPI_RESOURCE_SOURCE *ResourceSource)
229
{
230
ACPI_FUNCTION_ENTRY ();
231
232
233
/*
234
* If the ResourceSource string is valid, return the size of the string
235
* (StringLength includes the NULL terminator) plus the size of the
236
* ResourceSourceIndex (1).
237
*/
238
if (ResourceSource->StringPtr)
239
{
240
return ((ACPI_RS_LENGTH) (ResourceSource->StringLength + 1));
241
}
242
243
return (0);
244
}
245
246
247
/*******************************************************************************
248
*
249
* FUNCTION: AcpiRsStreamOptionLength
250
*
251
* PARAMETERS: ResourceLength - Length from the resource header
252
* MinimumTotalLength - Minimum length of this resource, before
253
* any optional fields. Includes header size
254
*
255
* RETURN: Length of optional string (0 if no string present)
256
*
257
* DESCRIPTION: Common code to handle optional ResourceSourceIndex and
258
* ResourceSource fields in some Large descriptors. Used during
259
* stream-to-list conversion
260
*
261
******************************************************************************/
262
263
static UINT32
264
AcpiRsStreamOptionLength (
265
UINT32 ResourceLength,
266
UINT32 MinimumAmlResourceLength)
267
{
268
UINT32 StringLength = 0;
269
270
271
ACPI_FUNCTION_ENTRY ();
272
273
274
/*
275
* The ResourceSourceIndex and ResourceSource are optional elements of
276
* some Large-type resource descriptors.
277
*/
278
279
/*
280
* If the length of the actual resource descriptor is greater than the
281
* ACPI spec-defined minimum length, it means that a ResourceSourceIndex
282
* exists and is followed by a (required) null terminated string. The
283
* string length (including the null terminator) is the resource length
284
* minus the minimum length, minus one byte for the ResourceSourceIndex
285
* itself.
286
*/
287
if (ResourceLength > MinimumAmlResourceLength)
288
{
289
/* Compute the length of the optional string */
290
291
StringLength = ResourceLength - MinimumAmlResourceLength - 1;
292
}
293
294
/*
295
* Round the length up to a multiple of the native word in order to
296
* guarantee that the entire resource descriptor is native word aligned
297
*/
298
return ((UINT32) ACPI_ROUND_UP_TO_NATIVE_WORD (StringLength));
299
}
300
301
302
/*******************************************************************************
303
*
304
* FUNCTION: AcpiRsGetAmlLength
305
*
306
* PARAMETERS: Resource - Pointer to the resource linked list
307
* ResourceListSize - Size of the resource linked list
308
* SizeNeeded - Where the required size is returned
309
*
310
* RETURN: Status
311
*
312
* DESCRIPTION: Takes a linked list of internal resource descriptors and
313
* calculates the size buffer needed to hold the corresponding
314
* external resource byte stream.
315
*
316
******************************************************************************/
317
318
ACPI_STATUS
319
AcpiRsGetAmlLength (
320
ACPI_RESOURCE *Resource,
321
ACPI_SIZE ResourceListSize,
322
ACPI_SIZE *SizeNeeded)
323
{
324
ACPI_SIZE AmlSizeNeeded = 0;
325
ACPI_RESOURCE *ResourceEnd;
326
ACPI_RS_LENGTH TotalSize;
327
328
329
ACPI_FUNCTION_TRACE (RsGetAmlLength);
330
331
332
/* Traverse entire list of internal resource descriptors */
333
334
ResourceEnd = ACPI_ADD_PTR (ACPI_RESOURCE, Resource, ResourceListSize);
335
while (Resource < ResourceEnd)
336
{
337
/* Validate the descriptor type */
338
339
if (Resource->Type > ACPI_RESOURCE_TYPE_MAX)
340
{
341
return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
342
}
343
344
/* Sanity check the length. It must not be zero, or we loop forever */
345
346
if (!Resource->Length)
347
{
348
return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH);
349
}
350
351
/* Get the base size of the (external stream) resource descriptor */
352
353
TotalSize = AcpiGbl_AmlResourceSizes [Resource->Type];
354
355
/*
356
* Augment the base size for descriptors with optional and/or
357
* variable-length fields
358
*/
359
switch (Resource->Type)
360
{
361
case ACPI_RESOURCE_TYPE_IRQ:
362
363
/* Length can be 3 or 2 */
364
365
if (Resource->Data.Irq.DescriptorLength == 2)
366
{
367
TotalSize--;
368
}
369
break;
370
371
372
case ACPI_RESOURCE_TYPE_START_DEPENDENT:
373
374
/* Length can be 1 or 0 */
375
376
if (Resource->Data.Irq.DescriptorLength == 0)
377
{
378
TotalSize--;
379
}
380
break;
381
382
383
case ACPI_RESOURCE_TYPE_VENDOR:
384
/*
385
* Vendor Defined Resource:
386
* For a Vendor Specific resource, if the Length is between 1 and 7
387
* it will be created as a Small Resource data type, otherwise it
388
* is a Large Resource data type.
389
*/
390
if (Resource->Data.Vendor.ByteLength > 7)
391
{
392
/* Base size of a Large resource descriptor */
393
394
TotalSize = sizeof (AML_RESOURCE_LARGE_HEADER);
395
}
396
397
/* Add the size of the vendor-specific data */
398
399
TotalSize = (ACPI_RS_LENGTH)
400
(TotalSize + Resource->Data.Vendor.ByteLength);
401
break;
402
403
404
case ACPI_RESOURCE_TYPE_END_TAG:
405
/*
406
* End Tag:
407
* We are done -- return the accumulated total size.
408
*/
409
*SizeNeeded = AmlSizeNeeded + TotalSize;
410
411
/* Normal exit */
412
413
return_ACPI_STATUS (AE_OK);
414
415
416
case ACPI_RESOURCE_TYPE_ADDRESS16:
417
/*
418
* 16-Bit Address Resource:
419
* Add the size of the optional ResourceSource info
420
*/
421
TotalSize = (ACPI_RS_LENGTH) (TotalSize +
422
AcpiRsStructOptionLength (
423
&Resource->Data.Address16.ResourceSource));
424
break;
425
426
427
case ACPI_RESOURCE_TYPE_ADDRESS32:
428
/*
429
* 32-Bit Address Resource:
430
* Add the size of the optional ResourceSource info
431
*/
432
TotalSize = (ACPI_RS_LENGTH) (TotalSize +
433
AcpiRsStructOptionLength (
434
&Resource->Data.Address32.ResourceSource));
435
break;
436
437
438
case ACPI_RESOURCE_TYPE_ADDRESS64:
439
/*
440
* 64-Bit Address Resource:
441
* Add the size of the optional ResourceSource info
442
*/
443
TotalSize = (ACPI_RS_LENGTH) (TotalSize +
444
AcpiRsStructOptionLength (
445
&Resource->Data.Address64.ResourceSource));
446
break;
447
448
449
case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
450
/*
451
* Extended IRQ Resource:
452
* Add the size of each additional optional interrupt beyond the
453
* required 1 (4 bytes for each UINT32 interrupt number)
454
*/
455
TotalSize = (ACPI_RS_LENGTH) (TotalSize +
456
((Resource->Data.ExtendedIrq.InterruptCount - 1) * 4) +
457
458
/* Add the size of the optional ResourceSource info */
459
460
AcpiRsStructOptionLength (
461
&Resource->Data.ExtendedIrq.ResourceSource));
462
break;
463
464
465
case ACPI_RESOURCE_TYPE_GPIO:
466
467
TotalSize = (ACPI_RS_LENGTH) (TotalSize +
468
(Resource->Data.Gpio.PinTableLength * 2) +
469
Resource->Data.Gpio.ResourceSource.StringLength +
470
Resource->Data.Gpio.VendorLength);
471
472
break;
473
474
case ACPI_RESOURCE_TYPE_PIN_FUNCTION:
475
476
TotalSize = (ACPI_RS_LENGTH) (TotalSize +
477
(Resource->Data.PinFunction.PinTableLength * 2) +
478
Resource->Data.PinFunction.ResourceSource.StringLength +
479
Resource->Data.PinFunction.VendorLength);
480
481
break;
482
483
case ACPI_RESOURCE_TYPE_CLOCK_INPUT:
484
485
TotalSize = (ACPI_RS_LENGTH) (TotalSize +
486
Resource->Data.ClockInput.ResourceSource.StringLength);
487
488
break;
489
490
491
case ACPI_RESOURCE_TYPE_SERIAL_BUS:
492
493
TotalSize = AcpiGbl_AmlResourceSerialBusSizes [
494
Resource->Data.CommonSerialBus.Type];
495
496
TotalSize = (ACPI_RS_LENGTH) (TotalSize +
497
Resource->Data.I2cSerialBus.ResourceSource.StringLength +
498
Resource->Data.I2cSerialBus.VendorLength);
499
500
break;
501
502
case ACPI_RESOURCE_TYPE_PIN_CONFIG:
503
504
TotalSize = (ACPI_RS_LENGTH) (TotalSize +
505
(Resource->Data.PinConfig.PinTableLength * 2) +
506
Resource->Data.PinConfig.ResourceSource.StringLength +
507
Resource->Data.PinConfig.VendorLength);
508
509
break;
510
511
case ACPI_RESOURCE_TYPE_PIN_GROUP:
512
513
TotalSize = (ACPI_RS_LENGTH) (TotalSize +
514
(Resource->Data.PinGroup.PinTableLength * 2) +
515
Resource->Data.PinGroup.ResourceLabel.StringLength +
516
Resource->Data.PinGroup.VendorLength);
517
518
break;
519
520
case ACPI_RESOURCE_TYPE_PIN_GROUP_FUNCTION:
521
522
TotalSize = (ACPI_RS_LENGTH) (TotalSize +
523
Resource->Data.PinGroupFunction.ResourceSource.StringLength +
524
Resource->Data.PinGroupFunction.ResourceSourceLabel.StringLength +
525
Resource->Data.PinGroupFunction.VendorLength);
526
527
break;
528
529
case ACPI_RESOURCE_TYPE_PIN_GROUP_CONFIG:
530
531
TotalSize = (ACPI_RS_LENGTH) (TotalSize +
532
Resource->Data.PinGroupConfig.ResourceSource.StringLength +
533
Resource->Data.PinGroupConfig.ResourceSourceLabel.StringLength +
534
Resource->Data.PinGroupConfig.VendorLength);
535
536
break;
537
538
default:
539
540
break;
541
}
542
543
/* Update the total */
544
545
AmlSizeNeeded += TotalSize;
546
547
/* Point to the next object */
548
549
Resource = ACPI_ADD_PTR (ACPI_RESOURCE, Resource, Resource->Length);
550
}
551
552
/* Did not find an EndTag resource descriptor */
553
554
return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG);
555
}
556
557
558
/*******************************************************************************
559
*
560
* FUNCTION: AcpiRsGetListLength
561
*
562
* PARAMETERS: AmlBuffer - Pointer to the resource byte stream
563
* AmlBufferLength - Size of AmlBuffer
564
* SizeNeeded - Where the size needed is returned
565
*
566
* RETURN: Status
567
*
568
* DESCRIPTION: Takes an external resource byte stream and calculates the size
569
* buffer needed to hold the corresponding internal resource
570
* descriptor linked list.
571
*
572
******************************************************************************/
573
574
ACPI_STATUS
575
AcpiRsGetListLength (
576
UINT8 *AmlBuffer,
577
UINT32 AmlBufferLength,
578
ACPI_SIZE *SizeNeeded)
579
{
580
ACPI_STATUS Status;
581
UINT8 *EndAml;
582
UINT8 *Buffer;
583
UINT32 BufferSize;
584
UINT16 Temp16;
585
UINT16 ResourceLength;
586
UINT32 ExtraStructBytes;
587
UINT8 ResourceIndex;
588
UINT8 MinimumAmlResourceLength;
589
AML_RESOURCE *AmlResource;
590
591
592
ACPI_FUNCTION_TRACE (RsGetListLength);
593
594
595
*SizeNeeded = ACPI_RS_SIZE_MIN; /* Minimum size is one EndTag */
596
EndAml = AmlBuffer + AmlBufferLength;
597
598
/* Walk the list of AML resource descriptors */
599
600
while (AmlBuffer < EndAml)
601
{
602
/* Validate the Resource Type and Resource Length */
603
604
Status = AcpiUtValidateResource (NULL, AmlBuffer, &ResourceIndex);
605
if (ACPI_FAILURE (Status))
606
{
607
/*
608
* Exit on failure. Cannot continue because the descriptor length
609
* may be bogus also.
610
*/
611
return_ACPI_STATUS (Status);
612
}
613
614
AmlResource = (void *) AmlBuffer;
615
616
/* Get the resource length and base (minimum) AML size */
617
618
ResourceLength = AcpiUtGetResourceLength (AmlBuffer);
619
MinimumAmlResourceLength = AcpiGbl_ResourceAmlSizes[ResourceIndex];
620
621
/*
622
* Augment the size for descriptors with optional
623
* and/or variable length fields
624
*/
625
ExtraStructBytes = 0;
626
Buffer = AmlBuffer + AcpiUtGetResourceHeaderLength (AmlBuffer);
627
628
switch (AcpiUtGetResourceType (AmlBuffer))
629
{
630
case ACPI_RESOURCE_NAME_IRQ:
631
/*
632
* IRQ Resource:
633
* Get the number of bits set in the 16-bit IRQ mask
634
*/
635
ACPI_MOVE_16_TO_16 (&Temp16, Buffer);
636
ExtraStructBytes = AcpiRsCountSetBits (Temp16);
637
break;
638
639
640
case ACPI_RESOURCE_NAME_DMA:
641
/*
642
* DMA Resource:
643
* Get the number of bits set in the 8-bit DMA mask
644
*/
645
ExtraStructBytes = AcpiRsCountSetBits (*Buffer);
646
break;
647
648
649
case ACPI_RESOURCE_NAME_VENDOR_SMALL:
650
case ACPI_RESOURCE_NAME_VENDOR_LARGE:
651
/*
652
* Vendor Resource:
653
* Get the number of vendor data bytes
654
*/
655
ExtraStructBytes = ResourceLength;
656
657
/*
658
* There is already one byte included in the minimum
659
* descriptor size. If there are extra struct bytes,
660
* subtract one from the count.
661
*/
662
if (ExtraStructBytes)
663
{
664
ExtraStructBytes--;
665
}
666
break;
667
668
669
case ACPI_RESOURCE_NAME_END_TAG:
670
/*
671
* End Tag: This is the normal exit
672
*/
673
return_ACPI_STATUS (AE_OK);
674
675
676
case ACPI_RESOURCE_NAME_ADDRESS32:
677
case ACPI_RESOURCE_NAME_ADDRESS16:
678
case ACPI_RESOURCE_NAME_ADDRESS64:
679
/*
680
* Address Resource:
681
* Add the size of the optional ResourceSource
682
*/
683
ExtraStructBytes = AcpiRsStreamOptionLength (
684
ResourceLength, MinimumAmlResourceLength);
685
break;
686
687
688
case ACPI_RESOURCE_NAME_EXTENDED_IRQ:
689
/*
690
* Extended IRQ Resource:
691
* Using the InterruptTableLength, add 4 bytes for each additional
692
* interrupt. Note: at least one interrupt is required and is
693
* included in the minimum descriptor size (reason for the -1)
694
*/
695
ExtraStructBytes = (Buffer[1] - 1) * sizeof (UINT32);
696
697
/* Add the size of the optional ResourceSource */
698
699
ExtraStructBytes += AcpiRsStreamOptionLength (
700
ResourceLength - ExtraStructBytes, MinimumAmlResourceLength);
701
break;
702
703
case ACPI_RESOURCE_NAME_GPIO:
704
705
/* Vendor data is optional */
706
707
if (AmlResource->Gpio.VendorLength)
708
{
709
ExtraStructBytes +=
710
AmlResource->Gpio.VendorOffset -
711
AmlResource->Gpio.PinTableOffset +
712
AmlResource->Gpio.VendorLength;
713
}
714
else
715
{
716
ExtraStructBytes +=
717
AmlResource->LargeHeader.ResourceLength +
718
sizeof (AML_RESOURCE_LARGE_HEADER) -
719
AmlResource->Gpio.PinTableOffset;
720
}
721
break;
722
723
case ACPI_RESOURCE_NAME_PIN_FUNCTION:
724
725
/* Vendor data is optional */
726
727
if (AmlResource->PinFunction.VendorLength)
728
{
729
ExtraStructBytes +=
730
AmlResource->PinFunction.VendorOffset -
731
AmlResource->PinFunction.PinTableOffset +
732
AmlResource->PinFunction.VendorLength;
733
}
734
else
735
{
736
ExtraStructBytes +=
737
AmlResource->LargeHeader.ResourceLength +
738
sizeof (AML_RESOURCE_LARGE_HEADER) -
739
AmlResource->PinFunction.PinTableOffset;
740
}
741
break;
742
743
case ACPI_RESOURCE_NAME_SERIAL_BUS: {
744
745
MinimumAmlResourceLength = AcpiGbl_ResourceAmlSerialBusSizes[
746
AmlResource->CommonSerialBus.Type];
747
ExtraStructBytes +=
748
AmlResource->CommonSerialBus.ResourceLength -
749
MinimumAmlResourceLength;
750
break;
751
}
752
753
case ACPI_RESOURCE_NAME_PIN_CONFIG:
754
755
/* Vendor data is optional */
756
757
if (AmlResource->PinConfig.VendorLength)
758
{
759
ExtraStructBytes +=
760
AmlResource->PinConfig.VendorOffset -
761
AmlResource->PinConfig.PinTableOffset +
762
AmlResource->PinConfig.VendorLength;
763
}
764
else
765
{
766
ExtraStructBytes +=
767
AmlResource->LargeHeader.ResourceLength +
768
sizeof (AML_RESOURCE_LARGE_HEADER) -
769
AmlResource->PinConfig.PinTableOffset;
770
}
771
break;
772
773
case ACPI_RESOURCE_NAME_PIN_GROUP:
774
775
ExtraStructBytes +=
776
AmlResource->PinGroup.VendorOffset -
777
AmlResource->PinGroup.PinTableOffset +
778
AmlResource->PinGroup.VendorLength;
779
780
break;
781
782
case ACPI_RESOURCE_NAME_PIN_GROUP_FUNCTION:
783
784
ExtraStructBytes +=
785
AmlResource->PinGroupFunction.VendorOffset -
786
AmlResource->PinGroupFunction.ResSourceOffset +
787
AmlResource->PinGroupFunction.VendorLength;
788
789
break;
790
791
case ACPI_RESOURCE_NAME_PIN_GROUP_CONFIG:
792
793
ExtraStructBytes +=
794
AmlResource->PinGroupConfig.VendorOffset -
795
AmlResource->PinGroupConfig.ResSourceOffset +
796
AmlResource->PinGroupConfig.VendorLength;
797
798
break;
799
800
case ACPI_RESOURCE_NAME_CLOCK_INPUT:
801
ExtraStructBytes = AcpiRsStreamOptionLength (
802
ResourceLength, MinimumAmlResourceLength);
803
804
break;
805
806
default:
807
808
break;
809
}
810
811
/*
812
* Update the required buffer size for the internal descriptor structs
813
*
814
* Important: Round the size up for the appropriate alignment. This
815
* is a requirement on IA64.
816
*/
817
if (AcpiUtGetResourceType (AmlBuffer) ==
818
ACPI_RESOURCE_NAME_SERIAL_BUS)
819
{
820
BufferSize = AcpiGbl_ResourceStructSerialBusSizes[
821
AmlResource->CommonSerialBus.Type] + ExtraStructBytes;
822
}
823
else
824
{
825
BufferSize = AcpiGbl_ResourceStructSizes[ResourceIndex] +
826
ExtraStructBytes;
827
}
828
829
BufferSize = (UINT32) ACPI_ROUND_UP_TO_NATIVE_WORD (BufferSize);
830
*SizeNeeded += BufferSize;
831
832
ACPI_DEBUG_PRINT ((ACPI_DB_RESOURCES,
833
"Type %.2X, AmlLength %.2X InternalLength %.2X%8X\n",
834
AcpiUtGetResourceType (AmlBuffer),
835
AcpiUtGetDescriptorLength (AmlBuffer), ACPI_FORMAT_UINT64(*SizeNeeded)));
836
837
/*
838
* Point to the next resource within the AML stream using the length
839
* contained in the resource descriptor header
840
*/
841
AmlBuffer += AcpiUtGetDescriptorLength (AmlBuffer);
842
}
843
844
/* Did not find an EndTag resource descriptor */
845
846
return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG);
847
}
848
849
850
/*******************************************************************************
851
*
852
* FUNCTION: AcpiRsGetPciRoutingTableLength
853
*
854
* PARAMETERS: PackageObject - Pointer to the package object
855
* BufferSizeNeeded - UINT32 pointer of the size buffer
856
* needed to properly return the
857
* parsed data
858
*
859
* RETURN: Status
860
*
861
* DESCRIPTION: Given a package representing a PCI routing table, this
862
* calculates the size of the corresponding linked list of
863
* descriptions.
864
*
865
******************************************************************************/
866
867
ACPI_STATUS
868
AcpiRsGetPciRoutingTableLength (
869
ACPI_OPERAND_OBJECT *PackageObject,
870
ACPI_SIZE *BufferSizeNeeded)
871
{
872
UINT32 NumberOfElements;
873
ACPI_SIZE TempSizeNeeded = 0;
874
ACPI_OPERAND_OBJECT **TopObjectList;
875
UINT32 Index;
876
ACPI_OPERAND_OBJECT *PackageElement;
877
ACPI_OPERAND_OBJECT **SubObjectList;
878
BOOLEAN NameFound;
879
UINT32 TableIndex;
880
881
882
ACPI_FUNCTION_TRACE (RsGetPciRoutingTableLength);
883
884
885
NumberOfElements = PackageObject->Package.Count;
886
887
/*
888
* Calculate the size of the return buffer.
889
* The base size is the number of elements * the sizes of the
890
* structures. Additional space for the strings is added below.
891
* The minus one is to subtract the size of the UINT8 Source[1]
892
* member because it is added below.
893
*
894
* But each PRT_ENTRY structure has a pointer to a string and
895
* the size of that string must be found.
896
*/
897
TopObjectList = PackageObject->Package.Elements;
898
899
for (Index = 0; Index < NumberOfElements; Index++)
900
{
901
/* Dereference the subpackage */
902
903
PackageElement = *TopObjectList;
904
905
/* We must have a valid Package object */
906
907
if (!PackageElement ||
908
(PackageElement->Common.Type != ACPI_TYPE_PACKAGE))
909
{
910
return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
911
}
912
913
/*
914
* The SubObjectList will now point to an array of the
915
* four IRQ elements: Address, Pin, Source and SourceIndex
916
*/
917
SubObjectList = PackageElement->Package.Elements;
918
919
/* Scan the IrqTableElements for the Source Name String */
920
921
NameFound = FALSE;
922
923
for (TableIndex = 0;
924
TableIndex < PackageElement->Package.Count && !NameFound;
925
TableIndex++)
926
{
927
if (*SubObjectList && /* Null object allowed */
928
929
((ACPI_TYPE_STRING ==
930
(*SubObjectList)->Common.Type) ||
931
932
((ACPI_TYPE_LOCAL_REFERENCE ==
933
(*SubObjectList)->Common.Type) &&
934
935
((*SubObjectList)->Reference.Class ==
936
ACPI_REFCLASS_NAME))))
937
{
938
NameFound = TRUE;
939
}
940
else
941
{
942
/* Look at the next element */
943
944
SubObjectList++;
945
}
946
}
947
948
TempSizeNeeded += (sizeof (ACPI_PCI_ROUTING_TABLE) - 4);
949
950
/* Was a String type found? */
951
952
if (NameFound)
953
{
954
if ((*SubObjectList)->Common.Type == ACPI_TYPE_STRING)
955
{
956
/*
957
* The length String.Length field does not include the
958
* terminating NULL, add 1
959
*/
960
TempSizeNeeded += ((ACPI_SIZE)
961
(*SubObjectList)->String.Length + 1);
962
}
963
else
964
{
965
TempSizeNeeded += AcpiNsGetPathnameLength (
966
(*SubObjectList)->Reference.Node);
967
}
968
}
969
else
970
{
971
/*
972
* If no name was found, then this is a NULL, which is
973
* translated as a UINT32 zero.
974
*/
975
TempSizeNeeded += sizeof (UINT32);
976
}
977
978
/* Round up the size since each element must be aligned */
979
980
TempSizeNeeded = ACPI_ROUND_UP_TO_64BIT (TempSizeNeeded);
981
982
/* Point to the next ACPI_OPERAND_OBJECT */
983
984
TopObjectList++;
985
}
986
987
/*
988
* Add an extra element to the end of the list, essentially a
989
* NULL terminator
990
*/
991
*BufferSizeNeeded = TempSizeNeeded + sizeof (ACPI_PCI_ROUTING_TABLE);
992
return_ACPI_STATUS (AE_OK);
993
}
994
995