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