rscalc.c revision 241973
167754Smsmith/******************************************************************************* 267754Smsmith * 377424Smsmith * Module Name: rscalc - Calculate stream and list lengths 467754Smsmith * 567754Smsmith ******************************************************************************/ 667754Smsmith 7217365Sjkim/* 8229989Sjkim * Copyright (C) 2000 - 2012, Intel Corp. 970243Smsmith * All rights reserved. 1067754Smsmith * 11217365Sjkim * Redistribution and use in source and binary forms, with or without 12217365Sjkim * modification, are permitted provided that the following conditions 13217365Sjkim * are met: 14217365Sjkim * 1. Redistributions of source code must retain the above copyright 15217365Sjkim * notice, this list of conditions, and the following disclaimer, 16217365Sjkim * without modification. 17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18217365Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 19217365Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 20217365Sjkim * including a substantially similar Disclaimer requirement for further 21217365Sjkim * binary redistribution. 22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 23217365Sjkim * of any contributors may be used to endorse or promote products derived 24217365Sjkim * from this software without specific prior written permission. 2567754Smsmith * 26217365Sjkim * Alternatively, this software may be distributed under the terms of the 27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 28217365Sjkim * Software Foundation. 2967754Smsmith * 30217365Sjkim * NO WARRANTY 31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41217365Sjkim * POSSIBILITY OF SUCH DAMAGES. 42217365Sjkim */ 4367754Smsmith 4467754Smsmith#define __RSCALC_C__ 4567754Smsmith 46193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 47193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 48193341Sjkim#include <contrib/dev/acpica/include/acresrc.h> 49193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 5067754Smsmith 51193267Sjkim 5277424Smsmith#define _COMPONENT ACPI_RESOURCES 5391116Smsmith ACPI_MODULE_NAME ("rscalc") 5467754Smsmith 5567754Smsmith 56151937Sjkim/* Local prototypes */ 57151937Sjkim 58151937Sjkimstatic UINT8 59151937SjkimAcpiRsCountSetBits ( 60151937Sjkim UINT16 BitField); 61151937Sjkim 62151937Sjkimstatic ACPI_RS_LENGTH 63151937SjkimAcpiRsStructOptionLength ( 64151937Sjkim ACPI_RESOURCE_SOURCE *ResourceSource); 65151937Sjkim 66151937Sjkimstatic UINT32 67151937SjkimAcpiRsStreamOptionLength ( 68151937Sjkim UINT32 ResourceLength, 69151937Sjkim UINT32 MinimumTotalLength); 70151937Sjkim 71151937Sjkim 7267754Smsmith/******************************************************************************* 7367754Smsmith * 74151937Sjkim * FUNCTION: AcpiRsCountSetBits 7567754Smsmith * 76151937Sjkim * PARAMETERS: BitField - Field in which to count bits 7767754Smsmith * 78151937Sjkim * RETURN: Number of bits set within the field 7967754Smsmith * 80151937Sjkim * DESCRIPTION: Count the number of bits set in a resource field. Used for 81151937Sjkim * (Short descriptor) interrupt and DMA lists. 8267754Smsmith * 8367754Smsmith ******************************************************************************/ 8467754Smsmith 85151937Sjkimstatic UINT8 86151937SjkimAcpiRsCountSetBits ( 87151937Sjkim UINT16 BitField) 8867754Smsmith{ 89151937Sjkim UINT8 BitsSet; 9067754Smsmith 9167754Smsmith 92151937Sjkim ACPI_FUNCTION_ENTRY (); 9367754Smsmith 9467754Smsmith 95151937Sjkim for (BitsSet = 0; BitField; BitsSet++) 9667754Smsmith { 97151937Sjkim /* Zero the least significant bit that is set */ 9867754Smsmith 99193267Sjkim BitField &= (UINT16) (BitField - 1); 100151937Sjkim } 10167754Smsmith 102151937Sjkim return (BitsSet); 103151937Sjkim} 10467754Smsmith 10567754Smsmith 106151937Sjkim/******************************************************************************* 107151937Sjkim * 108151937Sjkim * FUNCTION: AcpiRsStructOptionLength 109151937Sjkim * 110151937Sjkim * PARAMETERS: ResourceSource - Pointer to optional descriptor field 111151937Sjkim * 112151937Sjkim * RETURN: Status 113151937Sjkim * 114151937Sjkim * DESCRIPTION: Common code to handle optional ResourceSourceIndex and 115151937Sjkim * ResourceSource fields in some Large descriptors. Used during 116151937Sjkim * list-to-stream conversion 117151937Sjkim * 118151937Sjkim ******************************************************************************/ 11967754Smsmith 120151937Sjkimstatic ACPI_RS_LENGTH 121151937SjkimAcpiRsStructOptionLength ( 122151937Sjkim ACPI_RESOURCE_SOURCE *ResourceSource) 123151937Sjkim{ 124151937Sjkim ACPI_FUNCTION_ENTRY (); 12567754Smsmith 12667754Smsmith 127151937Sjkim /* 128151937Sjkim * If the ResourceSource string is valid, return the size of the string 129151937Sjkim * (StringLength includes the NULL terminator) plus the size of the 130151937Sjkim * ResourceSourceIndex (1). 131151937Sjkim */ 132151937Sjkim if (ResourceSource->StringPtr) 133151937Sjkim { 134151937Sjkim return ((ACPI_RS_LENGTH) (ResourceSource->StringLength + 1)); 135151937Sjkim } 13667754Smsmith 137151937Sjkim return (0); 138151937Sjkim} 13967754Smsmith 14067754Smsmith 141151937Sjkim/******************************************************************************* 142151937Sjkim * 143151937Sjkim * FUNCTION: AcpiRsStreamOptionLength 144151937Sjkim * 145151937Sjkim * PARAMETERS: ResourceLength - Length from the resource header 146151937Sjkim * MinimumTotalLength - Minimum length of this resource, before 147151937Sjkim * any optional fields. Includes header size 148151937Sjkim * 149151937Sjkim * RETURN: Length of optional string (0 if no string present) 150151937Sjkim * 151151937Sjkim * DESCRIPTION: Common code to handle optional ResourceSourceIndex and 152151937Sjkim * ResourceSource fields in some Large descriptors. Used during 153151937Sjkim * stream-to-list conversion 154151937Sjkim * 155151937Sjkim ******************************************************************************/ 15667754Smsmith 157151937Sjkimstatic UINT32 158151937SjkimAcpiRsStreamOptionLength ( 159151937Sjkim UINT32 ResourceLength, 160151937Sjkim UINT32 MinimumAmlResourceLength) 161151937Sjkim{ 162151937Sjkim UINT32 StringLength = 0; 16367754Smsmith 16467754Smsmith 165151937Sjkim ACPI_FUNCTION_ENTRY (); 16667754Smsmith 16767754Smsmith 168151937Sjkim /* 169151937Sjkim * The ResourceSourceIndex and ResourceSource are optional elements of some 170151937Sjkim * Large-type resource descriptors. 171151937Sjkim */ 17267754Smsmith 173151937Sjkim /* 174151937Sjkim * If the length of the actual resource descriptor is greater than the ACPI 175151937Sjkim * spec-defined minimum length, it means that a ResourceSourceIndex exists 176151937Sjkim * and is followed by a (required) null terminated string. The string length 177151937Sjkim * (including the null terminator) is the resource length minus the minimum 178151937Sjkim * length, minus one byte for the ResourceSourceIndex itself. 179151937Sjkim */ 180151937Sjkim if (ResourceLength > MinimumAmlResourceLength) 181151937Sjkim { 182151937Sjkim /* Compute the length of the optional string */ 18377424Smsmith 184151937Sjkim StringLength = ResourceLength - MinimumAmlResourceLength - 1; 185151937Sjkim } 18677424Smsmith 187167802Sjkim /* 188167802Sjkim * Round the length up to a multiple of the native word in order to 189167802Sjkim * guarantee that the entire resource descriptor is native word aligned 190167802Sjkim */ 191167802Sjkim return ((UINT32) ACPI_ROUND_UP_TO_NATIVE_WORD (StringLength)); 19267754Smsmith} 19367754Smsmith 19467754Smsmith 19567754Smsmith/******************************************************************************* 19667754Smsmith * 197151937Sjkim * FUNCTION: AcpiRsGetAmlLength 19867754Smsmith * 199151937Sjkim * PARAMETERS: Resource - Pointer to the resource linked list 200151937Sjkim * SizeNeeded - Where the required size is returned 20167754Smsmith * 20277424Smsmith * RETURN: Status 20367754Smsmith * 204151937Sjkim * DESCRIPTION: Takes a linked list of internal resource descriptors and 205151937Sjkim * calculates the size buffer needed to hold the corresponding 206151937Sjkim * external resource byte stream. 20767754Smsmith * 20867754Smsmith ******************************************************************************/ 20967754Smsmith 21067754SmsmithACPI_STATUS 211151937SjkimAcpiRsGetAmlLength ( 212151937Sjkim ACPI_RESOURCE *Resource, 21391116Smsmith ACPI_SIZE *SizeNeeded) 21467754Smsmith{ 215151937Sjkim ACPI_SIZE AmlSizeNeeded = 0; 216167802Sjkim ACPI_RS_LENGTH TotalSize; 21767754Smsmith 21867754Smsmith 219167802Sjkim ACPI_FUNCTION_TRACE (RsGetAmlLength); 22067754Smsmith 22167754Smsmith 222151937Sjkim /* Traverse entire list of internal resource descriptors */ 223151937Sjkim 224151937Sjkim while (Resource) 22567754Smsmith { 226151937Sjkim /* Validate the descriptor type */ 22767754Smsmith 228151937Sjkim if (Resource->Type > ACPI_RESOURCE_TYPE_MAX) 22967754Smsmith { 230151937Sjkim return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE); 231151937Sjkim } 23267754Smsmith 233151937Sjkim /* Get the base size of the (external stream) resource descriptor */ 23467754Smsmith 235151937Sjkim TotalSize = AcpiGbl_AmlResourceSizes [Resource->Type]; 23667754Smsmith 237151937Sjkim /* 238151937Sjkim * Augment the base size for descriptors with optional and/or 239151937Sjkim * variable-length fields 240151937Sjkim */ 241151937Sjkim switch (Resource->Type) 242151937Sjkim { 243193267Sjkim case ACPI_RESOURCE_TYPE_IRQ: 244193267Sjkim 245193267Sjkim /* Length can be 3 or 2 */ 246193267Sjkim 247193267Sjkim if (Resource->Data.Irq.DescriptorLength == 2) 248193267Sjkim { 249193267Sjkim TotalSize--; 250193267Sjkim } 251193267Sjkim break; 252193267Sjkim 253193267Sjkim 254193267Sjkim case ACPI_RESOURCE_TYPE_START_DEPENDENT: 255193267Sjkim 256193267Sjkim /* Length can be 1 or 0 */ 257193267Sjkim 258193267Sjkim if (Resource->Data.Irq.DescriptorLength == 0) 259193267Sjkim { 260193267Sjkim TotalSize--; 261193267Sjkim } 262193267Sjkim break; 263193267Sjkim 264193267Sjkim 265151937Sjkim case ACPI_RESOURCE_TYPE_VENDOR: 26677424Smsmith /* 267151937Sjkim * Vendor Defined Resource: 268151937Sjkim * For a Vendor Specific resource, if the Length is between 1 and 7 269151937Sjkim * it will be created as a Small Resource data type, otherwise it 270151937Sjkim * is a Large Resource data type. 27177424Smsmith */ 272151937Sjkim if (Resource->Data.Vendor.ByteLength > 7) 273151937Sjkim { 274151937Sjkim /* Base size of a Large resource descriptor */ 27567754Smsmith 276151937Sjkim TotalSize = sizeof (AML_RESOURCE_LARGE_HEADER); 277151937Sjkim } 27867754Smsmith 279151937Sjkim /* Add the size of the vendor-specific data */ 28077424Smsmith 281151937Sjkim TotalSize = (ACPI_RS_LENGTH) 282151937Sjkim (TotalSize + Resource->Data.Vendor.ByteLength); 28377424Smsmith break; 28467754Smsmith 28567754Smsmith 286151937Sjkim case ACPI_RESOURCE_TYPE_END_TAG: 28777424Smsmith /* 288151937Sjkim * End Tag: 289151937Sjkim * We are done -- return the accumulated total size. 29077424Smsmith */ 291151937Sjkim *SizeNeeded = AmlSizeNeeded + TotalSize; 29267754Smsmith 293151937Sjkim /* Normal exit */ 29467754Smsmith 295151937Sjkim return_ACPI_STATUS (AE_OK); 29667754Smsmith 297151937Sjkim 298151937Sjkim case ACPI_RESOURCE_TYPE_ADDRESS16: 29977424Smsmith /* 300151937Sjkim * 16-Bit Address Resource: 301151937Sjkim * Add the size of the optional ResourceSource info 30277424Smsmith */ 303151937Sjkim TotalSize = (ACPI_RS_LENGTH) 304151937Sjkim (TotalSize + AcpiRsStructOptionLength ( 305151937Sjkim &Resource->Data.Address16.ResourceSource)); 30677424Smsmith break; 30767754Smsmith 30867754Smsmith 309151937Sjkim case ACPI_RESOURCE_TYPE_ADDRESS32: 31077424Smsmith /* 311151937Sjkim * 32-Bit Address Resource: 312151937Sjkim * Add the size of the optional ResourceSource info 31377424Smsmith */ 314151937Sjkim TotalSize = (ACPI_RS_LENGTH) 315151937Sjkim (TotalSize + AcpiRsStructOptionLength ( 316151937Sjkim &Resource->Data.Address32.ResourceSource)); 317151937Sjkim break; 31867754Smsmith 31967754Smsmith 320151937Sjkim case ACPI_RESOURCE_TYPE_ADDRESS64: 32177424Smsmith /* 322151937Sjkim * 64-Bit Address Resource: 323151937Sjkim * Add the size of the optional ResourceSource info 32477424Smsmith */ 325151937Sjkim TotalSize = (ACPI_RS_LENGTH) 326151937Sjkim (TotalSize + AcpiRsStructOptionLength ( 327151937Sjkim &Resource->Data.Address64.ResourceSource)); 32877424Smsmith break; 32967754Smsmith 33067754Smsmith 331151937Sjkim case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: 33277424Smsmith /* 333151937Sjkim * Extended IRQ Resource: 334151937Sjkim * Add the size of each additional optional interrupt beyond the 335151937Sjkim * required 1 (4 bytes for each UINT32 interrupt number) 33677424Smsmith */ 337151937Sjkim TotalSize = (ACPI_RS_LENGTH) 338151937Sjkim (TotalSize + 339151937Sjkim ((Resource->Data.ExtendedIrq.InterruptCount - 1) * 4) + 34067754Smsmith 341151937Sjkim /* Add the size of the optional ResourceSource info */ 34267754Smsmith 343151937Sjkim AcpiRsStructOptionLength ( 344151937Sjkim &Resource->Data.ExtendedIrq.ResourceSource)); 345151937Sjkim break; 34667754Smsmith 34767754Smsmith 348228110Sjkim case ACPI_RESOURCE_TYPE_GPIO: 349228110Sjkim 350228110Sjkim TotalSize = (ACPI_RS_LENGTH) (TotalSize + (Resource->Data.Gpio.PinTableLength * 2) + 351228110Sjkim Resource->Data.Gpio.ResourceSource.StringLength + 352228110Sjkim Resource->Data.Gpio.VendorLength); 353228110Sjkim 354228110Sjkim break; 355228110Sjkim 356228110Sjkim 357228110Sjkim case ACPI_RESOURCE_TYPE_SERIAL_BUS: 358228110Sjkim 359228110Sjkim TotalSize = AcpiGbl_AmlResourceSerialBusSizes [Resource->Data.CommonSerialBus.Type]; 360228110Sjkim 361228110Sjkim TotalSize = (ACPI_RS_LENGTH) (TotalSize + 362228110Sjkim Resource->Data.I2cSerialBus.ResourceSource.StringLength + 363228110Sjkim Resource->Data.I2cSerialBus.VendorLength); 364228110Sjkim 365228110Sjkim break; 366228110Sjkim 367228110Sjkim 368151937Sjkim default: 36977424Smsmith break; 370151937Sjkim } 37167754Smsmith 372151937Sjkim /* Update the total */ 37367754Smsmith 374151937Sjkim AmlSizeNeeded += TotalSize; 37567754Smsmith 376151937Sjkim /* Point to the next object */ 37767754Smsmith 378167802Sjkim Resource = ACPI_ADD_PTR (ACPI_RESOURCE, Resource, Resource->Length); 379151937Sjkim } 38067754Smsmith 381167802Sjkim /* Did not find an EndTag resource descriptor */ 38267754Smsmith 383167802Sjkim return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG); 384151937Sjkim} 38567754Smsmith 38667754Smsmith 387151937Sjkim/******************************************************************************* 388151937Sjkim * 389151937Sjkim * FUNCTION: AcpiRsGetListLength 390151937Sjkim * 391151937Sjkim * PARAMETERS: AmlBuffer - Pointer to the resource byte stream 392151937Sjkim * AmlBufferLength - Size of AmlBuffer 393151937Sjkim * SizeNeeded - Where the size needed is returned 394151937Sjkim * 395151937Sjkim * RETURN: Status 396151937Sjkim * 397151937Sjkim * DESCRIPTION: Takes an external resource byte stream and calculates the size 398151937Sjkim * buffer needed to hold the corresponding internal resource 399151937Sjkim * descriptor linked list. 400151937Sjkim * 401151937Sjkim ******************************************************************************/ 40267754Smsmith 403151937SjkimACPI_STATUS 404151937SjkimAcpiRsGetListLength ( 405151937Sjkim UINT8 *AmlBuffer, 406151937Sjkim UINT32 AmlBufferLength, 407151937Sjkim ACPI_SIZE *SizeNeeded) 408151937Sjkim{ 409167802Sjkim ACPI_STATUS Status; 410167802Sjkim UINT8 *EndAml; 411151937Sjkim UINT8 *Buffer; 412167802Sjkim UINT32 BufferSize; 413151937Sjkim UINT16 Temp16; 414151937Sjkim UINT16 ResourceLength; 415151937Sjkim UINT32 ExtraStructBytes; 416167802Sjkim UINT8 ResourceIndex; 417167802Sjkim UINT8 MinimumAmlResourceLength; 418228110Sjkim AML_RESOURCE *AmlResource; 41967754Smsmith 42067754Smsmith 421167802Sjkim ACPI_FUNCTION_TRACE (RsGetListLength); 42267754Smsmith 42367754Smsmith 424228110Sjkim *SizeNeeded = ACPI_RS_SIZE_MIN; /* Minimum size is one EndTag */ 425167802Sjkim EndAml = AmlBuffer + AmlBufferLength; 42667754Smsmith 427167802Sjkim /* Walk the list of AML resource descriptors */ 42867754Smsmith 429167802Sjkim while (AmlBuffer < EndAml) 430167802Sjkim { 431167802Sjkim /* Validate the Resource Type and Resource Length */ 43267754Smsmith 433167802Sjkim Status = AcpiUtValidateResource (AmlBuffer, &ResourceIndex); 434167802Sjkim if (ACPI_FAILURE (Status)) 435151937Sjkim { 436228110Sjkim /* 437228110Sjkim * Exit on failure. Cannot continue because the descriptor length 438228110Sjkim * may be bogus also. 439228110Sjkim */ 440167802Sjkim return_ACPI_STATUS (Status); 441151937Sjkim } 44267754Smsmith 443228110Sjkim AmlResource = (void *) AmlBuffer; 444228110Sjkim 445167802Sjkim /* Get the resource length and base (minimum) AML size */ 44667754Smsmith 447151937Sjkim ResourceLength = AcpiUtGetResourceLength (AmlBuffer); 448167802Sjkim MinimumAmlResourceLength = AcpiGbl_ResourceAmlSizes[ResourceIndex]; 44967754Smsmith 450167802Sjkim /* 451167802Sjkim * Augment the size for descriptors with optional 452167802Sjkim * and/or variable length fields 453167802Sjkim */ 454151937Sjkim ExtraStructBytes = 0; 455167802Sjkim Buffer = AmlBuffer + AcpiUtGetResourceHeaderLength (AmlBuffer); 456138287Smarks 457167802Sjkim switch (AcpiUtGetResourceType (AmlBuffer)) 458151937Sjkim { 459167802Sjkim case ACPI_RESOURCE_NAME_IRQ: 46077424Smsmith /* 461167802Sjkim * IRQ Resource: 462167802Sjkim * Get the number of bits set in the 16-bit IRQ mask 46377424Smsmith */ 464167802Sjkim ACPI_MOVE_16_TO_16 (&Temp16, Buffer); 465167802Sjkim ExtraStructBytes = AcpiRsCountSetBits (Temp16); 466167802Sjkim break; 46767754Smsmith 46867754Smsmith 469167802Sjkim case ACPI_RESOURCE_NAME_DMA: 470167802Sjkim /* 471167802Sjkim * DMA Resource: 472167802Sjkim * Get the number of bits set in the 8-bit DMA mask 473167802Sjkim */ 474167802Sjkim ExtraStructBytes = AcpiRsCountSetBits (*Buffer); 475167802Sjkim break; 47667754Smsmith 47767754Smsmith 478167802Sjkim case ACPI_RESOURCE_NAME_VENDOR_SMALL: 479167802Sjkim case ACPI_RESOURCE_NAME_VENDOR_LARGE: 480167802Sjkim /* 481167802Sjkim * Vendor Resource: 482167802Sjkim * Get the number of vendor data bytes 483167802Sjkim */ 484167802Sjkim ExtraStructBytes = ResourceLength; 485241973Sjkim 486241973Sjkim /* 487241973Sjkim * There is already one byte included in the minimum 488241973Sjkim * descriptor size. If there are extra struct bytes, 489241973Sjkim * subtract one from the count. 490241973Sjkim */ 491241973Sjkim if (ExtraStructBytes) 492241973Sjkim { 493241973Sjkim ExtraStructBytes--; 494241973Sjkim } 495167802Sjkim break; 49667754Smsmith 49767754Smsmith 498167802Sjkim case ACPI_RESOURCE_NAME_END_TAG: 499167802Sjkim /* 500228110Sjkim * End Tag: This is the normal exit 501167802Sjkim */ 502167802Sjkim return_ACPI_STATUS (AE_OK); 503138287Smarks 50477424Smsmith 505167802Sjkim case ACPI_RESOURCE_NAME_ADDRESS32: 506167802Sjkim case ACPI_RESOURCE_NAME_ADDRESS16: 507167802Sjkim case ACPI_RESOURCE_NAME_ADDRESS64: 50877424Smsmith /* 509167802Sjkim * Address Resource: 510167802Sjkim * Add the size of the optional ResourceSource 51177424Smsmith */ 512167802Sjkim ExtraStructBytes = AcpiRsStreamOptionLength ( 513167802Sjkim ResourceLength, MinimumAmlResourceLength); 514167802Sjkim break; 51567754Smsmith 51667754Smsmith 517167802Sjkim case ACPI_RESOURCE_NAME_EXTENDED_IRQ: 518167802Sjkim /* 519167802Sjkim * Extended IRQ Resource: 520167802Sjkim * Using the InterruptTableLength, add 4 bytes for each additional 521167802Sjkim * interrupt. Note: at least one interrupt is required and is 522167802Sjkim * included in the minimum descriptor size (reason for the -1) 523167802Sjkim */ 524167802Sjkim ExtraStructBytes = (Buffer[1] - 1) * sizeof (UINT32); 52567754Smsmith 526167802Sjkim /* Add the size of the optional ResourceSource */ 52767754Smsmith 528167802Sjkim ExtraStructBytes += AcpiRsStreamOptionLength ( 529167802Sjkim ResourceLength - ExtraStructBytes, MinimumAmlResourceLength); 530167802Sjkim break; 53167754Smsmith 532228110Sjkim case ACPI_RESOURCE_NAME_GPIO: 53367754Smsmith 534228110Sjkim /* Vendor data is optional */ 535228110Sjkim 536228110Sjkim if (AmlResource->Gpio.VendorLength) 537228110Sjkim { 538228110Sjkim ExtraStructBytes += AmlResource->Gpio.VendorOffset - 539228110Sjkim AmlResource->Gpio.PinTableOffset + AmlResource->Gpio.VendorLength; 540228110Sjkim } 541228110Sjkim else 542228110Sjkim { 543228110Sjkim ExtraStructBytes += AmlResource->LargeHeader.ResourceLength + 544228110Sjkim sizeof (AML_RESOURCE_LARGE_HEADER) - 545228110Sjkim AmlResource->Gpio.PinTableOffset; 546228110Sjkim } 547228110Sjkim break; 548228110Sjkim 549228110Sjkim case ACPI_RESOURCE_NAME_SERIAL_BUS: 550228110Sjkim 551228110Sjkim MinimumAmlResourceLength = AcpiGbl_ResourceAmlSerialBusSizes[ 552228110Sjkim AmlResource->CommonSerialBus.Type]; 553228110Sjkim ExtraStructBytes += AmlResource->CommonSerialBus.ResourceLength - 554228110Sjkim MinimumAmlResourceLength; 555228110Sjkim break; 556228110Sjkim 557167802Sjkim default: 558167802Sjkim break; 559167802Sjkim } 56067754Smsmith 561167802Sjkim /* 562167802Sjkim * Update the required buffer size for the internal descriptor structs 563167802Sjkim * 564167802Sjkim * Important: Round the size up for the appropriate alignment. This 565167802Sjkim * is a requirement on IA64. 566167802Sjkim */ 567228110Sjkim if (AcpiUtGetResourceType (AmlBuffer) == ACPI_RESOURCE_NAME_SERIAL_BUS) 568228110Sjkim { 569228110Sjkim BufferSize = AcpiGbl_ResourceStructSerialBusSizes[ 570228110Sjkim AmlResource->CommonSerialBus.Type] + ExtraStructBytes; 571228110Sjkim } 572228110Sjkim else 573228110Sjkim { 574228110Sjkim BufferSize = AcpiGbl_ResourceStructSizes[ResourceIndex] + 575167802Sjkim ExtraStructBytes; 576228110Sjkim } 577167802Sjkim BufferSize = (UINT32) ACPI_ROUND_UP_TO_NATIVE_WORD (BufferSize); 57867754Smsmith 579167802Sjkim *SizeNeeded += BufferSize; 58067754Smsmith 581167802Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_RESOURCES, 582167802Sjkim "Type %.2X, AmlLength %.2X InternalLength %.2X\n", 583167802Sjkim AcpiUtGetResourceType (AmlBuffer), 584167802Sjkim AcpiUtGetDescriptorLength (AmlBuffer), BufferSize)); 58567754Smsmith 58667754Smsmith /* 587167802Sjkim * Point to the next resource within the AML stream using the length 588167802Sjkim * contained in the resource descriptor header 58967754Smsmith */ 590167802Sjkim AmlBuffer += AcpiUtGetDescriptorLength (AmlBuffer); 59167754Smsmith } 59267754Smsmith 593167802Sjkim /* Did not find an EndTag resource descriptor */ 594151937Sjkim 595167802Sjkim return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG); 59667754Smsmith} 59767754Smsmith 59867754Smsmith 59967754Smsmith/******************************************************************************* 60067754Smsmith * 60199679Siwasaki * FUNCTION: AcpiRsGetPciRoutingTableLength 60267754Smsmith * 60367754Smsmith * PARAMETERS: PackageObject - Pointer to the package object 60467754Smsmith * BufferSizeNeeded - UINT32 pointer of the size buffer 60577424Smsmith * needed to properly return the 60677424Smsmith * parsed data 60767754Smsmith * 60877424Smsmith * RETURN: Status 60967754Smsmith * 61067754Smsmith * DESCRIPTION: Given a package representing a PCI routing table, this 61177424Smsmith * calculates the size of the corresponding linked list of 61277424Smsmith * descriptions. 61367754Smsmith * 61467754Smsmith ******************************************************************************/ 61567754Smsmith 61667754SmsmithACPI_STATUS 61799679SiwasakiAcpiRsGetPciRoutingTableLength ( 61867754Smsmith ACPI_OPERAND_OBJECT *PackageObject, 61991116Smsmith ACPI_SIZE *BufferSizeNeeded) 62067754Smsmith{ 62167754Smsmith UINT32 NumberOfElements; 62299679Siwasaki ACPI_SIZE TempSizeNeeded = 0; 62367754Smsmith ACPI_OPERAND_OBJECT **TopObjectList; 62467754Smsmith UINT32 Index; 62567754Smsmith ACPI_OPERAND_OBJECT *PackageElement; 62667754Smsmith ACPI_OPERAND_OBJECT **SubObjectList; 62767754Smsmith BOOLEAN NameFound; 62867754Smsmith UINT32 TableIndex; 62967754Smsmith 63067754Smsmith 631167802Sjkim ACPI_FUNCTION_TRACE (RsGetPciRoutingTableLength); 63267754Smsmith 63367754Smsmith 63467754Smsmith NumberOfElements = PackageObject->Package.Count; 63567754Smsmith 63667754Smsmith /* 63767754Smsmith * Calculate the size of the return buffer. 63867754Smsmith * The base size is the number of elements * the sizes of the 639241973Sjkim * structures. Additional space for the strings is added below. 64067754Smsmith * The minus one is to subtract the size of the UINT8 Source[1] 64167754Smsmith * member because it is added below. 64267754Smsmith * 64367754Smsmith * But each PRT_ENTRY structure has a pointer to a string and 64467754Smsmith * the size of that string must be found. 64567754Smsmith */ 64667754Smsmith TopObjectList = PackageObject->Package.Elements; 64767754Smsmith 64867754Smsmith for (Index = 0; Index < NumberOfElements; Index++) 64967754Smsmith { 650151937Sjkim /* Dereference the sub-package */ 651151937Sjkim 65267754Smsmith PackageElement = *TopObjectList; 65367754Smsmith 654193267Sjkim /* We must have a valid Package object */ 655193267Sjkim 656193267Sjkim if (!PackageElement || 657193267Sjkim (PackageElement->Common.Type != ACPI_TYPE_PACKAGE)) 658193267Sjkim { 659193267Sjkim return_ACPI_STATUS (AE_AML_OPERAND_TYPE); 660193267Sjkim } 661193267Sjkim 66267754Smsmith /* 66367754Smsmith * The SubObjectList will now point to an array of the 66467754Smsmith * four IRQ elements: Address, Pin, Source and SourceIndex 66567754Smsmith */ 66667754Smsmith SubObjectList = PackageElement->Package.Elements; 66767754Smsmith 668151937Sjkim /* Scan the IrqTableElements for the Source Name String */ 669151937Sjkim 67067754Smsmith NameFound = FALSE; 67167754Smsmith 67267754Smsmith for (TableIndex = 0; TableIndex < 4 && !NameFound; TableIndex++) 67367754Smsmith { 674167802Sjkim if (*SubObjectList && /* Null object allowed */ 675167802Sjkim 676167802Sjkim ((ACPI_TYPE_STRING == 677193267Sjkim (*SubObjectList)->Common.Type) || 678151937Sjkim 679151937Sjkim ((ACPI_TYPE_LOCAL_REFERENCE == 680193267Sjkim (*SubObjectList)->Common.Type) && 681151937Sjkim 682193267Sjkim ((*SubObjectList)->Reference.Class == 683193267Sjkim ACPI_REFCLASS_NAME)))) 68467754Smsmith { 68567754Smsmith NameFound = TRUE; 68667754Smsmith } 68767754Smsmith else 68867754Smsmith { 689151937Sjkim /* Look at the next element */ 690151937Sjkim 69167754Smsmith SubObjectList++; 69267754Smsmith } 69367754Smsmith } 69467754Smsmith 69591116Smsmith TempSizeNeeded += (sizeof (ACPI_PCI_ROUTING_TABLE) - 4); 69669450Smsmith 697151937Sjkim /* Was a String type found? */ 698151937Sjkim 69999679Siwasaki if (NameFound) 70067754Smsmith { 701193267Sjkim if ((*SubObjectList)->Common.Type == ACPI_TYPE_STRING) 70273561Smsmith { 70373561Smsmith /* 704114237Snjl * The length String.Length field does not include the 705114237Snjl * terminating NULL, add 1 70673561Smsmith */ 707151937Sjkim TempSizeNeeded += ((ACPI_SIZE) 708151937Sjkim (*SubObjectList)->String.Length + 1); 70973561Smsmith } 71073561Smsmith else 71173561Smsmith { 71277424Smsmith TempSizeNeeded += AcpiNsGetPathnameLength ( 71377424Smsmith (*SubObjectList)->Reference.Node); 71473561Smsmith } 71567754Smsmith } 71667754Smsmith else 71767754Smsmith { 71867754Smsmith /* 71967754Smsmith * If no name was found, then this is a NULL, which is 72077424Smsmith * translated as a UINT32 zero. 72167754Smsmith */ 72277424Smsmith TempSizeNeeded += sizeof (UINT32); 72367754Smsmith } 72467754Smsmith 72569450Smsmith /* Round up the size since each element must be aligned */ 72669450Smsmith 727167802Sjkim TempSizeNeeded = ACPI_ROUND_UP_TO_64BIT (TempSizeNeeded); 72869450Smsmith 729151937Sjkim /* Point to the next ACPI_OPERAND_OBJECT */ 730151937Sjkim 73167754Smsmith TopObjectList++; 73267754Smsmith } 73367754Smsmith 73477424Smsmith /* 735167802Sjkim * Add an extra element to the end of the list, essentially a 736151937Sjkim * NULL terminator 73777424Smsmith */ 73891116Smsmith *BufferSizeNeeded = TempSizeNeeded + sizeof (ACPI_PCI_ROUTING_TABLE); 73967754Smsmith return_ACPI_STATUS (AE_OK); 74069450Smsmith} 741