1118611Snjl/****************************************************************************** 2118611Snjl * 3207344Sjkim * Module Name: aslresource - Resource template/descriptor utilities 4118611Snjl * 5118611Snjl *****************************************************************************/ 6118611Snjl 7217365Sjkim/* 8245582Sjkim * Copyright (C) 2000 - 2013, Intel Corp. 9118611Snjl * All rights reserved. 10118611Snjl * 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. 25118611Snjl * 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. 29118611Snjl * 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 */ 43118611Snjl 44118611Snjl 45151937Sjkim#include <contrib/dev/acpica/compiler/aslcompiler.h> 46118611Snjl#include "aslcompiler.y.h" 47193529Sjkim#include <contrib/dev/acpica/include/amlcode.h> 48118611Snjl 49118611Snjl 50118611Snjl#define _COMPONENT ACPI_COMPILER 51118611Snjl ACPI_MODULE_NAME ("aslresource") 52118611Snjl 53118611Snjl 54118611Snjl/******************************************************************************* 55118611Snjl * 56207344Sjkim * FUNCTION: RsSmallAddressCheck 57207344Sjkim * 58207344Sjkim * PARAMETERS: Minimum - Address Min value 59207344Sjkim * Maximum - Address Max value 60207344Sjkim * Length - Address range value 61207344Sjkim * Alignment - Address alignment value 62207344Sjkim * MinOp - Original Op for Address Min 63207344Sjkim * MaxOp - Original Op for Address Max 64207344Sjkim * LengthOp - Original Op for address range 65207344Sjkim * AlignOp - Original Op for address alignment. If 66207344Sjkim * NULL, means "zero value for alignment is 67207344Sjkim * OK, and means 64K alignment" (for 68207344Sjkim * Memory24 descriptor) 69213806Sjkim * Op - Parent Op for entire construct 70207344Sjkim * 71207344Sjkim * RETURN: None. Adds error messages to error log if necessary 72207344Sjkim * 73207344Sjkim * DESCRIPTION: Perform common value checks for "small" address descriptors. 74207344Sjkim * Currently: 75207344Sjkim * Io, Memory24, Memory32 76207344Sjkim * 77207344Sjkim ******************************************************************************/ 78207344Sjkim 79207344Sjkimvoid 80207344SjkimRsSmallAddressCheck ( 81207344Sjkim UINT8 Type, 82207344Sjkim UINT32 Minimum, 83207344Sjkim UINT32 Maximum, 84207344Sjkim UINT32 Length, 85207344Sjkim UINT32 Alignment, 86207344Sjkim ACPI_PARSE_OBJECT *MinOp, 87207344Sjkim ACPI_PARSE_OBJECT *MaxOp, 88207344Sjkim ACPI_PARSE_OBJECT *LengthOp, 89213806Sjkim ACPI_PARSE_OBJECT *AlignOp, 90213806Sjkim ACPI_PARSE_OBJECT *Op) 91207344Sjkim{ 92207344Sjkim 93207344Sjkim if (Gbl_NoResourceChecking) 94207344Sjkim { 95207344Sjkim return; 96207344Sjkim } 97207344Sjkim 98213806Sjkim /* 99213806Sjkim * Check for a so-called "null descriptor". These are descriptors that are 100213806Sjkim * created with most fields set to zero. The intent is that the descriptor 101213806Sjkim * will be updated/completed at runtime via a BufferField. 102213806Sjkim * 103213806Sjkim * If the descriptor does NOT have a resource tag, it cannot be referenced 104213806Sjkim * by a BufferField and we will flag this as an error. Conversely, if 105213806Sjkim * the descriptor has a resource tag, we will assume that a BufferField 106213806Sjkim * will be used to dynamically update it, so no error. 107213806Sjkim * 108213806Sjkim * A possible enhancement to this check would be to verify that in fact 109213806Sjkim * a BufferField is created using the resource tag, and perhaps even 110213806Sjkim * verify that a Store is performed to the BufferField. 111213806Sjkim * 112213806Sjkim * Note: for these descriptors, Alignment is allowed to be zero 113213806Sjkim */ 114213806Sjkim if (!Minimum && !Maximum && !Length) 115213806Sjkim { 116213806Sjkim if (!Op->Asl.ExternalName) 117213806Sjkim { 118213806Sjkim /* No resource tag. Descriptor is fixed and is also illegal */ 119213806Sjkim 120213806Sjkim AslError (ASL_ERROR, ASL_MSG_NULL_DESCRIPTOR, Op, NULL); 121213806Sjkim } 122213806Sjkim 123213806Sjkim return; 124213806Sjkim } 125213806Sjkim 126207344Sjkim /* Special case for Memory24, values are compressed */ 127207344Sjkim 128207344Sjkim if (Type == ACPI_RESOURCE_NAME_MEMORY24) 129207344Sjkim { 130207344Sjkim if (!Alignment) /* Alignment==0 means 64K - no invalid alignment */ 131207344Sjkim { 132207344Sjkim Alignment = ACPI_UINT16_MAX + 1; 133207344Sjkim } 134207344Sjkim 135207344Sjkim Minimum <<= 8; 136207344Sjkim Maximum <<= 8; 137207344Sjkim Length *= 256; 138207344Sjkim } 139207344Sjkim 140207344Sjkim /* IO descriptor has different definition of min/max, don't check */ 141207344Sjkim 142207344Sjkim if (Type != ACPI_RESOURCE_NAME_IO) 143207344Sjkim { 144207344Sjkim /* Basic checks on Min/Max/Length */ 145207344Sjkim 146207344Sjkim if (Minimum > Maximum) 147207344Sjkim { 148207344Sjkim AslError (ASL_ERROR, ASL_MSG_INVALID_MIN_MAX, MinOp, NULL); 149207344Sjkim } 150207344Sjkim else if (Length > (Maximum - Minimum + 1)) 151207344Sjkim { 152207344Sjkim AslError (ASL_ERROR, ASL_MSG_INVALID_LENGTH, LengthOp, NULL); 153207344Sjkim } 154207344Sjkim } 155207344Sjkim 156207344Sjkim /* Alignment of zero is not in ACPI spec, but is used to mean byte acc */ 157207344Sjkim 158207344Sjkim if (!Alignment) 159207344Sjkim { 160207344Sjkim Alignment = 1; 161207344Sjkim } 162207344Sjkim 163207344Sjkim /* Addresses must be an exact multiple of the alignment value */ 164207344Sjkim 165207344Sjkim if (Minimum % Alignment) 166207344Sjkim { 167207344Sjkim AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MinOp, NULL); 168207344Sjkim } 169207344Sjkim if (Maximum % Alignment) 170207344Sjkim { 171207344Sjkim AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MaxOp, NULL); 172207344Sjkim } 173207344Sjkim} 174207344Sjkim 175207344Sjkim 176207344Sjkim/******************************************************************************* 177207344Sjkim * 178207344Sjkim * FUNCTION: RsLargeAddressCheck 179207344Sjkim * 180207344Sjkim * PARAMETERS: Minimum - Address Min value 181207344Sjkim * Maximum - Address Max value 182207344Sjkim * Length - Address range value 183207344Sjkim * Granularity - Address granularity value 184207344Sjkim * Flags - General flags for address descriptors: 185207344Sjkim * _MIF, _MAF, _DEC 186207344Sjkim * MinOp - Original Op for Address Min 187207344Sjkim * MaxOp - Original Op for Address Max 188207344Sjkim * LengthOp - Original Op for address range 189207344Sjkim * GranOp - Original Op for address granularity 190213806Sjkim * Op - Parent Op for entire construct 191207344Sjkim * 192207344Sjkim * RETURN: None. Adds error messages to error log if necessary 193207344Sjkim * 194207344Sjkim * DESCRIPTION: Perform common value checks for "large" address descriptors. 195207344Sjkim * Currently: 196207344Sjkim * WordIo, WordBusNumber, WordSpace 197207344Sjkim * DWordIo, DWordMemory, DWordSpace 198207344Sjkim * QWordIo, QWordMemory, QWordSpace 199207344Sjkim * ExtendedIo, ExtendedMemory, ExtendedSpace 200207344Sjkim * 201207344Sjkim * _MIF flag set means that the minimum address is fixed and is not relocatable 202207344Sjkim * _MAF flag set means that the maximum address is fixed and is not relocatable 203207344Sjkim * Length of zero means that the record size is variable 204207344Sjkim * 205207344Sjkim * This function implements the LEN/MIF/MAF/MIN/MAX/GRA rules within Table 6-40 206207344Sjkim * of the ACPI 4.0a specification. Added 04/2010. 207207344Sjkim * 208207344Sjkim ******************************************************************************/ 209207344Sjkim 210207344Sjkimvoid 211207344SjkimRsLargeAddressCheck ( 212207344Sjkim UINT64 Minimum, 213207344Sjkim UINT64 Maximum, 214207344Sjkim UINT64 Length, 215207344Sjkim UINT64 Granularity, 216207344Sjkim UINT8 Flags, 217207344Sjkim ACPI_PARSE_OBJECT *MinOp, 218207344Sjkim ACPI_PARSE_OBJECT *MaxOp, 219207344Sjkim ACPI_PARSE_OBJECT *LengthOp, 220213806Sjkim ACPI_PARSE_OBJECT *GranOp, 221213806Sjkim ACPI_PARSE_OBJECT *Op) 222207344Sjkim{ 223207344Sjkim 224207344Sjkim if (Gbl_NoResourceChecking) 225207344Sjkim { 226207344Sjkim return; 227207344Sjkim } 228207344Sjkim 229213806Sjkim /* 230213806Sjkim * Check for a so-called "null descriptor". These are descriptors that are 231213806Sjkim * created with most fields set to zero. The intent is that the descriptor 232213806Sjkim * will be updated/completed at runtime via a BufferField. 233213806Sjkim * 234213806Sjkim * If the descriptor does NOT have a resource tag, it cannot be referenced 235213806Sjkim * by a BufferField and we will flag this as an error. Conversely, if 236213806Sjkim * the descriptor has a resource tag, we will assume that a BufferField 237213806Sjkim * will be used to dynamically update it, so no error. 238213806Sjkim * 239213806Sjkim * A possible enhancement to this check would be to verify that in fact 240213806Sjkim * a BufferField is created using the resource tag, and perhaps even 241213806Sjkim * verify that a Store is performed to the BufferField. 242213806Sjkim */ 243213806Sjkim if (!Minimum && !Maximum && !Length && !Granularity) 244213806Sjkim { 245213806Sjkim if (!Op->Asl.ExternalName) 246213806Sjkim { 247213806Sjkim /* No resource tag. Descriptor is fixed and is also illegal */ 248213806Sjkim 249213806Sjkim AslError (ASL_ERROR, ASL_MSG_NULL_DESCRIPTOR, Op, NULL); 250213806Sjkim } 251213806Sjkim 252213806Sjkim return; 253213806Sjkim } 254213806Sjkim 255207344Sjkim /* Basic checks on Min/Max/Length */ 256207344Sjkim 257207344Sjkim if (Minimum > Maximum) 258207344Sjkim { 259207344Sjkim AslError (ASL_ERROR, ASL_MSG_INVALID_MIN_MAX, MinOp, NULL); 260207344Sjkim return; 261207344Sjkim } 262207344Sjkim else if (Length > (Maximum - Minimum + 1)) 263207344Sjkim { 264207344Sjkim AslError (ASL_ERROR, ASL_MSG_INVALID_LENGTH, LengthOp, NULL); 265207344Sjkim return; 266207344Sjkim } 267207344Sjkim 268207344Sjkim /* If specified (non-zero), ensure granularity is a power-of-two minus one */ 269207344Sjkim 270207344Sjkim if (Granularity) 271207344Sjkim { 272207344Sjkim if ((Granularity + 1) & 273207344Sjkim Granularity) 274207344Sjkim { 275207344Sjkim AslError (ASL_ERROR, ASL_MSG_INVALID_GRANULARITY, GranOp, NULL); 276207344Sjkim return; 277207344Sjkim } 278207344Sjkim } 279207344Sjkim 280207344Sjkim /* 281207344Sjkim * Check the various combinations of Length, MinFixed, and MaxFixed 282207344Sjkim */ 283207344Sjkim if (Length) 284207344Sjkim { 285207344Sjkim /* Fixed non-zero length */ 286207344Sjkim 287207344Sjkim switch (Flags & (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF)) 288207344Sjkim { 289207344Sjkim case 0: 290207344Sjkim /* 291207344Sjkim * Fixed length, variable locations (both _MIN and _MAX). 292207344Sjkim * Length must be a multiple of granularity 293207344Sjkim */ 294207344Sjkim if (Granularity & Length) 295207344Sjkim { 296207344Sjkim AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, LengthOp, NULL); 297207344Sjkim } 298207344Sjkim break; 299207344Sjkim 300207344Sjkim case (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF): 301207344Sjkim 302207344Sjkim /* Fixed length, fixed location. Granularity must be zero */ 303207344Sjkim 304207344Sjkim if (Granularity != 0) 305207344Sjkim { 306207344Sjkim AslError (ASL_ERROR, ASL_MSG_INVALID_GRAN_FIXED, GranOp, NULL); 307207344Sjkim } 308207344Sjkim 309207344Sjkim /* Length must be exactly the size of the min/max window */ 310207344Sjkim 311207344Sjkim if (Length != (Maximum - Minimum + 1)) 312207344Sjkim { 313207344Sjkim AslError (ASL_ERROR, ASL_MSG_INVALID_LENGTH_FIXED, LengthOp, NULL); 314207344Sjkim } 315207344Sjkim break; 316207344Sjkim 317207344Sjkim /* All other combinations are invalid */ 318207344Sjkim 319207344Sjkim case ACPI_RESOURCE_FLAG_MIF: 320207344Sjkim case ACPI_RESOURCE_FLAG_MAF: 321207344Sjkim default: 322250838Sjkim 323207344Sjkim AslError (ASL_ERROR, ASL_MSG_INVALID_ADDR_FLAGS, LengthOp, NULL); 324207344Sjkim } 325207344Sjkim } 326207344Sjkim else 327207344Sjkim { 328207344Sjkim /* Variable length (length==0) */ 329207344Sjkim 330207344Sjkim switch (Flags & (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF)) 331207344Sjkim { 332207344Sjkim case 0: 333207344Sjkim /* 334207344Sjkim * Both _MIN and _MAX are variable. 335207344Sjkim * No additional requirements, just exit 336207344Sjkim */ 337207344Sjkim break; 338207344Sjkim 339207344Sjkim case ACPI_RESOURCE_FLAG_MIF: 340207344Sjkim 341207344Sjkim /* _MIN is fixed. _MIN must be multiple of _GRA */ 342207344Sjkim 343207344Sjkim /* 344207344Sjkim * The granularity is defined by the ACPI specification to be a 345207344Sjkim * power-of-two minus one, therefore the granularity is a 346207344Sjkim * bitmask which can be used to easily validate the addresses. 347207344Sjkim */ 348207344Sjkim if (Granularity & Minimum) 349207344Sjkim { 350207344Sjkim AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MinOp, NULL); 351207344Sjkim } 352207344Sjkim break; 353207344Sjkim 354207344Sjkim case ACPI_RESOURCE_FLAG_MAF: 355207344Sjkim 356207344Sjkim /* _MAX is fixed. (_MAX + 1) must be multiple of _GRA */ 357207344Sjkim 358207344Sjkim if (Granularity & (Maximum + 1)) 359207344Sjkim { 360207344Sjkim AslError (ASL_ERROR, ASL_MSG_ALIGNMENT, MaxOp, "-1"); 361207344Sjkim } 362207344Sjkim break; 363207344Sjkim 364207344Sjkim /* Both MIF/MAF set is invalid if length is zero */ 365207344Sjkim 366207344Sjkim case (ACPI_RESOURCE_FLAG_MIF | ACPI_RESOURCE_FLAG_MAF): 367207344Sjkim default: 368250838Sjkim 369207344Sjkim AslError (ASL_ERROR, ASL_MSG_INVALID_ADDR_FLAGS, LengthOp, NULL); 370207344Sjkim } 371207344Sjkim } 372207344Sjkim} 373207344Sjkim 374207344Sjkim 375207344Sjkim/******************************************************************************* 376207344Sjkim * 377207344Sjkim * FUNCTION: RsGetStringDataLength 378207344Sjkim * 379207344Sjkim * PARAMETERS: InitializerOp - Start of a subtree of init nodes 380207344Sjkim * 381207344Sjkim * RETURN: Valid string length if a string node is found (otherwise 0) 382207344Sjkim * 383207344Sjkim * DESCRIPTION: In a list of peer nodes, find the first one that contains a 384207344Sjkim * string and return the length of the string. 385207344Sjkim * 386207344Sjkim ******************************************************************************/ 387207344Sjkim 388207344SjkimUINT16 389207344SjkimRsGetStringDataLength ( 390207344Sjkim ACPI_PARSE_OBJECT *InitializerOp) 391207344Sjkim{ 392207344Sjkim 393207344Sjkim while (InitializerOp) 394207344Sjkim { 395207344Sjkim if (InitializerOp->Asl.ParseOpcode == PARSEOP_STRING_LITERAL) 396207344Sjkim { 397207344Sjkim return ((UINT16) (strlen (InitializerOp->Asl.Value.String) + 1)); 398207344Sjkim } 399207344Sjkim InitializerOp = ASL_GET_PEER_NODE (InitializerOp); 400207344Sjkim } 401207344Sjkim 402241973Sjkim return (0); 403207344Sjkim} 404207344Sjkim 405207344Sjkim 406207344Sjkim/******************************************************************************* 407207344Sjkim * 408118611Snjl * FUNCTION: RsAllocateResourceNode 409118611Snjl * 410118611Snjl * PARAMETERS: Size - Size of node in bytes 411118611Snjl * 412118611Snjl * RETURN: The allocated node - aborts on allocation failure 413118611Snjl * 414118611Snjl * DESCRIPTION: Allocate a resource description node and the resource 415118611Snjl * descriptor itself (the nodes are used to link descriptors). 416118611Snjl * 417118611Snjl ******************************************************************************/ 418118611Snjl 419118611SnjlASL_RESOURCE_NODE * 420118611SnjlRsAllocateResourceNode ( 421118611Snjl UINT32 Size) 422118611Snjl{ 423118611Snjl ASL_RESOURCE_NODE *Rnode; 424118611Snjl 425118611Snjl 426118611Snjl /* Allocate the node */ 427118611Snjl 428118611Snjl Rnode = UtLocalCalloc (sizeof (ASL_RESOURCE_NODE)); 429118611Snjl 430118611Snjl /* Allocate the resource descriptor itself */ 431118611Snjl 432118611Snjl Rnode->Buffer = UtLocalCalloc (Size); 433118611Snjl Rnode->BufferLength = Size; 434118611Snjl 435118611Snjl return (Rnode); 436118611Snjl} 437118611Snjl 438118611Snjl 439118611Snjl/******************************************************************************* 440118611Snjl * 441228110Sjkim * FUNCTION: RsCreateResourceField 442118611Snjl * 443151937Sjkim * PARAMETERS: Op - Resource field node 444118611Snjl * Name - Name of the field (Used only to reference 445118611Snjl * the field in the ASL, not in the AML) 446118611Snjl * ByteOffset - Offset from the field start 447118611Snjl * BitOffset - Additional bit offset 448228110Sjkim * BitLength - Number of bits in the field 449118611Snjl * 450118611Snjl * RETURN: None, sets fields within the input node 451118611Snjl * 452118611Snjl * DESCRIPTION: Utility function to generate a named bit field within a 453241973Sjkim * resource descriptor. Mark a node as 1) a field in a resource 454118611Snjl * descriptor, and 2) set the value to be a BIT offset 455118611Snjl * 456118611Snjl ******************************************************************************/ 457118611Snjl 458118611Snjlvoid 459228110SjkimRsCreateResourceField ( 460118611Snjl ACPI_PARSE_OBJECT *Op, 461118611Snjl char *Name, 462118611Snjl UINT32 ByteOffset, 463228110Sjkim UINT32 BitOffset, 464228110Sjkim UINT32 BitLength) 465118611Snjl{ 466118611Snjl 467228110Sjkim Op->Asl.ExternalName = Name; 468228110Sjkim Op->Asl.CompileFlags |= NODE_IS_RESOURCE_FIELD; 469118611Snjl 470118611Snjl 471228110Sjkim Op->Asl.Value.Tag.BitOffset = (ByteOffset * 8) + BitOffset; 472228110Sjkim Op->Asl.Value.Tag.BitLength = BitLength; 473118611Snjl} 474118611Snjl 475118611Snjl 476118611Snjl/******************************************************************************* 477118611Snjl * 478118611Snjl * FUNCTION: RsSetFlagBits 479118611Snjl * 480118611Snjl * PARAMETERS: *Flags - Pointer to the flag byte 481151937Sjkim * Op - Flag initialization node 482118611Snjl * Position - Bit position within the flag byte 483118611Snjl * Default - Used if the node is DEFAULT. 484118611Snjl * 485118611Snjl * RETURN: Sets bits within the *Flags output byte. 486118611Snjl * 487118611Snjl * DESCRIPTION: Set a bit in a cumulative flags word from an initialization 488241973Sjkim * node. Will use a default value if the node is DEFAULT, meaning 489241973Sjkim * that no value was specified in the ASL. Used to merge multiple 490118611Snjl * keywords into a single flags byte. 491118611Snjl * 492118611Snjl ******************************************************************************/ 493118611Snjl 494118611Snjlvoid 495118611SnjlRsSetFlagBits ( 496118611Snjl UINT8 *Flags, 497118611Snjl ACPI_PARSE_OBJECT *Op, 498118611Snjl UINT8 Position, 499118611Snjl UINT8 DefaultBit) 500118611Snjl{ 501118611Snjl 502118611Snjl if (Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 503118611Snjl { 504118611Snjl /* Use the default bit */ 505118611Snjl 506118611Snjl *Flags |= (DefaultBit << Position); 507118611Snjl } 508118611Snjl else 509118611Snjl { 510118611Snjl /* Use the bit specified in the initialization node */ 511118611Snjl 512118611Snjl *Flags |= (((UINT8) Op->Asl.Value.Integer) << Position); 513118611Snjl } 514118611Snjl} 515118611Snjl 516118611Snjl 517228110Sjkimvoid 518228110SjkimRsSetFlagBits16 ( 519228110Sjkim UINT16 *Flags, 520228110Sjkim ACPI_PARSE_OBJECT *Op, 521228110Sjkim UINT8 Position, 522228110Sjkim UINT8 DefaultBit) 523228110Sjkim{ 524228110Sjkim 525228110Sjkim if (Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 526228110Sjkim { 527228110Sjkim /* Use the default bit */ 528228110Sjkim 529228110Sjkim *Flags |= (DefaultBit << Position); 530228110Sjkim } 531228110Sjkim else 532228110Sjkim { 533228110Sjkim /* Use the bit specified in the initialization node */ 534228110Sjkim 535228110Sjkim *Flags |= (((UINT16) Op->Asl.Value.Integer) << Position); 536228110Sjkim } 537228110Sjkim} 538228110Sjkim 539228110Sjkim 540118611Snjl/******************************************************************************* 541118611Snjl * 542118611Snjl * FUNCTION: RsCompleteNodeAndGetNext 543118611Snjl * 544118611Snjl * PARAMETERS: Op - Resource node to be completed 545118611Snjl * 546118611Snjl * RETURN: The next peer to the input node. 547118611Snjl * 548118611Snjl * DESCRIPTION: Mark the current node completed and return the next peer. 549118611Snjl * The node ParseOpcode is set to DEFAULT_ARG, meaning that 550118611Snjl * this node is to be ignored from now on. 551118611Snjl * 552118611Snjl ******************************************************************************/ 553118611Snjl 554118611SnjlACPI_PARSE_OBJECT * 555118611SnjlRsCompleteNodeAndGetNext ( 556118611Snjl ACPI_PARSE_OBJECT *Op) 557118611Snjl{ 558118611Snjl 559118611Snjl /* Mark this node unused */ 560118611Snjl 561118611Snjl Op->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 562118611Snjl 563118611Snjl /* Move on to the next peer node in the initializer list */ 564118611Snjl 565118611Snjl return (ASL_GET_PEER_NODE (Op)); 566118611Snjl} 567118611Snjl 568118611Snjl 569118611Snjl/******************************************************************************* 570118611Snjl * 571151937Sjkim * FUNCTION: RsCheckListForDuplicates 572151937Sjkim * 573151937Sjkim * PARAMETERS: Op - First op in the initializer list 574151937Sjkim * 575151937Sjkim * RETURN: None 576151937Sjkim * 577151937Sjkim * DESCRIPTION: Check an initializer list for duplicate values. Emits an error 578151937Sjkim * if any duplicates are found. 579151937Sjkim * 580151937Sjkim ******************************************************************************/ 581151937Sjkim 582151937Sjkimvoid 583151937SjkimRsCheckListForDuplicates ( 584151937Sjkim ACPI_PARSE_OBJECT *Op) 585151937Sjkim{ 586151937Sjkim ACPI_PARSE_OBJECT *NextValueOp = Op; 587151937Sjkim ACPI_PARSE_OBJECT *NextOp; 588151937Sjkim UINT32 Value; 589151937Sjkim 590151937Sjkim 591151937Sjkim if (!Op) 592151937Sjkim { 593151937Sjkim return; 594151937Sjkim } 595151937Sjkim 596151937Sjkim /* Search list once for each value in the list */ 597151937Sjkim 598151937Sjkim while (NextValueOp) 599151937Sjkim { 600151937Sjkim Value = (UINT32) NextValueOp->Asl.Value.Integer; 601151937Sjkim 602151937Sjkim /* Compare this value to all remaining values in the list */ 603151937Sjkim 604151937Sjkim NextOp = ASL_GET_PEER_NODE (NextValueOp); 605151937Sjkim while (NextOp) 606151937Sjkim { 607151937Sjkim if (NextOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) 608151937Sjkim { 609151937Sjkim /* Compare values */ 610151937Sjkim 611151937Sjkim if (Value == (UINT32) NextOp->Asl.Value.Integer) 612151937Sjkim { 613151937Sjkim /* Emit error only once per duplicate node */ 614151937Sjkim 615151937Sjkim if (!(NextOp->Asl.CompileFlags & NODE_IS_DUPLICATE)) 616151937Sjkim { 617151937Sjkim NextOp->Asl.CompileFlags |= NODE_IS_DUPLICATE; 618151937Sjkim AslError (ASL_ERROR, ASL_MSG_DUPLICATE_ITEM, 619151937Sjkim NextOp, NULL); 620151937Sjkim } 621151937Sjkim } 622151937Sjkim } 623151937Sjkim 624151937Sjkim NextOp = ASL_GET_PEER_NODE (NextOp); 625151937Sjkim } 626151937Sjkim 627151937Sjkim NextValueOp = ASL_GET_PEER_NODE (NextValueOp); 628151937Sjkim } 629151937Sjkim} 630151937Sjkim 631151937Sjkim 632151937Sjkim/******************************************************************************* 633151937Sjkim * 634118611Snjl * FUNCTION: RsDoOneResourceDescriptor 635118611Snjl * 636118611Snjl * PARAMETERS: DescriptorTypeOp - Parent parse node of the descriptor 637118611Snjl * CurrentByteOffset - Offset in the resource descriptor 638118611Snjl * buffer. 639118611Snjl * 640118611Snjl * RETURN: A valid resource node for the descriptor 641118611Snjl * 642118611Snjl * DESCRIPTION: Dispatches the processing of one resource descriptor 643118611Snjl * 644118611Snjl ******************************************************************************/ 645118611Snjl 646118611SnjlASL_RESOURCE_NODE * 647118611SnjlRsDoOneResourceDescriptor ( 648118611Snjl ACPI_PARSE_OBJECT *DescriptorTypeOp, 649118611Snjl UINT32 CurrentByteOffset, 650118611Snjl UINT8 *State) 651118611Snjl{ 652118611Snjl ASL_RESOURCE_NODE *Rnode = NULL; 653118611Snjl 654118611Snjl 655167802Sjkim /* Construct the resource */ 656118611Snjl 657118611Snjl switch (DescriptorTypeOp->Asl.ParseOpcode) 658118611Snjl { 659118611Snjl case PARSEOP_DMA: 660250838Sjkim 661151937Sjkim Rnode = RsDoDmaDescriptor (DescriptorTypeOp, 662151937Sjkim CurrentByteOffset); 663118611Snjl break; 664118611Snjl 665228110Sjkim case PARSEOP_FIXEDDMA: 666250838Sjkim 667228110Sjkim Rnode = RsDoFixedDmaDescriptor (DescriptorTypeOp, 668228110Sjkim CurrentByteOffset); 669228110Sjkim break; 670228110Sjkim 671118611Snjl case PARSEOP_DWORDIO: 672250838Sjkim 673151937Sjkim Rnode = RsDoDwordIoDescriptor (DescriptorTypeOp, 674151937Sjkim CurrentByteOffset); 675118611Snjl break; 676118611Snjl 677118611Snjl case PARSEOP_DWORDMEMORY: 678250838Sjkim 679151937Sjkim Rnode = RsDoDwordMemoryDescriptor (DescriptorTypeOp, 680151937Sjkim CurrentByteOffset); 681118611Snjl break; 682118611Snjl 683151937Sjkim case PARSEOP_DWORDSPACE: 684250838Sjkim 685151937Sjkim Rnode = RsDoDwordSpaceDescriptor (DescriptorTypeOp, 686151937Sjkim CurrentByteOffset); 687151937Sjkim break; 688151937Sjkim 689118611Snjl case PARSEOP_ENDDEPENDENTFN: 690250838Sjkim 691118611Snjl switch (*State) 692118611Snjl { 693118611Snjl case ACPI_RSTATE_NORMAL: 694250838Sjkim 695151937Sjkim AslError (ASL_ERROR, ASL_MSG_MISSING_STARTDEPENDENT, 696151937Sjkim DescriptorTypeOp, NULL); 697118611Snjl break; 698118611Snjl 699118611Snjl case ACPI_RSTATE_START_DEPENDENT: 700250838Sjkim 701151937Sjkim AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING, 702151937Sjkim DescriptorTypeOp, NULL); 703118611Snjl break; 704118611Snjl 705118611Snjl case ACPI_RSTATE_DEPENDENT_LIST: 706118611Snjl default: 707250838Sjkim 708118611Snjl break; 709118611Snjl } 710118611Snjl 711118611Snjl *State = ACPI_RSTATE_NORMAL; 712151937Sjkim Rnode = RsDoEndDependentDescriptor (DescriptorTypeOp, 713151937Sjkim CurrentByteOffset); 714118611Snjl break; 715118611Snjl 716167802Sjkim case PARSEOP_ENDTAG: 717250838Sjkim 718167802Sjkim Rnode = RsDoEndTagDescriptor (DescriptorTypeOp, 719167802Sjkim CurrentByteOffset); 720167802Sjkim break; 721167802Sjkim 722151937Sjkim case PARSEOP_EXTENDEDIO: 723250838Sjkim 724151937Sjkim Rnode = RsDoExtendedIoDescriptor (DescriptorTypeOp, 725151937Sjkim CurrentByteOffset); 726151937Sjkim break; 727151937Sjkim 728151937Sjkim case PARSEOP_EXTENDEDMEMORY: 729250838Sjkim 730151937Sjkim Rnode = RsDoExtendedMemoryDescriptor (DescriptorTypeOp, 731151937Sjkim CurrentByteOffset); 732151937Sjkim break; 733151937Sjkim 734151937Sjkim case PARSEOP_EXTENDEDSPACE: 735250838Sjkim 736151937Sjkim Rnode = RsDoExtendedSpaceDescriptor (DescriptorTypeOp, 737151937Sjkim CurrentByteOffset); 738151937Sjkim break; 739151937Sjkim 740118611Snjl case PARSEOP_FIXEDIO: 741250838Sjkim 742151937Sjkim Rnode = RsDoFixedIoDescriptor (DescriptorTypeOp, 743151937Sjkim CurrentByteOffset); 744118611Snjl break; 745118611Snjl 746118611Snjl case PARSEOP_INTERRUPT: 747250838Sjkim 748151937Sjkim Rnode = RsDoInterruptDescriptor (DescriptorTypeOp, 749151937Sjkim CurrentByteOffset); 750118611Snjl break; 751118611Snjl 752118611Snjl case PARSEOP_IO: 753250838Sjkim 754151937Sjkim Rnode = RsDoIoDescriptor (DescriptorTypeOp, 755151937Sjkim CurrentByteOffset); 756118611Snjl break; 757118611Snjl 758118611Snjl case PARSEOP_IRQ: 759250838Sjkim 760151937Sjkim Rnode = RsDoIrqDescriptor (DescriptorTypeOp, 761151937Sjkim CurrentByteOffset); 762118611Snjl break; 763118611Snjl 764118611Snjl case PARSEOP_IRQNOFLAGS: 765250838Sjkim 766151937Sjkim Rnode = RsDoIrqNoFlagsDescriptor (DescriptorTypeOp, 767151937Sjkim CurrentByteOffset); 768118611Snjl break; 769118611Snjl 770118611Snjl case PARSEOP_MEMORY24: 771250838Sjkim 772151937Sjkim Rnode = RsDoMemory24Descriptor (DescriptorTypeOp, 773151937Sjkim CurrentByteOffset); 774118611Snjl break; 775118611Snjl 776118611Snjl case PARSEOP_MEMORY32: 777250838Sjkim 778151937Sjkim Rnode = RsDoMemory32Descriptor (DescriptorTypeOp, 779151937Sjkim CurrentByteOffset); 780118611Snjl break; 781118611Snjl 782118611Snjl case PARSEOP_MEMORY32FIXED: 783250838Sjkim 784151937Sjkim Rnode = RsDoMemory32FixedDescriptor (DescriptorTypeOp, 785151937Sjkim CurrentByteOffset); 786118611Snjl break; 787118611Snjl 788118611Snjl case PARSEOP_QWORDIO: 789250838Sjkim 790151937Sjkim Rnode = RsDoQwordIoDescriptor (DescriptorTypeOp, 791151937Sjkim CurrentByteOffset); 792118611Snjl break; 793118611Snjl 794118611Snjl case PARSEOP_QWORDMEMORY: 795250838Sjkim 796151937Sjkim Rnode = RsDoQwordMemoryDescriptor (DescriptorTypeOp, 797151937Sjkim CurrentByteOffset); 798118611Snjl break; 799118611Snjl 800151937Sjkim case PARSEOP_QWORDSPACE: 801250838Sjkim 802151937Sjkim Rnode = RsDoQwordSpaceDescriptor (DescriptorTypeOp, 803151937Sjkim CurrentByteOffset); 804151937Sjkim break; 805151937Sjkim 806118611Snjl case PARSEOP_REGISTER: 807250838Sjkim 808151937Sjkim Rnode = RsDoGeneralRegisterDescriptor (DescriptorTypeOp, 809151937Sjkim CurrentByteOffset); 810118611Snjl break; 811118611Snjl 812118611Snjl case PARSEOP_STARTDEPENDENTFN: 813250838Sjkim 814118611Snjl switch (*State) 815118611Snjl { 816118611Snjl case ACPI_RSTATE_START_DEPENDENT: 817250838Sjkim 818151937Sjkim AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING, 819151937Sjkim DescriptorTypeOp, NULL); 820118611Snjl break; 821118611Snjl 822118611Snjl case ACPI_RSTATE_NORMAL: 823118611Snjl case ACPI_RSTATE_DEPENDENT_LIST: 824118611Snjl default: 825250838Sjkim 826118611Snjl break; 827118611Snjl } 828118611Snjl 829118611Snjl *State = ACPI_RSTATE_START_DEPENDENT; 830151937Sjkim Rnode = RsDoStartDependentDescriptor (DescriptorTypeOp, 831151937Sjkim CurrentByteOffset); 832118611Snjl *State = ACPI_RSTATE_DEPENDENT_LIST; 833118611Snjl break; 834118611Snjl 835118611Snjl case PARSEOP_STARTDEPENDENTFN_NOPRI: 836250838Sjkim 837118611Snjl switch (*State) 838118611Snjl { 839118611Snjl case ACPI_RSTATE_START_DEPENDENT: 840250838Sjkim 841151937Sjkim AslError (ASL_ERROR, ASL_MSG_DEPENDENT_NESTING, 842151937Sjkim DescriptorTypeOp, NULL); 843118611Snjl break; 844118611Snjl 845118611Snjl case ACPI_RSTATE_NORMAL: 846118611Snjl case ACPI_RSTATE_DEPENDENT_LIST: 847118611Snjl default: 848250838Sjkim 849118611Snjl break; 850118611Snjl } 851118611Snjl 852118611Snjl *State = ACPI_RSTATE_START_DEPENDENT; 853151937Sjkim Rnode = RsDoStartDependentNoPriDescriptor (DescriptorTypeOp, 854151937Sjkim CurrentByteOffset); 855118611Snjl *State = ACPI_RSTATE_DEPENDENT_LIST; 856118611Snjl break; 857118611Snjl 858118611Snjl case PARSEOP_VENDORLONG: 859250838Sjkim 860151937Sjkim Rnode = RsDoVendorLargeDescriptor (DescriptorTypeOp, 861151937Sjkim CurrentByteOffset); 862118611Snjl break; 863118611Snjl 864118611Snjl case PARSEOP_VENDORSHORT: 865250838Sjkim 866151937Sjkim Rnode = RsDoVendorSmallDescriptor (DescriptorTypeOp, 867151937Sjkim CurrentByteOffset); 868118611Snjl break; 869118611Snjl 870118611Snjl case PARSEOP_WORDBUSNUMBER: 871250838Sjkim 872151937Sjkim Rnode = RsDoWordBusNumberDescriptor (DescriptorTypeOp, 873151937Sjkim CurrentByteOffset); 874118611Snjl break; 875118611Snjl 876118611Snjl case PARSEOP_WORDIO: 877250838Sjkim 878151937Sjkim Rnode = RsDoWordIoDescriptor (DescriptorTypeOp, 879151937Sjkim CurrentByteOffset); 880118611Snjl break; 881118611Snjl 882151937Sjkim case PARSEOP_WORDSPACE: 883250838Sjkim 884151937Sjkim Rnode = RsDoWordSpaceDescriptor (DescriptorTypeOp, 885151937Sjkim CurrentByteOffset); 886151937Sjkim break; 887151937Sjkim 888228110Sjkim case PARSEOP_GPIO_INT: 889250838Sjkim 890228110Sjkim Rnode = RsDoGpioIntDescriptor (DescriptorTypeOp, 891228110Sjkim CurrentByteOffset); 892228110Sjkim break; 893228110Sjkim 894228110Sjkim case PARSEOP_GPIO_IO: 895250838Sjkim 896228110Sjkim Rnode = RsDoGpioIoDescriptor (DescriptorTypeOp, 897228110Sjkim CurrentByteOffset); 898228110Sjkim break; 899228110Sjkim 900228110Sjkim case PARSEOP_I2C_SERIALBUS: 901250838Sjkim 902228110Sjkim Rnode = RsDoI2cSerialBusDescriptor (DescriptorTypeOp, 903228110Sjkim CurrentByteOffset); 904228110Sjkim break; 905228110Sjkim 906228110Sjkim case PARSEOP_SPI_SERIALBUS: 907250838Sjkim 908228110Sjkim Rnode = RsDoSpiSerialBusDescriptor (DescriptorTypeOp, 909228110Sjkim CurrentByteOffset); 910228110Sjkim break; 911228110Sjkim 912228110Sjkim case PARSEOP_UART_SERIALBUS: 913250838Sjkim 914228110Sjkim Rnode = RsDoUartSerialBusDescriptor (DescriptorTypeOp, 915228110Sjkim CurrentByteOffset); 916228110Sjkim break; 917228110Sjkim 918118611Snjl case PARSEOP_DEFAULT_ARG: 919250838Sjkim 920118611Snjl /* Just ignore any of these, they are used as fillers/placeholders */ 921118611Snjl break; 922118611Snjl 923118611Snjl default: 924250838Sjkim 925118611Snjl printf ("Unknown resource descriptor type [%s]\n", 926118611Snjl DescriptorTypeOp->Asl.ParseOpName); 927118611Snjl break; 928118611Snjl } 929118611Snjl 930118611Snjl /* 931118611Snjl * Mark original node as unused, but head of a resource descriptor. 932118611Snjl * This allows the resource to be installed in the namespace so that 933118611Snjl * references to the descriptor can be resolved. 934118611Snjl */ 935118611Snjl DescriptorTypeOp->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 936118611Snjl DescriptorTypeOp->Asl.CompileFlags = NODE_IS_RESOURCE_DESC; 937167802Sjkim DescriptorTypeOp->Asl.Value.Integer = CurrentByteOffset; 938118611Snjl 939167802Sjkim if (Rnode) 940167802Sjkim { 941167802Sjkim DescriptorTypeOp->Asl.FinalAmlLength = Rnode->BufferLength; 942249112Sjkim DescriptorTypeOp->Asl.Extra = ((AML_RESOURCE *) Rnode->Buffer)->DescriptorType; 943167802Sjkim } 944167802Sjkim 945118611Snjl return (Rnode); 946118611Snjl} 947118611Snjl 948118611Snjl 949118611Snjl/******************************************************************************* 950118611Snjl * 951118611Snjl * FUNCTION: RsLinkDescriptorChain 952118611Snjl * 953118611Snjl * PARAMETERS: PreviousRnode - Pointer to the node that will be previous 954118611Snjl * to the linked node, At exit, set to the 955118611Snjl * last node in the new chain. 956118611Snjl * Rnode - Resource node to link into the list 957118611Snjl * 958118611Snjl * RETURN: Cumulative buffer byte offset of the new segment of chain 959118611Snjl * 960118611Snjl * DESCRIPTION: Link a descriptor chain at the end of an existing chain. 961118611Snjl * 962118611Snjl ******************************************************************************/ 963118611Snjl 964118611SnjlUINT32 965118611SnjlRsLinkDescriptorChain ( 966118611Snjl ASL_RESOURCE_NODE **PreviousRnode, 967118611Snjl ASL_RESOURCE_NODE *Rnode) 968118611Snjl{ 969118611Snjl ASL_RESOURCE_NODE *LastRnode; 970118611Snjl UINT32 CurrentByteOffset; 971118611Snjl 972118611Snjl 973118611Snjl /* Anything to do? */ 974118611Snjl 975118611Snjl if (!Rnode) 976118611Snjl { 977241973Sjkim return (0); 978118611Snjl } 979118611Snjl 980118611Snjl /* Point the previous node to the new node */ 981118611Snjl 982118611Snjl (*PreviousRnode)->Next = Rnode; 983118611Snjl CurrentByteOffset = Rnode->BufferLength; 984118611Snjl 985118611Snjl /* Walk to the end of the chain headed by Rnode */ 986118611Snjl 987118611Snjl LastRnode = Rnode; 988118611Snjl while (LastRnode->Next) 989118611Snjl { 990118611Snjl LastRnode = LastRnode->Next; 991118611Snjl CurrentByteOffset += LastRnode->BufferLength; 992118611Snjl } 993118611Snjl 994118611Snjl /* Previous node becomes the last node in the chain */ 995118611Snjl 996118611Snjl *PreviousRnode = LastRnode; 997241973Sjkim return (CurrentByteOffset); 998118611Snjl} 999118611Snjl 1000118611Snjl 1001118611Snjl/******************************************************************************* 1002118611Snjl * 1003118611Snjl * FUNCTION: RsDoResourceTemplate 1004118611Snjl * 1005118611Snjl * PARAMETERS: Op - Parent of a resource template list 1006118611Snjl * 1007241973Sjkim * RETURN: None. Sets input node to point to a list of AML code 1008118611Snjl * 1009118611Snjl * DESCRIPTION: Merge a list of resource descriptors into a single AML buffer, 1010118611Snjl * in preparation for output to the AML output file. 1011118611Snjl * 1012118611Snjl ******************************************************************************/ 1013118611Snjl 1014118611Snjlvoid 1015118611SnjlRsDoResourceTemplate ( 1016118611Snjl ACPI_PARSE_OBJECT *Op) 1017118611Snjl{ 1018118611Snjl ACPI_PARSE_OBJECT *BufferLengthOp; 1019118611Snjl ACPI_PARSE_OBJECT *BufferOp; 1020118611Snjl ACPI_PARSE_OBJECT *DescriptorTypeOp; 1021118611Snjl ACPI_PARSE_OBJECT *LastOp = NULL; 1022118611Snjl UINT32 CurrentByteOffset = 0; 1023118611Snjl ASL_RESOURCE_NODE HeadRnode; 1024118611Snjl ASL_RESOURCE_NODE *PreviousRnode; 1025118611Snjl ASL_RESOURCE_NODE *Rnode; 1026118611Snjl UINT8 State; 1027118611Snjl 1028118611Snjl 1029167802Sjkim /* Mark parent as containing a resource template */ 1030167802Sjkim 1031167802Sjkim if (Op->Asl.Parent) 1032167802Sjkim { 1033167802Sjkim Op->Asl.Parent->Asl.CompileFlags |= NODE_IS_RESOURCE_DESC; 1034167802Sjkim } 1035167802Sjkim 1036118611Snjl /* ResourceTemplate Opcode is first (Op) */ 1037118611Snjl /* Buffer Length node is first child */ 1038118611Snjl 1039118611Snjl BufferLengthOp = ASL_GET_CHILD_NODE (Op); 1040118611Snjl 1041118611Snjl /* Buffer Op is first peer */ 1042118611Snjl 1043118611Snjl BufferOp = ASL_GET_PEER_NODE (BufferLengthOp); 1044118611Snjl 1045118611Snjl /* First Descriptor type is next */ 1046118611Snjl 1047118611Snjl DescriptorTypeOp = ASL_GET_PEER_NODE (BufferOp); 1048118611Snjl 1049167802Sjkim /* 1050167802Sjkim * Process all resource descriptors in the list 1051167802Sjkim * Note: It is assumed that the EndTag node has been automatically 1052167802Sjkim * inserted at the end of the template by the parser. 1053167802Sjkim */ 1054118611Snjl State = ACPI_RSTATE_NORMAL; 1055118611Snjl PreviousRnode = &HeadRnode; 1056118611Snjl while (DescriptorTypeOp) 1057118611Snjl { 1058167802Sjkim DescriptorTypeOp->Asl.CompileFlags |= NODE_IS_RESOURCE_DESC; 1059151937Sjkim Rnode = RsDoOneResourceDescriptor (DescriptorTypeOp, CurrentByteOffset, 1060151937Sjkim &State); 1061118611Snjl 1062118611Snjl /* 1063118611Snjl * Update current byte offset to indicate the number of bytes from the 1064241973Sjkim * start of the buffer. Buffer can include multiple descriptors, we 1065118611Snjl * must keep track of the offset of not only each descriptor, but each 1066118611Snjl * element (field) within each descriptor as well. 1067118611Snjl */ 1068118611Snjl CurrentByteOffset += RsLinkDescriptorChain (&PreviousRnode, Rnode); 1069118611Snjl 1070118611Snjl /* Get the next descriptor in the list */ 1071118611Snjl 1072118611Snjl LastOp = DescriptorTypeOp; 1073118611Snjl DescriptorTypeOp = ASL_GET_PEER_NODE (DescriptorTypeOp); 1074118611Snjl } 1075118611Snjl 1076118611Snjl if (State == ACPI_RSTATE_DEPENDENT_LIST) 1077118611Snjl { 1078118611Snjl if (LastOp) 1079118611Snjl { 1080118611Snjl LastOp = LastOp->Asl.Parent; 1081118611Snjl } 1082118611Snjl AslError (ASL_ERROR, ASL_MSG_MISSING_ENDDEPENDENT, LastOp, NULL); 1083118611Snjl } 1084118611Snjl 1085118611Snjl /* 1086118611Snjl * Transform the nodes into the following 1087118611Snjl * 1088118611Snjl * Op -> AML_BUFFER_OP 1089118611Snjl * First Child -> BufferLength 1090118611Snjl * Second Child -> Descriptor Buffer (raw byte data) 1091118611Snjl */ 1092118611Snjl Op->Asl.ParseOpcode = PARSEOP_BUFFER; 1093118611Snjl Op->Asl.AmlOpcode = AML_BUFFER_OP; 1094167802Sjkim Op->Asl.CompileFlags = NODE_AML_PACKAGE | NODE_IS_RESOURCE_DESC; 1095228110Sjkim UtSetParseOpName (Op); 1096118611Snjl 1097118611Snjl BufferLengthOp->Asl.ParseOpcode = PARSEOP_INTEGER; 1098118611Snjl BufferLengthOp->Asl.Value.Integer = CurrentByteOffset; 1099118611Snjl (void) OpcSetOptimalIntegerSize (BufferLengthOp); 1100228110Sjkim UtSetParseOpName (BufferLengthOp); 1101118611Snjl 1102118611Snjl BufferOp->Asl.ParseOpcode = PARSEOP_RAW_DATA; 1103118611Snjl BufferOp->Asl.AmlOpcode = AML_RAW_DATA_CHAIN; 1104118611Snjl BufferOp->Asl.AmlOpcodeLength = 0; 1105118611Snjl BufferOp->Asl.AmlLength = CurrentByteOffset; 1106118611Snjl BufferOp->Asl.Value.Buffer = (UINT8 *) HeadRnode.Next; 1107167802Sjkim BufferOp->Asl.CompileFlags |= NODE_IS_RESOURCE_DATA; 1108228110Sjkim UtSetParseOpName (BufferOp); 1109118611Snjl 1110118611Snjl return; 1111118611Snjl} 1112