dsobject.c revision 204773
167754Smsmith/****************************************************************************** 267754Smsmith * 367754Smsmith * Module Name: dsobject - Dispatcher object management routines 467754Smsmith * 567754Smsmith *****************************************************************************/ 667754Smsmith 767754Smsmith/****************************************************************************** 867754Smsmith * 967754Smsmith * 1. Copyright Notice 1067754Smsmith * 11202771Sjkim * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. 1270243Smsmith * All rights reserved. 1367754Smsmith * 1467754Smsmith * 2. License 1567754Smsmith * 1667754Smsmith * 2.1. This is your license from Intel Corp. under its intellectual property 1767754Smsmith * rights. You may have additional license terms from the party that provided 1867754Smsmith * you this software, covering your right to use that party's intellectual 1967754Smsmith * property rights. 2067754Smsmith * 2167754Smsmith * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 2267754Smsmith * copy of the source code appearing in this file ("Covered Code") an 2367754Smsmith * irrevocable, perpetual, worldwide license under Intel's copyrights in the 2467754Smsmith * base code distributed originally by Intel ("Original Intel Code") to copy, 2567754Smsmith * make derivatives, distribute, use and display any portion of the Covered 2667754Smsmith * Code in any form, with the right to sublicense such rights; and 2767754Smsmith * 2867754Smsmith * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 2967754Smsmith * license (with the right to sublicense), under only those claims of Intel 3067754Smsmith * patents that are infringed by the Original Intel Code, to make, use, sell, 3167754Smsmith * offer to sell, and import the Covered Code and derivative works thereof 3267754Smsmith * solely to the minimum extent necessary to exercise the above copyright 3367754Smsmith * license, and in no event shall the patent license extend to any additions 3467754Smsmith * to or modifications of the Original Intel Code. No other license or right 3567754Smsmith * is granted directly or by implication, estoppel or otherwise; 3667754Smsmith * 3767754Smsmith * The above copyright and patent license is granted only if the following 3867754Smsmith * conditions are met: 3967754Smsmith * 4067754Smsmith * 3. Conditions 4167754Smsmith * 4267754Smsmith * 3.1. Redistribution of Source with Rights to Further Distribute Source. 4367754Smsmith * Redistribution of source code of any substantial portion of the Covered 4467754Smsmith * Code or modification with rights to further distribute source must include 4567754Smsmith * the above Copyright Notice, the above License, this list of Conditions, 4667754Smsmith * and the following Disclaimer and Export Compliance provision. In addition, 4767754Smsmith * Licensee must cause all Covered Code to which Licensee contributes to 4867754Smsmith * contain a file documenting the changes Licensee made to create that Covered 4967754Smsmith * Code and the date of any change. Licensee must include in that file the 5067754Smsmith * documentation of any changes made by any predecessor Licensee. Licensee 5167754Smsmith * must include a prominent statement that the modification is derived, 5267754Smsmith * directly or indirectly, from Original Intel Code. 5367754Smsmith * 5467754Smsmith * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 5567754Smsmith * Redistribution of source code of any substantial portion of the Covered 5667754Smsmith * Code or modification without rights to further distribute source must 5767754Smsmith * include the following Disclaimer and Export Compliance provision in the 5867754Smsmith * documentation and/or other materials provided with distribution. In 5967754Smsmith * addition, Licensee may not authorize further sublicense of source of any 6067754Smsmith * portion of the Covered Code, and must include terms to the effect that the 6167754Smsmith * license from Licensee to its licensee is limited to the intellectual 6267754Smsmith * property embodied in the software Licensee provides to its licensee, and 6367754Smsmith * not to intellectual property embodied in modifications its licensee may 6467754Smsmith * make. 6567754Smsmith * 6667754Smsmith * 3.3. Redistribution of Executable. Redistribution in executable form of any 6767754Smsmith * substantial portion of the Covered Code or modification must reproduce the 6867754Smsmith * above Copyright Notice, and the following Disclaimer and Export Compliance 6967754Smsmith * provision in the documentation and/or other materials provided with the 7067754Smsmith * distribution. 7167754Smsmith * 7267754Smsmith * 3.4. Intel retains all right, title, and interest in and to the Original 7367754Smsmith * Intel Code. 7467754Smsmith * 7567754Smsmith * 3.5. Neither the name Intel nor any other trademark owned or controlled by 7667754Smsmith * Intel shall be used in advertising or otherwise to promote the sale, use or 7767754Smsmith * other dealings in products derived from or relating to the Covered Code 7867754Smsmith * without prior written authorization from Intel. 7967754Smsmith * 8067754Smsmith * 4. Disclaimer and Export Compliance 8167754Smsmith * 8267754Smsmith * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 8367754Smsmith * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 8467754Smsmith * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 8567754Smsmith * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 8667754Smsmith * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 8767754Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 8867754Smsmith * PARTICULAR PURPOSE. 8967754Smsmith * 9067754Smsmith * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 9167754Smsmith * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 9267754Smsmith * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 9367754Smsmith * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 9467754Smsmith * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 9567754Smsmith * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 9667754Smsmith * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 9767754Smsmith * LIMITED REMEDY. 9867754Smsmith * 9967754Smsmith * 4.3. Licensee shall not export, either directly or indirectly, any of this 10067754Smsmith * software or system incorporating such software without first obtaining any 10167754Smsmith * required license or other approval from the U. S. Department of Commerce or 10267754Smsmith * any other agency or department of the United States Government. In the 10367754Smsmith * event Licensee exports any such software from the United States or 10467754Smsmith * re-exports any such software from a foreign destination, Licensee shall 10567754Smsmith * ensure that the distribution and export/re-export of the software is in 10667754Smsmith * compliance with all laws, regulations, orders, or other restrictions of the 10767754Smsmith * U.S. Export Administration Regulations. Licensee agrees that neither it nor 10867754Smsmith * any of its subsidiaries will export/re-export any technical data, process, 10967754Smsmith * software, or service, directly or indirectly, to any country for which the 11067754Smsmith * United States government or any agency thereof requires an export license, 11167754Smsmith * other governmental approval, or letter of assurance, without first obtaining 11267754Smsmith * such license, approval or letter. 11367754Smsmith * 11467754Smsmith *****************************************************************************/ 11567754Smsmith 11667754Smsmith#define __DSOBJECT_C__ 11767754Smsmith 118193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 119193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 120193341Sjkim#include <contrib/dev/acpica/include/acparser.h> 121193341Sjkim#include <contrib/dev/acpica/include/amlcode.h> 122193341Sjkim#include <contrib/dev/acpica/include/acdispat.h> 123193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 124193341Sjkim#include <contrib/dev/acpica/include/acinterp.h> 12567754Smsmith 12677424Smsmith#define _COMPONENT ACPI_DISPATCHER 12791116Smsmith ACPI_MODULE_NAME ("dsobject") 12867754Smsmith 129167802Sjkim/* Local prototypes */ 130167802Sjkim 131151937Sjkimstatic ACPI_STATUS 132151937SjkimAcpiDsBuildInternalObject ( 133151937Sjkim ACPI_WALK_STATE *WalkState, 134151937Sjkim ACPI_PARSE_OBJECT *Op, 135151937Sjkim ACPI_OPERAND_OBJECT **ObjDescPtr); 13667754Smsmith 137151937Sjkim 138100966Siwasaki#ifndef ACPI_NO_METHOD_EXECUTION 139151937Sjkim/******************************************************************************* 14067754Smsmith * 14199146Siwasaki * FUNCTION: AcpiDsBuildInternalObject 14267754Smsmith * 14399146Siwasaki * PARAMETERS: WalkState - Current walk state 14499146Siwasaki * Op - Parser object to be translated 14567754Smsmith * ObjDescPtr - Where the ACPI internal object is returned 14667754Smsmith * 14767754Smsmith * RETURN: Status 14867754Smsmith * 14967754Smsmith * DESCRIPTION: Translate a parser Op object to the equivalent namespace object 15067754Smsmith * Simple objects are any objects other than a package object! 15167754Smsmith * 152151937Sjkim ******************************************************************************/ 15367754Smsmith 154151937Sjkimstatic ACPI_STATUS 15599146SiwasakiAcpiDsBuildInternalObject ( 15667754Smsmith ACPI_WALK_STATE *WalkState, 15767754Smsmith ACPI_PARSE_OBJECT *Op, 15867754Smsmith ACPI_OPERAND_OBJECT **ObjDescPtr) 15967754Smsmith{ 16067754Smsmith ACPI_OPERAND_OBJECT *ObjDesc; 16167754Smsmith ACPI_STATUS Status; 16267754Smsmith 16367754Smsmith 164167802Sjkim ACPI_FUNCTION_TRACE (DsBuildInternalObject); 16567754Smsmith 16667754Smsmith 167104470Siwasaki *ObjDescPtr = NULL; 16899679Siwasaki if (Op->Common.AmlOpcode == AML_INT_NAMEPATH_OP) 16967754Smsmith { 17067754Smsmith /* 171167802Sjkim * This is a named object reference. If this name was 17287031Smsmith * previously looked up in the namespace, it was stored in this op. 17367754Smsmith * Otherwise, go ahead and look it up now 17467754Smsmith */ 17599679Siwasaki if (!Op->Common.Node) 17667754Smsmith { 177151937Sjkim Status = AcpiNsLookup (WalkState->ScopeInfo, 178167802Sjkim Op->Common.Value.String, 179167802Sjkim ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, 180167802Sjkim ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL, 181167802Sjkim ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, &(Op->Common.Node))); 18267754Smsmith if (ACPI_FAILURE (Status)) 18367754Smsmith { 184167802Sjkim /* Check if we are resolving a named reference within a package */ 185167802Sjkim 186167802Sjkim if ((Status == AE_NOT_FOUND) && (AcpiGbl_EnableInterpreterSlack) && 187167802Sjkim 188167802Sjkim ((Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) || 189167802Sjkim (Op->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP))) 190167802Sjkim { 191167802Sjkim /* 192167802Sjkim * We didn't find the target and we are populating elements 193167802Sjkim * of a package - ignore if slack enabled. Some ASL code 194167802Sjkim * contains dangling invalid references in packages and 195167802Sjkim * expects that no exception will be issued. Leave the 196167802Sjkim * element as a null element. It cannot be used, but it 197167802Sjkim * can be overwritten by subsequent ASL code - this is 198167802Sjkim * typically the case. 199167802Sjkim */ 200167802Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 201167802Sjkim "Ignoring unresolved reference in package [%4.4s]\n", 202167802Sjkim WalkState->ScopeInfo->Scope.Node->Name.Ascii)); 203167802Sjkim 204167802Sjkim return_ACPI_STATUS (AE_OK); 205167802Sjkim } 206167802Sjkim else 207167802Sjkim { 208167802Sjkim ACPI_ERROR_NAMESPACE (Op->Common.Value.String, Status); 209167802Sjkim } 210167802Sjkim 211104470Siwasaki return_ACPI_STATUS (Status); 21267754Smsmith } 21367754Smsmith } 214193267Sjkim 215193267Sjkim /* Special object resolution for elements of a package */ 216193267Sjkim 217193267Sjkim if ((Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) || 218193267Sjkim (Op->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP)) 219193267Sjkim { 220193267Sjkim /* 221193267Sjkim * Attempt to resolve the node to a value before we insert it into 222193267Sjkim * the package. If this is a reference to a common data type, 223193267Sjkim * resolve it immediately. According to the ACPI spec, package 224193267Sjkim * elements can only be "data objects" or method references. 225193267Sjkim * Attempt to resolve to an Integer, Buffer, String or Package. 226193267Sjkim * If cannot, return the named reference (for things like Devices, 227193267Sjkim * Methods, etc.) Buffer Fields and Fields will resolve to simple 228193267Sjkim * objects (int/buf/str/pkg). 229193267Sjkim * 230193267Sjkim * NOTE: References to things like Devices, Methods, Mutexes, etc. 231193267Sjkim * will remain as named references. This behavior is not described 232193267Sjkim * in the ACPI spec, but it appears to be an oversight. 233193267Sjkim */ 234193267Sjkim ObjDesc = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Op->Common.Node); 235193267Sjkim 236193267Sjkim Status = AcpiExResolveNodeToValue ( 237193267Sjkim ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, &ObjDesc), 238193267Sjkim WalkState); 239193267Sjkim if (ACPI_FAILURE (Status)) 240193267Sjkim { 241193267Sjkim return_ACPI_STATUS (Status); 242193267Sjkim } 243193267Sjkim 244193267Sjkim switch (Op->Common.Node->Type) 245193267Sjkim { 246193267Sjkim /* 247193267Sjkim * For these types, we need the actual node, not the subobject. 248193267Sjkim * However, the subobject did not get an extra reference count above. 249193267Sjkim * 250193267Sjkim * TBD: should ExResolveNodeToValue be changed to fix this? 251193267Sjkim */ 252193267Sjkim case ACPI_TYPE_DEVICE: 253193267Sjkim case ACPI_TYPE_THERMAL: 254193267Sjkim 255193267Sjkim AcpiUtAddReference (Op->Common.Node->Object); 256193267Sjkim 257193267Sjkim /*lint -fallthrough */ 258193267Sjkim /* 259193267Sjkim * For these types, we need the actual node, not the subobject. 260193267Sjkim * The subobject got an extra reference count in ExResolveNodeToValue. 261193267Sjkim */ 262193267Sjkim case ACPI_TYPE_MUTEX: 263193267Sjkim case ACPI_TYPE_METHOD: 264193267Sjkim case ACPI_TYPE_POWER: 265193267Sjkim case ACPI_TYPE_PROCESSOR: 266193267Sjkim case ACPI_TYPE_EVENT: 267193267Sjkim case ACPI_TYPE_REGION: 268193267Sjkim 269193267Sjkim /* We will create a reference object for these types below */ 270193267Sjkim break; 271193267Sjkim 272193267Sjkim default: 273193267Sjkim /* 274193267Sjkim * All other types - the node was resolved to an actual 275193267Sjkim * object, we are done. 276193267Sjkim */ 277193267Sjkim goto Exit; 278193267Sjkim } 279193267Sjkim } 28067754Smsmith } 28167754Smsmith 282167802Sjkim /* Create and init a new internal ACPI object */ 28367754Smsmith 284151937Sjkim ObjDesc = AcpiUtCreateInternalObject ( 285151937Sjkim (AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode))->ObjectType); 28667754Smsmith if (!ObjDesc) 28767754Smsmith { 28867754Smsmith return_ACPI_STATUS (AE_NO_MEMORY); 28967754Smsmith } 29067754Smsmith 291151937Sjkim Status = AcpiDsInitObjectFromOp (WalkState, Op, Op->Common.AmlOpcode, 292151937Sjkim &ObjDesc); 29367754Smsmith if (ACPI_FAILURE (Status)) 29467754Smsmith { 29577424Smsmith AcpiUtRemoveReference (ObjDesc); 29667754Smsmith return_ACPI_STATUS (Status); 29767754Smsmith } 29867754Smsmith 299193267SjkimExit: 30067754Smsmith *ObjDescPtr = ObjDesc; 301193267Sjkim return_ACPI_STATUS (Status); 30267754Smsmith} 30367754Smsmith 30467754Smsmith 305151937Sjkim/******************************************************************************* 30667754Smsmith * 30799146Siwasaki * FUNCTION: AcpiDsBuildInternalBufferObj 30867754Smsmith * 30999679Siwasaki * PARAMETERS: WalkState - Current walk state 31099679Siwasaki * Op - Parser object to be translated 31199679Siwasaki * BufferLength - Length of the buffer 31267754Smsmith * ObjDescPtr - Where the ACPI internal object is returned 31367754Smsmith * 31467754Smsmith * RETURN: Status 31567754Smsmith * 31667754Smsmith * DESCRIPTION: Translate a parser Op package object to the equivalent 31767754Smsmith * namespace object 31867754Smsmith * 319151937Sjkim ******************************************************************************/ 32067754Smsmith 32167754SmsmithACPI_STATUS 32299146SiwasakiAcpiDsBuildInternalBufferObj ( 32367754Smsmith ACPI_WALK_STATE *WalkState, 32467754Smsmith ACPI_PARSE_OBJECT *Op, 32599146Siwasaki UINT32 BufferLength, 32667754Smsmith ACPI_OPERAND_OBJECT **ObjDescPtr) 32767754Smsmith{ 32867754Smsmith ACPI_PARSE_OBJECT *Arg; 32967754Smsmith ACPI_OPERAND_OBJECT *ObjDesc; 33099679Siwasaki ACPI_PARSE_OBJECT *ByteList; 33199146Siwasaki UINT32 ByteListLength = 0; 33267754Smsmith 33367754Smsmith 334167802Sjkim ACPI_FUNCTION_TRACE (DsBuildInternalBufferObj); 33567754Smsmith 33667754Smsmith 337167802Sjkim /* 338167802Sjkim * If we are evaluating a Named buffer object "Name (xxxx, Buffer)". 339167802Sjkim * The buffer object already exists (from the NS node), otherwise it must 340167802Sjkim * be created. 341167802Sjkim */ 34299146Siwasaki ObjDesc = *ObjDescPtr; 343167802Sjkim if (!ObjDesc) 34467754Smsmith { 34599146Siwasaki /* Create a new buffer object */ 34667754Smsmith 34799146Siwasaki ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_BUFFER); 34899146Siwasaki *ObjDescPtr = ObjDesc; 34999146Siwasaki if (!ObjDesc) 35099146Siwasaki { 35199146Siwasaki return_ACPI_STATUS (AE_NO_MEMORY); 35299146Siwasaki } 35399146Siwasaki } 35467754Smsmith 35567754Smsmith /* 35699146Siwasaki * Second arg is the buffer data (optional) ByteList can be either 357102550Siwasaki * individual bytes or a string initializer. In either case, a 35899146Siwasaki * ByteList appears in the AML. 35967754Smsmith */ 36099679Siwasaki Arg = Op->Common.Value.Arg; /* skip first arg */ 36167754Smsmith 36299679Siwasaki ByteList = Arg->Named.Next; 36399146Siwasaki if (ByteList) 36467754Smsmith { 36599679Siwasaki if (ByteList->Common.AmlOpcode != AML_INT_BYTELIST_OP) 36699146Siwasaki { 367167802Sjkim ACPI_ERROR ((AE_INFO, 368204773Sjkim "Expecting bytelist, found AML opcode 0x%X in op %p", 36999679Siwasaki ByteList->Common.AmlOpcode, ByteList)); 37099146Siwasaki 37199146Siwasaki AcpiUtRemoveReference (ObjDesc); 37299146Siwasaki return (AE_TYPE); 37399146Siwasaki } 37499146Siwasaki 375117521Snjl ByteListLength = (UINT32) ByteList->Common.Value.Integer; 37667754Smsmith } 37767754Smsmith 37867754Smsmith /* 37999146Siwasaki * The buffer length (number of bytes) will be the larger of: 380102550Siwasaki * 1) The specified buffer length and 38199146Siwasaki * 2) The length of the initializer byte list 38267754Smsmith */ 38399146Siwasaki ObjDesc->Buffer.Length = BufferLength; 38499146Siwasaki if (ByteListLength > BufferLength) 38567754Smsmith { 38699146Siwasaki ObjDesc->Buffer.Length = ByteListLength; 38799146Siwasaki } 38867754Smsmith 38999146Siwasaki /* Allocate the buffer */ 39067754Smsmith 39199146Siwasaki if (ObjDesc->Buffer.Length == 0) 39299146Siwasaki { 39399146Siwasaki ObjDesc->Buffer.Pointer = NULL; 394117521Snjl ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 395117521Snjl "Buffer defined with zero length in AML, creating\n")); 39667754Smsmith } 397114237Snjl else 39899146Siwasaki { 399167802Sjkim ObjDesc->Buffer.Pointer = ACPI_ALLOCATE_ZEROED ( 400114237Snjl ObjDesc->Buffer.Length); 401114237Snjl if (!ObjDesc->Buffer.Pointer) 402114237Snjl { 403114237Snjl AcpiUtDeleteObjectDesc (ObjDesc); 404114237Snjl return_ACPI_STATUS (AE_NO_MEMORY); 405114237Snjl } 40699146Siwasaki 407114237Snjl /* Initialize buffer from the ByteList (if present) */ 40899146Siwasaki 409114237Snjl if (ByteList) 410114237Snjl { 411114237Snjl ACPI_MEMCPY (ObjDesc->Buffer.Pointer, ByteList->Named.Data, 412114237Snjl ByteListLength); 413114237Snjl } 41499146Siwasaki } 41599146Siwasaki 41699146Siwasaki ObjDesc->Buffer.Flags |= AOPOBJ_DATA_VALID; 417167802Sjkim Op->Common.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjDesc); 41899146Siwasaki return_ACPI_STATUS (AE_OK); 41967754Smsmith} 42067754Smsmith 42167754Smsmith 422151937Sjkim/******************************************************************************* 42367754Smsmith * 42499146Siwasaki * FUNCTION: AcpiDsBuildInternalPackageObj 42567754Smsmith * 42699679Siwasaki * PARAMETERS: WalkState - Current walk state 42799679Siwasaki * Op - Parser object to be translated 428167802Sjkim * ElementCount - Number of elements in the package - this is 429167802Sjkim * the NumElements argument to Package() 43067754Smsmith * ObjDescPtr - Where the ACPI internal object is returned 43167754Smsmith * 43267754Smsmith * RETURN: Status 43367754Smsmith * 43499146Siwasaki * DESCRIPTION: Translate a parser Op package object to the equivalent 43599146Siwasaki * namespace object 43667754Smsmith * 437167802Sjkim * NOTE: The number of elements in the package will be always be the NumElements 438167802Sjkim * count, regardless of the number of elements in the package list. If 439167802Sjkim * NumElements is smaller, only that many package list elements are used. 440167802Sjkim * if NumElements is larger, the Package object is padded out with 441167802Sjkim * objects of type Uninitialized (as per ACPI spec.) 442167802Sjkim * 443167802Sjkim * Even though the ASL compilers do not allow NumElements to be smaller 444167802Sjkim * than the Package list length (for the fixed length package opcode), some 445167802Sjkim * BIOS code modifies the AML on the fly to adjust the NumElements, and 446167802Sjkim * this code compensates for that. This also provides compatibility with 447167802Sjkim * other AML interpreters. 448167802Sjkim * 449151937Sjkim ******************************************************************************/ 45067754Smsmith 45167754SmsmithACPI_STATUS 45299146SiwasakiAcpiDsBuildInternalPackageObj ( 45367754Smsmith ACPI_WALK_STATE *WalkState, 45467754Smsmith ACPI_PARSE_OBJECT *Op, 455167802Sjkim UINT32 ElementCount, 45667754Smsmith ACPI_OPERAND_OBJECT **ObjDescPtr) 45767754Smsmith{ 45899146Siwasaki ACPI_PARSE_OBJECT *Arg; 45999146Siwasaki ACPI_PARSE_OBJECT *Parent; 46099146Siwasaki ACPI_OPERAND_OBJECT *ObjDesc = NULL; 46199146Siwasaki ACPI_STATUS Status = AE_OK; 462193267Sjkim UINT32 i; 463167802Sjkim UINT16 Index; 464167802Sjkim UINT16 ReferenceCount; 46567754Smsmith 46667754Smsmith 467167802Sjkim ACPI_FUNCTION_TRACE (DsBuildInternalPackageObj); 46899146Siwasaki 46999146Siwasaki 47099146Siwasaki /* Find the parent of a possibly nested package */ 47199146Siwasaki 47299679Siwasaki Parent = Op->Common.Parent; 473167802Sjkim while ((Parent->Common.AmlOpcode == AML_PACKAGE_OP) || 47499679Siwasaki (Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP)) 47567754Smsmith { 47699679Siwasaki Parent = Parent->Common.Parent; 47799146Siwasaki } 47882367Smsmith 479167802Sjkim /* 480167802Sjkim * If we are evaluating a Named package object "Name (xxxx, Package)", 481167802Sjkim * the package object already exists, otherwise it must be created. 482167802Sjkim */ 48399146Siwasaki ObjDesc = *ObjDescPtr; 484167802Sjkim if (!ObjDesc) 48599146Siwasaki { 48699146Siwasaki ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_PACKAGE); 48799146Siwasaki *ObjDescPtr = ObjDesc; 48899146Siwasaki if (!ObjDesc) 48999146Siwasaki { 49099146Siwasaki return_ACPI_STATUS (AE_NO_MEMORY); 49199146Siwasaki } 49267754Smsmith 49399679Siwasaki ObjDesc->Package.Node = Parent->Common.Node; 49499146Siwasaki } 49582367Smsmith 49699146Siwasaki /* 497167802Sjkim * Allocate the element array (array of pointers to the individual 498167802Sjkim * objects) based on the NumElements parameter. Add an extra pointer slot 499167802Sjkim * so that the list is always null terminated. 50099146Siwasaki */ 501167802Sjkim ObjDesc->Package.Elements = ACPI_ALLOCATE_ZEROED ( 502167802Sjkim ((ACPI_SIZE) ElementCount + 1) * sizeof (void *)); 50399146Siwasaki 50499146Siwasaki if (!ObjDesc->Package.Elements) 50599146Siwasaki { 50699146Siwasaki AcpiUtDeleteObjectDesc (ObjDesc); 50799146Siwasaki return_ACPI_STATUS (AE_NO_MEMORY); 50899146Siwasaki } 50999146Siwasaki 510167802Sjkim ObjDesc->Package.Count = ElementCount; 511167802Sjkim 51299146Siwasaki /* 513167802Sjkim * Initialize the elements of the package, up to the NumElements count. 514167802Sjkim * Package is automatically padded with uninitialized (NULL) elements 515167802Sjkim * if NumElements is greater than the package list length. Likewise, 516167802Sjkim * Package is truncated if NumElements is less than the list length. 51799146Siwasaki */ 51899679Siwasaki Arg = Op->Common.Value.Arg; 51999679Siwasaki Arg = Arg->Common.Next; 520167802Sjkim for (i = 0; Arg && (i < ElementCount); i++) 52199146Siwasaki { 52299679Siwasaki if (Arg->Common.AmlOpcode == AML_INT_RETURN_VALUE_OP) 52399146Siwasaki { 524193267Sjkim if (Arg->Common.Node->Type == ACPI_TYPE_METHOD) 525193267Sjkim { 526193267Sjkim /* 527193267Sjkim * A method reference "looks" to the parser to be a method 528193267Sjkim * invocation, so we special case it here 529193267Sjkim */ 530193267Sjkim Arg->Common.AmlOpcode = AML_INT_NAMEPATH_OP; 531193267Sjkim Status = AcpiDsBuildInternalObject (WalkState, Arg, 532193267Sjkim &ObjDesc->Package.Elements[i]); 533193267Sjkim } 534193267Sjkim else 535193267Sjkim { 536193267Sjkim /* This package element is already built, just get it */ 53799146Siwasaki 538193267Sjkim ObjDesc->Package.Elements[i] = 539193267Sjkim ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Arg->Common.Node); 540193267Sjkim } 54199146Siwasaki } 54299146Siwasaki else 54399146Siwasaki { 54499146Siwasaki Status = AcpiDsBuildInternalObject (WalkState, Arg, 545151937Sjkim &ObjDesc->Package.Elements[i]); 54699146Siwasaki } 54799146Siwasaki 548167802Sjkim if (*ObjDescPtr) 549167802Sjkim { 550167802Sjkim /* Existing package, get existing reference count */ 551167802Sjkim 552167802Sjkim ReferenceCount = (*ObjDescPtr)->Common.ReferenceCount; 553167802Sjkim if (ReferenceCount > 1) 554167802Sjkim { 555167802Sjkim /* Make new element ref count match original ref count */ 556167802Sjkim 557167802Sjkim for (Index = 0; Index < (ReferenceCount - 1); Index++) 558167802Sjkim { 559167802Sjkim AcpiUtAddReference ((ObjDesc->Package.Elements[i])); 560167802Sjkim } 561167802Sjkim } 562167802Sjkim } 563167802Sjkim 56499679Siwasaki Arg = Arg->Common.Next; 56599146Siwasaki } 56699146Siwasaki 567193267Sjkim /* Check for match between NumElements and actual length of PackageList */ 568193267Sjkim 569193267Sjkim if (Arg) 570167802Sjkim { 571193267Sjkim /* 572193267Sjkim * NumElements was exhausted, but there are remaining elements in the 573197104Sjkim * PackageList. Truncate the package to NumElements. 574193267Sjkim * 575193267Sjkim * Note: technically, this is an error, from ACPI spec: "It is an error 576193267Sjkim * for NumElements to be less than the number of elements in the 577199337Sjkim * PackageList". However, we just print a message and 578197104Sjkim * no exception is returned. This provides Windows compatibility. Some 579197104Sjkim * BIOSs will alter the NumElements on the fly, creating this type 580197104Sjkim * of ill-formed package object. 581193267Sjkim */ 582193267Sjkim while (Arg) 583193267Sjkim { 584197104Sjkim /* 585197104Sjkim * We must delete any package elements that were created earlier 586197104Sjkim * and are not going to be used because of the package truncation. 587197104Sjkim */ 588197104Sjkim if (Arg->Common.Node) 589197104Sjkim { 590197104Sjkim AcpiUtRemoveReference ( 591197104Sjkim ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Arg->Common.Node)); 592197104Sjkim Arg->Common.Node = NULL; 593197104Sjkim } 594197104Sjkim 595193267Sjkim /* Find out how many elements there really are */ 596193267Sjkim 597193267Sjkim i++; 598193267Sjkim Arg = Arg->Common.Next; 599193267Sjkim } 600193267Sjkim 601199337Sjkim ACPI_INFO ((AE_INFO, 602204773Sjkim "Actual Package length (%u) is larger than NumElements field (%u), truncated\n", 603193267Sjkim i, ElementCount)); 604193267Sjkim } 605193267Sjkim else if (i < ElementCount) 606193267Sjkim { 607193267Sjkim /* 608193267Sjkim * Arg list (elements) was exhausted, but we did not reach NumElements count. 609193267Sjkim * Note: this is not an error, the package is padded out with NULLs. 610193267Sjkim */ 611167802Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 612204773Sjkim "Package List length (%u) smaller than NumElements count (%u), padded with null elements\n", 613193267Sjkim i, ElementCount)); 614167802Sjkim } 615167802Sjkim 61699146Siwasaki ObjDesc->Package.Flags |= AOPOBJ_DATA_VALID; 617167802Sjkim Op->Common.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjDesc); 61899146Siwasaki return_ACPI_STATUS (Status); 61967754Smsmith} 62067754Smsmith 62167754Smsmith 622151937Sjkim/******************************************************************************* 62367754Smsmith * 62467754Smsmith * FUNCTION: AcpiDsCreateNode 62567754Smsmith * 62699679Siwasaki * PARAMETERS: WalkState - Current walk state 62799679Siwasaki * Node - NS Node to be initialized 62899679Siwasaki * Op - Parser object to be translated 62967754Smsmith * 63067754Smsmith * RETURN: Status 63167754Smsmith * 63299679Siwasaki * DESCRIPTION: Create the object to be associated with a namespace node 63367754Smsmith * 634151937Sjkim ******************************************************************************/ 63567754Smsmith 63667754SmsmithACPI_STATUS 63767754SmsmithAcpiDsCreateNode ( 63867754Smsmith ACPI_WALK_STATE *WalkState, 63967754Smsmith ACPI_NAMESPACE_NODE *Node, 64067754Smsmith ACPI_PARSE_OBJECT *Op) 64167754Smsmith{ 64267754Smsmith ACPI_STATUS Status; 64367754Smsmith ACPI_OPERAND_OBJECT *ObjDesc; 64467754Smsmith 64567754Smsmith 646167802Sjkim ACPI_FUNCTION_TRACE_PTR (DsCreateNode, Op); 64767754Smsmith 64867754Smsmith 64985756Smsmith /* 65085756Smsmith * Because of the execution pass through the non-control-method 65185756Smsmith * parts of the table, we can arrive here twice. Only init 65285756Smsmith * the named object node the first time through 65385756Smsmith */ 65487031Smsmith if (AcpiNsGetAttachedObject (Node)) 65585756Smsmith { 65685756Smsmith return_ACPI_STATUS (AE_OK); 65785756Smsmith } 65885756Smsmith 65999679Siwasaki if (!Op->Common.Value.Arg) 66067754Smsmith { 66167754Smsmith /* No arguments, there is nothing to do */ 66267754Smsmith 66367754Smsmith return_ACPI_STATUS (AE_OK); 66467754Smsmith } 66567754Smsmith 66667754Smsmith /* Build an internal object for the argument(s) */ 66767754Smsmith 668151937Sjkim Status = AcpiDsBuildInternalObject (WalkState, Op->Common.Value.Arg, 669151937Sjkim &ObjDesc); 67067754Smsmith if (ACPI_FAILURE (Status)) 67167754Smsmith { 67267754Smsmith return_ACPI_STATUS (Status); 67367754Smsmith } 67467754Smsmith 675114237Snjl /* Re-type the object according to its argument */ 67667754Smsmith 677193267Sjkim Node->Type = ObjDesc->Common.Type; 67867754Smsmith 67999146Siwasaki /* Attach obj to node */ 68067754Smsmith 68191116Smsmith Status = AcpiNsAttachObject (Node, ObjDesc, Node->Type); 68267754Smsmith 68385756Smsmith /* Remove local reference to the object */ 68467754Smsmith 68577424Smsmith AcpiUtRemoveReference (ObjDesc); 68667754Smsmith return_ACPI_STATUS (Status); 68767754Smsmith} 68867754Smsmith 689100966Siwasaki#endif /* ACPI_NO_METHOD_EXECUTION */ 69067754Smsmith 691100966Siwasaki 692151937Sjkim/******************************************************************************* 693100966Siwasaki * 694100966Siwasaki * FUNCTION: AcpiDsInitObjectFromOp 695100966Siwasaki * 696100966Siwasaki * PARAMETERS: WalkState - Current walk state 697100966Siwasaki * Op - Parser op used to init the internal object 698100966Siwasaki * Opcode - AML opcode associated with the object 699100966Siwasaki * RetObjDesc - Namespace object to be initialized 700100966Siwasaki * 701100966Siwasaki * RETURN: Status 702100966Siwasaki * 703100966Siwasaki * DESCRIPTION: Initialize a namespace object from a parser Op and its 704100966Siwasaki * associated arguments. The namespace object is a more compact 705100966Siwasaki * representation of the Op and its arguments. 706100966Siwasaki * 707151937Sjkim ******************************************************************************/ 708100966Siwasaki 709100966SiwasakiACPI_STATUS 710100966SiwasakiAcpiDsInitObjectFromOp ( 711100966Siwasaki ACPI_WALK_STATE *WalkState, 712100966Siwasaki ACPI_PARSE_OBJECT *Op, 713100966Siwasaki UINT16 Opcode, 714100966Siwasaki ACPI_OPERAND_OBJECT **RetObjDesc) 715100966Siwasaki{ 716100966Siwasaki const ACPI_OPCODE_INFO *OpInfo; 717100966Siwasaki ACPI_OPERAND_OBJECT *ObjDesc; 718100966Siwasaki ACPI_STATUS Status = AE_OK; 719100966Siwasaki 720100966Siwasaki 721167802Sjkim ACPI_FUNCTION_TRACE (DsInitObjectFromOp); 722100966Siwasaki 723100966Siwasaki 724100966Siwasaki ObjDesc = *RetObjDesc; 725100966Siwasaki OpInfo = AcpiPsGetOpcodeInfo (Opcode); 726100966Siwasaki if (OpInfo->Class == AML_CLASS_UNKNOWN) 727100966Siwasaki { 728100966Siwasaki /* Unknown opcode */ 729100966Siwasaki 730100966Siwasaki return_ACPI_STATUS (AE_TYPE); 731100966Siwasaki } 732100966Siwasaki 733100966Siwasaki /* Perform per-object initialization */ 734100966Siwasaki 735193267Sjkim switch (ObjDesc->Common.Type) 736100966Siwasaki { 737100966Siwasaki case ACPI_TYPE_BUFFER: 738100966Siwasaki 739100966Siwasaki /* 740100966Siwasaki * Defer evaluation of Buffer TermArg operand 741100966Siwasaki */ 742167802Sjkim ObjDesc->Buffer.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, 743167802Sjkim WalkState->Operands[0]); 744100966Siwasaki ObjDesc->Buffer.AmlStart = Op->Named.Data; 745100966Siwasaki ObjDesc->Buffer.AmlLength = Op->Named.Length; 746100966Siwasaki break; 747100966Siwasaki 748100966Siwasaki 749100966Siwasaki case ACPI_TYPE_PACKAGE: 750100966Siwasaki 751100966Siwasaki /* 752100966Siwasaki * Defer evaluation of Package TermArg operand 753100966Siwasaki */ 754167802Sjkim ObjDesc->Package.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, 755167802Sjkim WalkState->Operands[0]); 756100966Siwasaki ObjDesc->Package.AmlStart = Op->Named.Data; 757100966Siwasaki ObjDesc->Package.AmlLength = Op->Named.Length; 758100966Siwasaki break; 759100966Siwasaki 760100966Siwasaki 761102550Siwasaki case ACPI_TYPE_INTEGER: 762100966Siwasaki 763100966Siwasaki switch (OpInfo->Type) 764100966Siwasaki { 765100966Siwasaki case AML_TYPE_CONSTANT: 766100966Siwasaki /* 767100966Siwasaki * Resolve AML Constants here - AND ONLY HERE! 768100966Siwasaki * All constants are integers. 769151937Sjkim * We mark the integer with a flag that indicates that it started 770151937Sjkim * life as a constant -- so that stores to constants will perform 771151937Sjkim * as expected (noop). ZeroOp is used as a placeholder for optional 772151937Sjkim * target operands. 773100966Siwasaki */ 774100966Siwasaki ObjDesc->Common.Flags = AOPOBJ_AML_CONSTANT; 775100966Siwasaki 776100966Siwasaki switch (Opcode) 777100966Siwasaki { 778100966Siwasaki case AML_ZERO_OP: 779100966Siwasaki 780100966Siwasaki ObjDesc->Integer.Value = 0; 781100966Siwasaki break; 782100966Siwasaki 783100966Siwasaki case AML_ONE_OP: 784100966Siwasaki 785100966Siwasaki ObjDesc->Integer.Value = 1; 786100966Siwasaki break; 787100966Siwasaki 788100966Siwasaki case AML_ONES_OP: 789100966Siwasaki 790202771Sjkim ObjDesc->Integer.Value = ACPI_UINT64_MAX; 791100966Siwasaki 792100966Siwasaki /* Truncate value if we are executing from a 32-bit ACPI table */ 793100966Siwasaki 794100966Siwasaki#ifndef ACPI_NO_METHOD_EXECUTION 795100966Siwasaki AcpiExTruncateFor32bitTable (ObjDesc); 796100966Siwasaki#endif 797100966Siwasaki break; 798100966Siwasaki 799100966Siwasaki case AML_REVISION_OP: 800100966Siwasaki 801151937Sjkim ObjDesc->Integer.Value = ACPI_CA_VERSION; 802100966Siwasaki break; 803100966Siwasaki 804100966Siwasaki default: 805100966Siwasaki 806167802Sjkim ACPI_ERROR ((AE_INFO, 807204773Sjkim "Unknown constant opcode 0x%X", Opcode)); 808100966Siwasaki Status = AE_AML_OPERAND_TYPE; 809100966Siwasaki break; 810100966Siwasaki } 811100966Siwasaki break; 812100966Siwasaki 813100966Siwasaki 814100966Siwasaki case AML_TYPE_LITERAL: 815100966Siwasaki 816100966Siwasaki ObjDesc->Integer.Value = Op->Common.Value.Integer; 817151937Sjkim#ifndef ACPI_NO_METHOD_EXECUTION 818151937Sjkim AcpiExTruncateFor32bitTable (ObjDesc); 819151937Sjkim#endif 820100966Siwasaki break; 821100966Siwasaki 822100966Siwasaki 823100966Siwasaki default: 824204773Sjkim ACPI_ERROR ((AE_INFO, "Unknown Integer type 0x%X", 825151937Sjkim OpInfo->Type)); 826100966Siwasaki Status = AE_AML_OPERAND_TYPE; 827100966Siwasaki break; 828100966Siwasaki } 829100966Siwasaki break; 830100966Siwasaki 831100966Siwasaki 832100966Siwasaki case ACPI_TYPE_STRING: 833100966Siwasaki 834100966Siwasaki ObjDesc->String.Pointer = Op->Common.Value.String; 835107325Siwasaki ObjDesc->String.Length = (UINT32) ACPI_STRLEN (Op->Common.Value.String); 836100966Siwasaki 837100966Siwasaki /* 838100966Siwasaki * The string is contained in the ACPI table, don't ever try 839100966Siwasaki * to delete it 840100966Siwasaki */ 841100966Siwasaki ObjDesc->Common.Flags |= AOPOBJ_STATIC_POINTER; 842100966Siwasaki break; 843100966Siwasaki 844100966Siwasaki 845100966Siwasaki case ACPI_TYPE_METHOD: 846100966Siwasaki break; 847100966Siwasaki 848100966Siwasaki 849107325Siwasaki case ACPI_TYPE_LOCAL_REFERENCE: 850100966Siwasaki 851100966Siwasaki switch (OpInfo->Type) 852100966Siwasaki { 853100966Siwasaki case AML_TYPE_LOCAL_VARIABLE: 854100966Siwasaki 855193267Sjkim /* Local ID (0-7) is (AML opcode - base AML_LOCAL_OP) */ 856100966Siwasaki 857193267Sjkim ObjDesc->Reference.Value = ((UINT32) Opcode) - AML_LOCAL_OP; 858193267Sjkim ObjDesc->Reference.Class = ACPI_REFCLASS_LOCAL; 859104470Siwasaki 860100966Siwasaki#ifndef ACPI_NO_METHOD_EXECUTION 861193267Sjkim Status = AcpiDsMethodDataGetNode (ACPI_REFCLASS_LOCAL, 862193267Sjkim ObjDesc->Reference.Value, WalkState, 863193267Sjkim ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, 864193267Sjkim &ObjDesc->Reference.Object)); 865100966Siwasaki#endif 866100966Siwasaki break; 867100966Siwasaki 868100966Siwasaki 869100966Siwasaki case AML_TYPE_METHOD_ARGUMENT: 870100966Siwasaki 871193267Sjkim /* Arg ID (0-6) is (AML opcode - base AML_ARG_OP) */ 872100966Siwasaki 873193267Sjkim ObjDesc->Reference.Value = ((UINT32) Opcode) - AML_ARG_OP; 874193267Sjkim ObjDesc->Reference.Class = ACPI_REFCLASS_ARG; 875126372Snjl 876126372Snjl#ifndef ACPI_NO_METHOD_EXECUTION 877193267Sjkim Status = AcpiDsMethodDataGetNode (ACPI_REFCLASS_ARG, 878193267Sjkim ObjDesc->Reference.Value, WalkState, 879193267Sjkim ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, 880193267Sjkim &ObjDesc->Reference.Object)); 881126372Snjl#endif 882100966Siwasaki break; 883100966Siwasaki 884193267Sjkim default: /* Object name or Debug object */ 885100966Siwasaki 886193267Sjkim switch (Op->Common.AmlOpcode) 887100966Siwasaki { 888193267Sjkim case AML_INT_NAMEPATH_OP: 889193267Sjkim 890100966Siwasaki /* Node was saved in Op */ 891100966Siwasaki 892100966Siwasaki ObjDesc->Reference.Node = Op->Common.Node; 893193267Sjkim ObjDesc->Reference.Object = Op->Common.Node->Object; 894193267Sjkim ObjDesc->Reference.Class = ACPI_REFCLASS_NAME; 895193267Sjkim break; 896193267Sjkim 897193267Sjkim case AML_DEBUG_OP: 898193267Sjkim 899193267Sjkim ObjDesc->Reference.Class = ACPI_REFCLASS_DEBUG; 900193267Sjkim break; 901193267Sjkim 902193267Sjkim default: 903193267Sjkim 904193267Sjkim ACPI_ERROR ((AE_INFO, 905204773Sjkim "Unimplemented reference type for AML opcode: 0x%4.4X", Opcode)); 906193267Sjkim return_ACPI_STATUS (AE_AML_OPERAND_TYPE); 907100966Siwasaki } 908100966Siwasaki break; 909100966Siwasaki } 910100966Siwasaki break; 911100966Siwasaki 912100966Siwasaki 913100966Siwasaki default: 914100966Siwasaki 915204773Sjkim ACPI_ERROR ((AE_INFO, "Unimplemented data type: 0x%X", 916193267Sjkim ObjDesc->Common.Type)); 917100966Siwasaki 918100966Siwasaki Status = AE_AML_OPERAND_TYPE; 919100966Siwasaki break; 920100966Siwasaki } 921100966Siwasaki 922100966Siwasaki return_ACPI_STATUS (Status); 923100966Siwasaki} 924100966Siwasaki 925100966Siwasaki 926