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