aslrestype2.c revision 245582
1285SN/A/****************************************************************************** 2462SN/A * 3285SN/A * Module Name: aslrestype2 - Miscellaneous Large resource descriptors 4285SN/A * 5285SN/A *****************************************************************************/ 6285SN/A 7285SN/A/* 8285SN/A * Copyright (C) 2000 - 2013, Intel Corp. 9285SN/A * All rights reserved. 10285SN/A * 11285SN/A * Redistribution and use in source and binary forms, with or without 12285SN/A * modification, are permitted provided that the following conditions 13285SN/A * are met: 14285SN/A * 1. Redistributions of source code must retain the above copyright 15285SN/A * notice, this list of conditions, and the following disclaimer, 16285SN/A * without modification. 17285SN/A * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18285SN/A * substantially similar to the "NO WARRANTY" disclaimer below 19285SN/A * ("Disclaimer") and any redistribution must be conditioned upon 20285SN/A * including a substantially similar Disclaimer requirement for further 21285SN/A * binary redistribution. 22285SN/A * 3. Neither the names of the above-listed copyright holders nor the names 23285SN/A * of any contributors may be used to endorse or promote products derived 24285SN/A * from this software without specific prior written permission. 25285SN/A * 26285SN/A * Alternatively, this software may be distributed under the terms of the 27285SN/A * GNU General Public License ("GPL") version 2 as published by the Free 28285SN/A * Software Foundation. 29285SN/A * 30285SN/A * NO WARRANTY 31396SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32396SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33396SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34396SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35396SN/A * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36285SN/A * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37285SN/A * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38285SN/A * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39285SN/A * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40285SN/A * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41285SN/A * POSSIBILITY OF SUCH DAMAGES. 42285SN/A */ 43285SN/A 44285SN/A 45285SN/A#include <contrib/dev/acpica/compiler/aslcompiler.h> 46285SN/A#include "aslcompiler.y.h" 47285SN/A#include <contrib/dev/acpica/include/amlcode.h> 48285SN/A 49285SN/A#define _COMPONENT ACPI_COMPILER 50285SN/A ACPI_MODULE_NAME ("aslrestype2") 51285SN/A 52285SN/A/* 53285SN/A * This module contains miscellaneous large resource descriptors: 54285SN/A * 55285SN/A * Register 56285SN/A * Interrupt 57285SN/A * VendorLong 58285SN/A */ 59285SN/A 60285SN/A/******************************************************************************* 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 74ASL_RESOURCE_NODE * 75RsDoGeneralRegisterDescriptor ( 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 170ASL_RESOURCE_NODE * 171RsDoInterruptDescriptor ( 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 409ASL_RESOURCE_NODE * 410RsDoVendorLargeDescriptor ( 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} 462