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