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 }