Home | History | Annotate | Line # | Download | only in examples
examples.c revision 1.1.1.4
      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 }
    485