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
64ACPI_STATUS
65AeSetupConfiguration (
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
100void
101AfInstallGpeBlock (
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
189void
190AeTestBufferArgument (
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
214static ACPI_OBJECT                 PkgArg;
215static ACPI_OBJECT                 PkgElements[5];
216static ACPI_OBJECT                 Pkg2Elements[5];
217static 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
227void
228AeTestPackageArgument (
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
281ACPI_STATUS
282AeGetDevices (
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
306ACPI_STATUS
307ExecuteOSI (
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
374ErrorExit:
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
391static ACPI_GENERIC_ADDRESS       GenericRegister;
392
393void
394AeGenericRegisters (
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