167754Smsmith/****************************************************************************** 267754Smsmith * 367754Smsmith * Module Name: dsobject - Dispatcher object management routines 467754Smsmith * 567754Smsmith *****************************************************************************/ 667754Smsmith 7217365Sjkim/* 8298714Sjkim * Copyright (C) 2000 - 2016, Intel Corp. 970243Smsmith * All rights reserved. 1067754Smsmith * 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. 2567754Smsmith * 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. 2967754Smsmith * 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 */ 4367754Smsmith 44193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 45193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 46193341Sjkim#include <contrib/dev/acpica/include/acparser.h> 47193341Sjkim#include <contrib/dev/acpica/include/amlcode.h> 48193341Sjkim#include <contrib/dev/acpica/include/acdispat.h> 49193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 50193341Sjkim#include <contrib/dev/acpica/include/acinterp.h> 5167754Smsmith 5277424Smsmith#define _COMPONENT ACPI_DISPATCHER 5391116Smsmith ACPI_MODULE_NAME ("dsobject") 5467754Smsmith 55167802Sjkim/* Local prototypes */ 56167802Sjkim 57151937Sjkimstatic ACPI_STATUS 58151937SjkimAcpiDsBuildInternalObject ( 59151937Sjkim ACPI_WALK_STATE *WalkState, 60151937Sjkim ACPI_PARSE_OBJECT *Op, 61151937Sjkim ACPI_OPERAND_OBJECT **ObjDescPtr); 6267754Smsmith 63151937Sjkim 64100966Siwasaki#ifndef ACPI_NO_METHOD_EXECUTION 65151937Sjkim/******************************************************************************* 6667754Smsmith * 6799146Siwasaki * FUNCTION: AcpiDsBuildInternalObject 6867754Smsmith * 6999146Siwasaki * PARAMETERS: WalkState - Current walk state 7099146Siwasaki * Op - Parser object to be translated 7167754Smsmith * ObjDescPtr - Where the ACPI internal object is returned 7267754Smsmith * 7367754Smsmith * RETURN: Status 7467754Smsmith * 7567754Smsmith * DESCRIPTION: Translate a parser Op object to the equivalent namespace object 7667754Smsmith * Simple objects are any objects other than a package object! 7767754Smsmith * 78151937Sjkim ******************************************************************************/ 7967754Smsmith 80151937Sjkimstatic ACPI_STATUS 8199146SiwasakiAcpiDsBuildInternalObject ( 8267754Smsmith ACPI_WALK_STATE *WalkState, 8367754Smsmith ACPI_PARSE_OBJECT *Op, 8467754Smsmith ACPI_OPERAND_OBJECT **ObjDescPtr) 8567754Smsmith{ 8667754Smsmith ACPI_OPERAND_OBJECT *ObjDesc; 8767754Smsmith ACPI_STATUS Status; 88209746Sjkim ACPI_OBJECT_TYPE Type; 8967754Smsmith 9067754Smsmith 91167802Sjkim ACPI_FUNCTION_TRACE (DsBuildInternalObject); 9267754Smsmith 9367754Smsmith 94104470Siwasaki *ObjDescPtr = NULL; 9599679Siwasaki if (Op->Common.AmlOpcode == AML_INT_NAMEPATH_OP) 9667754Smsmith { 9767754Smsmith /* 98167802Sjkim * This is a named object reference. If this name was 9987031Smsmith * previously looked up in the namespace, it was stored in this op. 10067754Smsmith * Otherwise, go ahead and look it up now 10167754Smsmith */ 10299679Siwasaki if (!Op->Common.Node) 10367754Smsmith { 104151937Sjkim Status = AcpiNsLookup (WalkState->ScopeInfo, 105298714Sjkim Op->Common.Value.String, 106298714Sjkim ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, 107298714Sjkim ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL, 108298714Sjkim ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, &(Op->Common.Node))); 10967754Smsmith if (ACPI_FAILURE (Status)) 11067754Smsmith { 111167802Sjkim /* Check if we are resolving a named reference within a package */ 112167802Sjkim 113167802Sjkim if ((Status == AE_NOT_FOUND) && (AcpiGbl_EnableInterpreterSlack) && 114167802Sjkim 115167802Sjkim ((Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) || 116167802Sjkim (Op->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP))) 117167802Sjkim { 118167802Sjkim /* 119167802Sjkim * We didn't find the target and we are populating elements 120167802Sjkim * of a package - ignore if slack enabled. Some ASL code 121167802Sjkim * contains dangling invalid references in packages and 122167802Sjkim * expects that no exception will be issued. Leave the 123167802Sjkim * element as a null element. It cannot be used, but it 124167802Sjkim * can be overwritten by subsequent ASL code - this is 125167802Sjkim * typically the case. 126167802Sjkim */ 127167802Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 128167802Sjkim "Ignoring unresolved reference in package [%4.4s]\n", 129167802Sjkim WalkState->ScopeInfo->Scope.Node->Name.Ascii)); 130167802Sjkim 131167802Sjkim return_ACPI_STATUS (AE_OK); 132167802Sjkim } 133167802Sjkim else 134167802Sjkim { 135167802Sjkim ACPI_ERROR_NAMESPACE (Op->Common.Value.String, Status); 136167802Sjkim } 137167802Sjkim 138104470Siwasaki return_ACPI_STATUS (Status); 13967754Smsmith } 14067754Smsmith } 141193267Sjkim 142193267Sjkim /* Special object resolution for elements of a package */ 143193267Sjkim 144193267Sjkim if ((Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) || 145193267Sjkim (Op->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP)) 146193267Sjkim { 147193267Sjkim /* 148193267Sjkim * Attempt to resolve the node to a value before we insert it into 149193267Sjkim * the package. If this is a reference to a common data type, 150193267Sjkim * resolve it immediately. According to the ACPI spec, package 151193267Sjkim * elements can only be "data objects" or method references. 152193267Sjkim * Attempt to resolve to an Integer, Buffer, String or Package. 153193267Sjkim * If cannot, return the named reference (for things like Devices, 154193267Sjkim * Methods, etc.) Buffer Fields and Fields will resolve to simple 155193267Sjkim * objects (int/buf/str/pkg). 156193267Sjkim * 157193267Sjkim * NOTE: References to things like Devices, Methods, Mutexes, etc. 158193267Sjkim * will remain as named references. This behavior is not described 159193267Sjkim * in the ACPI spec, but it appears to be an oversight. 160193267Sjkim */ 161193267Sjkim ObjDesc = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Op->Common.Node); 162193267Sjkim 163193267Sjkim Status = AcpiExResolveNodeToValue ( 164298714Sjkim ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, &ObjDesc), 165298714Sjkim WalkState); 166193267Sjkim if (ACPI_FAILURE (Status)) 167193267Sjkim { 168193267Sjkim return_ACPI_STATUS (Status); 169193267Sjkim } 170193267Sjkim 171209746Sjkim /* 172209746Sjkim * Special handling for Alias objects. We need to setup the type 173209746Sjkim * and the Op->Common.Node to point to the Alias target. Note, 174209746Sjkim * Alias has at most one level of indirection internally. 175209746Sjkim */ 176209746Sjkim Type = Op->Common.Node->Type; 177209746Sjkim if (Type == ACPI_TYPE_LOCAL_ALIAS) 178193267Sjkim { 179209746Sjkim Type = ObjDesc->Common.Type; 180209746Sjkim Op->Common.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, 181209746Sjkim Op->Common.Node->Object); 182209746Sjkim } 183209746Sjkim 184209746Sjkim switch (Type) 185209746Sjkim { 186193267Sjkim /* 187193267Sjkim * For these types, we need the actual node, not the subobject. 188193267Sjkim * However, the subobject did not get an extra reference count above. 189193267Sjkim * 190193267Sjkim * TBD: should ExResolveNodeToValue be changed to fix this? 191193267Sjkim */ 192193267Sjkim case ACPI_TYPE_DEVICE: 193193267Sjkim case ACPI_TYPE_THERMAL: 194193267Sjkim 195193267Sjkim AcpiUtAddReference (Op->Common.Node->Object); 196193267Sjkim 197193267Sjkim /*lint -fallthrough */ 198193267Sjkim /* 199193267Sjkim * For these types, we need the actual node, not the subobject. 200193267Sjkim * The subobject got an extra reference count in ExResolveNodeToValue. 201193267Sjkim */ 202193267Sjkim case ACPI_TYPE_MUTEX: 203193267Sjkim case ACPI_TYPE_METHOD: 204193267Sjkim case ACPI_TYPE_POWER: 205193267Sjkim case ACPI_TYPE_PROCESSOR: 206193267Sjkim case ACPI_TYPE_EVENT: 207193267Sjkim case ACPI_TYPE_REGION: 208193267Sjkim 209193267Sjkim /* We will create a reference object for these types below */ 210193267Sjkim break; 211193267Sjkim 212193267Sjkim default: 213193267Sjkim /* 214193267Sjkim * All other types - the node was resolved to an actual 215193267Sjkim * object, we are done. 216193267Sjkim */ 217193267Sjkim goto Exit; 218193267Sjkim } 219193267Sjkim } 22067754Smsmith } 22167754Smsmith 222167802Sjkim /* Create and init a new internal ACPI object */ 22367754Smsmith 224151937Sjkim ObjDesc = AcpiUtCreateInternalObject ( 225298714Sjkim (AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode))->ObjectType); 22667754Smsmith if (!ObjDesc) 22767754Smsmith { 22867754Smsmith return_ACPI_STATUS (AE_NO_MEMORY); 22967754Smsmith } 23067754Smsmith 231298714Sjkim Status = AcpiDsInitObjectFromOp ( 232298714Sjkim WalkState, Op, Op->Common.AmlOpcode, &ObjDesc); 23367754Smsmith if (ACPI_FAILURE (Status)) 23467754Smsmith { 23577424Smsmith AcpiUtRemoveReference (ObjDesc); 23667754Smsmith return_ACPI_STATUS (Status); 23767754Smsmith } 23867754Smsmith 239193267SjkimExit: 24067754Smsmith *ObjDescPtr = ObjDesc; 241193267Sjkim return_ACPI_STATUS (Status); 24267754Smsmith} 24367754Smsmith 24467754Smsmith 245151937Sjkim/******************************************************************************* 24667754Smsmith * 24799146Siwasaki * FUNCTION: AcpiDsBuildInternalBufferObj 24867754Smsmith * 24999679Siwasaki * PARAMETERS: WalkState - Current walk state 25099679Siwasaki * Op - Parser object to be translated 25199679Siwasaki * BufferLength - Length of the buffer 25267754Smsmith * ObjDescPtr - Where the ACPI internal object is returned 25367754Smsmith * 25467754Smsmith * RETURN: Status 25567754Smsmith * 25667754Smsmith * DESCRIPTION: Translate a parser Op package object to the equivalent 25767754Smsmith * namespace object 25867754Smsmith * 259151937Sjkim ******************************************************************************/ 26067754Smsmith 26167754SmsmithACPI_STATUS 26299146SiwasakiAcpiDsBuildInternalBufferObj ( 26367754Smsmith ACPI_WALK_STATE *WalkState, 26467754Smsmith ACPI_PARSE_OBJECT *Op, 26599146Siwasaki UINT32 BufferLength, 26667754Smsmith ACPI_OPERAND_OBJECT **ObjDescPtr) 26767754Smsmith{ 26867754Smsmith ACPI_PARSE_OBJECT *Arg; 26967754Smsmith ACPI_OPERAND_OBJECT *ObjDesc; 27099679Siwasaki ACPI_PARSE_OBJECT *ByteList; 27199146Siwasaki UINT32 ByteListLength = 0; 27267754Smsmith 27367754Smsmith 274167802Sjkim ACPI_FUNCTION_TRACE (DsBuildInternalBufferObj); 27567754Smsmith 27667754Smsmith 277167802Sjkim /* 278167802Sjkim * If we are evaluating a Named buffer object "Name (xxxx, Buffer)". 279167802Sjkim * The buffer object already exists (from the NS node), otherwise it must 280167802Sjkim * be created. 281167802Sjkim */ 28299146Siwasaki ObjDesc = *ObjDescPtr; 283167802Sjkim if (!ObjDesc) 28467754Smsmith { 28599146Siwasaki /* Create a new buffer object */ 28667754Smsmith 28799146Siwasaki ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_BUFFER); 28899146Siwasaki *ObjDescPtr = ObjDesc; 28999146Siwasaki if (!ObjDesc) 29099146Siwasaki { 29199146Siwasaki return_ACPI_STATUS (AE_NO_MEMORY); 29299146Siwasaki } 29399146Siwasaki } 29467754Smsmith 29567754Smsmith /* 29699146Siwasaki * Second arg is the buffer data (optional) ByteList can be either 297241973Sjkim * individual bytes or a string initializer. In either case, a 29899146Siwasaki * ByteList appears in the AML. 29967754Smsmith */ 30099679Siwasaki Arg = Op->Common.Value.Arg; /* skip first arg */ 30167754Smsmith 30299679Siwasaki ByteList = Arg->Named.Next; 30399146Siwasaki if (ByteList) 30467754Smsmith { 30599679Siwasaki if (ByteList->Common.AmlOpcode != AML_INT_BYTELIST_OP) 30699146Siwasaki { 307167802Sjkim ACPI_ERROR ((AE_INFO, 308204773Sjkim "Expecting bytelist, found AML opcode 0x%X in op %p", 30999679Siwasaki ByteList->Common.AmlOpcode, ByteList)); 31099146Siwasaki 31199146Siwasaki AcpiUtRemoveReference (ObjDesc); 31299146Siwasaki return (AE_TYPE); 31399146Siwasaki } 31499146Siwasaki 315117521Snjl ByteListLength = (UINT32) ByteList->Common.Value.Integer; 31667754Smsmith } 31767754Smsmith 31867754Smsmith /* 31999146Siwasaki * The buffer length (number of bytes) will be the larger of: 320102550Siwasaki * 1) The specified buffer length and 32199146Siwasaki * 2) The length of the initializer byte list 32267754Smsmith */ 32399146Siwasaki ObjDesc->Buffer.Length = BufferLength; 32499146Siwasaki if (ByteListLength > BufferLength) 32567754Smsmith { 32699146Siwasaki ObjDesc->Buffer.Length = ByteListLength; 32799146Siwasaki } 32867754Smsmith 32999146Siwasaki /* Allocate the buffer */ 33067754Smsmith 33199146Siwasaki if (ObjDesc->Buffer.Length == 0) 33299146Siwasaki { 33399146Siwasaki ObjDesc->Buffer.Pointer = NULL; 334117521Snjl ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 335117521Snjl "Buffer defined with zero length in AML, creating\n")); 33667754Smsmith } 337114237Snjl else 33899146Siwasaki { 339298714Sjkim ObjDesc->Buffer.Pointer = 340298714Sjkim ACPI_ALLOCATE_ZEROED (ObjDesc->Buffer.Length); 341114237Snjl if (!ObjDesc->Buffer.Pointer) 342114237Snjl { 343114237Snjl AcpiUtDeleteObjectDesc (ObjDesc); 344114237Snjl return_ACPI_STATUS (AE_NO_MEMORY); 345114237Snjl } 34699146Siwasaki 347114237Snjl /* Initialize buffer from the ByteList (if present) */ 34899146Siwasaki 349114237Snjl if (ByteList) 350114237Snjl { 351284583Sjkim memcpy (ObjDesc->Buffer.Pointer, ByteList->Named.Data, 352298714Sjkim ByteListLength); 353114237Snjl } 35499146Siwasaki } 35599146Siwasaki 35699146Siwasaki ObjDesc->Buffer.Flags |= AOPOBJ_DATA_VALID; 357167802Sjkim Op->Common.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjDesc); 35899146Siwasaki return_ACPI_STATUS (AE_OK); 35967754Smsmith} 36067754Smsmith 36167754Smsmith 362151937Sjkim/******************************************************************************* 36367754Smsmith * 36499146Siwasaki * FUNCTION: AcpiDsBuildInternalPackageObj 36567754Smsmith * 36699679Siwasaki * PARAMETERS: WalkState - Current walk state 36799679Siwasaki * Op - Parser object to be translated 368167802Sjkim * ElementCount - Number of elements in the package - this is 369167802Sjkim * the NumElements argument to Package() 37067754Smsmith * ObjDescPtr - Where the ACPI internal object is returned 37167754Smsmith * 37267754Smsmith * RETURN: Status 37367754Smsmith * 37499146Siwasaki * DESCRIPTION: Translate a parser Op package object to the equivalent 37599146Siwasaki * namespace object 37667754Smsmith * 377167802Sjkim * NOTE: The number of elements in the package will be always be the NumElements 378167802Sjkim * count, regardless of the number of elements in the package list. If 379167802Sjkim * NumElements is smaller, only that many package list elements are used. 380167802Sjkim * if NumElements is larger, the Package object is padded out with 381167802Sjkim * objects of type Uninitialized (as per ACPI spec.) 382167802Sjkim * 383167802Sjkim * Even though the ASL compilers do not allow NumElements to be smaller 384167802Sjkim * than the Package list length (for the fixed length package opcode), some 385167802Sjkim * BIOS code modifies the AML on the fly to adjust the NumElements, and 386167802Sjkim * this code compensates for that. This also provides compatibility with 387167802Sjkim * other AML interpreters. 388167802Sjkim * 389151937Sjkim ******************************************************************************/ 39067754Smsmith 39167754SmsmithACPI_STATUS 39299146SiwasakiAcpiDsBuildInternalPackageObj ( 39367754Smsmith ACPI_WALK_STATE *WalkState, 39467754Smsmith ACPI_PARSE_OBJECT *Op, 395167802Sjkim UINT32 ElementCount, 39667754Smsmith ACPI_OPERAND_OBJECT **ObjDescPtr) 39767754Smsmith{ 39899146Siwasaki ACPI_PARSE_OBJECT *Arg; 39999146Siwasaki ACPI_PARSE_OBJECT *Parent; 40099146Siwasaki ACPI_OPERAND_OBJECT *ObjDesc = NULL; 40199146Siwasaki ACPI_STATUS Status = AE_OK; 402193267Sjkim UINT32 i; 403167802Sjkim UINT16 Index; 404167802Sjkim UINT16 ReferenceCount; 40567754Smsmith 40667754Smsmith 407167802Sjkim ACPI_FUNCTION_TRACE (DsBuildInternalPackageObj); 40899146Siwasaki 40999146Siwasaki 41099146Siwasaki /* Find the parent of a possibly nested package */ 41199146Siwasaki 41299679Siwasaki Parent = Op->Common.Parent; 413167802Sjkim while ((Parent->Common.AmlOpcode == AML_PACKAGE_OP) || 41499679Siwasaki (Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP)) 41567754Smsmith { 41699679Siwasaki Parent = Parent->Common.Parent; 41799146Siwasaki } 41882367Smsmith 419167802Sjkim /* 420167802Sjkim * If we are evaluating a Named package object "Name (xxxx, Package)", 421167802Sjkim * the package object already exists, otherwise it must be created. 422167802Sjkim */ 42399146Siwasaki ObjDesc = *ObjDescPtr; 424167802Sjkim if (!ObjDesc) 42599146Siwasaki { 42699146Siwasaki ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_PACKAGE); 42799146Siwasaki *ObjDescPtr = ObjDesc; 42899146Siwasaki if (!ObjDesc) 42999146Siwasaki { 43099146Siwasaki return_ACPI_STATUS (AE_NO_MEMORY); 43199146Siwasaki } 43267754Smsmith 43399679Siwasaki ObjDesc->Package.Node = Parent->Common.Node; 43499146Siwasaki } 43582367Smsmith 43699146Siwasaki /* 437167802Sjkim * Allocate the element array (array of pointers to the individual 438167802Sjkim * objects) based on the NumElements parameter. Add an extra pointer slot 439167802Sjkim * so that the list is always null terminated. 44099146Siwasaki */ 441167802Sjkim ObjDesc->Package.Elements = ACPI_ALLOCATE_ZEROED ( 442167802Sjkim ((ACPI_SIZE) ElementCount + 1) * sizeof (void *)); 44399146Siwasaki 44499146Siwasaki if (!ObjDesc->Package.Elements) 44599146Siwasaki { 44699146Siwasaki AcpiUtDeleteObjectDesc (ObjDesc); 44799146Siwasaki return_ACPI_STATUS (AE_NO_MEMORY); 44899146Siwasaki } 44999146Siwasaki 450167802Sjkim ObjDesc->Package.Count = ElementCount; 451167802Sjkim 45299146Siwasaki /* 453167802Sjkim * Initialize the elements of the package, up to the NumElements count. 454167802Sjkim * Package is automatically padded with uninitialized (NULL) elements 455167802Sjkim * if NumElements is greater than the package list length. Likewise, 456167802Sjkim * Package is truncated if NumElements is less than the list length. 45799146Siwasaki */ 45899679Siwasaki Arg = Op->Common.Value.Arg; 45999679Siwasaki Arg = Arg->Common.Next; 460167802Sjkim for (i = 0; Arg && (i < ElementCount); i++) 46199146Siwasaki { 46299679Siwasaki if (Arg->Common.AmlOpcode == AML_INT_RETURN_VALUE_OP) 46399146Siwasaki { 464193267Sjkim if (Arg->Common.Node->Type == ACPI_TYPE_METHOD) 465193267Sjkim { 466193267Sjkim /* 467193267Sjkim * A method reference "looks" to the parser to be a method 468193267Sjkim * invocation, so we special case it here 469193267Sjkim */ 470193267Sjkim Arg->Common.AmlOpcode = AML_INT_NAMEPATH_OP; 471298714Sjkim Status = AcpiDsBuildInternalObject ( 472298714Sjkim WalkState, Arg, &ObjDesc->Package.Elements[i]); 473193267Sjkim } 474193267Sjkim else 475193267Sjkim { 476193267Sjkim /* This package element is already built, just get it */ 47799146Siwasaki 478193267Sjkim ObjDesc->Package.Elements[i] = 479193267Sjkim ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Arg->Common.Node); 480193267Sjkim } 48199146Siwasaki } 48299146Siwasaki else 48399146Siwasaki { 484298714Sjkim Status = AcpiDsBuildInternalObject ( 485298714Sjkim WalkState, Arg, &ObjDesc->Package.Elements[i]); 48699146Siwasaki } 48799146Siwasaki 488167802Sjkim if (*ObjDescPtr) 489167802Sjkim { 490167802Sjkim /* Existing package, get existing reference count */ 491167802Sjkim 492167802Sjkim ReferenceCount = (*ObjDescPtr)->Common.ReferenceCount; 493167802Sjkim if (ReferenceCount > 1) 494167802Sjkim { 495167802Sjkim /* Make new element ref count match original ref count */ 496167802Sjkim 497167802Sjkim for (Index = 0; Index < (ReferenceCount - 1); Index++) 498167802Sjkim { 499167802Sjkim AcpiUtAddReference ((ObjDesc->Package.Elements[i])); 500167802Sjkim } 501167802Sjkim } 502167802Sjkim } 503167802Sjkim 50499679Siwasaki Arg = Arg->Common.Next; 50599146Siwasaki } 50699146Siwasaki 507193267Sjkim /* Check for match between NumElements and actual length of PackageList */ 508193267Sjkim 509193267Sjkim if (Arg) 510167802Sjkim { 511193267Sjkim /* 512193267Sjkim * NumElements was exhausted, but there are remaining elements in the 513197104Sjkim * PackageList. Truncate the package to NumElements. 514193267Sjkim * 515193267Sjkim * Note: technically, this is an error, from ACPI spec: "It is an error 516193267Sjkim * for NumElements to be less than the number of elements in the 517199337Sjkim * PackageList". However, we just print a message and 518197104Sjkim * no exception is returned. This provides Windows compatibility. Some 519197104Sjkim * BIOSs will alter the NumElements on the fly, creating this type 520197104Sjkim * of ill-formed package object. 521193267Sjkim */ 522193267Sjkim while (Arg) 523193267Sjkim { 524197104Sjkim /* 525197104Sjkim * We must delete any package elements that were created earlier 526197104Sjkim * and are not going to be used because of the package truncation. 527197104Sjkim */ 528197104Sjkim if (Arg->Common.Node) 529197104Sjkim { 530197104Sjkim AcpiUtRemoveReference ( 531197104Sjkim ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Arg->Common.Node)); 532197104Sjkim Arg->Common.Node = NULL; 533197104Sjkim } 534197104Sjkim 535193267Sjkim /* Find out how many elements there really are */ 536193267Sjkim 537193267Sjkim i++; 538193267Sjkim Arg = Arg->Common.Next; 539193267Sjkim } 540193267Sjkim 541298714Sjkim ACPI_INFO (( 542298714Sjkim "Actual Package length (%u) is larger than " 543298714Sjkim "NumElements field (%u), truncated", 544193267Sjkim i, ElementCount)); 545193267Sjkim } 546193267Sjkim else if (i < ElementCount) 547193267Sjkim { 548193267Sjkim /* 549193267Sjkim * Arg list (elements) was exhausted, but we did not reach NumElements count. 550193267Sjkim * Note: this is not an error, the package is padded out with NULLs. 551193267Sjkim */ 552167802Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 553298714Sjkim "Package List length (%u) smaller than NumElements " 554298714Sjkim "count (%u), padded with null elements\n", 555193267Sjkim i, ElementCount)); 556167802Sjkim } 557167802Sjkim 55899146Siwasaki ObjDesc->Package.Flags |= AOPOBJ_DATA_VALID; 559167802Sjkim Op->Common.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjDesc); 56099146Siwasaki return_ACPI_STATUS (Status); 56167754Smsmith} 56267754Smsmith 56367754Smsmith 564151937Sjkim/******************************************************************************* 56567754Smsmith * 56667754Smsmith * FUNCTION: AcpiDsCreateNode 56767754Smsmith * 56899679Siwasaki * PARAMETERS: WalkState - Current walk state 56999679Siwasaki * Node - NS Node to be initialized 57099679Siwasaki * Op - Parser object to be translated 57167754Smsmith * 57267754Smsmith * RETURN: Status 57367754Smsmith * 57499679Siwasaki * DESCRIPTION: Create the object to be associated with a namespace node 57567754Smsmith * 576151937Sjkim ******************************************************************************/ 57767754Smsmith 57867754SmsmithACPI_STATUS 57967754SmsmithAcpiDsCreateNode ( 58067754Smsmith ACPI_WALK_STATE *WalkState, 58167754Smsmith ACPI_NAMESPACE_NODE *Node, 58267754Smsmith ACPI_PARSE_OBJECT *Op) 58367754Smsmith{ 58467754Smsmith ACPI_STATUS Status; 58567754Smsmith ACPI_OPERAND_OBJECT *ObjDesc; 58667754Smsmith 58767754Smsmith 588167802Sjkim ACPI_FUNCTION_TRACE_PTR (DsCreateNode, Op); 58967754Smsmith 59067754Smsmith 59185756Smsmith /* 59285756Smsmith * Because of the execution pass through the non-control-method 593241973Sjkim * parts of the table, we can arrive here twice. Only init 59485756Smsmith * the named object node the first time through 59585756Smsmith */ 59687031Smsmith if (AcpiNsGetAttachedObject (Node)) 59785756Smsmith { 59885756Smsmith return_ACPI_STATUS (AE_OK); 59985756Smsmith } 60085756Smsmith 60199679Siwasaki if (!Op->Common.Value.Arg) 60267754Smsmith { 60367754Smsmith /* No arguments, there is nothing to do */ 60467754Smsmith 60567754Smsmith return_ACPI_STATUS (AE_OK); 60667754Smsmith } 60767754Smsmith 60867754Smsmith /* Build an internal object for the argument(s) */ 60967754Smsmith 610298714Sjkim Status = AcpiDsBuildInternalObject ( 611298714Sjkim WalkState, Op->Common.Value.Arg, &ObjDesc); 61267754Smsmith if (ACPI_FAILURE (Status)) 61367754Smsmith { 61467754Smsmith return_ACPI_STATUS (Status); 61567754Smsmith } 61667754Smsmith 617114237Snjl /* Re-type the object according to its argument */ 61867754Smsmith 619193267Sjkim Node->Type = ObjDesc->Common.Type; 62067754Smsmith 62199146Siwasaki /* Attach obj to node */ 62267754Smsmith 62391116Smsmith Status = AcpiNsAttachObject (Node, ObjDesc, Node->Type); 62467754Smsmith 62585756Smsmith /* Remove local reference to the object */ 62667754Smsmith 62777424Smsmith AcpiUtRemoveReference (ObjDesc); 62867754Smsmith return_ACPI_STATUS (Status); 62967754Smsmith} 63067754Smsmith 631100966Siwasaki#endif /* ACPI_NO_METHOD_EXECUTION */ 63267754Smsmith 633100966Siwasaki 634151937Sjkim/******************************************************************************* 635100966Siwasaki * 636100966Siwasaki * FUNCTION: AcpiDsInitObjectFromOp 637100966Siwasaki * 638100966Siwasaki * PARAMETERS: WalkState - Current walk state 639100966Siwasaki * Op - Parser op used to init the internal object 640100966Siwasaki * Opcode - AML opcode associated with the object 641100966Siwasaki * RetObjDesc - Namespace object to be initialized 642100966Siwasaki * 643100966Siwasaki * RETURN: Status 644100966Siwasaki * 645100966Siwasaki * DESCRIPTION: Initialize a namespace object from a parser Op and its 646241973Sjkim * associated arguments. The namespace object is a more compact 647100966Siwasaki * representation of the Op and its arguments. 648100966Siwasaki * 649151937Sjkim ******************************************************************************/ 650100966Siwasaki 651100966SiwasakiACPI_STATUS 652100966SiwasakiAcpiDsInitObjectFromOp ( 653100966Siwasaki ACPI_WALK_STATE *WalkState, 654100966Siwasaki ACPI_PARSE_OBJECT *Op, 655100966Siwasaki UINT16 Opcode, 656100966Siwasaki ACPI_OPERAND_OBJECT **RetObjDesc) 657100966Siwasaki{ 658100966Siwasaki const ACPI_OPCODE_INFO *OpInfo; 659100966Siwasaki ACPI_OPERAND_OBJECT *ObjDesc; 660100966Siwasaki ACPI_STATUS Status = AE_OK; 661100966Siwasaki 662100966Siwasaki 663167802Sjkim ACPI_FUNCTION_TRACE (DsInitObjectFromOp); 664100966Siwasaki 665100966Siwasaki 666100966Siwasaki ObjDesc = *RetObjDesc; 667100966Siwasaki OpInfo = AcpiPsGetOpcodeInfo (Opcode); 668100966Siwasaki if (OpInfo->Class == AML_CLASS_UNKNOWN) 669100966Siwasaki { 670100966Siwasaki /* Unknown opcode */ 671100966Siwasaki 672100966Siwasaki return_ACPI_STATUS (AE_TYPE); 673100966Siwasaki } 674100966Siwasaki 675100966Siwasaki /* Perform per-object initialization */ 676100966Siwasaki 677193267Sjkim switch (ObjDesc->Common.Type) 678100966Siwasaki { 679100966Siwasaki case ACPI_TYPE_BUFFER: 680100966Siwasaki /* 681100966Siwasaki * Defer evaluation of Buffer TermArg operand 682100966Siwasaki */ 683298714Sjkim ObjDesc->Buffer.Node = ACPI_CAST_PTR ( 684298714Sjkim ACPI_NAMESPACE_NODE, WalkState->Operands[0]); 685298714Sjkim ObjDesc->Buffer.AmlStart = Op->Named.Data; 686100966Siwasaki ObjDesc->Buffer.AmlLength = Op->Named.Length; 687100966Siwasaki break; 688100966Siwasaki 689100966Siwasaki case ACPI_TYPE_PACKAGE: 690100966Siwasaki /* 691100966Siwasaki * Defer evaluation of Package TermArg operand 692100966Siwasaki */ 693298714Sjkim ObjDesc->Package.Node = ACPI_CAST_PTR ( 694298714Sjkim ACPI_NAMESPACE_NODE, WalkState->Operands[0]); 695298714Sjkim ObjDesc->Package.AmlStart = Op->Named.Data; 696100966Siwasaki ObjDesc->Package.AmlLength = Op->Named.Length; 697100966Siwasaki break; 698100966Siwasaki 699102550Siwasaki case ACPI_TYPE_INTEGER: 700100966Siwasaki 701100966Siwasaki switch (OpInfo->Type) 702100966Siwasaki { 703100966Siwasaki case AML_TYPE_CONSTANT: 704100966Siwasaki /* 705100966Siwasaki * Resolve AML Constants here - AND ONLY HERE! 706100966Siwasaki * All constants are integers. 707151937Sjkim * We mark the integer with a flag that indicates that it started 708151937Sjkim * life as a constant -- so that stores to constants will perform 709151937Sjkim * as expected (noop). ZeroOp is used as a placeholder for optional 710151937Sjkim * target operands. 711100966Siwasaki */ 712100966Siwasaki ObjDesc->Common.Flags = AOPOBJ_AML_CONSTANT; 713100966Siwasaki 714100966Siwasaki switch (Opcode) 715100966Siwasaki { 716100966Siwasaki case AML_ZERO_OP: 717100966Siwasaki 718100966Siwasaki ObjDesc->Integer.Value = 0; 719100966Siwasaki break; 720100966Siwasaki 721100966Siwasaki case AML_ONE_OP: 722100966Siwasaki 723100966Siwasaki ObjDesc->Integer.Value = 1; 724100966Siwasaki break; 725100966Siwasaki 726100966Siwasaki case AML_ONES_OP: 727100966Siwasaki 728202771Sjkim ObjDesc->Integer.Value = ACPI_UINT64_MAX; 729100966Siwasaki 730100966Siwasaki /* Truncate value if we are executing from a 32-bit ACPI table */ 731100966Siwasaki 732100966Siwasaki#ifndef ACPI_NO_METHOD_EXECUTION 733245582Sjkim (void) AcpiExTruncateFor32bitTable (ObjDesc); 734100966Siwasaki#endif 735100966Siwasaki break; 736100966Siwasaki 737100966Siwasaki case AML_REVISION_OP: 738100966Siwasaki 739151937Sjkim ObjDesc->Integer.Value = ACPI_CA_VERSION; 740100966Siwasaki break; 741100966Siwasaki 742100966Siwasaki default: 743100966Siwasaki 744167802Sjkim ACPI_ERROR ((AE_INFO, 745204773Sjkim "Unknown constant opcode 0x%X", Opcode)); 746100966Siwasaki Status = AE_AML_OPERAND_TYPE; 747100966Siwasaki break; 748100966Siwasaki } 749100966Siwasaki break; 750100966Siwasaki 751100966Siwasaki case AML_TYPE_LITERAL: 752100966Siwasaki 753100966Siwasaki ObjDesc->Integer.Value = Op->Common.Value.Integer; 754245582Sjkim 755151937Sjkim#ifndef ACPI_NO_METHOD_EXECUTION 756245582Sjkim if (AcpiExTruncateFor32bitTable (ObjDesc)) 757245582Sjkim { 758245582Sjkim /* Warn if we found a 64-bit constant in a 32-bit table */ 759245582Sjkim 760245582Sjkim ACPI_WARNING ((AE_INFO, 761245582Sjkim "Truncated 64-bit constant found in 32-bit table: %8.8X%8.8X => %8.8X", 762245582Sjkim ACPI_FORMAT_UINT64 (Op->Common.Value.Integer), 763245582Sjkim (UINT32) ObjDesc->Integer.Value)); 764245582Sjkim } 765151937Sjkim#endif 766100966Siwasaki break; 767100966Siwasaki 768250838Sjkim default: 769100966Siwasaki 770204773Sjkim ACPI_ERROR ((AE_INFO, "Unknown Integer type 0x%X", 771151937Sjkim OpInfo->Type)); 772100966Siwasaki Status = AE_AML_OPERAND_TYPE; 773100966Siwasaki break; 774100966Siwasaki } 775100966Siwasaki break; 776100966Siwasaki 777100966Siwasaki case ACPI_TYPE_STRING: 778100966Siwasaki 779100966Siwasaki ObjDesc->String.Pointer = Op->Common.Value.String; 780284583Sjkim ObjDesc->String.Length = (UINT32) strlen (Op->Common.Value.String); 781100966Siwasaki 782100966Siwasaki /* 783100966Siwasaki * The string is contained in the ACPI table, don't ever try 784100966Siwasaki * to delete it 785100966Siwasaki */ 786100966Siwasaki ObjDesc->Common.Flags |= AOPOBJ_STATIC_POINTER; 787100966Siwasaki break; 788100966Siwasaki 789100966Siwasaki case ACPI_TYPE_METHOD: 790100966Siwasaki break; 791100966Siwasaki 792107325Siwasaki case ACPI_TYPE_LOCAL_REFERENCE: 793100966Siwasaki 794100966Siwasaki switch (OpInfo->Type) 795100966Siwasaki { 796100966Siwasaki case AML_TYPE_LOCAL_VARIABLE: 797100966Siwasaki 798193267Sjkim /* Local ID (0-7) is (AML opcode - base AML_LOCAL_OP) */ 799100966Siwasaki 800193267Sjkim ObjDesc->Reference.Value = ((UINT32) Opcode) - AML_LOCAL_OP; 801193267Sjkim ObjDesc->Reference.Class = ACPI_REFCLASS_LOCAL; 802104470Siwasaki 803100966Siwasaki#ifndef ACPI_NO_METHOD_EXECUTION 804193267Sjkim Status = AcpiDsMethodDataGetNode (ACPI_REFCLASS_LOCAL, 805298714Sjkim ObjDesc->Reference.Value, WalkState, 806298714Sjkim ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, 807298714Sjkim &ObjDesc->Reference.Object)); 808100966Siwasaki#endif 809100966Siwasaki break; 810100966Siwasaki 811100966Siwasaki case AML_TYPE_METHOD_ARGUMENT: 812100966Siwasaki 813193267Sjkim /* Arg ID (0-6) is (AML opcode - base AML_ARG_OP) */ 814100966Siwasaki 815193267Sjkim ObjDesc->Reference.Value = ((UINT32) Opcode) - AML_ARG_OP; 816193267Sjkim ObjDesc->Reference.Class = ACPI_REFCLASS_ARG; 817126372Snjl 818126372Snjl#ifndef ACPI_NO_METHOD_EXECUTION 819193267Sjkim Status = AcpiDsMethodDataGetNode (ACPI_REFCLASS_ARG, 820298714Sjkim ObjDesc->Reference.Value, WalkState, 821298714Sjkim ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, 822298714Sjkim &ObjDesc->Reference.Object)); 823126372Snjl#endif 824100966Siwasaki break; 825100966Siwasaki 826193267Sjkim default: /* Object name or Debug object */ 827100966Siwasaki 828193267Sjkim switch (Op->Common.AmlOpcode) 829100966Siwasaki { 830193267Sjkim case AML_INT_NAMEPATH_OP: 831193267Sjkim 832100966Siwasaki /* Node was saved in Op */ 833100966Siwasaki 834100966Siwasaki ObjDesc->Reference.Node = Op->Common.Node; 835193267Sjkim ObjDesc->Reference.Object = Op->Common.Node->Object; 836193267Sjkim ObjDesc->Reference.Class = ACPI_REFCLASS_NAME; 837193267Sjkim break; 838193267Sjkim 839193267Sjkim case AML_DEBUG_OP: 840193267Sjkim 841193267Sjkim ObjDesc->Reference.Class = ACPI_REFCLASS_DEBUG; 842193267Sjkim break; 843193267Sjkim 844193267Sjkim default: 845193267Sjkim 846193267Sjkim ACPI_ERROR ((AE_INFO, 847204773Sjkim "Unimplemented reference type for AML opcode: 0x%4.4X", Opcode)); 848193267Sjkim return_ACPI_STATUS (AE_AML_OPERAND_TYPE); 849100966Siwasaki } 850100966Siwasaki break; 851100966Siwasaki } 852100966Siwasaki break; 853100966Siwasaki 854100966Siwasaki default: 855100966Siwasaki 856204773Sjkim ACPI_ERROR ((AE_INFO, "Unimplemented data type: 0x%X", 857193267Sjkim ObjDesc->Common.Type)); 858100966Siwasaki 859100966Siwasaki Status = AE_AML_OPERAND_TYPE; 860100966Siwasaki break; 861100966Siwasaki } 862100966Siwasaki 863100966Siwasaki return_ACPI_STATUS (Status); 864100966Siwasaki} 865