hwregs.c revision 67754
1 2/******************************************************************************* 3 * 4 * Module Name: hwregs - Read/write access functions for the various ACPI 5 * control and status registers. 6 * $Revision: 71 $ 7 * 8 ******************************************************************************/ 9 10/****************************************************************************** 11 * 12 * 1. Copyright Notice 13 * 14 * Some or all of this work - Copyright (c) 1999, Intel Corp. All rights 15 * reserved. 16 * 17 * 2. License 18 * 19 * 2.1. This is your license from Intel Corp. under its intellectual property 20 * rights. You may have additional license terms from the party that provided 21 * you this software, covering your right to use that party's intellectual 22 * property rights. 23 * 24 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 25 * copy of the source code appearing in this file ("Covered Code") an 26 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 27 * base code distributed originally by Intel ("Original Intel Code") to copy, 28 * make derivatives, distribute, use and display any portion of the Covered 29 * Code in any form, with the right to sublicense such rights; and 30 * 31 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 32 * license (with the right to sublicense), under only those claims of Intel 33 * patents that are infringed by the Original Intel Code, to make, use, sell, 34 * offer to sell, and import the Covered Code and derivative works thereof 35 * solely to the minimum extent necessary to exercise the above copyright 36 * license, and in no event shall the patent license extend to any additions 37 * to or modifications of the Original Intel Code. No other license or right 38 * is granted directly or by implication, estoppel or otherwise; 39 * 40 * The above copyright and patent license is granted only if the following 41 * conditions are met: 42 * 43 * 3. Conditions 44 * 45 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 46 * Redistribution of source code of any substantial portion of the Covered 47 * Code or modification with rights to further distribute source must include 48 * the above Copyright Notice, the above License, this list of Conditions, 49 * and the following Disclaimer and Export Compliance provision. In addition, 50 * Licensee must cause all Covered Code to which Licensee contributes to 51 * contain a file documenting the changes Licensee made to create that Covered 52 * Code and the date of any change. Licensee must include in that file the 53 * documentation of any changes made by any predecessor Licensee. Licensee 54 * must include a prominent statement that the modification is derived, 55 * directly or indirectly, from Original Intel Code. 56 * 57 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 58 * Redistribution of source code of any substantial portion of the Covered 59 * Code or modification without rights to further distribute source must 60 * include the following Disclaimer and Export Compliance provision in the 61 * documentation and/or other materials provided with distribution. In 62 * addition, Licensee may not authorize further sublicense of source of any 63 * portion of the Covered Code, and must include terms to the effect that the 64 * license from Licensee to its licensee is limited to the intellectual 65 * property embodied in the software Licensee provides to its licensee, and 66 * not to intellectual property embodied in modifications its licensee may 67 * make. 68 * 69 * 3.3. Redistribution of Executable. Redistribution in executable form of any 70 * substantial portion of the Covered Code or modification must reproduce the 71 * above Copyright Notice, and the following Disclaimer and Export Compliance 72 * provision in the documentation and/or other materials provided with the 73 * distribution. 74 * 75 * 3.4. Intel retains all right, title, and interest in and to the Original 76 * Intel Code. 77 * 78 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 79 * Intel shall be used in advertising or otherwise to promote the sale, use or 80 * other dealings in products derived from or relating to the Covered Code 81 * without prior written authorization from Intel. 82 * 83 * 4. Disclaimer and Export Compliance 84 * 85 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 86 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 87 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 88 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 89 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 90 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 91 * PARTICULAR PURPOSE. 92 * 93 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 94 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 95 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 96 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 97 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 98 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 99 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 100 * LIMITED REMEDY. 101 * 102 * 4.3. Licensee shall not export, either directly or indirectly, any of this 103 * software or system incorporating such software without first obtaining any 104 * required license or other approval from the U. S. Department of Commerce or 105 * any other agency or department of the United States Government. In the 106 * event Licensee exports any such software from the United States or 107 * re-exports any such software from a foreign destination, Licensee shall 108 * ensure that the distribution and export/re-export of the software is in 109 * compliance with all laws, regulations, orders, or other restrictions of the 110 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 111 * any of its subsidiaries will export/re-export any technical data, process, 112 * software, or service, directly or indirectly, to any country for which the 113 * United States government or any agency thereof requires an export license, 114 * other governmental approval, or letter of assurance, without first obtaining 115 * such license, approval or letter. 116 * 117 *****************************************************************************/ 118 119#define __HWREGS_C__ 120 121#include "acpi.h" 122#include "achware.h" 123#include "acnamesp.h" 124 125#define _COMPONENT HARDWARE 126 MODULE_NAME ("hwregs") 127 128 129/* This matches the #defines in actypes.h. */ 130 131NATIVE_CHAR *SleepStateTable[] = {"\\_S0_","\\_S1_","\\_S2_","\\_S3_", 132 "\\_S4_","\\_S4B","\\_S5_"}; 133 134 135/******************************************************************************* 136 * 137 * FUNCTION: AcpiHwGetBitShift 138 * 139 * PARAMETERS: Mask - Input mask to determine bit shift from. 140 * Must have at least 1 bit set. 141 * 142 * RETURN: Bit location of the lsb of the mask 143 * 144 * DESCRIPTION: Returns the bit number for the low order bit that's set. 145 * 146 ******************************************************************************/ 147 148UINT32 149AcpiHwGetBitShift ( 150 UINT32 Mask) 151{ 152 UINT32 Shift; 153 154 155 FUNCTION_TRACE ("HwGetBitShift"); 156 157 158 for (Shift = 0; ((Mask >> Shift) & 1) == 0; Shift++) 159 { ; } 160 161 return_VALUE (Shift); 162} 163 164 165/******************************************************************************* 166 * 167 * FUNCTION: AcpiHwClearAcpiStatus 168 * 169 * PARAMETERS: none 170 * 171 * RETURN: none 172 * 173 * DESCRIPTION: Clears all fixed and general purpose status bits 174 * 175 ******************************************************************************/ 176 177void 178AcpiHwClearAcpiStatus (void) 179{ 180 UINT16 GpeLength; 181 UINT16 Index; 182 183 184 FUNCTION_TRACE ("HwClearAcpiStatus"); 185 186 187 DEBUG_PRINT (TRACE_IO, ("About to write %04X to %04X\n", 188 ALL_FIXED_STS_BITS, (UINT16) AcpiGbl_FACP->Pm1aEvtBlk)); 189 190 191 AcpiCmAcquireMutex (ACPI_MTX_HARDWARE); 192 193 AcpiOsOut16 (AcpiGbl_FACP->Pm1aEvtBlk, (UINT16) ALL_FIXED_STS_BITS); 194 195 if (AcpiGbl_FACP->Pm1bEvtBlk) 196 { 197 AcpiOsOut16 ((UINT16) AcpiGbl_FACP->Pm1bEvtBlk, 198 (UINT16) ALL_FIXED_STS_BITS); 199 } 200 201 /* now clear the GPE Bits */ 202 203 if (AcpiGbl_FACP->Gpe0BlkLen) 204 { 205 GpeLength = (UINT16) DIV_2 (AcpiGbl_FACP->Gpe0BlkLen); 206 207 for (Index = 0; Index < GpeLength; Index++) 208 { 209 AcpiOsOut8 ((AcpiGbl_FACP->Gpe0Blk + Index), (UINT8) 0xff); 210 } 211 } 212 213 if (AcpiGbl_FACP->Gpe1BlkLen) 214 { 215 GpeLength = (UINT16) DIV_2 (AcpiGbl_FACP->Gpe1BlkLen); 216 217 for (Index = 0; Index < GpeLength; Index++) 218 { 219 AcpiOsOut8 ((AcpiGbl_FACP->Gpe1Blk + Index), (UINT8) 0xff); 220 } 221 } 222 223 AcpiCmReleaseMutex (ACPI_MTX_HARDWARE); 224 return_VOID; 225} 226 227 228/******************************************************************************* 229 * 230 * FUNCTION: AcpiHwObtainSleepTypeRegisterData 231 * 232 * PARAMETERS: SleepState - Numeric state requested 233 * *Slp_TypA - Pointer to byte to receive SLP_TYPa value 234 * *Slp_TypB - Pointer to byte to receive SLP_TYPb value 235 * 236 * RETURN: Status - ACPI status 237 * 238 * DESCRIPTION: AcpiHwObtainSleepTypeRegisterData() obtains the SLP_TYP and 239 * SLP_TYPb values for the sleep state requested. 240 * 241 ******************************************************************************/ 242 243ACPI_STATUS 244AcpiHwObtainSleepTypeRegisterData ( 245 UINT8 SleepState, 246 UINT8 *Slp_TypA, 247 UINT8 *Slp_TypB) 248{ 249 ACPI_STATUS Status = AE_OK; 250 ACPI_OPERAND_OBJECT *ObjDesc; 251 252 253 FUNCTION_TRACE ("HwObtainSleepTypeRegisterData"); 254 255 256 /* 257 * Validate parameters 258 */ 259 260 if ((SleepState > ACPI_S_STATES_MAX) || 261 !Slp_TypA || !Slp_TypB) 262 { 263 return_ACPI_STATUS (AE_BAD_PARAMETER); 264 } 265 266 /* 267 * AcpiEvaluate the namespace object containing the values for this state 268 */ 269 270 Status = AcpiNsEvaluateByName (SleepStateTable[SleepState], NULL, &ObjDesc); 271 if (ACPI_FAILURE (Status)) 272 { 273 return_ACPI_STATUS (Status); 274 } 275 276 if (!ObjDesc) 277 { 278 REPORT_ERROR (("Missing Sleep State object\n")); 279 return_ACPI_STATUS (AE_NOT_EXIST); 280 } 281 282 /* 283 * We got something, now ensure it is correct. The object must 284 * be a package and must have at least 2 numeric values as the 285 * two elements 286 */ 287 288 Status = AcpiCmResolvePackageReferences(ObjDesc); 289 290 if (ObjDesc->Package.Count < 2) 291 { 292 /* Must have at least two elements */ 293 294 REPORT_ERROR (("Sleep State package does not have at least two elements\n")); 295 Status = AE_ERROR; 296 } 297 298 else if (((ObjDesc->Package.Elements[0])->Common.Type != 299 ACPI_TYPE_NUMBER) || 300 ((ObjDesc->Package.Elements[1])->Common.Type != 301 ACPI_TYPE_NUMBER)) 302 { 303 /* Must have two */ 304 305 REPORT_ERROR (("Sleep State package elements are not both of type Number\n")); 306 Status = AE_ERROR; 307 } 308 309 else 310 { 311 /* 312 * Valid _Sx_ package size, type, and value 313 */ 314 *Slp_TypA = (UINT8) (ObjDesc->Package.Elements[0])->Number.Value; 315 316 *Slp_TypB = (UINT8) (ObjDesc->Package.Elements[1])->Number.Value; 317 } 318 319 320 if (ACPI_FAILURE (Status)) 321 { 322 DEBUG_PRINT (ACPI_ERROR, 323 ("SleepTypeRegisterData: Bad Sleep object %p type %X\n", 324 ObjDesc, ObjDesc->Common.Type)); 325 } 326 327 AcpiCmRemoveReference (ObjDesc); 328 329 return_ACPI_STATUS (Status); 330} 331 332 333/******************************************************************************* 334 * 335 * FUNCTION: AcpiHwRegisterAccess 336 * 337 * PARAMETERS: ReadWrite - Either ACPI_READ or ACPI_WRITE. 338 * UseLock - Lock the hardware 339 * RegisterId - index of ACPI register to access 340 * Value - (only used on write) value to write to the 341 * register. Shifted all the way right. 342 * 343 * RETURN: Value written to or read from specified register. This value 344 * is shifted all the way right. 345 * 346 * DESCRIPTION: Generic ACPI register read/write function. 347 * 348 ******************************************************************************/ 349 350UINT32 351AcpiHwRegisterAccess ( 352 NATIVE_UINT ReadWrite, 353 BOOLEAN UseLock, 354 UINT32 RegisterId, 355 ...) /* Value (only used on write) */ 356{ 357 UINT32 RegisterValue = 0; 358 UINT32 Mask = 0; 359 UINT32 Value = 0; 360 ACPI_IO_ADDRESS GpeReg = 0; 361 362 363 FUNCTION_TRACE ("HwRegisterIO"); 364 365 366 if (ReadWrite == ACPI_WRITE) 367 { 368 va_list marker; 369 370 va_start (marker, RegisterId); 371 Value = va_arg (marker, UINT32); 372 va_end (marker); 373 } 374 375 /* 376 * TBD: [Restructure] May want to split the AcpiEvent code and the 377 * Control code 378 */ 379 380 /* 381 * Decode the Register ID 382 */ 383 384 switch (RegisterId & REGISTER_BLOCK_MASK) 385 { 386 case PM1_EVT: 387 388 if (RegisterId < TMR_EN) 389 { 390 /* status register */ 391 392 if (ACPI_MTX_LOCK == UseLock) 393 { 394 AcpiCmAcquireMutex (ACPI_MTX_HARDWARE); 395 } 396 397 398 RegisterValue = (UINT32) AcpiOsIn16 (AcpiGbl_FACP->Pm1aEvtBlk); 399 DEBUG_PRINT (TRACE_IO, ("PM1a status: Read 0x%X from 0x%X\n", 400 RegisterValue, AcpiGbl_FACP->Pm1aEvtBlk)); 401 402 if (AcpiGbl_FACP->Pm1bEvtBlk) 403 { 404 RegisterValue |= (UINT32) AcpiOsIn16 (AcpiGbl_FACP->Pm1bEvtBlk); 405 DEBUG_PRINT (TRACE_IO, ("PM1b status: Read 0x%X from 0x%X\n", 406 RegisterValue, AcpiGbl_FACP->Pm1bEvtBlk)); 407 } 408 409 switch (RegisterId) 410 { 411 case TMR_STS: 412 Mask = TMR_STS_MASK; 413 break; 414 415 case BM_STS: 416 Mask = BM_STS_MASK; 417 break; 418 419 case GBL_STS: 420 Mask = GBL_STS_MASK; 421 break; 422 423 case PWRBTN_STS: 424 Mask = PWRBTN_STS_MASK; 425 break; 426 427 case SLPBTN_STS: 428 Mask = SLPBTN_STS_MASK; 429 break; 430 431 case RTC_STS: 432 Mask = RTC_STS_MASK; 433 break; 434 435 case WAK_STS: 436 Mask = WAK_STS_MASK; 437 break; 438 439 default: 440 Mask = 0; 441 break; 442 } 443 444 if (ReadWrite == ACPI_WRITE) 445 { 446 /* 447 * Status registers are different from the rest. Clear by 448 * writing 1, writing 0 has no effect. So, the only relevent 449 * information is the single bit we're interested in, all 450 * others should be written as 0 so they will be left 451 * unchanged 452 */ 453 454 Value <<= AcpiHwGetBitShift (Mask); 455 Value &= Mask; 456 457 if (Value) 458 { 459 DEBUG_PRINT (TRACE_IO, 460 ("About to write 0x%X to 0x%X\n", Value, 461 AcpiGbl_FACP->Pm1aEvtBlk)); 462 463 AcpiOsOut16 (AcpiGbl_FACP->Pm1aEvtBlk, (UINT16) Value); 464 465 if (AcpiGbl_FACP->Pm1bEvtBlk) 466 { 467 AcpiOsOut16 (AcpiGbl_FACP->Pm1bEvtBlk, (UINT16) Value); 468 } 469 470 RegisterValue = 0; 471 } 472 } 473 474 if (ACPI_MTX_LOCK == UseLock) 475 { 476 AcpiCmReleaseMutex (ACPI_MTX_HARDWARE); 477 } 478 } 479 480 else 481 { 482 /* enable register */ 483 484 if (ACPI_MTX_LOCK == UseLock) 485 { 486 AcpiCmAcquireMutex (ACPI_MTX_HARDWARE); 487 } 488 489 RegisterValue = (UINT32) AcpiOsIn16 (AcpiGbl_FACP->Pm1aEvtBlk + 490 DIV_2 (AcpiGbl_FACP->Pm1EvtLen)); 491 492 DEBUG_PRINT (TRACE_IO, ("PM1a enable: Read 0x%X from 0x%X\n", 493 RegisterValue, (AcpiGbl_FACP->Pm1aEvtBlk + 494 DIV_2 (AcpiGbl_FACP->Pm1EvtLen)))); 495 496 if (AcpiGbl_FACP->Pm1bEvtBlk) 497 { 498 RegisterValue |= (UINT32) AcpiOsIn16 (AcpiGbl_FACP->Pm1bEvtBlk + 499 DIV_2 (AcpiGbl_FACP->Pm1EvtLen)); 500 501 DEBUG_PRINT (TRACE_IO, ("PM1b enable: Read 0x%X from 0x%X\n", 502 RegisterValue, (AcpiGbl_FACP->Pm1bEvtBlk + 503 DIV_2 (AcpiGbl_FACP->Pm1EvtLen)))); 504 } 505 506 switch (RegisterId) 507 { 508 case TMR_EN: 509 Mask = TMR_EN_MASK; 510 break; 511 512 case GBL_EN: 513 Mask = GBL_EN_MASK; 514 break; 515 516 case PWRBTN_EN: 517 Mask = PWRBTN_EN_MASK; 518 break; 519 520 case SLPBTN_EN: 521 Mask = SLPBTN_EN_MASK; 522 break; 523 524 case RTC_EN: 525 Mask = RTC_EN_MASK; 526 break; 527 528 default: 529 Mask = 0; 530 break; 531 } 532 533 if (ReadWrite == ACPI_WRITE) 534 { 535 RegisterValue &= ~Mask; 536 Value <<= AcpiHwGetBitShift (Mask); 537 Value &= Mask; 538 RegisterValue |= Value; 539 540 DEBUG_PRINT (TRACE_IO, 541 ("About to write %04X to %04X\n", RegisterValue, 542 (AcpiGbl_FACP->Pm1aEvtBlk + 543 DIV_2 (AcpiGbl_FACP->Pm1EvtLen)))); 544 545 AcpiOsOut16 ((AcpiGbl_FACP->Pm1aEvtBlk + 546 DIV_2 (AcpiGbl_FACP->Pm1EvtLen)), 547 (UINT16) RegisterValue); 548 549 if (AcpiGbl_FACP->Pm1bEvtBlk) 550 { 551 AcpiOsOut16 ((AcpiGbl_FACP->Pm1bEvtBlk + 552 DIV_2 (AcpiGbl_FACP->Pm1EvtLen)), 553 (UINT16) RegisterValue); 554 } 555 } 556 if(ACPI_MTX_LOCK == UseLock) 557 { 558 AcpiCmReleaseMutex (ACPI_MTX_HARDWARE); 559 } 560 } 561 break; 562 563 564 case PM1_CONTROL: 565 566 RegisterValue = 0; 567 568 if (ACPI_MTX_LOCK == UseLock) 569 { 570 AcpiCmAcquireMutex (ACPI_MTX_HARDWARE); 571 } 572 573 if (RegisterId != SLP_TYPE_B) 574 { 575 /* 576 * SLP_TYPx registers are written differently 577 * than any other control registers with 578 * respect to A and B registers. The value 579 * for A may be different than the value for B 580 */ 581 582 RegisterValue = (UINT32) AcpiOsIn16 (AcpiGbl_FACP->Pm1aCntBlk); 583 DEBUG_PRINT (TRACE_IO, ("PM1a control: Read 0x%X from 0x%X\n", 584 RegisterValue, AcpiGbl_FACP->Pm1aCntBlk)); 585 } 586 587 if (AcpiGbl_FACP->Pm1bCntBlk && RegisterId != (UINT32) SLP_TYPE_A) 588 { 589 RegisterValue |= (UINT32) AcpiOsIn16 (AcpiGbl_FACP->Pm1bCntBlk); 590 DEBUG_PRINT (TRACE_IO, ("PM1b control: Read 0x%X from 0x%X\n", 591 RegisterValue, AcpiGbl_FACP->Pm1bCntBlk)); 592 } 593 594 switch (RegisterId) 595 { 596 case SCI_EN: 597 Mask = SCI_EN_MASK; 598 break; 599 600 case BM_RLD: 601 Mask = BM_RLD_MASK; 602 break; 603 604 case GBL_RLS: 605 Mask = GBL_RLS_MASK; 606 break; 607 608 case SLP_TYPE_A: 609 case SLP_TYPE_B: 610 Mask = SLP_TYPE_X_MASK; 611 break; 612 613 case SLP_EN: 614 Mask = SLP_EN_MASK; 615 break; 616 617 default: 618 Mask = 0; 619 break; 620 } 621 622 if (ReadWrite == ACPI_WRITE) 623 { 624 RegisterValue &= ~Mask; 625 Value <<= AcpiHwGetBitShift (Mask); 626 Value &= Mask; 627 RegisterValue |= Value; 628 629 /* 630 * SLP_TYPE_x registers are written differently 631 * than any other control registers with 632 * respect to A and B registers. The value 633 * for A may be different than the value for B 634 */ 635 636 if (RegisterId != SLP_TYPE_B) 637 { 638 if (Mask == SLP_EN_MASK) 639 { 640 disable(); /* disable interrupts */ 641 } 642 643 AcpiOsOut16 (AcpiGbl_FACP->Pm1aCntBlk, (UINT16) RegisterValue); 644 645 if (Mask == SLP_EN_MASK) 646 { 647 /* 648 * Enable interrupts, the SCI handler is likely going to 649 * be invoked as soon as interrupts are enabled, since gpe's 650 * and most fixed resume events also generate SCI's. 651 */ 652 enable(); 653 } 654 } 655 656 if (AcpiGbl_FACP->Pm1bCntBlk && RegisterId != (UINT32) SLP_TYPE_A) 657 { 658 AcpiOsOut16 (AcpiGbl_FACP->Pm1bCntBlk, (UINT16) RegisterValue); 659 } 660 } 661 662 if (ACPI_MTX_LOCK == UseLock) 663 { 664 AcpiCmReleaseMutex (ACPI_MTX_HARDWARE); 665 } 666 break; 667 668 669 case PM2_CONTROL: 670 671 if (ACPI_MTX_LOCK == UseLock) 672 { 673 AcpiCmAcquireMutex (ACPI_MTX_HARDWARE); 674 } 675 676 RegisterValue = (UINT32) AcpiOsIn16 (AcpiGbl_FACP->Pm2CntBlk); 677 DEBUG_PRINT (TRACE_IO, ("PM2 control: Read 0x%X from 0x%X\n", 678 RegisterValue, AcpiGbl_FACP->Pm2CntBlk)); 679 680 switch (RegisterId) 681 { 682 case ARB_DIS: 683 Mask = ARB_DIS_MASK; 684 break; 685 686 default: 687 Mask = 0; 688 break; 689 } 690 691 if (ReadWrite == ACPI_WRITE) 692 { 693 RegisterValue &= ~Mask; 694 Value <<= AcpiHwGetBitShift (Mask); 695 Value &= Mask; 696 RegisterValue |= Value; 697 698 DEBUG_PRINT (TRACE_IO, 699 ("About to write %04X to %04X\n", RegisterValue, 700 AcpiGbl_FACP->Pm2CntBlk)); 701 702 AcpiOsOut16 (AcpiGbl_FACP->Pm2CntBlk, (UINT16) RegisterValue); 703 } 704 705 if (ACPI_MTX_LOCK == UseLock) 706 { 707 AcpiCmReleaseMutex (ACPI_MTX_HARDWARE); 708 } 709 break; 710 711 712 case PM_TIMER: 713 714 RegisterValue = AcpiOsIn32 (AcpiGbl_FACP->PmTmrBlk); 715 DEBUG_PRINT (TRACE_IO, ("PM_TIMER: Read 0x%X from 0x%X\n", 716 RegisterValue, AcpiGbl_FACP->PmTmrBlk)); 717 718 Mask = ACPI_UINT32_MAX; 719 break; 720 721 722 case GPE1_EN_BLOCK: 723 724 GpeReg = (AcpiGbl_FACP->Gpe1Blk + AcpiGbl_FACP->Gpe1Base) + 725 (GpeReg + (DIV_2 (AcpiGbl_FACP->Gpe1BlkLen))); 726 727 728 case GPE1_STS_BLOCK: 729 730 if (!GpeReg) 731 { 732 GpeReg = (AcpiGbl_FACP->Gpe1Blk + AcpiGbl_FACP->Gpe1Base); 733 } 734 735 736 case GPE0_EN_BLOCK: 737 738 if (!GpeReg) 739 { 740 GpeReg = AcpiGbl_FACP->Gpe0Blk + DIV_2 (AcpiGbl_FACP->Gpe0BlkLen); 741 } 742 743 744 case GPE0_STS_BLOCK: 745 746 if (!GpeReg) 747 { 748 GpeReg = AcpiGbl_FACP->Gpe0Blk; 749 } 750 751 /* Determine the bit to be accessed */ 752 753 Mask = (((UINT32) RegisterId) & BIT_IN_REGISTER_MASK); 754 Mask = 1 << (Mask-1); 755 756 /* 757 * The base address of the GPE 0 Register Block 758 * Plus 1/2 the length of the GPE 0 Register Block 759 * The enable register is the register following the Status Register 760 * and each register is defined as 1/2 of the total Register Block 761 */ 762 763 /* 764 * This sets the bit within EnableBit that needs to be written to 765 * the register indicated in Mask to a 1, all others are 0 766 */ 767 768 if (Mask > LOW_BYTE) 769 { 770 /* Shift the value 1 byte to the right and add 1 to the register */ 771 772 Mask >>= ONE_BYTE; 773 GpeReg++; 774 } 775 776 /* Now get the current Enable Bits in the selected Reg */ 777 778 if(ACPI_MTX_LOCK == UseLock) 779 { 780 AcpiCmAcquireMutex (ACPI_MTX_HARDWARE); 781 } 782 783 RegisterValue = (UINT32) AcpiOsIn8 (GpeReg); 784 DEBUG_PRINT (TRACE_IO, ("GPE Enable bits: Read 0x%X from 0x%X\n", 785 RegisterValue, GpeReg)); 786 787 if (ReadWrite == ACPI_WRITE) 788 { 789 RegisterValue &= ~Mask; 790 Value <<= AcpiHwGetBitShift (Mask); 791 Value &= Mask; 792 RegisterValue |= Value; 793 794 /* This write will put the Action state into the General Purpose */ 795 796 /* Enable Register indexed by the value in Mask */ 797 798 DEBUG_PRINT (TRACE_IO, ("About to write %04X to %04X\n", 799 RegisterValue, GpeReg)); 800 801 AcpiOsOut8 (GpeReg, (UINT8) RegisterValue); 802 RegisterValue = (UINT32) AcpiOsIn8 (GpeReg); 803 } 804 805 if(ACPI_MTX_LOCK == UseLock) 806 { 807 AcpiCmReleaseMutex (ACPI_MTX_HARDWARE); 808 } 809 break; 810 811 812 case PROCESSOR_BLOCK: 813 default: 814 815 Mask = 0; 816 break; 817 } 818 819 820 RegisterValue &= Mask; 821 RegisterValue >>= AcpiHwGetBitShift (Mask); 822 823 DEBUG_PRINT (TRACE_IO, ("Register I/O: returning 0x%X\n", RegisterValue)); 824 return_VALUE (RegisterValue); 825} 826