1 /****************************************************************************** 2 * 3 * Module Name: examples - Example ACPICA initialization and execution code 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2013, 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 #define __EXAMPLES_C__ 45 #include "examples.h" 46 47 #define _COMPONENT ACPI_EXAMPLE 48 ACPI_MODULE_NAME ("examples") 49 50 51 /****************************************************************************** 52 * 53 * ACPICA Example Code 54 * 55 * This module contains examples of how the host OS should interface to the 56 * ACPICA subsystem. 57 * 58 * 1) How to use the platform/acenv.h file and how to set configuration 59 * options. 60 * 61 * 2) main - using the debug output mechanism and the error/warning output 62 * macros. 63 * 64 * 3) Two examples of the ACPICA initialization sequence. The first is a 65 * initialization with no "early" ACPI table access. The second shows 66 * how to use ACPICA to obtain the tables very early during kernel 67 * initialization, even before dynamic memory is available. 68 * 69 * 4) How to invoke a control method, including argument setup and how to 70 * access the return value. 71 * 72 *****************************************************************************/ 73 74 75 /* Local Prototypes */ 76 77 static ACPI_STATUS 78 InitializeFullAcpica (void); 79 80 static ACPI_STATUS 81 InstallHandlers (void); 82 83 static void 84 NotifyHandler ( 85 ACPI_HANDLE Device, 86 UINT32 Value, 87 void *Context); 88 89 static void 90 ExecuteMAIN (void); 91 92 static void 93 ExecuteOSI (void); 94 95 ACPI_STATUS 96 InitializeAcpiTables ( 97 void); 98 99 ACPI_STATUS 100 InitializeAcpi ( 101 void); 102 103 104 /****************************************************************************** 105 * 106 * FUNCTION: main 107 * 108 * PARAMETERS: argc, argv 109 * 110 * RETURN: Status 111 * 112 * DESCRIPTION: Main routine. Shows the use of the various output macros, as 113 * well as the use of the debug layer/level globals. 114 * 115 *****************************************************************************/ 116 117 int ACPI_SYSTEM_XFACE 118 main ( 119 int argc, 120 char **argv) 121 { 122 123 ACPI_DEBUG_INITIALIZE (); /* For debug version only */ 124 125 printf (ACPI_COMMON_SIGNON ("ACPI Example Code")); 126 127 /* Initialize the local ACPI tables (RSDP/RSDT/XSDT/FADT/DSDT/FACS) */ 128 129 ExInitializeAcpiTables (); 130 131 /* Initialize the ACPICA subsystem */ 132 133 InitializeFullAcpica (); 134 135 /* Example warning and error output */ 136 137 ACPI_INFO ((AE_INFO, "Example ACPICA info message")); 138 ACPI_WARNING ((AE_INFO, "Example ACPICA warning message")); 139 ACPI_ERROR ((AE_INFO, "Example ACPICA error message")); 140 ACPI_EXCEPTION ((AE_INFO, AE_AML_OPERAND_TYPE, "Example ACPICA exception message")); 141 142 ExecuteOSI (); 143 ExecuteMAIN (); 144 return (0); 145 } 146 147 148 /****************************************************************************** 149 * 150 * Example ACPICA initialization code. This shows a full initialization with 151 * no early ACPI table access. 152 * 153 *****************************************************************************/ 154 155 static ACPI_STATUS 156 InitializeFullAcpica (void) 157 { 158 ACPI_STATUS Status; 159 160 161 /* Initialize the ACPICA subsystem */ 162 163 Status = AcpiInitializeSubsystem (); 164 if (ACPI_FAILURE (Status)) 165 { 166 ACPI_EXCEPTION ((AE_INFO, Status, "While initializing ACPICA")); 167 return (Status); 168 } 169 170 /* Initialize the ACPICA Table Manager and get all ACPI tables */ 171 172 ACPI_INFO ((AE_INFO, "Loading ACPI tables")); 173 174 Status = AcpiInitializeTables (NULL, 16, FALSE); 175 if (ACPI_FAILURE (Status)) 176 { 177 ACPI_EXCEPTION ((AE_INFO, Status, "While initializing Table Manager")); 178 return (Status); 179 } 180 181 /* Create the ACPI namespace from ACPI tables */ 182 183 Status = AcpiLoadTables (); 184 if (ACPI_FAILURE (Status)) 185 { 186 ACPI_EXCEPTION ((AE_INFO, Status, "While loading ACPI tables")); 187 return (Status); 188 } 189 190 /* Install local handlers */ 191 192 Status = InstallHandlers (); 193 if (ACPI_FAILURE (Status)) 194 { 195 ACPI_EXCEPTION ((AE_INFO, Status, "While installing handlers")); 196 return (Status); 197 } 198 199 /* Initialize the ACPI hardware */ 200 201 Status = AcpiEnableSubsystem (ACPI_FULL_INITIALIZATION); 202 if (ACPI_FAILURE (Status)) 203 { 204 ACPI_EXCEPTION ((AE_INFO, Status, "While enabling ACPICA")); 205 return (Status); 206 } 207 208 /* Complete the ACPI namespace object initialization */ 209 210 Status = AcpiInitializeObjects (ACPI_FULL_INITIALIZATION); 211 if (ACPI_FAILURE (Status)) 212 { 213 ACPI_EXCEPTION ((AE_INFO, Status, "While initializing ACPICA objects")); 214 return (Status); 215 } 216 217 return (AE_OK); 218 } 219 220 221 /****************************************************************************** 222 * 223 * Example ACPICA initialization code with early ACPI table access. This shows 224 * an initialization that requires early access to ACPI tables (before 225 * kernel dynamic memory is available) 226 * 227 *****************************************************************************/ 228 229 /* 230 * The purpose of this static table array is to avoid the use of kernel 231 * dynamic memory which may not be available during early ACPI table 232 * access. 233 */ 234 #define ACPI_MAX_INIT_TABLES 16 235 static ACPI_TABLE_DESC TableArray[ACPI_MAX_INIT_TABLES]; 236 237 238 /* 239 * This function would be called early in kernel initialization. After this 240 * is called, all ACPI tables are available to the host. 241 */ 242 ACPI_STATUS 243 InitializeAcpiTables ( 244 void) 245 { 246 ACPI_STATUS Status; 247 248 249 /* Initialize the ACPICA Table Manager and get all ACPI tables */ 250 251 Status = AcpiInitializeTables (TableArray, ACPI_MAX_INIT_TABLES, TRUE); 252 return (Status); 253 } 254 255 256 /* 257 * This function would be called after the kernel is initialized and 258 * dynamic/virtual memory is available. It completes the initialization of 259 * the ACPICA subsystem. 260 */ 261 ACPI_STATUS 262 InitializeAcpi ( 263 void) 264 { 265 ACPI_STATUS Status; 266 267 268 /* Initialize the ACPICA subsystem */ 269 270 Status = AcpiInitializeSubsystem (); 271 if (ACPI_FAILURE (Status)) 272 { 273 return (Status); 274 } 275 276 /* Copy the root table list to dynamic memory */ 277 278 Status = AcpiReallocateRootTable (); 279 if (ACPI_FAILURE (Status)) 280 { 281 return (Status); 282 } 283 284 /* Create the ACPI namespace from ACPI tables */ 285 286 Status = AcpiLoadTables (); 287 if (ACPI_FAILURE (Status)) 288 { 289 return (Status); 290 } 291 292 /* Install local handlers */ 293 294 Status = InstallHandlers (); 295 if (ACPI_FAILURE (Status)) 296 { 297 ACPI_EXCEPTION ((AE_INFO, Status, "While installing handlers")); 298 return (Status); 299 } 300 301 /* Initialize the ACPI hardware */ 302 303 Status = AcpiEnableSubsystem (ACPI_FULL_INITIALIZATION); 304 if (ACPI_FAILURE (Status)) 305 { 306 return (Status); 307 } 308 309 /* Complete the ACPI namespace object initialization */ 310 311 Status = AcpiInitializeObjects (ACPI_FULL_INITIALIZATION); 312 if (ACPI_FAILURE (Status)) 313 { 314 return (Status); 315 } 316 317 return (AE_OK); 318 } 319 320 321 /****************************************************************************** 322 * 323 * Example ACPICA handler and handler installation 324 * 325 *****************************************************************************/ 326 327 static void 328 NotifyHandler ( 329 ACPI_HANDLE Device, 330 UINT32 Value, 331 void *Context) 332 { 333 334 ACPI_INFO ((AE_INFO, "Received a notify 0x%X", Value)); 335 } 336 337 338 static ACPI_STATUS 339 InstallHandlers (void) 340 { 341 ACPI_STATUS Status; 342 343 344 /* Install global notify handler */ 345 346 Status = AcpiInstallNotifyHandler (ACPI_ROOT_OBJECT, ACPI_SYSTEM_NOTIFY, 347 NotifyHandler, NULL); 348 if (ACPI_FAILURE (Status)) 349 { 350 ACPI_EXCEPTION ((AE_INFO, Status, "While installing Notify handler")); 351 return (Status); 352 } 353 354 return (AE_OK); 355 } 356 357 358 /****************************************************************************** 359 * 360 * Examples of control method execution. 361 * 362 * _OSI is a predefined method that is implemented internally within ACPICA. 363 * 364 * Shows the following elements: 365 * 366 * 1) How to setup a control method argument and argument list 367 * 2) How to setup the return value object 368 * 3) How to invoke AcpiEvaluateObject 369 * 4) How to check the returned ACPI_STATUS 370 * 5) How to analyze the return value 371 * 372 *****************************************************************************/ 373 374 static void 375 ExecuteOSI (void) 376 { 377 ACPI_STATUS Status; 378 ACPI_OBJECT_LIST ArgList; 379 ACPI_OBJECT Arg[1]; 380 ACPI_BUFFER ReturnValue; 381 ACPI_OBJECT *Object; 382 383 384 ACPI_INFO ((AE_INFO, "Executing _OSI reserved method")); 385 386 /* Setup input argument */ 387 388 ArgList.Count = 1; 389 ArgList.Pointer = Arg; 390 391 Arg[0].Type = ACPI_TYPE_STRING; 392 Arg[0].String.Pointer = "Windows 2001"; 393 Arg[0].String.Length = strlen (Arg[0].String.Pointer); 394 395 /* Ask ACPICA to allocate space for the return object */ 396 397 ReturnValue.Length = ACPI_ALLOCATE_BUFFER; 398 399 Status = AcpiEvaluateObject (NULL, "\\_OSI", &ArgList, &ReturnValue); 400 if (ACPI_FAILURE (Status)) 401 { 402 ACPI_EXCEPTION ((AE_INFO, Status, "While executing _OSI")); 403 return; 404 } 405 406 /* Ensure that the return object is large enough */ 407 408 if (ReturnValue.Length < sizeof (ACPI_OBJECT)) 409 { 410 AcpiOsPrintf ("Return value from _OSI method too small, %.8X\n", 411 ReturnValue.Length); 412 goto ErrorExit; 413 } 414 415 /* Expect an integer return value from execution of _OSI */ 416 417 Object = ReturnValue.Pointer; 418 if (Object->Type != ACPI_TYPE_INTEGER) 419 { 420 AcpiOsPrintf ("Invalid return type from _OSI, %.2X\n", Object->Type); 421 } 422 423 ACPI_INFO ((AE_INFO, "_OSI returned 0x%8.8X", (UINT32) Object->Integer.Value)); 424 425 426 ErrorExit: 427 428 /* Free a buffer created via ACPI_ALLOCATE_BUFFER */ 429 430 AcpiOsFree (ReturnValue.Pointer); 431 } 432 433 434 /****************************************************************************** 435 * 436 * Execute an actual control method in the DSDT (MAIN) 437 * 438 *****************************************************************************/ 439 440 static void 441 ExecuteMAIN (void) 442 { 443 ACPI_STATUS Status; 444 ACPI_OBJECT_LIST ArgList; 445 ACPI_OBJECT Arg[1]; 446 ACPI_BUFFER ReturnValue; 447 ACPI_OBJECT *Object; 448 449 450 ACPI_INFO ((AE_INFO, "Executing MAIN method")); 451 452 /* Setup input argument */ 453 454 ArgList.Count = 1; 455 ArgList.Pointer = Arg; 456 457 Arg[0].Type = ACPI_TYPE_STRING; 458 Arg[0].String.Pointer = "Method [MAIN] is executing"; 459 Arg[0].String.Length = strlen (Arg[0].String.Pointer); 460 461 /* Ask ACPICA to allocate space for the return object */ 462 463 ReturnValue.Length = ACPI_ALLOCATE_BUFFER; 464 465 Status = AcpiEvaluateObject (NULL, "\\MAIN", &ArgList, &ReturnValue); 466 if (ACPI_FAILURE (Status)) 467 { 468 ACPI_EXCEPTION ((AE_INFO, Status, "While executing MAIN")); 469 return; 470 } 471 472 if (ReturnValue.Pointer) 473 { 474 /* Obtain and validate the returned ACPI_OBJECT */ 475 476 Object = ReturnValue.Pointer; 477 if (Object->Type == ACPI_TYPE_STRING) 478 { 479 AcpiOsPrintf ("Method [MAIN] returned: \"%s\"\n", Object->String.Pointer); 480 } 481 482 ACPI_FREE (ReturnValue.Pointer); 483 } 484 }