hwregs.c revision 151937
1 2/******************************************************************************* 3 * 4 * Module Name: hwregs - Read/write access functions for the various ACPI 5 * control and status registers. 6 * $Revision: 1.172 $ 7 * 8 ******************************************************************************/ 9 10/****************************************************************************** 11 * 12 * 1. Copyright Notice 13 * 14 * Some or all of this work - Copyright (c) 1999 - 2005, Intel Corp. 15 * All rights 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 <contrib/dev/acpica/acpi.h> 122#include <contrib/dev/acpica/acnamesp.h> 123#include <contrib/dev/acpica/acevents.h> 124 125#define _COMPONENT ACPI_HARDWARE 126 ACPI_MODULE_NAME ("hwregs") 127 128 129/******************************************************************************* 130 * 131 * FUNCTION: AcpiHwClearAcpiStatus 132 * 133 * PARAMETERS: Flags - Lock the hardware or not 134 * 135 * RETURN: none 136 * 137 * DESCRIPTION: Clears all fixed and general purpose status bits 138 * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED 139 * 140 ******************************************************************************/ 141 142ACPI_STATUS 143AcpiHwClearAcpiStatus ( 144 UINT32 Flags) 145{ 146 ACPI_STATUS Status; 147 148 149 ACPI_FUNCTION_TRACE ("HwClearAcpiStatus"); 150 151 152 ACPI_DEBUG_PRINT ((ACPI_DB_IO, "About to write %04X to %04X\n", 153 ACPI_BITMASK_ALL_FIXED_STATUS, 154 (UINT16) ACPI_GET_ADDRESS (AcpiGbl_FADT->XPm1aEvtBlk.Address))); 155 156 if (Flags & ACPI_MTX_LOCK) 157 { 158 Status = AcpiUtAcquireMutex (ACPI_MTX_HARDWARE); 159 if (ACPI_FAILURE (Status)) 160 { 161 return_ACPI_STATUS (Status); 162 } 163 } 164 165 Status = AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, 166 ACPI_REGISTER_PM1_STATUS, 167 ACPI_BITMASK_ALL_FIXED_STATUS); 168 if (ACPI_FAILURE (Status)) 169 { 170 goto UnlockAndExit; 171 } 172 173 /* Clear the fixed events */ 174 175 if (ACPI_VALID_ADDRESS (AcpiGbl_FADT->XPm1bEvtBlk.Address)) 176 { 177 Status = AcpiHwLowLevelWrite (16, ACPI_BITMASK_ALL_FIXED_STATUS, 178 &AcpiGbl_FADT->XPm1bEvtBlk); 179 if (ACPI_FAILURE (Status)) 180 { 181 goto UnlockAndExit; 182 } 183 } 184 185 /* Clear the GPE Bits in all GPE registers in all GPE blocks */ 186 187 Status = AcpiEvWalkGpeList (AcpiHwClearGpeBlock); 188 189UnlockAndExit: 190 if (Flags & ACPI_MTX_LOCK) 191 { 192 (void) AcpiUtReleaseMutex (ACPI_MTX_HARDWARE); 193 } 194 return_ACPI_STATUS (Status); 195} 196 197 198/******************************************************************************* 199 * 200 * FUNCTION: AcpiGetSleepTypeData 201 * 202 * PARAMETERS: SleepState - Numeric sleep state 203 * *SleepTypeA - Where SLP_TYPa is returned 204 * *SleepTypeB - Where SLP_TYPb is returned 205 * 206 * RETURN: Status - ACPI status 207 * 208 * DESCRIPTION: Obtain the SLP_TYPa and SLP_TYPb values for the requested sleep 209 * state. 210 * 211 ******************************************************************************/ 212 213ACPI_STATUS 214AcpiGetSleepTypeData ( 215 UINT8 SleepState, 216 UINT8 *SleepTypeA, 217 UINT8 *SleepTypeB) 218{ 219 ACPI_STATUS Status = AE_OK; 220 ACPI_PARAMETER_INFO Info; 221 char *SleepStateName; 222 223 224 ACPI_FUNCTION_TRACE ("AcpiGetSleepTypeData"); 225 226 227 /* Validate parameters */ 228 229 if ((SleepState > ACPI_S_STATES_MAX) || 230 !SleepTypeA || !SleepTypeB) 231 { 232 return_ACPI_STATUS (AE_BAD_PARAMETER); 233 } 234 235 /* Evaluate the namespace object containing the values for this state */ 236 237 Info.Parameters = NULL; 238 Info.ReturnObject = NULL; 239 SleepStateName = (char *) AcpiGbl_SleepStateNames[SleepState]; 240 241 Status = AcpiNsEvaluateByName (SleepStateName, &Info); 242 if (ACPI_FAILURE (Status)) 243 { 244 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 245 "%s while evaluating SleepState [%s]\n", 246 AcpiFormatException (Status), SleepStateName)); 247 248 return_ACPI_STATUS (Status); 249 } 250 251 /* Must have a return object */ 252 253 if (!Info.ReturnObject) 254 { 255 ACPI_REPORT_ERROR (("No Sleep State object returned from [%s]\n", 256 SleepStateName)); 257 Status = AE_NOT_EXIST; 258 } 259 260 /* It must be of type Package */ 261 262 else if (ACPI_GET_OBJECT_TYPE (Info.ReturnObject) != ACPI_TYPE_PACKAGE) 263 { 264 ACPI_REPORT_ERROR (("Sleep State return object is not a Package\n")); 265 Status = AE_AML_OPERAND_TYPE; 266 } 267 268 /* 269 * The package must have at least two elements. NOTE (March 2005): This 270 * goes against the current ACPI spec which defines this object as a 271 * package with one encoded DWORD element. However, existing practice 272 * by BIOS vendors seems to be to have 2 or more elements, at least 273 * one per sleep type (A/B). 274 */ 275 else if (Info.ReturnObject->Package.Count < 2) 276 { 277 ACPI_REPORT_ERROR (( 278 "Sleep State return package does not have at least two elements\n")); 279 Status = AE_AML_NO_OPERAND; 280 } 281 282 /* The first two elements must both be of type Integer */ 283 284 else if ((ACPI_GET_OBJECT_TYPE (Info.ReturnObject->Package.Elements[0]) 285 != ACPI_TYPE_INTEGER) || 286 (ACPI_GET_OBJECT_TYPE (Info.ReturnObject->Package.Elements[1]) 287 != ACPI_TYPE_INTEGER)) 288 { 289 ACPI_REPORT_ERROR (( 290 "Sleep State return package elements are not both Integers (%s, %s)\n", 291 AcpiUtGetObjectTypeName (Info.ReturnObject->Package.Elements[0]), 292 AcpiUtGetObjectTypeName (Info.ReturnObject->Package.Elements[1]))); 293 Status = AE_AML_OPERAND_TYPE; 294 } 295 else 296 { 297 /* Valid _Sx_ package size, type, and value */ 298 299 *SleepTypeA = (UINT8) 300 (Info.ReturnObject->Package.Elements[0])->Integer.Value; 301 *SleepTypeB = (UINT8) 302 (Info.ReturnObject->Package.Elements[1])->Integer.Value; 303 } 304 305 if (ACPI_FAILURE (Status)) 306 { 307 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 308 "%s While evaluating SleepState [%s], bad Sleep object %p type %s\n", 309 AcpiFormatException (Status), 310 SleepStateName, Info.ReturnObject, 311 AcpiUtGetObjectTypeName (Info.ReturnObject))); 312 } 313 314 AcpiUtRemoveReference (Info.ReturnObject); 315 return_ACPI_STATUS (Status); 316} 317 318 319/******************************************************************************* 320 * 321 * FUNCTION: AcpiHwGetRegisterBitMask 322 * 323 * PARAMETERS: RegisterId - Index of ACPI Register to access 324 * 325 * RETURN: The bitmask to be used when accessing the register 326 * 327 * DESCRIPTION: Map RegisterId into a register bitmask. 328 * 329 ******************************************************************************/ 330 331ACPI_BIT_REGISTER_INFO * 332AcpiHwGetBitRegisterInfo ( 333 UINT32 RegisterId) 334{ 335 ACPI_FUNCTION_NAME ("HwGetBitRegisterInfo"); 336 337 338 if (RegisterId > ACPI_BITREG_MAX) 339 { 340 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid BitRegister ID: %X\n", RegisterId)); 341 return (NULL); 342 } 343 344 return (&AcpiGbl_BitRegisterInfo[RegisterId]); 345} 346 347 348/******************************************************************************* 349 * 350 * FUNCTION: AcpiGetRegister 351 * 352 * PARAMETERS: RegisterId - ID of ACPI BitRegister to access 353 * ReturnValue - Value that was read from the register 354 * Flags - Lock the hardware or not 355 * 356 * RETURN: Status and the value read from specified Register. Value 357 * returned is normalized to bit0 (is shifted all the way right) 358 * 359 * DESCRIPTION: ACPI BitRegister read function. 360 * 361 ******************************************************************************/ 362 363ACPI_STATUS 364AcpiGetRegister ( 365 UINT32 RegisterId, 366 UINT32 *ReturnValue, 367 UINT32 Flags) 368{ 369 UINT32 RegisterValue = 0; 370 ACPI_BIT_REGISTER_INFO *BitRegInfo; 371 ACPI_STATUS Status; 372 373 374 ACPI_FUNCTION_TRACE ("AcpiGetRegister"); 375 376 377 /* Get the info structure corresponding to the requested ACPI Register */ 378 379 BitRegInfo = AcpiHwGetBitRegisterInfo (RegisterId); 380 if (!BitRegInfo) 381 { 382 return_ACPI_STATUS (AE_BAD_PARAMETER); 383 } 384 385 if (Flags & ACPI_MTX_LOCK) 386 { 387 Status = AcpiUtAcquireMutex (ACPI_MTX_HARDWARE); 388 if (ACPI_FAILURE (Status)) 389 { 390 return_ACPI_STATUS (Status); 391 } 392 } 393 394 /* Read from the register */ 395 396 Status = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, 397 BitRegInfo->ParentRegister, &RegisterValue); 398 399 if (Flags & ACPI_MTX_LOCK) 400 { 401 (void) AcpiUtReleaseMutex (ACPI_MTX_HARDWARE); 402 } 403 404 if (ACPI_SUCCESS (Status)) 405 { 406 /* Normalize the value that was read */ 407 408 RegisterValue = ((RegisterValue & BitRegInfo->AccessBitMask) 409 >> BitRegInfo->BitPosition); 410 411 *ReturnValue = RegisterValue; 412 413 ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Read value %8.8X register %X\n", 414 RegisterValue, BitRegInfo->ParentRegister)); 415 } 416 417 return_ACPI_STATUS (Status); 418} 419 420 421/******************************************************************************* 422 * 423 * FUNCTION: AcpiSetRegister 424 * 425 * PARAMETERS: RegisterId - ID of ACPI BitRegister to access 426 * Value - (only used on write) value to write to the 427 * Register, NOT pre-normalized to the bit pos 428 * Flags - Lock the hardware or not 429 * 430 * RETURN: Status 431 * 432 * DESCRIPTION: ACPI Bit Register write function. 433 * 434 ******************************************************************************/ 435 436ACPI_STATUS 437AcpiSetRegister ( 438 UINT32 RegisterId, 439 UINT32 Value, 440 UINT32 Flags) 441{ 442 UINT32 RegisterValue = 0; 443 ACPI_BIT_REGISTER_INFO *BitRegInfo; 444 ACPI_STATUS Status; 445 446 447 ACPI_FUNCTION_TRACE_U32 ("AcpiSetRegister", RegisterId); 448 449 450 /* Get the info structure corresponding to the requested ACPI Register */ 451 452 BitRegInfo = AcpiHwGetBitRegisterInfo (RegisterId); 453 if (!BitRegInfo) 454 { 455 ACPI_REPORT_ERROR (("Bad ACPI HW RegisterId: %X\n", RegisterId)); 456 return_ACPI_STATUS (AE_BAD_PARAMETER); 457 } 458 459 if (Flags & ACPI_MTX_LOCK) 460 { 461 Status = AcpiUtAcquireMutex (ACPI_MTX_HARDWARE); 462 if (ACPI_FAILURE (Status)) 463 { 464 return_ACPI_STATUS (Status); 465 } 466 } 467 468 /* Always do a register read first so we can insert the new bits */ 469 470 Status = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, 471 BitRegInfo->ParentRegister, &RegisterValue); 472 if (ACPI_FAILURE (Status)) 473 { 474 goto UnlockAndExit; 475 } 476 477 /* 478 * Decode the Register ID 479 * Register ID = [Register block ID] | [bit ID] 480 * 481 * Check bit ID to fine locate Register offset. 482 * Check Mask to determine Register offset, and then read-write. 483 */ 484 switch (BitRegInfo->ParentRegister) 485 { 486 case ACPI_REGISTER_PM1_STATUS: 487 488 /* 489 * Status Registers are different from the rest. Clear by 490 * writing 1, and writing 0 has no effect. So, the only relevant 491 * information is the single bit we're interested in, all others should 492 * be written as 0 so they will be left unchanged. 493 */ 494 Value = ACPI_REGISTER_PREPARE_BITS (Value, 495 BitRegInfo->BitPosition, BitRegInfo->AccessBitMask); 496 if (Value) 497 { 498 Status = AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, 499 ACPI_REGISTER_PM1_STATUS, (UINT16) Value); 500 RegisterValue = 0; 501 } 502 break; 503 504 505 case ACPI_REGISTER_PM1_ENABLE: 506 507 ACPI_REGISTER_INSERT_VALUE (RegisterValue, BitRegInfo->BitPosition, 508 BitRegInfo->AccessBitMask, Value); 509 510 Status = AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, 511 ACPI_REGISTER_PM1_ENABLE, (UINT16) RegisterValue); 512 break; 513 514 515 case ACPI_REGISTER_PM1_CONTROL: 516 517 /* 518 * Write the PM1 Control register. 519 * Note that at this level, the fact that there are actually TWO 520 * registers (A and B - and B may not exist) is abstracted. 521 */ 522 ACPI_DEBUG_PRINT ((ACPI_DB_IO, "PM1 control: Read %X\n", RegisterValue)); 523 524 ACPI_REGISTER_INSERT_VALUE (RegisterValue, BitRegInfo->BitPosition, 525 BitRegInfo->AccessBitMask, Value); 526 527 Status = AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, 528 ACPI_REGISTER_PM1_CONTROL, (UINT16) RegisterValue); 529 break; 530 531 532 case ACPI_REGISTER_PM2_CONTROL: 533 534 Status = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, 535 ACPI_REGISTER_PM2_CONTROL, &RegisterValue); 536 if (ACPI_FAILURE (Status)) 537 { 538 goto UnlockAndExit; 539 } 540 541 ACPI_DEBUG_PRINT ((ACPI_DB_IO, "PM2 control: Read %X from %8.8X%8.8X\n", 542 RegisterValue, 543 ACPI_FORMAT_UINT64 (ACPI_GET_ADDRESS ( 544 AcpiGbl_FADT->XPm2CntBlk.Address)))); 545 546 ACPI_REGISTER_INSERT_VALUE (RegisterValue, BitRegInfo->BitPosition, 547 BitRegInfo->AccessBitMask, Value); 548 549 ACPI_DEBUG_PRINT ((ACPI_DB_IO, "About to write %4.4X to %8.8X%8.8X\n", 550 RegisterValue, 551 ACPI_FORMAT_UINT64 (ACPI_GET_ADDRESS ( 552 AcpiGbl_FADT->XPm2CntBlk.Address)))); 553 554 Status = AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, 555 ACPI_REGISTER_PM2_CONTROL, (UINT8) (RegisterValue)); 556 break; 557 558 559 default: 560 break; 561 } 562 563 564UnlockAndExit: 565 566 if (Flags & ACPI_MTX_LOCK) 567 { 568 (void) AcpiUtReleaseMutex (ACPI_MTX_HARDWARE); 569 } 570 571 /* Normalize the value that was read */ 572 573 ACPI_DEBUG_EXEC (RegisterValue = 574 ((RegisterValue & BitRegInfo->AccessBitMask) >> 575 BitRegInfo->BitPosition)); 576 577 ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Set bits: %8.8X actual %8.8X register %X\n", 578 Value, RegisterValue, BitRegInfo->ParentRegister)); 579 return_ACPI_STATUS (Status); 580} 581 582 583/****************************************************************************** 584 * 585 * FUNCTION: AcpiHwRegisterRead 586 * 587 * PARAMETERS: UseLock - Mutex hw access 588 * RegisterId - RegisterID + Offset 589 * ReturnValue - Where the register value is returned 590 * 591 * RETURN: Status and the value read. 592 * 593 * DESCRIPTION: Acpi register read function. Registers are read at the 594 * given offset. 595 * 596 ******************************************************************************/ 597 598ACPI_STATUS 599AcpiHwRegisterRead ( 600 BOOLEAN UseLock, 601 UINT32 RegisterId, 602 UINT32 *ReturnValue) 603{ 604 UINT32 Value1 = 0; 605 UINT32 Value2 = 0; 606 ACPI_STATUS Status; 607 608 609 ACPI_FUNCTION_TRACE ("HwRegisterRead"); 610 611 612 if (ACPI_MTX_LOCK == UseLock) 613 { 614 Status = AcpiUtAcquireMutex (ACPI_MTX_HARDWARE); 615 if (ACPI_FAILURE (Status)) 616 { 617 return_ACPI_STATUS (Status); 618 } 619 } 620 621 switch (RegisterId) 622 { 623 case ACPI_REGISTER_PM1_STATUS: /* 16-bit access */ 624 625 Status = AcpiHwLowLevelRead (16, &Value1, &AcpiGbl_FADT->XPm1aEvtBlk); 626 if (ACPI_FAILURE (Status)) 627 { 628 goto UnlockAndExit; 629 } 630 631 /* PM1B is optional */ 632 633 Status = AcpiHwLowLevelRead (16, &Value2, &AcpiGbl_FADT->XPm1bEvtBlk); 634 Value1 |= Value2; 635 break; 636 637 638 case ACPI_REGISTER_PM1_ENABLE: /* 16-bit access */ 639 640 Status = AcpiHwLowLevelRead (16, &Value1, &AcpiGbl_XPm1aEnable); 641 if (ACPI_FAILURE (Status)) 642 { 643 goto UnlockAndExit; 644 } 645 646 /* PM1B is optional */ 647 648 Status = AcpiHwLowLevelRead (16, &Value2, &AcpiGbl_XPm1bEnable); 649 Value1 |= Value2; 650 break; 651 652 653 case ACPI_REGISTER_PM1_CONTROL: /* 16-bit access */ 654 655 Status = AcpiHwLowLevelRead (16, &Value1, &AcpiGbl_FADT->XPm1aCntBlk); 656 if (ACPI_FAILURE (Status)) 657 { 658 goto UnlockAndExit; 659 } 660 661 Status = AcpiHwLowLevelRead (16, &Value2, &AcpiGbl_FADT->XPm1bCntBlk); 662 Value1 |= Value2; 663 break; 664 665 666 case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ 667 668 Status = AcpiHwLowLevelRead (8, &Value1, &AcpiGbl_FADT->XPm2CntBlk); 669 break; 670 671 672 case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ 673 674 Status = AcpiHwLowLevelRead (32, &Value1, &AcpiGbl_FADT->XPmTmrBlk); 675 break; 676 677 case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ 678 679 Status = AcpiOsReadPort (AcpiGbl_FADT->SmiCmd, &Value1, 8); 680 break; 681 682 default: 683 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Register ID: %X\n", 684 RegisterId)); 685 Status = AE_BAD_PARAMETER; 686 break; 687 } 688 689UnlockAndExit: 690 if (ACPI_MTX_LOCK == UseLock) 691 { 692 (void) AcpiUtReleaseMutex (ACPI_MTX_HARDWARE); 693 } 694 695 if (ACPI_SUCCESS (Status)) 696 { 697 *ReturnValue = Value1; 698 } 699 700 return_ACPI_STATUS (Status); 701} 702 703 704/****************************************************************************** 705 * 706 * FUNCTION: AcpiHwRegisterWrite 707 * 708 * PARAMETERS: UseLock - Mutex hw access 709 * RegisterId - RegisterID + Offset 710 * Value - The value to write 711 * 712 * RETURN: Status 713 * 714 * DESCRIPTION: Acpi register Write function. Registers are written at the 715 * given offset. 716 * 717 ******************************************************************************/ 718 719ACPI_STATUS 720AcpiHwRegisterWrite ( 721 BOOLEAN UseLock, 722 UINT32 RegisterId, 723 UINT32 Value) 724{ 725 ACPI_STATUS Status; 726 727 728 ACPI_FUNCTION_TRACE ("HwRegisterWrite"); 729 730 731 if (ACPI_MTX_LOCK == UseLock) 732 { 733 Status = AcpiUtAcquireMutex (ACPI_MTX_HARDWARE); 734 if (ACPI_FAILURE (Status)) 735 { 736 return_ACPI_STATUS (Status); 737 } 738 } 739 740 switch (RegisterId) 741 { 742 case ACPI_REGISTER_PM1_STATUS: /* 16-bit access */ 743 744 Status = AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aEvtBlk); 745 if (ACPI_FAILURE (Status)) 746 { 747 goto UnlockAndExit; 748 } 749 750 /* PM1B is optional */ 751 752 Status = AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bEvtBlk); 753 break; 754 755 756 case ACPI_REGISTER_PM1_ENABLE: /* 16-bit access*/ 757 758 Status = AcpiHwLowLevelWrite (16, Value, &AcpiGbl_XPm1aEnable); 759 if (ACPI_FAILURE (Status)) 760 { 761 goto UnlockAndExit; 762 } 763 764 /* PM1B is optional */ 765 766 Status = AcpiHwLowLevelWrite (16, Value, &AcpiGbl_XPm1bEnable); 767 break; 768 769 770 case ACPI_REGISTER_PM1_CONTROL: /* 16-bit access */ 771 772 Status = AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aCntBlk); 773 if (ACPI_FAILURE (Status)) 774 { 775 goto UnlockAndExit; 776 } 777 778 Status = AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bCntBlk); 779 break; 780 781 782 case ACPI_REGISTER_PM1A_CONTROL: /* 16-bit access */ 783 784 Status = AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aCntBlk); 785 break; 786 787 788 case ACPI_REGISTER_PM1B_CONTROL: /* 16-bit access */ 789 790 Status = AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bCntBlk); 791 break; 792 793 794 case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ 795 796 Status = AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XPm2CntBlk); 797 break; 798 799 800 case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ 801 802 Status = AcpiHwLowLevelWrite (32, Value, &AcpiGbl_FADT->XPmTmrBlk); 803 break; 804 805 806 case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ 807 808 /* SMI_CMD is currently always in IO space */ 809 810 Status = AcpiOsWritePort (AcpiGbl_FADT->SmiCmd, Value, 8); 811 break; 812 813 814 default: 815 Status = AE_BAD_PARAMETER; 816 break; 817 } 818 819UnlockAndExit: 820 if (ACPI_MTX_LOCK == UseLock) 821 { 822 (void) AcpiUtReleaseMutex (ACPI_MTX_HARDWARE); 823 } 824 825 return_ACPI_STATUS (Status); 826} 827 828 829/****************************************************************************** 830 * 831 * FUNCTION: AcpiHwLowLevelRead 832 * 833 * PARAMETERS: Width - 8, 16, or 32 834 * Value - Where the value is returned 835 * Reg - GAS register structure 836 * 837 * RETURN: Status 838 * 839 * DESCRIPTION: Read from either memory or IO space. 840 * 841 ******************************************************************************/ 842 843ACPI_STATUS 844AcpiHwLowLevelRead ( 845 UINT32 Width, 846 UINT32 *Value, 847 ACPI_GENERIC_ADDRESS *Reg) 848{ 849 UINT64 Address; 850 ACPI_STATUS Status; 851 852 853 ACPI_FUNCTION_NAME ("HwLowLevelRead"); 854 855 856 /* 857 * Must have a valid pointer to a GAS structure, and 858 * a non-zero address within. However, don't return an error 859 * because the PM1A/B code must not fail if B isn't present. 860 */ 861 if (!Reg) 862 { 863 return (AE_OK); 864 } 865 866 /* Get a local copy of the address. Handles possible alignment issues */ 867 868 ACPI_MOVE_64_TO_64 (&Address, &Reg->Address); 869 if (!ACPI_VALID_ADDRESS (Address)) 870 { 871 return (AE_OK); 872 } 873 *Value = 0; 874 875 /* 876 * Two address spaces supported: Memory or IO. 877 * PCI_Config is not supported here because the GAS struct is insufficient 878 */ 879 switch (Reg->AddressSpaceId) 880 { 881 case ACPI_ADR_SPACE_SYSTEM_MEMORY: 882 883 Status = AcpiOsReadMemory ( 884 (ACPI_PHYSICAL_ADDRESS) ACPI_GET_ADDRESS (Address), 885 Value, Width); 886 break; 887 888 889 case ACPI_ADR_SPACE_SYSTEM_IO: 890 891 Status = AcpiOsReadPort ((ACPI_IO_ADDRESS) ACPI_GET_ADDRESS (Address), 892 Value, Width); 893 break; 894 895 896 default: 897 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 898 "Unsupported address space: %X\n", Reg->AddressSpaceId)); 899 return (AE_BAD_PARAMETER); 900 } 901 902 ACPI_DEBUG_PRINT ((ACPI_DB_IO, 903 "Read: %8.8X width %2d from %8.8X%8.8X (%s)\n", 904 *Value, Width, 905 ACPI_FORMAT_UINT64 (ACPI_GET_ADDRESS (Address)), 906 AcpiUtGetRegionName (Reg->AddressSpaceId))); 907 908 return (Status); 909} 910 911 912/****************************************************************************** 913 * 914 * FUNCTION: AcpiHwLowLevelWrite 915 * 916 * PARAMETERS: Width - 8, 16, or 32 917 * Value - To be written 918 * Reg - GAS register structure 919 * 920 * RETURN: Status 921 * 922 * DESCRIPTION: Write to either memory or IO space. 923 * 924 ******************************************************************************/ 925 926ACPI_STATUS 927AcpiHwLowLevelWrite ( 928 UINT32 Width, 929 UINT32 Value, 930 ACPI_GENERIC_ADDRESS *Reg) 931{ 932 UINT64 Address; 933 ACPI_STATUS Status; 934 935 936 ACPI_FUNCTION_NAME ("HwLowLevelWrite"); 937 938 939 /* 940 * Must have a valid pointer to a GAS structure, and 941 * a non-zero address within. However, don't return an error 942 * because the PM1A/B code must not fail if B isn't present. 943 */ 944 if (!Reg) 945 { 946 return (AE_OK); 947 } 948 949 /* Get a local copy of the address. Handles possible alignment issues */ 950 951 ACPI_MOVE_64_TO_64 (&Address, &Reg->Address); 952 if (!ACPI_VALID_ADDRESS (Address)) 953 { 954 return (AE_OK); 955 } 956 957 /* 958 * Two address spaces supported: Memory or IO. 959 * PCI_Config is not supported here because the GAS struct is insufficient 960 */ 961 switch (Reg->AddressSpaceId) 962 { 963 case ACPI_ADR_SPACE_SYSTEM_MEMORY: 964 965 Status = AcpiOsWriteMemory ( 966 (ACPI_PHYSICAL_ADDRESS) ACPI_GET_ADDRESS (Address), 967 Value, Width); 968 break; 969 970 971 case ACPI_ADR_SPACE_SYSTEM_IO: 972 973 Status = AcpiOsWritePort ((ACPI_IO_ADDRESS) ACPI_GET_ADDRESS (Address), 974 Value, Width); 975 break; 976 977 978 default: 979 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 980 "Unsupported address space: %X\n", Reg->AddressSpaceId)); 981 return (AE_BAD_PARAMETER); 982 } 983 984 ACPI_DEBUG_PRINT ((ACPI_DB_IO, 985 "Wrote: %8.8X width %2d to %8.8X%8.8X (%s)\n", 986 Value, Width, 987 ACPI_FORMAT_UINT64 (ACPI_GET_ADDRESS (Address)), 988 AcpiUtGetRegionName (Reg->AddressSpaceId))); 989 990 return (Status); 991} 992