1 /****************************************************************************** 2 * 3 * Module Name: excreate - Named object creation 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2018, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 #include "acpi.h" 45 #include "accommon.h" 46 #include "acinterp.h" 47 #include "amlcode.h" 48 #include "acnamesp.h" 49 50 51 #define _COMPONENT ACPI_EXECUTER 52 ACPI_MODULE_NAME ("excreate") 53 54 55 #ifndef ACPI_NO_METHOD_EXECUTION 56 /******************************************************************************* 57 * 58 * FUNCTION: AcpiExCreateAlias 59 * 60 * PARAMETERS: WalkState - Current state, contains operands 61 * 62 * RETURN: Status 63 * 64 * DESCRIPTION: Create a new named alias 65 * 66 ******************************************************************************/ 67 68 ACPI_STATUS 69 AcpiExCreateAlias ( 70 ACPI_WALK_STATE *WalkState) 71 { 72 ACPI_NAMESPACE_NODE *TargetNode; 73 ACPI_NAMESPACE_NODE *AliasNode; 74 ACPI_STATUS Status = AE_OK; 75 76 77 ACPI_FUNCTION_TRACE (ExCreateAlias); 78 79 80 /* Get the source/alias operands (both namespace nodes) */ 81 82 AliasNode = (ACPI_NAMESPACE_NODE *) WalkState->Operands[0]; 83 TargetNode = (ACPI_NAMESPACE_NODE *) WalkState->Operands[1]; 84 85 if ((TargetNode->Type == ACPI_TYPE_LOCAL_ALIAS) || 86 (TargetNode->Type == ACPI_TYPE_LOCAL_METHOD_ALIAS)) 87 { 88 /* 89 * Dereference an existing alias so that we don't create a chain 90 * of aliases. With this code, we guarantee that an alias is 91 * always exactly one level of indirection away from the 92 * actual aliased name. 93 */ 94 TargetNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, TargetNode->Object); 95 } 96 97 /* Ensure that the target node is valid */ 98 99 if (!TargetNode) 100 { 101 return_ACPI_STATUS (AE_NULL_OBJECT); 102 } 103 104 /* Construct the alias object (a namespace node) */ 105 106 switch (TargetNode->Type) 107 { 108 case ACPI_TYPE_METHOD: 109 /* 110 * Control method aliases need to be differentiated with 111 * a special type 112 */ 113 AliasNode->Type = ACPI_TYPE_LOCAL_METHOD_ALIAS; 114 break; 115 116 default: 117 /* 118 * All other object types. 119 * 120 * The new alias has the type ALIAS and points to the original 121 * NS node, not the object itself. 122 */ 123 AliasNode->Type = ACPI_TYPE_LOCAL_ALIAS; 124 AliasNode->Object = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, TargetNode); 125 break; 126 } 127 128 /* Since both operands are Nodes, we don't need to delete them */ 129 130 AliasNode->Object = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, TargetNode); 131 return_ACPI_STATUS (Status); 132 } 133 134 135 /******************************************************************************* 136 * 137 * FUNCTION: AcpiExCreateEvent 138 * 139 * PARAMETERS: WalkState - Current state 140 * 141 * RETURN: Status 142 * 143 * DESCRIPTION: Create a new event object 144 * 145 ******************************************************************************/ 146 147 ACPI_STATUS 148 AcpiExCreateEvent ( 149 ACPI_WALK_STATE *WalkState) 150 { 151 ACPI_STATUS Status; 152 ACPI_OPERAND_OBJECT *ObjDesc; 153 154 155 ACPI_FUNCTION_TRACE (ExCreateEvent); 156 157 158 ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_EVENT); 159 if (!ObjDesc) 160 { 161 Status = AE_NO_MEMORY; 162 goto Cleanup; 163 } 164 165 /* 166 * Create the actual OS semaphore, with zero initial units -- meaning 167 * that the event is created in an unsignalled state 168 */ 169 Status = AcpiOsCreateSemaphore (ACPI_NO_UNIT_LIMIT, 0, 170 &ObjDesc->Event.OsSemaphore); 171 if (ACPI_FAILURE (Status)) 172 { 173 goto Cleanup; 174 } 175 176 /* Attach object to the Node */ 177 178 Status = AcpiNsAttachObject ( 179 (ACPI_NAMESPACE_NODE *) WalkState->Operands[0], 180 ObjDesc, ACPI_TYPE_EVENT); 181 182 Cleanup: 183 /* 184 * Remove local reference to the object (on error, will cause deletion 185 * of both object and semaphore if present.) 186 */ 187 AcpiUtRemoveReference (ObjDesc); 188 return_ACPI_STATUS (Status); 189 } 190 191 192 /******************************************************************************* 193 * 194 * FUNCTION: AcpiExCreateMutex 195 * 196 * PARAMETERS: WalkState - Current state 197 * 198 * RETURN: Status 199 * 200 * DESCRIPTION: Create a new mutex object 201 * 202 * Mutex (Name[0], SyncLevel[1]) 203 * 204 ******************************************************************************/ 205 206 ACPI_STATUS 207 AcpiExCreateMutex ( 208 ACPI_WALK_STATE *WalkState) 209 { 210 ACPI_STATUS Status = AE_OK; 211 ACPI_OPERAND_OBJECT *ObjDesc; 212 213 214 ACPI_FUNCTION_TRACE_PTR (ExCreateMutex, ACPI_WALK_OPERANDS); 215 216 217 /* Create the new mutex object */ 218 219 ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_MUTEX); 220 if (!ObjDesc) 221 { 222 Status = AE_NO_MEMORY; 223 goto Cleanup; 224 } 225 226 /* Create the actual OS Mutex */ 227 228 Status = AcpiOsCreateMutex (&ObjDesc->Mutex.OsMutex); 229 if (ACPI_FAILURE (Status)) 230 { 231 goto Cleanup; 232 } 233 234 /* Init object and attach to NS node */ 235 236 ObjDesc->Mutex.SyncLevel = (UINT8) WalkState->Operands[1]->Integer.Value; 237 ObjDesc->Mutex.Node = (ACPI_NAMESPACE_NODE *) WalkState->Operands[0]; 238 239 Status = AcpiNsAttachObject ( 240 ObjDesc->Mutex.Node, ObjDesc, ACPI_TYPE_MUTEX); 241 242 243 Cleanup: 244 /* 245 * Remove local reference to the object (on error, will cause deletion 246 * of both object and semaphore if present.) 247 */ 248 AcpiUtRemoveReference (ObjDesc); 249 return_ACPI_STATUS (Status); 250 } 251 252 253 /******************************************************************************* 254 * 255 * FUNCTION: AcpiExCreateRegion 256 * 257 * PARAMETERS: AmlStart - Pointer to the region declaration AML 258 * AmlLength - Max length of the declaration AML 259 * SpaceId - Address space ID for the region 260 * WalkState - Current state 261 * 262 * RETURN: Status 263 * 264 * DESCRIPTION: Create a new operation region object 265 * 266 ******************************************************************************/ 267 268 ACPI_STATUS 269 AcpiExCreateRegion ( 270 UINT8 *AmlStart, 271 UINT32 AmlLength, 272 UINT8 SpaceId, 273 ACPI_WALK_STATE *WalkState) 274 { 275 ACPI_STATUS Status; 276 ACPI_OPERAND_OBJECT *ObjDesc; 277 ACPI_NAMESPACE_NODE *Node; 278 ACPI_OPERAND_OBJECT *RegionObj2; 279 280 281 ACPI_FUNCTION_TRACE (ExCreateRegion); 282 283 284 /* Get the Namespace Node */ 285 286 Node = WalkState->Op->Common.Node; 287 288 /* 289 * If the region object is already attached to this node, 290 * just return 291 */ 292 if (AcpiNsGetAttachedObject (Node)) 293 { 294 return_ACPI_STATUS (AE_OK); 295 } 296 297 /* 298 * Space ID must be one of the predefined IDs, or in the user-defined 299 * range 300 */ 301 if (!AcpiIsValidSpaceId (SpaceId)) 302 { 303 /* 304 * Print an error message, but continue. We don't want to abort 305 * a table load for this exception. Instead, if the region is 306 * actually used at runtime, abort the executing method. 307 */ 308 ACPI_ERROR ((AE_INFO, 309 "Invalid/unknown Address Space ID: 0x%2.2X", SpaceId)); 310 } 311 312 ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "Region Type - %s (0x%X)\n", 313 AcpiUtGetRegionName (SpaceId), SpaceId)); 314 315 /* Create the region descriptor */ 316 317 ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_REGION); 318 if (!ObjDesc) 319 { 320 Status = AE_NO_MEMORY; 321 goto Cleanup; 322 } 323 324 /* 325 * Remember location in AML stream of address & length 326 * operands since they need to be evaluated at run time. 327 */ 328 RegionObj2 = AcpiNsGetSecondaryObject (ObjDesc); 329 RegionObj2->Extra.AmlStart = AmlStart; 330 RegionObj2->Extra.AmlLength = AmlLength; 331 RegionObj2->Extra.Method_REG = NULL; 332 if (WalkState->ScopeInfo) 333 { 334 RegionObj2->Extra.ScopeNode = WalkState->ScopeInfo->Scope.Node; 335 } 336 else 337 { 338 RegionObj2->Extra.ScopeNode = Node; 339 } 340 341 /* Init the region from the operands */ 342 343 ObjDesc->Region.SpaceId = SpaceId; 344 ObjDesc->Region.Address = 0; 345 ObjDesc->Region.Length = 0; 346 ObjDesc->Region.Node = Node; 347 ObjDesc->Region.Handler = NULL; 348 ObjDesc->Common.Flags &= 349 ~(AOPOBJ_SETUP_COMPLETE | AOPOBJ_REG_CONNECTED | 350 AOPOBJ_OBJECT_INITIALIZED); 351 352 /* Install the new region object in the parent Node */ 353 354 Status = AcpiNsAttachObject (Node, ObjDesc, ACPI_TYPE_REGION); 355 356 357 Cleanup: 358 359 /* Remove local reference to the object */ 360 361 AcpiUtRemoveReference (ObjDesc); 362 return_ACPI_STATUS (Status); 363 } 364 365 366 /******************************************************************************* 367 * 368 * FUNCTION: AcpiExCreateProcessor 369 * 370 * PARAMETERS: WalkState - Current state 371 * 372 * RETURN: Status 373 * 374 * DESCRIPTION: Create a new processor object and populate the fields 375 * 376 * Processor (Name[0], CpuID[1], PblockAddr[2], PblockLength[3]) 377 * 378 ******************************************************************************/ 379 380 ACPI_STATUS 381 AcpiExCreateProcessor ( 382 ACPI_WALK_STATE *WalkState) 383 { 384 ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0]; 385 ACPI_OPERAND_OBJECT *ObjDesc; 386 ACPI_STATUS Status; 387 388 389 ACPI_FUNCTION_TRACE_PTR (ExCreateProcessor, WalkState); 390 391 392 /* Create the processor object */ 393 394 ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_PROCESSOR); 395 if (!ObjDesc) 396 { 397 return_ACPI_STATUS (AE_NO_MEMORY); 398 } 399 400 /* Initialize the processor object from the operands */ 401 402 ObjDesc->Processor.ProcId = (UINT8) Operand[1]->Integer.Value; 403 ObjDesc->Processor.Length = (UINT8) Operand[3]->Integer.Value; 404 ObjDesc->Processor.Address = (ACPI_IO_ADDRESS) Operand[2]->Integer.Value; 405 406 /* Install the processor object in the parent Node */ 407 408 Status = AcpiNsAttachObject ((ACPI_NAMESPACE_NODE *) Operand[0], 409 ObjDesc, ACPI_TYPE_PROCESSOR); 410 411 /* Remove local reference to the object */ 412 413 AcpiUtRemoveReference (ObjDesc); 414 return_ACPI_STATUS (Status); 415 } 416 417 418 /******************************************************************************* 419 * 420 * FUNCTION: AcpiExCreatePowerResource 421 * 422 * PARAMETERS: WalkState - Current state 423 * 424 * RETURN: Status 425 * 426 * DESCRIPTION: Create a new PowerResource object and populate the fields 427 * 428 * PowerResource (Name[0], SystemLevel[1], ResourceOrder[2]) 429 * 430 ******************************************************************************/ 431 432 ACPI_STATUS 433 AcpiExCreatePowerResource ( 434 ACPI_WALK_STATE *WalkState) 435 { 436 ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0]; 437 ACPI_STATUS Status; 438 ACPI_OPERAND_OBJECT *ObjDesc; 439 440 441 ACPI_FUNCTION_TRACE_PTR (ExCreatePowerResource, WalkState); 442 443 444 /* Create the power resource object */ 445 446 ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_POWER); 447 if (!ObjDesc) 448 { 449 return_ACPI_STATUS (AE_NO_MEMORY); 450 } 451 452 /* Initialize the power object from the operands */ 453 454 ObjDesc->PowerResource.SystemLevel = (UINT8) Operand[1]->Integer.Value; 455 ObjDesc->PowerResource.ResourceOrder = (UINT16) Operand[2]->Integer.Value; 456 457 /* Install the power resource object in the parent Node */ 458 459 Status = AcpiNsAttachObject ((ACPI_NAMESPACE_NODE *) Operand[0], 460 ObjDesc, ACPI_TYPE_POWER); 461 462 /* Remove local reference to the object */ 463 464 AcpiUtRemoveReference (ObjDesc); 465 return_ACPI_STATUS (Status); 466 } 467 #endif 468 469 470 /******************************************************************************* 471 * 472 * FUNCTION: AcpiExCreateMethod 473 * 474 * PARAMETERS: AmlStart - First byte of the method's AML 475 * AmlLength - AML byte count for this method 476 * WalkState - Current state 477 * 478 * RETURN: Status 479 * 480 * DESCRIPTION: Create a new method object 481 * 482 ******************************************************************************/ 483 484 ACPI_STATUS 485 AcpiExCreateMethod ( 486 UINT8 *AmlStart, 487 UINT32 AmlLength, 488 ACPI_WALK_STATE *WalkState) 489 { 490 ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0]; 491 ACPI_OPERAND_OBJECT *ObjDesc; 492 ACPI_STATUS Status; 493 UINT8 MethodFlags; 494 495 496 ACPI_FUNCTION_TRACE_PTR (ExCreateMethod, WalkState); 497 498 499 /* Create a new method object */ 500 501 ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_METHOD); 502 if (!ObjDesc) 503 { 504 Status = AE_NO_MEMORY; 505 goto Exit; 506 } 507 508 /* Save the method's AML pointer and length */ 509 510 ObjDesc->Method.AmlStart = AmlStart; 511 ObjDesc->Method.AmlLength = AmlLength; 512 ObjDesc->Method.Node = Operand[0]; 513 514 /* 515 * Disassemble the method flags. Split off the ArgCount, Serialized 516 * flag, and SyncLevel for efficiency. 517 */ 518 MethodFlags = (UINT8) Operand[1]->Integer.Value; 519 ObjDesc->Method.ParamCount = (UINT8) 520 (MethodFlags & AML_METHOD_ARG_COUNT); 521 522 /* 523 * Get the SyncLevel. If method is serialized, a mutex will be 524 * created for this method when it is parsed. 525 */ 526 if (MethodFlags & AML_METHOD_SERIALIZED) 527 { 528 ObjDesc->Method.InfoFlags = ACPI_METHOD_SERIALIZED; 529 530 /* 531 * ACPI 1.0: SyncLevel = 0 532 * ACPI 2.0: SyncLevel = SyncLevel in method declaration 533 */ 534 ObjDesc->Method.SyncLevel = (UINT8) 535 ((MethodFlags & AML_METHOD_SYNC_LEVEL) >> 4); 536 } 537 538 /* Attach the new object to the method Node */ 539 540 Status = AcpiNsAttachObject ((ACPI_NAMESPACE_NODE *) Operand[0], 541 ObjDesc, ACPI_TYPE_METHOD); 542 543 /* Remove local reference to the object */ 544 545 AcpiUtRemoveReference (ObjDesc); 546 547 Exit: 548 /* Remove a reference to the operand */ 549 550 AcpiUtRemoveReference (Operand[1]); 551 return_ACPI_STATUS (Status); 552 } 553