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