1 /****************************************************************************** 2 * 3 * Module Name: aslrestype2 - Miscellaneous Large resource descriptors 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2013, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 45 #include "aslcompiler.h" 46 #include "aslcompiler.y.h" 47 #include "amlcode.h" 48 49 #define _COMPONENT ACPI_COMPILER 50 ACPI_MODULE_NAME ("aslrestype2") 51 52 /* 53 * This module contains miscellaneous large resource descriptors: 54 * 55 * Register 56 * Interrupt 57 * VendorLong 58 */ 59 60 /******************************************************************************* 61 * 62 * FUNCTION: RsDoGeneralRegisterDescriptor 63 * 64 * PARAMETERS: Op - Parent resource descriptor parse node 65 * CurrentByteOffset - Offset into the resource template AML 66 * buffer (to track references to the desc) 67 * 68 * RETURN: Completed resource node 69 * 70 * DESCRIPTION: Construct a long "Register" descriptor 71 * 72 ******************************************************************************/ 73 74 ASL_RESOURCE_NODE * 75 RsDoGeneralRegisterDescriptor ( 76 ACPI_PARSE_OBJECT *Op, 77 UINT32 CurrentByteOffset) 78 { 79 AML_RESOURCE *Descriptor; 80 ACPI_PARSE_OBJECT *InitializerOp; 81 ASL_RESOURCE_NODE *Rnode; 82 UINT32 i; 83 84 85 InitializerOp = Op->Asl.Child; 86 Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_GENERIC_REGISTER)); 87 88 Descriptor = Rnode->Buffer; 89 Descriptor->GenericReg.DescriptorType = ACPI_RESOURCE_NAME_GENERIC_REGISTER; 90 Descriptor->GenericReg.ResourceLength = 12; 91 92 /* Process all child initialization nodes */ 93 94 for (i = 0; InitializerOp; i++) 95 { 96 switch (i) 97 { 98 case 0: /* Address space */ 99 100 Descriptor->GenericReg.AddressSpaceId = (UINT8) InitializerOp->Asl.Value.Integer; 101 RsCreateByteField (InitializerOp, ACPI_RESTAG_ADDRESSSPACE, 102 CurrentByteOffset + ASL_RESDESC_OFFSET (GenericReg.AddressSpaceId)); 103 break; 104 105 case 1: /* Register Bit Width */ 106 107 Descriptor->GenericReg.BitWidth = (UINT8) InitializerOp->Asl.Value.Integer; 108 RsCreateByteField (InitializerOp, ACPI_RESTAG_REGISTERBITWIDTH, 109 CurrentByteOffset + ASL_RESDESC_OFFSET (GenericReg.BitWidth)); 110 break; 111 112 case 2: /* Register Bit Offset */ 113 114 Descriptor->GenericReg.BitOffset = (UINT8) InitializerOp->Asl.Value.Integer; 115 RsCreateByteField (InitializerOp, ACPI_RESTAG_REGISTERBITOFFSET, 116 CurrentByteOffset + ASL_RESDESC_OFFSET (GenericReg.BitOffset)); 117 break; 118 119 case 3: /* Register Address */ 120 121 Descriptor->GenericReg.Address = InitializerOp->Asl.Value.Integer; 122 RsCreateQwordField (InitializerOp, ACPI_RESTAG_ADDRESS, 123 CurrentByteOffset + ASL_RESDESC_OFFSET (GenericReg.Address)); 124 break; 125 126 case 4: /* Access Size (ACPI 3.0) */ 127 128 Descriptor->GenericReg.AccessSize = (UINT8) InitializerOp->Asl.Value.Integer; 129 RsCreateByteField (InitializerOp, ACPI_RESTAG_ACCESSSIZE, 130 CurrentByteOffset + ASL_RESDESC_OFFSET (GenericReg.AccessSize)); 131 132 if (Descriptor->GenericReg.AccessSize > AML_FIELD_ACCESS_QWORD) 133 { 134 AslError (ASL_ERROR, ASL_MSG_INVALID_ACCESS_SIZE, 135 InitializerOp, NULL); 136 } 137 break; 138 139 case 5: /* ResourceTag (ACPI 3.0b) */ 140 141 UtAttachNamepathToOwner (Op, InitializerOp); 142 break; 143 144 default: 145 146 AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL); 147 break; 148 } 149 150 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 151 } 152 return (Rnode); 153 } 154 155 156 /******************************************************************************* 157 * 158 * FUNCTION: RsDoInterruptDescriptor 159 * 160 * PARAMETERS: Op - Parent resource descriptor parse node 161 * CurrentByteOffset - Offset into the resource template AML 162 * buffer (to track references to the desc) 163 * 164 * RETURN: Completed resource node 165 * 166 * DESCRIPTION: Construct a long "Interrupt" descriptor 167 * 168 ******************************************************************************/ 169 170 ASL_RESOURCE_NODE * 171 RsDoInterruptDescriptor ( 172 ACPI_PARSE_OBJECT *Op, 173 UINT32 CurrentByteOffset) 174 { 175 AML_RESOURCE *Descriptor; 176 AML_RESOURCE *Rover = NULL; 177 ACPI_PARSE_OBJECT *InitializerOp; 178 ASL_RESOURCE_NODE *Rnode; 179 UINT16 StringLength = 0; 180 UINT32 OptionIndex = 0; 181 UINT32 i; 182 BOOLEAN HasResSourceIndex = FALSE; 183 UINT8 ResSourceIndex = 0; 184 UINT8 *ResSourceString = NULL; 185 186 187 InitializerOp = Op->Asl.Child; 188 StringLength = RsGetStringDataLength (InitializerOp); 189 190 /* Count the interrupt numbers */ 191 192 for (i = 0; InitializerOp; i++) 193 { 194 InitializerOp = ASL_GET_PEER_NODE (InitializerOp); 195 196 if (i <= 6) 197 { 198 if (i == 3 && 199 InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) 200 { 201 /* 202 * ResourceSourceIndex was specified, always make room for 203 * it, even if the ResourceSource was omitted. 204 */ 205 OptionIndex++; 206 } 207 208 continue; 209 } 210 211 OptionIndex += 4; 212 } 213 214 InitializerOp = Op->Asl.Child; 215 Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_EXTENDED_IRQ) + 216 1 + OptionIndex + StringLength); 217 218 Descriptor = Rnode->Buffer; 219 Descriptor->ExtendedIrq.DescriptorType = ACPI_RESOURCE_NAME_EXTENDED_IRQ; 220 221 /* 222 * Initial descriptor length -- may be enlarged if there are 223 * optional fields present 224 */ 225 Descriptor->ExtendedIrq.ResourceLength = 2; /* Flags and table length byte */ 226 Descriptor->ExtendedIrq.InterruptCount = 0; 227 228 Rover = ACPI_CAST_PTR (AML_RESOURCE, 229 (&(Descriptor->ExtendedIrq.Interrupts[0]))); 230 231 /* Process all child initialization nodes */ 232 233 for (i = 0; InitializerOp; i++) 234 { 235 switch (i) 236 { 237 case 0: /* Resource Usage (Default: consumer (1) */ 238 239 RsSetFlagBits (&Descriptor->ExtendedIrq.Flags, InitializerOp, 0, 1); 240 break; 241 242 case 1: /* Interrupt Type (or Mode - edge/level) */ 243 244 RsSetFlagBits (&Descriptor->ExtendedIrq.Flags, InitializerOp, 1, 0); 245 RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTTYPE, 246 CurrentByteOffset + ASL_RESDESC_OFFSET (ExtendedIrq.Flags), 1); 247 break; 248 249 case 2: /* Interrupt Level (or Polarity - Active high/low) */ 250 251 RsSetFlagBits (&Descriptor->ExtendedIrq.Flags, InitializerOp, 2, 0); 252 RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTLEVEL, 253 CurrentByteOffset + ASL_RESDESC_OFFSET (ExtendedIrq.Flags), 2); 254 break; 255 256 case 3: /* Share Type - Default: exclusive (0) */ 257 258 RsSetFlagBits (&Descriptor->ExtendedIrq.Flags, InitializerOp, 3, 0); 259 RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE, 260 CurrentByteOffset + ASL_RESDESC_OFFSET (ExtendedIrq.Flags), 3); 261 break; 262 263 case 4: /* ResSourceIndex [Optional Field - BYTE] */ 264 265 if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) 266 { 267 HasResSourceIndex = TRUE; 268 ResSourceIndex = (UINT8) InitializerOp->Asl.Value.Integer; 269 } 270 break; 271 272 case 5: /* ResSource [Optional Field - STRING] */ 273 274 if ((InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) && 275 (InitializerOp->Asl.Value.String)) 276 { 277 if (StringLength) 278 { 279 ResSourceString = (UINT8 *) InitializerOp->Asl.Value.String; 280 } 281 282 /* ResourceSourceIndex must also be valid */ 283 284 if (!HasResSourceIndex) 285 { 286 AslError (ASL_ERROR, ASL_MSG_RESOURCE_INDEX, 287 InitializerOp, NULL); 288 } 289 } 290 291 #if 0 292 /* 293 * Not a valid ResourceSource, ResourceSourceIndex must also 294 * be invalid 295 */ 296 else if (HasResSourceIndex) 297 { 298 AslError (ASL_ERROR, ASL_MSG_RESOURCE_SOURCE, 299 InitializerOp, NULL); 300 } 301 #endif 302 break; 303 304 case 6: /* ResourceTag */ 305 306 UtAttachNamepathToOwner (Op, InitializerOp); 307 break; 308 309 default: 310 /* 311 * Interrupt Numbers come through here, repeatedly 312 */ 313 314 /* Maximum 255 interrupts allowed for this descriptor */ 315 316 if (Descriptor->ExtendedIrq.InterruptCount == 255) 317 { 318 AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_LIST, 319 InitializerOp, NULL); 320 return (Rnode); 321 } 322 323 /* Each interrupt number must be a 32-bit value */ 324 325 if (InitializerOp->Asl.Value.Integer > ACPI_UINT32_MAX) 326 { 327 AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_NUMBER, 328 InitializerOp, NULL); 329 } 330 331 /* Save the integer and move pointer to the next one */ 332 333 Rover->DwordItem = (UINT32) InitializerOp->Asl.Value.Integer; 334 Rover = ACPI_ADD_PTR (AML_RESOURCE, &(Rover->DwordItem), 4); 335 Descriptor->ExtendedIrq.InterruptCount++; 336 Descriptor->ExtendedIrq.ResourceLength += 4; 337 338 /* Case 7: First interrupt number in list */ 339 340 if (i == 7) 341 { 342 if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 343 { 344 /* Must be at least one interrupt */ 345 346 AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_LIST_MIN, 347 InitializerOp, NULL); 348 } 349 350 /* Check now for duplicates in list */ 351 352 RsCheckListForDuplicates (InitializerOp); 353 354 /* Create a named field at the start of the list */ 355 356 RsCreateDwordField (InitializerOp, ACPI_RESTAG_INTERRUPT, 357 CurrentByteOffset + 358 ASL_RESDESC_OFFSET (ExtendedIrq.Interrupts[0])); 359 } 360 } 361 362 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 363 } 364 365 366 /* Add optional ResSourceIndex if present */ 367 368 if (HasResSourceIndex) 369 { 370 Rover->ByteItem = ResSourceIndex; 371 Rover = ACPI_ADD_PTR (AML_RESOURCE, &(Rover->ByteItem), 1); 372 Descriptor->ExtendedIrq.ResourceLength += 1; 373 } 374 375 /* Add optional ResSource string if present */ 376 377 if (StringLength && ResSourceString) 378 { 379 380 strcpy ((char *) Rover, (char *) ResSourceString); 381 Rover = ACPI_ADD_PTR ( 382 AML_RESOURCE, &(Rover->ByteItem), StringLength); 383 384 Descriptor->ExtendedIrq.ResourceLength = (UINT16) 385 (Descriptor->ExtendedIrq.ResourceLength + StringLength); 386 } 387 388 Rnode->BufferLength = (ASL_RESDESC_OFFSET (ExtendedIrq.Interrupts[0]) - 389 ASL_RESDESC_OFFSET (ExtendedIrq.DescriptorType)) 390 + OptionIndex + StringLength; 391 return (Rnode); 392 } 393 394 395 /******************************************************************************* 396 * 397 * FUNCTION: RsDoVendorLargeDescriptor 398 * 399 * PARAMETERS: Op - Parent resource descriptor parse node 400 * CurrentByteOffset - Offset into the resource template AML 401 * buffer (to track references to the desc) 402 * 403 * RETURN: Completed resource node 404 * 405 * DESCRIPTION: Construct a long "VendorLong" descriptor 406 * 407 ******************************************************************************/ 408 409 ASL_RESOURCE_NODE * 410 RsDoVendorLargeDescriptor ( 411 ACPI_PARSE_OBJECT *Op, 412 UINT32 CurrentByteOffset) 413 { 414 AML_RESOURCE *Descriptor; 415 ACPI_PARSE_OBJECT *InitializerOp; 416 ASL_RESOURCE_NODE *Rnode; 417 UINT8 *VendorData; 418 UINT32 i; 419 420 421 /* Count the number of data bytes */ 422 423 InitializerOp = Op->Asl.Child; 424 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 425 426 for (i = 0; InitializerOp; i++) 427 { 428 if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 429 { 430 break; 431 } 432 InitializerOp = InitializerOp->Asl.Next; 433 } 434 435 InitializerOp = Op->Asl.Child; 436 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 437 Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_VENDOR_LARGE) + i); 438 439 Descriptor = Rnode->Buffer; 440 Descriptor->VendorLarge.DescriptorType = ACPI_RESOURCE_NAME_VENDOR_LARGE; 441 Descriptor->VendorLarge.ResourceLength = (UINT16) i; 442 443 /* Point to end-of-descriptor for vendor data */ 444 445 VendorData = ((UINT8 *) Descriptor) + sizeof (AML_RESOURCE_LARGE_HEADER); 446 447 /* Process all child initialization nodes */ 448 449 for (i = 0; InitializerOp; i++) 450 { 451 if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 452 { 453 break; 454 } 455 456 VendorData[i] = (UINT8) InitializerOp->Asl.Value.Integer; 457 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 458 } 459 460 return (Rnode); 461 }