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