excreate.c revision 193529
1/******************************************************************************
2 *
3 * Module Name: excreate - Named object creation
4 *
5 *****************************************************************************/
6
7/******************************************************************************
8 *
9 * 1. Copyright Notice
10 *
11 * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp.
12 * All rights reserved.
13 *
14 * 2. License
15 *
16 * 2.1. This is your license from Intel Corp. under its intellectual property
17 * rights.  You may have additional license terms from the party that provided
18 * you this software, covering your right to use that party's intellectual
19 * property rights.
20 *
21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22 * copy of the source code appearing in this file ("Covered Code") an
23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24 * base code distributed originally by Intel ("Original Intel Code") to copy,
25 * make derivatives, distribute, use and display any portion of the Covered
26 * Code in any form, with the right to sublicense such rights; and
27 *
28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29 * license (with the right to sublicense), under only those claims of Intel
30 * patents that are infringed by the Original Intel Code, to make, use, sell,
31 * offer to sell, and import the Covered Code and derivative works thereof
32 * solely to the minimum extent necessary to exercise the above copyright
33 * license, and in no event shall the patent license extend to any additions
34 * to or modifications of the Original Intel Code.  No other license or right
35 * is granted directly or by implication, estoppel or otherwise;
36 *
37 * The above copyright and patent license is granted only if the following
38 * conditions are met:
39 *
40 * 3. Conditions
41 *
42 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43 * Redistribution of source code of any substantial portion of the Covered
44 * Code or modification with rights to further distribute source must include
45 * the above Copyright Notice, the above License, this list of Conditions,
46 * and the following Disclaimer and Export Compliance provision.  In addition,
47 * Licensee must cause all Covered Code to which Licensee contributes to
48 * contain a file documenting the changes Licensee made to create that Covered
49 * Code and the date of any change.  Licensee must include in that file the
50 * documentation of any changes made by any predecessor Licensee.  Licensee
51 * must include a prominent statement that the modification is derived,
52 * directly or indirectly, from Original Intel Code.
53 *
54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55 * Redistribution of source code of any substantial portion of the Covered
56 * Code or modification without rights to further distribute source must
57 * include the following Disclaimer and Export Compliance provision in the
58 * documentation and/or other materials provided with distribution.  In
59 * addition, Licensee may not authorize further sublicense of source of any
60 * portion of the Covered Code, and must include terms to the effect that the
61 * license from Licensee to its licensee is limited to the intellectual
62 * property embodied in the software Licensee provides to its licensee, and
63 * not to intellectual property embodied in modifications its licensee may
64 * make.
65 *
66 * 3.3. Redistribution of Executable. Redistribution in executable form of any
67 * substantial portion of the Covered Code or modification must reproduce the
68 * above Copyright Notice, and the following Disclaimer and Export Compliance
69 * provision in the documentation and/or other materials provided with the
70 * distribution.
71 *
72 * 3.4. Intel retains all right, title, and interest in and to the Original
73 * Intel Code.
74 *
75 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76 * Intel shall be used in advertising or otherwise to promote the sale, use or
77 * other dealings in products derived from or relating to the Covered Code
78 * without prior written authorization from Intel.
79 *
80 * 4. Disclaimer and Export Compliance
81 *
82 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83 * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
85 * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
86
87 * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
88 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
89 * PARTICULAR PURPOSE.
90 *
91 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
92 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
93 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
94 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
95 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
96 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
97 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
98 * LIMITED REMEDY.
99 *
100 * 4.3. Licensee shall not export, either directly or indirectly, any of this
101 * software or system incorporating such software without first obtaining any
102 * required license or other approval from the U. S. Department of Commerce or
103 * any other agency or department of the United States Government.  In the
104 * event Licensee exports any such software from the United States or
105 * re-exports any such software from a foreign destination, Licensee shall
106 * ensure that the distribution and export/re-export of the software is in
107 * compliance with all laws, regulations, orders, or other restrictions of the
108 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
109 * any of its subsidiaries will export/re-export any technical data, process,
110 * software, or service, directly or indirectly, to any country for which the
111 * United States government or any agency thereof requires an export license,
112 * other governmental approval, or letter of assurance, without first obtaining
113 * such license, approval or letter.
114 *
115 *****************************************************************************/
116
117#define __EXCREATE_C__
118
119#include <contrib/dev/acpica/include/acpi.h>
120#include <contrib/dev/acpica/include/accommon.h>
121#include <contrib/dev/acpica/include/acinterp.h>
122#include <contrib/dev/acpica/include/amlcode.h>
123#include <contrib/dev/acpica/include/acnamesp.h>
124
125
126#define _COMPONENT          ACPI_EXECUTER
127        ACPI_MODULE_NAME    ("excreate")
128
129
130#ifndef ACPI_NO_METHOD_EXECUTION
131/*******************************************************************************
132 *
133 * FUNCTION:    AcpiExCreateAlias
134 *
135 * PARAMETERS:  WalkState            - Current state, contains operands
136 *
137 * RETURN:      Status
138 *
139 * DESCRIPTION: Create a new named alias
140 *
141 ******************************************************************************/
142
143ACPI_STATUS
144AcpiExCreateAlias (
145    ACPI_WALK_STATE         *WalkState)
146{
147    ACPI_NAMESPACE_NODE     *TargetNode;
148    ACPI_NAMESPACE_NODE     *AliasNode;
149    ACPI_STATUS             Status = AE_OK;
150
151
152    ACPI_FUNCTION_TRACE (ExCreateAlias);
153
154
155    /* Get the source/alias operands (both namespace nodes) */
156
157    AliasNode =  (ACPI_NAMESPACE_NODE *) WalkState->Operands[0];
158    TargetNode = (ACPI_NAMESPACE_NODE *) WalkState->Operands[1];
159
160    if ((TargetNode->Type == ACPI_TYPE_LOCAL_ALIAS)  ||
161        (TargetNode->Type == ACPI_TYPE_LOCAL_METHOD_ALIAS))
162    {
163        /*
164         * Dereference an existing alias so that we don't create a chain
165         * of aliases.  With this code, we guarantee that an alias is
166         * always exactly one level of indirection away from the
167         * actual aliased name.
168         */
169        TargetNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, TargetNode->Object);
170    }
171
172    /*
173     * For objects that can never change (i.e., the NS node will
174     * permanently point to the same object), we can simply attach
175     * the object to the new NS node.  For other objects (such as
176     * Integers, buffers, etc.), we have to point the Alias node
177     * to the original Node.
178     */
179    switch (TargetNode->Type)
180    {
181
182    /* For these types, the sub-object can change dynamically via a Store */
183
184    case ACPI_TYPE_INTEGER:
185    case ACPI_TYPE_STRING:
186    case ACPI_TYPE_BUFFER:
187    case ACPI_TYPE_PACKAGE:
188    case ACPI_TYPE_BUFFER_FIELD:
189
190    /*
191     * These types open a new scope, so we need the NS node in order to access
192     * any children.
193     */
194    case ACPI_TYPE_DEVICE:
195    case ACPI_TYPE_POWER:
196    case ACPI_TYPE_PROCESSOR:
197    case ACPI_TYPE_THERMAL:
198    case ACPI_TYPE_LOCAL_SCOPE:
199
200        /*
201         * The new alias has the type ALIAS and points to the original
202         * NS node, not the object itself.
203         */
204        AliasNode->Type = ACPI_TYPE_LOCAL_ALIAS;
205        AliasNode->Object = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, TargetNode);
206        break;
207
208    case ACPI_TYPE_METHOD:
209
210        /*
211         * Control method aliases need to be differentiated
212         */
213        AliasNode->Type = ACPI_TYPE_LOCAL_METHOD_ALIAS;
214        AliasNode->Object = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, TargetNode);
215        break;
216
217    default:
218
219        /* Attach the original source object to the new Alias Node */
220
221        /*
222         * The new alias assumes the type of the target, and it points
223         * to the same object.  The reference count of the object has an
224         * additional reference to prevent deletion out from under either the
225         * target node or the alias Node
226         */
227        Status = AcpiNsAttachObject (AliasNode,
228                    AcpiNsGetAttachedObject (TargetNode), TargetNode->Type);
229        break;
230    }
231
232    /* Since both operands are Nodes, we don't need to delete them */
233
234    return_ACPI_STATUS (Status);
235}
236
237
238/*******************************************************************************
239 *
240 * FUNCTION:    AcpiExCreateEvent
241 *
242 * PARAMETERS:  WalkState           - Current state
243 *
244 * RETURN:      Status
245 *
246 * DESCRIPTION: Create a new event object
247 *
248 ******************************************************************************/
249
250ACPI_STATUS
251AcpiExCreateEvent (
252    ACPI_WALK_STATE         *WalkState)
253{
254    ACPI_STATUS             Status;
255    ACPI_OPERAND_OBJECT     *ObjDesc;
256
257
258    ACPI_FUNCTION_TRACE (ExCreateEvent);
259
260
261    ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_EVENT);
262    if (!ObjDesc)
263    {
264        Status = AE_NO_MEMORY;
265        goto Cleanup;
266    }
267
268    /*
269     * Create the actual OS semaphore, with zero initial units -- meaning
270     * that the event is created in an unsignalled state
271     */
272    Status = AcpiOsCreateSemaphore (ACPI_NO_UNIT_LIMIT, 0,
273                &ObjDesc->Event.OsSemaphore);
274    if (ACPI_FAILURE (Status))
275    {
276        goto Cleanup;
277    }
278
279    /* Attach object to the Node */
280
281    Status = AcpiNsAttachObject ((ACPI_NAMESPACE_NODE *) WalkState->Operands[0],
282                ObjDesc, ACPI_TYPE_EVENT);
283
284Cleanup:
285    /*
286     * Remove local reference to the object (on error, will cause deletion
287     * of both object and semaphore if present.)
288     */
289    AcpiUtRemoveReference (ObjDesc);
290    return_ACPI_STATUS (Status);
291}
292
293
294/*******************************************************************************
295 *
296 * FUNCTION:    AcpiExCreateMutex
297 *
298 * PARAMETERS:  WalkState           - Current state
299 *
300 * RETURN:      Status
301 *
302 * DESCRIPTION: Create a new mutex object
303 *
304 *              Mutex (Name[0], SyncLevel[1])
305 *
306 ******************************************************************************/
307
308ACPI_STATUS
309AcpiExCreateMutex (
310    ACPI_WALK_STATE         *WalkState)
311{
312    ACPI_STATUS             Status = AE_OK;
313    ACPI_OPERAND_OBJECT     *ObjDesc;
314
315
316    ACPI_FUNCTION_TRACE_PTR (ExCreateMutex, ACPI_WALK_OPERANDS);
317
318
319    /* Create the new mutex object */
320
321    ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_MUTEX);
322    if (!ObjDesc)
323    {
324        Status = AE_NO_MEMORY;
325        goto Cleanup;
326    }
327
328    /* Create the actual OS Mutex */
329
330    Status = AcpiOsCreateMutex (&ObjDesc->Mutex.OsMutex);
331    if (ACPI_FAILURE (Status))
332    {
333        goto Cleanup;
334    }
335
336    /* Init object and attach to NS node */
337
338    ObjDesc->Mutex.SyncLevel = (UINT8) WalkState->Operands[1]->Integer.Value;
339    ObjDesc->Mutex.Node = (ACPI_NAMESPACE_NODE *) WalkState->Operands[0];
340
341    Status = AcpiNsAttachObject (ObjDesc->Mutex.Node, ObjDesc, ACPI_TYPE_MUTEX);
342
343
344Cleanup:
345    /*
346     * Remove local reference to the object (on error, will cause deletion
347     * of both object and semaphore if present.)
348     */
349    AcpiUtRemoveReference (ObjDesc);
350    return_ACPI_STATUS (Status);
351}
352
353
354/*******************************************************************************
355 *
356 * FUNCTION:    AcpiExCreateRegion
357 *
358 * PARAMETERS:  AmlStart            - Pointer to the region declaration AML
359 *              AmlLength           - Max length of the declaration AML
360 *              RegionSpace         - SpaceID for the region
361 *              WalkState           - Current state
362 *
363 * RETURN:      Status
364 *
365 * DESCRIPTION: Create a new operation region object
366 *
367 ******************************************************************************/
368
369ACPI_STATUS
370AcpiExCreateRegion (
371    UINT8                   *AmlStart,
372    UINT32                  AmlLength,
373    UINT8                   RegionSpace,
374    ACPI_WALK_STATE         *WalkState)
375{
376    ACPI_STATUS             Status;
377    ACPI_OPERAND_OBJECT     *ObjDesc;
378    ACPI_NAMESPACE_NODE     *Node;
379    ACPI_OPERAND_OBJECT     *RegionObj2;
380
381
382    ACPI_FUNCTION_TRACE (ExCreateRegion);
383
384
385    /* Get the Namespace Node */
386
387    Node = WalkState->Op->Common.Node;
388
389    /*
390     * If the region object is already attached to this node,
391     * just return
392     */
393    if (AcpiNsGetAttachedObject (Node))
394    {
395        return_ACPI_STATUS (AE_OK);
396    }
397
398    /*
399     * Space ID must be one of the predefined IDs, or in the user-defined
400     * range
401     */
402    if ((RegionSpace >= ACPI_NUM_PREDEFINED_REGIONS) &&
403        (RegionSpace < ACPI_USER_REGION_BEGIN))
404    {
405        ACPI_ERROR ((AE_INFO, "Invalid AddressSpace type %X", RegionSpace));
406        return_ACPI_STATUS (AE_AML_INVALID_SPACE_ID);
407    }
408
409    ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "Region Type - %s (%X)\n",
410        AcpiUtGetRegionName (RegionSpace), RegionSpace));
411
412    /* Create the region descriptor */
413
414    ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_REGION);
415    if (!ObjDesc)
416    {
417        Status = AE_NO_MEMORY;
418        goto Cleanup;
419    }
420
421    /*
422     * Remember location in AML stream of address & length
423     * operands since they need to be evaluated at run time.
424     */
425    RegionObj2 = ObjDesc->Common.NextObject;
426    RegionObj2->Extra.AmlStart = AmlStart;
427    RegionObj2->Extra.AmlLength = AmlLength;
428
429    /* Init the region from the operands */
430
431    ObjDesc->Region.SpaceId = RegionSpace;
432    ObjDesc->Region.Address = 0;
433    ObjDesc->Region.Length = 0;
434    ObjDesc->Region.Node = Node;
435
436    /* Install the new region object in the parent Node */
437
438    Status = AcpiNsAttachObject (Node, ObjDesc, ACPI_TYPE_REGION);
439
440
441Cleanup:
442
443    /* Remove local reference to the object */
444
445    AcpiUtRemoveReference (ObjDesc);
446    return_ACPI_STATUS (Status);
447}
448
449
450/*******************************************************************************
451 *
452 * FUNCTION:    AcpiExCreateProcessor
453 *
454 * PARAMETERS:  WalkState           - Current state
455 *
456 * RETURN:      Status
457 *
458 * DESCRIPTION: Create a new processor object and populate the fields
459 *
460 *              Processor (Name[0], CpuID[1], PblockAddr[2], PblockLength[3])
461 *
462 ******************************************************************************/
463
464ACPI_STATUS
465AcpiExCreateProcessor (
466    ACPI_WALK_STATE         *WalkState)
467{
468    ACPI_OPERAND_OBJECT     **Operand = &WalkState->Operands[0];
469    ACPI_OPERAND_OBJECT     *ObjDesc;
470    ACPI_STATUS             Status;
471
472
473    ACPI_FUNCTION_TRACE_PTR (ExCreateProcessor, WalkState);
474
475
476    /* Create the processor object */
477
478    ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_PROCESSOR);
479    if (!ObjDesc)
480    {
481        return_ACPI_STATUS (AE_NO_MEMORY);
482    }
483
484    /* Initialize the processor object from the operands */
485
486    ObjDesc->Processor.ProcId = (UINT8) Operand[1]->Integer.Value;
487    ObjDesc->Processor.Length = (UINT8) Operand[3]->Integer.Value;
488    ObjDesc->Processor.Address = (ACPI_IO_ADDRESS) Operand[2]->Integer.Value;
489
490    /* Install the processor object in the parent Node */
491
492    Status = AcpiNsAttachObject ((ACPI_NAMESPACE_NODE *) Operand[0],
493                    ObjDesc, ACPI_TYPE_PROCESSOR);
494
495    /* Remove local reference to the object */
496
497    AcpiUtRemoveReference (ObjDesc);
498    return_ACPI_STATUS (Status);
499}
500
501
502/*******************************************************************************
503 *
504 * FUNCTION:    AcpiExCreatePowerResource
505 *
506 * PARAMETERS:  WalkState           - Current state
507 *
508 * RETURN:      Status
509 *
510 * DESCRIPTION: Create a new PowerResource object and populate the fields
511 *
512 *              PowerResource (Name[0], SystemLevel[1], ResourceOrder[2])
513 *
514 ******************************************************************************/
515
516ACPI_STATUS
517AcpiExCreatePowerResource (
518    ACPI_WALK_STATE         *WalkState)
519{
520    ACPI_OPERAND_OBJECT     **Operand = &WalkState->Operands[0];
521    ACPI_STATUS             Status;
522    ACPI_OPERAND_OBJECT     *ObjDesc;
523
524
525    ACPI_FUNCTION_TRACE_PTR (ExCreatePowerResource, WalkState);
526
527
528    /* Create the power resource object */
529
530    ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_POWER);
531    if (!ObjDesc)
532    {
533        return_ACPI_STATUS (AE_NO_MEMORY);
534    }
535
536    /* Initialize the power object from the operands */
537
538    ObjDesc->PowerResource.SystemLevel = (UINT8) Operand[1]->Integer.Value;
539    ObjDesc->PowerResource.ResourceOrder = (UINT16) Operand[2]->Integer.Value;
540
541    /* Install the  power resource object in the parent Node */
542
543    Status = AcpiNsAttachObject ((ACPI_NAMESPACE_NODE *) Operand[0],
544                    ObjDesc, ACPI_TYPE_POWER);
545
546    /* Remove local reference to the object */
547
548    AcpiUtRemoveReference (ObjDesc);
549    return_ACPI_STATUS (Status);
550}
551#endif
552
553
554/*******************************************************************************
555 *
556 * FUNCTION:    AcpiExCreateMethod
557 *
558 * PARAMETERS:  AmlStart        - First byte of the method's AML
559 *              AmlLength       - AML byte count for this method
560 *              WalkState       - Current state
561 *
562 * RETURN:      Status
563 *
564 * DESCRIPTION: Create a new method object
565 *
566 ******************************************************************************/
567
568ACPI_STATUS
569AcpiExCreateMethod (
570    UINT8                   *AmlStart,
571    UINT32                  AmlLength,
572    ACPI_WALK_STATE         *WalkState)
573{
574    ACPI_OPERAND_OBJECT     **Operand = &WalkState->Operands[0];
575    ACPI_OPERAND_OBJECT     *ObjDesc;
576    ACPI_STATUS             Status;
577    UINT8                   MethodFlags;
578
579
580    ACPI_FUNCTION_TRACE_PTR (ExCreateMethod, WalkState);
581
582
583    /* Create a new method object */
584
585    ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_METHOD);
586    if (!ObjDesc)
587    {
588       Status = AE_NO_MEMORY;
589       goto Exit;
590    }
591
592    /* Save the method's AML pointer and length  */
593
594    ObjDesc->Method.AmlStart = AmlStart;
595    ObjDesc->Method.AmlLength = AmlLength;
596
597    /*
598     * Disassemble the method flags. Split off the Arg Count
599     * for efficiency
600     */
601    MethodFlags = (UINT8) Operand[1]->Integer.Value;
602
603    ObjDesc->Method.MethodFlags = (UINT8) (MethodFlags & ~AML_METHOD_ARG_COUNT);
604    ObjDesc->Method.ParamCount = (UINT8) (MethodFlags & AML_METHOD_ARG_COUNT);
605
606    /*
607     * Get the SyncLevel. If method is serialized, a mutex will be
608     * created for this method when it is parsed.
609     */
610    if (MethodFlags & AML_METHOD_SERIALIZED)
611    {
612        /*
613         * ACPI 1.0: SyncLevel = 0
614         * ACPI 2.0: SyncLevel = SyncLevel in method declaration
615         */
616        ObjDesc->Method.SyncLevel = (UINT8)
617            ((MethodFlags & AML_METHOD_SYNC_LEVEL) >> 4);
618    }
619
620    /* Attach the new object to the method Node */
621
622    Status = AcpiNsAttachObject ((ACPI_NAMESPACE_NODE *) Operand[0],
623                    ObjDesc, ACPI_TYPE_METHOD);
624
625    /* Remove local reference to the object */
626
627    AcpiUtRemoveReference (ObjDesc);
628
629Exit:
630    /* Remove a reference to the operand */
631
632    AcpiUtRemoveReference (Operand[1]);
633    return_ACPI_STATUS (Status);
634}
635
636
637