xref: /netbsd-src/sys/external/bsd/acpica/dist/tools/acpiexec/aeinstall.c (revision e6c7e151de239c49d2e38720a061ed9d1fa99309)
1 /******************************************************************************
2  *
3  * Module Name: aeinstall - Installation of operation region handlers
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2020, Intel Corp.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions, and the following disclaimer,
16  *    without modification.
17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18  *    substantially similar to the "NO WARRANTY" disclaimer below
19  *    ("Disclaimer") and any redistribution must be conditioned upon
20  *    including a substantially similar Disclaimer requirement for further
21  *    binary redistribution.
22  * 3. Neither the names of the above-listed copyright holders nor the names
23  *    of any contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * Alternatively, this software may be distributed under the terms of the
27  * GNU General Public License ("GPL") version 2 as published by the Free
28  * Software Foundation.
29  *
30  * NO WARRANTY
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGES.
42  */
43 
44 #include "aecommon.h"
45 
46 #define _COMPONENT          ACPI_TOOLS
47         ACPI_MODULE_NAME    ("aeinstall")
48 
49 
50 static ACPI_STATUS
51 AeRegionInit (
52     ACPI_HANDLE             RegionHandle,
53     UINT32                  Function,
54     void                    *HandlerContext,
55     void                    **RegionContext);
56 
57 static ACPI_STATUS
58 AeInstallEcHandler (
59     ACPI_HANDLE             ObjHandle,
60     UINT32                  Level,
61     void                    *Context,
62     void                    **ReturnValue);
63 
64 static ACPI_STATUS
65 AeInstallPciHandler (
66     ACPI_HANDLE             ObjHandle,
67     UINT32                  Level,
68     void                    *Context,
69     void                    **ReturnValue);
70 
71 
72 BOOLEAN                     AcpiGbl_DisplayRegionAccess = FALSE;
73 ACPI_CONNECTION_INFO        AeMyContext;
74 
75 
76 /*
77  * We will override some of the default region handlers, especially
78  * the SystemMemory handler, which must be implemented locally.
79  * These handlers are installed "early" - before any _REG methods
80  * are executed - since they are special in the sense that the ACPI spec
81  * declares that they must "always be available". Cannot override the
82  * DataTable region handler either -- needed for test execution.
83  *
84  * NOTE: The local region handler will simulate access to these address
85  * spaces by creating a memory buffer behind each operation region.
86  */
87 static ACPI_ADR_SPACE_TYPE  DefaultSpaceIdList[] =
88 {
89     ACPI_ADR_SPACE_SYSTEM_MEMORY,
90     ACPI_ADR_SPACE_SYSTEM_IO,
91     ACPI_ADR_SPACE_PCI_CONFIG,
92     ACPI_ADR_SPACE_EC
93 };
94 
95 /*
96  * We will install handlers for some of the various address space IDs.
97  * Test one user-defined address space (used by aslts).
98  */
99 #define ACPI_ADR_SPACE_USER_DEFINED1        0x80
100 #define ACPI_ADR_SPACE_USER_DEFINED2        0xE4
101 
102 static ACPI_ADR_SPACE_TYPE  SpaceIdList[] =
103 {
104     ACPI_ADR_SPACE_SMBUS,
105     ACPI_ADR_SPACE_CMOS,
106     ACPI_ADR_SPACE_PCI_BAR_TARGET,
107     ACPI_ADR_SPACE_IPMI,
108     ACPI_ADR_SPACE_GPIO,
109     ACPI_ADR_SPACE_GSBUS,
110     ACPI_ADR_SPACE_PLATFORM_COMM,
111     ACPI_ADR_SPACE_FIXED_HARDWARE,
112     ACPI_ADR_SPACE_USER_DEFINED1,
113     ACPI_ADR_SPACE_USER_DEFINED2
114 };
115 
116 
117 /******************************************************************************
118  *
119  * FUNCTION:    AeRegionInit
120  *
121  * PARAMETERS:  Region init handler
122  *
123  * RETURN:      Status
124  *
125  * DESCRIPTION: Opregion init function.
126  *
127  *****************************************************************************/
128 
129 static ACPI_STATUS
130 AeRegionInit (
131     ACPI_HANDLE                 RegionHandle,
132     UINT32                      Function,
133     void                        *HandlerContext,
134     void                        **RegionContext)
135 {
136 
137     if (Function == ACPI_REGION_DEACTIVATE)
138     {
139         *RegionContext = NULL;
140     }
141     else
142     {
143         *RegionContext = RegionHandle;
144     }
145 
146     return (AE_OK);
147 }
148 
149 
150 /******************************************************************************
151  *
152  * FUNCTION:    AeOverrideRegionHandlers
153  *
154  * PARAMETERS:  None
155  *
156  * RETURN:      None
157  *
158  * DESCRIPTION: Override the default region handlers for memory, i/o, and
159  *              pci_config. Also install a handler for EC. This is part of
160  *              the "install early handlers" functionality.
161  *
162  *****************************************************************************/
163 
164 void
165 AeOverrideRegionHandlers (
166     void)
167 {
168     UINT32                  i;
169     ACPI_STATUS             Status;
170 
171     /*
172      * Install handlers that will override the default handlers for some of
173      * the space IDs.
174      */
175     for (i = 0; i < ACPI_ARRAY_LENGTH (DefaultSpaceIdList); i++)
176     {
177         /* Install handler at the root object */
178 
179         Status = AcpiInstallAddressSpaceHandler (ACPI_ROOT_OBJECT,
180             DefaultSpaceIdList[i], AeRegionHandler, AeRegionInit,
181             &AeMyContext);
182 
183         if (ACPI_FAILURE (Status))
184         {
185             ACPI_EXCEPTION ((AE_INFO, Status,
186                 "Could not install an OpRegion handler for %s space(%u)",
187                 AcpiUtGetRegionName ((UINT8) DefaultSpaceIdList[i]),
188                 DefaultSpaceIdList[i]));
189         }
190     }
191 }
192 
193 
194 /******************************************************************************
195  *
196  * FUNCTION:    AeInstallRegionHandlers
197  *
198  * PARAMETERS:  None
199  *
200  * RETURN:      None
201  *
202  * DESCRIPTION: Install handlers for the address spaces other than
203  *              SystemMemory, SystemIO, and PCI_CONFIG.
204  *
205  *****************************************************************************/
206 
207 void
208 AeInstallRegionHandlers (
209     void)
210 {
211     UINT32                  i;
212     ACPI_STATUS             Status;
213 
214 
215     /*
216      * Install handlers for some of the "device driver" address spaces
217      * such as SMBus, etc.
218      */
219     for (i = 0; i < ACPI_ARRAY_LENGTH (SpaceIdList); i++)
220     {
221         /* Install handler at the root object */
222 
223         Status = AcpiInstallAddressSpaceHandler (ACPI_ROOT_OBJECT,
224             SpaceIdList[i], AeRegionHandler, AeRegionInit,
225             &AeMyContext);
226 
227         if (ACPI_FAILURE (Status))
228         {
229             ACPI_EXCEPTION ((AE_INFO, Status,
230                 "Could not install an OpRegion handler for %s space(%u)",
231                 AcpiUtGetRegionName((UINT8) SpaceIdList[i]), SpaceIdList[i]));
232             return;
233         }
234     }
235 }
236 
237 
238 /*******************************************************************************
239  *
240  * FUNCTION:    AeInstallDeviceHandlers
241  *
242  * PARAMETERS:  None
243  *
244  * RETURN:      Status
245  *
246  * DESCRIPTION: Install handlers for all EC and PCI devices in the namespace
247  *
248  ******************************************************************************/
249 
250 ACPI_STATUS
251 AeInstallDeviceHandlers (
252     void)
253 {
254 
255     /* Find all Embedded Controller devices */
256 
257     AcpiGetDevices ("PNP0C09", AeInstallEcHandler, NULL, NULL);
258 
259     /* Install a PCI handler */
260 
261     AcpiGetDevices ("PNP0A08", AeInstallPciHandler, NULL, NULL);
262     return (AE_OK);
263 }
264 
265 
266 /*******************************************************************************
267  *
268  * FUNCTION:    AeInstallEcHandler
269  *
270  * PARAMETERS:  ACPI_WALK_NAMESPACE callback
271  *
272  * RETURN:      Status
273  *
274  * DESCRIPTION: Walk entire namespace, install a handler for every EC
275  *              device found.
276  *
277  ******************************************************************************/
278 
279 static ACPI_STATUS
280 AeInstallEcHandler (
281     ACPI_HANDLE             ObjHandle,
282     UINT32                  Level,
283     void                    *Context,
284     void                    **ReturnValue)
285 {
286     ACPI_STATUS             Status;
287 
288 
289     /* Install the handler for this EC device */
290 
291     Status = AcpiInstallAddressSpaceHandler (ObjHandle,
292         ACPI_ADR_SPACE_EC, AeRegionHandler, AeRegionInit, &AeMyContext);
293     if (ACPI_FAILURE (Status))
294     {
295         ACPI_EXCEPTION ((AE_INFO, Status,
296             "Could not install an OpRegion handler for EC device (%p)",
297             ObjHandle));
298     }
299 
300     return (Status);
301 }
302 
303 
304 /*******************************************************************************
305  *
306  * FUNCTION:    AeInstallPciHandler
307  *
308  * PARAMETERS:  ACPI_WALK_NAMESPACE callback
309  *
310  * RETURN:      Status
311  *
312  * DESCRIPTION: Walk entire namespace, install a handler for every PCI
313  *              device found.
314  *
315  ******************************************************************************/
316 
317 static ACPI_STATUS
318 AeInstallPciHandler (
319     ACPI_HANDLE             ObjHandle,
320     UINT32                  Level,
321     void                    *Context,
322     void                    **ReturnValue)
323 {
324     ACPI_STATUS             Status;
325 
326 
327     /* Install memory and I/O handlers for the PCI device */
328 
329     Status = AcpiInstallAddressSpaceHandler (ObjHandle,
330         ACPI_ADR_SPACE_SYSTEM_IO, AeRegionHandler, AeRegionInit,
331         &AeMyContext);
332     if (ACPI_FAILURE (Status))
333     {
334         ACPI_EXCEPTION ((AE_INFO, Status,
335             "Could not install an OpRegion handler for PCI device (%p)",
336             ObjHandle));
337     }
338 
339     Status = AcpiInstallAddressSpaceHandler (ObjHandle,
340         ACPI_ADR_SPACE_SYSTEM_MEMORY, AeRegionHandler, AeRegionInit,
341         &AeMyContext);
342     if (ACPI_FAILURE (Status))
343     {
344         ACPI_EXCEPTION ((AE_INFO, Status,
345             "Could not install an OpRegion handler for PCI device (%p)",
346             ObjHandle));
347     }
348 
349     return (AE_CTRL_TERMINATE);
350 }
351