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