]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/contrib/dev/acpica/exresolv.c
Initial import of the Intel-maintained ACPI Component Architecture. This
[FreeBSD/FreeBSD.git] / sys / contrib / dev / acpica / exresolv.c
1
2 /******************************************************************************
3  *
4  * Module Name: amresolv - AML Interpreter object resolution
5  *              $Revision: 76 $
6  *
7  *****************************************************************************/
8
9 /******************************************************************************
10  *
11  * 1. Copyright Notice
12  *
13  * Some or all of this work - Copyright (c) 1999, Intel Corp.  All rights
14  * 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
118 #define __AMRESOLV_C__
119
120 #include "acpi.h"
121 #include "amlcode.h"
122 #include "acparser.h"
123 #include "acdispat.h"
124 #include "acinterp.h"
125 #include "acnamesp.h"
126 #include "actables.h"
127 #include "acevents.h"
128
129
130 #define _COMPONENT          INTERPRETER
131         MODULE_NAME         ("amresolv")
132
133
134 /*******************************************************************************
135  *
136  * FUNCTION:    AcpiAmlGetFieldUnitValue
137  *
138  * PARAMETERS:  *FieldDesc          - Pointer to a FieldUnit
139  *              *ResultDesc         - Pointer to an empty descriptor
140  *                                    which will become a Number
141  *                                    containing the field's value.
142  *
143  * RETURN:      Status
144  *
145  * DESCRIPTION: Retrieve the value from a FieldUnit
146  *
147  ******************************************************************************/
148
149 ACPI_STATUS
150 AcpiAmlGetFieldUnitValue (
151     ACPI_OPERAND_OBJECT     *FieldDesc,
152     ACPI_OPERAND_OBJECT     *ResultDesc)
153 {
154     ACPI_STATUS             Status = AE_OK;
155     UINT32                  Mask;
156     UINT8                   *Location = NULL;
157     BOOLEAN                 Locked = FALSE;
158
159
160     FUNCTION_TRACE ("AmlGetFieldUnitValue");
161
162
163     if (!FieldDesc)
164     {
165         DEBUG_PRINT (ACPI_ERROR,
166             ("AmlGetFieldUnitValue: Internal error - null field pointer\n"));
167         Status = AE_AML_NO_OPERAND;
168     }
169
170     if (!(FieldDesc->Common.Flags & AOPOBJ_DATA_VALID))
171     {
172         Status = AcpiDsGetFieldUnitArguments (FieldDesc);
173         if (ACPI_FAILURE (Status))
174         {
175             return_ACPI_STATUS (Status);
176         }
177     }
178
179     if (!FieldDesc->FieldUnit.Container)
180     {
181         DEBUG_PRINT (ACPI_ERROR,
182             ("AmlGetFieldUnitValue: Internal error - null container pointer\n"));
183         Status = AE_AML_INTERNAL;
184     }
185
186     else if (ACPI_TYPE_BUFFER != FieldDesc->FieldUnit.Container->Common.Type)
187     {
188         DEBUG_PRINT (ACPI_ERROR,
189             ("AmlGetFieldUnitValue: Internal error - container is not a Buffer\n"));
190         Status = AE_AML_OPERAND_TYPE;
191     }
192
193     else if (!ResultDesc)
194     {
195         DEBUG_PRINT (ACPI_ERROR,
196             ("AmlGetFieldUnitValue: Internal error - null result pointer\n"));
197         Status = AE_AML_INTERNAL;
198     }
199
200     if (ACPI_FAILURE (Status))
201     {
202         return_ACPI_STATUS (Status);
203     }
204
205
206         /* Get the global lock if needed */
207
208     Locked = AcpiAmlAcquireGlobalLock (FieldDesc->FieldUnit.LockRule);
209
210     /* Field location is (base of buffer) + (byte offset) */
211
212     Location = FieldDesc->FieldUnit.Container->Buffer.Pointer
213                 + FieldDesc->FieldUnit.Offset;
214
215     /*
216      * Construct Mask with as many 1 bits as the field width
217      *
218      * NOTE: Only the bottom 5 bits are valid for a shift operation, so
219      *  special care must be taken for any shift greater than 31 bits.
220      *
221      * TBD: [Unhandled] Fields greater than 32-bits will not work.
222      */
223
224     if (FieldDesc->FieldUnit.Length < 32)
225     {
226         Mask = ((UINT32) 1 << FieldDesc->FieldUnit.Length) - (UINT32) 1;
227     }
228     else
229     {
230         Mask = ACPI_UINT32_MAX;
231     }
232
233     ResultDesc->Number.Type = (UINT8) ACPI_TYPE_NUMBER;
234
235     /* Get the 32 bit value at the location */
236
237     MOVE_UNALIGNED32_TO_32 (&ResultDesc->Number.Value, Location);
238
239     /*
240      * Shift the 32-bit word containing the field, and mask off the
241      * resulting value
242      */
243
244     ResultDesc->Number.Value =
245         (ResultDesc->Number.Value >> FieldDesc->FieldUnit.BitOffset) & Mask;
246
247     DEBUG_PRINT (ACPI_INFO,
248         ("** Read from buffer %p byte %ld bit %d width %d addr %p mask %08lx val %08lx\n",
249         FieldDesc->FieldUnit.Container->Buffer.Pointer,
250         FieldDesc->FieldUnit.Offset,
251         FieldDesc->FieldUnit.BitOffset,
252         FieldDesc->FieldUnit.Length,
253         Location, Mask, ResultDesc->Number.Value));
254
255     /* Release global lock if we acquired it earlier */
256
257     AcpiAmlReleaseGlobalLock (Locked);
258
259     return_ACPI_STATUS (Status);
260 }
261
262
263 /*******************************************************************************
264  *
265  * FUNCTION:    AcpiAmlResolveToValue
266  *
267  * PARAMETERS:  **StackPtr          - Points to entry on ObjStack, which can
268  *                                    be either an (ACPI_OPERAND_OBJECT  *)
269  *                                    or an ACPI_HANDLE.
270  *
271  * RETURN:      Status
272  *
273  * DESCRIPTION: Convert Reference entries on ObjStack to Rvalues
274  *
275  ******************************************************************************/
276
277 ACPI_STATUS
278 AcpiAmlResolveToValue (
279     ACPI_OPERAND_OBJECT     **StackPtr,
280     ACPI_WALK_STATE         *WalkState)
281 {
282     ACPI_STATUS             Status = AE_OK;
283
284
285     FUNCTION_TRACE_PTR ("AmlResolveToValue", StackPtr);
286
287
288     if (!StackPtr || !*StackPtr)
289     {
290         DEBUG_PRINT (ACPI_ERROR,
291             ("AmlResolveToValue: Internal error - null pointer\n"));
292         return_ACPI_STATUS (AE_AML_NO_OPERAND);
293     }
294
295
296     /*
297      * The entity pointed to by the StackPtr can be either
298      * 1) A valid ACPI_OPERAND_OBJECT, or
299      * 2) A ACPI_NAMESPACE_NODE (NamedObj)
300      */
301
302     if (VALID_DESCRIPTOR_TYPE (*StackPtr, ACPI_DESC_TYPE_INTERNAL))
303     {
304
305         Status = AcpiAmlResolveObjectToValue (StackPtr, WalkState);
306         if (ACPI_FAILURE (Status))
307         {
308             return_ACPI_STATUS (Status);
309         }
310     }
311
312     /*
313      * Object on the stack may have changed if AcpiAmlResolveObjectToValue()
314      * was called (i.e., we can't use an _else_ here.)
315      */
316
317     if (VALID_DESCRIPTOR_TYPE (*StackPtr, ACPI_DESC_TYPE_NAMED))
318     {
319         Status = AcpiAmlResolveNodeToValue ((ACPI_NAMESPACE_NODE **) StackPtr);
320     }
321
322
323     DEBUG_PRINT (ACPI_INFO,
324         ("AmlResolveToValue: Returning resolved object %p\n", *StackPtr));
325
326     return_ACPI_STATUS (Status);
327 }
328
329
330 /*******************************************************************************
331  *
332  * FUNCTION:    AcpiAmlResolveObjectToValue
333  *
334  * PARAMETERS:  StackPtr        - Pointer to a stack location that contains a
335  *                                ptr to an internal object.
336  *
337  * RETURN:      Status
338  *
339  * DESCRIPTION: Retrieve the value from an internal object.  The Reference type
340  *              uses the associated AML opcode to determine the value.
341  *
342  ******************************************************************************/
343
344 ACPI_STATUS
345 AcpiAmlResolveObjectToValue (
346     ACPI_OPERAND_OBJECT     **StackPtr,
347     ACPI_WALK_STATE         *WalkState)
348 {
349     ACPI_OPERAND_OBJECT     *StackDesc;
350     ACPI_STATUS             Status = AE_OK;
351     ACPI_HANDLE             TempHandle = NULL;
352     ACPI_OPERAND_OBJECT     *ObjDesc = NULL;
353     UINT32                  Index = 0;
354     UINT16                  Opcode;
355
356
357     FUNCTION_TRACE ("AmlResolveObjectToValue");
358
359
360     StackDesc = *StackPtr;
361
362     /* This is an ACPI_OPERAND_OBJECT  */
363
364     switch (StackDesc->Common.Type)
365     {
366
367     case INTERNAL_TYPE_REFERENCE:
368
369         Opcode = StackDesc->Reference.OpCode;
370
371         switch (Opcode)
372         {
373
374         case AML_NAME_OP:
375
376             /*
377              * Convert indirect name ptr to a direct name ptr.
378              * Then, AcpiAmlResolveNodeToValue can be used to get the value
379              */
380
381             TempHandle = StackDesc->Reference.Object;
382
383             /* Delete the Reference Object */
384
385             AcpiCmRemoveReference (StackDesc);
386
387             /* Put direct name pointer onto stack and exit */
388
389             (*StackPtr) = TempHandle;
390             Status = AE_OK;
391             break;
392
393
394         case AML_LOCAL_OP:
395
396             Index = StackDesc->Reference.Offset;
397
398             /*
399              * Get the local from the method's state info
400              * Note: this increments the local's object reference count
401              */
402
403             Status = AcpiDsMethodDataGetValue (MTH_TYPE_LOCAL, Index,
404                                                 WalkState, &ObjDesc);
405             if (ACPI_FAILURE (Status))
406             {
407                 return_ACPI_STATUS (Status);
408             }
409
410             /*
411              * Now we can delete the original Reference Object and
412              * replace it with the resolve value
413              */
414
415             AcpiCmRemoveReference (StackDesc);
416             *StackPtr = ObjDesc;
417
418             DEBUG_PRINT (ACPI_INFO,
419                 ("AmlResolveObjectToValue: [Local%d] ValueObj is %p\n",
420                 Index, ObjDesc));
421
422             if (ACPI_TYPE_NUMBER == ObjDesc->Common.Type)
423             {
424                 /* Value is a Number */
425
426                 DEBUG_PRINT (ACPI_INFO,
427                     ("AmlResolveObjectToValue: [Local%d] value is [0x%X] \n",
428                     Index, ObjDesc->Number.Value));
429             }
430
431             break;
432
433
434         case AML_ARG_OP:
435
436             Index = StackDesc->Reference.Offset;
437
438
439             /*
440              * Get the argument from the method's state info
441              * Note: this increments the object reference count
442              */
443
444             Status = AcpiDsMethodDataGetValue (MTH_TYPE_ARG, Index,
445                                                 WalkState, &ObjDesc);
446             if (ACPI_FAILURE (Status))
447             {
448                 return_ACPI_STATUS (Status);
449             }
450
451             /*
452              * Now we can delete the original Reference Object and
453              * replace it with the resolve value
454              */
455
456             AcpiCmRemoveReference (StackDesc);
457             *StackPtr = ObjDesc;
458
459             DEBUG_PRINT (TRACE_EXEC,
460                 ("AmlResolveObjectToValue: [Arg%d] ValueObj is %p\n",
461                 Index, ObjDesc));
462
463             if (ACPI_TYPE_NUMBER == ObjDesc->Common.Type)
464             {
465                 /* Value is a Number */
466
467                 DEBUG_PRINT (ACPI_INFO,
468                     ("AmlResolveObjectToValue: [Arg%d] value is [0x%X] \n",
469                     Index, ObjDesc->Number.Value));
470             }
471
472             break;
473
474
475         /*
476          * TBD: [Restructure] These next three opcodes change the type of
477          * the object, which is actually a no-no.
478          */
479
480         case AML_ZERO_OP:
481
482             StackDesc->Common.Type = (UINT8) ACPI_TYPE_NUMBER;
483             StackDesc->Number.Value = 0;
484             break;
485
486
487         case AML_ONE_OP:
488
489             StackDesc->Common.Type = (UINT8) ACPI_TYPE_NUMBER;
490             StackDesc->Number.Value = 1;
491             break;
492
493
494         case AML_ONES_OP:
495
496             StackDesc->Common.Type = (UINT8) ACPI_TYPE_NUMBER;
497             StackDesc->Number.Value = ACPI_INTEGER_MAX;
498             break;
499
500
501         case AML_INDEX_OP:
502
503             switch (StackDesc->Reference.TargetType)
504             {
505             case ACPI_TYPE_BUFFER_FIELD:
506
507                 /* Just return - leave the Reference on the stack */
508                 break;
509
510
511             case ACPI_TYPE_PACKAGE:
512                 ObjDesc = *StackDesc->Reference.Where;
513                 if (ObjDesc)
514                 {
515                     /*
516                      * Valid obj descriptor, copy pointer to return value
517                      * (i.e., dereference the package index)
518                      * Delete the ref object, increment the returned object
519                      */
520                     AcpiCmRemoveReference (StackDesc);
521                     AcpiCmAddReference (ObjDesc);
522                     *StackPtr = ObjDesc;
523                 }
524
525                 else
526                 {
527                     /*
528                      * A NULL object descriptor means an unitialized element of
529                      * the package, can't deref it
530                      */
531
532                     DEBUG_PRINT (ACPI_ERROR,
533                         ("AmlResolveObjectToValue: Attempt to deref an Index to NULL pkg element Idx=%p\n", StackDesc));
534                     Status = AE_AML_UNINITIALIZED_ELEMENT;
535                 }
536                 break;
537
538             default:
539                 /* Invalid reference OBJ*/
540
541                 DEBUG_PRINT (ACPI_ERROR,
542                     ("AmlResolveObjectToValue: Unknown TargetType %d in Index/Reference obj %p\n",
543                     StackDesc->Reference.TargetType, StackDesc));
544                 Status = AE_AML_INTERNAL;
545                 break;
546             }
547
548             break;
549
550
551         case AML_DEBUG_OP:
552
553             /* Just leave the object as-is */
554             break;
555
556
557         default:
558
559             DEBUG_PRINT (ACPI_ERROR,
560                 ("AmlResolveObjectToValue: Unknown Reference object subtype %02x in %p\n",
561                 Opcode, StackDesc));
562             Status = AE_AML_INTERNAL;
563
564         }   /* switch (Opcode) */
565
566
567         if (ACPI_FAILURE (Status))
568         {
569             return_ACPI_STATUS (Status);
570         }
571
572         break; /* case INTERNAL_TYPE_REFERENCE */
573
574
575     case ACPI_TYPE_FIELD_UNIT:
576
577         ObjDesc = AcpiCmCreateInternalObject (ACPI_TYPE_ANY);
578         if (!ObjDesc)
579         {
580             /* Descriptor allocation failure  */
581
582             return_ACPI_STATUS (AE_NO_MEMORY);
583         }
584
585         Status = AcpiAmlGetFieldUnitValue (StackDesc, ObjDesc);
586         if (ACPI_FAILURE (Status))
587         {
588             AcpiCmRemoveReference (ObjDesc);
589             ObjDesc = NULL;
590         }
591
592         *StackPtr = (void *) ObjDesc;
593         break;
594
595
596     case INTERNAL_TYPE_BANK_FIELD:
597
598         ObjDesc = AcpiCmCreateInternalObject (ACPI_TYPE_ANY);
599         if (!ObjDesc)
600         {
601             /* Descriptor allocation failure */
602
603             return_ACPI_STATUS (AE_NO_MEMORY);
604         }
605
606         Status = AcpiAmlGetFieldUnitValue (StackDesc, ObjDesc);
607         if (ACPI_FAILURE (Status))
608         {
609             AcpiCmRemoveReference (ObjDesc);
610             ObjDesc = NULL;
611         }
612
613         *StackPtr = (void *) ObjDesc;
614         break;
615
616
617     /* TBD: [Future] - may need to handle IndexField, and DefField someday */
618
619     default:
620
621         break;
622
623     }   /* switch (StackDesc->Common.Type) */
624
625
626     return_ACPI_STATUS (Status);
627 }
628
629