hwregs.c revision 116748
1130803Smarcel 2130803Smarcel/******************************************************************************* 3130803Smarcel * 4130803Smarcel * Module Name: hwregs - Read/write access functions for the various ACPI 5130803Smarcel * control and status registers. 6130803Smarcel * $Revision: 142 $ 7130803Smarcel * 8130803Smarcel ******************************************************************************/ 9130803Smarcel 10130803Smarcel/****************************************************************************** 11130803Smarcel * 12130803Smarcel * 1. Copyright Notice 13130803Smarcel * 14130803Smarcel * Some or all of this work - Copyright (c) 1999 - 2003, Intel Corp. 15130803Smarcel * All rights reserved. 16130803Smarcel * 17130803Smarcel * 2. License 18130803Smarcel * 19130803Smarcel * 2.1. This is your license from Intel Corp. under its intellectual property 20130803Smarcel * rights. You may have additional license terms from the party that provided 21130803Smarcel * you this software, covering your right to use that party's intellectual 22130803Smarcel * property rights. 23130803Smarcel * 24130803Smarcel * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 25130803Smarcel * copy of the source code appearing in this file ("Covered Code") an 26130803Smarcel * irrevocable, perpetual, worldwide license under Intel's copyrights in the 27130803Smarcel * base code distributed originally by Intel ("Original Intel Code") to copy, 28130803Smarcel * make derivatives, distribute, use and display any portion of the Covered 29130803Smarcel * Code in any form, with the right to sublicense such rights; and 30130803Smarcel * 31130803Smarcel * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 32130803Smarcel * license (with the right to sublicense), under only those claims of Intel 33130803Smarcel * patents that are infringed by the Original Intel Code, to make, use, sell, 34130803Smarcel * offer to sell, and import the Covered Code and derivative works thereof 35130803Smarcel * solely to the minimum extent necessary to exercise the above copyright 36130803Smarcel * license, and in no event shall the patent license extend to any additions 37130803Smarcel * to or modifications of the Original Intel Code. No other license or right 38130803Smarcel * is granted directly or by implication, estoppel or otherwise; 39130803Smarcel * 40130803Smarcel * The above copyright and patent license is granted only if the following 41130803Smarcel * conditions are met: 42130803Smarcel * 43130803Smarcel * 3. Conditions 44130803Smarcel * 45130803Smarcel * 3.1. Redistribution of Source with Rights to Further Distribute Source. 46130803Smarcel * Redistribution of source code of any substantial portion of the Covered 47130803Smarcel * Code or modification with rights to further distribute source must include 48130803Smarcel * the above Copyright Notice, the above License, this list of Conditions, 49130803Smarcel * and the following Disclaimer and Export Compliance provision. In addition, 50130803Smarcel * Licensee must cause all Covered Code to which Licensee contributes to 51130803Smarcel * contain a file documenting the changes Licensee made to create that Covered 52130803Smarcel * Code and the date of any change. Licensee must include in that file the 53130803Smarcel * documentation of any changes made by any predecessor Licensee. Licensee 54130803Smarcel * must include a prominent statement that the modification is derived, 55130803Smarcel * directly or indirectly, from Original Intel Code. 56130803Smarcel * 57130803Smarcel * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 58130803Smarcel * Redistribution of source code of any substantial portion of the Covered 59130803Smarcel * Code or modification without rights to further distribute source must 60130803Smarcel * include the following Disclaimer and Export Compliance provision in the 61130803Smarcel * documentation and/or other materials provided with distribution. In 62130803Smarcel * addition, Licensee may not authorize further sublicense of source of any 63130803Smarcel * portion of the Covered Code, and must include terms to the effect that the 64130803Smarcel * license from Licensee to its licensee is limited to the intellectual 65130803Smarcel * property embodied in the software Licensee provides to its licensee, and 66130803Smarcel * not to intellectual property embodied in modifications its licensee may 67130803Smarcel * make. 68130803Smarcel * 69130803Smarcel * 3.3. Redistribution of Executable. Redistribution in executable form of any 70130803Smarcel * substantial portion of the Covered Code or modification must reproduce the 71130803Smarcel * above Copyright Notice, and the following Disclaimer and Export Compliance 72130803Smarcel * provision in the documentation and/or other materials provided with the 73130803Smarcel * distribution. 74130803Smarcel * 75130803Smarcel * 3.4. Intel retains all right, title, and interest in and to the Original 76130803Smarcel * Intel Code. 77130803Smarcel * 78130803Smarcel * 3.5. Neither the name Intel nor any other trademark owned or controlled by 79130803Smarcel * Intel shall be used in advertising or otherwise to promote the sale, use or 80130803Smarcel * other dealings in products derived from or relating to the Covered Code 81130803Smarcel * without prior written authorization from Intel. 82130803Smarcel * 83130803Smarcel * 4. Disclaimer and Export Compliance 84130803Smarcel * 85130803Smarcel * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 86130803Smarcel * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 87130803Smarcel * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 88130803Smarcel * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 89130803Smarcel * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 90130803Smarcel * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 91130803Smarcel * PARTICULAR PURPOSE. 92130803Smarcel * 93130803Smarcel * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 94130803Smarcel * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 95130803Smarcel * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 96130803Smarcel * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 97130803Smarcel * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 98130803Smarcel * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 99130803Smarcel * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 100130803Smarcel * LIMITED REMEDY. 101130803Smarcel * 102130803Smarcel * 4.3. Licensee shall not export, either directly or indirectly, any of this 103130803Smarcel * software or system incorporating such software without first obtaining any 104130803Smarcel * required license or other approval from the U. S. Department of Commerce or 105130803Smarcel * any other agency or department of the United States Government. In the 106130803Smarcel * event Licensee exports any such software from the United States or 107130803Smarcel * re-exports any such software from a foreign destination, Licensee shall 108130803Smarcel * ensure that the distribution and export/re-export of the software is in 109130803Smarcel * compliance with all laws, regulations, orders, or other restrictions of the 110130803Smarcel * U.S. Export Administration Regulations. Licensee agrees that neither it nor 111130803Smarcel * any of its subsidiaries will export/re-export any technical data, process, 112130803Smarcel * software, or service, directly or indirectly, to any country for which the 113130803Smarcel * United States government or any agency thereof requires an export license, 114130803Smarcel * other governmental approval, or letter of assurance, without first obtaining 115130803Smarcel * such license, approval or letter. 116130803Smarcel * 117130803Smarcel *****************************************************************************/ 118130803Smarcel 119130803Smarcel#define __HWREGS_C__ 120130803Smarcel 121130803Smarcel#include "acpi.h" 122130803Smarcel#include "acnamesp.h" 123130803Smarcel 124130803Smarcel#define _COMPONENT ACPI_HARDWARE 125130803Smarcel ACPI_MODULE_NAME ("hwregs") 126130803Smarcel 127130803Smarcel 128130803Smarcel/******************************************************************************* 129130803Smarcel * 130130803Smarcel * FUNCTION: AcpiHwClearAcpiStatus 131130803Smarcel * 132130803Smarcel * PARAMETERS: none 133130803Smarcel * 134130803Smarcel * RETURN: none 135130803Smarcel * 136130803Smarcel * DESCRIPTION: Clears all fixed and general purpose status bits 137130803Smarcel * 138130803Smarcel ******************************************************************************/ 139130803Smarcel 140130803SmarcelACPI_STATUS 141130803SmarcelAcpiHwClearAcpiStatus (void) 142130803Smarcel{ 143130803Smarcel ACPI_NATIVE_UINT i; 144130803Smarcel ACPI_STATUS Status; 145130803Smarcel ACPI_GPE_BLOCK_INFO *GpeBlock; 146130803Smarcel 147130803Smarcel 148130803Smarcel ACPI_FUNCTION_TRACE ("HwClearAcpiStatus"); 149130803Smarcel 150130803Smarcel 151130803Smarcel ACPI_DEBUG_PRINT ((ACPI_DB_IO, "About to write %04X to %04X\n", 152130803Smarcel ACPI_BITMASK_ALL_FIXED_STATUS, 153130803Smarcel (UINT16) ACPI_GET_ADDRESS (AcpiGbl_FADT->XPm1aEvtBlk.Address))); 154130803Smarcel 155130803Smarcel 156130803Smarcel Status = AcpiUtAcquireMutex (ACPI_MTX_HARDWARE); 157130803Smarcel if (ACPI_FAILURE (Status)) 158130803Smarcel { 159130803Smarcel return_ACPI_STATUS (Status); 160130803Smarcel } 161130803Smarcel 162130803Smarcel Status = AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_STATUS, 163130803Smarcel ACPI_BITMASK_ALL_FIXED_STATUS); 164130803Smarcel if (ACPI_FAILURE (Status)) 165130803Smarcel { 166130803Smarcel goto UnlockAndExit; 167130803Smarcel } 168130803Smarcel 169130803Smarcel /* Clear the fixed events */ 170130803Smarcel 171130803Smarcel if (ACPI_VALID_ADDRESS (AcpiGbl_FADT->XPm1bEvtBlk.Address)) 172130803Smarcel { 173130803Smarcel Status = AcpiHwLowLevelWrite (16, ACPI_BITMASK_ALL_FIXED_STATUS, 174130803Smarcel &AcpiGbl_FADT->XPm1bEvtBlk, 0); 175130803Smarcel if (ACPI_FAILURE (Status)) 176130803Smarcel { 177130803Smarcel goto UnlockAndExit; 178130803Smarcel } 179130803Smarcel } 180130803Smarcel 181130803Smarcel /* Clear the GPE Bits in all GPE registers in all GPE blocks */ 182130803Smarcel 183130803Smarcel GpeBlock = AcpiGbl_GpeBlockListHead; 184130803Smarcel while (GpeBlock) 185130803Smarcel { 186130803Smarcel for (i = 0; i < GpeBlock->RegisterCount; i++) 187130803Smarcel { 188130803Smarcel Status = AcpiHwLowLevelWrite (8, 0xFF, 189130803Smarcel &GpeBlock->RegisterInfo[i].StatusAddress, (UINT32) 0); 190130803Smarcel if (ACPI_FAILURE (Status)) 191130803Smarcel { 192130803Smarcel goto UnlockAndExit; 193130803Smarcel } 194130803Smarcel } 195130803Smarcel 196130803Smarcel GpeBlock = GpeBlock->Next; 197130803Smarcel } 198130803Smarcel 199130803SmarcelUnlockAndExit: 200 (void) AcpiUtReleaseMutex (ACPI_MTX_HARDWARE); 201 return_ACPI_STATUS (Status); 202} 203 204 205/******************************************************************************* 206 * 207 * FUNCTION: AcpiGetSleepTypeData 208 * 209 * PARAMETERS: SleepState - Numeric sleep state 210 * *SleepTypeA - Where SLP_TYPa is returned 211 * *SleepTypeB - Where SLP_TYPb is returned 212 * 213 * RETURN: Status - ACPI status 214 * 215 * DESCRIPTION: Obtain the SLP_TYPa and SLP_TYPb values for the requested sleep 216 * state. 217 * 218 ******************************************************************************/ 219 220ACPI_STATUS 221AcpiGetSleepTypeData ( 222 UINT8 SleepState, 223 UINT8 *SleepTypeA, 224 UINT8 *SleepTypeB) 225{ 226 ACPI_STATUS Status = AE_OK; 227 ACPI_OPERAND_OBJECT *ObjDesc; 228 229 230 ACPI_FUNCTION_TRACE ("AcpiGetSleepTypeData"); 231 232 233 /* 234 * Validate parameters 235 */ 236 if ((SleepState > ACPI_S_STATES_MAX) || 237 !SleepTypeA || !SleepTypeB) 238 { 239 return_ACPI_STATUS (AE_BAD_PARAMETER); 240 } 241 242 /* 243 * Evaluate the namespace object containing the values for this state 244 */ 245 Status = AcpiNsEvaluateByName ((char *) AcpiGbl_DbSleepStates[SleepState], 246 NULL, &ObjDesc); 247 if (ACPI_FAILURE (Status)) 248 { 249 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%s while evaluating SleepState [%s]\n", 250 AcpiFormatException (Status), AcpiGbl_DbSleepStates[SleepState])); 251 252 return_ACPI_STATUS (Status); 253 } 254 255 /* Must have a return object */ 256 257 if (!ObjDesc) 258 { 259 ACPI_REPORT_ERROR (("Missing Sleep State object\n")); 260 Status = AE_NOT_EXIST; 261 } 262 263 /* It must be of type Package */ 264 265 else if (ACPI_GET_OBJECT_TYPE (ObjDesc) != ACPI_TYPE_PACKAGE) 266 { 267 ACPI_REPORT_ERROR (("Sleep State object not a Package\n")); 268 Status = AE_AML_OPERAND_TYPE; 269 } 270 271 /* The package must have at least two elements */ 272 273 else if (ObjDesc->Package.Count < 2) 274 { 275 ACPI_REPORT_ERROR (("Sleep State package does not have at least two elements\n")); 276 Status = AE_AML_NO_OPERAND; 277 } 278 279 /* The first two elements must both be of type Integer */ 280 281 else if ((ACPI_GET_OBJECT_TYPE (ObjDesc->Package.Elements[0]) != ACPI_TYPE_INTEGER) || 282 (ACPI_GET_OBJECT_TYPE (ObjDesc->Package.Elements[1]) != ACPI_TYPE_INTEGER)) 283 { 284 ACPI_REPORT_ERROR (("Sleep State package elements are not both Integers (%s, %s)\n", 285 AcpiUtGetObjectTypeName (ObjDesc->Package.Elements[0]), 286 AcpiUtGetObjectTypeName (ObjDesc->Package.Elements[1]))); 287 Status = AE_AML_OPERAND_TYPE; 288 } 289 else 290 { 291 /* 292 * Valid _Sx_ package size, type, and value 293 */ 294 *SleepTypeA = (UINT8) (ObjDesc->Package.Elements[0])->Integer.Value; 295 *SleepTypeB = (UINT8) (ObjDesc->Package.Elements[1])->Integer.Value; 296 } 297 298 if (ACPI_FAILURE (Status)) 299 { 300 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "While evaluating SleepState [%s], bad Sleep object %p type %s\n", 301 AcpiGbl_DbSleepStates[SleepState], ObjDesc, AcpiUtGetObjectTypeName (ObjDesc))); 302 } 303 304 AcpiUtRemoveReference (ObjDesc); 305 return_ACPI_STATUS (Status); 306} 307 308 309/******************************************************************************* 310 * 311 * FUNCTION: AcpiHwGetRegisterBitMask 312 * 313 * PARAMETERS: RegisterId - Index of ACPI Register to access 314 * 315 * RETURN: The bit mask to be used when accessing the register 316 * 317 * DESCRIPTION: Map RegisterId into a register bit mask. 318 * 319 ******************************************************************************/ 320 321ACPI_BIT_REGISTER_INFO * 322AcpiHwGetBitRegisterInfo ( 323 UINT32 RegisterId) 324{ 325 ACPI_FUNCTION_NAME ("HwGetBitRegisterInfo"); 326 327 328 if (RegisterId > ACPI_BITREG_MAX) 329 { 330 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid BitRegister ID: %X\n", RegisterId)); 331 return (NULL); 332 } 333 334 return (&AcpiGbl_BitRegisterInfo[RegisterId]); 335} 336 337 338/******************************************************************************* 339 * 340 * FUNCTION: AcpiGetRegister 341 * 342 * PARAMETERS: RegisterId - Index of ACPI Register to access 343 * UseLock - Lock the hardware 344 * 345 * RETURN: Value is read from specified Register. Value returned is 346 * normalized to bit0 (is shifted all the way right) 347 * 348 * DESCRIPTION: ACPI BitRegister read function. 349 * 350 ******************************************************************************/ 351 352ACPI_STATUS 353AcpiGetRegister ( 354 UINT32 RegisterId, 355 UINT32 *ReturnValue, 356 UINT32 Flags) 357{ 358 UINT32 RegisterValue = 0; 359 ACPI_BIT_REGISTER_INFO *BitRegInfo; 360 ACPI_STATUS Status; 361 362 363 ACPI_FUNCTION_TRACE ("AcpiGetRegister"); 364 365 366 /* Get the info structure corresponding to the requested ACPI Register */ 367 368 BitRegInfo = AcpiHwGetBitRegisterInfo (RegisterId); 369 if (!BitRegInfo) 370 { 371 return_ACPI_STATUS (AE_BAD_PARAMETER); 372 } 373 374 if (Flags & ACPI_MTX_LOCK) 375 { 376 Status = AcpiUtAcquireMutex (ACPI_MTX_HARDWARE); 377 if (ACPI_FAILURE (Status)) 378 { 379 return_ACPI_STATUS (Status); 380 } 381 } 382 383 Status = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, 384 BitRegInfo->ParentRegister, &RegisterValue); 385 386 if (Flags & ACPI_MTX_LOCK) 387 { 388 (void) AcpiUtReleaseMutex (ACPI_MTX_HARDWARE); 389 } 390 391 if (ACPI_SUCCESS (Status)) 392 { 393 /* Normalize the value that was read */ 394 395 RegisterValue = ((RegisterValue & BitRegInfo->AccessBitMask) 396 >> BitRegInfo->BitPosition); 397 398 *ReturnValue = RegisterValue; 399 400 ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Read value %X\n", RegisterValue)); 401 } 402 403 return_ACPI_STATUS (Status); 404} 405 406 407/******************************************************************************* 408 * 409 * FUNCTION: AcpiSetRegister 410 * 411 * PARAMETERS: RegisterId - ID of ACPI BitRegister to access 412 * Value - (only used on write) value to write to the 413 * Register, NOT pre-normalized to the bit pos. 414 * Flags - Lock the hardware or not 415 * 416 * RETURN: None 417 * 418 * DESCRIPTION: ACPI Bit Register write function. 419 * 420 ******************************************************************************/ 421 422ACPI_STATUS 423AcpiSetRegister ( 424 UINT32 RegisterId, 425 UINT32 Value, 426 UINT32 Flags) 427{ 428 UINT32 RegisterValue = 0; 429 ACPI_BIT_REGISTER_INFO *BitRegInfo; 430 ACPI_STATUS Status; 431 432 433 ACPI_FUNCTION_TRACE_U32 ("AcpiSetRegister", RegisterId); 434 435 436 /* Get the info structure corresponding to the requested ACPI Register */ 437 438 BitRegInfo = AcpiHwGetBitRegisterInfo (RegisterId); 439 if (!BitRegInfo) 440 { 441 ACPI_REPORT_ERROR (("Bad ACPI HW RegisterId: %X\n", RegisterId)); 442 return_ACPI_STATUS (AE_BAD_PARAMETER); 443 } 444 445 if (Flags & ACPI_MTX_LOCK) 446 { 447 Status = AcpiUtAcquireMutex (ACPI_MTX_HARDWARE); 448 if (ACPI_FAILURE (Status)) 449 { 450 return_ACPI_STATUS (Status); 451 } 452 } 453 454 /* Always do a register read first so we can insert the new bits */ 455 456 Status = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, 457 BitRegInfo->ParentRegister, &RegisterValue); 458 if (ACPI_FAILURE (Status)) 459 { 460 goto UnlockAndExit; 461 } 462 463 /* 464 * Decode the Register ID 465 * Register id = Register block id | bit id 466 * 467 * Check bit id to fine locate Register offset. 468 * Check Mask to determine Register offset, and then read-write. 469 */ 470 switch (BitRegInfo->ParentRegister) 471 { 472 case ACPI_REGISTER_PM1_STATUS: 473 474 /* 475 * Status Registers are different from the rest. Clear by 476 * writing 1, writing 0 has no effect. So, the only relevant 477 * information is the single bit we're interested in, all others should 478 * be written as 0 so they will be left unchanged 479 */ 480 Value = ACPI_REGISTER_PREPARE_BITS (Value, 481 BitRegInfo->BitPosition, BitRegInfo->AccessBitMask); 482 if (Value) 483 { 484 Status = AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, 485 ACPI_REGISTER_PM1_STATUS, (UINT16) Value); 486 RegisterValue = 0; 487 } 488 break; 489 490 491 case ACPI_REGISTER_PM1_ENABLE: 492 493 ACPI_REGISTER_INSERT_VALUE (RegisterValue, BitRegInfo->BitPosition, 494 BitRegInfo->AccessBitMask, Value); 495 496 Status = AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, 497 ACPI_REGISTER_PM1_ENABLE, (UINT16) RegisterValue); 498 break; 499 500 501 case ACPI_REGISTER_PM1_CONTROL: 502 503 /* 504 * Read the PM1 Control register. 505 * Note that at this level, the fact that there are actually TWO 506 * registers (A and B - and that B may not exist) is abstracted. 507 */ 508 ACPI_DEBUG_PRINT ((ACPI_DB_IO, "PM1 control: Read %X\n", RegisterValue)); 509 510 ACPI_REGISTER_INSERT_VALUE (RegisterValue, BitRegInfo->BitPosition, 511 BitRegInfo->AccessBitMask, Value); 512 513 Status = AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, 514 ACPI_REGISTER_PM1_CONTROL, (UINT16) RegisterValue); 515 break; 516 517 518 case ACPI_REGISTER_PM2_CONTROL: 519 520 Status = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, 521 ACPI_REGISTER_PM2_CONTROL, &RegisterValue); 522 if (ACPI_FAILURE (Status)) 523 { 524 goto UnlockAndExit; 525 } 526 527 ACPI_DEBUG_PRINT ((ACPI_DB_IO, "PM2 control: Read %X from %8.8X%8.8X\n", 528 RegisterValue, 529 ACPI_HIDWORD (ACPI_GET_ADDRESS (AcpiGbl_FADT->XPm2CntBlk.Address)), 530 ACPI_LODWORD (ACPI_GET_ADDRESS (AcpiGbl_FADT->XPm2CntBlk.Address)))); 531 532 ACPI_REGISTER_INSERT_VALUE (RegisterValue, BitRegInfo->BitPosition, 533 BitRegInfo->AccessBitMask, Value); 534 535 ACPI_DEBUG_PRINT ((ACPI_DB_IO, "About to write %4.4X to %8.8X%8.8X\n", 536 RegisterValue, 537 ACPI_HIDWORD (ACPI_GET_ADDRESS (AcpiGbl_FADT->XPm2CntBlk.Address)), 538 ACPI_LODWORD (ACPI_GET_ADDRESS (AcpiGbl_FADT->XPm2CntBlk.Address)))); 539 540 Status = AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, 541 ACPI_REGISTER_PM2_CONTROL, (UINT8) (RegisterValue)); 542 break; 543 544 545 default: 546 break; 547 } 548 549 550UnlockAndExit: 551 552 if (Flags & ACPI_MTX_LOCK) 553 { 554 (void) AcpiUtReleaseMutex (ACPI_MTX_HARDWARE); 555 } 556 557 /* Normalize the value that was read */ 558 559 ACPI_DEBUG_EXEC (RegisterValue = ((RegisterValue & BitRegInfo->AccessBitMask) >> BitRegInfo->BitPosition)); 560 561 ACPI_DEBUG_PRINT ((ACPI_DB_IO, "ACPI Register Write actual %X\n", RegisterValue)); 562 return_ACPI_STATUS (Status); 563} 564 565 566/****************************************************************************** 567 * 568 * FUNCTION: AcpiHwRegisterRead 569 * 570 * PARAMETERS: UseLock - Mutex hw access. 571 * RegisterId - RegisterID + Offset. 572 * 573 * RETURN: Value read or written. 574 * 575 * DESCRIPTION: Acpi register read function. Registers are read at the 576 * given offset. 577 * 578 ******************************************************************************/ 579 580ACPI_STATUS 581AcpiHwRegisterRead ( 582 BOOLEAN UseLock, 583 UINT32 RegisterId, 584 UINT32 *ReturnValue) 585{ 586 UINT32 Value1 = 0; 587 UINT32 Value2 = 0; 588 UINT32 BankOffset; 589 ACPI_STATUS Status; 590 591 592 ACPI_FUNCTION_TRACE ("HwRegisterRead"); 593 594 595 if (ACPI_MTX_LOCK == UseLock) 596 { 597 Status = AcpiUtAcquireMutex (ACPI_MTX_HARDWARE); 598 if (ACPI_FAILURE (Status)) 599 { 600 return_ACPI_STATUS (Status); 601 } 602 } 603 604 switch (RegisterId) 605 { 606 case ACPI_REGISTER_PM1_STATUS: /* 16-bit access */ 607 608 Status = AcpiHwLowLevelRead (16, &Value1, &AcpiGbl_FADT->XPm1aEvtBlk, 0); 609 if (ACPI_FAILURE (Status)) 610 { 611 goto UnlockAndExit; 612 } 613 614 Status = AcpiHwLowLevelRead (16, &Value2, &AcpiGbl_FADT->XPm1bEvtBlk, 0); 615 Value1 |= Value2; 616 break; 617 618 619 case ACPI_REGISTER_PM1_ENABLE: /* 16-bit access*/ 620 621 BankOffset = ACPI_DIV_2 (AcpiGbl_FADT->Pm1EvtLen); 622 Status = AcpiHwLowLevelRead (16, &Value1, &AcpiGbl_FADT->XPm1aEvtBlk, BankOffset); 623 if (ACPI_FAILURE (Status)) 624 { 625 goto UnlockAndExit; 626 } 627 628 Status = AcpiHwLowLevelRead (16, &Value2, &AcpiGbl_FADT->XPm1bEvtBlk, BankOffset); 629 Value1 |= Value2; 630 break; 631 632 633 case ACPI_REGISTER_PM1_CONTROL: /* 16-bit access */ 634 635 Status = AcpiHwLowLevelRead (16, &Value1, &AcpiGbl_FADT->XPm1aCntBlk, 0); 636 if (ACPI_FAILURE (Status)) 637 { 638 goto UnlockAndExit; 639 } 640 641 Status = AcpiHwLowLevelRead (16, &Value2, &AcpiGbl_FADT->XPm1bCntBlk, 0); 642 Value1 |= Value2; 643 break; 644 645 646 case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ 647 648 Status = AcpiHwLowLevelRead (8, &Value1, &AcpiGbl_FADT->XPm2CntBlk, 0); 649 break; 650 651 652 case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ 653 654 Status = AcpiHwLowLevelRead (32, &Value1, &AcpiGbl_FADT->XPmTmrBlk, 0); 655 break; 656 657 case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ 658 659 Status = AcpiOsReadPort (AcpiGbl_FADT->SmiCmd, &Value1, 8); 660 break; 661 662 default: 663 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Register ID: %X\n", RegisterId)); 664 Status = AE_BAD_PARAMETER; 665 break; 666 } 667 668UnlockAndExit: 669 if (ACPI_MTX_LOCK == UseLock) 670 { 671 (void) AcpiUtReleaseMutex (ACPI_MTX_HARDWARE); 672 } 673 674 if (ACPI_SUCCESS (Status)) 675 { 676 *ReturnValue = Value1; 677 } 678 679 return_ACPI_STATUS (Status); 680} 681 682 683/****************************************************************************** 684 * 685 * FUNCTION: AcpiHwRegisterWrite 686 * 687 * PARAMETERS: UseLock - Mutex hw access. 688 * RegisterId - RegisterID + Offset. 689 * 690 * RETURN: Value read or written. 691 * 692 * DESCRIPTION: Acpi register Write function. Registers are written at the 693 * given offset. 694 * 695 ******************************************************************************/ 696 697ACPI_STATUS 698AcpiHwRegisterWrite ( 699 BOOLEAN UseLock, 700 UINT32 RegisterId, 701 UINT32 Value) 702{ 703 UINT32 BankOffset; 704 ACPI_STATUS Status; 705 706 707 ACPI_FUNCTION_TRACE ("HwRegisterWrite"); 708 709 710 if (ACPI_MTX_LOCK == UseLock) 711 { 712 Status = AcpiUtAcquireMutex (ACPI_MTX_HARDWARE); 713 if (ACPI_FAILURE (Status)) 714 { 715 return_ACPI_STATUS (Status); 716 } 717 } 718 719 switch (RegisterId) 720 { 721 case ACPI_REGISTER_PM1_STATUS: /* 16-bit access */ 722 723 Status = AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aEvtBlk, 0); 724 if (ACPI_FAILURE (Status)) 725 { 726 goto UnlockAndExit; 727 } 728 729 Status = AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bEvtBlk, 0); 730 break; 731 732 733 case ACPI_REGISTER_PM1_ENABLE: /* 16-bit access*/ 734 735 BankOffset = ACPI_DIV_2 (AcpiGbl_FADT->Pm1EvtLen); 736 Status = AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aEvtBlk, BankOffset); 737 if (ACPI_FAILURE (Status)) 738 { 739 goto UnlockAndExit; 740 } 741 742 Status = AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bEvtBlk, BankOffset); 743 break; 744 745 746 case ACPI_REGISTER_PM1_CONTROL: /* 16-bit access */ 747 748 Status = AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aCntBlk, 0); 749 if (ACPI_FAILURE (Status)) 750 { 751 goto UnlockAndExit; 752 } 753 754 Status = AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bCntBlk, 0); 755 break; 756 757 758 case ACPI_REGISTER_PM1A_CONTROL: /* 16-bit access */ 759 760 Status = AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aCntBlk, 0); 761 break; 762 763 764 case ACPI_REGISTER_PM1B_CONTROL: /* 16-bit access */ 765 766 Status = AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bCntBlk, 0); 767 break; 768 769 770 case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ 771 772 Status = AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XPm2CntBlk, 0); 773 break; 774 775 776 case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ 777 778 Status = AcpiHwLowLevelWrite (32, Value, &AcpiGbl_FADT->XPmTmrBlk, 0); 779 break; 780 781 782 case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ 783 784 /* SMI_CMD is currently always in IO space */ 785 786 Status = AcpiOsWritePort (AcpiGbl_FADT->SmiCmd, (ACPI_INTEGER) Value, 8); 787 break; 788 789 790 default: 791 Status = AE_BAD_PARAMETER; 792 break; 793 } 794 795UnlockAndExit: 796 if (ACPI_MTX_LOCK == UseLock) 797 { 798 (void) AcpiUtReleaseMutex (ACPI_MTX_HARDWARE); 799 } 800 801 return_ACPI_STATUS (Status); 802} 803 804 805/****************************************************************************** 806 * 807 * FUNCTION: AcpiHwLowLevelRead 808 * 809 * PARAMETERS: Register - GAS register structure 810 * Offset - Offset from the base address in the GAS 811 * Width - 8, 16, or 32 812 * 813 * RETURN: Value read 814 * 815 * DESCRIPTION: Read from either memory, IO, or PCI config space. 816 * 817 ******************************************************************************/ 818 819ACPI_STATUS 820AcpiHwLowLevelRead ( 821 UINT32 Width, 822 UINT32 *Value, 823 ACPI_GENERIC_ADDRESS *Reg, 824 UINT32 Offset) 825{ 826 ACPI_PHYSICAL_ADDRESS MemAddress; 827 ACPI_IO_ADDRESS IoAddress; 828 ACPI_PCI_ID PciId; 829 UINT16 PciRegister; 830 ACPI_STATUS Status; 831 832 833 ACPI_FUNCTION_NAME ("HwLowLevelRead"); 834 835 836 /* 837 * Must have a valid pointer to a GAS structure, and 838 * a non-zero address within. However, don't return an error 839 * because the PM1A/B code must not fail if B isn't present. 840 */ 841 if ((!Reg) || 842 (!ACPI_VALID_ADDRESS (Reg->Address))) 843 { 844 return (AE_OK); 845 } 846 *Value = 0; 847 848 /* 849 * Three address spaces supported: 850 * Memory, Io, or PCI config. 851 */ 852 switch (Reg->AddressSpaceId) 853 { 854 case ACPI_ADR_SPACE_SYSTEM_MEMORY: 855 856 MemAddress = (ACPI_GET_ADDRESS (Reg->Address) 857 + (ACPI_PHYSICAL_ADDRESS) Offset); 858 859 Status = AcpiOsReadMemory (MemAddress, Value, Width); 860 break; 861 862 863 case ACPI_ADR_SPACE_SYSTEM_IO: 864 865 IoAddress = (ACPI_IO_ADDRESS) (ACPI_GET_ADDRESS (Reg->Address) 866 + (ACPI_PHYSICAL_ADDRESS) Offset); 867 868 Status = AcpiOsReadPort (IoAddress, Value, Width); 869 break; 870 871 872 case ACPI_ADR_SPACE_PCI_CONFIG: 873 874 PciId.Segment = 0; 875 PciId.Bus = 0; 876 PciId.Device = ACPI_PCI_DEVICE (ACPI_GET_ADDRESS (Reg->Address)); 877 PciId.Function = ACPI_PCI_FUNCTION (ACPI_GET_ADDRESS (Reg->Address)); 878 PciRegister = (UINT16) (ACPI_PCI_REGISTER (ACPI_GET_ADDRESS (Reg->Address)) 879 + Offset); 880 881 Status = AcpiOsReadPciConfiguration (&PciId, PciRegister, Value, Width); 882 break; 883 884 885 default: 886 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unsupported address space: %X\n", Reg->AddressSpaceId)); 887 Status = AE_BAD_PARAMETER; 888 break; 889 } 890 891 return (Status); 892} 893 894 895/****************************************************************************** 896 * 897 * FUNCTION: AcpiHwLowLevelWrite 898 * 899 * PARAMETERS: Width - 8, 16, or 32 900 * Value - To be written 901 * Register - GAS register structure 902 * Offset - Offset from the base address in the GAS 903 * 904 * 905 * RETURN: Value read 906 * 907 * DESCRIPTION: Read from either memory, IO, or PCI config space. 908 * 909 ******************************************************************************/ 910 911ACPI_STATUS 912AcpiHwLowLevelWrite ( 913 UINT32 Width, 914 UINT32 Value, 915 ACPI_GENERIC_ADDRESS *Reg, 916 UINT32 Offset) 917{ 918 ACPI_PHYSICAL_ADDRESS MemAddress; 919 ACPI_IO_ADDRESS IoAddress; 920 ACPI_PCI_ID PciId; 921 UINT16 PciRegister; 922 ACPI_STATUS Status; 923 924 925 ACPI_FUNCTION_NAME ("HwLowLevelWrite"); 926 927 928 /* 929 * Must have a valid pointer to a GAS structure, and 930 * a non-zero address within. However, don't return an error 931 * because the PM1A/B code must not fail if B isn't present. 932 */ 933 if ((!Reg) || 934 (!ACPI_VALID_ADDRESS (Reg->Address))) 935 { 936 return (AE_OK); 937 } 938 /* 939 * Three address spaces supported: 940 * Memory, Io, or PCI config. 941 */ 942 switch (Reg->AddressSpaceId) 943 { 944 case ACPI_ADR_SPACE_SYSTEM_MEMORY: 945 946 MemAddress = (ACPI_GET_ADDRESS (Reg->Address) 947 + (ACPI_PHYSICAL_ADDRESS) Offset); 948 949 Status = AcpiOsWriteMemory (MemAddress, (ACPI_INTEGER) Value, Width); 950 break; 951 952 953 case ACPI_ADR_SPACE_SYSTEM_IO: 954 955 IoAddress = (ACPI_IO_ADDRESS) (ACPI_GET_ADDRESS (Reg->Address) 956 + (ACPI_PHYSICAL_ADDRESS) Offset); 957 958 Status = AcpiOsWritePort (IoAddress, (ACPI_INTEGER) Value, Width); 959 break; 960 961 962 case ACPI_ADR_SPACE_PCI_CONFIG: 963 964 PciId.Segment = 0; 965 PciId.Bus = 0; 966 PciId.Device = ACPI_PCI_DEVICE (ACPI_GET_ADDRESS (Reg->Address)); 967 PciId.Function = ACPI_PCI_FUNCTION (ACPI_GET_ADDRESS (Reg->Address)); 968 PciRegister = (UINT16) (ACPI_PCI_REGISTER (ACPI_GET_ADDRESS (Reg->Address)) 969 + Offset); 970 971 Status = AcpiOsWritePciConfiguration (&PciId, PciRegister, (ACPI_INTEGER) Value, Width); 972 break; 973 974 975 default: 976 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unsupported address space: %X\n", Reg->AddressSpaceId)); 977 Status = AE_BAD_PARAMETER; 978 break; 979 } 980 981 return (Status); 982} 983