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