1119895Sanholt/******************************************************************************
2152909Sanholt *
3152909Sanholt * Module Name: dsopcode - Dispatcher support for regions and fields
4119895Sanholt *
5119895Sanholt *****************************************************************************/
6119895Sanholt
7119895Sanholt/*
8119895Sanholt * Copyright (C) 2000 - 2013, Intel Corp.
9119895Sanholt * All rights reserved.
10119895Sanholt *
11119895Sanholt * Redistribution and use in source and binary forms, with or without
12119895Sanholt * modification, are permitted provided that the following conditions
13145132Sanholt * are met:
14119895Sanholt * 1. Redistributions of source code must retain the above copyright
15119895Sanholt *    notice, this list of conditions, and the following disclaimer,
16119895Sanholt *    without modification.
17145132Sanholt * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18119895Sanholt *    substantially similar to the "NO WARRANTY" disclaimer below
19119895Sanholt *    ("Disclaimer") and any redistribution must be conditioned upon
20119895Sanholt *    including a substantially similar Disclaimer requirement for further
21119895Sanholt *    binary redistribution.
22119895Sanholt * 3. Neither the names of the above-listed copyright holders nor the names
23119895Sanholt *    of any contributors may be used to endorse or promote products derived
24119895Sanholt *    from this software without specific prior written permission.
25145132Sanholt *
26119895Sanholt * Alternatively, this software may be distributed under the terms of the
27119895Sanholt * GNU General Public License ("GPL") version 2 as published by the Free
28145132Sanholt * Software Foundation.
29119895Sanholt *
30119895Sanholt * NO WARRANTY
31152909Sanholt * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32152909Sanholt * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33152909Sanholt * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34119895Sanholt * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35130331Sanholt * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36130331Sanholt * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37130331Sanholt * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38119895Sanholt * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39119895Sanholt * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40130331Sanholt * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41145132Sanholt * POSSIBILITY OF SUCH DAMAGES.
42145132Sanholt */
43145132Sanholt
44145132Sanholt#define __DSOPCODE_C__
45119895Sanholt
46119895Sanholt#include <contrib/dev/acpica/include/acpi.h>
47145132Sanholt#include <contrib/dev/acpica/include/accommon.h>
48119895Sanholt#include <contrib/dev/acpica/include/acparser.h>
49119895Sanholt#include <contrib/dev/acpica/include/amlcode.h>
50119895Sanholt#include <contrib/dev/acpica/include/acdispat.h>
51119895Sanholt#include <contrib/dev/acpica/include/acinterp.h>
52119895Sanholt#include <contrib/dev/acpica/include/acnamesp.h>
53145132Sanholt#include <contrib/dev/acpica/include/acevents.h>
54119895Sanholt#include <contrib/dev/acpica/include/actables.h>
55119895Sanholt
56119895Sanholt#define _COMPONENT          ACPI_DISPATCHER
57119895Sanholt        ACPI_MODULE_NAME    ("dsopcode")
58119895Sanholt
59119895Sanholt/* Local prototypes */
60119895Sanholt
61145132Sanholtstatic ACPI_STATUS
62119895SanholtAcpiDsInitBufferField (
63145132Sanholt    UINT16                  AmlOpcode,
64119895Sanholt    ACPI_OPERAND_OBJECT     *ObjDesc,
65119895Sanholt    ACPI_OPERAND_OBJECT     *BufferDesc,
66119895Sanholt    ACPI_OPERAND_OBJECT     *OffsetDesc,
67119895Sanholt    ACPI_OPERAND_OBJECT     *LengthDesc,
68119895Sanholt    ACPI_OPERAND_OBJECT     *ResultDesc);
69119895Sanholt
70119895Sanholt
71119895Sanholt/*******************************************************************************
72145132Sanholt *
73119895Sanholt * FUNCTION:    AcpiDsInitializeRegion
74119895Sanholt *
75119895Sanholt * PARAMETERS:  ObjHandle       - Region namespace node
76145132Sanholt *
77119895Sanholt * RETURN:      Status
78119895Sanholt *
79119895Sanholt * DESCRIPTION: Front end to EvInitializeRegion
80119895Sanholt *
81119895Sanholt ******************************************************************************/
82119895Sanholt
83119895SanholtACPI_STATUS
84145132SanholtAcpiDsInitializeRegion (
85119895Sanholt    ACPI_HANDLE             ObjHandle)
86119895Sanholt{
87182080Srnoland    ACPI_OPERAND_OBJECT     *ObjDesc;
88119895Sanholt    ACPI_STATUS             Status;
89119895Sanholt
90119895Sanholt
91119895Sanholt    ObjDesc = AcpiNsGetAttachedObject (ObjHandle);
92182080Srnoland
93119895Sanholt    /* Namespace is NOT locked */
94182080Srnoland
95119895Sanholt    Status = AcpiEvInitializeRegion (ObjDesc, FALSE);
96119895Sanholt    return (Status);
97119895Sanholt}
98182080Srnoland
99119895Sanholt
100119895Sanholt/*******************************************************************************
101119895Sanholt *
102182080Srnoland * FUNCTION:    AcpiDsInitBufferField
103182080Srnoland *
104182080Srnoland * PARAMETERS:  AmlOpcode       - CreateXxxField
105119895Sanholt *              ObjDesc         - BufferField object
106119895Sanholt *              BufferDesc      - Host Buffer
107182080Srnoland *              OffsetDesc      - Offset into buffer
108119895Sanholt *              LengthDesc      - Length of field (CREATE_FIELD_OP only)
109145132Sanholt *              ResultDesc      - Where to store the result
110182080Srnoland *
111182080Srnoland * RETURN:      Status
112182080Srnoland *
113119895Sanholt * DESCRIPTION: Perform actual initialization of a buffer field
114119895Sanholt *
115182080Srnoland ******************************************************************************/
116119895Sanholt
117119895Sanholtstatic ACPI_STATUS
118119895SanholtAcpiDsInitBufferField (
119119895Sanholt    UINT16                  AmlOpcode,
120182080Srnoland    ACPI_OPERAND_OBJECT     *ObjDesc,
121119895Sanholt    ACPI_OPERAND_OBJECT     *BufferDesc,
122119895Sanholt    ACPI_OPERAND_OBJECT     *OffsetDesc,
123119895Sanholt    ACPI_OPERAND_OBJECT     *LengthDesc,
124119895Sanholt    ACPI_OPERAND_OBJECT     *ResultDesc)
125182080Srnoland{
126182080Srnoland    UINT32                  Offset;
127119895Sanholt    UINT32                  BitOffset;
128182080Srnoland    UINT32                  BitCount;
129182080Srnoland    UINT8                   FieldFlags;
130182080Srnoland    ACPI_STATUS             Status;
131119895Sanholt
132182080Srnoland
133119895Sanholt    ACPI_FUNCTION_TRACE_PTR (DsInitBufferField, ObjDesc);
134119895Sanholt
135119895Sanholt
136119895Sanholt    /* Host object must be a Buffer */
137119895Sanholt
138119895Sanholt    if (BufferDesc->Common.Type != ACPI_TYPE_BUFFER)
139119895Sanholt    {
140119895Sanholt        ACPI_ERROR ((AE_INFO,
141119895Sanholt            "Target of Create Field is not a Buffer object - %s",
142119895Sanholt            AcpiUtGetObjectTypeName (BufferDesc)));
143119895Sanholt
144119895Sanholt        Status = AE_AML_OPERAND_TYPE;
145119895Sanholt        goto Cleanup;
146119895Sanholt    }
147119895Sanholt
148119895Sanholt    /*
149182080Srnoland     * The last parameter to all of these opcodes (ResultDesc) started
150119895Sanholt     * out as a NameString, and should therefore now be a NS node
151119895Sanholt     * after resolution in AcpiExResolveOperands().
152182080Srnoland     */
153119895Sanholt    if (ACPI_GET_DESCRIPTOR_TYPE (ResultDesc) != ACPI_DESC_TYPE_NAMED)
154119895Sanholt    {
155145132Sanholt        ACPI_ERROR ((AE_INFO,
156145132Sanholt            "(%s) destination not a NS Node [%s]",
157119895Sanholt            AcpiPsGetOpcodeName (AmlOpcode),
158119895Sanholt            AcpiUtGetDescriptorName (ResultDesc)));
159119895Sanholt
160119895Sanholt        Status = AE_AML_OPERAND_TYPE;
161119895Sanholt        goto Cleanup;
162119895Sanholt    }
163182080Srnoland
164119895Sanholt    Offset = (UINT32) OffsetDesc->Integer.Value;
165182080Srnoland
166119895Sanholt    /*
167182080Srnoland     * Setup the Bit offsets and counts, according to the opcode
168119895Sanholt     */
169119895Sanholt    switch (AmlOpcode)
170119895Sanholt    {
171119895Sanholt    case AML_CREATE_FIELD_OP:
172182080Srnoland
173119895Sanholt        /* Offset is in bits, count is in bits */
174119895Sanholt
175182080Srnoland        FieldFlags = AML_FIELD_ACCESS_BYTE;
176119895Sanholt        BitOffset  = Offset;
177119895Sanholt        BitCount   = (UINT32) LengthDesc->Integer.Value;
178119895Sanholt
179119895Sanholt        /* Must have a valid (>0) bit count */
180182080Srnoland
181145132Sanholt        if (BitCount == 0)
182182080Srnoland        {
183119895Sanholt            ACPI_ERROR ((AE_INFO,
184119895Sanholt                "Attempt to CreateField of length zero"));
185182080Srnoland            Status = AE_AML_OPERAND_VALUE;
186182080Srnoland            goto Cleanup;
187182080Srnoland        }
188119895Sanholt        break;
189182080Srnoland
190182080Srnoland    case AML_CREATE_BIT_FIELD_OP:
191119895Sanholt
192119895Sanholt        /* Offset is in bits, Field is one bit */
193182080Srnoland
194182080Srnoland        BitOffset  = Offset;
195182080Srnoland        BitCount   = 1;
196119895Sanholt        FieldFlags = AML_FIELD_ACCESS_BYTE;
197119895Sanholt        break;
198182080Srnoland
199119895Sanholt    case AML_CREATE_BYTE_FIELD_OP:
200119895Sanholt
201119895Sanholt        /* Offset is in bytes, field is one byte */
202119895Sanholt
203182080Srnoland        BitOffset  = 8 * Offset;
204119895Sanholt        BitCount   = 8;
205119895Sanholt        FieldFlags = AML_FIELD_ACCESS_BYTE;
206182080Srnoland        break;
207119895Sanholt
208119895Sanholt    case AML_CREATE_WORD_FIELD_OP:
209182080Srnoland
210119895Sanholt        /* Offset is in bytes, field is one word */
211182080Srnoland
212182080Srnoland        BitOffset  = 8 * Offset;
213119895Sanholt        BitCount   = 16;
214182080Srnoland        FieldFlags = AML_FIELD_ACCESS_WORD;
215182080Srnoland        break;
216182080Srnoland
217119895Sanholt    case AML_CREATE_DWORD_FIELD_OP:
218182080Srnoland
219119895Sanholt        /* Offset is in bytes, field is one dword */
220119895Sanholt
221119895Sanholt        BitOffset  = 8 * Offset;
222119895Sanholt        BitCount   = 32;
223119895Sanholt        FieldFlags = AML_FIELD_ACCESS_DWORD;
224119895Sanholt        break;
225145132Sanholt
226119895Sanholt    case AML_CREATE_QWORD_FIELD_OP:
227182080Srnoland
228119895Sanholt        /* Offset is in bytes, field is one qword */
229119895Sanholt
230182080Srnoland        BitOffset  = 8 * Offset;
231119895Sanholt        BitCount   = 64;
232119895Sanholt        FieldFlags = AML_FIELD_ACCESS_QWORD;
233145132Sanholt        break;
234145132Sanholt
235119895Sanholt    default:
236119895Sanholt
237119895Sanholt        ACPI_ERROR ((AE_INFO,
238119895Sanholt            "Unknown field creation opcode 0x%02X",
239119895Sanholt            AmlOpcode));
240119895Sanholt        Status = AE_AML_BAD_OPCODE;
241182080Srnoland        goto Cleanup;
242119895Sanholt    }
243182080Srnoland
244119895Sanholt    /* Entire field must fit within the current length of the buffer */
245182080Srnoland
246119895Sanholt    if ((BitOffset + BitCount) >
247119895Sanholt        (8 * (UINT32) BufferDesc->Buffer.Length))
248119895Sanholt    {
249119895Sanholt        ACPI_ERROR ((AE_INFO,
250182080Srnoland            "Field [%4.4s] at %u exceeds Buffer [%4.4s] size %u (bits)",
251119895Sanholt            AcpiUtGetNodeName (ResultDesc),
252119895Sanholt            BitOffset + BitCount,
253182080Srnoland            AcpiUtGetNodeName (BufferDesc->Buffer.Node),
254119895Sanholt            8 * (UINT32) BufferDesc->Buffer.Length));
255119895Sanholt        Status = AE_AML_BUFFER_LIMIT;
256145132Sanholt        goto Cleanup;
257119895Sanholt    }
258182080Srnoland
259145132Sanholt    /*
260182080Srnoland     * Initialize areas of the field object that are common to all fields
261119895Sanholt     * For FieldFlags, use LOCK_RULE = 0 (NO_LOCK),
262119895Sanholt     * UPDATE_RULE = 0 (UPDATE_PRESERVE)
263182080Srnoland     */
264182080Srnoland    Status = AcpiExPrepCommonFieldObject (ObjDesc, FieldFlags, 0,
265182080Srnoland                                            BitOffset, BitCount);
266119895Sanholt    if (ACPI_FAILURE (Status))
267182080Srnoland    {
268119895Sanholt        goto Cleanup;
269119895Sanholt    }
270145132Sanholt
271182080Srnoland    ObjDesc->BufferField.BufferObj = BufferDesc;
272182080Srnoland
273182080Srnoland    /* Reference count for BufferDesc inherits ObjDesc count */
274119895Sanholt
275119895Sanholt    BufferDesc->Common.ReferenceCount = (UINT16)
276182080Srnoland        (BufferDesc->Common.ReferenceCount + ObjDesc->Common.ReferenceCount);
277182080Srnoland
278119895Sanholt
279119895SanholtCleanup:
280119895Sanholt
281119895Sanholt    /* Always delete the operands */
282182080Srnoland
283119895Sanholt    AcpiUtRemoveReference (OffsetDesc);
284119895Sanholt    AcpiUtRemoveReference (BufferDesc);
285182080Srnoland
286119895Sanholt    if (AmlOpcode == AML_CREATE_FIELD_OP)
287119895Sanholt    {
288182080Srnoland        AcpiUtRemoveReference (LengthDesc);
289119895Sanholt    }
290182080Srnoland
291182080Srnoland    /* On failure, delete the result descriptor */
292119895Sanholt
293182080Srnoland    if (ACPI_FAILURE (Status))
294182080Srnoland    {
295182080Srnoland        AcpiUtRemoveReference (ResultDesc);     /* Result descriptor */
296119895Sanholt    }
297182080Srnoland    else
298119895Sanholt    {
299119895Sanholt        /* Now the address and length are valid for this BufferField */
300119895Sanholt
301119895Sanholt        ObjDesc->BufferField.Flags |= AOPOBJ_DATA_VALID;
302145132Sanholt    }
303119895Sanholt
304119895Sanholt    return_ACPI_STATUS (Status);
305119895Sanholt}
306145132Sanholt
307119895Sanholt
308119895Sanholt/*******************************************************************************
309119895Sanholt *
310119895Sanholt * FUNCTION:    AcpiDsEvalBufferFieldOperands
311119895Sanholt *
312119895Sanholt * PARAMETERS:  WalkState       - Current walk
313145132Sanholt *              Op              - A valid BufferField Op object
314119895Sanholt *
315119895Sanholt * RETURN:      Status
316119895Sanholt *
317119895Sanholt * DESCRIPTION: Get BufferField Buffer and Index
318119895Sanholt *              Called from AcpiDsExecEndOp during BufferField parse tree walk
319119895Sanholt *
320145132Sanholt ******************************************************************************/
321119895Sanholt
322119895SanholtACPI_STATUS
323119895SanholtAcpiDsEvalBufferFieldOperands (
324119895Sanholt    ACPI_WALK_STATE         *WalkState,
325145132Sanholt    ACPI_PARSE_OBJECT       *Op)
326119895Sanholt{
327119895Sanholt    ACPI_STATUS             Status;
328119895Sanholt    ACPI_OPERAND_OBJECT     *ObjDesc;
329145132Sanholt    ACPI_NAMESPACE_NODE     *Node;
330119895Sanholt    ACPI_PARSE_OBJECT       *NextOp;
331119895Sanholt
332119895Sanholt
333145132Sanholt    ACPI_FUNCTION_TRACE_PTR (DsEvalBufferFieldOperands, Op);
334119895Sanholt
335119895Sanholt
336119895Sanholt    /*
337145132Sanholt     * This is where we evaluate the address and length fields of the
338119895Sanholt     * CreateXxxField declaration
339119895Sanholt     */
340119895Sanholt    Node =  Op->Common.Node;
341119895Sanholt
342119895Sanholt    /* NextOp points to the op that holds the Buffer */
343119895Sanholt
344119895Sanholt    NextOp = Op->Common.Value.Arg;
345126525Sobrien
346119895Sanholt    /* Evaluate/create the address and length operands */
347119895Sanholt
348119895Sanholt    Status = AcpiDsCreateOperands (WalkState, NextOp);
349119895Sanholt    if (ACPI_FAILURE (Status))
350119895Sanholt    {
351119895Sanholt        return_ACPI_STATUS (Status);
352119895Sanholt    }
353119895Sanholt
354126525Sobrien    ObjDesc = AcpiNsGetAttachedObject (Node);
355119895Sanholt    if (!ObjDesc)
356119895Sanholt    {
357119895Sanholt        return_ACPI_STATUS (AE_NOT_EXIST);
358145132Sanholt    }
359119895Sanholt
360119895Sanholt    /* Resolve the operands */
361119895Sanholt
362119895Sanholt    Status = AcpiExResolveOperands (Op->Common.AmlOpcode,
363119895Sanholt                    ACPI_WALK_OPERANDS, WalkState);
364119895Sanholt    if (ACPI_FAILURE (Status))
365119895Sanholt    {
366119895Sanholt        ACPI_ERROR ((AE_INFO, "(%s) bad operand(s), status 0x%X",
367119895Sanholt            AcpiPsGetOpcodeName (Op->Common.AmlOpcode), Status));
368126525Sobrien
369145132Sanholt        return_ACPI_STATUS (Status);
370119895Sanholt    }
371119895Sanholt
372119895Sanholt    /* Initialize the Buffer Field */
373119895Sanholt
374145132Sanholt    if (Op->Common.AmlOpcode == AML_CREATE_FIELD_OP)
375145132Sanholt    {
376145132Sanholt        /* NOTE: Slightly different operands for this opcode */
377119895Sanholt
378119895Sanholt        Status = AcpiDsInitBufferField (Op->Common.AmlOpcode, ObjDesc,
379145132Sanholt                    WalkState->Operands[0], WalkState->Operands[1],
380145132Sanholt                    WalkState->Operands[2], WalkState->Operands[3]);
381182080Srnoland    }
382182080Srnoland    else
383182080Srnoland    {
384182080Srnoland        /* All other, CreateXxxField opcodes */
385182080Srnoland
386182080Srnoland        Status = AcpiDsInitBufferField (Op->Common.AmlOpcode, ObjDesc,
387145132Sanholt                    WalkState->Operands[0], WalkState->Operands[1],
388145132Sanholt                                      NULL, WalkState->Operands[2]);
389145132Sanholt    }
390
391    return_ACPI_STATUS (Status);
392}
393
394
395/*******************************************************************************
396 *
397 * FUNCTION:    AcpiDsEvalRegionOperands
398 *
399 * PARAMETERS:  WalkState       - Current walk
400 *              Op              - A valid region Op object
401 *
402 * RETURN:      Status
403 *
404 * DESCRIPTION: Get region address and length
405 *              Called from AcpiDsExecEndOp during OpRegion parse tree walk
406 *
407 ******************************************************************************/
408
409ACPI_STATUS
410AcpiDsEvalRegionOperands (
411    ACPI_WALK_STATE         *WalkState,
412    ACPI_PARSE_OBJECT       *Op)
413{
414    ACPI_STATUS             Status;
415    ACPI_OPERAND_OBJECT     *ObjDesc;
416    ACPI_OPERAND_OBJECT     *OperandDesc;
417    ACPI_NAMESPACE_NODE     *Node;
418    ACPI_PARSE_OBJECT       *NextOp;
419
420
421    ACPI_FUNCTION_TRACE_PTR (DsEvalRegionOperands, Op);
422
423
424    /*
425     * This is where we evaluate the address and length fields of the
426     * OpRegion declaration
427     */
428    Node =  Op->Common.Node;
429
430    /* NextOp points to the op that holds the SpaceID */
431
432    NextOp = Op->Common.Value.Arg;
433
434    /* NextOp points to address op */
435
436    NextOp = NextOp->Common.Next;
437
438    /* Evaluate/create the address and length operands */
439
440    Status = AcpiDsCreateOperands (WalkState, NextOp);
441    if (ACPI_FAILURE (Status))
442    {
443        return_ACPI_STATUS (Status);
444    }
445
446    /* Resolve the length and address operands to numbers */
447
448    Status = AcpiExResolveOperands (Op->Common.AmlOpcode,
449                ACPI_WALK_OPERANDS, WalkState);
450    if (ACPI_FAILURE (Status))
451    {
452        return_ACPI_STATUS (Status);
453    }
454
455    ObjDesc = AcpiNsGetAttachedObject (Node);
456    if (!ObjDesc)
457    {
458        return_ACPI_STATUS (AE_NOT_EXIST);
459    }
460
461    /*
462     * Get the length operand and save it
463     * (at Top of stack)
464     */
465    OperandDesc = WalkState->Operands[WalkState->NumOperands - 1];
466
467    ObjDesc->Region.Length = (UINT32) OperandDesc->Integer.Value;
468    AcpiUtRemoveReference (OperandDesc);
469
470    /*
471     * Get the address and save it
472     * (at top of stack - 1)
473     */
474    OperandDesc = WalkState->Operands[WalkState->NumOperands - 2];
475
476    ObjDesc->Region.Address = (ACPI_PHYSICAL_ADDRESS)
477                                OperandDesc->Integer.Value;
478    AcpiUtRemoveReference (OperandDesc);
479
480    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
481        ObjDesc,
482        ACPI_FORMAT_NATIVE_UINT (ObjDesc->Region.Address),
483        ObjDesc->Region.Length));
484
485    /* Now the address and length are valid for this opregion */
486
487    ObjDesc->Region.Flags |= AOPOBJ_DATA_VALID;
488
489    return_ACPI_STATUS (Status);
490}
491
492
493/*******************************************************************************
494 *
495 * FUNCTION:    AcpiDsEvalTableRegionOperands
496 *
497 * PARAMETERS:  WalkState       - Current walk
498 *              Op              - A valid region Op object
499 *
500 * RETURN:      Status
501 *
502 * DESCRIPTION: Get region address and length.
503 *              Called from AcpiDsExecEndOp during DataTableRegion parse
504 *              tree walk.
505 *
506 ******************************************************************************/
507
508ACPI_STATUS
509AcpiDsEvalTableRegionOperands (
510    ACPI_WALK_STATE         *WalkState,
511    ACPI_PARSE_OBJECT       *Op)
512{
513    ACPI_STATUS             Status;
514    ACPI_OPERAND_OBJECT     *ObjDesc;
515    ACPI_OPERAND_OBJECT     **Operand;
516    ACPI_NAMESPACE_NODE     *Node;
517    ACPI_PARSE_OBJECT       *NextOp;
518    UINT32                  TableIndex;
519    ACPI_TABLE_HEADER       *Table;
520
521
522    ACPI_FUNCTION_TRACE_PTR (DsEvalTableRegionOperands, Op);
523
524
525    /*
526     * This is where we evaluate the Signature string, OemId string,
527     * and OemTableId string of the Data Table Region declaration
528     */
529    Node =  Op->Common.Node;
530
531    /* NextOp points to Signature string op */
532
533    NextOp = Op->Common.Value.Arg;
534
535    /*
536     * Evaluate/create the Signature string, OemId string,
537     * and OemTableId string operands
538     */
539    Status = AcpiDsCreateOperands (WalkState, NextOp);
540    if (ACPI_FAILURE (Status))
541    {
542        return_ACPI_STATUS (Status);
543    }
544
545    /*
546     * Resolve the Signature string, OemId string,
547     * and OemTableId string operands
548     */
549    Status = AcpiExResolveOperands (Op->Common.AmlOpcode,
550                ACPI_WALK_OPERANDS, WalkState);
551    if (ACPI_FAILURE (Status))
552    {
553        return_ACPI_STATUS (Status);
554    }
555
556    Operand = &WalkState->Operands[0];
557
558    /* Find the ACPI table */
559
560    Status = AcpiTbFindTable (Operand[0]->String.Pointer,
561                Operand[1]->String.Pointer, Operand[2]->String.Pointer,
562                &TableIndex);
563    if (ACPI_FAILURE (Status))
564    {
565        return_ACPI_STATUS (Status);
566    }
567
568    AcpiUtRemoveReference (Operand[0]);
569    AcpiUtRemoveReference (Operand[1]);
570    AcpiUtRemoveReference (Operand[2]);
571
572    Status = AcpiGetTableByIndex (TableIndex, &Table);
573    if (ACPI_FAILURE (Status))
574    {
575        return_ACPI_STATUS (Status);
576    }
577
578    ObjDesc = AcpiNsGetAttachedObject (Node);
579    if (!ObjDesc)
580    {
581        return_ACPI_STATUS (AE_NOT_EXIST);
582    }
583
584    ObjDesc->Region.Address = (ACPI_PHYSICAL_ADDRESS) ACPI_TO_INTEGER (Table);
585    ObjDesc->Region.Length = Table->Length;
586
587    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
588        ObjDesc,
589        ACPI_FORMAT_NATIVE_UINT (ObjDesc->Region.Address),
590        ObjDesc->Region.Length));
591
592    /* Now the address and length are valid for this opregion */
593
594    ObjDesc->Region.Flags |= AOPOBJ_DATA_VALID;
595
596    return_ACPI_STATUS (Status);
597}
598
599
600/*******************************************************************************
601 *
602 * FUNCTION:    AcpiDsEvalDataObjectOperands
603 *
604 * PARAMETERS:  WalkState       - Current walk
605 *              Op              - A valid DataObject Op object
606 *              ObjDesc         - DataObject
607 *
608 * RETURN:      Status
609 *
610 * DESCRIPTION: Get the operands and complete the following data object types:
611 *              Buffer, Package.
612 *
613 ******************************************************************************/
614
615ACPI_STATUS
616AcpiDsEvalDataObjectOperands (
617    ACPI_WALK_STATE         *WalkState,
618    ACPI_PARSE_OBJECT       *Op,
619    ACPI_OPERAND_OBJECT     *ObjDesc)
620{
621    ACPI_STATUS             Status;
622    ACPI_OPERAND_OBJECT     *ArgDesc;
623    UINT32                  Length;
624
625
626    ACPI_FUNCTION_TRACE (DsEvalDataObjectOperands);
627
628
629    /* The first operand (for all of these data objects) is the length */
630
631    /*
632     * Set proper index into operand stack for AcpiDsObjStackPush
633     * invoked inside AcpiDsCreateOperand.
634     */
635    WalkState->OperandIndex = WalkState->NumOperands;
636
637    Status = AcpiDsCreateOperand (WalkState, Op->Common.Value.Arg, 1);
638    if (ACPI_FAILURE (Status))
639    {
640        return_ACPI_STATUS (Status);
641    }
642
643    Status = AcpiExResolveOperands (WalkState->Opcode,
644                    &(WalkState->Operands [WalkState->NumOperands -1]),
645                    WalkState);
646    if (ACPI_FAILURE (Status))
647    {
648        return_ACPI_STATUS (Status);
649    }
650
651    /* Extract length operand */
652
653    ArgDesc = WalkState->Operands [WalkState->NumOperands - 1];
654    Length = (UINT32) ArgDesc->Integer.Value;
655
656    /* Cleanup for length operand */
657
658    Status = AcpiDsObjStackPop (1, WalkState);
659    if (ACPI_FAILURE (Status))
660    {
661        return_ACPI_STATUS (Status);
662    }
663
664    AcpiUtRemoveReference (ArgDesc);
665
666    /*
667     * Create the actual data object
668     */
669    switch (Op->Common.AmlOpcode)
670    {
671    case AML_BUFFER_OP:
672
673        Status = AcpiDsBuildInternalBufferObj (WalkState, Op, Length, &ObjDesc);
674        break;
675
676    case AML_PACKAGE_OP:
677    case AML_VAR_PACKAGE_OP:
678
679        Status = AcpiDsBuildInternalPackageObj (WalkState, Op, Length, &ObjDesc);
680        break;
681
682    default:
683
684        return_ACPI_STATUS (AE_AML_BAD_OPCODE);
685    }
686
687    if (ACPI_SUCCESS (Status))
688    {
689        /*
690         * Return the object in the WalkState, unless the parent is a package -
691         * in this case, the return object will be stored in the parse tree
692         * for the package.
693         */
694        if ((!Op->Common.Parent) ||
695            ((Op->Common.Parent->Common.AmlOpcode != AML_PACKAGE_OP) &&
696             (Op->Common.Parent->Common.AmlOpcode != AML_VAR_PACKAGE_OP) &&
697             (Op->Common.Parent->Common.AmlOpcode != AML_NAME_OP)))
698        {
699            WalkState->ResultObj = ObjDesc;
700        }
701    }
702
703    return_ACPI_STATUS (Status);
704}
705
706
707/*******************************************************************************
708 *
709 * FUNCTION:    AcpiDsEvalBankFieldOperands
710 *
711 * PARAMETERS:  WalkState       - Current walk
712 *              Op              - A valid BankField Op object
713 *
714 * RETURN:      Status
715 *
716 * DESCRIPTION: Get BankField BankValue
717 *              Called from AcpiDsExecEndOp during BankField parse tree walk
718 *
719 ******************************************************************************/
720
721ACPI_STATUS
722AcpiDsEvalBankFieldOperands (
723    ACPI_WALK_STATE         *WalkState,
724    ACPI_PARSE_OBJECT       *Op)
725{
726    ACPI_STATUS             Status;
727    ACPI_OPERAND_OBJECT     *ObjDesc;
728    ACPI_OPERAND_OBJECT     *OperandDesc;
729    ACPI_NAMESPACE_NODE     *Node;
730    ACPI_PARSE_OBJECT       *NextOp;
731    ACPI_PARSE_OBJECT       *Arg;
732
733
734    ACPI_FUNCTION_TRACE_PTR (DsEvalBankFieldOperands, Op);
735
736
737    /*
738     * This is where we evaluate the BankValue field of the
739     * BankField declaration
740     */
741
742    /* NextOp points to the op that holds the Region */
743
744    NextOp = Op->Common.Value.Arg;
745
746    /* NextOp points to the op that holds the Bank Register */
747
748    NextOp = NextOp->Common.Next;
749
750    /* NextOp points to the op that holds the Bank Value */
751
752    NextOp = NextOp->Common.Next;
753
754    /*
755     * Set proper index into operand stack for AcpiDsObjStackPush
756     * invoked inside AcpiDsCreateOperand.
757     *
758     * We use WalkState->Operands[0] to store the evaluated BankValue
759     */
760    WalkState->OperandIndex = 0;
761
762    Status = AcpiDsCreateOperand (WalkState, NextOp, 0);
763    if (ACPI_FAILURE (Status))
764    {
765        return_ACPI_STATUS (Status);
766    }
767
768    Status = AcpiExResolveToValue (&WalkState->Operands[0], WalkState);
769    if (ACPI_FAILURE (Status))
770    {
771        return_ACPI_STATUS (Status);
772    }
773
774    ACPI_DUMP_OPERANDS (ACPI_WALK_OPERANDS,
775        AcpiPsGetOpcodeName (Op->Common.AmlOpcode), 1);
776    /*
777     * Get the BankValue operand and save it
778     * (at Top of stack)
779     */
780    OperandDesc = WalkState->Operands[0];
781
782    /* Arg points to the start Bank Field */
783
784    Arg = AcpiPsGetArg (Op, 4);
785    while (Arg)
786    {
787        /* Ignore OFFSET and ACCESSAS terms here */
788
789        if (Arg->Common.AmlOpcode == AML_INT_NAMEDFIELD_OP)
790        {
791            Node = Arg->Common.Node;
792
793            ObjDesc = AcpiNsGetAttachedObject (Node);
794            if (!ObjDesc)
795            {
796                return_ACPI_STATUS (AE_NOT_EXIST);
797            }
798
799            ObjDesc->BankField.Value = (UINT32) OperandDesc->Integer.Value;
800        }
801
802        /* Move to next field in the list */
803
804        Arg = Arg->Common.Next;
805    }
806
807    AcpiUtRemoveReference (OperandDesc);
808    return_ACPI_STATUS (Status);
809}
810