Initial import of binutils 2.22 on the new vendor branch
[dragonfly.git] / sys / contrib / dev / acpica-unix / tools / acpiexec / aehandlers.c
1 /******************************************************************************
2  *
3  * Module Name: aehandlers - Various handlers for acpiexec
4  *
5  *****************************************************************************/
6
7 /******************************************************************************
8  *
9  * 1. Copyright Notice
10  *
11  * Some or all of this work - Copyright (c) 1999 - 2011, 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 #include "aecommon.h"
117
118 #define _COMPONENT          ACPI_TOOLS
119         ACPI_MODULE_NAME    ("aehandlers")
120
121 /* Local prototypes */
122
123 static void
124 AeNotifyHandler (
125     ACPI_HANDLE             Device,
126     UINT32                  Value,
127     void                    *Context);
128
129 static void
130 AeDeviceNotifyHandler (
131     ACPI_HANDLE             Device,
132     UINT32                  Value,
133     void                    *Context);
134
135 static ACPI_STATUS
136 AeExceptionHandler (
137     ACPI_STATUS             AmlStatus,
138     ACPI_NAME               Name,
139     UINT16                  Opcode,
140     UINT32                  AmlOffset,
141     void                    *Context);
142
143 static ACPI_STATUS
144 AeTableHandler (
145     UINT32                  Event,
146     void                    *Table,
147     void                    *Context);
148
149 static ACPI_STATUS
150 AeRegionInit (
151     ACPI_HANDLE             RegionHandle,
152     UINT32                  Function,
153     void                    *HandlerContext,
154     void                    **RegionContext);
155
156 static void
157 AeAttachedDataHandler (
158     ACPI_HANDLE             Object,
159     void                    *Data);
160
161 static UINT32
162 AeInterfaceHandler (
163     ACPI_STRING             InterfaceName,
164     UINT32                  Supported);
165
166 static UINT32
167 AeEventHandler (
168     void                    *Context);
169
170 static UINT32               SigintCount = 0;
171 static AE_DEBUG_REGIONS     AeRegions;
172
173
174 /*
175  * We will override default region handlers for memory and I/O. Especially
176  * the SystemMemory handler, which must be implemented locally to simulate
177  * memory operation regions. Do not override the PCI_Config handler since
178  * we would like to exercise the default handler code. Do not override
179  * DataTable handler, since the default handler works correctly under
180  * acpiexec (and is used by the test suites.)
181  */
182 static ACPI_ADR_SPACE_TYPE  DefaultSpaceIdList[] =
183 {
184     ACPI_ADR_SPACE_SYSTEM_MEMORY,
185     ACPI_ADR_SPACE_SYSTEM_IO
186 };
187
188 /*
189  * We will install handlers for some of the various address space IDs
190  */
191 static ACPI_ADR_SPACE_TYPE  SpaceIdList[] =
192 {
193     ACPI_ADR_SPACE_EC,
194     ACPI_ADR_SPACE_SMBUS,
195     ACPI_ADR_SPACE_PCI_BAR_TARGET,
196     ACPI_ADR_SPACE_IPMI,
197     ACPI_ADR_SPACE_FIXED_HARDWARE
198 };
199
200
201 /******************************************************************************
202  *
203  * FUNCTION:    AeCtrlCHandler
204  *
205  * PARAMETERS:  Sig
206  *
207  * RETURN:      none
208  *
209  * DESCRIPTION: Control-C handler.  Abort running control method if any.
210  *
211  *****************************************************************************/
212
213 void ACPI_SYSTEM_XFACE
214 AeCtrlCHandler (
215     int                     Sig)
216 {
217
218     signal (SIGINT, SIG_IGN);
219     SigintCount++;
220
221     AcpiOsPrintf ("Caught a ctrl-c (#%u)\n\n", SigintCount);
222
223     if (AcpiGbl_MethodExecuting)
224     {
225         AcpiGbl_AbortMethod = TRUE;
226         signal (SIGINT, AeCtrlCHandler);
227
228         if (SigintCount < 10)
229         {
230             return;
231         }
232     }
233
234     exit (0);
235 }
236
237
238 /******************************************************************************
239  *
240  * FUNCTION:    AeNotifyHandler
241  *
242  * PARAMETERS:  Standard notify handler parameters
243  *
244  * RETURN:      Status
245  *
246  * DESCRIPTION: System notify handler for AcpiExec utility.  Used by the ASL
247  *              test suite(s) to communicate errors and other information to
248  *              this utility via the Notify() operator.
249  *
250  *****************************************************************************/
251
252 static void
253 AeNotifyHandler (
254     ACPI_HANDLE                 Device,
255     UINT32                      Value,
256     void                        *Context)
257 {
258
259     switch (Value)
260     {
261 #if 0
262     case 0:
263         printf ("[AcpiExec] Method Error 0x%X: Results not equal\n", Value);
264         if (AcpiGbl_DebugFile)
265         {
266             AcpiOsPrintf ("[AcpiExec] Method Error: Results not equal\n");
267         }
268         break;
269
270
271     case 1:
272         printf ("[AcpiExec] Method Error: Incorrect numeric result\n");
273         if (AcpiGbl_DebugFile)
274         {
275             AcpiOsPrintf ("[AcpiExec] Method Error: Incorrect numeric result\n");
276         }
277         break;
278
279
280     case 2:
281         printf ("[AcpiExec] Method Error: An operand was overwritten\n");
282         if (AcpiGbl_DebugFile)
283         {
284             AcpiOsPrintf ("[AcpiExec] Method Error: An operand was overwritten\n");
285         }
286         break;
287
288 #endif
289
290     default:
291         printf ("[AcpiExec] Received a System Notify on [%4.4s] %p Value 0x%2.2X (%s)\n",
292             AcpiUtGetNodeName (Device), Device, Value,
293             AcpiUtGetNotifyName (Value));
294         if (AcpiGbl_DebugFile)
295         {
296             AcpiOsPrintf ("[AcpiExec] Received a system notify, Value 0x%2.2X\n", Value);
297         }
298
299         (void) AcpiEvaluateObject (Device, "_NOT", NULL, NULL);
300         break;
301     }
302 }
303
304
305 /******************************************************************************
306  *
307  * FUNCTION:    AeDeviceNotifyHandler
308  *
309  * PARAMETERS:  Standard notify handler parameters
310  *
311  * RETURN:      Status
312  *
313  * DESCRIPTION: Device notify handler for AcpiExec utility.  Used by the ASL
314  *              test suite(s) to communicate errors and other information to
315  *              this utility via the Notify() operator.
316  *
317  *****************************************************************************/
318
319 static void
320 AeDeviceNotifyHandler (
321     ACPI_HANDLE                 Device,
322     UINT32                      Value,
323     void                        *Context)
324 {
325
326     printf ("[AcpiExec] Received a Device Notify on [%4.4s] %p Value 0x%2.2X (%s)\n",
327         AcpiUtGetNodeName (Device), Device, Value,
328         AcpiUtGetNotifyName (Value));
329     if (AcpiGbl_DebugFile)
330     {
331         AcpiOsPrintf ("[AcpiExec] Received a device notify, Value 0x%2.2X\n", Value);
332     }
333
334     (void) AcpiEvaluateObject (Device, "_NOT", NULL, NULL);
335 }
336
337
338 /******************************************************************************
339  *
340  * FUNCTION:    AeExceptionHandler
341  *
342  * PARAMETERS:  Standard exception handler parameters
343  *
344  * RETURN:      Status
345  *
346  * DESCRIPTION: System exception handler for AcpiExec utility.
347  *
348  *****************************************************************************/
349
350 static ACPI_STATUS
351 AeExceptionHandler (
352     ACPI_STATUS             AmlStatus,
353     ACPI_NAME               Name,
354     UINT16                  Opcode,
355     UINT32                  AmlOffset,
356     void                    *Context)
357 {
358     ACPI_STATUS             NewAmlStatus = AmlStatus;
359     ACPI_STATUS             Status;
360     ACPI_BUFFER             ReturnObj;
361     ACPI_OBJECT_LIST        ArgList;
362     ACPI_OBJECT             Arg[3];
363     const char              *Exception;
364
365
366     Exception = AcpiFormatException (AmlStatus);
367     AcpiOsPrintf ("[AcpiExec] Exception %s during execution ", Exception);
368     if (Name)
369     {
370         AcpiOsPrintf ("of method [%4.4s]", (char *) &Name);
371     }
372     else
373     {
374         AcpiOsPrintf ("at module level (table load)");
375     }
376     AcpiOsPrintf (" Opcode [%s] @%X\n", AcpiPsGetOpcodeName (Opcode), AmlOffset);
377
378     /*
379      * Invoke the _ERR method if present
380      *
381      * Setup parameter object
382      */
383     ArgList.Count = 3;
384     ArgList.Pointer = Arg;
385
386     Arg[0].Type = ACPI_TYPE_INTEGER;
387     Arg[0].Integer.Value = AmlStatus;
388
389     Arg[1].Type = ACPI_TYPE_STRING;
390     Arg[1].String.Pointer = ACPI_CAST_PTR (char, Exception);
391     Arg[1].String.Length = ACPI_STRLEN (Exception);
392
393     Arg[2].Type = ACPI_TYPE_INTEGER;
394     Arg[2].Integer.Value = AcpiOsGetThreadId();
395
396     /* Setup return buffer */
397
398     ReturnObj.Pointer = NULL;
399     ReturnObj.Length = ACPI_ALLOCATE_BUFFER;
400
401     Status = AcpiEvaluateObject (NULL, "\\_ERR", &ArgList, &ReturnObj);
402     if (ACPI_SUCCESS (Status))
403     {
404         if (ReturnObj.Pointer)
405         {
406             /* Override original status */
407
408             NewAmlStatus = (ACPI_STATUS)
409                 ((ACPI_OBJECT *) ReturnObj.Pointer)->Integer.Value;
410
411             AcpiOsFree (ReturnObj.Pointer);
412         }
413     }
414     else if (Status != AE_NOT_FOUND)
415     {
416         AcpiOsPrintf ("[AcpiExec] Could not execute _ERR method, %s\n",
417             AcpiFormatException (Status));
418     }
419
420     /* Global override */
421
422     if (AcpiGbl_IgnoreErrors)
423     {
424         NewAmlStatus = AE_OK;
425     }
426
427     if (NewAmlStatus != AmlStatus)
428     {
429         AcpiOsPrintf ("[AcpiExec] Exception override, new status %s\n",
430             AcpiFormatException (NewAmlStatus));
431     }
432
433     return (NewAmlStatus);
434 }
435
436
437 /******************************************************************************
438  *
439  * FUNCTION:    AeTableHandler
440  *
441  * PARAMETERS:  Table handler
442  *
443  * RETURN:      Status
444  *
445  * DESCRIPTION: System table handler for AcpiExec utility.
446  *
447  *****************************************************************************/
448
449 static char                *TableEvents[] =
450 {
451     "LOAD",
452     "UNLOAD",
453     "UNKNOWN"
454 };
455
456 static ACPI_STATUS
457 AeTableHandler (
458     UINT32                  Event,
459     void                    *Table,
460     void                    *Context)
461 {
462     ACPI_STATUS             Status;
463
464
465     if (Event > ACPI_NUM_TABLE_EVENTS)
466     {
467         Event = ACPI_NUM_TABLE_EVENTS;
468     }
469
470     /* Enable any GPEs associated with newly-loaded GPE methods */
471
472     Status = AcpiUpdateAllGpes ();
473     AE_CHECK_OK (AcpiUpdateAllGpes, Status);
474
475     printf ("[AcpiExec] Table Event %s, [%4.4s] %p\n",
476         TableEvents[Event], ((ACPI_TABLE_HEADER *) Table)->Signature, Table);
477     return (AE_OK);
478 }
479
480
481 /******************************************************************************
482  *
483  * FUNCTION:    AeGpeHandler
484  *
485  * DESCRIPTION: Common GPE handler for acpiexec
486  *
487  *****************************************************************************/
488
489 UINT32
490 AeGpeHandler (
491     ACPI_HANDLE             GpeDevice,
492     UINT32                  GpeNumber,
493     void                    *Context)
494 {
495     ACPI_NAMESPACE_NODE     *DeviceNode = (ACPI_NAMESPACE_NODE *) GpeDevice;
496
497
498     AcpiOsPrintf ("[AcpiExec] GPE Handler received GPE%02X (GPE block %4.4s)\n",
499         GpeNumber, GpeDevice ? DeviceNode->Name.Ascii : "FADT");
500
501     return (ACPI_REENABLE_GPE);
502 }
503
504
505 /******************************************************************************
506  *
507  * FUNCTION:    AeGlobalEventHandler
508  *
509  * DESCRIPTION: Global GPE/Fixed event handler
510  *
511  *****************************************************************************/
512
513 void
514 AeGlobalEventHandler (
515     UINT32                  Type,
516     ACPI_HANDLE             Device,
517     UINT32                  EventNumber,
518     void                    *Context)
519 {
520     char                    *TypeName;
521
522
523     switch (Type)
524     {
525     case ACPI_EVENT_TYPE_GPE:
526         TypeName = "GPE";
527         break;
528
529     case ACPI_EVENT_TYPE_FIXED:
530         TypeName = "FixedEvent";
531         break;
532
533     default:
534         TypeName = "UNKNOWN";
535         break;
536     }
537
538     AcpiOsPrintf ("[AcpiExec] Global Event Handler received: Type %s Number %.2X Dev %p\n",
539         TypeName, EventNumber, Device);
540 }
541
542
543 /******************************************************************************
544  *
545  * FUNCTION:    AeAttachedDataHandler
546  *
547  * DESCRIPTION: Handler for deletion of nodes with attached data (attached via
548  *              AcpiAttachData)
549  *
550  *****************************************************************************/
551
552 static void
553 AeAttachedDataHandler (
554     ACPI_HANDLE             Object,
555     void                    *Data)
556 {
557     ACPI_NAMESPACE_NODE     *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Data);
558
559
560     AcpiOsPrintf ("Received an attached data deletion on %4.4s\n",
561         Node->Name.Ascii);
562 }
563
564
565 /******************************************************************************
566  *
567  * FUNCTION:    AeInterfaceHandler
568  *
569  * DESCRIPTION: Handler for _OSI invocations
570  *
571  *****************************************************************************/
572
573 static UINT32
574 AeInterfaceHandler (
575     ACPI_STRING             InterfaceName,
576     UINT32                  Supported)
577 {
578     ACPI_FUNCTION_NAME (AeInterfaceHandler);
579
580
581     ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
582         "Received _OSI (\"%s\"), is %ssupported\n",
583         InterfaceName, Supported == 0 ? "not " : ""));
584
585     return (Supported);
586 }
587
588
589 /******************************************************************************
590  *
591  * FUNCTION:    AeEventHandler
592  *
593  * DESCRIPTION: Handler for Fixed Events
594  *
595  *****************************************************************************/
596
597 static UINT32
598 AeEventHandler (
599     void                    *Context)
600 {
601     return (0);
602 }
603
604
605 /******************************************************************************
606  *
607  * FUNCTION:    AeRegionInit
608  *
609  * PARAMETERS:  None
610  *
611  * RETURN:      Status
612  *
613  * DESCRIPTION: Opregion init function.
614  *
615  *****************************************************************************/
616
617 static ACPI_STATUS
618 AeRegionInit (
619     ACPI_HANDLE                 RegionHandle,
620     UINT32                      Function,
621     void                        *HandlerContext,
622     void                        **RegionContext)
623 {
624     /*
625      * Real simple, set the RegionContext to the RegionHandle
626      */
627     *RegionContext = RegionHandle;
628
629     return (AE_OK);
630 }
631
632
633 /******************************************************************************
634  *
635  * FUNCTION:    AeInstallLateHandlers
636  *
637  * PARAMETERS:  None
638  *
639  * RETURN:      Status
640  *
641  * DESCRIPTION: Install handlers for the AcpiExec utility.
642  *
643  *****************************************************************************/
644
645 ACPI_STATUS
646 AeInstallLateHandlers (
647     void)
648 {
649     ACPI_STATUS             Status;
650     UINT32                  i;
651
652
653     /* Install some fixed event handlers */
654
655     Status = AcpiInstallFixedEventHandler (ACPI_EVENT_GLOBAL, AeEventHandler, NULL);
656     AE_CHECK_OK (AcpiInstallFixedEventHandler, Status);
657
658     Status = AcpiInstallFixedEventHandler (ACPI_EVENT_RTC, AeEventHandler, NULL);
659     AE_CHECK_OK (AcpiInstallFixedEventHandler, Status);
660
661     /*
662      * Install handlers for some of the "device driver" address spaces
663      * such as EC, SMBus, etc.
664      */
665     for (i = 0; i < ACPI_ARRAY_LENGTH (SpaceIdList); i++)
666     {
667         /* Install handler at the root object */
668
669         Status = AcpiInstallAddressSpaceHandler (AcpiGbl_RootNode,
670                         SpaceIdList[i], AeRegionHandler, AeRegionInit, NULL);
671         if (ACPI_FAILURE (Status))
672         {
673             ACPI_EXCEPTION ((AE_INFO, Status,
674                 "Could not install an OpRegion handler for %s space(%u)",
675                 AcpiUtGetRegionName((UINT8) SpaceIdList[i]), SpaceIdList[i]));
676             return (Status);
677         }
678     }
679
680     return (AE_OK);
681 }
682
683
684 /******************************************************************************
685  *
686  * FUNCTION:    AeInstallEarlyHandlers
687  *
688  * PARAMETERS:  None
689  *
690  * RETURN:      Status
691  *
692  * DESCRIPTION: Install handlers for the AcpiExec utility.
693  *
694  * Notes:       Don't install handler for PCI_Config, we want to use the
695  *              default handler to exercise that code.
696  *
697  *****************************************************************************/
698
699 ACPI_STATUS
700 AeInstallEarlyHandlers (
701     void)
702 {
703     ACPI_STATUS             Status;
704     UINT32                  i;
705     ACPI_HANDLE             Handle;
706
707
708     ACPI_FUNCTION_ENTRY ();
709
710
711     Status = AcpiInstallInterfaceHandler (AeInterfaceHandler);
712     if (ACPI_FAILURE (Status))
713     {
714         printf ("Could not install interface handler, %s\n",
715             AcpiFormatException (Status));
716     }
717
718     Status = AcpiInstallTableHandler (AeTableHandler, NULL);
719     if (ACPI_FAILURE (Status))
720     {
721         printf ("Could not install table handler, %s\n",
722             AcpiFormatException (Status));
723     }
724
725     Status = AcpiInstallExceptionHandler (AeExceptionHandler);
726     if (ACPI_FAILURE (Status))
727     {
728         printf ("Could not install exception handler, %s\n",
729             AcpiFormatException (Status));
730     }
731
732     /* Install global notify handler */
733
734     Status = AcpiInstallNotifyHandler (ACPI_ROOT_OBJECT, ACPI_SYSTEM_NOTIFY,
735                                         AeNotifyHandler, NULL);
736     if (ACPI_FAILURE (Status))
737     {
738         printf ("Could not install a global notify handler, %s\n",
739             AcpiFormatException (Status));
740     }
741
742     Status = AcpiInstallNotifyHandler (ACPI_ROOT_OBJECT, ACPI_DEVICE_NOTIFY,
743                                         AeDeviceNotifyHandler, NULL);
744     if (ACPI_FAILURE (Status))
745     {
746         printf ("Could not install a global notify handler, %s\n",
747             AcpiFormatException (Status));
748     }
749
750     Status = AcpiGetHandle (NULL, "\\_SB", &Handle);
751     if (ACPI_SUCCESS (Status))
752     {
753         Status = AcpiInstallNotifyHandler (Handle, ACPI_SYSTEM_NOTIFY,
754                                             AeNotifyHandler, NULL);
755         if (ACPI_FAILURE (Status))
756         {
757             printf ("Could not install a notify handler, %s\n",
758                 AcpiFormatException (Status));
759         }
760
761         Status = AcpiRemoveNotifyHandler (Handle, ACPI_SYSTEM_NOTIFY,
762                                             AeNotifyHandler);
763         if (ACPI_FAILURE (Status))
764         {
765             printf ("Could not remove a notify handler, %s\n",
766                 AcpiFormatException (Status));
767         }
768
769         Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY,
770                                             AeNotifyHandler, NULL);
771         AE_CHECK_OK (AcpiInstallNotifyHandler, Status);
772
773         Status = AcpiRemoveNotifyHandler (Handle, ACPI_ALL_NOTIFY,
774                                             AeNotifyHandler);
775         AE_CHECK_OK (AcpiRemoveNotifyHandler, Status);
776
777         Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY,
778                                             AeNotifyHandler, NULL);
779         if (ACPI_FAILURE (Status))
780         {
781             printf ("Could not install a notify handler, %s\n",
782                 AcpiFormatException (Status));
783         }
784
785         Status = AcpiAttachData (Handle, AeAttachedDataHandler, Handle);
786         AE_CHECK_OK (AcpiAttachData, Status);
787
788         Status = AcpiDetachData (Handle, AeAttachedDataHandler);
789         AE_CHECK_OK (AcpiDetachData, Status);
790
791         Status = AcpiAttachData (Handle, AeAttachedDataHandler, Handle);
792         AE_CHECK_OK (AcpiAttachData, Status);
793     }
794     else
795     {
796         printf ("No _SB_ found, %s\n", AcpiFormatException (Status));
797     }
798
799
800     /*
801      * Install handlers that will override the default handlers for some of
802      * the space IDs.
803      */
804     for (i = 0; i < ACPI_ARRAY_LENGTH (DefaultSpaceIdList); i++)
805     {
806         /* Install handler at the root object */
807
808         Status = AcpiInstallAddressSpaceHandler (AcpiGbl_RootNode,
809                     DefaultSpaceIdList[i], AeRegionHandler,
810                     AeRegionInit, NULL);
811         if (ACPI_FAILURE (Status))
812         {
813             ACPI_EXCEPTION ((AE_INFO, Status,
814                 "Could not install a default OpRegion handler for %s space(%u)",
815                 AcpiUtGetRegionName ((UINT8) DefaultSpaceIdList[i]),
816                 DefaultSpaceIdList[i]));
817             return (Status);
818         }
819     }
820
821     /*
822      * Initialize the global Region Handler space
823      * MCW 3/23/00
824      */
825     AeRegions.NumberOfRegions = 0;
826     AeRegions.RegionList = NULL;
827     return (Status);
828 }
829
830
831 /******************************************************************************
832  *
833  * FUNCTION:    AeRegionHandler
834  *
835  * PARAMETERS:  Standard region handler parameters
836  *
837  * RETURN:      Status
838  *
839  * DESCRIPTION: Test handler - Handles some dummy regions via memory that can
840  *              be manipulated in Ring 3. Simulates actual reads and writes.
841  *
842  *****************************************************************************/
843
844 ACPI_STATUS
845 AeRegionHandler (
846     UINT32                  Function,
847     ACPI_PHYSICAL_ADDRESS   Address,
848     UINT32                  BitWidth,
849     UINT64                  *Value,
850     void                    *HandlerContext,
851     void                    *RegionContext)
852 {
853
854     ACPI_OPERAND_OBJECT     *RegionObject = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, RegionContext);
855     UINT8                   *Buffer = ACPI_CAST_PTR (UINT8, Value);
856     ACPI_PHYSICAL_ADDRESS   BaseAddress;
857     ACPI_SIZE               Length;
858     BOOLEAN                 BufferExists;
859     AE_REGION               *RegionElement;
860     void                    *BufferValue;
861     ACPI_STATUS             Status;
862     UINT32                  ByteWidth;
863     UINT32                  i;
864     UINT8                   SpaceId;
865
866
867     ACPI_FUNCTION_NAME (AeRegionHandler);
868
869     /*
870      * If the object is not a region, simply return
871      */
872     if (RegionObject->Region.Type != ACPI_TYPE_REGION)
873     {
874         return (AE_OK);
875     }
876
877     /*
878      * Region support can be disabled with the -r option.
879      * We use this to support dynamically loaded tables where we pass a valid
880      * address to the AML.
881      */
882     if (AcpiGbl_DbOpt_NoRegionSupport)
883     {
884         BufferValue = ACPI_TO_POINTER (Address);
885         ByteWidth = (BitWidth / 8);
886
887         if (BitWidth % 8)
888         {
889             ByteWidth += 1;
890         }
891         goto DoFunction;
892     }
893
894     /*
895      * Find the region's address space and length before searching
896      * the linked list.
897      */
898     BaseAddress = RegionObject->Region.Address;
899     Length = (ACPI_SIZE) RegionObject->Region.Length;
900     SpaceId = RegionObject->Region.SpaceId;
901
902     ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, "Operation Region request on %s at 0x%X\n",
903             AcpiUtGetRegionName (RegionObject->Region.SpaceId),
904             (UINT32) Address));
905
906     switch (SpaceId)
907     {
908     case ACPI_ADR_SPACE_SYSTEM_IO:
909         /*
910          * For I/O space, exercise the port validation
911          */
912         switch (Function & ACPI_IO_MASK)
913         {
914         case ACPI_READ:
915             Status = AcpiHwReadPort (Address, (UINT32 *) Value, BitWidth);
916             AE_CHECK_OK (AcpiHwReadPort, Status);
917             break;
918
919         case ACPI_WRITE:
920             Status = AcpiHwWritePort (Address, (UINT32) *Value, BitWidth);
921             AE_CHECK_OK (AcpiHwWritePort, Status);
922             break;
923
924         default:
925             Status = AE_BAD_PARAMETER;
926             break;
927         }
928
929         if (ACPI_FAILURE (Status))
930         {
931             return (Status);
932         }
933
934         /* Now go ahead and simulate the hardware */
935         break;
936
937
938     case ACPI_ADR_SPACE_SMBUS:
939
940         Length = 0;
941
942         switch (Function & ACPI_IO_MASK)
943         {
944         case ACPI_READ:
945             switch (Function >> 16)
946             {
947             case AML_FIELD_ATTRIB_SMB_QUICK:
948             case AML_FIELD_ATTRIB_SMB_SEND_RCV:
949             case AML_FIELD_ATTRIB_SMB_BYTE:
950                 Length = 1;
951                 break;
952
953             case AML_FIELD_ATTRIB_SMB_WORD:
954             case AML_FIELD_ATTRIB_SMB_WORD_CALL:
955                 Length = 2;
956                 break;
957
958             case AML_FIELD_ATTRIB_SMB_BLOCK:
959             case AML_FIELD_ATTRIB_SMB_BLOCK_CALL:
960                 Length = 32;
961                 break;
962
963             default:
964                 break;
965             }
966             break;
967
968         case ACPI_WRITE:
969             switch (Function >> 16)
970             {
971             case AML_FIELD_ATTRIB_SMB_QUICK:
972             case AML_FIELD_ATTRIB_SMB_SEND_RCV:
973             case AML_FIELD_ATTRIB_SMB_BYTE:
974             case AML_FIELD_ATTRIB_SMB_WORD:
975             case AML_FIELD_ATTRIB_SMB_BLOCK:
976                 Length = 0;
977                 break;
978
979             case AML_FIELD_ATTRIB_SMB_WORD_CALL:
980                 Length = 2;
981                 break;
982
983             case AML_FIELD_ATTRIB_SMB_BLOCK_CALL:
984                 Length = 32;
985                 break;
986
987             default:
988                 break;
989             }
990             break;
991
992         default:
993             break;
994         }
995
996         for (i = 0; i < Length; i++)
997         {
998             Buffer[i+2] = (UINT8) (0xA0 + i);
999         }
1000
1001         Buffer[0] = 0x7A;
1002         Buffer[1] = (UINT8) Length;
1003         return (AE_OK);
1004
1005
1006     case ACPI_ADR_SPACE_IPMI: /* ACPI 4.0 */
1007
1008         AcpiOsPrintf ("AcpiExec: Received IPMI request: "
1009             "Address %X BaseAddress %X Length %X Width %X BufferLength %u\n",
1010             (UINT32) Address, (UINT32) BaseAddress,
1011             Length, BitWidth, Buffer[1]);
1012
1013         /*
1014          * Regardless of a READ or WRITE, this handler is passed a 66-byte
1015          * buffer in which to return the IPMI status/length/data.
1016          *
1017          * Return some example data to show use of the bidirectional buffer
1018          */
1019         Buffer[0] = 0;       /* Status byte */
1020         Buffer[1] = 64;      /* Return buffer data length */
1021         Buffer[2] = 0;       /* Completion code */
1022         Buffer[3] = 0x34;    /* Power measurement */
1023         Buffer[4] = 0x12;    /* Power measurement */
1024         Buffer[65] = 0xEE;   /* last buffer byte */
1025         return (AE_OK);
1026
1027     default:
1028         break;
1029     }
1030
1031     /*
1032      * Search through the linked list for this region's buffer
1033      */
1034     BufferExists = FALSE;
1035     RegionElement = AeRegions.RegionList;
1036
1037     if (AeRegions.NumberOfRegions)
1038     {
1039         while (!BufferExists && RegionElement)
1040         {
1041             if (RegionElement->Address == BaseAddress &&
1042                 RegionElement->Length == Length &&
1043                 RegionElement->SpaceId == SpaceId)
1044             {
1045                 BufferExists = TRUE;
1046             }
1047             else
1048             {
1049                 RegionElement = RegionElement->NextRegion;
1050             }
1051         }
1052     }
1053
1054     /*
1055      * If the Region buffer does not exist, create it now
1056      */
1057     if (!BufferExists)
1058     {
1059         /*
1060          * Do the memory allocations first
1061          */
1062         RegionElement = AcpiOsAllocate (sizeof (AE_REGION));
1063         if (!RegionElement)
1064         {
1065             return (AE_NO_MEMORY);
1066         }
1067
1068         RegionElement->Buffer = AcpiOsAllocate (Length);
1069         if (!RegionElement->Buffer)
1070         {
1071             AcpiOsFree (RegionElement);
1072             return (AE_NO_MEMORY);
1073         }
1074
1075         /* Initialize the region with the default fill value */
1076
1077         ACPI_MEMSET (RegionElement->Buffer, AcpiGbl_RegionFillValue, Length);
1078
1079         RegionElement->Address      = BaseAddress;
1080         RegionElement->Length       = Length;
1081         RegionElement->SpaceId      = SpaceId;
1082         RegionElement->NextRegion   = NULL;
1083
1084         /*
1085          * Increment the number of regions and put this one
1086          *  at the head of the list as it will probably get accessed
1087          *  more often anyway.
1088          */
1089         AeRegions.NumberOfRegions += 1;
1090
1091         if (AeRegions.RegionList)
1092         {
1093             RegionElement->NextRegion = AeRegions.RegionList;
1094         }
1095
1096         AeRegions.RegionList = RegionElement;
1097     }
1098
1099     /*
1100      * Calculate the size of the memory copy
1101      */
1102     ByteWidth = (BitWidth / 8);
1103
1104     if (BitWidth % 8)
1105     {
1106         ByteWidth += 1;
1107     }
1108
1109     /*
1110      * The buffer exists and is pointed to by RegionElement.
1111      * We now need to verify the request is valid and perform the operation.
1112      *
1113      * NOTE: RegionElement->Length is in bytes, therefore it we compare against
1114      * ByteWidth (see above)
1115      */
1116     if (((UINT64) Address + ByteWidth) >
1117         ((UINT64)(RegionElement->Address) + RegionElement->Length))
1118     {
1119         ACPI_WARNING ((AE_INFO,
1120             "Request on [%4.4s] is beyond region limit Req-0x%X+0x%X, Base=0x%X, Len-0x%X",
1121             (RegionObject->Region.Node)->Name.Ascii, (UINT32) Address,
1122             ByteWidth, (UINT32)(RegionElement->Address),
1123             RegionElement->Length));
1124
1125         return (AE_AML_REGION_LIMIT);
1126     }
1127
1128     /*
1129      * Get BufferValue to point to the "address" in the buffer
1130      */
1131     BufferValue = ((UINT8 *) RegionElement->Buffer +
1132                     ((UINT64) Address - (UINT64) RegionElement->Address));
1133
1134 DoFunction:
1135
1136     /*
1137      * Perform a read or write to the buffer space
1138      */
1139     switch (Function)
1140     {
1141     case ACPI_READ:
1142         /*
1143          * Set the pointer Value to whatever is in the buffer
1144          */
1145         ACPI_MEMCPY (Value, BufferValue, ByteWidth);
1146         break;
1147
1148     case ACPI_WRITE:
1149         /*
1150          * Write the contents of Value to the buffer
1151          */
1152         ACPI_MEMCPY (BufferValue, Value, ByteWidth);
1153         break;
1154
1155     default:
1156         return (AE_BAD_PARAMETER);
1157     }
1158
1159     return (AE_OK);
1160 }
1161
1162