excreate.c revision 67754
1/****************************************************************************** 2 * 3 * Module Name: amcreate - Named object creation 4 * $Revision: 48 $ 5 * 6 *****************************************************************************/ 7 8/****************************************************************************** 9 * 10 * 1. Copyright Notice 11 * 12 * Some or all of this work - Copyright (c) 1999, Intel Corp. All rights 13 * reserved. 14 * 15 * 2. License 16 * 17 * 2.1. This is your license from Intel Corp. under its intellectual property 18 * rights. You may have additional license terms from the party that provided 19 * you this software, covering your right to use that party's intellectual 20 * property rights. 21 * 22 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 23 * copy of the source code appearing in this file ("Covered Code") an 24 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 25 * base code distributed originally by Intel ("Original Intel Code") to copy, 26 * make derivatives, distribute, use and display any portion of the Covered 27 * Code in any form, with the right to sublicense such rights; and 28 * 29 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 30 * license (with the right to sublicense), under only those claims of Intel 31 * patents that are infringed by the Original Intel Code, to make, use, sell, 32 * offer to sell, and import the Covered Code and derivative works thereof 33 * solely to the minimum extent necessary to exercise the above copyright 34 * license, and in no event shall the patent license extend to any additions 35 * to or modifications of the Original Intel Code. No other license or right 36 * is granted directly or by implication, estoppel or otherwise; 37 * 38 * The above copyright and patent license is granted only if the following 39 * conditions are met: 40 * 41 * 3. Conditions 42 * 43 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 44 * Redistribution of source code of any substantial portion of the Covered 45 * Code or modification with rights to further distribute source must include 46 * the above Copyright Notice, the above License, this list of Conditions, 47 * and the following Disclaimer and Export Compliance provision. In addition, 48 * Licensee must cause all Covered Code to which Licensee contributes to 49 * contain a file documenting the changes Licensee made to create that Covered 50 * Code and the date of any change. Licensee must include in that file the 51 * documentation of any changes made by any predecessor Licensee. Licensee 52 * must include a prominent statement that the modification is derived, 53 * directly or indirectly, from Original Intel Code. 54 * 55 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 56 * Redistribution of source code of any substantial portion of the Covered 57 * Code or modification without rights to further distribute source must 58 * include the following Disclaimer and Export Compliance provision in the 59 * documentation and/or other materials provided with distribution. In 60 * addition, Licensee may not authorize further sublicense of source of any 61 * portion of the Covered Code, and must include terms to the effect that the 62 * license from Licensee to its licensee is limited to the intellectual 63 * property embodied in the software Licensee provides to its licensee, and 64 * not to intellectual property embodied in modifications its licensee may 65 * make. 66 * 67 * 3.3. Redistribution of Executable. Redistribution in executable form of any 68 * substantial portion of the Covered Code or modification must reproduce the 69 * above Copyright Notice, and the following Disclaimer and Export Compliance 70 * provision in the documentation and/or other materials provided with the 71 * distribution. 72 * 73 * 3.4. Intel retains all right, title, and interest in and to the Original 74 * Intel Code. 75 * 76 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 77 * Intel shall be used in advertising or otherwise to promote the sale, use or 78 * other dealings in products derived from or relating to the Covered Code 79 * without prior written authorization from Intel. 80 * 81 * 4. Disclaimer and Export Compliance 82 * 83 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 84 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 85 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 86 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 87 88 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 89 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 90 * PARTICULAR PURPOSE. 91 * 92 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 93 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 94 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 95 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 96 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 97 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 98 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 99 * LIMITED REMEDY. 100 * 101 * 4.3. Licensee shall not export, either directly or indirectly, any of this 102 * software or system incorporating such software without first obtaining any 103 * required license or other approval from the U. S. Department of Commerce or 104 * any other agency or department of the United States Government. In the 105 * event Licensee exports any such software from the United States or 106 * re-exports any such software from a foreign destination, Licensee shall 107 * ensure that the distribution and export/re-export of the software is in 108 * compliance with all laws, regulations, orders, or other restrictions of the 109 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 110 * any of its subsidiaries will export/re-export any technical data, process, 111 * software, or service, directly or indirectly, to any country for which the 112 * United States government or any agency thereof requires an export license, 113 * other governmental approval, or letter of assurance, without first obtaining 114 * such license, approval or letter. 115 * 116 *****************************************************************************/ 117 118#define __AMCREATE_C__ 119 120#include "acpi.h" 121#include "acparser.h" 122#include "acinterp.h" 123#include "amlcode.h" 124#include "acnamesp.h" 125#include "acevents.h" 126#include "acdispat.h" 127 128 129#define _COMPONENT INTERPRETER 130 MODULE_NAME ("amcreate") 131 132 133/******************************************************************************* 134 * 135 * FUNCTION: AcpiAmlExecCreateField 136 * 137 * PARAMETERS: Opcode - The opcode to be executed 138 * Operands - List of operands for the opcode 139 * 140 * RETURN: Status 141 * 142 * DESCRIPTION: Execute CreateField operators: CreateBitFieldOp, 143 * CreateByteFieldOp, CreateWordFieldOp, CreateDWordFieldOp, 144 * CreateFieldOp (which define fields in buffers) 145 * 146 * ALLOCATION: Deletes CreateFieldOp's count operand descriptor 147 * 148 * 149 * ACPI SPECIFICATION REFERENCES: 150 * DefCreateBitField := CreateBitFieldOp SrcBuf BitIdx NameString 151 * DefCreateByteField := CreateByteFieldOp SrcBuf ByteIdx NameString 152 * DefCreateDWordField := CreateDWordFieldOp SrcBuf ByteIdx NameString 153 * DefCreateField := CreateFieldOp SrcBuf BitIdx NumBits NameString 154 * DefCreateWordField := CreateWordFieldOp SrcBuf ByteIdx NameString 155 * BitIndex := TermArg=>Integer 156 * ByteIndex := TermArg=>Integer 157 * NumBits := TermArg=>Integer 158 * SourceBuff := TermArg=>Buffer 159 * 160 ******************************************************************************/ 161 162 163ACPI_STATUS 164AcpiAmlExecCreateField ( 165 UINT8 *AmlPtr, 166 UINT32 AmlLength, 167 ACPI_NAMESPACE_NODE *Node, 168 ACPI_WALK_STATE *WalkState) 169{ 170 ACPI_STATUS Status; 171 ACPI_OPERAND_OBJECT *ObjDesc; 172 ACPI_OPERAND_OBJECT *TmpDesc; 173 174 175 FUNCTION_TRACE ("AmlExecCreateField"); 176 177 178 /* Create the region descriptor */ 179 180 ObjDesc = AcpiCmCreateInternalObject (ACPI_TYPE_FIELD_UNIT); 181 if (!ObjDesc) 182 { 183 Status = AE_NO_MEMORY; 184 goto Cleanup; 185 } 186 187 /* Construct the field object */ 188 189 ObjDesc->FieldUnit.Access = (UINT8) ACCESS_ANY_ACC; 190 ObjDesc->FieldUnit.LockRule = (UINT8) GLOCK_NEVER_LOCK; 191 ObjDesc->FieldUnit.UpdateRule = (UINT8) UPDATE_PRESERVE; 192 193 /* 194 * Allocate a method object for this field unit 195 */ 196 197 ObjDesc->FieldUnit.Extra = AcpiCmCreateInternalObject ( 198 INTERNAL_TYPE_EXTRA); 199 if (!ObjDesc->FieldUnit.Extra) 200 { 201 Status = AE_NO_MEMORY; 202 goto Cleanup; 203 } 204 205 /* 206 * Remember location in AML stream of the field unit 207 * opcode and operands -- since the buffer and index 208 * operands must be evaluated. 209 */ 210 211 ObjDesc->FieldUnit.Extra->Extra.Pcode = AmlPtr; 212 ObjDesc->FieldUnit.Extra->Extra.PcodeLength = AmlLength; 213 ObjDesc->FieldUnit.Node = Node; 214 215 216/* 217 Status = AcpiNsAttachObject (Node, ObjDesc, 218 (UINT8) ACPI_TYPE_FIELD_UNIT); 219 220 if (ACPI_FAILURE (Status)) 221 { 222 goto Cleanup; 223 } 224*/ 225 226 /* 227 * This operation is supposed to cause the destination Name to refer 228 * to the defined FieldUnit -- it must not store the constructed 229 * FieldUnit object (or its current value) in some location that the 230 * Name may already be pointing to. So, if the Name currently contains 231 * a reference which would cause AcpiAmlExecStore() to perform an indirect 232 * store rather than setting the value of the Name itself, clobber that 233 * reference before calling AcpiAmlExecStore(). 234 */ 235 236 /* Type of Name's existing value */ 237 238 switch (AcpiNsGetType (Node)) 239 { 240 241 case ACPI_TYPE_FIELD_UNIT: 242 243 case INTERNAL_TYPE_ALIAS: 244 case INTERNAL_TYPE_BANK_FIELD: 245 case INTERNAL_TYPE_DEF_FIELD: 246 case INTERNAL_TYPE_INDEX_FIELD: 247 248 TmpDesc = AcpiNsGetAttachedObject (Node); 249 if (TmpDesc) 250 { 251 /* 252 * There is an existing object here; delete it and zero out the 253 * object field within the Node 254 */ 255 256 DUMP_PATHNAME (Node, 257 "AmlExecCreateField: Removing Current Reference", 258 TRACE_BFIELD, _COMPONENT); 259 260 DUMP_ENTRY (Node, TRACE_BFIELD); 261 DUMP_STACK_ENTRY (TmpDesc); 262 263 AcpiCmRemoveReference (TmpDesc); 264 AcpiNsAttachObject ((ACPI_NAMESPACE_NODE *) Node, NULL, 265 ACPI_TYPE_ANY); 266 } 267 268 /* Set the type to ANY (or the store below will fail) */ 269 270 ((ACPI_NAMESPACE_NODE *) Node)->Type = ACPI_TYPE_ANY; 271 272 break; 273 274 275 default: 276 277 break; 278 } 279 280 281 /* Store constructed field descriptor in result location */ 282 283 Status = AcpiAmlExecStore (ObjDesc, (ACPI_OPERAND_OBJECT *) Node, WalkState); 284 285 /* 286 * If the field descriptor was not physically stored (or if a failure 287 * above), we must delete it 288 */ 289 if (ObjDesc->Common.ReferenceCount <= 1) 290 { 291 AcpiCmRemoveReference (ObjDesc); 292 } 293 294 295 return_ACPI_STATUS (AE_OK); 296 297 298Cleanup: 299 300 /* Delete region object and method subobject */ 301 302 if (ObjDesc) 303 { 304 /* Remove deletes both objects! */ 305 306 AcpiCmRemoveReference (ObjDesc); 307 ObjDesc = NULL; 308 } 309 310 return_ACPI_STATUS (Status); 311} 312 313 314ACPI_STATUS 315AcpiAmlExecCreateField_original ( 316 UINT16 Opcode, 317 ACPI_WALK_STATE *WalkState) 318{ 319 ACPI_OPERAND_OBJECT *ResDesc = NULL; 320 ACPI_OPERAND_OBJECT *CntDesc = NULL; 321 ACPI_OPERAND_OBJECT *OffDesc = NULL; 322 ACPI_OPERAND_OBJECT *SrcDesc = NULL; 323 ACPI_OPERAND_OBJECT *FieldDesc; 324 ACPI_OPERAND_OBJECT *ObjDesc; 325 OBJECT_TYPE_INTERNAL ResType; 326 ACPI_STATUS Status; 327 UINT32 NumOperands = 3; 328 UINT32 Offset; 329 UINT32 BitOffset; 330 UINT16 BitCount; 331 UINT8 TypeFound; 332 333 334 FUNCTION_TRACE ("AmlExecCreateField"); 335 336 337 /* Resolve the operands */ 338 339 Status = AcpiAmlResolveOperands (Opcode, WALK_OPERANDS, WalkState); 340 DUMP_OPERANDS (WALK_OPERANDS, IMODE_EXECUTE, AcpiPsGetOpcodeName (Opcode), 341 NumOperands, "after AcpiAmlResolveOperands"); 342 343 344 /* Get the operands */ 345 346 Status |= AcpiDsObjStackPopObject (&ResDesc, WalkState); 347 if (AML_CREATE_FIELD_OP == Opcode) 348 { 349 NumOperands = 4; 350 Status |= AcpiDsObjStackPopObject (&CntDesc, WalkState); 351 } 352 353 Status |= AcpiDsObjStackPopObject (&OffDesc, WalkState); 354 Status |= AcpiDsObjStackPopObject (&SrcDesc, WalkState); 355 356 if (ACPI_FAILURE (Status)) 357 { 358 /* Invalid parameters on object stack */ 359 360 DEBUG_PRINT (ACPI_ERROR, 361 ("ExecCreateField/%s: bad operand(s) (0x%X)\n", 362 AcpiPsGetOpcodeName (Opcode), Status)); 363 364 goto Cleanup; 365 } 366 367 368 Offset = (UINT32) OffDesc->Number.Value; 369 370 371 /* 372 * If ResDesc is a Name, it will be a direct name pointer after 373 * AcpiAmlResolveOperands() 374 */ 375 376 if (!VALID_DESCRIPTOR_TYPE (ResDesc, ACPI_DESC_TYPE_NAMED)) 377 { 378 DEBUG_PRINT (ACPI_ERROR, 379 ("AmlExecCreateField (%s): destination must be a Node\n", 380 AcpiPsGetOpcodeName (Opcode))); 381 382 Status = AE_AML_OPERAND_TYPE; 383 goto Cleanup; 384 } 385 386 387 /* 388 * Setup the Bit offsets and counts, according to the opcode 389 */ 390 391 switch (Opcode) 392 { 393 394 /* DefCreateBitField */ 395 396 case AML_BIT_FIELD_OP: 397 398 /* Offset is in bits, Field is a bit */ 399 400 BitOffset = Offset; 401 BitCount = 1; 402 break; 403 404 405 /* DefCreateByteField */ 406 407 case AML_BYTE_FIELD_OP: 408 409 /* Offset is in bytes, field is a byte */ 410 411 BitOffset = 8 * Offset; 412 BitCount = 8; 413 break; 414 415 416 /* DefCreateWordField */ 417 418 case AML_WORD_FIELD_OP: 419 420 /* Offset is in bytes, field is a word */ 421 422 BitOffset = 8 * Offset; 423 BitCount = 16; 424 break; 425 426 427 /* DefCreateDWordField */ 428 429 case AML_DWORD_FIELD_OP: 430 431 /* Offset is in bytes, field is a dword */ 432 433 BitOffset = 8 * Offset; 434 BitCount = 32; 435 break; 436 437 438 /* DefCreateField */ 439 440 case AML_CREATE_FIELD_OP: 441 442 /* Offset is in bits, count is in bits */ 443 444 BitOffset = Offset; 445 BitCount = (UINT16) CntDesc->Number.Value; 446 break; 447 448 449 default: 450 451 DEBUG_PRINT (ACPI_ERROR, 452 ("AmlExecCreateField: Internal error - unknown field creation opcode %02x\n", 453 Opcode)); 454 Status = AE_AML_BAD_OPCODE; 455 goto Cleanup; 456 } 457 458 459 /* 460 * Setup field according to the object type 461 */ 462 463 switch (SrcDesc->Common.Type) 464 { 465 466 /* SourceBuff := TermArg=>Buffer */ 467 468 case ACPI_TYPE_BUFFER: 469 470 if (BitOffset + (UINT32) BitCount > 471 (8 * (UINT32) SrcDesc->Buffer.Length)) 472 { 473 DEBUG_PRINT (ACPI_ERROR, 474 ("AmlExecCreateField: Field exceeds Buffer %d > %d\n", 475 BitOffset + (UINT32) BitCount, 476 8 * (UINT32) SrcDesc->Buffer.Length)); 477 Status = AE_AML_BUFFER_LIMIT; 478 goto Cleanup; 479 } 480 481 482 /* Allocate an object for the field */ 483 484 FieldDesc = AcpiCmCreateInternalObject (ACPI_TYPE_FIELD_UNIT); 485 if (!FieldDesc) 486 { 487 Status = AE_NO_MEMORY; 488 goto Cleanup; 489 } 490 491 /* Construct the field object */ 492 493 FieldDesc->FieldUnit.Access = (UINT8) ACCESS_ANY_ACC; 494 FieldDesc->FieldUnit.LockRule = (UINT8) GLOCK_NEVER_LOCK; 495 FieldDesc->FieldUnit.UpdateRule = (UINT8) UPDATE_PRESERVE; 496 FieldDesc->FieldUnit.Length = BitCount; 497 FieldDesc->FieldUnit.BitOffset = (UINT8) (BitOffset % 8); 498 FieldDesc->FieldUnit.Offset = DIV_8 (BitOffset); 499 FieldDesc->FieldUnit.Container = SrcDesc; 500 501 /* An additional reference for SrcDesc */ 502 503 AcpiCmAddReference (SrcDesc); 504 505 break; 506 507 508 /* Improper object type */ 509 510 default: 511 512 TypeFound = SrcDesc->Common.Type; 513 514 if ((TypeFound > (UINT8) INTERNAL_TYPE_REFERENCE) || 515 !AcpiCmValidObjectType (TypeFound)) 516 { 517 DEBUG_PRINT (ACPI_ERROR, 518 ("AmlExecCreateField: Tried to create field in invalid object type - 0x%X\n", 519 TypeFound)); 520 } 521 522 else 523 { 524 DEBUG_PRINT (ACPI_ERROR, 525 ("AmlExecCreateField: Tried to create field in improper object type - %s\n", 526 AcpiCmGetTypeName (TypeFound))); 527 } 528 529 Status = AE_AML_OPERAND_TYPE; 530 goto Cleanup; 531 } 532 533 534 if (AML_CREATE_FIELD_OP == Opcode) 535 { 536 /* Delete object descriptor unique to CreateField */ 537 538 AcpiCmRemoveReference (CntDesc); 539 CntDesc = NULL; 540 } 541 542 /* 543 * This operation is supposed to cause the destination Name to refer 544 * to the defined FieldUnit -- it must not store the constructed 545 * FieldUnit object (or its current value) in some location that the 546 * Name may already be pointing to. So, if the Name currently contains 547 * a reference which would cause AcpiAmlExecStore() to perform an indirect 548 * store rather than setting the value of the Name itself, clobber that 549 * reference before calling AcpiAmlExecStore(). 550 */ 551 552 ResType = AcpiNsGetType (ResDesc); 553 554 /* Type of Name's existing value */ 555 556 switch (ResType) 557 { 558 559 case ACPI_TYPE_FIELD_UNIT: 560 561 case INTERNAL_TYPE_ALIAS: 562 case INTERNAL_TYPE_BANK_FIELD: 563 case INTERNAL_TYPE_DEF_FIELD: 564 case INTERNAL_TYPE_INDEX_FIELD: 565 566 ObjDesc = AcpiNsGetAttachedObject (ResDesc); 567 if (ObjDesc) 568 { 569 /* 570 * There is an existing object here; delete it and zero out the 571 * object field within the Node 572 */ 573 574 DUMP_PATHNAME (ResDesc, 575 "AmlExecCreateField: Removing Current Reference", 576 TRACE_BFIELD, _COMPONENT); 577 578 DUMP_ENTRY (ResDesc, TRACE_BFIELD); 579 DUMP_STACK_ENTRY (ObjDesc); 580 581 AcpiCmRemoveReference (ObjDesc); 582 AcpiNsAttachObject ((ACPI_NAMESPACE_NODE *) ResDesc, NULL, 583 ACPI_TYPE_ANY); 584 } 585 586 /* Set the type to ANY (or the store below will fail) */ 587 588 ((ACPI_NAMESPACE_NODE *) ResDesc)->Type = ACPI_TYPE_ANY; 589 590 break; 591 592 593 default: 594 595 break; 596 } 597 598 599 /* Store constructed field descriptor in result location */ 600 601 Status = AcpiAmlExecStore (FieldDesc, ResDesc, WalkState); 602 603 /* 604 * If the field descriptor was not physically stored (or if a failure 605 * above), we must delete it 606 */ 607 if (FieldDesc->Common.ReferenceCount <= 1) 608 { 609 AcpiCmRemoveReference (FieldDesc); 610 } 611 612 613Cleanup: 614 615 /* Always delete the operands */ 616 617 AcpiCmRemoveReference (OffDesc); 618 AcpiCmRemoveReference (SrcDesc); 619 620 if (AML_CREATE_FIELD_OP == Opcode) 621 { 622 AcpiCmRemoveReference (CntDesc); 623 } 624 625 /* On failure, delete the result descriptor */ 626 627 if (ACPI_FAILURE (Status)) 628 { 629 AcpiCmRemoveReference (ResDesc); /* Result descriptor */ 630 } 631 632 return_ACPI_STATUS (Status); 633} 634 635 636/***************************************************************************** 637 * 638 * FUNCTION: AcpiAmlExecCreateAlias 639 * 640 * PARAMETERS: Operands - List of operands for the opcode 641 * 642 * RETURN: Status 643 * 644 * DESCRIPTION: Create a new named alias 645 * 646 ****************************************************************************/ 647 648ACPI_STATUS 649AcpiAmlExecCreateAlias ( 650 ACPI_WALK_STATE *WalkState) 651{ 652 ACPI_NAMESPACE_NODE *SourceNode; 653 ACPI_NAMESPACE_NODE *AliasNode; 654 ACPI_STATUS Status; 655 656 657 FUNCTION_TRACE ("AmlExecCreateAlias"); 658 659 660 /* Get the source/alias operands (both NTEs) */ 661 662 Status = AcpiDsObjStackPopObject ((ACPI_OPERAND_OBJECT **) &SourceNode, 663 WalkState); 664 if (ACPI_FAILURE (Status)) 665 { 666 return_ACPI_STATUS (Status); 667 } 668 669 /* 670 * Don't pop it, it gets removed in the calling routine 671 */ 672 673 AliasNode = AcpiDsObjStackGetValue (0, WalkState); 674 675 /* Add an additional reference to the object */ 676 677 AcpiCmAddReference (SourceNode->Object); 678 679 /* 680 * Attach the original source Node to the new Alias Node. 681 */ 682 Status = AcpiNsAttachObject (AliasNode, SourceNode->Object, 683 SourceNode->Type); 684 685 686 /* 687 * The new alias assumes the type of the source, but it points 688 * to the same object. The reference count of the object has two 689 * additional references to prevent deletion out from under either the 690 * source or the alias Node 691 */ 692 693 /* Since both operands are NTEs, we don't need to delete them */ 694 695 return_ACPI_STATUS (Status); 696} 697 698 699/***************************************************************************** 700 * 701 * FUNCTION: AcpiAmlExecCreateEvent 702 * 703 * PARAMETERS: None 704 * 705 * RETURN: Status 706 * 707 * DESCRIPTION: Create a new event object 708 * 709 ****************************************************************************/ 710 711ACPI_STATUS 712AcpiAmlExecCreateEvent ( 713 ACPI_WALK_STATE *WalkState) 714{ 715 ACPI_STATUS Status; 716 ACPI_OPERAND_OBJECT *ObjDesc; 717 718 719 FUNCTION_TRACE ("AmlExecCreateEvent"); 720 721 722 BREAKPOINT3; 723 724 ObjDesc = AcpiCmCreateInternalObject (ACPI_TYPE_EVENT); 725 if (!ObjDesc) 726 { 727 Status = AE_NO_MEMORY; 728 goto Cleanup; 729 } 730 731 /* Create the actual OS semaphore */ 732 733 /* TBD: [Investigate] should be created with 0 or 1 units? */ 734 735 Status = AcpiOsCreateSemaphore (ACPI_NO_UNIT_LIMIT, 1, 736 &ObjDesc->Event.Semaphore); 737 if (ACPI_FAILURE (Status)) 738 { 739 AcpiCmRemoveReference (ObjDesc); 740 goto Cleanup; 741 } 742 743 /* Attach object to the Node */ 744 745 Status = AcpiNsAttachObject (AcpiDsObjStackGetValue (0, WalkState), 746 ObjDesc, (UINT8) ACPI_TYPE_EVENT); 747 if (ACPI_FAILURE (Status)) 748 { 749 AcpiOsDeleteSemaphore (ObjDesc->Event.Semaphore); 750 AcpiCmRemoveReference (ObjDesc); 751 goto Cleanup; 752 } 753 754 755Cleanup: 756 757 return_ACPI_STATUS (Status); 758} 759 760 761/***************************************************************************** 762 * 763 * FUNCTION: AcpiAmlExecCreateMutex 764 * 765 * PARAMETERS: InterpreterMode - Current running mode (load1/Load2/Exec) 766 * Operands - List of operands for the opcode 767 * 768 * RETURN: Status 769 * 770 * DESCRIPTION: Create a new mutex object 771 * 772 ****************************************************************************/ 773 774ACPI_STATUS 775AcpiAmlExecCreateMutex ( 776 ACPI_WALK_STATE *WalkState) 777{ 778 ACPI_STATUS Status = AE_OK; 779 ACPI_OPERAND_OBJECT *SyncDesc; 780 ACPI_OPERAND_OBJECT *ObjDesc; 781 782 783 FUNCTION_TRACE_PTR ("AmlExecCreateMutex", WALK_OPERANDS); 784 785 786 /* Get the operand */ 787 788 Status = AcpiDsObjStackPopObject (&SyncDesc, WalkState); 789 if (ACPI_FAILURE (Status)) 790 { 791 return_ACPI_STATUS (Status); 792 } 793 794 /* Attempt to allocate a new object */ 795 796 ObjDesc = AcpiCmCreateInternalObject (ACPI_TYPE_MUTEX); 797 if (!ObjDesc) 798 { 799 Status = AE_NO_MEMORY; 800 goto Cleanup; 801 } 802 803 /* Create the actual OS semaphore */ 804 805 Status = AcpiOsCreateSemaphore (1, 1, &ObjDesc->Mutex.Semaphore); 806 if (ACPI_FAILURE (Status)) 807 { 808 AcpiCmRemoveReference (ObjDesc); 809 goto Cleanup; 810 } 811 812 ObjDesc->Mutex.SyncLevel = (UINT8) SyncDesc->Number.Value; 813 814 /* ObjDesc was on the stack top, and the name is below it */ 815 816 Status = AcpiNsAttachObject (AcpiDsObjStackGetValue (0, WalkState), 817 ObjDesc, (UINT8) ACPI_TYPE_MUTEX); 818 if (ACPI_FAILURE (Status)) 819 { 820 AcpiOsDeleteSemaphore (ObjDesc->Mutex.Semaphore); 821 AcpiCmRemoveReference (ObjDesc); 822 goto Cleanup; 823 } 824 825 826Cleanup: 827 828 /* Always delete the operand */ 829 830 AcpiCmRemoveReference (SyncDesc); 831 832 return_ACPI_STATUS (Status); 833} 834 835 836/***************************************************************************** 837 * 838 * FUNCTION: AcpiAmlExecCreateRegion 839 * 840 * PARAMETERS: AmlPtr - Pointer to the region declaration AML 841 * AmlLength - Max length of the declaration AML 842 * Operands - List of operands for the opcode 843 * InterpreterMode - Load1/Load2/Execute 844 * 845 * RETURN: Status 846 * 847 * DESCRIPTION: Create a new operation region object 848 * 849 ****************************************************************************/ 850 851ACPI_STATUS 852AcpiAmlExecCreateRegion ( 853 UINT8 *AmlPtr, 854 UINT32 AmlLength, 855 UINT32 RegionSpace, 856 ACPI_WALK_STATE *WalkState) 857{ 858 ACPI_STATUS Status; 859 ACPI_OPERAND_OBJECT *ObjDesc; 860 ACPI_NAMESPACE_NODE *Node; 861 862 863 FUNCTION_TRACE ("AmlExecCreateRegion"); 864 865 866 if (RegionSpace >= NUM_REGION_TYPES) 867 { 868 /* TBD: [Future] In ACPI 2.0, valid region space 869 * includes types 0-6 (Adding CMOS and PCIBARTarget). 870 * Also, types 0x80-0xff are defined as "OEM Region 871 * Space handler" 872 * 873 * Should this return an error, or should we just keep 874 * going? How do we handle the OEM region handlers? 875 */ 876 REPORT_WARNING (("Invalid AddressSpace type %X\n", RegionSpace)); 877 } 878 879 DEBUG_PRINT (TRACE_LOAD, ("AmlDoNode: Region Type [%s]\n", 880 AcpiGbl_RegionTypes[RegionSpace])); 881 882 883 /* Get the Node from the object stack */ 884 885 Node = (ACPI_NAMESPACE_NODE *) AcpiDsObjStackGetValue (0, WalkState); 886 887 /* Create the region descriptor */ 888 889 ObjDesc = AcpiCmCreateInternalObject (ACPI_TYPE_REGION); 890 if (!ObjDesc) 891 { 892 Status = AE_NO_MEMORY; 893 goto Cleanup; 894 } 895 896 /* 897 * Allocate a method object for this region. 898 */ 899 900 ObjDesc->Region.Extra = AcpiCmCreateInternalObject ( 901 INTERNAL_TYPE_EXTRA); 902 if (!ObjDesc->Region.Extra) 903 { 904 Status = AE_NO_MEMORY; 905 goto Cleanup; 906 } 907 908 /* 909 * Remember location in AML stream of address & length 910 * operands since they need to be evaluated at run time. 911 */ 912 913 ObjDesc->Region.Extra->Extra.Pcode = AmlPtr; 914 ObjDesc->Region.Extra->Extra.PcodeLength = AmlLength; 915 916 /* Init the region from the operands */ 917 918 ObjDesc->Region.SpaceId = (UINT8) RegionSpace; 919 ObjDesc->Region.Address = 0; 920 ObjDesc->Region.Length = 0; 921 922 923 /* Install the new region object in the parent Node */ 924 925 ObjDesc->Region.Node = Node; 926 927 Status = AcpiNsAttachObject (Node, ObjDesc, 928 (UINT8) ACPI_TYPE_REGION); 929 930 if (ACPI_FAILURE (Status)) 931 { 932 goto Cleanup; 933 } 934 935 /* 936 * If we have a valid region, initialize it 937 * Namespace is NOT locked at this point. 938 */ 939 940 Status = AcpiEvInitializeRegion (ObjDesc, FALSE); 941 942 if (ACPI_FAILURE (Status)) 943 { 944 /* 945 * If AE_NOT_EXIST is returned, it is not fatal 946 * because many regions get created before a handler 947 * is installed for said region. 948 */ 949 if (AE_NOT_EXIST == Status) 950 { 951 Status = AE_OK; 952 } 953 } 954 955Cleanup: 956 957 if (ACPI_FAILURE (Status)) 958 { 959 /* Delete region object and method subobject */ 960 961 if (ObjDesc) 962 { 963 /* Remove deletes both objects! */ 964 965 AcpiCmRemoveReference (ObjDesc); 966 ObjDesc = NULL; 967 } 968 } 969 970 return_ACPI_STATUS (Status); 971} 972 973 974/***************************************************************************** 975 * 976 * FUNCTION: AcpiAmlExecCreateProcessor 977 * 978 * PARAMETERS: Op - Op containing the Processor definition and 979 * args 980 * ProcessorNTE - Node for the containing Node 981 * 982 * RETURN: Status 983 * 984 * DESCRIPTION: Create a new processor object and populate the fields 985 * 986 ****************************************************************************/ 987 988ACPI_STATUS 989AcpiAmlExecCreateProcessor ( 990 ACPI_PARSE_OBJECT *Op, 991 ACPI_HANDLE ProcessorNTE) 992{ 993 ACPI_STATUS Status; 994 ACPI_PARSE_OBJECT *Arg; 995 ACPI_OPERAND_OBJECT *ObjDesc; 996 997 998 FUNCTION_TRACE_PTR ("AmlExecCreateProcessor", Op); 999 1000 1001 ObjDesc = AcpiCmCreateInternalObject (ACPI_TYPE_PROCESSOR); 1002 if (!ObjDesc) 1003 { 1004 Status = AE_NO_MEMORY; 1005 return_ACPI_STATUS (Status); 1006 } 1007 1008 /* Install the new processor object in the parent Node */ 1009 1010 Status = AcpiNsAttachObject (ProcessorNTE, ObjDesc, 1011 (UINT8) ACPI_TYPE_PROCESSOR); 1012 if (ACPI_FAILURE (Status)) 1013 { 1014 return_ACPI_STATUS(Status); 1015 } 1016 1017 Arg = Op->Value.Arg; 1018 1019 /* check existence */ 1020 1021 if (!Arg) 1022 { 1023 Status = AE_AML_NO_OPERAND; 1024 return_ACPI_STATUS (Status); 1025 } 1026 1027 /* First arg is the Processor ID */ 1028 1029 ObjDesc->Processor.ProcId = (UINT8) Arg->Value.Integer; 1030 1031 /* Move to next arg and check existence */ 1032 1033 Arg = Arg->Next; 1034 if (!Arg) 1035 { 1036 Status = AE_AML_NO_OPERAND; 1037 return_ACPI_STATUS (Status); 1038 } 1039 1040 /* Second arg is the PBlock Address */ 1041 1042 ObjDesc->Processor.Address = (ACPI_IO_ADDRESS) Arg->Value.Integer; 1043 1044 /* Move to next arg and check existence */ 1045 1046 Arg = Arg->Next; 1047 if (!Arg) 1048 { 1049 Status = AE_AML_NO_OPERAND; 1050 return_ACPI_STATUS (Status); 1051 } 1052 1053 /* Third arg is the PBlock Length */ 1054 1055 ObjDesc->Processor.Length = (UINT8) Arg->Value.Integer; 1056 1057 return_ACPI_STATUS (AE_OK); 1058} 1059 1060 1061/***************************************************************************** 1062 * 1063 * FUNCTION: AcpiAmlExecCreatePowerResource 1064 * 1065 * PARAMETERS: Op - Op containing the PowerResource definition 1066 * and args 1067 * PowerResNTE - Node for the containing Node 1068 * 1069 * RETURN: Status 1070 * 1071 * DESCRIPTION: Create a new PowerResource object and populate the fields 1072 * 1073 ****************************************************************************/ 1074 1075ACPI_STATUS 1076AcpiAmlExecCreatePowerResource ( 1077 ACPI_PARSE_OBJECT *Op, 1078 ACPI_HANDLE PowerResNTE) 1079{ 1080 ACPI_STATUS Status; 1081 ACPI_PARSE_OBJECT *Arg; 1082 ACPI_OPERAND_OBJECT *ObjDesc; 1083 1084 1085 FUNCTION_TRACE_PTR ("AmlExecCreatePowerResource", Op); 1086 1087 1088 ObjDesc = AcpiCmCreateInternalObject (ACPI_TYPE_POWER); 1089 if (!ObjDesc) 1090 { 1091 Status = AE_NO_MEMORY; 1092 return_ACPI_STATUS (Status); 1093 } 1094 1095 /* Install the new power resource object in the parent Node */ 1096 1097 Status = AcpiNsAttachObject (PowerResNTE, ObjDesc, 1098 (UINT8) ACPI_TYPE_POWER); 1099 if (ACPI_FAILURE (Status)) 1100 { 1101 return_ACPI_STATUS(Status); 1102 } 1103 1104 Arg = Op->Value.Arg; 1105 1106 /* check existence */ 1107 1108 if (!Arg) 1109 { 1110 Status = AE_AML_NO_OPERAND; 1111 return_ACPI_STATUS (Status); 1112 } 1113 1114 /* First arg is the SystemLevel */ 1115 1116 ObjDesc->PowerResource.SystemLevel = (UINT8) Arg->Value.Integer; 1117 1118 /* Move to next arg and check existence */ 1119 1120 Arg = Arg->Next; 1121 if (!Arg) 1122 { 1123 Status = AE_AML_NO_OPERAND; 1124 return_ACPI_STATUS (Status); 1125 } 1126 1127 /* Second arg is the PBlock Address */ 1128 1129 ObjDesc->PowerResource.ResourceOrder = (UINT16) Arg->Value.Integer; 1130 1131 return_ACPI_STATUS (AE_OK); 1132} 1133 1134 1135/***************************************************************************** 1136 * 1137 * FUNCTION: AcpiAmlExecCreateMethod 1138 * 1139 * PARAMETERS: AmlPtr - First byte of the method's AML 1140 * AmlLength - AML byte count for this method 1141 * MethodFlags - AML method flag byte 1142 * Method - Method Node 1143 * 1144 * RETURN: Status 1145 * 1146 * DESCRIPTION: Create a new method object 1147 * 1148 ****************************************************************************/ 1149 1150ACPI_STATUS 1151AcpiAmlExecCreateMethod ( 1152 UINT8 *AmlPtr, 1153 UINT32 AmlLength, 1154 UINT32 MethodFlags, 1155 ACPI_HANDLE Method) 1156{ 1157 ACPI_OPERAND_OBJECT *ObjDesc; 1158 ACPI_STATUS Status; 1159 1160 1161 FUNCTION_TRACE_PTR ("AmlExecCreateMethod", Method); 1162 1163 1164 /* Create a new method object */ 1165 1166 ObjDesc = AcpiCmCreateInternalObject (ACPI_TYPE_METHOD); 1167 if (!ObjDesc) 1168 { 1169 return_ACPI_STATUS (AE_NO_MEMORY); 1170 } 1171 1172 /* Get the method's AML pointer/length from the Op */ 1173 1174 ObjDesc->Method.Pcode = AmlPtr; 1175 ObjDesc->Method.PcodeLength = AmlLength; 1176 1177 /* 1178 * First argument is the Method Flags (contains parameter count for the 1179 * method) 1180 */ 1181 1182 ObjDesc->Method.MethodFlags = (UINT8) MethodFlags; 1183 ObjDesc->Method.ParamCount = (UINT8) (MethodFlags & 1184 METHOD_FLAGS_ARG_COUNT); 1185 1186 /* 1187 * Get the concurrency count. If required, a semaphore will be 1188 * created for this method when it is parsed. 1189 * 1190 * TBD: [Future] for APCI 2.0, there will be a SyncLevel value, not 1191 * just a flag 1192 * Concurrency = SyncLevel + 1;. 1193 */ 1194 1195 if (MethodFlags & METHOD_FLAGS_SERIALIZED) 1196 { 1197 ObjDesc->Method.Concurrency = 1; 1198 } 1199 1200 else 1201 { 1202 ObjDesc->Method.Concurrency = INFINITE_CONCURRENCY; 1203 } 1204 1205 /* Attach the new object to the method Node */ 1206 1207 Status = AcpiNsAttachObject (Method, ObjDesc, (UINT8) ACPI_TYPE_METHOD); 1208 if (ACPI_FAILURE (Status)) 1209 { 1210 AcpiCmDeleteObjectDesc (ObjDesc); 1211 } 1212 1213 return_ACPI_STATUS (Status); 1214} 1215 1216 1217