rscalc.c revision 77424
167754Smsmith/******************************************************************************* 267754Smsmith * 377424Smsmith * Module Name: rscalc - Calculate stream and list lengths 477424Smsmith * $Revision: 30 $ 567754Smsmith * 667754Smsmith ******************************************************************************/ 767754Smsmith 867754Smsmith/****************************************************************************** 967754Smsmith * 1067754Smsmith * 1. Copyright Notice 1167754Smsmith * 1271867Smsmith * Some or all of this work - Copyright (c) 1999, 2000, 2001, Intel Corp. 1370243Smsmith * All rights reserved. 1467754Smsmith * 1567754Smsmith * 2. License 1667754Smsmith * 1767754Smsmith * 2.1. This is your license from Intel Corp. under its intellectual property 1867754Smsmith * rights. You may have additional license terms from the party that provided 1967754Smsmith * you this software, covering your right to use that party's intellectual 2067754Smsmith * property rights. 2167754Smsmith * 2267754Smsmith * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 2367754Smsmith * copy of the source code appearing in this file ("Covered Code") an 2467754Smsmith * irrevocable, perpetual, worldwide license under Intel's copyrights in the 2567754Smsmith * base code distributed originally by Intel ("Original Intel Code") to copy, 2667754Smsmith * make derivatives, distribute, use and display any portion of the Covered 2767754Smsmith * Code in any form, with the right to sublicense such rights; and 2867754Smsmith * 2967754Smsmith * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 3067754Smsmith * license (with the right to sublicense), under only those claims of Intel 3167754Smsmith * patents that are infringed by the Original Intel Code, to make, use, sell, 3267754Smsmith * offer to sell, and import the Covered Code and derivative works thereof 3367754Smsmith * solely to the minimum extent necessary to exercise the above copyright 3467754Smsmith * license, and in no event shall the patent license extend to any additions 3567754Smsmith * to or modifications of the Original Intel Code. No other license or right 3667754Smsmith * is granted directly or by implication, estoppel or otherwise; 3767754Smsmith * 3867754Smsmith * The above copyright and patent license is granted only if the following 3967754Smsmith * conditions are met: 4067754Smsmith * 4167754Smsmith * 3. Conditions 4267754Smsmith * 4367754Smsmith * 3.1. Redistribution of Source with Rights to Further Distribute Source. 4467754Smsmith * Redistribution of source code of any substantial portion of the Covered 4567754Smsmith * Code or modification with rights to further distribute source must include 4667754Smsmith * the above Copyright Notice, the above License, this list of Conditions, 4767754Smsmith * and the following Disclaimer and Export Compliance provision. In addition, 4867754Smsmith * Licensee must cause all Covered Code to which Licensee contributes to 4967754Smsmith * contain a file documenting the changes Licensee made to create that Covered 5067754Smsmith * Code and the date of any change. Licensee must include in that file the 5167754Smsmith * documentation of any changes made by any predecessor Licensee. Licensee 5267754Smsmith * must include a prominent statement that the modification is derived, 5367754Smsmith * directly or indirectly, from Original Intel Code. 5467754Smsmith * 5567754Smsmith * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 5667754Smsmith * Redistribution of source code of any substantial portion of the Covered 5767754Smsmith * Code or modification without rights to further distribute source must 5867754Smsmith * include the following Disclaimer and Export Compliance provision in the 5967754Smsmith * documentation and/or other materials provided with distribution. In 6067754Smsmith * addition, Licensee may not authorize further sublicense of source of any 6167754Smsmith * portion of the Covered Code, and must include terms to the effect that the 6267754Smsmith * license from Licensee to its licensee is limited to the intellectual 6367754Smsmith * property embodied in the software Licensee provides to its licensee, and 6467754Smsmith * not to intellectual property embodied in modifications its licensee may 6567754Smsmith * make. 6667754Smsmith * 6767754Smsmith * 3.3. Redistribution of Executable. Redistribution in executable form of any 6867754Smsmith * substantial portion of the Covered Code or modification must reproduce the 6967754Smsmith * above Copyright Notice, and the following Disclaimer and Export Compliance 7067754Smsmith * provision in the documentation and/or other materials provided with the 7167754Smsmith * distribution. 7267754Smsmith * 7367754Smsmith * 3.4. Intel retains all right, title, and interest in and to the Original 7467754Smsmith * Intel Code. 7567754Smsmith * 7667754Smsmith * 3.5. Neither the name Intel nor any other trademark owned or controlled by 7767754Smsmith * Intel shall be used in advertising or otherwise to promote the sale, use or 7867754Smsmith * other dealings in products derived from or relating to the Covered Code 7967754Smsmith * without prior written authorization from Intel. 8067754Smsmith * 8167754Smsmith * 4. Disclaimer and Export Compliance 8267754Smsmith * 8367754Smsmith * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 8467754Smsmith * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 8567754Smsmith * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 8667754Smsmith * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 8767754Smsmith * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 8867754Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 8967754Smsmith * PARTICULAR PURPOSE. 9067754Smsmith * 9167754Smsmith * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 9267754Smsmith * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 9367754Smsmith * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 9467754Smsmith * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 9567754Smsmith * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 9667754Smsmith * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 9767754Smsmith * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 9867754Smsmith * LIMITED REMEDY. 9967754Smsmith * 10067754Smsmith * 4.3. Licensee shall not export, either directly or indirectly, any of this 10167754Smsmith * software or system incorporating such software without first obtaining any 10267754Smsmith * required license or other approval from the U. S. Department of Commerce or 10367754Smsmith * any other agency or department of the United States Government. In the 10467754Smsmith * event Licensee exports any such software from the United States or 10567754Smsmith * re-exports any such software from a foreign destination, Licensee shall 10667754Smsmith * ensure that the distribution and export/re-export of the software is in 10767754Smsmith * compliance with all laws, regulations, orders, or other restrictions of the 10867754Smsmith * U.S. Export Administration Regulations. Licensee agrees that neither it nor 10967754Smsmith * any of its subsidiaries will export/re-export any technical data, process, 11067754Smsmith * software, or service, directly or indirectly, to any country for which the 11167754Smsmith * United States government or any agency thereof requires an export license, 11267754Smsmith * other governmental approval, or letter of assurance, without first obtaining 11367754Smsmith * such license, approval or letter. 11467754Smsmith * 11567754Smsmith *****************************************************************************/ 11667754Smsmith 11767754Smsmith#define __RSCALC_C__ 11867754Smsmith 11967754Smsmith#include "acpi.h" 12069450Smsmith#include "acresrc.h" 12173561Smsmith#include "amlcode.h" 12273561Smsmith#include "acnamesp.h" 12367754Smsmith 12477424Smsmith#define _COMPONENT ACPI_RESOURCES 12567754Smsmith MODULE_NAME ("rscalc") 12667754Smsmith 12767754Smsmith 12867754Smsmith/******************************************************************************* 12967754Smsmith * 13067754Smsmith * FUNCTION: AcpiRsCalculateByteStreamLength 13167754Smsmith * 13267754Smsmith * PARAMETERS: LinkedList - Pointer to the resource linked list 13367754Smsmith * SizeNeeded - UINT32 pointer of the size buffer needed 13477424Smsmith * to properly return the parsed data 13567754Smsmith * 13677424Smsmith * RETURN: Status 13767754Smsmith * 13867754Smsmith * DESCRIPTION: Takes the resource byte stream and parses it once, calculating 13967754Smsmith * the size buffer needed to hold the linked list that conveys 14067754Smsmith * the resource data. 14167754Smsmith * 14267754Smsmith ******************************************************************************/ 14367754Smsmith 14467754SmsmithACPI_STATUS 14567754SmsmithAcpiRsCalculateByteStreamLength ( 14677424Smsmith ACPI_RESOURCE *LinkedList, 14767754Smsmith UINT32 *SizeNeeded) 14867754Smsmith{ 14967754Smsmith UINT32 ByteStreamSizeNeeded = 0; 15067754Smsmith UINT32 SegmentSize; 15177424Smsmith ACPI_RESOURCE_EXT_IRQ *ExIrq = NULL; 15267754Smsmith BOOLEAN Done = FALSE; 15367754Smsmith 15467754Smsmith 15567754Smsmith FUNCTION_TRACE ("RsCalculateByteStreamLength"); 15667754Smsmith 15767754Smsmith 15867754Smsmith while (!Done) 15967754Smsmith { 16067754Smsmith /* 16177424Smsmith * Init the variable that will hold the size to add to the total. 16267754Smsmith */ 16367754Smsmith SegmentSize = 0; 16467754Smsmith 16567754Smsmith switch (LinkedList->Id) 16667754Smsmith { 16777424Smsmith case ACPI_RSTYPE_IRQ: 16867754Smsmith /* 16967754Smsmith * IRQ Resource 17067754Smsmith * For an IRQ Resource, Byte 3, although optional, will 17177424Smsmith * always be created - it holds IRQ information. 17267754Smsmith */ 17367754Smsmith SegmentSize = 4; 17467754Smsmith break; 17567754Smsmith 17677424Smsmith case ACPI_RSTYPE_DMA: 17767754Smsmith /* 17867754Smsmith * DMA Resource 17967754Smsmith * For this resource the size is static 18067754Smsmith */ 18167754Smsmith SegmentSize = 3; 18267754Smsmith break; 18367754Smsmith 18477424Smsmith case ACPI_RSTYPE_START_DPF: 18567754Smsmith /* 18667754Smsmith * Start Dependent Functions Resource 18767754Smsmith * For a StartDependentFunctions Resource, Byte 1, 18867754Smsmith * although optional, will always be created. 18967754Smsmith */ 19067754Smsmith SegmentSize = 2; 19167754Smsmith break; 19267754Smsmith 19377424Smsmith case ACPI_RSTYPE_END_DPF: 19467754Smsmith /* 19567754Smsmith * End Dependent Functions Resource 19667754Smsmith * For this resource the size is static 19767754Smsmith */ 19867754Smsmith SegmentSize = 1; 19967754Smsmith break; 20067754Smsmith 20177424Smsmith case ACPI_RSTYPE_IO: 20267754Smsmith /* 20367754Smsmith * IO Port Resource 20467754Smsmith * For this resource the size is static 20567754Smsmith */ 20667754Smsmith SegmentSize = 8; 20767754Smsmith break; 20867754Smsmith 20977424Smsmith case ACPI_RSTYPE_FIXED_IO: 21067754Smsmith /* 21167754Smsmith * Fixed IO Port Resource 21267754Smsmith * For this resource the size is static 21367754Smsmith */ 21467754Smsmith SegmentSize = 4; 21567754Smsmith break; 21667754Smsmith 21777424Smsmith case ACPI_RSTYPE_VENDOR: 21867754Smsmith /* 21967754Smsmith * Vendor Defined Resource 22067754Smsmith * For a Vendor Specific resource, if the Length is 22177424Smsmith * between 1 and 7 it will be created as a Small 22277424Smsmith * Resource data type, otherwise it is a Large 22377424Smsmith * Resource data type. 22467754Smsmith */ 22577424Smsmith if (LinkedList->Data.VendorSpecific.Length > 7) 22667754Smsmith { 22767754Smsmith SegmentSize = 3; 22867754Smsmith } 22967754Smsmith else 23067754Smsmith { 23167754Smsmith SegmentSize = 1; 23267754Smsmith } 23377424Smsmith SegmentSize += LinkedList->Data.VendorSpecific.Length; 23467754Smsmith break; 23567754Smsmith 23677424Smsmith case ACPI_RSTYPE_END_TAG: 23767754Smsmith /* 23867754Smsmith * End Tag 23967754Smsmith * For this resource the size is static 24067754Smsmith */ 24167754Smsmith SegmentSize = 2; 24267754Smsmith Done = TRUE; 24367754Smsmith break; 24467754Smsmith 24577424Smsmith case ACPI_RSTYPE_MEM24: 24667754Smsmith /* 24767754Smsmith * 24-Bit Memory Resource 24867754Smsmith * For this resource the size is static 24967754Smsmith */ 25067754Smsmith SegmentSize = 12; 25167754Smsmith break; 25267754Smsmith 25377424Smsmith case ACPI_RSTYPE_MEM32: 25467754Smsmith /* 25567754Smsmith * 32-Bit Memory Range Resource 25667754Smsmith * For this resource the size is static 25767754Smsmith */ 25867754Smsmith SegmentSize = 20; 25967754Smsmith break; 26067754Smsmith 26177424Smsmith case ACPI_RSTYPE_FIXED_MEM32: 26267754Smsmith /* 26367754Smsmith * 32-Bit Fixed Memory Resource 26467754Smsmith * For this resource the size is static 26567754Smsmith */ 26667754Smsmith SegmentSize = 12; 26767754Smsmith break; 26867754Smsmith 26977424Smsmith case ACPI_RSTYPE_ADDRESS16: 27067754Smsmith /* 27167754Smsmith * 16-Bit Address Resource 27267754Smsmith * The base size of this byte stream is 16. If a 27377424Smsmith * Resource Source string is not NULL, add 1 for 27477424Smsmith * the Index + the length of the null terminated 27577424Smsmith * string Resource Source + 1 for the null. 27667754Smsmith */ 27767754Smsmith SegmentSize = 16; 27867754Smsmith 27977424Smsmith if (NULL != LinkedList->Data.Address16.ResourceSource.StringPtr) 28067754Smsmith { 28167754Smsmith SegmentSize += (1 + 28277424Smsmith LinkedList->Data.Address16.ResourceSource.StringLength); 28367754Smsmith } 28467754Smsmith break; 28567754Smsmith 28677424Smsmith case ACPI_RSTYPE_ADDRESS32: 28767754Smsmith /* 28867754Smsmith * 32-Bit Address Resource 28967754Smsmith * The base size of this byte stream is 26. If a Resource 29077424Smsmith * Source string is not NULL, add 1 for the Index + the 29177424Smsmith * length of the null terminated string Resource Source + 29277424Smsmith * 1 for the null. 29367754Smsmith */ 29467754Smsmith SegmentSize = 26; 29567754Smsmith 29677424Smsmith if (NULL != LinkedList->Data.Address32.ResourceSource.StringPtr) 29767754Smsmith { 29867754Smsmith SegmentSize += (1 + 29977424Smsmith LinkedList->Data.Address32.ResourceSource.StringLength); 30067754Smsmith } 30167754Smsmith break; 30267754Smsmith 30377424Smsmith case ACPI_RSTYPE_ADDRESS64: 30467754Smsmith /* 30577424Smsmith * 64-Bit Address Resource 30677424Smsmith * The base size of this byte stream is 46. If a Resource 30777424Smsmith * Source string is not NULL, add 1 for the Index + the 30877424Smsmith * length of the null terminated string Resource Source + 30977424Smsmith * 1 for the null. 31067754Smsmith */ 31177424Smsmith SegmentSize = 46; 31277424Smsmith 31377424Smsmith if (NULL != LinkedList->Data.Address64.ResourceSource.StringPtr) 31477424Smsmith { 31577424Smsmith SegmentSize += (1 + 31677424Smsmith LinkedList->Data.Address64.ResourceSource.StringLength); 31777424Smsmith } 31877424Smsmith break; 31977424Smsmith 32077424Smsmith case ACPI_RSTYPE_EXT_IRQ: 32167754Smsmith /* 32277424Smsmith * Extended IRQ Resource 32367754Smsmith * The base size of this byte stream is 9. This is for an 32477424Smsmith * Interrupt table length of 1. For each additional 32577424Smsmith * interrupt, add 4. 32667754Smsmith * If a Resource Source string is not NULL, add 1 for the 32777424Smsmith * Index + the length of the null terminated string 32877424Smsmith * Resource Source + 1 for the null. 32967754Smsmith */ 33077424Smsmith SegmentSize = 9 + 33177424Smsmith ((LinkedList->Data.ExtendedIrq.NumberOfInterrupts - 1) * 4); 33267754Smsmith 33377424Smsmith if (NULL != ExIrq->ResourceSource.StringPtr) 33467754Smsmith { 33567754Smsmith SegmentSize += (1 + 33677424Smsmith LinkedList->Data.ExtendedIrq.ResourceSource.StringLength); 33767754Smsmith } 33867754Smsmith break; 33967754Smsmith 34067754Smsmith default: 34167754Smsmith /* 34267754Smsmith * If we get here, everything is out of sync, 34377424Smsmith * so exit with an error 34467754Smsmith */ 34577424Smsmith return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE); 34667754Smsmith break; 34767754Smsmith 34867754Smsmith } /* switch (LinkedList->Id) */ 34967754Smsmith 35067754Smsmith /* 35167754Smsmith * Update the total 35267754Smsmith */ 35367754Smsmith ByteStreamSizeNeeded += SegmentSize; 35467754Smsmith 35567754Smsmith /* 35667754Smsmith * Point to the next object 35767754Smsmith */ 35877424Smsmith LinkedList = POINTER_ADD (ACPI_RESOURCE, 35977424Smsmith LinkedList, LinkedList->Length); 36067754Smsmith } 36167754Smsmith 36267754Smsmith /* 36367754Smsmith * This is the data the caller needs 36467754Smsmith */ 36567754Smsmith *SizeNeeded = ByteStreamSizeNeeded; 36667754Smsmith return_ACPI_STATUS (AE_OK); 36767754Smsmith} 36867754Smsmith 36967754Smsmith 37067754Smsmith/******************************************************************************* 37167754Smsmith * 37267754Smsmith * FUNCTION: AcpiRsCalculateListLength 37367754Smsmith * 37467754Smsmith * PARAMETERS: ByteStreamBuffer - Pointer to the resource byte stream 37567754Smsmith * ByteStreamBufferLength - Size of ByteStreamBuffer 37667754Smsmith * SizeNeeded - UINT32 pointer of the size buffer 37777424Smsmith * needed to properly return the 37877424Smsmith * parsed data 37967754Smsmith * 38077424Smsmith * RETURN: Status 38167754Smsmith * 38267754Smsmith * DESCRIPTION: Takes the resource byte stream and parses it once, calculating 38367754Smsmith * the size buffer needed to hold the linked list that conveys 38467754Smsmith * the resource data. 38567754Smsmith * 38667754Smsmith ******************************************************************************/ 38767754Smsmith 38867754SmsmithACPI_STATUS 38967754SmsmithAcpiRsCalculateListLength ( 39067754Smsmith UINT8 *ByteStreamBuffer, 39167754Smsmith UINT32 ByteStreamBufferLength, 39267754Smsmith UINT32 *SizeNeeded) 39367754Smsmith{ 39467754Smsmith UINT32 BufferSize = 0; 39567754Smsmith UINT32 BytesParsed = 0; 39667754Smsmith UINT8 NumberOfInterrupts = 0; 39767754Smsmith UINT8 NumberOfChannels = 0; 39867754Smsmith UINT8 ResourceType; 39967754Smsmith UINT32 StructureSize; 40067754Smsmith UINT32 BytesConsumed; 40167754Smsmith UINT8 *Buffer; 40267754Smsmith UINT8 Temp8; 40367754Smsmith UINT16 Temp16; 40467754Smsmith UINT8 Index; 40567754Smsmith UINT8 AdditionalBytes; 40667754Smsmith 40767754Smsmith 40867754Smsmith FUNCTION_TRACE ("RsCalculateListLength"); 40967754Smsmith 41067754Smsmith 41167754Smsmith while (BytesParsed < ByteStreamBufferLength) 41267754Smsmith { 41367754Smsmith /* 41477424Smsmith * The next byte in the stream is the resource type 41567754Smsmith */ 41677424Smsmith ResourceType = AcpiRsGetResourceType (*ByteStreamBuffer); 41767754Smsmith 41877424Smsmith switch (ResourceType) 41967754Smsmith { 42077424Smsmith case RESOURCE_DESC_MEMORY_24: 42167754Smsmith /* 42277424Smsmith * 24-Bit Memory Resource 42367754Smsmith */ 42477424Smsmith BytesConsumed = 12; 42567754Smsmith 42677424Smsmith StructureSize = SIZEOF_RESOURCE (ACPI_RESOURCE_MEM24); 42777424Smsmith break; 42867754Smsmith 42967754Smsmith 43077424Smsmith case RESOURCE_DESC_LARGE_VENDOR: 43177424Smsmith /* 43277424Smsmith * Vendor Defined Resource 43377424Smsmith */ 43477424Smsmith Buffer = ByteStreamBuffer; 43577424Smsmith ++Buffer; 43667754Smsmith 43777424Smsmith MOVE_UNALIGNED16_TO_16 (&Temp16, Buffer); 43877424Smsmith BytesConsumed = Temp16 + 3; 43967754Smsmith 44077424Smsmith /* 44177424Smsmith * Ensure a 32-bit boundary for the structure 44277424Smsmith */ 44377424Smsmith Temp16 = (UINT16) ROUND_UP_TO_32BITS (Temp16); 44477424Smsmith 44577424Smsmith StructureSize = SIZEOF_RESOURCE (ACPI_RESOURCE_VENDOR) + 44667754Smsmith (Temp16 * sizeof (UINT8)); 44777424Smsmith break; 44867754Smsmith 44967754Smsmith 45077424Smsmith case RESOURCE_DESC_MEMORY_32: 45177424Smsmith /* 45277424Smsmith * 32-Bit Memory Range Resource 45377424Smsmith */ 45467754Smsmith 45577424Smsmith BytesConsumed = 20; 45667754Smsmith 45777424Smsmith StructureSize = SIZEOF_RESOURCE (ACPI_RESOURCE_MEM32); 45877424Smsmith break; 45967754Smsmith 46067754Smsmith 46177424Smsmith case RESOURCE_DESC_FIXED_MEMORY_32: 46277424Smsmith /* 46377424Smsmith * 32-Bit Fixed Memory Resource 46477424Smsmith */ 46577424Smsmith BytesConsumed = 12; 46667754Smsmith 46777424Smsmith StructureSize = SIZEOF_RESOURCE (ACPI_RESOURCE_FIXED_MEM32); 46877424Smsmith break; 46967754Smsmith 47067754Smsmith 47177424Smsmith case RESOURCE_DESC_QWORD_ADDRESS_SPACE: 47277424Smsmith /* 47377424Smsmith * 64-Bit Address Resource 47477424Smsmith */ 47577424Smsmith Buffer = ByteStreamBuffer; 47667754Smsmith 47777424Smsmith ++Buffer; 47877424Smsmith MOVE_UNALIGNED16_TO_16 (&Temp16, Buffer); 47967754Smsmith 48077424Smsmith BytesConsumed = Temp16 + 3; 48167754Smsmith 48277424Smsmith /* 48377424Smsmith * Resource Source Index and Resource Source are 48477424Smsmith * optional elements. Check the length of the 48577424Smsmith * Bytestream. If it is greater than 43, that 48677424Smsmith * means that an Index exists and is followed by 48777424Smsmith * a null termininated string. Therefore, set 48877424Smsmith * the temp variable to the length minus the minimum 48977424Smsmith * byte stream length plus the byte for the Index to 49077424Smsmith * determine the size of the NULL terminiated string. 49177424Smsmith */ 49277424Smsmith if (43 < Temp16) 49377424Smsmith { 49477424Smsmith Temp8 = (UINT8) (Temp16 - 44); 49577424Smsmith } 49677424Smsmith else 49777424Smsmith { 49877424Smsmith Temp8 = 0; 49977424Smsmith } 50067754Smsmith 50177424Smsmith /* 50277424Smsmith * Ensure a 64-bit boundary for the structure 50377424Smsmith */ 50477424Smsmith Temp8 = (UINT8) ROUND_UP_TO_64BITS (Temp8); 50567754Smsmith 50677424Smsmith StructureSize = SIZEOF_RESOURCE (ACPI_RESOURCE_ADDRESS64) + 50777424Smsmith (Temp8 * sizeof (UINT8)); 50877424Smsmith break; 50967754Smsmith 51067754Smsmith 51177424Smsmith case RESOURCE_DESC_DWORD_ADDRESS_SPACE: 51277424Smsmith /* 51377424Smsmith * 32-Bit Address Resource 51477424Smsmith */ 51577424Smsmith Buffer = ByteStreamBuffer; 51667754Smsmith 51777424Smsmith ++Buffer; 51877424Smsmith MOVE_UNALIGNED16_TO_16 (&Temp16, Buffer); 51967754Smsmith 52077424Smsmith BytesConsumed = Temp16 + 3; 52167754Smsmith 52277424Smsmith /* 52377424Smsmith * Resource Source Index and Resource Source are 52477424Smsmith * optional elements. Check the length of the 52577424Smsmith * Bytestream. If it is greater than 23, that 52677424Smsmith * means that an Index exists and is followed by 52777424Smsmith * a null termininated string. Therefore, set 52877424Smsmith * the temp variable to the length minus the minimum 52977424Smsmith * byte stream length plus the byte for the Index to 53077424Smsmith * determine the size of the NULL terminiated string. 53177424Smsmith */ 53277424Smsmith if (23 < Temp16) 53377424Smsmith { 53477424Smsmith Temp8 = (UINT8) (Temp16 - 24); 53577424Smsmith } 53677424Smsmith else 53777424Smsmith { 53877424Smsmith Temp8 = 0; 53977424Smsmith } 54067754Smsmith 54177424Smsmith /* 54277424Smsmith * Ensure a 32-bit boundary for the structure 54377424Smsmith */ 54477424Smsmith Temp8 = (UINT8) ROUND_UP_TO_32BITS (Temp8); 54567754Smsmith 54677424Smsmith StructureSize = SIZEOF_RESOURCE (ACPI_RESOURCE_ADDRESS32) + 54777424Smsmith (Temp8 * sizeof (UINT8)); 54877424Smsmith break; 54967754Smsmith 55067754Smsmith 55177424Smsmith case RESOURCE_DESC_WORD_ADDRESS_SPACE: 55277424Smsmith /* 55377424Smsmith * 16-Bit Address Resource 55477424Smsmith */ 55577424Smsmith Buffer = ByteStreamBuffer; 55667754Smsmith 55777424Smsmith ++Buffer; 55877424Smsmith MOVE_UNALIGNED16_TO_16 (&Temp16, Buffer); 55967754Smsmith 56077424Smsmith BytesConsumed = Temp16 + 3; 56167754Smsmith 56277424Smsmith /* 56377424Smsmith * Resource Source Index and Resource Source are 56477424Smsmith * optional elements. Check the length of the 56577424Smsmith * Bytestream. If it is greater than 13, that 56677424Smsmith * means that an Index exists and is followed by 56777424Smsmith * a null termininated string. Therefore, set 56877424Smsmith * the temp variable to the length minus the minimum 56977424Smsmith * byte stream length plus the byte for the Index to 57077424Smsmith * determine the size of the NULL terminiated string. 57177424Smsmith */ 57277424Smsmith if (13 < Temp16) 57377424Smsmith { 57477424Smsmith Temp8 = (UINT8) (Temp16 - 14); 57577424Smsmith } 57677424Smsmith else 57777424Smsmith { 57877424Smsmith Temp8 = 0; 57977424Smsmith } 58067754Smsmith 58177424Smsmith /* 58277424Smsmith * Ensure a 32-bit boundary for the structure 58377424Smsmith */ 58477424Smsmith Temp8 = (UINT8) ROUND_UP_TO_32BITS (Temp8); 58567754Smsmith 58677424Smsmith StructureSize = SIZEOF_RESOURCE (ACPI_RESOURCE_ADDRESS16) + 58777424Smsmith (Temp8 * sizeof (UINT8)); 58877424Smsmith break; 58967754Smsmith 59067754Smsmith 59177424Smsmith case RESOURCE_DESC_EXTENDED_XRUPT: 59267754Smsmith /* 59377424Smsmith * Extended IRQ 59467754Smsmith */ 59577424Smsmith Buffer = ByteStreamBuffer; 59667754Smsmith 59777424Smsmith ++Buffer; 59877424Smsmith MOVE_UNALIGNED16_TO_16 (&Temp16, Buffer); 59967754Smsmith 60077424Smsmith BytesConsumed = Temp16 + 3; 60167754Smsmith 60277424Smsmith /* 60377424Smsmith * Point past the length field and the 60477424Smsmith * Interrupt vector flags to save off the 60577424Smsmith * Interrupt table length to the Temp8 variable. 60677424Smsmith */ 60777424Smsmith Buffer += 3; 60877424Smsmith Temp8 = *Buffer; 60967754Smsmith 61077424Smsmith /* 61177424Smsmith * To compensate for multiple interrupt numbers, add 4 bytes for 61277424Smsmith * each additional interrupts greater than 1 61377424Smsmith */ 61477424Smsmith AdditionalBytes = (UINT8) ((Temp8 - 1) * 4); 61567754Smsmith 61677424Smsmith /* 61777424Smsmith * Resource Source Index and Resource Source are 61877424Smsmith * optional elements. Check the length of the 61977424Smsmith * Bytestream. If it is greater than 9, that 62077424Smsmith * means that an Index exists and is followed by 62177424Smsmith * a null termininated string. Therefore, set 62277424Smsmith * the temp variable to the length minus the minimum 62377424Smsmith * byte stream length plus the byte for the Index to 62477424Smsmith * determine the size of the NULL terminiated string. 62577424Smsmith */ 62677424Smsmith if (9 + AdditionalBytes < Temp16) 62777424Smsmith { 62877424Smsmith Temp8 = (UINT8) (Temp16 - (9 + AdditionalBytes)); 62977424Smsmith } 63067754Smsmith 63177424Smsmith else 63277424Smsmith { 63377424Smsmith Temp8 = 0; 63477424Smsmith } 63567754Smsmith 63677424Smsmith /* 63777424Smsmith * Ensure a 32-bit boundary for the structure 63877424Smsmith */ 63977424Smsmith Temp8 = (UINT8) ROUND_UP_TO_32BITS (Temp8); 64067754Smsmith 64177424Smsmith StructureSize = SIZEOF_RESOURCE (ACPI_RESOURCE_EXT_IRQ) + 64277424Smsmith (AdditionalBytes * sizeof (UINT8)) + 64377424Smsmith (Temp8 * sizeof (UINT8)); 64477424Smsmith break; 64567754Smsmith 64667754Smsmith 64777424Smsmith case RESOURCE_DESC_IRQ_FORMAT: 64877424Smsmith /* 64977424Smsmith * IRQ Resource. 65077424Smsmith * Determine if it there are two or three trailing bytes 65177424Smsmith */ 65277424Smsmith Buffer = ByteStreamBuffer; 65377424Smsmith Temp8 = *Buffer; 65467754Smsmith 65577424Smsmith if(Temp8 & 0x01) 65677424Smsmith { 65777424Smsmith BytesConsumed = 4; 65877424Smsmith } 65967754Smsmith 66077424Smsmith else 66177424Smsmith { 66267754Smsmith BytesConsumed = 3; 66377424Smsmith } 66467754Smsmith 66577424Smsmith /* 66677424Smsmith * Point past the descriptor 66777424Smsmith */ 66877424Smsmith ++Buffer; 66967754Smsmith 67077424Smsmith /* 67177424Smsmith * Look at the number of bits set 67277424Smsmith */ 67377424Smsmith MOVE_UNALIGNED16_TO_16 (&Temp16, Buffer); 67467754Smsmith 67577424Smsmith for (Index = 0; Index < 16; Index++) 67677424Smsmith { 67777424Smsmith if (Temp16 & 0x1) 67867754Smsmith { 67977424Smsmith ++NumberOfInterrupts; 68067754Smsmith } 68167754Smsmith 68277424Smsmith Temp16 >>= 1; 68377424Smsmith } 68467754Smsmith 68577424Smsmith StructureSize = SIZEOF_RESOURCE (ACPI_RESOURCE_IO) + 68677424Smsmith (NumberOfInterrupts * sizeof (UINT32)); 68777424Smsmith break; 68867754Smsmith 68967754Smsmith 69077424Smsmith case RESOURCE_DESC_DMA_FORMAT: 69177424Smsmith /* 69277424Smsmith * DMA Resource 69377424Smsmith */ 69477424Smsmith Buffer = ByteStreamBuffer; 69577424Smsmith BytesConsumed = 3; 69667754Smsmith 69777424Smsmith /* 69877424Smsmith * Point past the descriptor 69977424Smsmith */ 70077424Smsmith ++Buffer; 70177424Smsmith 70277424Smsmith /* 70377424Smsmith * Look at the number of bits set 70477424Smsmith */ 70577424Smsmith Temp8 = *Buffer; 70677424Smsmith 70777424Smsmith for(Index = 0; Index < 8; Index++) 70877424Smsmith { 70977424Smsmith if(Temp8 & 0x1) 71067754Smsmith { 71177424Smsmith ++NumberOfChannels; 71267754Smsmith } 71367754Smsmith 71477424Smsmith Temp8 >>= 1; 71577424Smsmith } 71667754Smsmith 71777424Smsmith StructureSize = SIZEOF_RESOURCE (ACPI_RESOURCE_DMA) + 71877424Smsmith (NumberOfChannels * sizeof (UINT32)); 71977424Smsmith break; 72067754Smsmith 72167754Smsmith 72277424Smsmith case RESOURCE_DESC_START_DEPENDENT: 72377424Smsmith /* 72477424Smsmith * Start Dependent Functions Resource 72577424Smsmith * Determine if it there are two or three trailing bytes 72677424Smsmith */ 72777424Smsmith Buffer = ByteStreamBuffer; 72877424Smsmith Temp8 = *Buffer; 72967754Smsmith 73077424Smsmith if(Temp8 & 0x01) 73177424Smsmith { 73277424Smsmith BytesConsumed = 2; 73377424Smsmith } 73477424Smsmith else 73577424Smsmith { 73667754Smsmith BytesConsumed = 1; 73777424Smsmith } 73867754Smsmith 73977424Smsmith StructureSize = SIZEOF_RESOURCE (ACPI_RESOURCE_START_DPF); 74077424Smsmith break; 74167754Smsmith 74267754Smsmith 74377424Smsmith case RESOURCE_DESC_END_DEPENDENT: 74477424Smsmith /* 74577424Smsmith * End Dependent Functions Resource 74677424Smsmith */ 74777424Smsmith BytesConsumed = 1; 74877424Smsmith StructureSize = ACPI_RESOURCE_LENGTH; 74977424Smsmith break; 75067754Smsmith 75167754Smsmith 75277424Smsmith case RESOURCE_DESC_IO_PORT: 75377424Smsmith /* 75477424Smsmith * IO Port Resource 75577424Smsmith */ 75677424Smsmith BytesConsumed = 8; 75777424Smsmith StructureSize = SIZEOF_RESOURCE (ACPI_RESOURCE_IO); 75877424Smsmith break; 75967754Smsmith 76067754Smsmith 76177424Smsmith case RESOURCE_DESC_FIXED_IO_PORT: 76277424Smsmith /* 76377424Smsmith * Fixed IO Port Resource 76477424Smsmith */ 76577424Smsmith BytesConsumed = 4; 76677424Smsmith StructureSize = SIZEOF_RESOURCE (ACPI_RESOURCE_FIXED_IO); 76777424Smsmith break; 76867754Smsmith 76967754Smsmith 77077424Smsmith case RESOURCE_DESC_SMALL_VENDOR: 77177424Smsmith /* 77277424Smsmith * Vendor Specific Resource 77377424Smsmith */ 77477424Smsmith Buffer = ByteStreamBuffer; 77567754Smsmith 77677424Smsmith Temp8 = *Buffer; 77777424Smsmith Temp8 = (UINT8) (Temp8 & 0x7); 77877424Smsmith BytesConsumed = Temp8 + 1; 77977424Smsmith 78077424Smsmith /* 78177424Smsmith * Ensure a 32-bit boundary for the structure 78277424Smsmith */ 78377424Smsmith Temp8 = (UINT8) ROUND_UP_TO_32BITS (Temp8); 78477424Smsmith StructureSize = SIZEOF_RESOURCE (ACPI_RESOURCE_VENDOR) + 78567754Smsmith (Temp8 * sizeof (UINT8)); 78677424Smsmith break; 78767754Smsmith 78867754Smsmith 78977424Smsmith case RESOURCE_DESC_END_TAG: 79077424Smsmith /* 79177424Smsmith * End Tag 79277424Smsmith */ 79377424Smsmith BytesConsumed = 2; 79477424Smsmith StructureSize = ACPI_RESOURCE_LENGTH; 79577424Smsmith ByteStreamBufferLength = BytesParsed; 79677424Smsmith break; 79767754Smsmith 79867754Smsmith 79977424Smsmith default: 80077424Smsmith /* 80177424Smsmith * If we get here, everything is out of sync, 80277424Smsmith * so exit with an error 80377424Smsmith */ 80477424Smsmith return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE); 80577424Smsmith break; 80677424Smsmith } 80767754Smsmith 80867754Smsmith 80967754Smsmith /* 81067754Smsmith * Update the return value and counter 81167754Smsmith */ 81267754Smsmith BufferSize += StructureSize; 81367754Smsmith BytesParsed += BytesConsumed; 81467754Smsmith 81567754Smsmith /* 81667754Smsmith * Set the byte stream to point to the next resource 81767754Smsmith */ 81867754Smsmith ByteStreamBuffer += BytesConsumed; 81967754Smsmith } 82067754Smsmith 82177424Smsmith 82267754Smsmith /* 82367754Smsmith * This is the data the caller needs 82467754Smsmith */ 82567754Smsmith *SizeNeeded = BufferSize; 82667754Smsmith return_ACPI_STATUS (AE_OK); 82767754Smsmith} 82867754Smsmith 82967754Smsmith 83067754Smsmith/******************************************************************************* 83167754Smsmith * 83267754Smsmith * FUNCTION: AcpiRsCalculatePciRoutingTableLength 83367754Smsmith * 83467754Smsmith * PARAMETERS: PackageObject - Pointer to the package object 83567754Smsmith * BufferSizeNeeded - UINT32 pointer of the size buffer 83677424Smsmith * needed to properly return the 83777424Smsmith * parsed data 83867754Smsmith * 83977424Smsmith * RETURN: Status 84067754Smsmith * 84167754Smsmith * DESCRIPTION: Given a package representing a PCI routing table, this 84277424Smsmith * calculates the size of the corresponding linked list of 84377424Smsmith * descriptions. 84467754Smsmith * 84567754Smsmith ******************************************************************************/ 84667754Smsmith 84767754SmsmithACPI_STATUS 84867754SmsmithAcpiRsCalculatePciRoutingTableLength ( 84967754Smsmith ACPI_OPERAND_OBJECT *PackageObject, 85067754Smsmith UINT32 *BufferSizeNeeded) 85167754Smsmith{ 85267754Smsmith UINT32 NumberOfElements; 85369450Smsmith UINT32 TempSizeNeeded = 0; 85467754Smsmith ACPI_OPERAND_OBJECT **TopObjectList; 85567754Smsmith UINT32 Index; 85667754Smsmith ACPI_OPERAND_OBJECT *PackageElement; 85767754Smsmith ACPI_OPERAND_OBJECT **SubObjectList; 85867754Smsmith BOOLEAN NameFound; 85967754Smsmith UINT32 TableIndex; 86067754Smsmith 86167754Smsmith 86267754Smsmith FUNCTION_TRACE ("AcpiRsCalculatePciRoutingTableLength"); 86367754Smsmith 86467754Smsmith 86567754Smsmith NumberOfElements = PackageObject->Package.Count; 86667754Smsmith 86767754Smsmith /* 86867754Smsmith * Calculate the size of the return buffer. 86967754Smsmith * The base size is the number of elements * the sizes of the 87067754Smsmith * structures. Additional space for the strings is added below. 87167754Smsmith * The minus one is to subtract the size of the UINT8 Source[1] 87267754Smsmith * member because it is added below. 87367754Smsmith * 87467754Smsmith * But each PRT_ENTRY structure has a pointer to a string and 87567754Smsmith * the size of that string must be found. 87667754Smsmith */ 87767754Smsmith TopObjectList = PackageObject->Package.Elements; 87867754Smsmith 87967754Smsmith for (Index = 0; Index < NumberOfElements; Index++) 88067754Smsmith { 88167754Smsmith /* 88267754Smsmith * Dereference the sub-package 88367754Smsmith */ 88467754Smsmith PackageElement = *TopObjectList; 88567754Smsmith 88667754Smsmith /* 88767754Smsmith * The SubObjectList will now point to an array of the 88867754Smsmith * four IRQ elements: Address, Pin, Source and SourceIndex 88967754Smsmith */ 89067754Smsmith SubObjectList = PackageElement->Package.Elements; 89167754Smsmith 89267754Smsmith /* 89367754Smsmith * Scan the IrqTableElements for the Source Name String 89467754Smsmith */ 89567754Smsmith NameFound = FALSE; 89667754Smsmith 89767754Smsmith for (TableIndex = 0; TableIndex < 4 && !NameFound; TableIndex++) 89867754Smsmith { 89973561Smsmith if ((ACPI_TYPE_STRING == (*SubObjectList)->Common.Type) || 90073561Smsmith ((INTERNAL_TYPE_REFERENCE == (*SubObjectList)->Common.Type) && 90177424Smsmith ((*SubObjectList)->Reference.Opcode == AML_INT_NAMEPATH_OP))) 90267754Smsmith { 90367754Smsmith NameFound = TRUE; 90467754Smsmith } 90567754Smsmith 90667754Smsmith else 90767754Smsmith { 90867754Smsmith /* 90967754Smsmith * Look at the next element 91067754Smsmith */ 91167754Smsmith SubObjectList++; 91267754Smsmith } 91367754Smsmith } 91467754Smsmith 91573561Smsmith TempSizeNeeded += (sizeof (PCI_ROUTING_TABLE) - 4); 91669450Smsmith 91767754Smsmith /* 91867754Smsmith * Was a String type found? 91967754Smsmith */ 92067754Smsmith if (TRUE == NameFound) 92167754Smsmith { 92273561Smsmith if (ACPI_TYPE_STRING == (*SubObjectList)->Common.Type) 92373561Smsmith { 92473561Smsmith /* 92573561Smsmith * The length String.Length field includes the 92673561Smsmith * terminating NULL 92773561Smsmith */ 92873561Smsmith TempSizeNeeded += (*SubObjectList)->String.Length; 92973561Smsmith } 93077424Smsmith 93173561Smsmith else 93273561Smsmith { 93377424Smsmith TempSizeNeeded += AcpiNsGetPathnameLength ( 93477424Smsmith (*SubObjectList)->Reference.Node); 93573561Smsmith } 93667754Smsmith } 93767754Smsmith 93867754Smsmith else 93967754Smsmith { 94067754Smsmith /* 94167754Smsmith * If no name was found, then this is a NULL, which is 94277424Smsmith * translated as a UINT32 zero. 94367754Smsmith */ 94477424Smsmith TempSizeNeeded += sizeof (UINT32); 94567754Smsmith } 94667754Smsmith 94769450Smsmith /* Round up the size since each element must be aligned */ 94869450Smsmith 94969450Smsmith TempSizeNeeded = ROUND_UP_TO_64BITS (TempSizeNeeded); 95069450Smsmith 95167754Smsmith /* 95267754Smsmith * Point to the next ACPI_OPERAND_OBJECT 95367754Smsmith */ 95467754Smsmith TopObjectList++; 95567754Smsmith } 95667754Smsmith 95767754Smsmith 95877424Smsmith /* 95977424Smsmith * Adding an extra element to the end of the list, essentially a NULL terminator 96077424Smsmith */ 96177424Smsmith *BufferSizeNeeded = TempSizeNeeded + sizeof (PCI_ROUTING_TABLE); 96267754Smsmith return_ACPI_STATUS (AE_OK); 96369450Smsmith} 964