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