1a159c266SJung-uk Kim /******************************************************************************* 2a159c266SJung-uk Kim * 3a159c266SJung-uk Kim * Module Name: nseval - Object evaluation, includes control method execution 4a159c266SJung-uk Kim * 5a159c266SJung-uk Kim ******************************************************************************/ 6a159c266SJung-uk Kim 7a159c266SJung-uk Kim /* 81c0e1b6dSJung-uk Kim * Copyright (C) 2000 - 2015, Intel Corp. 9a159c266SJung-uk Kim * All rights reserved. 10a159c266SJung-uk Kim * 11a159c266SJung-uk Kim * Redistribution and use in source and binary forms, with or without 12a159c266SJung-uk Kim * modification, are permitted provided that the following conditions 13a159c266SJung-uk Kim * are met: 14a159c266SJung-uk Kim * 1. Redistributions of source code must retain the above copyright 15a159c266SJung-uk Kim * notice, this list of conditions, and the following disclaimer, 16a159c266SJung-uk Kim * without modification. 17a159c266SJung-uk Kim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18a159c266SJung-uk Kim * substantially similar to the "NO WARRANTY" disclaimer below 19a159c266SJung-uk Kim * ("Disclaimer") and any redistribution must be conditioned upon 20a159c266SJung-uk Kim * including a substantially similar Disclaimer requirement for further 21a159c266SJung-uk Kim * binary redistribution. 22a159c266SJung-uk Kim * 3. Neither the names of the above-listed copyright holders nor the names 23a159c266SJung-uk Kim * of any contributors may be used to endorse or promote products derived 24a159c266SJung-uk Kim * from this software without specific prior written permission. 25a159c266SJung-uk Kim * 26a159c266SJung-uk Kim * Alternatively, this software may be distributed under the terms of the 27a159c266SJung-uk Kim * GNU General Public License ("GPL") version 2 as published by the Free 28a159c266SJung-uk Kim * Software Foundation. 29a159c266SJung-uk Kim * 30a159c266SJung-uk Kim * NO WARRANTY 31a159c266SJung-uk Kim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32a159c266SJung-uk Kim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33a159c266SJung-uk Kim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34a159c266SJung-uk Kim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35a159c266SJung-uk Kim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36a159c266SJung-uk Kim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37a159c266SJung-uk Kim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38a159c266SJung-uk Kim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39a159c266SJung-uk Kim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40a159c266SJung-uk Kim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41a159c266SJung-uk Kim * POSSIBILITY OF SUCH DAMAGES. 42a159c266SJung-uk Kim */ 43a159c266SJung-uk Kim 44a159c266SJung-uk Kim #include <contrib/dev/acpica/include/acpi.h> 45a159c266SJung-uk Kim #include <contrib/dev/acpica/include/accommon.h> 46a159c266SJung-uk Kim #include <contrib/dev/acpica/include/acparser.h> 47a159c266SJung-uk Kim #include <contrib/dev/acpica/include/acinterp.h> 48a159c266SJung-uk Kim #include <contrib/dev/acpica/include/acnamesp.h> 49a159c266SJung-uk Kim 50a159c266SJung-uk Kim 51a159c266SJung-uk Kim #define _COMPONENT ACPI_NAMESPACE 52a159c266SJung-uk Kim ACPI_MODULE_NAME ("nseval") 53a159c266SJung-uk Kim 54a159c266SJung-uk Kim /* Local prototypes */ 55a159c266SJung-uk Kim 56a159c266SJung-uk Kim static void 57a159c266SJung-uk Kim AcpiNsExecModuleCode ( 58a159c266SJung-uk Kim ACPI_OPERAND_OBJECT *MethodObj, 59a159c266SJung-uk Kim ACPI_EVALUATE_INFO *Info); 60a159c266SJung-uk Kim 61a159c266SJung-uk Kim 62a159c266SJung-uk Kim /******************************************************************************* 63a159c266SJung-uk Kim * 64a159c266SJung-uk Kim * FUNCTION: AcpiNsEvaluate 65a159c266SJung-uk Kim * 665ef50723SJung-uk Kim * PARAMETERS: Info - Evaluation info block, contains these fields 675ef50723SJung-uk Kim * and more: 68a159c266SJung-uk Kim * PrefixNode - Prefix or Method/Object Node to execute 69895f26a9SJung-uk Kim * RelativePath - Name of method to execute, If NULL, the 70a159c266SJung-uk Kim * Node is the object to execute 71a159c266SJung-uk Kim * Parameters - List of parameters to pass to the method, 72a159c266SJung-uk Kim * terminated by NULL. Params itself may be 73a159c266SJung-uk Kim * NULL if no parameters are being passed. 74a159c266SJung-uk Kim * ParameterType - Type of Parameter list 75a159c266SJung-uk Kim * ReturnObject - Where to put method's return value (if 76a159c266SJung-uk Kim * any). If NULL, no value is returned. 77a159c266SJung-uk Kim * Flags - ACPI_IGNORE_RETURN_VALUE to delete return 78a159c266SJung-uk Kim * 79a159c266SJung-uk Kim * RETURN: Status 80a159c266SJung-uk Kim * 81a159c266SJung-uk Kim * DESCRIPTION: Execute a control method or return the current value of an 82a159c266SJung-uk Kim * ACPI namespace object. 83a159c266SJung-uk Kim * 84a159c266SJung-uk Kim * MUTEX: Locks interpreter 85a159c266SJung-uk Kim * 86a159c266SJung-uk Kim ******************************************************************************/ 87a159c266SJung-uk Kim 88a159c266SJung-uk Kim ACPI_STATUS 89a159c266SJung-uk Kim AcpiNsEvaluate ( 90a159c266SJung-uk Kim ACPI_EVALUATE_INFO *Info) 91a159c266SJung-uk Kim { 92a159c266SJung-uk Kim ACPI_STATUS Status; 93a159c266SJung-uk Kim 94a159c266SJung-uk Kim 95a159c266SJung-uk Kim ACPI_FUNCTION_TRACE (NsEvaluate); 96a159c266SJung-uk Kim 97a159c266SJung-uk Kim 98a159c266SJung-uk Kim if (!Info) 99a159c266SJung-uk Kim { 100a159c266SJung-uk Kim return_ACPI_STATUS (AE_BAD_PARAMETER); 101a159c266SJung-uk Kim } 102a159c266SJung-uk Kim 103895f26a9SJung-uk Kim if (!Info->Node) 1049c7c683cSJung-uk Kim { 105a159c266SJung-uk Kim /* 106895f26a9SJung-uk Kim * Get the actual namespace node for the target object if we 107895f26a9SJung-uk Kim * need to. Handles these cases: 108a159c266SJung-uk Kim * 109895f26a9SJung-uk Kim * 1) Null node, valid pathname from root (absolute path) 110895f26a9SJung-uk Kim * 2) Node and valid pathname (path relative to Node) 111895f26a9SJung-uk Kim * 3) Node, Null pathname 112a159c266SJung-uk Kim */ 113895f26a9SJung-uk Kim Status = AcpiNsGetNode (Info->PrefixNode, Info->RelativePathname, 114895f26a9SJung-uk Kim ACPI_NS_NO_UPSEARCH, &Info->Node); 115a159c266SJung-uk Kim if (ACPI_FAILURE (Status)) 116a159c266SJung-uk Kim { 117a159c266SJung-uk Kim return_ACPI_STATUS (Status); 118a159c266SJung-uk Kim } 1199c7c683cSJung-uk Kim } 120a159c266SJung-uk Kim 121a159c266SJung-uk Kim /* 122895f26a9SJung-uk Kim * For a method alias, we must grab the actual method node so that 123895f26a9SJung-uk Kim * proper scoping context will be established before execution. 124a159c266SJung-uk Kim */ 125895f26a9SJung-uk Kim if (AcpiNsGetType (Info->Node) == ACPI_TYPE_LOCAL_METHOD_ALIAS) 126a159c266SJung-uk Kim { 127895f26a9SJung-uk Kim Info->Node = ACPI_CAST_PTR ( 128895f26a9SJung-uk Kim ACPI_NAMESPACE_NODE, Info->Node->Object); 129a159c266SJung-uk Kim } 130a159c266SJung-uk Kim 131895f26a9SJung-uk Kim /* Complete the info block initialization */ 132a159c266SJung-uk Kim 133895f26a9SJung-uk Kim Info->ReturnObject = NULL; 134895f26a9SJung-uk Kim Info->NodeFlags = Info->Node->Flags; 135895f26a9SJung-uk Kim Info->ObjDesc = AcpiNsGetAttachedObject (Info->Node); 136a159c266SJung-uk Kim 137895f26a9SJung-uk Kim ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%s [%p] Value %p\n", 138895f26a9SJung-uk Kim Info->RelativePathname, Info->Node, 139895f26a9SJung-uk Kim AcpiNsGetAttachedObject (Info->Node))); 140895f26a9SJung-uk Kim 141895f26a9SJung-uk Kim /* Get info if we have a predefined name (_HID, etc.) */ 142895f26a9SJung-uk Kim 143895f26a9SJung-uk Kim Info->Predefined = AcpiUtMatchPredefinedMethod (Info->Node->Name.Ascii); 144895f26a9SJung-uk Kim 145895f26a9SJung-uk Kim /* Get the full pathname to the object, for use in warning messages */ 146895f26a9SJung-uk Kim 147895f26a9SJung-uk Kim Info->FullPathname = AcpiNsGetExternalPathname (Info->Node); 148895f26a9SJung-uk Kim if (!Info->FullPathname) 149a159c266SJung-uk Kim { 150895f26a9SJung-uk Kim return_ACPI_STATUS (AE_NO_MEMORY); 151a159c266SJung-uk Kim } 152a159c266SJung-uk Kim 153895f26a9SJung-uk Kim /* Count the number of arguments being passed in */ 154a159c266SJung-uk Kim 155895f26a9SJung-uk Kim Info->ParamCount = 0; 156a159c266SJung-uk Kim if (Info->Parameters) 157a159c266SJung-uk Kim { 158a159c266SJung-uk Kim while (Info->Parameters[Info->ParamCount]) 159a159c266SJung-uk Kim { 160a159c266SJung-uk Kim Info->ParamCount++; 161a159c266SJung-uk Kim } 162895f26a9SJung-uk Kim 163895f26a9SJung-uk Kim /* Warn on impossible argument count */ 164895f26a9SJung-uk Kim 165895f26a9SJung-uk Kim if (Info->ParamCount > ACPI_METHOD_NUM_ARGS) 166895f26a9SJung-uk Kim { 167895f26a9SJung-uk Kim ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, ACPI_WARN_ALWAYS, 168895f26a9SJung-uk Kim "Excess arguments (%u) - using only %u", 169895f26a9SJung-uk Kim Info->ParamCount, ACPI_METHOD_NUM_ARGS)); 170895f26a9SJung-uk Kim 171895f26a9SJung-uk Kim Info->ParamCount = ACPI_METHOD_NUM_ARGS; 172895f26a9SJung-uk Kim } 173a159c266SJung-uk Kim } 174a159c266SJung-uk Kim 175895f26a9SJung-uk Kim /* 176895f26a9SJung-uk Kim * For predefined names: Check that the declared argument count 177895f26a9SJung-uk Kim * matches the ACPI spec -- otherwise this is a BIOS error. 178895f26a9SJung-uk Kim */ 179895f26a9SJung-uk Kim AcpiNsCheckAcpiCompliance (Info->FullPathname, Info->Node, 180895f26a9SJung-uk Kim Info->Predefined); 181895f26a9SJung-uk Kim 182895f26a9SJung-uk Kim /* 183895f26a9SJung-uk Kim * For all names: Check that the incoming argument count for 184895f26a9SJung-uk Kim * this method/object matches the actual ASL/AML definition. 185895f26a9SJung-uk Kim */ 186895f26a9SJung-uk Kim AcpiNsCheckArgumentCount (Info->FullPathname, Info->Node, 187895f26a9SJung-uk Kim Info->ParamCount, Info->Predefined); 188895f26a9SJung-uk Kim 189895f26a9SJung-uk Kim /* For predefined names: Typecheck all incoming arguments */ 190895f26a9SJung-uk Kim 191895f26a9SJung-uk Kim AcpiNsCheckArgumentTypes (Info); 192895f26a9SJung-uk Kim 193895f26a9SJung-uk Kim /* 194895f26a9SJung-uk Kim * Three major evaluation cases: 195895f26a9SJung-uk Kim * 196895f26a9SJung-uk Kim * 1) Object types that cannot be evaluated by definition 197895f26a9SJung-uk Kim * 2) The object is a control method -- execute it 198895f26a9SJung-uk Kim * 3) The object is not a method -- just return it's current value 199895f26a9SJung-uk Kim */ 200895f26a9SJung-uk Kim switch (AcpiNsGetType (Info->Node)) 201895f26a9SJung-uk Kim { 202895f26a9SJung-uk Kim case ACPI_TYPE_DEVICE: 203895f26a9SJung-uk Kim case ACPI_TYPE_EVENT: 204895f26a9SJung-uk Kim case ACPI_TYPE_MUTEX: 205895f26a9SJung-uk Kim case ACPI_TYPE_REGION: 206895f26a9SJung-uk Kim case ACPI_TYPE_THERMAL: 207895f26a9SJung-uk Kim case ACPI_TYPE_LOCAL_SCOPE: 208895f26a9SJung-uk Kim /* 209895f26a9SJung-uk Kim * 1) Disallow evaluation of certain object types. For these, 210895f26a9SJung-uk Kim * object evaluation is undefined and not supported. 211895f26a9SJung-uk Kim */ 212895f26a9SJung-uk Kim ACPI_ERROR ((AE_INFO, 213895f26a9SJung-uk Kim "%s: Evaluation of object type [%s] is not supported", 214895f26a9SJung-uk Kim Info->FullPathname, 215895f26a9SJung-uk Kim AcpiUtGetTypeName (Info->Node->Type))); 216895f26a9SJung-uk Kim 217895f26a9SJung-uk Kim Status = AE_TYPE; 218895f26a9SJung-uk Kim goto Cleanup; 219895f26a9SJung-uk Kim 220895f26a9SJung-uk Kim case ACPI_TYPE_METHOD: 221895f26a9SJung-uk Kim /* 222895f26a9SJung-uk Kim * 2) Object is a control method - execute it 223895f26a9SJung-uk Kim */ 224895f26a9SJung-uk Kim 225895f26a9SJung-uk Kim /* Verify that there is a method object associated with this node */ 226895f26a9SJung-uk Kim 227895f26a9SJung-uk Kim if (!Info->ObjDesc) 228895f26a9SJung-uk Kim { 229895f26a9SJung-uk Kim ACPI_ERROR ((AE_INFO, "%s: Method has no attached sub-object", 230895f26a9SJung-uk Kim Info->FullPathname)); 231895f26a9SJung-uk Kim Status = AE_NULL_OBJECT; 232895f26a9SJung-uk Kim goto Cleanup; 233895f26a9SJung-uk Kim } 234a159c266SJung-uk Kim 235a159c266SJung-uk Kim ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 236895f26a9SJung-uk Kim "**** Execute method [%s] at AML address %p length %X\n", 237895f26a9SJung-uk Kim Info->FullPathname, 238a159c266SJung-uk Kim Info->ObjDesc->Method.AmlStart + 1, 239a159c266SJung-uk Kim Info->ObjDesc->Method.AmlLength - 1)); 240a159c266SJung-uk Kim 241a159c266SJung-uk Kim /* 242a159c266SJung-uk Kim * Any namespace deletion must acquire both the namespace and 243a159c266SJung-uk Kim * interpreter locks to ensure that no thread is using the portion of 244a159c266SJung-uk Kim * the namespace that is being deleted. 245a159c266SJung-uk Kim * 246a159c266SJung-uk Kim * Execute the method via the interpreter. The interpreter is locked 247a159c266SJung-uk Kim * here before calling into the AML parser 248a159c266SJung-uk Kim */ 249a159c266SJung-uk Kim AcpiExEnterInterpreter (); 250a159c266SJung-uk Kim Status = AcpiPsExecuteMethod (Info); 251a159c266SJung-uk Kim AcpiExExitInterpreter (); 252895f26a9SJung-uk Kim break; 253a159c266SJung-uk Kim 254a159c266SJung-uk Kim default: 255895f26a9SJung-uk Kim /* 256895f26a9SJung-uk Kim * 3) All other non-method objects -- get the current object value 257895f26a9SJung-uk Kim */ 258a159c266SJung-uk Kim 259a159c266SJung-uk Kim /* 260895f26a9SJung-uk Kim * Some objects require additional resolution steps (e.g., the Node 261895f26a9SJung-uk Kim * may be a field that must be read, etc.) -- we can't just grab 262895f26a9SJung-uk Kim * the object out of the node. 263a159c266SJung-uk Kim * 264a159c266SJung-uk Kim * Use ResolveNodeToValue() to get the associated value. 265a159c266SJung-uk Kim * 266a159c266SJung-uk Kim * NOTE: we can get away with passing in NULL for a walk state because 267895f26a9SJung-uk Kim * the Node is guaranteed to not be a reference to either a method 268a159c266SJung-uk Kim * local or a method argument (because this interface is never called 269a159c266SJung-uk Kim * from a running method.) 270a159c266SJung-uk Kim * 271a159c266SJung-uk Kim * Even though we do not directly invoke the interpreter for object 272895f26a9SJung-uk Kim * resolution, we must lock it because we could access an OpRegion. 273895f26a9SJung-uk Kim * The OpRegion access code assumes that the interpreter is locked. 274a159c266SJung-uk Kim */ 275a159c266SJung-uk Kim AcpiExEnterInterpreter (); 276a159c266SJung-uk Kim 277895f26a9SJung-uk Kim /* TBD: ResolveNodeToValue has a strange interface, fix */ 278a159c266SJung-uk Kim 279895f26a9SJung-uk Kim Info->ReturnObject = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Info->Node); 280895f26a9SJung-uk Kim 281895f26a9SJung-uk Kim Status = AcpiExResolveNodeToValue (ACPI_CAST_INDIRECT_PTR ( 282895f26a9SJung-uk Kim ACPI_NAMESPACE_NODE, &Info->ReturnObject), NULL); 283a159c266SJung-uk Kim AcpiExExitInterpreter (); 284a159c266SJung-uk Kim 285895f26a9SJung-uk Kim if (ACPI_FAILURE (Status)) 286a159c266SJung-uk Kim { 287*70e6ab8fSJung-uk Kim Info->ReturnObject = NULL; 288895f26a9SJung-uk Kim goto Cleanup; 289895f26a9SJung-uk Kim } 290a159c266SJung-uk Kim 291895f26a9SJung-uk Kim ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Returned object %p [%s]\n", 292a159c266SJung-uk Kim Info->ReturnObject, 293a159c266SJung-uk Kim AcpiUtGetObjectTypeName (Info->ReturnObject))); 294895f26a9SJung-uk Kim 295895f26a9SJung-uk Kim Status = AE_CTRL_RETURN_VALUE; /* Always has a "return value" */ 296895f26a9SJung-uk Kim break; 297a159c266SJung-uk Kim } 298a159c266SJung-uk Kim 299a159c266SJung-uk Kim /* 300895f26a9SJung-uk Kim * For predefined names, check the return value against the ACPI 301895f26a9SJung-uk Kim * specification. Some incorrect return value types are repaired. 302a159c266SJung-uk Kim */ 303895f26a9SJung-uk Kim (void) AcpiNsCheckReturnValue (Info->Node, Info, Info->ParamCount, 304a159c266SJung-uk Kim Status, &Info->ReturnObject); 305a159c266SJung-uk Kim 306a159c266SJung-uk Kim /* Check if there is a return value that must be dealt with */ 307a159c266SJung-uk Kim 308a159c266SJung-uk Kim if (Status == AE_CTRL_RETURN_VALUE) 309a159c266SJung-uk Kim { 310a159c266SJung-uk Kim /* If caller does not want the return value, delete it */ 311a159c266SJung-uk Kim 312a159c266SJung-uk Kim if (Info->Flags & ACPI_IGNORE_RETURN_VALUE) 313a159c266SJung-uk Kim { 314a159c266SJung-uk Kim AcpiUtRemoveReference (Info->ReturnObject); 315a159c266SJung-uk Kim Info->ReturnObject = NULL; 316a159c266SJung-uk Kim } 317a159c266SJung-uk Kim 318a159c266SJung-uk Kim /* Map AE_CTRL_RETURN_VALUE to AE_OK, we are done with it */ 319a159c266SJung-uk Kim 320a159c266SJung-uk Kim Status = AE_OK; 321a159c266SJung-uk Kim } 322a159c266SJung-uk Kim 323a159c266SJung-uk Kim ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 324895f26a9SJung-uk Kim "*** Completed evaluation of object %s ***\n", 325895f26a9SJung-uk Kim Info->RelativePathname)); 326a159c266SJung-uk Kim 327895f26a9SJung-uk Kim Cleanup: 328a159c266SJung-uk Kim /* 329a159c266SJung-uk Kim * Namespace was unlocked by the handling AcpiNs* function, so we 330895f26a9SJung-uk Kim * just free the pathname and return 331a159c266SJung-uk Kim */ 332895f26a9SJung-uk Kim ACPI_FREE (Info->FullPathname); 333895f26a9SJung-uk Kim Info->FullPathname = NULL; 334a159c266SJung-uk Kim return_ACPI_STATUS (Status); 335a159c266SJung-uk Kim } 336a159c266SJung-uk Kim 337a159c266SJung-uk Kim 338a159c266SJung-uk Kim /******************************************************************************* 339a159c266SJung-uk Kim * 340a159c266SJung-uk Kim * FUNCTION: AcpiNsExecModuleCodeList 341a159c266SJung-uk Kim * 342a159c266SJung-uk Kim * PARAMETERS: None 343a159c266SJung-uk Kim * 344a159c266SJung-uk Kim * RETURN: None. Exceptions during method execution are ignored, since 345a159c266SJung-uk Kim * we cannot abort a table load. 346a159c266SJung-uk Kim * 347a159c266SJung-uk Kim * DESCRIPTION: Execute all elements of the global module-level code list. 348a159c266SJung-uk Kim * Each element is executed as a single control method. 349a159c266SJung-uk Kim * 350a159c266SJung-uk Kim ******************************************************************************/ 351a159c266SJung-uk Kim 352a159c266SJung-uk Kim void 353a159c266SJung-uk Kim AcpiNsExecModuleCodeList ( 354a159c266SJung-uk Kim void) 355a159c266SJung-uk Kim { 356a159c266SJung-uk Kim ACPI_OPERAND_OBJECT *Prev; 357a159c266SJung-uk Kim ACPI_OPERAND_OBJECT *Next; 358a159c266SJung-uk Kim ACPI_EVALUATE_INFO *Info; 359a159c266SJung-uk Kim UINT32 MethodCount = 0; 360a159c266SJung-uk Kim 361a159c266SJung-uk Kim 362a159c266SJung-uk Kim ACPI_FUNCTION_TRACE (NsExecModuleCodeList); 363a159c266SJung-uk Kim 364a159c266SJung-uk Kim 365a159c266SJung-uk Kim /* Exit now if the list is empty */ 366a159c266SJung-uk Kim 367a159c266SJung-uk Kim Next = AcpiGbl_ModuleCodeList; 368a159c266SJung-uk Kim if (!Next) 369a159c266SJung-uk Kim { 370a159c266SJung-uk Kim return_VOID; 371a159c266SJung-uk Kim } 372a159c266SJung-uk Kim 373a159c266SJung-uk Kim /* Allocate the evaluation information block */ 374a159c266SJung-uk Kim 375a159c266SJung-uk Kim Info = ACPI_ALLOCATE (sizeof (ACPI_EVALUATE_INFO)); 376a159c266SJung-uk Kim if (!Info) 377a159c266SJung-uk Kim { 378a159c266SJung-uk Kim return_VOID; 379a159c266SJung-uk Kim } 380a159c266SJung-uk Kim 381a159c266SJung-uk Kim /* Walk the list, executing each "method" */ 382a159c266SJung-uk Kim 383a159c266SJung-uk Kim while (Next) 384a159c266SJung-uk Kim { 385a159c266SJung-uk Kim Prev = Next; 386a159c266SJung-uk Kim Next = Next->Method.Mutex; 387a159c266SJung-uk Kim 388a159c266SJung-uk Kim /* Clear the link field and execute the method */ 389a159c266SJung-uk Kim 390a159c266SJung-uk Kim Prev->Method.Mutex = NULL; 391a159c266SJung-uk Kim AcpiNsExecModuleCode (Prev, Info); 392a159c266SJung-uk Kim MethodCount++; 393a159c266SJung-uk Kim 394a159c266SJung-uk Kim /* Delete the (temporary) method object */ 395a159c266SJung-uk Kim 396a159c266SJung-uk Kim AcpiUtRemoveReference (Prev); 397a159c266SJung-uk Kim } 398a159c266SJung-uk Kim 399a159c266SJung-uk Kim ACPI_INFO ((AE_INFO, 400a159c266SJung-uk Kim "Executed %u blocks of module-level executable AML code", 401a159c266SJung-uk Kim MethodCount)); 402a159c266SJung-uk Kim 403a159c266SJung-uk Kim ACPI_FREE (Info); 404a159c266SJung-uk Kim AcpiGbl_ModuleCodeList = NULL; 405a159c266SJung-uk Kim return_VOID; 406a159c266SJung-uk Kim } 407a159c266SJung-uk Kim 408a159c266SJung-uk Kim 409a159c266SJung-uk Kim /******************************************************************************* 410a159c266SJung-uk Kim * 411a159c266SJung-uk Kim * FUNCTION: AcpiNsExecModuleCode 412a159c266SJung-uk Kim * 413a159c266SJung-uk Kim * PARAMETERS: MethodObj - Object container for the module-level code 414a159c266SJung-uk Kim * Info - Info block for method evaluation 415a159c266SJung-uk Kim * 416a159c266SJung-uk Kim * RETURN: None. Exceptions during method execution are ignored, since 417a159c266SJung-uk Kim * we cannot abort a table load. 418a159c266SJung-uk Kim * 419a159c266SJung-uk Kim * DESCRIPTION: Execute a control method containing a block of module-level 420a159c266SJung-uk Kim * executable AML code. The control method is temporarily 421a159c266SJung-uk Kim * installed to the root node, then evaluated. 422a159c266SJung-uk Kim * 423a159c266SJung-uk Kim ******************************************************************************/ 424a159c266SJung-uk Kim 425a159c266SJung-uk Kim static void 426a159c266SJung-uk Kim AcpiNsExecModuleCode ( 427a159c266SJung-uk Kim ACPI_OPERAND_OBJECT *MethodObj, 428a159c266SJung-uk Kim ACPI_EVALUATE_INFO *Info) 429a159c266SJung-uk Kim { 430a159c266SJung-uk Kim ACPI_OPERAND_OBJECT *ParentObj; 431a159c266SJung-uk Kim ACPI_NAMESPACE_NODE *ParentNode; 432a159c266SJung-uk Kim ACPI_OBJECT_TYPE Type; 433a159c266SJung-uk Kim ACPI_STATUS Status; 434a159c266SJung-uk Kim 435a159c266SJung-uk Kim 436a159c266SJung-uk Kim ACPI_FUNCTION_TRACE (NsExecModuleCode); 437a159c266SJung-uk Kim 438a159c266SJung-uk Kim 439a159c266SJung-uk Kim /* 440a159c266SJung-uk Kim * Get the parent node. We cheat by using the NextObject field 441a159c266SJung-uk Kim * of the method object descriptor. 442a159c266SJung-uk Kim */ 443a159c266SJung-uk Kim ParentNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, 444a159c266SJung-uk Kim MethodObj->Method.NextObject); 445a159c266SJung-uk Kim Type = AcpiNsGetType (ParentNode); 446a159c266SJung-uk Kim 447a159c266SJung-uk Kim /* 448a159c266SJung-uk Kim * Get the region handler and save it in the method object. We may need 449a159c266SJung-uk Kim * this if an operation region declaration causes a _REG method to be run. 450a159c266SJung-uk Kim * 451a159c266SJung-uk Kim * We can't do this in AcpiPsLinkModuleCode because 452a159c266SJung-uk Kim * AcpiGbl_RootNode->Object is NULL at PASS1. 453a159c266SJung-uk Kim */ 454a159c266SJung-uk Kim if ((Type == ACPI_TYPE_DEVICE) && ParentNode->Object) 455a159c266SJung-uk Kim { 456a159c266SJung-uk Kim MethodObj->Method.Dispatch.Handler = 457a159c266SJung-uk Kim ParentNode->Object->Device.Handler; 458a159c266SJung-uk Kim } 459a159c266SJung-uk Kim 460a159c266SJung-uk Kim /* Must clear NextObject (AcpiNsAttachObject needs the field) */ 461a159c266SJung-uk Kim 462a159c266SJung-uk Kim MethodObj->Method.NextObject = NULL; 463a159c266SJung-uk Kim 464a159c266SJung-uk Kim /* Initialize the evaluation information block */ 465a159c266SJung-uk Kim 4665ef50723SJung-uk Kim memset (Info, 0, sizeof (ACPI_EVALUATE_INFO)); 467a159c266SJung-uk Kim Info->PrefixNode = ParentNode; 468a159c266SJung-uk Kim 469a159c266SJung-uk Kim /* 470a159c266SJung-uk Kim * Get the currently attached parent object. Add a reference, because the 471a159c266SJung-uk Kim * ref count will be decreased when the method object is installed to 472a159c266SJung-uk Kim * the parent node. 473a159c266SJung-uk Kim */ 474a159c266SJung-uk Kim ParentObj = AcpiNsGetAttachedObject (ParentNode); 475a159c266SJung-uk Kim if (ParentObj) 476a159c266SJung-uk Kim { 477a159c266SJung-uk Kim AcpiUtAddReference (ParentObj); 478a159c266SJung-uk Kim } 479a159c266SJung-uk Kim 480a159c266SJung-uk Kim /* Install the method (module-level code) in the parent node */ 481a159c266SJung-uk Kim 482a159c266SJung-uk Kim Status = AcpiNsAttachObject (ParentNode, MethodObj, 483a159c266SJung-uk Kim ACPI_TYPE_METHOD); 484a159c266SJung-uk Kim if (ACPI_FAILURE (Status)) 485a159c266SJung-uk Kim { 486a159c266SJung-uk Kim goto Exit; 487a159c266SJung-uk Kim } 488a159c266SJung-uk Kim 489a159c266SJung-uk Kim /* Execute the parent node as a control method */ 490a159c266SJung-uk Kim 491a159c266SJung-uk Kim Status = AcpiNsEvaluate (Info); 492a159c266SJung-uk Kim 493*70e6ab8fSJung-uk Kim ACPI_DEBUG_PRINT ((ACPI_DB_INIT_NAMES, 494*70e6ab8fSJung-uk Kim "Executed module-level code at %p\n", 495a159c266SJung-uk Kim MethodObj->Method.AmlStart)); 496a159c266SJung-uk Kim 497a159c266SJung-uk Kim /* Delete a possible implicit return value (in slack mode) */ 498a159c266SJung-uk Kim 499a159c266SJung-uk Kim if (Info->ReturnObject) 500a159c266SJung-uk Kim { 501a159c266SJung-uk Kim AcpiUtRemoveReference (Info->ReturnObject); 502a159c266SJung-uk Kim } 503a159c266SJung-uk Kim 504a159c266SJung-uk Kim /* Detach the temporary method object */ 505a159c266SJung-uk Kim 506a159c266SJung-uk Kim AcpiNsDetachObject (ParentNode); 507a159c266SJung-uk Kim 508a159c266SJung-uk Kim /* Restore the original parent object */ 509a159c266SJung-uk Kim 510a159c266SJung-uk Kim if (ParentObj) 511a159c266SJung-uk Kim { 512a159c266SJung-uk Kim Status = AcpiNsAttachObject (ParentNode, ParentObj, Type); 513a159c266SJung-uk Kim } 514a159c266SJung-uk Kim else 515a159c266SJung-uk Kim { 516a159c266SJung-uk Kim ParentNode->Type = (UINT8) Type; 517a159c266SJung-uk Kim } 518a159c266SJung-uk Kim 519a159c266SJung-uk Kim Exit: 520a159c266SJung-uk Kim if (ParentObj) 521a159c266SJung-uk Kim { 522a159c266SJung-uk Kim AcpiUtRemoveReference (ParentObj); 523a159c266SJung-uk Kim } 524a159c266SJung-uk Kim return_VOID; 525a159c266SJung-uk Kim } 526