rscalc.c revision 71867
167754Smsmith/******************************************************************************* 267754Smsmith * 367754Smsmith * Module Name: rscalc - AcpiRsCalculateByteStreamLength 467754Smsmith * AcpiRsCalculateListLength 571867Smsmith * $Revision: 18 $ 667754Smsmith * 767754Smsmith ******************************************************************************/ 867754Smsmith 967754Smsmith/****************************************************************************** 1067754Smsmith * 1167754Smsmith * 1. Copyright Notice 1267754Smsmith * 1371867Smsmith * Some or all of this work - Copyright (c) 1999, 2000, 2001, Intel Corp. 1470243Smsmith * All rights reserved. 1567754Smsmith * 1667754Smsmith * 2. License 1767754Smsmith * 1867754Smsmith * 2.1. This is your license from Intel Corp. under its intellectual property 1967754Smsmith * rights. You may have additional license terms from the party that provided 2067754Smsmith * you this software, covering your right to use that party's intellectual 2167754Smsmith * property rights. 2267754Smsmith * 2367754Smsmith * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 2467754Smsmith * copy of the source code appearing in this file ("Covered Code") an 2567754Smsmith * irrevocable, perpetual, worldwide license under Intel's copyrights in the 2667754Smsmith * base code distributed originally by Intel ("Original Intel Code") to copy, 2767754Smsmith * make derivatives, distribute, use and display any portion of the Covered 2867754Smsmith * Code in any form, with the right to sublicense such rights; and 2967754Smsmith * 3067754Smsmith * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 3167754Smsmith * license (with the right to sublicense), under only those claims of Intel 3267754Smsmith * patents that are infringed by the Original Intel Code, to make, use, sell, 3367754Smsmith * offer to sell, and import the Covered Code and derivative works thereof 3467754Smsmith * solely to the minimum extent necessary to exercise the above copyright 3567754Smsmith * license, and in no event shall the patent license extend to any additions 3667754Smsmith * to or modifications of the Original Intel Code. No other license or right 3767754Smsmith * is granted directly or by implication, estoppel or otherwise; 3867754Smsmith * 3967754Smsmith * The above copyright and patent license is granted only if the following 4067754Smsmith * conditions are met: 4167754Smsmith * 4267754Smsmith * 3. Conditions 4367754Smsmith * 4467754Smsmith * 3.1. Redistribution of Source with Rights to Further Distribute Source. 4567754Smsmith * Redistribution of source code of any substantial portion of the Covered 4667754Smsmith * Code or modification with rights to further distribute source must include 4767754Smsmith * the above Copyright Notice, the above License, this list of Conditions, 4867754Smsmith * and the following Disclaimer and Export Compliance provision. In addition, 4967754Smsmith * Licensee must cause all Covered Code to which Licensee contributes to 5067754Smsmith * contain a file documenting the changes Licensee made to create that Covered 5167754Smsmith * Code and the date of any change. Licensee must include in that file the 5267754Smsmith * documentation of any changes made by any predecessor Licensee. Licensee 5367754Smsmith * must include a prominent statement that the modification is derived, 5467754Smsmith * directly or indirectly, from Original Intel Code. 5567754Smsmith * 5667754Smsmith * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 5767754Smsmith * Redistribution of source code of any substantial portion of the Covered 5867754Smsmith * Code or modification without rights to further distribute source must 5967754Smsmith * include the following Disclaimer and Export Compliance provision in the 6067754Smsmith * documentation and/or other materials provided with distribution. In 6167754Smsmith * addition, Licensee may not authorize further sublicense of source of any 6267754Smsmith * portion of the Covered Code, and must include terms to the effect that the 6367754Smsmith * license from Licensee to its licensee is limited to the intellectual 6467754Smsmith * property embodied in the software Licensee provides to its licensee, and 6567754Smsmith * not to intellectual property embodied in modifications its licensee may 6667754Smsmith * make. 6767754Smsmith * 6867754Smsmith * 3.3. Redistribution of Executable. Redistribution in executable form of any 6967754Smsmith * substantial portion of the Covered Code or modification must reproduce the 7067754Smsmith * above Copyright Notice, and the following Disclaimer and Export Compliance 7167754Smsmith * provision in the documentation and/or other materials provided with the 7267754Smsmith * distribution. 7367754Smsmith * 7467754Smsmith * 3.4. Intel retains all right, title, and interest in and to the Original 7567754Smsmith * Intel Code. 7667754Smsmith * 7767754Smsmith * 3.5. Neither the name Intel nor any other trademark owned or controlled by 7867754Smsmith * Intel shall be used in advertising or otherwise to promote the sale, use or 7967754Smsmith * other dealings in products derived from or relating to the Covered Code 8067754Smsmith * without prior written authorization from Intel. 8167754Smsmith * 8267754Smsmith * 4. Disclaimer and Export Compliance 8367754Smsmith * 8467754Smsmith * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 8567754Smsmith * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 8667754Smsmith * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 8767754Smsmith * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 8867754Smsmith * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 8967754Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 9067754Smsmith * PARTICULAR PURPOSE. 9167754Smsmith * 9267754Smsmith * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 9367754Smsmith * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 9467754Smsmith * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 9567754Smsmith * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 9667754Smsmith * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 9767754Smsmith * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 9867754Smsmith * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 9967754Smsmith * LIMITED REMEDY. 10067754Smsmith * 10167754Smsmith * 4.3. Licensee shall not export, either directly or indirectly, any of this 10267754Smsmith * software or system incorporating such software without first obtaining any 10367754Smsmith * required license or other approval from the U. S. Department of Commerce or 10467754Smsmith * any other agency or department of the United States Government. In the 10567754Smsmith * event Licensee exports any such software from the United States or 10667754Smsmith * re-exports any such software from a foreign destination, Licensee shall 10767754Smsmith * ensure that the distribution and export/re-export of the software is in 10867754Smsmith * compliance with all laws, regulations, orders, or other restrictions of the 10967754Smsmith * U.S. Export Administration Regulations. Licensee agrees that neither it nor 11067754Smsmith * any of its subsidiaries will export/re-export any technical data, process, 11167754Smsmith * software, or service, directly or indirectly, to any country for which the 11267754Smsmith * United States government or any agency thereof requires an export license, 11367754Smsmith * other governmental approval, or letter of assurance, without first obtaining 11467754Smsmith * such license, approval or letter. 11567754Smsmith * 11667754Smsmith *****************************************************************************/ 11767754Smsmith 11867754Smsmith#define __RSCALC_C__ 11967754Smsmith 12067754Smsmith#include "acpi.h" 12169450Smsmith#include "acresrc.h" 12267754Smsmith 12367754Smsmith#define _COMPONENT RESOURCE_MANAGER 12467754Smsmith MODULE_NAME ("rscalc") 12567754Smsmith 12667754Smsmith 12767754Smsmith/******************************************************************************* 12867754Smsmith * 12967754Smsmith * FUNCTION: AcpiRsCalculateByteStreamLength 13067754Smsmith * 13167754Smsmith * PARAMETERS: LinkedList - Pointer to the resource linked list 13267754Smsmith * SizeNeeded - UINT32 pointer of the size buffer needed 13367754Smsmith * to properly return the parsed data 13467754Smsmith * 13567754Smsmith * RETURN: Status AE_OK if okay, else a valid ACPI_STATUS code 13667754Smsmith * 13767754Smsmith * DESCRIPTION: Takes the resource byte stream and parses it once, calculating 13867754Smsmith * the size buffer needed to hold the linked list that conveys 13967754Smsmith * the resource data. 14067754Smsmith * 14167754Smsmith ******************************************************************************/ 14267754Smsmith 14367754SmsmithACPI_STATUS 14467754SmsmithAcpiRsCalculateByteStreamLength ( 14567754Smsmith RESOURCE *LinkedList, 14667754Smsmith UINT32 *SizeNeeded) 14767754Smsmith{ 14867754Smsmith UINT32 ByteStreamSizeNeeded = 0; 14967754Smsmith UINT32 SegmentSize; 15067754Smsmith EXTENDED_IRQ_RESOURCE *ExIrq = NULL; 15167754Smsmith BOOLEAN Done = FALSE; 15267754Smsmith 15367754Smsmith 15467754Smsmith FUNCTION_TRACE ("RsCalculateByteStreamLength"); 15567754Smsmith 15667754Smsmith 15767754Smsmith while (!Done) 15867754Smsmith { 15967754Smsmith 16067754Smsmith /* 16167754Smsmith * Init the variable that will hold the size to add to the 16267754Smsmith * total. 16367754Smsmith */ 16467754Smsmith SegmentSize = 0; 16567754Smsmith 16667754Smsmith switch (LinkedList->Id) 16767754Smsmith { 16867754Smsmith case Irq: 16967754Smsmith /* 17067754Smsmith * IRQ Resource 17167754Smsmith */ 17267754Smsmith /* 17367754Smsmith * For an IRQ Resource, Byte 3, although optional, will 17467754Smsmith * always be created - it holds IRQ information. 17567754Smsmith */ 17667754Smsmith SegmentSize = 4; 17767754Smsmith break; 17867754Smsmith 17967754Smsmith case Dma: 18067754Smsmith /* 18167754Smsmith * DMA Resource 18267754Smsmith */ 18367754Smsmith /* 18467754Smsmith * For this resource the size is static 18567754Smsmith */ 18667754Smsmith SegmentSize = 3; 18767754Smsmith break; 18867754Smsmith 18967754Smsmith case StartDependentFunctions: 19067754Smsmith /* 19167754Smsmith * Start Dependent Functions Resource 19267754Smsmith */ 19367754Smsmith /* 19467754Smsmith * For a StartDependentFunctions Resource, Byte 1, 19567754Smsmith * although optional, will always be created. 19667754Smsmith */ 19767754Smsmith SegmentSize = 2; 19867754Smsmith break; 19967754Smsmith 20067754Smsmith case EndDependentFunctions: 20167754Smsmith /* 20267754Smsmith * End Dependent Functions Resource 20367754Smsmith */ 20467754Smsmith /* 20567754Smsmith * For this resource the size is static 20667754Smsmith */ 20767754Smsmith SegmentSize = 1; 20867754Smsmith break; 20967754Smsmith 21067754Smsmith case Io: 21167754Smsmith /* 21267754Smsmith * IO Port Resource 21367754Smsmith */ 21467754Smsmith /* 21567754Smsmith * For this resource the size is static 21667754Smsmith */ 21767754Smsmith SegmentSize = 8; 21867754Smsmith break; 21967754Smsmith 22067754Smsmith case FixedIo: 22167754Smsmith /* 22267754Smsmith * Fixed IO Port Resource 22367754Smsmith */ 22467754Smsmith /* 22567754Smsmith * For this resource the size is static 22667754Smsmith */ 22767754Smsmith SegmentSize = 4; 22867754Smsmith break; 22967754Smsmith 23067754Smsmith case VendorSpecific: 23167754Smsmith /* 23267754Smsmith * Vendor Defined Resource 23367754Smsmith */ 23467754Smsmith /* 23567754Smsmith * For a Vendor Specific resource, if the Length is 23667754Smsmith * between 1 and 7 it will be created as a Small 23767754Smsmith * Resource data type, otherwise it is a Large 23867754Smsmith * Resource data type. 23967754Smsmith */ 24067754Smsmith if(LinkedList->Data.VendorSpecific.Length > 7) 24167754Smsmith { 24267754Smsmith SegmentSize = 3; 24367754Smsmith } 24467754Smsmith else 24567754Smsmith { 24667754Smsmith SegmentSize = 1; 24767754Smsmith } 24867754Smsmith SegmentSize += 24967754Smsmith LinkedList->Data.VendorSpecific.Length; 25067754Smsmith break; 25167754Smsmith 25267754Smsmith case EndTag: 25367754Smsmith /* 25467754Smsmith * End Tag 25567754Smsmith */ 25667754Smsmith /* 25767754Smsmith * For this resource the size is static 25867754Smsmith */ 25967754Smsmith SegmentSize = 2; 26067754Smsmith Done = TRUE; 26167754Smsmith break; 26267754Smsmith 26367754Smsmith case Memory24: 26467754Smsmith /* 26567754Smsmith * 24-Bit Memory Resource 26667754Smsmith */ 26767754Smsmith /* 26867754Smsmith * For this resource the size is static 26967754Smsmith */ 27067754Smsmith SegmentSize = 12; 27167754Smsmith break; 27267754Smsmith 27367754Smsmith case Memory32: 27467754Smsmith /* 27567754Smsmith * 32-Bit Memory Range Resource 27667754Smsmith */ 27767754Smsmith /* 27867754Smsmith * For this resource the size is static 27967754Smsmith */ 28067754Smsmith SegmentSize = 20; 28167754Smsmith break; 28267754Smsmith 28367754Smsmith case FixedMemory32: 28467754Smsmith /* 28567754Smsmith * 32-Bit Fixed Memory Resource 28667754Smsmith */ 28767754Smsmith /* 28867754Smsmith * For this resource the size is static 28967754Smsmith */ 29067754Smsmith SegmentSize = 12; 29167754Smsmith break; 29267754Smsmith 29367754Smsmith case Address16: 29467754Smsmith /* 29567754Smsmith * 16-Bit Address Resource 29667754Smsmith */ 29767754Smsmith /* 29867754Smsmith * The base size of this byte stream is 16. If a 29967754Smsmith * Resource Source string is not NULL, add 1 for 30067754Smsmith * the Index + the length of the null terminated 30167754Smsmith * string Resource Source + 1 for the null. 30267754Smsmith */ 30367754Smsmith SegmentSize = 16; 30467754Smsmith 30567754Smsmith if(NULL != LinkedList->Data.Address16.ResourceSource) 30667754Smsmith { 30767754Smsmith SegmentSize += (1 + 30867754Smsmith LinkedList->Data.Address16.ResourceSourceStringLength); 30967754Smsmith } 31067754Smsmith break; 31167754Smsmith 31267754Smsmith case Address32: 31367754Smsmith /* 31467754Smsmith * 32-Bit Address Resource 31567754Smsmith */ 31667754Smsmith /* 31767754Smsmith * The base size of this byte stream is 26. If a Resource 31867754Smsmith * Source string is not NULL, add 1 for the Index + the 31967754Smsmith * length of the null terminated string Resource Source + 32067754Smsmith * 1 for the null. 32167754Smsmith */ 32267754Smsmith SegmentSize = 26; 32367754Smsmith 32467754Smsmith if(NULL != LinkedList->Data.Address16.ResourceSource) 32567754Smsmith { 32667754Smsmith SegmentSize += (1 + 32767754Smsmith LinkedList->Data.Address16.ResourceSourceStringLength); 32867754Smsmith } 32967754Smsmith break; 33067754Smsmith 33167754Smsmith case ExtendedIrq: 33267754Smsmith /* 33367754Smsmith * Extended IRQ Resource 33467754Smsmith */ 33567754Smsmith /* 33667754Smsmith * The base size of this byte stream is 9. This is for an 33767754Smsmith * Interrupt table length of 1. For each additional 33867754Smsmith * interrupt, add 4. 33967754Smsmith * If a Resource Source string is not NULL, add 1 for the 34067754Smsmith * Index + the length of the null terminated string 34167754Smsmith * Resource Source + 1 for the null. 34267754Smsmith */ 34367754Smsmith SegmentSize = 9; 34467754Smsmith 34567754Smsmith SegmentSize += 34667754Smsmith (LinkedList->Data.ExtendedIrq.NumberOfInterrupts - 34767754Smsmith 1) * 4; 34867754Smsmith 34967754Smsmith if(NULL != ExIrq->ResourceSource) 35067754Smsmith { 35167754Smsmith SegmentSize += (1 + 35267754Smsmith LinkedList->Data.ExtendedIrq.ResourceSourceStringLength); 35367754Smsmith } 35467754Smsmith break; 35567754Smsmith 35667754Smsmith default: 35767754Smsmith /* 35867754Smsmith * If we get here, everything is out of sync, 35967754Smsmith * so exit with an error 36067754Smsmith */ 36167754Smsmith return_ACPI_STATUS (AE_AML_ERROR); 36267754Smsmith break; 36367754Smsmith 36467754Smsmith } /* switch (LinkedList->Id) */ 36567754Smsmith 36667754Smsmith /* 36767754Smsmith * Update the total 36867754Smsmith */ 36967754Smsmith ByteStreamSizeNeeded += SegmentSize; 37067754Smsmith 37167754Smsmith /* 37267754Smsmith * Point to the next object 37367754Smsmith */ 37467754Smsmith LinkedList = (RESOURCE *) ((NATIVE_UINT) LinkedList + 37567754Smsmith (NATIVE_UINT) LinkedList->Length); 37667754Smsmith } 37767754Smsmith 37867754Smsmith /* 37967754Smsmith * This is the data the caller needs 38067754Smsmith */ 38167754Smsmith *SizeNeeded = ByteStreamSizeNeeded; 38267754Smsmith 38367754Smsmith return_ACPI_STATUS (AE_OK); 38467754Smsmith} 38567754Smsmith 38667754Smsmith 38767754Smsmith/******************************************************************************* 38867754Smsmith * 38967754Smsmith * FUNCTION: AcpiRsCalculateListLength 39067754Smsmith * 39167754Smsmith * PARAMETERS: ByteStreamBuffer - Pointer to the resource byte stream 39267754Smsmith * ByteStreamBufferLength - Size of ByteStreamBuffer 39367754Smsmith * SizeNeeded - UINT32 pointer of the size buffer 39467754Smsmith * needed to properly return the 39567754Smsmith * parsed data 39667754Smsmith * 39767754Smsmith * RETURN: Status AE_OK if okay, else a valid ACPI_STATUS code 39867754Smsmith * 39967754Smsmith * DESCRIPTION: Takes the resource byte stream and parses it once, calculating 40067754Smsmith * the size buffer needed to hold the linked list that conveys 40167754Smsmith * the resource data. 40267754Smsmith * 40367754Smsmith ******************************************************************************/ 40467754Smsmith 40567754SmsmithACPI_STATUS 40667754SmsmithAcpiRsCalculateListLength ( 40767754Smsmith UINT8 *ByteStreamBuffer, 40867754Smsmith UINT32 ByteStreamBufferLength, 40967754Smsmith UINT32 *SizeNeeded) 41067754Smsmith{ 41167754Smsmith UINT32 BufferSize = 0; 41267754Smsmith UINT32 BytesParsed = 0; 41367754Smsmith UINT8 NumberOfInterrupts = 0; 41467754Smsmith UINT8 NumberOfChannels = 0; 41567754Smsmith UINT8 ResourceType; 41667754Smsmith UINT32 StructureSize; 41767754Smsmith UINT32 BytesConsumed; 41867754Smsmith UINT8 *Buffer; 41967754Smsmith UINT8 Temp8; 42067754Smsmith UINT16 Temp16; 42167754Smsmith UINT8 Index; 42267754Smsmith UINT8 AdditionalBytes; 42367754Smsmith 42467754Smsmith 42567754Smsmith FUNCTION_TRACE ("RsCalculateListLength"); 42667754Smsmith 42767754Smsmith 42867754Smsmith while (BytesParsed < ByteStreamBufferLength) 42967754Smsmith { 43067754Smsmith /* 43167754Smsmith * Look at the next byte in the stream 43267754Smsmith */ 43367754Smsmith ResourceType = *ByteStreamBuffer; 43467754Smsmith 43567754Smsmith /* 43667754Smsmith * See if this is a small or large resource 43767754Smsmith */ 43867754Smsmith if(ResourceType & 0x80) 43967754Smsmith { 44067754Smsmith /* 44167754Smsmith * Large Resource Type 44267754Smsmith */ 44367754Smsmith switch (ResourceType) 44467754Smsmith { 44567754Smsmith case MEMORY_RANGE_24: 44667754Smsmith /* 44767754Smsmith * 24-Bit Memory Resource 44867754Smsmith */ 44967754Smsmith BytesConsumed = 12; 45067754Smsmith 45167754Smsmith StructureSize = sizeof (MEMORY24_RESOURCE) + 45267754Smsmith RESOURCE_LENGTH_NO_DATA; 45367754Smsmith break; 45467754Smsmith 45567754Smsmith case LARGE_VENDOR_DEFINED: 45667754Smsmith /* 45767754Smsmith * Vendor Defined Resource 45867754Smsmith */ 45967754Smsmith Buffer = ByteStreamBuffer; 46067754Smsmith ++Buffer; 46167754Smsmith 46267754Smsmith MOVE_UNALIGNED16_TO_16 (&Temp16, Buffer); 46367754Smsmith BytesConsumed = Temp16 + 3; 46467754Smsmith 46567754Smsmith /* 46667754Smsmith * Ensure a 32-bit boundary for the structure 46767754Smsmith */ 46867754Smsmith Temp16 = (UINT16) ROUND_UP_TO_32BITS (Temp16); 46967754Smsmith 47067754Smsmith StructureSize = sizeof (VENDOR_RESOURCE) + 47167754Smsmith RESOURCE_LENGTH_NO_DATA + 47267754Smsmith (Temp16 * sizeof (UINT8)); 47367754Smsmith break; 47467754Smsmith 47567754Smsmith case MEMORY_RANGE_32: 47667754Smsmith /* 47767754Smsmith * 32-Bit Memory Range Resource 47867754Smsmith */ 47967754Smsmith 48067754Smsmith BytesConsumed = 20; 48167754Smsmith 48267754Smsmith StructureSize = sizeof (MEMORY32_RESOURCE) + 48367754Smsmith RESOURCE_LENGTH_NO_DATA; 48467754Smsmith break; 48567754Smsmith 48667754Smsmith case FIXED_MEMORY_RANGE_32: 48767754Smsmith /* 48867754Smsmith * 32-Bit Fixed Memory Resource 48967754Smsmith */ 49067754Smsmith BytesConsumed = 12; 49167754Smsmith 49267754Smsmith StructureSize = sizeof(FIXED_MEMORY32_RESOURCE) + 49367754Smsmith RESOURCE_LENGTH_NO_DATA; 49467754Smsmith break; 49567754Smsmith 49667754Smsmith case DWORD_ADDRESS_SPACE: 49767754Smsmith /* 49867754Smsmith * 32-Bit Address Resource 49967754Smsmith */ 50067754Smsmith Buffer = ByteStreamBuffer; 50167754Smsmith 50267754Smsmith ++Buffer; 50367754Smsmith MOVE_UNALIGNED16_TO_16 (&Temp16, Buffer); 50467754Smsmith 50567754Smsmith BytesConsumed = Temp16 + 3; 50667754Smsmith 50767754Smsmith /* 50867754Smsmith * Resource Source Index and Resource Source are 50967754Smsmith * optional elements. Check the length of the 51067754Smsmith * Bytestream. If it is greater than 23, that 51167754Smsmith * means that an Index exists and is followed by 51267754Smsmith * a null termininated string. Therefore, set 51367754Smsmith * the temp variable to the length minus the minimum 51467754Smsmith * byte stream length plus the byte for the Index to 51567754Smsmith * determine the size of the NULL terminiated string. 51667754Smsmith */ 51767754Smsmith if (23 < Temp16) 51867754Smsmith { 51967754Smsmith Temp8 = (UINT8) (Temp16 - 24); 52067754Smsmith } 52167754Smsmith else 52267754Smsmith { 52367754Smsmith Temp8 = 0; 52467754Smsmith } 52567754Smsmith 52667754Smsmith /* 52767754Smsmith * Ensure a 32-bit boundary for the structure 52867754Smsmith */ 52967754Smsmith Temp8 = (UINT8) ROUND_UP_TO_32BITS (Temp8); 53067754Smsmith 53167754Smsmith StructureSize = sizeof (ADDRESS32_RESOURCE) + 53267754Smsmith RESOURCE_LENGTH_NO_DATA + 53367754Smsmith (Temp8 * sizeof (UINT8)); 53467754Smsmith break; 53567754Smsmith 53667754Smsmith case WORD_ADDRESS_SPACE: 53767754Smsmith /* 53867754Smsmith * 16-Bit Address Resource 53967754Smsmith */ 54067754Smsmith Buffer = ByteStreamBuffer; 54167754Smsmith 54267754Smsmith ++Buffer; 54367754Smsmith MOVE_UNALIGNED16_TO_16 (&Temp16, Buffer); 54467754Smsmith 54567754Smsmith BytesConsumed = Temp16 + 3; 54667754Smsmith 54767754Smsmith /* 54867754Smsmith * Resource Source Index and Resource Source are 54967754Smsmith * optional elements. Check the length of the 55067754Smsmith * Bytestream. If it is greater than 13, that 55167754Smsmith * means that an Index exists and is followed by 55267754Smsmith * a null termininated string. Therefore, set 55367754Smsmith * the temp variable to the length minus the minimum 55467754Smsmith * byte stream length plus the byte for the Index to 55567754Smsmith * determine the size of the NULL terminiated string. 55667754Smsmith */ 55767754Smsmith if (13 < Temp16) 55867754Smsmith { 55967754Smsmith Temp8 = (UINT8) (Temp16 - 14); 56067754Smsmith } 56167754Smsmith else 56267754Smsmith { 56367754Smsmith Temp8 = 0; 56467754Smsmith } 56567754Smsmith 56667754Smsmith /* 56767754Smsmith * Ensure a 32-bit boundry for the structure 56867754Smsmith */ 56967754Smsmith Temp8 = (UINT8) ROUND_UP_TO_32BITS (Temp8); 57067754Smsmith 57167754Smsmith StructureSize = sizeof (ADDRESS16_RESOURCE) + 57267754Smsmith RESOURCE_LENGTH_NO_DATA + 57367754Smsmith (Temp8 * sizeof (UINT8)); 57467754Smsmith break; 57567754Smsmith 57667754Smsmith case EXTENDED_IRQ: 57767754Smsmith /* 57867754Smsmith * Extended IRQ 57967754Smsmith */ 58067754Smsmith Buffer = ByteStreamBuffer; 58167754Smsmith 58267754Smsmith ++Buffer; 58367754Smsmith MOVE_UNALIGNED16_TO_16 (&Temp16, Buffer); 58467754Smsmith 58567754Smsmith BytesConsumed = Temp16 + 3; 58667754Smsmith 58767754Smsmith /* 58867754Smsmith * Point past the length field and the 58967754Smsmith * Interrupt vector flags to save off the 59067754Smsmith * Interrupt table length to the Temp8 variable. 59167754Smsmith */ 59267754Smsmith Buffer += 3; 59367754Smsmith Temp8 = *Buffer; 59467754Smsmith 59567754Smsmith /* 59667754Smsmith * To compensate for multiple interrupt numbers, 59767754Smsmith * Add 4 bytes for each additional interrupts 59867754Smsmith * greater than 1 59967754Smsmith */ 60067754Smsmith AdditionalBytes = (UINT8) ((Temp8 - 1) * 4); 60167754Smsmith 60267754Smsmith /* 60367754Smsmith * Resource Source Index and Resource Source are 60467754Smsmith * optional elements. Check the length of the 60567754Smsmith * Bytestream. If it is greater than 9, that 60667754Smsmith * means that an Index exists and is followed by 60767754Smsmith * a null termininated string. Therefore, set 60867754Smsmith * the temp variable to the length minus the minimum 60967754Smsmith * byte stream length plus the byte for the Index to 61067754Smsmith * determine the size of the NULL terminiated string. 61167754Smsmith */ 61267754Smsmith if (9 + AdditionalBytes < Temp16) 61367754Smsmith { 61467754Smsmith Temp8 = (UINT8) (Temp16 - (9 + AdditionalBytes)); 61567754Smsmith } 61667754Smsmith 61767754Smsmith else 61867754Smsmith { 61967754Smsmith Temp8 = 0; 62067754Smsmith } 62167754Smsmith 62267754Smsmith /* 62367754Smsmith * Ensure a 32-bit boundry for the structure 62467754Smsmith */ 62567754Smsmith Temp8 = (UINT8) ROUND_UP_TO_32BITS (Temp8); 62667754Smsmith 62767754Smsmith StructureSize = sizeof (EXTENDED_IRQ_RESOURCE) + 62867754Smsmith RESOURCE_LENGTH_NO_DATA + 62967754Smsmith (AdditionalBytes * sizeof (UINT8)) + 63067754Smsmith (Temp8 * sizeof (UINT8)); 63167754Smsmith 63267754Smsmith break; 63367754Smsmith 63467754Smsmith/* TBD: [Future] 64-bit not currently supported */ 63567754Smsmith/* 63667754Smsmith case 0x8A: 63767754Smsmith break; 63867754Smsmith*/ 63967754Smsmith 64067754Smsmith default: 64167754Smsmith /* 64267754Smsmith * If we get here, everything is out of sync, 64367754Smsmith * so exit with an error 64467754Smsmith */ 64567754Smsmith return_ACPI_STATUS (AE_AML_ERROR); 64667754Smsmith break; 64767754Smsmith } 64867754Smsmith } 64967754Smsmith 65067754Smsmith else 65167754Smsmith { 65267754Smsmith /* 65367754Smsmith * Small Resource Type 65467754Smsmith * Only bits 7:3 are valid 65567754Smsmith */ 65667754Smsmith ResourceType >>= 3; 65767754Smsmith 65867754Smsmith switch (ResourceType) 65967754Smsmith { 66067754Smsmith case IRQ_FORMAT: 66167754Smsmith /* 66267754Smsmith * IRQ Resource 66367754Smsmith */ 66467754Smsmith /* 66567754Smsmith * Determine if it there are two or three 66667754Smsmith * trailing bytes 66767754Smsmith */ 66867754Smsmith Buffer = ByteStreamBuffer; 66967754Smsmith Temp8 = *Buffer; 67067754Smsmith 67167754Smsmith if(Temp8 & 0x01) 67267754Smsmith { 67367754Smsmith BytesConsumed = 4; 67467754Smsmith } 67567754Smsmith 67667754Smsmith else 67767754Smsmith { 67867754Smsmith BytesConsumed = 3; 67967754Smsmith } 68067754Smsmith 68167754Smsmith /* 68267754Smsmith * Point past the descriptor 68367754Smsmith */ 68467754Smsmith ++Buffer; 68567754Smsmith 68667754Smsmith /* 68767754Smsmith * Look at the number of bits set 68867754Smsmith */ 68967754Smsmith MOVE_UNALIGNED16_TO_16 (&Temp16, Buffer); 69067754Smsmith 69167754Smsmith for (Index = 0; Index < 16; Index++) 69267754Smsmith { 69367754Smsmith if (Temp16 & 0x1) 69467754Smsmith { 69567754Smsmith ++NumberOfInterrupts; 69667754Smsmith } 69767754Smsmith 69867754Smsmith Temp16 >>= 1; 69967754Smsmith } 70067754Smsmith 70167754Smsmith StructureSize = sizeof (IO_RESOURCE) + 70267754Smsmith RESOURCE_LENGTH_NO_DATA + 70367754Smsmith (NumberOfInterrupts * sizeof (UINT32)); 70467754Smsmith break; 70567754Smsmith 70667754Smsmith 70767754Smsmith case DMA_FORMAT: 70867754Smsmith 70967754Smsmith /* 71067754Smsmith * DMA Resource 71167754Smsmith */ 71267754Smsmith Buffer = ByteStreamBuffer; 71367754Smsmith 71467754Smsmith BytesConsumed = 3; 71567754Smsmith 71667754Smsmith /* 71767754Smsmith * Point past the descriptor 71867754Smsmith */ 71967754Smsmith ++Buffer; 72067754Smsmith 72167754Smsmith /* 72267754Smsmith * Look at the number of bits set 72367754Smsmith */ 72467754Smsmith Temp8 = *Buffer; 72567754Smsmith 72667754Smsmith for(Index = 0; Index < 8; Index++) 72767754Smsmith { 72867754Smsmith if(Temp8 & 0x1) 72967754Smsmith { 73067754Smsmith ++NumberOfChannels; 73167754Smsmith } 73267754Smsmith 73367754Smsmith Temp8 >>= 1; 73467754Smsmith } 73567754Smsmith 73667754Smsmith StructureSize = sizeof (DMA_RESOURCE) + 73767754Smsmith RESOURCE_LENGTH_NO_DATA + 73867754Smsmith (NumberOfChannels * sizeof (UINT32)); 73967754Smsmith break; 74067754Smsmith 74167754Smsmith 74267754Smsmith case START_DEPENDENT_TAG: 74367754Smsmith 74467754Smsmith /* 74567754Smsmith * Start Dependent Functions Resource 74667754Smsmith */ 74767754Smsmith /* 74867754Smsmith * Determine if it there are two or three trailing bytes 74967754Smsmith */ 75067754Smsmith Buffer = ByteStreamBuffer; 75167754Smsmith Temp8 = *Buffer; 75267754Smsmith 75367754Smsmith if(Temp8 & 0x01) 75467754Smsmith { 75567754Smsmith BytesConsumed = 2; 75667754Smsmith } 75767754Smsmith else 75867754Smsmith { 75967754Smsmith BytesConsumed = 1; 76067754Smsmith } 76167754Smsmith 76267754Smsmith 76367754Smsmith StructureSize = 76467754Smsmith sizeof (START_DEPENDENT_FUNCTIONS_RESOURCE) + 76567754Smsmith RESOURCE_LENGTH_NO_DATA; 76667754Smsmith break; 76767754Smsmith 76867754Smsmith 76967754Smsmith case END_DEPENDENT_TAG: 77067754Smsmith 77167754Smsmith /* 77267754Smsmith * End Dependent Functions Resource 77367754Smsmith */ 77467754Smsmith BytesConsumed = 1; 77567754Smsmith StructureSize = RESOURCE_LENGTH; 77667754Smsmith break; 77767754Smsmith 77867754Smsmith 77967754Smsmith case IO_PORT_DESCRIPTOR: 78067754Smsmith /* 78167754Smsmith * IO Port Resource 78267754Smsmith */ 78367754Smsmith BytesConsumed = 8; 78467754Smsmith StructureSize = sizeof (IO_RESOURCE) + 78567754Smsmith RESOURCE_LENGTH_NO_DATA; 78667754Smsmith break; 78767754Smsmith 78867754Smsmith 78967754Smsmith case FIXED_LOCATION_IO_DESCRIPTOR: 79067754Smsmith 79167754Smsmith /* 79267754Smsmith * Fixed IO Port Resource 79367754Smsmith */ 79467754Smsmith BytesConsumed = 4; 79567754Smsmith StructureSize = sizeof (FIXED_IO_RESOURCE) + 79667754Smsmith RESOURCE_LENGTH_NO_DATA; 79767754Smsmith break; 79867754Smsmith 79967754Smsmith 80067754Smsmith case SMALL_VENDOR_DEFINED: 80167754Smsmith 80267754Smsmith /* 80367754Smsmith * Vendor Specific Resource 80467754Smsmith */ 80567754Smsmith Buffer = ByteStreamBuffer; 80667754Smsmith 80767754Smsmith Temp8 = *Buffer; 80867754Smsmith Temp8 = (UINT8) (Temp8 & 0x7); 80967754Smsmith BytesConsumed = Temp8 + 1; 81067754Smsmith 81167754Smsmith /* 81267754Smsmith * Ensure a 32-bit boundry for the structure 81367754Smsmith */ 81467754Smsmith Temp8 = (UINT8) ROUND_UP_TO_32BITS (Temp8); 81567754Smsmith StructureSize = sizeof (VENDOR_RESOURCE) + 81667754Smsmith RESOURCE_LENGTH_NO_DATA + 81767754Smsmith (Temp8 * sizeof (UINT8)); 81867754Smsmith break; 81967754Smsmith 82067754Smsmith 82167754Smsmith case END_TAG: 82267754Smsmith 82367754Smsmith /* 82467754Smsmith * End Tag 82567754Smsmith */ 82667754Smsmith BytesConsumed = 2; 82767754Smsmith StructureSize = RESOURCE_LENGTH; 82867754Smsmith break; 82967754Smsmith 83067754Smsmith 83167754Smsmith default: 83267754Smsmith /* 83367754Smsmith * If we get here, everything is out of sync, 83467754Smsmith * so exit with an error 83567754Smsmith */ 83667754Smsmith return_ACPI_STATUS (AE_AML_ERROR); 83767754Smsmith break; 83867754Smsmith 83967754Smsmith } /* switch */ 84067754Smsmith 84167754Smsmith } /* if(ResourceType & 0x80) */ 84267754Smsmith 84367754Smsmith /* 84467754Smsmith * Update the return value and counter 84567754Smsmith */ 84667754Smsmith BufferSize += StructureSize; 84767754Smsmith BytesParsed += BytesConsumed; 84867754Smsmith 84967754Smsmith /* 85067754Smsmith * Set the byte stream to point to the next resource 85167754Smsmith */ 85267754Smsmith ByteStreamBuffer += BytesConsumed; 85367754Smsmith 85467754Smsmith } 85567754Smsmith 85667754Smsmith /* 85767754Smsmith * This is the data the caller needs 85867754Smsmith */ 85967754Smsmith *SizeNeeded = BufferSize; 86067754Smsmith 86167754Smsmith return_ACPI_STATUS (AE_OK); 86267754Smsmith} 86367754Smsmith 86467754Smsmith 86567754Smsmith/******************************************************************************* 86667754Smsmith * 86767754Smsmith * FUNCTION: AcpiRsCalculatePciRoutingTableLength 86867754Smsmith * 86967754Smsmith * PARAMETERS: PackageObject - Pointer to the package object 87067754Smsmith * BufferSizeNeeded - UINT32 pointer of the size buffer 87167754Smsmith * needed to properly return the 87267754Smsmith * parsed data 87367754Smsmith * 87467754Smsmith * RETURN: Status AE_OK 87567754Smsmith * 87667754Smsmith * DESCRIPTION: Given a package representing a PCI routing table, this 87767754Smsmith * calculates the size of the corresponding linked list of 87867754Smsmith * descriptions. 87967754Smsmith * 88067754Smsmith ******************************************************************************/ 88167754Smsmith 88267754SmsmithACPI_STATUS 88367754SmsmithAcpiRsCalculatePciRoutingTableLength ( 88467754Smsmith ACPI_OPERAND_OBJECT *PackageObject, 88567754Smsmith UINT32 *BufferSizeNeeded) 88667754Smsmith{ 88767754Smsmith UINT32 NumberOfElements; 88869450Smsmith UINT32 TempSizeNeeded = 0; 88967754Smsmith ACPI_OPERAND_OBJECT **TopObjectList; 89067754Smsmith UINT32 Index; 89167754Smsmith ACPI_OPERAND_OBJECT *PackageElement; 89267754Smsmith ACPI_OPERAND_OBJECT **SubObjectList; 89367754Smsmith BOOLEAN NameFound; 89467754Smsmith UINT32 TableIndex; 89567754Smsmith 89667754Smsmith 89767754Smsmith FUNCTION_TRACE ("AcpiRsCalculatePciRoutingTableLength"); 89867754Smsmith 89967754Smsmith 90067754Smsmith NumberOfElements = PackageObject->Package.Count; 90167754Smsmith 90267754Smsmith /* 90367754Smsmith * Calculate the size of the return buffer. 90467754Smsmith * The base size is the number of elements * the sizes of the 90567754Smsmith * structures. Additional space for the strings is added below. 90667754Smsmith * The minus one is to subtract the size of the UINT8 Source[1] 90767754Smsmith * member because it is added below. 90867754Smsmith * 90967754Smsmith * NOTE: The NumberOfElements is incremented by one to add an end 91067754Smsmith * table structure that is essentially a structure of zeros. 91167754Smsmith */ 91267754Smsmith 91367754Smsmith /* 91467754Smsmith * But each PRT_ENTRY structure has a pointer to a string and 91567754Smsmith * the size of that string must be found. 91667754Smsmith */ 91767754Smsmith TopObjectList = PackageObject->Package.Elements; 91867754Smsmith 91967754Smsmith for (Index = 0; Index < NumberOfElements; Index++) 92067754Smsmith { 92167754Smsmith /* 92267754Smsmith * Dereference the sub-package 92367754Smsmith */ 92467754Smsmith PackageElement = *TopObjectList; 92567754Smsmith 92667754Smsmith /* 92767754Smsmith * The SubObjectList will now point to an array of the 92867754Smsmith * four IRQ elements: Address, Pin, Source and SourceIndex 92967754Smsmith */ 93067754Smsmith SubObjectList = PackageElement->Package.Elements; 93167754Smsmith 93267754Smsmith /* 93367754Smsmith * Scan the IrqTableElements for the Source Name String 93467754Smsmith */ 93567754Smsmith NameFound = FALSE; 93667754Smsmith 93767754Smsmith for (TableIndex = 0; TableIndex < 4 && !NameFound; TableIndex++) 93867754Smsmith { 93967754Smsmith if (ACPI_TYPE_STRING == (*SubObjectList)->Common.Type) 94067754Smsmith { 94167754Smsmith NameFound = TRUE; 94267754Smsmith } 94367754Smsmith 94467754Smsmith else 94567754Smsmith { 94667754Smsmith /* 94767754Smsmith * Look at the next element 94867754Smsmith */ 94967754Smsmith SubObjectList++; 95067754Smsmith } 95167754Smsmith } 95267754Smsmith 95369450Smsmith TempSizeNeeded += (sizeof (PCI_ROUTING_TABLE) - 1); 95469450Smsmith 95567754Smsmith /* 95667754Smsmith * Was a String type found? 95767754Smsmith */ 95867754Smsmith if (TRUE == NameFound) 95967754Smsmith { 96067754Smsmith /* 96167754Smsmith * The length String.Length field includes the 96267754Smsmith * terminating NULL 96367754Smsmith */ 96467754Smsmith TempSizeNeeded += (*SubObjectList)->String.Length; 96567754Smsmith } 96667754Smsmith 96767754Smsmith else 96867754Smsmith { 96967754Smsmith /* 97067754Smsmith * If no name was found, then this is a NULL, which is 97167754Smsmith * translated as a UINT32 zero. 97267754Smsmith */ 97367754Smsmith TempSizeNeeded += sizeof(UINT32); 97467754Smsmith } 97567754Smsmith 97669450Smsmith 97769450Smsmith /* Round up the size since each element must be aligned */ 97869450Smsmith 97969450Smsmith TempSizeNeeded = ROUND_UP_TO_64BITS (TempSizeNeeded); 98069450Smsmith 98167754Smsmith /* 98267754Smsmith * Point to the next ACPI_OPERAND_OBJECT 98367754Smsmith */ 98467754Smsmith TopObjectList++; 98567754Smsmith } 98667754Smsmith 98767754Smsmith 98869450Smsmith *BufferSizeNeeded = TempSizeNeeded + sizeof (PCI_ROUTING_TABLE); 98967754Smsmith 99067754Smsmith return_ACPI_STATUS (AE_OK); 99169450Smsmith} 992