aehandlers.c revision 1.1.1.4 1 /******************************************************************************
2 *
3 * Module Name: aehandlers - Various handlers for acpiexec
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 #include "aecommon.h"
45
46 #define _COMPONENT ACPI_TOOLS
47 ACPI_MODULE_NAME ("aehandlers")
48
49 /* Local prototypes */
50
51 static void
52 AeNotifyHandler1 (
53 ACPI_HANDLE Device,
54 UINT32 Value,
55 void *Context);
56
57 static void
58 AeNotifyHandler2 (
59 ACPI_HANDLE Device,
60 UINT32 Value,
61 void *Context);
62
63 static void
64 AeCommonNotifyHandler (
65 ACPI_HANDLE Device,
66 UINT32 Value,
67 UINT32 HandlerId);
68
69 static void
70 AeDeviceNotifyHandler (
71 ACPI_HANDLE Device,
72 UINT32 Value,
73 void *Context);
74
75 static ACPI_STATUS
76 AeExceptionHandler (
77 ACPI_STATUS AmlStatus,
78 ACPI_NAME Name,
79 UINT16 Opcode,
80 UINT32 AmlOffset,
81 void *Context);
82
83 static ACPI_STATUS
84 AeTableHandler (
85 UINT32 Event,
86 void *Table,
87 void *Context);
88
89 static ACPI_STATUS
90 AeRegionInit (
91 ACPI_HANDLE RegionHandle,
92 UINT32 Function,
93 void *HandlerContext,
94 void **RegionContext);
95
96 static void
97 AeAttachedDataHandler (
98 ACPI_HANDLE Object,
99 void *Data);
100
101 static void
102 AeAttachedDataHandler2 (
103 ACPI_HANDLE Object,
104 void *Data);
105
106 static UINT32
107 AeInterfaceHandler (
108 ACPI_STRING InterfaceName,
109 UINT32 Supported);
110
111 static ACPI_STATUS
112 AeInstallEcHandler (
113 ACPI_HANDLE ObjHandle,
114 UINT32 Level,
115 void *Context,
116 void **ReturnValue);
117
118 static ACPI_STATUS
119 AeInstallPciHandler (
120 ACPI_HANDLE ObjHandle,
121 UINT32 Level,
122 void *Context,
123 void **ReturnValue);
124
125 static ACPI_STATUS
126 AeInstallDeviceHandlers (
127 void);
128
129 #if (!ACPI_REDUCED_HARDWARE)
130 static UINT32
131 AeEventHandler (
132 void *Context);
133
134 static UINT32
135 AeSciHandler (
136 void *Context);
137
138 static char *TableEvents[] =
139 {
140 "LOAD",
141 "UNLOAD",
142 "UNKNOWN"
143 };
144 #endif /* !ACPI_REDUCED_HARDWARE */
145
146
147 static UINT32 SigintCount = 0;
148 static AE_DEBUG_REGIONS AeRegions;
149 BOOLEAN AcpiGbl_DisplayRegionAccess = FALSE;
150
151 /*
152 * We will override some of the default region handlers, especially the
153 * SystemMemory handler, which must be implemented locally. Do not override
154 * the PCI_Config handler since we would like to exercise the default handler
155 * code. These handlers are installed "early" - before any _REG methods
156 * are executed - since they are special in the sense that the ACPI spec
157 * declares that they must "always be available". Cannot override the
158 * DataTable region handler either -- needed for test execution.
159 */
160 static ACPI_ADR_SPACE_TYPE DefaultSpaceIdList[] =
161 {
162 ACPI_ADR_SPACE_SYSTEM_MEMORY,
163 ACPI_ADR_SPACE_SYSTEM_IO
164 };
165
166 /*
167 * We will install handlers for some of the various address space IDs.
168 * Test one user-defined address space (used by aslts).
169 */
170 #define ACPI_ADR_SPACE_USER_DEFINED1 0x80
171 #define ACPI_ADR_SPACE_USER_DEFINED2 0xE4
172
173 static ACPI_ADR_SPACE_TYPE SpaceIdList[] =
174 {
175 ACPI_ADR_SPACE_SMBUS,
176 ACPI_ADR_SPACE_CMOS,
177 ACPI_ADR_SPACE_PCI_BAR_TARGET,
178 ACPI_ADR_SPACE_IPMI,
179 ACPI_ADR_SPACE_GPIO,
180 ACPI_ADR_SPACE_GSBUS,
181 ACPI_ADR_SPACE_FIXED_HARDWARE,
182 ACPI_ADR_SPACE_USER_DEFINED1,
183 ACPI_ADR_SPACE_USER_DEFINED2
184 };
185
186 static ACPI_CONNECTION_INFO AeMyContext;
187
188
189 /******************************************************************************
190 *
191 * FUNCTION: AeCtrlCHandler
192 *
193 * PARAMETERS: Sig
194 *
195 * RETURN: none
196 *
197 * DESCRIPTION: Control-C handler. Abort running control method if any.
198 *
199 *****************************************************************************/
200
201 void ACPI_SYSTEM_XFACE
202 AeCtrlCHandler (
203 int Sig)
204 {
205
206 signal (SIGINT, SIG_IGN);
207 SigintCount++;
208
209 AcpiOsPrintf ("Caught a ctrl-c (#%u)\n\n", SigintCount);
210
211 if (AcpiGbl_MethodExecuting)
212 {
213 AcpiGbl_AbortMethod = TRUE;
214 signal (SIGINT, AeCtrlCHandler);
215
216 if (SigintCount < 10)
217 {
218 return;
219 }
220 }
221
222 (void) AcpiOsTerminate ();
223 exit (0);
224 }
225
226
227 /******************************************************************************
228 *
229 * FUNCTION: AeNotifyHandler(s)
230 *
231 * PARAMETERS: Standard notify handler parameters
232 *
233 * RETURN: Status
234 *
235 * DESCRIPTION: Notify handlers for AcpiExec utility. Used by the ASL
236 * test suite(s) to communicate errors and other information to
237 * this utility via the Notify() operator. Tests notify handling
238 * and multiple notify handler support.
239 *
240 *****************************************************************************/
241
242 static void
243 AeNotifyHandler1 (
244 ACPI_HANDLE Device,
245 UINT32 Value,
246 void *Context)
247 {
248 AeCommonNotifyHandler (Device, Value, 1);
249 }
250
251 static void
252 AeNotifyHandler2 (
253 ACPI_HANDLE Device,
254 UINT32 Value,
255 void *Context)
256 {
257 AeCommonNotifyHandler (Device, Value, 2);
258 }
259
260 static void
261 AeCommonNotifyHandler (
262 ACPI_HANDLE Device,
263 UINT32 Value,
264 UINT32 HandlerId)
265 {
266 char *Type;
267
268
269 Type = "Device";
270 if (Value <= ACPI_MAX_SYS_NOTIFY)
271 {
272 Type = "System";
273 }
274
275 switch (Value)
276 {
277 #if 0
278 case 0:
279
280 printf ("[AcpiExec] Method Error 0x%X: Results not equal\n", Value);
281 if (AcpiGbl_DebugFile)
282 {
283 AcpiOsPrintf ("[AcpiExec] Method Error: Results not equal\n");
284 }
285 break;
286
287 case 1:
288
289 printf ("[AcpiExec] Method Error: Incorrect numeric result\n");
290 if (AcpiGbl_DebugFile)
291 {
292 AcpiOsPrintf ("[AcpiExec] Method Error: Incorrect numeric result\n");
293 }
294 break;
295
296 case 2:
297
298 printf ("[AcpiExec] Method Error: An operand was overwritten\n");
299 if (AcpiGbl_DebugFile)
300 {
301 AcpiOsPrintf ("[AcpiExec] Method Error: An operand was overwritten\n");
302 }
303 break;
304
305 #endif
306
307 default:
308
309 printf ("[AcpiExec] Handler %u: Received a %s Notify on [%4.4s] %p Value 0x%2.2X (%s)\n",
310 HandlerId, Type, AcpiUtGetNodeName (Device), Device, Value,
311 AcpiUtGetNotifyName (Value));
312 if (AcpiGbl_DebugFile)
313 {
314 AcpiOsPrintf ("[AcpiExec] Handler %u: Received a %s notify, Value 0x%2.2X\n",
315 HandlerId, Type, Value);
316 }
317
318 (void) AcpiEvaluateObject (Device, "_NOT", NULL, NULL);
319 break;
320 }
321 }
322
323
324 /******************************************************************************
325 *
326 * FUNCTION: AeSystemNotifyHandler
327 *
328 * PARAMETERS: Standard notify handler parameters
329 *
330 * RETURN: Status
331 *
332 * DESCRIPTION: System notify handler for AcpiExec utility. Used by the ASL
333 * test suite(s) to communicate errors and other information to
334 * this utility via the Notify() operator.
335 *
336 *****************************************************************************/
337
338 static void
339 AeSystemNotifyHandler (
340 ACPI_HANDLE Device,
341 UINT32 Value,
342 void *Context)
343 {
344
345 printf ("[AcpiExec] Global: Received a System Notify on [%4.4s] %p Value 0x%2.2X (%s)\n",
346 AcpiUtGetNodeName (Device), Device, Value,
347 AcpiUtGetNotifyName (Value));
348 if (AcpiGbl_DebugFile)
349 {
350 AcpiOsPrintf ("[AcpiExec] Global: Received a System Notify, Value 0x%2.2X\n", Value);
351 }
352
353 (void) AcpiEvaluateObject (Device, "_NOT", NULL, NULL);
354 }
355
356
357 /******************************************************************************
358 *
359 * FUNCTION: AeDeviceNotifyHandler
360 *
361 * PARAMETERS: Standard notify handler parameters
362 *
363 * RETURN: Status
364 *
365 * DESCRIPTION: Device notify handler for AcpiExec utility. Used by the ASL
366 * test suite(s) to communicate errors and other information to
367 * this utility via the Notify() operator.
368 *
369 *****************************************************************************/
370
371 static void
372 AeDeviceNotifyHandler (
373 ACPI_HANDLE Device,
374 UINT32 Value,
375 void *Context)
376 {
377
378 printf ("[AcpiExec] Global: Received a Device Notify on [%4.4s] %p Value 0x%2.2X (%s)\n",
379 AcpiUtGetNodeName (Device), Device, Value,
380 AcpiUtGetNotifyName (Value));
381 if (AcpiGbl_DebugFile)
382 {
383 AcpiOsPrintf ("[AcpiExec] Global: Received a Device Notify, Value 0x%2.2X\n", Value);
384 }
385
386 (void) AcpiEvaluateObject (Device, "_NOT", NULL, NULL);
387 }
388
389
390 /******************************************************************************
391 *
392 * FUNCTION: AeExceptionHandler
393 *
394 * PARAMETERS: Standard exception handler parameters
395 *
396 * RETURN: Status
397 *
398 * DESCRIPTION: System exception handler for AcpiExec utility.
399 *
400 *****************************************************************************/
401
402 static ACPI_STATUS
403 AeExceptionHandler (
404 ACPI_STATUS AmlStatus,
405 ACPI_NAME Name,
406 UINT16 Opcode,
407 UINT32 AmlOffset,
408 void *Context)
409 {
410 ACPI_STATUS NewAmlStatus = AmlStatus;
411 ACPI_STATUS Status;
412 ACPI_BUFFER ReturnObj;
413 ACPI_OBJECT_LIST ArgList;
414 ACPI_OBJECT Arg[3];
415 const char *Exception;
416
417
418 Exception = AcpiFormatException (AmlStatus);
419 AcpiOsPrintf ("[AcpiExec] Exception %s during execution ", Exception);
420 if (Name)
421 {
422 AcpiOsPrintf ("of method [%4.4s]", (char *) &Name);
423 }
424 else
425 {
426 AcpiOsPrintf ("at module level (table load)");
427 }
428 AcpiOsPrintf (" Opcode [%s] @%X\n", AcpiPsGetOpcodeName (Opcode), AmlOffset);
429
430 /*
431 * Invoke the _ERR method if present
432 *
433 * Setup parameter object
434 */
435 ArgList.Count = 3;
436 ArgList.Pointer = Arg;
437
438 Arg[0].Type = ACPI_TYPE_INTEGER;
439 Arg[0].Integer.Value = AmlStatus;
440
441 Arg[1].Type = ACPI_TYPE_STRING;
442 Arg[1].String.Pointer = ACPI_CAST_PTR (char, Exception);
443 Arg[1].String.Length = ACPI_STRLEN (Exception);
444
445 Arg[2].Type = ACPI_TYPE_INTEGER;
446 Arg[2].Integer.Value = AcpiOsGetThreadId();
447
448 /* Setup return buffer */
449
450 ReturnObj.Pointer = NULL;
451 ReturnObj.Length = ACPI_ALLOCATE_BUFFER;
452
453 Status = AcpiEvaluateObject (NULL, "\\_ERR", &ArgList, &ReturnObj);
454 if (ACPI_SUCCESS (Status))
455 {
456 if (ReturnObj.Pointer)
457 {
458 /* Override original status */
459
460 NewAmlStatus = (ACPI_STATUS)
461 ((ACPI_OBJECT *) ReturnObj.Pointer)->Integer.Value;
462
463 /* Free a buffer created via ACPI_ALLOCATE_BUFFER */
464
465 AcpiOsFree (ReturnObj.Pointer);
466 }
467 }
468 else if (Status != AE_NOT_FOUND)
469 {
470 AcpiOsPrintf ("[AcpiExec] Could not execute _ERR method, %s\n",
471 AcpiFormatException (Status));
472 }
473
474 /* Global override */
475
476 if (AcpiGbl_IgnoreErrors)
477 {
478 NewAmlStatus = AE_OK;
479 }
480
481 if (NewAmlStatus != AmlStatus)
482 {
483 AcpiOsPrintf ("[AcpiExec] Exception override, new status %s\n",
484 AcpiFormatException (NewAmlStatus));
485 }
486
487 return (NewAmlStatus);
488 }
489
490
491 /******************************************************************************
492 *
493 * FUNCTION: AeTableHandler
494 *
495 * PARAMETERS: Table handler
496 *
497 * RETURN: Status
498 *
499 * DESCRIPTION: System table handler for AcpiExec utility.
500 *
501 *****************************************************************************/
502
503 static ACPI_STATUS
504 AeTableHandler (
505 UINT32 Event,
506 void *Table,
507 void *Context)
508 {
509 #if (!ACPI_REDUCED_HARDWARE)
510 ACPI_STATUS Status;
511 #endif /* !ACPI_REDUCED_HARDWARE */
512
513
514 if (Event > ACPI_NUM_TABLE_EVENTS)
515 {
516 Event = ACPI_NUM_TABLE_EVENTS;
517 }
518
519 #if (!ACPI_REDUCED_HARDWARE)
520 /* Enable any GPEs associated with newly-loaded GPE methods */
521
522 Status = AcpiUpdateAllGpes ();
523 AE_CHECK_OK (AcpiUpdateAllGpes, Status);
524
525 printf ("[AcpiExec] Table Event %s, [%4.4s] %p\n",
526 TableEvents[Event], ((ACPI_TABLE_HEADER *) Table)->Signature, Table);
527 #endif /* !ACPI_REDUCED_HARDWARE */
528
529 return (AE_OK);
530 }
531
532
533 /******************************************************************************
534 *
535 * FUNCTION: AeGpeHandler
536 *
537 * DESCRIPTION: Common GPE handler for acpiexec
538 *
539 *****************************************************************************/
540
541 UINT32
542 AeGpeHandler (
543 ACPI_HANDLE GpeDevice,
544 UINT32 GpeNumber,
545 void *Context)
546 {
547 ACPI_NAMESPACE_NODE *DeviceNode = (ACPI_NAMESPACE_NODE *) GpeDevice;
548
549
550 AcpiOsPrintf ("[AcpiExec] GPE Handler received GPE%02X (GPE block %4.4s)\n",
551 GpeNumber, GpeDevice ? DeviceNode->Name.Ascii : "FADT");
552
553 return (ACPI_REENABLE_GPE);
554 }
555
556
557 /******************************************************************************
558 *
559 * FUNCTION: AeGlobalEventHandler
560 *
561 * DESCRIPTION: Global GPE/Fixed event handler
562 *
563 *****************************************************************************/
564
565 void
566 AeGlobalEventHandler (
567 UINT32 Type,
568 ACPI_HANDLE Device,
569 UINT32 EventNumber,
570 void *Context)
571 {
572 char *TypeName;
573
574
575 switch (Type)
576 {
577 case ACPI_EVENT_TYPE_GPE:
578
579 TypeName = "GPE";
580 break;
581
582 case ACPI_EVENT_TYPE_FIXED:
583
584 TypeName = "FixedEvent";
585 break;
586
587 default:
588
589 TypeName = "UNKNOWN";
590 break;
591 }
592
593 AcpiOsPrintf ("[AcpiExec] Global Event Handler received: Type %s Number %.2X Dev %p\n",
594 TypeName, EventNumber, Device);
595 }
596
597
598 /******************************************************************************
599 *
600 * FUNCTION: AeAttachedDataHandler
601 *
602 * DESCRIPTION: Handler for deletion of nodes with attached data (attached via
603 * AcpiAttachData)
604 *
605 *****************************************************************************/
606
607 static void
608 AeAttachedDataHandler (
609 ACPI_HANDLE Object,
610 void *Data)
611 {
612 ACPI_NAMESPACE_NODE *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Data);
613
614
615 AcpiOsPrintf ("Received an attached data deletion (1) on %4.4s\n",
616 Node->Name.Ascii);
617 }
618
619
620 /******************************************************************************
621 *
622 * FUNCTION: AeAttachedDataHandler2
623 *
624 * DESCRIPTION: Handler for deletion of nodes with attached data (attached via
625 * AcpiAttachData)
626 *
627 *****************************************************************************/
628
629 static void
630 AeAttachedDataHandler2 (
631 ACPI_HANDLE Object,
632 void *Data)
633 {
634 ACPI_NAMESPACE_NODE *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Data);
635
636
637 AcpiOsPrintf ("Received an attached data deletion (2) on %4.4s\n",
638 Node->Name.Ascii);
639 }
640
641
642 /******************************************************************************
643 *
644 * FUNCTION: AeInterfaceHandler
645 *
646 * DESCRIPTION: Handler for _OSI invocations
647 *
648 *****************************************************************************/
649
650 static UINT32
651 AeInterfaceHandler (
652 ACPI_STRING InterfaceName,
653 UINT32 Supported)
654 {
655 ACPI_FUNCTION_NAME (AeInterfaceHandler);
656
657
658 ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
659 "Received _OSI (\"%s\"), is %ssupported\n",
660 InterfaceName, Supported == 0 ? "not " : ""));
661
662 return (Supported);
663 }
664
665
666 #if (!ACPI_REDUCED_HARDWARE)
667 /******************************************************************************
668 *
669 * FUNCTION: AeEventHandler, AeSciHandler
670 *
671 * DESCRIPTION: Handler for Fixed Events and SCIs
672 *
673 *****************************************************************************/
674
675 static UINT32
676 AeEventHandler (
677 void *Context)
678 {
679 return (0);
680 }
681
682 static UINT32
683 AeSciHandler (
684 void *Context)
685 {
686
687 AcpiOsPrintf ("[AcpiExec] Received an SCI at handler\n");
688 return (0);
689 }
690
691 #endif /* !ACPI_REDUCED_HARDWARE */
692
693
694 /******************************************************************************
695 *
696 * FUNCTION: AeRegionInit
697 *
698 * PARAMETERS: None
699 *
700 * RETURN: Status
701 *
702 * DESCRIPTION: Opregion init function.
703 *
704 *****************************************************************************/
705
706 static ACPI_STATUS
707 AeRegionInit (
708 ACPI_HANDLE RegionHandle,
709 UINT32 Function,
710 void *HandlerContext,
711 void **RegionContext)
712 {
713
714 if (Function == ACPI_REGION_DEACTIVATE)
715 {
716 *RegionContext = NULL;
717 }
718 else
719 {
720 *RegionContext = RegionHandle;
721 }
722
723 return (AE_OK);
724 }
725
726
727 /*******************************************************************************
728 *
729 * FUNCTION: AeInstallSciHandler
730 *
731 * PARAMETERS: None
732 *
733 * RETURN: Status
734 *
735 * DESCRIPTION: Install handler for SCIs. Exercise the code by doing an
736 * install/remove/install.
737 *
738 ******************************************************************************/
739
740 static ACPI_STATUS
741 AeInstallSciHandler (
742 void)
743 {
744 ACPI_STATUS Status;
745
746
747 Status = AcpiInstallSciHandler (AeSciHandler, &AeMyContext);
748 if (ACPI_FAILURE (Status))
749 {
750 ACPI_EXCEPTION ((AE_INFO, Status,
751 "Could not install an SCI handler (1)"));
752 }
753
754 Status = AcpiRemoveSciHandler (AeSciHandler);
755 if (ACPI_FAILURE (Status))
756 {
757 ACPI_EXCEPTION ((AE_INFO, Status,
758 "Could not remove an SCI handler"));
759 }
760
761 Status = AcpiInstallSciHandler (AeSciHandler, &AeMyContext);
762 if (ACPI_FAILURE (Status))
763 {
764 ACPI_EXCEPTION ((AE_INFO, Status,
765 "Could not install an SCI handler (2)"));
766 }
767
768 return (Status);
769 }
770
771
772 /*******************************************************************************
773 *
774 * FUNCTION: AeInstallDeviceHandlers, AeInstallEcHandler,
775 * AeInstallPciHandler
776 *
777 * PARAMETERS: ACPI_WALK_NAMESPACE callback
778 *
779 * RETURN: Status
780 *
781 * DESCRIPTION: Walk entire namespace, install a handler for every EC
782 * and PCI device found.
783 *
784 ******************************************************************************/
785
786 static ACPI_STATUS
787 AeInstallEcHandler (
788 ACPI_HANDLE ObjHandle,
789 UINT32 Level,
790 void *Context,
791 void **ReturnValue)
792 {
793 ACPI_STATUS Status;
794
795
796 /* Install the handler for this EC device */
797
798 Status = AcpiInstallAddressSpaceHandler (ObjHandle, ACPI_ADR_SPACE_EC,
799 AeRegionHandler, AeRegionInit, &AeMyContext);
800 if (ACPI_FAILURE (Status))
801 {
802 ACPI_EXCEPTION ((AE_INFO, Status,
803 "Could not install an OpRegion handler for EC device (%p)",
804 ObjHandle));
805 }
806
807 return (Status);
808 }
809
810 static ACPI_STATUS
811 AeInstallPciHandler (
812 ACPI_HANDLE ObjHandle,
813 UINT32 Level,
814 void *Context,
815 void **ReturnValue)
816 {
817 ACPI_STATUS Status;
818
819
820 /* Install memory and I/O handlers for the PCI device */
821
822 Status = AcpiInstallAddressSpaceHandler (ObjHandle, ACPI_ADR_SPACE_SYSTEM_IO,
823 AeRegionHandler, AeRegionInit, &AeMyContext);
824 if (ACPI_FAILURE (Status))
825 {
826 ACPI_EXCEPTION ((AE_INFO, Status,
827 "Could not install an OpRegion handler for PCI device (%p)",
828 ObjHandle));
829 }
830
831 Status = AcpiInstallAddressSpaceHandler (ObjHandle, ACPI_ADR_SPACE_SYSTEM_MEMORY,
832 AeRegionHandler, AeRegionInit, &AeMyContext);
833 if (ACPI_FAILURE (Status))
834 {
835 ACPI_EXCEPTION ((AE_INFO, Status,
836 "Could not install an OpRegion handler for PCI device (%p)",
837 ObjHandle));
838 }
839
840 return (AE_CTRL_TERMINATE);
841 }
842
843 static ACPI_STATUS
844 AeInstallDeviceHandlers (
845 void)
846 {
847
848 /* Find all Embedded Controller devices */
849
850 AcpiGetDevices ("PNP0C09", AeInstallEcHandler, NULL, NULL);
851
852 /* Install a PCI handler */
853
854 AcpiGetDevices ("PNP0A08", AeInstallPciHandler, NULL, NULL);
855 return (AE_OK);
856 }
857
858
859 /******************************************************************************
860 *
861 * FUNCTION: AeInstallLateHandlers
862 *
863 * PARAMETERS: None
864 *
865 * RETURN: Status
866 *
867 * DESCRIPTION: Install handlers for the AcpiExec utility.
868 *
869 *****************************************************************************/
870
871 ACPI_STATUS
872 AeInstallLateHandlers (
873 void)
874 {
875 ACPI_STATUS Status;
876 UINT32 i;
877
878
879 #if (!ACPI_REDUCED_HARDWARE)
880 if (!AcpiGbl_ReducedHardware)
881 {
882 /* Install a user SCI handler */
883
884 Status = AeInstallSciHandler ();
885 AE_CHECK_OK (AeInstallSciHandler, Status);
886
887 /* Install some fixed event handlers */
888
889 Status = AcpiInstallFixedEventHandler (ACPI_EVENT_GLOBAL, AeEventHandler, NULL);
890 AE_CHECK_OK (AcpiInstallFixedEventHandler, Status);
891
892 Status = AcpiInstallFixedEventHandler (ACPI_EVENT_RTC, AeEventHandler, NULL);
893 AE_CHECK_OK (AcpiInstallFixedEventHandler, Status);
894 }
895 #endif /* !ACPI_REDUCED_HARDWARE */
896
897 AeMyContext.Connection = NULL;
898 AeMyContext.AccessLength = 0xA5;
899
900 /*
901 * We will install a handler for each EC device, directly under the EC
902 * device definition. This is unlike the other handlers which we install
903 * at the root node. Also install memory and I/O handlers at any PCI
904 * devices.
905 */
906 AeInstallDeviceHandlers ();
907
908 /*
909 * Install handlers for some of the "device driver" address spaces
910 * such as SMBus, etc.
911 */
912 for (i = 0; i < ACPI_ARRAY_LENGTH (SpaceIdList); i++)
913 {
914 /* Install handler at the root object */
915
916 Status = AcpiInstallAddressSpaceHandler (ACPI_ROOT_OBJECT,
917 SpaceIdList[i], AeRegionHandler,
918 AeRegionInit, &AeMyContext);
919 if (ACPI_FAILURE (Status))
920 {
921 ACPI_EXCEPTION ((AE_INFO, Status,
922 "Could not install an OpRegion handler for %s space(%u)",
923 AcpiUtGetRegionName((UINT8) SpaceIdList[i]), SpaceIdList[i]));
924 return (Status);
925 }
926 }
927
928 return (AE_OK);
929 }
930
931
932 /******************************************************************************
933 *
934 * FUNCTION: AeInstallEarlyHandlers
935 *
936 * PARAMETERS: None
937 *
938 * RETURN: Status
939 *
940 * DESCRIPTION: Install handlers for the AcpiExec utility.
941 *
942 * Notes: Don't install handler for PCI_Config, we want to use the
943 * default handler to exercise that code.
944 *
945 *****************************************************************************/
946
947 ACPI_STATUS
948 AeInstallEarlyHandlers (
949 void)
950 {
951 ACPI_STATUS Status;
952 UINT32 i;
953 ACPI_HANDLE Handle;
954
955
956 ACPI_FUNCTION_ENTRY ();
957
958
959 Status = AcpiInstallInterfaceHandler (AeInterfaceHandler);
960 if (ACPI_FAILURE (Status))
961 {
962 printf ("Could not install interface handler, %s\n",
963 AcpiFormatException (Status));
964 }
965
966 Status = AcpiInstallTableHandler (AeTableHandler, NULL);
967 if (ACPI_FAILURE (Status))
968 {
969 printf ("Could not install table handler, %s\n",
970 AcpiFormatException (Status));
971 }
972
973 Status = AcpiInstallExceptionHandler (AeExceptionHandler);
974 if (ACPI_FAILURE (Status))
975 {
976 printf ("Could not install exception handler, %s\n",
977 AcpiFormatException (Status));
978 }
979
980 /* Install global notify handlers */
981
982 Status = AcpiInstallNotifyHandler (ACPI_ROOT_OBJECT, ACPI_SYSTEM_NOTIFY,
983 AeSystemNotifyHandler, NULL);
984 if (ACPI_FAILURE (Status))
985 {
986 printf ("Could not install a global system notify handler, %s\n",
987 AcpiFormatException (Status));
988 }
989
990 Status = AcpiInstallNotifyHandler (ACPI_ROOT_OBJECT, ACPI_DEVICE_NOTIFY,
991 AeDeviceNotifyHandler, NULL);
992 if (ACPI_FAILURE (Status))
993 {
994 printf ("Could not install a global notify handler, %s\n",
995 AcpiFormatException (Status));
996 }
997
998 Status = AcpiGetHandle (NULL, "\\_SB", &Handle);
999 if (ACPI_SUCCESS (Status))
1000 {
1001 Status = AcpiInstallNotifyHandler (Handle, ACPI_SYSTEM_NOTIFY,
1002 AeNotifyHandler1, NULL);
1003 if (ACPI_FAILURE (Status))
1004 {
1005 printf ("Could not install a notify handler, %s\n",
1006 AcpiFormatException (Status));
1007 }
1008
1009 Status = AcpiRemoveNotifyHandler (Handle, ACPI_SYSTEM_NOTIFY,
1010 AeNotifyHandler1);
1011 if (ACPI_FAILURE (Status))
1012 {
1013 printf ("Could not remove a notify handler, %s\n",
1014 AcpiFormatException (Status));
1015 }
1016
1017 Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY,
1018 AeNotifyHandler1, NULL);
1019 AE_CHECK_OK (AcpiInstallNotifyHandler, Status);
1020
1021 Status = AcpiRemoveNotifyHandler (Handle, ACPI_ALL_NOTIFY,
1022 AeNotifyHandler1);
1023 AE_CHECK_OK (AcpiRemoveNotifyHandler, Status);
1024
1025 #if 0
1026 Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY,
1027 AeNotifyHandler1, NULL);
1028 if (ACPI_FAILURE (Status))
1029 {
1030 printf ("Could not install a notify handler, %s\n",
1031 AcpiFormatException (Status));
1032 }
1033 #endif
1034
1035 /* Install two handlers for _SB_ */
1036
1037 Status = AcpiInstallNotifyHandler (Handle, ACPI_SYSTEM_NOTIFY,
1038 AeNotifyHandler1, ACPI_CAST_PTR (void, 0x01234567));
1039
1040 Status = AcpiInstallNotifyHandler (Handle, ACPI_SYSTEM_NOTIFY,
1041 AeNotifyHandler2, ACPI_CAST_PTR (void, 0x89ABCDEF));
1042
1043 /* Attempt duplicate handler installation, should fail */
1044
1045 Status = AcpiInstallNotifyHandler (Handle, ACPI_SYSTEM_NOTIFY,
1046 AeNotifyHandler1, ACPI_CAST_PTR (void, 0x77777777));
1047
1048 Status = AcpiAttachData (Handle, AeAttachedDataHandler, Handle);
1049 AE_CHECK_OK (AcpiAttachData, Status);
1050
1051 Status = AcpiDetachData (Handle, AeAttachedDataHandler);
1052 AE_CHECK_OK (AcpiDetachData, Status);
1053
1054 Status = AcpiAttachData (Handle, AeAttachedDataHandler, Handle);
1055 AE_CHECK_OK (AcpiAttachData, Status);
1056
1057 /* Test support for multiple attaches */
1058
1059 Status = AcpiAttachData (Handle, AeAttachedDataHandler2, Handle);
1060 AE_CHECK_OK (AcpiAttachData, Status);
1061 }
1062 else
1063 {
1064 printf ("No _SB_ found, %s\n", AcpiFormatException (Status));
1065 }
1066
1067
1068 Status = AcpiGetHandle (NULL, "\\_TZ.TZ1", &Handle);
1069 if (ACPI_SUCCESS (Status))
1070 {
1071 Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY,
1072 AeNotifyHandler1, ACPI_CAST_PTR (void, 0x01234567));
1073
1074 Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY,
1075 AeNotifyHandler2, ACPI_CAST_PTR (void, 0x89ABCDEF));
1076
1077 Status = AcpiRemoveNotifyHandler (Handle, ACPI_ALL_NOTIFY,
1078 AeNotifyHandler1);
1079 Status = AcpiRemoveNotifyHandler (Handle, ACPI_ALL_NOTIFY,
1080 AeNotifyHandler2);
1081
1082 Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY,
1083 AeNotifyHandler2, ACPI_CAST_PTR (void, 0x89ABCDEF));
1084
1085 Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY,
1086 AeNotifyHandler1, ACPI_CAST_PTR (void, 0x01234567));
1087 }
1088
1089 Status = AcpiGetHandle (NULL, "\\_PR.CPU0", &Handle);
1090 if (ACPI_SUCCESS (Status))
1091 {
1092 Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY,
1093 AeNotifyHandler1, ACPI_CAST_PTR (void, 0x01234567));
1094
1095 Status = AcpiInstallNotifyHandler (Handle, ACPI_SYSTEM_NOTIFY,
1096 AeNotifyHandler2, ACPI_CAST_PTR (void, 0x89ABCDEF));
1097 }
1098
1099 /*
1100 * Install handlers that will override the default handlers for some of
1101 * the space IDs.
1102 */
1103 for (i = 0; i < ACPI_ARRAY_LENGTH (DefaultSpaceIdList); i++)
1104 {
1105 /* Install handler at the root object */
1106
1107 Status = AcpiInstallAddressSpaceHandler (ACPI_ROOT_OBJECT,
1108 DefaultSpaceIdList[i], AeRegionHandler,
1109 AeRegionInit, &AeMyContext);
1110 if (ACPI_FAILURE (Status))
1111 {
1112 ACPI_EXCEPTION ((AE_INFO, Status,
1113 "Could not install a default OpRegion handler for %s space(%u)",
1114 AcpiUtGetRegionName ((UINT8) DefaultSpaceIdList[i]),
1115 DefaultSpaceIdList[i]));
1116 return (Status);
1117 }
1118 }
1119
1120 /*
1121 * Initialize the global Region Handler space
1122 * MCW 3/23/00
1123 */
1124 AeRegions.NumberOfRegions = 0;
1125 AeRegions.RegionList = NULL;
1126 return (Status);
1127 }
1128
1129
1130 /******************************************************************************
1131 *
1132 * FUNCTION: AeRegionHandler
1133 *
1134 * PARAMETERS: Standard region handler parameters
1135 *
1136 * RETURN: Status
1137 *
1138 * DESCRIPTION: Test handler - Handles some dummy regions via memory that can
1139 * be manipulated in Ring 3. Simulates actual reads and writes.
1140 *
1141 *****************************************************************************/
1142
1143 ACPI_STATUS
1144 AeRegionHandler (
1145 UINT32 Function,
1146 ACPI_PHYSICAL_ADDRESS Address,
1147 UINT32 BitWidth,
1148 UINT64 *Value,
1149 void *HandlerContext,
1150 void *RegionContext)
1151 {
1152
1153 ACPI_OPERAND_OBJECT *RegionObject = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, RegionContext);
1154 UINT8 *Buffer = ACPI_CAST_PTR (UINT8, Value);
1155 ACPI_PHYSICAL_ADDRESS BaseAddress;
1156 ACPI_SIZE Length;
1157 BOOLEAN BufferExists;
1158 AE_REGION *RegionElement;
1159 void *BufferValue;
1160 ACPI_STATUS Status;
1161 UINT32 ByteWidth;
1162 UINT32 i;
1163 UINT8 SpaceId;
1164 ACPI_CONNECTION_INFO *MyContext;
1165 UINT32 Value1;
1166 UINT32 Value2;
1167 ACPI_RESOURCE *Resource;
1168
1169
1170 ACPI_FUNCTION_NAME (AeRegionHandler);
1171
1172 /*
1173 * If the object is not a region, simply return
1174 */
1175 if (RegionObject->Region.Type != ACPI_TYPE_REGION)
1176 {
1177 return (AE_OK);
1178 }
1179
1180 /* Check that we actually got back our context parameter */
1181
1182 if (HandlerContext != &AeMyContext)
1183 {
1184 printf ("Region handler received incorrect context %p, should be %p\n",
1185 HandlerContext, &AeMyContext);
1186 }
1187
1188 MyContext = ACPI_CAST_PTR (ACPI_CONNECTION_INFO, HandlerContext);
1189
1190 /*
1191 * Find the region's address space and length before searching
1192 * the linked list.
1193 */
1194 BaseAddress = RegionObject->Region.Address;
1195 Length = (ACPI_SIZE) RegionObject->Region.Length;
1196 SpaceId = RegionObject->Region.SpaceId;
1197
1198 ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, "Operation Region request on %s at 0x%X\n",
1199 AcpiUtGetRegionName (RegionObject->Region.SpaceId),
1200 (UINT32) Address));
1201
1202 /*
1203 * Region support can be disabled with the -do option.
1204 * We use this to support dynamically loaded tables where we pass a valid
1205 * address to the AML.
1206 */
1207 if (AcpiGbl_DbOpt_NoRegionSupport)
1208 {
1209 BufferValue = ACPI_TO_POINTER (Address);
1210 ByteWidth = (BitWidth / 8);
1211
1212 if (BitWidth % 8)
1213 {
1214 ByteWidth += 1;
1215 }
1216 goto DoFunction;
1217 }
1218
1219 switch (SpaceId)
1220 {
1221 case ACPI_ADR_SPACE_SYSTEM_IO:
1222 /*
1223 * For I/O space, exercise the port validation
1224 * Note: ReadPort currently always returns all ones, length=BitLength
1225 */
1226 switch (Function & ACPI_IO_MASK)
1227 {
1228 case ACPI_READ:
1229
1230 if (BitWidth == 64)
1231 {
1232 /* Split the 64-bit request into two 32-bit requests */
1233
1234 Status = AcpiHwReadPort (Address, &Value1, 32);
1235 AE_CHECK_OK (AcpiHwReadPort, Status);
1236 Status = AcpiHwReadPort (Address+4, &Value2, 32);
1237 AE_CHECK_OK (AcpiHwReadPort, Status);
1238
1239 *Value = Value1 | ((UINT64) Value2 << 32);
1240 }
1241 else
1242 {
1243 Status = AcpiHwReadPort (Address, &Value1, BitWidth);
1244 AE_CHECK_OK (AcpiHwReadPort, Status);
1245 *Value = (UINT64) Value1;
1246 }
1247 break;
1248
1249 case ACPI_WRITE:
1250
1251 if (BitWidth == 64)
1252 {
1253 /* Split the 64-bit request into two 32-bit requests */
1254
1255 Status = AcpiHwWritePort (Address, ACPI_LODWORD (*Value), 32);
1256 AE_CHECK_OK (AcpiHwWritePort, Status);
1257 Status = AcpiHwWritePort (Address+4, ACPI_HIDWORD (*Value), 32);
1258 AE_CHECK_OK (AcpiHwWritePort, Status);
1259 }
1260 else
1261 {
1262 Status = AcpiHwWritePort (Address, (UINT32) *Value, BitWidth);
1263 AE_CHECK_OK (AcpiHwWritePort, Status);
1264 }
1265 break;
1266
1267 default:
1268
1269 Status = AE_BAD_PARAMETER;
1270 break;
1271 }
1272
1273 if (ACPI_FAILURE (Status))
1274 {
1275 return (Status);
1276 }
1277
1278 /* Now go ahead and simulate the hardware */
1279 break;
1280
1281 /*
1282 * SMBus and GenericSerialBus support the various bidirectional
1283 * protocols.
1284 */
1285 case ACPI_ADR_SPACE_SMBUS:
1286 case ACPI_ADR_SPACE_GSBUS: /* ACPI 5.0 */
1287
1288 Length = 0;
1289
1290 switch (Function & ACPI_IO_MASK)
1291 {
1292 case ACPI_READ:
1293
1294 switch (Function >> 16)
1295 {
1296 case AML_FIELD_ATTRIB_QUICK:
1297 case AML_FIELD_ATTRIB_SEND_RCV:
1298 case AML_FIELD_ATTRIB_BYTE:
1299
1300 Length = 1;
1301 break;
1302
1303 case AML_FIELD_ATTRIB_WORD:
1304 case AML_FIELD_ATTRIB_WORD_CALL:
1305
1306 Length = 2;
1307 break;
1308
1309 case AML_FIELD_ATTRIB_BLOCK:
1310 case AML_FIELD_ATTRIB_BLOCK_CALL:
1311
1312 Length = 32;
1313 break;
1314
1315 case AML_FIELD_ATTRIB_MULTIBYTE:
1316 case AML_FIELD_ATTRIB_RAW_BYTES:
1317 case AML_FIELD_ATTRIB_RAW_PROCESS:
1318
1319 /* (-2) for status/length */
1320 Length = MyContext->AccessLength - 2;
1321 break;
1322
1323 default:
1324
1325 break;
1326 }
1327 break;
1328
1329 case ACPI_WRITE:
1330
1331 switch (Function >> 16)
1332 {
1333 case AML_FIELD_ATTRIB_QUICK:
1334 case AML_FIELD_ATTRIB_SEND_RCV:
1335 case AML_FIELD_ATTRIB_BYTE:
1336 case AML_FIELD_ATTRIB_WORD:
1337 case AML_FIELD_ATTRIB_BLOCK:
1338
1339 Length = 0;
1340 break;
1341
1342 case AML_FIELD_ATTRIB_WORD_CALL:
1343 Length = 2;
1344 break;
1345
1346 case AML_FIELD_ATTRIB_BLOCK_CALL:
1347 Length = 32;
1348 break;
1349
1350 case AML_FIELD_ATTRIB_MULTIBYTE:
1351 case AML_FIELD_ATTRIB_RAW_BYTES:
1352 case AML_FIELD_ATTRIB_RAW_PROCESS:
1353
1354 /* (-2) for status/length */
1355 Length = MyContext->AccessLength - 2;
1356 break;
1357
1358 default:
1359
1360 break;
1361 }
1362 break;
1363
1364 default:
1365
1366 break;
1367 }
1368
1369 if (AcpiGbl_DisplayRegionAccess)
1370 {
1371 AcpiOsPrintf ("AcpiExec: %s "
1372 "%s: Attr %X Addr %.4X BaseAddr %.4X Len %.2X Width %X BufLen %X",
1373 AcpiUtGetRegionName (SpaceId),
1374 (Function & ACPI_IO_MASK) ? "Write" : "Read ",
1375 (UINT32) (Function >> 16),
1376 (UINT32) Address, (UINT32) BaseAddress,
1377 Length, BitWidth, Buffer[1]);
1378
1379 /* GenericSerialBus has a Connection() parameter */
1380
1381 if (SpaceId == ACPI_ADR_SPACE_GSBUS)
1382 {
1383 Status = AcpiBufferToResource (MyContext->Connection,
1384 MyContext->Length, &Resource);
1385
1386 AcpiOsPrintf (" [AccLen %.2X Conn %p]",
1387 MyContext->AccessLength, MyContext->Connection);
1388 }
1389 AcpiOsPrintf ("\n");
1390 }
1391
1392 /* Setup the return buffer. Note: ASLTS depends on these fill values */
1393
1394 for (i = 0; i < Length; i++)
1395 {
1396 Buffer[i+2] = (UINT8) (0xA0 + i);
1397 }
1398
1399 Buffer[0] = 0x7A;
1400 Buffer[1] = (UINT8) Length;
1401 return (AE_OK);
1402
1403
1404 case ACPI_ADR_SPACE_IPMI: /* ACPI 4.0 */
1405
1406 if (AcpiGbl_DisplayRegionAccess)
1407 {
1408 AcpiOsPrintf ("AcpiExec: IPMI "
1409 "%s: Attr %X Addr %.4X BaseAddr %.4X Len %.2X Width %X BufLen %X\n",
1410 (Function & ACPI_IO_MASK) ? "Write" : "Read ",
1411 (UINT32) (Function >> 16), (UINT32) Address, (UINT32) BaseAddress,
1412 Length, BitWidth, Buffer[1]);
1413 }
1414
1415 /*
1416 * Regardless of a READ or WRITE, this handler is passed a 66-byte
1417 * buffer in which to return the IPMI status/length/data.
1418 *
1419 * Return some example data to show use of the bidirectional buffer
1420 */
1421 Buffer[0] = 0; /* Status byte */
1422 Buffer[1] = 64; /* Return buffer data length */
1423 Buffer[2] = 0; /* Completion code */
1424 Buffer[3] = 0; /* Reserved */
1425
1426 /*
1427 * Fill the 66-byte buffer with the return data.
1428 * Note: ASLTS depends on these fill values.
1429 */
1430 for (i = 4; i < 66; i++)
1431 {
1432 Buffer[i] = (UINT8) (i);
1433 }
1434 return (AE_OK);
1435
1436 default:
1437 break;
1438 }
1439
1440 /*
1441 * Search through the linked list for this region's buffer
1442 */
1443 BufferExists = FALSE;
1444 RegionElement = AeRegions.RegionList;
1445
1446 if (AeRegions.NumberOfRegions)
1447 {
1448 while (!BufferExists && RegionElement)
1449 {
1450 if (RegionElement->Address == BaseAddress &&
1451 RegionElement->Length == Length &&
1452 RegionElement->SpaceId == SpaceId)
1453 {
1454 BufferExists = TRUE;
1455 }
1456 else
1457 {
1458 RegionElement = RegionElement->NextRegion;
1459 }
1460 }
1461 }
1462
1463 /*
1464 * If the Region buffer does not exist, create it now
1465 */
1466 if (!BufferExists)
1467 {
1468 /*
1469 * Do the memory allocations first
1470 */
1471 RegionElement = AcpiOsAllocate (sizeof (AE_REGION));
1472 if (!RegionElement)
1473 {
1474 return (AE_NO_MEMORY);
1475 }
1476
1477 RegionElement->Buffer = AcpiOsAllocate (Length);
1478 if (!RegionElement->Buffer)
1479 {
1480 AcpiOsFree (RegionElement);
1481 return (AE_NO_MEMORY);
1482 }
1483
1484 /* Initialize the region with the default fill value */
1485
1486 ACPI_MEMSET (RegionElement->Buffer, AcpiGbl_RegionFillValue, Length);
1487
1488 RegionElement->Address = BaseAddress;
1489 RegionElement->Length = Length;
1490 RegionElement->SpaceId = SpaceId;
1491 RegionElement->NextRegion = NULL;
1492
1493 /*
1494 * Increment the number of regions and put this one
1495 * at the head of the list as it will probably get accessed
1496 * more often anyway.
1497 */
1498 AeRegions.NumberOfRegions += 1;
1499
1500 if (AeRegions.RegionList)
1501 {
1502 RegionElement->NextRegion = AeRegions.RegionList;
1503 }
1504
1505 AeRegions.RegionList = RegionElement;
1506 }
1507
1508 /*
1509 * Calculate the size of the memory copy
1510 */
1511 ByteWidth = (BitWidth / 8);
1512
1513 if (BitWidth % 8)
1514 {
1515 ByteWidth += 1;
1516 }
1517
1518 /*
1519 * The buffer exists and is pointed to by RegionElement.
1520 * We now need to verify the request is valid and perform the operation.
1521 *
1522 * NOTE: RegionElement->Length is in bytes, therefore it we compare against
1523 * ByteWidth (see above)
1524 */
1525 if (((UINT64) Address + ByteWidth) >
1526 ((UINT64)(RegionElement->Address) + RegionElement->Length))
1527 {
1528 ACPI_WARNING ((AE_INFO,
1529 "Request on [%4.4s] is beyond region limit Req-0x%X+0x%X, Base=0x%X, Len-0x%X",
1530 (RegionObject->Region.Node)->Name.Ascii, (UINT32) Address,
1531 ByteWidth, (UINT32)(RegionElement->Address),
1532 RegionElement->Length));
1533
1534 return (AE_AML_REGION_LIMIT);
1535 }
1536
1537 /*
1538 * Get BufferValue to point to the "address" in the buffer
1539 */
1540 BufferValue = ((UINT8 *) RegionElement->Buffer +
1541 ((UINT64) Address - (UINT64) RegionElement->Address));
1542
1543 DoFunction:
1544 /*
1545 * Perform a read or write to the buffer space
1546 */
1547 switch (Function)
1548 {
1549 case ACPI_READ:
1550 /*
1551 * Set the pointer Value to whatever is in the buffer
1552 */
1553 ACPI_MEMCPY (Value, BufferValue, ByteWidth);
1554 break;
1555
1556 case ACPI_WRITE:
1557 /*
1558 * Write the contents of Value to the buffer
1559 */
1560 ACPI_MEMCPY (BufferValue, Value, ByteWidth);
1561 break;
1562
1563 default:
1564
1565 return (AE_BAD_PARAMETER);
1566 }
1567
1568 if (AcpiGbl_DisplayRegionAccess)
1569 {
1570 switch (SpaceId)
1571 {
1572 case ACPI_ADR_SPACE_SYSTEM_MEMORY:
1573
1574 AcpiOsPrintf ("AcpiExec: SystemMemory "
1575 "%s: Val %.8X Addr %.4X Width %X [REGION: BaseAddr %.4X Len %.2X]\n",
1576 (Function & ACPI_IO_MASK) ? "Write" : "Read ",
1577 (UINT32) *Value, (UINT32) Address, BitWidth, (UINT32) BaseAddress, Length);
1578 break;
1579
1580 case ACPI_ADR_SPACE_GPIO: /* ACPI 5.0 */
1581
1582 /* This space is required to always be ByteAcc */
1583
1584 Status = AcpiBufferToResource (MyContext->Connection,
1585 MyContext->Length, &Resource);
1586
1587 AcpiOsPrintf ("AcpiExec: GeneralPurposeIo "
1588 "%s: Val %.8X Addr %.4X BaseAddr %.4X Len %.2X Width %X AccLen %.2X Conn %p\n",
1589 (Function & ACPI_IO_MASK) ? "Write" : "Read ", (UINT32) *Value,
1590 (UINT32) Address, (UINT32) BaseAddress, Length, BitWidth,
1591 MyContext->AccessLength, MyContext->Connection);
1592 break;
1593
1594 default:
1595
1596 break;
1597 }
1598 }
1599
1600 return (AE_OK);
1601 }
1602