1 /****************************************************************************** 2 * 3 * Module Name: aslrestype2 - Miscellaneous Large resource descriptors 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2016, 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 151 return (Rnode); 152 } 153 154 155 /******************************************************************************* 156 * 157 * FUNCTION: RsDoInterruptDescriptor 158 * 159 * PARAMETERS: Info - Parse Op and resource template offset 160 * 161 * RETURN: Completed resource node 162 * 163 * DESCRIPTION: Construct a long "Interrupt" descriptor 164 * 165 ******************************************************************************/ 166 167 ASL_RESOURCE_NODE * 168 RsDoInterruptDescriptor ( 169 ASL_RESOURCE_INFO *Info) 170 { 171 AML_RESOURCE *Descriptor; 172 AML_RESOURCE *Rover = NULL; 173 ACPI_PARSE_OBJECT *InitializerOp; 174 ASL_RESOURCE_NODE *Rnode; 175 UINT16 StringLength = 0; 176 UINT32 OptionIndex = 0; 177 UINT32 CurrentByteOffset; 178 UINT32 i; 179 BOOLEAN HasResSourceIndex = FALSE; 180 UINT8 ResSourceIndex = 0; 181 UINT8 *ResSourceString = NULL; 182 183 184 InitializerOp = Info->DescriptorTypeOp->Asl.Child; 185 CurrentByteOffset = Info->CurrentByteOffset; 186 StringLength = RsGetStringDataLength (InitializerOp); 187 188 /* Count the interrupt numbers */ 189 190 for (i = 0; InitializerOp; i++) 191 { 192 InitializerOp = ASL_GET_PEER_NODE (InitializerOp); 193 194 if (i <= 6) 195 { 196 if (i == 3 && 197 InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) 198 { 199 /* 200 * ResourceSourceIndex was specified, always make room for 201 * it, even if the ResourceSource was omitted. 202 */ 203 OptionIndex++; 204 } 205 206 continue; 207 } 208 209 OptionIndex += 4; 210 } 211 212 InitializerOp = Info->DescriptorTypeOp->Asl.Child; 213 Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_EXTENDED_IRQ) + 214 1 + OptionIndex + StringLength); 215 216 Descriptor = Rnode->Buffer; 217 Descriptor->ExtendedIrq.DescriptorType = ACPI_RESOURCE_NAME_EXTENDED_IRQ; 218 219 /* 220 * Initial descriptor length -- may be enlarged if there are 221 * optional fields present 222 */ 223 Descriptor->ExtendedIrq.ResourceLength = 2; /* Flags and table length byte */ 224 Descriptor->ExtendedIrq.InterruptCount = 0; 225 226 Rover = ACPI_CAST_PTR (AML_RESOURCE, 227 (&(Descriptor->ExtendedIrq.Interrupts[0]))); 228 229 /* Process all child initialization nodes */ 230 231 for (i = 0; InitializerOp; i++) 232 { 233 switch (i) 234 { 235 case 0: /* Resource Usage (Default: consumer (1) */ 236 237 RsSetFlagBits (&Descriptor->ExtendedIrq.Flags, InitializerOp, 0, 1); 238 break; 239 240 case 1: /* Interrupt Type (or Mode - edge/level) */ 241 242 RsSetFlagBits (&Descriptor->ExtendedIrq.Flags, InitializerOp, 1, 0); 243 RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTTYPE, 244 CurrentByteOffset + ASL_RESDESC_OFFSET (ExtendedIrq.Flags), 1); 245 break; 246 247 case 2: /* Interrupt Level (or Polarity - Active high/low) */ 248 249 RsSetFlagBits (&Descriptor->ExtendedIrq.Flags, InitializerOp, 2, 0); 250 RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTLEVEL, 251 CurrentByteOffset + ASL_RESDESC_OFFSET (ExtendedIrq.Flags), 2); 252 break; 253 254 case 3: /* Share Type - Default: exclusive (0) */ 255 256 RsSetFlagBits (&Descriptor->ExtendedIrq.Flags, InitializerOp, 3, 0); 257 RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE, 258 CurrentByteOffset + ASL_RESDESC_OFFSET (ExtendedIrq.Flags), 3); 259 break; 260 261 case 4: /* ResSourceIndex [Optional Field - BYTE] */ 262 263 if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) 264 { 265 HasResSourceIndex = TRUE; 266 ResSourceIndex = (UINT8) InitializerOp->Asl.Value.Integer; 267 } 268 break; 269 270 case 5: /* ResSource [Optional Field - STRING] */ 271 272 if ((InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) && 273 (InitializerOp->Asl.Value.String)) 274 { 275 if (StringLength) 276 { 277 ResSourceString = (UINT8 *) InitializerOp->Asl.Value.String; 278 } 279 280 /* ResourceSourceIndex must also be valid */ 281 282 if (!HasResSourceIndex) 283 { 284 AslError (ASL_ERROR, ASL_MSG_RESOURCE_INDEX, 285 InitializerOp, NULL); 286 } 287 } 288 289 #if 0 290 /* 291 * Not a valid ResourceSource, ResourceSourceIndex must also 292 * be invalid 293 */ 294 else if (HasResSourceIndex) 295 { 296 AslError (ASL_ERROR, ASL_MSG_RESOURCE_SOURCE, 297 InitializerOp, NULL); 298 } 299 #endif 300 break; 301 302 case 6: /* ResourceTag */ 303 304 UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp); 305 break; 306 307 default: 308 /* 309 * Interrupt Numbers come through here, repeatedly 310 */ 311 312 /* Maximum 255 interrupts allowed for this descriptor */ 313 314 if (Descriptor->ExtendedIrq.InterruptCount == 255) 315 { 316 AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_LIST, 317 InitializerOp, NULL); 318 return (Rnode); 319 } 320 321 /* Each interrupt number must be a 32-bit value */ 322 323 if (InitializerOp->Asl.Value.Integer > ACPI_UINT32_MAX) 324 { 325 AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_NUMBER, 326 InitializerOp, NULL); 327 } 328 329 /* Save the integer and move pointer to the next one */ 330 331 Rover->DwordItem = (UINT32) InitializerOp->Asl.Value.Integer; 332 Rover = ACPI_ADD_PTR (AML_RESOURCE, &(Rover->DwordItem), 4); 333 Descriptor->ExtendedIrq.InterruptCount++; 334 Descriptor->ExtendedIrq.ResourceLength += 4; 335 336 /* Case 7: First interrupt number in list */ 337 338 if (i == 7) 339 { 340 if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 341 { 342 /* Must be at least one interrupt */ 343 344 AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_LIST_MIN, 345 InitializerOp, NULL); 346 } 347 348 /* Check now for duplicates in list */ 349 350 RsCheckListForDuplicates (InitializerOp); 351 352 /* Create a named field at the start of the list */ 353 354 RsCreateDwordField (InitializerOp, ACPI_RESTAG_INTERRUPT, 355 CurrentByteOffset + 356 ASL_RESDESC_OFFSET (ExtendedIrq.Interrupts[0])); 357 } 358 } 359 360 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 361 } 362 363 364 /* Add optional ResSourceIndex if present */ 365 366 if (HasResSourceIndex) 367 { 368 Rover->ByteItem = ResSourceIndex; 369 Rover = ACPI_ADD_PTR (AML_RESOURCE, &(Rover->ByteItem), 1); 370 Descriptor->ExtendedIrq.ResourceLength += 1; 371 } 372 373 /* Add optional ResSource string if present */ 374 375 if (StringLength && ResSourceString) 376 { 377 378 strcpy ((char *) Rover, (char *) ResSourceString); 379 Rover = ACPI_ADD_PTR ( 380 AML_RESOURCE, &(Rover->ByteItem), StringLength); 381 382 Descriptor->ExtendedIrq.ResourceLength = (UINT16) 383 (Descriptor->ExtendedIrq.ResourceLength + StringLength); 384 } 385 386 Rnode->BufferLength = 387 (ASL_RESDESC_OFFSET (ExtendedIrq.Interrupts[0]) - 388 ASL_RESDESC_OFFSET (ExtendedIrq.DescriptorType)) 389 + OptionIndex + StringLength; 390 return (Rnode); 391 } 392 393 394 /******************************************************************************* 395 * 396 * FUNCTION: RsDoVendorLargeDescriptor 397 * 398 * PARAMETERS: Info - Parse Op and resource template offset 399 * 400 * RETURN: Completed resource node 401 * 402 * DESCRIPTION: Construct a long "VendorLong" descriptor 403 * 404 ******************************************************************************/ 405 406 ASL_RESOURCE_NODE * 407 RsDoVendorLargeDescriptor ( 408 ASL_RESOURCE_INFO *Info) 409 { 410 AML_RESOURCE *Descriptor; 411 ACPI_PARSE_OBJECT *InitializerOp; 412 ASL_RESOURCE_NODE *Rnode; 413 UINT8 *VendorData; 414 UINT32 i; 415 416 417 /* Count the number of data bytes */ 418 419 InitializerOp = Info->DescriptorTypeOp->Asl.Child; 420 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 421 422 for (i = 0; InitializerOp; i++) 423 { 424 if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 425 { 426 break; 427 } 428 InitializerOp = InitializerOp->Asl.Next; 429 } 430 431 InitializerOp = Info->DescriptorTypeOp->Asl.Child; 432 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 433 Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_VENDOR_LARGE) + i); 434 435 Descriptor = Rnode->Buffer; 436 Descriptor->VendorLarge.DescriptorType = ACPI_RESOURCE_NAME_VENDOR_LARGE; 437 Descriptor->VendorLarge.ResourceLength = (UINT16) i; 438 439 /* Point to end-of-descriptor for vendor data */ 440 441 VendorData = ((UINT8 *) Descriptor) + sizeof (AML_RESOURCE_LARGE_HEADER); 442 443 /* Process all child initialization nodes */ 444 445 for (i = 0; InitializerOp; i++) 446 { 447 if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 448 { 449 break; 450 } 451 452 VendorData[i] = (UINT8) InitializerOp->Asl.Value.Integer; 453 InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 454 } 455 456 return (Rnode); 457 } 458