1 /****************************************************************************** 2 * 3 * Module Name: hwxface - Public ACPICA hardware interfaces 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2013, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 #include <contrib/dev/acpica/include/acpi.h> 45 #include <contrib/dev/acpica/include/accommon.h> 46 #include <contrib/dev/acpica/include/acnamesp.h> 47 48 #define _COMPONENT ACPI_HARDWARE 49 ACPI_MODULE_NAME ("hwxface") 50 51 52 /****************************************************************************** 53 * 54 * FUNCTION: AcpiReset 55 * 56 * PARAMETERS: None 57 * 58 * RETURN: Status 59 * 60 * DESCRIPTION: Set reset register in memory or IO space. Note: Does not 61 * support reset register in PCI config space, this must be 62 * handled separately. 63 * 64 ******************************************************************************/ 65 66 ACPI_STATUS 67 AcpiReset ( 68 void) 69 { 70 ACPI_GENERIC_ADDRESS *ResetReg; 71 ACPI_STATUS Status; 72 73 74 ACPI_FUNCTION_TRACE (AcpiReset); 75 76 77 ResetReg = &AcpiGbl_FADT.ResetRegister; 78 79 /* Check if the reset register is supported */ 80 81 if (!(AcpiGbl_FADT.Flags & ACPI_FADT_RESET_REGISTER) || 82 !ResetReg->Address) 83 { 84 return_ACPI_STATUS (AE_NOT_EXIST); 85 } 86 87 if (ResetReg->SpaceId == ACPI_ADR_SPACE_SYSTEM_IO) 88 { 89 /* 90 * For I/O space, write directly to the OSL. This bypasses the port 91 * validation mechanism, which may block a valid write to the reset 92 * register. 93 */ 94 Status = AcpiOsWritePort ((ACPI_IO_ADDRESS) ResetReg->Address, 95 AcpiGbl_FADT.ResetValue, ResetReg->BitWidth); 96 } 97 else 98 { 99 /* Write the reset value to the reset register */ 100 101 Status = AcpiHwWrite (AcpiGbl_FADT.ResetValue, ResetReg); 102 } 103 104 return_ACPI_STATUS (Status); 105 } 106 107 ACPI_EXPORT_SYMBOL (AcpiReset) 108 109 110 /****************************************************************************** 111 * 112 * FUNCTION: AcpiRead 113 * 114 * PARAMETERS: Value - Where the value is returned 115 * Reg - GAS register structure 116 * 117 * RETURN: Status 118 * 119 * DESCRIPTION: Read from either memory or IO space. 120 * 121 * LIMITATIONS: <These limitations also apply to AcpiWrite> 122 * BitWidth must be exactly 8, 16, 32, or 64. 123 * SpaceID must be SystemMemory or SystemIO. 124 * BitOffset and AccessWidth are currently ignored, as there has 125 * not been a need to implement these. 126 * 127 ******************************************************************************/ 128 129 ACPI_STATUS 130 AcpiRead ( 131 UINT64 *ReturnValue, 132 ACPI_GENERIC_ADDRESS *Reg) 133 { 134 UINT32 ValueLo; 135 UINT32 ValueHi; 136 UINT32 Width; 137 UINT64 Address; 138 ACPI_STATUS Status; 139 140 141 ACPI_FUNCTION_NAME (AcpiRead); 142 143 144 if (!ReturnValue) 145 { 146 return (AE_BAD_PARAMETER); 147 } 148 149 /* Validate contents of the GAS register. Allow 64-bit transfers */ 150 151 Status = AcpiHwValidateRegister (Reg, 64, &Address); 152 if (ACPI_FAILURE (Status)) 153 { 154 return (Status); 155 } 156 157 /* 158 * Two address spaces supported: Memory or I/O. PCI_Config is 159 * not supported here because the GAS structure is insufficient 160 */ 161 if (Reg->SpaceId == ACPI_ADR_SPACE_SYSTEM_MEMORY) 162 { 163 Status = AcpiOsReadMemory ((ACPI_PHYSICAL_ADDRESS) 164 Address, ReturnValue, Reg->BitWidth); 165 if (ACPI_FAILURE (Status)) 166 { 167 return (Status); 168 } 169 } 170 else /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ 171 { 172 ValueLo = 0; 173 ValueHi = 0; 174 175 Width = Reg->BitWidth; 176 if (Width == 64) 177 { 178 Width = 32; /* Break into two 32-bit transfers */ 179 } 180 181 Status = AcpiHwReadPort ((ACPI_IO_ADDRESS) 182 Address, &ValueLo, Width); 183 if (ACPI_FAILURE (Status)) 184 { 185 return (Status); 186 } 187 188 if (Reg->BitWidth == 64) 189 { 190 /* Read the top 32 bits */ 191 192 Status = AcpiHwReadPort ((ACPI_IO_ADDRESS) 193 (Address + 4), &ValueHi, 32); 194 if (ACPI_FAILURE (Status)) 195 { 196 return (Status); 197 } 198 } 199 200 /* Set the return value only if status is AE_OK */ 201 202 *ReturnValue = (ValueLo | ((UINT64) ValueHi << 32)); 203 } 204 205 ACPI_DEBUG_PRINT ((ACPI_DB_IO, 206 "Read: %8.8X%8.8X width %2d from %8.8X%8.8X (%s)\n", 207 ACPI_FORMAT_UINT64 (*ReturnValue), Reg->BitWidth, 208 ACPI_FORMAT_UINT64 (Address), 209 AcpiUtGetRegionName (Reg->SpaceId))); 210 211 return (AE_OK); 212 } 213 214 ACPI_EXPORT_SYMBOL (AcpiRead) 215 216 217 /****************************************************************************** 218 * 219 * FUNCTION: AcpiWrite 220 * 221 * PARAMETERS: Value - Value to be written 222 * Reg - GAS register structure 223 * 224 * RETURN: Status 225 * 226 * DESCRIPTION: Write to either memory or IO space. 227 * 228 ******************************************************************************/ 229 230 ACPI_STATUS 231 AcpiWrite ( 232 UINT64 Value, 233 ACPI_GENERIC_ADDRESS *Reg) 234 { 235 UINT32 Width; 236 UINT64 Address; 237 ACPI_STATUS Status; 238 239 240 ACPI_FUNCTION_NAME (AcpiWrite); 241 242 243 /* Validate contents of the GAS register. Allow 64-bit transfers */ 244 245 Status = AcpiHwValidateRegister (Reg, 64, &Address); 246 if (ACPI_FAILURE (Status)) 247 { 248 return (Status); 249 } 250 251 /* 252 * Two address spaces supported: Memory or IO. PCI_Config is 253 * not supported here because the GAS structure is insufficient 254 */ 255 if (Reg->SpaceId == ACPI_ADR_SPACE_SYSTEM_MEMORY) 256 { 257 Status = AcpiOsWriteMemory ((ACPI_PHYSICAL_ADDRESS) 258 Address, Value, Reg->BitWidth); 259 if (ACPI_FAILURE (Status)) 260 { 261 return (Status); 262 } 263 } 264 else /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ 265 { 266 Width = Reg->BitWidth; 267 if (Width == 64) 268 { 269 Width = 32; /* Break into two 32-bit transfers */ 270 } 271 272 Status = AcpiHwWritePort ((ACPI_IO_ADDRESS) 273 Address, ACPI_LODWORD (Value), Width); 274 if (ACPI_FAILURE (Status)) 275 { 276 return (Status); 277 } 278 279 if (Reg->BitWidth == 64) 280 { 281 Status = AcpiHwWritePort ((ACPI_IO_ADDRESS) 282 (Address + 4), ACPI_HIDWORD (Value), 32); 283 if (ACPI_FAILURE (Status)) 284 { 285 return (Status); 286 } 287 } 288 } 289 290 ACPI_DEBUG_PRINT ((ACPI_DB_IO, 291 "Wrote: %8.8X%8.8X width %2d to %8.8X%8.8X (%s)\n", 292 ACPI_FORMAT_UINT64 (Value), Reg->BitWidth, 293 ACPI_FORMAT_UINT64 (Address), 294 AcpiUtGetRegionName (Reg->SpaceId))); 295 296 return (Status); 297 } 298 299 ACPI_EXPORT_SYMBOL (AcpiWrite) 300 301 302 #if (!ACPI_REDUCED_HARDWARE) 303 /******************************************************************************* 304 * 305 * FUNCTION: AcpiReadBitRegister 306 * 307 * PARAMETERS: RegisterId - ID of ACPI Bit Register to access 308 * ReturnValue - Value that was read from the register, 309 * normalized to bit position zero. 310 * 311 * RETURN: Status and the value read from the specified Register. Value 312 * returned is normalized to bit0 (is shifted all the way right) 313 * 314 * DESCRIPTION: ACPI BitRegister read function. Does not acquire the HW lock. 315 * 316 * SUPPORTS: Bit fields in PM1 Status, PM1 Enable, PM1 Control, and 317 * PM2 Control. 318 * 319 * Note: The hardware lock is not required when reading the ACPI bit registers 320 * since almost all of them are single bit and it does not matter that 321 * the parent hardware register can be split across two physical 322 * registers. The only multi-bit field is SLP_TYP in the PM1 control 323 * register, but this field does not cross an 8-bit boundary (nor does 324 * it make much sense to actually read this field.) 325 * 326 ******************************************************************************/ 327 328 ACPI_STATUS 329 AcpiReadBitRegister ( 330 UINT32 RegisterId, 331 UINT32 *ReturnValue) 332 { 333 ACPI_BIT_REGISTER_INFO *BitRegInfo; 334 UINT32 RegisterValue; 335 UINT32 Value; 336 ACPI_STATUS Status; 337 338 339 ACPI_FUNCTION_TRACE_U32 (AcpiReadBitRegister, RegisterId); 340 341 342 /* Get the info structure corresponding to the requested ACPI Register */ 343 344 BitRegInfo = AcpiHwGetBitRegisterInfo (RegisterId); 345 if (!BitRegInfo) 346 { 347 return_ACPI_STATUS (AE_BAD_PARAMETER); 348 } 349 350 /* Read the entire parent register */ 351 352 Status = AcpiHwRegisterRead (BitRegInfo->ParentRegister, 353 &RegisterValue); 354 if (ACPI_FAILURE (Status)) 355 { 356 return_ACPI_STATUS (Status); 357 } 358 359 /* Normalize the value that was read, mask off other bits */ 360 361 Value = ((RegisterValue & BitRegInfo->AccessBitMask) 362 >> BitRegInfo->BitPosition); 363 364 ACPI_DEBUG_PRINT ((ACPI_DB_IO, 365 "BitReg %X, ParentReg %X, Actual %8.8X, ReturnValue %8.8X\n", 366 RegisterId, BitRegInfo->ParentRegister, RegisterValue, Value)); 367 368 *ReturnValue = Value; 369 return_ACPI_STATUS (AE_OK); 370 } 371 372 ACPI_EXPORT_SYMBOL (AcpiReadBitRegister) 373 374 375 /******************************************************************************* 376 * 377 * FUNCTION: AcpiWriteBitRegister 378 * 379 * PARAMETERS: RegisterId - ID of ACPI Bit Register to access 380 * Value - Value to write to the register, in bit 381 * position zero. The bit is automatically 382 * shifted to the correct position. 383 * 384 * RETURN: Status 385 * 386 * DESCRIPTION: ACPI Bit Register write function. Acquires the hardware lock 387 * since most operations require a read/modify/write sequence. 388 * 389 * SUPPORTS: Bit fields in PM1 Status, PM1 Enable, PM1 Control, and 390 * PM2 Control. 391 * 392 * Note that at this level, the fact that there may be actually two 393 * hardware registers (A and B - and B may not exist) is abstracted. 394 * 395 ******************************************************************************/ 396 397 ACPI_STATUS 398 AcpiWriteBitRegister ( 399 UINT32 RegisterId, 400 UINT32 Value) 401 { 402 ACPI_BIT_REGISTER_INFO *BitRegInfo; 403 ACPI_CPU_FLAGS LockFlags; 404 UINT32 RegisterValue; 405 ACPI_STATUS Status = AE_OK; 406 407 408 ACPI_FUNCTION_TRACE_U32 (AcpiWriteBitRegister, RegisterId); 409 410 411 /* Get the info structure corresponding to the requested ACPI Register */ 412 413 BitRegInfo = AcpiHwGetBitRegisterInfo (RegisterId); 414 if (!BitRegInfo) 415 { 416 return_ACPI_STATUS (AE_BAD_PARAMETER); 417 } 418 419 LockFlags = AcpiOsAcquireLock (AcpiGbl_HardwareLock); 420 421 /* 422 * At this point, we know that the parent register is one of the 423 * following: PM1 Status, PM1 Enable, PM1 Control, or PM2 Control 424 */ 425 if (BitRegInfo->ParentRegister != ACPI_REGISTER_PM1_STATUS) 426 { 427 /* 428 * 1) Case for PM1 Enable, PM1 Control, and PM2 Control 429 * 430 * Perform a register read to preserve the bits that we are not 431 * interested in 432 */ 433 Status = AcpiHwRegisterRead (BitRegInfo->ParentRegister, 434 &RegisterValue); 435 if (ACPI_FAILURE (Status)) 436 { 437 goto UnlockAndExit; 438 } 439 440 /* 441 * Insert the input bit into the value that was just read 442 * and write the register 443 */ 444 ACPI_REGISTER_INSERT_VALUE (RegisterValue, BitRegInfo->BitPosition, 445 BitRegInfo->AccessBitMask, Value); 446 447 Status = AcpiHwRegisterWrite (BitRegInfo->ParentRegister, 448 RegisterValue); 449 } 450 else 451 { 452 /* 453 * 2) Case for PM1 Status 454 * 455 * The Status register is different from the rest. Clear an event 456 * by writing 1, writing 0 has no effect. So, the only relevant 457 * information is the single bit we're interested in, all others 458 * should be written as 0 so they will be left unchanged. 459 */ 460 RegisterValue = ACPI_REGISTER_PREPARE_BITS (Value, 461 BitRegInfo->BitPosition, BitRegInfo->AccessBitMask); 462 463 /* No need to write the register if value is all zeros */ 464 465 if (RegisterValue) 466 { 467 Status = AcpiHwRegisterWrite (ACPI_REGISTER_PM1_STATUS, 468 RegisterValue); 469 } 470 } 471 472 ACPI_DEBUG_PRINT ((ACPI_DB_IO, 473 "BitReg %X, ParentReg %X, Value %8.8X, Actual %8.8X\n", 474 RegisterId, BitRegInfo->ParentRegister, Value, RegisterValue)); 475 476 477 UnlockAndExit: 478 479 AcpiOsReleaseLock (AcpiGbl_HardwareLock, LockFlags); 480 return_ACPI_STATUS (Status); 481 } 482 483 ACPI_EXPORT_SYMBOL (AcpiWriteBitRegister) 484 485 #endif /* !ACPI_REDUCED_HARDWARE */ 486 487 488 /******************************************************************************* 489 * 490 * FUNCTION: AcpiGetSleepTypeData 491 * 492 * PARAMETERS: SleepState - Numeric sleep state 493 * *SleepTypeA - Where SLP_TYPa is returned 494 * *SleepTypeB - Where SLP_TYPb is returned 495 * 496 * RETURN: Status 497 * 498 * DESCRIPTION: Obtain the SLP_TYPa and SLP_TYPb values for the requested 499 * sleep state via the appropriate \_Sx object. 500 * 501 * The sleep state package returned from the corresponding \_Sx_ object 502 * must contain at least one integer. 503 * 504 * March 2005: 505 * Added support for a package that contains two integers. This 506 * goes against the ACPI specification which defines this object as a 507 * package with one encoded DWORD integer. However, existing practice 508 * by many BIOS vendors is to return a package with 2 or more integer 509 * elements, at least one per sleep type (A/B). 510 * 511 * January 2013: 512 * Therefore, we must be prepared to accept a package with either a 513 * single integer or multiple integers. 514 * 515 * The single integer DWORD format is as follows: 516 * BYTE 0 - Value for the PM1A SLP_TYP register 517 * BYTE 1 - Value for the PM1B SLP_TYP register 518 * BYTE 2-3 - Reserved 519 * 520 * The dual integer format is as follows: 521 * Integer 0 - Value for the PM1A SLP_TYP register 522 * Integer 1 - Value for the PM1A SLP_TYP register 523 * 524 ******************************************************************************/ 525 526 ACPI_STATUS 527 AcpiGetSleepTypeData ( 528 UINT8 SleepState, 529 UINT8 *SleepTypeA, 530 UINT8 *SleepTypeB) 531 { 532 ACPI_STATUS Status; 533 ACPI_EVALUATE_INFO *Info; 534 ACPI_OPERAND_OBJECT **Elements; 535 536 537 ACPI_FUNCTION_TRACE (AcpiGetSleepTypeData); 538 539 540 /* Validate parameters */ 541 542 if ((SleepState > ACPI_S_STATES_MAX) || 543 !SleepTypeA || !SleepTypeB) 544 { 545 return_ACPI_STATUS (AE_BAD_PARAMETER); 546 } 547 548 /* Allocate the evaluation information block */ 549 550 Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO)); 551 if (!Info) 552 { 553 return_ACPI_STATUS (AE_NO_MEMORY); 554 } 555 556 /* 557 * Evaluate the \_Sx namespace object containing the register values 558 * for this state 559 */ 560 Info->RelativePathname = ACPI_CAST_PTR ( 561 char, AcpiGbl_SleepStateNames[SleepState]); 562 Status = AcpiNsEvaluate (Info); 563 if (ACPI_FAILURE (Status)) 564 { 565 goto Cleanup; 566 } 567 568 /* Must have a return object */ 569 570 if (!Info->ReturnObject) 571 { 572 ACPI_ERROR ((AE_INFO, "No Sleep State object returned from [%s]", 573 Info->RelativePathname)); 574 Status = AE_AML_NO_RETURN_VALUE; 575 goto Cleanup; 576 } 577 578 /* Return object must be of type Package */ 579 580 if (Info->ReturnObject->Common.Type != ACPI_TYPE_PACKAGE) 581 { 582 ACPI_ERROR ((AE_INFO, "Sleep State return object is not a Package")); 583 Status = AE_AML_OPERAND_TYPE; 584 goto Cleanup1; 585 } 586 587 /* 588 * Any warnings about the package length or the object types have 589 * already been issued by the predefined name module -- there is no 590 * need to repeat them here. 591 */ 592 Elements = Info->ReturnObject->Package.Elements; 593 switch (Info->ReturnObject->Package.Count) 594 { 595 case 0: 596 597 Status = AE_AML_PACKAGE_LIMIT; 598 break; 599 600 case 1: 601 602 if (Elements[0]->Common.Type != ACPI_TYPE_INTEGER) 603 { 604 Status = AE_AML_OPERAND_TYPE; 605 break; 606 } 607 608 /* A valid _Sx_ package with one integer */ 609 610 *SleepTypeA = (UINT8) Elements[0]->Integer.Value; 611 *SleepTypeB = (UINT8) (Elements[0]->Integer.Value >> 8); 612 break; 613 614 case 2: 615 default: 616 617 if ((Elements[0]->Common.Type != ACPI_TYPE_INTEGER) || 618 (Elements[1]->Common.Type != ACPI_TYPE_INTEGER)) 619 { 620 Status = AE_AML_OPERAND_TYPE; 621 break; 622 } 623 624 /* A valid _Sx_ package with two integers */ 625 626 *SleepTypeA = (UINT8) Elements[0]->Integer.Value; 627 *SleepTypeB = (UINT8) Elements[1]->Integer.Value; 628 break; 629 } 630 631 Cleanup1: 632 AcpiUtRemoveReference (Info->ReturnObject); 633 634 Cleanup: 635 if (ACPI_FAILURE (Status)) 636 { 637 ACPI_EXCEPTION ((AE_INFO, Status, 638 "While evaluating Sleep State [%s]", Info->RelativePathname)); 639 } 640 641 ACPI_FREE (Info); 642 return_ACPI_STATUS (Status); 643 } 644 645 ACPI_EXPORT_SYMBOL (AcpiGetSleepTypeData) 646