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