exprep.c revision 246849
1229997Sken/******************************************************************************
2229997Sken *
3232604Strasz * Module Name: exprep - ACPI AML (p-code) execution - field prep utilities
4229997Sken *
5229997Sken *****************************************************************************/
6232604Strasz
7232604Strasz/*
8232604Strasz * Copyright (C) 2000 - 2013, Intel Corp.
9229997Sken * All rights reserved.
10229997Sken *
11229997Sken * Redistribution and use in source and binary forms, with or without
12229997Sken * modification, are permitted provided that the following conditions
13229997Sken * are met:
14229997Sken * 1. Redistributions of source code must retain the above copyright
15229997Sken *    notice, this list of conditions, and the following disclaimer,
16229997Sken *    without modification.
17229997Sken * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18229997Sken *    substantially similar to the "NO WARRANTY" disclaimer below
19229997Sken *    ("Disclaimer") and any redistribution must be conditioned upon
20229997Sken *    including a substantially similar Disclaimer requirement for further
21229997Sken *    binary redistribution.
22229997Sken * 3. Neither the names of the above-listed copyright holders nor the names
23229997Sken *    of any contributors may be used to endorse or promote products derived
24229997Sken *    from this software without specific prior written permission.
25229997Sken *
26229997Sken * Alternatively, this software may be distributed under the terms of the
27229997Sken * GNU General Public License ("GPL") version 2 as published by the Free
28229997Sken * Software Foundation.
29229997Sken *
30229997Sken * NO WARRANTY
31229997Sken * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32229997Sken * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33229997Sken * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34229997Sken * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35229997Sken * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36229997Sken * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37229997Sken * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38229997Sken * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39229997Sken * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40229997Sken * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41229997Sken * POSSIBILITY OF SUCH DAMAGES.
42229997Sken */
43229997Sken
44229997Sken#define __EXPREP_C__
45229997Sken
46229997Sken#include <contrib/dev/acpica/include/acpi.h>
47229997Sken#include <contrib/dev/acpica/include/accommon.h>
48229997Sken#include <contrib/dev/acpica/include/acinterp.h>
49229997Sken#include <contrib/dev/acpica/include/amlcode.h>
50229997Sken#include <contrib/dev/acpica/include/acnamesp.h>
51229997Sken#include <contrib/dev/acpica/include/acdispat.h>
52229997Sken
53264886Smav
54229997Sken#define _COMPONENT          ACPI_EXECUTER
55229997Sken        ACPI_MODULE_NAME    ("exprep")
56229997Sken
57229997Sken/* Local prototypes */
58229997Sken
59287621Smavstatic UINT32
60229997SkenAcpiExDecodeFieldAccess (
61229997Sken    ACPI_OPERAND_OBJECT     *ObjDesc,
62287621Smav    UINT8                   FieldFlags,
63229997Sken    UINT32                  *ReturnByteAlignment);
64229997Sken
65229997Sken
66229997Sken#ifdef ACPI_UNDER_DEVELOPMENT
67229997Sken
68229997Skenstatic UINT32
69287621SmavAcpiExGenerateAccess (
70287621Smav    UINT32                  FieldBitOffset,
71229997Sken    UINT32                  FieldBitLength,
72229997Sken    UINT32                  RegionLength);
73229997Sken
74229997Sken/*******************************************************************************
75229997Sken *
76229997Sken * FUNCTION:    AcpiExGenerateAccess
77229997Sken *
78229997Sken * PARAMETERS:  FieldBitOffset      - Start of field within parent region/buffer
79229997Sken *              FieldBitLength      - Length of field in bits
80287500Smav *              RegionLength        - Length of parent in bytes
81264886Smav *
82229997Sken * RETURN:      Field granularity (8, 16, 32 or 64) and
83229997Sken *              ByteAlignment (1, 2, 3, or 4)
84229997Sken *
85229997Sken * DESCRIPTION: Generate an optimal access width for fields defined with the
86229997Sken *              AnyAcc keyword.
87287499Smav *
88264886Smav * NOTE: Need to have the RegionLength in order to check for boundary
89264886Smav *       conditions (end-of-region). However, the RegionLength is a deferred
90264886Smav *       operation. Therefore, to complete this implementation, the generation
91267877Smav *       of this access width must be deferred until the region length has
92229997Sken *       been evaluated.
93229997Sken *
94229997Sken ******************************************************************************/
95229997Sken
96229997Skenstatic UINT32
97229997SkenAcpiExGenerateAccess (
98229997Sken    UINT32                  FieldBitOffset,
99229997Sken    UINT32                  FieldBitLength,
100229997Sken    UINT32                  RegionLength)
101229997Sken{
102229997Sken    UINT32                  FieldByteLength;
103229997Sken    UINT32                  FieldByteOffset;
104229997Sken    UINT32                  FieldByteEndOffset;
105229997Sken    UINT32                  AccessByteWidth;
106229997Sken    UINT32                  FieldStartOffset;
107229997Sken    UINT32                  FieldEndOffset;
108287621Smav    UINT32                  MinimumAccessWidth = 0xFFFFFFFF;
109229997Sken    UINT32                  MinimumAccesses = 0xFFFFFFFF;
110229997Sken    UINT32                  Accesses;
111229997Sken
112229997Sken
113229997Sken    ACPI_FUNCTION_TRACE (ExGenerateAccess);
114264886Smav
115229997Sken
116229997Sken    /* Round Field start offset and length to "minimal" byte boundaries */
117229997Sken
118229997Sken    FieldByteOffset    = ACPI_DIV_8 (ACPI_ROUND_DOWN (FieldBitOffset, 8));
119229997Sken    FieldByteEndOffset = ACPI_DIV_8 (ACPI_ROUND_UP   (FieldBitLength +
120287499Smav                                                      FieldBitOffset, 8));
121232604Strasz    FieldByteLength    = FieldByteEndOffset - FieldByteOffset;
122232604Strasz
123264886Smav    ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
124229997Sken        "Bit length %u, Bit offset %u\n",
125229997Sken        FieldBitLength, FieldBitOffset));
126229997Sken
127229997Sken    ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
128229997Sken        "Byte Length %u, Byte Offset %u, End Offset %u\n",
129229997Sken        FieldByteLength, FieldByteOffset, FieldByteEndOffset));
130229997Sken
131229997Sken    /*
132230334Sken     * Iterative search for the maximum access width that is both aligned
133230334Sken     * and does not go beyond the end of the region
134230334Sken     *
135230334Sken     * Start at ByteAcc and work upwards to QwordAcc max. (1,2,4,8 bytes)
136230334Sken     */
137230334Sken    for (AccessByteWidth = 1; AccessByteWidth <= 8; AccessByteWidth <<= 1)
138230334Sken    {
139230334Sken        /*
140229997Sken         * 1) Round end offset up to next access boundary and make sure that
141229997Sken         *    this does not go beyond the end of the parent region.
142229997Sken         * 2) When the Access width is greater than the FieldByteLength, we
143229997Sken         *    are done. (This does not optimize for the perfectly aligned
144229997Sken         *    case yet).
145229997Sken         */
146229997Sken        if (ACPI_ROUND_UP (FieldByteEndOffset, AccessByteWidth) <= RegionLength)
147229997Sken        {
148288220Smav            FieldStartOffset =
149229997Sken                ACPI_ROUND_DOWN (FieldByteOffset, AccessByteWidth) /
150240993Strasz                AccessByteWidth;
151229997Sken
152229997Sken            FieldEndOffset =
153229997Sken                ACPI_ROUND_UP ((FieldByteLength + FieldByteOffset),
154267877Smav                    AccessByteWidth) / AccessByteWidth;
155229997Sken
156264886Smav            Accesses = FieldEndOffset - FieldStartOffset;
157229997Sken
158229997Sken            ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
159229997Sken                "AccessWidth %u end is within region\n", AccessByteWidth));
160229997Sken
161229997Sken            ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
162240993Strasz                "Field Start %u, Field End %u -- requires %u accesses\n",
163229997Sken                FieldStartOffset, FieldEndOffset, Accesses));
164229997Sken
165229997Sken            /* Single access is optimal */
166229997Sken
167229997Sken            if (Accesses <= 1)
168229997Sken            {
169229997Sken                ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
170229997Sken                    "Entire field can be accessed with one operation of size %u\n",
171229997Sken                    AccessByteWidth));
172229997Sken                return_VALUE (AccessByteWidth);
173229997Sken            }
174229997Sken
175288220Smav            /*
176229997Sken             * Fits in the region, but requires more than one read/write.
177229997Sken             * try the next wider access on next iteration
178229997Sken             */
179229997Sken            if (Accesses < MinimumAccesses)
180229997Sken            {
181229997Sken                MinimumAccesses    = Accesses;
182229997Sken                MinimumAccessWidth = AccessByteWidth;
183229997Sken            }
184229997Sken        }
185229997Sken        else
186229997Sken        {
187229997Sken            ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
188229997Sken                "AccessWidth %u end is NOT within region\n", AccessByteWidth));
189229997Sken            if (AccessByteWidth == 1)
190229997Sken            {
191229997Sken                ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
192229997Sken                    "Field goes beyond end-of-region!\n"));
193229997Sken
194229997Sken                /* Field does not fit in the region at all */
195229997Sken
196287499Smav                return_VALUE (0);
197287499Smav            }
198229997Sken
199229997Sken            /*
200229997Sken             * This width goes beyond the end-of-region, back off to
201229997Sken             * previous access
202229997Sken             */
203229997Sken            ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
204229997Sken                "Backing off to previous optimal access width of %u\n",
205229997Sken                MinimumAccessWidth));
206229997Sken            return_VALUE (MinimumAccessWidth);
207229997Sken        }
208229997Sken    }
209229997Sken
210229997Sken    /*
211229997Sken     * Could not read/write field with one operation,
212229997Sken     * just use max access width
213229997Sken     */
214229997Sken    ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
215229997Sken        "Cannot access field in one operation, using width 8\n"));
216229997Sken    return_VALUE (8);
217229997Sken}
218229997Sken#endif /* ACPI_UNDER_DEVELOPMENT */
219229997Sken
220287499Smav
221264886Smav/*******************************************************************************
222229997Sken *
223229997Sken * FUNCTION:    AcpiExDecodeFieldAccess
224229997Sken *
225229997Sken * PARAMETERS:  ObjDesc             - Field object
226229997Sken *              FieldFlags          - Encoded fieldflags (contains access bits)
227287499Smav *              ReturnByteAlignment - Where the byte alignment is returned
228264886Smav *
229287499Smav * RETURN:      Field granularity (8, 16, 32 or 64) and
230264886Smav *              ByteAlignment (1, 2, 3, or 4)
231288215Smav *
232264886Smav * DESCRIPTION: Decode the AccessType bits of a field definition.
233264886Smav *
234288215Smav ******************************************************************************/
235264886Smav
236264886Smavstatic UINT32
237264886SmavAcpiExDecodeFieldAccess (
238264886Smav    ACPI_OPERAND_OBJECT     *ObjDesc,
239275058Smav    UINT8                   FieldFlags,
240275058Smav    UINT32                  *ReturnByteAlignment)
241275058Smav{
242275058Smav    UINT32                  Access;
243267519Smav    UINT32                  ByteAlignment;
244267877Smav    UINT32                  BitLength;
245264886Smav
246264886Smav
247267877Smav    ACPI_FUNCTION_TRACE (ExDecodeFieldAccess);
248264886Smav
249264886Smav
250264886Smav    Access = (FieldFlags & AML_FIELD_ACCESS_TYPE_MASK);
251264886Smav
252275009Smav    switch (Access)
253275058Smav    {
254275058Smav    case AML_FIELD_ACCESS_ANY:
255275058Smav
256229997Sken#ifdef ACPI_UNDER_DEVELOPMENT
257229997Sken        ByteAlignment =
258229997Sken            AcpiExGenerateAccess (ObjDesc->CommonField.StartFieldBitOffset,
259229997Sken                ObjDesc->CommonField.BitLength,
260229997Sken                0xFFFFFFFF /* Temp until we pass RegionLength as parameter */);
261229997Sken        BitLength = ByteAlignment * 8;
262229997Sken#endif
263229997Sken
264229997Sken        ByteAlignment = 1;
265229997Sken        BitLength = 8;
266229997Sken        break;
267229997Sken
268229997Sken    case AML_FIELD_ACCESS_BYTE:
269267537Smav    case AML_FIELD_ACCESS_BUFFER:   /* ACPI 2.0 (SMBus Buffer) */
270229997Sken        ByteAlignment = 1;
271229997Sken        BitLength     = 8;
272229997Sken        break;
273229997Sken
274229997Sken    case AML_FIELD_ACCESS_WORD:
275229997Sken        ByteAlignment = 2;
276287499Smav        BitLength     = 16;
277267537Smav        break;
278229997Sken
279287499Smav    case AML_FIELD_ACCESS_DWORD:
280267519Smav        ByteAlignment = 4;
281267537Smav        BitLength     = 32;
282267537Smav        break;
283267537Smav
284267537Smav    case AML_FIELD_ACCESS_QWORD:    /* ACPI 2.0 */
285267537Smav        ByteAlignment = 8;
286267537Smav        BitLength     = 64;
287267519Smav        break;
288287499Smav
289264886Smav    default:
290264886Smav        /* Invalid field access type */
291264886Smav
292229997Sken        ACPI_ERROR ((AE_INFO,
293264886Smav            "Unknown field access type 0x%X",
294264886Smav            Access));
295264886Smav        return_UINT32 (0);
296264886Smav    }
297264886Smav
298264886Smav    if (ObjDesc->Common.Type == ACPI_TYPE_BUFFER_FIELD)
299264886Smav    {
300264886Smav        /*
301264886Smav         * BufferField access can be on any byte boundary, so the
302229997Sken         * ByteAlignment is always 1 byte -- regardless of any ByteAlignment
303264886Smav         * implied by the field access type.
304267519Smav         */
305229997Sken        ByteAlignment = 1;
306264886Smav    }
307264886Smav
308229997Sken    *ReturnByteAlignment = ByteAlignment;
309264886Smav    return_UINT32 (BitLength);
310229997Sken}
311229997Sken
312264886Smav
313229997Sken/*******************************************************************************
314275953Smav *
315264886Smav * FUNCTION:    AcpiExPrepCommonFieldObject
316229997Sken *
317229997Sken * PARAMETERS:  ObjDesc             - The field object
318264886Smav *              FieldFlags          - Access, LockRule, and UpdateRule.
319264886Smav *                                    The format of a FieldFlag is described
320229997Sken *                                    in the ACPI specification
321264886Smav *              FieldAttribute      - Special attributes (not used)
322229997Sken *              FieldBitPosition    - Field start position
323264886Smav *              FieldBitLength      - Field length in number of bits
324264886Smav *
325264886Smav * RETURN:      Status
326264886Smav *
327229997Sken * DESCRIPTION: Initialize the areas of the field object that are common
328267514Smav *              to the various types of fields. Note: This is very "sensitive"
329267514Smav *              code because we are solving the general case for field
330264886Smav *              alignment.
331264886Smav *
332264886Smav ******************************************************************************/
333267519Smav
334229997SkenACPI_STATUS
335288215SmavAcpiExPrepCommonFieldObject (
336229997Sken    ACPI_OPERAND_OBJECT     *ObjDesc,
337229997Sken    UINT8                   FieldFlags,
338264886Smav    UINT8                   FieldAttribute,
339229997Sken    UINT32                  FieldBitPosition,
340264886Smav    UINT32                  FieldBitLength)
341264886Smav{
342264886Smav    UINT32                  AccessBitWidth;
343264886Smav    UINT32                  ByteAlignment;
344264886Smav    UINT32                  NearestByteAddress;
345264886Smav
346264886Smav
347264886Smav    ACPI_FUNCTION_TRACE (ExPrepCommonFieldObject);
348264886Smav
349264886Smav
350267877Smav    /*
351264886Smav     * Note: the structure being initialized is the
352264886Smav     * ACPI_COMMON_FIELD_INFO;  No structure fields outside of the common
353264886Smav     * area are initialized by this procedure.
354264886Smav     */
355264886Smav    ObjDesc->CommonField.FieldFlags = FieldFlags;
356267877Smav    ObjDesc->CommonField.Attribute  = FieldAttribute;
357264886Smav    ObjDesc->CommonField.BitLength  = FieldBitLength;
358267877Smav
359264886Smav    /*
360264886Smav     * Decode the access type so we can compute offsets. The access type gives
361264886Smav     * two pieces of information - the width of each field access and the
362264886Smav     * necessary ByteAlignment (address granularity) of the access.
363264886Smav     *
364264886Smav     * For AnyAcc, the AccessBitWidth is the largest width that is both
365264886Smav     * necessary and possible in an attempt to access the whole field in one
366264886Smav     * I/O operation. However, for AnyAcc, the ByteAlignment is always one
367264886Smav     * byte.
368267877Smav     *
369229997Sken     * For all Buffer Fields, the ByteAlignment is always one byte.
370229997Sken     *
371229997Sken     * For all other access types (Byte, Word, Dword, Qword), the Bitwidth is
372229997Sken     * the same (equivalent) as the ByteAlignment.
373229997Sken     */
374229997Sken    AccessBitWidth = AcpiExDecodeFieldAccess (ObjDesc, FieldFlags,
375288220Smav                        &ByteAlignment);
376288220Smav    if (!AccessBitWidth)
377229997Sken    {
378229997Sken        return_ACPI_STATUS (AE_AML_OPERAND_VALUE);
379229997Sken    }
380229997Sken
381288220Smav    /* Setup width (access granularity) fields (values are: 1, 2, 4, 8) */
382229997Sken
383229997Sken    ObjDesc->CommonField.AccessByteWidth = (UINT8)
384229997Sken        ACPI_DIV_8 (AccessBitWidth);
385287499Smav
386229997Sken    /*
387229997Sken     * BaseByteOffset is the address of the start of the field within the
388229997Sken     * region. It is the byte address of the first *datum* (field-width data
389229997Sken     * unit) of the field. (i.e., the first datum that contains at least the
390232604Strasz     * first *bit* of the field.)
391232604Strasz     *
392232604Strasz     * Note: ByteAlignment is always either equal to the AccessBitWidth or 8
393229997Sken     * (Byte access), and it defines the addressing granularity of the parent
394229997Sken     * region or buffer.
395229997Sken     */
396229997Sken    NearestByteAddress =
397229997Sken        ACPI_ROUND_BITS_DOWN_TO_BYTES (FieldBitPosition);
398229997Sken    ObjDesc->CommonField.BaseByteOffset = (UINT32)
399229997Sken        ACPI_ROUND_DOWN (NearestByteAddress, ByteAlignment);
400229997Sken
401229997Sken    /*
402229997Sken     * StartFieldBitOffset is the offset of the first bit of the field within
403229997Sken     * a field datum.
404229997Sken     */
405229997Sken    ObjDesc->CommonField.StartFieldBitOffset = (UINT8)
406229997Sken        (FieldBitPosition - ACPI_MUL_8 (ObjDesc->CommonField.BaseByteOffset));
407229997Sken
408229997Sken    return_ACPI_STATUS (AE_OK);
409229997Sken}
410229997Sken
411229997Sken
412229997Sken/*******************************************************************************
413229997Sken *
414229997Sken * FUNCTION:    AcpiExPrepFieldValue
415229997Sken *
416229997Sken * PARAMETERS:  Info    - Contains all field creation info
417229997Sken *
418229997Sken * RETURN:      Status
419229997Sken *
420229997Sken * DESCRIPTION: Construct an object of type ACPI_OPERAND_OBJECT with a
421287499Smav *              subtype of DefField and connect it to the parent Node.
422229997Sken *
423229997Sken ******************************************************************************/
424229997Sken
425229997SkenACPI_STATUS
426229997SkenAcpiExPrepFieldValue (
427229997Sken    ACPI_CREATE_FIELD_INFO  *Info)
428229997Sken{
429229997Sken    ACPI_OPERAND_OBJECT     *ObjDesc;
430229997Sken    ACPI_OPERAND_OBJECT     *SecondDesc = NULL;
431229997Sken    ACPI_STATUS             Status;
432287499Smav    UINT32                  AccessByteWidth;
433229997Sken    UINT32                  Type;
434229997Sken
435229997Sken
436229997Sken    ACPI_FUNCTION_TRACE (ExPrepFieldValue);
437229997Sken
438229997Sken
439229997Sken    /* Parameter validation */
440229997Sken
441229997Sken    if (Info->FieldType != ACPI_TYPE_LOCAL_INDEX_FIELD)
442229997Sken    {
443229997Sken        if (!Info->RegionNode)
444229997Sken        {
445229997Sken            ACPI_ERROR ((AE_INFO, "Null RegionNode"));
446229997Sken            return_ACPI_STATUS (AE_AML_NO_OPERAND);
447229997Sken        }
448229997Sken
449229997Sken        Type = AcpiNsGetType (Info->RegionNode);
450229997Sken        if (Type != ACPI_TYPE_REGION)
451229997Sken        {
452287499Smav            ACPI_ERROR ((AE_INFO, "Needed Region, found type 0x%X (%s)",
453229997Sken                Type, AcpiUtGetTypeName (Type)));
454229997Sken
455229997Sken            return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
456229997Sken        }
457252569Smav    }
458252569Smav
459252569Smav    /* Allocate a new field object */
460229997Sken
461229997Sken    ObjDesc = AcpiUtCreateInternalObject (Info->FieldType);
462229997Sken    if (!ObjDesc)
463229997Sken    {
464229997Sken        return_ACPI_STATUS (AE_NO_MEMORY);
465229997Sken    }
466288220Smav
467229997Sken    /* Initialize areas of the object that are common to all fields */
468229997Sken
469229997Sken    ObjDesc->CommonField.Node = Info->FieldNode;
470229997Sken    Status = AcpiExPrepCommonFieldObject (ObjDesc,
471229997Sken                Info->FieldFlags, Info->Attribute,
472229997Sken                Info->FieldBitPosition, Info->FieldBitLength);
473229997Sken    if (ACPI_FAILURE (Status))
474229997Sken    {
475229997Sken        AcpiUtDeleteObjectDesc (ObjDesc);
476229997Sken        return_ACPI_STATUS (Status);
477229997Sken    }
478229997Sken
479229997Sken    /* Initialize areas of the object that are specific to the field type */
480229997Sken
481229997Sken    switch (Info->FieldType)
482229997Sken    {
483229997Sken    case ACPI_TYPE_LOCAL_REGION_FIELD:
484229997Sken
485264886Smav        ObjDesc->Field.RegionObj = AcpiNsGetAttachedObject (Info->RegionNode);
486287670Smav
487264886Smav        /* Fields specific to GenericSerialBus fields */
488287499Smav
489267877Smav        ObjDesc->Field.AccessLength = Info->AccessLength;
490229997Sken
491264886Smav        if (Info->ConnectionNode)
492229997Sken        {
493229997Sken            SecondDesc = Info->ConnectionNode->Object;
494229997Sken            if (!(SecondDesc->Common.Flags & AOPOBJ_DATA_VALID))
495229997Sken            {
496229997Sken                Status = AcpiDsGetBufferArguments (SecondDesc);
497229997Sken                if (ACPI_FAILURE (Status))
498229997Sken                {
499229997Sken                    AcpiUtDeleteObjectDesc (ObjDesc);
500229997Sken                    return_ACPI_STATUS (Status);
501229997Sken                }
502229997Sken            }
503287499Smav
504229997Sken            ObjDesc->Field.ResourceBuffer = SecondDesc->Buffer.Pointer;
505229997Sken            ObjDesc->Field.ResourceLength = (UINT16) SecondDesc->Buffer.Length;
506287499Smav        }
507229997Sken        else if (Info->ResourceBuffer)
508267481Smav        {
509229997Sken            ObjDesc->Field.ResourceBuffer = Info->ResourceBuffer;
510287499Smav            ObjDesc->Field.ResourceLength = Info->ResourceLength;
511229997Sken        }
512229997Sken
513229997Sken        /* Allow full data read from EC address space */
514229997Sken
515287499Smav        if ((ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_EC) &&
516287499Smav            (ObjDesc->CommonField.BitLength > 8))
517287499Smav        {
518287500Smav            AccessByteWidth = ACPI_ROUND_BITS_UP_TO_BYTES (
519287499Smav                ObjDesc->CommonField.BitLength);
520264886Smav
521287499Smav            /* Maximum byte width supported is 255 */
522229997Sken
523229997Sken            if (AccessByteWidth < 256)
524287499Smav            {
525229997Sken                ObjDesc->CommonField.AccessByteWidth = (UINT8) AccessByteWidth;
526287499Smav            }
527287499Smav        }
528287621Smav
529287621Smav        /* An additional reference for the container */
530287621Smav
531287621Smav        AcpiUtAddReference (ObjDesc->Field.RegionObj);
532287621Smav
533287621Smav        ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
534287621Smav            "RegionField: BitOff %X, Off %X, Gran %X, Region %p\n",
535229997Sken            ObjDesc->Field.StartFieldBitOffset, ObjDesc->Field.BaseByteOffset,
536287499Smav            ObjDesc->Field.AccessByteWidth, ObjDesc->Field.RegionObj));
537287499Smav        break;
538287499Smav
539287499Smav
540287499Smav    case ACPI_TYPE_LOCAL_BANK_FIELD:
541287499Smav
542229997Sken        ObjDesc->BankField.Value = Info->BankValue;
543229997Sken        ObjDesc->BankField.RegionObj =
544287499Smav            AcpiNsGetAttachedObject (Info->RegionNode);
545229997Sken        ObjDesc->BankField.BankObj =
546229997Sken            AcpiNsGetAttachedObject (Info->RegisterNode);
547287499Smav
548287499Smav        /* An additional reference for the attached objects */
549287499Smav
550287499Smav        AcpiUtAddReference (ObjDesc->BankField.RegionObj);
551287499Smav        AcpiUtAddReference (ObjDesc->BankField.BankObj);
552229997Sken
553229997Sken        ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
554229997Sken            "Bank Field: BitOff %X, Off %X, Gran %X, Region %p, BankReg %p\n",
555287499Smav            ObjDesc->BankField.StartFieldBitOffset,
556229997Sken            ObjDesc->BankField.BaseByteOffset,
557229997Sken            ObjDesc->Field.AccessByteWidth,
558287499Smav            ObjDesc->BankField.RegionObj,
559267481Smav            ObjDesc->BankField.BankObj));
560287499Smav
561287499Smav        /*
562287499Smav         * Remember location in AML stream of the field unit
563287499Smav         * opcode and operands -- since the BankValue
564287499Smav         * operands must be evaluated.
565287499Smav         */
566287499Smav        SecondDesc = ObjDesc->Common.NextObject;
567287499Smav        SecondDesc->Extra.AmlStart = ACPI_CAST_PTR (ACPI_PARSE_OBJECT,
568287499Smav            Info->DataRegisterNode)->Named.Data;
569287499Smav        SecondDesc->Extra.AmlLength = ACPI_CAST_PTR (ACPI_PARSE_OBJECT,
570287499Smav            Info->DataRegisterNode)->Named.Length;
571287499Smav
572254759Strasz        break;
573229997Sken
574287499Smav
575287499Smav    case ACPI_TYPE_LOCAL_INDEX_FIELD:
576229997Sken
577287499Smav        /* Get the Index and Data registers */
578229997Sken
579287499Smav        ObjDesc->IndexField.IndexObj =
580287499Smav            AcpiNsGetAttachedObject (Info->RegisterNode);
581287499Smav        ObjDesc->IndexField.DataObj =
582229997Sken            AcpiNsGetAttachedObject (Info->DataRegisterNode);
583229997Sken
584229997Sken        if (!ObjDesc->IndexField.DataObj || !ObjDesc->IndexField.IndexObj)
585287499Smav        {
586287499Smav            ACPI_ERROR ((AE_INFO, "Null Index Object during field prep"));
587229997Sken            AcpiUtDeleteObjectDesc (ObjDesc);
588229997Sken            return_ACPI_STATUS (AE_AML_INTERNAL);
589229997Sken        }
590275953Smav
591229997Sken        /* An additional reference for the attached objects */
592287499Smav
593287499Smav        AcpiUtAddReference (ObjDesc->IndexField.DataObj);
594275953Smav        AcpiUtAddReference (ObjDesc->IndexField.IndexObj);
595229997Sken
596229997Sken        /*
597229997Sken         * April 2006: Changed to match MS behavior
598287499Smav         *
599287499Smav         * The value written to the Index register is the byte offset of the
600229997Sken         * target field in units of the granularity of the IndexField
601229997Sken         *
602229997Sken         * Previously, the value was calculated as an index in terms of the
603275953Smav         * width of the Data register, as below:
604229997Sken         *
605287499Smav         *      ObjDesc->IndexField.Value = (UINT32)
606287499Smav         *          (Info->FieldBitPosition / ACPI_MUL_8 (
607275953Smav         *              ObjDesc->Field.AccessByteWidth));
608229997Sken         *
609229997Sken         * February 2006: Tried value as a byte offset:
610264886Smav         *      ObjDesc->IndexField.Value = (UINT32)
611267877Smav         *          ACPI_DIV_8 (Info->FieldBitPosition);
612264886Smav         */
613264886Smav        ObjDesc->IndexField.Value = (UINT32) ACPI_ROUND_DOWN (
614264886Smav            ACPI_DIV_8 (Info->FieldBitPosition),
615264886Smav            ObjDesc->IndexField.AccessByteWidth);
616264886Smav
617264886Smav        ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
618264886Smav            "IndexField: BitOff %X, Off %X, Value %X, Gran %X, Index %p, Data %p\n",
619264886Smav            ObjDesc->IndexField.StartFieldBitOffset,
620264886Smav            ObjDesc->IndexField.BaseByteOffset,
621264886Smav            ObjDesc->IndexField.Value,
622264886Smav            ObjDesc->Field.AccessByteWidth,
623264886Smav            ObjDesc->IndexField.IndexObj,
624264886Smav            ObjDesc->IndexField.DataObj));
625264886Smav        break;
626264886Smav
627264886Smav    default:
628264886Smav        /* No other types should get here */
629264886Smav        break;
630264886Smav    }
631229997Sken
632229997Sken    /*
633229997Sken     * Store the constructed descriptor (ObjDesc) into the parent Node,
634229997Sken     * preserving the current type of that NamedObj.
635229997Sken     */
636287499Smav    Status = AcpiNsAttachObject (Info->FieldNode, ObjDesc,
637229997Sken                AcpiNsGetType (Info->FieldNode));
638229997Sken
639229997Sken    ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Set NamedObj %p [%4.4s], ObjDesc %p\n",
640229997Sken        Info->FieldNode, AcpiUtGetNodeName (Info->FieldNode), ObjDesc));
641229997Sken
642229997Sken    /* Remove local reference to the object */
643229997Sken
644229997Sken    AcpiUtRemoveReference (ObjDesc);
645229997Sken    return_ACPI_STATUS (Status);
646229997Sken}
647229997Sken