1118611Snjl/****************************************************************************** 2118611Snjl * 3207344Sjkim * Module Name: aslresource - Resource template/descriptor utilities 4118611Snjl * 5118611Snjl *****************************************************************************/ 6118611Snjl 7316303Sjkim/****************************************************************************** 8316303Sjkim * 9316303Sjkim * 1. Copyright Notice 10316303Sjkim * 11316303Sjkim * Some or all of this work - Copyright (c) 1999 - 2017, Intel Corp. 12118611Snjl * All rights reserved. 13118611Snjl * 14316303Sjkim * 2. License 15316303Sjkim * 16316303Sjkim * 2.1. This is your license from Intel Corp. under its intellectual property 17316303Sjkim * rights. You may have additional license terms from the party that provided 18316303Sjkim * you this software, covering your right to use that party's intellectual 19316303Sjkim * property rights. 20316303Sjkim * 21316303Sjkim * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 22316303Sjkim * copy of the source code appearing in this file ("Covered Code") an 23316303Sjkim * irrevocable, perpetual, worldwide license under Intel's copyrights in the 24316303Sjkim * base code distributed originally by Intel ("Original Intel Code") to copy, 25316303Sjkim * make derivatives, distribute, use and display any portion of the Covered 26316303Sjkim * Code in any form, with the right to sublicense such rights; and 27316303Sjkim * 28316303Sjkim * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 29316303Sjkim * license (with the right to sublicense), under only those claims of Intel 30316303Sjkim * patents that are infringed by the Original Intel Code, to make, use, sell, 31316303Sjkim * offer to sell, and import the Covered Code and derivative works thereof 32316303Sjkim * solely to the minimum extent necessary to exercise the above copyright 33316303Sjkim * license, and in no event shall the patent license extend to any additions 34316303Sjkim * to or modifications of the Original Intel Code. No other license or right 35316303Sjkim * is granted directly or by implication, estoppel or otherwise; 36316303Sjkim * 37316303Sjkim * The above copyright and patent license is granted only if the following 38316303Sjkim * conditions are met: 39316303Sjkim * 40316303Sjkim * 3. Conditions 41316303Sjkim * 42316303Sjkim * 3.1. Redistribution of Source with Rights to Further Distribute Source. 43316303Sjkim * Redistribution of source code of any substantial portion of the Covered 44316303Sjkim * Code or modification with rights to further distribute source must include 45316303Sjkim * the above Copyright Notice, the above License, this list of Conditions, 46316303Sjkim * and the following Disclaimer and Export Compliance provision. In addition, 47316303Sjkim * Licensee must cause all Covered Code to which Licensee contributes to 48316303Sjkim * contain a file documenting the changes Licensee made to create that Covered 49316303Sjkim * Code and the date of any change. Licensee must include in that file the 50316303Sjkim * documentation of any changes made by any predecessor Licensee. Licensee 51316303Sjkim * must include a prominent statement that the modification is derived, 52316303Sjkim * directly or indirectly, from Original Intel Code. 53316303Sjkim * 54316303Sjkim * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 55316303Sjkim * Redistribution of source code of any substantial portion of the Covered 56316303Sjkim * Code or modification without rights to further distribute source must 57316303Sjkim * include the following Disclaimer and Export Compliance provision in the 58316303Sjkim * documentation and/or other materials provided with distribution. In 59316303Sjkim * addition, Licensee may not authorize further sublicense of source of any 60316303Sjkim * portion of the Covered Code, and must include terms to the effect that the 61316303Sjkim * license from Licensee to its licensee is limited to the intellectual 62316303Sjkim * property embodied in the software Licensee provides to its licensee, and 63316303Sjkim * not to intellectual property embodied in modifications its licensee may 64316303Sjkim * make. 65316303Sjkim * 66316303Sjkim * 3.3. Redistribution of Executable. Redistribution in executable form of any 67316303Sjkim * substantial portion of the Covered Code or modification must reproduce the 68316303Sjkim * above Copyright Notice, and the following Disclaimer and Export Compliance 69316303Sjkim * provision in the documentation and/or other materials provided with the 70316303Sjkim * distribution. 71316303Sjkim * 72316303Sjkim * 3.4. Intel retains all right, title, and interest in and to the Original 73316303Sjkim * Intel Code. 74316303Sjkim * 75316303Sjkim * 3.5. Neither the name Intel nor any other trademark owned or controlled by 76316303Sjkim * Intel shall be used in advertising or otherwise to promote the sale, use or 77316303Sjkim * other dealings in products derived from or relating to the Covered Code 78316303Sjkim * without prior written authorization from Intel. 79316303Sjkim * 80316303Sjkim * 4. Disclaimer and Export Compliance 81316303Sjkim * 82316303Sjkim * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 83316303Sjkim * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 84316303Sjkim * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 85316303Sjkim * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 86316303Sjkim * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 87316303Sjkim * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 88316303Sjkim * PARTICULAR PURPOSE. 89316303Sjkim * 90316303Sjkim * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 91316303Sjkim * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 92316303Sjkim * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 93316303Sjkim * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 94316303Sjkim * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 95316303Sjkim * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 96316303Sjkim * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 97316303Sjkim * LIMITED REMEDY. 98316303Sjkim * 99316303Sjkim * 4.3. Licensee shall not export, either directly or indirectly, any of this 100316303Sjkim * software or system incorporating such software without first obtaining any 101316303Sjkim * required license or other approval from the U. S. Department of Commerce or 102316303Sjkim * any other agency or department of the United States Government. In the 103316303Sjkim * event Licensee exports any such software from the United States or 104316303Sjkim * re-exports any such software from a foreign destination, Licensee shall 105316303Sjkim * ensure that the distribution and export/re-export of the software is in 106316303Sjkim * compliance with all laws, regulations, orders, or other restrictions of the 107316303Sjkim * U.S. Export Administration Regulations. Licensee agrees that neither it nor 108316303Sjkim * any of its subsidiaries will export/re-export any technical data, process, 109316303Sjkim * software, or service, directly or indirectly, to any country for which the 110316303Sjkim * United States government or any agency thereof requires an export license, 111316303Sjkim * other governmental approval, or letter of assurance, without first obtaining 112316303Sjkim * such license, approval or letter. 113316303Sjkim * 114316303Sjkim ***************************************************************************** 115316303Sjkim * 116316303Sjkim * Alternatively, you may choose to be licensed under the terms of the 117316303Sjkim * following license: 118316303Sjkim * 119217365Sjkim * Redistribution and use in source and binary forms, with or without 120217365Sjkim * modification, are permitted provided that the following conditions 121217365Sjkim * are met: 122217365Sjkim * 1. Redistributions of source code must retain the above copyright 123217365Sjkim * notice, this list of conditions, and the following disclaimer, 124217365Sjkim * without modification. 125217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 126217365Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 127217365Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 128217365Sjkim * including a substantially similar Disclaimer requirement for further 129217365Sjkim * binary redistribution. 130217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 131217365Sjkim * of any contributors may be used to endorse or promote products derived 132217365Sjkim * from this software without specific prior written permission. 133118611Snjl * 134316303Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 135316303Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 136316303Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 137316303Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 138316303Sjkim * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 139316303Sjkim * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 140316303Sjkim * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 141316303Sjkim * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 142316303Sjkim * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 143316303Sjkim * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 144316303Sjkim * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 145316303Sjkim * 146316303Sjkim * Alternatively, you may choose to be licensed under the terms of the 147217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 148217365Sjkim * Software Foundation. 149118611Snjl * 150316303Sjkim *****************************************************************************/ 151118611Snjl 152151937Sjkim#include <contrib/dev/acpica/compiler/aslcompiler.h> 153118611Snjl#include "aslcompiler.y.h" 154193529Sjkim#include <contrib/dev/acpica/include/amlcode.h> 155118611Snjl 156118611Snjl 157118611Snjl#define _COMPONENT ACPI_COMPILER 158118611Snjl ACPI_MODULE_NAME ("aslresource") 159118611Snjl 160118611Snjl 161118611Snjl/******************************************************************************* 162118611Snjl * 163207344Sjkim * FUNCTION: RsSmallAddressCheck 164207344Sjkim * 165207344Sjkim * PARAMETERS: Minimum - Address Min value 166207344Sjkim * Maximum - Address Max value 167207344Sjkim * Length - Address range value 168207344Sjkim * Alignment - Address alignment value 169207344Sjkim * MinOp - Original Op for Address Min 170207344Sjkim * MaxOp - Original Op for Address Max 171207344Sjkim * LengthOp - Original Op for address range 172207344Sjkim * AlignOp - Original Op for address alignment. If 173207344Sjkim * NULL, means "zero value for alignment is 174207344Sjkim * OK, and means 64K alignment" (for 175207344Sjkim * Memory24 descriptor) 176213806Sjkim * Op - Parent Op for entire construct 177207344Sjkim * 178207344Sjkim * RETURN: None. Adds error messages to error log if necessary 179207344Sjkim * 180207344Sjkim * DESCRIPTION: Perform common value checks for "small" address descriptors. 181207344Sjkim * Currently: 182207344Sjkim * Io, Memory24, Memory32 183207344Sjkim * 184207344Sjkim ******************************************************************************/ 185207344Sjkim 186207344Sjkimvoid 187207344SjkimRsSmallAddressCheck ( 188207344Sjkim UINT8 Type, 189207344Sjkim UINT32 Minimum, 190207344Sjkim UINT32 Maximum, 191207344Sjkim UINT32 Length, 192207344Sjkim UINT32 Alignment, 193207344Sjkim ACPI_PARSE_OBJECT *MinOp, 194207344Sjkim ACPI_PARSE_OBJECT *MaxOp, 195207344Sjkim ACPI_PARSE_OBJECT *LengthOp, 196213806Sjkim ACPI_PARSE_OBJECT *AlignOp, 197213806Sjkim ACPI_PARSE_OBJECT *Op) 198207344Sjkim{ 199207344Sjkim 200207344Sjkim if (Gbl_NoResourceChecking) 201207344Sjkim { 202207344Sjkim return; 203207344Sjkim } 204207344Sjkim 205213806Sjkim /* 206213806Sjkim * Check for a so-called "null descriptor". These are descriptors that are 207213806Sjkim * created with most fields set to zero. The intent is that the descriptor 208213806Sjkim * will be updated/completed at runtime via a BufferField. 209213806Sjkim * 210213806Sjkim * If the descriptor does NOT have a resource tag, it cannot be referenced 211213806Sjkim * by a BufferField and we will flag this as an error. Conversely, if 212213806Sjkim * the descriptor has a resource tag, we will assume that a BufferField 213213806Sjkim * will be used to dynamically update it, so no error. 214213806Sjkim * 215213806Sjkim * A possible enhancement to this check would be to verify that in fact 216213806Sjkim * a BufferField is created using the resource tag, and perhaps even 217213806Sjkim * verify that a Store is performed to the BufferField. 218213806Sjkim * 219213806Sjkim * Note: for these descriptors, Alignment is allowed to be zero 220213806Sjkim */ 221213806Sjkim if (!Minimum && !Maximum && !Length) 222213806Sjkim { 223213806Sjkim if (!Op->Asl.ExternalName) 224213806Sjkim { 225213806Sjkim /* No resource tag. Descriptor is fixed and is also illegal */ 226213806Sjkim 227213806Sjkim AslError (ASL_ERROR, ASL_MSG_NULL_DESCRIPTOR, Op, NULL); 228213806Sjkim } 229213806Sjkim 230213806Sjkim return; 231213806Sjkim } 232213806Sjkim 233272444Sjkim /* 234272444Sjkim * Range checks for Memory24 and Memory32. 235272444Sjkim * IO descriptor has different definition of min/max, don't check. 236272444Sjkim */ 237207344Sjkim if (Type != ACPI_RESOURCE_NAME_IO) 238207344Sjkim { 239207344Sjkim /* Basic checks on Min/Max/Length */ 240207344Sjkim 241207344Sjkim if (Minimum > Maximum) 242207344Sjkim { 243207344Sjkim AslError (ASL_ERROR, ASL_MSG_INVALID_MIN_MAX, MinOp, NULL); 244207344Sjkim } 245207344Sjkim else if (Length > (Maximum - Minimum + 1)) 246207344Sjkim { 247207344Sjkim AslError (ASL_ERROR, ASL_MSG_INVALID_LENGTH, LengthOp, NULL); 248207344Sjkim } 249272444Sjkim 250272444Sjkim /* Special case for Memory24, min/max values are compressed */ 251272444Sjkim 252272444Sjkim if (Type == ACPI_RESOURCE_NAME_MEMORY24) 253272444Sjkim { 254272444Sjkim if (!Alignment) /* Alignment==0 means 64K alignment */ 255272444Sjkim { 256272444Sjkim Alignment = ACPI_UINT16_MAX + 1; 257272444Sjkim } 258272444Sjkim 259272444Sjkim Minimum <<= 8; 260272444Sjkim Maximum <<= 8; 261272444Sjkim } 262207344Sjkim } 263207344Sjkim 264207344Sjkim /* Alignment of zero is not in ACPI spec, but is used to mean byte acc */ 265207344Sjkim 266207344Sjkim if (!Alignment) 267207344Sjkim { 268207344Sjkim Alignment = 1; 269207344Sjkim } 270207344Sjkim 271207344Sjkim /* Addresses must be an exact multiple of the alignment value */ 272207344Sjkim 273207344Sjkim if (Minimum % Alignment) 274207344Sjkim { 275207344Sjkim AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MinOp, NULL); 276207344Sjkim } 277207344Sjkim if (Maximum % Alignment) 278207344Sjkim { 279207344Sjkim AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MaxOp, NULL); 280207344Sjkim } 281207344Sjkim} 282207344Sjkim 283207344Sjkim 284207344Sjkim/******************************************************************************* 285207344Sjkim * 286207344Sjkim * FUNCTION: RsLargeAddressCheck 287207344Sjkim * 288207344Sjkim * PARAMETERS: Minimum - Address Min value 289207344Sjkim * Maximum - Address Max value 290207344Sjkim * Length - Address range value 291207344Sjkim * Granularity - Address granularity value 292207344Sjkim * Flags - General flags for address descriptors: 293207344Sjkim * _MIF, _MAF, _DEC 294207344Sjkim * MinOp - Original Op for Address Min 295207344Sjkim * MaxOp - Original Op for Address Max 296207344Sjkim * LengthOp - Original Op for address range 297207344Sjkim * GranOp - Original Op for address granularity 298213806Sjkim * Op - Parent Op for entire construct 299207344Sjkim * 300207344Sjkim * RETURN: None. Adds error messages to error log if necessary 301207344Sjkim * 302207344Sjkim * DESCRIPTION: Perform common value checks for "large" address descriptors. 303207344Sjkim * Currently: 304207344Sjkim * WordIo, WordBusNumber, WordSpace 305207344Sjkim * DWordIo, DWordMemory, DWordSpace 306207344Sjkim * QWordIo, QWordMemory, QWordSpace 307207344Sjkim * ExtendedIo, ExtendedMemory, ExtendedSpace 308207344Sjkim * 309207344Sjkim * _MIF flag set means that the minimum address is fixed and is not relocatable 310207344Sjkim * _MAF flag set means that the maximum address is fixed and is not relocatable 311207344Sjkim * Length of zero means that the record size is variable 312207344Sjkim * 313207344Sjkim * This function implements the LEN/MIF/MAF/MIN/MAX/GRA rules within Table 6-40 314207344Sjkim * of the ACPI 4.0a specification. Added 04/2010. 315207344Sjkim * 316207344Sjkim ******************************************************************************/ 317207344Sjkim 318207344Sjkimvoid 319207344SjkimRsLargeAddressCheck ( 320207344Sjkim UINT64 Minimum, 321207344Sjkim UINT64 Maximum, 322207344Sjkim UINT64 Length, 323207344Sjkim UINT64 Granularity, 324207344Sjkim UINT8 Flags, 325207344Sjkim ACPI_PARSE_OBJECT *MinOp, 326207344Sjkim ACPI_PARSE_OBJECT *MaxOp, 327207344Sjkim ACPI_PARSE_OBJECT *LengthOp, 328213806Sjkim ACPI_PARSE_OBJECT *GranOp, 329213806Sjkim ACPI_PARSE_OBJECT *Op) 330207344Sjkim{ 331207344Sjkim 332207344Sjkim if (Gbl_NoResourceChecking) 333207344Sjkim { 334207344Sjkim return; 335207344Sjkim } 336207344Sjkim 337213806Sjkim /* 338213806Sjkim * Check for a so-called "null descriptor". These are descriptors that are 339213806Sjkim * created with most fields set to zero. The intent is that the descriptor 340213806Sjkim * will be updated/completed at runtime via a BufferField. 341213806Sjkim * 342213806Sjkim * If the descriptor does NOT have a resource tag, it cannot be referenced 343213806Sjkim * by a BufferField and we will flag this as an error. Conversely, if 344213806Sjkim * the descriptor has a resource tag, we will assume that a BufferField 345213806Sjkim * will be used to dynamically update it, so no error. 346213806Sjkim * 347213806Sjkim * A possible enhancement to this check would be to verify that in fact 348213806Sjkim * a BufferField is created using the resource tag, and perhaps even 349213806Sjkim * verify that a Store is performed to the BufferField. 350213806Sjkim */ 351213806Sjkim if (!Minimum && !Maximum && !Length && !Granularity) 352213806Sjkim { 353213806Sjkim if (!Op->Asl.ExternalName) 354213806Sjkim { 355213806Sjkim /* No resource tag. Descriptor is fixed and is also illegal */ 356213806Sjkim 357213806Sjkim AslError (ASL_ERROR, ASL_MSG_NULL_DESCRIPTOR, Op, NULL); 358213806Sjkim } 359213806Sjkim 360213806Sjkim return; 361213806Sjkim } 362213806Sjkim 363207344Sjkim /* Basic checks on Min/Max/Length */ 364207344Sjkim 365207344Sjkim if (Minimum > Maximum) 366207344Sjkim { 367207344Sjkim AslError (ASL_ERROR, ASL_MSG_INVALID_MIN_MAX, MinOp, NULL); 368207344Sjkim return; 369207344Sjkim } 370207344Sjkim else if (Length > (Maximum - Minimum + 1)) 371207344Sjkim { 372207344Sjkim AslError (ASL_ERROR, ASL_MSG_INVALID_LENGTH, LengthOp, NULL); 373207344Sjkim return; 374207344Sjkim } 375207344Sjkim 376207344Sjkim /* If specified (non-zero), ensure granularity is a power-of-two minus one */ 377207344Sjkim 378207344Sjkim if (Granularity) 379207344Sjkim { 380207344Sjkim if ((Granularity + 1) & 381207344Sjkim Granularity) 382207344Sjkim { 383207344Sjkim AslError (ASL_ERROR, ASL_MSG_INVALID_GRANULARITY, GranOp, NULL); 384207344Sjkim return; 385207344Sjkim } 386207344Sjkim } 387207344Sjkim 388207344Sjkim /* 389207344Sjkim * Check the various combinations of Length, MinFixed, and MaxFixed 390207344Sjkim */ 391207344Sjkim if (Length) 392207344Sjkim { 393207344Sjkim /* Fixed non-zero length */ 394207344Sjkim 395207344Sjkim switch (Flags & (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF)) 396207344Sjkim { 397207344Sjkim case 0: 398207344Sjkim /* 399207344Sjkim * Fixed length, variable locations (both _MIN and _MAX). 400207344Sjkim * Length must be a multiple of granularity 401207344Sjkim */ 402207344Sjkim if (Granularity & Length) 403207344Sjkim { 404207344Sjkim AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, LengthOp, NULL); 405207344Sjkim } 406207344Sjkim break; 407207344Sjkim 408207344Sjkim case (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF): 409207344Sjkim 410207344Sjkim /* Fixed length, fixed location. Granularity must be zero */ 411207344Sjkim 412207344Sjkim if (Granularity != 0) 413207344Sjkim { 414207344Sjkim AslError (ASL_ERROR, ASL_MSG_INVALID_GRAN_FIXED, GranOp, NULL); 415207344Sjkim } 416207344Sjkim 417207344Sjkim /* Length must be exactly the size of the min/max window */ 418207344Sjkim 419207344Sjkim if (Length != (Maximum - Minimum + 1)) 420207344Sjkim { 421207344Sjkim AslError (ASL_ERROR, ASL_MSG_INVALID_LENGTH_FIXED, LengthOp, NULL); 422207344Sjkim } 423207344Sjkim break; 424207344Sjkim 425207344Sjkim /* All other combinations are invalid */ 426207344Sjkim 427207344Sjkim case ACPI_RESOURCE_FLAG_MIF: 428207344Sjkim case ACPI_RESOURCE_FLAG_MAF: 429207344Sjkim default: 430250838Sjkim 431207344Sjkim AslError (ASL_ERROR, ASL_MSG_INVALID_ADDR_FLAGS, LengthOp, NULL); 432207344Sjkim } 433207344Sjkim } 434207344Sjkim else 435207344Sjkim { 436207344Sjkim /* Variable length (length==0) */ 437207344Sjkim 438207344Sjkim switch (Flags & (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF)) 439207344Sjkim { 440207344Sjkim case 0: 441207344Sjkim /* 442207344Sjkim * Both _MIN and _MAX are variable. 443207344Sjkim * No additional requirements, just exit 444207344Sjkim */ 445207344Sjkim break; 446207344Sjkim 447207344Sjkim case ACPI_RESOURCE_FLAG_MIF: 448207344Sjkim 449207344Sjkim /* _MIN is fixed. _MIN must be multiple of _GRA */ 450207344Sjkim 451207344Sjkim /* 452207344Sjkim * The granularity is defined by the ACPI specification to be a 453207344Sjkim * power-of-two minus one, therefore the granularity is a 454207344Sjkim * bitmask which can be used to easily validate the addresses. 455207344Sjkim */ 456207344Sjkim if (Granularity & Minimum) 457207344Sjkim { 458207344Sjkim AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MinOp, NULL); 459207344Sjkim } 460207344Sjkim break; 461207344Sjkim 462207344Sjkim case ACPI_RESOURCE_FLAG_MAF: 463207344Sjkim 464207344Sjkim /* _MAX is fixed. (_MAX + 1) must be multiple of _GRA */ 465207344Sjkim 466207344Sjkim if (Granularity & (Maximum + 1)) 467207344Sjkim { 468207344Sjkim AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MaxOp, "-1"); 469207344Sjkim } 470207344Sjkim break; 471207344Sjkim 472207344Sjkim /* Both MIF/MAF set is invalid if length is zero */ 473207344Sjkim 474207344Sjkim case (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF): 475207344Sjkim default: 476250838Sjkim 477207344Sjkim AslError (ASL_ERROR, ASL_MSG_INVALID_ADDR_FLAGS, LengthOp, NULL); 478207344Sjkim } 479207344Sjkim } 480207344Sjkim} 481207344Sjkim 482207344Sjkim 483207344Sjkim/******************************************************************************* 484207344Sjkim * 485207344Sjkim * FUNCTION: RsGetStringDataLength 486207344Sjkim * 487207344Sjkim * PARAMETERS: InitializerOp - Start of a subtree of init nodes 488207344Sjkim * 489207344Sjkim * RETURN: Valid string length if a string node is found (otherwise 0) 490207344Sjkim * 491207344Sjkim * DESCRIPTION: In a list of peer nodes, find the first one that contains a 492207344Sjkim * string and return the length of the string. 493207344Sjkim * 494207344Sjkim ******************************************************************************/ 495207344Sjkim 496207344SjkimUINT16 497207344SjkimRsGetStringDataLength ( 498207344Sjkim ACPI_PARSE_OBJECT *InitializerOp) 499207344Sjkim{ 500207344Sjkim 501207344Sjkim while (InitializerOp) 502207344Sjkim { 503207344Sjkim if (InitializerOp->Asl.ParseOpcode == PARSEOP_STRING_LITERAL) 504207344Sjkim { 505207344Sjkim return ((UINT16) (strlen (InitializerOp->Asl.Value.String) + 1)); 506207344Sjkim } 507298714Sjkim 508207344Sjkim InitializerOp = ASL_GET_PEER_NODE (InitializerOp); 509207344Sjkim } 510207344Sjkim 511241973Sjkim return (0); 512207344Sjkim} 513207344Sjkim 514207344Sjkim 515207344Sjkim/******************************************************************************* 516207344Sjkim * 517118611Snjl * FUNCTION: RsAllocateResourceNode 518118611Snjl * 519118611Snjl * PARAMETERS: Size - Size of node in bytes 520118611Snjl * 521118611Snjl * RETURN: The allocated node - aborts on allocation failure 522118611Snjl * 523118611Snjl * DESCRIPTION: Allocate a resource description node and the resource 524118611Snjl * descriptor itself (the nodes are used to link descriptors). 525118611Snjl * 526118611Snjl ******************************************************************************/ 527118611Snjl 528118611SnjlASL_RESOURCE_NODE * 529118611SnjlRsAllocateResourceNode ( 530118611Snjl UINT32 Size) 531118611Snjl{ 532118611Snjl ASL_RESOURCE_NODE *Rnode; 533118611Snjl 534118611Snjl 535118611Snjl /* Allocate the node */ 536118611Snjl 537118611Snjl Rnode = UtLocalCalloc (sizeof (ASL_RESOURCE_NODE)); 538118611Snjl 539118611Snjl /* Allocate the resource descriptor itself */ 540118611Snjl 541118611Snjl Rnode->Buffer = UtLocalCalloc (Size); 542118611Snjl Rnode->BufferLength = Size; 543118611Snjl return (Rnode); 544118611Snjl} 545118611Snjl 546118611Snjl 547118611Snjl/******************************************************************************* 548118611Snjl * 549228110Sjkim * FUNCTION: RsCreateResourceField 550118611Snjl * 551151937Sjkim * PARAMETERS: Op - Resource field node 552118611Snjl * Name - Name of the field (Used only to reference 553118611Snjl * the field in the ASL, not in the AML) 554118611Snjl * ByteOffset - Offset from the field start 555118611Snjl * BitOffset - Additional bit offset 556228110Sjkim * BitLength - Number of bits in the field 557118611Snjl * 558118611Snjl * RETURN: None, sets fields within the input node 559118611Snjl * 560118611Snjl * DESCRIPTION: Utility function to generate a named bit field within a 561241973Sjkim * resource descriptor. Mark a node as 1) a field in a resource 562118611Snjl * descriptor, and 2) set the value to be a BIT offset 563118611Snjl * 564118611Snjl ******************************************************************************/ 565118611Snjl 566118611Snjlvoid 567228110SjkimRsCreateResourceField ( 568118611Snjl ACPI_PARSE_OBJECT *Op, 569118611Snjl char *Name, 570118611Snjl UINT32 ByteOffset, 571228110Sjkim UINT32 BitOffset, 572228110Sjkim UINT32 BitLength) 573118611Snjl{ 574118611Snjl 575228110Sjkim Op->Asl.ExternalName = Name; 576322877Sjkim Op->Asl.CompileFlags |= OP_IS_RESOURCE_FIELD; 577118611Snjl 578228110Sjkim Op->Asl.Value.Tag.BitOffset = (ByteOffset * 8) + BitOffset; 579228110Sjkim Op->Asl.Value.Tag.BitLength = BitLength; 580118611Snjl} 581118611Snjl 582118611Snjl 583118611Snjl/******************************************************************************* 584118611Snjl * 585118611Snjl * FUNCTION: RsSetFlagBits 586118611Snjl * 587118611Snjl * PARAMETERS: *Flags - Pointer to the flag byte 588151937Sjkim * Op - Flag initialization node 589118611Snjl * Position - Bit position within the flag byte 590118611Snjl * Default - Used if the node is DEFAULT. 591118611Snjl * 592118611Snjl * RETURN: Sets bits within the *Flags output byte. 593118611Snjl * 594118611Snjl * DESCRIPTION: Set a bit in a cumulative flags word from an initialization 595241973Sjkim * node. Will use a default value if the node is DEFAULT, meaning 596241973Sjkim * that no value was specified in the ASL. Used to merge multiple 597118611Snjl * keywords into a single flags byte. 598118611Snjl * 599118611Snjl ******************************************************************************/ 600118611Snjl 601118611Snjlvoid 602118611SnjlRsSetFlagBits ( 603118611Snjl UINT8 *Flags, 604118611Snjl ACPI_PARSE_OBJECT *Op, 605118611Snjl UINT8 Position, 606118611Snjl UINT8 DefaultBit) 607118611Snjl{ 608118611Snjl 609118611Snjl if (Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 610118611Snjl { 611118611Snjl /* Use the default bit */ 612118611Snjl 613118611Snjl *Flags |= (DefaultBit << Position); 614118611Snjl } 615118611Snjl else 616118611Snjl { 617118611Snjl /* Use the bit specified in the initialization node */ 618118611Snjl 619118611Snjl *Flags |= (((UINT8) Op->Asl.Value.Integer) << Position); 620118611Snjl } 621118611Snjl} 622118611Snjl 623118611Snjl 624228110Sjkimvoid 625228110SjkimRsSetFlagBits16 ( 626228110Sjkim UINT16 *Flags, 627228110Sjkim ACPI_PARSE_OBJECT *Op, 628228110Sjkim UINT8 Position, 629228110Sjkim UINT8 DefaultBit) 630228110Sjkim{ 631228110Sjkim 632228110Sjkim if (Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 633228110Sjkim { 634228110Sjkim /* Use the default bit */ 635228110Sjkim 636228110Sjkim *Flags |= (DefaultBit << Position); 637228110Sjkim } 638228110Sjkim else 639228110Sjkim { 640228110Sjkim /* Use the bit specified in the initialization node */ 641228110Sjkim 642228110Sjkim *Flags |= (((UINT16) Op->Asl.Value.Integer) << Position); 643228110Sjkim } 644228110Sjkim} 645228110Sjkim 646228110Sjkim 647118611Snjl/******************************************************************************* 648118611Snjl * 649118611Snjl * FUNCTION: RsCompleteNodeAndGetNext 650118611Snjl * 651118611Snjl * PARAMETERS: Op - Resource node to be completed 652118611Snjl * 653118611Snjl * RETURN: The next peer to the input node. 654118611Snjl * 655118611Snjl * DESCRIPTION: Mark the current node completed and return the next peer. 656118611Snjl * The node ParseOpcode is set to DEFAULT_ARG, meaning that 657118611Snjl * this node is to be ignored from now on. 658118611Snjl * 659118611Snjl ******************************************************************************/ 660118611Snjl 661118611SnjlACPI_PARSE_OBJECT * 662118611SnjlRsCompleteNodeAndGetNext ( 663118611Snjl ACPI_PARSE_OBJECT *Op) 664118611Snjl{ 665118611Snjl 666118611Snjl /* Mark this node unused */ 667118611Snjl 668118611Snjl Op->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 669118611Snjl 670118611Snjl /* Move on to the next peer node in the initializer list */ 671118611Snjl 672118611Snjl return (ASL_GET_PEER_NODE (Op)); 673118611Snjl} 674118611Snjl 675118611Snjl 676118611Snjl/******************************************************************************* 677118611Snjl * 678151937Sjkim * FUNCTION: RsCheckListForDuplicates 679151937Sjkim * 680151937Sjkim * PARAMETERS: Op - First op in the initializer list 681151937Sjkim * 682151937Sjkim * RETURN: None 683151937Sjkim * 684151937Sjkim * DESCRIPTION: Check an initializer list for duplicate values. Emits an error 685151937Sjkim * if any duplicates are found. 686151937Sjkim * 687151937Sjkim ******************************************************************************/ 688151937Sjkim 689151937Sjkimvoid 690151937SjkimRsCheckListForDuplicates ( 691151937Sjkim ACPI_PARSE_OBJECT *Op) 692151937Sjkim{ 693151937Sjkim ACPI_PARSE_OBJECT *NextValueOp = Op; 694151937Sjkim ACPI_PARSE_OBJECT *NextOp; 695151937Sjkim UINT32 Value; 696151937Sjkim 697151937Sjkim 698151937Sjkim if (!Op) 699151937Sjkim { 700151937Sjkim return; 701151937Sjkim } 702151937Sjkim 703151937Sjkim /* Search list once for each value in the list */ 704151937Sjkim 705151937Sjkim while (NextValueOp) 706151937Sjkim { 707151937Sjkim Value = (UINT32) NextValueOp->Asl.Value.Integer; 708151937Sjkim 709151937Sjkim /* Compare this value to all remaining values in the list */ 710151937Sjkim 711151937Sjkim NextOp = ASL_GET_PEER_NODE (NextValueOp); 712151937Sjkim while (NextOp) 713151937Sjkim { 714151937Sjkim if (NextOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) 715151937Sjkim { 716151937Sjkim /* Compare values */ 717151937Sjkim 718151937Sjkim if (Value == (UINT32) NextOp->Asl.Value.Integer) 719151937Sjkim { 720151937Sjkim /* Emit error only once per duplicate node */ 721151937Sjkim 722322877Sjkim if (!(NextOp->Asl.CompileFlags & OP_IS_DUPLICATE)) 723151937Sjkim { 724322877Sjkim NextOp->Asl.CompileFlags |= OP_IS_DUPLICATE; 725151937Sjkim AslError (ASL_ERROR, ASL_MSG_DUPLICATE_ITEM, 726151937Sjkim NextOp, NULL); 727151937Sjkim } 728151937Sjkim } 729151937Sjkim } 730151937Sjkim 731151937Sjkim NextOp = ASL_GET_PEER_NODE (NextOp); 732151937Sjkim } 733151937Sjkim 734151937Sjkim NextValueOp = ASL_GET_PEER_NODE (NextValueOp); 735151937Sjkim } 736151937Sjkim} 737151937Sjkim 738151937Sjkim 739151937Sjkim/******************************************************************************* 740151937Sjkim * 741118611Snjl * FUNCTION: RsDoOneResourceDescriptor 742118611Snjl * 743118611Snjl * PARAMETERS: DescriptorTypeOp - Parent parse node of the descriptor 744118611Snjl * CurrentByteOffset - Offset in the resource descriptor 745118611Snjl * buffer. 746118611Snjl * 747118611Snjl * RETURN: A valid resource node for the descriptor 748118611Snjl * 749118611Snjl * DESCRIPTION: Dispatches the processing of one resource descriptor 750118611Snjl * 751118611Snjl ******************************************************************************/ 752118611Snjl 753118611SnjlASL_RESOURCE_NODE * 754118611SnjlRsDoOneResourceDescriptor ( 755272444Sjkim ASL_RESOURCE_INFO *Info, 756118611Snjl UINT8 *State) 757118611Snjl{ 758118611Snjl ASL_RESOURCE_NODE *Rnode = NULL; 759118611Snjl 760118611Snjl 761167802Sjkim /* Construct the resource */ 762118611Snjl 763272444Sjkim switch (Info->DescriptorTypeOp->Asl.ParseOpcode) 764118611Snjl { 765118611Snjl case PARSEOP_DMA: 766250838Sjkim 767272444Sjkim Rnode = RsDoDmaDescriptor (Info); 768118611Snjl break; 769118611Snjl 770228110Sjkim case PARSEOP_FIXEDDMA: 771250838Sjkim 772272444Sjkim Rnode = RsDoFixedDmaDescriptor (Info); 773228110Sjkim break; 774228110Sjkim 775118611Snjl case PARSEOP_DWORDIO: 776250838Sjkim 777272444Sjkim Rnode = RsDoDwordIoDescriptor (Info); 778118611Snjl break; 779118611Snjl 780118611Snjl case PARSEOP_DWORDMEMORY: 781250838Sjkim 782272444Sjkim Rnode = RsDoDwordMemoryDescriptor (Info); 783118611Snjl break; 784118611Snjl 785151937Sjkim case PARSEOP_DWORDSPACE: 786250838Sjkim 787272444Sjkim Rnode = RsDoDwordSpaceDescriptor (Info); 788151937Sjkim break; 789151937Sjkim 790118611Snjl case PARSEOP_ENDDEPENDENTFN: 791250838Sjkim 792118611Snjl switch (*State) 793118611Snjl { 794118611Snjl case ACPI_RSTATE_NORMAL: 795250838Sjkim 796151937Sjkim AslError (ASL_ERROR, ASL_MSG_MISSING_STARTDEPENDENT, 797272444Sjkim Info->DescriptorTypeOp, NULL); 798118611Snjl break; 799118611Snjl 800118611Snjl case ACPI_RSTATE_START_DEPENDENT: 801250838Sjkim 802151937Sjkim AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING, 803272444Sjkim Info->DescriptorTypeOp, NULL); 804118611Snjl break; 805118611Snjl 806118611Snjl case ACPI_RSTATE_DEPENDENT_LIST: 807118611Snjl default: 808250838Sjkim 809118611Snjl break; 810118611Snjl } 811118611Snjl 812118611Snjl *State = ACPI_RSTATE_NORMAL; 813272444Sjkim Rnode = RsDoEndDependentDescriptor (Info); 814118611Snjl break; 815118611Snjl 816167802Sjkim case PARSEOP_ENDTAG: 817250838Sjkim 818272444Sjkim Rnode = RsDoEndTagDescriptor (Info); 819167802Sjkim break; 820167802Sjkim 821151937Sjkim case PARSEOP_EXTENDEDIO: 822250838Sjkim 823272444Sjkim Rnode = RsDoExtendedIoDescriptor (Info); 824151937Sjkim break; 825151937Sjkim 826151937Sjkim case PARSEOP_EXTENDEDMEMORY: 827250838Sjkim 828272444Sjkim Rnode = RsDoExtendedMemoryDescriptor (Info); 829151937Sjkim break; 830151937Sjkim 831151937Sjkim case PARSEOP_EXTENDEDSPACE: 832250838Sjkim 833272444Sjkim Rnode = RsDoExtendedSpaceDescriptor (Info); 834151937Sjkim break; 835151937Sjkim 836118611Snjl case PARSEOP_FIXEDIO: 837250838Sjkim 838272444Sjkim Rnode = RsDoFixedIoDescriptor (Info); 839118611Snjl break; 840118611Snjl 841118611Snjl case PARSEOP_INTERRUPT: 842250838Sjkim 843272444Sjkim Rnode = RsDoInterruptDescriptor (Info); 844118611Snjl break; 845118611Snjl 846118611Snjl case PARSEOP_IO: 847250838Sjkim 848272444Sjkim Rnode = RsDoIoDescriptor (Info); 849118611Snjl break; 850118611Snjl 851118611Snjl case PARSEOP_IRQ: 852250838Sjkim 853272444Sjkim Rnode = RsDoIrqDescriptor (Info); 854118611Snjl break; 855118611Snjl 856118611Snjl case PARSEOP_IRQNOFLAGS: 857250838Sjkim 858272444Sjkim Rnode = RsDoIrqNoFlagsDescriptor (Info); 859118611Snjl break; 860118611Snjl 861118611Snjl case PARSEOP_MEMORY24: 862250838Sjkim 863272444Sjkim Rnode = RsDoMemory24Descriptor (Info); 864118611Snjl break; 865118611Snjl 866118611Snjl case PARSEOP_MEMORY32: 867250838Sjkim 868272444Sjkim Rnode = RsDoMemory32Descriptor (Info); 869118611Snjl break; 870118611Snjl 871118611Snjl case PARSEOP_MEMORY32FIXED: 872250838Sjkim 873272444Sjkim Rnode = RsDoMemory32FixedDescriptor (Info); 874118611Snjl break; 875118611Snjl 876118611Snjl case PARSEOP_QWORDIO: 877250838Sjkim 878272444Sjkim Rnode = RsDoQwordIoDescriptor (Info); 879118611Snjl break; 880118611Snjl 881118611Snjl case PARSEOP_QWORDMEMORY: 882250838Sjkim 883272444Sjkim Rnode = RsDoQwordMemoryDescriptor (Info); 884118611Snjl break; 885118611Snjl 886151937Sjkim case PARSEOP_QWORDSPACE: 887250838Sjkim 888272444Sjkim Rnode = RsDoQwordSpaceDescriptor (Info); 889151937Sjkim break; 890151937Sjkim 891118611Snjl case PARSEOP_REGISTER: 892250838Sjkim 893272444Sjkim Rnode = RsDoGeneralRegisterDescriptor (Info); 894118611Snjl break; 895118611Snjl 896118611Snjl case PARSEOP_STARTDEPENDENTFN: 897250838Sjkim 898118611Snjl switch (*State) 899118611Snjl { 900118611Snjl case ACPI_RSTATE_START_DEPENDENT: 901250838Sjkim 902151937Sjkim AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING, 903272444Sjkim Info->DescriptorTypeOp, NULL); 904118611Snjl break; 905118611Snjl 906118611Snjl case ACPI_RSTATE_NORMAL: 907118611Snjl case ACPI_RSTATE_DEPENDENT_LIST: 908118611Snjl default: 909250838Sjkim 910118611Snjl break; 911118611Snjl } 912118611Snjl 913118611Snjl *State = ACPI_RSTATE_START_DEPENDENT; 914272444Sjkim Rnode = RsDoStartDependentDescriptor (Info); 915118611Snjl *State = ACPI_RSTATE_DEPENDENT_LIST; 916118611Snjl break; 917118611Snjl 918118611Snjl case PARSEOP_STARTDEPENDENTFN_NOPRI: 919250838Sjkim 920118611Snjl switch (*State) 921118611Snjl { 922118611Snjl case ACPI_RSTATE_START_DEPENDENT: 923250838Sjkim 924151937Sjkim AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING, 925272444Sjkim Info->DescriptorTypeOp, NULL); 926118611Snjl break; 927118611Snjl 928118611Snjl case ACPI_RSTATE_NORMAL: 929118611Snjl case ACPI_RSTATE_DEPENDENT_LIST: 930118611Snjl default: 931250838Sjkim 932118611Snjl break; 933118611Snjl } 934118611Snjl 935118611Snjl *State = ACPI_RSTATE_START_DEPENDENT; 936272444Sjkim Rnode = RsDoStartDependentNoPriDescriptor (Info); 937118611Snjl *State = ACPI_RSTATE_DEPENDENT_LIST; 938118611Snjl break; 939118611Snjl 940118611Snjl case PARSEOP_VENDORLONG: 941250838Sjkim 942272444Sjkim Rnode = RsDoVendorLargeDescriptor (Info); 943118611Snjl break; 944118611Snjl 945118611Snjl case PARSEOP_VENDORSHORT: 946250838Sjkim 947272444Sjkim Rnode = RsDoVendorSmallDescriptor (Info); 948118611Snjl break; 949118611Snjl 950118611Snjl case PARSEOP_WORDBUSNUMBER: 951250838Sjkim 952272444Sjkim Rnode = RsDoWordBusNumberDescriptor (Info); 953118611Snjl break; 954118611Snjl 955118611Snjl case PARSEOP_WORDIO: 956250838Sjkim 957272444Sjkim Rnode = RsDoWordIoDescriptor (Info); 958118611Snjl break; 959118611Snjl 960151937Sjkim case PARSEOP_WORDSPACE: 961250838Sjkim 962272444Sjkim Rnode = RsDoWordSpaceDescriptor (Info); 963151937Sjkim break; 964151937Sjkim 965228110Sjkim case PARSEOP_GPIO_INT: 966250838Sjkim 967272444Sjkim Rnode = RsDoGpioIntDescriptor (Info); 968228110Sjkim break; 969228110Sjkim 970228110Sjkim case PARSEOP_GPIO_IO: 971250838Sjkim 972272444Sjkim Rnode = RsDoGpioIoDescriptor (Info); 973228110Sjkim break; 974228110Sjkim 975228110Sjkim case PARSEOP_I2C_SERIALBUS: 976298714Sjkim case PARSEOP_I2C_SERIALBUS_V2: 977250838Sjkim 978272444Sjkim Rnode = RsDoI2cSerialBusDescriptor (Info); 979228110Sjkim break; 980228110Sjkim 981228110Sjkim case PARSEOP_SPI_SERIALBUS: 982298714Sjkim case PARSEOP_SPI_SERIALBUS_V2: 983250838Sjkim 984272444Sjkim Rnode = RsDoSpiSerialBusDescriptor (Info); 985228110Sjkim break; 986228110Sjkim 987228110Sjkim case PARSEOP_UART_SERIALBUS: 988298714Sjkim case PARSEOP_UART_SERIALBUS_V2: 989250838Sjkim 990272444Sjkim Rnode = RsDoUartSerialBusDescriptor (Info); 991228110Sjkim break; 992228110Sjkim 993322877Sjkim case PARSEOP_PINCONFIG: 994322877Sjkim 995322877Sjkim Rnode = RsDoPinConfigDescriptor (Info); 996322877Sjkim break; 997322877Sjkim 998322877Sjkim case PARSEOP_PINFUNCTION: 999322877Sjkim 1000322877Sjkim Rnode = RsDoPinFunctionDescriptor (Info); 1001322877Sjkim break; 1002322877Sjkim 1003322877Sjkim case PARSEOP_PINGROUP: 1004322877Sjkim 1005322877Sjkim Rnode = RsDoPinGroupDescriptor (Info); 1006322877Sjkim break; 1007322877Sjkim 1008322877Sjkim case PARSEOP_PINGROUPFUNCTION: 1009322877Sjkim 1010322877Sjkim Rnode = RsDoPinGroupFunctionDescriptor (Info); 1011322877Sjkim break; 1012322877Sjkim 1013322877Sjkim case PARSEOP_PINGROUPCONFIG: 1014322877Sjkim 1015322877Sjkim Rnode = RsDoPinGroupConfigDescriptor (Info); 1016322877Sjkim break; 1017322877Sjkim 1018118611Snjl case PARSEOP_DEFAULT_ARG: 1019250838Sjkim 1020118611Snjl /* Just ignore any of these, they are used as fillers/placeholders */ 1021118611Snjl break; 1022118611Snjl 1023118611Snjl default: 1024250838Sjkim 1025118611Snjl printf ("Unknown resource descriptor type [%s]\n", 1026298714Sjkim Info->DescriptorTypeOp->Asl.ParseOpName); 1027118611Snjl break; 1028118611Snjl } 1029118611Snjl 1030118611Snjl /* 1031118611Snjl * Mark original node as unused, but head of a resource descriptor. 1032118611Snjl * This allows the resource to be installed in the namespace so that 1033118611Snjl * references to the descriptor can be resolved. 1034118611Snjl */ 1035272444Sjkim Info->DescriptorTypeOp->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 1036322877Sjkim Info->DescriptorTypeOp->Asl.CompileFlags = OP_IS_RESOURCE_DESC; 1037272444Sjkim Info->DescriptorTypeOp->Asl.Value.Integer = Info->CurrentByteOffset; 1038118611Snjl 1039167802Sjkim if (Rnode) 1040167802Sjkim { 1041272444Sjkim Info->DescriptorTypeOp->Asl.FinalAmlLength = Rnode->BufferLength; 1042298714Sjkim Info->DescriptorTypeOp->Asl.Extra = 1043298714Sjkim ((AML_RESOURCE *) Rnode->Buffer)->DescriptorType; 1044167802Sjkim } 1045167802Sjkim 1046118611Snjl return (Rnode); 1047118611Snjl} 1048118611Snjl 1049118611Snjl 1050118611Snjl/******************************************************************************* 1051118611Snjl * 1052118611Snjl * FUNCTION: RsLinkDescriptorChain 1053118611Snjl * 1054118611Snjl * PARAMETERS: PreviousRnode - Pointer to the node that will be previous 1055118611Snjl * to the linked node, At exit, set to the 1056118611Snjl * last node in the new chain. 1057118611Snjl * Rnode - Resource node to link into the list 1058118611Snjl * 1059118611Snjl * RETURN: Cumulative buffer byte offset of the new segment of chain 1060118611Snjl * 1061118611Snjl * DESCRIPTION: Link a descriptor chain at the end of an existing chain. 1062118611Snjl * 1063118611Snjl ******************************************************************************/ 1064118611Snjl 1065118611SnjlUINT32 1066118611SnjlRsLinkDescriptorChain ( 1067118611Snjl ASL_RESOURCE_NODE **PreviousRnode, 1068118611Snjl ASL_RESOURCE_NODE *Rnode) 1069118611Snjl{ 1070118611Snjl ASL_RESOURCE_NODE *LastRnode; 1071118611Snjl UINT32 CurrentByteOffset; 1072118611Snjl 1073118611Snjl 1074118611Snjl /* Anything to do? */ 1075118611Snjl 1076118611Snjl if (!Rnode) 1077118611Snjl { 1078241973Sjkim return (0); 1079118611Snjl } 1080118611Snjl 1081118611Snjl /* Point the previous node to the new node */ 1082118611Snjl 1083118611Snjl (*PreviousRnode)->Next = Rnode; 1084118611Snjl CurrentByteOffset = Rnode->BufferLength; 1085118611Snjl 1086118611Snjl /* Walk to the end of the chain headed by Rnode */ 1087118611Snjl 1088118611Snjl LastRnode = Rnode; 1089118611Snjl while (LastRnode->Next) 1090118611Snjl { 1091118611Snjl LastRnode = LastRnode->Next; 1092118611Snjl CurrentByteOffset += LastRnode->BufferLength; 1093118611Snjl } 1094118611Snjl 1095118611Snjl /* Previous node becomes the last node in the chain */ 1096118611Snjl 1097118611Snjl *PreviousRnode = LastRnode; 1098241973Sjkim return (CurrentByteOffset); 1099118611Snjl} 1100118611Snjl 1101118611Snjl 1102118611Snjl/******************************************************************************* 1103118611Snjl * 1104118611Snjl * FUNCTION: RsDoResourceTemplate 1105118611Snjl * 1106118611Snjl * PARAMETERS: Op - Parent of a resource template list 1107118611Snjl * 1108241973Sjkim * RETURN: None. Sets input node to point to a list of AML code 1109118611Snjl * 1110118611Snjl * DESCRIPTION: Merge a list of resource descriptors into a single AML buffer, 1111118611Snjl * in preparation for output to the AML output file. 1112118611Snjl * 1113118611Snjl ******************************************************************************/ 1114118611Snjl 1115118611Snjlvoid 1116118611SnjlRsDoResourceTemplate ( 1117118611Snjl ACPI_PARSE_OBJECT *Op) 1118118611Snjl{ 1119118611Snjl ACPI_PARSE_OBJECT *BufferLengthOp; 1120118611Snjl ACPI_PARSE_OBJECT *BufferOp; 1121118611Snjl ACPI_PARSE_OBJECT *DescriptorTypeOp; 1122118611Snjl ACPI_PARSE_OBJECT *LastOp = NULL; 1123118611Snjl UINT32 CurrentByteOffset = 0; 1124118611Snjl ASL_RESOURCE_NODE HeadRnode; 1125118611Snjl ASL_RESOURCE_NODE *PreviousRnode; 1126118611Snjl ASL_RESOURCE_NODE *Rnode; 1127272444Sjkim ASL_RESOURCE_INFO Info; 1128118611Snjl UINT8 State; 1129118611Snjl 1130118611Snjl 1131167802Sjkim /* Mark parent as containing a resource template */ 1132167802Sjkim 1133167802Sjkim if (Op->Asl.Parent) 1134167802Sjkim { 1135322877Sjkim Op->Asl.Parent->Asl.CompileFlags |= OP_IS_RESOURCE_DESC; 1136167802Sjkim } 1137167802Sjkim 1138118611Snjl /* ResourceTemplate Opcode is first (Op) */ 1139118611Snjl /* Buffer Length node is first child */ 1140118611Snjl 1141118611Snjl BufferLengthOp = ASL_GET_CHILD_NODE (Op); 1142118611Snjl 1143118611Snjl /* Buffer Op is first peer */ 1144118611Snjl 1145118611Snjl BufferOp = ASL_GET_PEER_NODE (BufferLengthOp); 1146118611Snjl 1147118611Snjl /* First Descriptor type is next */ 1148118611Snjl 1149118611Snjl DescriptorTypeOp = ASL_GET_PEER_NODE (BufferOp); 1150118611Snjl 1151327557Sjkim /* DEFAULT_ARG indicates null template - ResourceTemplate(){} */ 1152327557Sjkim 1153327557Sjkim if (DescriptorTypeOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 1154327557Sjkim { 1155327557Sjkim AslError (ASL_WARNING, ASL_MSG_NULL_RESOURCE_TEMPLATE, 1156327557Sjkim DescriptorTypeOp, DescriptorTypeOp->Asl.Value.String); 1157327557Sjkim } 1158327557Sjkim 1159167802Sjkim /* 1160167802Sjkim * Process all resource descriptors in the list 1161167802Sjkim * Note: It is assumed that the EndTag node has been automatically 1162167802Sjkim * inserted at the end of the template by the parser. 1163167802Sjkim */ 1164118611Snjl State = ACPI_RSTATE_NORMAL; 1165118611Snjl PreviousRnode = &HeadRnode; 1166118611Snjl while (DescriptorTypeOp) 1167118611Snjl { 1168272444Sjkim /* Save information for optional mapfile */ 1169272444Sjkim 1170272444Sjkim if (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONNECTION) 1171272444Sjkim { 1172272444Sjkim Info.MappingOp = Op->Asl.Parent; 1173272444Sjkim } 1174272444Sjkim else 1175272444Sjkim { 1176272444Sjkim Info.MappingOp = DescriptorTypeOp; 1177272444Sjkim } 1178272444Sjkim 1179272444Sjkim Info.DescriptorTypeOp = DescriptorTypeOp; 1180272444Sjkim Info.CurrentByteOffset = CurrentByteOffset; 1181272444Sjkim 1182322877Sjkim DescriptorTypeOp->Asl.CompileFlags |= OP_IS_RESOURCE_DESC; 1183272444Sjkim Rnode = RsDoOneResourceDescriptor (&Info, &State); 1184118611Snjl 1185118611Snjl /* 1186118611Snjl * Update current byte offset to indicate the number of bytes from the 1187241973Sjkim * start of the buffer. Buffer can include multiple descriptors, we 1188118611Snjl * must keep track of the offset of not only each descriptor, but each 1189118611Snjl * element (field) within each descriptor as well. 1190118611Snjl */ 1191118611Snjl CurrentByteOffset += RsLinkDescriptorChain (&PreviousRnode, Rnode); 1192118611Snjl 1193118611Snjl /* Get the next descriptor in the list */ 1194118611Snjl 1195118611Snjl LastOp = DescriptorTypeOp; 1196118611Snjl DescriptorTypeOp = ASL_GET_PEER_NODE (DescriptorTypeOp); 1197118611Snjl } 1198118611Snjl 1199118611Snjl if (State == ACPI_RSTATE_DEPENDENT_LIST) 1200118611Snjl { 1201118611Snjl if (LastOp) 1202118611Snjl { 1203118611Snjl LastOp = LastOp->Asl.Parent; 1204118611Snjl } 1205118611Snjl AslError (ASL_ERROR, ASL_MSG_MISSING_ENDDEPENDENT, LastOp, NULL); 1206118611Snjl } 1207118611Snjl 1208118611Snjl /* 1209118611Snjl * Transform the nodes into the following 1210118611Snjl * 1211118611Snjl * Op -> AML_BUFFER_OP 1212118611Snjl * First Child -> BufferLength 1213118611Snjl * Second Child -> Descriptor Buffer (raw byte data) 1214118611Snjl */ 1215118611Snjl Op->Asl.ParseOpcode = PARSEOP_BUFFER; 1216118611Snjl Op->Asl.AmlOpcode = AML_BUFFER_OP; 1217322877Sjkim Op->Asl.CompileFlags = OP_AML_PACKAGE | OP_IS_RESOURCE_DESC; 1218228110Sjkim UtSetParseOpName (Op); 1219118611Snjl 1220118611Snjl BufferLengthOp->Asl.ParseOpcode = PARSEOP_INTEGER; 1221118611Snjl BufferLengthOp->Asl.Value.Integer = CurrentByteOffset; 1222118611Snjl (void) OpcSetOptimalIntegerSize (BufferLengthOp); 1223228110Sjkim UtSetParseOpName (BufferLengthOp); 1224118611Snjl 1225118611Snjl BufferOp->Asl.ParseOpcode = PARSEOP_RAW_DATA; 1226118611Snjl BufferOp->Asl.AmlOpcode = AML_RAW_DATA_CHAIN; 1227118611Snjl BufferOp->Asl.AmlOpcodeLength = 0; 1228118611Snjl BufferOp->Asl.AmlLength = CurrentByteOffset; 1229118611Snjl BufferOp->Asl.Value.Buffer = (UINT8 *) HeadRnode.Next; 1230322877Sjkim BufferOp->Asl.CompileFlags |= OP_IS_RESOURCE_DATA; 1231228110Sjkim UtSetParseOpName (BufferOp); 1232118611Snjl 1233118611Snjl return; 1234118611Snjl} 1235