167754Smsmith/******************************************************************************* 267754Smsmith * 377424Smsmith * Module Name: rscalc - Calculate stream and list lengths 467754Smsmith * 567754Smsmith ******************************************************************************/ 667754Smsmith 7217365Sjkim/* 8306536Sjkim * Copyright (C) 2000 - 2016, 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 /* 167306536Sjkim * The ResourceSourceIndex and ResourceSource are optional elements of 168306536Sjkim * some Large-type resource descriptors. 169151937Sjkim */ 17067754Smsmith 171151937Sjkim /* 172306536Sjkim * If the length of the actual resource descriptor is greater than the 173306536Sjkim * ACPI spec-defined minimum length, it means that a ResourceSourceIndex 174306536Sjkim * exists and is followed by a (required) null terminated string. The 175306536Sjkim * string length (including the null terminator) is the resource length 176306536Sjkim * minus the minimum length, minus one byte for the ResourceSourceIndex 177306536Sjkim * itself. 178151937Sjkim */ 179151937Sjkim if (ResourceLength > MinimumAmlResourceLength) 180151937Sjkim { 181151937Sjkim /* Compute the length of the optional string */ 18277424Smsmith 183151937Sjkim StringLength = ResourceLength - MinimumAmlResourceLength - 1; 184151937Sjkim } 18577424Smsmith 186167802Sjkim /* 187167802Sjkim * Round the length up to a multiple of the native word in order to 188167802Sjkim * guarantee that the entire resource descriptor is native word aligned 189167802Sjkim */ 190167802Sjkim return ((UINT32) ACPI_ROUND_UP_TO_NATIVE_WORD (StringLength)); 19167754Smsmith} 19267754Smsmith 19367754Smsmith 19467754Smsmith/******************************************************************************* 19567754Smsmith * 196151937Sjkim * FUNCTION: AcpiRsGetAmlLength 19767754Smsmith * 198151937Sjkim * PARAMETERS: Resource - Pointer to the resource linked list 199281075Sdim * ResourceListSize - Size of 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, 213281075Sdim ACPI_SIZE ResourceListSize, 21491116Smsmith ACPI_SIZE *SizeNeeded) 21567754Smsmith{ 216151937Sjkim ACPI_SIZE AmlSizeNeeded = 0; 217281075Sdim ACPI_RESOURCE *ResourceEnd; 218167802Sjkim ACPI_RS_LENGTH TotalSize; 21967754Smsmith 22067754Smsmith 221167802Sjkim ACPI_FUNCTION_TRACE (RsGetAmlLength); 22267754Smsmith 22367754Smsmith 224151937Sjkim /* Traverse entire list of internal resource descriptors */ 225151937Sjkim 226281075Sdim ResourceEnd = ACPI_ADD_PTR (ACPI_RESOURCE, Resource, ResourceListSize); 227281075Sdim while (Resource < ResourceEnd) 22867754Smsmith { 229151937Sjkim /* Validate the descriptor type */ 23067754Smsmith 231151937Sjkim if (Resource->Type > ACPI_RESOURCE_TYPE_MAX) 23267754Smsmith { 233151937Sjkim return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE); 234151937Sjkim } 23567754Smsmith 236246849Sjkim /* Sanity check the length. It must not be zero, or we loop forever */ 237246849Sjkim 238246849Sjkim if (!Resource->Length) 239246849Sjkim { 240246849Sjkim return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH); 241246849Sjkim } 242246849Sjkim 243151937Sjkim /* Get the base size of the (external stream) resource descriptor */ 24467754Smsmith 245151937Sjkim TotalSize = AcpiGbl_AmlResourceSizes [Resource->Type]; 24667754Smsmith 247151937Sjkim /* 248151937Sjkim * Augment the base size for descriptors with optional and/or 249151937Sjkim * variable-length fields 250151937Sjkim */ 251151937Sjkim switch (Resource->Type) 252151937Sjkim { 253193267Sjkim case ACPI_RESOURCE_TYPE_IRQ: 254193267Sjkim 255193267Sjkim /* Length can be 3 or 2 */ 256193267Sjkim 257193267Sjkim if (Resource->Data.Irq.DescriptorLength == 2) 258193267Sjkim { 259193267Sjkim TotalSize--; 260193267Sjkim } 261193267Sjkim break; 262193267Sjkim 263193267Sjkim 264193267Sjkim case ACPI_RESOURCE_TYPE_START_DEPENDENT: 265193267Sjkim 266193267Sjkim /* Length can be 1 or 0 */ 267193267Sjkim 268193267Sjkim if (Resource->Data.Irq.DescriptorLength == 0) 269193267Sjkim { 270193267Sjkim TotalSize--; 271193267Sjkim } 272193267Sjkim break; 273193267Sjkim 274193267Sjkim 275151937Sjkim case ACPI_RESOURCE_TYPE_VENDOR: 27677424Smsmith /* 277151937Sjkim * Vendor Defined Resource: 278151937Sjkim * For a Vendor Specific resource, if the Length is between 1 and 7 279151937Sjkim * it will be created as a Small Resource data type, otherwise it 280151937Sjkim * is a Large Resource data type. 28177424Smsmith */ 282151937Sjkim if (Resource->Data.Vendor.ByteLength > 7) 283151937Sjkim { 284151937Sjkim /* Base size of a Large resource descriptor */ 28567754Smsmith 286151937Sjkim TotalSize = sizeof (AML_RESOURCE_LARGE_HEADER); 287151937Sjkim } 28867754Smsmith 289151937Sjkim /* Add the size of the vendor-specific data */ 29077424Smsmith 291151937Sjkim TotalSize = (ACPI_RS_LENGTH) 292151937Sjkim (TotalSize + Resource->Data.Vendor.ByteLength); 29377424Smsmith break; 29467754Smsmith 29567754Smsmith 296151937Sjkim case ACPI_RESOURCE_TYPE_END_TAG: 29777424Smsmith /* 298151937Sjkim * End Tag: 299151937Sjkim * We are done -- return the accumulated total size. 30077424Smsmith */ 301151937Sjkim *SizeNeeded = AmlSizeNeeded + TotalSize; 30267754Smsmith 303151937Sjkim /* Normal exit */ 30467754Smsmith 305151937Sjkim return_ACPI_STATUS (AE_OK); 30667754Smsmith 307151937Sjkim 308151937Sjkim case ACPI_RESOURCE_TYPE_ADDRESS16: 30977424Smsmith /* 310151937Sjkim * 16-Bit Address Resource: 311151937Sjkim * Add the size of the optional ResourceSource info 31277424Smsmith */ 313306536Sjkim TotalSize = (ACPI_RS_LENGTH) (TotalSize + 314306536Sjkim AcpiRsStructOptionLength ( 315306536Sjkim &Resource->Data.Address16.ResourceSource)); 31677424Smsmith break; 31767754Smsmith 31867754Smsmith 319151937Sjkim case ACPI_RESOURCE_TYPE_ADDRESS32: 32077424Smsmith /* 321151937Sjkim * 32-Bit Address Resource: 322151937Sjkim * Add the size of the optional ResourceSource info 32377424Smsmith */ 324306536Sjkim TotalSize = (ACPI_RS_LENGTH) (TotalSize + 325306536Sjkim AcpiRsStructOptionLength ( 326306536Sjkim &Resource->Data.Address32.ResourceSource)); 327151937Sjkim break; 32867754Smsmith 32967754Smsmith 330151937Sjkim case ACPI_RESOURCE_TYPE_ADDRESS64: 33177424Smsmith /* 332151937Sjkim * 64-Bit Address Resource: 333151937Sjkim * Add the size of the optional ResourceSource info 33477424Smsmith */ 335306536Sjkim TotalSize = (ACPI_RS_LENGTH) (TotalSize + 336306536Sjkim AcpiRsStructOptionLength ( 337306536Sjkim &Resource->Data.Address64.ResourceSource)); 33877424Smsmith break; 33967754Smsmith 34067754Smsmith 341151937Sjkim case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: 34277424Smsmith /* 343151937Sjkim * Extended IRQ Resource: 344151937Sjkim * Add the size of each additional optional interrupt beyond the 345151937Sjkim * required 1 (4 bytes for each UINT32 interrupt number) 34677424Smsmith */ 347306536Sjkim TotalSize = (ACPI_RS_LENGTH) (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 359306536Sjkim TotalSize = (ACPI_RS_LENGTH) (TotalSize + 360306536Sjkim (Resource->Data.Gpio.PinTableLength * 2) + 361228110Sjkim Resource->Data.Gpio.ResourceSource.StringLength + 362228110Sjkim Resource->Data.Gpio.VendorLength); 363228110Sjkim 364228110Sjkim break; 365228110Sjkim 366228110Sjkim 367228110Sjkim case ACPI_RESOURCE_TYPE_SERIAL_BUS: 368228110Sjkim 369306536Sjkim TotalSize = AcpiGbl_AmlResourceSerialBusSizes [ 370306536Sjkim Resource->Data.CommonSerialBus.Type]; 371228110Sjkim 372228110Sjkim TotalSize = (ACPI_RS_LENGTH) (TotalSize + 373228110Sjkim Resource->Data.I2cSerialBus.ResourceSource.StringLength + 374228110Sjkim Resource->Data.I2cSerialBus.VendorLength); 375228110Sjkim 376228110Sjkim break; 377228110Sjkim 378250838Sjkim default: 379228110Sjkim 38077424Smsmith break; 381151937Sjkim } 38267754Smsmith 383151937Sjkim /* Update the total */ 38467754Smsmith 385151937Sjkim AmlSizeNeeded += TotalSize; 38667754Smsmith 387151937Sjkim /* Point to the next object */ 38867754Smsmith 389167802Sjkim Resource = ACPI_ADD_PTR (ACPI_RESOURCE, Resource, Resource->Length); 390151937Sjkim } 39167754Smsmith 392167802Sjkim /* Did not find an EndTag resource descriptor */ 39367754Smsmith 394167802Sjkim return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG); 395151937Sjkim} 39667754Smsmith 39767754Smsmith 398151937Sjkim/******************************************************************************* 399151937Sjkim * 400151937Sjkim * FUNCTION: AcpiRsGetListLength 401151937Sjkim * 402151937Sjkim * PARAMETERS: AmlBuffer - Pointer to the resource byte stream 403151937Sjkim * AmlBufferLength - Size of AmlBuffer 404151937Sjkim * SizeNeeded - Where the size needed is returned 405151937Sjkim * 406151937Sjkim * RETURN: Status 407151937Sjkim * 408151937Sjkim * DESCRIPTION: Takes an external resource byte stream and calculates the size 409151937Sjkim * buffer needed to hold the corresponding internal resource 410151937Sjkim * descriptor linked list. 411151937Sjkim * 412151937Sjkim ******************************************************************************/ 41367754Smsmith 414151937SjkimACPI_STATUS 415151937SjkimAcpiRsGetListLength ( 416151937Sjkim UINT8 *AmlBuffer, 417151937Sjkim UINT32 AmlBufferLength, 418151937Sjkim ACPI_SIZE *SizeNeeded) 419151937Sjkim{ 420167802Sjkim ACPI_STATUS Status; 421167802Sjkim UINT8 *EndAml; 422151937Sjkim UINT8 *Buffer; 423167802Sjkim UINT32 BufferSize; 424151937Sjkim UINT16 Temp16; 425151937Sjkim UINT16 ResourceLength; 426151937Sjkim UINT32 ExtraStructBytes; 427167802Sjkim UINT8 ResourceIndex; 428167802Sjkim UINT8 MinimumAmlResourceLength; 429228110Sjkim AML_RESOURCE *AmlResource; 43067754Smsmith 43167754Smsmith 432167802Sjkim ACPI_FUNCTION_TRACE (RsGetListLength); 43367754Smsmith 43467754Smsmith 435228110Sjkim *SizeNeeded = ACPI_RS_SIZE_MIN; /* Minimum size is one EndTag */ 436167802Sjkim EndAml = AmlBuffer + AmlBufferLength; 43767754Smsmith 438167802Sjkim /* Walk the list of AML resource descriptors */ 43967754Smsmith 440167802Sjkim while (AmlBuffer < EndAml) 441167802Sjkim { 442167802Sjkim /* Validate the Resource Type and Resource Length */ 44367754Smsmith 444243347Sjkim Status = AcpiUtValidateResource (NULL, AmlBuffer, &ResourceIndex); 445167802Sjkim if (ACPI_FAILURE (Status)) 446151937Sjkim { 447228110Sjkim /* 448228110Sjkim * Exit on failure. Cannot continue because the descriptor length 449228110Sjkim * may be bogus also. 450228110Sjkim */ 451167802Sjkim return_ACPI_STATUS (Status); 452151937Sjkim } 45367754Smsmith 454228110Sjkim AmlResource = (void *) AmlBuffer; 455228110Sjkim 456167802Sjkim /* Get the resource length and base (minimum) AML size */ 45767754Smsmith 458151937Sjkim ResourceLength = AcpiUtGetResourceLength (AmlBuffer); 459167802Sjkim MinimumAmlResourceLength = AcpiGbl_ResourceAmlSizes[ResourceIndex]; 46067754Smsmith 461167802Sjkim /* 462167802Sjkim * Augment the size for descriptors with optional 463167802Sjkim * and/or variable length fields 464167802Sjkim */ 465151937Sjkim ExtraStructBytes = 0; 466167802Sjkim Buffer = AmlBuffer + AcpiUtGetResourceHeaderLength (AmlBuffer); 467138287Smarks 468167802Sjkim switch (AcpiUtGetResourceType (AmlBuffer)) 469151937Sjkim { 470167802Sjkim case ACPI_RESOURCE_NAME_IRQ: 47177424Smsmith /* 472167802Sjkim * IRQ Resource: 473167802Sjkim * Get the number of bits set in the 16-bit IRQ mask 47477424Smsmith */ 475167802Sjkim ACPI_MOVE_16_TO_16 (&Temp16, Buffer); 476167802Sjkim ExtraStructBytes = AcpiRsCountSetBits (Temp16); 477167802Sjkim break; 47867754Smsmith 47967754Smsmith 480167802Sjkim case ACPI_RESOURCE_NAME_DMA: 481167802Sjkim /* 482167802Sjkim * DMA Resource: 483167802Sjkim * Get the number of bits set in the 8-bit DMA mask 484167802Sjkim */ 485167802Sjkim ExtraStructBytes = AcpiRsCountSetBits (*Buffer); 486167802Sjkim break; 48767754Smsmith 48867754Smsmith 489167802Sjkim case ACPI_RESOURCE_NAME_VENDOR_SMALL: 490167802Sjkim case ACPI_RESOURCE_NAME_VENDOR_LARGE: 491167802Sjkim /* 492167802Sjkim * Vendor Resource: 493167802Sjkim * Get the number of vendor data bytes 494167802Sjkim */ 495167802Sjkim ExtraStructBytes = ResourceLength; 496241973Sjkim 497241973Sjkim /* 498241973Sjkim * There is already one byte included in the minimum 499241973Sjkim * descriptor size. If there are extra struct bytes, 500241973Sjkim * subtract one from the count. 501241973Sjkim */ 502241973Sjkim if (ExtraStructBytes) 503241973Sjkim { 504241973Sjkim ExtraStructBytes--; 505241973Sjkim } 506167802Sjkim break; 50767754Smsmith 50867754Smsmith 509167802Sjkim case ACPI_RESOURCE_NAME_END_TAG: 510167802Sjkim /* 511228110Sjkim * End Tag: This is the normal exit 512167802Sjkim */ 513167802Sjkim return_ACPI_STATUS (AE_OK); 514138287Smarks 51577424Smsmith 516167802Sjkim case ACPI_RESOURCE_NAME_ADDRESS32: 517167802Sjkim case ACPI_RESOURCE_NAME_ADDRESS16: 518167802Sjkim case ACPI_RESOURCE_NAME_ADDRESS64: 51977424Smsmith /* 520167802Sjkim * Address Resource: 521167802Sjkim * Add the size of the optional ResourceSource 52277424Smsmith */ 523167802Sjkim ExtraStructBytes = AcpiRsStreamOptionLength ( 524167802Sjkim ResourceLength, MinimumAmlResourceLength); 525167802Sjkim break; 52667754Smsmith 52767754Smsmith 528167802Sjkim case ACPI_RESOURCE_NAME_EXTENDED_IRQ: 529167802Sjkim /* 530167802Sjkim * Extended IRQ Resource: 531167802Sjkim * Using the InterruptTableLength, add 4 bytes for each additional 532167802Sjkim * interrupt. Note: at least one interrupt is required and is 533167802Sjkim * included in the minimum descriptor size (reason for the -1) 534167802Sjkim */ 535167802Sjkim ExtraStructBytes = (Buffer[1] - 1) * sizeof (UINT32); 53667754Smsmith 537167802Sjkim /* Add the size of the optional ResourceSource */ 53867754Smsmith 539167802Sjkim ExtraStructBytes += AcpiRsStreamOptionLength ( 540167802Sjkim ResourceLength - ExtraStructBytes, MinimumAmlResourceLength); 541167802Sjkim break; 54267754Smsmith 543228110Sjkim case ACPI_RESOURCE_NAME_GPIO: 54467754Smsmith 545228110Sjkim /* Vendor data is optional */ 546228110Sjkim 547228110Sjkim if (AmlResource->Gpio.VendorLength) 548228110Sjkim { 549306536Sjkim ExtraStructBytes += 550306536Sjkim AmlResource->Gpio.VendorOffset - 551306536Sjkim AmlResource->Gpio.PinTableOffset + 552306536Sjkim AmlResource->Gpio.VendorLength; 553228110Sjkim } 554228110Sjkim else 555228110Sjkim { 556306536Sjkim ExtraStructBytes += 557306536Sjkim AmlResource->LargeHeader.ResourceLength + 558228110Sjkim sizeof (AML_RESOURCE_LARGE_HEADER) - 559228110Sjkim AmlResource->Gpio.PinTableOffset; 560228110Sjkim } 561228110Sjkim break; 562228110Sjkim 563228110Sjkim case ACPI_RESOURCE_NAME_SERIAL_BUS: 564228110Sjkim 565228110Sjkim MinimumAmlResourceLength = AcpiGbl_ResourceAmlSerialBusSizes[ 566228110Sjkim AmlResource->CommonSerialBus.Type]; 567306536Sjkim ExtraStructBytes += 568306536Sjkim AmlResource->CommonSerialBus.ResourceLength - 569228110Sjkim MinimumAmlResourceLength; 570228110Sjkim break; 571228110Sjkim 572167802Sjkim default: 573250838Sjkim 574167802Sjkim break; 575167802Sjkim } 57667754Smsmith 577167802Sjkim /* 578167802Sjkim * Update the required buffer size for the internal descriptor structs 579167802Sjkim * 580167802Sjkim * Important: Round the size up for the appropriate alignment. This 581167802Sjkim * is a requirement on IA64. 582167802Sjkim */ 583306536Sjkim if (AcpiUtGetResourceType (AmlBuffer) == 584306536Sjkim ACPI_RESOURCE_NAME_SERIAL_BUS) 585228110Sjkim { 586228110Sjkim BufferSize = AcpiGbl_ResourceStructSerialBusSizes[ 587228110Sjkim AmlResource->CommonSerialBus.Type] + ExtraStructBytes; 588228110Sjkim } 589228110Sjkim else 590228110Sjkim { 591228110Sjkim BufferSize = AcpiGbl_ResourceStructSizes[ResourceIndex] + 592306536Sjkim ExtraStructBytes; 593228110Sjkim } 594306536Sjkim 595167802Sjkim BufferSize = (UINT32) ACPI_ROUND_UP_TO_NATIVE_WORD (BufferSize); 596167802Sjkim *SizeNeeded += BufferSize; 59767754Smsmith 598167802Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_RESOURCES, 599167802Sjkim "Type %.2X, AmlLength %.2X InternalLength %.2X\n", 600167802Sjkim AcpiUtGetResourceType (AmlBuffer), 601167802Sjkim AcpiUtGetDescriptorLength (AmlBuffer), BufferSize)); 60267754Smsmith 60367754Smsmith /* 604167802Sjkim * Point to the next resource within the AML stream using the length 605167802Sjkim * contained in the resource descriptor header 60667754Smsmith */ 607167802Sjkim AmlBuffer += AcpiUtGetDescriptorLength (AmlBuffer); 60867754Smsmith } 60967754Smsmith 610167802Sjkim /* Did not find an EndTag resource descriptor */ 611151937Sjkim 612167802Sjkim return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG); 61367754Smsmith} 61467754Smsmith 61567754Smsmith 61667754Smsmith/******************************************************************************* 61767754Smsmith * 61899679Siwasaki * FUNCTION: AcpiRsGetPciRoutingTableLength 61967754Smsmith * 62067754Smsmith * PARAMETERS: PackageObject - Pointer to the package object 62167754Smsmith * BufferSizeNeeded - UINT32 pointer of the size buffer 62277424Smsmith * needed to properly return the 62377424Smsmith * parsed data 62467754Smsmith * 62577424Smsmith * RETURN: Status 62667754Smsmith * 62767754Smsmith * DESCRIPTION: Given a package representing a PCI routing table, this 62877424Smsmith * calculates the size of the corresponding linked list of 62977424Smsmith * descriptions. 63067754Smsmith * 63167754Smsmith ******************************************************************************/ 63267754Smsmith 63367754SmsmithACPI_STATUS 63499679SiwasakiAcpiRsGetPciRoutingTableLength ( 63567754Smsmith ACPI_OPERAND_OBJECT *PackageObject, 63691116Smsmith ACPI_SIZE *BufferSizeNeeded) 63767754Smsmith{ 63867754Smsmith UINT32 NumberOfElements; 63999679Siwasaki ACPI_SIZE TempSizeNeeded = 0; 64067754Smsmith ACPI_OPERAND_OBJECT **TopObjectList; 64167754Smsmith UINT32 Index; 64267754Smsmith ACPI_OPERAND_OBJECT *PackageElement; 64367754Smsmith ACPI_OPERAND_OBJECT **SubObjectList; 64467754Smsmith BOOLEAN NameFound; 64567754Smsmith UINT32 TableIndex; 64667754Smsmith 64767754Smsmith 648167802Sjkim ACPI_FUNCTION_TRACE (RsGetPciRoutingTableLength); 64967754Smsmith 65067754Smsmith 65167754Smsmith NumberOfElements = PackageObject->Package.Count; 65267754Smsmith 65367754Smsmith /* 65467754Smsmith * Calculate the size of the return buffer. 65567754Smsmith * The base size is the number of elements * the sizes of the 656241973Sjkim * structures. Additional space for the strings is added below. 65767754Smsmith * The minus one is to subtract the size of the UINT8 Source[1] 65867754Smsmith * member because it is added below. 65967754Smsmith * 66067754Smsmith * But each PRT_ENTRY structure has a pointer to a string and 66167754Smsmith * the size of that string must be found. 66267754Smsmith */ 66367754Smsmith TopObjectList = PackageObject->Package.Elements; 66467754Smsmith 66567754Smsmith for (Index = 0; Index < NumberOfElements; Index++) 66667754Smsmith { 667281075Sdim /* Dereference the subpackage */ 668151937Sjkim 66967754Smsmith PackageElement = *TopObjectList; 67067754Smsmith 671193267Sjkim /* We must have a valid Package object */ 672193267Sjkim 673193267Sjkim if (!PackageElement || 674193267Sjkim (PackageElement->Common.Type != ACPI_TYPE_PACKAGE)) 675193267Sjkim { 676193267Sjkim return_ACPI_STATUS (AE_AML_OPERAND_TYPE); 677193267Sjkim } 678193267Sjkim 67967754Smsmith /* 68067754Smsmith * The SubObjectList will now point to an array of the 68167754Smsmith * four IRQ elements: Address, Pin, Source and SourceIndex 68267754Smsmith */ 68367754Smsmith SubObjectList = PackageElement->Package.Elements; 68467754Smsmith 685151937Sjkim /* Scan the IrqTableElements for the Source Name String */ 686151937Sjkim 68767754Smsmith NameFound = FALSE; 68867754Smsmith 689250838Sjkim for (TableIndex = 0; 690250838Sjkim TableIndex < PackageElement->Package.Count && !NameFound; 691250838Sjkim TableIndex++) 69267754Smsmith { 693167802Sjkim if (*SubObjectList && /* Null object allowed */ 694167802Sjkim 695167802Sjkim ((ACPI_TYPE_STRING == 696193267Sjkim (*SubObjectList)->Common.Type) || 697151937Sjkim 698151937Sjkim ((ACPI_TYPE_LOCAL_REFERENCE == 699193267Sjkim (*SubObjectList)->Common.Type) && 700151937Sjkim 701193267Sjkim ((*SubObjectList)->Reference.Class == 702193267Sjkim ACPI_REFCLASS_NAME)))) 70367754Smsmith { 70467754Smsmith NameFound = TRUE; 70567754Smsmith } 70667754Smsmith else 70767754Smsmith { 708151937Sjkim /* Look at the next element */ 709151937Sjkim 71067754Smsmith SubObjectList++; 71167754Smsmith } 71267754Smsmith } 71367754Smsmith 71491116Smsmith TempSizeNeeded += (sizeof (ACPI_PCI_ROUTING_TABLE) - 4); 71569450Smsmith 716151937Sjkim /* Was a String type found? */ 717151937Sjkim 71899679Siwasaki if (NameFound) 71967754Smsmith { 720193267Sjkim if ((*SubObjectList)->Common.Type == ACPI_TYPE_STRING) 72173561Smsmith { 72273561Smsmith /* 723114237Snjl * The length String.Length field does not include the 724114237Snjl * terminating NULL, add 1 72573561Smsmith */ 726151937Sjkim TempSizeNeeded += ((ACPI_SIZE) 727151937Sjkim (*SubObjectList)->String.Length + 1); 72873561Smsmith } 72973561Smsmith else 73073561Smsmith { 73177424Smsmith TempSizeNeeded += AcpiNsGetPathnameLength ( 732306536Sjkim (*SubObjectList)->Reference.Node); 73373561Smsmith } 73467754Smsmith } 73567754Smsmith else 73667754Smsmith { 73767754Smsmith /* 73867754Smsmith * If no name was found, then this is a NULL, which is 73977424Smsmith * translated as a UINT32 zero. 74067754Smsmith */ 74177424Smsmith TempSizeNeeded += sizeof (UINT32); 74267754Smsmith } 74367754Smsmith 74469450Smsmith /* Round up the size since each element must be aligned */ 74569450Smsmith 746167802Sjkim TempSizeNeeded = ACPI_ROUND_UP_TO_64BIT (TempSizeNeeded); 74769450Smsmith 748151937Sjkim /* Point to the next ACPI_OPERAND_OBJECT */ 749151937Sjkim 75067754Smsmith TopObjectList++; 75167754Smsmith } 75267754Smsmith 75377424Smsmith /* 754167802Sjkim * Add an extra element to the end of the list, essentially a 755151937Sjkim * NULL terminator 75677424Smsmith */ 75791116Smsmith *BufferSizeNeeded = TempSizeNeeded + sizeof (ACPI_PCI_ROUTING_TABLE); 75867754Smsmith return_ACPI_STATUS (AE_OK); 75969450Smsmith} 760