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