1118611Snjl 2118611Snjl/****************************************************************************** 3118611Snjl * 4207344Sjkim * Module Name: aslrestype2 - Miscellaneous Large resource descriptors 5118611Snjl * 6118611Snjl *****************************************************************************/ 7118611Snjl 8217365Sjkim/* 9217365Sjkim * Copyright (C) 2000 - 2011, Intel Corp. 10118611Snjl * All rights reserved. 11118611Snjl * 12217365Sjkim * Redistribution and use in source and binary forms, with or without 13217365Sjkim * modification, are permitted provided that the following conditions 14217365Sjkim * are met: 15217365Sjkim * 1. Redistributions of source code must retain the above copyright 16217365Sjkim * notice, this list of conditions, and the following disclaimer, 17217365Sjkim * without modification. 18217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 19217365Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 20217365Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 21217365Sjkim * including a substantially similar Disclaimer requirement for further 22217365Sjkim * binary redistribution. 23217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 24217365Sjkim * of any contributors may be used to endorse or promote products derived 25217365Sjkim * from this software without specific prior written permission. 26118611Snjl * 27217365Sjkim * Alternatively, this software may be distributed under the terms of the 28217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 29217365Sjkim * Software Foundation. 30118611Snjl * 31217365Sjkim * NO WARRANTY 32217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 33217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 34217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 35217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 36217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 37217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 38217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 39217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 40217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 41217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 42217365Sjkim * POSSIBILITY OF SUCH DAMAGES. 43217365Sjkim */ 44118611Snjl 45118611Snjl 46151937Sjkim#include <contrib/dev/acpica/compiler/aslcompiler.h> 47118611Snjl#include "aslcompiler.y.h" 48207344Sjkim#include <contrib/dev/acpica/include/amlcode.h> 49118611Snjl 50118611Snjl#define _COMPONENT ACPI_COMPILER 51118611Snjl ACPI_MODULE_NAME ("aslrestype2") 52118611Snjl 53207344Sjkim/* 54207344Sjkim * This module contains miscellaneous large resource descriptors: 55118611Snjl * 56207344Sjkim * Register 57207344Sjkim * Interrupt 58207344Sjkim * VendorLong 59207344Sjkim */ 60118611Snjl 61118611Snjl/******************************************************************************* 62118611Snjl * 63207344Sjkim * FUNCTION: RsDoGeneralRegisterDescriptor 64118611Snjl * 65118611Snjl * PARAMETERS: Op - Parent resource descriptor parse node 66118611Snjl * CurrentByteOffset - Offset into the resource template AML 67118611Snjl * buffer (to track references to the desc) 68118611Snjl * 69118611Snjl * RETURN: Completed resource node 70118611Snjl * 71207344Sjkim * DESCRIPTION: Construct a long "Register" descriptor 72118611Snjl * 73118611Snjl ******************************************************************************/ 74118611Snjl 75118611SnjlASL_RESOURCE_NODE * 76207344SjkimRsDoGeneralRegisterDescriptor ( 77118611Snjl ACPI_PARSE_OBJECT *Op, 78118611Snjl UINT32 CurrentByteOffset) 79118611Snjl{ 80151937Sjkim AML_RESOURCE *Descriptor; 81118611Snjl ACPI_PARSE_OBJECT *InitializerOp; 82118611Snjl ASL_RESOURCE_NODE *Rnode; 83118611Snjl UINT32 i; 84118611Snjl 85118611Snjl 86118611Snjl InitializerOp = Op->Asl.Child; 87207344Sjkim Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_GENERIC_REGISTER)); 88118611Snjl 89118611Snjl Descriptor = Rnode->Buffer; 90207344Sjkim Descriptor->GenericReg.DescriptorType = ACPI_RESOURCE_NAME_GENERIC_REGISTER; 91207344Sjkim Descriptor->GenericReg.ResourceLength = 12; 92118611Snjl 93151937Sjkim /* Process all child initialization nodes */ 94151937Sjkim 95118611Snjl for (i = 0; InitializerOp; i++) 96118611Snjl { 97118611Snjl switch (i) 98118611Snjl { 99207344Sjkim case 0: /* Address space */ 100118611Snjl 101207344Sjkim Descriptor->GenericReg.AddressSpaceId = (UINT8) InitializerOp->Asl.Value.Integer; 102207344Sjkim RsCreateByteField (InitializerOp, ACPI_RESTAG_ADDRESSSPACE, 103207344Sjkim CurrentByteOffset + ASL_RESDESC_OFFSET (GenericReg.AddressSpaceId)); 104151937Sjkim break; 105151937Sjkim 106207344Sjkim case 1: /* Register Bit Width */ 107151937Sjkim 108207344Sjkim Descriptor->GenericReg.BitWidth = (UINT8) InitializerOp->Asl.Value.Integer; 109207344Sjkim RsCreateByteField (InitializerOp, ACPI_RESTAG_REGISTERBITWIDTH, 110207344Sjkim CurrentByteOffset + ASL_RESDESC_OFFSET (GenericReg.BitWidth)); 111151937Sjkim break; 112151937Sjkim 113207344Sjkim case 2: /* Register Bit Offset */ 114151937Sjkim 115207344Sjkim Descriptor->GenericReg.BitOffset = (UINT8) InitializerOp->Asl.Value.Integer; 116207344Sjkim RsCreateByteField (InitializerOp, ACPI_RESTAG_REGISTERBITOFFSET, 117207344Sjkim CurrentByteOffset + ASL_RESDESC_OFFSET (GenericReg.BitOffset)); 118151937Sjkim break; 119151937Sjkim 120207344Sjkim case 3: /* Register Address */ 121151937Sjkim 122207344Sjkim Descriptor->GenericReg.Address = InitializerOp->Asl.Value.Integer; 123207344Sjkim RsCreateByteField (InitializerOp, ACPI_RESTAG_ADDRESS, 124207344Sjkim CurrentByteOffset + ASL_RESDESC_OFFSET (GenericReg.Address)); 125151937Sjkim break; 126151937Sjkim 127207344Sjkim case 4: /* Access Size (ACPI 3.0) */ 128151937Sjkim 129207344Sjkim Descriptor->GenericReg.AccessSize = (UINT8) InitializerOp->Asl.Value.Integer; 130207344Sjkim RsCreateByteField (InitializerOp, ACPI_RESTAG_ACCESSSIZE, 131207344Sjkim CurrentByteOffset + ASL_RESDESC_OFFSET (GenericReg.AccessSize)); 132151937Sjkim 133207344Sjkim if (Descriptor->GenericReg.AccessSize > AML_FIELD_ACCESS_QWORD) 134118611Snjl { 135207344Sjkim AslError (ASL_ERROR, ASL_MSG_INVALID_ACCESS_SIZE, 136151937Sjkim InitializerOp, NULL); 137151937Sjkim } 138118611Snjl break; 139118611Snjl 140207344Sjkim case 5: /* ResourceTag (ACPI 3.0b) */ 141118611Snjl 142118611Snjl UtAttachNamepathToOwner (Op, InitializerOp); 143118611Snjl break; 144118611Snjl 145118611Snjl default: 146118611Snjl 147118611Snjl AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL); 148118611Snjl break; 149118611Snjl } 150118611Snjl 151118611Snjl InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 152118611Snjl } 153118611Snjl return (Rnode); 154118611Snjl} 155118611Snjl 156118611Snjl 157118611Snjl/******************************************************************************* 158118611Snjl * 159118611Snjl * FUNCTION: RsDoInterruptDescriptor 160118611Snjl * 161118611Snjl * PARAMETERS: Op - Parent resource descriptor parse node 162118611Snjl * CurrentByteOffset - Offset into the resource template AML 163118611Snjl * buffer (to track references to the desc) 164118611Snjl * 165118611Snjl * RETURN: Completed resource node 166118611Snjl * 167118611Snjl * DESCRIPTION: Construct a long "Interrupt" descriptor 168118611Snjl * 169118611Snjl ******************************************************************************/ 170118611Snjl 171118611SnjlASL_RESOURCE_NODE * 172118611SnjlRsDoInterruptDescriptor ( 173118611Snjl ACPI_PARSE_OBJECT *Op, 174118611Snjl UINT32 CurrentByteOffset) 175118611Snjl{ 176151937Sjkim AML_RESOURCE *Descriptor; 177151937Sjkim AML_RESOURCE *Rover = NULL; 178118611Snjl ACPI_PARSE_OBJECT *InitializerOp; 179118611Snjl ASL_RESOURCE_NODE *Rnode; 180151937Sjkim UINT16 StringLength = 0; 181118611Snjl UINT32 OptionIndex = 0; 182118611Snjl UINT32 i; 183118611Snjl BOOLEAN HasResSourceIndex = FALSE; 184118611Snjl UINT8 ResSourceIndex = 0; 185118611Snjl UINT8 *ResSourceString = NULL; 186118611Snjl 187118611Snjl 188118611Snjl InitializerOp = Op->Asl.Child; 189118611Snjl StringLength = RsGetStringDataLength (InitializerOp); 190118611Snjl 191118611Snjl /* Count the interrupt numbers */ 192118611Snjl 193118611Snjl for (i = 0; InitializerOp; i++) 194118611Snjl { 195118611Snjl InitializerOp = ASL_GET_PEER_NODE (InitializerOp); 196193529Sjkim 197118611Snjl if (i <= 6) 198118611Snjl { 199193529Sjkim if (i == 3 && 200193529Sjkim InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) 201193529Sjkim { 202193529Sjkim /* 203193529Sjkim * ResourceSourceIndex was specified, always make room for 204193529Sjkim * it, even if the ResourceSource was omitted. 205193529Sjkim */ 206193529Sjkim OptionIndex++; 207193529Sjkim } 208193529Sjkim 209118611Snjl continue; 210118611Snjl } 211118611Snjl 212118611Snjl OptionIndex += 4; 213118611Snjl } 214118611Snjl 215118611Snjl InitializerOp = Op->Asl.Child; 216151937Sjkim Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_EXTENDED_IRQ) + 217151937Sjkim 1 + OptionIndex + StringLength); 218151937Sjkim 219118611Snjl Descriptor = Rnode->Buffer; 220151937Sjkim Descriptor->ExtendedIrq.DescriptorType = ACPI_RESOURCE_NAME_EXTENDED_IRQ; 221118611Snjl 222118611Snjl /* 223118611Snjl * Initial descriptor length -- may be enlarged if there are 224118611Snjl * optional fields present 225118611Snjl */ 226151937Sjkim Descriptor->ExtendedIrq.ResourceLength = 2; /* Flags and table length byte */ 227151937Sjkim Descriptor->ExtendedIrq.InterruptCount = 0; 228118611Snjl 229151937Sjkim Rover = ACPI_CAST_PTR (AML_RESOURCE, 230151937Sjkim (&(Descriptor->ExtendedIrq.Interrupts[0]))); 231118611Snjl 232151937Sjkim /* Process all child initialization nodes */ 233151937Sjkim 234118611Snjl for (i = 0; InitializerOp; i++) 235118611Snjl { 236118611Snjl switch (i) 237118611Snjl { 238151937Sjkim case 0: /* Resource Usage (Default: consumer (1) */ 239118611Snjl 240151937Sjkim RsSetFlagBits (&Descriptor->ExtendedIrq.Flags, InitializerOp, 0, 1); 241118611Snjl break; 242118611Snjl 243118611Snjl case 1: /* Interrupt Type (or Mode - edge/level) */ 244118611Snjl 245151937Sjkim RsSetFlagBits (&Descriptor->ExtendedIrq.Flags, InitializerOp, 1, 0); 246167802Sjkim RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTTYPE, 247151937Sjkim CurrentByteOffset + ASL_RESDESC_OFFSET (ExtendedIrq.Flags), 1); 248118611Snjl break; 249118611Snjl 250118611Snjl case 2: /* Interrupt Level (or Polarity - Active high/low) */ 251118611Snjl 252151937Sjkim RsSetFlagBits (&Descriptor->ExtendedIrq.Flags, InitializerOp, 2, 0); 253167802Sjkim RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTLEVEL, 254151937Sjkim CurrentByteOffset + ASL_RESDESC_OFFSET (ExtendedIrq.Flags), 2); 255118611Snjl break; 256118611Snjl 257118611Snjl case 3: /* Share Type - Default: exclusive (0) */ 258118611Snjl 259151937Sjkim RsSetFlagBits (&Descriptor->ExtendedIrq.Flags, InitializerOp, 3, 0); 260167802Sjkim RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE, 261151937Sjkim CurrentByteOffset + ASL_RESDESC_OFFSET (ExtendedIrq.Flags), 3); 262118611Snjl break; 263118611Snjl 264118611Snjl case 4: /* ResSourceIndex [Optional Field - BYTE] */ 265118611Snjl 266118611Snjl if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) 267118611Snjl { 268118611Snjl HasResSourceIndex = TRUE; 269118611Snjl ResSourceIndex = (UINT8) InitializerOp->Asl.Value.Integer; 270118611Snjl } 271118611Snjl break; 272118611Snjl 273118611Snjl case 5: /* ResSource [Optional Field - STRING] */ 274118611Snjl 275118611Snjl if ((InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) && 276118611Snjl (InitializerOp->Asl.Value.String)) 277118611Snjl { 278118611Snjl if (StringLength) 279118611Snjl { 280118611Snjl ResSourceString = (UINT8 *) InitializerOp->Asl.Value.String; 281118611Snjl } 282151937Sjkim 283151937Sjkim /* ResourceSourceIndex must also be valid */ 284151937Sjkim 285151937Sjkim if (!HasResSourceIndex) 286151937Sjkim { 287151937Sjkim AslError (ASL_ERROR, ASL_MSG_RESOURCE_INDEX, 288151937Sjkim InitializerOp, NULL); 289151937Sjkim } 290118611Snjl } 291151937Sjkim 292151937Sjkim#if 0 293151937Sjkim /* 294151937Sjkim * Not a valid ResourceSource, ResourceSourceIndex must also 295151937Sjkim * be invalid 296151937Sjkim */ 297151937Sjkim else if (HasResSourceIndex) 298151937Sjkim { 299151937Sjkim AslError (ASL_ERROR, ASL_MSG_RESOURCE_SOURCE, 300151937Sjkim InitializerOp, NULL); 301151937Sjkim } 302151937Sjkim#endif 303118611Snjl break; 304118611Snjl 305118611Snjl case 6: /* ResourceTag */ 306118611Snjl 307118611Snjl UtAttachNamepathToOwner (Op, InitializerOp); 308118611Snjl break; 309118611Snjl 310118611Snjl default: 311118611Snjl /* 312151937Sjkim * Interrupt Numbers come through here, repeatedly 313118611Snjl */ 314151937Sjkim 315151937Sjkim /* Maximum 255 interrupts allowed for this descriptor */ 316151937Sjkim 317151937Sjkim if (Descriptor->ExtendedIrq.InterruptCount == 255) 318151937Sjkim { 319151937Sjkim AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_LIST, 320151937Sjkim InitializerOp, NULL); 321151937Sjkim return (Rnode); 322151937Sjkim } 323151937Sjkim 324151937Sjkim /* Each interrupt number must be a 32-bit value */ 325151937Sjkim 326151937Sjkim if (InitializerOp->Asl.Value.Integer > ACPI_UINT32_MAX) 327151937Sjkim { 328151937Sjkim AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_NUMBER, 329151937Sjkim InitializerOp, NULL); 330151937Sjkim } 331151937Sjkim 332151937Sjkim /* Save the integer and move pointer to the next one */ 333151937Sjkim 334167802Sjkim Rover->DwordItem = (UINT32) InitializerOp->Asl.Value.Integer; 335167802Sjkim Rover = ACPI_ADD_PTR (AML_RESOURCE, &(Rover->DwordItem), 4); 336151937Sjkim Descriptor->ExtendedIrq.InterruptCount++; 337151937Sjkim Descriptor->ExtendedIrq.ResourceLength += 4; 338118611Snjl 339151937Sjkim /* Case 7: First interrupt number in list */ 340118611Snjl 341151937Sjkim if (i == 7) 342118611Snjl { 343193529Sjkim if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 344193529Sjkim { 345193529Sjkim /* Must be at least one interrupt */ 346193529Sjkim 347193529Sjkim AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_LIST_MIN, 348193529Sjkim InitializerOp, NULL); 349193529Sjkim } 350193529Sjkim 351151937Sjkim /* Check now for duplicates in list */ 352151937Sjkim 353151937Sjkim RsCheckListForDuplicates (InitializerOp); 354151937Sjkim 355151937Sjkim /* Create a named field at the start of the list */ 356151937Sjkim 357167802Sjkim RsCreateByteField (InitializerOp, ACPI_RESTAG_INTERRUPT, 358151937Sjkim CurrentByteOffset + 359151937Sjkim ASL_RESDESC_OFFSET (ExtendedIrq.Interrupts[0])); 360118611Snjl } 361118611Snjl } 362118611Snjl 363118611Snjl InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 364118611Snjl } 365118611Snjl 366151937Sjkim 367151937Sjkim /* Add optional ResSourceIndex if present */ 368151937Sjkim 369118611Snjl if (HasResSourceIndex) 370118611Snjl { 371167802Sjkim Rover->ByteItem = ResSourceIndex; 372167802Sjkim Rover = ACPI_ADD_PTR (AML_RESOURCE, &(Rover->ByteItem), 1); 373151937Sjkim Descriptor->ExtendedIrq.ResourceLength += 1; 374118611Snjl } 375118611Snjl 376151937Sjkim /* Add optional ResSource string if present */ 377151937Sjkim 378118611Snjl if (StringLength && ResSourceString) 379118611Snjl { 380118611Snjl 381118611Snjl strcpy ((char *) Rover, (char *) ResSourceString); 382167802Sjkim Rover = ACPI_ADD_PTR ( 383167802Sjkim AML_RESOURCE, &(Rover->ByteItem), StringLength); 384151937Sjkim 385151937Sjkim Descriptor->ExtendedIrq.ResourceLength = (UINT16) 386151937Sjkim (Descriptor->ExtendedIrq.ResourceLength + StringLength); 387118611Snjl } 388118611Snjl 389151937Sjkim Rnode->BufferLength = (ASL_RESDESC_OFFSET (ExtendedIrq.Interrupts[0]) - 390151937Sjkim ASL_RESDESC_OFFSET (ExtendedIrq.DescriptorType)) 391118611Snjl + OptionIndex + StringLength; 392118611Snjl return (Rnode); 393118611Snjl} 394118611Snjl 395118611Snjl 396118611Snjl/******************************************************************************* 397118611Snjl * 398118611Snjl * FUNCTION: RsDoVendorLargeDescriptor 399118611Snjl * 400118611Snjl * PARAMETERS: Op - Parent resource descriptor parse node 401118611Snjl * CurrentByteOffset - Offset into the resource template AML 402118611Snjl * buffer (to track references to the desc) 403118611Snjl * 404118611Snjl * RETURN: Completed resource node 405118611Snjl * 406118611Snjl * DESCRIPTION: Construct a long "VendorLong" descriptor 407118611Snjl * 408118611Snjl ******************************************************************************/ 409118611Snjl 410118611SnjlASL_RESOURCE_NODE * 411118611SnjlRsDoVendorLargeDescriptor ( 412118611Snjl ACPI_PARSE_OBJECT *Op, 413118611Snjl UINT32 CurrentByteOffset) 414118611Snjl{ 415151937Sjkim AML_RESOURCE *Descriptor; 416118611Snjl ACPI_PARSE_OBJECT *InitializerOp; 417118611Snjl ASL_RESOURCE_NODE *Rnode; 418151937Sjkim UINT8 *VendorData; 419118611Snjl UINT32 i; 420118611Snjl 421118611Snjl 422118611Snjl /* Count the number of data bytes */ 423118611Snjl 424118611Snjl InitializerOp = Op->Asl.Child; 425118611Snjl InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 426118611Snjl 427118611Snjl for (i = 0; InitializerOp; i++) 428118611Snjl { 429167802Sjkim if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 430167802Sjkim { 431167802Sjkim break; 432167802Sjkim } 433118611Snjl InitializerOp = InitializerOp->Asl.Next; 434118611Snjl } 435118611Snjl 436118611Snjl InitializerOp = Op->Asl.Child; 437118611Snjl InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 438151937Sjkim Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_VENDOR_LARGE) + i); 439118611Snjl 440118611Snjl Descriptor = Rnode->Buffer; 441151937Sjkim Descriptor->VendorLarge.DescriptorType = ACPI_RESOURCE_NAME_VENDOR_LARGE; 442151937Sjkim Descriptor->VendorLarge.ResourceLength = (UINT16) i; 443118611Snjl 444151937Sjkim /* Point to end-of-descriptor for vendor data */ 445151937Sjkim 446151937Sjkim VendorData = ((UINT8 *) Descriptor) + sizeof (AML_RESOURCE_LARGE_HEADER); 447151937Sjkim 448151937Sjkim /* Process all child initialization nodes */ 449151937Sjkim 450118611Snjl for (i = 0; InitializerOp; i++) 451118611Snjl { 452167802Sjkim if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 453167802Sjkim { 454167802Sjkim break; 455167802Sjkim } 456167802Sjkim 457151937Sjkim VendorData[i] = (UINT8) InitializerOp->Asl.Value.Integer; 458118611Snjl InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); 459118611Snjl } 460118611Snjl 461118611Snjl return (Rnode); 462118611Snjl} 463