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