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 }