1167802Sjkim/******************************************************************************* 2167802Sjkim * 3238381Sjkim * Module Name: utresrc - Resource management utilities 4167802Sjkim * 5167802Sjkim ******************************************************************************/ 6167802Sjkim 7217365Sjkim/* 8306536Sjkim * Copyright (C) 2000 - 2016, Intel Corp. 9167802Sjkim * All rights reserved. 10167802Sjkim * 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. 25167802Sjkim * 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. 29167802Sjkim * 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 */ 43167802Sjkim 44193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 45193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 46228110Sjkim#include <contrib/dev/acpica/include/acresrc.h> 47167802Sjkim 48167802Sjkim 49167802Sjkim#define _COMPONENT ACPI_UTILITIES 50167802Sjkim ACPI_MODULE_NAME ("utresrc") 51167802Sjkim 52167802Sjkim 53281075Sdim#if defined(ACPI_DEBUG_OUTPUT) || defined (ACPI_DISASSEMBLER) || defined (ACPI_DEBUGGER) 54167802Sjkim 55167802Sjkim/* 56167802Sjkim * Strings used to decode resource descriptors. 57238381Sjkim * Used by both the disassembler and the debugger resource dump routines 58167802Sjkim */ 59167802Sjkimconst char *AcpiGbl_BmDecode[] = 60167802Sjkim{ 61167802Sjkim "NotBusMaster", 62167802Sjkim "BusMaster" 63167802Sjkim}; 64167802Sjkim 65167802Sjkimconst char *AcpiGbl_ConfigDecode[] = 66167802Sjkim{ 67167802Sjkim "0 - Good Configuration", 68167802Sjkim "1 - Acceptable Configuration", 69167802Sjkim "2 - Suboptimal Configuration", 70167802Sjkim "3 - ***Invalid Configuration***", 71167802Sjkim}; 72167802Sjkim 73167802Sjkimconst char *AcpiGbl_ConsumeDecode[] = 74167802Sjkim{ 75167802Sjkim "ResourceProducer", 76167802Sjkim "ResourceConsumer" 77167802Sjkim}; 78167802Sjkim 79167802Sjkimconst char *AcpiGbl_DecDecode[] = 80167802Sjkim{ 81167802Sjkim "PosDecode", 82167802Sjkim "SubDecode" 83167802Sjkim}; 84167802Sjkim 85167802Sjkimconst char *AcpiGbl_HeDecode[] = 86167802Sjkim{ 87167802Sjkim "Level", 88167802Sjkim "Edge" 89167802Sjkim}; 90167802Sjkim 91167802Sjkimconst char *AcpiGbl_IoDecode[] = 92167802Sjkim{ 93167802Sjkim "Decode10", 94167802Sjkim "Decode16" 95167802Sjkim}; 96167802Sjkim 97167802Sjkimconst char *AcpiGbl_LlDecode[] = 98167802Sjkim{ 99167802Sjkim "ActiveHigh", 100281075Sdim "ActiveLow", 101281075Sdim "ActiveBoth", 102281075Sdim "Reserved" 103167802Sjkim}; 104167802Sjkim 105167802Sjkimconst char *AcpiGbl_MaxDecode[] = 106167802Sjkim{ 107167802Sjkim "MaxNotFixed", 108167802Sjkim "MaxFixed" 109167802Sjkim}; 110167802Sjkim 111167802Sjkimconst char *AcpiGbl_MemDecode[] = 112167802Sjkim{ 113167802Sjkim "NonCacheable", 114167802Sjkim "Cacheable", 115167802Sjkim "WriteCombining", 116167802Sjkim "Prefetchable" 117167802Sjkim}; 118167802Sjkim 119167802Sjkimconst char *AcpiGbl_MinDecode[] = 120167802Sjkim{ 121167802Sjkim "MinNotFixed", 122167802Sjkim "MinFixed" 123167802Sjkim}; 124167802Sjkim 125167802Sjkimconst char *AcpiGbl_MtpDecode[] = 126167802Sjkim{ 127167802Sjkim "AddressRangeMemory", 128167802Sjkim "AddressRangeReserved", 129167802Sjkim "AddressRangeACPI", 130167802Sjkim "AddressRangeNVS" 131167802Sjkim}; 132167802Sjkim 133167802Sjkimconst char *AcpiGbl_RngDecode[] = 134167802Sjkim{ 135167802Sjkim "InvalidRanges", 136167802Sjkim "NonISAOnlyRanges", 137167802Sjkim "ISAOnlyRanges", 138167802Sjkim "EntireRange" 139167802Sjkim}; 140167802Sjkim 141167802Sjkimconst char *AcpiGbl_RwDecode[] = 142167802Sjkim{ 143167802Sjkim "ReadOnly", 144167802Sjkim "ReadWrite" 145167802Sjkim}; 146167802Sjkim 147167802Sjkimconst char *AcpiGbl_ShrDecode[] = 148167802Sjkim{ 149167802Sjkim "Exclusive", 150243347Sjkim "Shared", 151243347Sjkim "ExclusiveAndWake", /* ACPI 5.0 */ 152243347Sjkim "SharedAndWake" /* ACPI 5.0 */ 153167802Sjkim}; 154167802Sjkim 155167802Sjkimconst char *AcpiGbl_SizDecode[] = 156167802Sjkim{ 157167802Sjkim "Transfer8", 158167802Sjkim "Transfer8_16", 159167802Sjkim "Transfer16", 160167802Sjkim "InvalidSize" 161167802Sjkim}; 162167802Sjkim 163167802Sjkimconst char *AcpiGbl_TrsDecode[] = 164167802Sjkim{ 165167802Sjkim "DenseTranslation", 166167802Sjkim "SparseTranslation" 167167802Sjkim}; 168167802Sjkim 169167802Sjkimconst char *AcpiGbl_TtpDecode[] = 170167802Sjkim{ 171167802Sjkim "TypeStatic", 172167802Sjkim "TypeTranslation" 173167802Sjkim}; 174167802Sjkim 175167802Sjkimconst char *AcpiGbl_TypDecode[] = 176167802Sjkim{ 177167802Sjkim "Compatibility", 178167802Sjkim "TypeA", 179167802Sjkim "TypeB", 180167802Sjkim "TypeF" 181167802Sjkim}; 182167802Sjkim 183228110Sjkimconst char *AcpiGbl_PpcDecode[] = 184228110Sjkim{ 185228110Sjkim "PullDefault", 186228110Sjkim "PullUp", 187228110Sjkim "PullDown", 188228110Sjkim "PullNone" 189228110Sjkim}; 190228110Sjkim 191228110Sjkimconst char *AcpiGbl_IorDecode[] = 192228110Sjkim{ 193228110Sjkim "IoRestrictionNone", 194228110Sjkim "IoRestrictionInputOnly", 195228110Sjkim "IoRestrictionOutputOnly", 196228110Sjkim "IoRestrictionNoneAndPreserve" 197228110Sjkim}; 198228110Sjkim 199228110Sjkimconst char *AcpiGbl_DtsDecode[] = 200228110Sjkim{ 201228110Sjkim "Width8bit", 202228110Sjkim "Width16bit", 203228110Sjkim "Width32bit", 204228110Sjkim "Width64bit", 205228110Sjkim "Width128bit", 206228110Sjkim "Width256bit", 207228110Sjkim}; 208228110Sjkim 209228110Sjkim/* GPIO connection type */ 210228110Sjkim 211228110Sjkimconst char *AcpiGbl_CtDecode[] = 212228110Sjkim{ 213228110Sjkim "Interrupt", 214228110Sjkim "I/O" 215228110Sjkim}; 216228110Sjkim 217228110Sjkim/* Serial bus type */ 218228110Sjkim 219228110Sjkimconst char *AcpiGbl_SbtDecode[] = 220228110Sjkim{ 221228110Sjkim "/* UNKNOWN serial bus type */", 222228110Sjkim "I2C", 223228110Sjkim "SPI", 224228110Sjkim "UART" 225228110Sjkim}; 226228110Sjkim 227228110Sjkim/* I2C serial bus access mode */ 228228110Sjkim 229228110Sjkimconst char *AcpiGbl_AmDecode[] = 230228110Sjkim{ 231228110Sjkim "AddressingMode7Bit", 232228110Sjkim "AddressingMode10Bit" 233228110Sjkim}; 234228110Sjkim 235228110Sjkim/* I2C serial bus slave mode */ 236228110Sjkim 237228110Sjkimconst char *AcpiGbl_SmDecode[] = 238228110Sjkim{ 239228110Sjkim "ControllerInitiated", 240228110Sjkim "DeviceInitiated" 241228110Sjkim}; 242228110Sjkim 243228110Sjkim/* SPI serial bus wire mode */ 244228110Sjkim 245228110Sjkimconst char *AcpiGbl_WmDecode[] = 246228110Sjkim{ 247228110Sjkim "FourWireMode", 248228110Sjkim "ThreeWireMode" 249228110Sjkim}; 250228110Sjkim 251228110Sjkim/* SPI serial clock phase */ 252228110Sjkim 253228110Sjkimconst char *AcpiGbl_CphDecode[] = 254228110Sjkim{ 255228110Sjkim "ClockPhaseFirst", 256228110Sjkim "ClockPhaseSecond" 257228110Sjkim}; 258228110Sjkim 259228110Sjkim/* SPI serial bus clock polarity */ 260228110Sjkim 261228110Sjkimconst char *AcpiGbl_CpoDecode[] = 262228110Sjkim{ 263228110Sjkim "ClockPolarityLow", 264228110Sjkim "ClockPolarityHigh" 265228110Sjkim}; 266228110Sjkim 267228110Sjkim/* SPI serial bus device polarity */ 268228110Sjkim 269228110Sjkimconst char *AcpiGbl_DpDecode[] = 270228110Sjkim{ 271228110Sjkim "PolarityLow", 272228110Sjkim "PolarityHigh" 273228110Sjkim}; 274228110Sjkim 275228110Sjkim/* UART serial bus endian */ 276228110Sjkim 277228110Sjkimconst char *AcpiGbl_EdDecode[] = 278228110Sjkim{ 279228110Sjkim "LittleEndian", 280228110Sjkim "BigEndian" 281228110Sjkim}; 282228110Sjkim 283228110Sjkim/* UART serial bus bits per byte */ 284228110Sjkim 285228110Sjkimconst char *AcpiGbl_BpbDecode[] = 286228110Sjkim{ 287228110Sjkim "DataBitsFive", 288228110Sjkim "DataBitsSix", 289228110Sjkim "DataBitsSeven", 290228110Sjkim "DataBitsEight", 291228110Sjkim "DataBitsNine", 292228110Sjkim "/* UNKNOWN Bits per byte */", 293228110Sjkim "/* UNKNOWN Bits per byte */", 294228110Sjkim "/* UNKNOWN Bits per byte */" 295228110Sjkim}; 296228110Sjkim 297228110Sjkim/* UART serial bus stop bits */ 298228110Sjkim 299228110Sjkimconst char *AcpiGbl_SbDecode[] = 300228110Sjkim{ 301281075Sdim "StopBitsZero", 302228110Sjkim "StopBitsOne", 303228110Sjkim "StopBitsOnePlusHalf", 304228110Sjkim "StopBitsTwo" 305228110Sjkim}; 306228110Sjkim 307228110Sjkim/* UART serial bus flow control */ 308228110Sjkim 309228110Sjkimconst char *AcpiGbl_FcDecode[] = 310228110Sjkim{ 311228110Sjkim "FlowControlNone", 312228110Sjkim "FlowControlHardware", 313228110Sjkim "FlowControlXON", 314228110Sjkim "/* UNKNOWN flow control keyword */" 315228110Sjkim}; 316228110Sjkim 317228110Sjkim/* UART serial bus parity type */ 318228110Sjkim 319228110Sjkimconst char *AcpiGbl_PtDecode[] = 320228110Sjkim{ 321228110Sjkim "ParityTypeNone", 322228110Sjkim "ParityTypeEven", 323228110Sjkim "ParityTypeOdd", 324228110Sjkim "ParityTypeMark", 325228110Sjkim "ParityTypeSpace", 326228110Sjkim "/* UNKNOWN parity keyword */", 327228110Sjkim "/* UNKNOWN parity keyword */", 328228110Sjkim "/* UNKNOWN parity keyword */" 329228110Sjkim}; 330228110Sjkim 331167802Sjkim#endif 332167802Sjkim 333167802Sjkim 334167802Sjkim/* 335167802Sjkim * Base sizes of the raw AML resource descriptors, indexed by resource type. 336167802Sjkim * Zero indicates a reserved (and therefore invalid) resource type. 337167802Sjkim */ 338167802Sjkimconst UINT8 AcpiGbl_ResourceAmlSizes[] = 339167802Sjkim{ 340167802Sjkim /* Small descriptors */ 341167802Sjkim 342167802Sjkim 0, 343167802Sjkim 0, 344167802Sjkim 0, 345167802Sjkim 0, 346167802Sjkim ACPI_AML_SIZE_SMALL (AML_RESOURCE_IRQ), 347167802Sjkim ACPI_AML_SIZE_SMALL (AML_RESOURCE_DMA), 348167802Sjkim ACPI_AML_SIZE_SMALL (AML_RESOURCE_START_DEPENDENT), 349167802Sjkim ACPI_AML_SIZE_SMALL (AML_RESOURCE_END_DEPENDENT), 350167802Sjkim ACPI_AML_SIZE_SMALL (AML_RESOURCE_IO), 351167802Sjkim ACPI_AML_SIZE_SMALL (AML_RESOURCE_FIXED_IO), 352228110Sjkim ACPI_AML_SIZE_SMALL (AML_RESOURCE_FIXED_DMA), 353167802Sjkim 0, 354167802Sjkim 0, 355167802Sjkim 0, 356167802Sjkim ACPI_AML_SIZE_SMALL (AML_RESOURCE_VENDOR_SMALL), 357167802Sjkim ACPI_AML_SIZE_SMALL (AML_RESOURCE_END_TAG), 358167802Sjkim 359167802Sjkim /* Large descriptors */ 360167802Sjkim 361167802Sjkim 0, 362167802Sjkim ACPI_AML_SIZE_LARGE (AML_RESOURCE_MEMORY24), 363167802Sjkim ACPI_AML_SIZE_LARGE (AML_RESOURCE_GENERIC_REGISTER), 364167802Sjkim 0, 365167802Sjkim ACPI_AML_SIZE_LARGE (AML_RESOURCE_VENDOR_LARGE), 366167802Sjkim ACPI_AML_SIZE_LARGE (AML_RESOURCE_MEMORY32), 367167802Sjkim ACPI_AML_SIZE_LARGE (AML_RESOURCE_FIXED_MEMORY32), 368167802Sjkim ACPI_AML_SIZE_LARGE (AML_RESOURCE_ADDRESS32), 369167802Sjkim ACPI_AML_SIZE_LARGE (AML_RESOURCE_ADDRESS16), 370167802Sjkim ACPI_AML_SIZE_LARGE (AML_RESOURCE_EXTENDED_IRQ), 371167802Sjkim ACPI_AML_SIZE_LARGE (AML_RESOURCE_ADDRESS64), 372228110Sjkim ACPI_AML_SIZE_LARGE (AML_RESOURCE_EXTENDED_ADDRESS64), 373228110Sjkim ACPI_AML_SIZE_LARGE (AML_RESOURCE_GPIO), 374228110Sjkim 0, 375228110Sjkim ACPI_AML_SIZE_LARGE (AML_RESOURCE_COMMON_SERIALBUS), 376167802Sjkim}; 377167802Sjkim 378228110Sjkimconst UINT8 AcpiGbl_ResourceAmlSerialBusSizes[] = 379228110Sjkim{ 380228110Sjkim 0, 381228110Sjkim ACPI_AML_SIZE_LARGE (AML_RESOURCE_I2C_SERIALBUS), 382228110Sjkim ACPI_AML_SIZE_LARGE (AML_RESOURCE_SPI_SERIALBUS), 383228110Sjkim ACPI_AML_SIZE_LARGE (AML_RESOURCE_UART_SERIALBUS), 384228110Sjkim}; 385167802Sjkim 386228110Sjkim 387167802Sjkim/* 388167802Sjkim * Resource types, used to validate the resource length field. 389167802Sjkim * The length of fixed-length types must match exactly, variable 390167802Sjkim * lengths must meet the minimum required length, etc. 391167802Sjkim * Zero indicates a reserved (and therefore invalid) resource type. 392167802Sjkim */ 393167802Sjkimstatic const UINT8 AcpiGbl_ResourceTypes[] = 394167802Sjkim{ 395167802Sjkim /* Small descriptors */ 396167802Sjkim 397167802Sjkim 0, 398167802Sjkim 0, 399167802Sjkim 0, 400167802Sjkim 0, 401228110Sjkim ACPI_SMALL_VARIABLE_LENGTH, /* 04 IRQ */ 402228110Sjkim ACPI_FIXED_LENGTH, /* 05 DMA */ 403228110Sjkim ACPI_SMALL_VARIABLE_LENGTH, /* 06 StartDependentFunctions */ 404228110Sjkim ACPI_FIXED_LENGTH, /* 07 EndDependentFunctions */ 405228110Sjkim ACPI_FIXED_LENGTH, /* 08 IO */ 406228110Sjkim ACPI_FIXED_LENGTH, /* 09 FixedIO */ 407228110Sjkim ACPI_FIXED_LENGTH, /* 0A FixedDMA */ 408167802Sjkim 0, 409167802Sjkim 0, 410167802Sjkim 0, 411228110Sjkim ACPI_VARIABLE_LENGTH, /* 0E VendorShort */ 412228110Sjkim ACPI_FIXED_LENGTH, /* 0F EndTag */ 413167802Sjkim 414167802Sjkim /* Large descriptors */ 415167802Sjkim 416167802Sjkim 0, 417228110Sjkim ACPI_FIXED_LENGTH, /* 01 Memory24 */ 418228110Sjkim ACPI_FIXED_LENGTH, /* 02 GenericRegister */ 419167802Sjkim 0, 420228110Sjkim ACPI_VARIABLE_LENGTH, /* 04 VendorLong */ 421228110Sjkim ACPI_FIXED_LENGTH, /* 05 Memory32 */ 422228110Sjkim ACPI_FIXED_LENGTH, /* 06 Memory32Fixed */ 423228110Sjkim ACPI_VARIABLE_LENGTH, /* 07 Dword* address */ 424228110Sjkim ACPI_VARIABLE_LENGTH, /* 08 Word* address */ 425228110Sjkim ACPI_VARIABLE_LENGTH, /* 09 ExtendedIRQ */ 426228110Sjkim ACPI_VARIABLE_LENGTH, /* 0A Qword* address */ 427228110Sjkim ACPI_FIXED_LENGTH, /* 0B Extended* address */ 428228110Sjkim ACPI_VARIABLE_LENGTH, /* 0C Gpio* */ 429228110Sjkim 0, 430228110Sjkim ACPI_VARIABLE_LENGTH /* 0E *SerialBus */ 431167802Sjkim}; 432167802Sjkim 433167802Sjkim 434167802Sjkim/******************************************************************************* 435167802Sjkim * 436167802Sjkim * FUNCTION: AcpiUtWalkAmlResources 437167802Sjkim * 438243347Sjkim * PARAMETERS: WalkState - Current walk info 439243347Sjkim * PARAMETERS: Aml - Pointer to the raw AML resource template 440243347Sjkim * AmlLength - Length of the entire template 441243347Sjkim * UserFunction - Called once for each descriptor found. If 442243347Sjkim * NULL, a pointer to the EndTag is returned 443243347Sjkim * Context - Passed to UserFunction 444167802Sjkim * 445167802Sjkim * RETURN: Status 446167802Sjkim * 447167802Sjkim * DESCRIPTION: Walk a raw AML resource list(buffer). User function called 448167802Sjkim * once for each resource found. 449167802Sjkim * 450167802Sjkim ******************************************************************************/ 451167802Sjkim 452167802SjkimACPI_STATUS 453167802SjkimAcpiUtWalkAmlResources ( 454243347Sjkim ACPI_WALK_STATE *WalkState, 455167802Sjkim UINT8 *Aml, 456167802Sjkim ACPI_SIZE AmlLength, 457167802Sjkim ACPI_WALK_AML_CALLBACK UserFunction, 458245582Sjkim void **Context) 459167802Sjkim{ 460167802Sjkim ACPI_STATUS Status; 461167802Sjkim UINT8 *EndAml; 462167802Sjkim UINT8 ResourceIndex; 463167802Sjkim UINT32 Length; 464167802Sjkim UINT32 Offset = 0; 465228110Sjkim UINT8 EndTag[2] = {0x79, 0x00}; 466167802Sjkim 467167802Sjkim 468167802Sjkim ACPI_FUNCTION_TRACE (UtWalkAmlResources); 469167802Sjkim 470167802Sjkim 471167802Sjkim /* The absolute minimum resource template is one EndTag descriptor */ 472167802Sjkim 473167802Sjkim if (AmlLength < sizeof (AML_RESOURCE_END_TAG)) 474167802Sjkim { 475167802Sjkim return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG); 476167802Sjkim } 477167802Sjkim 478167802Sjkim /* Point to the end of the resource template buffer */ 479167802Sjkim 480167802Sjkim EndAml = Aml + AmlLength; 481167802Sjkim 482167802Sjkim /* Walk the byte list, abort on any invalid descriptor type or length */ 483167802Sjkim 484167802Sjkim while (Aml < EndAml) 485167802Sjkim { 486167802Sjkim /* Validate the Resource Type and Resource Length */ 487167802Sjkim 488243347Sjkim Status = AcpiUtValidateResource (WalkState, Aml, &ResourceIndex); 489167802Sjkim if (ACPI_FAILURE (Status)) 490167802Sjkim { 491228110Sjkim /* 492306536Sjkim * Exit on failure. Cannot continue because the descriptor 493306536Sjkim * length may be bogus also. 494228110Sjkim */ 495167802Sjkim return_ACPI_STATUS (Status); 496167802Sjkim } 497167802Sjkim 498167802Sjkim /* Get the length of this descriptor */ 499167802Sjkim 500167802Sjkim Length = AcpiUtGetDescriptorLength (Aml); 501167802Sjkim 502167802Sjkim /* Invoke the user function */ 503167802Sjkim 504167802Sjkim if (UserFunction) 505167802Sjkim { 506306536Sjkim Status = UserFunction ( 507306536Sjkim Aml, Length, Offset, ResourceIndex, Context); 508167802Sjkim if (ACPI_FAILURE (Status)) 509167802Sjkim { 510228110Sjkim return_ACPI_STATUS (Status); 511167802Sjkim } 512167802Sjkim } 513167802Sjkim 514167802Sjkim /* An EndTag descriptor terminates this resource template */ 515167802Sjkim 516167802Sjkim if (AcpiUtGetResourceType (Aml) == ACPI_RESOURCE_NAME_END_TAG) 517167802Sjkim { 518167802Sjkim /* 519167802Sjkim * There must be at least one more byte in the buffer for 520167802Sjkim * the 2nd byte of the EndTag 521167802Sjkim */ 522167802Sjkim if ((Aml + 1) >= EndAml) 523167802Sjkim { 524167802Sjkim return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG); 525167802Sjkim } 526167802Sjkim 527167802Sjkim /* Return the pointer to the EndTag if requested */ 528167802Sjkim 529167802Sjkim if (!UserFunction) 530167802Sjkim { 531245582Sjkim *Context = Aml; 532167802Sjkim } 533167802Sjkim 534167802Sjkim /* Normal exit */ 535167802Sjkim 536167802Sjkim return_ACPI_STATUS (AE_OK); 537167802Sjkim } 538167802Sjkim 539167802Sjkim Aml += Length; 540167802Sjkim Offset += Length; 541167802Sjkim } 542167802Sjkim 543167802Sjkim /* Did not find an EndTag descriptor */ 544167802Sjkim 545228110Sjkim if (UserFunction) 546228110Sjkim { 547228110Sjkim /* Insert an EndTag anyway. AcpiRsGetListLength always leaves room */ 548228110Sjkim 549243347Sjkim (void) AcpiUtValidateResource (WalkState, EndTag, &ResourceIndex); 550228110Sjkim Status = UserFunction (EndTag, 2, Offset, ResourceIndex, Context); 551228110Sjkim if (ACPI_FAILURE (Status)) 552228110Sjkim { 553228110Sjkim return_ACPI_STATUS (Status); 554228110Sjkim } 555228110Sjkim } 556228110Sjkim 557228110Sjkim return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG); 558167802Sjkim} 559167802Sjkim 560167802Sjkim 561167802Sjkim/******************************************************************************* 562167802Sjkim * 563167802Sjkim * FUNCTION: AcpiUtValidateResource 564167802Sjkim * 565243347Sjkim * PARAMETERS: WalkState - Current walk info 566243347Sjkim * Aml - Pointer to the raw AML resource descriptor 567243347Sjkim * ReturnIndex - Where the resource index is returned. NULL 568243347Sjkim * if the index is not required. 569167802Sjkim * 570167802Sjkim * RETURN: Status, and optionally the Index into the global resource tables 571167802Sjkim * 572167802Sjkim * DESCRIPTION: Validate an AML resource descriptor by checking the Resource 573167802Sjkim * Type and Resource Length. Returns an index into the global 574167802Sjkim * resource information/dispatch tables for later use. 575167802Sjkim * 576167802Sjkim ******************************************************************************/ 577167802Sjkim 578167802SjkimACPI_STATUS 579167802SjkimAcpiUtValidateResource ( 580243347Sjkim ACPI_WALK_STATE *WalkState, 581167802Sjkim void *Aml, 582167802Sjkim UINT8 *ReturnIndex) 583167802Sjkim{ 584228110Sjkim AML_RESOURCE *AmlResource; 585167802Sjkim UINT8 ResourceType; 586167802Sjkim UINT8 ResourceIndex; 587167802Sjkim ACPI_RS_LENGTH ResourceLength; 588167802Sjkim ACPI_RS_LENGTH MinimumResourceLength; 589167802Sjkim 590167802Sjkim 591167802Sjkim ACPI_FUNCTION_ENTRY (); 592167802Sjkim 593167802Sjkim 594167802Sjkim /* 595167802Sjkim * 1) Validate the ResourceType field (Byte 0) 596167802Sjkim */ 597167802Sjkim ResourceType = ACPI_GET8 (Aml); 598167802Sjkim 599167802Sjkim /* 600167802Sjkim * Byte 0 contains the descriptor name (Resource Type) 601167802Sjkim * Examine the large/small bit in the resource header 602167802Sjkim */ 603167802Sjkim if (ResourceType & ACPI_RESOURCE_NAME_LARGE) 604167802Sjkim { 605167802Sjkim /* Verify the large resource type (name) against the max */ 606167802Sjkim 607167802Sjkim if (ResourceType > ACPI_RESOURCE_NAME_LARGE_MAX) 608167802Sjkim { 609228110Sjkim goto InvalidResource; 610167802Sjkim } 611167802Sjkim 612167802Sjkim /* 613167802Sjkim * Large Resource Type -- bits 6:0 contain the name 614167802Sjkim * Translate range 0x80-0x8B to index range 0x10-0x1B 615167802Sjkim */ 616167802Sjkim ResourceIndex = (UINT8) (ResourceType - 0x70); 617167802Sjkim } 618167802Sjkim else 619167802Sjkim { 620167802Sjkim /* 621167802Sjkim * Small Resource Type -- bits 6:3 contain the name 622167802Sjkim * Shift range to index range 0x00-0x0F 623167802Sjkim */ 624167802Sjkim ResourceIndex = (UINT8) 625167802Sjkim ((ResourceType & ACPI_RESOURCE_NAME_SMALL_MASK) >> 3); 626167802Sjkim } 627167802Sjkim 628228110Sjkim /* 629306536Sjkim * Check validity of the resource type, via AcpiGbl_ResourceTypes. 630306536Sjkim * Zero indicates an invalid resource. 631228110Sjkim */ 632167802Sjkim if (!AcpiGbl_ResourceTypes[ResourceIndex]) 633167802Sjkim { 634228110Sjkim goto InvalidResource; 635167802Sjkim } 636167802Sjkim 637167802Sjkim /* 638228110Sjkim * Validate the ResourceLength field. This ensures that the length 639228110Sjkim * is at least reasonable, and guarantees that it is non-zero. 640167802Sjkim */ 641167802Sjkim ResourceLength = AcpiUtGetResourceLength (Aml); 642167802Sjkim MinimumResourceLength = AcpiGbl_ResourceAmlSizes[ResourceIndex]; 643167802Sjkim 644167802Sjkim /* Validate based upon the type of resource - fixed length or variable */ 645167802Sjkim 646167802Sjkim switch (AcpiGbl_ResourceTypes[ResourceIndex]) 647167802Sjkim { 648167802Sjkim case ACPI_FIXED_LENGTH: 649167802Sjkim 650167802Sjkim /* Fixed length resource, length must match exactly */ 651167802Sjkim 652167802Sjkim if (ResourceLength != MinimumResourceLength) 653167802Sjkim { 654228110Sjkim goto BadResourceLength; 655167802Sjkim } 656167802Sjkim break; 657167802Sjkim 658167802Sjkim case ACPI_VARIABLE_LENGTH: 659167802Sjkim 660167802Sjkim /* Variable length resource, length must be at least the minimum */ 661167802Sjkim 662167802Sjkim if (ResourceLength < MinimumResourceLength) 663167802Sjkim { 664228110Sjkim goto BadResourceLength; 665167802Sjkim } 666167802Sjkim break; 667167802Sjkim 668167802Sjkim case ACPI_SMALL_VARIABLE_LENGTH: 669167802Sjkim 670167802Sjkim /* Small variable length resource, length can be (Min) or (Min-1) */ 671167802Sjkim 672167802Sjkim if ((ResourceLength > MinimumResourceLength) || 673167802Sjkim (ResourceLength < (MinimumResourceLength - 1))) 674167802Sjkim { 675228110Sjkim goto BadResourceLength; 676167802Sjkim } 677167802Sjkim break; 678167802Sjkim 679167802Sjkim default: 680167802Sjkim 681167802Sjkim /* Shouldn't happen (because of validation earlier), but be sure */ 682167802Sjkim 683228110Sjkim goto InvalidResource; 684167802Sjkim } 685167802Sjkim 686228110Sjkim AmlResource = ACPI_CAST_PTR (AML_RESOURCE, Aml); 687228110Sjkim if (ResourceType == ACPI_RESOURCE_NAME_SERIAL_BUS) 688228110Sjkim { 689228110Sjkim /* Validate the BusType field */ 690228110Sjkim 691228110Sjkim if ((AmlResource->CommonSerialBus.Type == 0) || 692228110Sjkim (AmlResource->CommonSerialBus.Type > AML_RESOURCE_MAX_SERIALBUSTYPE)) 693228110Sjkim { 694243347Sjkim if (WalkState) 695243347Sjkim { 696243347Sjkim ACPI_ERROR ((AE_INFO, 697243347Sjkim "Invalid/unsupported SerialBus resource descriptor: BusType 0x%2.2X", 698243347Sjkim AmlResource->CommonSerialBus.Type)); 699243347Sjkim } 700228110Sjkim return (AE_AML_INVALID_RESOURCE_TYPE); 701228110Sjkim } 702228110Sjkim } 703228110Sjkim 704167802Sjkim /* Optionally return the resource table index */ 705167802Sjkim 706167802Sjkim if (ReturnIndex) 707167802Sjkim { 708167802Sjkim *ReturnIndex = ResourceIndex; 709167802Sjkim } 710167802Sjkim 711167802Sjkim return (AE_OK); 712228110Sjkim 713228110Sjkim 714228110SjkimInvalidResource: 715228110Sjkim 716243347Sjkim if (WalkState) 717243347Sjkim { 718243347Sjkim ACPI_ERROR ((AE_INFO, 719243347Sjkim "Invalid/unsupported resource descriptor: Type 0x%2.2X", 720243347Sjkim ResourceType)); 721243347Sjkim } 722228110Sjkim return (AE_AML_INVALID_RESOURCE_TYPE); 723228110Sjkim 724228110SjkimBadResourceLength: 725228110Sjkim 726243347Sjkim if (WalkState) 727243347Sjkim { 728243347Sjkim ACPI_ERROR ((AE_INFO, 729243347Sjkim "Invalid resource descriptor length: Type " 730243347Sjkim "0x%2.2X, Length 0x%4.4X, MinLength 0x%4.4X", 731243347Sjkim ResourceType, ResourceLength, MinimumResourceLength)); 732243347Sjkim } 733228110Sjkim return (AE_AML_BAD_RESOURCE_LENGTH); 734167802Sjkim} 735167802Sjkim 736167802Sjkim 737167802Sjkim/******************************************************************************* 738167802Sjkim * 739167802Sjkim * FUNCTION: AcpiUtGetResourceType 740167802Sjkim * 741167802Sjkim * PARAMETERS: Aml - Pointer to the raw AML resource descriptor 742167802Sjkim * 743167802Sjkim * RETURN: The Resource Type with no extraneous bits (except the 744167802Sjkim * Large/Small descriptor bit -- this is left alone) 745167802Sjkim * 746167802Sjkim * DESCRIPTION: Extract the Resource Type/Name from the first byte of 747167802Sjkim * a resource descriptor. 748167802Sjkim * 749167802Sjkim ******************************************************************************/ 750167802Sjkim 751167802SjkimUINT8 752167802SjkimAcpiUtGetResourceType ( 753167802Sjkim void *Aml) 754167802Sjkim{ 755167802Sjkim ACPI_FUNCTION_ENTRY (); 756167802Sjkim 757167802Sjkim 758167802Sjkim /* 759167802Sjkim * Byte 0 contains the descriptor name (Resource Type) 760167802Sjkim * Examine the large/small bit in the resource header 761167802Sjkim */ 762167802Sjkim if (ACPI_GET8 (Aml) & ACPI_RESOURCE_NAME_LARGE) 763167802Sjkim { 764167802Sjkim /* Large Resource Type -- bits 6:0 contain the name */ 765167802Sjkim 766167802Sjkim return (ACPI_GET8 (Aml)); 767167802Sjkim } 768167802Sjkim else 769167802Sjkim { 770167802Sjkim /* Small Resource Type -- bits 6:3 contain the name */ 771167802Sjkim 772167802Sjkim return ((UINT8) (ACPI_GET8 (Aml) & ACPI_RESOURCE_NAME_SMALL_MASK)); 773167802Sjkim } 774167802Sjkim} 775167802Sjkim 776167802Sjkim 777167802Sjkim/******************************************************************************* 778167802Sjkim * 779167802Sjkim * FUNCTION: AcpiUtGetResourceLength 780167802Sjkim * 781167802Sjkim * PARAMETERS: Aml - Pointer to the raw AML resource descriptor 782167802Sjkim * 783167802Sjkim * RETURN: Byte Length 784167802Sjkim * 785167802Sjkim * DESCRIPTION: Get the "Resource Length" of a raw AML descriptor. By 786167802Sjkim * definition, this does not include the size of the descriptor 787167802Sjkim * header or the length field itself. 788167802Sjkim * 789167802Sjkim ******************************************************************************/ 790167802Sjkim 791167802SjkimUINT16 792167802SjkimAcpiUtGetResourceLength ( 793167802Sjkim void *Aml) 794167802Sjkim{ 795167802Sjkim ACPI_RS_LENGTH ResourceLength; 796167802Sjkim 797167802Sjkim 798167802Sjkim ACPI_FUNCTION_ENTRY (); 799167802Sjkim 800167802Sjkim 801167802Sjkim /* 802167802Sjkim * Byte 0 contains the descriptor name (Resource Type) 803167802Sjkim * Examine the large/small bit in the resource header 804167802Sjkim */ 805167802Sjkim if (ACPI_GET8 (Aml) & ACPI_RESOURCE_NAME_LARGE) 806167802Sjkim { 807167802Sjkim /* Large Resource type -- bytes 1-2 contain the 16-bit length */ 808167802Sjkim 809167802Sjkim ACPI_MOVE_16_TO_16 (&ResourceLength, ACPI_ADD_PTR (UINT8, Aml, 1)); 810167802Sjkim 811167802Sjkim } 812167802Sjkim else 813167802Sjkim { 814167802Sjkim /* Small Resource type -- bits 2:0 of byte 0 contain the length */ 815167802Sjkim 816167802Sjkim ResourceLength = (UINT16) (ACPI_GET8 (Aml) & 817306536Sjkim ACPI_RESOURCE_NAME_SMALL_LENGTH_MASK); 818167802Sjkim } 819167802Sjkim 820167802Sjkim return (ResourceLength); 821167802Sjkim} 822167802Sjkim 823167802Sjkim 824167802Sjkim/******************************************************************************* 825167802Sjkim * 826167802Sjkim * FUNCTION: AcpiUtGetResourceHeaderLength 827167802Sjkim * 828167802Sjkim * PARAMETERS: Aml - Pointer to the raw AML resource descriptor 829167802Sjkim * 830167802Sjkim * RETURN: Length of the AML header (depends on large/small descriptor) 831167802Sjkim * 832167802Sjkim * DESCRIPTION: Get the length of the header for this resource. 833167802Sjkim * 834167802Sjkim ******************************************************************************/ 835167802Sjkim 836167802SjkimUINT8 837167802SjkimAcpiUtGetResourceHeaderLength ( 838167802Sjkim void *Aml) 839167802Sjkim{ 840167802Sjkim ACPI_FUNCTION_ENTRY (); 841167802Sjkim 842167802Sjkim 843167802Sjkim /* Examine the large/small bit in the resource header */ 844167802Sjkim 845167802Sjkim if (ACPI_GET8 (Aml) & ACPI_RESOURCE_NAME_LARGE) 846167802Sjkim { 847167802Sjkim return (sizeof (AML_RESOURCE_LARGE_HEADER)); 848167802Sjkim } 849167802Sjkim else 850167802Sjkim { 851167802Sjkim return (sizeof (AML_RESOURCE_SMALL_HEADER)); 852167802Sjkim } 853167802Sjkim} 854167802Sjkim 855167802Sjkim 856167802Sjkim/******************************************************************************* 857167802Sjkim * 858167802Sjkim * FUNCTION: AcpiUtGetDescriptorLength 859167802Sjkim * 860167802Sjkim * PARAMETERS: Aml - Pointer to the raw AML resource descriptor 861167802Sjkim * 862167802Sjkim * RETURN: Byte length 863167802Sjkim * 864167802Sjkim * DESCRIPTION: Get the total byte length of a raw AML descriptor, including the 865167802Sjkim * length of the descriptor header and the length field itself. 866167802Sjkim * Used to walk descriptor lists. 867167802Sjkim * 868167802Sjkim ******************************************************************************/ 869167802Sjkim 870167802SjkimUINT32 871167802SjkimAcpiUtGetDescriptorLength ( 872167802Sjkim void *Aml) 873167802Sjkim{ 874167802Sjkim ACPI_FUNCTION_ENTRY (); 875167802Sjkim 876167802Sjkim 877167802Sjkim /* 878167802Sjkim * Get the Resource Length (does not include header length) and add 879167802Sjkim * the header length (depends on if this is a small or large resource) 880167802Sjkim */ 881167802Sjkim return (AcpiUtGetResourceLength (Aml) + 882306536Sjkim AcpiUtGetResourceHeaderLength (Aml)); 883167802Sjkim} 884167802Sjkim 885167802Sjkim 886167802Sjkim/******************************************************************************* 887167802Sjkim * 888167802Sjkim * FUNCTION: AcpiUtGetResourceEndTag 889167802Sjkim * 890167802Sjkim * PARAMETERS: ObjDesc - The resource template buffer object 891167802Sjkim * EndTag - Where the pointer to the EndTag is returned 892167802Sjkim * 893167802Sjkim * RETURN: Status, pointer to the end tag 894167802Sjkim * 895167802Sjkim * DESCRIPTION: Find the EndTag resource descriptor in an AML resource template 896167802Sjkim * Note: allows a buffer length of zero. 897167802Sjkim * 898167802Sjkim ******************************************************************************/ 899167802Sjkim 900167802SjkimACPI_STATUS 901167802SjkimAcpiUtGetResourceEndTag ( 902167802Sjkim ACPI_OPERAND_OBJECT *ObjDesc, 903167802Sjkim UINT8 **EndTag) 904167802Sjkim{ 905167802Sjkim ACPI_STATUS Status; 906167802Sjkim 907167802Sjkim 908167802Sjkim ACPI_FUNCTION_TRACE (UtGetResourceEndTag); 909167802Sjkim 910167802Sjkim 911167802Sjkim /* Allow a buffer length of zero */ 912167802Sjkim 913167802Sjkim if (!ObjDesc->Buffer.Length) 914167802Sjkim { 915167802Sjkim *EndTag = ObjDesc->Buffer.Pointer; 916167802Sjkim return_ACPI_STATUS (AE_OK); 917167802Sjkim } 918167802Sjkim 919167802Sjkim /* Validate the template and get a pointer to the EndTag */ 920167802Sjkim 921243347Sjkim Status = AcpiUtWalkAmlResources (NULL, ObjDesc->Buffer.Pointer, 922306536Sjkim ObjDesc->Buffer.Length, NULL, (void **) EndTag); 923167802Sjkim 924167802Sjkim return_ACPI_STATUS (Status); 925167802Sjkim} 926