1 /****************************************************************************** 2 * 3 * Module Name: evgpeblk - GPE block creation and initialization. 4 * $Revision: 1.56 $ 5 * 6 *****************************************************************************/ 7 8 /****************************************************************************** 9 * 10 * 1. Copyright Notice 11 * 12 * Some or all of this work - Copyright (c) 1999 - 2006, Intel Corp. 13 * All rights reserved. 14 * 15 * 2. License 16 * 17 * 2.1. This is your license from Intel Corp. under its intellectual property 18 * rights. You may have additional license terms from the party that provided 19 * you this software, covering your right to use that party's intellectual 20 * property rights. 21 * 22 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 23 * copy of the source code appearing in this file ("Covered Code") an 24 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 25 * base code distributed originally by Intel ("Original Intel Code") to copy, 26 * make derivatives, distribute, use and display any portion of the Covered 27 * Code in any form, with the right to sublicense such rights; and 28 * 29 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 30 * license (with the right to sublicense), under only those claims of Intel 31 * patents that are infringed by the Original Intel Code, to make, use, sell, 32 * offer to sell, and import the Covered Code and derivative works thereof 33 * solely to the minimum extent necessary to exercise the above copyright 34 * license, and in no event shall the patent license extend to any additions 35 * to or modifications of the Original Intel Code. No other license or right 36 * is granted directly or by implication, estoppel or otherwise; 37 * 38 * The above copyright and patent license is granted only if the following 39 * conditions are met: 40 * 41 * 3. Conditions 42 * 43 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 44 * Redistribution of source code of any substantial portion of the Covered 45 * Code or modification with rights to further distribute source must include 46 * the above Copyright Notice, the above License, this list of Conditions, 47 * and the following Disclaimer and Export Compliance provision. In addition, 48 * Licensee must cause all Covered Code to which Licensee contributes to 49 * contain a file documenting the changes Licensee made to create that Covered 50 * Code and the date of any change. Licensee must include in that file the 51 * documentation of any changes made by any predecessor Licensee. Licensee 52 * must include a prominent statement that the modification is derived, 53 * directly or indirectly, from Original Intel Code. 54 * 55 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 56 * Redistribution of source code of any substantial portion of the Covered 57 * Code or modification without rights to further distribute source must 58 * include the following Disclaimer and Export Compliance provision in the 59 * documentation and/or other materials provided with distribution. In 60 * addition, Licensee may not authorize further sublicense of source of any 61 * portion of the Covered Code, and must include terms to the effect that the 62 * license from Licensee to its licensee is limited to the intellectual 63 * property embodied in the software Licensee provides to its licensee, and 64 * not to intellectual property embodied in modifications its licensee may 65 * make. 66 * 67 * 3.3. Redistribution of Executable. Redistribution in executable form of any 68 * substantial portion of the Covered Code or modification must reproduce the 69 * above Copyright Notice, and the following Disclaimer and Export Compliance 70 * provision in the documentation and/or other materials provided with the 71 * distribution. 72 * 73 * 3.4. Intel retains all right, title, and interest in and to the Original 74 * Intel Code. 75 * 76 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 77 * Intel shall be used in advertising or otherwise to promote the sale, use or 78 * other dealings in products derived from or relating to the Covered Code 79 * without prior written authorization from Intel. 80 * 81 * 4. Disclaimer and Export Compliance 82 * 83 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 84 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 85 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 86 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 87 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 88 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 89 * PARTICULAR PURPOSE. 90 * 91 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 92 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 93 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 94 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 95 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 96 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 97 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 98 * LIMITED REMEDY. 99 * 100 * 4.3. Licensee shall not export, either directly or indirectly, any of this 101 * software or system incorporating such software without first obtaining any 102 * required license or other approval from the U. S. Department of Commerce or 103 * any other agency or department of the United States Government. In the 104 * event Licensee exports any such software from the United States or 105 * re-exports any such software from a foreign destination, Licensee shall 106 * ensure that the distribution and export/re-export of the software is in 107 * compliance with all laws, regulations, orders, or other restrictions of the 108 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 109 * any of its subsidiaries will export/re-export any technical data, process, 110 * software, or service, directly or indirectly, to any country for which the 111 * United States government or any agency thereof requires an export license, 112 * other governmental approval, or letter of assurance, without first obtaining 113 * such license, approval or letter. 114 * 115 *****************************************************************************/ 116 117 #include "acpi.h" 118 #include "acevents.h" 119 #include "acnamesp.h" 120 121 #define _COMPONENT ACPI_EVENTS 122 ACPI_MODULE_NAME ("evgpeblk") 123 124 /* Local prototypes */ 125 126 static ACPI_STATUS 127 AcpiEvSaveMethodInfo ( 128 ACPI_HANDLE ObjHandle, 129 UINT32 Level, 130 void *ObjDesc, 131 void **ReturnValue); 132 133 static ACPI_STATUS 134 AcpiEvMatchPrwAndGpe ( 135 ACPI_HANDLE ObjHandle, 136 UINT32 Level, 137 void *Info, 138 void **ReturnValue); 139 140 static ACPI_GPE_XRUPT_INFO * 141 AcpiEvGetGpeXruptBlock ( 142 UINT32 InterruptNumber); 143 144 static ACPI_STATUS 145 AcpiEvDeleteGpeXrupt ( 146 ACPI_GPE_XRUPT_INFO *GpeXrupt); 147 148 static ACPI_STATUS 149 AcpiEvInstallGpeBlock ( 150 ACPI_GPE_BLOCK_INFO *GpeBlock, 151 UINT32 InterruptNumber); 152 153 static ACPI_STATUS 154 AcpiEvCreateGpeInfoBlocks ( 155 ACPI_GPE_BLOCK_INFO *GpeBlock); 156 157 158 /******************************************************************************* 159 * 160 * FUNCTION: AcpiEvValidGpeEvent 161 * 162 * PARAMETERS: GpeEventInfo - Info for this GPE 163 * 164 * RETURN: TRUE if the GpeEvent is valid 165 * 166 * DESCRIPTION: Validate a GPE event. DO NOT CALL FROM INTERRUPT LEVEL. 167 * Should be called only when the GPE lists are semaphore locked 168 * and not subject to change. 169 * 170 ******************************************************************************/ 171 172 BOOLEAN 173 AcpiEvValidGpeEvent ( 174 ACPI_GPE_EVENT_INFO *GpeEventInfo) 175 { 176 ACPI_GPE_XRUPT_INFO *GpeXruptBlock; 177 ACPI_GPE_BLOCK_INFO *GpeBlock; 178 179 180 ACPI_FUNCTION_ENTRY (); 181 182 183 /* No need for spin lock since we are not changing any list elements */ 184 185 /* Walk the GPE interrupt levels */ 186 187 GpeXruptBlock = AcpiGbl_GpeXruptListHead; 188 while (GpeXruptBlock) 189 { 190 GpeBlock = GpeXruptBlock->GpeBlockListHead; 191 192 /* Walk the GPE blocks on this interrupt level */ 193 194 while (GpeBlock) 195 { 196 if ((&GpeBlock->EventInfo[0] <= GpeEventInfo) && 197 (&GpeBlock->EventInfo[((ACPI_SIZE) GpeBlock->RegisterCount) * 8] > GpeEventInfo)) 198 { 199 return (TRUE); 200 } 201 202 GpeBlock = GpeBlock->Next; 203 } 204 205 GpeXruptBlock = GpeXruptBlock->Next; 206 } 207 208 return (FALSE); 209 } 210 211 212 /******************************************************************************* 213 * 214 * FUNCTION: AcpiEvWalkGpeList 215 * 216 * PARAMETERS: GpeWalkCallback - Routine called for each GPE block 217 * 218 * RETURN: Status 219 * 220 * DESCRIPTION: Walk the GPE lists. 221 * 222 ******************************************************************************/ 223 224 ACPI_STATUS 225 AcpiEvWalkGpeList ( 226 ACPI_GPE_CALLBACK GpeWalkCallback) 227 { 228 ACPI_GPE_BLOCK_INFO *GpeBlock; 229 ACPI_GPE_XRUPT_INFO *GpeXruptInfo; 230 ACPI_STATUS Status = AE_OK; 231 ACPI_CPU_FLAGS Flags; 232 233 234 ACPI_FUNCTION_TRACE (EvWalkGpeList); 235 236 237 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 238 239 /* Walk the interrupt level descriptor list */ 240 241 GpeXruptInfo = AcpiGbl_GpeXruptListHead; 242 while (GpeXruptInfo) 243 { 244 /* Walk all Gpe Blocks attached to this interrupt level */ 245 246 GpeBlock = GpeXruptInfo->GpeBlockListHead; 247 while (GpeBlock) 248 { 249 /* One callback per GPE block */ 250 251 Status = GpeWalkCallback (GpeXruptInfo, GpeBlock); 252 if (ACPI_FAILURE (Status)) 253 { 254 goto UnlockAndExit; 255 } 256 257 GpeBlock = GpeBlock->Next; 258 } 259 260 GpeXruptInfo = GpeXruptInfo->Next; 261 } 262 263 UnlockAndExit: 264 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 265 return_ACPI_STATUS (Status); 266 } 267 268 269 /******************************************************************************* 270 * 271 * FUNCTION: AcpiEvDeleteGpeHandlers 272 * 273 * PARAMETERS: GpeXruptInfo - GPE Interrupt info 274 * GpeBlock - Gpe Block info 275 * 276 * RETURN: Status 277 * 278 * DESCRIPTION: Delete all Handler objects found in the GPE data structs. 279 * Used only prior to termination. 280 * 281 ******************************************************************************/ 282 283 ACPI_STATUS 284 AcpiEvDeleteGpeHandlers ( 285 ACPI_GPE_XRUPT_INFO *GpeXruptInfo, 286 ACPI_GPE_BLOCK_INFO *GpeBlock) 287 { 288 ACPI_GPE_EVENT_INFO *GpeEventInfo; 289 ACPI_NATIVE_UINT i; 290 ACPI_NATIVE_UINT j; 291 292 293 ACPI_FUNCTION_TRACE (EvDeleteGpeHandlers); 294 295 296 /* Examine each GPE Register within the block */ 297 298 for (i = 0; i < GpeBlock->RegisterCount; i++) 299 { 300 /* Now look at the individual GPEs in this byte register */ 301 302 for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) 303 { 304 GpeEventInfo = &GpeBlock->EventInfo[(i * ACPI_GPE_REGISTER_WIDTH) + j]; 305 306 if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) == 307 ACPI_GPE_DISPATCH_HANDLER) 308 { 309 ACPI_FREE (GpeEventInfo->Dispatch.Handler); 310 GpeEventInfo->Dispatch.Handler = NULL; 311 GpeEventInfo->Flags &= ~ACPI_GPE_DISPATCH_MASK; 312 } 313 } 314 } 315 316 return_ACPI_STATUS (AE_OK); 317 } 318 319 320 /******************************************************************************* 321 * 322 * FUNCTION: AcpiEvSaveMethodInfo 323 * 324 * PARAMETERS: Callback from WalkNamespace 325 * 326 * RETURN: Status 327 * 328 * DESCRIPTION: Called from AcpiWalkNamespace. Expects each object to be a 329 * control method under the _GPE portion of the namespace. 330 * Extract the name and GPE type from the object, saving this 331 * information for quick lookup during GPE dispatch 332 * 333 * The name of each GPE control method is of the form: 334 * "_Lxx" or "_Exx" 335 * Where: 336 * L - means that the GPE is level triggered 337 * E - means that the GPE is edge triggered 338 * xx - is the GPE number [in HEX] 339 * 340 ******************************************************************************/ 341 342 static ACPI_STATUS 343 AcpiEvSaveMethodInfo ( 344 ACPI_HANDLE ObjHandle, 345 UINT32 Level, 346 void *ObjDesc, 347 void **ReturnValue) 348 { 349 ACPI_GPE_BLOCK_INFO *GpeBlock = (void *) ObjDesc; 350 ACPI_GPE_EVENT_INFO *GpeEventInfo; 351 UINT32 GpeNumber; 352 char Name[ACPI_NAME_SIZE + 1]; 353 UINT8 Type; 354 ACPI_STATUS Status; 355 356 357 ACPI_FUNCTION_TRACE (EvSaveMethodInfo); 358 359 360 /* 361 * _Lxx and _Exx GPE method support 362 * 363 * 1) Extract the name from the object and convert to a string 364 */ 365 ACPI_MOVE_32_TO_32 ( 366 Name, &((ACPI_NAMESPACE_NODE *) ObjHandle)->Name.Integer); 367 Name[ACPI_NAME_SIZE] = 0; 368 369 /* 370 * 2) Edge/Level determination is based on the 2nd character 371 * of the method name 372 * 373 * NOTE: Default GPE type is RUNTIME. May be changed later to WAKE 374 * if a _PRW object is found that points to this GPE. 375 */ 376 switch (Name[1]) 377 { 378 case 'L': 379 Type = ACPI_GPE_LEVEL_TRIGGERED; 380 break; 381 382 case 'E': 383 Type = ACPI_GPE_EDGE_TRIGGERED; 384 break; 385 386 default: 387 /* Unknown method type, just ignore it! */ 388 389 ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, 390 "Ignoring unknown GPE method type: %s (name not of form _Lxx or _Exx)", 391 Name)); 392 return_ACPI_STATUS (AE_OK); 393 } 394 395 /* Convert the last two characters of the name to the GPE Number */ 396 397 GpeNumber = ACPI_STRTOUL (&Name[2], NULL, 16); 398 if (GpeNumber == ACPI_UINT32_MAX) 399 { 400 /* Conversion failed; invalid method, just ignore it */ 401 402 ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, 403 "Could not extract GPE number from name: %s (name is not of form _Lxx or _Exx)", 404 Name)); 405 return_ACPI_STATUS (AE_OK); 406 } 407 408 /* Ensure that we have a valid GPE number for this GPE block */ 409 410 if ((GpeNumber < GpeBlock->BlockBaseNumber) || 411 (GpeNumber >= (GpeBlock->BlockBaseNumber + (GpeBlock->RegisterCount * 8)))) 412 { 413 /* 414 * Not valid for this GPE block, just ignore it 415 * However, it may be valid for a different GPE block, since GPE0 and GPE1 416 * methods both appear under \_GPE. 417 */ 418 return_ACPI_STATUS (AE_OK); 419 } 420 421 /* 422 * Now we can add this information to the GpeEventInfo block 423 * for use during dispatch of this GPE. Default type is RUNTIME, although 424 * this may change when the _PRW methods are executed later. 425 */ 426 GpeEventInfo = &GpeBlock->EventInfo[GpeNumber - GpeBlock->BlockBaseNumber]; 427 428 GpeEventInfo->Flags = (UINT8) 429 (Type | ACPI_GPE_DISPATCH_METHOD | ACPI_GPE_TYPE_RUNTIME); 430 431 GpeEventInfo->Dispatch.MethodNode = (ACPI_NAMESPACE_NODE *) ObjHandle; 432 433 /* Update enable mask, but don't enable the HW GPE as of yet */ 434 435 Status = AcpiEvEnableGpe (GpeEventInfo, FALSE); 436 437 ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, 438 "Registered GPE method %s as GPE number 0x%.2X\n", 439 Name, GpeNumber)); 440 return_ACPI_STATUS (Status); 441 } 442 443 444 /******************************************************************************* 445 * 446 * FUNCTION: AcpiEvMatchPrwAndGpe 447 * 448 * PARAMETERS: Callback from WalkNamespace 449 * 450 * RETURN: Status. NOTE: We ignore errors so that the _PRW walk is 451 * not aborted on a single _PRW failure. 452 * 453 * DESCRIPTION: Called from AcpiWalkNamespace. Expects each object to be a 454 * Device. Run the _PRW method. If present, extract the GPE 455 * number and mark the GPE as a WAKE GPE. 456 * 457 ******************************************************************************/ 458 459 static ACPI_STATUS 460 AcpiEvMatchPrwAndGpe ( 461 ACPI_HANDLE ObjHandle, 462 UINT32 Level, 463 void *Info, 464 void **ReturnValue) 465 { 466 ACPI_GPE_WALK_INFO *GpeInfo = (void *) Info; 467 ACPI_NAMESPACE_NODE *GpeDevice; 468 ACPI_GPE_BLOCK_INFO *GpeBlock; 469 ACPI_NAMESPACE_NODE *TargetGpeDevice; 470 ACPI_GPE_EVENT_INFO *GpeEventInfo; 471 ACPI_OPERAND_OBJECT *PkgDesc; 472 ACPI_OPERAND_OBJECT *ObjDesc; 473 UINT32 GpeNumber; 474 ACPI_STATUS Status; 475 476 477 ACPI_FUNCTION_TRACE (EvMatchPrwAndGpe); 478 479 480 /* Check for a _PRW method under this device */ 481 482 Status = AcpiUtEvaluateObject (ObjHandle, METHOD_NAME__PRW, 483 ACPI_BTYPE_PACKAGE, &PkgDesc); 484 if (ACPI_FAILURE (Status)) 485 { 486 /* Ignore all errors from _PRW, we don't want to abort the subsystem */ 487 488 return_ACPI_STATUS (AE_OK); 489 } 490 491 /* The returned _PRW package must have at least two elements */ 492 493 if (PkgDesc->Package.Count < 2) 494 { 495 goto Cleanup; 496 } 497 498 /* Extract pointers from the input context */ 499 500 GpeDevice = GpeInfo->GpeDevice; 501 GpeBlock = GpeInfo->GpeBlock; 502 503 /* 504 * The _PRW object must return a package, we are only interested 505 * in the first element 506 */ 507 ObjDesc = PkgDesc->Package.Elements[0]; 508 509 if (ACPI_GET_OBJECT_TYPE (ObjDesc) == ACPI_TYPE_INTEGER) 510 { 511 /* Use FADT-defined GPE device (from definition of _PRW) */ 512 513 TargetGpeDevice = AcpiGbl_FadtGpeDevice; 514 515 /* Integer is the GPE number in the FADT described GPE blocks */ 516 517 GpeNumber = (UINT32) ObjDesc->Integer.Value; 518 } 519 else if (ACPI_GET_OBJECT_TYPE (ObjDesc) == ACPI_TYPE_PACKAGE) 520 { 521 /* Package contains a GPE reference and GPE number within a GPE block */ 522 523 if ((ObjDesc->Package.Count < 2) || 524 (ACPI_GET_OBJECT_TYPE (ObjDesc->Package.Elements[0]) != ACPI_TYPE_LOCAL_REFERENCE) || 525 (ACPI_GET_OBJECT_TYPE (ObjDesc->Package.Elements[1]) != ACPI_TYPE_INTEGER)) 526 { 527 goto Cleanup; 528 } 529 530 /* Get GPE block reference and decode */ 531 532 TargetGpeDevice = ObjDesc->Package.Elements[0]->Reference.Node; 533 GpeNumber = (UINT32) ObjDesc->Package.Elements[1]->Integer.Value; 534 } 535 else 536 { 537 /* Unknown type, just ignore it */ 538 539 goto Cleanup; 540 } 541 542 /* 543 * Is this GPE within this block? 544 * 545 * TRUE iff these conditions are true: 546 * 1) The GPE devices match. 547 * 2) The GPE index(number) is within the range of the Gpe Block 548 * associated with the GPE device. 549 */ 550 if ((GpeDevice == TargetGpeDevice) && 551 (GpeNumber >= GpeBlock->BlockBaseNumber) && 552 (GpeNumber < GpeBlock->BlockBaseNumber + (GpeBlock->RegisterCount * 8))) 553 { 554 GpeEventInfo = &GpeBlock->EventInfo[GpeNumber - GpeBlock->BlockBaseNumber]; 555 556 /* Mark GPE for WAKE-ONLY but WAKE_DISABLED */ 557 558 GpeEventInfo->Flags &= ~(ACPI_GPE_WAKE_ENABLED | ACPI_GPE_RUN_ENABLED); 559 560 Status = AcpiEvSetGpeType (GpeEventInfo, ACPI_GPE_TYPE_WAKE); 561 if (ACPI_FAILURE (Status)) 562 { 563 goto Cleanup; 564 } 565 Status = AcpiEvUpdateGpeEnableMasks (GpeEventInfo, ACPI_GPE_DISABLE); 566 } 567 568 Cleanup: 569 AcpiUtRemoveReference (PkgDesc); 570 return_ACPI_STATUS (AE_OK); 571 } 572 573 574 /******************************************************************************* 575 * 576 * FUNCTION: AcpiEvGetGpeXruptBlock 577 * 578 * PARAMETERS: InterruptNumber - Interrupt for a GPE block 579 * 580 * RETURN: A GPE interrupt block 581 * 582 * DESCRIPTION: Get or Create a GPE interrupt block. There is one interrupt 583 * block per unique interrupt level used for GPEs. 584 * Should be called only when the GPE lists are semaphore locked 585 * and not subject to change. 586 * 587 ******************************************************************************/ 588 589 static ACPI_GPE_XRUPT_INFO * 590 AcpiEvGetGpeXruptBlock ( 591 UINT32 InterruptNumber) 592 { 593 ACPI_GPE_XRUPT_INFO *NextGpeXrupt; 594 ACPI_GPE_XRUPT_INFO *GpeXrupt; 595 ACPI_STATUS Status; 596 ACPI_CPU_FLAGS Flags; 597 598 599 ACPI_FUNCTION_TRACE (EvGetGpeXruptBlock); 600 601 602 /* No need for lock since we are not changing any list elements here */ 603 604 NextGpeXrupt = AcpiGbl_GpeXruptListHead; 605 while (NextGpeXrupt) 606 { 607 if (NextGpeXrupt->InterruptNumber == InterruptNumber) 608 { 609 return_PTR (NextGpeXrupt); 610 } 611 612 NextGpeXrupt = NextGpeXrupt->Next; 613 } 614 615 /* Not found, must allocate a new xrupt descriptor */ 616 617 GpeXrupt = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_XRUPT_INFO)); 618 if (!GpeXrupt) 619 { 620 return_PTR (NULL); 621 } 622 623 GpeXrupt->InterruptNumber = InterruptNumber; 624 625 /* Install new interrupt descriptor with spin lock */ 626 627 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 628 if (AcpiGbl_GpeXruptListHead) 629 { 630 NextGpeXrupt = AcpiGbl_GpeXruptListHead; 631 while (NextGpeXrupt->Next) 632 { 633 NextGpeXrupt = NextGpeXrupt->Next; 634 } 635 636 NextGpeXrupt->Next = GpeXrupt; 637 GpeXrupt->Previous = NextGpeXrupt; 638 } 639 else 640 { 641 AcpiGbl_GpeXruptListHead = GpeXrupt; 642 } 643 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 644 645 /* Install new interrupt handler if not SCI_INT */ 646 647 if (InterruptNumber != AcpiGbl_FADT->SciInt) 648 { 649 Status = AcpiOsInstallInterruptHandler (InterruptNumber, 650 AcpiEvGpeXruptHandler, GpeXrupt); 651 if (ACPI_FAILURE (Status)) 652 { 653 ACPI_ERROR ((AE_INFO, 654 "Could not install GPE interrupt handler at level 0x%X", 655 InterruptNumber)); 656 return_PTR (NULL); 657 } 658 } 659 660 return_PTR (GpeXrupt); 661 } 662 663 664 /******************************************************************************* 665 * 666 * FUNCTION: AcpiEvDeleteGpeXrupt 667 * 668 * PARAMETERS: GpeXrupt - A GPE interrupt info block 669 * 670 * RETURN: Status 671 * 672 * DESCRIPTION: Remove and free a GpeXrupt block. Remove an associated 673 * interrupt handler if not the SCI interrupt. 674 * 675 ******************************************************************************/ 676 677 static ACPI_STATUS 678 AcpiEvDeleteGpeXrupt ( 679 ACPI_GPE_XRUPT_INFO *GpeXrupt) 680 { 681 ACPI_STATUS Status; 682 ACPI_CPU_FLAGS Flags; 683 684 685 ACPI_FUNCTION_TRACE (EvDeleteGpeXrupt); 686 687 688 /* We never want to remove the SCI interrupt handler */ 689 690 if (GpeXrupt->InterruptNumber == AcpiGbl_FADT->SciInt) 691 { 692 GpeXrupt->GpeBlockListHead = NULL; 693 return_ACPI_STATUS (AE_OK); 694 } 695 696 /* Disable this interrupt */ 697 698 Status = AcpiOsRemoveInterruptHandler ( 699 GpeXrupt->InterruptNumber, AcpiEvGpeXruptHandler); 700 if (ACPI_FAILURE (Status)) 701 { 702 return_ACPI_STATUS (Status); 703 } 704 705 /* Unlink the interrupt block with lock */ 706 707 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 708 if (GpeXrupt->Previous) 709 { 710 GpeXrupt->Previous->Next = GpeXrupt->Next; 711 } 712 713 if (GpeXrupt->Next) 714 { 715 GpeXrupt->Next->Previous = GpeXrupt->Previous; 716 } 717 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 718 719 /* Free the block */ 720 721 ACPI_FREE (GpeXrupt); 722 return_ACPI_STATUS (AE_OK); 723 } 724 725 726 /******************************************************************************* 727 * 728 * FUNCTION: AcpiEvInstallGpeBlock 729 * 730 * PARAMETERS: GpeBlock - New GPE block 731 * InterruptNumber - Xrupt to be associated with this GPE block 732 * 733 * RETURN: Status 734 * 735 * DESCRIPTION: Install new GPE block with mutex support 736 * 737 ******************************************************************************/ 738 739 static ACPI_STATUS 740 AcpiEvInstallGpeBlock ( 741 ACPI_GPE_BLOCK_INFO *GpeBlock, 742 UINT32 InterruptNumber) 743 { 744 ACPI_GPE_BLOCK_INFO *NextGpeBlock; 745 ACPI_GPE_XRUPT_INFO *GpeXruptBlock; 746 ACPI_STATUS Status; 747 ACPI_CPU_FLAGS Flags; 748 749 750 ACPI_FUNCTION_TRACE (EvInstallGpeBlock); 751 752 753 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 754 if (ACPI_FAILURE (Status)) 755 { 756 return_ACPI_STATUS (Status); 757 } 758 759 GpeXruptBlock = AcpiEvGetGpeXruptBlock (InterruptNumber); 760 if (!GpeXruptBlock) 761 { 762 Status = AE_NO_MEMORY; 763 goto UnlockAndExit; 764 } 765 766 /* Install the new block at the end of the list with lock */ 767 768 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 769 if (GpeXruptBlock->GpeBlockListHead) 770 { 771 NextGpeBlock = GpeXruptBlock->GpeBlockListHead; 772 while (NextGpeBlock->Next) 773 { 774 NextGpeBlock = NextGpeBlock->Next; 775 } 776 777 NextGpeBlock->Next = GpeBlock; 778 GpeBlock->Previous = NextGpeBlock; 779 } 780 else 781 { 782 GpeXruptBlock->GpeBlockListHead = GpeBlock; 783 } 784 785 GpeBlock->XruptBlock = GpeXruptBlock; 786 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 787 788 789 UnlockAndExit: 790 Status = AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 791 return_ACPI_STATUS (Status); 792 } 793 794 795 /******************************************************************************* 796 * 797 * FUNCTION: AcpiEvDeleteGpeBlock 798 * 799 * PARAMETERS: GpeBlock - Existing GPE block 800 * 801 * RETURN: Status 802 * 803 * DESCRIPTION: Remove a GPE block 804 * 805 ******************************************************************************/ 806 807 ACPI_STATUS 808 AcpiEvDeleteGpeBlock ( 809 ACPI_GPE_BLOCK_INFO *GpeBlock) 810 { 811 ACPI_STATUS Status; 812 ACPI_CPU_FLAGS Flags; 813 814 815 ACPI_FUNCTION_TRACE (EvInstallGpeBlock); 816 817 818 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 819 if (ACPI_FAILURE (Status)) 820 { 821 return_ACPI_STATUS (Status); 822 } 823 824 /* Disable all GPEs in this block */ 825 826 Status = AcpiHwDisableGpeBlock (GpeBlock->XruptBlock, GpeBlock); 827 828 if (!GpeBlock->Previous && !GpeBlock->Next) 829 { 830 /* This is the last GpeBlock on this interrupt */ 831 832 Status = AcpiEvDeleteGpeXrupt (GpeBlock->XruptBlock); 833 if (ACPI_FAILURE (Status)) 834 { 835 goto UnlockAndExit; 836 } 837 } 838 else 839 { 840 /* Remove the block on this interrupt with lock */ 841 842 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 843 if (GpeBlock->Previous) 844 { 845 GpeBlock->Previous->Next = GpeBlock->Next; 846 } 847 else 848 { 849 GpeBlock->XruptBlock->GpeBlockListHead = GpeBlock->Next; 850 } 851 852 if (GpeBlock->Next) 853 { 854 GpeBlock->Next->Previous = GpeBlock->Previous; 855 } 856 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 857 } 858 859 /* Free the GpeBlock */ 860 861 ACPI_FREE (GpeBlock->RegisterInfo); 862 ACPI_FREE (GpeBlock->EventInfo); 863 ACPI_FREE (GpeBlock); 864 865 UnlockAndExit: 866 Status = AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 867 return_ACPI_STATUS (Status); 868 } 869 870 871 /******************************************************************************* 872 * 873 * FUNCTION: AcpiEvCreateGpeInfoBlocks 874 * 875 * PARAMETERS: GpeBlock - New GPE block 876 * 877 * RETURN: Status 878 * 879 * DESCRIPTION: Create the RegisterInfo and EventInfo blocks for this GPE block 880 * 881 ******************************************************************************/ 882 883 static ACPI_STATUS 884 AcpiEvCreateGpeInfoBlocks ( 885 ACPI_GPE_BLOCK_INFO *GpeBlock) 886 { 887 ACPI_GPE_REGISTER_INFO *GpeRegisterInfo = NULL; 888 ACPI_GPE_EVENT_INFO *GpeEventInfo = NULL; 889 ACPI_GPE_EVENT_INFO *ThisEvent; 890 ACPI_GPE_REGISTER_INFO *ThisRegister; 891 ACPI_NATIVE_UINT i; 892 ACPI_NATIVE_UINT j; 893 ACPI_STATUS Status; 894 895 896 ACPI_FUNCTION_TRACE (EvCreateGpeInfoBlocks); 897 898 899 /* Allocate the GPE register information block */ 900 901 GpeRegisterInfo = ACPI_ALLOCATE_ZEROED ( 902 (ACPI_SIZE) GpeBlock->RegisterCount * 903 sizeof (ACPI_GPE_REGISTER_INFO)); 904 if (!GpeRegisterInfo) 905 { 906 ACPI_ERROR ((AE_INFO, 907 "Could not allocate the GpeRegisterInfo table")); 908 return_ACPI_STATUS (AE_NO_MEMORY); 909 } 910 911 /* 912 * Allocate the GPE EventInfo block. There are eight distinct GPEs 913 * per register. Initialization to zeros is sufficient. 914 */ 915 GpeEventInfo = ACPI_ALLOCATE_ZEROED ( 916 ((ACPI_SIZE) GpeBlock->RegisterCount * 917 ACPI_GPE_REGISTER_WIDTH) * 918 sizeof (ACPI_GPE_EVENT_INFO)); 919 if (!GpeEventInfo) 920 { 921 ACPI_ERROR ((AE_INFO, 922 "Could not allocate the GpeEventInfo table")); 923 Status = AE_NO_MEMORY; 924 goto ErrorExit; 925 } 926 927 /* Save the new Info arrays in the GPE block */ 928 929 GpeBlock->RegisterInfo = GpeRegisterInfo; 930 GpeBlock->EventInfo = GpeEventInfo; 931 932 /* 933 * Initialize the GPE Register and Event structures. A goal of these 934 * tables is to hide the fact that there are two separate GPE register sets 935 * in a given GPE hardware block, the status registers occupy the first half, 936 * and the enable registers occupy the second half. 937 */ 938 ThisRegister = GpeRegisterInfo; 939 ThisEvent = GpeEventInfo; 940 941 for (i = 0; i < GpeBlock->RegisterCount; i++) 942 { 943 /* Init the RegisterInfo for this GPE register (8 GPEs) */ 944 945 ThisRegister->BaseGpeNumber = (UINT8) (GpeBlock->BlockBaseNumber + 946 (i * ACPI_GPE_REGISTER_WIDTH)); 947 948 ACPI_STORE_ADDRESS (ThisRegister->StatusAddress.Address, 949 (ACPI_GET_ADDRESS (GpeBlock->BlockAddress.Address) 950 + i)); 951 952 ACPI_STORE_ADDRESS (ThisRegister->EnableAddress.Address, 953 (ACPI_GET_ADDRESS (GpeBlock->BlockAddress.Address) 954 + i 955 + GpeBlock->RegisterCount)); 956 957 ThisRegister->StatusAddress.AddressSpaceId = GpeBlock->BlockAddress.AddressSpaceId; 958 ThisRegister->EnableAddress.AddressSpaceId = GpeBlock->BlockAddress.AddressSpaceId; 959 ThisRegister->StatusAddress.RegisterBitWidth = ACPI_GPE_REGISTER_WIDTH; 960 ThisRegister->EnableAddress.RegisterBitWidth = ACPI_GPE_REGISTER_WIDTH; 961 ThisRegister->StatusAddress.RegisterBitOffset = ACPI_GPE_REGISTER_WIDTH; 962 ThisRegister->EnableAddress.RegisterBitOffset = ACPI_GPE_REGISTER_WIDTH; 963 964 /* Init the EventInfo for each GPE within this register */ 965 966 for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) 967 { 968 ThisEvent->RegisterBit = AcpiGbl_DecodeTo8bit[j]; 969 ThisEvent->RegisterInfo = ThisRegister; 970 ThisEvent++; 971 } 972 973 /* Disable all GPEs within this register */ 974 975 Status = AcpiHwLowLevelWrite (ACPI_GPE_REGISTER_WIDTH, 0x00, 976 &ThisRegister->EnableAddress); 977 if (ACPI_FAILURE (Status)) 978 { 979 goto ErrorExit; 980 } 981 982 /* Clear any pending GPE events within this register */ 983 984 Status = AcpiHwLowLevelWrite (ACPI_GPE_REGISTER_WIDTH, 0xFF, 985 &ThisRegister->StatusAddress); 986 if (ACPI_FAILURE (Status)) 987 { 988 goto ErrorExit; 989 } 990 991 ThisRegister++; 992 } 993 994 return_ACPI_STATUS (AE_OK); 995 996 997 ErrorExit: 998 if (GpeRegisterInfo) 999 { 1000 ACPI_FREE (GpeRegisterInfo); 1001 } 1002 if (GpeEventInfo) 1003 { 1004 ACPI_FREE (GpeEventInfo); 1005 } 1006 1007 return_ACPI_STATUS (Status); 1008 } 1009 1010 1011 /******************************************************************************* 1012 * 1013 * FUNCTION: AcpiEvCreateGpeBlock 1014 * 1015 * PARAMETERS: GpeDevice - Handle to the parent GPE block 1016 * GpeBlockAddress - Address and SpaceID 1017 * RegisterCount - Number of GPE register pairs in the block 1018 * GpeBlockBaseNumber - Starting GPE number for the block 1019 * InterruptNumber - H/W interrupt for the block 1020 * ReturnGpeBlock - Where the new block descriptor is returned 1021 * 1022 * RETURN: Status 1023 * 1024 * DESCRIPTION: Create and Install a block of GPE registers. All GPEs within 1025 * the block are disabled at exit. 1026 * Note: Assumes namespace is locked. 1027 * 1028 ******************************************************************************/ 1029 1030 ACPI_STATUS 1031 AcpiEvCreateGpeBlock ( 1032 ACPI_NAMESPACE_NODE *GpeDevice, 1033 ACPI_GENERIC_ADDRESS *GpeBlockAddress, 1034 UINT32 RegisterCount, 1035 UINT8 GpeBlockBaseNumber, 1036 UINT32 InterruptNumber, 1037 ACPI_GPE_BLOCK_INFO **ReturnGpeBlock) 1038 { 1039 ACPI_STATUS Status; 1040 ACPI_GPE_BLOCK_INFO *GpeBlock; 1041 1042 1043 ACPI_FUNCTION_TRACE (EvCreateGpeBlock); 1044 1045 1046 if (!RegisterCount) 1047 { 1048 return_ACPI_STATUS (AE_OK); 1049 } 1050 1051 /* Allocate a new GPE block */ 1052 1053 GpeBlock = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_BLOCK_INFO)); 1054 if (!GpeBlock) 1055 { 1056 return_ACPI_STATUS (AE_NO_MEMORY); 1057 } 1058 1059 /* Initialize the new GPE block */ 1060 1061 GpeBlock->Node = GpeDevice; 1062 GpeBlock->RegisterCount = RegisterCount; 1063 GpeBlock->BlockBaseNumber = GpeBlockBaseNumber; 1064 1065 ACPI_MEMCPY (&GpeBlock->BlockAddress, GpeBlockAddress, 1066 sizeof (ACPI_GENERIC_ADDRESS)); 1067 1068 /* 1069 * Create the RegisterInfo and EventInfo sub-structures 1070 * Note: disables and clears all GPEs in the block 1071 */ 1072 Status = AcpiEvCreateGpeInfoBlocks (GpeBlock); 1073 if (ACPI_FAILURE (Status)) 1074 { 1075 ACPI_FREE (GpeBlock); 1076 return_ACPI_STATUS (Status); 1077 } 1078 1079 /* Install the new block in the global lists */ 1080 1081 Status = AcpiEvInstallGpeBlock (GpeBlock, InterruptNumber); 1082 if (ACPI_FAILURE (Status)) 1083 { 1084 ACPI_FREE (GpeBlock); 1085 return_ACPI_STATUS (Status); 1086 } 1087 1088 /* Find all GPE methods (_Lxx, _Exx) for this block */ 1089 1090 Status = AcpiNsWalkNamespace (ACPI_TYPE_METHOD, GpeDevice, 1091 ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK, 1092 AcpiEvSaveMethodInfo, GpeBlock, NULL); 1093 1094 /* Return the new block */ 1095 1096 if (ReturnGpeBlock) 1097 { 1098 (*ReturnGpeBlock) = GpeBlock; 1099 } 1100 1101 ACPI_DEBUG_PRINT ((ACPI_DB_INIT, 1102 "GPE %02X to %02X [%4.4s] %u regs on int 0x%X\n", 1103 (UINT32) GpeBlock->BlockBaseNumber, 1104 (UINT32) (GpeBlock->BlockBaseNumber + 1105 ((GpeBlock->RegisterCount * ACPI_GPE_REGISTER_WIDTH) -1)), 1106 GpeDevice->Name.Ascii, 1107 GpeBlock->RegisterCount, 1108 InterruptNumber)); 1109 1110 return_ACPI_STATUS (AE_OK); 1111 } 1112 1113 1114 /******************************************************************************* 1115 * 1116 * FUNCTION: AcpiEvInitializeGpeBlock 1117 * 1118 * PARAMETERS: GpeDevice - Handle to the parent GPE block 1119 * GpeBlock - Gpe Block info 1120 * 1121 * RETURN: Status 1122 * 1123 * DESCRIPTION: Initialize and enable a GPE block. First find and run any 1124 * _PRT methods associated with the block, then enable the 1125 * appropriate GPEs. 1126 * Note: Assumes namespace is locked. 1127 * 1128 ******************************************************************************/ 1129 1130 ACPI_STATUS 1131 AcpiEvInitializeGpeBlock ( 1132 ACPI_NAMESPACE_NODE *GpeDevice, 1133 ACPI_GPE_BLOCK_INFO *GpeBlock) 1134 { 1135 ACPI_STATUS Status; 1136 ACPI_GPE_EVENT_INFO *GpeEventInfo; 1137 ACPI_GPE_WALK_INFO GpeInfo; 1138 UINT32 WakeGpeCount; 1139 UINT32 GpeEnabledCount; 1140 ACPI_NATIVE_UINT i; 1141 ACPI_NATIVE_UINT j; 1142 1143 1144 ACPI_FUNCTION_TRACE (EvInitializeGpeBlock); 1145 1146 1147 /* Ignore a null GPE block (e.g., if no GPE block 1 exists) */ 1148 1149 if (!GpeBlock) 1150 { 1151 return_ACPI_STATUS (AE_OK); 1152 } 1153 1154 /* 1155 * Runtime option: Should wake GPEs be enabled at runtime? The default 1156 * is no, they should only be enabled just as the machine goes to sleep. 1157 */ 1158 if (AcpiGbl_LeaveWakeGpesDisabled) 1159 { 1160 /* 1161 * Differentiate runtime vs wake GPEs, via the _PRW control methods. 1162 * Each GPE that has one or more _PRWs that reference it is by 1163 * definition a wake GPE and will not be enabled while the machine 1164 * is running. 1165 */ 1166 GpeInfo.GpeBlock = GpeBlock; 1167 GpeInfo.GpeDevice = GpeDevice; 1168 1169 Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 1170 ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK, 1171 AcpiEvMatchPrwAndGpe, &GpeInfo, NULL); 1172 } 1173 1174 /* 1175 * Enable all GPEs in this block that have these attributes: 1176 * 1) are "runtime" or "run/wake" GPEs, and 1177 * 2) have a corresponding _Lxx or _Exx method 1178 * 1179 * Any other GPEs within this block must be enabled via the AcpiEnableGpe() 1180 * external interface. 1181 */ 1182 WakeGpeCount = 0; 1183 GpeEnabledCount = 0; 1184 1185 for (i = 0; i < GpeBlock->RegisterCount; i++) 1186 { 1187 for (j = 0; j < 8; j++) 1188 { 1189 /* Get the info block for this particular GPE */ 1190 1191 GpeEventInfo = &GpeBlock->EventInfo[(i * ACPI_GPE_REGISTER_WIDTH) + j]; 1192 1193 if (((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) == ACPI_GPE_DISPATCH_METHOD) && 1194 (GpeEventInfo->Flags & ACPI_GPE_TYPE_RUNTIME)) 1195 { 1196 GpeEnabledCount++; 1197 } 1198 1199 if (GpeEventInfo->Flags & ACPI_GPE_TYPE_WAKE) 1200 { 1201 WakeGpeCount++; 1202 } 1203 } 1204 } 1205 1206 ACPI_DEBUG_PRINT ((ACPI_DB_INIT, 1207 "Found %u Wake, Enabled %u Runtime GPEs in this block\n", 1208 WakeGpeCount, GpeEnabledCount)); 1209 1210 /* Enable all valid runtime GPEs found above */ 1211 1212 Status = AcpiHwEnableRuntimeGpeBlock (NULL, GpeBlock); 1213 if (ACPI_FAILURE (Status)) 1214 { 1215 ACPI_ERROR ((AE_INFO, "Could not enable GPEs in GpeBlock %p", 1216 GpeBlock)); 1217 } 1218 1219 return_ACPI_STATUS (Status); 1220 } 1221 1222 1223 /******************************************************************************* 1224 * 1225 * FUNCTION: AcpiEvGpeInitialize 1226 * 1227 * PARAMETERS: None 1228 * 1229 * RETURN: Status 1230 * 1231 * DESCRIPTION: Initialize the GPE data structures 1232 * 1233 ******************************************************************************/ 1234 1235 ACPI_STATUS 1236 AcpiEvGpeInitialize ( 1237 void) 1238 { 1239 UINT32 RegisterCount0 = 0; 1240 UINT32 RegisterCount1 = 0; 1241 UINT32 GpeNumberMax = 0; 1242 ACPI_STATUS Status; 1243 1244 1245 ACPI_FUNCTION_TRACE (EvGpeInitialize); 1246 1247 1248 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 1249 if (ACPI_FAILURE (Status)) 1250 { 1251 return_ACPI_STATUS (Status); 1252 } 1253 1254 /* 1255 * Initialize the GPE Block(s) defined in the FADT 1256 * 1257 * Why the GPE register block lengths are divided by 2: From the ACPI Spec, 1258 * section "General-Purpose Event Registers", we have: 1259 * 1260 * "Each register block contains two registers of equal length 1261 * GPEx_STS and GPEx_EN (where x is 0 or 1). The length of the 1262 * GPE0_STS and GPE0_EN registers is equal to half the GPE0_LEN 1263 * The length of the GPE1_STS and GPE1_EN registers is equal to 1264 * half the GPE1_LEN. If a generic register block is not supported 1265 * then its respective block pointer and block length values in the 1266 * FADT table contain zeros. The GPE0_LEN and GPE1_LEN do not need 1267 * to be the same size." 1268 */ 1269 1270 /* 1271 * Determine the maximum GPE number for this machine. 1272 * 1273 * Note: both GPE0 and GPE1 are optional, and either can exist without 1274 * the other. 1275 * 1276 * If EITHER the register length OR the block address are zero, then that 1277 * particular block is not supported. 1278 */ 1279 if (AcpiGbl_FADT->Gpe0BlkLen && 1280 ACPI_GET_ADDRESS (AcpiGbl_FADT->XGpe0Blk.Address)) 1281 { 1282 /* GPE block 0 exists (has both length and address > 0) */ 1283 1284 RegisterCount0 = (UINT16) (AcpiGbl_FADT->Gpe0BlkLen / 2); 1285 1286 GpeNumberMax = (RegisterCount0 * ACPI_GPE_REGISTER_WIDTH) - 1; 1287 1288 /* Install GPE Block 0 */ 1289 1290 Status = AcpiEvCreateGpeBlock (AcpiGbl_FadtGpeDevice, 1291 &AcpiGbl_FADT->XGpe0Blk, RegisterCount0, 0, 1292 AcpiGbl_FADT->SciInt, &AcpiGbl_GpeFadtBlocks[0]); 1293 1294 if (ACPI_FAILURE (Status)) 1295 { 1296 ACPI_EXCEPTION ((AE_INFO, Status, 1297 "Could not create GPE Block 0")); 1298 } 1299 } 1300 1301 if (AcpiGbl_FADT->Gpe1BlkLen && 1302 ACPI_GET_ADDRESS (AcpiGbl_FADT->XGpe1Blk.Address)) 1303 { 1304 /* GPE block 1 exists (has both length and address > 0) */ 1305 1306 RegisterCount1 = (UINT16) (AcpiGbl_FADT->Gpe1BlkLen / 2); 1307 1308 /* Check for GPE0/GPE1 overlap (if both banks exist) */ 1309 1310 if ((RegisterCount0) && 1311 (GpeNumberMax >= AcpiGbl_FADT->Gpe1Base)) 1312 { 1313 ACPI_ERROR ((AE_INFO, 1314 "GPE0 block (GPE 0 to %d) overlaps the GPE1 block (GPE %d to %d) - Ignoring GPE1", 1315 GpeNumberMax, AcpiGbl_FADT->Gpe1Base, 1316 AcpiGbl_FADT->Gpe1Base + 1317 ((RegisterCount1 * ACPI_GPE_REGISTER_WIDTH) - 1))); 1318 1319 /* Ignore GPE1 block by setting the register count to zero */ 1320 1321 RegisterCount1 = 0; 1322 } 1323 else 1324 { 1325 /* Install GPE Block 1 */ 1326 1327 Status = AcpiEvCreateGpeBlock (AcpiGbl_FadtGpeDevice, 1328 &AcpiGbl_FADT->XGpe1Blk, RegisterCount1, 1329 AcpiGbl_FADT->Gpe1Base, 1330 AcpiGbl_FADT->SciInt, &AcpiGbl_GpeFadtBlocks[1]); 1331 1332 if (ACPI_FAILURE (Status)) 1333 { 1334 ACPI_EXCEPTION ((AE_INFO, Status, 1335 "Could not create GPE Block 1")); 1336 } 1337 1338 /* 1339 * GPE0 and GPE1 do not have to be contiguous in the GPE number 1340 * space. However, GPE0 always starts at GPE number zero. 1341 */ 1342 GpeNumberMax = AcpiGbl_FADT->Gpe1Base + 1343 ((RegisterCount1 * ACPI_GPE_REGISTER_WIDTH) - 1); 1344 } 1345 } 1346 1347 /* Exit if there are no GPE registers */ 1348 1349 if ((RegisterCount0 + RegisterCount1) == 0) 1350 { 1351 /* GPEs are not required by ACPI, this is OK */ 1352 1353 ACPI_DEBUG_PRINT ((ACPI_DB_INIT, 1354 "There are no GPE blocks defined in the FADT\n")); 1355 Status = AE_OK; 1356 goto Cleanup; 1357 } 1358 1359 /* Check for Max GPE number out-of-range */ 1360 1361 if (GpeNumberMax > ACPI_GPE_MAX) 1362 { 1363 ACPI_ERROR ((AE_INFO, 1364 "Maximum GPE number from FADT is too large: 0x%X", 1365 GpeNumberMax)); 1366 Status = AE_BAD_VALUE; 1367 goto Cleanup; 1368 } 1369 1370 Cleanup: 1371 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 1372 return_ACPI_STATUS (AE_OK); 1373 } 1374 1375 1376