evrgnini.c revision 99679
1/******************************************************************************
2 *
3 * Module Name: evrgnini- ACPI AddressSpace (OpRegion) init
4 *              $Revision: 62 $
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
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            Temp;
249    ACPI_PCI_ID             *PciId = *RegionContext;
250    ACPI_OPERAND_OBJECT     *HandlerObj;
251    ACPI_NAMESPACE_NODE     *Node;
252    ACPI_OPERAND_OBJECT     *RegionObj = (ACPI_OPERAND_OBJECT  *) Handle;
253    ACPI_DEVICE_ID          ObjectHID;
254
255
256    ACPI_FUNCTION_TRACE ("EvPciConfigRegionSetup");
257
258
259    HandlerObj = RegionObj->Region.AddrHandler;
260    if (!HandlerObj)
261    {
262        /*
263         * No installed handler. This shouldn't happen because the dispatch
264         * routine checks before we get here, but we check again just in case.
265         */
266        ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
267            "Attempting to init a region %p, with no handler\n", RegionObj));
268        return_ACPI_STATUS (AE_NOT_EXIST);
269    }
270
271    if (Function == ACPI_REGION_DEACTIVATE)
272    {
273        if (PciId)
274        {
275            ACPI_MEM_FREE (PciId);
276            *RegionContext = NULL;
277        }
278
279        return_ACPI_STATUS (Status);
280    }
281
282    /* Create a new context */
283
284    PciId = ACPI_MEM_CALLOCATE (sizeof (ACPI_PCI_ID));
285    if (!PciId)
286    {
287        return_ACPI_STATUS (AE_NO_MEMORY);
288    }
289
290    /*
291     * For PCI Config space access, we have to pass the segment, bus,
292     * device and function numbers.  This routine must acquire those.
293     */
294
295    /*
296     * First get device and function numbers from the _ADR object
297     * in the parent's scope.
298     */
299    Node = AcpiNsGetParentNode (RegionObj->Region.Node);
300
301    /* Evaluate the _ADR object */
302
303    Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR, Node, &Temp);
304
305    /*
306     * The default is zero, and since the allocation above zeroed
307     * the data, just do nothing on failure.
308     */
309    if (ACPI_SUCCESS (Status))
310    {
311        PciId->Device   = ACPI_HIWORD (ACPI_LODWORD (Temp));
312        PciId->Function = ACPI_LOWORD (ACPI_LODWORD (Temp));
313    }
314
315    /*
316     * Get the _SEG and _BBN values from the device upon which the handler
317     * is installed.
318     *
319     * We need to get the _SEG and _BBN objects relative to the PCI BUS device.
320     * This is the device the handler has been registered to handle.
321     */
322
323    /*
324     * If the AddrHandler.Node is still pointing to the root, we need
325     * to scan upward for a PCI Root bridge and re-associate the OpRegion
326     * handlers with that device.
327     */
328    if (HandlerObj->AddrHandler.Node == AcpiGbl_RootNode)
329    {
330        /*
331         * Node is currently the parent object
332         */
333        while (Node != AcpiGbl_RootNode)
334        {
335            Status = AcpiUtExecute_HID (Node, &ObjectHID);
336            if (ACPI_SUCCESS (Status))
337            {
338                /* Got a valid _HID, check if this is a PCI root */
339
340                if (!(ACPI_STRNCMP (ObjectHID.Buffer, PCI_ROOT_HID_STRING,
341                                    sizeof (PCI_ROOT_HID_STRING))))
342                {
343                    /* Install a handler for this PCI root bridge */
344
345                    Status = AcpiInstallAddressSpaceHandler ((ACPI_HANDLE) Node,
346                                        ACPI_ADR_SPACE_PCI_CONFIG,
347                                        ACPI_DEFAULT_HANDLER, NULL, NULL);
348                    if (ACPI_FAILURE (Status))
349                    {
350                        ACPI_REPORT_ERROR (("Could not install PciConfig handler for %4.4s, %s\n",
351                            Node->Name.Ascii, AcpiFormatException (Status)));
352                    }
353                    break;
354                }
355            }
356
357            Node = AcpiNsGetParentNode (Node);
358        }
359    }
360    else
361    {
362        Node = HandlerObj->AddrHandler.Node;
363    }
364
365    /*
366     * The PCI segment number comes from the _SEG method
367     */
368    Status = AcpiUtEvaluateNumericObject (METHOD_NAME__SEG, Node, &Temp);
369    if (ACPI_SUCCESS (Status))
370    {
371        PciId->Segment = ACPI_LOWORD (Temp);
372    }
373
374    /*
375     * The PCI bus number comes from the _BBN method
376     */
377    Status = AcpiUtEvaluateNumericObject (METHOD_NAME__BBN, Node, &Temp);
378    if (ACPI_SUCCESS (Status))
379    {
380        PciId->Bus = ACPI_LOWORD (Temp);
381    }
382
383    *RegionContext = PciId;
384    return_ACPI_STATUS (AE_OK);
385}
386
387
388/*******************************************************************************
389 *
390 * FUNCTION:    AcpiEvPciBarRegionSetup
391 *
392 * PARAMETERS:  RegionObj           - Region we are interested in
393 *              Function            - Start or stop
394 *              HandlerContext      - Address space handler context
395 *              RegionContext       - Region specific context
396 *
397 * RETURN:      Status
398 *
399 * DESCRIPTION: Do any prep work for region handling
400 *
401 * MUTEX:       Assumes namespace is not locked
402 *
403 ******************************************************************************/
404
405ACPI_STATUS
406AcpiEvPciBarRegionSetup (
407    ACPI_HANDLE             Handle,
408    UINT32                  Function,
409    void                    *HandlerContext,
410    void                    **RegionContext)
411{
412    ACPI_FUNCTION_TRACE ("EvPciBarRegionSetup");
413
414
415    return_ACPI_STATUS (AE_OK);
416}
417
418
419/*******************************************************************************
420 *
421 * FUNCTION:    AcpiEvCmosRegionSetup
422 *
423 * PARAMETERS:  RegionObj           - Region we are interested in
424 *              Function            - Start or stop
425 *              HandlerContext      - Address space handler context
426 *              RegionContext       - Region specific context
427 *
428 * RETURN:      Status
429 *
430 * DESCRIPTION: Do any prep work for region handling
431 *
432 * MUTEX:       Assumes namespace is not locked
433 *
434 ******************************************************************************/
435
436ACPI_STATUS
437AcpiEvCmosRegionSetup (
438    ACPI_HANDLE             Handle,
439    UINT32                  Function,
440    void                    *HandlerContext,
441    void                    **RegionContext)
442{
443    ACPI_FUNCTION_TRACE ("EvCmosRegionSetup");
444
445
446    return_ACPI_STATUS (AE_OK);
447}
448
449
450/*******************************************************************************
451 *
452 * FUNCTION:    AcpiEvDefaultRegionSetup
453 *
454 * PARAMETERS:  RegionObj           - Region we are interested in
455 *              Function            - Start or stop
456 *              HandlerContext      - Address space handler context
457 *              RegionContext       - Region specific context
458 *
459 * RETURN:      Status
460 *
461 * DESCRIPTION: Do any prep work for region handling
462 *
463 ******************************************************************************/
464
465ACPI_STATUS
466AcpiEvDefaultRegionSetup (
467    ACPI_HANDLE             Handle,
468    UINT32                  Function,
469    void                    *HandlerContext,
470    void                    **RegionContext)
471{
472    ACPI_FUNCTION_TRACE ("EvDefaultRegionSetup");
473
474
475    if (Function == ACPI_REGION_DEACTIVATE)
476    {
477        *RegionContext = NULL;
478    }
479    else
480    {
481        *RegionContext = HandlerContext;
482    }
483
484    return_ACPI_STATUS (AE_OK);
485}
486
487
488/*******************************************************************************
489 *
490 * FUNCTION:    AcpiEvInitializeRegion
491 *
492 * PARAMETERS:  RegionObj       - Region we are initializing
493 *              AcpiNsLocked    - Is namespace locked?
494 *
495 * RETURN:      Status
496 *
497 * DESCRIPTION: Initializes the region, finds any _REG methods and saves them
498 *              for execution at a later time
499 *
500 *              Get the appropriate address space handler for a newly
501 *              created region.
502 *
503 *              This also performs address space specific intialization.  For
504 *              example, PCI regions must have an _ADR object that contains
505 *              a PCI address in the scope of the definition.  This address is
506 *              required to perform an access to PCI config space.
507 *
508 ******************************************************************************/
509
510ACPI_STATUS
511AcpiEvInitializeRegion (
512    ACPI_OPERAND_OBJECT     *RegionObj,
513    BOOLEAN                 AcpiNsLocked)
514{
515    ACPI_OPERAND_OBJECT     *HandlerObj;
516    ACPI_OPERAND_OBJECT     *ObjDesc;
517    ACPI_ADR_SPACE_TYPE     SpaceId;
518    ACPI_NAMESPACE_NODE     *Node;
519    ACPI_STATUS             Status;
520    ACPI_NAMESPACE_NODE     *MethodNode;
521    ACPI_NAME               *RegNamePtr = (ACPI_NAME *) METHOD_NAME__REG;
522    ACPI_OPERAND_OBJECT     *RegionObj2;
523
524
525    ACPI_FUNCTION_TRACE_U32 ("EvInitializeRegion", AcpiNsLocked);
526
527
528    if (!RegionObj)
529    {
530        return_ACPI_STATUS (AE_BAD_PARAMETER);
531    }
532
533    if (RegionObj->Common.Flags & AOPOBJ_OBJECT_INITIALIZED)
534    {
535        return_ACPI_STATUS (AE_OK);
536    }
537
538    RegionObj2 = AcpiNsGetSecondaryObject (RegionObj);
539    if (!RegionObj2)
540    {
541        return_ACPI_STATUS (AE_NOT_EXIST);
542    }
543
544    Node = AcpiNsGetParentNode (RegionObj->Region.Node);
545    SpaceId = RegionObj->Region.SpaceId;
546
547    RegionObj->Region.AddrHandler = NULL;
548    RegionObj2->Extra.Method_REG = NULL;
549    RegionObj->Common.Flags &= ~(AOPOBJ_SETUP_COMPLETE);
550    RegionObj->Common.Flags |= AOPOBJ_OBJECT_INITIALIZED;
551
552    /*
553     * Find any "_REG" method associated with this region definition
554     */
555    Status = AcpiNsSearchNode (*RegNamePtr, Node,
556                                   ACPI_TYPE_METHOD, &MethodNode);
557    if (ACPI_SUCCESS (Status))
558    {
559        /*
560         * The _REG method is optional and there can be only one per region
561         * definition.  This will be executed when the handler is attached
562         * or removed
563         */
564        RegionObj2->Extra.Method_REG = MethodNode;
565    }
566
567    /*
568     * The following loop depends upon the root Node having no parent
569     * ie: AcpiGbl_RootNode->ParentEntry being set to NULL
570     */
571    while (Node)
572    {
573        /*
574         * Check to see if a handler exists
575         */
576        HandlerObj = NULL;
577        ObjDesc = AcpiNsGetAttachedObject (Node);
578        if (ObjDesc)
579        {
580            /*
581             * Can only be a handler if the object exists
582             */
583            switch (Node->Type)
584            {
585            case ACPI_TYPE_DEVICE:
586
587                HandlerObj = ObjDesc->Device.AddrHandler;
588                break;
589
590            case ACPI_TYPE_PROCESSOR:
591
592                HandlerObj = ObjDesc->Processor.AddrHandler;
593                break;
594
595            case ACPI_TYPE_THERMAL:
596
597                HandlerObj = ObjDesc->ThermalZone.AddrHandler;
598                break;
599
600            default:
601                /* Ignore other objects */
602                break;
603            }
604
605            while (HandlerObj)
606            {
607                /* Is this handler of the correct type? */
608
609                if (HandlerObj->AddrHandler.SpaceId == SpaceId)
610                {
611                    /* Found correct handler */
612
613                    ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
614                        "Found handler %p for region %p in obj %p\n",
615                        HandlerObj, RegionObj, ObjDesc));
616
617                    Status = AcpiEvAttachRegion (HandlerObj, RegionObj,
618                                AcpiNsLocked);
619
620                    return_ACPI_STATUS (AE_OK);
621                }
622
623                /* Try next handler in the list */
624
625                HandlerObj = HandlerObj->AddrHandler.Next;
626            }
627        }
628
629        /*
630         * This node does not have the handler we need;
631         * Pop up one level
632         */
633        Node = AcpiNsGetParentNode (Node);
634    }
635
636    /*
637     * If we get here, there is no handler for this region
638     */
639    ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
640        "No handler for RegionType %s(%X) (RegionObj %p)\n",
641        AcpiUtGetRegionName (SpaceId), SpaceId, RegionObj));
642
643    return_ACPI_STATUS (AE_NOT_EXIST);
644}
645
646