rscalc.c revision 281075
167754Smsmith/******************************************************************************* 267754Smsmith * 377424Smsmith * Module Name: rscalc - Calculate stream and list lengths 467754Smsmith * 567754Smsmith ******************************************************************************/ 667754Smsmith 7217365Sjkim/* 8281075Sdim * Copyright (C) 2000 - 2015, 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 44193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 45193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 46193341Sjkim#include <contrib/dev/acpica/include/acresrc.h> 47193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 4867754Smsmith 49193267Sjkim 5077424Smsmith#define _COMPONENT ACPI_RESOURCES 5191116Smsmith ACPI_MODULE_NAME ("rscalc") 5267754Smsmith 5367754Smsmith 54151937Sjkim/* Local prototypes */ 55151937Sjkim 56151937Sjkimstatic UINT8 57151937SjkimAcpiRsCountSetBits ( 58151937Sjkim UINT16 BitField); 59151937Sjkim 60151937Sjkimstatic ACPI_RS_LENGTH 61151937SjkimAcpiRsStructOptionLength ( 62151937Sjkim ACPI_RESOURCE_SOURCE *ResourceSource); 63151937Sjkim 64151937Sjkimstatic UINT32 65151937SjkimAcpiRsStreamOptionLength ( 66151937Sjkim UINT32 ResourceLength, 67151937Sjkim UINT32 MinimumTotalLength); 68151937Sjkim 69151937Sjkim 7067754Smsmith/******************************************************************************* 7167754Smsmith * 72151937Sjkim * FUNCTION: AcpiRsCountSetBits 7367754Smsmith * 74151937Sjkim * PARAMETERS: BitField - Field in which to count bits 7567754Smsmith * 76151937Sjkim * RETURN: Number of bits set within the field 7767754Smsmith * 78151937Sjkim * DESCRIPTION: Count the number of bits set in a resource field. Used for 79151937Sjkim * (Short descriptor) interrupt and DMA lists. 8067754Smsmith * 8167754Smsmith ******************************************************************************/ 8267754Smsmith 83151937Sjkimstatic UINT8 84151937SjkimAcpiRsCountSetBits ( 85151937Sjkim UINT16 BitField) 8667754Smsmith{ 87151937Sjkim UINT8 BitsSet; 8867754Smsmith 8967754Smsmith 90151937Sjkim ACPI_FUNCTION_ENTRY (); 9167754Smsmith 9267754Smsmith 93151937Sjkim for (BitsSet = 0; BitField; BitsSet++) 9467754Smsmith { 95151937Sjkim /* Zero the least significant bit that is set */ 9667754Smsmith 97193267Sjkim BitField &= (UINT16) (BitField - 1); 98151937Sjkim } 9967754Smsmith 100151937Sjkim return (BitsSet); 101151937Sjkim} 10267754Smsmith 10367754Smsmith 104151937Sjkim/******************************************************************************* 105151937Sjkim * 106151937Sjkim * FUNCTION: AcpiRsStructOptionLength 107151937Sjkim * 108151937Sjkim * PARAMETERS: ResourceSource - Pointer to optional descriptor field 109151937Sjkim * 110151937Sjkim * RETURN: Status 111151937Sjkim * 112151937Sjkim * DESCRIPTION: Common code to handle optional ResourceSourceIndex and 113151937Sjkim * ResourceSource fields in some Large descriptors. Used during 114151937Sjkim * list-to-stream conversion 115151937Sjkim * 116151937Sjkim ******************************************************************************/ 11767754Smsmith 118151937Sjkimstatic ACPI_RS_LENGTH 119151937SjkimAcpiRsStructOptionLength ( 120151937Sjkim ACPI_RESOURCE_SOURCE *ResourceSource) 121151937Sjkim{ 122151937Sjkim ACPI_FUNCTION_ENTRY (); 12367754Smsmith 12467754Smsmith 125151937Sjkim /* 126151937Sjkim * If the ResourceSource string is valid, return the size of the string 127151937Sjkim * (StringLength includes the NULL terminator) plus the size of the 128151937Sjkim * ResourceSourceIndex (1). 129151937Sjkim */ 130151937Sjkim if (ResourceSource->StringPtr) 131151937Sjkim { 132151937Sjkim return ((ACPI_RS_LENGTH) (ResourceSource->StringLength + 1)); 133151937Sjkim } 13467754Smsmith 135151937Sjkim return (0); 136151937Sjkim} 13767754Smsmith 13867754Smsmith 139151937Sjkim/******************************************************************************* 140151937Sjkim * 141151937Sjkim * FUNCTION: AcpiRsStreamOptionLength 142151937Sjkim * 143151937Sjkim * PARAMETERS: ResourceLength - Length from the resource header 144151937Sjkim * MinimumTotalLength - Minimum length of this resource, before 145151937Sjkim * any optional fields. Includes header size 146151937Sjkim * 147151937Sjkim * RETURN: Length of optional string (0 if no string present) 148151937Sjkim * 149151937Sjkim * DESCRIPTION: Common code to handle optional ResourceSourceIndex and 150151937Sjkim * ResourceSource fields in some Large descriptors. Used during 151151937Sjkim * stream-to-list conversion 152151937Sjkim * 153151937Sjkim ******************************************************************************/ 15467754Smsmith 155151937Sjkimstatic UINT32 156151937SjkimAcpiRsStreamOptionLength ( 157151937Sjkim UINT32 ResourceLength, 158151937Sjkim UINT32 MinimumAmlResourceLength) 159151937Sjkim{ 160151937Sjkim UINT32 StringLength = 0; 16167754Smsmith 16267754Smsmith 163151937Sjkim ACPI_FUNCTION_ENTRY (); 16467754Smsmith 16567754Smsmith 166151937Sjkim /* 167151937Sjkim * The ResourceSourceIndex and ResourceSource are optional elements of some 168151937Sjkim * Large-type resource descriptors. 169151937Sjkim */ 17067754Smsmith 171151937Sjkim /* 172151937Sjkim * If the length of the actual resource descriptor is greater than the ACPI 173151937Sjkim * spec-defined minimum length, it means that a ResourceSourceIndex exists 174151937Sjkim * and is followed by a (required) null terminated string. The string length 175151937Sjkim * (including the null terminator) is the resource length minus the minimum 176151937Sjkim * length, minus one byte for the ResourceSourceIndex itself. 177151937Sjkim */ 178151937Sjkim if (ResourceLength > MinimumAmlResourceLength) 179151937Sjkim { 180151937Sjkim /* Compute the length of the optional string */ 18177424Smsmith 182151937Sjkim StringLength = ResourceLength - MinimumAmlResourceLength - 1; 183151937Sjkim } 18477424Smsmith 185167802Sjkim /* 186167802Sjkim * Round the length up to a multiple of the native word in order to 187167802Sjkim * guarantee that the entire resource descriptor is native word aligned 188167802Sjkim */ 189167802Sjkim return ((UINT32) ACPI_ROUND_UP_TO_NATIVE_WORD (StringLength)); 19067754Smsmith} 19167754Smsmith 19267754Smsmith 19367754Smsmith/******************************************************************************* 19467754Smsmith * 195151937Sjkim * FUNCTION: AcpiRsGetAmlLength 19667754Smsmith * 197151937Sjkim * PARAMETERS: Resource - Pointer to the resource linked list 198281075Sdim * ResourceListSize - Size of the resource linked list 199151937Sjkim * SizeNeeded - Where the required size is returned 20067754Smsmith * 20177424Smsmith * RETURN: Status 20267754Smsmith * 203151937Sjkim * DESCRIPTION: Takes a linked list of internal resource descriptors and 204151937Sjkim * calculates the size buffer needed to hold the corresponding 205151937Sjkim * external resource byte stream. 20667754Smsmith * 20767754Smsmith ******************************************************************************/ 20867754Smsmith 20967754SmsmithACPI_STATUS 210151937SjkimAcpiRsGetAmlLength ( 211151937Sjkim ACPI_RESOURCE *Resource, 212281075Sdim ACPI_SIZE ResourceListSize, 21391116Smsmith ACPI_SIZE *SizeNeeded) 21467754Smsmith{ 215151937Sjkim ACPI_SIZE AmlSizeNeeded = 0; 216281075Sdim ACPI_RESOURCE *ResourceEnd; 217167802Sjkim ACPI_RS_LENGTH TotalSize; 21867754Smsmith 21967754Smsmith 220167802Sjkim ACPI_FUNCTION_TRACE (RsGetAmlLength); 22167754Smsmith 22267754Smsmith 223151937Sjkim /* Traverse entire list of internal resource descriptors */ 224151937Sjkim 225281075Sdim ResourceEnd = ACPI_ADD_PTR (ACPI_RESOURCE, Resource, ResourceListSize); 226281075Sdim while (Resource < ResourceEnd) 22767754Smsmith { 228151937Sjkim /* Validate the descriptor type */ 22967754Smsmith 230151937Sjkim if (Resource->Type > ACPI_RESOURCE_TYPE_MAX) 23167754Smsmith { 232151937Sjkim return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE); 233151937Sjkim } 23467754Smsmith 235246849Sjkim /* Sanity check the length. It must not be zero, or we loop forever */ 236246849Sjkim 237246849Sjkim if (!Resource->Length) 238246849Sjkim { 239246849Sjkim return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH); 240246849Sjkim } 241246849Sjkim 242151937Sjkim /* Get the base size of the (external stream) resource descriptor */ 24367754Smsmith 244151937Sjkim TotalSize = AcpiGbl_AmlResourceSizes [Resource->Type]; 24567754Smsmith 246151937Sjkim /* 247151937Sjkim * Augment the base size for descriptors with optional and/or 248151937Sjkim * variable-length fields 249151937Sjkim */ 250151937Sjkim switch (Resource->Type) 251151937Sjkim { 252193267Sjkim case ACPI_RESOURCE_TYPE_IRQ: 253193267Sjkim 254193267Sjkim /* Length can be 3 or 2 */ 255193267Sjkim 256193267Sjkim if (Resource->Data.Irq.DescriptorLength == 2) 257193267Sjkim { 258193267Sjkim TotalSize--; 259193267Sjkim } 260193267Sjkim break; 261193267Sjkim 262193267Sjkim 263193267Sjkim case ACPI_RESOURCE_TYPE_START_DEPENDENT: 264193267Sjkim 265193267Sjkim /* Length can be 1 or 0 */ 266193267Sjkim 267193267Sjkim if (Resource->Data.Irq.DescriptorLength == 0) 268193267Sjkim { 269193267Sjkim TotalSize--; 270193267Sjkim } 271193267Sjkim break; 272193267Sjkim 273193267Sjkim 274151937Sjkim case ACPI_RESOURCE_TYPE_VENDOR: 27577424Smsmith /* 276151937Sjkim * Vendor Defined Resource: 277151937Sjkim * For a Vendor Specific resource, if the Length is between 1 and 7 278151937Sjkim * it will be created as a Small Resource data type, otherwise it 279151937Sjkim * is a Large Resource data type. 28077424Smsmith */ 281151937Sjkim if (Resource->Data.Vendor.ByteLength > 7) 282151937Sjkim { 283151937Sjkim /* Base size of a Large resource descriptor */ 28467754Smsmith 285151937Sjkim TotalSize = sizeof (AML_RESOURCE_LARGE_HEADER); 286151937Sjkim } 28767754Smsmith 288151937Sjkim /* Add the size of the vendor-specific data */ 28977424Smsmith 290151937Sjkim TotalSize = (ACPI_RS_LENGTH) 291151937Sjkim (TotalSize + Resource->Data.Vendor.ByteLength); 29277424Smsmith break; 29367754Smsmith 29467754Smsmith 295151937Sjkim case ACPI_RESOURCE_TYPE_END_TAG: 29677424Smsmith /* 297151937Sjkim * End Tag: 298151937Sjkim * We are done -- return the accumulated total size. 29977424Smsmith */ 300151937Sjkim *SizeNeeded = AmlSizeNeeded + TotalSize; 30167754Smsmith 302151937Sjkim /* Normal exit */ 30367754Smsmith 304151937Sjkim return_ACPI_STATUS (AE_OK); 30567754Smsmith 306151937Sjkim 307151937Sjkim case ACPI_RESOURCE_TYPE_ADDRESS16: 30877424Smsmith /* 309151937Sjkim * 16-Bit Address Resource: 310151937Sjkim * Add the size of the optional ResourceSource info 31177424Smsmith */ 312151937Sjkim TotalSize = (ACPI_RS_LENGTH) 313151937Sjkim (TotalSize + AcpiRsStructOptionLength ( 314151937Sjkim &Resource->Data.Address16.ResourceSource)); 31577424Smsmith break; 31667754Smsmith 31767754Smsmith 318151937Sjkim case ACPI_RESOURCE_TYPE_ADDRESS32: 31977424Smsmith /* 320151937Sjkim * 32-Bit Address Resource: 321151937Sjkim * Add the size of the optional ResourceSource info 32277424Smsmith */ 323151937Sjkim TotalSize = (ACPI_RS_LENGTH) 324151937Sjkim (TotalSize + AcpiRsStructOptionLength ( 325151937Sjkim &Resource->Data.Address32.ResourceSource)); 326151937Sjkim break; 32767754Smsmith 32867754Smsmith 329151937Sjkim case ACPI_RESOURCE_TYPE_ADDRESS64: 33077424Smsmith /* 331151937Sjkim * 64-Bit Address Resource: 332151937Sjkim * Add the size of the optional ResourceSource info 33377424Smsmith */ 334151937Sjkim TotalSize = (ACPI_RS_LENGTH) 335151937Sjkim (TotalSize + AcpiRsStructOptionLength ( 336151937Sjkim &Resource->Data.Address64.ResourceSource)); 33777424Smsmith break; 33867754Smsmith 33967754Smsmith 340151937Sjkim case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: 34177424Smsmith /* 342151937Sjkim * Extended IRQ Resource: 343151937Sjkim * Add the size of each additional optional interrupt beyond the 344151937Sjkim * required 1 (4 bytes for each UINT32 interrupt number) 34577424Smsmith */ 346151937Sjkim TotalSize = (ACPI_RS_LENGTH) 347151937Sjkim (TotalSize + 348151937Sjkim ((Resource->Data.ExtendedIrq.InterruptCount - 1) * 4) + 34967754Smsmith 350151937Sjkim /* Add the size of the optional ResourceSource info */ 35167754Smsmith 352151937Sjkim AcpiRsStructOptionLength ( 353151937Sjkim &Resource->Data.ExtendedIrq.ResourceSource)); 354151937Sjkim break; 35567754Smsmith 35667754Smsmith 357228110Sjkim case ACPI_RESOURCE_TYPE_GPIO: 358228110Sjkim 359228110Sjkim TotalSize = (ACPI_RS_LENGTH) (TotalSize + (Resource->Data.Gpio.PinTableLength * 2) + 360228110Sjkim Resource->Data.Gpio.ResourceSource.StringLength + 361228110Sjkim Resource->Data.Gpio.VendorLength); 362228110Sjkim 363228110Sjkim break; 364228110Sjkim 365228110Sjkim 366228110Sjkim case ACPI_RESOURCE_TYPE_SERIAL_BUS: 367228110Sjkim 368228110Sjkim TotalSize = AcpiGbl_AmlResourceSerialBusSizes [Resource->Data.CommonSerialBus.Type]; 369228110Sjkim 370228110Sjkim TotalSize = (ACPI_RS_LENGTH) (TotalSize + 371228110Sjkim Resource->Data.I2cSerialBus.ResourceSource.StringLength + 372228110Sjkim Resource->Data.I2cSerialBus.VendorLength); 373228110Sjkim 374228110Sjkim break; 375228110Sjkim 376250838Sjkim default: 377228110Sjkim 37877424Smsmith break; 379151937Sjkim } 38067754Smsmith 381151937Sjkim /* Update the total */ 38267754Smsmith 383151937Sjkim AmlSizeNeeded += TotalSize; 38467754Smsmith 385151937Sjkim /* Point to the next object */ 38667754Smsmith 387167802Sjkim Resource = ACPI_ADD_PTR (ACPI_RESOURCE, Resource, Resource->Length); 388151937Sjkim } 38967754Smsmith 390167802Sjkim /* Did not find an EndTag resource descriptor */ 39167754Smsmith 392167802Sjkim return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG); 393151937Sjkim} 39467754Smsmith 39567754Smsmith 396151937Sjkim/******************************************************************************* 397151937Sjkim * 398151937Sjkim * FUNCTION: AcpiRsGetListLength 399151937Sjkim * 400151937Sjkim * PARAMETERS: AmlBuffer - Pointer to the resource byte stream 401151937Sjkim * AmlBufferLength - Size of AmlBuffer 402151937Sjkim * SizeNeeded - Where the size needed is returned 403151937Sjkim * 404151937Sjkim * RETURN: Status 405151937Sjkim * 406151937Sjkim * DESCRIPTION: Takes an external resource byte stream and calculates the size 407151937Sjkim * buffer needed to hold the corresponding internal resource 408151937Sjkim * descriptor linked list. 409151937Sjkim * 410151937Sjkim ******************************************************************************/ 41167754Smsmith 412151937SjkimACPI_STATUS 413151937SjkimAcpiRsGetListLength ( 414151937Sjkim UINT8 *AmlBuffer, 415151937Sjkim UINT32 AmlBufferLength, 416151937Sjkim ACPI_SIZE *SizeNeeded) 417151937Sjkim{ 418167802Sjkim ACPI_STATUS Status; 419167802Sjkim UINT8 *EndAml; 420151937Sjkim UINT8 *Buffer; 421167802Sjkim UINT32 BufferSize; 422151937Sjkim UINT16 Temp16; 423151937Sjkim UINT16 ResourceLength; 424151937Sjkim UINT32 ExtraStructBytes; 425167802Sjkim UINT8 ResourceIndex; 426167802Sjkim UINT8 MinimumAmlResourceLength; 427228110Sjkim AML_RESOURCE *AmlResource; 42867754Smsmith 42967754Smsmith 430167802Sjkim ACPI_FUNCTION_TRACE (RsGetListLength); 43167754Smsmith 43267754Smsmith 433228110Sjkim *SizeNeeded = ACPI_RS_SIZE_MIN; /* Minimum size is one EndTag */ 434167802Sjkim EndAml = AmlBuffer + AmlBufferLength; 43567754Smsmith 436167802Sjkim /* Walk the list of AML resource descriptors */ 43767754Smsmith 438167802Sjkim while (AmlBuffer < EndAml) 439167802Sjkim { 440167802Sjkim /* Validate the Resource Type and Resource Length */ 44167754Smsmith 442243347Sjkim Status = AcpiUtValidateResource (NULL, AmlBuffer, &ResourceIndex); 443167802Sjkim if (ACPI_FAILURE (Status)) 444151937Sjkim { 445228110Sjkim /* 446228110Sjkim * Exit on failure. Cannot continue because the descriptor length 447228110Sjkim * may be bogus also. 448228110Sjkim */ 449167802Sjkim return_ACPI_STATUS (Status); 450151937Sjkim } 45167754Smsmith 452228110Sjkim AmlResource = (void *) AmlBuffer; 453228110Sjkim 454167802Sjkim /* Get the resource length and base (minimum) AML size */ 45567754Smsmith 456151937Sjkim ResourceLength = AcpiUtGetResourceLength (AmlBuffer); 457167802Sjkim MinimumAmlResourceLength = AcpiGbl_ResourceAmlSizes[ResourceIndex]; 45867754Smsmith 459167802Sjkim /* 460167802Sjkim * Augment the size for descriptors with optional 461167802Sjkim * and/or variable length fields 462167802Sjkim */ 463151937Sjkim ExtraStructBytes = 0; 464167802Sjkim Buffer = AmlBuffer + AcpiUtGetResourceHeaderLength (AmlBuffer); 465138287Smarks 466167802Sjkim switch (AcpiUtGetResourceType (AmlBuffer)) 467151937Sjkim { 468167802Sjkim case ACPI_RESOURCE_NAME_IRQ: 46977424Smsmith /* 470167802Sjkim * IRQ Resource: 471167802Sjkim * Get the number of bits set in the 16-bit IRQ mask 47277424Smsmith */ 473167802Sjkim ACPI_MOVE_16_TO_16 (&Temp16, Buffer); 474167802Sjkim ExtraStructBytes = AcpiRsCountSetBits (Temp16); 475167802Sjkim break; 47667754Smsmith 47767754Smsmith 478167802Sjkim case ACPI_RESOURCE_NAME_DMA: 479167802Sjkim /* 480167802Sjkim * DMA Resource: 481167802Sjkim * Get the number of bits set in the 8-bit DMA mask 482167802Sjkim */ 483167802Sjkim ExtraStructBytes = AcpiRsCountSetBits (*Buffer); 484167802Sjkim break; 48567754Smsmith 48667754Smsmith 487167802Sjkim case ACPI_RESOURCE_NAME_VENDOR_SMALL: 488167802Sjkim case ACPI_RESOURCE_NAME_VENDOR_LARGE: 489167802Sjkim /* 490167802Sjkim * Vendor Resource: 491167802Sjkim * Get the number of vendor data bytes 492167802Sjkim */ 493167802Sjkim ExtraStructBytes = ResourceLength; 494241973Sjkim 495241973Sjkim /* 496241973Sjkim * There is already one byte included in the minimum 497241973Sjkim * descriptor size. If there are extra struct bytes, 498241973Sjkim * subtract one from the count. 499241973Sjkim */ 500241973Sjkim if (ExtraStructBytes) 501241973Sjkim { 502241973Sjkim ExtraStructBytes--; 503241973Sjkim } 504167802Sjkim break; 50567754Smsmith 50667754Smsmith 507167802Sjkim case ACPI_RESOURCE_NAME_END_TAG: 508167802Sjkim /* 509228110Sjkim * End Tag: This is the normal exit 510167802Sjkim */ 511167802Sjkim return_ACPI_STATUS (AE_OK); 512138287Smarks 51377424Smsmith 514167802Sjkim case ACPI_RESOURCE_NAME_ADDRESS32: 515167802Sjkim case ACPI_RESOURCE_NAME_ADDRESS16: 516167802Sjkim case ACPI_RESOURCE_NAME_ADDRESS64: 51777424Smsmith /* 518167802Sjkim * Address Resource: 519167802Sjkim * Add the size of the optional ResourceSource 52077424Smsmith */ 521167802Sjkim ExtraStructBytes = AcpiRsStreamOptionLength ( 522167802Sjkim ResourceLength, MinimumAmlResourceLength); 523167802Sjkim break; 52467754Smsmith 52567754Smsmith 526167802Sjkim case ACPI_RESOURCE_NAME_EXTENDED_IRQ: 527167802Sjkim /* 528167802Sjkim * Extended IRQ Resource: 529167802Sjkim * Using the InterruptTableLength, add 4 bytes for each additional 530167802Sjkim * interrupt. Note: at least one interrupt is required and is 531167802Sjkim * included in the minimum descriptor size (reason for the -1) 532167802Sjkim */ 533167802Sjkim ExtraStructBytes = (Buffer[1] - 1) * sizeof (UINT32); 53467754Smsmith 535167802Sjkim /* Add the size of the optional ResourceSource */ 53667754Smsmith 537167802Sjkim ExtraStructBytes += AcpiRsStreamOptionLength ( 538167802Sjkim ResourceLength - ExtraStructBytes, MinimumAmlResourceLength); 539167802Sjkim break; 54067754Smsmith 541228110Sjkim case ACPI_RESOURCE_NAME_GPIO: 54267754Smsmith 543228110Sjkim /* Vendor data is optional */ 544228110Sjkim 545228110Sjkim if (AmlResource->Gpio.VendorLength) 546228110Sjkim { 547228110Sjkim ExtraStructBytes += AmlResource->Gpio.VendorOffset - 548228110Sjkim AmlResource->Gpio.PinTableOffset + AmlResource->Gpio.VendorLength; 549228110Sjkim } 550228110Sjkim else 551228110Sjkim { 552228110Sjkim ExtraStructBytes += AmlResource->LargeHeader.ResourceLength + 553228110Sjkim sizeof (AML_RESOURCE_LARGE_HEADER) - 554228110Sjkim AmlResource->Gpio.PinTableOffset; 555228110Sjkim } 556228110Sjkim break; 557228110Sjkim 558228110Sjkim case ACPI_RESOURCE_NAME_SERIAL_BUS: 559228110Sjkim 560228110Sjkim MinimumAmlResourceLength = AcpiGbl_ResourceAmlSerialBusSizes[ 561228110Sjkim AmlResource->CommonSerialBus.Type]; 562228110Sjkim ExtraStructBytes += AmlResource->CommonSerialBus.ResourceLength - 563228110Sjkim MinimumAmlResourceLength; 564228110Sjkim break; 565228110Sjkim 566167802Sjkim default: 567250838Sjkim 568167802Sjkim break; 569167802Sjkim } 57067754Smsmith 571167802Sjkim /* 572167802Sjkim * Update the required buffer size for the internal descriptor structs 573167802Sjkim * 574167802Sjkim * Important: Round the size up for the appropriate alignment. This 575167802Sjkim * is a requirement on IA64. 576167802Sjkim */ 577228110Sjkim if (AcpiUtGetResourceType (AmlBuffer) == ACPI_RESOURCE_NAME_SERIAL_BUS) 578228110Sjkim { 579228110Sjkim BufferSize = AcpiGbl_ResourceStructSerialBusSizes[ 580228110Sjkim AmlResource->CommonSerialBus.Type] + ExtraStructBytes; 581228110Sjkim } 582228110Sjkim else 583228110Sjkim { 584228110Sjkim BufferSize = AcpiGbl_ResourceStructSizes[ResourceIndex] + 585167802Sjkim ExtraStructBytes; 586228110Sjkim } 587167802Sjkim BufferSize = (UINT32) ACPI_ROUND_UP_TO_NATIVE_WORD (BufferSize); 58867754Smsmith 589167802Sjkim *SizeNeeded += BufferSize; 59067754Smsmith 591167802Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_RESOURCES, 592167802Sjkim "Type %.2X, AmlLength %.2X InternalLength %.2X\n", 593167802Sjkim AcpiUtGetResourceType (AmlBuffer), 594167802Sjkim AcpiUtGetDescriptorLength (AmlBuffer), BufferSize)); 59567754Smsmith 59667754Smsmith /* 597167802Sjkim * Point to the next resource within the AML stream using the length 598167802Sjkim * contained in the resource descriptor header 59967754Smsmith */ 600167802Sjkim AmlBuffer += AcpiUtGetDescriptorLength (AmlBuffer); 60167754Smsmith } 60267754Smsmith 603167802Sjkim /* Did not find an EndTag resource descriptor */ 604151937Sjkim 605167802Sjkim return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG); 60667754Smsmith} 60767754Smsmith 60867754Smsmith 60967754Smsmith/******************************************************************************* 61067754Smsmith * 61199679Siwasaki * FUNCTION: AcpiRsGetPciRoutingTableLength 61267754Smsmith * 61367754Smsmith * PARAMETERS: PackageObject - Pointer to the package object 61467754Smsmith * BufferSizeNeeded - UINT32 pointer of the size buffer 61577424Smsmith * needed to properly return the 61677424Smsmith * parsed data 61767754Smsmith * 61877424Smsmith * RETURN: Status 61967754Smsmith * 62067754Smsmith * DESCRIPTION: Given a package representing a PCI routing table, this 62177424Smsmith * calculates the size of the corresponding linked list of 62277424Smsmith * descriptions. 62367754Smsmith * 62467754Smsmith ******************************************************************************/ 62567754Smsmith 62667754SmsmithACPI_STATUS 62799679SiwasakiAcpiRsGetPciRoutingTableLength ( 62867754Smsmith ACPI_OPERAND_OBJECT *PackageObject, 62991116Smsmith ACPI_SIZE *BufferSizeNeeded) 63067754Smsmith{ 63167754Smsmith UINT32 NumberOfElements; 63299679Siwasaki ACPI_SIZE TempSizeNeeded = 0; 63367754Smsmith ACPI_OPERAND_OBJECT **TopObjectList; 63467754Smsmith UINT32 Index; 63567754Smsmith ACPI_OPERAND_OBJECT *PackageElement; 63667754Smsmith ACPI_OPERAND_OBJECT **SubObjectList; 63767754Smsmith BOOLEAN NameFound; 63867754Smsmith UINT32 TableIndex; 63967754Smsmith 64067754Smsmith 641167802Sjkim ACPI_FUNCTION_TRACE (RsGetPciRoutingTableLength); 64267754Smsmith 64367754Smsmith 64467754Smsmith NumberOfElements = PackageObject->Package.Count; 64567754Smsmith 64667754Smsmith /* 64767754Smsmith * Calculate the size of the return buffer. 64867754Smsmith * The base size is the number of elements * the sizes of the 649241973Sjkim * structures. Additional space for the strings is added below. 65067754Smsmith * The minus one is to subtract the size of the UINT8 Source[1] 65167754Smsmith * member because it is added below. 65267754Smsmith * 65367754Smsmith * But each PRT_ENTRY structure has a pointer to a string and 65467754Smsmith * the size of that string must be found. 65567754Smsmith */ 65667754Smsmith TopObjectList = PackageObject->Package.Elements; 65767754Smsmith 65867754Smsmith for (Index = 0; Index < NumberOfElements; Index++) 65967754Smsmith { 660281075Sdim /* Dereference the subpackage */ 661151937Sjkim 66267754Smsmith PackageElement = *TopObjectList; 66367754Smsmith 664193267Sjkim /* We must have a valid Package object */ 665193267Sjkim 666193267Sjkim if (!PackageElement || 667193267Sjkim (PackageElement->Common.Type != ACPI_TYPE_PACKAGE)) 668193267Sjkim { 669193267Sjkim return_ACPI_STATUS (AE_AML_OPERAND_TYPE); 670193267Sjkim } 671193267Sjkim 67267754Smsmith /* 67367754Smsmith * The SubObjectList will now point to an array of the 67467754Smsmith * four IRQ elements: Address, Pin, Source and SourceIndex 67567754Smsmith */ 67667754Smsmith SubObjectList = PackageElement->Package.Elements; 67767754Smsmith 678151937Sjkim /* Scan the IrqTableElements for the Source Name String */ 679151937Sjkim 68067754Smsmith NameFound = FALSE; 68167754Smsmith 682250838Sjkim for (TableIndex = 0; 683250838Sjkim TableIndex < PackageElement->Package.Count && !NameFound; 684250838Sjkim TableIndex++) 68567754Smsmith { 686167802Sjkim if (*SubObjectList && /* Null object allowed */ 687167802Sjkim 688167802Sjkim ((ACPI_TYPE_STRING == 689193267Sjkim (*SubObjectList)->Common.Type) || 690151937Sjkim 691151937Sjkim ((ACPI_TYPE_LOCAL_REFERENCE == 692193267Sjkim (*SubObjectList)->Common.Type) && 693151937Sjkim 694193267Sjkim ((*SubObjectList)->Reference.Class == 695193267Sjkim ACPI_REFCLASS_NAME)))) 69667754Smsmith { 69767754Smsmith NameFound = TRUE; 69867754Smsmith } 69967754Smsmith else 70067754Smsmith { 701151937Sjkim /* Look at the next element */ 702151937Sjkim 70367754Smsmith SubObjectList++; 70467754Smsmith } 70567754Smsmith } 70667754Smsmith 70791116Smsmith TempSizeNeeded += (sizeof (ACPI_PCI_ROUTING_TABLE) - 4); 70869450Smsmith 709151937Sjkim /* Was a String type found? */ 710151937Sjkim 71199679Siwasaki if (NameFound) 71267754Smsmith { 713193267Sjkim if ((*SubObjectList)->Common.Type == ACPI_TYPE_STRING) 71473561Smsmith { 71573561Smsmith /* 716114237Snjl * The length String.Length field does not include the 717114237Snjl * terminating NULL, add 1 71873561Smsmith */ 719151937Sjkim TempSizeNeeded += ((ACPI_SIZE) 720151937Sjkim (*SubObjectList)->String.Length + 1); 72173561Smsmith } 72273561Smsmith else 72373561Smsmith { 72477424Smsmith TempSizeNeeded += AcpiNsGetPathnameLength ( 72577424Smsmith (*SubObjectList)->Reference.Node); 72673561Smsmith } 72767754Smsmith } 72867754Smsmith else 72967754Smsmith { 73067754Smsmith /* 73167754Smsmith * If no name was found, then this is a NULL, which is 73277424Smsmith * translated as a UINT32 zero. 73367754Smsmith */ 73477424Smsmith TempSizeNeeded += sizeof (UINT32); 73567754Smsmith } 73667754Smsmith 73769450Smsmith /* Round up the size since each element must be aligned */ 73869450Smsmith 739167802Sjkim TempSizeNeeded = ACPI_ROUND_UP_TO_64BIT (TempSizeNeeded); 74069450Smsmith 741151937Sjkim /* Point to the next ACPI_OPERAND_OBJECT */ 742151937Sjkim 74367754Smsmith TopObjectList++; 74467754Smsmith } 74567754Smsmith 74677424Smsmith /* 747167802Sjkim * Add an extra element to the end of the list, essentially a 748151937Sjkim * NULL terminator 74977424Smsmith */ 75091116Smsmith *BufferSizeNeeded = TempSizeNeeded + sizeof (ACPI_PCI_ROUTING_TABLE); 75167754Smsmith return_ACPI_STATUS (AE_OK); 75269450Smsmith} 753