Merge from vendor branch BINUTILS:
[dragonfly.git] / sys / contrib / dev / acpica / evrgnini.c
1 /******************************************************************************
2  *
3  * Module Name: evrgnini- ACPI AddressSpace (OpRegion) init
4  *              $Revision: 66 $
5  *
6  *****************************************************************************/
7
8 /******************************************************************************
9  *
10  * 1. Copyright Notice
11  *
12  * Some or all of this work - Copyright (c) 1999 - 2003, 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 /* $DragonFly: src/sys/contrib/dev/acpica/Attic/evrgnini.c,v 1.1 2003/09/24 03:32:15 drhodus Exp $                                                               */
117
118
119 #define __EVRGNINI_C__
120
121 #include "acpi.h"
122 #include "acevents.h"
123 #include "acnamesp.h"
124
125 #define _COMPONENT          ACPI_EVENTS
126         ACPI_MODULE_NAME    ("evrgnini")
127
128
129 /*******************************************************************************
130  *
131  * FUNCTION:    AcpiEvSystemMemoryRegionSetup
132  *
133  * PARAMETERS:  RegionObj           - Region we are interested in
134  *              Function            - Start or stop
135  *              HandlerContext      - Address space handler context
136  *              RegionContext       - Region specific context
137  *
138  * RETURN:      Status
139  *
140  * DESCRIPTION: Do any prep work for region handling, a nop for now
141  *
142  ******************************************************************************/
143
144 ACPI_STATUS
145 AcpiEvSystemMemoryRegionSetup (
146     ACPI_HANDLE             Handle,
147     UINT32                  Function,
148     void                    *HandlerContext,
149     void                    **RegionContext)
150 {
151     ACPI_OPERAND_OBJECT     *RegionDesc = (ACPI_OPERAND_OBJECT *) Handle;
152     ACPI_MEM_SPACE_CONTEXT  *LocalRegionContext;
153
154
155     ACPI_FUNCTION_TRACE ("EvSystemMemoryRegionSetup");
156
157
158     if (Function == ACPI_REGION_DEACTIVATE)
159     {
160         if (*RegionContext)
161         {
162             ACPI_MEM_FREE (*RegionContext);
163             *RegionContext = NULL;
164         }
165         return_ACPI_STATUS (AE_OK);
166     }
167
168     /* Create a new context */
169
170     LocalRegionContext = ACPI_MEM_CALLOCATE (sizeof (ACPI_MEM_SPACE_CONTEXT));
171     if (!(LocalRegionContext))
172     {
173         return_ACPI_STATUS (AE_NO_MEMORY);
174     }
175
176     /* Save the region length and address for use in the handler */
177
178     LocalRegionContext->Length  = RegionDesc->Region.Length;
179     LocalRegionContext->Address = RegionDesc->Region.Address;
180
181     *RegionContext = LocalRegionContext;
182     return_ACPI_STATUS (AE_OK);
183 }
184
185
186 /*******************************************************************************
187  *
188  * FUNCTION:    AcpiEvIoSpaceRegionSetup
189  *
190  * PARAMETERS:  RegionObj           - Region we are interested in
191  *              Function            - Start or stop
192  *              HandlerContext      - Address space handler context
193  *              RegionContext       - Region specific context
194  *
195  * RETURN:      Status
196  *
197  * DESCRIPTION: Do any prep work for region handling
198  *
199  ******************************************************************************/
200
201 ACPI_STATUS
202 AcpiEvIoSpaceRegionSetup (
203     ACPI_HANDLE             Handle,
204     UINT32                  Function,
205     void                    *HandlerContext,
206     void                    **RegionContext)
207 {
208     ACPI_FUNCTION_TRACE ("EvIoSpaceRegionSetup");
209
210
211     if (Function == ACPI_REGION_DEACTIVATE)
212     {
213         *RegionContext = NULL;
214     }
215     else
216     {
217         *RegionContext = HandlerContext;
218     }
219
220     return_ACPI_STATUS (AE_OK);
221 }
222
223
224 /*******************************************************************************
225  *
226  * FUNCTION:    AcpiEvPciConfigRegionSetup
227  *
228  * PARAMETERS:  RegionObj           - Region we are interested in
229  *              Function            - Start or stop
230  *              HandlerContext      - Address space handler context
231  *              RegionContext       - Region specific context
232  *
233  * RETURN:      Status
234  *
235  * DESCRIPTION: Do any prep work for region handling
236  *
237  * MUTEX:       Assumes namespace is not locked
238  *
239  ******************************************************************************/
240
241 ACPI_STATUS
242 AcpiEvPciConfigRegionSetup (
243     ACPI_HANDLE             Handle,
244     UINT32                  Function,
245     void                    *HandlerContext,
246     void                    **RegionContext)
247 {
248     ACPI_STATUS             Status = AE_OK;
249     ACPI_INTEGER            Temp;
250     ACPI_PCI_ID             *PciId = *RegionContext;
251     ACPI_OPERAND_OBJECT     *HandlerObj;
252     ACPI_NAMESPACE_NODE     *Node;
253     ACPI_OPERAND_OBJECT     *RegionObj = (ACPI_OPERAND_OBJECT  *) Handle;
254     ACPI_DEVICE_ID          ObjectHID;
255
256
257     ACPI_FUNCTION_TRACE ("EvPciConfigRegionSetup");
258
259
260     HandlerObj = RegionObj->Region.AddrHandler;
261     if (!HandlerObj)
262     {
263         /*
264          * No installed handler. This shouldn't happen because the dispatch
265          * routine checks before we get here, but we check again just in case.
266          */
267         ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
268             "Attempting to init a region %p, with no handler\n", RegionObj));
269         return_ACPI_STATUS (AE_NOT_EXIST);
270     }
271
272     if (Function == ACPI_REGION_DEACTIVATE)
273     {
274         if (PciId)
275         {
276             ACPI_MEM_FREE (PciId);
277             *RegionContext = NULL;
278         }
279
280         return_ACPI_STATUS (Status);
281     }
282
283     /* Create a new context */
284
285     PciId = ACPI_MEM_CALLOCATE (sizeof (ACPI_PCI_ID));
286     if (!PciId)
287     {
288         return_ACPI_STATUS (AE_NO_MEMORY);
289     }
290
291     /*
292      * For PCI Config space access, we have to pass the segment, bus,
293      * device and function numbers.  This routine must acquire those.
294      */
295
296     /*
297      * First get device and function numbers from the _ADR object
298      * in the parent's scope.
299      */
300     Node = AcpiNsGetParentNode (RegionObj->Region.Node);
301
302     /* Evaluate the _ADR object */
303
304     Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR, Node, &Temp);
305
306     /*
307      * The default is zero, and since the allocation above zeroed
308      * the data, just do nothing on failure.
309      */
310     if (ACPI_SUCCESS (Status))
311     {
312         PciId->Device   = ACPI_HIWORD (ACPI_LODWORD (Temp));
313         PciId->Function = ACPI_LOWORD (ACPI_LODWORD (Temp));
314     }
315
316     /*
317      * Get the _SEG and _BBN values from the device upon which the handler
318      * is installed.
319      *
320      * We need to get the _SEG and _BBN objects relative to the PCI BUS device.
321      * This is the device the handler has been registered to handle.
322      */
323
324     /*
325      * If the AddrHandler.Node is still pointing to the root, we need
326      * to scan upward for a PCI Root bridge and re-associate the OpRegion
327      * handlers with that device.
328      */
329     if (HandlerObj->AddrHandler.Node == AcpiGbl_RootNode)
330     {
331         /*
332          * Node is currently the parent object
333          */
334         while (Node != AcpiGbl_RootNode)
335         {
336             Status = AcpiUtExecute_HID (Node, &ObjectHID);
337             if (ACPI_SUCCESS (Status))
338             {
339                 /* Got a valid _HID, check if this is a PCI root */
340
341                 if (!(ACPI_STRNCMP (ObjectHID.Buffer, PCI_ROOT_HID_STRING,
342                                     sizeof (PCI_ROOT_HID_STRING))))
343                 {
344                     /* Install a handler for this PCI root bridge */
345
346                     Status = AcpiInstallAddressSpaceHandler ((ACPI_HANDLE) Node,
347                                         ACPI_ADR_SPACE_PCI_CONFIG,
348                                         ACPI_DEFAULT_HANDLER, NULL, NULL);
349                     if (ACPI_FAILURE (Status))
350                     {
351                         ACPI_REPORT_ERROR (("Could not install PciConfig handler for %4.4s, %s\n",
352                             Node->Name.Ascii, AcpiFormatException (Status)));
353                     }
354                     break;
355                 }
356             }
357
358             Node = AcpiNsGetParentNode (Node);
359         }
360     }
361     else
362     {
363         Node = HandlerObj->AddrHandler.Node;
364     }
365
366     /*
367      * The PCI segment number comes from the _SEG method
368      */
369     Status = AcpiUtEvaluateNumericObject (METHOD_NAME__SEG, Node, &Temp);
370     if (ACPI_SUCCESS (Status))
371     {
372         PciId->Segment = ACPI_LOWORD (Temp);
373     }
374
375     /*
376      * The PCI bus number comes from the _BBN method
377      */
378     Status = AcpiUtEvaluateNumericObject (METHOD_NAME__BBN, Node, &Temp);
379     if (ACPI_SUCCESS (Status))
380     {
381         PciId->Bus = ACPI_LOWORD (Temp);
382     }
383
384     /*
385      * Complete this device's PciId
386      */
387     AcpiOsDerivePciId (Node, RegionObj->Region.Node, &PciId);
388
389     *RegionContext = PciId;
390     return_ACPI_STATUS (AE_OK);
391 }
392
393
394 /*******************************************************************************
395  *
396  * FUNCTION:    AcpiEvPciBarRegionSetup
397  *
398  * PARAMETERS:  RegionObj           - Region we are interested in
399  *              Function            - Start or stop
400  *              HandlerContext      - Address space handler context
401  *              RegionContext       - Region specific context
402  *
403  * RETURN:      Status
404  *
405  * DESCRIPTION: Do any prep work for region handling
406  *
407  * MUTEX:       Assumes namespace is not locked
408  *
409  ******************************************************************************/
410
411 ACPI_STATUS
412 AcpiEvPciBarRegionSetup (
413     ACPI_HANDLE             Handle,
414     UINT32                  Function,
415     void                    *HandlerContext,
416     void                    **RegionContext)
417 {
418     ACPI_FUNCTION_TRACE ("EvPciBarRegionSetup");
419
420
421     return_ACPI_STATUS (AE_OK);
422 }
423
424
425 /*******************************************************************************
426  *
427  * FUNCTION:    AcpiEvCmosRegionSetup
428  *
429  * PARAMETERS:  RegionObj           - Region we are interested in
430  *              Function            - Start or stop
431  *              HandlerContext      - Address space handler context
432  *              RegionContext       - Region specific context
433  *
434  * RETURN:      Status
435  *
436  * DESCRIPTION: Do any prep work for region handling
437  *
438  * MUTEX:       Assumes namespace is not locked
439  *
440  ******************************************************************************/
441
442 ACPI_STATUS
443 AcpiEvCmosRegionSetup (
444     ACPI_HANDLE             Handle,
445     UINT32                  Function,
446     void                    *HandlerContext,
447     void                    **RegionContext)
448 {
449     ACPI_FUNCTION_TRACE ("EvCmosRegionSetup");
450
451
452     return_ACPI_STATUS (AE_OK);
453 }
454
455
456 /*******************************************************************************
457  *
458  * FUNCTION:    AcpiEvDefaultRegionSetup
459  *
460  * PARAMETERS:  RegionObj           - Region we are interested in
461  *              Function            - Start or stop
462  *              HandlerContext      - Address space handler context
463  *              RegionContext       - Region specific context
464  *
465  * RETURN:      Status
466  *
467  * DESCRIPTION: Do any prep work for region handling
468  *
469  ******************************************************************************/
470
471 ACPI_STATUS
472 AcpiEvDefaultRegionSetup (
473     ACPI_HANDLE             Handle,
474     UINT32                  Function,
475     void                    *HandlerContext,
476     void                    **RegionContext)
477 {
478     ACPI_FUNCTION_TRACE ("EvDefaultRegionSetup");
479
480
481     if (Function == ACPI_REGION_DEACTIVATE)
482     {
483         *RegionContext = NULL;
484     }
485     else
486     {
487         *RegionContext = HandlerContext;
488     }
489
490     return_ACPI_STATUS (AE_OK);
491 }
492
493
494 /*******************************************************************************
495  *
496  * FUNCTION:    AcpiEvInitializeRegion
497  *
498  * PARAMETERS:  RegionObj       - Region we are initializing
499  *              AcpiNsLocked    - Is namespace locked?
500  *
501  * RETURN:      Status
502  *
503  * DESCRIPTION: Initializes the region, finds any _REG methods and saves them
504  *              for execution at a later time
505  *
506  *              Get the appropriate address space handler for a newly
507  *              created region.
508  *
509  *              This also performs address space specific initialization.  For
510  *              example, PCI regions must have an _ADR object that contains
511  *              a PCI address in the scope of the definition.  This address is
512  *              required to perform an access to PCI config space.
513  *
514  ******************************************************************************/
515
516 ACPI_STATUS
517 AcpiEvInitializeRegion (
518     ACPI_OPERAND_OBJECT     *RegionObj,
519     BOOLEAN                 AcpiNsLocked)
520 {
521     ACPI_OPERAND_OBJECT     *HandlerObj;
522     ACPI_OPERAND_OBJECT     *ObjDesc;
523     ACPI_ADR_SPACE_TYPE     SpaceId;
524     ACPI_NAMESPACE_NODE     *Node;
525     ACPI_STATUS             Status;
526     ACPI_NAMESPACE_NODE     *MethodNode;
527     ACPI_NAME               *RegNamePtr = (ACPI_NAME *) METHOD_NAME__REG;
528     ACPI_OPERAND_OBJECT     *RegionObj2;
529
530
531     ACPI_FUNCTION_TRACE_U32 ("EvInitializeRegion", AcpiNsLocked);
532
533
534     if (!RegionObj)
535     {
536         return_ACPI_STATUS (AE_BAD_PARAMETER);
537     }
538
539     if (RegionObj->Common.Flags & AOPOBJ_OBJECT_INITIALIZED)
540     {
541         return_ACPI_STATUS (AE_OK);
542     }
543
544     RegionObj2 = AcpiNsGetSecondaryObject (RegionObj);
545     if (!RegionObj2)
546     {
547         return_ACPI_STATUS (AE_NOT_EXIST);
548     }
549
550     Node = AcpiNsGetParentNode (RegionObj->Region.Node);
551     SpaceId = RegionObj->Region.SpaceId;
552
553     RegionObj->Region.AddrHandler = NULL;
554     RegionObj2->Extra.Method_REG = NULL;
555     RegionObj->Common.Flags &= ~(AOPOBJ_SETUP_COMPLETE);
556     RegionObj->Common.Flags |= AOPOBJ_OBJECT_INITIALIZED;
557
558     /*
559      * Find any "_REG" method associated with this region definition
560      */
561     Status = AcpiNsSearchNode (*RegNamePtr, Node,
562                                    ACPI_TYPE_METHOD, &MethodNode);
563     if (ACPI_SUCCESS (Status))
564     {
565         /*
566          * The _REG method is optional and there can be only one per region
567          * definition.  This will be executed when the handler is attached
568          * or removed
569          */
570         RegionObj2->Extra.Method_REG = MethodNode;
571     }
572
573     /*
574      * The following loop depends upon the root Node having no parent
575      * ie: AcpiGbl_RootNode->ParentEntry being set to NULL
576      */
577     while (Node)
578     {
579         /*
580          * Check to see if a handler exists
581          */
582         HandlerObj = NULL;
583         ObjDesc = AcpiNsGetAttachedObject (Node);
584         if (ObjDesc)
585         {
586             /*
587              * Can only be a handler if the object exists
588              */
589             switch (Node->Type)
590             {
591             case ACPI_TYPE_DEVICE:
592
593                 HandlerObj = ObjDesc->Device.AddrHandler;
594                 break;
595
596             case ACPI_TYPE_PROCESSOR:
597
598                 HandlerObj = ObjDesc->Processor.AddrHandler;
599                 break;
600
601             case ACPI_TYPE_THERMAL:
602
603                 HandlerObj = ObjDesc->ThermalZone.AddrHandler;
604                 break;
605
606             default:
607                 /* Ignore other objects */
608                 break;
609             }
610
611             while (HandlerObj)
612             {
613                 /* Is this handler of the correct type? */
614
615                 if (HandlerObj->AddrHandler.SpaceId == SpaceId)
616                 {
617                     /* Found correct handler */
618
619                     ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
620                         "Found handler %p for region %p in obj %p\n",
621                         HandlerObj, RegionObj, ObjDesc));
622
623                     Status = AcpiEvAttachRegion (HandlerObj, RegionObj,
624                                 AcpiNsLocked);
625
626                     return_ACPI_STATUS (AE_OK);
627                 }
628
629                 /* Try next handler in the list */
630
631                 HandlerObj = HandlerObj->AddrHandler.Next;
632             }
633         }
634
635         /*
636          * This node does not have the handler we need;
637          * Pop up one level
638          */
639         Node = AcpiNsGetParentNode (Node);
640     }
641
642     /*
643      * If we get here, there is no handler for this region
644      */
645     ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
646         "No handler for RegionType %s(%X) (RegionObj %p)\n",
647         AcpiUtGetRegionName (SpaceId), SpaceId, RegionObj));
648
649     return_ACPI_STATUS (AE_NOT_EXIST);
650 }
651