1 /****************************************************************************** 2 * 3 * Module Name: evgpeblk - GPE block creation and initialization. 4 * $Revision: 1.62 $ 5 * 6 *****************************************************************************/ 7 8 /****************************************************************************** 9 * 10 * 1. Copyright Notice 11 * 12 * Some or all of this work - Copyright (c) 1999 - 2008, 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 UINT32 i; 290 UINT32 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[((ACPI_SIZE) 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.SciInterrupt) 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.SciInterrupt) 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 else 713 { 714 /* No previous, update list head */ 715 716 AcpiGbl_GpeXruptListHead = GpeXrupt->Next; 717 } 718 719 if (GpeXrupt->Next) 720 { 721 GpeXrupt->Next->Previous = GpeXrupt->Previous; 722 } 723 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 724 725 /* Free the block */ 726 727 ACPI_FREE (GpeXrupt); 728 return_ACPI_STATUS (AE_OK); 729 } 730 731 732 /******************************************************************************* 733 * 734 * FUNCTION: AcpiEvInstallGpeBlock 735 * 736 * PARAMETERS: GpeBlock - New GPE block 737 * InterruptNumber - Xrupt to be associated with this GPE block 738 * 739 * RETURN: Status 740 * 741 * DESCRIPTION: Install new GPE block with mutex support 742 * 743 ******************************************************************************/ 744 745 static ACPI_STATUS 746 AcpiEvInstallGpeBlock ( 747 ACPI_GPE_BLOCK_INFO *GpeBlock, 748 UINT32 InterruptNumber) 749 { 750 ACPI_GPE_BLOCK_INFO *NextGpeBlock; 751 ACPI_GPE_XRUPT_INFO *GpeXruptBlock; 752 ACPI_STATUS Status; 753 ACPI_CPU_FLAGS Flags; 754 755 756 ACPI_FUNCTION_TRACE (EvInstallGpeBlock); 757 758 759 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 760 if (ACPI_FAILURE (Status)) 761 { 762 return_ACPI_STATUS (Status); 763 } 764 765 GpeXruptBlock = AcpiEvGetGpeXruptBlock (InterruptNumber); 766 if (!GpeXruptBlock) 767 { 768 Status = AE_NO_MEMORY; 769 goto UnlockAndExit; 770 } 771 772 /* Install the new block at the end of the list with lock */ 773 774 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 775 if (GpeXruptBlock->GpeBlockListHead) 776 { 777 NextGpeBlock = GpeXruptBlock->GpeBlockListHead; 778 while (NextGpeBlock->Next) 779 { 780 NextGpeBlock = NextGpeBlock->Next; 781 } 782 783 NextGpeBlock->Next = GpeBlock; 784 GpeBlock->Previous = NextGpeBlock; 785 } 786 else 787 { 788 GpeXruptBlock->GpeBlockListHead = GpeBlock; 789 } 790 791 GpeBlock->XruptBlock = GpeXruptBlock; 792 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 793 794 795 UnlockAndExit: 796 Status = AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 797 return_ACPI_STATUS (Status); 798 } 799 800 801 /******************************************************************************* 802 * 803 * FUNCTION: AcpiEvDeleteGpeBlock 804 * 805 * PARAMETERS: GpeBlock - Existing GPE block 806 * 807 * RETURN: Status 808 * 809 * DESCRIPTION: Remove a GPE block 810 * 811 ******************************************************************************/ 812 813 ACPI_STATUS 814 AcpiEvDeleteGpeBlock ( 815 ACPI_GPE_BLOCK_INFO *GpeBlock) 816 { 817 ACPI_STATUS Status; 818 ACPI_CPU_FLAGS Flags; 819 820 821 ACPI_FUNCTION_TRACE (EvInstallGpeBlock); 822 823 824 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 825 if (ACPI_FAILURE (Status)) 826 { 827 return_ACPI_STATUS (Status); 828 } 829 830 /* Disable all GPEs in this block */ 831 832 Status = AcpiHwDisableGpeBlock (GpeBlock->XruptBlock, GpeBlock); 833 834 if (!GpeBlock->Previous && !GpeBlock->Next) 835 { 836 /* This is the last GpeBlock on this interrupt */ 837 838 Status = AcpiEvDeleteGpeXrupt (GpeBlock->XruptBlock); 839 if (ACPI_FAILURE (Status)) 840 { 841 goto UnlockAndExit; 842 } 843 } 844 else 845 { 846 /* Remove the block on this interrupt with lock */ 847 848 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 849 if (GpeBlock->Previous) 850 { 851 GpeBlock->Previous->Next = GpeBlock->Next; 852 } 853 else 854 { 855 GpeBlock->XruptBlock->GpeBlockListHead = GpeBlock->Next; 856 } 857 858 if (GpeBlock->Next) 859 { 860 GpeBlock->Next->Previous = GpeBlock->Previous; 861 } 862 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 863 } 864 865 /* Free the GpeBlock */ 866 867 ACPI_FREE (GpeBlock->RegisterInfo); 868 ACPI_FREE (GpeBlock->EventInfo); 869 ACPI_FREE (GpeBlock); 870 871 UnlockAndExit: 872 Status = AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 873 return_ACPI_STATUS (Status); 874 } 875 876 877 /******************************************************************************* 878 * 879 * FUNCTION: AcpiEvCreateGpeInfoBlocks 880 * 881 * PARAMETERS: GpeBlock - New GPE block 882 * 883 * RETURN: Status 884 * 885 * DESCRIPTION: Create the RegisterInfo and EventInfo blocks for this GPE block 886 * 887 ******************************************************************************/ 888 889 static ACPI_STATUS 890 AcpiEvCreateGpeInfoBlocks ( 891 ACPI_GPE_BLOCK_INFO *GpeBlock) 892 { 893 ACPI_GPE_REGISTER_INFO *GpeRegisterInfo = NULL; 894 ACPI_GPE_EVENT_INFO *GpeEventInfo = NULL; 895 ACPI_GPE_EVENT_INFO *ThisEvent; 896 ACPI_GPE_REGISTER_INFO *ThisRegister; 897 UINT32 i; 898 UINT32 j; 899 ACPI_STATUS Status; 900 901 902 ACPI_FUNCTION_TRACE (EvCreateGpeInfoBlocks); 903 904 905 /* Allocate the GPE register information block */ 906 907 GpeRegisterInfo = ACPI_ALLOCATE_ZEROED ( 908 (ACPI_SIZE) GpeBlock->RegisterCount * 909 sizeof (ACPI_GPE_REGISTER_INFO)); 910 if (!GpeRegisterInfo) 911 { 912 ACPI_ERROR ((AE_INFO, 913 "Could not allocate the GpeRegisterInfo table")); 914 return_ACPI_STATUS (AE_NO_MEMORY); 915 } 916 917 /* 918 * Allocate the GPE EventInfo block. There are eight distinct GPEs 919 * per register. Initialization to zeros is sufficient. 920 */ 921 GpeEventInfo = ACPI_ALLOCATE_ZEROED ( 922 ((ACPI_SIZE) GpeBlock->RegisterCount * 923 ACPI_GPE_REGISTER_WIDTH) * 924 sizeof (ACPI_GPE_EVENT_INFO)); 925 if (!GpeEventInfo) 926 { 927 ACPI_ERROR ((AE_INFO, 928 "Could not allocate the GpeEventInfo table")); 929 Status = AE_NO_MEMORY; 930 goto ErrorExit; 931 } 932 933 /* Save the new Info arrays in the GPE block */ 934 935 GpeBlock->RegisterInfo = GpeRegisterInfo; 936 GpeBlock->EventInfo = GpeEventInfo; 937 938 /* 939 * Initialize the GPE Register and Event structures. A goal of these 940 * tables is to hide the fact that there are two separate GPE register sets 941 * in a given GPE hardware block, the status registers occupy the first half, 942 * and the enable registers occupy the second half. 943 */ 944 ThisRegister = GpeRegisterInfo; 945 ThisEvent = GpeEventInfo; 946 947 for (i = 0; i < GpeBlock->RegisterCount; i++) 948 { 949 /* Init the RegisterInfo for this GPE register (8 GPEs) */ 950 951 ThisRegister->BaseGpeNumber = (UINT8) (GpeBlock->BlockBaseNumber + 952 (i * ACPI_GPE_REGISTER_WIDTH)); 953 954 ThisRegister->StatusAddress.Address = 955 GpeBlock->BlockAddress.Address + i; 956 957 ThisRegister->EnableAddress.Address = 958 GpeBlock->BlockAddress.Address + i + GpeBlock->RegisterCount; 959 960 ThisRegister->StatusAddress.SpaceId = GpeBlock->BlockAddress.SpaceId; 961 ThisRegister->EnableAddress.SpaceId = GpeBlock->BlockAddress.SpaceId; 962 ThisRegister->StatusAddress.BitWidth = ACPI_GPE_REGISTER_WIDTH; 963 ThisRegister->EnableAddress.BitWidth = ACPI_GPE_REGISTER_WIDTH; 964 ThisRegister->StatusAddress.BitOffset = ACPI_GPE_REGISTER_WIDTH; 965 ThisRegister->EnableAddress.BitOffset = ACPI_GPE_REGISTER_WIDTH; 966 967 /* Init the EventInfo for each GPE within this register */ 968 969 for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) 970 { 971 ThisEvent->GpeNumber = (UINT8) (ThisRegister->BaseGpeNumber + j); 972 ThisEvent->RegisterInfo = ThisRegister; 973 ThisEvent++; 974 } 975 976 /* Disable all GPEs within this register */ 977 978 Status = AcpiHwLowLevelWrite (ACPI_GPE_REGISTER_WIDTH, 0x00, 979 &ThisRegister->EnableAddress); 980 if (ACPI_FAILURE (Status)) 981 { 982 goto ErrorExit; 983 } 984 985 /* Clear any pending GPE events within this register */ 986 987 Status = AcpiHwLowLevelWrite (ACPI_GPE_REGISTER_WIDTH, 0xFF, 988 &ThisRegister->StatusAddress); 989 if (ACPI_FAILURE (Status)) 990 { 991 goto ErrorExit; 992 } 993 994 ThisRegister++; 995 } 996 997 return_ACPI_STATUS (AE_OK); 998 999 1000 ErrorExit: 1001 if (GpeRegisterInfo) 1002 { 1003 ACPI_FREE (GpeRegisterInfo); 1004 } 1005 if (GpeEventInfo) 1006 { 1007 ACPI_FREE (GpeEventInfo); 1008 } 1009 1010 return_ACPI_STATUS (Status); 1011 } 1012 1013 1014 /******************************************************************************* 1015 * 1016 * FUNCTION: AcpiEvCreateGpeBlock 1017 * 1018 * PARAMETERS: GpeDevice - Handle to the parent GPE block 1019 * GpeBlockAddress - Address and SpaceID 1020 * RegisterCount - Number of GPE register pairs in the block 1021 * GpeBlockBaseNumber - Starting GPE number for the block 1022 * InterruptNumber - H/W interrupt for the block 1023 * ReturnGpeBlock - Where the new block descriptor is returned 1024 * 1025 * RETURN: Status 1026 * 1027 * DESCRIPTION: Create and Install a block of GPE registers. All GPEs within 1028 * the block are disabled at exit. 1029 * Note: Assumes namespace is locked. 1030 * 1031 ******************************************************************************/ 1032 1033 ACPI_STATUS 1034 AcpiEvCreateGpeBlock ( 1035 ACPI_NAMESPACE_NODE *GpeDevice, 1036 ACPI_GENERIC_ADDRESS *GpeBlockAddress, 1037 UINT32 RegisterCount, 1038 UINT8 GpeBlockBaseNumber, 1039 UINT32 InterruptNumber, 1040 ACPI_GPE_BLOCK_INFO **ReturnGpeBlock) 1041 { 1042 ACPI_STATUS Status; 1043 ACPI_GPE_BLOCK_INFO *GpeBlock; 1044 1045 1046 ACPI_FUNCTION_TRACE (EvCreateGpeBlock); 1047 1048 1049 if (!RegisterCount) 1050 { 1051 return_ACPI_STATUS (AE_OK); 1052 } 1053 1054 /* Allocate a new GPE block */ 1055 1056 GpeBlock = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_BLOCK_INFO)); 1057 if (!GpeBlock) 1058 { 1059 return_ACPI_STATUS (AE_NO_MEMORY); 1060 } 1061 1062 /* Initialize the new GPE block */ 1063 1064 GpeBlock->Node = GpeDevice; 1065 GpeBlock->RegisterCount = RegisterCount; 1066 GpeBlock->BlockBaseNumber = GpeBlockBaseNumber; 1067 1068 ACPI_MEMCPY (&GpeBlock->BlockAddress, GpeBlockAddress, 1069 sizeof (ACPI_GENERIC_ADDRESS)); 1070 1071 /* 1072 * Create the RegisterInfo and EventInfo sub-structures 1073 * Note: disables and clears all GPEs in the block 1074 */ 1075 Status = AcpiEvCreateGpeInfoBlocks (GpeBlock); 1076 if (ACPI_FAILURE (Status)) 1077 { 1078 ACPI_FREE (GpeBlock); 1079 return_ACPI_STATUS (Status); 1080 } 1081 1082 /* Install the new block in the global lists */ 1083 1084 Status = AcpiEvInstallGpeBlock (GpeBlock, InterruptNumber); 1085 if (ACPI_FAILURE (Status)) 1086 { 1087 ACPI_FREE (GpeBlock); 1088 return_ACPI_STATUS (Status); 1089 } 1090 1091 /* Find all GPE methods (_Lxx, _Exx) for this block */ 1092 1093 Status = AcpiNsWalkNamespace (ACPI_TYPE_METHOD, GpeDevice, 1094 ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK, 1095 AcpiEvSaveMethodInfo, GpeBlock, NULL); 1096 1097 /* Return the new block */ 1098 1099 if (ReturnGpeBlock) 1100 { 1101 (*ReturnGpeBlock) = GpeBlock; 1102 } 1103 1104 ACPI_DEBUG_PRINT ((ACPI_DB_INIT, 1105 "GPE %02X to %02X [%4.4s] %u regs on int 0x%X\n", 1106 (UINT32) GpeBlock->BlockBaseNumber, 1107 (UINT32) (GpeBlock->BlockBaseNumber + 1108 ((GpeBlock->RegisterCount * ACPI_GPE_REGISTER_WIDTH) -1)), 1109 GpeDevice->Name.Ascii, 1110 GpeBlock->RegisterCount, 1111 InterruptNumber)); 1112 1113 return_ACPI_STATUS (AE_OK); 1114 } 1115 1116 1117 /******************************************************************************* 1118 * 1119 * FUNCTION: AcpiEvInitializeGpeBlock 1120 * 1121 * PARAMETERS: GpeDevice - Handle to the parent GPE block 1122 * GpeBlock - Gpe Block info 1123 * 1124 * RETURN: Status 1125 * 1126 * DESCRIPTION: Initialize and enable a GPE block. First find and run any 1127 * _PRT methods associated with the block, then enable the 1128 * appropriate GPEs. 1129 * Note: Assumes namespace is locked. 1130 * 1131 ******************************************************************************/ 1132 1133 ACPI_STATUS 1134 AcpiEvInitializeGpeBlock ( 1135 ACPI_NAMESPACE_NODE *GpeDevice, 1136 ACPI_GPE_BLOCK_INFO *GpeBlock) 1137 { 1138 ACPI_STATUS Status; 1139 ACPI_GPE_EVENT_INFO *GpeEventInfo; 1140 ACPI_GPE_WALK_INFO GpeInfo; 1141 UINT32 WakeGpeCount; 1142 UINT32 GpeEnabledCount; 1143 UINT32 i; 1144 UINT32 j; 1145 1146 1147 ACPI_FUNCTION_TRACE (EvInitializeGpeBlock); 1148 1149 1150 /* Ignore a null GPE block (e.g., if no GPE block 1 exists) */ 1151 1152 if (!GpeBlock) 1153 { 1154 return_ACPI_STATUS (AE_OK); 1155 } 1156 1157 /* 1158 * Runtime option: Should wake GPEs be enabled at runtime? The default 1159 * is no, they should only be enabled just as the machine goes to sleep. 1160 */ 1161 if (AcpiGbl_LeaveWakeGpesDisabled) 1162 { 1163 /* 1164 * Differentiate runtime vs wake GPEs, via the _PRW control methods. 1165 * Each GPE that has one or more _PRWs that reference it is by 1166 * definition a wake GPE and will not be enabled while the machine 1167 * is running. 1168 */ 1169 GpeInfo.GpeBlock = GpeBlock; 1170 GpeInfo.GpeDevice = GpeDevice; 1171 1172 Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 1173 ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK, 1174 AcpiEvMatchPrwAndGpe, &GpeInfo, NULL); 1175 } 1176 1177 /* 1178 * Enable all GPEs in this block that have these attributes: 1179 * 1) are "runtime" or "run/wake" GPEs, and 1180 * 2) have a corresponding _Lxx or _Exx method 1181 * 1182 * Any other GPEs within this block must be enabled via the AcpiEnableGpe() 1183 * external interface. 1184 */ 1185 WakeGpeCount = 0; 1186 GpeEnabledCount = 0; 1187 1188 for (i = 0; i < GpeBlock->RegisterCount; i++) 1189 { 1190 for (j = 0; j < 8; j++) 1191 { 1192 /* Get the info block for this particular GPE */ 1193 1194 GpeEventInfo = &GpeBlock->EventInfo[((ACPI_SIZE) i * ACPI_GPE_REGISTER_WIDTH) + j]; 1195 1196 if (((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) == ACPI_GPE_DISPATCH_METHOD) && 1197 (GpeEventInfo->Flags & ACPI_GPE_TYPE_RUNTIME)) 1198 { 1199 GpeEnabledCount++; 1200 } 1201 1202 if (GpeEventInfo->Flags & ACPI_GPE_TYPE_WAKE) 1203 { 1204 WakeGpeCount++; 1205 } 1206 } 1207 } 1208 1209 ACPI_DEBUG_PRINT ((ACPI_DB_INIT, 1210 "Found %u Wake, Enabled %u Runtime GPEs in this block\n", 1211 WakeGpeCount, GpeEnabledCount)); 1212 1213 /* Enable all valid runtime GPEs found above */ 1214 1215 Status = AcpiHwEnableRuntimeGpeBlock (NULL, GpeBlock); 1216 if (ACPI_FAILURE (Status)) 1217 { 1218 ACPI_ERROR ((AE_INFO, "Could not enable GPEs in GpeBlock %p", 1219 GpeBlock)); 1220 } 1221 1222 return_ACPI_STATUS (Status); 1223 } 1224 1225 1226 /******************************************************************************* 1227 * 1228 * FUNCTION: AcpiEvGpeInitialize 1229 * 1230 * PARAMETERS: None 1231 * 1232 * RETURN: Status 1233 * 1234 * DESCRIPTION: Initialize the GPE data structures 1235 * 1236 ******************************************************************************/ 1237 1238 ACPI_STATUS 1239 AcpiEvGpeInitialize ( 1240 void) 1241 { 1242 UINT32 RegisterCount0 = 0; 1243 UINT32 RegisterCount1 = 0; 1244 UINT32 GpeNumberMax = 0; 1245 ACPI_STATUS Status; 1246 1247 1248 ACPI_FUNCTION_TRACE (EvGpeInitialize); 1249 1250 1251 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 1252 if (ACPI_FAILURE (Status)) 1253 { 1254 return_ACPI_STATUS (Status); 1255 } 1256 1257 /* 1258 * Initialize the GPE Block(s) defined in the FADT 1259 * 1260 * Why the GPE register block lengths are divided by 2: From the ACPI Spec, 1261 * section "General-Purpose Event Registers", we have: 1262 * 1263 * "Each register block contains two registers of equal length 1264 * GPEx_STS and GPEx_EN (where x is 0 or 1). The length of the 1265 * GPE0_STS and GPE0_EN registers is equal to half the GPE0_LEN 1266 * The length of the GPE1_STS and GPE1_EN registers is equal to 1267 * half the GPE1_LEN. If a generic register block is not supported 1268 * then its respective block pointer and block length values in the 1269 * FADT table contain zeros. The GPE0_LEN and GPE1_LEN do not need 1270 * to be the same size." 1271 */ 1272 1273 /* 1274 * Determine the maximum GPE number for this machine. 1275 * 1276 * Note: both GPE0 and GPE1 are optional, and either can exist without 1277 * the other. 1278 * 1279 * If EITHER the register length OR the block address are zero, then that 1280 * particular block is not supported. 1281 */ 1282 if (AcpiGbl_FADT.Gpe0BlockLength && 1283 AcpiGbl_FADT.XGpe0Block.Address) 1284 { 1285 /* GPE block 0 exists (has both length and address > 0) */ 1286 1287 RegisterCount0 = (UINT16) (AcpiGbl_FADT.Gpe0BlockLength / 2); 1288 1289 GpeNumberMax = (RegisterCount0 * ACPI_GPE_REGISTER_WIDTH) - 1; 1290 1291 /* Install GPE Block 0 */ 1292 1293 Status = AcpiEvCreateGpeBlock (AcpiGbl_FadtGpeDevice, 1294 &AcpiGbl_FADT.XGpe0Block, RegisterCount0, 0, 1295 AcpiGbl_FADT.SciInterrupt, &AcpiGbl_GpeFadtBlocks[0]); 1296 1297 if (ACPI_FAILURE (Status)) 1298 { 1299 ACPI_EXCEPTION ((AE_INFO, Status, 1300 "Could not create GPE Block 0")); 1301 } 1302 } 1303 1304 if (AcpiGbl_FADT.Gpe1BlockLength && 1305 AcpiGbl_FADT.XGpe1Block.Address) 1306 { 1307 /* GPE block 1 exists (has both length and address > 0) */ 1308 1309 RegisterCount1 = (UINT16) (AcpiGbl_FADT.Gpe1BlockLength / 2); 1310 1311 /* Check for GPE0/GPE1 overlap (if both banks exist) */ 1312 1313 if ((RegisterCount0) && 1314 (GpeNumberMax >= AcpiGbl_FADT.Gpe1Base)) 1315 { 1316 ACPI_ERROR ((AE_INFO, 1317 "GPE0 block (GPE 0 to %d) overlaps the GPE1 block (GPE %d to %d) - Ignoring GPE1", 1318 GpeNumberMax, AcpiGbl_FADT.Gpe1Base, 1319 AcpiGbl_FADT.Gpe1Base + 1320 ((RegisterCount1 * ACPI_GPE_REGISTER_WIDTH) - 1))); 1321 1322 /* Ignore GPE1 block by setting the register count to zero */ 1323 1324 RegisterCount1 = 0; 1325 } 1326 else 1327 { 1328 /* Install GPE Block 1 */ 1329 1330 Status = AcpiEvCreateGpeBlock (AcpiGbl_FadtGpeDevice, 1331 &AcpiGbl_FADT.XGpe1Block, RegisterCount1, 1332 AcpiGbl_FADT.Gpe1Base, 1333 AcpiGbl_FADT.SciInterrupt, &AcpiGbl_GpeFadtBlocks[1]); 1334 1335 if (ACPI_FAILURE (Status)) 1336 { 1337 ACPI_EXCEPTION ((AE_INFO, Status, 1338 "Could not create GPE Block 1")); 1339 } 1340 1341 /* 1342 * GPE0 and GPE1 do not have to be contiguous in the GPE number 1343 * space. However, GPE0 always starts at GPE number zero. 1344 */ 1345 GpeNumberMax = AcpiGbl_FADT.Gpe1Base + 1346 ((RegisterCount1 * ACPI_GPE_REGISTER_WIDTH) - 1); 1347 } 1348 } 1349 1350 /* Exit if there are no GPE registers */ 1351 1352 if ((RegisterCount0 + RegisterCount1) == 0) 1353 { 1354 /* GPEs are not required by ACPI, this is OK */ 1355 1356 ACPI_DEBUG_PRINT ((ACPI_DB_INIT, 1357 "There are no GPE blocks defined in the FADT\n")); 1358 Status = AE_OK; 1359 goto Cleanup; 1360 } 1361 1362 /* Check for Max GPE number out-of-range */ 1363 1364 if (GpeNumberMax > ACPI_GPE_MAX) 1365 { 1366 ACPI_ERROR ((AE_INFO, 1367 "Maximum GPE number from FADT is too large: 0x%X", 1368 GpeNumberMax)); 1369 Status = AE_BAD_VALUE; 1370 goto Cleanup; 1371 } 1372 1373 Cleanup: 1374 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 1375 return_ACPI_STATUS (AE_OK); 1376 } 1377 1378 1379