![]() |
|
|||
File indexing completed on 2025-05-11 08:24:03
0001 /******************************************************************************* 0002 * 0003 * Module Name: rscalc - Calculate stream and list lengths 0004 * 0005 ******************************************************************************/ 0006 0007 /****************************************************************************** 0008 * 0009 * 1. Copyright Notice 0010 * 0011 * Some or all of this work - Copyright (c) 1999 - 2024, Intel Corp. 0012 * All rights reserved. 0013 * 0014 * 2. License 0015 * 0016 * 2.1. This is your license from Intel Corp. under its intellectual property 0017 * rights. You may have additional license terms from the party that provided 0018 * you this software, covering your right to use that party's intellectual 0019 * property rights. 0020 * 0021 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 0022 * copy of the source code appearing in this file ("Covered Code") an 0023 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 0024 * base code distributed originally by Intel ("Original Intel Code") to copy, 0025 * make derivatives, distribute, use and display any portion of the Covered 0026 * Code in any form, with the right to sublicense such rights; and 0027 * 0028 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 0029 * license (with the right to sublicense), under only those claims of Intel 0030 * patents that are infringed by the Original Intel Code, to make, use, sell, 0031 * offer to sell, and import the Covered Code and derivative works thereof 0032 * solely to the minimum extent necessary to exercise the above copyright 0033 * license, and in no event shall the patent license extend to any additions 0034 * to or modifications of the Original Intel Code. No other license or right 0035 * is granted directly or by implication, estoppel or otherwise; 0036 * 0037 * The above copyright and patent license is granted only if the following 0038 * conditions are met: 0039 * 0040 * 3. Conditions 0041 * 0042 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 0043 * Redistribution of source code of any substantial portion of the Covered 0044 * Code or modification with rights to further distribute source must include 0045 * the above Copyright Notice, the above License, this list of Conditions, 0046 * and the following Disclaimer and Export Compliance provision. In addition, 0047 * Licensee must cause all Covered Code to which Licensee contributes to 0048 * contain a file documenting the changes Licensee made to create that Covered 0049 * Code and the date of any change. Licensee must include in that file the 0050 * documentation of any changes made by any predecessor Licensee. Licensee 0051 * must include a prominent statement that the modification is derived, 0052 * directly or indirectly, from Original Intel Code. 0053 * 0054 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 0055 * Redistribution of source code of any substantial portion of the Covered 0056 * Code or modification without rights to further distribute source must 0057 * include the following Disclaimer and Export Compliance provision in the 0058 * documentation and/or other materials provided with distribution. In 0059 * addition, Licensee may not authorize further sublicense of source of any 0060 * portion of the Covered Code, and must include terms to the effect that the 0061 * license from Licensee to its licensee is limited to the intellectual 0062 * property embodied in the software Licensee provides to its licensee, and 0063 * not to intellectual property embodied in modifications its licensee may 0064 * make. 0065 * 0066 * 3.3. Redistribution of Executable. Redistribution in executable form of any 0067 * substantial portion of the Covered Code or modification must reproduce the 0068 * above Copyright Notice, and the following Disclaimer and Export Compliance 0069 * provision in the documentation and/or other materials provided with the 0070 * distribution. 0071 * 0072 * 3.4. Intel retains all right, title, and interest in and to the Original 0073 * Intel Code. 0074 * 0075 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 0076 * Intel shall be used in advertising or otherwise to promote the sale, use or 0077 * other dealings in products derived from or relating to the Covered Code 0078 * without prior written authorization from Intel. 0079 * 0080 * 4. Disclaimer and Export Compliance 0081 * 0082 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 0083 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 0084 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 0085 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 0086 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 0087 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 0088 * PARTICULAR PURPOSE. 0089 * 0090 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 0091 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 0092 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 0093 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 0094 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 0095 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 0096 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 0097 * LIMITED REMEDY. 0098 * 0099 * 4.3. Licensee shall not export, either directly or indirectly, any of this 0100 * software or system incorporating such software without first obtaining any 0101 * required license or other approval from the U. S. Department of Commerce or 0102 * any other agency or department of the United States Government. In the 0103 * event Licensee exports any such software from the United States or 0104 * re-exports any such software from a foreign destination, Licensee shall 0105 * ensure that the distribution and export/re-export of the software is in 0106 * compliance with all laws, regulations, orders, or other restrictions of the 0107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 0108 * any of its subsidiaries will export/re-export any technical data, process, 0109 * software, or service, directly or indirectly, to any country for which the 0110 * United States government or any agency thereof requires an export license, 0111 * other governmental approval, or letter of assurance, without first obtaining 0112 * such license, approval or letter. 0113 * 0114 ***************************************************************************** 0115 * 0116 * Alternatively, you may choose to be licensed under the terms of the 0117 * following license: 0118 * 0119 * Redistribution and use in source and binary forms, with or without 0120 * modification, are permitted provided that the following conditions 0121 * are met: 0122 * 1. Redistributions of source code must retain the above copyright 0123 * notice, this list of conditions, and the following disclaimer, 0124 * without modification. 0125 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 0126 * substantially similar to the "NO WARRANTY" disclaimer below 0127 * ("Disclaimer") and any redistribution must be conditioned upon 0128 * including a substantially similar Disclaimer requirement for further 0129 * binary redistribution. 0130 * 3. Neither the names of the above-listed copyright holders nor the names 0131 * of any contributors may be used to endorse or promote products derived 0132 * from this software without specific prior written permission. 0133 * 0134 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 0135 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 0136 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 0137 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 0138 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 0139 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 0140 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 0141 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 0142 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 0143 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 0144 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 0145 * 0146 * Alternatively, you may choose to be licensed under the terms of the 0147 * GNU General Public License ("GPL") version 2 as published by the Free 0148 * Software Foundation. 0149 * 0150 *****************************************************************************/ 0151 0152 #include "acpi.h" 0153 #include "accommon.h" 0154 #include "acresrc.h" 0155 #include "acnamesp.h" 0156 0157 0158 #define _COMPONENT ACPI_RESOURCES 0159 ACPI_MODULE_NAME ("rscalc") 0160 0161 0162 /* Local prototypes */ 0163 0164 static UINT8 0165 AcpiRsCountSetBits ( 0166 UINT16 BitField); 0167 0168 static ACPI_RS_LENGTH 0169 AcpiRsStructOptionLength ( 0170 ACPI_RESOURCE_SOURCE *ResourceSource); 0171 0172 static UINT32 0173 AcpiRsStreamOptionLength ( 0174 UINT32 ResourceLength, 0175 UINT32 MinimumTotalLength); 0176 0177 0178 /******************************************************************************* 0179 * 0180 * FUNCTION: AcpiRsCountSetBits 0181 * 0182 * PARAMETERS: BitField - Field in which to count bits 0183 * 0184 * RETURN: Number of bits set within the field 0185 * 0186 * DESCRIPTION: Count the number of bits set in a resource field. Used for 0187 * (Short descriptor) interrupt and DMA lists. 0188 * 0189 ******************************************************************************/ 0190 0191 static UINT8 0192 AcpiRsCountSetBits ( 0193 UINT16 BitField) 0194 { 0195 UINT8 BitsSet; 0196 0197 0198 ACPI_FUNCTION_ENTRY (); 0199 0200 0201 for (BitsSet = 0; BitField; BitsSet++) 0202 { 0203 /* Zero the least significant bit that is set */ 0204 0205 BitField &= (UINT16) (BitField - 1); 0206 } 0207 0208 return (BitsSet); 0209 } 0210 0211 0212 /******************************************************************************* 0213 * 0214 * FUNCTION: AcpiRsStructOptionLength 0215 * 0216 * PARAMETERS: ResourceSource - Pointer to optional descriptor field 0217 * 0218 * RETURN: Status 0219 * 0220 * DESCRIPTION: Common code to handle optional ResourceSourceIndex and 0221 * ResourceSource fields in some Large descriptors. Used during 0222 * list-to-stream conversion 0223 * 0224 ******************************************************************************/ 0225 0226 static ACPI_RS_LENGTH 0227 AcpiRsStructOptionLength ( 0228 ACPI_RESOURCE_SOURCE *ResourceSource) 0229 { 0230 ACPI_FUNCTION_ENTRY (); 0231 0232 0233 /* 0234 * If the ResourceSource string is valid, return the size of the string 0235 * (StringLength includes the NULL terminator) plus the size of the 0236 * ResourceSourceIndex (1). 0237 */ 0238 if (ResourceSource->StringPtr) 0239 { 0240 return ((ACPI_RS_LENGTH) (ResourceSource->StringLength + 1)); 0241 } 0242 0243 return (0); 0244 } 0245 0246 0247 /******************************************************************************* 0248 * 0249 * FUNCTION: AcpiRsStreamOptionLength 0250 * 0251 * PARAMETERS: ResourceLength - Length from the resource header 0252 * MinimumTotalLength - Minimum length of this resource, before 0253 * any optional fields. Includes header size 0254 * 0255 * RETURN: Length of optional string (0 if no string present) 0256 * 0257 * DESCRIPTION: Common code to handle optional ResourceSourceIndex and 0258 * ResourceSource fields in some Large descriptors. Used during 0259 * stream-to-list conversion 0260 * 0261 ******************************************************************************/ 0262 0263 static UINT32 0264 AcpiRsStreamOptionLength ( 0265 UINT32 ResourceLength, 0266 UINT32 MinimumAmlResourceLength) 0267 { 0268 UINT32 StringLength = 0; 0269 0270 0271 ACPI_FUNCTION_ENTRY (); 0272 0273 0274 /* 0275 * The ResourceSourceIndex and ResourceSource are optional elements of 0276 * some Large-type resource descriptors. 0277 */ 0278 0279 /* 0280 * If the length of the actual resource descriptor is greater than the 0281 * ACPI spec-defined minimum length, it means that a ResourceSourceIndex 0282 * exists and is followed by a (required) null terminated string. The 0283 * string length (including the null terminator) is the resource length 0284 * minus the minimum length, minus one byte for the ResourceSourceIndex 0285 * itself. 0286 */ 0287 if (ResourceLength > MinimumAmlResourceLength) 0288 { 0289 /* Compute the length of the optional string */ 0290 0291 StringLength = ResourceLength - MinimumAmlResourceLength - 1; 0292 } 0293 0294 /* 0295 * Round the length up to a multiple of the native word in order to 0296 * guarantee that the entire resource descriptor is native word aligned 0297 */ 0298 return ((UINT32) ACPI_ROUND_UP_TO_NATIVE_WORD (StringLength)); 0299 } 0300 0301 0302 /******************************************************************************* 0303 * 0304 * FUNCTION: AcpiRsGetAmlLength 0305 * 0306 * PARAMETERS: Resource - Pointer to the resource linked list 0307 * ResourceListSize - Size of the resource linked list 0308 * SizeNeeded - Where the required size is returned 0309 * 0310 * RETURN: Status 0311 * 0312 * DESCRIPTION: Takes a linked list of internal resource descriptors and 0313 * calculates the size buffer needed to hold the corresponding 0314 * external resource byte stream. 0315 * 0316 ******************************************************************************/ 0317 0318 ACPI_STATUS 0319 AcpiRsGetAmlLength ( 0320 ACPI_RESOURCE *Resource, 0321 ACPI_SIZE ResourceListSize, 0322 ACPI_SIZE *SizeNeeded) 0323 { 0324 ACPI_SIZE AmlSizeNeeded = 0; 0325 ACPI_RESOURCE *ResourceEnd; 0326 ACPI_RS_LENGTH TotalSize; 0327 0328 0329 ACPI_FUNCTION_TRACE (RsGetAmlLength); 0330 0331 0332 /* Traverse entire list of internal resource descriptors */ 0333 0334 ResourceEnd = ACPI_ADD_PTR (ACPI_RESOURCE, Resource, ResourceListSize); 0335 while (Resource < ResourceEnd) 0336 { 0337 /* Validate the descriptor type */ 0338 0339 if (Resource->Type > ACPI_RESOURCE_TYPE_MAX) 0340 { 0341 return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE); 0342 } 0343 0344 /* Sanity check the length. It must not be zero, or we loop forever */ 0345 0346 if (!Resource->Length) 0347 { 0348 return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH); 0349 } 0350 0351 /* Get the base size of the (external stream) resource descriptor */ 0352 0353 TotalSize = AcpiGbl_AmlResourceSizes [Resource->Type]; 0354 0355 /* 0356 * Augment the base size for descriptors with optional and/or 0357 * variable-length fields 0358 */ 0359 switch (Resource->Type) 0360 { 0361 case ACPI_RESOURCE_TYPE_IRQ: 0362 0363 /* Length can be 3 or 2 */ 0364 0365 if (Resource->Data.Irq.DescriptorLength == 2) 0366 { 0367 TotalSize--; 0368 } 0369 break; 0370 0371 0372 case ACPI_RESOURCE_TYPE_START_DEPENDENT: 0373 0374 /* Length can be 1 or 0 */ 0375 0376 if (Resource->Data.Irq.DescriptorLength == 0) 0377 { 0378 TotalSize--; 0379 } 0380 break; 0381 0382 0383 case ACPI_RESOURCE_TYPE_VENDOR: 0384 /* 0385 * Vendor Defined Resource: 0386 * For a Vendor Specific resource, if the Length is between 1 and 7 0387 * it will be created as a Small Resource data type, otherwise it 0388 * is a Large Resource data type. 0389 */ 0390 if (Resource->Data.Vendor.ByteLength > 7) 0391 { 0392 /* Base size of a Large resource descriptor */ 0393 0394 TotalSize = sizeof (AML_RESOURCE_LARGE_HEADER); 0395 } 0396 0397 /* Add the size of the vendor-specific data */ 0398 0399 TotalSize = (ACPI_RS_LENGTH) 0400 (TotalSize + Resource->Data.Vendor.ByteLength); 0401 break; 0402 0403 0404 case ACPI_RESOURCE_TYPE_END_TAG: 0405 /* 0406 * End Tag: 0407 * We are done -- return the accumulated total size. 0408 */ 0409 *SizeNeeded = AmlSizeNeeded + TotalSize; 0410 0411 /* Normal exit */ 0412 0413 return_ACPI_STATUS (AE_OK); 0414 0415 0416 case ACPI_RESOURCE_TYPE_ADDRESS16: 0417 /* 0418 * 16-Bit Address Resource: 0419 * Add the size of the optional ResourceSource info 0420 */ 0421 TotalSize = (ACPI_RS_LENGTH) (TotalSize + 0422 AcpiRsStructOptionLength ( 0423 &Resource->Data.Address16.ResourceSource)); 0424 break; 0425 0426 0427 case ACPI_RESOURCE_TYPE_ADDRESS32: 0428 /* 0429 * 32-Bit Address Resource: 0430 * Add the size of the optional ResourceSource info 0431 */ 0432 TotalSize = (ACPI_RS_LENGTH) (TotalSize + 0433 AcpiRsStructOptionLength ( 0434 &Resource->Data.Address32.ResourceSource)); 0435 break; 0436 0437 0438 case ACPI_RESOURCE_TYPE_ADDRESS64: 0439 /* 0440 * 64-Bit Address Resource: 0441 * Add the size of the optional ResourceSource info 0442 */ 0443 TotalSize = (ACPI_RS_LENGTH) (TotalSize + 0444 AcpiRsStructOptionLength ( 0445 &Resource->Data.Address64.ResourceSource)); 0446 break; 0447 0448 0449 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: 0450 /* 0451 * Extended IRQ Resource: 0452 * Add the size of each additional optional interrupt beyond the 0453 * required 1 (4 bytes for each UINT32 interrupt number) 0454 */ 0455 TotalSize = (ACPI_RS_LENGTH) (TotalSize + 0456 ((Resource->Data.ExtendedIrq.InterruptCount - 1) * 4) + 0457 0458 /* Add the size of the optional ResourceSource info */ 0459 0460 AcpiRsStructOptionLength ( 0461 &Resource->Data.ExtendedIrq.ResourceSource)); 0462 break; 0463 0464 0465 case ACPI_RESOURCE_TYPE_GPIO: 0466 0467 TotalSize = (ACPI_RS_LENGTH) (TotalSize + 0468 (Resource->Data.Gpio.PinTableLength * 2) + 0469 Resource->Data.Gpio.ResourceSource.StringLength + 0470 Resource->Data.Gpio.VendorLength); 0471 0472 break; 0473 0474 case ACPI_RESOURCE_TYPE_PIN_FUNCTION: 0475 0476 TotalSize = (ACPI_RS_LENGTH) (TotalSize + 0477 (Resource->Data.PinFunction.PinTableLength * 2) + 0478 Resource->Data.PinFunction.ResourceSource.StringLength + 0479 Resource->Data.PinFunction.VendorLength); 0480 0481 break; 0482 0483 case ACPI_RESOURCE_TYPE_CLOCK_INPUT: 0484 0485 TotalSize = (ACPI_RS_LENGTH) (TotalSize + 0486 Resource->Data.ClockInput.ResourceSource.StringLength); 0487 0488 break; 0489 0490 0491 case ACPI_RESOURCE_TYPE_SERIAL_BUS: 0492 0493 TotalSize = AcpiGbl_AmlResourceSerialBusSizes [ 0494 Resource->Data.CommonSerialBus.Type]; 0495 0496 TotalSize = (ACPI_RS_LENGTH) (TotalSize + 0497 Resource->Data.I2cSerialBus.ResourceSource.StringLength + 0498 Resource->Data.I2cSerialBus.VendorLength); 0499 0500 break; 0501 0502 case ACPI_RESOURCE_TYPE_PIN_CONFIG: 0503 0504 TotalSize = (ACPI_RS_LENGTH) (TotalSize + 0505 (Resource->Data.PinConfig.PinTableLength * 2) + 0506 Resource->Data.PinConfig.ResourceSource.StringLength + 0507 Resource->Data.PinConfig.VendorLength); 0508 0509 break; 0510 0511 case ACPI_RESOURCE_TYPE_PIN_GROUP: 0512 0513 TotalSize = (ACPI_RS_LENGTH) (TotalSize + 0514 (Resource->Data.PinGroup.PinTableLength * 2) + 0515 Resource->Data.PinGroup.ResourceLabel.StringLength + 0516 Resource->Data.PinGroup.VendorLength); 0517 0518 break; 0519 0520 case ACPI_RESOURCE_TYPE_PIN_GROUP_FUNCTION: 0521 0522 TotalSize = (ACPI_RS_LENGTH) (TotalSize + 0523 Resource->Data.PinGroupFunction.ResourceSource.StringLength + 0524 Resource->Data.PinGroupFunction.ResourceSourceLabel.StringLength + 0525 Resource->Data.PinGroupFunction.VendorLength); 0526 0527 break; 0528 0529 case ACPI_RESOURCE_TYPE_PIN_GROUP_CONFIG: 0530 0531 TotalSize = (ACPI_RS_LENGTH) (TotalSize + 0532 Resource->Data.PinGroupConfig.ResourceSource.StringLength + 0533 Resource->Data.PinGroupConfig.ResourceSourceLabel.StringLength + 0534 Resource->Data.PinGroupConfig.VendorLength); 0535 0536 break; 0537 0538 default: 0539 0540 break; 0541 } 0542 0543 /* Update the total */ 0544 0545 AmlSizeNeeded += TotalSize; 0546 0547 /* Point to the next object */ 0548 0549 Resource = ACPI_ADD_PTR (ACPI_RESOURCE, Resource, Resource->Length); 0550 } 0551 0552 /* Did not find an EndTag resource descriptor */ 0553 0554 return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG); 0555 } 0556 0557 0558 /******************************************************************************* 0559 * 0560 * FUNCTION: AcpiRsGetListLength 0561 * 0562 * PARAMETERS: AmlBuffer - Pointer to the resource byte stream 0563 * AmlBufferLength - Size of AmlBuffer 0564 * SizeNeeded - Where the size needed is returned 0565 * 0566 * RETURN: Status 0567 * 0568 * DESCRIPTION: Takes an external resource byte stream and calculates the size 0569 * buffer needed to hold the corresponding internal resource 0570 * descriptor linked list. 0571 * 0572 ******************************************************************************/ 0573 0574 ACPI_STATUS 0575 AcpiRsGetListLength ( 0576 UINT8 *AmlBuffer, 0577 UINT32 AmlBufferLength, 0578 ACPI_SIZE *SizeNeeded) 0579 { 0580 ACPI_STATUS Status; 0581 UINT8 *EndAml; 0582 UINT8 *Buffer; 0583 UINT32 BufferSize; 0584 UINT16 Temp16; 0585 UINT16 ResourceLength; 0586 UINT32 ExtraStructBytes; 0587 UINT8 ResourceIndex; 0588 UINT8 MinimumAmlResourceLength; 0589 AML_RESOURCE *AmlResource; 0590 0591 0592 ACPI_FUNCTION_TRACE (RsGetListLength); 0593 0594 0595 *SizeNeeded = ACPI_RS_SIZE_MIN; /* Minimum size is one EndTag */ 0596 EndAml = AmlBuffer + AmlBufferLength; 0597 0598 /* Walk the list of AML resource descriptors */ 0599 0600 while (AmlBuffer < EndAml) 0601 { 0602 /* Validate the Resource Type and Resource Length */ 0603 0604 Status = AcpiUtValidateResource (NULL, AmlBuffer, &ResourceIndex); 0605 if (ACPI_FAILURE (Status)) 0606 { 0607 /* 0608 * Exit on failure. Cannot continue because the descriptor length 0609 * may be bogus also. 0610 */ 0611 return_ACPI_STATUS (Status); 0612 } 0613 0614 AmlResource = (void *) AmlBuffer; 0615 0616 /* Get the resource length and base (minimum) AML size */ 0617 0618 ResourceLength = AcpiUtGetResourceLength (AmlBuffer); 0619 MinimumAmlResourceLength = AcpiGbl_ResourceAmlSizes[ResourceIndex]; 0620 0621 /* 0622 * Augment the size for descriptors with optional 0623 * and/or variable length fields 0624 */ 0625 ExtraStructBytes = 0; 0626 Buffer = AmlBuffer + AcpiUtGetResourceHeaderLength (AmlBuffer); 0627 0628 switch (AcpiUtGetResourceType (AmlBuffer)) 0629 { 0630 case ACPI_RESOURCE_NAME_IRQ: 0631 /* 0632 * IRQ Resource: 0633 * Get the number of bits set in the 16-bit IRQ mask 0634 */ 0635 ACPI_MOVE_16_TO_16 (&Temp16, Buffer); 0636 ExtraStructBytes = AcpiRsCountSetBits (Temp16); 0637 break; 0638 0639 0640 case ACPI_RESOURCE_NAME_DMA: 0641 /* 0642 * DMA Resource: 0643 * Get the number of bits set in the 8-bit DMA mask 0644 */ 0645 ExtraStructBytes = AcpiRsCountSetBits (*Buffer); 0646 break; 0647 0648 0649 case ACPI_RESOURCE_NAME_VENDOR_SMALL: 0650 case ACPI_RESOURCE_NAME_VENDOR_LARGE: 0651 /* 0652 * Vendor Resource: 0653 * Get the number of vendor data bytes 0654 */ 0655 ExtraStructBytes = ResourceLength; 0656 0657 /* 0658 * There is already one byte included in the minimum 0659 * descriptor size. If there are extra struct bytes, 0660 * subtract one from the count. 0661 */ 0662 if (ExtraStructBytes) 0663 { 0664 ExtraStructBytes--; 0665 } 0666 break; 0667 0668 0669 case ACPI_RESOURCE_NAME_END_TAG: 0670 /* 0671 * End Tag: This is the normal exit 0672 */ 0673 return_ACPI_STATUS (AE_OK); 0674 0675 0676 case ACPI_RESOURCE_NAME_ADDRESS32: 0677 case ACPI_RESOURCE_NAME_ADDRESS16: 0678 case ACPI_RESOURCE_NAME_ADDRESS64: 0679 /* 0680 * Address Resource: 0681 * Add the size of the optional ResourceSource 0682 */ 0683 ExtraStructBytes = AcpiRsStreamOptionLength ( 0684 ResourceLength, MinimumAmlResourceLength); 0685 break; 0686 0687 0688 case ACPI_RESOURCE_NAME_EXTENDED_IRQ: 0689 /* 0690 * Extended IRQ Resource: 0691 * Using the InterruptTableLength, add 4 bytes for each additional 0692 * interrupt. Note: at least one interrupt is required and is 0693 * included in the minimum descriptor size (reason for the -1) 0694 */ 0695 ExtraStructBytes = (Buffer[1] - 1) * sizeof (UINT32); 0696 0697 /* Add the size of the optional ResourceSource */ 0698 0699 ExtraStructBytes += AcpiRsStreamOptionLength ( 0700 ResourceLength - ExtraStructBytes, MinimumAmlResourceLength); 0701 break; 0702 0703 case ACPI_RESOURCE_NAME_GPIO: 0704 0705 /* Vendor data is optional */ 0706 0707 if (AmlResource->Gpio.VendorLength) 0708 { 0709 ExtraStructBytes += 0710 AmlResource->Gpio.VendorOffset - 0711 AmlResource->Gpio.PinTableOffset + 0712 AmlResource->Gpio.VendorLength; 0713 } 0714 else 0715 { 0716 ExtraStructBytes += 0717 AmlResource->LargeHeader.ResourceLength + 0718 sizeof (AML_RESOURCE_LARGE_HEADER) - 0719 AmlResource->Gpio.PinTableOffset; 0720 } 0721 break; 0722 0723 case ACPI_RESOURCE_NAME_PIN_FUNCTION: 0724 0725 /* Vendor data is optional */ 0726 0727 if (AmlResource->PinFunction.VendorLength) 0728 { 0729 ExtraStructBytes += 0730 AmlResource->PinFunction.VendorOffset - 0731 AmlResource->PinFunction.PinTableOffset + 0732 AmlResource->PinFunction.VendorLength; 0733 } 0734 else 0735 { 0736 ExtraStructBytes += 0737 AmlResource->LargeHeader.ResourceLength + 0738 sizeof (AML_RESOURCE_LARGE_HEADER) - 0739 AmlResource->PinFunction.PinTableOffset; 0740 } 0741 break; 0742 0743 case ACPI_RESOURCE_NAME_SERIAL_BUS: { 0744 /* Avoid undefined behavior: member access within misaligned address */ 0745 0746 AML_RESOURCE_COMMON_SERIALBUS CommonSerialBus; 0747 memcpy(&CommonSerialBus, AmlResource, sizeof(CommonSerialBus)); 0748 0749 MinimumAmlResourceLength = AcpiGbl_ResourceAmlSerialBusSizes[ 0750 CommonSerialBus.Type]; 0751 ExtraStructBytes += 0752 CommonSerialBus.ResourceLength - 0753 MinimumAmlResourceLength; 0754 break; 0755 } 0756 0757 case ACPI_RESOURCE_NAME_PIN_CONFIG: 0758 0759 /* Vendor data is optional */ 0760 0761 if (AmlResource->PinConfig.VendorLength) 0762 { 0763 ExtraStructBytes += 0764 AmlResource->PinConfig.VendorOffset - 0765 AmlResource->PinConfig.PinTableOffset + 0766 AmlResource->PinConfig.VendorLength; 0767 } 0768 else 0769 { 0770 ExtraStructBytes += 0771 AmlResource->LargeHeader.ResourceLength + 0772 sizeof (AML_RESOURCE_LARGE_HEADER) - 0773 AmlResource->PinConfig.PinTableOffset; 0774 } 0775 break; 0776 0777 case ACPI_RESOURCE_NAME_PIN_GROUP: 0778 0779 ExtraStructBytes += 0780 AmlResource->PinGroup.VendorOffset - 0781 AmlResource->PinGroup.PinTableOffset + 0782 AmlResource->PinGroup.VendorLength; 0783 0784 break; 0785 0786 case ACPI_RESOURCE_NAME_PIN_GROUP_FUNCTION: 0787 0788 ExtraStructBytes += 0789 AmlResource->PinGroupFunction.VendorOffset - 0790 AmlResource->PinGroupFunction.ResSourceOffset + 0791 AmlResource->PinGroupFunction.VendorLength; 0792 0793 break; 0794 0795 case ACPI_RESOURCE_NAME_PIN_GROUP_CONFIG: 0796 0797 ExtraStructBytes += 0798 AmlResource->PinGroupConfig.VendorOffset - 0799 AmlResource->PinGroupConfig.ResSourceOffset + 0800 AmlResource->PinGroupConfig.VendorLength; 0801 0802 break; 0803 0804 case ACPI_RESOURCE_NAME_CLOCK_INPUT: 0805 ExtraStructBytes = AcpiRsStreamOptionLength ( 0806 ResourceLength, MinimumAmlResourceLength); 0807 0808 break; 0809 0810 default: 0811 0812 break; 0813 } 0814 0815 /* 0816 * Update the required buffer size for the internal descriptor structs 0817 * 0818 * Important: Round the size up for the appropriate alignment. This 0819 * is a requirement on IA64. 0820 */ 0821 if (AcpiUtGetResourceType (AmlBuffer) == 0822 ACPI_RESOURCE_NAME_SERIAL_BUS) 0823 { 0824 /* Avoid undefined behavior: member access within misaligned address */ 0825 0826 AML_RESOURCE_COMMON_SERIALBUS CommonSerialBus; 0827 memcpy(&CommonSerialBus, AmlResource, sizeof(CommonSerialBus)); 0828 0829 BufferSize = AcpiGbl_ResourceStructSerialBusSizes[ 0830 CommonSerialBus.Type] + ExtraStructBytes; 0831 } 0832 else 0833 { 0834 BufferSize = AcpiGbl_ResourceStructSizes[ResourceIndex] + 0835 ExtraStructBytes; 0836 } 0837 0838 BufferSize = (UINT32) ACPI_ROUND_UP_TO_NATIVE_WORD (BufferSize); 0839 *SizeNeeded += BufferSize; 0840 0841 ACPI_DEBUG_PRINT ((ACPI_DB_RESOURCES, 0842 "Type %.2X, AmlLength %.2X InternalLength %.2X%8X\n", 0843 AcpiUtGetResourceType (AmlBuffer), 0844 AcpiUtGetDescriptorLength (AmlBuffer), ACPI_FORMAT_UINT64(*SizeNeeded))); 0845 0846 /* 0847 * Point to the next resource within the AML stream using the length 0848 * contained in the resource descriptor header 0849 */ 0850 AmlBuffer += AcpiUtGetDescriptorLength (AmlBuffer); 0851 } 0852 0853 /* Did not find an EndTag resource descriptor */ 0854 0855 return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG); 0856 } 0857 0858 0859 /******************************************************************************* 0860 * 0861 * FUNCTION: AcpiRsGetPciRoutingTableLength 0862 * 0863 * PARAMETERS: PackageObject - Pointer to the package object 0864 * BufferSizeNeeded - UINT32 pointer of the size buffer 0865 * needed to properly return the 0866 * parsed data 0867 * 0868 * RETURN: Status 0869 * 0870 * DESCRIPTION: Given a package representing a PCI routing table, this 0871 * calculates the size of the corresponding linked list of 0872 * descriptions. 0873 * 0874 ******************************************************************************/ 0875 0876 ACPI_STATUS 0877 AcpiRsGetPciRoutingTableLength ( 0878 ACPI_OPERAND_OBJECT *PackageObject, 0879 ACPI_SIZE *BufferSizeNeeded) 0880 { 0881 UINT32 NumberOfElements; 0882 ACPI_SIZE TempSizeNeeded = 0; 0883 ACPI_OPERAND_OBJECT **TopObjectList; 0884 UINT32 Index; 0885 ACPI_OPERAND_OBJECT *PackageElement; 0886 ACPI_OPERAND_OBJECT **SubObjectList; 0887 BOOLEAN NameFound; 0888 UINT32 TableIndex; 0889 0890 0891 ACPI_FUNCTION_TRACE (RsGetPciRoutingTableLength); 0892 0893 0894 NumberOfElements = PackageObject->Package.Count; 0895 0896 /* 0897 * Calculate the size of the return buffer. 0898 * The base size is the number of elements * the sizes of the 0899 * structures. Additional space for the strings is added below. 0900 * The minus one is to subtract the size of the UINT8 Source[1] 0901 * member because it is added below. 0902 * 0903 * But each PRT_ENTRY structure has a pointer to a string and 0904 * the size of that string must be found. 0905 */ 0906 TopObjectList = PackageObject->Package.Elements; 0907 0908 for (Index = 0; Index < NumberOfElements; Index++) 0909 { 0910 /* Dereference the subpackage */ 0911 0912 PackageElement = *TopObjectList; 0913 0914 /* We must have a valid Package object */ 0915 0916 if (!PackageElement || 0917 (PackageElement->Common.Type != ACPI_TYPE_PACKAGE)) 0918 { 0919 return_ACPI_STATUS (AE_AML_OPERAND_TYPE); 0920 } 0921 0922 /* 0923 * The SubObjectList will now point to an array of the 0924 * four IRQ elements: Address, Pin, Source and SourceIndex 0925 */ 0926 SubObjectList = PackageElement->Package.Elements; 0927 0928 /* Scan the IrqTableElements for the Source Name String */ 0929 0930 NameFound = FALSE; 0931 0932 for (TableIndex = 0; 0933 TableIndex < PackageElement->Package.Count && !NameFound; 0934 TableIndex++) 0935 { 0936 if (*SubObjectList && /* Null object allowed */ 0937 0938 ((ACPI_TYPE_STRING == 0939 (*SubObjectList)->Common.Type) || 0940 0941 ((ACPI_TYPE_LOCAL_REFERENCE == 0942 (*SubObjectList)->Common.Type) && 0943 0944 ((*SubObjectList)->Reference.Class == 0945 ACPI_REFCLASS_NAME)))) 0946 { 0947 NameFound = TRUE; 0948 } 0949 else 0950 { 0951 /* Look at the next element */ 0952 0953 SubObjectList++; 0954 } 0955 } 0956 0957 TempSizeNeeded += (sizeof (ACPI_PCI_ROUTING_TABLE) - 4); 0958 0959 /* Was a String type found? */ 0960 0961 if (NameFound) 0962 { 0963 if ((*SubObjectList)->Common.Type == ACPI_TYPE_STRING) 0964 { 0965 /* 0966 * The length String.Length field does not include the 0967 * terminating NULL, add 1 0968 */ 0969 TempSizeNeeded += ((ACPI_SIZE) 0970 (*SubObjectList)->String.Length + 1); 0971 } 0972 else 0973 { 0974 TempSizeNeeded += AcpiNsGetPathnameLength ( 0975 (*SubObjectList)->Reference.Node); 0976 } 0977 } 0978 else 0979 { 0980 /* 0981 * If no name was found, then this is a NULL, which is 0982 * translated as a UINT32 zero. 0983 */ 0984 TempSizeNeeded += sizeof (UINT32); 0985 } 0986 0987 /* Round up the size since each element must be aligned */ 0988 0989 TempSizeNeeded = ACPI_ROUND_UP_TO_64BIT (TempSizeNeeded); 0990 0991 /* Point to the next ACPI_OPERAND_OBJECT */ 0992 0993 TopObjectList++; 0994 } 0995 0996 /* 0997 * Add an extra element to the end of the list, essentially a 0998 * NULL terminator 0999 */ 1000 *BufferSizeNeeded = TempSizeNeeded + sizeof (ACPI_PCI_ROUTING_TABLE); 1001 return_ACPI_STATUS (AE_OK); 1002 }
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |