rscalc.c revision 193267
167754Smsmith/******************************************************************************* 267754Smsmith * 377424Smsmith * Module Name: rscalc - Calculate stream and list lengths 467754Smsmith * 567754Smsmith ******************************************************************************/ 667754Smsmith 767754Smsmith/****************************************************************************** 867754Smsmith * 967754Smsmith * 1. Copyright Notice 1067754Smsmith * 11193267Sjkim * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. 1270243Smsmith * All rights reserved. 1367754Smsmith * 1467754Smsmith * 2. License 1567754Smsmith * 1667754Smsmith * 2.1. This is your license from Intel Corp. under its intellectual property 1767754Smsmith * rights. You may have additional license terms from the party that provided 1867754Smsmith * you this software, covering your right to use that party's intellectual 1967754Smsmith * property rights. 2067754Smsmith * 2167754Smsmith * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 2267754Smsmith * copy of the source code appearing in this file ("Covered Code") an 2367754Smsmith * irrevocable, perpetual, worldwide license under Intel's copyrights in the 2467754Smsmith * base code distributed originally by Intel ("Original Intel Code") to copy, 2567754Smsmith * make derivatives, distribute, use and display any portion of the Covered 2667754Smsmith * Code in any form, with the right to sublicense such rights; and 2767754Smsmith * 2867754Smsmith * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 2967754Smsmith * license (with the right to sublicense), under only those claims of Intel 3067754Smsmith * patents that are infringed by the Original Intel Code, to make, use, sell, 3167754Smsmith * offer to sell, and import the Covered Code and derivative works thereof 3267754Smsmith * solely to the minimum extent necessary to exercise the above copyright 3367754Smsmith * license, and in no event shall the patent license extend to any additions 3467754Smsmith * to or modifications of the Original Intel Code. No other license or right 3567754Smsmith * is granted directly or by implication, estoppel or otherwise; 3667754Smsmith * 3767754Smsmith * The above copyright and patent license is granted only if the following 3867754Smsmith * conditions are met: 3967754Smsmith * 4067754Smsmith * 3. Conditions 4167754Smsmith * 4267754Smsmith * 3.1. Redistribution of Source with Rights to Further Distribute Source. 4367754Smsmith * Redistribution of source code of any substantial portion of the Covered 4467754Smsmith * Code or modification with rights to further distribute source must include 4567754Smsmith * the above Copyright Notice, the above License, this list of Conditions, 4667754Smsmith * and the following Disclaimer and Export Compliance provision. In addition, 4767754Smsmith * Licensee must cause all Covered Code to which Licensee contributes to 4867754Smsmith * contain a file documenting the changes Licensee made to create that Covered 4967754Smsmith * Code and the date of any change. Licensee must include in that file the 5067754Smsmith * documentation of any changes made by any predecessor Licensee. Licensee 5167754Smsmith * must include a prominent statement that the modification is derived, 5267754Smsmith * directly or indirectly, from Original Intel Code. 5367754Smsmith * 5467754Smsmith * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 5567754Smsmith * Redistribution of source code of any substantial portion of the Covered 5667754Smsmith * Code or modification without rights to further distribute source must 5767754Smsmith * include the following Disclaimer and Export Compliance provision in the 5867754Smsmith * documentation and/or other materials provided with distribution. In 5967754Smsmith * addition, Licensee may not authorize further sublicense of source of any 6067754Smsmith * portion of the Covered Code, and must include terms to the effect that the 6167754Smsmith * license from Licensee to its licensee is limited to the intellectual 6267754Smsmith * property embodied in the software Licensee provides to its licensee, and 6367754Smsmith * not to intellectual property embodied in modifications its licensee may 6467754Smsmith * make. 6567754Smsmith * 6667754Smsmith * 3.3. Redistribution of Executable. Redistribution in executable form of any 6767754Smsmith * substantial portion of the Covered Code or modification must reproduce the 6867754Smsmith * above Copyright Notice, and the following Disclaimer and Export Compliance 6967754Smsmith * provision in the documentation and/or other materials provided with the 7067754Smsmith * distribution. 7167754Smsmith * 7267754Smsmith * 3.4. Intel retains all right, title, and interest in and to the Original 7367754Smsmith * Intel Code. 7467754Smsmith * 7567754Smsmith * 3.5. Neither the name Intel nor any other trademark owned or controlled by 7667754Smsmith * Intel shall be used in advertising or otherwise to promote the sale, use or 7767754Smsmith * other dealings in products derived from or relating to the Covered Code 7867754Smsmith * without prior written authorization from Intel. 7967754Smsmith * 8067754Smsmith * 4. Disclaimer and Export Compliance 8167754Smsmith * 8267754Smsmith * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 8367754Smsmith * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 8467754Smsmith * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 8567754Smsmith * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 8667754Smsmith * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 8767754Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 8867754Smsmith * PARTICULAR PURPOSE. 8967754Smsmith * 9067754Smsmith * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 9167754Smsmith * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 9267754Smsmith * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 9367754Smsmith * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 9467754Smsmith * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 9567754Smsmith * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 9667754Smsmith * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 9767754Smsmith * LIMITED REMEDY. 9867754Smsmith * 9967754Smsmith * 4.3. Licensee shall not export, either directly or indirectly, any of this 10067754Smsmith * software or system incorporating such software without first obtaining any 10167754Smsmith * required license or other approval from the U. S. Department of Commerce or 10267754Smsmith * any other agency or department of the United States Government. In the 10367754Smsmith * event Licensee exports any such software from the United States or 10467754Smsmith * re-exports any such software from a foreign destination, Licensee shall 10567754Smsmith * ensure that the distribution and export/re-export of the software is in 10667754Smsmith * compliance with all laws, regulations, orders, or other restrictions of the 10767754Smsmith * U.S. Export Administration Regulations. Licensee agrees that neither it nor 10867754Smsmith * any of its subsidiaries will export/re-export any technical data, process, 10967754Smsmith * software, or service, directly or indirectly, to any country for which the 11067754Smsmith * United States government or any agency thereof requires an export license, 11167754Smsmith * other governmental approval, or letter of assurance, without first obtaining 11267754Smsmith * such license, approval or letter. 11367754Smsmith * 11467754Smsmith *****************************************************************************/ 11567754Smsmith 11667754Smsmith#define __RSCALC_C__ 11767754Smsmith 118193251Sjkim#include "acpi.h" 119193267Sjkim#include "accommon.h" 120193251Sjkim#include "acresrc.h" 121193251Sjkim#include "acnamesp.h" 12267754Smsmith 123193267Sjkim 12477424Smsmith#define _COMPONENT ACPI_RESOURCES 12591116Smsmith ACPI_MODULE_NAME ("rscalc") 12667754Smsmith 12767754Smsmith 128151937Sjkim/* Local prototypes */ 129151937Sjkim 130151937Sjkimstatic UINT8 131151937SjkimAcpiRsCountSetBits ( 132151937Sjkim UINT16 BitField); 133151937Sjkim 134151937Sjkimstatic ACPI_RS_LENGTH 135151937SjkimAcpiRsStructOptionLength ( 136151937Sjkim ACPI_RESOURCE_SOURCE *ResourceSource); 137151937Sjkim 138151937Sjkimstatic UINT32 139151937SjkimAcpiRsStreamOptionLength ( 140151937Sjkim UINT32 ResourceLength, 141151937Sjkim UINT32 MinimumTotalLength); 142151937Sjkim 143151937Sjkim 14467754Smsmith/******************************************************************************* 14567754Smsmith * 146151937Sjkim * FUNCTION: AcpiRsCountSetBits 14767754Smsmith * 148151937Sjkim * PARAMETERS: BitField - Field in which to count bits 14967754Smsmith * 150151937Sjkim * RETURN: Number of bits set within the field 15167754Smsmith * 152151937Sjkim * DESCRIPTION: Count the number of bits set in a resource field. Used for 153151937Sjkim * (Short descriptor) interrupt and DMA lists. 15467754Smsmith * 15567754Smsmith ******************************************************************************/ 15667754Smsmith 157151937Sjkimstatic UINT8 158151937SjkimAcpiRsCountSetBits ( 159151937Sjkim UINT16 BitField) 16067754Smsmith{ 161151937Sjkim UINT8 BitsSet; 16267754Smsmith 16367754Smsmith 164151937Sjkim ACPI_FUNCTION_ENTRY (); 16567754Smsmith 16667754Smsmith 167151937Sjkim for (BitsSet = 0; BitField; BitsSet++) 16867754Smsmith { 169151937Sjkim /* Zero the least significant bit that is set */ 17067754Smsmith 171193267Sjkim BitField &= (UINT16) (BitField - 1); 172151937Sjkim } 17367754Smsmith 174151937Sjkim return (BitsSet); 175151937Sjkim} 17667754Smsmith 17767754Smsmith 178151937Sjkim/******************************************************************************* 179151937Sjkim * 180151937Sjkim * FUNCTION: AcpiRsStructOptionLength 181151937Sjkim * 182151937Sjkim * PARAMETERS: ResourceSource - Pointer to optional descriptor field 183151937Sjkim * 184151937Sjkim * RETURN: Status 185151937Sjkim * 186151937Sjkim * DESCRIPTION: Common code to handle optional ResourceSourceIndex and 187151937Sjkim * ResourceSource fields in some Large descriptors. Used during 188151937Sjkim * list-to-stream conversion 189151937Sjkim * 190151937Sjkim ******************************************************************************/ 19167754Smsmith 192151937Sjkimstatic ACPI_RS_LENGTH 193151937SjkimAcpiRsStructOptionLength ( 194151937Sjkim ACPI_RESOURCE_SOURCE *ResourceSource) 195151937Sjkim{ 196151937Sjkim ACPI_FUNCTION_ENTRY (); 19767754Smsmith 19867754Smsmith 199151937Sjkim /* 200151937Sjkim * If the ResourceSource string is valid, return the size of the string 201151937Sjkim * (StringLength includes the NULL terminator) plus the size of the 202151937Sjkim * ResourceSourceIndex (1). 203151937Sjkim */ 204151937Sjkim if (ResourceSource->StringPtr) 205151937Sjkim { 206151937Sjkim return ((ACPI_RS_LENGTH) (ResourceSource->StringLength + 1)); 207151937Sjkim } 20867754Smsmith 209151937Sjkim return (0); 210151937Sjkim} 21167754Smsmith 21267754Smsmith 213151937Sjkim/******************************************************************************* 214151937Sjkim * 215151937Sjkim * FUNCTION: AcpiRsStreamOptionLength 216151937Sjkim * 217151937Sjkim * PARAMETERS: ResourceLength - Length from the resource header 218151937Sjkim * MinimumTotalLength - Minimum length of this resource, before 219151937Sjkim * any optional fields. Includes header size 220151937Sjkim * 221151937Sjkim * RETURN: Length of optional string (0 if no string present) 222151937Sjkim * 223151937Sjkim * DESCRIPTION: Common code to handle optional ResourceSourceIndex and 224151937Sjkim * ResourceSource fields in some Large descriptors. Used during 225151937Sjkim * stream-to-list conversion 226151937Sjkim * 227151937Sjkim ******************************************************************************/ 22867754Smsmith 229151937Sjkimstatic UINT32 230151937SjkimAcpiRsStreamOptionLength ( 231151937Sjkim UINT32 ResourceLength, 232151937Sjkim UINT32 MinimumAmlResourceLength) 233151937Sjkim{ 234151937Sjkim UINT32 StringLength = 0; 23567754Smsmith 23667754Smsmith 237151937Sjkim ACPI_FUNCTION_ENTRY (); 23867754Smsmith 23967754Smsmith 240151937Sjkim /* 241151937Sjkim * The ResourceSourceIndex and ResourceSource are optional elements of some 242151937Sjkim * Large-type resource descriptors. 243151937Sjkim */ 24467754Smsmith 245151937Sjkim /* 246151937Sjkim * If the length of the actual resource descriptor is greater than the ACPI 247151937Sjkim * spec-defined minimum length, it means that a ResourceSourceIndex exists 248151937Sjkim * and is followed by a (required) null terminated string. The string length 249151937Sjkim * (including the null terminator) is the resource length minus the minimum 250151937Sjkim * length, minus one byte for the ResourceSourceIndex itself. 251151937Sjkim */ 252151937Sjkim if (ResourceLength > MinimumAmlResourceLength) 253151937Sjkim { 254151937Sjkim /* Compute the length of the optional string */ 25577424Smsmith 256151937Sjkim StringLength = ResourceLength - MinimumAmlResourceLength - 1; 257151937Sjkim } 25877424Smsmith 259167802Sjkim /* 260167802Sjkim * Round the length up to a multiple of the native word in order to 261167802Sjkim * guarantee that the entire resource descriptor is native word aligned 262167802Sjkim */ 263167802Sjkim return ((UINT32) ACPI_ROUND_UP_TO_NATIVE_WORD (StringLength)); 26467754Smsmith} 26567754Smsmith 26667754Smsmith 26767754Smsmith/******************************************************************************* 26867754Smsmith * 269151937Sjkim * FUNCTION: AcpiRsGetAmlLength 27067754Smsmith * 271151937Sjkim * PARAMETERS: Resource - Pointer to the resource linked list 272151937Sjkim * SizeNeeded - Where the required size is returned 27367754Smsmith * 27477424Smsmith * RETURN: Status 27567754Smsmith * 276151937Sjkim * DESCRIPTION: Takes a linked list of internal resource descriptors and 277151937Sjkim * calculates the size buffer needed to hold the corresponding 278151937Sjkim * external resource byte stream. 27967754Smsmith * 28067754Smsmith ******************************************************************************/ 28167754Smsmith 28267754SmsmithACPI_STATUS 283151937SjkimAcpiRsGetAmlLength ( 284151937Sjkim ACPI_RESOURCE *Resource, 28591116Smsmith ACPI_SIZE *SizeNeeded) 28667754Smsmith{ 287151937Sjkim ACPI_SIZE AmlSizeNeeded = 0; 288167802Sjkim ACPI_RS_LENGTH TotalSize; 28967754Smsmith 29067754Smsmith 291167802Sjkim ACPI_FUNCTION_TRACE (RsGetAmlLength); 29267754Smsmith 29367754Smsmith 294151937Sjkim /* Traverse entire list of internal resource descriptors */ 295151937Sjkim 296151937Sjkim while (Resource) 29767754Smsmith { 298151937Sjkim /* Validate the descriptor type */ 29967754Smsmith 300151937Sjkim if (Resource->Type > ACPI_RESOURCE_TYPE_MAX) 30167754Smsmith { 302151937Sjkim return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE); 303151937Sjkim } 30467754Smsmith 305151937Sjkim /* Get the base size of the (external stream) resource descriptor */ 30667754Smsmith 307151937Sjkim TotalSize = AcpiGbl_AmlResourceSizes [Resource->Type]; 30867754Smsmith 309151937Sjkim /* 310151937Sjkim * Augment the base size for descriptors with optional and/or 311151937Sjkim * variable-length fields 312151937Sjkim */ 313151937Sjkim switch (Resource->Type) 314151937Sjkim { 315193267Sjkim case ACPI_RESOURCE_TYPE_IRQ: 316193267Sjkim 317193267Sjkim /* Length can be 3 or 2 */ 318193267Sjkim 319193267Sjkim if (Resource->Data.Irq.DescriptorLength == 2) 320193267Sjkim { 321193267Sjkim TotalSize--; 322193267Sjkim } 323193267Sjkim break; 324193267Sjkim 325193267Sjkim 326193267Sjkim case ACPI_RESOURCE_TYPE_START_DEPENDENT: 327193267Sjkim 328193267Sjkim /* Length can be 1 or 0 */ 329193267Sjkim 330193267Sjkim if (Resource->Data.Irq.DescriptorLength == 0) 331193267Sjkim { 332193267Sjkim TotalSize--; 333193267Sjkim } 334193267Sjkim break; 335193267Sjkim 336193267Sjkim 337151937Sjkim case ACPI_RESOURCE_TYPE_VENDOR: 33877424Smsmith /* 339151937Sjkim * Vendor Defined Resource: 340151937Sjkim * For a Vendor Specific resource, if the Length is between 1 and 7 341151937Sjkim * it will be created as a Small Resource data type, otherwise it 342151937Sjkim * is a Large Resource data type. 34377424Smsmith */ 344151937Sjkim if (Resource->Data.Vendor.ByteLength > 7) 345151937Sjkim { 346151937Sjkim /* Base size of a Large resource descriptor */ 34767754Smsmith 348151937Sjkim TotalSize = sizeof (AML_RESOURCE_LARGE_HEADER); 349151937Sjkim } 35067754Smsmith 351151937Sjkim /* Add the size of the vendor-specific data */ 35277424Smsmith 353151937Sjkim TotalSize = (ACPI_RS_LENGTH) 354151937Sjkim (TotalSize + Resource->Data.Vendor.ByteLength); 35577424Smsmith break; 35667754Smsmith 35767754Smsmith 358151937Sjkim case ACPI_RESOURCE_TYPE_END_TAG: 35977424Smsmith /* 360151937Sjkim * End Tag: 361151937Sjkim * We are done -- return the accumulated total size. 36277424Smsmith */ 363151937Sjkim *SizeNeeded = AmlSizeNeeded + TotalSize; 36467754Smsmith 365151937Sjkim /* Normal exit */ 36667754Smsmith 367151937Sjkim return_ACPI_STATUS (AE_OK); 36867754Smsmith 369151937Sjkim 370151937Sjkim case ACPI_RESOURCE_TYPE_ADDRESS16: 37177424Smsmith /* 372151937Sjkim * 16-Bit Address Resource: 373151937Sjkim * Add the size of the optional ResourceSource info 37477424Smsmith */ 375151937Sjkim TotalSize = (ACPI_RS_LENGTH) 376151937Sjkim (TotalSize + AcpiRsStructOptionLength ( 377151937Sjkim &Resource->Data.Address16.ResourceSource)); 37877424Smsmith break; 37967754Smsmith 38067754Smsmith 381151937Sjkim case ACPI_RESOURCE_TYPE_ADDRESS32: 38277424Smsmith /* 383151937Sjkim * 32-Bit Address Resource: 384151937Sjkim * Add the size of the optional ResourceSource info 38577424Smsmith */ 386151937Sjkim TotalSize = (ACPI_RS_LENGTH) 387151937Sjkim (TotalSize + AcpiRsStructOptionLength ( 388151937Sjkim &Resource->Data.Address32.ResourceSource)); 389151937Sjkim break; 39067754Smsmith 39167754Smsmith 392151937Sjkim case ACPI_RESOURCE_TYPE_ADDRESS64: 39377424Smsmith /* 394151937Sjkim * 64-Bit Address Resource: 395151937Sjkim * Add the size of the optional ResourceSource info 39677424Smsmith */ 397151937Sjkim TotalSize = (ACPI_RS_LENGTH) 398151937Sjkim (TotalSize + AcpiRsStructOptionLength ( 399151937Sjkim &Resource->Data.Address64.ResourceSource)); 40077424Smsmith break; 40167754Smsmith 40267754Smsmith 403151937Sjkim case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: 40477424Smsmith /* 405151937Sjkim * Extended IRQ Resource: 406151937Sjkim * Add the size of each additional optional interrupt beyond the 407151937Sjkim * required 1 (4 bytes for each UINT32 interrupt number) 40877424Smsmith */ 409151937Sjkim TotalSize = (ACPI_RS_LENGTH) 410151937Sjkim (TotalSize + 411151937Sjkim ((Resource->Data.ExtendedIrq.InterruptCount - 1) * 4) + 41267754Smsmith 413151937Sjkim /* Add the size of the optional ResourceSource info */ 41467754Smsmith 415151937Sjkim AcpiRsStructOptionLength ( 416151937Sjkim &Resource->Data.ExtendedIrq.ResourceSource)); 417151937Sjkim break; 41867754Smsmith 41967754Smsmith 420151937Sjkim default: 42177424Smsmith break; 422151937Sjkim } 42367754Smsmith 424151937Sjkim /* Update the total */ 42567754Smsmith 426151937Sjkim AmlSizeNeeded += TotalSize; 42767754Smsmith 428151937Sjkim /* Point to the next object */ 42967754Smsmith 430167802Sjkim Resource = ACPI_ADD_PTR (ACPI_RESOURCE, Resource, Resource->Length); 431151937Sjkim } 43267754Smsmith 433167802Sjkim /* Did not find an EndTag resource descriptor */ 43467754Smsmith 435167802Sjkim return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG); 436151937Sjkim} 43767754Smsmith 43867754Smsmith 439151937Sjkim/******************************************************************************* 440151937Sjkim * 441151937Sjkim * FUNCTION: AcpiRsGetListLength 442151937Sjkim * 443151937Sjkim * PARAMETERS: AmlBuffer - Pointer to the resource byte stream 444151937Sjkim * AmlBufferLength - Size of AmlBuffer 445151937Sjkim * SizeNeeded - Where the size needed is returned 446151937Sjkim * 447151937Sjkim * RETURN: Status 448151937Sjkim * 449151937Sjkim * DESCRIPTION: Takes an external resource byte stream and calculates the size 450151937Sjkim * buffer needed to hold the corresponding internal resource 451151937Sjkim * descriptor linked list. 452151937Sjkim * 453151937Sjkim ******************************************************************************/ 45467754Smsmith 455151937SjkimACPI_STATUS 456151937SjkimAcpiRsGetListLength ( 457151937Sjkim UINT8 *AmlBuffer, 458151937Sjkim UINT32 AmlBufferLength, 459151937Sjkim ACPI_SIZE *SizeNeeded) 460151937Sjkim{ 461167802Sjkim ACPI_STATUS Status; 462167802Sjkim UINT8 *EndAml; 463151937Sjkim UINT8 *Buffer; 464167802Sjkim UINT32 BufferSize; 465151937Sjkim UINT16 Temp16; 466151937Sjkim UINT16 ResourceLength; 467151937Sjkim UINT32 ExtraStructBytes; 468167802Sjkim UINT8 ResourceIndex; 469167802Sjkim UINT8 MinimumAmlResourceLength; 47067754Smsmith 47167754Smsmith 472167802Sjkim ACPI_FUNCTION_TRACE (RsGetListLength); 47367754Smsmith 47467754Smsmith 475167802Sjkim *SizeNeeded = 0; 476167802Sjkim EndAml = AmlBuffer + AmlBufferLength; 47767754Smsmith 478167802Sjkim /* Walk the list of AML resource descriptors */ 47967754Smsmith 480167802Sjkim while (AmlBuffer < EndAml) 481167802Sjkim { 482167802Sjkim /* Validate the Resource Type and Resource Length */ 48367754Smsmith 484167802Sjkim Status = AcpiUtValidateResource (AmlBuffer, &ResourceIndex); 485167802Sjkim if (ACPI_FAILURE (Status)) 486151937Sjkim { 487167802Sjkim return_ACPI_STATUS (Status); 488151937Sjkim } 48967754Smsmith 490167802Sjkim /* Get the resource length and base (minimum) AML size */ 49167754Smsmith 492151937Sjkim ResourceLength = AcpiUtGetResourceLength (AmlBuffer); 493167802Sjkim MinimumAmlResourceLength = AcpiGbl_ResourceAmlSizes[ResourceIndex]; 49467754Smsmith 495167802Sjkim /* 496167802Sjkim * Augment the size for descriptors with optional 497167802Sjkim * and/or variable length fields 498167802Sjkim */ 499151937Sjkim ExtraStructBytes = 0; 500167802Sjkim Buffer = AmlBuffer + AcpiUtGetResourceHeaderLength (AmlBuffer); 501138287Smarks 502167802Sjkim switch (AcpiUtGetResourceType (AmlBuffer)) 503151937Sjkim { 504167802Sjkim case ACPI_RESOURCE_NAME_IRQ: 50577424Smsmith /* 506167802Sjkim * IRQ Resource: 507167802Sjkim * Get the number of bits set in the 16-bit IRQ mask 50877424Smsmith */ 509167802Sjkim ACPI_MOVE_16_TO_16 (&Temp16, Buffer); 510167802Sjkim ExtraStructBytes = AcpiRsCountSetBits (Temp16); 511167802Sjkim break; 51267754Smsmith 51367754Smsmith 514167802Sjkim case ACPI_RESOURCE_NAME_DMA: 515167802Sjkim /* 516167802Sjkim * DMA Resource: 517167802Sjkim * Get the number of bits set in the 8-bit DMA mask 518167802Sjkim */ 519167802Sjkim ExtraStructBytes = AcpiRsCountSetBits (*Buffer); 520167802Sjkim break; 52167754Smsmith 52267754Smsmith 523167802Sjkim case ACPI_RESOURCE_NAME_VENDOR_SMALL: 524167802Sjkim case ACPI_RESOURCE_NAME_VENDOR_LARGE: 525167802Sjkim /* 526167802Sjkim * Vendor Resource: 527167802Sjkim * Get the number of vendor data bytes 528167802Sjkim */ 529167802Sjkim ExtraStructBytes = ResourceLength; 530167802Sjkim break; 53167754Smsmith 53267754Smsmith 533167802Sjkim case ACPI_RESOURCE_NAME_END_TAG: 534167802Sjkim /* 535167802Sjkim * End Tag: 536167802Sjkim * This is the normal exit, add size of EndTag 537167802Sjkim */ 538167802Sjkim *SizeNeeded += ACPI_RS_SIZE_MIN; 539167802Sjkim return_ACPI_STATUS (AE_OK); 540138287Smarks 54177424Smsmith 542167802Sjkim case ACPI_RESOURCE_NAME_ADDRESS32: 543167802Sjkim case ACPI_RESOURCE_NAME_ADDRESS16: 544167802Sjkim case ACPI_RESOURCE_NAME_ADDRESS64: 54577424Smsmith /* 546167802Sjkim * Address Resource: 547167802Sjkim * Add the size of the optional ResourceSource 54877424Smsmith */ 549167802Sjkim ExtraStructBytes = AcpiRsStreamOptionLength ( 550167802Sjkim ResourceLength, MinimumAmlResourceLength); 551167802Sjkim break; 55267754Smsmith 55367754Smsmith 554167802Sjkim case ACPI_RESOURCE_NAME_EXTENDED_IRQ: 555167802Sjkim /* 556167802Sjkim * Extended IRQ Resource: 557167802Sjkim * Using the InterruptTableLength, add 4 bytes for each additional 558167802Sjkim * interrupt. Note: at least one interrupt is required and is 559167802Sjkim * included in the minimum descriptor size (reason for the -1) 560167802Sjkim */ 561167802Sjkim ExtraStructBytes = (Buffer[1] - 1) * sizeof (UINT32); 56267754Smsmith 563167802Sjkim /* Add the size of the optional ResourceSource */ 56467754Smsmith 565167802Sjkim ExtraStructBytes += AcpiRsStreamOptionLength ( 566167802Sjkim ResourceLength - ExtraStructBytes, MinimumAmlResourceLength); 567167802Sjkim break; 56867754Smsmith 56967754Smsmith 570167802Sjkim default: 571167802Sjkim break; 572167802Sjkim } 57367754Smsmith 574167802Sjkim /* 575167802Sjkim * Update the required buffer size for the internal descriptor structs 576167802Sjkim * 577167802Sjkim * Important: Round the size up for the appropriate alignment. This 578167802Sjkim * is a requirement on IA64. 579167802Sjkim */ 580167802Sjkim BufferSize = AcpiGbl_ResourceStructSizes[ResourceIndex] + 581167802Sjkim ExtraStructBytes; 582167802Sjkim BufferSize = (UINT32) ACPI_ROUND_UP_TO_NATIVE_WORD (BufferSize); 58367754Smsmith 584167802Sjkim *SizeNeeded += BufferSize; 58567754Smsmith 586167802Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_RESOURCES, 587167802Sjkim "Type %.2X, AmlLength %.2X InternalLength %.2X\n", 588167802Sjkim AcpiUtGetResourceType (AmlBuffer), 589167802Sjkim AcpiUtGetDescriptorLength (AmlBuffer), BufferSize)); 59067754Smsmith 59167754Smsmith /* 592167802Sjkim * Point to the next resource within the AML stream using the length 593167802Sjkim * contained in the resource descriptor header 59467754Smsmith */ 595167802Sjkim AmlBuffer += AcpiUtGetDescriptorLength (AmlBuffer); 59667754Smsmith } 59767754Smsmith 598167802Sjkim /* Did not find an EndTag resource descriptor */ 599151937Sjkim 600167802Sjkim return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG); 60167754Smsmith} 60267754Smsmith 60367754Smsmith 60467754Smsmith/******************************************************************************* 60567754Smsmith * 60699679Siwasaki * FUNCTION: AcpiRsGetPciRoutingTableLength 60767754Smsmith * 60867754Smsmith * PARAMETERS: PackageObject - Pointer to the package object 60967754Smsmith * BufferSizeNeeded - UINT32 pointer of the size buffer 61077424Smsmith * needed to properly return the 61177424Smsmith * parsed data 61267754Smsmith * 61377424Smsmith * RETURN: Status 61467754Smsmith * 61567754Smsmith * DESCRIPTION: Given a package representing a PCI routing table, this 61677424Smsmith * calculates the size of the corresponding linked list of 61777424Smsmith * descriptions. 61867754Smsmith * 61967754Smsmith ******************************************************************************/ 62067754Smsmith 62167754SmsmithACPI_STATUS 62299679SiwasakiAcpiRsGetPciRoutingTableLength ( 62367754Smsmith ACPI_OPERAND_OBJECT *PackageObject, 62491116Smsmith ACPI_SIZE *BufferSizeNeeded) 62567754Smsmith{ 62667754Smsmith UINT32 NumberOfElements; 62799679Siwasaki ACPI_SIZE TempSizeNeeded = 0; 62867754Smsmith ACPI_OPERAND_OBJECT **TopObjectList; 62967754Smsmith UINT32 Index; 63067754Smsmith ACPI_OPERAND_OBJECT *PackageElement; 63167754Smsmith ACPI_OPERAND_OBJECT **SubObjectList; 63267754Smsmith BOOLEAN NameFound; 63367754Smsmith UINT32 TableIndex; 63467754Smsmith 63567754Smsmith 636167802Sjkim ACPI_FUNCTION_TRACE (RsGetPciRoutingTableLength); 63767754Smsmith 63867754Smsmith 63967754Smsmith NumberOfElements = PackageObject->Package.Count; 64067754Smsmith 64167754Smsmith /* 64267754Smsmith * Calculate the size of the return buffer. 64367754Smsmith * The base size is the number of elements * the sizes of the 64467754Smsmith * structures. Additional space for the strings is added below. 64567754Smsmith * The minus one is to subtract the size of the UINT8 Source[1] 64667754Smsmith * member because it is added below. 64767754Smsmith * 64867754Smsmith * But each PRT_ENTRY structure has a pointer to a string and 64967754Smsmith * the size of that string must be found. 65067754Smsmith */ 65167754Smsmith TopObjectList = PackageObject->Package.Elements; 65267754Smsmith 65367754Smsmith for (Index = 0; Index < NumberOfElements; Index++) 65467754Smsmith { 655151937Sjkim /* Dereference the sub-package */ 656151937Sjkim 65767754Smsmith PackageElement = *TopObjectList; 65867754Smsmith 659193267Sjkim /* We must have a valid Package object */ 660193267Sjkim 661193267Sjkim if (!PackageElement || 662193267Sjkim (PackageElement->Common.Type != ACPI_TYPE_PACKAGE)) 663193267Sjkim { 664193267Sjkim return_ACPI_STATUS (AE_AML_OPERAND_TYPE); 665193267Sjkim } 666193267Sjkim 66767754Smsmith /* 66867754Smsmith * The SubObjectList will now point to an array of the 66967754Smsmith * four IRQ elements: Address, Pin, Source and SourceIndex 67067754Smsmith */ 67167754Smsmith SubObjectList = PackageElement->Package.Elements; 67267754Smsmith 673151937Sjkim /* Scan the IrqTableElements for the Source Name String */ 674151937Sjkim 67567754Smsmith NameFound = FALSE; 67667754Smsmith 67767754Smsmith for (TableIndex = 0; TableIndex < 4 && !NameFound; TableIndex++) 67867754Smsmith { 679167802Sjkim if (*SubObjectList && /* Null object allowed */ 680167802Sjkim 681167802Sjkim ((ACPI_TYPE_STRING == 682193267Sjkim (*SubObjectList)->Common.Type) || 683151937Sjkim 684151937Sjkim ((ACPI_TYPE_LOCAL_REFERENCE == 685193267Sjkim (*SubObjectList)->Common.Type) && 686151937Sjkim 687193267Sjkim ((*SubObjectList)->Reference.Class == 688193267Sjkim ACPI_REFCLASS_NAME)))) 68967754Smsmith { 69067754Smsmith NameFound = TRUE; 69167754Smsmith } 69267754Smsmith else 69367754Smsmith { 694151937Sjkim /* Look at the next element */ 695151937Sjkim 69667754Smsmith SubObjectList++; 69767754Smsmith } 69867754Smsmith } 69967754Smsmith 70091116Smsmith TempSizeNeeded += (sizeof (ACPI_PCI_ROUTING_TABLE) - 4); 70169450Smsmith 702151937Sjkim /* Was a String type found? */ 703151937Sjkim 70499679Siwasaki if (NameFound) 70567754Smsmith { 706193267Sjkim if ((*SubObjectList)->Common.Type == ACPI_TYPE_STRING) 70773561Smsmith { 70873561Smsmith /* 709114237Snjl * The length String.Length field does not include the 710114237Snjl * terminating NULL, add 1 71173561Smsmith */ 712151937Sjkim TempSizeNeeded += ((ACPI_SIZE) 713151937Sjkim (*SubObjectList)->String.Length + 1); 71473561Smsmith } 71573561Smsmith else 71673561Smsmith { 71777424Smsmith TempSizeNeeded += AcpiNsGetPathnameLength ( 71877424Smsmith (*SubObjectList)->Reference.Node); 71973561Smsmith } 72067754Smsmith } 72167754Smsmith else 72267754Smsmith { 72367754Smsmith /* 72467754Smsmith * If no name was found, then this is a NULL, which is 72577424Smsmith * translated as a UINT32 zero. 72667754Smsmith */ 72777424Smsmith TempSizeNeeded += sizeof (UINT32); 72867754Smsmith } 72967754Smsmith 73069450Smsmith /* Round up the size since each element must be aligned */ 73169450Smsmith 732167802Sjkim TempSizeNeeded = ACPI_ROUND_UP_TO_64BIT (TempSizeNeeded); 73369450Smsmith 734151937Sjkim /* Point to the next ACPI_OPERAND_OBJECT */ 735151937Sjkim 73667754Smsmith TopObjectList++; 73767754Smsmith } 73867754Smsmith 73977424Smsmith /* 740167802Sjkim * Add an extra element to the end of the list, essentially a 741151937Sjkim * NULL terminator 74277424Smsmith */ 74391116Smsmith *BufferSizeNeeded = TempSizeNeeded + sizeof (ACPI_PCI_ROUTING_TABLE); 74467754Smsmith return_ACPI_STATUS (AE_OK); 74569450Smsmith} 746