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