Path: blob/main/sys/contrib/dev/acpica/components/dispatcher/dsobject.c
48521 views
/******************************************************************************1*2* Module Name: dsobject - Dispatcher object management routines3*4*****************************************************************************/56/******************************************************************************7*8* 1. Copyright Notice9*10* Some or all of this work - Copyright (c) 1999 - 2025, Intel Corp.11* All rights reserved.12*13* 2. License14*15* 2.1. This is your license from Intel Corp. under its intellectual property16* rights. You may have additional license terms from the party that provided17* you this software, covering your right to use that party's intellectual18* property rights.19*20* 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a21* copy of the source code appearing in this file ("Covered Code") an22* irrevocable, perpetual, worldwide license under Intel's copyrights in the23* base code distributed originally by Intel ("Original Intel Code") to copy,24* make derivatives, distribute, use and display any portion of the Covered25* Code in any form, with the right to sublicense such rights; and26*27* 2.3. Intel grants Licensee a non-exclusive and non-transferable patent28* license (with the right to sublicense), under only those claims of Intel29* patents that are infringed by the Original Intel Code, to make, use, sell,30* offer to sell, and import the Covered Code and derivative works thereof31* solely to the minimum extent necessary to exercise the above copyright32* license, and in no event shall the patent license extend to any additions33* to or modifications of the Original Intel Code. No other license or right34* is granted directly or by implication, estoppel or otherwise;35*36* The above copyright and patent license is granted only if the following37* conditions are met:38*39* 3. Conditions40*41* 3.1. Redistribution of Source with Rights to Further Distribute Source.42* Redistribution of source code of any substantial portion of the Covered43* Code or modification with rights to further distribute source must include44* the above Copyright Notice, the above License, this list of Conditions,45* and the following Disclaimer and Export Compliance provision. In addition,46* Licensee must cause all Covered Code to which Licensee contributes to47* contain a file documenting the changes Licensee made to create that Covered48* Code and the date of any change. Licensee must include in that file the49* documentation of any changes made by any predecessor Licensee. Licensee50* must include a prominent statement that the modification is derived,51* directly or indirectly, from Original Intel Code.52*53* 3.2. Redistribution of Source with no Rights to Further Distribute Source.54* Redistribution of source code of any substantial portion of the Covered55* Code or modification without rights to further distribute source must56* include the following Disclaimer and Export Compliance provision in the57* documentation and/or other materials provided with distribution. In58* addition, Licensee may not authorize further sublicense of source of any59* portion of the Covered Code, and must include terms to the effect that the60* license from Licensee to its licensee is limited to the intellectual61* property embodied in the software Licensee provides to its licensee, and62* not to intellectual property embodied in modifications its licensee may63* make.64*65* 3.3. Redistribution of Executable. Redistribution in executable form of any66* substantial portion of the Covered Code or modification must reproduce the67* above Copyright Notice, and the following Disclaimer and Export Compliance68* provision in the documentation and/or other materials provided with the69* distribution.70*71* 3.4. Intel retains all right, title, and interest in and to the Original72* Intel Code.73*74* 3.5. Neither the name Intel nor any other trademark owned or controlled by75* Intel shall be used in advertising or otherwise to promote the sale, use or76* other dealings in products derived from or relating to the Covered Code77* without prior written authorization from Intel.78*79* 4. Disclaimer and Export Compliance80*81* 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED82* HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE83* IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,84* INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY85* UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY86* IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A87* PARTICULAR PURPOSE.88*89* 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES90* OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR91* COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,92* SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY93* CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL94* HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS95* SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY96* LIMITED REMEDY.97*98* 4.3. Licensee shall not export, either directly or indirectly, any of this99* software or system incorporating such software without first obtaining any100* required license or other approval from the U. S. Department of Commerce or101* any other agency or department of the United States Government. In the102* event Licensee exports any such software from the United States or103* re-exports any such software from a foreign destination, Licensee shall104* ensure that the distribution and export/re-export of the software is in105* compliance with all laws, regulations, orders, or other restrictions of the106* U.S. Export Administration Regulations. Licensee agrees that neither it nor107* any of its subsidiaries will export/re-export any technical data, process,108* software, or service, directly or indirectly, to any country for which the109* United States government or any agency thereof requires an export license,110* other governmental approval, or letter of assurance, without first obtaining111* such license, approval or letter.112*113*****************************************************************************114*115* Alternatively, you may choose to be licensed under the terms of the116* following license:117*118* Redistribution and use in source and binary forms, with or without119* modification, are permitted provided that the following conditions120* are met:121* 1. Redistributions of source code must retain the above copyright122* notice, this list of conditions, and the following disclaimer,123* without modification.124* 2. Redistributions in binary form must reproduce at minimum a disclaimer125* substantially similar to the "NO WARRANTY" disclaimer below126* ("Disclaimer") and any redistribution must be conditioned upon127* including a substantially similar Disclaimer requirement for further128* binary redistribution.129* 3. Neither the names of the above-listed copyright holders nor the names130* of any contributors may be used to endorse or promote products derived131* from this software without specific prior written permission.132*133* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS134* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT135* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR136* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT137* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,138* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT139* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,140* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY141* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT142* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE143* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.144*145* Alternatively, you may choose to be licensed under the terms of the146* GNU General Public License ("GPL") version 2 as published by the Free147* Software Foundation.148*149*****************************************************************************/150151#include <contrib/dev/acpica/include/acpi.h>152#include <contrib/dev/acpica/include/accommon.h>153#include <contrib/dev/acpica/include/acparser.h>154#include <contrib/dev/acpica/include/amlcode.h>155#include <contrib/dev/acpica/include/acdispat.h>156#include <contrib/dev/acpica/include/acnamesp.h>157#include <contrib/dev/acpica/include/acinterp.h>158159#define _COMPONENT ACPI_DISPATCHER160ACPI_MODULE_NAME ("dsobject")161162163/*******************************************************************************164*165* FUNCTION: AcpiDsBuildInternalObject166*167* PARAMETERS: WalkState - Current walk state168* Op - Parser object to be translated169* ObjDescPtr - Where the ACPI internal object is returned170*171* RETURN: Status172*173* DESCRIPTION: Translate a parser Op object to the equivalent namespace object174* Simple objects are any objects other than a package object!175*176******************************************************************************/177178ACPI_STATUS179AcpiDsBuildInternalObject (180ACPI_WALK_STATE *WalkState,181ACPI_PARSE_OBJECT *Op,182ACPI_OPERAND_OBJECT **ObjDescPtr)183{184ACPI_OPERAND_OBJECT *ObjDesc;185ACPI_STATUS Status;186187188ACPI_FUNCTION_TRACE (DsBuildInternalObject);189190191*ObjDescPtr = NULL;192if (Op->Common.AmlOpcode == AML_INT_NAMEPATH_OP)193{194/*195* This is a named object reference. If this name was196* previously looked up in the namespace, it was stored in197* this op. Otherwise, go ahead and look it up now198*/199if (!Op->Common.Node)200{201/* Check if we are resolving a named reference within a package */202203if ((Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||204(Op->Common.Parent->Common.AmlOpcode == AML_VARIABLE_PACKAGE_OP))205{206/*207* We won't resolve package elements here, we will do this208* after all ACPI tables are loaded into the namespace. This209* behavior supports both forward references to named objects210* and external references to objects in other tables.211*/212goto CreateNewObject;213}214else215{216Status = AcpiNsLookup (WalkState->ScopeInfo,217Op->Common.Value.String,218ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,219ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL,220ACPI_CAST_INDIRECT_PTR (221ACPI_NAMESPACE_NODE, &(Op->Common.Node)));222if (ACPI_FAILURE (Status))223{224ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo,225Op->Common.Value.String, Status);226return_ACPI_STATUS (Status);227}228}229}230}231232CreateNewObject:233234/* Create and init a new internal ACPI object */235236ObjDesc = AcpiUtCreateInternalObject (237(AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode))->ObjectType);238if (!ObjDesc)239{240return_ACPI_STATUS (AE_NO_MEMORY);241}242243Status = AcpiDsInitObjectFromOp (244WalkState, Op, Op->Common.AmlOpcode, &ObjDesc);245if (ACPI_FAILURE (Status))246{247AcpiUtRemoveReference (ObjDesc);248return_ACPI_STATUS (Status);249}250251/*252* Handling for unresolved package reference elements.253* These are elements that are namepaths.254*/255if ((Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||256(Op->Common.Parent->Common.AmlOpcode == AML_VARIABLE_PACKAGE_OP))257{258ObjDesc->Reference.Resolved = TRUE;259260if ((Op->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&261!ObjDesc->Reference.Node)262{263/*264* Name was unresolved above.265* Get the prefix node for later lookup266*/267ObjDesc->Reference.Node = WalkState->ScopeInfo->Scope.Node;268ObjDesc->Reference.Aml = Op->Common.Aml;269ObjDesc->Reference.Resolved = FALSE;270}271}272273*ObjDescPtr = ObjDesc;274return_ACPI_STATUS (Status);275}276277278/*******************************************************************************279*280* FUNCTION: AcpiDsBuildInternalBufferObj281*282* PARAMETERS: WalkState - Current walk state283* Op - Parser object to be translated284* BufferLength - Length of the buffer285* ObjDescPtr - Where the ACPI internal object is returned286*287* RETURN: Status288*289* DESCRIPTION: Translate a parser Op package object to the equivalent290* namespace object291*292******************************************************************************/293294ACPI_STATUS295AcpiDsBuildInternalBufferObj (296ACPI_WALK_STATE *WalkState,297ACPI_PARSE_OBJECT *Op,298UINT32 BufferLength,299ACPI_OPERAND_OBJECT **ObjDescPtr)300{301ACPI_PARSE_OBJECT *Arg;302ACPI_OPERAND_OBJECT *ObjDesc;303ACPI_PARSE_OBJECT *ByteList;304UINT32 ByteListLength = 0;305306307ACPI_FUNCTION_TRACE (DsBuildInternalBufferObj);308309310/*311* If we are evaluating a Named buffer object "Name (xxxx, Buffer)".312* The buffer object already exists (from the NS node), otherwise it must313* be created.314*/315ObjDesc = *ObjDescPtr;316if (!ObjDesc)317{318/* Create a new buffer object */319320ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_BUFFER);321*ObjDescPtr = ObjDesc;322if (!ObjDesc)323{324return_ACPI_STATUS (AE_NO_MEMORY);325}326}327328/*329* Second arg is the buffer data (optional) ByteList can be either330* individual bytes or a string initializer. In either case, a331* ByteList appears in the AML.332*/333Arg = Op->Common.Value.Arg; /* skip first arg */334335ByteList = Arg->Named.Next;336if (ByteList)337{338if (ByteList->Common.AmlOpcode != AML_INT_BYTELIST_OP)339{340ACPI_ERROR ((AE_INFO,341"Expecting bytelist, found AML opcode 0x%X in op %p",342ByteList->Common.AmlOpcode, ByteList));343344AcpiUtRemoveReference (ObjDesc);345return (AE_TYPE);346}347348ByteListLength = (UINT32) ByteList->Common.Value.Integer;349}350351/*352* The buffer length (number of bytes) will be the larger of:353* 1) The specified buffer length and354* 2) The length of the initializer byte list355*/356ObjDesc->Buffer.Length = BufferLength;357if (ByteListLength > BufferLength)358{359ObjDesc->Buffer.Length = ByteListLength;360}361362/* Allocate the buffer */363364if (ObjDesc->Buffer.Length == 0)365{366ObjDesc->Buffer.Pointer = NULL;367ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,368"Buffer defined with zero length in AML, creating\n"));369}370else371{372ObjDesc->Buffer.Pointer =373ACPI_ALLOCATE_ZEROED (ObjDesc->Buffer.Length);374if (!ObjDesc->Buffer.Pointer)375{376AcpiUtDeleteObjectDesc (ObjDesc);377return_ACPI_STATUS (AE_NO_MEMORY);378}379380/* Initialize buffer from the ByteList (if present) */381382if (ByteList)383{384memcpy (ObjDesc->Buffer.Pointer, ByteList->Named.Data,385ByteListLength);386}387}388389ObjDesc->Buffer.Flags |= AOPOBJ_DATA_VALID;390Op->Common.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjDesc);391return_ACPI_STATUS (AE_OK);392}393394/*******************************************************************************395*396* FUNCTION: AcpiDsCreateNode397*398* PARAMETERS: WalkState - Current walk state399* Node - NS Node to be initialized400* Op - Parser object to be translated401*402* RETURN: Status403*404* DESCRIPTION: Create the object to be associated with a namespace node405*406******************************************************************************/407408ACPI_STATUS409AcpiDsCreateNode (410ACPI_WALK_STATE *WalkState,411ACPI_NAMESPACE_NODE *Node,412ACPI_PARSE_OBJECT *Op)413{414ACPI_STATUS Status;415ACPI_OPERAND_OBJECT *ObjDesc;416417418ACPI_FUNCTION_TRACE_PTR (DsCreateNode, Op);419420421/*422* Because of the execution pass through the non-control-method423* parts of the table, we can arrive here twice. Only init424* the named object node the first time through425*/426if (AcpiNsGetAttachedObject (Node))427{428return_ACPI_STATUS (AE_OK);429}430431if (!Op->Common.Value.Arg)432{433/* No arguments, there is nothing to do */434435return_ACPI_STATUS (AE_OK);436}437438/* Build an internal object for the argument(s) */439440Status = AcpiDsBuildInternalObject (441WalkState, Op->Common.Value.Arg, &ObjDesc);442if (ACPI_FAILURE (Status))443{444return_ACPI_STATUS (Status);445}446447/* Re-type the object according to its argument */448449Node->Type = ObjDesc->Common.Type;450451/* Attach obj to node */452453Status = AcpiNsAttachObject (Node, ObjDesc, Node->Type);454455/* Remove local reference to the object */456457AcpiUtRemoveReference (ObjDesc);458return_ACPI_STATUS (Status);459}460461462/*******************************************************************************463*464* FUNCTION: AcpiDsInitObjectFromOp465*466* PARAMETERS: WalkState - Current walk state467* Op - Parser op used to init the internal object468* Opcode - AML opcode associated with the object469* RetObjDesc - Namespace object to be initialized470*471* RETURN: Status472*473* DESCRIPTION: Initialize a namespace object from a parser Op and its474* associated arguments. The namespace object is a more compact475* representation of the Op and its arguments.476*477******************************************************************************/478479ACPI_STATUS480AcpiDsInitObjectFromOp (481ACPI_WALK_STATE *WalkState,482ACPI_PARSE_OBJECT *Op,483UINT16 Opcode,484ACPI_OPERAND_OBJECT **RetObjDesc)485{486const ACPI_OPCODE_INFO *OpInfo;487ACPI_OPERAND_OBJECT *ObjDesc;488ACPI_STATUS Status = AE_OK;489490491ACPI_FUNCTION_TRACE (DsInitObjectFromOp);492493494ObjDesc = *RetObjDesc;495OpInfo = AcpiPsGetOpcodeInfo (Opcode);496if (OpInfo->Class == AML_CLASS_UNKNOWN)497{498/* Unknown opcode */499500return_ACPI_STATUS (AE_TYPE);501}502503/* Perform per-object initialization */504505switch (ObjDesc->Common.Type)506{507case ACPI_TYPE_BUFFER:508/*509* Defer evaluation of Buffer TermArg operand510*/511ObjDesc->Buffer.Node = ACPI_CAST_PTR (512ACPI_NAMESPACE_NODE, WalkState->Operands[0]);513ObjDesc->Buffer.AmlStart = Op->Named.Data;514ObjDesc->Buffer.AmlLength = Op->Named.Length;515break;516517case ACPI_TYPE_PACKAGE:518/*519* Defer evaluation of Package TermArg operand and all520* package elements. (01/2017): We defer the element521* resolution to allow forward references from the package522* in order to provide compatibility with other ACPI523* implementations.524*/525ObjDesc->Package.Node = ACPI_CAST_PTR (526ACPI_NAMESPACE_NODE, WalkState->Operands[0]);527528if (!Op->Named.Data)529{530return_ACPI_STATUS (AE_OK);531}532533ObjDesc->Package.AmlStart = Op->Named.Data;534ObjDesc->Package.AmlLength = Op->Named.Length;535break;536537case ACPI_TYPE_INTEGER:538539switch (OpInfo->Type)540{541case AML_TYPE_CONSTANT:542/*543* Resolve AML Constants here - AND ONLY HERE!544* All constants are integers.545* We mark the integer with a flag that indicates that it started546* life as a constant -- so that stores to constants will perform547* as expected (noop). ZeroOp is used as a placeholder for optional548* target operands.549*/550ObjDesc->Common.Flags = AOPOBJ_AML_CONSTANT;551552switch (Opcode)553{554case AML_ZERO_OP:555556ObjDesc->Integer.Value = 0;557break;558559case AML_ONE_OP:560561ObjDesc->Integer.Value = 1;562break;563564case AML_ONES_OP:565566ObjDesc->Integer.Value = ACPI_UINT64_MAX;567568/* Truncate value if we are executing from a 32-bit ACPI table */569570(void) AcpiExTruncateFor32bitTable (ObjDesc);571break;572573case AML_REVISION_OP:574575ObjDesc->Integer.Value = ACPI_CA_VERSION;576break;577578default:579580ACPI_ERROR ((AE_INFO,581"Unknown constant opcode 0x%X", Opcode));582Status = AE_AML_OPERAND_TYPE;583break;584}585break;586587case AML_TYPE_LITERAL:588589ObjDesc->Integer.Value = Op->Common.Value.Integer;590591if (AcpiExTruncateFor32bitTable (ObjDesc))592{593/* Warn if we found a 64-bit constant in a 32-bit table */594595ACPI_WARNING ((AE_INFO,596"Truncated 64-bit constant found in 32-bit table: %8.8X%8.8X => %8.8X",597ACPI_FORMAT_UINT64 (Op->Common.Value.Integer),598(UINT32) ObjDesc->Integer.Value));599}600break;601602default:603604ACPI_ERROR ((AE_INFO, "Unknown Integer type 0x%X",605OpInfo->Type));606Status = AE_AML_OPERAND_TYPE;607break;608}609break;610611case ACPI_TYPE_STRING:612613ObjDesc->String.Pointer = Op->Common.Value.String;614ObjDesc->String.Length = (UINT32) strlen (Op->Common.Value.String);615616/*617* The string is contained in the ACPI table, don't ever try618* to delete it619*/620ObjDesc->Common.Flags |= AOPOBJ_STATIC_POINTER;621break;622623case ACPI_TYPE_METHOD:624break;625626case ACPI_TYPE_LOCAL_REFERENCE:627628switch (OpInfo->Type)629{630case AML_TYPE_LOCAL_VARIABLE:631632/* Local ID (0-7) is (AML opcode - base AML_FIRST_LOCAL_OP) */633634ObjDesc->Reference.Value = ((UINT32) Opcode) - AML_FIRST_LOCAL_OP;635ObjDesc->Reference.Class = ACPI_REFCLASS_LOCAL;636637Status = AcpiDsMethodDataGetNode (ACPI_REFCLASS_LOCAL,638ObjDesc->Reference.Value, WalkState,639ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE,640&ObjDesc->Reference.Object));641break;642643case AML_TYPE_METHOD_ARGUMENT:644645/* Arg ID (0-6) is (AML opcode - base AML_FIRST_ARG_OP) */646647ObjDesc->Reference.Value = ((UINT32) Opcode) - AML_FIRST_ARG_OP;648ObjDesc->Reference.Class = ACPI_REFCLASS_ARG;649650Status = AcpiDsMethodDataGetNode (ACPI_REFCLASS_ARG,651ObjDesc->Reference.Value, WalkState,652ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE,653&ObjDesc->Reference.Object));654break;655656default: /* Object name or Debug object */657658switch (Op->Common.AmlOpcode)659{660case AML_INT_NAMEPATH_OP:661662/* Node was saved in Op */663664ObjDesc->Reference.Node = Op->Common.Node;665ObjDesc->Reference.Class = ACPI_REFCLASS_NAME;666if (Op->Common.Node)667{668ObjDesc->Reference.Object = Op->Common.Node->Object;669}670break;671672case AML_DEBUG_OP:673674ObjDesc->Reference.Class = ACPI_REFCLASS_DEBUG;675break;676677default:678679ACPI_ERROR ((AE_INFO,680"Unimplemented reference type for AML opcode: 0x%4.4X", Opcode));681return_ACPI_STATUS (AE_AML_OPERAND_TYPE);682}683break;684}685break;686687default:688689ACPI_ERROR ((AE_INFO, "Unimplemented data type: 0x%X",690ObjDesc->Common.Type));691692Status = AE_AML_OPERAND_TYPE;693break;694}695696return_ACPI_STATUS (Status);697}698699700