xref: /freebsd/sys/contrib/dev/acpica/components/events/evrgnini.c (revision 722b16673c40aedf280895f2f2f676bb494518d7)
1 /******************************************************************************
2  *
3  * Module Name: evrgnini- ACPI AddressSpace (OpRegion) init
4  *
5  *****************************************************************************/
6 
7 /******************************************************************************
8  *
9  * 1. Copyright Notice
10  *
11  * Some or all of this work - Copyright (c) 1999 - 2023, Intel Corp.
12  * All rights reserved.
13  *
14  * 2. License
15  *
16  * 2.1. This is your license from Intel Corp. under its intellectual property
17  * rights. You may have additional license terms from the party that provided
18  * you this software, covering your right to use that party's intellectual
19  * property rights.
20  *
21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22  * copy of the source code appearing in this file ("Covered Code") an
23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24  * base code distributed originally by Intel ("Original Intel Code") to copy,
25  * make derivatives, distribute, use and display any portion of the Covered
26  * Code in any form, with the right to sublicense such rights; and
27  *
28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29  * license (with the right to sublicense), under only those claims of Intel
30  * patents that are infringed by the Original Intel Code, to make, use, sell,
31  * offer to sell, and import the Covered Code and derivative works thereof
32  * solely to the minimum extent necessary to exercise the above copyright
33  * license, and in no event shall the patent license extend to any additions
34  * to or modifications of the Original Intel Code. No other license or right
35  * is granted directly or by implication, estoppel or otherwise;
36  *
37  * The above copyright and patent license is granted only if the following
38  * conditions are met:
39  *
40  * 3. Conditions
41  *
42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43  * Redistribution of source code of any substantial portion of the Covered
44  * Code or modification with rights to further distribute source must include
45  * the above Copyright Notice, the above License, this list of Conditions,
46  * and the following Disclaimer and Export Compliance provision. In addition,
47  * Licensee must cause all Covered Code to which Licensee contributes to
48  * contain a file documenting the changes Licensee made to create that Covered
49  * Code and the date of any change. Licensee must include in that file the
50  * documentation of any changes made by any predecessor Licensee. Licensee
51  * must include a prominent statement that the modification is derived,
52  * directly or indirectly, from Original Intel Code.
53  *
54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55  * Redistribution of source code of any substantial portion of the Covered
56  * Code or modification without rights to further distribute source must
57  * include the following Disclaimer and Export Compliance provision in the
58  * documentation and/or other materials provided with distribution. In
59  * addition, Licensee may not authorize further sublicense of source of any
60  * portion of the Covered Code, and must include terms to the effect that the
61  * license from Licensee to its licensee is limited to the intellectual
62  * property embodied in the software Licensee provides to its licensee, and
63  * not to intellectual property embodied in modifications its licensee may
64  * make.
65  *
66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
67  * substantial portion of the Covered Code or modification must reproduce the
68  * above Copyright Notice, and the following Disclaimer and Export Compliance
69  * provision in the documentation and/or other materials provided with the
70  * distribution.
71  *
72  * 3.4. Intel retains all right, title, and interest in and to the Original
73  * Intel Code.
74  *
75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76  * Intel shall be used in advertising or otherwise to promote the sale, use or
77  * other dealings in products derived from or relating to the Covered Code
78  * without prior written authorization from Intel.
79  *
80  * 4. Disclaimer and Export Compliance
81  *
82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88  * PARTICULAR PURPOSE.
89  *
90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97  * LIMITED REMEDY.
98  *
99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
100  * software or system incorporating such software without first obtaining any
101  * required license or other approval from the U. S. Department of Commerce or
102  * any other agency or department of the United States Government. In the
103  * event Licensee exports any such software from the United States or
104  * re-exports any such software from a foreign destination, Licensee shall
105  * ensure that the distribution and export/re-export of the software is in
106  * compliance with all laws, regulations, orders, or other restrictions of the
107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108  * any of its subsidiaries will export/re-export any technical data, process,
109  * software, or service, directly or indirectly, to any country for which the
110  * United States government or any agency thereof requires an export license,
111  * other governmental approval, or letter of assurance, without first obtaining
112  * such license, approval or letter.
113  *
114  *****************************************************************************
115  *
116  * Alternatively, you may choose to be licensed under the terms of the
117  * following license:
118  *
119  * Redistribution and use in source and binary forms, with or without
120  * modification, are permitted provided that the following conditions
121  * are met:
122  * 1. Redistributions of source code must retain the above copyright
123  *    notice, this list of conditions, and the following disclaimer,
124  *    without modification.
125  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126  *    substantially similar to the "NO WARRANTY" disclaimer below
127  *    ("Disclaimer") and any redistribution must be conditioned upon
128  *    including a substantially similar Disclaimer requirement for further
129  *    binary redistribution.
130  * 3. Neither the names of the above-listed copyright holders nor the names
131  *    of any contributors may be used to endorse or promote products derived
132  *    from this software without specific prior written permission.
133  *
134  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145  *
146  * Alternatively, you may choose to be licensed under the terms of the
147  * GNU General Public License ("GPL") version 2 as published by the Free
148  * Software Foundation.
149  *
150  *****************************************************************************/
151 
152 #include <contrib/dev/acpica/include/acpi.h>
153 #include <contrib/dev/acpica/include/accommon.h>
154 #include <contrib/dev/acpica/include/acevents.h>
155 #include <contrib/dev/acpica/include/acnamesp.h>
156 #include <contrib/dev/acpica/include/acinterp.h>
157 
158 #define _COMPONENT          ACPI_EVENTS
159         ACPI_MODULE_NAME    ("evrgnini")
160 
161 
162 /*******************************************************************************
163  *
164  * FUNCTION:    AcpiEvSystemMemoryRegionSetup
165  *
166  * PARAMETERS:  Handle              - Region we are interested in
167  *              Function            - Start or stop
168  *              HandlerContext      - Address space handler context
169  *              RegionContext       - Region specific context
170  *
171  * RETURN:      Status
172  *
173  * DESCRIPTION: Setup a SystemMemory operation region
174  *
175  ******************************************************************************/
176 
177 ACPI_STATUS
AcpiEvSystemMemoryRegionSetup(ACPI_HANDLE Handle,UINT32 Function,void * HandlerContext,void ** RegionContext)178 AcpiEvSystemMemoryRegionSetup (
179     ACPI_HANDLE             Handle,
180     UINT32                  Function,
181     void                    *HandlerContext,
182     void                    **RegionContext)
183 {
184     ACPI_OPERAND_OBJECT     *RegionDesc = (ACPI_OPERAND_OBJECT *) Handle;
185     ACPI_MEM_SPACE_CONTEXT  *LocalRegionContext;
186     ACPI_MEM_MAPPING        *Mm;
187 
188 
189     ACPI_FUNCTION_TRACE (EvSystemMemoryRegionSetup);
190 
191 
192     if (Function == ACPI_REGION_DEACTIVATE)
193     {
194         if (*RegionContext)
195         {
196             LocalRegionContext = (ACPI_MEM_SPACE_CONTEXT *) *RegionContext;
197 
198             /* Delete memory mappings if present */
199 
200             while (LocalRegionContext->FirstMm)
201             {
202                 Mm = LocalRegionContext->FirstMm;
203                 LocalRegionContext->FirstMm = Mm->NextMm;
204                 AcpiOsUnmapMemory(Mm->LogicalAddress, Mm->Length);
205                 ACPI_FREE(Mm);
206             }
207             ACPI_FREE (LocalRegionContext);
208             *RegionContext = NULL;
209         }
210         return_ACPI_STATUS (AE_OK);
211     }
212 
213     /* Create a new context */
214 
215     LocalRegionContext = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_MEM_SPACE_CONTEXT));
216     if (!(LocalRegionContext))
217     {
218         return_ACPI_STATUS (AE_NO_MEMORY);
219     }
220 
221     /* Save the region length and address for use in the handler */
222 
223     LocalRegionContext->Length  = RegionDesc->Region.Length;
224     LocalRegionContext->Address = RegionDesc->Region.Address;
225 
226     *RegionContext = LocalRegionContext;
227     return_ACPI_STATUS (AE_OK);
228 }
229 
230 
231 /*******************************************************************************
232  *
233  * FUNCTION:    AcpiEvIoSpaceRegionSetup
234  *
235  * PARAMETERS:  Handle              - Region we are interested in
236  *              Function            - Start or stop
237  *              HandlerContext      - Address space handler context
238  *              RegionContext       - Region specific context
239  *
240  * RETURN:      Status
241  *
242  * DESCRIPTION: Setup a IO operation region
243  *
244  ******************************************************************************/
245 
246 ACPI_STATUS
AcpiEvIoSpaceRegionSetup(ACPI_HANDLE Handle,UINT32 Function,void * HandlerContext,void ** RegionContext)247 AcpiEvIoSpaceRegionSetup (
248     ACPI_HANDLE             Handle,
249     UINT32                  Function,
250     void                    *HandlerContext,
251     void                    **RegionContext)
252 {
253     ACPI_FUNCTION_TRACE (EvIoSpaceRegionSetup);
254 
255 
256     if (Function == ACPI_REGION_DEACTIVATE)
257     {
258         *RegionContext = NULL;
259     }
260     else
261     {
262         *RegionContext = HandlerContext;
263     }
264 
265     return_ACPI_STATUS (AE_OK);
266 }
267 
268 
269 /*******************************************************************************
270  *
271  * FUNCTION:    AcpiEvPciConfigRegionSetup
272  *
273  * PARAMETERS:  Handle              - Region we are interested in
274  *              Function            - Start or stop
275  *              HandlerContext      - Address space handler context
276  *              RegionContext       - Region specific context
277  *
278  * RETURN:      Status
279  *
280  * DESCRIPTION: Setup a PCI_Config operation region
281  *
282  * MUTEX:       Assumes namespace is not locked
283  *
284  ******************************************************************************/
285 
286 ACPI_STATUS
AcpiEvPciConfigRegionSetup(ACPI_HANDLE Handle,UINT32 Function,void * HandlerContext,void ** RegionContext)287 AcpiEvPciConfigRegionSetup (
288     ACPI_HANDLE             Handle,
289     UINT32                  Function,
290     void                    *HandlerContext,
291     void                    **RegionContext)
292 {
293     ACPI_STATUS             Status = AE_OK;
294     UINT64                  PciValue;
295     ACPI_PCI_ID             *PciId = *RegionContext;
296     ACPI_OPERAND_OBJECT     *HandlerObj;
297     ACPI_NAMESPACE_NODE     *ParentNode;
298     ACPI_NAMESPACE_NODE     *PciRootNode;
299     ACPI_NAMESPACE_NODE     *PciDeviceNode;
300     ACPI_OPERAND_OBJECT     *RegionObj = (ACPI_OPERAND_OBJECT  *) Handle;
301 
302 
303     ACPI_FUNCTION_TRACE (EvPciConfigRegionSetup);
304 
305 
306     HandlerObj = RegionObj->Region.Handler;
307     if (!HandlerObj)
308     {
309         /*
310          * No installed handler. This shouldn't happen because the dispatch
311          * routine checks before we get here, but we check again just in case.
312          */
313         ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
314             "Attempting to init a region %p, with no handler\n", RegionObj));
315         return_ACPI_STATUS (AE_NOT_EXIST);
316     }
317 
318     *RegionContext = NULL;
319     if (Function == ACPI_REGION_DEACTIVATE)
320     {
321         if (PciId)
322         {
323             ACPI_FREE (PciId);
324         }
325         return_ACPI_STATUS (Status);
326     }
327 
328     ParentNode = RegionObj->Region.Node->Parent;
329 
330     /*
331      * Get the _SEG and _BBN values from the device upon which the handler
332      * is installed.
333      *
334      * We need to get the _SEG and _BBN objects relative to the PCI BUS device.
335      * This is the device the handler has been registered to handle.
336      */
337 
338     /*
339      * If the AddressSpace.Node is still pointing to the root, we need
340      * to scan upward for a PCI Root bridge and re-associate the OpRegion
341      * handlers with that device.
342      */
343     if (HandlerObj->AddressSpace.Node == AcpiGbl_RootNode)
344     {
345         /* Start search from the parent object */
346 
347         PciRootNode = ParentNode;
348         while (PciRootNode != AcpiGbl_RootNode)
349         {
350             /* Get the _HID/_CID in order to detect a RootBridge */
351 
352             if (AcpiEvIsPciRootBridge (PciRootNode))
353             {
354                 /* Install a handler for this PCI root bridge */
355 
356                 Status = AcpiInstallAddressSpaceHandler (
357                     (ACPI_HANDLE) PciRootNode,
358                     ACPI_ADR_SPACE_PCI_CONFIG,
359                     ACPI_DEFAULT_HANDLER, NULL, NULL);
360                 if (ACPI_FAILURE (Status))
361                 {
362                     if (Status == AE_SAME_HANDLER)
363                     {
364                         /*
365                          * It is OK if the handler is already installed on the
366                          * root bridge. Still need to return a context object
367                          * for the new PCI_Config operation region, however.
368                          */
369                     }
370                     else
371                     {
372                         ACPI_EXCEPTION ((AE_INFO, Status,
373                             "Could not install PciConfig handler "
374                             "for Root Bridge %4.4s",
375                             AcpiUtGetNodeName (PciRootNode)));
376                     }
377                 }
378                 break;
379             }
380 
381             PciRootNode = PciRootNode->Parent;
382         }
383 
384         /* PCI root bridge not found, use namespace root node */
385     }
386     else
387     {
388         PciRootNode = HandlerObj->AddressSpace.Node;
389     }
390 
391     /*
392      * If this region is now initialized, we are done.
393      * (InstallAddressSpaceHandler could have initialized it)
394      */
395     if (RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE)
396     {
397         return_ACPI_STATUS (AE_OK);
398     }
399 
400     /* Region is still not initialized. Create a new context */
401 
402     PciId = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_PCI_ID));
403     if (!PciId)
404     {
405         return_ACPI_STATUS (AE_NO_MEMORY);
406     }
407 
408     /*
409      * For PCI_Config space access, we need the segment, bus, device and
410      * function numbers. Acquire them here.
411      *
412      * Find the parent device object. (This allows the operation region to be
413      * within a subscope under the device, such as a control method.)
414      */
415     PciDeviceNode = RegionObj->Region.Node;
416     while (PciDeviceNode && (PciDeviceNode->Type != ACPI_TYPE_DEVICE))
417     {
418         PciDeviceNode = PciDeviceNode->Parent;
419     }
420 
421     if (!PciDeviceNode)
422     {
423         ACPI_FREE (PciId);
424         return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
425     }
426 
427     /*
428      * Get the PCI device and function numbers from the _ADR object
429      * contained in the parent's scope.
430      */
431     Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR,
432         PciDeviceNode, &PciValue);
433 
434     /*
435      * The default is zero, and since the allocation above zeroed the data,
436      * just do nothing on failure.
437      */
438     if (ACPI_SUCCESS (Status))
439     {
440         PciId->Device   = ACPI_HIWORD (ACPI_LODWORD (PciValue));
441         PciId->Function = ACPI_LOWORD (ACPI_LODWORD (PciValue));
442     }
443 
444     /* The PCI segment number comes from the _SEG method */
445 
446     Status = AcpiUtEvaluateNumericObject (METHOD_NAME__SEG,
447         PciRootNode, &PciValue);
448     if (ACPI_SUCCESS (Status))
449     {
450         PciId->Segment = ACPI_LOWORD (PciValue);
451     }
452 
453     /* The PCI bus number comes from the _BBN method */
454 
455     Status = AcpiUtEvaluateNumericObject (METHOD_NAME__BBN,
456         PciRootNode, &PciValue);
457     if (ACPI_SUCCESS (Status))
458     {
459         PciId->Bus = ACPI_LOWORD (PciValue);
460     }
461 
462     /* Complete/update the PCI ID for this device */
463 
464     Status = AcpiHwDerivePciId (PciId, PciRootNode, RegionObj->Region.Node);
465     if (ACPI_FAILURE (Status))
466     {
467         ACPI_FREE (PciId);
468         return_ACPI_STATUS (Status);
469     }
470 
471     *RegionContext = PciId;
472     return_ACPI_STATUS (AE_OK);
473 }
474 
475 
476 /*******************************************************************************
477  *
478  * FUNCTION:    AcpiEvIsPciRootBridge
479  *
480  * PARAMETERS:  Node            - Device node being examined
481  *
482  * RETURN:      TRUE if device is a PCI/PCI-Express Root Bridge
483  *
484  * DESCRIPTION: Determine if the input device represents a PCI Root Bridge by
485  *              examining the _HID and _CID for the device.
486  *
487  ******************************************************************************/
488 
489 BOOLEAN
AcpiEvIsPciRootBridge(ACPI_NAMESPACE_NODE * Node)490 AcpiEvIsPciRootBridge (
491     ACPI_NAMESPACE_NODE     *Node)
492 {
493     ACPI_STATUS             Status;
494     ACPI_PNP_DEVICE_ID      *Hid;
495     ACPI_PNP_DEVICE_ID_LIST *Cid;
496     UINT32                  i;
497     BOOLEAN                 Match;
498 
499 
500     /* Get the _HID and check for a PCI Root Bridge */
501 
502     Status = AcpiUtExecute_HID (Node, &Hid);
503     if (ACPI_FAILURE (Status))
504     {
505         return (FALSE);
506     }
507 
508     Match = AcpiUtIsPciRootBridge (Hid->String);
509     ACPI_FREE (Hid);
510 
511     if (Match)
512     {
513         return (TRUE);
514     }
515 
516     /* The _HID did not match. Get the _CID and check for a PCI Root Bridge */
517 
518     Status = AcpiUtExecute_CID (Node, &Cid);
519     if (ACPI_FAILURE (Status))
520     {
521         return (FALSE);
522     }
523 
524     /* Check all _CIDs in the returned list */
525 
526     for (i = 0; i < Cid->Count; i++)
527     {
528         if (AcpiUtIsPciRootBridge (Cid->Ids[i].String))
529         {
530             ACPI_FREE (Cid);
531             return (TRUE);
532         }
533     }
534 
535     ACPI_FREE (Cid);
536     return (FALSE);
537 }
538 
539 
540 /*******************************************************************************
541  *
542  * FUNCTION:    AcpiEvPciBarRegionSetup
543  *
544  * PARAMETERS:  Handle              - Region we are interested in
545  *              Function            - Start or stop
546  *              HandlerContext      - Address space handler context
547  *              RegionContext       - Region specific context
548  *
549  * RETURN:      Status
550  *
551  * DESCRIPTION: Setup a PciBAR operation region
552  *
553  * MUTEX:       Assumes namespace is not locked
554  *
555  ******************************************************************************/
556 
557 ACPI_STATUS
AcpiEvPciBarRegionSetup(ACPI_HANDLE Handle,UINT32 Function,void * HandlerContext,void ** RegionContext)558 AcpiEvPciBarRegionSetup (
559     ACPI_HANDLE             Handle,
560     UINT32                  Function,
561     void                    *HandlerContext,
562     void                    **RegionContext)
563 {
564     ACPI_FUNCTION_TRACE (EvPciBarRegionSetup);
565 
566 
567     return_ACPI_STATUS (AE_OK);
568 }
569 
570 
571 /*******************************************************************************
572  *
573  * FUNCTION:    AcpiEvCmosRegionSetup
574  *
575  * PARAMETERS:  Handle              - Region we are interested in
576  *              Function            - Start or stop
577  *              HandlerContext      - Address space handler context
578  *              RegionContext       - Region specific context
579  *
580  * RETURN:      Status
581  *
582  * DESCRIPTION: Setup a CMOS operation region
583  *
584  * MUTEX:       Assumes namespace is not locked
585  *
586  ******************************************************************************/
587 
588 ACPI_STATUS
AcpiEvCmosRegionSetup(ACPI_HANDLE Handle,UINT32 Function,void * HandlerContext,void ** RegionContext)589 AcpiEvCmosRegionSetup (
590     ACPI_HANDLE             Handle,
591     UINT32                  Function,
592     void                    *HandlerContext,
593     void                    **RegionContext)
594 {
595     ACPI_FUNCTION_TRACE (EvCmosRegionSetup);
596 
597 
598     return_ACPI_STATUS (AE_OK);
599 }
600 
601 
602 /*******************************************************************************
603  *
604  * FUNCTION:    AcpiEvDataTableRegionSetup
605  *
606  * PARAMETERS:  Handle              - Region we are interested in
607  *              Function            - Start or stop
608  *              HandlerContext      - Address space handler context
609  *              RegionContext       - Region specific context
610  *
611  * RETURN:      Status
612  *
613  * DESCRIPTION: Setup a DataTableRegion
614  *
615  * MUTEX:       Assumes namespace is not locked
616  *
617  ******************************************************************************/
618 
619 ACPI_STATUS
AcpiEvDataTableRegionSetup(ACPI_HANDLE Handle,UINT32 Function,void * HandlerContext,void ** RegionContext)620 AcpiEvDataTableRegionSetup (
621     ACPI_HANDLE             Handle,
622     UINT32                  Function,
623     void                    *HandlerContext,
624     void                    **RegionContext)
625 {
626     ACPI_OPERAND_OBJECT     *RegionDesc = (ACPI_OPERAND_OBJECT *) Handle;
627     ACPI_DATA_TABLE_MAPPING *LocalRegionContext;
628 
629 
630     ACPI_FUNCTION_TRACE (EvDataTableRegionSetup);
631 
632 
633     if (Function == ACPI_REGION_DEACTIVATE)
634     {
635         if (*RegionContext)
636         {
637             ACPI_FREE (*RegionContext);
638             *RegionContext = NULL;
639         }
640         return_ACPI_STATUS (AE_OK);
641     }
642 
643     /* Create a new context */
644 
645     LocalRegionContext = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_DATA_TABLE_MAPPING));
646     if (!(LocalRegionContext))
647     {
648         return_ACPI_STATUS (AE_NO_MEMORY);
649     }
650 
651     /* Save the data table pointer for use in the handler */
652 
653     LocalRegionContext->Pointer = RegionDesc->Region.Pointer;
654 
655     *RegionContext = LocalRegionContext;
656     return_ACPI_STATUS (AE_OK);
657 }
658 
659 
660 /*******************************************************************************
661  *
662  * FUNCTION:    AcpiEvDefaultRegionSetup
663  *
664  * PARAMETERS:  Handle              - Region we are interested in
665  *              Function            - Start or stop
666  *              HandlerContext      - Address space handler context
667  *              RegionContext       - Region specific context
668  *
669  * RETURN:      Status
670  *
671  * DESCRIPTION: Default region initialization
672  *
673  ******************************************************************************/
674 
675 ACPI_STATUS
AcpiEvDefaultRegionSetup(ACPI_HANDLE Handle,UINT32 Function,void * HandlerContext,void ** RegionContext)676 AcpiEvDefaultRegionSetup (
677     ACPI_HANDLE             Handle,
678     UINT32                  Function,
679     void                    *HandlerContext,
680     void                    **RegionContext)
681 {
682     ACPI_FUNCTION_TRACE (EvDefaultRegionSetup);
683 
684 
685     if (Function == ACPI_REGION_DEACTIVATE)
686     {
687         *RegionContext = NULL;
688     }
689     else
690     {
691         *RegionContext = HandlerContext;
692     }
693 
694     return_ACPI_STATUS (AE_OK);
695 }
696 
697 
698 /*******************************************************************************
699  *
700  * FUNCTION:    AcpiEvInitializeRegion
701  *
702  * PARAMETERS:  RegionObj       - Region we are initializing
703  *
704  * RETURN:      Status
705  *
706  * DESCRIPTION: Initializes the region, finds any _REG methods and saves them
707  *              for execution at a later time
708  *
709  *              Get the appropriate address space handler for a newly
710  *              created region.
711  *
712  *              This also performs address space specific initialization. For
713  *              example, PCI regions must have an _ADR object that contains
714  *              a PCI address in the scope of the definition. This address is
715  *              required to perform an access to PCI config space.
716  *
717  * MUTEX:       Interpreter should be unlocked, because we may run the _REG
718  *              method for this region.
719  *
720  * NOTE:        Possible incompliance:
721  *              There is a behavior conflict in automatic _REG execution:
722  *              1. When the interpreter is evaluating a method, we can only
723  *                 automatically run _REG for the following case:
724  *                   Method(_REG, 2) {}
725  *                   OperationRegion (OPR1, 0x80, 0x1000010, 0x4)
726  *              2. When the interpreter is loading a table, we can also
727  *                 automatically run _REG for the following case:
728  *                   OperationRegion (OPR1, 0x80, 0x1000010, 0x4)
729  *                   Method(_REG, 2) {}
730  *              Though this may not be compliant to the de-facto standard, the
731  *              logic is kept in order not to trigger regressions. And keeping
732  *              this logic should be taken care by the caller of this function.
733  *
734  ******************************************************************************/
735 
736 ACPI_STATUS
AcpiEvInitializeRegion(ACPI_OPERAND_OBJECT * RegionObj)737 AcpiEvInitializeRegion (
738     ACPI_OPERAND_OBJECT     *RegionObj)
739 {
740     ACPI_OPERAND_OBJECT     *HandlerObj;
741     ACPI_OPERAND_OBJECT     *ObjDesc;
742     ACPI_ADR_SPACE_TYPE     SpaceId;
743     ACPI_NAMESPACE_NODE     *Node;
744 
745 
746     ACPI_FUNCTION_TRACE (EvInitializeRegion);
747 
748 
749     if (!RegionObj)
750     {
751         return_ACPI_STATUS (AE_BAD_PARAMETER);
752     }
753 
754     if (RegionObj->Common.Flags & AOPOBJ_OBJECT_INITIALIZED)
755     {
756         return_ACPI_STATUS (AE_OK);
757     }
758 
759     RegionObj->Common.Flags |= AOPOBJ_OBJECT_INITIALIZED;
760 
761     Node = RegionObj->Region.Node->Parent;
762     SpaceId = RegionObj->Region.SpaceId;
763 
764     /*
765      * The following loop depends upon the root Node having no parent
766      * ie: AcpiGbl_RootNode->Parent being set to NULL
767      */
768     while (Node)
769     {
770         /* Check to see if a handler exists */
771 
772         HandlerObj = NULL;
773         ObjDesc = AcpiNsGetAttachedObject (Node);
774         if (ObjDesc)
775         {
776             /* Can only be a handler if the object exists */
777 
778             switch (Node->Type)
779             {
780             case ACPI_TYPE_DEVICE:
781             case ACPI_TYPE_PROCESSOR:
782             case ACPI_TYPE_THERMAL:
783 
784                 HandlerObj = ObjDesc->CommonNotify.Handler;
785                 break;
786 
787             default:
788 
789                 /* Ignore other objects */
790 
791                 break;
792             }
793 
794             HandlerObj = AcpiEvFindRegionHandler (SpaceId, HandlerObj);
795             if (HandlerObj)
796             {
797                 /* Found correct handler */
798 
799                 ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
800                     "Found handler %p for region %p in obj %p\n",
801                     HandlerObj, RegionObj, ObjDesc));
802 
803                 (void) AcpiEvAttachRegion (HandlerObj, RegionObj, FALSE);
804 
805                 /*
806                  * Tell all users that this region is usable by
807                  * running the _REG method
808                  */
809                 AcpiExExitInterpreter ();
810                 (void) AcpiEvExecuteRegMethod (RegionObj, ACPI_REG_CONNECT);
811                 AcpiExEnterInterpreter ();
812                 return_ACPI_STATUS (AE_OK);
813             }
814         }
815 
816         /* This node does not have the handler we need; Pop up one level */
817 
818         Node = Node->Parent;
819     }
820 
821     /*
822      * If we get here, there is no handler for this region. This is not
823      * fatal because many regions get created before a handler is installed
824      * for said region.
825      */
826     ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
827         "No handler for RegionType %s(%X) (RegionObj %p)\n",
828         AcpiUtGetRegionName (SpaceId), SpaceId, RegionObj));
829 
830     return_ACPI_STATUS (AE_OK);
831 }
832