dsfield.c revision 85756
1218885Sdim/******************************************************************************
2218885Sdim *
3218885Sdim * Module Name: dsfield - Dispatcher field routines
4218885Sdim *              $Revision: 46 $
5218885Sdim *
6218885Sdim *****************************************************************************/
7218885Sdim
8218885Sdim/******************************************************************************
9218885Sdim *
10218885Sdim * 1. Copyright Notice
11218885Sdim *
12218885Sdim * Some or all of this work - Copyright (c) 1999, 2000, 2001, Intel Corp.
13218885Sdim * All rights reserved.
14218885Sdim *
15218885Sdim * 2. License
16218885Sdim *
17218885Sdim * 2.1. This is your license from Intel Corp. under its intellectual property
18249423Sdim * rights.  You may have additional license terms from the party that provided
19218885Sdim * you this software, covering your right to use that party's intellectual
20239462Sdim * property rights.
21249423Sdim *
22249423Sdim * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
23249423Sdim * copy of the source code appearing in this file ("Covered Code") an
24218885Sdim * irrevocable, perpetual, worldwide license under Intel's copyrights in the
25218885Sdim * base code distributed originally by Intel ("Original Intel Code") to copy,
26218885Sdim * make derivatives, distribute, use and display any portion of the Covered
27276479Sdim * Code in any form, with the right to sublicense such rights; and
28276479Sdim *
29218885Sdim * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
30218885Sdim * license (with the right to sublicense), under only those claims of Intel
31218885Sdim * patents that are infringed by the Original Intel Code, to make, use, sell,
32296417Sdim * offer to sell, and import the Covered Code and derivative works thereof
33296417Sdim * solely to the minimum extent necessary to exercise the above copyright
34249423Sdim * license, and in no event shall the patent license extend to any additions
35249423Sdim * to or modifications of the Original Intel Code.  No other license or right
36249423Sdim * is granted directly or by implication, estoppel or otherwise;
37249423Sdim *
38296417Sdim * The above copyright and patent license is granted only if the following
39249423Sdim * conditions are met:
40218885Sdim *
41249423Sdim * 3. Conditions
42249423Sdim *
43249423Sdim * 3.1. Redistribution of Source with Rights to Further Distribute Source.
44249423Sdim * Redistribution of source code of any substantial portion of the Covered
45249423Sdim * Code or modification with rights to further distribute source must include
46249423Sdim * the above Copyright Notice, the above License, this list of Conditions,
47249423Sdim * and the following Disclaimer and Export Compliance provision.  In addition,
48249423Sdim * Licensee must cause all Covered Code to which Licensee contributes to
49249423Sdim * contain a file documenting the changes Licensee made to create that Covered
50249423Sdim * Code and the date of any change.  Licensee must include in that file the
51249423Sdim * documentation of any changes made by any predecessor Licensee.  Licensee
52249423Sdim * must include a prominent statement that the modification is derived,
53249423Sdim * directly or indirectly, from Original Intel Code.
54218885Sdim *
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 * 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 __DSFIELD_C__
118
119#include "acpi.h"
120#include "amlcode.h"
121#include "acdispat.h"
122#include "acinterp.h"
123#include "acnamesp.h"
124#include "acparser.h"
125
126
127#define _COMPONENT          ACPI_DISPATCHER
128        MODULE_NAME         ("dsfield")
129
130
131
132/*******************************************************************************
133 *
134 * FUNCTION:    AcpiDsCreateBufferField
135 *
136 * PARAMETERS:  Opcode              - The opcode to be executed
137 *              Operands            - List of operands for the opcode
138 *              WalkState           - Current state
139 *
140 * RETURN:      Status
141 *
142 * DESCRIPTION: Execute the CreateField operators:
143 *              CreateBitFieldOp,
144 *              CreateByteFieldOp,
145 *              CreateWordFieldOp,
146 *              CreateDWordFieldOp,
147 *              CreateQWordFieldOp,
148 *              CreateFieldOp       (all of which define fields in buffers)
149 *
150 ******************************************************************************/
151
152ACPI_STATUS
153AcpiDsCreateBufferField (
154    ACPI_PARSE_OBJECT       *Op,
155    ACPI_WALK_STATE         *WalkState)
156{
157    ACPI_PARSE_OBJECT       *Arg;
158    ACPI_NAMESPACE_NODE     *Node;
159    ACPI_STATUS             Status;
160    ACPI_OPERAND_OBJECT     *ObjDesc;
161
162
163    FUNCTION_TRACE ("DsCreateBufferField");
164
165
166    /* Get the NameString argument */
167
168    if (Op->Opcode == AML_CREATE_FIELD_OP)
169    {
170        Arg = AcpiPsGetArg (Op, 3);
171    }
172    else
173    {
174        /* Create Bit/Byte/Word/Dword field */
175
176        Arg = AcpiPsGetArg (Op, 2);
177    }
178
179    if (!Arg)
180    {
181        return_ACPI_STATUS (AE_AML_NO_OPERAND);
182    }
183
184    /*
185     * Enter the NameString into the namespace
186     */
187    Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Value.String,
188                            INTERNAL_TYPE_DEF_ANY, IMODE_LOAD_PASS1,
189                            NS_NO_UPSEARCH | NS_DONT_OPEN_SCOPE,
190                            WalkState, &(Node));
191    if (ACPI_FAILURE (Status))
192    {
193        return_ACPI_STATUS (Status);
194    }
195
196    /* We could put the returned object (Node) on the object stack for later, but
197     * for now, we will put it in the "op" object that the parser uses, so we
198     * can get it again at the end of this scope
199     */
200    Op->Node = Node;
201
202    /*
203     * If there is no object attached to the node, this node was just created and
204     * we need to create the field object.  Otherwise, this was a lookup of an
205     * existing node and we don't want to create the field object again.
206     */
207    if (Node->Object)
208    {
209        return_ACPI_STATUS (AE_OK);
210    }
211
212    /*
213     * The Field definition is not fully parsed at this time.
214     * (We must save the address of the AML for the buffer and index operands)
215     */
216
217    /* Create the buffer field object */
218
219    ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_BUFFER_FIELD);
220    if (!ObjDesc)
221    {
222        Status = AE_NO_MEMORY;
223        goto Cleanup;
224    }
225
226    /*
227     * Allocate a method object for this field unit
228     */
229    ObjDesc->BufferField.Extra = AcpiUtCreateInternalObject (
230                                    INTERNAL_TYPE_EXTRA);
231    if (!ObjDesc->BufferField.Extra)
232    {
233        Status = AE_NO_MEMORY;
234        goto Cleanup;
235    }
236
237    /*
238     * Remember location in AML stream of the field unit
239     * opcode and operands -- since the buffer and index
240     * operands must be evaluated.
241     */
242    ObjDesc->BufferField.Extra->Extra.AmlStart  = ((ACPI_PARSE2_OBJECT *) Op)->Data;
243    ObjDesc->BufferField.Extra->Extra.AmlLength = ((ACPI_PARSE2_OBJECT *) Op)->Length;
244    ObjDesc->BufferField.Node = Node;
245
246    /* Attach constructed field descriptor to parent node */
247
248    Status = AcpiNsAttachObject (Node, ObjDesc, ACPI_TYPE_BUFFER_FIELD);
249
250
251Cleanup:
252
253    /* Remove local reference to the object */
254
255    AcpiUtRemoveReference (ObjDesc);
256    return_ACPI_STATUS (Status);
257}
258
259
260
261/*******************************************************************************
262 *
263 * FUNCTION:    AcpiDsGetFieldNames
264 *
265 * PARAMETERS:  Info            - CreateField info structure
266 *  `           WalkState       - Current method state
267 *              Arg             - First parser arg for the field name list
268 *
269 * RETURN:      Status
270 *
271 * DESCRIPTION: Process all named fields in a field declaration.  Names are
272 *              entered into the namespace.
273 *
274 ******************************************************************************/
275
276ACPI_STATUS
277AcpiDsGetFieldNames (
278    ACPI_CREATE_FIELD_INFO  *Info,
279    ACPI_WALK_STATE         *WalkState,
280    ACPI_PARSE_OBJECT       *Arg)
281{
282    ACPI_STATUS             Status;
283
284
285    FUNCTION_TRACE_U32 ("DsGetFieldNames", Info);
286
287
288    /* First field starts at bit zero */
289
290    Info->FieldBitPosition = 0;
291
292    /* Process all elements in the field list (of parse nodes) */
293
294    while (Arg)
295    {
296        /*
297         * Three types of field elements are handled:
298         * 1) Offset - specifies a bit offset
299         * 2) AccessAs - changes the access mode
300         * 3) Name - Enters a new named field into the namespace
301         */
302        switch (Arg->Opcode)
303        {
304        case AML_INT_RESERVEDFIELD_OP:
305
306            Info->FieldBitPosition += Arg->Value.Size;
307            break;
308
309
310        case AML_INT_ACCESSFIELD_OP:
311
312            /*
313             * Get a new AccessType and AccessAttribute for all
314             * entries (until end or another AccessAs keyword)
315             */
316            Info->FieldFlags  = (UINT8) ((Info->FieldFlags & FIELD_ACCESS_TYPE_MASK) ||
317                                        ((UINT8) (Arg->Value.Integer >> 8)));
318            break;
319
320
321        case AML_INT_NAMEDFIELD_OP:
322
323            /* Enter a new field name into the namespace */
324
325            Status = AcpiNsLookup (WalkState->ScopeInfo,
326                            (NATIVE_CHAR *) &((ACPI_PARSE2_OBJECT *)Arg)->Name,
327                            Info->FieldType, IMODE_LOAD_PASS1,
328                            NS_NO_UPSEARCH | NS_DONT_OPEN_SCOPE,
329                            NULL, &Info->FieldNode);
330            if (ACPI_FAILURE (Status))
331            {
332                return_ACPI_STATUS (Status);
333            }
334
335            /* Create and initialize an object for the new Field Node */
336
337            Info->FieldBitLength = Arg->Value.Size;
338
339            Status = AcpiExPrepFieldValue (Info);
340            if (ACPI_FAILURE (Status))
341            {
342                return_ACPI_STATUS (Status);
343            }
344
345            /* Keep track of bit position for the next field */
346
347            Info->FieldBitPosition += Info->FieldBitLength;
348            break;
349
350
351        default:
352
353            ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid opcode in field list: %X\n",
354                Arg->Opcode));
355            return_ACPI_STATUS (AE_AML_ERROR);
356            break;
357        }
358
359        Arg = Arg->Next;
360    }
361
362    return_ACPI_STATUS (AE_OK);
363}
364
365
366/*******************************************************************************
367 *
368 * FUNCTION:    AcpiDsCreateField
369 *
370 * PARAMETERS:  Op              - Op containing the Field definition and args
371 *              RegionNode      - Object for the containing Operation Region
372 *  `           WalkState       - Current method state
373 *
374 * RETURN:      Status
375 *
376 * DESCRIPTION: Create a new field in the specified operation region
377 *
378 ******************************************************************************/
379
380ACPI_STATUS
381AcpiDsCreateField (
382    ACPI_PARSE_OBJECT       *Op,
383    ACPI_NAMESPACE_NODE     *RegionNode,
384    ACPI_WALK_STATE         *WalkState)
385{
386    ACPI_STATUS             Status = AE_AML_ERROR;
387    ACPI_PARSE_OBJECT       *Arg;
388    ACPI_CREATE_FIELD_INFO  Info;
389
390
391    FUNCTION_TRACE_PTR ("DsCreateField", Op);
392
393
394    /* First arg is the name of the parent OpRegion (must already exist) */
395
396    Arg = Op->Value.Arg;
397    if (!RegionNode)
398    {
399        Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Value.Name,
400                        ACPI_TYPE_REGION, IMODE_EXECUTE,
401                        NS_SEARCH_PARENT, WalkState, &RegionNode);
402        if (ACPI_FAILURE (Status))
403        {
404            return_ACPI_STATUS (Status);
405        }
406    }
407
408    /* Second arg is the field flags */
409
410    Arg = Arg->Next;
411    Info.FieldFlags = Arg->Value.Integer8;
412
413    /* Each remaining arg is a Named Field */
414
415    Info.FieldType = INTERNAL_TYPE_REGION_FIELD;
416    Info.RegionNode = RegionNode;
417
418    Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Next);
419
420    return_ACPI_STATUS (Status);
421}
422
423
424/*******************************************************************************
425 *
426 * FUNCTION:    AcpiDsCreateBankField
427 *
428 * PARAMETERS:  Op              - Op containing the Field definition and args
429 *              RegionNode      - Object for the containing Operation Region
430 *  `           WalkState       - Current method state
431 *
432 * RETURN:      Status
433 *
434 * DESCRIPTION: Create a new bank field in the specified operation region
435 *
436 ******************************************************************************/
437
438ACPI_STATUS
439AcpiDsCreateBankField (
440    ACPI_PARSE_OBJECT       *Op,
441    ACPI_NAMESPACE_NODE     *RegionNode,
442    ACPI_WALK_STATE         *WalkState)
443{
444    ACPI_STATUS             Status = AE_AML_ERROR;
445    ACPI_PARSE_OBJECT       *Arg;
446    ACPI_CREATE_FIELD_INFO  Info;
447
448
449    FUNCTION_TRACE_PTR ("DsCreateBankField", Op);
450
451
452    /* First arg is the name of the parent OpRegion (must already exist) */
453
454    Arg = Op->Value.Arg;
455    if (!RegionNode)
456    {
457        Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Value.Name,
458                        ACPI_TYPE_REGION, IMODE_EXECUTE,
459                        NS_SEARCH_PARENT, WalkState, &RegionNode);
460        if (ACPI_FAILURE (Status))
461        {
462            return_ACPI_STATUS (Status);
463        }
464    }
465
466    /* Second arg is the Bank Register (must already exist) */
467
468    Arg = Arg->Next;
469    Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Value.String,
470                    INTERNAL_TYPE_BANK_FIELD_DEFN, IMODE_EXECUTE,
471                    NS_SEARCH_PARENT, WalkState, &Info.RegisterNode);
472    if (ACPI_FAILURE (Status))
473    {
474        return_ACPI_STATUS (Status);
475    }
476
477    /* Third arg is the BankValue */
478
479    Arg = Arg->Next;
480    Info.BankValue = Arg->Value.Integer32;
481
482    /* Fourth arg is the field flags */
483
484    Arg = Arg->Next;
485    Info.FieldFlags = Arg->Value.Integer8;
486
487    /* Each remaining arg is a Named Field */
488
489    Info.FieldType = INTERNAL_TYPE_BANK_FIELD;
490    Info.RegionNode = RegionNode;
491
492    Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Next);
493
494    return_ACPI_STATUS (Status);
495}
496
497
498/*******************************************************************************
499 *
500 * FUNCTION:    AcpiDsCreateIndexField
501 *
502 * PARAMETERS:  Op              - Op containing the Field definition and args
503 *              RegionNode      - Object for the containing Operation Region
504 *  `           WalkState       - Current method state
505 *
506 * RETURN:      Status
507 *
508 * DESCRIPTION: Create a new index field in the specified operation region
509 *
510 ******************************************************************************/
511
512ACPI_STATUS
513AcpiDsCreateIndexField (
514    ACPI_PARSE_OBJECT       *Op,
515    ACPI_NAMESPACE_NODE     *RegionNode,
516    ACPI_WALK_STATE         *WalkState)
517{
518    ACPI_STATUS             Status;
519    ACPI_PARSE_OBJECT       *Arg;
520    ACPI_CREATE_FIELD_INFO  Info;
521
522
523    FUNCTION_TRACE_PTR ("DsCreateIndexField", Op);
524
525
526    /* First arg is the name of the Index register (must already exist) */
527
528    Arg = Op->Value.Arg;
529    Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Value.String,
530                    ACPI_TYPE_ANY, IMODE_EXECUTE,
531                    NS_SEARCH_PARENT, WalkState, &Info.RegisterNode);
532    if (ACPI_FAILURE (Status))
533    {
534        return_ACPI_STATUS (Status);
535    }
536
537    /* Second arg is the data register (must already exist) */
538
539    Arg = Arg->Next;
540    Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Value.String,
541                    INTERNAL_TYPE_INDEX_FIELD_DEFN, IMODE_EXECUTE,
542                    NS_SEARCH_PARENT, WalkState, &Info.DataRegisterNode);
543    if (ACPI_FAILURE (Status))
544    {
545        return_ACPI_STATUS (Status);
546    }
547
548    /* Next arg is the field flags */
549
550    Arg = Arg->Next;
551    Info.FieldFlags = Arg->Value.Integer8;
552
553
554    /* Each remaining arg is a Named Field */
555
556    Info.FieldType = INTERNAL_TYPE_INDEX_FIELD;
557    Info.RegionNode = RegionNode;
558
559    Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Next);
560
561    return_ACPI_STATUS (Status);
562}
563
564
565