xref: /netbsd-src/sys/external/bsd/acpica/dist/tools/acpiexec/aeexec.c (revision 046a29855e04359424fd074e8313af6b6be8cfb6)
1 /******************************************************************************
2  *
3  * Module Name: aeexec - Argument testing for control method execution.
4  *                       Also some other miscellaneous tests.
5  *
6  *****************************************************************************/
7 
8 /*
9  * Copyright (C) 2000 - 2023, Intel Corp.
10  * All rights reserved.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions, and the following disclaimer,
17  *    without modification.
18  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19  *    substantially similar to the "NO WARRANTY" disclaimer below
20  *    ("Disclaimer") and any redistribution must be conditioned upon
21  *    including a substantially similar Disclaimer requirement for further
22  *    binary redistribution.
23  * 3. Neither the names of the above-listed copyright holders nor the names
24  *    of any contributors may be used to endorse or promote products derived
25  *    from this software without specific prior written permission.
26  *
27  * Alternatively, this software may be distributed under the terms of the
28  * GNU General Public License ("GPL") version 2 as published by the Free
29  * Software Foundation.
30  *
31  * NO WARRANTY
32  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
35  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42  * POSSIBILITY OF SUCH DAMAGES.
43  */
44 
45 #include "aecommon.h"
46 
47 #define _COMPONENT          ACPI_TOOLS
48         ACPI_MODULE_NAME    ("aeexec")
49 
50 
51 /******************************************************************************
52  *
53  * FUNCTION:    AeSetupConfiguration
54  *
55  * PARAMETERS:  RegionAddr          - Address for an ACPI table to be loaded
56  *                                    dynamically. Test purposes only.
57  *
58  * RETURN:      Status
59  *
60  * DESCRIPTION: Call AML _CFG configuration control method
61  *
62  *****************************************************************************/
63 
64 ACPI_STATUS
AeSetupConfiguration(void * RegionAddr)65 AeSetupConfiguration (
66     void                    *RegionAddr)
67 {
68     ACPI_OBJECT_LIST        ArgList;
69     ACPI_OBJECT             Arg[3];
70 
71 
72     /*
73      * Invoke _CFG method if present
74      */
75     ArgList.Count = 1;
76     ArgList.Pointer = Arg;
77 
78     Arg[0].Type = ACPI_TYPE_INTEGER;
79     Arg[0].Integer.Value = ACPI_TO_INTEGER (RegionAddr);
80 
81     (void) AcpiEvaluateObject (NULL, "\\_CFG", &ArgList, NULL);
82     return (AE_OK);
83 }
84 
85 
86 #if (!ACPI_REDUCED_HARDWARE)
87 /******************************************************************************
88  *
89  * FUNCTION:    AfInstallGpeBlock
90  *
91  * PARAMETERS:  None
92  *
93  * RETURN:      None
94  *
95  * DESCRIPTION: Test GPE block device initialization. Requires test ASL with
96  *              A \GPE2 device.
97  *
98  *****************************************************************************/
99 
100 void
AfInstallGpeBlock(void)101 AfInstallGpeBlock (
102     void)
103 {
104     ACPI_STATUS                 Status;
105     ACPI_HANDLE                 Handle;
106     ACPI_GENERIC_ADDRESS        BlockAddress;
107     ACPI_HANDLE                 GpeDevice;
108     ACPI_OBJECT_TYPE            Type;
109 
110 
111     /* _GPE should always exist */
112 
113     Status = AcpiGetHandle (NULL, "\\_GPE", &Handle);
114     ACPI_CHECK_OK (AcpiGetHandle, Status);
115     if (ACPI_FAILURE (Status))
116     {
117         return;
118     }
119 
120     memset (&BlockAddress, 0, sizeof (ACPI_GENERIC_ADDRESS));
121     BlockAddress.SpaceId = ACPI_ADR_SPACE_SYSTEM_MEMORY;
122     BlockAddress.Address = 0x76540000;
123 
124     /* Attempt to install a GPE block on GPE2 (if present) */
125 
126     Status = AcpiGetHandle (NULL, "\\GPE2", &Handle);
127     if (ACPI_SUCCESS (Status))
128     {
129         Status = AcpiGetType (Handle, &Type);
130         if (ACPI_FAILURE (Status) ||
131            (Type != ACPI_TYPE_DEVICE))
132         {
133             return;
134         }
135 
136         Status = AcpiInstallGpeBlock (Handle, &BlockAddress, 7, 8);
137         ACPI_CHECK_OK (AcpiInstallGpeBlock, Status);
138 
139         Status = AcpiInstallGpeHandler (Handle, 8,
140             ACPI_GPE_LEVEL_TRIGGERED, AeGpeHandler, NULL);
141         ACPI_CHECK_OK (AcpiInstallGpeHandler, Status);
142 
143         Status = AcpiEnableGpe (Handle, 8);
144         ACPI_CHECK_OK (AcpiEnableGpe, Status);
145 
146         Status = AcpiGetGpeDevice (0x30, &GpeDevice);
147         ACPI_CHECK_OK (AcpiGetGpeDevice, Status);
148 
149         Status = AcpiGetGpeDevice (0x42, &GpeDevice);
150         ACPI_CHECK_OK (AcpiGetGpeDevice, Status);
151 
152         Status = AcpiGetGpeDevice (AcpiCurrentGpeCount-1, &GpeDevice);
153         ACPI_CHECK_OK (AcpiGetGpeDevice, Status);
154 
155         Status = AcpiGetGpeDevice (AcpiCurrentGpeCount, &GpeDevice);
156         ACPI_CHECK_STATUS (AcpiGetGpeDevice, Status, AE_NOT_EXIST);
157 
158         Status = AcpiRemoveGpeHandler (Handle, 8, AeGpeHandler);
159         ACPI_CHECK_OK (AcpiRemoveGpeHandler, Status);
160     }
161 
162     /* Attempt to install a GPE block on GPE3 (if present) */
163 
164     Status = AcpiGetHandle (NULL, "\\GPE3", &Handle);
165     if (ACPI_SUCCESS (Status))
166     {
167         Status = AcpiGetType (Handle, &Type);
168         if (ACPI_FAILURE (Status) ||
169            (Type != ACPI_TYPE_DEVICE))
170         {
171             return;
172         }
173 
174         Status = AcpiInstallGpeBlock (Handle, &BlockAddress, 8, 11);
175         ACPI_CHECK_OK (AcpiInstallGpeBlock, Status);
176     }
177 }
178 #endif /* !ACPI_REDUCED_HARDWARE */
179 
180 
181 /******************************************************************************
182  *
183  * FUNCTION:    AeTestBufferArgument
184  *
185  * DESCRIPTION: Test using a Buffer object as a method argument
186  *
187  *****************************************************************************/
188 
189 void
AeTestBufferArgument(void)190 AeTestBufferArgument (
191     void)
192 {
193     ACPI_OBJECT_LIST        Params;
194     ACPI_OBJECT             BufArg;
195     UINT8                   Buffer[] =
196     {
197         0,0,0,0,
198         4,0,0,0,
199         1,2,3,4
200     };
201 
202 
203     BufArg.Type = ACPI_TYPE_BUFFER;
204     BufArg.Buffer.Length = 12;
205     BufArg.Buffer.Pointer = Buffer;
206 
207     Params.Count = 1;
208     Params.Pointer = &BufArg;
209 
210     (void) AcpiEvaluateObject (NULL, "\\BUF", &Params, NULL);
211 }
212 
213 
214 static ACPI_OBJECT                 PkgArg;
215 static ACPI_OBJECT                 PkgElements[5];
216 static ACPI_OBJECT                 Pkg2Elements[5];
217 static ACPI_OBJECT_LIST            Params;
218 
219 /******************************************************************************
220  *
221  * FUNCTION:    AeTestPackageArgument
222  *
223  * DESCRIPTION: Test using a Package object as a method argument
224  *
225  *****************************************************************************/
226 
227 void
AeTestPackageArgument(void)228 AeTestPackageArgument (
229     void)
230 {
231 
232     /* Main package */
233 
234     PkgArg.Type = ACPI_TYPE_PACKAGE;
235     PkgArg.Package.Count = 4;
236     PkgArg.Package.Elements = PkgElements;
237 
238     /* Main package elements */
239 
240     PkgElements[0].Type = ACPI_TYPE_INTEGER;
241     PkgElements[0].Integer.Value = 0x22228888;
242 
243     PkgElements[1].Type = ACPI_TYPE_STRING;
244     PkgElements[1].String.Length = sizeof ("Top-level package");
245     PkgElements[1].String.Pointer = "Top-level package";
246 
247     PkgElements[2].Type = ACPI_TYPE_BUFFER;
248     PkgElements[2].Buffer.Length = sizeof ("XXXX");
249     PkgElements[2].Buffer.Pointer = (UINT8 *) "XXXX";
250 
251     PkgElements[3].Type = ACPI_TYPE_PACKAGE;
252     PkgElements[3].Package.Count = 2;
253     PkgElements[3].Package.Elements = Pkg2Elements;
254 
255     /* Subpackage elements */
256 
257     Pkg2Elements[0].Type = ACPI_TYPE_INTEGER;
258     Pkg2Elements[0].Integer.Value = 0xAAAABBBB;
259 
260     Pkg2Elements[1].Type = ACPI_TYPE_STRING;
261     Pkg2Elements[1].String.Length = sizeof ("Nested Package");
262     Pkg2Elements[1].String.Pointer = "Nested Package";
263 
264     /* Parameter object */
265 
266     Params.Count = 1;
267     Params.Pointer = &PkgArg;
268 
269     (void) AcpiEvaluateObject (NULL, "\\_PKG", &Params, NULL);
270 }
271 
272 
273 /******************************************************************************
274  *
275  * FUNCTION:    AeGetDevices
276  *
277  * DESCRIPTION: Stubbed at this time.
278  *
279  *****************************************************************************/
280 
281 ACPI_STATUS
AeGetDevices(ACPI_HANDLE ObjHandle,UINT32 NestingLevel,void * Context,void ** ReturnValue)282 AeGetDevices (
283     ACPI_HANDLE                     ObjHandle,
284     UINT32                          NestingLevel,
285     void                            *Context,
286     void                            **ReturnValue)
287 {
288 
289     return (AE_OK);
290 }
291 
292 
293 /******************************************************************************
294  *
295  * FUNCTION:    ExecuteOSI
296  *
297  * PARAMETERS:  OsiString           - String passed to _OSI method
298  *              ExpectedResult      - 0 (FALSE) or ACPI_UINT64_MAX (TRUE)
299  *
300  * RETURN:      Status
301  *
302  * DESCRIPTION: Execute the internally implemented (in ACPICA) _OSI method.
303  *
304  *****************************************************************************/
305 
306 ACPI_STATUS
ExecuteOSI(char * OsiString,UINT64 ExpectedResult)307 ExecuteOSI (
308     char                    *OsiString,
309     UINT64                  ExpectedResult)
310 {
311     ACPI_STATUS             Status;
312     ACPI_OBJECT_LIST        ArgList;
313     ACPI_OBJECT             Arg[1];
314     ACPI_BUFFER             ReturnValue;
315     ACPI_OBJECT             *Obj;
316 
317 
318     /* Setup input argument */
319 
320     ArgList.Count = 1;
321     ArgList.Pointer = Arg;
322 
323     Arg[0].Type = ACPI_TYPE_STRING;
324     Arg[0].String.Pointer = OsiString;
325     Arg[0].String.Length = strlen (Arg[0].String.Pointer);
326 
327     /* Ask ACPICA to allocate space for the return object */
328 
329     ReturnValue.Length = ACPI_ALLOCATE_BUFFER;
330 
331     Status = AcpiEvaluateObject (NULL, "\\_OSI", &ArgList, &ReturnValue);
332 
333     if (ACPI_FAILURE (Status))
334     {
335         AcpiOsPrintf (
336             "Could not execute _OSI method, %s\n",
337             AcpiFormatException (Status));
338         return (Status);
339     }
340 
341     Status = AE_ERROR;
342 
343     if (ReturnValue.Length < sizeof (ACPI_OBJECT))
344     {
345         AcpiOsPrintf (
346             "Return value from _OSI method too small, %.8X\n",
347             (UINT32) ReturnValue.Length);
348         goto ErrorExit;
349     }
350 
351     Obj = ReturnValue.Pointer;
352     if (Obj->Type != ACPI_TYPE_INTEGER)
353     {
354         AcpiOsPrintf (
355             "Invalid return type from _OSI method, %.2X\n", Obj->Type);
356         goto ErrorExit;
357     }
358 
359     if (Obj->Integer.Value != ExpectedResult)
360     {
361         AcpiOsPrintf (
362             "Invalid return value from _OSI, expected %8.8X%8.8X found %8.8X%8.8X\n",
363             ACPI_FORMAT_UINT64 (ExpectedResult),
364             ACPI_FORMAT_UINT64 (Obj->Integer.Value));
365         goto ErrorExit;
366     }
367 
368     Status = AE_OK;
369 
370     /* Reset the OSI data */
371 
372     AcpiGbl_OsiData = 0;
373 
374 ErrorExit:
375 
376     /* Free a buffer created via ACPI_ALLOCATE_BUFFER */
377 
378     AcpiOsFree (ReturnValue.Pointer);
379     return (Status);
380 }
381 
382 
383 /******************************************************************************
384  *
385  * FUNCTION:    AeGenericRegisters
386  *
387  * DESCRIPTION: Call the AcpiRead/Write interfaces.
388  *
389  *****************************************************************************/
390 
391 static ACPI_GENERIC_ADDRESS       GenericRegister;
392 
393 void
AeGenericRegisters(void)394 AeGenericRegisters (
395     void)
396 {
397     ACPI_STATUS             Status;
398     UINT64                  Value;
399 
400 
401     GenericRegister.Address = 0x1234;
402     GenericRegister.BitWidth = 64;
403     GenericRegister.BitOffset = 0;
404     GenericRegister.SpaceId = ACPI_ADR_SPACE_SYSTEM_IO;
405 
406     Status = AcpiRead (&Value, &GenericRegister);
407     ACPI_CHECK_OK (AcpiRead, Status);
408 
409     Status = AcpiWrite (Value, &GenericRegister);
410     ACPI_CHECK_OK (AcpiWrite, Status);
411 
412     GenericRegister.Address = 0x12345678;
413     GenericRegister.BitOffset = 0;
414     GenericRegister.SpaceId = ACPI_ADR_SPACE_SYSTEM_MEMORY;
415 
416     Status = AcpiRead (&Value, &GenericRegister);
417     ACPI_CHECK_OK (AcpiRead, Status);
418 
419     Status = AcpiWrite (Value, &GenericRegister);
420     ACPI_CHECK_OK (AcpiWrite, Status);
421 }
422