exprep.c revision 229989
1
2/******************************************************************************
3 *
4 * Module Name: exprep - ACPI AML (p-code) execution - field prep utilities
5 *
6 *****************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2012, Intel Corp.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 *    notice, this list of conditions, and the following disclaimer,
17 *    without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 *    substantially similar to the "NO WARRANTY" disclaimer below
20 *    ("Disclaimer") and any redistribution must be conditioned upon
21 *    including a substantially similar Disclaimer requirement for further
22 *    binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 *    of any contributors may be used to endorse or promote products derived
25 *    from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45#define __EXPREP_C__
46
47#include <contrib/dev/acpica/include/acpi.h>
48#include <contrib/dev/acpica/include/accommon.h>
49#include <contrib/dev/acpica/include/acinterp.h>
50#include <contrib/dev/acpica/include/amlcode.h>
51#include <contrib/dev/acpica/include/acnamesp.h>
52#include <contrib/dev/acpica/include/acdispat.h>
53
54
55#define _COMPONENT          ACPI_EXECUTER
56        ACPI_MODULE_NAME    ("exprep")
57
58/* Local prototypes */
59
60static UINT32
61AcpiExDecodeFieldAccess (
62    ACPI_OPERAND_OBJECT     *ObjDesc,
63    UINT8                   FieldFlags,
64    UINT32                  *ReturnByteAlignment);
65
66
67#ifdef ACPI_UNDER_DEVELOPMENT
68
69static UINT32
70AcpiExGenerateAccess (
71    UINT32                  FieldBitOffset,
72    UINT32                  FieldBitLength,
73    UINT32                  RegionLength);
74
75/*******************************************************************************
76 *
77 * FUNCTION:    AcpiExGenerateAccess
78 *
79 * PARAMETERS:  FieldBitOffset      - Start of field within parent region/buffer
80 *              FieldBitLength      - Length of field in bits
81 *              RegionLength        - Length of parent in bytes
82 *
83 * RETURN:      Field granularity (8, 16, 32 or 64) and
84 *              ByteAlignment (1, 2, 3, or 4)
85 *
86 * DESCRIPTION: Generate an optimal access width for fields defined with the
87 *              AnyAcc keyword.
88 *
89 * NOTE: Need to have the RegionLength in order to check for boundary
90 *       conditions (end-of-region).  However, the RegionLength is a deferred
91 *       operation.  Therefore, to complete this implementation, the generation
92 *       of this access width must be deferred until the region length has
93 *       been evaluated.
94 *
95 ******************************************************************************/
96
97static UINT32
98AcpiExGenerateAccess (
99    UINT32                  FieldBitOffset,
100    UINT32                  FieldBitLength,
101    UINT32                  RegionLength)
102{
103    UINT32                  FieldByteLength;
104    UINT32                  FieldByteOffset;
105    UINT32                  FieldByteEndOffset;
106    UINT32                  AccessByteWidth;
107    UINT32                  FieldStartOffset;
108    UINT32                  FieldEndOffset;
109    UINT32                  MinimumAccessWidth = 0xFFFFFFFF;
110    UINT32                  MinimumAccesses = 0xFFFFFFFF;
111    UINT32                  Accesses;
112
113
114    ACPI_FUNCTION_TRACE (ExGenerateAccess);
115
116
117    /* Round Field start offset and length to "minimal" byte boundaries */
118
119    FieldByteOffset    = ACPI_DIV_8 (ACPI_ROUND_DOWN (FieldBitOffset, 8));
120    FieldByteEndOffset = ACPI_DIV_8 (ACPI_ROUND_UP   (FieldBitLength +
121                                                      FieldBitOffset, 8));
122    FieldByteLength    = FieldByteEndOffset - FieldByteOffset;
123
124    ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
125        "Bit length %u, Bit offset %u\n",
126        FieldBitLength, FieldBitOffset));
127
128    ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
129        "Byte Length %u, Byte Offset %u, End Offset %u\n",
130        FieldByteLength, FieldByteOffset, FieldByteEndOffset));
131
132    /*
133     * Iterative search for the maximum access width that is both aligned
134     * and does not go beyond the end of the region
135     *
136     * Start at ByteAcc and work upwards to QwordAcc max. (1,2,4,8 bytes)
137     */
138    for (AccessByteWidth = 1; AccessByteWidth <= 8; AccessByteWidth <<= 1)
139    {
140        /*
141         * 1) Round end offset up to next access boundary and make sure that
142         *    this does not go beyond the end of the parent region.
143         * 2) When the Access width is greater than the FieldByteLength, we
144         *    are done. (This does not optimize for the perfectly aligned
145         *    case yet).
146         */
147        if (ACPI_ROUND_UP (FieldByteEndOffset, AccessByteWidth) <= RegionLength)
148        {
149            FieldStartOffset =
150                ACPI_ROUND_DOWN (FieldByteOffset, AccessByteWidth) /
151                AccessByteWidth;
152
153            FieldEndOffset =
154                ACPI_ROUND_UP ((FieldByteLength + FieldByteOffset),
155                    AccessByteWidth) / AccessByteWidth;
156
157            Accesses = FieldEndOffset - FieldStartOffset;
158
159            ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
160                "AccessWidth %u end is within region\n", AccessByteWidth));
161
162            ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
163                "Field Start %u, Field End %u -- requires %u accesses\n",
164                FieldStartOffset, FieldEndOffset, Accesses));
165
166            /* Single access is optimal */
167
168            if (Accesses <= 1)
169            {
170                ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
171                    "Entire field can be accessed with one operation of size %u\n",
172                    AccessByteWidth));
173                return_VALUE (AccessByteWidth);
174            }
175
176            /*
177             * Fits in the region, but requires more than one read/write.
178             * try the next wider access on next iteration
179             */
180            if (Accesses < MinimumAccesses)
181            {
182                MinimumAccesses    = Accesses;
183                MinimumAccessWidth = AccessByteWidth;
184            }
185        }
186        else
187        {
188            ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
189                "AccessWidth %u end is NOT within region\n", AccessByteWidth));
190            if (AccessByteWidth == 1)
191            {
192                ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
193                    "Field goes beyond end-of-region!\n"));
194
195                /* Field does not fit in the region at all */
196
197                return_VALUE (0);
198            }
199
200            /*
201             * This width goes beyond the end-of-region, back off to
202             * previous access
203             */
204            ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
205                "Backing off to previous optimal access width of %u\n",
206                MinimumAccessWidth));
207            return_VALUE (MinimumAccessWidth);
208        }
209    }
210
211    /*
212     * Could not read/write field with one operation,
213     * just use max access width
214     */
215    ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
216        "Cannot access field in one operation, using width 8\n"));
217    return_VALUE (8);
218}
219#endif /* ACPI_UNDER_DEVELOPMENT */
220
221
222/*******************************************************************************
223 *
224 * FUNCTION:    AcpiExDecodeFieldAccess
225 *
226 * PARAMETERS:  ObjDesc             - Field object
227 *              FieldFlags          - Encoded fieldflags (contains access bits)
228 *              ReturnByteAlignment - Where the byte alignment is returned
229 *
230 * RETURN:      Field granularity (8, 16, 32 or 64) and
231 *              ByteAlignment (1, 2, 3, or 4)
232 *
233 * DESCRIPTION: Decode the AccessType bits of a field definition.
234 *
235 ******************************************************************************/
236
237static UINT32
238AcpiExDecodeFieldAccess (
239    ACPI_OPERAND_OBJECT     *ObjDesc,
240    UINT8                   FieldFlags,
241    UINT32                  *ReturnByteAlignment)
242{
243    UINT32                  Access;
244    UINT32                  ByteAlignment;
245    UINT32                  BitLength;
246
247
248    ACPI_FUNCTION_TRACE (ExDecodeFieldAccess);
249
250
251    Access = (FieldFlags & AML_FIELD_ACCESS_TYPE_MASK);
252
253    switch (Access)
254    {
255    case AML_FIELD_ACCESS_ANY:
256
257#ifdef ACPI_UNDER_DEVELOPMENT
258        ByteAlignment =
259            AcpiExGenerateAccess (ObjDesc->CommonField.StartFieldBitOffset,
260                ObjDesc->CommonField.BitLength,
261                0xFFFFFFFF /* Temp until we pass RegionLength as parameter */);
262        BitLength = ByteAlignment * 8;
263#endif
264
265        ByteAlignment = 1;
266        BitLength = 8;
267        break;
268
269    case AML_FIELD_ACCESS_BYTE:
270    case AML_FIELD_ACCESS_BUFFER:   /* ACPI 2.0 (SMBus Buffer) */
271        ByteAlignment = 1;
272        BitLength     = 8;
273        break;
274
275    case AML_FIELD_ACCESS_WORD:
276        ByteAlignment = 2;
277        BitLength     = 16;
278        break;
279
280    case AML_FIELD_ACCESS_DWORD:
281        ByteAlignment = 4;
282        BitLength     = 32;
283        break;
284
285    case AML_FIELD_ACCESS_QWORD:    /* ACPI 2.0 */
286        ByteAlignment = 8;
287        BitLength     = 64;
288        break;
289
290    default:
291        /* Invalid field access type */
292
293        ACPI_ERROR ((AE_INFO,
294            "Unknown field access type 0x%X",
295            Access));
296        return_UINT32 (0);
297    }
298
299    if (ObjDesc->Common.Type == ACPI_TYPE_BUFFER_FIELD)
300    {
301        /*
302         * BufferField access can be on any byte boundary, so the
303         * ByteAlignment is always 1 byte -- regardless of any ByteAlignment
304         * implied by the field access type.
305         */
306        ByteAlignment = 1;
307    }
308
309    *ReturnByteAlignment = ByteAlignment;
310    return_UINT32 (BitLength);
311}
312
313
314/*******************************************************************************
315 *
316 * FUNCTION:    AcpiExPrepCommonFieldObject
317 *
318 * PARAMETERS:  ObjDesc             - The field object
319 *              FieldFlags          - Access, LockRule, and UpdateRule.
320 *                                    The format of a FieldFlag is described
321 *                                    in the ACPI specification
322 *              FieldAttribute      - Special attributes (not used)
323 *              FieldBitPosition    - Field start position
324 *              FieldBitLength      - Field length in number of bits
325 *
326 * RETURN:      Status
327 *
328 * DESCRIPTION: Initialize the areas of the field object that are common
329 *              to the various types of fields.  Note: This is very "sensitive"
330 *              code because we are solving the general case for field
331 *              alignment.
332 *
333 ******************************************************************************/
334
335ACPI_STATUS
336AcpiExPrepCommonFieldObject (
337    ACPI_OPERAND_OBJECT     *ObjDesc,
338    UINT8                   FieldFlags,
339    UINT8                   FieldAttribute,
340    UINT32                  FieldBitPosition,
341    UINT32                  FieldBitLength)
342{
343    UINT32                  AccessBitWidth;
344    UINT32                  ByteAlignment;
345    UINT32                  NearestByteAddress;
346
347
348    ACPI_FUNCTION_TRACE (ExPrepCommonFieldObject);
349
350
351    /*
352     * Note: the structure being initialized is the
353     * ACPI_COMMON_FIELD_INFO;  No structure fields outside of the common
354     * area are initialized by this procedure.
355     */
356    ObjDesc->CommonField.FieldFlags = FieldFlags;
357    ObjDesc->CommonField.Attribute  = FieldAttribute;
358    ObjDesc->CommonField.BitLength  = FieldBitLength;
359
360    /*
361     * Decode the access type so we can compute offsets.  The access type gives
362     * two pieces of information - the width of each field access and the
363     * necessary ByteAlignment (address granularity) of the access.
364     *
365     * For AnyAcc, the AccessBitWidth is the largest width that is both
366     * necessary and possible in an attempt to access the whole field in one
367     * I/O operation.  However, for AnyAcc, the ByteAlignment is always one
368     * byte.
369     *
370     * For all Buffer Fields, the ByteAlignment is always one byte.
371     *
372     * For all other access types (Byte, Word, Dword, Qword), the Bitwidth is
373     * the same (equivalent) as the ByteAlignment.
374     */
375    AccessBitWidth = AcpiExDecodeFieldAccess (ObjDesc, FieldFlags,
376                        &ByteAlignment);
377    if (!AccessBitWidth)
378    {
379        return_ACPI_STATUS (AE_AML_OPERAND_VALUE);
380    }
381
382    /* Setup width (access granularity) fields (values are: 1, 2, 4, 8) */
383
384    ObjDesc->CommonField.AccessByteWidth = (UINT8)
385        ACPI_DIV_8 (AccessBitWidth);
386
387    /*
388     * BaseByteOffset is the address of the start of the field within the
389     * region.  It is the byte address of the first *datum* (field-width data
390     * unit) of the field. (i.e., the first datum that contains at least the
391     * first *bit* of the field.)
392     *
393     * Note: ByteAlignment is always either equal to the AccessBitWidth or 8
394     * (Byte access), and it defines the addressing granularity of the parent
395     * region or buffer.
396     */
397    NearestByteAddress =
398        ACPI_ROUND_BITS_DOWN_TO_BYTES (FieldBitPosition);
399    ObjDesc->CommonField.BaseByteOffset = (UINT32)
400        ACPI_ROUND_DOWN (NearestByteAddress, ByteAlignment);
401
402    /*
403     * StartFieldBitOffset is the offset of the first bit of the field within
404     * a field datum.
405     */
406    ObjDesc->CommonField.StartFieldBitOffset = (UINT8)
407        (FieldBitPosition - ACPI_MUL_8 (ObjDesc->CommonField.BaseByteOffset));
408
409    return_ACPI_STATUS (AE_OK);
410}
411
412
413/*******************************************************************************
414 *
415 * FUNCTION:    AcpiExPrepFieldValue
416 *
417 * PARAMETERS:  Info    - Contains all field creation info
418 *
419 * RETURN:      Status
420 *
421 * DESCRIPTION: Construct an ACPI_OPERAND_OBJECT of type DefField and
422 *              connect it to the parent Node.
423 *
424 ******************************************************************************/
425
426ACPI_STATUS
427AcpiExPrepFieldValue (
428    ACPI_CREATE_FIELD_INFO  *Info)
429{
430    ACPI_OPERAND_OBJECT     *ObjDesc;
431    ACPI_OPERAND_OBJECT     *SecondDesc = NULL;
432    ACPI_STATUS             Status;
433    UINT32                  AccessByteWidth;
434    UINT32                  Type;
435
436
437    ACPI_FUNCTION_TRACE (ExPrepFieldValue);
438
439
440    /* Parameter validation */
441
442    if (Info->FieldType != ACPI_TYPE_LOCAL_INDEX_FIELD)
443    {
444        if (!Info->RegionNode)
445        {
446            ACPI_ERROR ((AE_INFO, "Null RegionNode"));
447            return_ACPI_STATUS (AE_AML_NO_OPERAND);
448        }
449
450        Type = AcpiNsGetType (Info->RegionNode);
451        if (Type != ACPI_TYPE_REGION)
452        {
453            ACPI_ERROR ((AE_INFO, "Needed Region, found type 0x%X (%s)",
454                Type, AcpiUtGetTypeName (Type)));
455
456            return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
457        }
458    }
459
460    /* Allocate a new field object */
461
462    ObjDesc = AcpiUtCreateInternalObject (Info->FieldType);
463    if (!ObjDesc)
464    {
465        return_ACPI_STATUS (AE_NO_MEMORY);
466    }
467
468    /* Initialize areas of the object that are common to all fields */
469
470    ObjDesc->CommonField.Node = Info->FieldNode;
471    Status = AcpiExPrepCommonFieldObject (ObjDesc,
472                Info->FieldFlags, Info->Attribute,
473                Info->FieldBitPosition, Info->FieldBitLength);
474    if (ACPI_FAILURE (Status))
475    {
476        AcpiUtDeleteObjectDesc (ObjDesc);
477        return_ACPI_STATUS (Status);
478    }
479
480    /* Initialize areas of the object that are specific to the field type */
481
482    switch (Info->FieldType)
483    {
484    case ACPI_TYPE_LOCAL_REGION_FIELD:
485
486        ObjDesc->Field.RegionObj = AcpiNsGetAttachedObject (Info->RegionNode);
487
488        /* Fields specific to GenericSerialBus fields */
489
490        ObjDesc->Field.AccessLength = Info->AccessLength;
491
492        if (Info->ConnectionNode)
493        {
494            SecondDesc = Info->ConnectionNode->Object;
495            if (!(SecondDesc->Common.Flags & AOPOBJ_DATA_VALID))
496            {
497                Status = AcpiDsGetBufferArguments (SecondDesc);
498                if (ACPI_FAILURE (Status))
499                {
500                    AcpiUtDeleteObjectDesc (ObjDesc);
501                    return_ACPI_STATUS (Status);
502                }
503            }
504
505            ObjDesc->Field.ResourceBuffer = SecondDesc->Buffer.Pointer;
506            ObjDesc->Field.ResourceLength = (UINT16) SecondDesc->Buffer.Length;
507        }
508        else if (Info->ResourceBuffer)
509        {
510            ObjDesc->Field.ResourceBuffer = Info->ResourceBuffer;
511            ObjDesc->Field.ResourceLength = Info->ResourceLength;
512        }
513
514        /* Allow full data read from EC address space */
515
516        if ((ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_EC) &&
517            (ObjDesc->CommonField.BitLength > 8))
518        {
519            AccessByteWidth = ACPI_ROUND_BITS_UP_TO_BYTES (
520                ObjDesc->CommonField.BitLength);
521
522            /* Maximum byte width supported is 255 */
523
524            if (AccessByteWidth < 256)
525            {
526                ObjDesc->CommonField.AccessByteWidth = (UINT8) AccessByteWidth;
527            }
528        }
529
530        /* An additional reference for the container */
531
532        AcpiUtAddReference (ObjDesc->Field.RegionObj);
533
534        ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
535            "RegionField: BitOff %X, Off %X, Gran %X, Region %p\n",
536            ObjDesc->Field.StartFieldBitOffset, ObjDesc->Field.BaseByteOffset,
537            ObjDesc->Field.AccessByteWidth, ObjDesc->Field.RegionObj));
538        break;
539
540
541    case ACPI_TYPE_LOCAL_BANK_FIELD:
542
543        ObjDesc->BankField.Value = Info->BankValue;
544        ObjDesc->BankField.RegionObj =
545            AcpiNsGetAttachedObject (Info->RegionNode);
546        ObjDesc->BankField.BankObj =
547            AcpiNsGetAttachedObject (Info->RegisterNode);
548
549        /* An additional reference for the attached objects */
550
551        AcpiUtAddReference (ObjDesc->BankField.RegionObj);
552        AcpiUtAddReference (ObjDesc->BankField.BankObj);
553
554        ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
555            "Bank Field: BitOff %X, Off %X, Gran %X, Region %p, BankReg %p\n",
556            ObjDesc->BankField.StartFieldBitOffset,
557            ObjDesc->BankField.BaseByteOffset,
558            ObjDesc->Field.AccessByteWidth,
559            ObjDesc->BankField.RegionObj,
560            ObjDesc->BankField.BankObj));
561
562        /*
563         * Remember location in AML stream of the field unit
564         * opcode and operands -- since the BankValue
565         * operands must be evaluated.
566         */
567        SecondDesc = ObjDesc->Common.NextObject;
568        SecondDesc->Extra.AmlStart = ACPI_CAST_PTR (ACPI_PARSE_OBJECT,
569            Info->DataRegisterNode)->Named.Data;
570        SecondDesc->Extra.AmlLength = ACPI_CAST_PTR (ACPI_PARSE_OBJECT,
571            Info->DataRegisterNode)->Named.Length;
572
573        break;
574
575
576    case ACPI_TYPE_LOCAL_INDEX_FIELD:
577
578        /* Get the Index and Data registers */
579
580        ObjDesc->IndexField.IndexObj =
581            AcpiNsGetAttachedObject (Info->RegisterNode);
582        ObjDesc->IndexField.DataObj =
583            AcpiNsGetAttachedObject (Info->DataRegisterNode);
584
585        if (!ObjDesc->IndexField.DataObj || !ObjDesc->IndexField.IndexObj)
586        {
587            ACPI_ERROR ((AE_INFO, "Null Index Object during field prep"));
588            AcpiUtDeleteObjectDesc (ObjDesc);
589            return_ACPI_STATUS (AE_AML_INTERNAL);
590        }
591
592        /* An additional reference for the attached objects */
593
594        AcpiUtAddReference (ObjDesc->IndexField.DataObj);
595        AcpiUtAddReference (ObjDesc->IndexField.IndexObj);
596
597        /*
598         * April 2006: Changed to match MS behavior
599         *
600         * The value written to the Index register is the byte offset of the
601         * target field in units of the granularity of the IndexField
602         *
603         * Previously, the value was calculated as an index in terms of the
604         * width of the Data register, as below:
605         *
606         *      ObjDesc->IndexField.Value = (UINT32)
607         *          (Info->FieldBitPosition / ACPI_MUL_8 (
608         *              ObjDesc->Field.AccessByteWidth));
609         *
610         * February 2006: Tried value as a byte offset:
611         *      ObjDesc->IndexField.Value = (UINT32)
612         *          ACPI_DIV_8 (Info->FieldBitPosition);
613         */
614        ObjDesc->IndexField.Value = (UINT32) ACPI_ROUND_DOWN (
615            ACPI_DIV_8 (Info->FieldBitPosition),
616            ObjDesc->IndexField.AccessByteWidth);
617
618        ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
619            "IndexField: BitOff %X, Off %X, Value %X, Gran %X, Index %p, Data %p\n",
620            ObjDesc->IndexField.StartFieldBitOffset,
621            ObjDesc->IndexField.BaseByteOffset,
622            ObjDesc->IndexField.Value,
623            ObjDesc->Field.AccessByteWidth,
624            ObjDesc->IndexField.IndexObj,
625            ObjDesc->IndexField.DataObj));
626        break;
627
628    default:
629        /* No other types should get here */
630        break;
631    }
632
633    /*
634     * Store the constructed descriptor (ObjDesc) into the parent Node,
635     * preserving the current type of that NamedObj.
636     */
637    Status = AcpiNsAttachObject (Info->FieldNode, ObjDesc,
638                AcpiNsGetType (Info->FieldNode));
639
640    ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Set NamedObj %p [%4.4s], ObjDesc %p\n",
641        Info->FieldNode, AcpiUtGetNodeName (Info->FieldNode), ObjDesc));
642
643    /* Remove local reference to the object */
644
645    AcpiUtRemoveReference (ObjDesc);
646    return_ACPI_STATUS (Status);
647}
648
649