excreate.c revision 298714
1193323Sed/****************************************************************************** 2193323Sed * 3193323Sed * Module Name: excreate - Named object creation 4193323Sed * 5193323Sed *****************************************************************************/ 6193323Sed 7193323Sed/* 8193323Sed * Copyright (C) 2000 - 2016, Intel Corp. 9193323Sed * All rights reserved. 10193323Sed * 11193323Sed * Redistribution and use in source and binary forms, with or without 12193323Sed * modification, are permitted provided that the following conditions 13210299Sed * are met: 14210299Sed * 1. Redistributions of source code must retain the above copyright 15210299Sed * notice, this list of conditions, and the following disclaimer, 16210299Sed * without modification. 17193323Sed * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18193323Sed * substantially similar to the "NO WARRANTY" disclaimer below 19193323Sed * ("Disclaimer") and any redistribution must be conditioned upon 20193323Sed * including a substantially similar Disclaimer requirement for further 21193323Sed * binary redistribution. 22193323Sed * 3. Neither the names of the above-listed copyright holders nor the names 23263508Sdim * of any contributors may be used to endorse or promote products derived 24218893Sdim * from this software without specific prior written permission. 25193323Sed * 26193323Sed * Alternatively, this software may be distributed under the terms of the 27193323Sed * GNU General Public License ("GPL") version 2 as published by the Free 28193323Sed * Software Foundation. 29193323Sed * 30193323Sed * NO WARRANTY 31193323Sed * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32226633Sdim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33193323Sed * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34226633Sdim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35193323Sed * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36193323Sed * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37193323Sed * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38193323Sed * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39226633Sdim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40226633Sdim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41193323Sed * POSSIBILITY OF SUCH DAMAGES. 42226633Sdim */ 43193323Sed 44193323Sed#include <contrib/dev/acpica/include/acpi.h> 45193323Sed#include <contrib/dev/acpica/include/accommon.h> 46193323Sed#include <contrib/dev/acpica/include/acinterp.h> 47193323Sed#include <contrib/dev/acpica/include/amlcode.h> 48210299Sed#include <contrib/dev/acpica/include/acnamesp.h> 49210299Sed 50210299Sed 51210299Sed#define _COMPONENT ACPI_EXECUTER 52210299Sed ACPI_MODULE_NAME ("excreate") 53210299Sed 54210299Sed 55210299Sed#ifndef ACPI_NO_METHOD_EXECUTION 56210299Sed/******************************************************************************* 57210299Sed * 58210299Sed * FUNCTION: AcpiExCreateAlias 59210299Sed * 60210299Sed * PARAMETERS: WalkState - Current state, contains operands 61210299Sed * 62210299Sed * RETURN: Status 63193323Sed * 64210299Sed * DESCRIPTION: Create a new named alias 65193323Sed * 66193323Sed ******************************************************************************/ 67193323Sed 68193323SedACPI_STATUS 69193323SedAcpiExCreateAlias ( 70193323Sed ACPI_WALK_STATE *WalkState) 71193323Sed{ 72193323Sed ACPI_NAMESPACE_NODE *TargetNode; 73193323Sed ACPI_NAMESPACE_NODE *AliasNode; 74193323Sed ACPI_STATUS Status = AE_OK; 75193323Sed 76193323Sed 77193323Sed ACPI_FUNCTION_TRACE (ExCreateAlias); 78210299Sed 79210299Sed 80193323Sed /* Get the source/alias operands (both namespace nodes) */ 81210299Sed 82210299Sed AliasNode = (ACPI_NAMESPACE_NODE *) WalkState->Operands[0]; 83193323Sed TargetNode = (ACPI_NAMESPACE_NODE *) WalkState->Operands[1]; 84193323Sed 85193323Sed if ((TargetNode->Type == ACPI_TYPE_LOCAL_ALIAS) || 86193323Sed (TargetNode->Type == ACPI_TYPE_LOCAL_METHOD_ALIAS)) 87193323Sed { 88210299Sed /* 89226633Sdim * Dereference an existing alias so that we don't create a chain 90226633Sdim * of aliases. With this code, we guarantee that an alias is 91226633Sdim * always exactly one level of indirection away from the 92193323Sed * actual aliased name. 93193323Sed */ 94193323Sed TargetNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, TargetNode->Object); 95226633Sdim } 96226633Sdim 97226633Sdim /* 98226633Sdim * For objects that can never change (i.e., the NS node will 99226633Sdim * permanently point to the same object), we can simply attach 100226633Sdim * the object to the new NS node. For other objects (such as 101226633Sdim * Integers, buffers, etc.), we have to point the Alias node 102210299Sed * to the original Node. 103210299Sed */ 104210299Sed switch (TargetNode->Type) 105210299Sed { 106210299Sed 107193323Sed /* For these types, the sub-object can change dynamically via a Store */ 108193323Sed 109193323Sed case ACPI_TYPE_INTEGER: 110193323Sed case ACPI_TYPE_STRING: 111193323Sed case ACPI_TYPE_BUFFER: 112193323Sed case ACPI_TYPE_PACKAGE: 113193323Sed case ACPI_TYPE_BUFFER_FIELD: 114193323Sed /* 115193323Sed * These types open a new scope, so we need the NS node in order to access 116193323Sed * any children. 117193323Sed */ 118193323Sed case ACPI_TYPE_DEVICE: 119193323Sed case ACPI_TYPE_POWER: 120207618Srdivacky case ACPI_TYPE_PROCESSOR: 121207618Srdivacky case ACPI_TYPE_THERMAL: 122207618Srdivacky case ACPI_TYPE_LOCAL_SCOPE: 123207618Srdivacky /* 124207618Srdivacky * The new alias has the type ALIAS and points to the original 125207618Srdivacky * NS node, not the object itself. 126193323Sed */ 127193323Sed AliasNode->Type = ACPI_TYPE_LOCAL_ALIAS; 128226633Sdim AliasNode->Object = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, TargetNode); 129226633Sdim break; 130226633Sdim 131226633Sdim case ACPI_TYPE_METHOD: 132226633Sdim /* 133226633Sdim * Control method aliases need to be differentiated 134226633Sdim */ 135226633Sdim AliasNode->Type = ACPI_TYPE_LOCAL_METHOD_ALIAS; 136226633Sdim AliasNode->Object = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, TargetNode); 137226633Sdim break; 138226633Sdim 139226633Sdim default: 140226633Sdim 141226633Sdim /* Attach the original source object to the new Alias Node */ 142226633Sdim 143226633Sdim /* 144226633Sdim * The new alias assumes the type of the target, and it points 145226633Sdim * to the same object. The reference count of the object has an 146226633Sdim * additional reference to prevent deletion out from under either the 147226633Sdim * target node or the alias Node 148226633Sdim */ 149226633Sdim Status = AcpiNsAttachObject (AliasNode, 150226633Sdim AcpiNsGetAttachedObject (TargetNode), TargetNode->Type); 151226633Sdim break; 152226633Sdim } 153226633Sdim 154226633Sdim /* Since both operands are Nodes, we don't need to delete them */ 155226633Sdim 156226633Sdim return_ACPI_STATUS (Status); 157226633Sdim} 158226633Sdim 159226633Sdim 160226633Sdim/******************************************************************************* 161226633Sdim * 162226633Sdim * FUNCTION: AcpiExCreateEvent 163226633Sdim * 164226633Sdim * PARAMETERS: WalkState - Current state 165226633Sdim * 166226633Sdim * RETURN: Status 167226633Sdim * 168226633Sdim * DESCRIPTION: Create a new event object 169226633Sdim * 170226633Sdim ******************************************************************************/ 171226633Sdim 172226633SdimACPI_STATUS 173226633SdimAcpiExCreateEvent ( 174226633Sdim ACPI_WALK_STATE *WalkState) 175226633Sdim{ 176226633Sdim ACPI_STATUS Status; 177226633Sdim ACPI_OPERAND_OBJECT *ObjDesc; 178226633Sdim 179226633Sdim 180226633Sdim ACPI_FUNCTION_TRACE (ExCreateEvent); 181226633Sdim 182226633Sdim 183226633Sdim ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_EVENT); 184226633Sdim if (!ObjDesc) 185226633Sdim { 186226633Sdim Status = AE_NO_MEMORY; 187226633Sdim goto Cleanup; 188226633Sdim } 189226633Sdim 190226633Sdim /* 191226633Sdim * Create the actual OS semaphore, with zero initial units -- meaning 192226633Sdim * that the event is created in an unsignalled state 193226633Sdim */ 194226633Sdim Status = AcpiOsCreateSemaphore (ACPI_NO_UNIT_LIMIT, 0, 195226633Sdim &ObjDesc->Event.OsSemaphore); 196226633Sdim if (ACPI_FAILURE (Status)) 197226633Sdim { 198226633Sdim goto Cleanup; 199226633Sdim } 200226633Sdim 201226633Sdim /* Attach object to the Node */ 202226633Sdim 203226633Sdim Status = AcpiNsAttachObject ( 204226633Sdim (ACPI_NAMESPACE_NODE *) WalkState->Operands[0], 205226633Sdim ObjDesc, ACPI_TYPE_EVENT); 206226633Sdim 207226633SdimCleanup: 208226633Sdim /* 209226633Sdim * Remove local reference to the object (on error, will cause deletion 210226633Sdim * of both object and semaphore if present.) 211226633Sdim */ 212226633Sdim AcpiUtRemoveReference (ObjDesc); 213226633Sdim return_ACPI_STATUS (Status); 214226633Sdim} 215226633Sdim 216226633Sdim 217226633Sdim/******************************************************************************* 218226633Sdim * 219226633Sdim * FUNCTION: AcpiExCreateMutex 220226633Sdim * 221226633Sdim * PARAMETERS: WalkState - Current state 222226633Sdim * 223226633Sdim * RETURN: Status 224226633Sdim * 225226633Sdim * DESCRIPTION: Create a new mutex object 226226633Sdim * 227226633Sdim * Mutex (Name[0], SyncLevel[1]) 228226633Sdim * 229226633Sdim ******************************************************************************/ 230226633Sdim 231226633SdimACPI_STATUS 232226633SdimAcpiExCreateMutex ( 233226633Sdim ACPI_WALK_STATE *WalkState) 234226633Sdim{ 235226633Sdim ACPI_STATUS Status = AE_OK; 236226633Sdim ACPI_OPERAND_OBJECT *ObjDesc; 237226633Sdim 238226633Sdim 239226633Sdim ACPI_FUNCTION_TRACE_PTR (ExCreateMutex, ACPI_WALK_OPERANDS); 240226633Sdim 241226633Sdim 242226633Sdim /* Create the new mutex object */ 243226633Sdim 244226633Sdim ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_MUTEX); 245226633Sdim if (!ObjDesc) 246226633Sdim { 247226633Sdim Status = AE_NO_MEMORY; 248226633Sdim goto Cleanup; 249226633Sdim } 250226633Sdim 251226633Sdim /* Create the actual OS Mutex */ 252239462Sdim 253226633Sdim Status = AcpiOsCreateMutex (&ObjDesc->Mutex.OsMutex); 254226633Sdim if (ACPI_FAILURE (Status)) 255226633Sdim { 256226633Sdim goto Cleanup; 257226633Sdim } 258226633Sdim 259226633Sdim /* Init object and attach to NS node */ 260226633Sdim 261226633Sdim ObjDesc->Mutex.SyncLevel = (UINT8) WalkState->Operands[1]->Integer.Value; 262226633Sdim ObjDesc->Mutex.Node = (ACPI_NAMESPACE_NODE *) WalkState->Operands[0]; 263226633Sdim 264226633Sdim Status = AcpiNsAttachObject ( 265226633Sdim ObjDesc->Mutex.Node, ObjDesc, ACPI_TYPE_MUTEX); 266226633Sdim 267226633Sdim 268226633SdimCleanup: 269226633Sdim /* 270226633Sdim * Remove local reference to the object (on error, will cause deletion 271226633Sdim * of both object and semaphore if present.) 272226633Sdim */ 273226633Sdim AcpiUtRemoveReference (ObjDesc); 274226633Sdim return_ACPI_STATUS (Status); 275249423Sdim} 276226633Sdim 277226633Sdim 278226633Sdim/******************************************************************************* 279226633Sdim * 280226633Sdim * FUNCTION: AcpiExCreateRegion 281226633Sdim * 282226633Sdim * PARAMETERS: AmlStart - Pointer to the region declaration AML 283226633Sdim * AmlLength - Max length of the declaration AML 284226633Sdim * SpaceId - Address space ID for the region 285226633Sdim * WalkState - Current state 286226633Sdim * 287226633Sdim * RETURN: Status 288226633Sdim * 289226633Sdim * DESCRIPTION: Create a new operation region object 290263508Sdim * 291193323Sed ******************************************************************************/ 292193323Sed 293193323SedACPI_STATUS 294193323SedAcpiExCreateRegion ( 295218893Sdim UINT8 *AmlStart, 296193323Sed UINT32 AmlLength, 297193323Sed UINT8 SpaceId, 298193323Sed ACPI_WALK_STATE *WalkState) 299193323Sed{ 300193323Sed ACPI_STATUS Status; 301193323Sed ACPI_OPERAND_OBJECT *ObjDesc; 302210299Sed ACPI_NAMESPACE_NODE *Node; 303193323Sed ACPI_OPERAND_OBJECT *RegionObj2; 304193323Sed 305193323Sed 306193323Sed ACPI_FUNCTION_TRACE (ExCreateRegion); 307210299Sed 308207618Srdivacky 309210299Sed /* Get the Namespace Node */ 310210299Sed 311210299Sed Node = WalkState->Op->Common.Node; 312263508Sdim 313263508Sdim /* 314210299Sed * If the region object is already attached to this node, 315210299Sed * just return 316210299Sed */ 317210299Sed if (AcpiNsGetAttachedObject (Node)) 318210299Sed { 319210299Sed return_ACPI_STATUS (AE_OK); 320210299Sed } 321210299Sed 322210299Sed /* 323210299Sed * Space ID must be one of the predefined IDs, or in the user-defined 324210299Sed * range 325210299Sed */ 326210299Sed if (!AcpiIsValidSpaceId (SpaceId)) 327210299Sed { 328210299Sed /* 329210299Sed * Print an error message, but continue. We don't want to abort 330207618Srdivacky * a table load for this exception. Instead, if the region is 331207618Srdivacky * actually used at runtime, abort the executing method. 332210299Sed */ 333210299Sed ACPI_ERROR ((AE_INFO, 334210299Sed "Invalid/unknown Address Space ID: 0x%2.2X", SpaceId)); 335210299Sed } 336210299Sed 337210299Sed ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "Region Type - %s (0x%X)\n", 338210299Sed AcpiUtGetRegionName (SpaceId), SpaceId)); 339210299Sed 340210299Sed /* Create the region descriptor */ 341210299Sed 342210299Sed ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_REGION); 343210299Sed if (!ObjDesc) 344210299Sed { 345210299Sed Status = AE_NO_MEMORY; 346210299Sed goto Cleanup; 347210299Sed } 348210299Sed 349210299Sed /* 350210299Sed * Remember location in AML stream of address & length 351210299Sed * operands since they need to be evaluated at run time. 352210299Sed */ 353210299Sed RegionObj2 = AcpiNsGetSecondaryObject (ObjDesc); 354210299Sed RegionObj2->Extra.AmlStart = AmlStart; 355210299Sed RegionObj2->Extra.AmlLength = AmlLength; 356210299Sed RegionObj2->Extra.Method_REG = NULL; 357210299Sed if (WalkState->ScopeInfo) 358210299Sed { 359210299Sed RegionObj2->Extra.ScopeNode = WalkState->ScopeInfo->Scope.Node; 360210299Sed } 361226633Sdim else 362226633Sdim { 363226633Sdim RegionObj2->Extra.ScopeNode = Node; 364226633Sdim } 365226633Sdim 366210299Sed /* Init the region from the operands */ 367210299Sed 368210299Sed ObjDesc->Region.SpaceId = SpaceId; 369210299Sed ObjDesc->Region.Address = 0; 370249423Sdim ObjDesc->Region.Length = 0; 371249423Sdim ObjDesc->Region.Node = Node; 372210299Sed ObjDesc->Region.Handler = NULL; 373210299Sed ObjDesc->Common.Flags &= 374212904Sdim ~(AOPOBJ_SETUP_COMPLETE | AOPOBJ_REG_CONNECTED | 375212904Sdim AOPOBJ_OBJECT_INITIALIZED); 376212904Sdim 377212904Sdim /* Install the new region object in the parent Node */ 378212904Sdim 379212904Sdim Status = AcpiNsAttachObject (Node, ObjDesc, ACPI_TYPE_REGION); 380212904Sdim 381212904Sdim 382212904SdimCleanup: 383212904Sdim 384212904Sdim /* Remove local reference to the object */ 385212904Sdim 386212904Sdim AcpiUtRemoveReference (ObjDesc); 387212904Sdim return_ACPI_STATUS (Status); 388212904Sdim} 389218893Sdim 390218893Sdim 391218893Sdim/******************************************************************************* 392218893Sdim * 393218893Sdim * FUNCTION: AcpiExCreateProcessor 394218893Sdim * 395212904Sdim * PARAMETERS: WalkState - Current state 396212904Sdim * 397212904Sdim * RETURN: Status 398218893Sdim * 399218893Sdim * DESCRIPTION: Create a new processor object and populate the fields 400218893Sdim * 401218893Sdim * Processor (Name[0], CpuID[1], PblockAddr[2], PblockLength[3]) 402218893Sdim * 403218893Sdim ******************************************************************************/ 404218893Sdim 405218893SdimACPI_STATUS 406218893SdimAcpiExCreateProcessor ( 407218893Sdim ACPI_WALK_STATE *WalkState) 408218893Sdim{ 409218893Sdim ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0]; 410218893Sdim ACPI_OPERAND_OBJECT *ObjDesc; 411218893Sdim ACPI_STATUS Status; 412218893Sdim 413218893Sdim 414218893Sdim ACPI_FUNCTION_TRACE_PTR (ExCreateProcessor, WalkState); 415218893Sdim 416218893Sdim 417218893Sdim /* Create the processor object */ 418212904Sdim 419212904Sdim ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_PROCESSOR); 420243830Sdim if (!ObjDesc) 421226633Sdim { 422226633Sdim return_ACPI_STATUS (AE_NO_MEMORY); 423226633Sdim } 424226633Sdim 425226633Sdim /* Initialize the processor object from the operands */ 426226633Sdim 427226633Sdim ObjDesc->Processor.ProcId = (UINT8) Operand[1]->Integer.Value; 428226633Sdim ObjDesc->Processor.Length = (UINT8) Operand[3]->Integer.Value; 429226633Sdim ObjDesc->Processor.Address = (ACPI_IO_ADDRESS) Operand[2]->Integer.Value; 430226633Sdim 431226633Sdim /* Install the processor object in the parent Node */ 432226633Sdim 433226633Sdim Status = AcpiNsAttachObject ((ACPI_NAMESPACE_NODE *) Operand[0], 434226633Sdim ObjDesc, ACPI_TYPE_PROCESSOR); 435226633Sdim 436263508Sdim /* Remove local reference to the object */ 437263508Sdim 438263508Sdim AcpiUtRemoveReference (ObjDesc); 439263508Sdim return_ACPI_STATUS (Status); 440243830Sdim} 441263508Sdim 442263508Sdim 443263508Sdim/******************************************************************************* 444243830Sdim * 445263508Sdim * FUNCTION: AcpiExCreatePowerResource 446263508Sdim * 447263508Sdim * PARAMETERS: WalkState - Current state 448263508Sdim * 449263508Sdim * RETURN: Status 450263508Sdim * 451263508Sdim * DESCRIPTION: Create a new PowerResource object and populate the fields 452263508Sdim * 453263508Sdim * PowerResource (Name[0], SystemLevel[1], ResourceOrder[2]) 454263508Sdim * 455263508Sdim ******************************************************************************/ 456263508Sdim 457263508SdimACPI_STATUS 458263508SdimAcpiExCreatePowerResource ( 459263508Sdim ACPI_WALK_STATE *WalkState) 460263508Sdim{ 461263508Sdim ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0]; 462263508Sdim ACPI_STATUS Status; 463263508Sdim ACPI_OPERAND_OBJECT *ObjDesc; 464263508Sdim 465263508Sdim 466263508Sdim ACPI_FUNCTION_TRACE_PTR (ExCreatePowerResource, WalkState); 467263508Sdim 468263508Sdim 469263508Sdim /* Create the power resource object */ 470263508Sdim 471263508Sdim ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_POWER); 472263508Sdim if (!ObjDesc) 473263508Sdim { 474263508Sdim return_ACPI_STATUS (AE_NO_MEMORY); 475226633Sdim } 476218893Sdim 477243830Sdim /* Initialize the power object from the operands */ 478243830Sdim 479251662Sdim ObjDesc->PowerResource.SystemLevel = (UINT8) Operand[1]->Integer.Value; 480249423Sdim ObjDesc->PowerResource.ResourceOrder = (UINT16) Operand[2]->Integer.Value; 481263508Sdim 482263508Sdim /* Install the power resource object in the parent Node */ 483243830Sdim 484243830Sdim Status = AcpiNsAttachObject ((ACPI_NAMESPACE_NODE *) Operand[0], 485263508Sdim ObjDesc, ACPI_TYPE_POWER); 486243830Sdim 487263508Sdim /* Remove local reference to the object */ 488263508Sdim 489243830Sdim AcpiUtRemoveReference (ObjDesc); 490263508Sdim return_ACPI_STATUS (Status); 491263508Sdim} 492263508Sdim#endif 493263508Sdim 494263508Sdim 495263508Sdim/******************************************************************************* 496263508Sdim * 497249423Sdim * FUNCTION: AcpiExCreateMethod 498243830Sdim * 499243830Sdim * PARAMETERS: AmlStart - First byte of the method's AML 500263508Sdim * AmlLength - AML byte count for this method 501243830Sdim * WalkState - Current state 502263508Sdim * 503249423Sdim * RETURN: Status 504243830Sdim * 505249423Sdim * DESCRIPTION: Create a new method object 506263508Sdim * 507249423Sdim ******************************************************************************/ 508243830Sdim 509249423SdimACPI_STATUS 510249423SdimAcpiExCreateMethod ( 511263508Sdim UINT8 *AmlStart, 512263508Sdim UINT32 AmlLength, 513249423Sdim ACPI_WALK_STATE *WalkState) 514249423Sdim{ 515249423Sdim ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0]; 516263508Sdim ACPI_OPERAND_OBJECT *ObjDesc; 517263508Sdim ACPI_STATUS Status; 518249423Sdim UINT8 MethodFlags; 519263508Sdim 520251662Sdim 521263508Sdim ACPI_FUNCTION_TRACE_PTR (ExCreateMethod, WalkState); 522263508Sdim 523249423Sdim 524263508Sdim /* Create a new method object */ 525249423Sdim 526263508Sdim ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_METHOD); 527263508Sdim if (!ObjDesc) 528249423Sdim { 529263508Sdim Status = AE_NO_MEMORY; 530249423Sdim goto Exit; 531263508Sdim } 532249423Sdim 533263508Sdim /* Save the method's AML pointer and length */ 534249423Sdim 535263508Sdim ObjDesc->Method.AmlStart = AmlStart; 536249423Sdim ObjDesc->Method.AmlLength = AmlLength; 537263508Sdim ObjDesc->Method.Node = Operand[0]; 538249423Sdim 539263508Sdim /* 540263508Sdim * Disassemble the method flags. Split off the ArgCount, Serialized 541263508Sdim * flag, and SyncLevel for efficiency. 542263508Sdim */ 543263508Sdim MethodFlags = (UINT8) Operand[1]->Integer.Value; 544263508Sdim ObjDesc->Method.ParamCount = (UINT8) 545263508Sdim (MethodFlags & AML_METHOD_ARG_COUNT); 546263508Sdim 547263508Sdim /* 548263508Sdim * Get the SyncLevel. If method is serialized, a mutex will be 549263508Sdim * created for this method when it is parsed. 550263508Sdim */ 551263508Sdim if (MethodFlags & AML_METHOD_SERIALIZED) 552263508Sdim { 553263508Sdim ObjDesc->Method.InfoFlags = ACPI_METHOD_SERIALIZED; 554263508Sdim 555249423Sdim /* 556263508Sdim * ACPI 1.0: SyncLevel = 0 557263508Sdim * ACPI 2.0: SyncLevel = SyncLevel in method declaration 558263508Sdim */ 559263508Sdim ObjDesc->Method.SyncLevel = (UINT8) 560263508Sdim ((MethodFlags & AML_METHOD_SYNC_LEVEL) >> 4); 561243830Sdim } 562243830Sdim 563249423Sdim /* Attach the new object to the method Node */ 564249423Sdim 565249423Sdim Status = AcpiNsAttachObject ((ACPI_NAMESPACE_NODE *) Operand[0], 566249423Sdim ObjDesc, ACPI_TYPE_METHOD); 567249423Sdim 568249423Sdim /* Remove local reference to the object */ 569249423Sdim 570249423Sdim AcpiUtRemoveReference (ObjDesc); 571249423Sdim 572249423SdimExit: 573249423Sdim /* Remove a reference to the operand */ 574249423Sdim 575249423Sdim AcpiUtRemoveReference (Operand[1]); 576249423Sdim return_ACPI_STATUS (Status); 577249423Sdim} 578249423Sdim