1 /****************************************************************************** 2 * 3 * Module Name: aslrestype2 - Miscellaneous Large resource descriptors 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2014, 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 #include "aslcompiler.h" 45 #include "aslcompiler.y.h" 46 #include "amlcode.h" 47 48 #define _COMPONENT ACPI_COMPILER 49 ACPI_MODULE_NAME ("aslrestype2") 50 51 /* 52 * This module contains miscellaneous large resource descriptors: 53 * 54 * Register 55 * Interrupt 56 * VendorLong 57 */ 58 59 /******************************************************************************* 60 * 61 * FUNCTION: RsDoGeneralRegisterDescriptor 62 * 63 * PARAMETERS: Info - Parse Op and resource template offset 64 * 65 * RETURN: Completed resource node 66 * 67 * DESCRIPTION: Construct a long "Register" descriptor 68 * 69 ******************************************************************************/ 70 71 ASL_RESOURCE_NODE * 72 RsDoGeneralRegisterDescriptor ( 73 ASL_RESOURCE_INFO *Info) 74 { 75 AML_RESOURCE *Descriptor; 76 ACPI_PARSE_OBJECT *InitializerOp; 77 ASL_RESOURCE_NODE *Rnode; 78 UINT32 CurrentByteOffset; 79 UINT32 i; 80 81 82 InitializerOp = Info->DescriptorTypeOp->Asl.Child; 83 CurrentByteOffset = Info->CurrentByteOffset; 84 Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_GENERIC_REGISTER)); 85 86 Descriptor = Rnode->Buffer; 87 Descriptor->GenericReg.DescriptorType = ACPI_RESOURCE_NAME_GENERIC_REGISTER; 88 Descriptor->GenericReg.ResourceLength = 12; 89 90 /* Process all child initialization nodes */ 91 92 for (i = 0; InitializerOp; i++) 93 { 94 switch (i) 95 { 96 case 0: /* Address space */ 97 98 Descriptor->GenericReg.AddressSpaceId = (UINT8) InitializerOp->Asl.Value.Integer; 99 RsCreateByteField (InitializerOp, ACPI_RESTAG_ADDRESSSPACE, 100 CurrentByteOffset + ASL_RESDESC_OFFSET (GenericReg.AddressSpaceId)); 101 break; 102 103 case 1: /* Register Bit Width */ 104 105 Descriptor->GenericReg.BitWidth = (UINT8) InitializerOp->Asl.Value.Integer; 106 RsCreateByteField (InitializerOp, ACPI_RESTAG_REGISTERBITWIDTH, 107 CurrentByteOffset + ASL_RESDESC_OFFSET (GenericReg.BitWidth)); 108 break; 109 110 case 2: /* Register Bit Offset */ 111 112 Descriptor->GenericReg.BitOffset = (UINT8) InitializerOp->Asl.Value.Integer; 113 RsCreateByteField (InitializerOp, ACPI_RESTAG_REGISTERBITOFFSET, 114 CurrentByteOffset + ASL_RESDESC_OFFSET (GenericReg.BitOffset)); 115 break; 116 117 case 3: /* Register Address */ 118 119 Descriptor->GenericReg.Address = InitializerOp->Asl.Value.Integer; 120 RsCreateQwordField (InitializerOp, ACPI_RESTAG_ADDRESS, 121 CurrentByteOffset + ASL_RESDESC_OFFSET (GenericReg.Address)); 122 break; 123 124 case 4: /* Access Size (ACPI 3.0) */ 125 126 Descriptor->GenericReg.AccessSize = (UINT8) InitializerOp->Asl.Value.Integer; 127 RsCreateByteField (InitializerOp, ACPI_RESTAG_ACCESSSIZE, 128 CurrentByteOffset + ASL_RESDESC_OFFSET (GenericReg.AccessSize)); 129 130 if (Descriptor->GenericReg.AccessSize > AML_FIELD_ACCESS_QWORD) 131 { 132 AslError (ASL_ERROR, ASL_MSG_INVALID_ACCESS_SIZE, 133 InitializerOp, NULL); 134 } 135 break; 136 137 case 5: /* ResourceTag (ACPI 3.0b) */ 138 139 UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp); 140 break; 141 142 default: 143 144 AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL); 145 break; 146 } 147 148 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 149 } 150 return (Rnode); 151 } 152 153 154 /******************************************************************************* 155 * 156 * FUNCTION: RsDoInterruptDescriptor 157 * 158 * PARAMETERS: Info - Parse Op and resource template offset 159 * 160 * RETURN: Completed resource node 161 * 162 * DESCRIPTION: Construct a long "Interrupt" descriptor 163 * 164 ******************************************************************************/ 165 166 ASL_RESOURCE_NODE * 167 RsDoInterruptDescriptor ( 168 ASL_RESOURCE_INFO *Info) 169 { 170 AML_RESOURCE *Descriptor; 171 AML_RESOURCE *Rover = NULL; 172 ACPI_PARSE_OBJECT *InitializerOp; 173 ASL_RESOURCE_NODE *Rnode; 174 UINT16 StringLength = 0; 175 UINT32 OptionIndex = 0; 176 UINT32 CurrentByteOffset; 177 UINT32 i; 178 BOOLEAN HasResSourceIndex = FALSE; 179 UINT8 ResSourceIndex = 0; 180 UINT8 *ResSourceString = NULL; 181 182 183 InitializerOp = Info->DescriptorTypeOp->Asl.Child; 184 CurrentByteOffset = Info->CurrentByteOffset; 185 StringLength = RsGetStringDataLength (InitializerOp); 186 187 /* Count the interrupt numbers */ 188 189 for (i = 0; InitializerOp; i++) 190 { 191 InitializerOp = ASL_GET_PEER_NODE (InitializerOp); 192 193 if (i <= 6) 194 { 195 if (i == 3 && 196 InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) 197 { 198 /* 199 * ResourceSourceIndex was specified, always make room for 200 * it, even if the ResourceSource was omitted. 201 */ 202 OptionIndex++; 203 } 204 205 continue; 206 } 207 208 OptionIndex += 4; 209 } 210 211 InitializerOp = Info->DescriptorTypeOp->Asl.Child; 212 Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_EXTENDED_IRQ) + 213 1 + OptionIndex + StringLength); 214 215 Descriptor = Rnode->Buffer; 216 Descriptor->ExtendedIrq.DescriptorType = ACPI_RESOURCE_NAME_EXTENDED_IRQ; 217 218 /* 219 * Initial descriptor length -- may be enlarged if there are 220 * optional fields present 221 */ 222 Descriptor->ExtendedIrq.ResourceLength = 2; /* Flags and table length byte */ 223 Descriptor->ExtendedIrq.InterruptCount = 0; 224 225 Rover = ACPI_CAST_PTR (AML_RESOURCE, 226 (&(Descriptor->ExtendedIrq.Interrupts[0]))); 227 228 /* Process all child initialization nodes */ 229 230 for (i = 0; InitializerOp; i++) 231 { 232 switch (i) 233 { 234 case 0: /* Resource Usage (Default: consumer (1) */ 235 236 RsSetFlagBits (&Descriptor->ExtendedIrq.Flags, InitializerOp, 0, 1); 237 break; 238 239 case 1: /* Interrupt Type (or Mode - edge/level) */ 240 241 RsSetFlagBits (&Descriptor->ExtendedIrq.Flags, InitializerOp, 1, 0); 242 RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTTYPE, 243 CurrentByteOffset + ASL_RESDESC_OFFSET (ExtendedIrq.Flags), 1); 244 break; 245 246 case 2: /* Interrupt Level (or Polarity - Active high/low) */ 247 248 RsSetFlagBits (&Descriptor->ExtendedIrq.Flags, InitializerOp, 2, 0); 249 RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTLEVEL, 250 CurrentByteOffset + ASL_RESDESC_OFFSET (ExtendedIrq.Flags), 2); 251 break; 252 253 case 3: /* Share Type - Default: exclusive (0) */ 254 255 RsSetFlagBits (&Descriptor->ExtendedIrq.Flags, InitializerOp, 3, 0); 256 RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE, 257 CurrentByteOffset + ASL_RESDESC_OFFSET (ExtendedIrq.Flags), 3); 258 break; 259 260 case 4: /* ResSourceIndex [Optional Field - BYTE] */ 261 262 if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) 263 { 264 HasResSourceIndex = TRUE; 265 ResSourceIndex = (UINT8) InitializerOp->Asl.Value.Integer; 266 } 267 break; 268 269 case 5: /* ResSource [Optional Field - STRING] */ 270 271 if ((InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) && 272 (InitializerOp->Asl.Value.String)) 273 { 274 if (StringLength) 275 { 276 ResSourceString = (UINT8 *) InitializerOp->Asl.Value.String; 277 } 278 279 /* ResourceSourceIndex must also be valid */ 280 281 if (!HasResSourceIndex) 282 { 283 AslError (ASL_ERROR, ASL_MSG_RESOURCE_INDEX, 284 InitializerOp, NULL); 285 } 286 } 287 288 #if 0 289 /* 290 * Not a valid ResourceSource, ResourceSourceIndex must also 291 * be invalid 292 */ 293 else if (HasResSourceIndex) 294 { 295 AslError (ASL_ERROR, ASL_MSG_RESOURCE_SOURCE, 296 InitializerOp, NULL); 297 } 298 #endif 299 break; 300 301 case 6: /* ResourceTag */ 302 303 UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp); 304 break; 305 306 default: 307 /* 308 * Interrupt Numbers come through here, repeatedly 309 */ 310 311 /* Maximum 255 interrupts allowed for this descriptor */ 312 313 if (Descriptor->ExtendedIrq.InterruptCount == 255) 314 { 315 AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_LIST, 316 InitializerOp, NULL); 317 return (Rnode); 318 } 319 320 /* Each interrupt number must be a 32-bit value */ 321 322 if (InitializerOp->Asl.Value.Integer > ACPI_UINT32_MAX) 323 { 324 AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_NUMBER, 325 InitializerOp, NULL); 326 } 327 328 /* Save the integer and move pointer to the next one */ 329 330 Rover->DwordItem = (UINT32) InitializerOp->Asl.Value.Integer; 331 Rover = ACPI_ADD_PTR (AML_RESOURCE, &(Rover->DwordItem), 4); 332 Descriptor->ExtendedIrq.InterruptCount++; 333 Descriptor->ExtendedIrq.ResourceLength += 4; 334 335 /* Case 7: First interrupt number in list */ 336 337 if (i == 7) 338 { 339 if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 340 { 341 /* Must be at least one interrupt */ 342 343 AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_LIST_MIN, 344 InitializerOp, NULL); 345 } 346 347 /* Check now for duplicates in list */ 348 349 RsCheckListForDuplicates (InitializerOp); 350 351 /* Create a named field at the start of the list */ 352 353 RsCreateDwordField (InitializerOp, ACPI_RESTAG_INTERRUPT, 354 CurrentByteOffset + 355 ASL_RESDESC_OFFSET (ExtendedIrq.Interrupts[0])); 356 } 357 } 358 359 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 360 } 361 362 363 /* Add optional ResSourceIndex if present */ 364 365 if (HasResSourceIndex) 366 { 367 Rover->ByteItem = ResSourceIndex; 368 Rover = ACPI_ADD_PTR (AML_RESOURCE, &(Rover->ByteItem), 1); 369 Descriptor->ExtendedIrq.ResourceLength += 1; 370 } 371 372 /* Add optional ResSource string if present */ 373 374 if (StringLength && ResSourceString) 375 { 376 377 strcpy ((char *) Rover, (char *) ResSourceString); 378 Rover = ACPI_ADD_PTR ( 379 AML_RESOURCE, &(Rover->ByteItem), StringLength); 380 381 Descriptor->ExtendedIrq.ResourceLength = (UINT16) 382 (Descriptor->ExtendedIrq.ResourceLength + StringLength); 383 } 384 385 Rnode->BufferLength = (ASL_RESDESC_OFFSET (ExtendedIrq.Interrupts[0]) - 386 ASL_RESDESC_OFFSET (ExtendedIrq.DescriptorType)) 387 + OptionIndex + StringLength; 388 return (Rnode); 389 } 390 391 392 /******************************************************************************* 393 * 394 * FUNCTION: RsDoVendorLargeDescriptor 395 * 396 * PARAMETERS: Info - Parse Op and resource template offset 397 * 398 * RETURN: Completed resource node 399 * 400 * DESCRIPTION: Construct a long "VendorLong" descriptor 401 * 402 ******************************************************************************/ 403 404 ASL_RESOURCE_NODE * 405 RsDoVendorLargeDescriptor ( 406 ASL_RESOURCE_INFO *Info) 407 { 408 AML_RESOURCE *Descriptor; 409 ACPI_PARSE_OBJECT *InitializerOp; 410 ASL_RESOURCE_NODE *Rnode; 411 UINT8 *VendorData; 412 UINT32 i; 413 414 415 /* Count the number of data bytes */ 416 417 InitializerOp = Info->DescriptorTypeOp->Asl.Child; 418 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 419 420 for (i = 0; InitializerOp; i++) 421 { 422 if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 423 { 424 break; 425 } 426 InitializerOp = InitializerOp->Asl.Next; 427 } 428 429 InitializerOp = Info->DescriptorTypeOp->Asl.Child; 430 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 431 Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_VENDOR_LARGE) + i); 432 433 Descriptor = Rnode->Buffer; 434 Descriptor->VendorLarge.DescriptorType = ACPI_RESOURCE_NAME_VENDOR_LARGE; 435 Descriptor->VendorLarge.ResourceLength = (UINT16) i; 436 437 /* Point to end-of-descriptor for vendor data */ 438 439 VendorData = ((UINT8 *) Descriptor) + sizeof (AML_RESOURCE_LARGE_HEADER); 440 441 /* Process all child initialization nodes */ 442 443 for (i = 0; InitializerOp; i++) 444 { 445 if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 446 { 447 break; 448 } 449 450 VendorData[i] = (UINT8) InitializerOp->Asl.Value.Integer; 451 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 452 } 453 454 return (Rnode); 455 } 456