xref: /dflybsd-src/sys/contrib/dev/acpica/source/tools/examples/examples.c (revision 383048aca08c2de51d27aa8638a36982a0d74550)
1  /******************************************************************************
2   *
3   * Module Name: examples - Example ACPICA initialization and execution code
4   *
5   *****************************************************************************/
6  
7  /******************************************************************************
8   *
9   * 1. Copyright Notice
10   *
11   * Some or all of this work - Copyright (c) 1999 - 2021, Intel Corp.
12   * All rights reserved.
13   *
14   * 2. License
15   *
16   * 2.1. This is your license from Intel Corp. under its intellectual property
17   * rights. You may have additional license terms from the party that provided
18   * you this software, covering your right to use that party's intellectual
19   * property rights.
20   *
21   * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22   * copy of the source code appearing in this file ("Covered Code") an
23   * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24   * base code distributed originally by Intel ("Original Intel Code") to copy,
25   * make derivatives, distribute, use and display any portion of the Covered
26   * Code in any form, with the right to sublicense such rights; and
27   *
28   * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29   * license (with the right to sublicense), under only those claims of Intel
30   * patents that are infringed by the Original Intel Code, to make, use, sell,
31   * offer to sell, and import the Covered Code and derivative works thereof
32   * solely to the minimum extent necessary to exercise the above copyright
33   * license, and in no event shall the patent license extend to any additions
34   * to or modifications of the Original Intel Code. No other license or right
35   * is granted directly or by implication, estoppel or otherwise;
36   *
37   * The above copyright and patent license is granted only if the following
38   * conditions are met:
39   *
40   * 3. Conditions
41   *
42   * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43   * Redistribution of source code of any substantial portion of the Covered
44   * Code or modification with rights to further distribute source must include
45   * the above Copyright Notice, the above License, this list of Conditions,
46   * and the following Disclaimer and Export Compliance provision. In addition,
47   * Licensee must cause all Covered Code to which Licensee contributes to
48   * contain a file documenting the changes Licensee made to create that Covered
49   * Code and the date of any change. Licensee must include in that file the
50   * documentation of any changes made by any predecessor Licensee. Licensee
51   * must include a prominent statement that the modification is derived,
52   * directly or indirectly, from Original Intel Code.
53   *
54   * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55   * Redistribution of source code of any substantial portion of the Covered
56   * Code or modification without rights to further distribute source must
57   * include the following Disclaimer and Export Compliance provision in the
58   * documentation and/or other materials provided with distribution. In
59   * addition, Licensee may not authorize further sublicense of source of any
60   * portion of the Covered Code, and must include terms to the effect that the
61   * license from Licensee to its licensee is limited to the intellectual
62   * property embodied in the software Licensee provides to its licensee, and
63   * not to intellectual property embodied in modifications its licensee may
64   * make.
65   *
66   * 3.3. Redistribution of Executable. Redistribution in executable form of any
67   * substantial portion of the Covered Code or modification must reproduce the
68   * above Copyright Notice, and the following Disclaimer and Export Compliance
69   * provision in the documentation and/or other materials provided with the
70   * distribution.
71   *
72   * 3.4. Intel retains all right, title, and interest in and to the Original
73   * Intel Code.
74   *
75   * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76   * Intel shall be used in advertising or otherwise to promote the sale, use or
77   * other dealings in products derived from or relating to the Covered Code
78   * without prior written authorization from Intel.
79   *
80   * 4. Disclaimer and Export Compliance
81   *
82   * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83   * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84   * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85   * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86   * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87   * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88   * PARTICULAR PURPOSE.
89   *
90   * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91   * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92   * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93   * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94   * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95   * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96   * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97   * LIMITED REMEDY.
98   *
99   * 4.3. Licensee shall not export, either directly or indirectly, any of this
100   * software or system incorporating such software without first obtaining any
101   * required license or other approval from the U. S. Department of Commerce or
102   * any other agency or department of the United States Government. In the
103   * event Licensee exports any such software from the United States or
104   * re-exports any such software from a foreign destination, Licensee shall
105   * ensure that the distribution and export/re-export of the software is in
106   * compliance with all laws, regulations, orders, or other restrictions of the
107   * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108   * any of its subsidiaries will export/re-export any technical data, process,
109   * software, or service, directly or indirectly, to any country for which the
110   * United States government or any agency thereof requires an export license,
111   * other governmental approval, or letter of assurance, without first obtaining
112   * such license, approval or letter.
113   *
114   *****************************************************************************
115   *
116   * Alternatively, you may choose to be licensed under the terms of the
117   * following license:
118   *
119   * Redistribution and use in source and binary forms, with or without
120   * modification, are permitted provided that the following conditions
121   * are met:
122   * 1. Redistributions of source code must retain the above copyright
123   *    notice, this list of conditions, and the following disclaimer,
124   *    without modification.
125   * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126   *    substantially similar to the "NO WARRANTY" disclaimer below
127   *    ("Disclaimer") and any redistribution must be conditioned upon
128   *    including a substantially similar Disclaimer requirement for further
129   *    binary redistribution.
130   * 3. Neither the names of the above-listed copyright holders nor the names
131   *    of any contributors may be used to endorse or promote products derived
132   *    from this software without specific prior written permission.
133   *
134   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135   * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136   * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137   * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138   * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141   * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142   * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145   *
146   * Alternatively, you may choose to be licensed under the terms of the
147   * GNU General Public License ("GPL") version 2 as published by the Free
148   * Software Foundation.
149   *
150   *****************************************************************************/
151  
152  #include "examples.h"
153  
154  #define _COMPONENT          ACPI_EXAMPLE
155          ACPI_MODULE_NAME    ("examples")
156  
157  
158  /******************************************************************************
159   *
160   * ACPICA Example Code
161   *
162   * This module contains examples of how the host OS should interface to the
163   * ACPICA subsystem.
164   *
165   * 1) How to use the platform/acenv.h file and how to set configuration
166   *      options.
167   *
168   * 2) main - using the debug output mechanism and the error/warning output
169   *      macros.
170   *
171   * 3) Two examples of the ACPICA initialization sequence. The first is a
172   *      initialization with no "early" ACPI table access. The second shows
173   *      how to use ACPICA to obtain the tables very early during kernel
174   *      initialization, even before dynamic memory is available.
175   *
176   * 4) How to invoke a control method, including argument setup and how to
177   *      access the return value.
178   *
179   *****************************************************************************/
180  
181  
182  /* Local Prototypes */
183  
184  static ACPI_STATUS
185  InitializeFullAcpica (void);
186  
187  static ACPI_STATUS
188  InstallHandlers (void);
189  
190  static void
191  NotifyHandler (
192      ACPI_HANDLE             Device,
193      UINT32                  Value,
194      void                    *Context);
195  
196  static ACPI_STATUS
197  RegionHandler (
198      UINT32                  Function,
199      ACPI_PHYSICAL_ADDRESS   Address,
200      UINT32                  BitWidth,
201      UINT64                  *Value,
202      void                    *HandlerContext,
203      void                    *RegionContext);
204  
205  static ACPI_STATUS
206  RegionInit (
207      ACPI_HANDLE             RegionHandle,
208      UINT32                  Function,
209      void                    *HandlerContext,
210      void                    **RegionContext);
211  
212  static void
213  ExecuteMAIN (void);
214  
215  ACPI_STATUS
216  InitializeAcpiTables (
217      void);
218  
219  ACPI_STATUS
220  InitializeAcpi (
221      void);
222  
223  
224  /******************************************************************************
225   *
226   * FUNCTION:    main
227   *
228   * PARAMETERS:  argc, argv
229   *
230   * RETURN:      Status
231   *
232   * DESCRIPTION: Main routine. Shows the use of the various output macros, as
233   *              well as the use of the debug layer/level globals.
234   *
235   *****************************************************************************/
236  
237  int ACPI_SYSTEM_XFACE
main(int argc,char ** argv)238  main (
239      int                     argc,
240      char                    **argv)
241  {
242  
243      ACPI_DEBUG_INITIALIZE (); /* For debug version only */
244  
245      printf (ACPI_COMMON_SIGNON ("ACPI Example Code"));
246  
247      /* Initialize the local ACPI tables (RSDP/RSDT/XSDT/FADT/DSDT/FACS) */
248  
249      ExInitializeAcpiTables ();
250  
251      /* Initialize the ACPICA subsystem */
252  
253      InitializeFullAcpica ();
254  
255      /* Example warning and error output */
256  
257      ACPI_INFO        (("Example ACPICA info message"));
258      ACPI_WARNING     ((AE_INFO, "Example ACPICA warning message"));
259      ACPI_ERROR       ((AE_INFO, "Example ACPICA error message"));
260      ACPI_EXCEPTION   ((AE_INFO, AE_AML_OPERAND_TYPE,
261          "Example ACPICA exception message"));
262  
263      ExecuteOSI (NULL, 0);
264      ExecuteMAIN ();
265      return (0);
266  }
267  
268  
269  /******************************************************************************
270   *
271   * Example ACPICA initialization code. This shows a full initialization with
272   * no early ACPI table access.
273   *
274   *****************************************************************************/
275  
276  static ACPI_STATUS
InitializeFullAcpica(void)277  InitializeFullAcpica (void)
278  {
279      ACPI_STATUS             Status;
280  
281  
282      /* Initialize the ACPICA subsystem */
283  
284      Status = AcpiInitializeSubsystem ();
285      if (ACPI_FAILURE (Status))
286      {
287          ACPI_EXCEPTION ((AE_INFO, Status, "While initializing ACPICA"));
288          return (Status);
289      }
290  
291      /* Initialize the ACPICA Table Manager and get all ACPI tables */
292  
293      ACPI_INFO (("Loading ACPI tables"));
294  
295      Status = AcpiInitializeTables (NULL, 16, FALSE);
296      if (ACPI_FAILURE (Status))
297      {
298          ACPI_EXCEPTION ((AE_INFO, Status, "While initializing Table Manager"));
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          ACPI_EXCEPTION ((AE_INFO, Status, "While enabling ACPICA"));
317          return (Status);
318      }
319  
320      /* Create the ACPI namespace from ACPI tables */
321  
322      Status = AcpiLoadTables ();
323      if (ACPI_FAILURE (Status))
324      {
325          ACPI_EXCEPTION ((AE_INFO, Status, "While loading ACPI tables"));
326          return (Status);
327      }
328  
329      /* Complete the ACPI namespace object initialization */
330  
331      Status = AcpiInitializeObjects (ACPI_FULL_INITIALIZATION);
332      if (ACPI_FAILURE (Status))
333      {
334          ACPI_EXCEPTION ((AE_INFO, Status, "While initializing ACPICA objects"));
335          return (Status);
336      }
337  
338      return (AE_OK);
339  }
340  
341  
342  /******************************************************************************
343   *
344   * Example ACPICA initialization code with early ACPI table access. This shows
345   * an initialization that requires early access to ACPI tables (before
346   * kernel dynamic memory is available)
347   *
348   *****************************************************************************/
349  
350  /*
351   * The purpose of this static table array is to avoid the use of kernel
352   * dynamic memory which may not be available during early ACPI table
353   * access.
354   */
355  #define ACPI_MAX_INIT_TABLES    16
356  static ACPI_TABLE_DESC      TableArray[ACPI_MAX_INIT_TABLES];
357  
358  
359  /*
360   * This function would be called early in kernel initialization. After this
361   * is called, all ACPI tables are available to the host.
362   */
363  ACPI_STATUS
InitializeAcpiTables(void)364  InitializeAcpiTables (
365      void)
366  {
367      ACPI_STATUS             Status;
368  
369  
370      /* Initialize the ACPICA Table Manager and get all ACPI tables */
371  
372      Status = AcpiInitializeTables (TableArray, ACPI_MAX_INIT_TABLES, TRUE);
373      return (Status);
374  }
375  
376  
377  /*
378   * This function would be called after the kernel is initialized and
379   * dynamic/virtual memory is available. It completes the initialization of
380   * the ACPICA subsystem.
381   */
382  ACPI_STATUS
InitializeAcpi(void)383  InitializeAcpi (
384      void)
385  {
386      ACPI_STATUS             Status;
387  
388  
389      /* Initialize the ACPICA subsystem */
390  
391      Status = AcpiInitializeSubsystem ();
392      if (ACPI_FAILURE (Status))
393      {
394          return (Status);
395      }
396  
397      /* Copy the root table list to dynamic memory */
398  
399      Status = AcpiReallocateRootTable ();
400      if (ACPI_FAILURE (Status))
401      {
402          return (Status);
403      }
404  
405      /* Install local handlers */
406  
407      Status = InstallHandlers ();
408      if (ACPI_FAILURE (Status))
409      {
410          ACPI_EXCEPTION ((AE_INFO, Status, "While installing handlers"));
411          return (Status);
412      }
413  
414      /* Initialize the ACPI hardware */
415  
416      Status = AcpiEnableSubsystem (ACPI_FULL_INITIALIZATION);
417      if (ACPI_FAILURE (Status))
418      {
419          return (Status);
420      }
421  
422      /* Create the ACPI namespace from ACPI tables */
423  
424      Status = AcpiLoadTables ();
425      if (ACPI_FAILURE (Status))
426      {
427          return (Status);
428      }
429  
430      /* Complete the ACPI namespace object initialization */
431  
432      Status = AcpiInitializeObjects (ACPI_FULL_INITIALIZATION);
433      if (ACPI_FAILURE (Status))
434      {
435          return (Status);
436      }
437  
438      return (AE_OK);
439  }
440  
441  
442  /******************************************************************************
443   *
444   * Example ACPICA handler and handler installation
445   *
446   *****************************************************************************/
447  
448  static void
NotifyHandler(ACPI_HANDLE Device,UINT32 Value,void * Context)449  NotifyHandler (
450      ACPI_HANDLE                 Device,
451      UINT32                      Value,
452      void                        *Context)
453  {
454  
455      ACPI_INFO (("Received a notify 0x%X", Value));
456  }
457  
458  
459  static ACPI_STATUS
RegionInit(ACPI_HANDLE RegionHandle,UINT32 Function,void * HandlerContext,void ** RegionContext)460  RegionInit (
461      ACPI_HANDLE                 RegionHandle,
462      UINT32                      Function,
463      void                        *HandlerContext,
464      void                        **RegionContext)
465  {
466  
467      if (Function == ACPI_REGION_DEACTIVATE)
468      {
469          *RegionContext = NULL;
470      }
471      else
472      {
473          *RegionContext = RegionHandle;
474      }
475  
476      return (AE_OK);
477  }
478  
479  
480  static ACPI_STATUS
RegionHandler(UINT32 Function,ACPI_PHYSICAL_ADDRESS Address,UINT32 BitWidth,UINT64 * Value,void * HandlerContext,void * RegionContext)481  RegionHandler (
482      UINT32                      Function,
483      ACPI_PHYSICAL_ADDRESS       Address,
484      UINT32                      BitWidth,
485      UINT64                      *Value,
486      void                        *HandlerContext,
487      void                        *RegionContext)
488  {
489  
490      ACPI_INFO (("Received a region access"));
491  
492      return (AE_OK);
493  }
494  
495  
496  static ACPI_STATUS
InstallHandlers(void)497  InstallHandlers (void)
498  {
499      ACPI_STATUS             Status;
500  
501  
502      /* Install global notify handler */
503  
504      Status = AcpiInstallNotifyHandler (ACPI_ROOT_OBJECT,
505          ACPI_SYSTEM_NOTIFY, NotifyHandler, NULL);
506      if (ACPI_FAILURE (Status))
507      {
508          ACPI_EXCEPTION ((AE_INFO, Status, "While installing Notify handler"));
509          return (Status);
510      }
511  
512      Status = AcpiInstallAddressSpaceHandler (ACPI_ROOT_OBJECT,
513          ACPI_ADR_SPACE_SYSTEM_MEMORY, RegionHandler, RegionInit, NULL);
514      if (ACPI_FAILURE (Status))
515      {
516          ACPI_EXCEPTION ((AE_INFO, Status, "While installing an OpRegion handler"));
517          return (Status);
518      }
519  
520      return (AE_OK);
521  }
522  
523  
524  /******************************************************************************
525   *
526   * Examples of control method execution.
527   *
528   * _OSI is a predefined method that is implemented internally within ACPICA.
529   *
530   * Shows the following elements:
531   *
532   * 1) How to setup a control method argument and argument list
533   * 2) How to setup the return value object
534   * 3) How to invoke AcpiEvaluateObject
535   * 4) How to check the returned ACPI_STATUS
536   * 5) How to analyze the return value
537   *
538   *****************************************************************************/
539  
540  ACPI_STATUS
ExecuteOSI(char * OsiString,UINT64 ExpectedResult)541  ExecuteOSI (
542      char                    *OsiString,
543      UINT64                  ExpectedResult)
544  {
545      ACPI_STATUS             Status;
546      ACPI_OBJECT_LIST        ArgList;
547      ACPI_OBJECT             Arg[1];
548      ACPI_BUFFER             ReturnValue;
549      ACPI_OBJECT             *Object;
550  
551  
552      ACPI_INFO (("Executing _OSI reserved method"));
553  
554      /* Setup input argument */
555  
556      ArgList.Count = 1;
557      ArgList.Pointer = Arg;
558  
559      Arg[0].Type = ACPI_TYPE_STRING;
560      Arg[0].String.Pointer = "Windows 2001";
561      Arg[0].String.Length = strlen (Arg[0].String.Pointer);
562  
563      /* Ask ACPICA to allocate space for the return object */
564  
565      ReturnValue.Length = ACPI_ALLOCATE_BUFFER;
566  
567      Status = AcpiEvaluateObject (NULL, "\\_OSI", &ArgList, &ReturnValue);
568      if (ACPI_FAILURE (Status))
569      {
570          ACPI_EXCEPTION ((AE_INFO, Status, "While executing _OSI"));
571          return (AE_OK);
572      }
573  
574      /* Ensure that the return object is large enough */
575  
576      if (ReturnValue.Length < sizeof (ACPI_OBJECT))
577      {
578          AcpiOsPrintf ("Return value from _OSI method too small, %.8X\n",
579              (UINT32) ReturnValue.Length);
580          goto ErrorExit;
581      }
582  
583      /* Expect an integer return value from execution of _OSI */
584  
585      Object = ReturnValue.Pointer;
586      if (Object->Type != ACPI_TYPE_INTEGER)
587      {
588          AcpiOsPrintf ("Invalid return type from _OSI, %.2X\n", Object->Type);
589      }
590  
591      ACPI_INFO (("_OSI returned 0x%8.8X",
592          (UINT32) Object->Integer.Value));
593  
594  
595  ErrorExit:
596  
597      /* Free a buffer created via ACPI_ALLOCATE_BUFFER */
598  
599      AcpiOsFree (ReturnValue.Pointer);
600      return (AE_OK);
601  }
602  
603  
604  /******************************************************************************
605   *
606   * Execute an actual control method in the DSDT (MAIN)
607   *
608   *****************************************************************************/
609  
610  static void
ExecuteMAIN(void)611  ExecuteMAIN (void)
612  {
613      ACPI_STATUS             Status;
614      ACPI_OBJECT_LIST        ArgList;
615      ACPI_OBJECT             Arg[1];
616      ACPI_BUFFER             ReturnValue;
617      ACPI_OBJECT             *Object;
618  
619  
620      ACPI_INFO (("Executing MAIN method"));
621  
622      /* Setup input argument */
623  
624      ArgList.Count = 1;
625      ArgList.Pointer = Arg;
626  
627      Arg[0].Type = ACPI_TYPE_STRING;
628      Arg[0].String.Pointer = "Method [MAIN] is executing";
629      Arg[0].String.Length = strlen (Arg[0].String.Pointer);
630  
631      /* Ask ACPICA to allocate space for the return object */
632  
633      ReturnValue.Length = ACPI_ALLOCATE_BUFFER;
634  
635      Status = AcpiEvaluateObject (NULL, "\\MAIN", &ArgList, &ReturnValue);
636      if (ACPI_FAILURE (Status))
637      {
638          ACPI_EXCEPTION ((AE_INFO, Status, "While executing MAIN"));
639          return;
640      }
641  
642      if (ReturnValue.Pointer)
643      {
644          /* Obtain and validate the returned ACPI_OBJECT */
645  
646          Object = ReturnValue.Pointer;
647          if (Object->Type == ACPI_TYPE_STRING)
648          {
649              AcpiOsPrintf ("Method [MAIN] returned: \"%s\"\n",
650                  Object->String.Pointer);
651          }
652  
653          ACPI_FREE (ReturnValue.Pointer);
654      }
655  }
656