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