rscalc.c revision 77424
185587Sobrien/******************************************************************************* 285587Sobrien * 385587Sobrien * Module Name: rscalc - Calculate stream and list lengths 485587Sobrien * $Revision: 30 $ 585587Sobrien * 685587Sobrien ******************************************************************************/ 785587Sobrien 885587Sobrien/****************************************************************************** 985587Sobrien * 1085587Sobrien * 1. Copyright Notice 1185587Sobrien * 1285587Sobrien * Some or all of this work - Copyright (c) 1999, 2000, 2001, Intel Corp. 1385587Sobrien * All rights reserved. 1485587Sobrien * 1585587Sobrien * 2. License 1685587Sobrien * 1785587Sobrien * 2.1. This is your license from Intel Corp. under its intellectual property 1885587Sobrien * rights. You may have additional license terms from the party that provided 1985587Sobrien * you this software, covering your right to use that party's intellectual 2085587Sobrien * property rights. 2185587Sobrien * 2285587Sobrien * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 2385587Sobrien * copy of the source code appearing in this file ("Covered Code") an 2485587Sobrien * irrevocable, perpetual, worldwide license under Intel's copyrights in the 2585587Sobrien * base code distributed originally by Intel ("Original Intel Code") to copy, 2685587Sobrien * make derivatives, distribute, use and display any portion of the Covered 2785587Sobrien * Code in any form, with the right to sublicense such rights; and 2885587Sobrien * 2985587Sobrien * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 3085587Sobrien * license (with the right to sublicense), under only those claims of Intel 3185587Sobrien * patents that are infringed by the Original Intel Code, to make, use, sell, 3285587Sobrien * offer to sell, and import the Covered Code and derivative works thereof 3385587Sobrien * solely to the minimum extent necessary to exercise the above copyright 3485587Sobrien * license, and in no event shall the patent license extend to any additions 3585587Sobrien * to or modifications of the Original Intel Code. No other license or right 3685587Sobrien * is granted directly or by implication, estoppel or otherwise; 3785587Sobrien * 3885587Sobrien * The above copyright and patent license is granted only if the following 3985587Sobrien * conditions are met: 4085587Sobrien * 4185587Sobrien * 3. Conditions 4285587Sobrien * 4385587Sobrien * 3.1. Redistribution of Source with Rights to Further Distribute Source. 4485587Sobrien * Redistribution of source code of any substantial portion of the Covered 4585587Sobrien * Code or modification with rights to further distribute source must include 4685587Sobrien * the above Copyright Notice, the above License, this list of Conditions, 4785587Sobrien * and the following Disclaimer and Export Compliance provision. In addition, 4885587Sobrien * Licensee must cause all Covered Code to which Licensee contributes to 4985587Sobrien * contain a file documenting the changes Licensee made to create that Covered 5085587Sobrien * Code and the date of any change. Licensee must include in that file the 5185587Sobrien * documentation of any changes made by any predecessor Licensee. Licensee 5285587Sobrien * must include a prominent statement that the modification is derived, 5385587Sobrien * directly or indirectly, from Original Intel Code. 5485587Sobrien * 5585587Sobrien * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 5685587Sobrien * Redistribution of source code of any substantial portion of the Covered 5785587Sobrien * Code or modification without rights to further distribute source must 5885587Sobrien * include the following Disclaimer and Export Compliance provision in the 5985587Sobrien * documentation and/or other materials provided with distribution. In 6085587Sobrien * addition, Licensee may not authorize further sublicense of source of any 6185587Sobrien * portion of the Covered Code, and must include terms to the effect that the 6285587Sobrien * license from Licensee to its licensee is limited to the intellectual 6385587Sobrien * property embodied in the software Licensee provides to its licensee, and 6485587Sobrien * not to intellectual property embodied in modifications its licensee may 6585587Sobrien * make. 6685587Sobrien * 6785587Sobrien * 3.3. Redistribution of Executable. Redistribution in executable form of any 6885587Sobrien * substantial portion of the Covered Code or modification must reproduce the 6985587Sobrien * above Copyright Notice, and the following Disclaimer and Export Compliance 7085587Sobrien * provision in the documentation and/or other materials provided with the 7185587Sobrien * distribution. 7285587Sobrien * 7385587Sobrien * 3.4. Intel retains all right, title, and interest in and to the Original 7485587Sobrien * Intel Code. 7585587Sobrien * 7685587Sobrien * 3.5. Neither the name Intel nor any other trademark owned or controlled by 7785587Sobrien * Intel shall be used in advertising or otherwise to promote the sale, use or 7885587Sobrien * other dealings in products derived from or relating to the Covered Code 7985587Sobrien * without prior written authorization from Intel. 8085587Sobrien * 8185587Sobrien * 4. Disclaimer and Export Compliance 8285587Sobrien * 8385587Sobrien * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 8485587Sobrien * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 8585587Sobrien * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 8685587Sobrien * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 8785587Sobrien * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 8885587Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 8985587Sobrien * PARTICULAR PURPOSE. 9085587Sobrien * 9185587Sobrien * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 9285587Sobrien * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 9385587Sobrien * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 9485587Sobrien * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 9585587Sobrien * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 9685587Sobrien * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 9785587Sobrien * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 9885587Sobrien * LIMITED REMEDY. 9985587Sobrien * 10085587Sobrien * 4.3. Licensee shall not export, either directly or indirectly, any of this 10185587Sobrien * software or system incorporating such software without first obtaining any 10285587Sobrien * required license or other approval from the U. S. Department of Commerce or 10385587Sobrien * any other agency or department of the United States Government. In the 10485587Sobrien * event Licensee exports any such software from the United States or 10585587Sobrien * re-exports any such software from a foreign destination, Licensee shall 10685587Sobrien * ensure that the distribution and export/re-export of the software is in 10785587Sobrien * compliance with all laws, regulations, orders, or other restrictions of the 10885587Sobrien * U.S. Export Administration Regulations. Licensee agrees that neither it nor 10985587Sobrien * any of its subsidiaries will export/re-export any technical data, process, 11085587Sobrien * software, or service, directly or indirectly, to any country for which the 11185587Sobrien * United States government or any agency thereof requires an export license, 11285587Sobrien * other governmental approval, or letter of assurance, without first obtaining 11385587Sobrien * such license, approval or letter. 11485587Sobrien * 11585587Sobrien *****************************************************************************/ 11685587Sobrien 11785587Sobrien#define __RSCALC_C__ 11885587Sobrien 11985587Sobrien#include "acpi.h" 12085587Sobrien#include "acresrc.h" 12185587Sobrien#include "amlcode.h" 12285587Sobrien#include "acnamesp.h" 12385587Sobrien 12485587Sobrien#define _COMPONENT ACPI_RESOURCES 12585587Sobrien MODULE_NAME ("rscalc") 12685587Sobrien 12785587Sobrien 12885587Sobrien/******************************************************************************* 12985587Sobrien * 13085587Sobrien * FUNCTION: AcpiRsCalculateByteStreamLength 13185587Sobrien * 13285587Sobrien * PARAMETERS: LinkedList - Pointer to the resource linked list 13385587Sobrien * SizeNeeded - UINT32 pointer of the size buffer needed 13485587Sobrien * to properly return the parsed data 13585587Sobrien * 13685587Sobrien * RETURN: Status 13785587Sobrien * 13885587Sobrien * DESCRIPTION: Takes the resource byte stream and parses it once, calculating 13985587Sobrien * the size buffer needed to hold the linked list that conveys 14085587Sobrien * the resource data. 14185587Sobrien * 14285587Sobrien ******************************************************************************/ 14385587Sobrien 14485587SobrienACPI_STATUS 14585587SobrienAcpiRsCalculateByteStreamLength ( 14685587Sobrien ACPI_RESOURCE *LinkedList, 14785587Sobrien UINT32 *SizeNeeded) 14885587Sobrien{ 14985587Sobrien UINT32 ByteStreamSizeNeeded = 0; 15085587Sobrien UINT32 SegmentSize; 15185587Sobrien ACPI_RESOURCE_EXT_IRQ *ExIrq = NULL; 15285587Sobrien BOOLEAN Done = FALSE; 15385587Sobrien 15485587Sobrien 15585587Sobrien FUNCTION_TRACE ("RsCalculateByteStreamLength"); 15685587Sobrien 15785587Sobrien 15885587Sobrien while (!Done) 15985587Sobrien { 16085587Sobrien /* 16185587Sobrien * Init the variable that will hold the size to add to the total. 16285587Sobrien */ 16385587Sobrien SegmentSize = 0; 16485587Sobrien 16585587Sobrien switch (LinkedList->Id) 16685587Sobrien { 16785587Sobrien case ACPI_RSTYPE_IRQ: 16885587Sobrien /* 16985587Sobrien * IRQ Resource 17085587Sobrien * For an IRQ Resource, Byte 3, although optional, will 17185587Sobrien * always be created - it holds IRQ information. 17285587Sobrien */ 17385587Sobrien SegmentSize = 4; 17485587Sobrien break; 17585587Sobrien 17685587Sobrien case ACPI_RSTYPE_DMA: 17785587Sobrien /* 17885587Sobrien * DMA Resource 17985587Sobrien * For this resource the size is static 18085587Sobrien */ 18185587Sobrien SegmentSize = 3; 18285587Sobrien break; 18385587Sobrien 18485587Sobrien case ACPI_RSTYPE_START_DPF: 18585587Sobrien /* 18685587Sobrien * Start Dependent Functions Resource 18785587Sobrien * For a StartDependentFunctions Resource, Byte 1, 18885587Sobrien * although optional, will always be created. 18985587Sobrien */ 19085587Sobrien SegmentSize = 2; 19185587Sobrien break; 19285587Sobrien 19385587Sobrien case ACPI_RSTYPE_END_DPF: 19485587Sobrien /* 19585587Sobrien * End Dependent Functions Resource 19685587Sobrien * For this resource the size is static 19785587Sobrien */ 19885587Sobrien SegmentSize = 1; 19985587Sobrien break; 20085587Sobrien 20185587Sobrien case ACPI_RSTYPE_IO: 20285587Sobrien /* 20385587Sobrien * IO Port Resource 20485587Sobrien * For this resource the size is static 20585587Sobrien */ 20685587Sobrien SegmentSize = 8; 20785587Sobrien break; 20885587Sobrien 20985587Sobrien case ACPI_RSTYPE_FIXED_IO: 21085587Sobrien /* 211272918Spfg * Fixed IO Port Resource 21285587Sobrien * For this resource the size is static 21385587Sobrien */ 21485587Sobrien SegmentSize = 4; 21585587Sobrien break; 21685587Sobrien 21785587Sobrien case ACPI_RSTYPE_VENDOR: 21885587Sobrien /* 21985587Sobrien * Vendor Defined Resource 22085587Sobrien * For a Vendor Specific resource, if the Length is 22185587Sobrien * between 1 and 7 it will be created as a Small 22285587Sobrien * Resource data type, otherwise it is a Large 22385587Sobrien * Resource data type. 22485587Sobrien */ 22585587Sobrien if (LinkedList->Data.VendorSpecific.Length > 7) 22685587Sobrien { 22785587Sobrien SegmentSize = 3; 22885587Sobrien } 22985587Sobrien else 23085587Sobrien { 23185587Sobrien SegmentSize = 1; 23285587Sobrien } 23385587Sobrien SegmentSize += LinkedList->Data.VendorSpecific.Length; 23485587Sobrien break; 23585587Sobrien 23685587Sobrien case ACPI_RSTYPE_END_TAG: 23785587Sobrien /* 23885587Sobrien * End Tag 23985587Sobrien * For this resource the size is static 24085587Sobrien */ 24185587Sobrien SegmentSize = 2; 24285587Sobrien Done = TRUE; 24385587Sobrien break; 24485587Sobrien 24585587Sobrien case ACPI_RSTYPE_MEM24: 24685587Sobrien /* 24785587Sobrien * 24-Bit Memory Resource 24885587Sobrien * For this resource the size is static 24985587Sobrien */ 25085587Sobrien SegmentSize = 12; 25185587Sobrien break; 25285587Sobrien 25385587Sobrien case ACPI_RSTYPE_MEM32: 25485587Sobrien /* 25585587Sobrien * 32-Bit Memory Range Resource 25685587Sobrien * For this resource the size is static 25785587Sobrien */ 25885587Sobrien SegmentSize = 20; 25985587Sobrien break; 26085587Sobrien 26185587Sobrien case ACPI_RSTYPE_FIXED_MEM32: 26285587Sobrien /* 26385587Sobrien * 32-Bit Fixed Memory Resource 26485587Sobrien * For this resource the size is static 26585587Sobrien */ 26685587Sobrien SegmentSize = 12; 26785587Sobrien break; 26885587Sobrien 26985587Sobrien case ACPI_RSTYPE_ADDRESS16: 27085587Sobrien /* 27185587Sobrien * 16-Bit Address Resource 27285587Sobrien * The base size of this byte stream is 16. If a 27385587Sobrien * Resource Source string is not NULL, add 1 for 27485587Sobrien * the Index + the length of the null terminated 27585587Sobrien * string Resource Source + 1 for the null. 27685587Sobrien */ 27785587Sobrien SegmentSize = 16; 27885587Sobrien 27985587Sobrien if (NULL != LinkedList->Data.Address16.ResourceSource.StringPtr) 28085587Sobrien { 28185587Sobrien SegmentSize += (1 + 28285587Sobrien LinkedList->Data.Address16.ResourceSource.StringLength); 28385587Sobrien } 28485587Sobrien break; 28585587Sobrien 28685587Sobrien case ACPI_RSTYPE_ADDRESS32: 28785587Sobrien /* 28885587Sobrien * 32-Bit Address Resource 28985587Sobrien * The base size of this byte stream is 26. If a Resource 29085587Sobrien * Source string is not NULL, add 1 for the Index + the 29185587Sobrien * length of the null terminated string Resource Source + 29285587Sobrien * 1 for the null. 29385587Sobrien */ 29485587Sobrien SegmentSize = 26; 29585587Sobrien 29685587Sobrien if (NULL != LinkedList->Data.Address32.ResourceSource.StringPtr) 29785587Sobrien { 29885587Sobrien SegmentSize += (1 + 29985587Sobrien LinkedList->Data.Address32.ResourceSource.StringLength); 30085587Sobrien } 30185587Sobrien break; 30285587Sobrien 30385587Sobrien case ACPI_RSTYPE_ADDRESS64: 30485587Sobrien /* 30585587Sobrien * 64-Bit Address Resource 30685587Sobrien * The base size of this byte stream is 46. If a Resource 30785587Sobrien * Source string is not NULL, add 1 for the Index + the 30885587Sobrien * length of the null terminated string Resource Source + 30985587Sobrien * 1 for the null. 31085587Sobrien */ 31185587Sobrien SegmentSize = 46; 31285587Sobrien 31385587Sobrien if (NULL != LinkedList->Data.Address64.ResourceSource.StringPtr) 31485587Sobrien { 31585587Sobrien SegmentSize += (1 + 31685587Sobrien LinkedList->Data.Address64.ResourceSource.StringLength); 31785587Sobrien } 31885587Sobrien break; 31985587Sobrien 32085587Sobrien case ACPI_RSTYPE_EXT_IRQ: 32185587Sobrien /* 32285587Sobrien * Extended IRQ Resource 32385587Sobrien * The base size of this byte stream is 9. This is for an 32485587Sobrien * Interrupt table length of 1. For each additional 32585587Sobrien * interrupt, add 4. 32685587Sobrien * If a Resource Source string is not NULL, add 1 for the 32785587Sobrien * Index + the length of the null terminated string 32885587Sobrien * Resource Source + 1 for the null. 32985587Sobrien */ 33085587Sobrien SegmentSize = 9 + 33185587Sobrien ((LinkedList->Data.ExtendedIrq.NumberOfInterrupts - 1) * 4); 33285587Sobrien 33385587Sobrien if (NULL != ExIrq->ResourceSource.StringPtr) 33485587Sobrien { 33585587Sobrien SegmentSize += (1 + 33685587Sobrien LinkedList->Data.ExtendedIrq.ResourceSource.StringLength); 33785587Sobrien } 33885587Sobrien break; 33985587Sobrien 34085587Sobrien default: 34185587Sobrien /* 34285587Sobrien * If we get here, everything is out of sync, 34385587Sobrien * so exit with an error 34485587Sobrien */ 34585587Sobrien return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE); 34685587Sobrien break; 34785587Sobrien 34885587Sobrien } /* switch (LinkedList->Id) */ 34985587Sobrien 35085587Sobrien /* 35185587Sobrien * Update the total 35285587Sobrien */ 35385587Sobrien ByteStreamSizeNeeded += SegmentSize; 35485587Sobrien 35585587Sobrien /* 35685587Sobrien * Point to the next object 35785587Sobrien */ 35885587Sobrien LinkedList = POINTER_ADD (ACPI_RESOURCE, 35985587Sobrien LinkedList, LinkedList->Length); 36085587Sobrien } 36185587Sobrien 36285587Sobrien /* 36385587Sobrien * This is the data the caller needs 36485587Sobrien */ 36585587Sobrien *SizeNeeded = ByteStreamSizeNeeded; 36685587Sobrien return_ACPI_STATUS (AE_OK); 36785587Sobrien} 36885587Sobrien 36985587Sobrien 37085587Sobrien/******************************************************************************* 37185587Sobrien * 37285587Sobrien * FUNCTION: AcpiRsCalculateListLength 37385587Sobrien * 37485587Sobrien * PARAMETERS: ByteStreamBuffer - Pointer to the resource byte stream 37585587Sobrien * ByteStreamBufferLength - Size of ByteStreamBuffer 37685587Sobrien * SizeNeeded - UINT32 pointer of the size buffer 37785587Sobrien * needed to properly return the 37885587Sobrien * parsed data 37985587Sobrien * 38085587Sobrien * RETURN: Status 38185587Sobrien * 38285587Sobrien * DESCRIPTION: Takes the resource byte stream and parses it once, calculating 38385587Sobrien * the size buffer needed to hold the linked list that conveys 38485587Sobrien * the resource data. 38585587Sobrien * 38685587Sobrien ******************************************************************************/ 38785587Sobrien 38885587SobrienACPI_STATUS 38985587SobrienAcpiRsCalculateListLength ( 39085587Sobrien UINT8 *ByteStreamBuffer, 39185587Sobrien UINT32 ByteStreamBufferLength, 39285587Sobrien UINT32 *SizeNeeded) 39385587Sobrien{ 39485587Sobrien UINT32 BufferSize = 0; 39585587Sobrien UINT32 BytesParsed = 0; 39685587Sobrien UINT8 NumberOfInterrupts = 0; 39785587Sobrien UINT8 NumberOfChannels = 0; 39885587Sobrien UINT8 ResourceType; 39985587Sobrien UINT32 StructureSize; 40085587Sobrien UINT32 BytesConsumed; 40185587Sobrien UINT8 *Buffer; 40285587Sobrien UINT8 Temp8; 40385587Sobrien UINT16 Temp16; 40485587Sobrien UINT8 Index; 40585587Sobrien UINT8 AdditionalBytes; 40685587Sobrien 40785587Sobrien 40885587Sobrien FUNCTION_TRACE ("RsCalculateListLength"); 40985587Sobrien 41085587Sobrien 41185587Sobrien while (BytesParsed < ByteStreamBufferLength) 41285587Sobrien { 41385587Sobrien /* 41485587Sobrien * The next byte in the stream is the resource type 41585587Sobrien */ 41685587Sobrien ResourceType = AcpiRsGetResourceType (*ByteStreamBuffer); 41785587Sobrien 41885587Sobrien switch (ResourceType) 41985587Sobrien { 42085587Sobrien case RESOURCE_DESC_MEMORY_24: 42185587Sobrien /* 42285587Sobrien * 24-Bit Memory Resource 42385587Sobrien */ 42485587Sobrien BytesConsumed = 12; 42585587Sobrien 42685587Sobrien StructureSize = SIZEOF_RESOURCE (ACPI_RESOURCE_MEM24); 42785587Sobrien break; 42885587Sobrien 42985587Sobrien 43085587Sobrien case RESOURCE_DESC_LARGE_VENDOR: 43185587Sobrien /* 43285587Sobrien * Vendor Defined Resource 43385587Sobrien */ 43485587Sobrien Buffer = ByteStreamBuffer; 43585587Sobrien ++Buffer; 43685587Sobrien 43785587Sobrien MOVE_UNALIGNED16_TO_16 (&Temp16, Buffer); 43885587Sobrien BytesConsumed = Temp16 + 3; 43985587Sobrien 44085587Sobrien /* 44185587Sobrien * Ensure a 32-bit boundary for the structure 44285587Sobrien */ 44385587Sobrien Temp16 = (UINT16) ROUND_UP_TO_32BITS (Temp16); 44485587Sobrien 44585587Sobrien StructureSize = SIZEOF_RESOURCE (ACPI_RESOURCE_VENDOR) + 44685587Sobrien (Temp16 * sizeof (UINT8)); 44785587Sobrien break; 44885587Sobrien 44985587Sobrien 45085587Sobrien case RESOURCE_DESC_MEMORY_32: 45185587Sobrien /* 45285587Sobrien * 32-Bit Memory Range Resource 45385587Sobrien */ 45485587Sobrien 45585587Sobrien BytesConsumed = 20; 45685587Sobrien 45785587Sobrien StructureSize = SIZEOF_RESOURCE (ACPI_RESOURCE_MEM32); 45885587Sobrien break; 45985587Sobrien 46085587Sobrien 46185587Sobrien case RESOURCE_DESC_FIXED_MEMORY_32: 46285587Sobrien /* 46385587Sobrien * 32-Bit Fixed Memory Resource 46485587Sobrien */ 46585587Sobrien BytesConsumed = 12; 46685587Sobrien 46785587Sobrien StructureSize = SIZEOF_RESOURCE (ACPI_RESOURCE_FIXED_MEM32); 46885587Sobrien break; 46985587Sobrien 47085587Sobrien 47185587Sobrien case RESOURCE_DESC_QWORD_ADDRESS_SPACE: 47285587Sobrien /* 47385587Sobrien * 64-Bit Address Resource 47485587Sobrien */ 47585587Sobrien Buffer = ByteStreamBuffer; 47685587Sobrien 47785587Sobrien ++Buffer; 47885587Sobrien MOVE_UNALIGNED16_TO_16 (&Temp16, Buffer); 47985587Sobrien 48085587Sobrien BytesConsumed = Temp16 + 3; 48185587Sobrien 48285587Sobrien /* 48385587Sobrien * Resource Source Index and Resource Source are 48485587Sobrien * optional elements. Check the length of the 48585587Sobrien * Bytestream. If it is greater than 43, that 48685587Sobrien * means that an Index exists and is followed by 48785587Sobrien * a null termininated string. Therefore, set 48885587Sobrien * the temp variable to the length minus the minimum 48985587Sobrien * byte stream length plus the byte for the Index to 49085587Sobrien * determine the size of the NULL terminiated string. 49185587Sobrien */ 49285587Sobrien if (43 < Temp16) 49385587Sobrien { 49485587Sobrien Temp8 = (UINT8) (Temp16 - 44); 49585587Sobrien } 49685587Sobrien else 49785587Sobrien { 49885587Sobrien Temp8 = 0; 49985587Sobrien } 50085587Sobrien 50185587Sobrien /* 50285587Sobrien * Ensure a 64-bit boundary for the structure 50385587Sobrien */ 50485587Sobrien Temp8 = (UINT8) ROUND_UP_TO_64BITS (Temp8); 50585587Sobrien 50685587Sobrien StructureSize = SIZEOF_RESOURCE (ACPI_RESOURCE_ADDRESS64) + 50785587Sobrien (Temp8 * sizeof (UINT8)); 50885587Sobrien break; 50985587Sobrien 51085587Sobrien 51185587Sobrien case RESOURCE_DESC_DWORD_ADDRESS_SPACE: 51285587Sobrien /* 51385587Sobrien * 32-Bit Address Resource 51485587Sobrien */ 51585587Sobrien Buffer = ByteStreamBuffer; 51685587Sobrien 51785587Sobrien ++Buffer; 51885587Sobrien MOVE_UNALIGNED16_TO_16 (&Temp16, Buffer); 51985587Sobrien 52085587Sobrien BytesConsumed = Temp16 + 3; 52185587Sobrien 52285587Sobrien /* 52385587Sobrien * Resource Source Index and Resource Source are 52485587Sobrien * optional elements. Check the length of the 52585587Sobrien * Bytestream. If it is greater than 23, that 52685587Sobrien * means that an Index exists and is followed by 52785587Sobrien * a null termininated string. Therefore, set 52885587Sobrien * the temp variable to the length minus the minimum 52985587Sobrien * byte stream length plus the byte for the Index to 530 * determine the size of the NULL terminiated string. 531 */ 532 if (23 < Temp16) 533 { 534 Temp8 = (UINT8) (Temp16 - 24); 535 } 536 else 537 { 538 Temp8 = 0; 539 } 540 541 /* 542 * Ensure a 32-bit boundary for the structure 543 */ 544 Temp8 = (UINT8) ROUND_UP_TO_32BITS (Temp8); 545 546 StructureSize = SIZEOF_RESOURCE (ACPI_RESOURCE_ADDRESS32) + 547 (Temp8 * sizeof (UINT8)); 548 break; 549 550 551 case RESOURCE_DESC_WORD_ADDRESS_SPACE: 552 /* 553 * 16-Bit Address Resource 554 */ 555 Buffer = ByteStreamBuffer; 556 557 ++Buffer; 558 MOVE_UNALIGNED16_TO_16 (&Temp16, Buffer); 559 560 BytesConsumed = Temp16 + 3; 561 562 /* 563 * Resource Source Index and Resource Source are 564 * optional elements. Check the length of the 565 * Bytestream. If it is greater than 13, that 566 * means that an Index exists and is followed by 567 * a null termininated string. Therefore, set 568 * the temp variable to the length minus the minimum 569 * byte stream length plus the byte for the Index to 570 * determine the size of the NULL terminiated string. 571 */ 572 if (13 < Temp16) 573 { 574 Temp8 = (UINT8) (Temp16 - 14); 575 } 576 else 577 { 578 Temp8 = 0; 579 } 580 581 /* 582 * Ensure a 32-bit boundary for the structure 583 */ 584 Temp8 = (UINT8) ROUND_UP_TO_32BITS (Temp8); 585 586 StructureSize = SIZEOF_RESOURCE (ACPI_RESOURCE_ADDRESS16) + 587 (Temp8 * sizeof (UINT8)); 588 break; 589 590 591 case RESOURCE_DESC_EXTENDED_XRUPT: 592 /* 593 * Extended IRQ 594 */ 595 Buffer = ByteStreamBuffer; 596 597 ++Buffer; 598 MOVE_UNALIGNED16_TO_16 (&Temp16, Buffer); 599 600 BytesConsumed = Temp16 + 3; 601 602 /* 603 * Point past the length field and the 604 * Interrupt vector flags to save off the 605 * Interrupt table length to the Temp8 variable. 606 */ 607 Buffer += 3; 608 Temp8 = *Buffer; 609 610 /* 611 * To compensate for multiple interrupt numbers, add 4 bytes for 612 * each additional interrupts greater than 1 613 */ 614 AdditionalBytes = (UINT8) ((Temp8 - 1) * 4); 615 616 /* 617 * Resource Source Index and Resource Source are 618 * optional elements. Check the length of the 619 * Bytestream. If it is greater than 9, that 620 * means that an Index exists and is followed by 621 * a null termininated string. Therefore, set 622 * the temp variable to the length minus the minimum 623 * byte stream length plus the byte for the Index to 624 * determine the size of the NULL terminiated string. 625 */ 626 if (9 + AdditionalBytes < Temp16) 627 { 628 Temp8 = (UINT8) (Temp16 - (9 + AdditionalBytes)); 629 } 630 631 else 632 { 633 Temp8 = 0; 634 } 635 636 /* 637 * Ensure a 32-bit boundary for the structure 638 */ 639 Temp8 = (UINT8) ROUND_UP_TO_32BITS (Temp8); 640 641 StructureSize = SIZEOF_RESOURCE (ACPI_RESOURCE_EXT_IRQ) + 642 (AdditionalBytes * sizeof (UINT8)) + 643 (Temp8 * sizeof (UINT8)); 644 break; 645 646 647 case RESOURCE_DESC_IRQ_FORMAT: 648 /* 649 * IRQ Resource. 650 * Determine if it there are two or three trailing bytes 651 */ 652 Buffer = ByteStreamBuffer; 653 Temp8 = *Buffer; 654 655 if(Temp8 & 0x01) 656 { 657 BytesConsumed = 4; 658 } 659 660 else 661 { 662 BytesConsumed = 3; 663 } 664 665 /* 666 * Point past the descriptor 667 */ 668 ++Buffer; 669 670 /* 671 * Look at the number of bits set 672 */ 673 MOVE_UNALIGNED16_TO_16 (&Temp16, Buffer); 674 675 for (Index = 0; Index < 16; Index++) 676 { 677 if (Temp16 & 0x1) 678 { 679 ++NumberOfInterrupts; 680 } 681 682 Temp16 >>= 1; 683 } 684 685 StructureSize = SIZEOF_RESOURCE (ACPI_RESOURCE_IO) + 686 (NumberOfInterrupts * sizeof (UINT32)); 687 break; 688 689 690 case RESOURCE_DESC_DMA_FORMAT: 691 /* 692 * DMA Resource 693 */ 694 Buffer = ByteStreamBuffer; 695 BytesConsumed = 3; 696 697 /* 698 * Point past the descriptor 699 */ 700 ++Buffer; 701 702 /* 703 * Look at the number of bits set 704 */ 705 Temp8 = *Buffer; 706 707 for(Index = 0; Index < 8; Index++) 708 { 709 if(Temp8 & 0x1) 710 { 711 ++NumberOfChannels; 712 } 713 714 Temp8 >>= 1; 715 } 716 717 StructureSize = SIZEOF_RESOURCE (ACPI_RESOURCE_DMA) + 718 (NumberOfChannels * sizeof (UINT32)); 719 break; 720 721 722 case RESOURCE_DESC_START_DEPENDENT: 723 /* 724 * Start Dependent Functions Resource 725 * Determine if it there are two or three trailing bytes 726 */ 727 Buffer = ByteStreamBuffer; 728 Temp8 = *Buffer; 729 730 if(Temp8 & 0x01) 731 { 732 BytesConsumed = 2; 733 } 734 else 735 { 736 BytesConsumed = 1; 737 } 738 739 StructureSize = SIZEOF_RESOURCE (ACPI_RESOURCE_START_DPF); 740 break; 741 742 743 case RESOURCE_DESC_END_DEPENDENT: 744 /* 745 * End Dependent Functions Resource 746 */ 747 BytesConsumed = 1; 748 StructureSize = ACPI_RESOURCE_LENGTH; 749 break; 750 751 752 case RESOURCE_DESC_IO_PORT: 753 /* 754 * IO Port Resource 755 */ 756 BytesConsumed = 8; 757 StructureSize = SIZEOF_RESOURCE (ACPI_RESOURCE_IO); 758 break; 759 760 761 case RESOURCE_DESC_FIXED_IO_PORT: 762 /* 763 * Fixed IO Port Resource 764 */ 765 BytesConsumed = 4; 766 StructureSize = SIZEOF_RESOURCE (ACPI_RESOURCE_FIXED_IO); 767 break; 768 769 770 case RESOURCE_DESC_SMALL_VENDOR: 771 /* 772 * Vendor Specific Resource 773 */ 774 Buffer = ByteStreamBuffer; 775 776 Temp8 = *Buffer; 777 Temp8 = (UINT8) (Temp8 & 0x7); 778 BytesConsumed = Temp8 + 1; 779 780 /* 781 * Ensure a 32-bit boundary for the structure 782 */ 783 Temp8 = (UINT8) ROUND_UP_TO_32BITS (Temp8); 784 StructureSize = SIZEOF_RESOURCE (ACPI_RESOURCE_VENDOR) + 785 (Temp8 * sizeof (UINT8)); 786 break; 787 788 789 case RESOURCE_DESC_END_TAG: 790 /* 791 * End Tag 792 */ 793 BytesConsumed = 2; 794 StructureSize = ACPI_RESOURCE_LENGTH; 795 ByteStreamBufferLength = BytesParsed; 796 break; 797 798 799 default: 800 /* 801 * If we get here, everything is out of sync, 802 * so exit with an error 803 */ 804 return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE); 805 break; 806 } 807 808 809 /* 810 * Update the return value and counter 811 */ 812 BufferSize += StructureSize; 813 BytesParsed += BytesConsumed; 814 815 /* 816 * Set the byte stream to point to the next resource 817 */ 818 ByteStreamBuffer += BytesConsumed; 819 } 820 821 822 /* 823 * This is the data the caller needs 824 */ 825 *SizeNeeded = BufferSize; 826 return_ACPI_STATUS (AE_OK); 827} 828 829 830/******************************************************************************* 831 * 832 * FUNCTION: AcpiRsCalculatePciRoutingTableLength 833 * 834 * PARAMETERS: PackageObject - Pointer to the package object 835 * BufferSizeNeeded - UINT32 pointer of the size buffer 836 * needed to properly return the 837 * parsed data 838 * 839 * RETURN: Status 840 * 841 * DESCRIPTION: Given a package representing a PCI routing table, this 842 * calculates the size of the corresponding linked list of 843 * descriptions. 844 * 845 ******************************************************************************/ 846 847ACPI_STATUS 848AcpiRsCalculatePciRoutingTableLength ( 849 ACPI_OPERAND_OBJECT *PackageObject, 850 UINT32 *BufferSizeNeeded) 851{ 852 UINT32 NumberOfElements; 853 UINT32 TempSizeNeeded = 0; 854 ACPI_OPERAND_OBJECT **TopObjectList; 855 UINT32 Index; 856 ACPI_OPERAND_OBJECT *PackageElement; 857 ACPI_OPERAND_OBJECT **SubObjectList; 858 BOOLEAN NameFound; 859 UINT32 TableIndex; 860 861 862 FUNCTION_TRACE ("AcpiRsCalculatePciRoutingTableLength"); 863 864 865 NumberOfElements = PackageObject->Package.Count; 866 867 /* 868 * Calculate the size of the return buffer. 869 * The base size is the number of elements * the sizes of the 870 * structures. Additional space for the strings is added below. 871 * The minus one is to subtract the size of the UINT8 Source[1] 872 * member because it is added below. 873 * 874 * But each PRT_ENTRY structure has a pointer to a string and 875 * the size of that string must be found. 876 */ 877 TopObjectList = PackageObject->Package.Elements; 878 879 for (Index = 0; Index < NumberOfElements; Index++) 880 { 881 /* 882 * Dereference the sub-package 883 */ 884 PackageElement = *TopObjectList; 885 886 /* 887 * The SubObjectList will now point to an array of the 888 * four IRQ elements: Address, Pin, Source and SourceIndex 889 */ 890 SubObjectList = PackageElement->Package.Elements; 891 892 /* 893 * Scan the IrqTableElements for the Source Name String 894 */ 895 NameFound = FALSE; 896 897 for (TableIndex = 0; TableIndex < 4 && !NameFound; TableIndex++) 898 { 899 if ((ACPI_TYPE_STRING == (*SubObjectList)->Common.Type) || 900 ((INTERNAL_TYPE_REFERENCE == (*SubObjectList)->Common.Type) && 901 ((*SubObjectList)->Reference.Opcode == AML_INT_NAMEPATH_OP))) 902 { 903 NameFound = TRUE; 904 } 905 906 else 907 { 908 /* 909 * Look at the next element 910 */ 911 SubObjectList++; 912 } 913 } 914 915 TempSizeNeeded += (sizeof (PCI_ROUTING_TABLE) - 4); 916 917 /* 918 * Was a String type found? 919 */ 920 if (TRUE == NameFound) 921 { 922 if (ACPI_TYPE_STRING == (*SubObjectList)->Common.Type) 923 { 924 /* 925 * The length String.Length field includes the 926 * terminating NULL 927 */ 928 TempSizeNeeded += (*SubObjectList)->String.Length; 929 } 930 931 else 932 { 933 TempSizeNeeded += AcpiNsGetPathnameLength ( 934 (*SubObjectList)->Reference.Node); 935 } 936 } 937 938 else 939 { 940 /* 941 * If no name was found, then this is a NULL, which is 942 * translated as a UINT32 zero. 943 */ 944 TempSizeNeeded += sizeof (UINT32); 945 } 946 947 /* Round up the size since each element must be aligned */ 948 949 TempSizeNeeded = ROUND_UP_TO_64BITS (TempSizeNeeded); 950 951 /* 952 * Point to the next ACPI_OPERAND_OBJECT 953 */ 954 TopObjectList++; 955 } 956 957 958 /* 959 * Adding an extra element to the end of the list, essentially a NULL terminator 960 */ 961 *BufferSizeNeeded = TempSizeNeeded + sizeof (PCI_ROUTING_TABLE); 962 return_ACPI_STATUS (AE_OK); 963} 964