Merge from vendor branch GCC:
[dragonfly.git] / sys / contrib / dev / acpica / exprep.c
1
2 /******************************************************************************
3  *
4  * Module Name: exprep - ACPI AML (p-code) execution - field prep utilities
5  *              $Revision: 122 $
6  *
7  *****************************************************************************/
8
9 /******************************************************************************
10  *
11  * 1. Copyright Notice
12  *
13  * Some or all of this work - Copyright (c) 1999 - 2003, Intel Corp.
14  * All rights reserved.
15  *
16  * 2. License
17  *
18  * 2.1. This is your license from Intel Corp. under its intellectual property
19  * rights.  You may have additional license terms from the party that provided
20  * you this software, covering your right to use that party's intellectual
21  * property rights.
22  *
23  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
24  * copy of the source code appearing in this file ("Covered Code") an
25  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
26  * base code distributed originally by Intel ("Original Intel Code") to copy,
27  * make derivatives, distribute, use and display any portion of the Covered
28  * Code in any form, with the right to sublicense such rights; and
29  *
30  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
31  * license (with the right to sublicense), under only those claims of Intel
32  * patents that are infringed by the Original Intel Code, to make, use, sell,
33  * offer to sell, and import the Covered Code and derivative works thereof
34  * solely to the minimum extent necessary to exercise the above copyright
35  * license, and in no event shall the patent license extend to any additions
36  * to or modifications of the Original Intel Code.  No other license or right
37  * is granted directly or by implication, estoppel or otherwise;
38  *
39  * The above copyright and patent license is granted only if the following
40  * conditions are met:
41  *
42  * 3. Conditions
43  *
44  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
45  * Redistribution of source code of any substantial portion of the Covered
46  * Code or modification with rights to further distribute source must include
47  * the above Copyright Notice, the above License, this list of Conditions,
48  * and the following Disclaimer and Export Compliance provision.  In addition,
49  * Licensee must cause all Covered Code to which Licensee contributes to
50  * contain a file documenting the changes Licensee made to create that Covered
51  * Code and the date of any change.  Licensee must include in that file the
52  * documentation of any changes made by any predecessor Licensee.  Licensee
53  * must include a prominent statement that the modification is derived,
54  * directly or indirectly, from Original Intel Code.
55  *
56  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
57  * Redistribution of source code of any substantial portion of the Covered
58  * Code or modification without rights to further distribute source must
59  * include the following Disclaimer and Export Compliance provision in the
60  * documentation and/or other materials provided with distribution.  In
61  * addition, Licensee may not authorize further sublicense of source of any
62  * portion of the Covered Code, and must include terms to the effect that the
63  * license from Licensee to its licensee is limited to the intellectual
64  * property embodied in the software Licensee provides to its licensee, and
65  * not to intellectual property embodied in modifications its licensee may
66  * make.
67  *
68  * 3.3. Redistribution of Executable. Redistribution in executable form of any
69  * substantial portion of the Covered Code or modification must reproduce the
70  * above Copyright Notice, and the following Disclaimer and Export Compliance
71  * provision in the documentation and/or other materials provided with the
72  * distribution.
73  *
74  * 3.4. Intel retains all right, title, and interest in and to the Original
75  * Intel Code.
76  *
77  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
78  * Intel shall be used in advertising or otherwise to promote the sale, use or
79  * other dealings in products derived from or relating to the Covered Code
80  * without prior written authorization from Intel.
81  *
82  * 4. Disclaimer and Export Compliance
83  *
84  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
85  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
86  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
87  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
88  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
89  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
90  * PARTICULAR PURPOSE.
91  *
92  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
93  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
94  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
95  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
96  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
97  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
98  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
99  * LIMITED REMEDY.
100  *
101  * 4.3. Licensee shall not export, either directly or indirectly, any of this
102  * software or system incorporating such software without first obtaining any
103  * required license or other approval from the U. S. Department of Commerce or
104  * any other agency or department of the United States Government.  In the
105  * event Licensee exports any such software from the United States or
106  * re-exports any such software from a foreign destination, Licensee shall
107  * ensure that the distribution and export/re-export of the software is in
108  * compliance with all laws, regulations, orders, or other restrictions of the
109  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
110  * any of its subsidiaries will export/re-export any technical data, process,
111  * software, or service, directly or indirectly, to any country for which the
112  * United States government or any agency thereof requires an export license,
113  * other governmental approval, or letter of assurance, without first obtaining
114  * such license, approval or letter.
115  *
116  *****************************************************************************/
117 /* $DragonFly: src/sys/contrib/dev/acpica/Attic/exprep.c,v 1.1 2003/09/24 03:32:16 drhodus Exp $                                                               */
118
119 #define __EXPREP_C__
120
121 #include "acpi.h"
122 #include "acinterp.h"
123 #include "amlcode.h"
124 #include "acnamesp.h"
125
126
127 #define _COMPONENT          ACPI_EXECUTER
128         ACPI_MODULE_NAME    ("exprep")
129
130
131 /*******************************************************************************
132  *
133  * FUNCTION:    AcpiExDecodeFieldAccess
134  *
135  * PARAMETERS:  Access          - Encoded field access bits
136  *              Length          - Field length.
137  *
138  * RETURN:      Field granularity (8, 16, 32 or 64) and
139  *              ByteAlignment (1, 2, 3, or 4)
140  *
141  * DESCRIPTION: Decode the AccessType bits of a field definition.
142  *
143  ******************************************************************************/
144
145 static UINT32
146 AcpiExDecodeFieldAccess (
147     ACPI_OPERAND_OBJECT     *ObjDesc,
148     UINT8                   FieldFlags,
149     UINT32                  *ReturnByteAlignment)
150 {
151     UINT32                  Access;
152     UINT8                   ByteAlignment;
153     UINT8                   BitLength;
154 /*    UINT32                  Length; */
155
156
157     ACPI_FUNCTION_NAME ("ExDecodeFieldAccess");
158
159
160     Access = (FieldFlags & AML_FIELD_ACCESS_TYPE_MASK);
161
162     switch (Access)
163     {
164     case AML_FIELD_ACCESS_ANY:
165
166         ByteAlignment = 1;
167         BitLength = 8;
168
169 #if 0
170         /*
171          * TBD: optimize
172          *
173          * Any attempt to optimize the access size to the size of the field
174          * must take into consideration the length of the region and take
175          * care that an access to the field will not attempt to access
176          * beyond the end of the region.
177          */
178
179         /* Use the length to set the access type */
180
181         Length = ObjDesc->CommonField.BitLength;
182
183         if (Length <= 8)
184         {
185             BitLength = 8;
186         }
187         else if (Length <= 16)
188         {
189             BitLength = 16;
190         }
191         else if (Length <= 32)
192         {
193             BitLength = 32;
194         }
195         else if (Length <= 64)
196         {
197             BitLength = 64;
198         }
199         else
200         {
201             /* Larger than Qword - just use byte-size chunks */
202
203             BitLength = 8;
204         }
205 #endif
206         break;
207
208     case AML_FIELD_ACCESS_BYTE:
209     case AML_FIELD_ACCESS_BUFFER:   /* ACPI 2.0 (SMBus Buffer) */
210         ByteAlignment = 1;
211         BitLength     = 8;
212         break;
213
214     case AML_FIELD_ACCESS_WORD:
215         ByteAlignment = 2;
216         BitLength     = 16;
217         break;
218
219     case AML_FIELD_ACCESS_DWORD:
220         ByteAlignment = 4;
221         BitLength     = 32;
222         break;
223
224     case AML_FIELD_ACCESS_QWORD:    /* ACPI 2.0 */
225         ByteAlignment = 8;
226         BitLength     = 64;
227         break;
228
229     default:
230         /* Invalid field access type */
231
232         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
233             "Unknown field access type %X\n",
234             Access));
235         return (0);
236     }
237
238     if (ACPI_GET_OBJECT_TYPE (ObjDesc) == ACPI_TYPE_BUFFER_FIELD)
239     {
240         /*
241          * BufferField access can be on any byte boundary, so the
242          * ByteAlignment is always 1 byte -- regardless of any ByteAlignment
243          * implied by the field access type.
244          */
245         ByteAlignment = 1;
246     }
247
248     *ReturnByteAlignment = ByteAlignment;
249     return (BitLength);
250 }
251
252
253 /*******************************************************************************
254  *
255  * FUNCTION:    AcpiExPrepCommonFieldObject
256  *
257  * PARAMETERS:  ObjDesc             - The field object
258  *              FieldFlags          - Access, LockRule, and UpdateRule.
259  *                                    The format of a FieldFlag is described
260  *                                    in the ACPI specification
261  *              FieldBitPosition    - Field start position
262  *              FieldBitLength      - Field length in number of bits
263  *
264  * RETURN:      Status
265  *
266  * DESCRIPTION: Initialize the areas of the field object that are common
267  *              to the various types of fields.  Note: This is very "sensitive"
268  *              code because we are solving the general case for field
269  *              alignment.
270  *
271  ******************************************************************************/
272
273 ACPI_STATUS
274 AcpiExPrepCommonFieldObject (
275     ACPI_OPERAND_OBJECT     *ObjDesc,
276     UINT8                   FieldFlags,
277     UINT8                   FieldAttribute,
278     UINT32                  FieldBitPosition,
279     UINT32                  FieldBitLength)
280 {
281     UINT32                  AccessBitWidth;
282     UINT32                  ByteAlignment;
283     UINT32                  NearestByteAddress;
284
285
286     ACPI_FUNCTION_TRACE ("ExPrepCommonFieldObject");
287
288
289     /*
290      * Note: the structure being initialized is the
291      * ACPI_COMMON_FIELD_INFO;  No structure fields outside of the common
292      * area are initialized by this procedure.
293      */
294     ObjDesc->CommonField.FieldFlags = FieldFlags;
295     ObjDesc->CommonField.Attribute  = FieldAttribute;
296     ObjDesc->CommonField.BitLength  = FieldBitLength;
297
298     /*
299      * Decode the access type so we can compute offsets.  The access type gives
300      * two pieces of information - the width of each field access and the
301      * necessary ByteAlignment (address granularity) of the access.
302      *
303      * For AnyAcc, the AccessBitWidth is the largest width that is both
304      * necessary and possible in an attempt to access the whole field in one
305      * I/O operation.  However, for AnyAcc, the ByteAlignment is always one
306      * byte.
307      *
308      * For all Buffer Fields, the ByteAlignment is always one byte.
309      *
310      * For all other access types (Byte, Word, Dword, Qword), the Bitwidth is
311      * the same (equivalent) as the ByteAlignment.
312      */
313     AccessBitWidth = AcpiExDecodeFieldAccess (ObjDesc, FieldFlags,
314                                 &ByteAlignment);
315     if (!AccessBitWidth)
316     {
317         return_ACPI_STATUS (AE_AML_OPERAND_VALUE);
318     }
319
320     /* Setup width (access granularity) fields */
321
322     ObjDesc->CommonField.AccessByteWidth = (UINT8)
323             ACPI_DIV_8 (AccessBitWidth); /* 1,  2,  4,  8 */
324
325     /*
326      * BaseByteOffset is the address of the start of the field within the
327      * region.  It is the byte address of the first *datum* (field-width data
328      * unit) of the field. (i.e., the first datum that contains at least the
329      * first *bit* of the field.)
330      *
331      * Note: ByteAlignment is always either equal to the AccessBitWidth or 8
332      * (Byte access), and it defines the addressing granularity of the parent
333      * region or buffer.
334      */
335     NearestByteAddress =
336             ACPI_ROUND_BITS_DOWN_TO_BYTES (FieldBitPosition);
337     ObjDesc->CommonField.BaseByteOffset =
338             ACPI_ROUND_DOWN (NearestByteAddress, ByteAlignment);
339
340     /*
341      * StartFieldBitOffset is the offset of the first bit of the field within
342      * a field datum.
343      */
344     ObjDesc->CommonField.StartFieldBitOffset = (UINT8)
345         (FieldBitPosition - ACPI_MUL_8 (ObjDesc->CommonField.BaseByteOffset));
346
347     /*
348      * Valid bits -- the number of bits that compose a partial datum,
349      * 1) At the end of the field within the region (arbitrary starting bit
350      *    offset)
351      * 2) At the end of a buffer used to contain the field (starting offset
352      *    always zero)
353      */
354     ObjDesc->CommonField.EndFieldValidBits   = (UINT8)
355         ((ObjDesc->CommonField.StartFieldBitOffset + FieldBitLength) %
356                                                             AccessBitWidth);
357     /* StartBufferBitOffset always = 0 */
358
359     ObjDesc->CommonField.EndBufferValidBits  = (UINT8)
360         (FieldBitLength % AccessBitWidth);
361
362     /*
363      * DatumValidBits is the number of valid field bits in the first
364      * field datum.
365      */
366     ObjDesc->CommonField.DatumValidBits      = (UINT8)
367         (AccessBitWidth - ObjDesc->CommonField.StartFieldBitOffset);
368
369     /*
370      * Does the entire field fit within a single field access element? (datum)
371      * (i.e., without crossing a datum boundary)
372      */
373     if ((ObjDesc->CommonField.StartFieldBitOffset + FieldBitLength) <=
374             (UINT16) AccessBitWidth)
375     {
376         ObjDesc->Common.Flags |= AOPOBJ_SINGLE_DATUM;
377     }
378
379     return_ACPI_STATUS (AE_OK);
380 }
381
382
383 /*******************************************************************************
384  *
385  * FUNCTION:    AcpiExPrepFieldValue
386  *
387  * PARAMETERS:  Node                - Owning Node
388  *              RegionNode          - Region in which field is being defined
389  *              FieldFlags          - Access, LockRule, and UpdateRule.
390  *              FieldBitPosition    - Field start position
391  *              FieldBitLength      - Field length in number of bits
392  *
393  * RETURN:      Status
394  *
395  * DESCRIPTION: Construct an ACPI_OPERAND_OBJECT of type DefField and
396  *              connect it to the parent Node.
397  *
398  ******************************************************************************/
399
400 ACPI_STATUS
401 AcpiExPrepFieldValue (
402     ACPI_CREATE_FIELD_INFO  *Info)
403 {
404     ACPI_OPERAND_OBJECT     *ObjDesc;
405     UINT32                  Type;
406     ACPI_STATUS             Status;
407
408
409     ACPI_FUNCTION_TRACE ("ExPrepFieldValue");
410
411
412     /* Parameter validation */
413
414     if (Info->FieldType != ACPI_TYPE_LOCAL_INDEX_FIELD)
415     {
416         if (!Info->RegionNode)
417         {
418             ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null RegionNode\n"));
419             return_ACPI_STATUS (AE_AML_NO_OPERAND);
420         }
421
422         Type = AcpiNsGetType (Info->RegionNode);
423         if (Type != ACPI_TYPE_REGION)
424         {
425             ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
426                 "Needed Region, found type %X %s\n",
427                 Type, AcpiUtGetTypeName (Type)));
428
429             return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
430         }
431     }
432
433     /* Allocate a new field object */
434
435     ObjDesc = AcpiUtCreateInternalObject (Info->FieldType);
436     if (!ObjDesc)
437     {
438         return_ACPI_STATUS (AE_NO_MEMORY);
439     }
440
441     /* Initialize areas of the object that are common to all fields */
442
443     ObjDesc->CommonField.Node = Info->FieldNode;
444     Status = AcpiExPrepCommonFieldObject (ObjDesc, Info->FieldFlags,
445                 Info->Attribute, Info->FieldBitPosition, Info->FieldBitLength);
446     if (ACPI_FAILURE (Status))
447     {
448         AcpiUtDeleteObjectDesc (ObjDesc);
449         return_ACPI_STATUS (Status);
450     }
451
452     /* Initialize areas of the object that are specific to the field type */
453
454     switch (Info->FieldType)
455     {
456     case ACPI_TYPE_LOCAL_REGION_FIELD:
457
458         ObjDesc->Field.RegionObj     = AcpiNsGetAttachedObject (Info->RegionNode);
459
460         /* An additional reference for the container */
461
462         AcpiUtAddReference (ObjDesc->Field.RegionObj);
463
464         ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
465             "RegionField: Bitoff=%X Off=%X Gran=%X Region %p\n",
466             ObjDesc->Field.StartFieldBitOffset, ObjDesc->Field.BaseByteOffset,
467             ObjDesc->Field.AccessByteWidth, ObjDesc->Field.RegionObj));
468         break;
469
470
471     case ACPI_TYPE_LOCAL_BANK_FIELD:
472
473         ObjDesc->BankField.Value     = Info->BankValue;
474         ObjDesc->BankField.RegionObj = AcpiNsGetAttachedObject (Info->RegionNode);
475         ObjDesc->BankField.BankObj   = AcpiNsGetAttachedObject (Info->RegisterNode);
476
477         /* An additional reference for the attached objects */
478
479         AcpiUtAddReference (ObjDesc->BankField.RegionObj);
480         AcpiUtAddReference (ObjDesc->BankField.BankObj);
481
482         ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
483             "Bank Field: BitOff=%X Off=%X Gran=%X Region %p BankReg %p\n",
484             ObjDesc->BankField.StartFieldBitOffset,
485             ObjDesc->BankField.BaseByteOffset,
486             ObjDesc->Field.AccessByteWidth,
487             ObjDesc->BankField.RegionObj,
488             ObjDesc->BankField.BankObj));
489         break;
490
491
492     case ACPI_TYPE_LOCAL_INDEX_FIELD:
493
494         ObjDesc->IndexField.IndexObj = AcpiNsGetAttachedObject (Info->RegisterNode);
495         ObjDesc->IndexField.DataObj  = AcpiNsGetAttachedObject (Info->DataRegisterNode);
496         ObjDesc->IndexField.Value    = (UINT32)
497             (Info->FieldBitPosition / ACPI_MUL_8 (ObjDesc->Field.AccessByteWidth));
498
499         if (!ObjDesc->IndexField.DataObj || !ObjDesc->IndexField.IndexObj)
500         {
501             ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null Index Object\n"));
502             return_ACPI_STATUS (AE_AML_INTERNAL);
503         }
504
505         /* An additional reference for the attached objects */
506
507         AcpiUtAddReference (ObjDesc->IndexField.DataObj);
508         AcpiUtAddReference (ObjDesc->IndexField.IndexObj);
509
510         ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
511             "IndexField: bitoff=%X off=%X gran=%X Index %p Data %p\n",
512             ObjDesc->IndexField.StartFieldBitOffset,
513             ObjDesc->IndexField.BaseByteOffset,
514             ObjDesc->Field.AccessByteWidth,
515             ObjDesc->IndexField.IndexObj,
516             ObjDesc->IndexField.DataObj));
517         break;
518
519     default:
520         /* No other types should get here */
521         break;
522     }
523
524     /*
525      * Store the constructed descriptor (ObjDesc) into the parent Node,
526      * preserving the current type of that NamedObj.
527      */
528     Status = AcpiNsAttachObject (Info->FieldNode, ObjDesc,
529                     AcpiNsGetType (Info->FieldNode));
530
531     ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "set NamedObj %p (%4.4s) val = %p\n",
532             Info->FieldNode, Info->FieldNode->Name.Ascii, ObjDesc));
533
534     /* Remove local reference to the object */
535
536     AcpiUtRemoveReference (ObjDesc);
537     return_ACPI_STATUS (Status);
538 }
539