1/******************************************************************************
2 *
3 * Module Name: dsfield - Dispatcher field routines
4 *
5 *****************************************************************************/
6
7/******************************************************************************
8 *
9 * 1. Copyright Notice
10 *
11 * Some or all of this work - Copyright (c) 1999 - 2023, 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 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88 * PARTICULAR PURPOSE.
89 *
90 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97 * LIMITED REMEDY.
98 *
99 * 4.3. Licensee shall not export, either directly or indirectly, any of this
100 * software or system incorporating such software without first obtaining any
101 * required license or other approval from the U. S. Department of Commerce or
102 * any other agency or department of the United States Government. In the
103 * event Licensee exports any such software from the United States or
104 * re-exports any such software from a foreign destination, Licensee shall
105 * ensure that the distribution and export/re-export of the software is in
106 * compliance with all laws, regulations, orders, or other restrictions of the
107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108 * any of its subsidiaries will export/re-export any technical data, process,
109 * software, or service, directly or indirectly, to any country for which the
110 * United States government or any agency thereof requires an export license,
111 * other governmental approval, or letter of assurance, without first obtaining
112 * such license, approval or letter.
113 *
114 *****************************************************************************
115 *
116 * Alternatively, you may choose to be licensed under the terms of the
117 * following license:
118 *
119 * Redistribution and use in source and binary forms, with or without
120 * modification, are permitted provided that the following conditions
121 * are met:
122 * 1. Redistributions of source code must retain the above copyright
123 *    notice, this list of conditions, and the following disclaimer,
124 *    without modification.
125 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126 *    substantially similar to the "NO WARRANTY" disclaimer below
127 *    ("Disclaimer") and any redistribution must be conditioned upon
128 *    including a substantially similar Disclaimer requirement for further
129 *    binary redistribution.
130 * 3. Neither the names of the above-listed copyright holders nor the names
131 *    of any contributors may be used to endorse or promote products derived
132 *    from this software without specific prior written permission.
133 *
134 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145 *
146 * Alternatively, you may choose to be licensed under the terms of the
147 * GNU General Public License ("GPL") version 2 as published by the Free
148 * Software Foundation.
149 *
150 *****************************************************************************/
151
152#include "acpi.h"
153#include "accommon.h"
154#include "amlcode.h"
155#include "acdispat.h"
156#include "acinterp.h"
157#include "acnamesp.h"
158#include "acparser.h"
159
160#ifdef ACPI_EXEC_APP
161#include "aecommon.h"
162#endif
163
164
165#define _COMPONENT          ACPI_DISPATCHER
166        ACPI_MODULE_NAME    ("dsfield")
167
168/* Local prototypes */
169
170#ifdef ACPI_ASL_COMPILER
171#include "acdisasm.h"
172
173static ACPI_STATUS
174AcpiDsCreateExternalRegion (
175    ACPI_STATUS             LookupStatus,
176    ACPI_PARSE_OBJECT       *Op,
177    char                    *Path,
178    ACPI_WALK_STATE         *WalkState,
179    ACPI_NAMESPACE_NODE     **Node);
180#endif
181
182static ACPI_STATUS
183AcpiDsGetFieldNames (
184    ACPI_CREATE_FIELD_INFO  *Info,
185    ACPI_WALK_STATE         *WalkState,
186    ACPI_PARSE_OBJECT       *Arg);
187
188
189#ifdef ACPI_ASL_COMPILER
190/*******************************************************************************
191 *
192 * FUNCTION:    AcpiDsCreateExternalRegion (iASL Disassembler only)
193 *
194 * PARAMETERS:  LookupStatus    - Status from NsLookup operation
195 *              Op              - Op containing the Field definition and args
196 *              Path            - Pathname of the region
197 *  `           WalkState       - Current method state
198 *              Node            - Where the new region node is returned
199 *
200 * RETURN:      Status
201 *
202 * DESCRIPTION: Add region to the external list if NOT_FOUND. Create a new
203 *              region node/object.
204 *
205 ******************************************************************************/
206
207static ACPI_STATUS
208AcpiDsCreateExternalRegion (
209    ACPI_STATUS             LookupStatus,
210    ACPI_PARSE_OBJECT       *Op,
211    char                    *Path,
212    ACPI_WALK_STATE         *WalkState,
213    ACPI_NAMESPACE_NODE     **Node)
214{
215    ACPI_STATUS             Status;
216    ACPI_OPERAND_OBJECT     *ObjDesc;
217
218
219    if (LookupStatus != AE_NOT_FOUND)
220    {
221        return (LookupStatus);
222    }
223
224    /*
225     * Table disassembly:
226     * OperationRegion not found. Generate an External for it, and
227     * insert the name into the namespace.
228     */
229    AcpiDmAddOpToExternalList (Op, Path, ACPI_TYPE_REGION, 0, 0);
230
231    Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_REGION,
232       ACPI_IMODE_LOAD_PASS1, ACPI_NS_SEARCH_PARENT, WalkState, Node);
233    if (ACPI_FAILURE (Status))
234    {
235        return (Status);
236    }
237
238    /* Must create and install a region object for the new node */
239
240    ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_REGION);
241    if (!ObjDesc)
242    {
243        return (AE_NO_MEMORY);
244    }
245
246    ObjDesc->Region.Node = *Node;
247    Status = AcpiNsAttachObject (*Node, ObjDesc, ACPI_TYPE_REGION);
248    return (Status);
249}
250#endif
251
252
253/*******************************************************************************
254 *
255 * FUNCTION:    AcpiDsCreateBufferField
256 *
257 * PARAMETERS:  Op                  - Current parse op (CreateXXField)
258 *              WalkState           - Current state
259 *
260 * RETURN:      Status
261 *
262 * DESCRIPTION: Execute the CreateField operators:
263 *              CreateBitFieldOp,
264 *              CreateByteFieldOp,
265 *              CreateWordFieldOp,
266 *              CreateDwordFieldOp,
267 *              CreateQwordFieldOp,
268 *              CreateFieldOp       (all of which define a field in a buffer)
269 *
270 ******************************************************************************/
271
272ACPI_STATUS
273AcpiDsCreateBufferField (
274    ACPI_PARSE_OBJECT       *Op,
275    ACPI_WALK_STATE         *WalkState)
276{
277    ACPI_PARSE_OBJECT       *Arg;
278    ACPI_NAMESPACE_NODE     *Node;
279    ACPI_STATUS             Status;
280    ACPI_OPERAND_OBJECT     *ObjDesc;
281    ACPI_OPERAND_OBJECT     *SecondDesc = NULL;
282    UINT32                  Flags;
283
284
285    ACPI_FUNCTION_TRACE (DsCreateBufferField);
286
287
288    /*
289     * Get the NameString argument (name of the new BufferField)
290     */
291    if (Op->Common.AmlOpcode == AML_CREATE_FIELD_OP)
292    {
293        /* For CreateField, name is the 4th argument */
294
295        Arg = AcpiPsGetArg (Op, 3);
296    }
297    else
298    {
299        /* For all other CreateXXXField operators, name is the 3rd argument */
300
301        Arg = AcpiPsGetArg (Op, 2);
302    }
303
304    if (!Arg)
305    {
306        return_ACPI_STATUS (AE_AML_NO_OPERAND);
307    }
308
309    if (WalkState->DeferredNode)
310    {
311        Node = WalkState->DeferredNode;
312    }
313    else
314    {
315        /* Execute flag should always be set when this function is entered */
316
317        if (!(WalkState->ParseFlags & ACPI_PARSE_EXECUTE))
318        {
319            ACPI_ERROR ((AE_INFO,
320                "Parse execute mode is not set"));
321            return_ACPI_STATUS (AE_AML_INTERNAL);
322        }
323
324        /* Creating new namespace node, should not already exist */
325
326        Flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
327            ACPI_NS_ERROR_IF_FOUND;
328
329        /*
330         * Mark node temporary if we are executing a normal control
331         * method. (Don't mark if this is a module-level code method)
332         */
333        if (WalkState->MethodNode &&
334            !(WalkState->ParseFlags & ACPI_PARSE_MODULE_LEVEL))
335        {
336            Flags |= ACPI_NS_TEMPORARY;
337        }
338
339        /* Enter the NameString into the namespace */
340
341        Status = AcpiNsLookup (WalkState->ScopeInfo,
342            Arg->Common.Value.String, ACPI_TYPE_ANY,
343            ACPI_IMODE_LOAD_PASS1, Flags, WalkState, &Node);
344        if ((WalkState->ParseFlags & ACPI_PARSE_DISASSEMBLE) &&
345            Status == AE_ALREADY_EXISTS)
346        {
347            Status = AE_OK;
348        }
349        else if (ACPI_FAILURE (Status))
350        {
351            ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo,
352                Arg->Common.Value.String, Status);
353            return_ACPI_STATUS (Status);
354        }
355    }
356
357    /*
358     * We could put the returned object (Node) on the object stack for later,
359     * but for now, we will put it in the "op" object that the parser uses,
360     * so we can get it again at the end of this scope.
361     */
362    Op->Common.Node = Node;
363
364    /*
365     * If there is no object attached to the node, this node was just created
366     * and we need to create the field object. Otherwise, this was a lookup
367     * of an existing node and we don't want to create the field object again.
368     */
369    ObjDesc = AcpiNsGetAttachedObject (Node);
370    if (ObjDesc)
371    {
372        return_ACPI_STATUS (AE_OK);
373    }
374
375    /*
376     * The Field definition is not fully parsed at this time.
377     * (We must save the address of the AML for the buffer and index operands)
378     */
379
380    /* Create the buffer field object */
381
382    ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_BUFFER_FIELD);
383    if (!ObjDesc)
384    {
385        Status = AE_NO_MEMORY;
386        goto Cleanup;
387    }
388
389    /*
390     * Remember location in AML stream of the field unit opcode and operands
391     * -- since the buffer and index operands must be evaluated.
392     */
393    SecondDesc = ObjDesc->Common.NextObject;
394    SecondDesc->Extra.AmlStart = Op->Named.Data;
395    SecondDesc->Extra.AmlLength = Op->Named.Length;
396    ObjDesc->BufferField.Node = Node;
397
398    /* Attach constructed field descriptors to parent node */
399
400    Status = AcpiNsAttachObject (Node, ObjDesc, ACPI_TYPE_BUFFER_FIELD);
401    if (ACPI_FAILURE (Status))
402    {
403        goto Cleanup;
404    }
405
406
407Cleanup:
408
409    /* Remove local reference to the object */
410
411    AcpiUtRemoveReference (ObjDesc);
412    return_ACPI_STATUS (Status);
413}
414
415
416/*******************************************************************************
417 *
418 * FUNCTION:    AcpiDsGetFieldNames
419 *
420 * PARAMETERS:  Info            - CreateField info structure
421 *              WalkState       - Current method state
422 *              Arg             - First parser arg for the field name list
423 *
424 * RETURN:      Status
425 *
426 * DESCRIPTION: Process all named fields in a field declaration. Names are
427 *              entered into the namespace.
428 *
429 ******************************************************************************/
430
431static ACPI_STATUS
432AcpiDsGetFieldNames (
433    ACPI_CREATE_FIELD_INFO  *Info,
434    ACPI_WALK_STATE         *WalkState,
435    ACPI_PARSE_OBJECT       *Arg)
436{
437    ACPI_STATUS             Status;
438    UINT64                  Position;
439    ACPI_PARSE_OBJECT       *Child;
440
441#ifdef ACPI_EXEC_APP
442    ACPI_OPERAND_OBJECT     *ResultDesc;
443    ACPI_OPERAND_OBJECT     *ObjDesc;
444    char                    *NamePath;
445#endif
446
447
448    ACPI_FUNCTION_TRACE_PTR (DsGetFieldNames, Info);
449
450
451    /* First field starts at bit zero */
452
453    Info->FieldBitPosition = 0;
454
455    /* Process all elements in the field list (of parse nodes) */
456
457    while (Arg)
458    {
459        /*
460         * Four types of field elements are handled:
461         * 1) Name - Enters a new named field into the namespace
462         * 2) Offset - specifies a bit offset
463         * 3) AccessAs - changes the access mode/attributes
464         * 4) Connection - Associate a resource template with the field
465         */
466        switch (Arg->Common.AmlOpcode)
467        {
468        case AML_INT_RESERVEDFIELD_OP:
469
470            Position = (UINT64) Info->FieldBitPosition +
471                (UINT64) Arg->Common.Value.Size;
472
473            if (Position > ACPI_UINT32_MAX)
474            {
475                ACPI_ERROR ((AE_INFO,
476                    "Bit offset within field too large (> 0xFFFFFFFF)"));
477                return_ACPI_STATUS (AE_SUPPORT);
478            }
479
480            Info->FieldBitPosition = (UINT32) Position;
481            break;
482
483        case AML_INT_ACCESSFIELD_OP:
484        case AML_INT_EXTACCESSFIELD_OP:
485            /*
486             * Get new AccessType, AccessAttribute, and AccessLength fields
487             * -- to be used for all field units that follow, until the
488             * end-of-field or another AccessAs keyword is encountered.
489             * NOTE. These three bytes are encoded in the integer value
490             * of the parseop for convenience.
491             *
492             * In FieldFlags, preserve the flag bits other than the
493             * ACCESS_TYPE bits.
494             */
495
496            /* AccessType (ByteAcc, WordAcc, etc.) */
497
498            Info->FieldFlags = (UINT8)
499                ((Info->FieldFlags & ~(AML_FIELD_ACCESS_TYPE_MASK)) |
500                ((UINT8) ((UINT32) (Arg->Common.Value.Integer & 0x07))));
501
502            /* AccessAttribute (AttribQuick, AttribByte, etc.) */
503
504            Info->Attribute = (UINT8)
505                ((Arg->Common.Value.Integer >> 8) & 0xFF);
506
507            /* AccessLength (for serial/buffer protocols) */
508
509            Info->AccessLength = (UINT8)
510                ((Arg->Common.Value.Integer >> 16) & 0xFF);
511            break;
512
513        case AML_INT_CONNECTION_OP:
514            /*
515             * Clear any previous connection. New connection is used for all
516             * fields that follow, similar to AccessAs
517             */
518            Info->ResourceBuffer = NULL;
519            Info->ConnectionNode = NULL;
520            Info->PinNumberIndex = 0;
521
522            /*
523             * A Connection() is either an actual resource descriptor (buffer)
524             * or a named reference to a resource template
525             */
526            Child = Arg->Common.Value.Arg;
527            if (Child->Common.AmlOpcode == AML_INT_BYTELIST_OP)
528            {
529                Info->ResourceBuffer = Child->Named.Data;
530                Info->ResourceLength = (UINT16) Child->Named.Value.Integer;
531            }
532            else
533            {
534                /* Lookup the Connection() namepath, it should already exist */
535
536                Status = AcpiNsLookup (WalkState->ScopeInfo,
537                    Child->Common.Value.Name, ACPI_TYPE_ANY,
538                    ACPI_IMODE_EXECUTE, ACPI_NS_DONT_OPEN_SCOPE,
539                    WalkState, &Info->ConnectionNode);
540                if (ACPI_FAILURE (Status))
541                {
542                    ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo,
543                        Child->Common.Value.Name, Status);
544                    return_ACPI_STATUS (Status);
545                }
546            }
547            break;
548
549        case AML_INT_NAMEDFIELD_OP:
550
551            /* Lookup the name, it should already exist */
552
553            Status = AcpiNsLookup (WalkState->ScopeInfo,
554                (char *) &Arg->Named.Name, Info->FieldType,
555                ACPI_IMODE_EXECUTE, ACPI_NS_DONT_OPEN_SCOPE,
556                WalkState, &Info->FieldNode);
557            if (ACPI_FAILURE (Status))
558            {
559                ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo,
560                    (char *) &Arg->Named.Name, Status);
561                return_ACPI_STATUS (Status);
562            }
563            else
564            {
565                Arg->Common.Node = Info->FieldNode;
566                Info->FieldBitLength = Arg->Common.Value.Size;
567
568                /*
569                 * If there is no object attached to the node, this node was
570                 * just created and we need to create the field object.
571                 * Otherwise, this was a lookup of an existing node and we
572                 * don't want to create the field object again.
573                 */
574                if (!AcpiNsGetAttachedObject (Info->FieldNode))
575                {
576                    Status = AcpiExPrepFieldValue (Info);
577                    if (ACPI_FAILURE (Status))
578                    {
579                        return_ACPI_STATUS (Status);
580                    }
581#ifdef ACPI_EXEC_APP
582                    NamePath = AcpiNsGetExternalPathname (Info->FieldNode);
583                    if (ACPI_SUCCESS (AeLookupInitFileEntry (NamePath, &ObjDesc)))
584                    {
585                        AcpiExWriteDataToField (ObjDesc,
586                            AcpiNsGetAttachedObject (Info->FieldNode),
587                            &ResultDesc);
588                        AcpiUtRemoveReference (ObjDesc);
589                    }
590                    ACPI_FREE (NamePath);
591#endif
592                }
593            }
594
595            /* Keep track of bit position for the next field */
596
597            Position = (UINT64) Info->FieldBitPosition +
598                (UINT64) Arg->Common.Value.Size;
599
600            if (Position > ACPI_UINT32_MAX)
601            {
602                ACPI_ERROR ((AE_INFO,
603                    "Field [%4.4s] bit offset too large (> 0xFFFFFFFF)",
604                    ACPI_CAST_PTR (char, &Info->FieldNode->Name)));
605                return_ACPI_STATUS (AE_SUPPORT);
606            }
607
608            Info->FieldBitPosition += Info->FieldBitLength;
609            Info->PinNumberIndex++; /* Index relative to previous Connection() */
610            break;
611
612        default:
613
614            ACPI_ERROR ((AE_INFO,
615                "Invalid opcode in field list: 0x%X",
616                Arg->Common.AmlOpcode));
617            return_ACPI_STATUS (AE_AML_BAD_OPCODE);
618        }
619
620        Arg = Arg->Common.Next;
621    }
622
623    return_ACPI_STATUS (AE_OK);
624}
625
626
627/*******************************************************************************
628 *
629 * FUNCTION:    AcpiDsCreateField
630 *
631 * PARAMETERS:  Op              - Op containing the Field definition and args
632 *              RegionNode      - Object for the containing Operation Region
633 *  `           WalkState       - Current method state
634 *
635 * RETURN:      Status
636 *
637 * DESCRIPTION: Create a new field in the specified operation region
638 *
639 ******************************************************************************/
640
641ACPI_STATUS
642AcpiDsCreateField (
643    ACPI_PARSE_OBJECT       *Op,
644    ACPI_NAMESPACE_NODE     *RegionNode,
645    ACPI_WALK_STATE         *WalkState)
646{
647    ACPI_STATUS             Status;
648    ACPI_PARSE_OBJECT       *Arg;
649    ACPI_CREATE_FIELD_INFO  Info;
650
651
652    ACPI_FUNCTION_TRACE_PTR (DsCreateField, Op);
653
654
655    /* First arg is the name of the parent OpRegion (must already exist) */
656
657    Arg = Op->Common.Value.Arg;
658
659    if (!RegionNode)
660    {
661        Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.Name,
662            ACPI_TYPE_REGION, ACPI_IMODE_EXECUTE,
663            ACPI_NS_SEARCH_PARENT, WalkState, &RegionNode);
664#ifdef ACPI_ASL_COMPILER
665        Status = AcpiDsCreateExternalRegion (Status, Arg,
666            Arg->Common.Value.Name, WalkState, &RegionNode);
667#endif
668        if (ACPI_FAILURE (Status))
669        {
670            ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo,
671                Arg->Common.Value.Name, Status);
672            return_ACPI_STATUS (Status);
673        }
674    }
675
676    memset (&Info, 0, sizeof (ACPI_CREATE_FIELD_INFO));
677
678    /* Second arg is the field flags */
679
680    Arg = Arg->Common.Next;
681    Info.FieldFlags = (UINT8) Arg->Common.Value.Integer;
682    Info.Attribute = 0;
683
684    /* Each remaining arg is a Named Field */
685
686    Info.FieldType = ACPI_TYPE_LOCAL_REGION_FIELD;
687    Info.RegionNode = RegionNode;
688
689    Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Common.Next);
690    if (ACPI_FAILURE (Status))
691    {
692        return_ACPI_STATUS (Status);
693    }
694
695    if (Info.RegionNode->Object->Region.SpaceId == ACPI_ADR_SPACE_PLATFORM_COMM)
696    {
697        RegionNode->Object->Field.InternalPccBuffer =
698            ACPI_ALLOCATE_ZEROED(Info.RegionNode->Object->Region.Length);
699        if (!RegionNode->Object->Field.InternalPccBuffer)
700        {
701            return_ACPI_STATUS (AE_NO_MEMORY);
702        }
703    }
704
705    return_ACPI_STATUS (Status);
706}
707
708
709/*******************************************************************************
710 *
711 * FUNCTION:    AcpiDsInitFieldObjects
712 *
713 * PARAMETERS:  Op              - Op containing the Field definition and args
714 *  `           WalkState       - Current method state
715 *
716 * RETURN:      Status
717 *
718 * DESCRIPTION: For each "Field Unit" name in the argument list that is
719 *              part of the field declaration, enter the name into the
720 *              namespace.
721 *
722 ******************************************************************************/
723
724ACPI_STATUS
725AcpiDsInitFieldObjects (
726    ACPI_PARSE_OBJECT       *Op,
727    ACPI_WALK_STATE         *WalkState)
728{
729    ACPI_STATUS             Status;
730    ACPI_PARSE_OBJECT       *Arg = NULL;
731    ACPI_NAMESPACE_NODE     *Node;
732    UINT8                   Type = 0;
733    UINT32                  Flags;
734
735
736    ACPI_FUNCTION_TRACE_PTR (DsInitFieldObjects, Op);
737
738
739    /* Execute flag should always be set when this function is entered */
740
741    if (!(WalkState->ParseFlags & ACPI_PARSE_EXECUTE))
742    {
743        if (WalkState->ParseFlags & ACPI_PARSE_DEFERRED_OP)
744        {
745            /* BankField Op is deferred, just return OK */
746
747            return_ACPI_STATUS (AE_OK);
748        }
749
750        ACPI_ERROR ((AE_INFO,
751            "Parse deferred mode is not set"));
752        return_ACPI_STATUS (AE_AML_INTERNAL);
753    }
754
755    /*
756     * Get the FieldList argument for this opcode. This is the start of the
757     * list of field elements.
758     */
759    switch (WalkState->Opcode)
760    {
761    case AML_FIELD_OP:
762
763        Arg = AcpiPsGetArg (Op, 2);
764        Type = ACPI_TYPE_LOCAL_REGION_FIELD;
765        break;
766
767    case AML_BANK_FIELD_OP:
768
769        Arg = AcpiPsGetArg (Op, 4);
770        Type = ACPI_TYPE_LOCAL_BANK_FIELD;
771        break;
772
773    case AML_INDEX_FIELD_OP:
774
775        Arg = AcpiPsGetArg (Op, 3);
776        Type = ACPI_TYPE_LOCAL_INDEX_FIELD;
777        break;
778
779    default:
780
781        return_ACPI_STATUS (AE_BAD_PARAMETER);
782    }
783
784    /* Creating new namespace node(s), should not already exist */
785
786    Flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
787        ACPI_NS_ERROR_IF_FOUND;
788
789    /*
790     * Mark node(s) temporary if we are executing a normal control
791     * method. (Don't mark if this is a module-level code method)
792     */
793    if (WalkState->MethodNode &&
794        !(WalkState->ParseFlags & ACPI_PARSE_MODULE_LEVEL))
795    {
796        Flags |= ACPI_NS_TEMPORARY;
797    }
798
799#ifdef ACPI_EXEC_APP
800    Flags |= ACPI_NS_OVERRIDE_IF_FOUND;
801#endif
802    /*
803     * Walk the list of entries in the FieldList
804     * Note: FieldList can be of zero length. In this case, Arg will be NULL.
805     */
806    while (Arg)
807    {
808        /*
809         * Ignore OFFSET/ACCESSAS/CONNECTION terms here; we are only interested
810         * in the field names in order to enter them into the namespace.
811         */
812        if (Arg->Common.AmlOpcode == AML_INT_NAMEDFIELD_OP)
813        {
814            Status = AcpiNsLookup (WalkState->ScopeInfo,
815                (char *) &Arg->Named.Name, Type, ACPI_IMODE_LOAD_PASS1,
816                Flags, WalkState, &Node);
817            if (ACPI_FAILURE (Status))
818            {
819                ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo,
820                    (char *) &Arg->Named.Name, Status);
821                if (Status != AE_ALREADY_EXISTS)
822                {
823                    return_ACPI_STATUS (Status);
824                }
825
826                /* Name already exists, just ignore this error */
827            }
828
829            Arg->Common.Node = Node;
830        }
831
832        /* Get the next field element in the list */
833
834        Arg = Arg->Common.Next;
835    }
836
837    return_ACPI_STATUS (AE_OK);
838}
839
840
841/*******************************************************************************
842 *
843 * FUNCTION:    AcpiDsCreateBankField
844 *
845 * PARAMETERS:  Op              - Op containing the Field definition and args
846 *              RegionNode      - Object for the containing Operation Region
847 *              WalkState       - Current method state
848 *
849 * RETURN:      Status
850 *
851 * DESCRIPTION: Create a new bank field in the specified operation region
852 *
853 ******************************************************************************/
854
855ACPI_STATUS
856AcpiDsCreateBankField (
857    ACPI_PARSE_OBJECT       *Op,
858    ACPI_NAMESPACE_NODE     *RegionNode,
859    ACPI_WALK_STATE         *WalkState)
860{
861    ACPI_STATUS             Status;
862    ACPI_PARSE_OBJECT       *Arg;
863    ACPI_CREATE_FIELD_INFO  Info;
864
865
866    ACPI_FUNCTION_TRACE_PTR (DsCreateBankField, Op);
867
868
869    /* First arg is the name of the parent OpRegion (must already exist) */
870
871    Arg = Op->Common.Value.Arg;
872    if (!RegionNode)
873    {
874        Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.Name,
875            ACPI_TYPE_REGION, ACPI_IMODE_EXECUTE,
876            ACPI_NS_SEARCH_PARENT, WalkState, &RegionNode);
877#ifdef ACPI_ASL_COMPILER
878        Status = AcpiDsCreateExternalRegion (Status, Arg,
879            Arg->Common.Value.Name, WalkState, &RegionNode);
880#endif
881        if (ACPI_FAILURE (Status))
882        {
883            ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo,
884                Arg->Common.Value.Name, Status);
885            return_ACPI_STATUS (Status);
886        }
887    }
888
889    /* Second arg is the Bank Register (Field) (must already exist) */
890
891    Arg = Arg->Common.Next;
892    Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String,
893        ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
894        ACPI_NS_SEARCH_PARENT, WalkState, &Info.RegisterNode);
895    if (ACPI_FAILURE (Status))
896    {
897        ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo,
898            Arg->Common.Value.String, Status);
899        return_ACPI_STATUS (Status);
900    }
901
902    /*
903     * Third arg is the BankValue
904     * This arg is a TermArg, not a constant
905     * It will be evaluated later, by AcpiDsEvalBankFieldOperands
906     */
907    Arg = Arg->Common.Next;
908
909    /* Fourth arg is the field flags */
910
911    Arg = Arg->Common.Next;
912    Info.FieldFlags = (UINT8) Arg->Common.Value.Integer;
913
914    /* Each remaining arg is a Named Field */
915
916    Info.FieldType = ACPI_TYPE_LOCAL_BANK_FIELD;
917    Info.RegionNode = RegionNode;
918
919    /*
920     * Use Info.DataRegisterNode to store BankField Op
921     * It's safe because DataRegisterNode will never be used when create
922     * bank field \we store AmlStart and AmlLength in the BankField Op for
923     * late evaluation. Used in AcpiExPrepFieldValue(Info)
924     *
925     * TBD: Or, should we add a field in ACPI_CREATE_FIELD_INFO, like
926     * "void *ParentOp"?
927     */
928    Info.DataRegisterNode = (ACPI_NAMESPACE_NODE*) Op;
929
930    Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Common.Next);
931    return_ACPI_STATUS (Status);
932}
933
934
935/*******************************************************************************
936 *
937 * FUNCTION:    AcpiDsCreateIndexField
938 *
939 * PARAMETERS:  Op              - Op containing the Field definition and args
940 *              RegionNode      - Object for the containing Operation Region
941 *  `           WalkState       - Current method state
942 *
943 * RETURN:      Status
944 *
945 * DESCRIPTION: Create a new index field in the specified operation region
946 *
947 ******************************************************************************/
948
949ACPI_STATUS
950AcpiDsCreateIndexField (
951    ACPI_PARSE_OBJECT       *Op,
952    ACPI_NAMESPACE_NODE     *RegionNode,
953    ACPI_WALK_STATE         *WalkState)
954{
955    ACPI_STATUS             Status;
956    ACPI_PARSE_OBJECT       *Arg;
957    ACPI_CREATE_FIELD_INFO  Info;
958
959
960    ACPI_FUNCTION_TRACE_PTR (DsCreateIndexField, Op);
961
962
963    /* First arg is the name of the Index register (must already exist) */
964
965    Arg = Op->Common.Value.Arg;
966    Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String,
967        ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
968        ACPI_NS_SEARCH_PARENT, WalkState, &Info.RegisterNode);
969    if (ACPI_FAILURE (Status))
970    {
971        ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo,
972            Arg->Common.Value.String, Status);
973        return_ACPI_STATUS (Status);
974    }
975
976    /* Second arg is the data register (must already exist) */
977
978    Arg = Arg->Common.Next;
979    Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String,
980        ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
981        ACPI_NS_SEARCH_PARENT, WalkState, &Info.DataRegisterNode);
982    if (ACPI_FAILURE (Status))
983    {
984        ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo,
985            Arg->Common.Value.String, Status);
986        return_ACPI_STATUS (Status);
987    }
988
989    /* Next arg is the field flags */
990
991    Arg = Arg->Common.Next;
992    Info.FieldFlags = (UINT8) Arg->Common.Value.Integer;
993
994    /* Each remaining arg is a Named Field */
995
996    Info.FieldType = ACPI_TYPE_LOCAL_INDEX_FIELD;
997    Info.RegionNode = RegionNode;
998
999    Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Common.Next);
1000    return_ACPI_STATUS (Status);
1001}
1002