evrgnini.c revision 77424
1/******************************************************************************
2 *
3 * Module Name: evrgnini- ACPI AddressSpace (OpRegion) init
4 *              $Revision: 40 $
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            AcpiUtFree (*RegionContext);
160            *RegionContext = NULL;
161        }
162        return_ACPI_STATUS (AE_OK);
163    }
164
165
166    /* Activate.  Create a new context */
167
168    *RegionContext = AcpiUtCallocate (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_SPACE_CONTEXT  *PciContext = *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        DEBUG_PRINTP (TRACE_OPREGION,
260            ("Attempting to init a region %X, with no handler\n", RegionObj));
261        return_ACPI_STATUS (AE_NOT_EXIST);
262    }
263
264    if (Function == ACPI_REGION_DEACTIVATE)
265    {
266        if (PciContext)
267        {
268            AcpiUtFree (PciContext);
269            *RegionContext = NULL;
270        }
271
272        return_ACPI_STATUS (Status);
273    }
274
275
276    /* Create a new context */
277
278    PciContext = AcpiUtCallocate (sizeof (ACPI_PCI_SPACE_CONTEXT));
279    if (!PciContext)
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    ACPI_ASSERT (RegionObj->Region.Node);
294
295    Node = AcpiNsGetParentObject (RegionObj->Region.Node);
296
297
298    /* AcpiEvaluate the _ADR object */
299
300    Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR, Node, &Temp);
301
302    /*
303     *  The default is zero, since the allocation above zeroed the data, just
304     *  do nothing on failures.
305     */
306    if (ACPI_SUCCESS (Status))
307    {
308        PciContext->DevFunc = (UINT32) Temp;
309    }
310
311    /*
312     *  Get the _SEG and _BBN values from the device upon which the handler
313     *  is installed.
314     *
315     *  We need to get the _SEG and _BBN objects relative to the PCI BUS device.
316     *  This is the device the handler has been registered to handle.
317     */
318
319    /*
320     *  If the AddrHandler.Node is still pointing to the root, we need
321     *  to scan upward for a PCI Root bridge and re-associate the OpRegion
322     *  handlers with that device.
323     */
324    if (HandlerObj->AddrHandler.Node == AcpiGbl_RootNode)
325    {
326        /*
327         * Node is currently the parent object
328         */
329        while (Node != AcpiGbl_RootNode)
330        {
331            Status = AcpiUtExecute_HID (Node, &ObjectHID);
332            if (ACPI_SUCCESS (Status))
333            {
334                if (!(STRNCMP (ObjectHID.Buffer, PCI_ROOT_HID_STRING,
335                                    sizeof (PCI_ROOT_HID_STRING))))
336                {
337                    AcpiInstallAddressSpaceHandler (Node,
338                                        ACPI_ADR_SPACE_PCI_CONFIG,
339                                        ACPI_DEFAULT_HANDLER, NULL, NULL);
340                    break;
341                }
342            }
343
344            Node = AcpiNsGetParentObject (Node);
345        }
346    }
347    else
348    {
349        Node = HandlerObj->AddrHandler.Node;
350    }
351
352    Status = AcpiUtEvaluateNumericObject (METHOD_NAME__SEG, Node, &Temp);
353    if (ACPI_SUCCESS (Status))
354    {
355        PciContext->Seg = (UINT32) Temp;
356    }
357
358    Status = AcpiUtEvaluateNumericObject (METHOD_NAME__BBN, Node, &Temp);
359    if (ACPI_SUCCESS (Status))
360    {
361        PciContext->Bus = (UINT32) Temp;
362    }
363
364    *RegionContext = PciContext;
365
366    return_ACPI_STATUS (AE_OK);
367}
368
369
370/*******************************************************************************
371 *
372 * FUNCTION:    AcpiEvDefaultRegionSetup
373 *
374 * PARAMETERS:  RegionObj           - region we are interested in
375 *              Function            - start or stop
376 *              HandlerContext      - Address space handler context
377 *              RegionContext       - Region specific context
378 *
379 * RETURN:      Status
380 *
381 * DESCRIPTION: Do any prep work for region handling
382 *
383 ******************************************************************************/
384
385ACPI_STATUS
386AcpiEvDefaultRegionSetup (
387    ACPI_HANDLE             Handle,
388    UINT32                  Function,
389    void                    *HandlerContext,
390    void                    **RegionContext)
391{
392    FUNCTION_TRACE ("EvDefaultRegionSetup");
393
394
395    if (Function == ACPI_REGION_DEACTIVATE)
396    {
397        *RegionContext = NULL;
398    }
399    else
400    {
401        *RegionContext = HandlerContext;
402    }
403
404    return_ACPI_STATUS (AE_OK);
405}
406
407
408/*******************************************************************************
409 *
410 * FUNCTION:    AcpiEvInitializeRegion
411 *
412 * PARAMETERS:  RegionObj  - Region we are initializing
413 *
414 * RETURN:      Status
415 *
416 * DESCRIPTION: Initializes the region, finds any _REG methods and saves them
417 *              for execution at a later time
418 *
419 *              Get the appropriate address space handler for a newly
420 *              created region.
421 *
422 *              This also performs address space specific intialization.  For
423 *              example, PCI regions must have an _ADR object that contains
424 *              a PCI address in the scope of the definition.  This address is
425 *              required to perform an access to PCI config space.
426 *
427 ******************************************************************************/
428
429ACPI_STATUS
430AcpiEvInitializeRegion (
431    ACPI_OPERAND_OBJECT     *RegionObj,
432    BOOLEAN                 AcpiNsLocked)
433{
434    ACPI_OPERAND_OBJECT     *HandlerObj;
435    ACPI_OPERAND_OBJECT     *ObjDesc;
436    ACPI_ADR_SPACE_TYPE     SpaceId;
437    ACPI_NAMESPACE_NODE     *Node;
438    ACPI_STATUS             Status;
439    ACPI_NAMESPACE_NODE     *MethodNode;
440    ACPI_NAME               *RegNamePtr = (ACPI_NAME *) METHOD_NAME__REG;
441
442
443    FUNCTION_TRACE_U32 ("EvInitializeRegion", AcpiNsLocked);
444
445
446    if (!RegionObj)
447    {
448        return_ACPI_STATUS (AE_BAD_PARAMETER);
449    }
450
451    ACPI_ASSERT (RegionObj->Region.Node);
452
453    Node = AcpiNsGetParentObject (RegionObj->Region.Node);
454    SpaceId = RegionObj->Region.SpaceId;
455
456    RegionObj->Region.AddrHandler = NULL;
457    RegionObj->Region.Extra->Extra.Method_REG = NULL;
458    RegionObj->Region.Flags &= ~(AOPOBJ_INITIALIZED);
459
460    /*
461     *  Find any "_REG" associated with this region definition
462     */
463    Status = AcpiNsSearchNode (*RegNamePtr, Node,
464                                   ACPI_TYPE_METHOD, &MethodNode);
465    if (ACPI_SUCCESS (Status))
466    {
467        /*
468         *  The _REG method is optional and there can be only one per region
469         *  definition.  This will be executed when the handler is attached
470         *  or removed
471         */
472        RegionObj->Region.Extra->Extra.Method_REG = MethodNode;
473    }
474
475    /*
476     *  The following loop depends upon the root Node having no parent
477     *  ie: AcpiGbl_RootNode->ParentEntry being set to NULL
478     */
479    while (Node)
480    {
481        /*
482         *  Check to see if a handler exists
483         */
484        HandlerObj = NULL;
485        ObjDesc = AcpiNsGetAttachedObject (Node);
486        if (ObjDesc)
487        {
488            /*
489             *  can only be a handler if the object exists
490             */
491            switch (Node->Type)
492            {
493            case ACPI_TYPE_DEVICE:
494
495                HandlerObj = ObjDesc->Device.AddrHandler;
496                break;
497
498            case ACPI_TYPE_PROCESSOR:
499
500                HandlerObj = ObjDesc->Processor.AddrHandler;
501                break;
502
503            case ACPI_TYPE_THERMAL:
504
505                HandlerObj = ObjDesc->ThermalZone.AddrHandler;
506                break;
507            }
508
509            while (HandlerObj)
510            {
511                /*
512                 *  This guy has at least one address handler
513                 *  see if it has the type we want
514                 */
515                if (HandlerObj->AddrHandler.SpaceId == SpaceId)
516                {
517                    DEBUG_PRINTP (TRACE_OPREGION,
518                        ("Found handler %p for region %p in obj %p\n",
519                        HandlerObj, RegionObj, ObjDesc));
520
521                    /*
522                     *  Found it! Now update the region and the handler
523                     */
524                    AcpiEvAssociateRegionAndHandler (HandlerObj, RegionObj,
525                            AcpiNsLocked);
526                    return_ACPI_STATUS (AE_OK);
527                }
528
529                HandlerObj = HandlerObj->AddrHandler.Next;
530
531            } /* while handlerobj */
532        }
533
534        /*
535         *  This one does not have the handler we need
536         *  Pop up one level
537         */
538        Node = AcpiNsGetParentObject (Node);
539
540    } /* while Node != ROOT */
541
542    /*
543     *  If we get here, there is no handler for this region
544     */
545    DEBUG_PRINTP (TRACE_OPREGION,
546        ("No handler for RegionType %s(%X) (RegionObj %p)\n",
547        AcpiUtGetRegionName (SpaceId), SpaceId, RegionObj));
548
549    return_ACPI_STATUS (AE_NOT_EXIST);
550}
551
552