exfield.c revision 71867
1/******************************************************************************
2 *
3 * Module Name: amfield - ACPI AML (p-code) execution - field manipulation
4 *              $Revision: 77 $
5 *
6 *****************************************************************************/
7
8/******************************************************************************
9 *
10 * 1. Copyright Notice
11 *
12 * Some or all of this work - Copyright (c) 1999, 2000, 2001, Intel Corp.
13 * All rights reserved.
14 *
15 * 2. License
16 *
17 * 2.1. This is your license from Intel Corp. under its intellectual property
18 * rights.  You may have additional license terms from the party that provided
19 * you this software, covering your right to use that party's intellectual
20 * property rights.
21 *
22 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
23 * copy of the source code appearing in this file ("Covered Code") an
24 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
25 * base code distributed originally by Intel ("Original Intel Code") to copy,
26 * make derivatives, distribute, use and display any portion of the Covered
27 * Code in any form, with the right to sublicense such rights; and
28 *
29 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
30 * license (with the right to sublicense), under only those claims of Intel
31 * patents that are infringed by the Original Intel Code, to make, use, sell,
32 * offer to sell, and import the Covered Code and derivative works thereof
33 * solely to the minimum extent necessary to exercise the above copyright
34 * license, and in no event shall the patent license extend to any additions
35 * to or modifications of the Original Intel Code.  No other license or right
36 * is granted directly or by implication, estoppel or otherwise;
37 *
38 * The above copyright and patent license is granted only if the following
39 * conditions are met:
40 *
41 * 3. Conditions
42 *
43 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
44 * Redistribution of source code of any substantial portion of the Covered
45 * Code or modification with rights to further distribute source must include
46 * the above Copyright Notice, the above License, this list of Conditions,
47 * and the following Disclaimer and Export Compliance provision.  In addition,
48 * Licensee must cause all Covered Code to which Licensee contributes to
49 * contain a file documenting the changes Licensee made to create that Covered
50 * Code and the date of any change.  Licensee must include in that file the
51 * documentation of any changes made by any predecessor Licensee.  Licensee
52 * must include a prominent statement that the modification is derived,
53 * directly or indirectly, from Original Intel Code.
54 *
55 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
56 * Redistribution of source code of any substantial portion of the Covered
57 * Code or modification without rights to further distribute source must
58 * include the following Disclaimer and Export Compliance provision in the
59 * documentation and/or other materials provided with distribution.  In
60 * addition, Licensee may not authorize further sublicense of source of any
61 * portion of the Covered Code, and must include terms to the effect that the
62 * license from Licensee to its licensee is limited to the intellectual
63 * property embodied in the software Licensee provides to its licensee, and
64 * not to intellectual property embodied in modifications its licensee may
65 * make.
66 *
67 * 3.3. Redistribution of Executable. Redistribution in executable form of any
68 * substantial portion of the Covered Code or modification must reproduce the
69 * above Copyright Notice, and the following Disclaimer and Export Compliance
70 * provision in the documentation and/or other materials provided with the
71 * distribution.
72 *
73 * 3.4. Intel retains all right, title, and interest in and to the Original
74 * Intel Code.
75 *
76 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
77 * Intel shall be used in advertising or otherwise to promote the sale, use or
78 * other dealings in products derived from or relating to the Covered Code
79 * without prior written authorization from Intel.
80 *
81 * 4. Disclaimer and Export Compliance
82 *
83 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
84 * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
85 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
86 * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
87 * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
88 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
89 * PARTICULAR PURPOSE.
90 *
91 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
92 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
93 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
94 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
95 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
96 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
97 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
98 * LIMITED REMEDY.
99 *
100 * 4.3. Licensee shall not export, either directly or indirectly, any of this
101 * software or system incorporating such software without first obtaining any
102 * required license or other approval from the U. S. Department of Commerce or
103 * any other agency or department of the United States Government.  In the
104 * event Licensee exports any such software from the United States or
105 * re-exports any such software from a foreign destination, Licensee shall
106 * ensure that the distribution and export/re-export of the software is in
107 * compliance with all laws, regulations, orders, or other restrictions of the
108 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
109 * any of its subsidiaries will export/re-export any technical data, process,
110 * software, or service, directly or indirectly, to any country for which the
111 * United States government or any agency thereof requires an export license,
112 * other governmental approval, or letter of assurance, without first obtaining
113 * such license, approval or letter.
114 *
115 *****************************************************************************/
116
117
118#define __AMFIELD_C__
119
120#include "acpi.h"
121#include "acdispat.h"
122#include "acinterp.h"
123#include "amlcode.h"
124#include "acnamesp.h"
125#include "achware.h"
126#include "acevents.h"
127
128
129#define _COMPONENT          INTERPRETER
130        MODULE_NAME         ("amfield")
131
132
133/*******************************************************************************
134 *
135 * FUNCTION:    AcpiAmlSetupField
136 *
137 * PARAMETERS:  *ObjDesc            - Field to be read or written
138 *              *RgnDesc            - Region containing field
139 *              FieldBitWidth       - Field Width in bits (8, 16, or 32)
140 *
141 * RETURN:      Status
142 *
143 * DESCRIPTION: Common processing for AcpiAmlReadField and AcpiAmlWriteField
144 *
145 *  ACPI SPECIFICATION REFERENCES:
146 *  Each of the Type1Opcodes is defined as specified in in-line
147 *  comments below. For each one, use the following definitions.
148 *
149 *  DefBitField     :=  BitFieldOp      SrcBuf  BitIdx  Destination
150 *  DefByteField    :=  ByteFieldOp     SrcBuf  ByteIdx Destination
151 *  DefCreateField  :=  CreateFieldOp   SrcBuf  BitIdx  NumBits  NameString
152 *  DefDWordField   :=  DWordFieldOp    SrcBuf  ByteIdx Destination
153 *  DefWordField    :=  WordFieldOp     SrcBuf  ByteIdx Destination
154 *  BitIndex        :=  TermArg=>Integer
155 *  ByteIndex       :=  TermArg=>Integer
156 *  Destination     :=  NameString
157 *  NumBits         :=  TermArg=>Integer
158 *  SourceBuf       :=  TermArg=>Buffer
159 *
160 ******************************************************************************/
161
162ACPI_STATUS
163AcpiAmlSetupField (
164    ACPI_OPERAND_OBJECT     *ObjDesc,
165    ACPI_OPERAND_OBJECT     *RgnDesc,
166    UINT32                  FieldBitWidth)
167{
168    ACPI_STATUS             Status = AE_OK;
169    UINT32                  FieldByteWidth;
170
171
172    FUNCTION_TRACE ("AmlSetupField");
173
174
175    /* Parameter validation */
176
177    if (!ObjDesc || !RgnDesc)
178    {
179        DEBUG_PRINT (ACPI_ERROR,
180            ("AmlSetupField: Internal error - null handle\n"));
181        return_ACPI_STATUS (AE_AML_NO_OPERAND);
182    }
183
184    if (ACPI_TYPE_REGION != RgnDesc->Common.Type)
185    {
186        DEBUG_PRINT (ACPI_ERROR,
187            ("AmlSetupField: Needed Region, found type %x %s\n",
188            RgnDesc->Common.Type, AcpiCmGetTypeName (RgnDesc->Common.Type)));
189        return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
190    }
191
192
193    /*
194     * TBD: [Future] Acpi 2.0 supports Qword fields
195     *
196     * Init and validate Field width
197     * Possible values are 1, 2, 4
198     */
199
200    FieldByteWidth = DIV_8 (FieldBitWidth);
201
202    if ((FieldBitWidth != 8) &&
203        (FieldBitWidth != 16) &&
204        (FieldBitWidth != 32))
205    {
206        DEBUG_PRINT (ACPI_ERROR,
207            ("AmlSetupField: Internal error - bad width %d\n", FieldBitWidth));
208        return_ACPI_STATUS (AE_AML_OPERAND_VALUE);
209    }
210
211
212    /*
213     * If the Region Address and Length have not been previously evaluated,
214     * evaluate them and save the results.
215     */
216    if (!(RgnDesc->Region.Flags & AOPOBJ_DATA_VALID))
217    {
218
219        Status = AcpiDsGetRegionArguments (RgnDesc);
220        if (ACPI_FAILURE (Status))
221        {
222            return_ACPI_STATUS (Status);
223        }
224    }
225
226
227    if ((ObjDesc->Common.Type == ACPI_TYPE_FIELD_UNIT) &&
228        (!(ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)))
229    {
230        /*
231         * Field Buffer and Index have not been previously evaluated,
232         */
233        DEBUG_PRINT (ACPI_ERROR, ("Uninitialized field!\n"));
234        return_ACPI_STATUS (AE_AML_INTERNAL);
235    }
236
237    if (RgnDesc->Region.Length <
238       (ObjDesc->Field.Offset & ~((UINT32) FieldByteWidth - 1)) +
239            FieldByteWidth)
240    {
241        /*
242         * Offset rounded up to next multiple of field width
243         * exceeds region length, indicate an error
244         */
245
246        DUMP_STACK_ENTRY (RgnDesc);
247        DUMP_STACK_ENTRY (ObjDesc);
248
249        DEBUG_PRINT (ACPI_ERROR,
250            ("AmlSetupField: Operation at %08lX width %d bits exceeds len %08lX field=%p region=%p\n",
251            ObjDesc->Field.Offset, FieldBitWidth, RgnDesc->Region.Length,
252            ObjDesc, RgnDesc));
253
254        return_ACPI_STATUS (AE_AML_REGION_LIMIT);
255    }
256
257    return_ACPI_STATUS (AE_OK);
258}
259
260
261/*******************************************************************************
262 *
263 * FUNCTION:    AcpiAmlAccessNamedField
264 *
265 * PARAMETERS:  Mode                - ACPI_READ or ACPI_WRITE
266 *              NamedField          - Handle for field to be accessed
267 *              *Buffer             - Value(s) to be read or written
268 *              BufferLength          - Number of bytes to transfer
269 *
270 * RETURN:      Status
271 *
272 * DESCRIPTION: Read or write a named field
273 *
274 ******************************************************************************/
275
276ACPI_STATUS
277AcpiAmlAccessNamedField (
278    UINT32                  Mode,
279    ACPI_HANDLE             NamedField,
280    void                    *Buffer,
281    UINT32                  BufferLength)
282{
283    ACPI_OPERAND_OBJECT     *ObjDesc = NULL;
284    ACPI_STATUS             Status = AE_OK;
285    BOOLEAN                 Locked = FALSE;
286    UINT32                  BitGranularity = 0;
287    UINT32                  ByteGranularity;
288    UINT32                  DatumLength;
289    UINT32                  ActualByteLength;
290    UINT32                  ByteFieldLength;
291
292
293    FUNCTION_TRACE_PTR ("AmlAccessNamedField", NamedField);
294
295
296    /* Parameter validation */
297
298    if ((!NamedField) || (ACPI_READ == Mode && !Buffer))
299    {
300        DEBUG_PRINT (ACPI_ERROR,
301            ("AcpiAmlAccessNamedField: Internal error - null parameter\n"));
302        return_ACPI_STATUS (AE_AML_INTERNAL);
303    }
304
305    /* Get the attached field object */
306
307    ObjDesc = AcpiNsGetAttachedObject (NamedField);
308    if (!ObjDesc)
309    {
310        DEBUG_PRINT (ACPI_ERROR,
311            ("AmlAccessNamedField: Internal error - null value pointer\n"));
312        return_ACPI_STATUS (AE_AML_INTERNAL);
313    }
314
315    /* Check the type */
316
317    if (INTERNAL_TYPE_DEF_FIELD != AcpiNsGetType (NamedField))
318    {
319        DEBUG_PRINT (ACPI_ERROR,
320            ("AmlAccessNamedField: Name %4.4s type %x is not a defined field\n",
321            &(((ACPI_NAMESPACE_NODE *) NamedField)->Name),
322            AcpiNsGetType (NamedField)));
323        return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
324    }
325
326    /* ObjDesc valid and NamedField is a defined field  */
327
328    DEBUG_PRINT (ACPI_INFO,
329        ("AccessNamedField: Obj=%p Type=%x Buf=%p Len=%x\n",
330        ObjDesc, ObjDesc->Common.Type, Buffer, BufferLength));
331    DEBUG_PRINT (ACPI_INFO,
332        ("AccessNamedField: Mode=%d FieldLen=%d, BitOffset=%d\n",
333        Mode, ObjDesc->FieldUnit.Length, ObjDesc->FieldUnit.BitOffset));
334    DUMP_ENTRY (NamedField, ACPI_INFO);
335
336
337    /* Double-check that the attached object is also a field */
338
339    if (INTERNAL_TYPE_DEF_FIELD != ObjDesc->Common.Type)
340    {
341        DEBUG_PRINT (ACPI_ERROR,
342            ("AmlAccessNamedField: Internal error - Name %4.4s type %x does not match value-type %x at %p\n",
343            &(((ACPI_NAMESPACE_NODE *) NamedField)->Name),
344            AcpiNsGetType (NamedField), ObjDesc->Common.Type, ObjDesc));
345        return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
346    }
347
348
349    /*
350     * Granularity was decoded from the field access type
351     * (AnyAcc will be the same as ByteAcc)
352     */
353
354    BitGranularity = ObjDesc->FieldUnit.Granularity;
355    ByteGranularity = DIV_8 (BitGranularity);
356
357    /*
358     * Check if request is too large for the field, and silently truncate
359     * if necessary
360     */
361
362    /* TBD: [Errors] should an error be returned in this case? */
363
364    ByteFieldLength = (UINT32) DIV_8 (ObjDesc->FieldUnit.Length + 7);
365
366
367    ActualByteLength = BufferLength;
368    if (BufferLength > ByteFieldLength)
369    {
370        DEBUG_PRINT (ACPI_INFO,
371            ("AmlAccessNamedField: Byte length %X truncated to %X\n",
372            ActualByteLength, ByteFieldLength));
373
374        ActualByteLength = ByteFieldLength;
375    }
376
377    /* TBD: should these round down to a power of 2? */
378
379    if (DIV_8 (BitGranularity) > ByteFieldLength)
380    {
381        DEBUG_PRINT (ACPI_INFO,
382            ("AmlAccessNamedField: Bit granularity %X truncated to %X\n",
383            BitGranularity, MUL_8(ByteFieldLength)));
384
385        BitGranularity = MUL_8(ByteFieldLength);
386    }
387
388    if (ByteGranularity > ByteFieldLength)
389    {
390        DEBUG_PRINT (ACPI_INFO,
391            ("AmlAccessNamedField: Byte granularity %X truncated to %X\n",
392            ByteGranularity, ByteFieldLength));
393
394        ByteGranularity = ByteFieldLength;
395    }
396
397
398    /* Convert byte count to datum count, round up if necessary */
399
400    DatumLength = (ActualByteLength + (ByteGranularity-1)) / ByteGranularity;
401
402    DEBUG_PRINT (ACPI_INFO,
403        ("ByteLen=%x, DatumLen=%x, BitGran=%x, ByteGran=%x\n",
404        ActualByteLength, DatumLength, BitGranularity, ByteGranularity));
405
406
407    /* Get the global lock if needed */
408
409    Locked = AcpiAmlAcquireGlobalLock (ObjDesc->FieldUnit.LockRule);
410
411
412    /* Perform the actual read or write of the buffer */
413
414    switch (Mode)
415    {
416    case ACPI_READ:
417
418        Status = AcpiAmlReadField (ObjDesc, Buffer, BufferLength,
419                                    ActualByteLength, DatumLength,
420                                    BitGranularity, ByteGranularity);
421        break;
422
423
424    case ACPI_WRITE:
425
426        Status = AcpiAmlWriteField (ObjDesc, Buffer, BufferLength,
427                                    ActualByteLength, DatumLength,
428                                    BitGranularity, ByteGranularity);
429        break;
430
431
432    default:
433
434        DEBUG_PRINT (ACPI_ERROR,
435            ("AccessNamedField: Unknown I/O Mode: %X\n", Mode));
436        Status = AE_BAD_PARAMETER;
437        break;
438    }
439
440
441    /* Release global lock if we acquired it earlier */
442
443    AcpiAmlReleaseGlobalLock (Locked);
444
445    return_ACPI_STATUS (Status);
446}
447
448