1 /****************************************************************************** 2 * 3 * Module Name: excreate - Named object creation 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2022, 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.Pointer = NULL; 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 468 469 /******************************************************************************* 470 * 471 * FUNCTION: AcpiExCreateMethod 472 * 473 * PARAMETERS: AmlStart - First byte of the method's AML 474 * AmlLength - AML byte count for this method 475 * WalkState - Current state 476 * 477 * RETURN: Status 478 * 479 * DESCRIPTION: Create a new method object 480 * 481 ******************************************************************************/ 482 483 ACPI_STATUS 484 AcpiExCreateMethod ( 485 UINT8 *AmlStart, 486 UINT32 AmlLength, 487 ACPI_WALK_STATE *WalkState) 488 { 489 ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0]; 490 ACPI_OPERAND_OBJECT *ObjDesc; 491 ACPI_STATUS Status; 492 UINT8 MethodFlags; 493 494 495 ACPI_FUNCTION_TRACE_PTR (ExCreateMethod, WalkState); 496 497 498 /* Create a new method object */ 499 500 ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_METHOD); 501 if (!ObjDesc) 502 { 503 Status = AE_NO_MEMORY; 504 goto Exit; 505 } 506 507 /* Save the method's AML pointer and length */ 508 509 ObjDesc->Method.AmlStart = AmlStart; 510 ObjDesc->Method.AmlLength = AmlLength; 511 ObjDesc->Method.Node = Operand[0]; 512 513 /* 514 * Disassemble the method flags. Split off the ArgCount, Serialized 515 * flag, and SyncLevel for efficiency. 516 */ 517 MethodFlags = (UINT8) Operand[1]->Integer.Value; 518 ObjDesc->Method.ParamCount = (UINT8) 519 (MethodFlags & AML_METHOD_ARG_COUNT); 520 521 /* 522 * Get the SyncLevel. If method is serialized, a mutex will be 523 * created for this method when it is parsed. 524 */ 525 if (MethodFlags & AML_METHOD_SERIALIZED) 526 { 527 ObjDesc->Method.InfoFlags = ACPI_METHOD_SERIALIZED; 528 529 /* 530 * ACPI 1.0: SyncLevel = 0 531 * ACPI 2.0: SyncLevel = SyncLevel in method declaration 532 */ 533 ObjDesc->Method.SyncLevel = (UINT8) 534 ((MethodFlags & AML_METHOD_SYNC_LEVEL) >> 4); 535 } 536 537 /* Attach the new object to the method Node */ 538 539 Status = AcpiNsAttachObject ((ACPI_NAMESPACE_NODE *) Operand[0], 540 ObjDesc, ACPI_TYPE_METHOD); 541 542 /* Remove local reference to the object */ 543 544 AcpiUtRemoveReference (ObjDesc); 545 546 Exit: 547 /* Remove a reference to the operand */ 548 549 AcpiUtRemoveReference (Operand[1]); 550 return_ACPI_STATUS (Status); 551 } 552