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