rscalc.c revision 67754
167754Smsmith/******************************************************************************* 267754Smsmith * 367754Smsmith * Module Name: rscalc - AcpiRsCalculateByteStreamLength 467754Smsmith * AcpiRsCalculateListLength 567754Smsmith * $Revision: 11 $ 667754Smsmith * 767754Smsmith ******************************************************************************/ 867754Smsmith 967754Smsmith/****************************************************************************** 1067754Smsmith * 1167754Smsmith * 1. Copyright Notice 1267754Smsmith * 1367754Smsmith * Some or all of this work - Copyright (c) 1999, Intel Corp. All rights 1467754Smsmith * 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" 12167754Smsmith 12267754Smsmith#define _COMPONENT RESOURCE_MANAGER 12367754Smsmith MODULE_NAME ("rscalc") 12467754Smsmith 12567754Smsmith 12667754Smsmith/******************************************************************************* 12767754Smsmith * 12867754Smsmith * FUNCTION: AcpiRsCalculateByteStreamLength 12967754Smsmith * 13067754Smsmith * PARAMETERS: LinkedList - Pointer to the resource linked list 13167754Smsmith * SizeNeeded - UINT32 pointer of the size buffer needed 13267754Smsmith * to properly return the parsed data 13367754Smsmith * 13467754Smsmith * RETURN: Status AE_OK if okay, else a valid ACPI_STATUS code 13567754Smsmith * 13667754Smsmith * DESCRIPTION: Takes the resource byte stream and parses it once, calculating 13767754Smsmith * the size buffer needed to hold the linked list that conveys 13867754Smsmith * the resource data. 13967754Smsmith * 14067754Smsmith ******************************************************************************/ 14167754Smsmith 14267754SmsmithACPI_STATUS 14367754SmsmithAcpiRsCalculateByteStreamLength ( 14467754Smsmith RESOURCE *LinkedList, 14567754Smsmith UINT32 *SizeNeeded) 14667754Smsmith{ 14767754Smsmith UINT32 ByteStreamSizeNeeded = 0; 14867754Smsmith UINT32 SegmentSize; 14967754Smsmith EXTENDED_IRQ_RESOURCE *ExIrq = NULL; 15067754Smsmith BOOLEAN Done = FALSE; 15167754Smsmith 15267754Smsmith 15367754Smsmith FUNCTION_TRACE ("RsCalculateByteStreamLength"); 15467754Smsmith 15567754Smsmith 15667754Smsmith while (!Done) 15767754Smsmith { 15867754Smsmith 15967754Smsmith /* 16067754Smsmith * Init the variable that will hold the size to add to the 16167754Smsmith * total. 16267754Smsmith */ 16367754Smsmith SegmentSize = 0; 16467754Smsmith 16567754Smsmith switch (LinkedList->Id) 16667754Smsmith { 16767754Smsmith case Irq: 16867754Smsmith /* 16967754Smsmith * IRQ Resource 17067754Smsmith */ 17167754Smsmith /* 17267754Smsmith * For an IRQ Resource, Byte 3, although optional, will 17367754Smsmith * always be created - it holds IRQ information. 17467754Smsmith */ 17567754Smsmith SegmentSize = 4; 17667754Smsmith break; 17767754Smsmith 17867754Smsmith case Dma: 17967754Smsmith /* 18067754Smsmith * DMA Resource 18167754Smsmith */ 18267754Smsmith /* 18367754Smsmith * For this resource the size is static 18467754Smsmith */ 18567754Smsmith SegmentSize = 3; 18667754Smsmith break; 18767754Smsmith 18867754Smsmith case StartDependentFunctions: 18967754Smsmith /* 19067754Smsmith * Start Dependent Functions Resource 19167754Smsmith */ 19267754Smsmith /* 19367754Smsmith * For a StartDependentFunctions Resource, Byte 1, 19467754Smsmith * although optional, will always be created. 19567754Smsmith */ 19667754Smsmith SegmentSize = 2; 19767754Smsmith break; 19867754Smsmith 19967754Smsmith case EndDependentFunctions: 20067754Smsmith /* 20167754Smsmith * End Dependent Functions Resource 20267754Smsmith */ 20367754Smsmith /* 20467754Smsmith * For this resource the size is static 20567754Smsmith */ 20667754Smsmith SegmentSize = 1; 20767754Smsmith break; 20867754Smsmith 20967754Smsmith case Io: 21067754Smsmith /* 21167754Smsmith * IO Port Resource 21267754Smsmith */ 21367754Smsmith /* 21467754Smsmith * For this resource the size is static 21567754Smsmith */ 21667754Smsmith SegmentSize = 8; 21767754Smsmith break; 21867754Smsmith 21967754Smsmith case FixedIo: 22067754Smsmith /* 22167754Smsmith * Fixed IO Port Resource 22267754Smsmith */ 22367754Smsmith /* 22467754Smsmith * For this resource the size is static 22567754Smsmith */ 22667754Smsmith SegmentSize = 4; 22767754Smsmith break; 22867754Smsmith 22967754Smsmith case VendorSpecific: 23067754Smsmith /* 23167754Smsmith * Vendor Defined Resource 23267754Smsmith */ 23367754Smsmith /* 23467754Smsmith * For a Vendor Specific resource, if the Length is 23567754Smsmith * between 1 and 7 it will be created as a Small 23667754Smsmith * Resource data type, otherwise it is a Large 23767754Smsmith * Resource data type. 23867754Smsmith */ 23967754Smsmith if(LinkedList->Data.VendorSpecific.Length > 7) 24067754Smsmith { 24167754Smsmith SegmentSize = 3; 24267754Smsmith } 24367754Smsmith else 24467754Smsmith { 24567754Smsmith SegmentSize = 1; 24667754Smsmith } 24767754Smsmith SegmentSize += 24867754Smsmith LinkedList->Data.VendorSpecific.Length; 24967754Smsmith break; 25067754Smsmith 25167754Smsmith case EndTag: 25267754Smsmith /* 25367754Smsmith * End Tag 25467754Smsmith */ 25567754Smsmith /* 25667754Smsmith * For this resource the size is static 25767754Smsmith */ 25867754Smsmith SegmentSize = 2; 25967754Smsmith Done = TRUE; 26067754Smsmith break; 26167754Smsmith 26267754Smsmith case Memory24: 26367754Smsmith /* 26467754Smsmith * 24-Bit Memory Resource 26567754Smsmith */ 26667754Smsmith /* 26767754Smsmith * For this resource the size is static 26867754Smsmith */ 26967754Smsmith SegmentSize = 12; 27067754Smsmith break; 27167754Smsmith 27267754Smsmith case Memory32: 27367754Smsmith /* 27467754Smsmith * 32-Bit Memory Range Resource 27567754Smsmith */ 27667754Smsmith /* 27767754Smsmith * For this resource the size is static 27867754Smsmith */ 27967754Smsmith SegmentSize = 20; 28067754Smsmith break; 28167754Smsmith 28267754Smsmith case FixedMemory32: 28367754Smsmith /* 28467754Smsmith * 32-Bit Fixed Memory Resource 28567754Smsmith */ 28667754Smsmith /* 28767754Smsmith * For this resource the size is static 28867754Smsmith */ 28967754Smsmith SegmentSize = 12; 29067754Smsmith break; 29167754Smsmith 29267754Smsmith case Address16: 29367754Smsmith /* 29467754Smsmith * 16-Bit Address Resource 29567754Smsmith */ 29667754Smsmith /* 29767754Smsmith * The base size of this byte stream is 16. If a 29867754Smsmith * Resource Source string is not NULL, add 1 for 29967754Smsmith * the Index + the length of the null terminated 30067754Smsmith * string Resource Source + 1 for the null. 30167754Smsmith */ 30267754Smsmith SegmentSize = 16; 30367754Smsmith 30467754Smsmith if(NULL != LinkedList->Data.Address16.ResourceSource) 30567754Smsmith { 30667754Smsmith SegmentSize += (1 + 30767754Smsmith LinkedList->Data.Address16.ResourceSourceStringLength); 30867754Smsmith } 30967754Smsmith break; 31067754Smsmith 31167754Smsmith case Address32: 31267754Smsmith /* 31367754Smsmith * 32-Bit Address Resource 31467754Smsmith */ 31567754Smsmith /* 31667754Smsmith * The base size of this byte stream is 26. If a Resource 31767754Smsmith * Source string is not NULL, add 1 for the Index + the 31867754Smsmith * length of the null terminated string Resource Source + 31967754Smsmith * 1 for the null. 32067754Smsmith */ 32167754Smsmith SegmentSize = 26; 32267754Smsmith 32367754Smsmith if(NULL != LinkedList->Data.Address16.ResourceSource) 32467754Smsmith { 32567754Smsmith SegmentSize += (1 + 32667754Smsmith LinkedList->Data.Address16.ResourceSourceStringLength); 32767754Smsmith } 32867754Smsmith break; 32967754Smsmith 33067754Smsmith case ExtendedIrq: 33167754Smsmith /* 33267754Smsmith * Extended IRQ Resource 33367754Smsmith */ 33467754Smsmith /* 33567754Smsmith * The base size of this byte stream is 9. This is for an 33667754Smsmith * Interrupt table length of 1. For each additional 33767754Smsmith * interrupt, add 4. 33867754Smsmith * If a Resource Source string is not NULL, add 1 for the 33967754Smsmith * Index + the length of the null terminated string 34067754Smsmith * Resource Source + 1 for the null. 34167754Smsmith */ 34267754Smsmith SegmentSize = 9; 34367754Smsmith 34467754Smsmith SegmentSize += 34567754Smsmith (LinkedList->Data.ExtendedIrq.NumberOfInterrupts - 34667754Smsmith 1) * 4; 34767754Smsmith 34867754Smsmith if(NULL != ExIrq->ResourceSource) 34967754Smsmith { 35067754Smsmith SegmentSize += (1 + 35167754Smsmith LinkedList->Data.ExtendedIrq.ResourceSourceStringLength); 35267754Smsmith } 35367754Smsmith break; 35467754Smsmith 35567754Smsmith default: 35667754Smsmith /* 35767754Smsmith * If we get here, everything is out of sync, 35867754Smsmith * so exit with an error 35967754Smsmith */ 36067754Smsmith return_ACPI_STATUS (AE_AML_ERROR); 36167754Smsmith break; 36267754Smsmith 36367754Smsmith } /* switch (LinkedList->Id) */ 36467754Smsmith 36567754Smsmith /* 36667754Smsmith * Update the total 36767754Smsmith */ 36867754Smsmith ByteStreamSizeNeeded += SegmentSize; 36967754Smsmith 37067754Smsmith /* 37167754Smsmith * Point to the next object 37267754Smsmith */ 37367754Smsmith LinkedList = (RESOURCE *) ((NATIVE_UINT) LinkedList + 37467754Smsmith (NATIVE_UINT) LinkedList->Length); 37567754Smsmith } 37667754Smsmith 37767754Smsmith /* 37867754Smsmith * This is the data the caller needs 37967754Smsmith */ 38067754Smsmith *SizeNeeded = ByteStreamSizeNeeded; 38167754Smsmith 38267754Smsmith return_ACPI_STATUS (AE_OK); 38367754Smsmith} 38467754Smsmith 38567754Smsmith 38667754Smsmith/******************************************************************************* 38767754Smsmith * 38867754Smsmith * FUNCTION: AcpiRsCalculateListLength 38967754Smsmith * 39067754Smsmith * PARAMETERS: ByteStreamBuffer - Pointer to the resource byte stream 39167754Smsmith * ByteStreamBufferLength - Size of ByteStreamBuffer 39267754Smsmith * SizeNeeded - UINT32 pointer of the size buffer 39367754Smsmith * needed to properly return the 39467754Smsmith * parsed data 39567754Smsmith * 39667754Smsmith * RETURN: Status AE_OK if okay, else a valid ACPI_STATUS code 39767754Smsmith * 39867754Smsmith * DESCRIPTION: Takes the resource byte stream and parses it once, calculating 39967754Smsmith * the size buffer needed to hold the linked list that conveys 40067754Smsmith * the resource data. 40167754Smsmith * 40267754Smsmith ******************************************************************************/ 40367754Smsmith 40467754SmsmithACPI_STATUS 40567754SmsmithAcpiRsCalculateListLength ( 40667754Smsmith UINT8 *ByteStreamBuffer, 40767754Smsmith UINT32 ByteStreamBufferLength, 40867754Smsmith UINT32 *SizeNeeded) 40967754Smsmith{ 41067754Smsmith UINT32 BufferSize = 0; 41167754Smsmith UINT32 BytesParsed = 0; 41267754Smsmith UINT8 NumberOfInterrupts = 0; 41367754Smsmith UINT8 NumberOfChannels = 0; 41467754Smsmith UINT8 ResourceType; 41567754Smsmith UINT32 StructureSize; 41667754Smsmith UINT32 BytesConsumed; 41767754Smsmith UINT8 *Buffer; 41867754Smsmith UINT8 Temp8; 41967754Smsmith UINT16 Temp16; 42067754Smsmith UINT8 Index; 42167754Smsmith UINT8 AdditionalBytes; 42267754Smsmith 42367754Smsmith 42467754Smsmith FUNCTION_TRACE ("RsCalculateListLength"); 42567754Smsmith 42667754Smsmith 42767754Smsmith while (BytesParsed < ByteStreamBufferLength) 42867754Smsmith { 42967754Smsmith /* 43067754Smsmith * Look at the next byte in the stream 43167754Smsmith */ 43267754Smsmith ResourceType = *ByteStreamBuffer; 43367754Smsmith 43467754Smsmith /* 43567754Smsmith * See if this is a small or large resource 43667754Smsmith */ 43767754Smsmith if(ResourceType & 0x80) 43867754Smsmith { 43967754Smsmith /* 44067754Smsmith * Large Resource Type 44167754Smsmith */ 44267754Smsmith switch (ResourceType) 44367754Smsmith { 44467754Smsmith case MEMORY_RANGE_24: 44567754Smsmith /* 44667754Smsmith * 24-Bit Memory Resource 44767754Smsmith */ 44867754Smsmith BytesConsumed = 12; 44967754Smsmith 45067754Smsmith StructureSize = sizeof (MEMORY24_RESOURCE) + 45167754Smsmith RESOURCE_LENGTH_NO_DATA; 45267754Smsmith break; 45367754Smsmith 45467754Smsmith case LARGE_VENDOR_DEFINED: 45567754Smsmith /* 45667754Smsmith * Vendor Defined Resource 45767754Smsmith */ 45867754Smsmith Buffer = ByteStreamBuffer; 45967754Smsmith ++Buffer; 46067754Smsmith 46167754Smsmith MOVE_UNALIGNED16_TO_16 (&Temp16, Buffer); 46267754Smsmith BytesConsumed = Temp16 + 3; 46367754Smsmith 46467754Smsmith /* 46567754Smsmith * Ensure a 32-bit boundary for the structure 46667754Smsmith */ 46767754Smsmith Temp16 = (UINT16) ROUND_UP_TO_32BITS (Temp16); 46867754Smsmith 46967754Smsmith StructureSize = sizeof (VENDOR_RESOURCE) + 47067754Smsmith RESOURCE_LENGTH_NO_DATA + 47167754Smsmith (Temp16 * sizeof (UINT8)); 47267754Smsmith break; 47367754Smsmith 47467754Smsmith case MEMORY_RANGE_32: 47567754Smsmith /* 47667754Smsmith * 32-Bit Memory Range Resource 47767754Smsmith */ 47867754Smsmith 47967754Smsmith BytesConsumed = 20; 48067754Smsmith 48167754Smsmith StructureSize = sizeof (MEMORY32_RESOURCE) + 48267754Smsmith RESOURCE_LENGTH_NO_DATA; 48367754Smsmith break; 48467754Smsmith 48567754Smsmith case FIXED_MEMORY_RANGE_32: 48667754Smsmith /* 48767754Smsmith * 32-Bit Fixed Memory Resource 48867754Smsmith */ 48967754Smsmith BytesConsumed = 12; 49067754Smsmith 49167754Smsmith StructureSize = sizeof(FIXED_MEMORY32_RESOURCE) + 49267754Smsmith RESOURCE_LENGTH_NO_DATA; 49367754Smsmith break; 49467754Smsmith 49567754Smsmith case DWORD_ADDRESS_SPACE: 49667754Smsmith /* 49767754Smsmith * 32-Bit Address Resource 49867754Smsmith */ 49967754Smsmith Buffer = ByteStreamBuffer; 50067754Smsmith 50167754Smsmith ++Buffer; 50267754Smsmith MOVE_UNALIGNED16_TO_16 (&Temp16, Buffer); 50367754Smsmith 50467754Smsmith BytesConsumed = Temp16 + 3; 50567754Smsmith 50667754Smsmith /* 50767754Smsmith * Resource Source Index and Resource Source are 50867754Smsmith * optional elements. Check the length of the 50967754Smsmith * Bytestream. If it is greater than 23, that 51067754Smsmith * means that an Index exists and is followed by 51167754Smsmith * a null termininated string. Therefore, set 51267754Smsmith * the temp variable to the length minus the minimum 51367754Smsmith * byte stream length plus the byte for the Index to 51467754Smsmith * determine the size of the NULL terminiated string. 51567754Smsmith */ 51667754Smsmith if (23 < Temp16) 51767754Smsmith { 51867754Smsmith Temp8 = (UINT8) (Temp16 - 24); 51967754Smsmith } 52067754Smsmith else 52167754Smsmith { 52267754Smsmith Temp8 = 0; 52367754Smsmith } 52467754Smsmith 52567754Smsmith /* 52667754Smsmith * Ensure a 32-bit boundary for the structure 52767754Smsmith */ 52867754Smsmith Temp8 = (UINT8) ROUND_UP_TO_32BITS (Temp8); 52967754Smsmith 53067754Smsmith StructureSize = sizeof (ADDRESS32_RESOURCE) + 53167754Smsmith RESOURCE_LENGTH_NO_DATA + 53267754Smsmith (Temp8 * sizeof (UINT8)); 53367754Smsmith break; 53467754Smsmith 53567754Smsmith case WORD_ADDRESS_SPACE: 53667754Smsmith /* 53767754Smsmith * 16-Bit Address Resource 53867754Smsmith */ 53967754Smsmith Buffer = ByteStreamBuffer; 54067754Smsmith 54167754Smsmith ++Buffer; 54267754Smsmith MOVE_UNALIGNED16_TO_16 (&Temp16, Buffer); 54367754Smsmith 54467754Smsmith BytesConsumed = Temp16 + 3; 54567754Smsmith 54667754Smsmith /* 54767754Smsmith * Resource Source Index and Resource Source are 54867754Smsmith * optional elements. Check the length of the 54967754Smsmith * Bytestream. If it is greater than 13, that 55067754Smsmith * means that an Index exists and is followed by 55167754Smsmith * a null termininated string. Therefore, set 55267754Smsmith * the temp variable to the length minus the minimum 55367754Smsmith * byte stream length plus the byte for the Index to 55467754Smsmith * determine the size of the NULL terminiated string. 55567754Smsmith */ 55667754Smsmith if (13 < Temp16) 55767754Smsmith { 55867754Smsmith Temp8 = (UINT8) (Temp16 - 14); 55967754Smsmith } 56067754Smsmith else 56167754Smsmith { 56267754Smsmith Temp8 = 0; 56367754Smsmith } 56467754Smsmith 56567754Smsmith /* 56667754Smsmith * Ensure a 32-bit boundry for the structure 56767754Smsmith */ 56867754Smsmith Temp8 = (UINT8) ROUND_UP_TO_32BITS (Temp8); 56967754Smsmith 57067754Smsmith StructureSize = sizeof (ADDRESS16_RESOURCE) + 57167754Smsmith RESOURCE_LENGTH_NO_DATA + 57267754Smsmith (Temp8 * sizeof (UINT8)); 57367754Smsmith break; 57467754Smsmith 57567754Smsmith case EXTENDED_IRQ: 57667754Smsmith /* 57767754Smsmith * Extended IRQ 57867754Smsmith */ 57967754Smsmith Buffer = ByteStreamBuffer; 58067754Smsmith 58167754Smsmith ++Buffer; 58267754Smsmith MOVE_UNALIGNED16_TO_16 (&Temp16, Buffer); 58367754Smsmith 58467754Smsmith BytesConsumed = Temp16 + 3; 58567754Smsmith 58667754Smsmith /* 58767754Smsmith * Point past the length field and the 58867754Smsmith * Interrupt vector flags to save off the 58967754Smsmith * Interrupt table length to the Temp8 variable. 59067754Smsmith */ 59167754Smsmith Buffer += 3; 59267754Smsmith Temp8 = *Buffer; 59367754Smsmith 59467754Smsmith /* 59567754Smsmith * To compensate for multiple interrupt numbers, 59667754Smsmith * Add 4 bytes for each additional interrupts 59767754Smsmith * greater than 1 59867754Smsmith */ 59967754Smsmith AdditionalBytes = (UINT8) ((Temp8 - 1) * 4); 60067754Smsmith 60167754Smsmith /* 60267754Smsmith * Resource Source Index and Resource Source are 60367754Smsmith * optional elements. Check the length of the 60467754Smsmith * Bytestream. If it is greater than 9, that 60567754Smsmith * means that an Index exists and is followed by 60667754Smsmith * a null termininated string. Therefore, set 60767754Smsmith * the temp variable to the length minus the minimum 60867754Smsmith * byte stream length plus the byte for the Index to 60967754Smsmith * determine the size of the NULL terminiated string. 61067754Smsmith */ 61167754Smsmith if (9 + AdditionalBytes < Temp16) 61267754Smsmith { 61367754Smsmith Temp8 = (UINT8) (Temp16 - (9 + AdditionalBytes)); 61467754Smsmith } 61567754Smsmith 61667754Smsmith else 61767754Smsmith { 61867754Smsmith Temp8 = 0; 61967754Smsmith } 62067754Smsmith 62167754Smsmith /* 62267754Smsmith * Ensure a 32-bit boundry for the structure 62367754Smsmith */ 62467754Smsmith Temp8 = (UINT8) ROUND_UP_TO_32BITS (Temp8); 62567754Smsmith 62667754Smsmith StructureSize = sizeof (EXTENDED_IRQ_RESOURCE) + 62767754Smsmith RESOURCE_LENGTH_NO_DATA + 62867754Smsmith (AdditionalBytes * sizeof (UINT8)) + 62967754Smsmith (Temp8 * sizeof (UINT8)); 63067754Smsmith 63167754Smsmith break; 63267754Smsmith 63367754Smsmith/* TBD: [Future] 64-bit not currently supported */ 63467754Smsmith/* 63567754Smsmith case 0x8A: 63667754Smsmith break; 63767754Smsmith*/ 63867754Smsmith 63967754Smsmith default: 64067754Smsmith /* 64167754Smsmith * If we get here, everything is out of sync, 64267754Smsmith * so exit with an error 64367754Smsmith */ 64467754Smsmith return_ACPI_STATUS (AE_AML_ERROR); 64567754Smsmith break; 64667754Smsmith } 64767754Smsmith } 64867754Smsmith 64967754Smsmith else 65067754Smsmith { 65167754Smsmith /* 65267754Smsmith * Small Resource Type 65367754Smsmith * Only bits 7:3 are valid 65467754Smsmith */ 65567754Smsmith ResourceType >>= 3; 65667754Smsmith 65767754Smsmith switch (ResourceType) 65867754Smsmith { 65967754Smsmith case IRQ_FORMAT: 66067754Smsmith /* 66167754Smsmith * IRQ Resource 66267754Smsmith */ 66367754Smsmith /* 66467754Smsmith * Determine if it there are two or three 66567754Smsmith * trailing bytes 66667754Smsmith */ 66767754Smsmith Buffer = ByteStreamBuffer; 66867754Smsmith Temp8 = *Buffer; 66967754Smsmith 67067754Smsmith if(Temp8 & 0x01) 67167754Smsmith { 67267754Smsmith BytesConsumed = 4; 67367754Smsmith } 67467754Smsmith 67567754Smsmith else 67667754Smsmith { 67767754Smsmith BytesConsumed = 3; 67867754Smsmith } 67967754Smsmith 68067754Smsmith /* 68167754Smsmith * Point past the descriptor 68267754Smsmith */ 68367754Smsmith ++Buffer; 68467754Smsmith 68567754Smsmith /* 68667754Smsmith * Look at the number of bits set 68767754Smsmith */ 68867754Smsmith MOVE_UNALIGNED16_TO_16 (&Temp16, Buffer); 68967754Smsmith 69067754Smsmith for (Index = 0; Index < 16; Index++) 69167754Smsmith { 69267754Smsmith if (Temp16 & 0x1) 69367754Smsmith { 69467754Smsmith ++NumberOfInterrupts; 69567754Smsmith } 69667754Smsmith 69767754Smsmith Temp16 >>= 1; 69867754Smsmith } 69967754Smsmith 70067754Smsmith StructureSize = sizeof (IO_RESOURCE) + 70167754Smsmith RESOURCE_LENGTH_NO_DATA + 70267754Smsmith (NumberOfInterrupts * sizeof (UINT32)); 70367754Smsmith break; 70467754Smsmith 70567754Smsmith 70667754Smsmith case DMA_FORMAT: 70767754Smsmith 70867754Smsmith /* 70967754Smsmith * DMA Resource 71067754Smsmith */ 71167754Smsmith Buffer = ByteStreamBuffer; 71267754Smsmith 71367754Smsmith BytesConsumed = 3; 71467754Smsmith 71567754Smsmith /* 71667754Smsmith * Point past the descriptor 71767754Smsmith */ 71867754Smsmith ++Buffer; 71967754Smsmith 72067754Smsmith /* 72167754Smsmith * Look at the number of bits set 72267754Smsmith */ 72367754Smsmith Temp8 = *Buffer; 72467754Smsmith 72567754Smsmith for(Index = 0; Index < 8; Index++) 72667754Smsmith { 72767754Smsmith if(Temp8 & 0x1) 72867754Smsmith { 72967754Smsmith ++NumberOfChannels; 73067754Smsmith } 73167754Smsmith 73267754Smsmith Temp8 >>= 1; 73367754Smsmith } 73467754Smsmith 73567754Smsmith StructureSize = sizeof (DMA_RESOURCE) + 73667754Smsmith RESOURCE_LENGTH_NO_DATA + 73767754Smsmith (NumberOfChannels * sizeof (UINT32)); 73867754Smsmith break; 73967754Smsmith 74067754Smsmith 74167754Smsmith case START_DEPENDENT_TAG: 74267754Smsmith 74367754Smsmith /* 74467754Smsmith * Start Dependent Functions Resource 74567754Smsmith */ 74667754Smsmith /* 74767754Smsmith * Determine if it there are two or three trailing bytes 74867754Smsmith */ 74967754Smsmith Buffer = ByteStreamBuffer; 75067754Smsmith Temp8 = *Buffer; 75167754Smsmith 75267754Smsmith if(Temp8 & 0x01) 75367754Smsmith { 75467754Smsmith BytesConsumed = 2; 75567754Smsmith } 75667754Smsmith else 75767754Smsmith { 75867754Smsmith BytesConsumed = 1; 75967754Smsmith } 76067754Smsmith 76167754Smsmith 76267754Smsmith StructureSize = 76367754Smsmith sizeof (START_DEPENDENT_FUNCTIONS_RESOURCE) + 76467754Smsmith RESOURCE_LENGTH_NO_DATA; 76567754Smsmith break; 76667754Smsmith 76767754Smsmith 76867754Smsmith case END_DEPENDENT_TAG: 76967754Smsmith 77067754Smsmith /* 77167754Smsmith * End Dependent Functions Resource 77267754Smsmith */ 77367754Smsmith BytesConsumed = 1; 77467754Smsmith StructureSize = RESOURCE_LENGTH; 77567754Smsmith break; 77667754Smsmith 77767754Smsmith 77867754Smsmith case IO_PORT_DESCRIPTOR: 77967754Smsmith /* 78067754Smsmith * IO Port Resource 78167754Smsmith */ 78267754Smsmith BytesConsumed = 8; 78367754Smsmith StructureSize = sizeof (IO_RESOURCE) + 78467754Smsmith RESOURCE_LENGTH_NO_DATA; 78567754Smsmith break; 78667754Smsmith 78767754Smsmith 78867754Smsmith case FIXED_LOCATION_IO_DESCRIPTOR: 78967754Smsmith 79067754Smsmith /* 79167754Smsmith * Fixed IO Port Resource 79267754Smsmith */ 79367754Smsmith BytesConsumed = 4; 79467754Smsmith StructureSize = sizeof (FIXED_IO_RESOURCE) + 79567754Smsmith RESOURCE_LENGTH_NO_DATA; 79667754Smsmith break; 79767754Smsmith 79867754Smsmith 79967754Smsmith case SMALL_VENDOR_DEFINED: 80067754Smsmith 80167754Smsmith /* 80267754Smsmith * Vendor Specific Resource 80367754Smsmith */ 80467754Smsmith Buffer = ByteStreamBuffer; 80567754Smsmith 80667754Smsmith Temp8 = *Buffer; 80767754Smsmith Temp8 = (UINT8) (Temp8 & 0x7); 80867754Smsmith BytesConsumed = Temp8 + 1; 80967754Smsmith 81067754Smsmith /* 81167754Smsmith * Ensure a 32-bit boundry for the structure 81267754Smsmith */ 81367754Smsmith Temp8 = (UINT8) ROUND_UP_TO_32BITS (Temp8); 81467754Smsmith StructureSize = sizeof (VENDOR_RESOURCE) + 81567754Smsmith RESOURCE_LENGTH_NO_DATA + 81667754Smsmith (Temp8 * sizeof (UINT8)); 81767754Smsmith break; 81867754Smsmith 81967754Smsmith 82067754Smsmith case END_TAG: 82167754Smsmith 82267754Smsmith /* 82367754Smsmith * End Tag 82467754Smsmith */ 82567754Smsmith BytesConsumed = 2; 82667754Smsmith StructureSize = RESOURCE_LENGTH; 82767754Smsmith break; 82867754Smsmith 82967754Smsmith 83067754Smsmith default: 83167754Smsmith /* 83267754Smsmith * If we get here, everything is out of sync, 83367754Smsmith * so exit with an error 83467754Smsmith */ 83567754Smsmith return_ACPI_STATUS (AE_AML_ERROR); 83667754Smsmith break; 83767754Smsmith 83867754Smsmith } /* switch */ 83967754Smsmith 84067754Smsmith } /* if(ResourceType & 0x80) */ 84167754Smsmith 84267754Smsmith /* 84367754Smsmith * Update the return value and counter 84467754Smsmith */ 84567754Smsmith BufferSize += StructureSize; 84667754Smsmith BytesParsed += BytesConsumed; 84767754Smsmith 84867754Smsmith /* 84967754Smsmith * Set the byte stream to point to the next resource 85067754Smsmith */ 85167754Smsmith ByteStreamBuffer += BytesConsumed; 85267754Smsmith 85367754Smsmith } 85467754Smsmith 85567754Smsmith /* 85667754Smsmith * This is the data the caller needs 85767754Smsmith */ 85867754Smsmith *SizeNeeded = BufferSize; 85967754Smsmith 86067754Smsmith return_ACPI_STATUS (AE_OK); 86167754Smsmith} 86267754Smsmith 86367754Smsmith 86467754Smsmith/******************************************************************************* 86567754Smsmith * 86667754Smsmith * FUNCTION: AcpiRsCalculatePciRoutingTableLength 86767754Smsmith * 86867754Smsmith * PARAMETERS: PackageObject - Pointer to the package object 86967754Smsmith * BufferSizeNeeded - UINT32 pointer of the size buffer 87067754Smsmith * needed to properly return the 87167754Smsmith * parsed data 87267754Smsmith * 87367754Smsmith * RETURN: Status AE_OK 87467754Smsmith * 87567754Smsmith * DESCRIPTION: Given a package representing a PCI routing table, this 87667754Smsmith * calculates the size of the corresponding linked list of 87767754Smsmith * descriptions. 87867754Smsmith * 87967754Smsmith ******************************************************************************/ 88067754Smsmith 88167754SmsmithACPI_STATUS 88267754SmsmithAcpiRsCalculatePciRoutingTableLength ( 88367754Smsmith ACPI_OPERAND_OBJECT *PackageObject, 88467754Smsmith UINT32 *BufferSizeNeeded) 88567754Smsmith{ 88667754Smsmith UINT32 NumberOfElements; 88767754Smsmith UINT32 TempSizeNeeded; 88867754Smsmith ACPI_OPERAND_OBJECT **TopObjectList; 88967754Smsmith UINT32 Index; 89067754Smsmith ACPI_OPERAND_OBJECT *PackageElement; 89167754Smsmith ACPI_OPERAND_OBJECT **SubObjectList; 89267754Smsmith BOOLEAN NameFound; 89367754Smsmith UINT32 TableIndex; 89467754Smsmith 89567754Smsmith 89667754Smsmith FUNCTION_TRACE ("AcpiRsCalculatePciRoutingTableLength"); 89767754Smsmith 89867754Smsmith 89967754Smsmith NumberOfElements = PackageObject->Package.Count; 90067754Smsmith 90167754Smsmith /* 90267754Smsmith * Calculate the size of the return buffer. 90367754Smsmith * The base size is the number of elements * the sizes of the 90467754Smsmith * structures. Additional space for the strings is added below. 90567754Smsmith * The minus one is to subtract the size of the UINT8 Source[1] 90667754Smsmith * member because it is added below. 90767754Smsmith * 90867754Smsmith * NOTE: The NumberOfElements is incremented by one to add an end 90967754Smsmith * table structure that is essentially a structure of zeros. 91067754Smsmith */ 91167754Smsmith TempSizeNeeded = (NumberOfElements + 1) * 91267754Smsmith (sizeof (PCI_ROUTING_TABLE) - 1); 91367754Smsmith 91467754Smsmith /* 91567754Smsmith * But each PRT_ENTRY structure has a pointer to a string and 91667754Smsmith * the size of that string must be found. 91767754Smsmith */ 91867754Smsmith TopObjectList = PackageObject->Package.Elements; 91967754Smsmith 92067754Smsmith for (Index = 0; Index < NumberOfElements; Index++) 92167754Smsmith { 92267754Smsmith /* 92367754Smsmith * Dereference the sub-package 92467754Smsmith */ 92567754Smsmith PackageElement = *TopObjectList; 92667754Smsmith 92767754Smsmith /* 92867754Smsmith * The SubObjectList will now point to an array of the 92967754Smsmith * four IRQ elements: Address, Pin, Source and SourceIndex 93067754Smsmith */ 93167754Smsmith SubObjectList = PackageElement->Package.Elements; 93267754Smsmith 93367754Smsmith /* 93467754Smsmith * Scan the IrqTableElements for the Source Name String 93567754Smsmith */ 93667754Smsmith NameFound = FALSE; 93767754Smsmith 93867754Smsmith for (TableIndex = 0; TableIndex < 4 && !NameFound; TableIndex++) 93967754Smsmith { 94067754Smsmith if (ACPI_TYPE_STRING == (*SubObjectList)->Common.Type) 94167754Smsmith { 94267754Smsmith NameFound = TRUE; 94367754Smsmith } 94467754Smsmith 94567754Smsmith else 94667754Smsmith { 94767754Smsmith /* 94867754Smsmith * Look at the next element 94967754Smsmith */ 95067754Smsmith SubObjectList++; 95167754Smsmith } 95267754Smsmith } 95367754Smsmith 95467754Smsmith /* 95567754Smsmith * Was a String type found? 95667754Smsmith */ 95767754Smsmith if (TRUE == NameFound) 95867754Smsmith { 95967754Smsmith /* 96067754Smsmith * The length String.Length field includes the 96167754Smsmith * terminating NULL 96267754Smsmith */ 96367754Smsmith TempSizeNeeded += (*SubObjectList)->String.Length; 96467754Smsmith } 96567754Smsmith 96667754Smsmith else 96767754Smsmith { 96867754Smsmith /* 96967754Smsmith * If no name was found, then this is a NULL, which is 97067754Smsmith * translated as a UINT32 zero. 97167754Smsmith */ 97267754Smsmith TempSizeNeeded += sizeof(UINT32); 97367754Smsmith } 97467754Smsmith 97567754Smsmith /* 97667754Smsmith * Point to the next ACPI_OPERAND_OBJECT 97767754Smsmith */ 97867754Smsmith TopObjectList++; 97967754Smsmith } 98067754Smsmith 98167754Smsmith /* Align the count before returning it */ 98267754Smsmith 98367754Smsmith *BufferSizeNeeded = ROUND_UP_TO_32BITS (TempSizeNeeded); 98467754Smsmith 98567754Smsmith return_ACPI_STATUS (AE_OK); 98667754Smsmith}