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