exprep.c revision 151937
1136384Srwatson
2136384Srwatson/******************************************************************************
3136384Srwatson *
4136384Srwatson * Module Name: exprep - ACPI AML (p-code) execution - field prep utilities
5136384Srwatson *              $Revision: 1.135 $
6136384Srwatson *
7136384Srwatson *****************************************************************************/
8136384Srwatson
9136384Srwatson/******************************************************************************
10136384Srwatson *
11136384Srwatson * 1. Copyright Notice
12136384Srwatson *
13136384Srwatson * Some or all of this work - Copyright (c) 1999 - 2005, Intel Corp.
14136384Srwatson * All rights reserved.
15136384Srwatson *
16136384Srwatson * 2. License
17136384Srwatson *
18136384Srwatson * 2.1. This is your license from Intel Corp. under its intellectual property
19136384Srwatson * rights.  You may have additional license terms from the party that provided
20136384Srwatson * you this software, covering your right to use that party's intellectual
21136384Srwatson * property rights.
22136384Srwatson *
23136384Srwatson * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
24136384Srwatson * copy of the source code appearing in this file ("Covered Code") an
25136384Srwatson * irrevocable, perpetual, worldwide license under Intel's copyrights in the
26136384Srwatson * base code distributed originally by Intel ("Original Intel Code") to copy,
27136384Srwatson * make derivatives, distribute, use and display any portion of the Covered
28136384Srwatson * Code in any form, with the right to sublicense such rights; and
29136384Srwatson *
30136384Srwatson * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
31136384Srwatson * license (with the right to sublicense), under only those claims of Intel
32136384Srwatson * patents that are infringed by the Original Intel Code, to make, use, sell,
33136384Srwatson * offer to sell, and import the Covered Code and derivative works thereof
34136384Srwatson * solely to the minimum extent necessary to exercise the above copyright
35166437Sbms * license, and in no event shall the patent license extend to any additions
36136384Srwatson * to or modifications of the Original Intel Code.  No other license or right
37136384Srwatson * is granted directly or by implication, estoppel or otherwise;
38136384Srwatson *
39166437Sbms * The above copyright and patent license is granted only if the following
40136384Srwatson * conditions are met:
41136384Srwatson *
42136384Srwatson * 3. Conditions
43136384Srwatson *
44136384Srwatson * 3.1. Redistribution of Source with Rights to Further Distribute Source.
45166437Sbms * Redistribution of source code of any substantial portion of the Covered
46166437Sbms * Code or modification with rights to further distribute source must include
47166437Sbms * the above Copyright Notice, the above License, this list of Conditions,
48166437Sbms * and the following Disclaimer and Export Compliance provision.  In addition,
49136384Srwatson * Licensee must cause all Covered Code to which Licensee contributes to
50136384Srwatson * contain a file documenting the changes Licensee made to create that Covered
51136384Srwatson * Code and the date of any change.  Licensee must include in that file the
52136384Srwatson * documentation of any changes made by any predecessor Licensee.  Licensee
53136384Srwatson * must include a prominent statement that the modification is derived,
54136384Srwatson * directly or indirectly, from Original Intel Code.
55136384Srwatson *
56136384Srwatson * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
57136384Srwatson * Redistribution of source code of any substantial portion of the Covered
58136390Srwatson * Code or modification without rights to further distribute source must
59136390Srwatson * include the following Disclaimer and Export Compliance provision in the
60136390Srwatson * documentation and/or other materials provided with distribution.  In
61136390Srwatson * addition, Licensee may not authorize further sublicense of source of any
62136390Srwatson * portion of the Covered Code, and must include terms to the effect that the
63136390Srwatson * license from Licensee to its licensee is limited to the intellectual
64136390Srwatson * property embodied in the software Licensee provides to its licensee, and
65136390Srwatson * not to intellectual property embodied in modifications its licensee may
66136390Srwatson * make.
67136390Srwatson *
68136390Srwatson * 3.3. Redistribution of Executable. Redistribution in executable form of any
69136390Srwatson * substantial portion of the Covered Code or modification must reproduce the
70136390Srwatson * above Copyright Notice, and the following Disclaimer and Export Compliance
71136390Srwatson * provision in the documentation and/or other materials provided with the
72136390Srwatson * distribution.
73136390Srwatson *
74136390Srwatson * 3.4. Intel retains all right, title, and interest in and to the Original
75136390Srwatson * Intel Code.
76136390Srwatson *
77136390Srwatson * 3.5. Neither the name Intel nor any other trademark owned or controlled by
78136390Srwatson * Intel shall be used in advertising or otherwise to promote the sale, use or
79136390Srwatson * other dealings in products derived from or relating to the Covered Code
80136390Srwatson * without prior written authorization from Intel.
81136390Srwatson *
82136390Srwatson * 4. Disclaimer and Export Compliance
83136390Srwatson *
84136390Srwatson * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
85136390Srwatson * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
86136390Srwatson * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
87136390Srwatson * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
88136390Srwatson * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
89136390Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
90136390Srwatson * PARTICULAR PURPOSE.
91136390Srwatson *
92136390Srwatson * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
93136390Srwatson * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
94136390Srwatson * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
95136390Srwatson * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
96136390Srwatson * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
97136390Srwatson * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
98136390Srwatson * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
99136390Srwatson * LIMITED REMEDY.
100136390Srwatson *
101136390Srwatson * 4.3. Licensee shall not export, either directly or indirectly, any of this
102136390Srwatson * software or system incorporating such software without first obtaining any
103136390Srwatson * required license or other approval from the U. S. Department of Commerce or
104136390Srwatson * any other agency or department of the United States Government.  In the
105136384Srwatson * event Licensee exports any such software from the United States or
106136384Srwatson * re-exports any such software from a foreign destination, Licensee shall
107136384Srwatson * ensure that the distribution and export/re-export of the software is in
108136384Srwatson * compliance with all laws, regulations, orders, or other restrictions of the
109136384Srwatson * U.S. Export Administration Regulations. Licensee agrees that neither it nor
110136384Srwatson * any of its subsidiaries will export/re-export any technical data, process,
111136384Srwatson * software, or service, directly or indirectly, to any country for which the
112136384Srwatson * United States government or any agency thereof requires an export license,
113136384Srwatson * other governmental approval, or letter of assurance, without first obtaining
114136390Srwatson * such license, approval or letter.
115136384Srwatson *
116136384Srwatson *****************************************************************************/
117136384Srwatson
118136384Srwatson#define __EXPREP_C__
119136384Srwatson
120136384Srwatson#include <contrib/dev/acpica/acpi.h>
121136384Srwatson#include <contrib/dev/acpica/acinterp.h>
122136384Srwatson#include <contrib/dev/acpica/amlcode.h>
123136384Srwatson#include <contrib/dev/acpica/acnamesp.h>
124136384Srwatson
125136390Srwatson
126136390Srwatson#define _COMPONENT          ACPI_EXECUTER
127136384Srwatson        ACPI_MODULE_NAME    ("exprep")
128136384Srwatson
129136390Srwatson/* Local prototypes */
130136390Srwatson
131136384Srwatsonstatic UINT32
132136384SrwatsonAcpiExDecodeFieldAccess (
133136384Srwatson    ACPI_OPERAND_OBJECT     *ObjDesc,
134136384Srwatson    UINT8                   FieldFlags,
135136384Srwatson    UINT32                  *ReturnByteAlignment);
136136384Srwatson
137136384Srwatson
138136384Srwatson#ifdef ACPI_UNDER_DEVELOPMENT
139136384Srwatson
140136384Srwatsonstatic UINT32
141136384SrwatsonAcpiExGenerateAccess (
142136390Srwatson    UINT32                  FieldBitOffset,
143136390Srwatson    UINT32                  FieldBitLength,
144136384Srwatson    UINT32                  RegionLength);
145136384Srwatson
146136384Srwatson/*******************************************************************************
147136384Srwatson *
148136384Srwatson * FUNCTION:    AcpiExGenerateAccess
149136384Srwatson *
150136384Srwatson * PARAMETERS:  FieldBitOffset      - Start of field within parent region/buffer
151136384Srwatson *              FieldBitLength      - Length of field in bits
152136384Srwatson *              RegionLength        - Length of parent in bytes
153136384Srwatson *
154136384Srwatson * RETURN:      Field granularity (8, 16, 32 or 64) and
155136390Srwatson *              ByteAlignment (1, 2, 3, or 4)
156136390Srwatson *
157136384Srwatson * DESCRIPTION: Generate an optimal access width for fields defined with the
158136384Srwatson *              AnyAcc keyword.
159136384Srwatson *
160136384Srwatson * NOTE: Need to have the RegionLength in order to check for boundary
161136384Srwatson *       conditions (end-of-region).  However, the RegionLength is a deferred
162136390Srwatson *       operation.  Therefore, to complete this implementation, the generation
163136390Srwatson *       of this access width must be deferred until the region length has
164136384Srwatson *       been evaluated.
165136384Srwatson *
166136384Srwatson ******************************************************************************/
167136384Srwatson
168136384Srwatsonstatic UINT32
169136384SrwatsonAcpiExGenerateAccess (
170136390Srwatson    UINT32                  FieldBitOffset,
171136390Srwatson    UINT32                  FieldBitLength,
172136384Srwatson    UINT32                  RegionLength)
173136384Srwatson{
174136384Srwatson    UINT32                  FieldByteLength;
175136384Srwatson    UINT32                  FieldByteOffset;
176136384Srwatson    UINT32                  FieldByteEndOffset;
177136390Srwatson    UINT32                  AccessByteWidth;
178136390Srwatson    UINT32                  FieldStartOffset;
179136390Srwatson    UINT32                  FieldEndOffset;
180136384Srwatson    UINT32                  MinimumAccessWidth = 0xFFFFFFFF;
181136384Srwatson    UINT32                  MinimumAccesses = 0xFFFFFFFF;
182136384Srwatson    UINT32                  Accesses;
183136384Srwatson
184136384Srwatson
185136390Srwatson    ACPI_FUNCTION_TRACE ("ExGenerateAccess");
186136390Srwatson
187136384Srwatson
188136384Srwatson    /* Round Field start offset and length to "minimal" byte boundaries */
189136384Srwatson
190136384Srwatson    FieldByteOffset    = ACPI_DIV_8 (ACPI_ROUND_DOWN (FieldBitOffset, 8));
191136384Srwatson    FieldByteEndOffset = ACPI_DIV_8 (ACPI_ROUND_UP   (FieldBitLength +
192136384Srwatson                                                      FieldBitOffset, 8));
193136384Srwatson    FieldByteLength    = FieldByteEndOffset - FieldByteOffset;
194136384Srwatson
195136390Srwatson    ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
196136390Srwatson            "Bit length %d, Bit offset %d\n",
197136384Srwatson            FieldBitLength, FieldBitOffset));
198136384Srwatson
199136390Srwatson    ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
200136390Srwatson            "Byte Length %d, Byte Offset %d, End Offset %d\n",
201136384Srwatson            FieldByteLength, FieldByteOffset, FieldByteEndOffset));
202136384Srwatson
203136384Srwatson    /*
204136384Srwatson     * Iterative search for the maximum access width that is both aligned
205136384Srwatson     * and does not go beyond the end of the region
206136384Srwatson     *
207136384Srwatson     * Start at ByteAcc and work upwards to QwordAcc max. (1,2,4,8 bytes)
208136384Srwatson     */
209136384Srwatson    for (AccessByteWidth = 1; AccessByteWidth <= 8; AccessByteWidth <<= 1)
210136390Srwatson    {
211136390Srwatson        /*
212136390Srwatson         * 1) Round end offset up to next access boundary and make sure that
213136384Srwatson         *    this does not go beyond the end of the parent region.
214136384Srwatson         * 2) When the Access width is greater than the FieldByteLength, we
215136384Srwatson         *    are done. (This does not optimize for the perfectly aligned
216136384Srwatson         *    case yet).
217136384Srwatson         */
218136384Srwatson        if (ACPI_ROUND_UP (FieldByteEndOffset, AccessByteWidth) <= RegionLength)
219136384Srwatson        {
220136384Srwatson            FieldStartOffset =
221136384Srwatson                ACPI_ROUND_DOWN (FieldByteOffset, AccessByteWidth) /
222136384Srwatson                AccessByteWidth;
223136384Srwatson
224136390Srwatson            FieldEndOffset =
225136390Srwatson                ACPI_ROUND_UP ((FieldByteLength + FieldByteOffset),
226136384Srwatson                    AccessByteWidth) / AccessByteWidth;
227136384Srwatson
228136384Srwatson            Accesses = FieldEndOffset - FieldStartOffset;
229136390Srwatson
230136390Srwatson            ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
231136384Srwatson                    "AccessWidth %d end is within region\n", AccessByteWidth));
232136390Srwatson
233136390Srwatson            ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
234136390Srwatson                    "Field Start %d, Field End %d -- requires %d accesses\n",
235136390Srwatson                    FieldStartOffset, FieldEndOffset, Accesses));
236136384Srwatson
237136384Srwatson            /* Single access is optimal */
238136384Srwatson
239136390Srwatson            if (Accesses <= 1)
240136390Srwatson            {
241136390Srwatson                ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
242136384Srwatson                    "Entire field can be accessed with one operation of size %d\n",
243136390Srwatson                    AccessByteWidth));
244136390Srwatson                return_VALUE (AccessByteWidth);
245136390Srwatson            }
246136390Srwatson
247136384Srwatson            /*
248136384Srwatson             * Fits in the region, but requires more than one read/write.
249136384Srwatson             * try the next wider access on next iteration
250136384Srwatson             */
251136384Srwatson            if (Accesses < MinimumAccesses)
252136384Srwatson            {
253136384Srwatson                MinimumAccesses    = Accesses;
254136390Srwatson                MinimumAccessWidth = AccessByteWidth;
255136390Srwatson            }
256136384Srwatson        }
257136384Srwatson        else
258136384Srwatson        {
259136390Srwatson            ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
260136390Srwatson                "AccessWidth %d end is NOT within region\n", AccessByteWidth));
261136390Srwatson            if (AccessByteWidth == 1)
262136384Srwatson            {
263136390Srwatson                ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
264136390Srwatson                        "Field goes beyond end-of-region!\n"));
265136390Srwatson
266136390Srwatson                /* Field does not fit in the region at all */
267136384Srwatson
268136384Srwatson                return_VALUE (0);
269136390Srwatson            }
270136390Srwatson
271136390Srwatson            /*
272136384Srwatson             * This width goes beyond the end-of-region, back off to
273136390Srwatson             * previous access
274136390Srwatson             */
275136390Srwatson            ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
276136390Srwatson                    "Backing off to previous optimal access width of %d\n",
277136384Srwatson                    MinimumAccessWidth));
278136384Srwatson            return_VALUE (MinimumAccessWidth);
279136384Srwatson        }
280136384Srwatson    }
281136384Srwatson
282136384Srwatson    /*
283136384Srwatson     * Could not read/write field with one operation,
284136384Srwatson     * just use max access width
285136384Srwatson     */
286136384Srwatson    ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
287136384Srwatson            "Cannot access field in one operation, using width 8\n"));
288136384Srwatson    return_VALUE (8);
289136384Srwatson}
290136384Srwatson#endif /* ACPI_UNDER_DEVELOPMENT */
291136384Srwatson
292136384Srwatson
293136384Srwatson/*******************************************************************************
294136390Srwatson *
295136390Srwatson * FUNCTION:    AcpiExDecodeFieldAccess
296136384Srwatson *
297136384Srwatson * PARAMETERS:  ObjDesc             - Field object
298136384Srwatson *              FieldFlags          - Encoded fieldflags (contains access bits)
299136384Srwatson *              ReturnByteAlignment - Where the byte alignment is returned
300136384Srwatson *
301136384Srwatson * RETURN:      Field granularity (8, 16, 32 or 64) and
302136384Srwatson *              ByteAlignment (1, 2, 3, or 4)
303136390Srwatson *
304136390Srwatson * DESCRIPTION: Decode the AccessType bits of a field definition.
305136390Srwatson *
306136384Srwatson ******************************************************************************/
307136390Srwatson
308136390Srwatsonstatic UINT32
309136384SrwatsonAcpiExDecodeFieldAccess (
310136384Srwatson    ACPI_OPERAND_OBJECT     *ObjDesc,
311136390Srwatson    UINT8                   FieldFlags,
312136390Srwatson    UINT32                  *ReturnByteAlignment)
313136384Srwatson{
314136384Srwatson    UINT32                  Access;
315136384Srwatson    UINT32                  ByteAlignment;
316136384Srwatson    UINT32                  BitLength;
317136384Srwatson
318136384Srwatson
319136384Srwatson    ACPI_FUNCTION_TRACE ("ExDecodeFieldAccess");
320136390Srwatson
321136390Srwatson
322136384Srwatson    Access = (FieldFlags & AML_FIELD_ACCESS_TYPE_MASK);
323136384Srwatson
324136384Srwatson    switch (Access)
325136384Srwatson    {
326136384Srwatson    case AML_FIELD_ACCESS_ANY:
327136384Srwatson
328136384Srwatson#ifdef ACPI_UNDER_DEVELOPMENT
329136390Srwatson        ByteAlignment =
330136390Srwatson            AcpiExGenerateAccess (ObjDesc->CommonField.StartFieldBitOffset,
331136390Srwatson                ObjDesc->CommonField.BitLength,
332136384Srwatson                0xFFFFFFFF /* Temp until we pass RegionLength as parameter */);
333136390Srwatson        BitLength = ByteAlignment * 8;
334136390Srwatson#endif
335136384Srwatson
336136384Srwatson        ByteAlignment = 1;
337136384Srwatson        BitLength = 8;
338136390Srwatson        break;
339136390Srwatson
340136384Srwatson    case AML_FIELD_ACCESS_BYTE:
341136384Srwatson    case AML_FIELD_ACCESS_BUFFER:   /* ACPI 2.0 (SMBus Buffer) */
342136384Srwatson        ByteAlignment = 1;
343136384Srwatson        BitLength     = 8;
344136384Srwatson        break;
345136384Srwatson
346136384Srwatson    case AML_FIELD_ACCESS_WORD:
347136384Srwatson        ByteAlignment = 2;
348136390Srwatson        BitLength     = 16;
349136390Srwatson        break;
350136384Srwatson
351136384Srwatson    case AML_FIELD_ACCESS_DWORD:
352136384Srwatson        ByteAlignment = 4;
353136384Srwatson        BitLength     = 32;
354136384Srwatson        break;
355136384Srwatson
356136384Srwatson    case AML_FIELD_ACCESS_QWORD:    /* ACPI 2.0 */
357136390Srwatson        ByteAlignment = 8;
358136390Srwatson        BitLength     = 64;
359136390Srwatson        break;
360136384Srwatson
361136390Srwatson    default:
362136390Srwatson        /* Invalid field access type */
363136384Srwatson
364136384Srwatson        ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
365136384Srwatson            "Unknown field access type %X\n",
366136384Srwatson            Access));
367136384Srwatson        return_UINT32 (0);
368136384Srwatson    }
369136384Srwatson
370136384Srwatson    if (ACPI_GET_OBJECT_TYPE (ObjDesc) == ACPI_TYPE_BUFFER_FIELD)
371136384Srwatson    {
372136384Srwatson        /*
373136384Srwatson         * BufferField access can be on any byte boundary, so the
374136384Srwatson         * ByteAlignment is always 1 byte -- regardless of any ByteAlignment
375136384Srwatson         * implied by the field access type.
376136384Srwatson         */
377136384Srwatson        ByteAlignment = 1;
378136384Srwatson    }
379136384Srwatson
380136384Srwatson    *ReturnByteAlignment = ByteAlignment;
381136384Srwatson    return_UINT32 (BitLength);
382136384Srwatson}
383136384Srwatson
384136384Srwatson
385136384Srwatson/*******************************************************************************
386136384Srwatson *
387136384Srwatson * FUNCTION:    AcpiExPrepCommonFieldObject
388136384Srwatson *
389136384Srwatson * PARAMETERS:  ObjDesc             - The field object
390136384Srwatson *              FieldFlags          - Access, LockRule, and UpdateRule.
391136390Srwatson *                                    The format of a FieldFlag is described
392136390Srwatson *                                    in the ACPI specification
393136384Srwatson *              FieldAttribute      - Special attributes (not used)
394136390Srwatson *              FieldBitPosition    - Field start position
395136384Srwatson *              FieldBitLength      - Field length in number of bits
396136384Srwatson *
397136384Srwatson * RETURN:      Status
398136384Srwatson *
399136384Srwatson * DESCRIPTION: Initialize the areas of the field object that are common
400136384Srwatson *              to the various types of fields.  Note: This is very "sensitive"
401136384Srwatson *              code because we are solving the general case for field
402136384Srwatson *              alignment.
403136384Srwatson *
404136384Srwatson ******************************************************************************/
405136390Srwatson
406136390SrwatsonACPI_STATUS
407136384SrwatsonAcpiExPrepCommonFieldObject (
408136384Srwatson    ACPI_OPERAND_OBJECT     *ObjDesc,
409136390Srwatson    UINT8                   FieldFlags,
410136390Srwatson    UINT8                   FieldAttribute,
411136384Srwatson    UINT32                  FieldBitPosition,
412136384Srwatson    UINT32                  FieldBitLength)
413136390Srwatson{
414136390Srwatson    UINT32                  AccessBitWidth;
415136384Srwatson    UINT32                  ByteAlignment;
416136384Srwatson    UINT32                  NearestByteAddress;
417136390Srwatson
418136390Srwatson
419136390Srwatson    ACPI_FUNCTION_TRACE ("ExPrepCommonFieldObject");
420136384Srwatson
421136384Srwatson
422136384Srwatson    /*
423136384Srwatson     * Note: the structure being initialized is the
424136384Srwatson     * ACPI_COMMON_FIELD_INFO;  No structure fields outside of the common
425136384Srwatson     * area are initialized by this procedure.
426136384Srwatson     */
427136390Srwatson    ObjDesc->CommonField.FieldFlags = FieldFlags;
428136390Srwatson    ObjDesc->CommonField.Attribute  = FieldAttribute;
429136384Srwatson    ObjDesc->CommonField.BitLength  = FieldBitLength;
430136384Srwatson
431136384Srwatson    /*
432136384Srwatson     * Decode the access type so we can compute offsets.  The access type gives
433136384Srwatson     * two pieces of information - the width of each field access and the
434136384Srwatson     * necessary ByteAlignment (address granularity) of the access.
435136384Srwatson     *
436136384Srwatson     * For AnyAcc, the AccessBitWidth is the largest width that is both
437136390Srwatson     * necessary and possible in an attempt to access the whole field in one
438136390Srwatson     * I/O operation.  However, for AnyAcc, the ByteAlignment is always one
439136384Srwatson     * byte.
440136384Srwatson     *
441136390Srwatson     * For all Buffer Fields, the ByteAlignment is always one byte.
442136390Srwatson     *
443136384Srwatson     * For all other access types (Byte, Word, Dword, Qword), the Bitwidth is
444136384Srwatson     * the same (equivalent) as the ByteAlignment.
445136390Srwatson     */
446136390Srwatson    AccessBitWidth = AcpiExDecodeFieldAccess (ObjDesc, FieldFlags,
447136384Srwatson                                &ByteAlignment);
448136384Srwatson    if (!AccessBitWidth)
449136390Srwatson    {
450136390Srwatson        return_ACPI_STATUS (AE_AML_OPERAND_VALUE);
451136384Srwatson    }
452136384Srwatson
453136384Srwatson    /* Setup width (access granularity) fields */
454136384Srwatson
455136384Srwatson    ObjDesc->CommonField.AccessByteWidth = (UINT8)
456136384Srwatson            ACPI_DIV_8 (AccessBitWidth);            /* 1,  2,  4,  8 */
457136384Srwatson
458136390Srwatson    ObjDesc->CommonField.AccessBitWidth = (UINT8) AccessBitWidth;
459136390Srwatson
460136384Srwatson    /*
461136384Srwatson     * BaseByteOffset is the address of the start of the field within the
462136390Srwatson     * region.  It is the byte address of the first *datum* (field-width data
463136390Srwatson     * unit) of the field. (i.e., the first datum that contains at least the
464136390Srwatson     * first *bit* of the field.)
465136384Srwatson     *
466136384Srwatson     * Note: ByteAlignment is always either equal to the AccessBitWidth or 8
467136390Srwatson     * (Byte access), and it defines the addressing granularity of the parent
468136390Srwatson     * region or buffer.
469136384Srwatson     */
470136384Srwatson    NearestByteAddress =
471136390Srwatson            ACPI_ROUND_BITS_DOWN_TO_BYTES (FieldBitPosition);
472136390Srwatson    ObjDesc->CommonField.BaseByteOffset = (UINT32)
473136390Srwatson            ACPI_ROUND_DOWN (NearestByteAddress, ByteAlignment);
474136384Srwatson
475136384Srwatson    /*
476136384Srwatson     * StartFieldBitOffset is the offset of the first bit of the field within
477136384Srwatson     * a field datum.
478136384Srwatson     */
479136384Srwatson    ObjDesc->CommonField.StartFieldBitOffset = (UINT8)
480136384Srwatson        (FieldBitPosition - ACPI_MUL_8 (ObjDesc->CommonField.BaseByteOffset));
481136384Srwatson
482136384Srwatson    /*
483136384Srwatson     * Does the entire field fit within a single field access element? (datum)
484136384Srwatson     * (i.e., without crossing a datum boundary)
485136384Srwatson     */
486136384Srwatson    if ((ObjDesc->CommonField.StartFieldBitOffset + FieldBitLength) <=
487136384Srwatson            (UINT16) AccessBitWidth)
488136390Srwatson    {
489136384Srwatson        ObjDesc->Common.Flags |= AOPOBJ_SINGLE_DATUM;
490136390Srwatson    }
491136390Srwatson
492136384Srwatson    return_ACPI_STATUS (AE_OK);
493136384Srwatson}
494136384Srwatson
495136384Srwatson
496136384Srwatson/*******************************************************************************
497136384Srwatson *
498136390Srwatson * FUNCTION:    AcpiExPrepFieldValue
499136390Srwatson *
500136384Srwatson * PARAMETERS:  Info    - Contains all field creation info
501136384Srwatson *
502136390Srwatson * RETURN:      Status
503136390Srwatson *
504136390Srwatson * DESCRIPTION: Construct an ACPI_OPERAND_OBJECT of type DefField and
505136384Srwatson *              connect it to the parent Node.
506136384Srwatson *
507136390Srwatson ******************************************************************************/
508136390Srwatson
509136384SrwatsonACPI_STATUS
510136384SrwatsonAcpiExPrepFieldValue (
511136390Srwatson    ACPI_CREATE_FIELD_INFO  *Info)
512136390Srwatson{
513136390Srwatson    ACPI_OPERAND_OBJECT     *ObjDesc;
514136384Srwatson    UINT32                  Type;
515136384Srwatson    ACPI_STATUS             Status;
516136384Srwatson
517136384Srwatson
518136384Srwatson    ACPI_FUNCTION_TRACE ("ExPrepFieldValue");
519136384Srwatson
520136384Srwatson
521136384Srwatson    /* Parameter validation */
522136384Srwatson
523136384Srwatson    if (Info->FieldType != ACPI_TYPE_LOCAL_INDEX_FIELD)
524136384Srwatson    {
525136384Srwatson        if (!Info->RegionNode)
526136384Srwatson        {
527136384Srwatson            ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null RegionNode\n"));
528136384Srwatson            return_ACPI_STATUS (AE_AML_NO_OPERAND);
529136384Srwatson        }
530136384Srwatson
531136390Srwatson        Type = AcpiNsGetType (Info->RegionNode);
532136390Srwatson        if (Type != ACPI_TYPE_REGION)
533136384Srwatson        {
534136390Srwatson            ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
535136384Srwatson                "Needed Region, found type %X (%s)\n",
536136384Srwatson                Type, AcpiUtGetTypeName (Type)));
537136384Srwatson
538136384Srwatson            return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
539136384Srwatson        }
540136384Srwatson    }
541136384Srwatson
542136384Srwatson    /* Allocate a new field object */
543136384Srwatson
544136384Srwatson    ObjDesc = AcpiUtCreateInternalObject (Info->FieldType);
545136384Srwatson    if (!ObjDesc)
546136384Srwatson    {
547136384Srwatson        return_ACPI_STATUS (AE_NO_MEMORY);
548136384Srwatson    }
549136384Srwatson
550136384Srwatson    /* Initialize areas of the object that are common to all fields */
551136384Srwatson
552136384Srwatson    ObjDesc->CommonField.Node = Info->FieldNode;
553136384Srwatson    Status = AcpiExPrepCommonFieldObject (ObjDesc, Info->FieldFlags,
554136390Srwatson                Info->Attribute, Info->FieldBitPosition, Info->FieldBitLength);
555136390Srwatson    if (ACPI_FAILURE (Status))
556136384Srwatson    {
557136384Srwatson        AcpiUtDeleteObjectDesc (ObjDesc);
558136390Srwatson        return_ACPI_STATUS (Status);
559136390Srwatson    }
560136384Srwatson
561136384Srwatson    /* Initialize areas of the object that are specific to the field type */
562136390Srwatson
563136390Srwatson    switch (Info->FieldType)
564136390Srwatson    {
565136384Srwatson    case ACPI_TYPE_LOCAL_REGION_FIELD:
566136384Srwatson
567136384Srwatson        ObjDesc->Field.RegionObj = AcpiNsGetAttachedObject (Info->RegionNode);
568136384Srwatson
569136384Srwatson        /* An additional reference for the container */
570136384Srwatson
571136390Srwatson        AcpiUtAddReference (ObjDesc->Field.RegionObj);
572136390Srwatson
573136384Srwatson        ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
574136384Srwatson            "RegionField: BitOff %X, Off %X, Gran %X, Region %p\n",
575136384Srwatson            ObjDesc->Field.StartFieldBitOffset, ObjDesc->Field.BaseByteOffset,
576136384Srwatson            ObjDesc->Field.AccessByteWidth, ObjDesc->Field.RegionObj));
577136384Srwatson        break;
578136384Srwatson
579136384Srwatson
580136384Srwatson    case ACPI_TYPE_LOCAL_BANK_FIELD:
581136384Srwatson
582136390Srwatson        ObjDesc->BankField.Value     = Info->BankValue;
583136390Srwatson        ObjDesc->BankField.RegionObj = AcpiNsGetAttachedObject (
584136384Srwatson                                            Info->RegionNode);
585136384Srwatson        ObjDesc->BankField.BankObj   = AcpiNsGetAttachedObject (
586136390Srwatson                                            Info->RegisterNode);
587136390Srwatson
588136390Srwatson        /* An additional reference for the attached objects */
589136384Srwatson
590136384Srwatson        AcpiUtAddReference (ObjDesc->BankField.RegionObj);
591136390Srwatson        AcpiUtAddReference (ObjDesc->BankField.BankObj);
592136390Srwatson
593136390Srwatson        ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
594136384Srwatson            "Bank Field: BitOff %X, Off %X, Gran %X, Region %p, BankReg %p\n",
595136384Srwatson            ObjDesc->BankField.StartFieldBitOffset,
596136384Srwatson            ObjDesc->BankField.BaseByteOffset,
597136384Srwatson            ObjDesc->Field.AccessByteWidth,
598136384Srwatson            ObjDesc->BankField.RegionObj,
599136390Srwatson            ObjDesc->BankField.BankObj));
600136390Srwatson        break;
601136390Srwatson
602136384Srwatson
603136384Srwatson    case ACPI_TYPE_LOCAL_INDEX_FIELD:
604136384Srwatson
605136384Srwatson        ObjDesc->IndexField.IndexObj = AcpiNsGetAttachedObject (
606136384Srwatson                                            Info->RegisterNode);
607136384Srwatson        ObjDesc->IndexField.DataObj  = AcpiNsGetAttachedObject (
608136384Srwatson                                            Info->DataRegisterNode);
609136390Srwatson        ObjDesc->IndexField.Value    = (UINT32)
610136390Srwatson            (Info->FieldBitPosition / ACPI_MUL_8 (
611136384Srwatson                                        ObjDesc->Field.AccessByteWidth));
612136384Srwatson
613136384Srwatson        if (!ObjDesc->IndexField.DataObj || !ObjDesc->IndexField.IndexObj)
614136384Srwatson        {
615136384Srwatson            ACPI_REPORT_ERROR (("Null Index Object during field prep\n"));
616136384Srwatson            AcpiUtDeleteObjectDesc (ObjDesc);
617136384Srwatson            return_ACPI_STATUS (AE_AML_INTERNAL);
618136384Srwatson        }
619136390Srwatson
620136390Srwatson        /* An additional reference for the attached objects */
621136384Srwatson
622136384Srwatson        AcpiUtAddReference (ObjDesc->IndexField.DataObj);
623136390Srwatson        AcpiUtAddReference (ObjDesc->IndexField.IndexObj);
624136390Srwatson
625136384Srwatson        ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
626136384Srwatson            "IndexField: BitOff %X, Off %X, Value %X, Gran %X, Index %p, Data %p\n",
627136390Srwatson            ObjDesc->IndexField.StartFieldBitOffset,
628136390Srwatson            ObjDesc->IndexField.BaseByteOffset,
629136384Srwatson            ObjDesc->IndexField.Value,
630136384Srwatson            ObjDesc->Field.AccessByteWidth,
631136390Srwatson            ObjDesc->IndexField.IndexObj,
632136390Srwatson            ObjDesc->IndexField.DataObj));
633136384Srwatson        break;
634136384Srwatson
635136384Srwatson    default:
636158561Sbms        /* No other types should get here */
637158561Sbms        break;
638158561Sbms    }
639158561Sbms
640158561Sbms    /*
641158561Sbms     * Store the constructed descriptor (ObjDesc) into the parent Node,
642158561Sbms     * preserving the current type of that NamedObj.
643166437Sbms     */
644158561Sbms    Status = AcpiNsAttachObject (Info->FieldNode, ObjDesc,
645158561Sbms                    AcpiNsGetType (Info->FieldNode));
646158561Sbms
647158561Sbms    ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Set NamedObj %p [%4.4s], ObjDesc %p\n",
648158561Sbms            Info->FieldNode, AcpiUtGetNodeName (Info->FieldNode), ObjDesc));
649158561Sbms
650158561Sbms    /* Remove local reference to the object */
651158561Sbms
652158561Sbms    AcpiUtRemoveReference (ObjDesc);
653158561Sbms    return_ACPI_STATUS (Status);
654158561Sbms}
655158561Sbms
656158561Sbms