1118611Snjl/****************************************************************************** 2118611Snjl * 3207344Sjkim * Module Name: aslrestype2 - Miscellaneous Large resource descriptors 4118611Snjl * 5118611Snjl *****************************************************************************/ 6118611Snjl 7217365Sjkim/* 8245582Sjkim * Copyright (C) 2000 - 2013, Intel Corp. 9118611Snjl * All rights reserved. 10118611Snjl * 11217365Sjkim * Redistribution and use in source and binary forms, with or without 12217365Sjkim * modification, are permitted provided that the following conditions 13217365Sjkim * are met: 14217365Sjkim * 1. Redistributions of source code must retain the above copyright 15217365Sjkim * notice, this list of conditions, and the following disclaimer, 16217365Sjkim * without modification. 17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18217365Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 19217365Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 20217365Sjkim * including a substantially similar Disclaimer requirement for further 21217365Sjkim * binary redistribution. 22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 23217365Sjkim * of any contributors may be used to endorse or promote products derived 24217365Sjkim * from this software without specific prior written permission. 25118611Snjl * 26217365Sjkim * Alternatively, this software may be distributed under the terms of the 27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 28217365Sjkim * Software Foundation. 29118611Snjl * 30217365Sjkim * NO WARRANTY 31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41217365Sjkim * POSSIBILITY OF SUCH DAMAGES. 42217365Sjkim */ 43118611Snjl 44118611Snjl 45151937Sjkim#include <contrib/dev/acpica/compiler/aslcompiler.h> 46118611Snjl#include "aslcompiler.y.h" 47207344Sjkim#include <contrib/dev/acpica/include/amlcode.h> 48118611Snjl 49118611Snjl#define _COMPONENT ACPI_COMPILER 50118611Snjl ACPI_MODULE_NAME ("aslrestype2") 51118611Snjl 52207344Sjkim/* 53207344Sjkim * This module contains miscellaneous large resource descriptors: 54118611Snjl * 55207344Sjkim * Register 56207344Sjkim * Interrupt 57207344Sjkim * VendorLong 58207344Sjkim */ 59118611Snjl 60118611Snjl/******************************************************************************* 61118611Snjl * 62207344Sjkim * FUNCTION: RsDoGeneralRegisterDescriptor 63118611Snjl * 64118611Snjl * PARAMETERS: Op - Parent resource descriptor parse node 65118611Snjl * CurrentByteOffset - Offset into the resource template AML 66118611Snjl * buffer (to track references to the desc) 67118611Snjl * 68118611Snjl * RETURN: Completed resource node 69118611Snjl * 70207344Sjkim * DESCRIPTION: Construct a long "Register" descriptor 71118611Snjl * 72118611Snjl ******************************************************************************/ 73118611Snjl 74118611SnjlASL_RESOURCE_NODE * 75207344SjkimRsDoGeneralRegisterDescriptor ( 76118611Snjl ACPI_PARSE_OBJECT *Op, 77118611Snjl UINT32 CurrentByteOffset) 78118611Snjl{ 79151937Sjkim AML_RESOURCE *Descriptor; 80118611Snjl ACPI_PARSE_OBJECT *InitializerOp; 81118611Snjl ASL_RESOURCE_NODE *Rnode; 82118611Snjl UINT32 i; 83118611Snjl 84118611Snjl 85118611Snjl InitializerOp = Op->Asl.Child; 86207344Sjkim Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_GENERIC_REGISTER)); 87118611Snjl 88118611Snjl Descriptor = Rnode->Buffer; 89207344Sjkim Descriptor->GenericReg.DescriptorType = ACPI_RESOURCE_NAME_GENERIC_REGISTER; 90207344Sjkim Descriptor->GenericReg.ResourceLength = 12; 91118611Snjl 92151937Sjkim /* Process all child initialization nodes */ 93151937Sjkim 94118611Snjl for (i = 0; InitializerOp; i++) 95118611Snjl { 96118611Snjl switch (i) 97118611Snjl { 98207344Sjkim case 0: /* Address space */ 99118611Snjl 100207344Sjkim Descriptor->GenericReg.AddressSpaceId = (UINT8) InitializerOp->Asl.Value.Integer; 101207344Sjkim RsCreateByteField (InitializerOp, ACPI_RESTAG_ADDRESSSPACE, 102207344Sjkim CurrentByteOffset + ASL_RESDESC_OFFSET (GenericReg.AddressSpaceId)); 103151937Sjkim break; 104151937Sjkim 105207344Sjkim case 1: /* Register Bit Width */ 106151937Sjkim 107207344Sjkim Descriptor->GenericReg.BitWidth = (UINT8) InitializerOp->Asl.Value.Integer; 108207344Sjkim RsCreateByteField (InitializerOp, ACPI_RESTAG_REGISTERBITWIDTH, 109207344Sjkim CurrentByteOffset + ASL_RESDESC_OFFSET (GenericReg.BitWidth)); 110151937Sjkim break; 111151937Sjkim 112207344Sjkim case 2: /* Register Bit Offset */ 113151937Sjkim 114207344Sjkim Descriptor->GenericReg.BitOffset = (UINT8) InitializerOp->Asl.Value.Integer; 115207344Sjkim RsCreateByteField (InitializerOp, ACPI_RESTAG_REGISTERBITOFFSET, 116207344Sjkim CurrentByteOffset + ASL_RESDESC_OFFSET (GenericReg.BitOffset)); 117151937Sjkim break; 118151937Sjkim 119207344Sjkim case 3: /* Register Address */ 120151937Sjkim 121207344Sjkim Descriptor->GenericReg.Address = InitializerOp->Asl.Value.Integer; 122228110Sjkim RsCreateQwordField (InitializerOp, ACPI_RESTAG_ADDRESS, 123207344Sjkim CurrentByteOffset + ASL_RESDESC_OFFSET (GenericReg.Address)); 124151937Sjkim break; 125151937Sjkim 126207344Sjkim case 4: /* Access Size (ACPI 3.0) */ 127151937Sjkim 128207344Sjkim Descriptor->GenericReg.AccessSize = (UINT8) InitializerOp->Asl.Value.Integer; 129207344Sjkim RsCreateByteField (InitializerOp, ACPI_RESTAG_ACCESSSIZE, 130207344Sjkim CurrentByteOffset + ASL_RESDESC_OFFSET (GenericReg.AccessSize)); 131151937Sjkim 132207344Sjkim if (Descriptor->GenericReg.AccessSize > AML_FIELD_ACCESS_QWORD) 133118611Snjl { 134207344Sjkim AslError (ASL_ERROR, ASL_MSG_INVALID_ACCESS_SIZE, 135151937Sjkim InitializerOp, NULL); 136151937Sjkim } 137118611Snjl break; 138118611Snjl 139207344Sjkim case 5: /* ResourceTag (ACPI 3.0b) */ 140118611Snjl 141118611Snjl UtAttachNamepathToOwner (Op, InitializerOp); 142118611Snjl break; 143118611Snjl 144118611Snjl default: 145118611Snjl 146118611Snjl AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL); 147118611Snjl break; 148118611Snjl } 149118611Snjl 150118611Snjl InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 151118611Snjl } 152118611Snjl return (Rnode); 153118611Snjl} 154118611Snjl 155118611Snjl 156118611Snjl/******************************************************************************* 157118611Snjl * 158118611Snjl * FUNCTION: RsDoInterruptDescriptor 159118611Snjl * 160118611Snjl * PARAMETERS: Op - Parent resource descriptor parse node 161118611Snjl * CurrentByteOffset - Offset into the resource template AML 162118611Snjl * buffer (to track references to the desc) 163118611Snjl * 164118611Snjl * RETURN: Completed resource node 165118611Snjl * 166118611Snjl * DESCRIPTION: Construct a long "Interrupt" descriptor 167118611Snjl * 168118611Snjl ******************************************************************************/ 169118611Snjl 170118611SnjlASL_RESOURCE_NODE * 171118611SnjlRsDoInterruptDescriptor ( 172118611Snjl ACPI_PARSE_OBJECT *Op, 173118611Snjl UINT32 CurrentByteOffset) 174118611Snjl{ 175151937Sjkim AML_RESOURCE *Descriptor; 176151937Sjkim AML_RESOURCE *Rover = NULL; 177118611Snjl ACPI_PARSE_OBJECT *InitializerOp; 178118611Snjl ASL_RESOURCE_NODE *Rnode; 179151937Sjkim UINT16 StringLength = 0; 180118611Snjl UINT32 OptionIndex = 0; 181118611Snjl UINT32 i; 182118611Snjl BOOLEAN HasResSourceIndex = FALSE; 183118611Snjl UINT8 ResSourceIndex = 0; 184118611Snjl UINT8 *ResSourceString = NULL; 185118611Snjl 186118611Snjl 187118611Snjl InitializerOp = Op->Asl.Child; 188118611Snjl StringLength = RsGetStringDataLength (InitializerOp); 189118611Snjl 190118611Snjl /* Count the interrupt numbers */ 191118611Snjl 192118611Snjl for (i = 0; InitializerOp; i++) 193118611Snjl { 194118611Snjl InitializerOp = ASL_GET_PEER_NODE (InitializerOp); 195193529Sjkim 196118611Snjl if (i <= 6) 197118611Snjl { 198193529Sjkim if (i == 3 && 199193529Sjkim InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) 200193529Sjkim { 201193529Sjkim /* 202193529Sjkim * ResourceSourceIndex was specified, always make room for 203193529Sjkim * it, even if the ResourceSource was omitted. 204193529Sjkim */ 205193529Sjkim OptionIndex++; 206193529Sjkim } 207193529Sjkim 208118611Snjl continue; 209118611Snjl } 210118611Snjl 211118611Snjl OptionIndex += 4; 212118611Snjl } 213118611Snjl 214118611Snjl InitializerOp = Op->Asl.Child; 215151937Sjkim Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_EXTENDED_IRQ) + 216151937Sjkim 1 + OptionIndex + StringLength); 217151937Sjkim 218118611Snjl Descriptor = Rnode->Buffer; 219151937Sjkim Descriptor->ExtendedIrq.DescriptorType = ACPI_RESOURCE_NAME_EXTENDED_IRQ; 220118611Snjl 221118611Snjl /* 222118611Snjl * Initial descriptor length -- may be enlarged if there are 223118611Snjl * optional fields present 224118611Snjl */ 225151937Sjkim Descriptor->ExtendedIrq.ResourceLength = 2; /* Flags and table length byte */ 226151937Sjkim Descriptor->ExtendedIrq.InterruptCount = 0; 227118611Snjl 228151937Sjkim Rover = ACPI_CAST_PTR (AML_RESOURCE, 229151937Sjkim (&(Descriptor->ExtendedIrq.Interrupts[0]))); 230118611Snjl 231151937Sjkim /* Process all child initialization nodes */ 232151937Sjkim 233118611Snjl for (i = 0; InitializerOp; i++) 234118611Snjl { 235118611Snjl switch (i) 236118611Snjl { 237151937Sjkim case 0: /* Resource Usage (Default: consumer (1) */ 238118611Snjl 239151937Sjkim RsSetFlagBits (&Descriptor->ExtendedIrq.Flags, InitializerOp, 0, 1); 240118611Snjl break; 241118611Snjl 242118611Snjl case 1: /* Interrupt Type (or Mode - edge/level) */ 243118611Snjl 244151937Sjkim RsSetFlagBits (&Descriptor->ExtendedIrq.Flags, InitializerOp, 1, 0); 245167802Sjkim RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTTYPE, 246151937Sjkim CurrentByteOffset + ASL_RESDESC_OFFSET (ExtendedIrq.Flags), 1); 247118611Snjl break; 248118611Snjl 249118611Snjl case 2: /* Interrupt Level (or Polarity - Active high/low) */ 250118611Snjl 251151937Sjkim RsSetFlagBits (&Descriptor->ExtendedIrq.Flags, InitializerOp, 2, 0); 252167802Sjkim RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTLEVEL, 253151937Sjkim CurrentByteOffset + ASL_RESDESC_OFFSET (ExtendedIrq.Flags), 2); 254118611Snjl break; 255118611Snjl 256118611Snjl case 3: /* Share Type - Default: exclusive (0) */ 257118611Snjl 258151937Sjkim RsSetFlagBits (&Descriptor->ExtendedIrq.Flags, InitializerOp, 3, 0); 259167802Sjkim RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE, 260151937Sjkim CurrentByteOffset + ASL_RESDESC_OFFSET (ExtendedIrq.Flags), 3); 261118611Snjl break; 262118611Snjl 263118611Snjl case 4: /* ResSourceIndex [Optional Field - BYTE] */ 264118611Snjl 265118611Snjl if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) 266118611Snjl { 267118611Snjl HasResSourceIndex = TRUE; 268118611Snjl ResSourceIndex = (UINT8) InitializerOp->Asl.Value.Integer; 269118611Snjl } 270118611Snjl break; 271118611Snjl 272118611Snjl case 5: /* ResSource [Optional Field - STRING] */ 273118611Snjl 274118611Snjl if ((InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) && 275118611Snjl (InitializerOp->Asl.Value.String)) 276118611Snjl { 277118611Snjl if (StringLength) 278118611Snjl { 279118611Snjl ResSourceString = (UINT8 *) InitializerOp->Asl.Value.String; 280118611Snjl } 281151937Sjkim 282151937Sjkim /* ResourceSourceIndex must also be valid */ 283151937Sjkim 284151937Sjkim if (!HasResSourceIndex) 285151937Sjkim { 286151937Sjkim AslError (ASL_ERROR, ASL_MSG_RESOURCE_INDEX, 287151937Sjkim InitializerOp, NULL); 288151937Sjkim } 289118611Snjl } 290151937Sjkim 291151937Sjkim#if 0 292151937Sjkim /* 293151937Sjkim * Not a valid ResourceSource, ResourceSourceIndex must also 294151937Sjkim * be invalid 295151937Sjkim */ 296151937Sjkim else if (HasResSourceIndex) 297151937Sjkim { 298151937Sjkim AslError (ASL_ERROR, ASL_MSG_RESOURCE_SOURCE, 299151937Sjkim InitializerOp, NULL); 300151937Sjkim } 301151937Sjkim#endif 302118611Snjl break; 303118611Snjl 304118611Snjl case 6: /* ResourceTag */ 305118611Snjl 306118611Snjl UtAttachNamepathToOwner (Op, InitializerOp); 307118611Snjl break; 308118611Snjl 309118611Snjl default: 310118611Snjl /* 311151937Sjkim * Interrupt Numbers come through here, repeatedly 312118611Snjl */ 313151937Sjkim 314151937Sjkim /* Maximum 255 interrupts allowed for this descriptor */ 315151937Sjkim 316151937Sjkim if (Descriptor->ExtendedIrq.InterruptCount == 255) 317151937Sjkim { 318151937Sjkim AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_LIST, 319151937Sjkim InitializerOp, NULL); 320151937Sjkim return (Rnode); 321151937Sjkim } 322151937Sjkim 323151937Sjkim /* Each interrupt number must be a 32-bit value */ 324151937Sjkim 325151937Sjkim if (InitializerOp->Asl.Value.Integer > ACPI_UINT32_MAX) 326151937Sjkim { 327151937Sjkim AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_NUMBER, 328151937Sjkim InitializerOp, NULL); 329151937Sjkim } 330151937Sjkim 331151937Sjkim /* Save the integer and move pointer to the next one */ 332151937Sjkim 333167802Sjkim Rover->DwordItem = (UINT32) InitializerOp->Asl.Value.Integer; 334167802Sjkim Rover = ACPI_ADD_PTR (AML_RESOURCE, &(Rover->DwordItem), 4); 335151937Sjkim Descriptor->ExtendedIrq.InterruptCount++; 336151937Sjkim Descriptor->ExtendedIrq.ResourceLength += 4; 337118611Snjl 338151937Sjkim /* Case 7: First interrupt number in list */ 339118611Snjl 340151937Sjkim if (i == 7) 341118611Snjl { 342193529Sjkim if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 343193529Sjkim { 344193529Sjkim /* Must be at least one interrupt */ 345193529Sjkim 346193529Sjkim AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_LIST_MIN, 347193529Sjkim InitializerOp, NULL); 348193529Sjkim } 349193529Sjkim 350151937Sjkim /* Check now for duplicates in list */ 351151937Sjkim 352151937Sjkim RsCheckListForDuplicates (InitializerOp); 353151937Sjkim 354151937Sjkim /* Create a named field at the start of the list */ 355151937Sjkim 356228110Sjkim RsCreateDwordField (InitializerOp, ACPI_RESTAG_INTERRUPT, 357151937Sjkim CurrentByteOffset + 358151937Sjkim ASL_RESDESC_OFFSET (ExtendedIrq.Interrupts[0])); 359118611Snjl } 360118611Snjl } 361118611Snjl 362118611Snjl InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 363118611Snjl } 364118611Snjl 365151937Sjkim 366151937Sjkim /* Add optional ResSourceIndex if present */ 367151937Sjkim 368118611Snjl if (HasResSourceIndex) 369118611Snjl { 370167802Sjkim Rover->ByteItem = ResSourceIndex; 371167802Sjkim Rover = ACPI_ADD_PTR (AML_RESOURCE, &(Rover->ByteItem), 1); 372151937Sjkim Descriptor->ExtendedIrq.ResourceLength += 1; 373118611Snjl } 374118611Snjl 375151937Sjkim /* Add optional ResSource string if present */ 376151937Sjkim 377118611Snjl if (StringLength && ResSourceString) 378118611Snjl { 379118611Snjl 380118611Snjl strcpy ((char *) Rover, (char *) ResSourceString); 381167802Sjkim Rover = ACPI_ADD_PTR ( 382167802Sjkim AML_RESOURCE, &(Rover->ByteItem), StringLength); 383151937Sjkim 384151937Sjkim Descriptor->ExtendedIrq.ResourceLength = (UINT16) 385151937Sjkim (Descriptor->ExtendedIrq.ResourceLength + StringLength); 386118611Snjl } 387118611Snjl 388151937Sjkim Rnode->BufferLength = (ASL_RESDESC_OFFSET (ExtendedIrq.Interrupts[0]) - 389151937Sjkim ASL_RESDESC_OFFSET (ExtendedIrq.DescriptorType)) 390118611Snjl + OptionIndex + StringLength; 391118611Snjl return (Rnode); 392118611Snjl} 393118611Snjl 394118611Snjl 395118611Snjl/******************************************************************************* 396118611Snjl * 397118611Snjl * FUNCTION: RsDoVendorLargeDescriptor 398118611Snjl * 399118611Snjl * PARAMETERS: Op - Parent resource descriptor parse node 400118611Snjl * CurrentByteOffset - Offset into the resource template AML 401118611Snjl * buffer (to track references to the desc) 402118611Snjl * 403118611Snjl * RETURN: Completed resource node 404118611Snjl * 405118611Snjl * DESCRIPTION: Construct a long "VendorLong" descriptor 406118611Snjl * 407118611Snjl ******************************************************************************/ 408118611Snjl 409118611SnjlASL_RESOURCE_NODE * 410118611SnjlRsDoVendorLargeDescriptor ( 411118611Snjl ACPI_PARSE_OBJECT *Op, 412118611Snjl UINT32 CurrentByteOffset) 413118611Snjl{ 414151937Sjkim AML_RESOURCE *Descriptor; 415118611Snjl ACPI_PARSE_OBJECT *InitializerOp; 416118611Snjl ASL_RESOURCE_NODE *Rnode; 417151937Sjkim UINT8 *VendorData; 418118611Snjl UINT32 i; 419118611Snjl 420118611Snjl 421118611Snjl /* Count the number of data bytes */ 422118611Snjl 423118611Snjl InitializerOp = Op->Asl.Child; 424118611Snjl InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 425118611Snjl 426118611Snjl for (i = 0; InitializerOp; i++) 427118611Snjl { 428167802Sjkim if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 429167802Sjkim { 430167802Sjkim break; 431167802Sjkim } 432118611Snjl InitializerOp = InitializerOp->Asl.Next; 433118611Snjl } 434118611Snjl 435118611Snjl InitializerOp = Op->Asl.Child; 436118611Snjl InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 437151937Sjkim Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_VENDOR_LARGE) + i); 438118611Snjl 439118611Snjl Descriptor = Rnode->Buffer; 440151937Sjkim Descriptor->VendorLarge.DescriptorType = ACPI_RESOURCE_NAME_VENDOR_LARGE; 441151937Sjkim Descriptor->VendorLarge.ResourceLength = (UINT16) i; 442118611Snjl 443151937Sjkim /* Point to end-of-descriptor for vendor data */ 444151937Sjkim 445151937Sjkim VendorData = ((UINT8 *) Descriptor) + sizeof (AML_RESOURCE_LARGE_HEADER); 446151937Sjkim 447151937Sjkim /* Process all child initialization nodes */ 448151937Sjkim 449118611Snjl for (i = 0; InitializerOp; i++) 450118611Snjl { 451167802Sjkim if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 452167802Sjkim { 453167802Sjkim break; 454167802Sjkim } 455167802Sjkim 456151937Sjkim VendorData[i] = (UINT8) InitializerOp->Asl.Value.Integer; 457118611Snjl InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 458118611Snjl } 459118611Snjl 460118611Snjl return (Rnode); 461118611Snjl} 462