1 /******************************************************************************* 2 * 3 * Module Name: hwregs - Read/write access functions for the various ACPI 4 * control and status registers. 5 * 6 ******************************************************************************/ 7 8 /* 9 * Copyright (C) 2000 - 2012, Intel Corp. 10 * All rights reserved. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions, and the following disclaimer, 17 * without modification. 18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 19 * substantially similar to the "NO WARRANTY" disclaimer below 20 * ("Disclaimer") and any redistribution must be conditioned upon 21 * including a substantially similar Disclaimer requirement for further 22 * binary redistribution. 23 * 3. Neither the names of the above-listed copyright holders nor the names 24 * of any contributors may be used to endorse or promote products derived 25 * from this software without specific prior written permission. 26 * 27 * Alternatively, this software may be distributed under the terms of the 28 * GNU General Public License ("GPL") version 2 as published by the Free 29 * Software Foundation. 30 * 31 * NO WARRANTY 32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 42 * POSSIBILITY OF SUCH DAMAGES. 43 */ 44 45 #include <acpi/acpi.h> 46 #include "accommon.h" 47 #include "acnamesp.h" 48 #include "acevents.h" 49 50 #define _COMPONENT ACPI_HARDWARE 51 ACPI_MODULE_NAME("hwregs") 52 53 #if (!ACPI_REDUCED_HARDWARE) 54 /* Local Prototypes */ 55 static acpi_status 56 acpi_hw_read_multiple(u32 *value, 57 struct acpi_generic_address *register_a, 58 struct acpi_generic_address *register_b); 59 60 static acpi_status 61 acpi_hw_write_multiple(u32 value, 62 struct acpi_generic_address *register_a, 63 struct acpi_generic_address *register_b); 64 65 #endif /* !ACPI_REDUCED_HARDWARE */ 66 67 /****************************************************************************** 68 * 69 * FUNCTION: acpi_hw_validate_register 70 * 71 * PARAMETERS: reg - GAS register structure 72 * max_bit_width - Max bit_width supported (32 or 64) 73 * address - Pointer to where the gas->address 74 * is returned 75 * 76 * RETURN: Status 77 * 78 * DESCRIPTION: Validate the contents of a GAS register. Checks the GAS 79 * pointer, Address, space_id, bit_width, and bit_offset. 80 * 81 ******************************************************************************/ 82 83 acpi_status 84 acpi_hw_validate_register(struct acpi_generic_address *reg, 85 u8 max_bit_width, u64 *address) 86 { 87 88 /* Must have a valid pointer to a GAS structure */ 89 90 if (!reg) { 91 return (AE_BAD_PARAMETER); 92 } 93 94 /* 95 * Copy the target address. This handles possible alignment issues. 96 * Address must not be null. A null address also indicates an optional 97 * ACPI register that is not supported, so no error message. 98 */ 99 ACPI_MOVE_64_TO_64(address, ®->address); 100 if (!(*address)) { 101 return (AE_BAD_ADDRESS); 102 } 103 104 /* Validate the space_ID */ 105 106 if ((reg->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) && 107 (reg->space_id != ACPI_ADR_SPACE_SYSTEM_IO)) { 108 ACPI_ERROR((AE_INFO, 109 "Unsupported address space: 0x%X", reg->space_id)); 110 return (AE_SUPPORT); 111 } 112 113 /* Validate the bit_width */ 114 115 if ((reg->bit_width != 8) && 116 (reg->bit_width != 16) && 117 (reg->bit_width != 32) && (reg->bit_width != max_bit_width)) { 118 ACPI_ERROR((AE_INFO, 119 "Unsupported register bit width: 0x%X", 120 reg->bit_width)); 121 return (AE_SUPPORT); 122 } 123 124 /* Validate the bit_offset. Just a warning for now. */ 125 126 if (reg->bit_offset != 0) { 127 ACPI_WARNING((AE_INFO, 128 "Unsupported register bit offset: 0x%X", 129 reg->bit_offset)); 130 } 131 132 return (AE_OK); 133 } 134 135 /****************************************************************************** 136 * 137 * FUNCTION: acpi_hw_read 138 * 139 * PARAMETERS: value - Where the value is returned 140 * reg - GAS register structure 141 * 142 * RETURN: Status 143 * 144 * DESCRIPTION: Read from either memory or IO space. This is a 32-bit max 145 * version of acpi_read, used internally since the overhead of 146 * 64-bit values is not needed. 147 * 148 * LIMITATIONS: <These limitations also apply to acpi_hw_write> 149 * bit_width must be exactly 8, 16, or 32. 150 * space_ID must be system_memory or system_IO. 151 * bit_offset and access_width are currently ignored, as there has 152 * not been a need to implement these. 153 * 154 ******************************************************************************/ 155 156 acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg) 157 { 158 u64 address; 159 u64 value64; 160 acpi_status status; 161 162 ACPI_FUNCTION_NAME(hw_read); 163 164 /* Validate contents of the GAS register */ 165 166 status = acpi_hw_validate_register(reg, 32, &address); 167 if (ACPI_FAILURE(status)) { 168 return (status); 169 } 170 171 /* Initialize entire 32-bit return value to zero */ 172 173 *value = 0; 174 175 /* 176 * Two address spaces supported: Memory or IO. PCI_Config is 177 * not supported here because the GAS structure is insufficient 178 */ 179 if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { 180 status = acpi_os_read_memory((acpi_physical_address) 181 address, &value64, reg->bit_width); 182 183 *value = (u32)value64; 184 } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ 185 186 status = acpi_hw_read_port((acpi_io_address) 187 address, value, reg->bit_width); 188 } 189 190 ACPI_DEBUG_PRINT((ACPI_DB_IO, 191 "Read: %8.8X width %2d from %8.8X%8.8X (%s)\n", 192 *value, reg->bit_width, ACPI_FORMAT_UINT64(address), 193 acpi_ut_get_region_name(reg->space_id))); 194 195 return (status); 196 } 197 198 /****************************************************************************** 199 * 200 * FUNCTION: acpi_hw_write 201 * 202 * PARAMETERS: value - Value to be written 203 * reg - GAS register structure 204 * 205 * RETURN: Status 206 * 207 * DESCRIPTION: Write to either memory or IO space. This is a 32-bit max 208 * version of acpi_write, used internally since the overhead of 209 * 64-bit values is not needed. 210 * 211 ******************************************************************************/ 212 213 acpi_status acpi_hw_write(u32 value, struct acpi_generic_address *reg) 214 { 215 u64 address; 216 acpi_status status; 217 218 ACPI_FUNCTION_NAME(hw_write); 219 220 /* Validate contents of the GAS register */ 221 222 status = acpi_hw_validate_register(reg, 32, &address); 223 if (ACPI_FAILURE(status)) { 224 return (status); 225 } 226 227 /* 228 * Two address spaces supported: Memory or IO. PCI_Config is 229 * not supported here because the GAS structure is insufficient 230 */ 231 if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { 232 status = acpi_os_write_memory((acpi_physical_address) 233 address, (u64)value, 234 reg->bit_width); 235 } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ 236 237 status = acpi_hw_write_port((acpi_io_address) 238 address, value, reg->bit_width); 239 } 240 241 ACPI_DEBUG_PRINT((ACPI_DB_IO, 242 "Wrote: %8.8X width %2d to %8.8X%8.8X (%s)\n", 243 value, reg->bit_width, ACPI_FORMAT_UINT64(address), 244 acpi_ut_get_region_name(reg->space_id))); 245 246 return (status); 247 } 248 249 #if (!ACPI_REDUCED_HARDWARE) 250 /******************************************************************************* 251 * 252 * FUNCTION: acpi_hw_clear_acpi_status 253 * 254 * PARAMETERS: None 255 * 256 * RETURN: Status 257 * 258 * DESCRIPTION: Clears all fixed and general purpose status bits 259 * 260 ******************************************************************************/ 261 262 acpi_status acpi_hw_clear_acpi_status(void) 263 { 264 acpi_status status; 265 acpi_cpu_flags lock_flags = 0; 266 267 ACPI_FUNCTION_TRACE(hw_clear_acpi_status); 268 269 ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %04X to %8.8X%8.8X\n", 270 ACPI_BITMASK_ALL_FIXED_STATUS, 271 ACPI_FORMAT_UINT64(acpi_gbl_xpm1a_status.address))); 272 273 lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); 274 275 /* Clear the fixed events in PM1 A/B */ 276 277 status = acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS, 278 ACPI_BITMASK_ALL_FIXED_STATUS); 279 280 acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags); 281 282 if (ACPI_FAILURE(status)) 283 goto exit; 284 285 /* Clear the GPE Bits in all GPE registers in all GPE blocks */ 286 287 status = acpi_ev_walk_gpe_list(acpi_hw_clear_gpe_block, NULL); 288 289 exit: 290 return_ACPI_STATUS(status); 291 } 292 293 /******************************************************************************* 294 * 295 * FUNCTION: acpi_hw_get_bit_register_info 296 * 297 * PARAMETERS: register_id - Index of ACPI Register to access 298 * 299 * RETURN: The bitmask to be used when accessing the register 300 * 301 * DESCRIPTION: Map register_id into a register bitmask. 302 * 303 ******************************************************************************/ 304 305 struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id) 306 { 307 ACPI_FUNCTION_ENTRY(); 308 309 if (register_id > ACPI_BITREG_MAX) { 310 ACPI_ERROR((AE_INFO, "Invalid BitRegister ID: 0x%X", 311 register_id)); 312 return (NULL); 313 } 314 315 return (&acpi_gbl_bit_register_info[register_id]); 316 } 317 318 /****************************************************************************** 319 * 320 * FUNCTION: acpi_hw_write_pm1_control 321 * 322 * PARAMETERS: pm1a_control - Value to be written to PM1A control 323 * pm1b_control - Value to be written to PM1B control 324 * 325 * RETURN: Status 326 * 327 * DESCRIPTION: Write the PM1 A/B control registers. These registers are 328 * different than than the PM1 A/B status and enable registers 329 * in that different values can be written to the A/B registers. 330 * Most notably, the SLP_TYP bits can be different, as per the 331 * values returned from the _Sx predefined methods. 332 * 333 ******************************************************************************/ 334 335 acpi_status acpi_hw_write_pm1_control(u32 pm1a_control, u32 pm1b_control) 336 { 337 acpi_status status; 338 339 ACPI_FUNCTION_TRACE(hw_write_pm1_control); 340 341 status = 342 acpi_hw_write(pm1a_control, &acpi_gbl_FADT.xpm1a_control_block); 343 if (ACPI_FAILURE(status)) { 344 return_ACPI_STATUS(status); 345 } 346 347 if (acpi_gbl_FADT.xpm1b_control_block.address) { 348 status = 349 acpi_hw_write(pm1b_control, 350 &acpi_gbl_FADT.xpm1b_control_block); 351 } 352 return_ACPI_STATUS(status); 353 } 354 355 /****************************************************************************** 356 * 357 * FUNCTION: acpi_hw_register_read 358 * 359 * PARAMETERS: register_id - ACPI Register ID 360 * return_value - Where the register value is returned 361 * 362 * RETURN: Status and the value read. 363 * 364 * DESCRIPTION: Read from the specified ACPI register 365 * 366 ******************************************************************************/ 367 acpi_status 368 acpi_hw_register_read(u32 register_id, u32 * return_value) 369 { 370 u32 value = 0; 371 acpi_status status; 372 373 ACPI_FUNCTION_TRACE(hw_register_read); 374 375 switch (register_id) { 376 case ACPI_REGISTER_PM1_STATUS: /* PM1 A/B: 16-bit access each */ 377 378 status = acpi_hw_read_multiple(&value, 379 &acpi_gbl_xpm1a_status, 380 &acpi_gbl_xpm1b_status); 381 break; 382 383 case ACPI_REGISTER_PM1_ENABLE: /* PM1 A/B: 16-bit access each */ 384 385 status = acpi_hw_read_multiple(&value, 386 &acpi_gbl_xpm1a_enable, 387 &acpi_gbl_xpm1b_enable); 388 break; 389 390 case ACPI_REGISTER_PM1_CONTROL: /* PM1 A/B: 16-bit access each */ 391 392 status = acpi_hw_read_multiple(&value, 393 &acpi_gbl_FADT. 394 xpm1a_control_block, 395 &acpi_gbl_FADT. 396 xpm1b_control_block); 397 398 /* 399 * Zero the write-only bits. From the ACPI specification, "Hardware 400 * Write-Only Bits": "Upon reads to registers with write-only bits, 401 * software masks out all write-only bits." 402 */ 403 value &= ~ACPI_PM1_CONTROL_WRITEONLY_BITS; 404 break; 405 406 case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ 407 408 status = 409 acpi_hw_read(&value, &acpi_gbl_FADT.xpm2_control_block); 410 break; 411 412 case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ 413 414 status = acpi_hw_read(&value, &acpi_gbl_FADT.xpm_timer_block); 415 break; 416 417 case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ 418 419 status = 420 acpi_hw_read_port(acpi_gbl_FADT.smi_command, &value, 8); 421 break; 422 423 default: 424 ACPI_ERROR((AE_INFO, "Unknown Register ID: 0x%X", register_id)); 425 status = AE_BAD_PARAMETER; 426 break; 427 } 428 429 if (ACPI_SUCCESS(status)) { 430 *return_value = value; 431 } 432 433 return_ACPI_STATUS(status); 434 } 435 436 /****************************************************************************** 437 * 438 * FUNCTION: acpi_hw_register_write 439 * 440 * PARAMETERS: register_id - ACPI Register ID 441 * value - The value to write 442 * 443 * RETURN: Status 444 * 445 * DESCRIPTION: Write to the specified ACPI register 446 * 447 * NOTE: In accordance with the ACPI specification, this function automatically 448 * preserves the value of the following bits, meaning that these bits cannot be 449 * changed via this interface: 450 * 451 * PM1_CONTROL[0] = SCI_EN 452 * PM1_CONTROL[9] 453 * PM1_STATUS[11] 454 * 455 * ACPI References: 456 * 1) Hardware Ignored Bits: When software writes to a register with ignored 457 * bit fields, it preserves the ignored bit fields 458 * 2) SCI_EN: OSPM always preserves this bit position 459 * 460 ******************************************************************************/ 461 462 acpi_status acpi_hw_register_write(u32 register_id, u32 value) 463 { 464 acpi_status status; 465 u32 read_value; 466 467 ACPI_FUNCTION_TRACE(hw_register_write); 468 469 switch (register_id) { 470 case ACPI_REGISTER_PM1_STATUS: /* PM1 A/B: 16-bit access each */ 471 /* 472 * Handle the "ignored" bit in PM1 Status. According to the ACPI 473 * specification, ignored bits are to be preserved when writing. 474 * Normally, this would mean a read/modify/write sequence. However, 475 * preserving a bit in the status register is different. Writing a 476 * one clears the status, and writing a zero preserves the status. 477 * Therefore, we must always write zero to the ignored bit. 478 * 479 * This behavior is clarified in the ACPI 4.0 specification. 480 */ 481 value &= ~ACPI_PM1_STATUS_PRESERVED_BITS; 482 483 status = acpi_hw_write_multiple(value, 484 &acpi_gbl_xpm1a_status, 485 &acpi_gbl_xpm1b_status); 486 break; 487 488 case ACPI_REGISTER_PM1_ENABLE: /* PM1 A/B: 16-bit access */ 489 490 status = acpi_hw_write_multiple(value, 491 &acpi_gbl_xpm1a_enable, 492 &acpi_gbl_xpm1b_enable); 493 break; 494 495 case ACPI_REGISTER_PM1_CONTROL: /* PM1 A/B: 16-bit access each */ 496 497 /* 498 * Perform a read first to preserve certain bits (per ACPI spec) 499 * Note: This includes SCI_EN, we never want to change this bit 500 */ 501 status = acpi_hw_read_multiple(&read_value, 502 &acpi_gbl_FADT. 503 xpm1a_control_block, 504 &acpi_gbl_FADT. 505 xpm1b_control_block); 506 if (ACPI_FAILURE(status)) { 507 goto exit; 508 } 509 510 /* Insert the bits to be preserved */ 511 512 ACPI_INSERT_BITS(value, ACPI_PM1_CONTROL_PRESERVED_BITS, 513 read_value); 514 515 /* Now we can write the data */ 516 517 status = acpi_hw_write_multiple(value, 518 &acpi_gbl_FADT. 519 xpm1a_control_block, 520 &acpi_gbl_FADT. 521 xpm1b_control_block); 522 break; 523 524 case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ 525 526 /* 527 * For control registers, all reserved bits must be preserved, 528 * as per the ACPI spec. 529 */ 530 status = 531 acpi_hw_read(&read_value, 532 &acpi_gbl_FADT.xpm2_control_block); 533 if (ACPI_FAILURE(status)) { 534 goto exit; 535 } 536 537 /* Insert the bits to be preserved */ 538 539 ACPI_INSERT_BITS(value, ACPI_PM2_CONTROL_PRESERVED_BITS, 540 read_value); 541 542 status = 543 acpi_hw_write(value, &acpi_gbl_FADT.xpm2_control_block); 544 break; 545 546 case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ 547 548 status = acpi_hw_write(value, &acpi_gbl_FADT.xpm_timer_block); 549 break; 550 551 case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ 552 553 /* SMI_CMD is currently always in IO space */ 554 555 status = 556 acpi_hw_write_port(acpi_gbl_FADT.smi_command, value, 8); 557 break; 558 559 default: 560 ACPI_ERROR((AE_INFO, "Unknown Register ID: 0x%X", register_id)); 561 status = AE_BAD_PARAMETER; 562 break; 563 } 564 565 exit: 566 return_ACPI_STATUS(status); 567 } 568 569 /****************************************************************************** 570 * 571 * FUNCTION: acpi_hw_read_multiple 572 * 573 * PARAMETERS: value - Where the register value is returned 574 * register_a - First ACPI register (required) 575 * register_b - Second ACPI register (optional) 576 * 577 * RETURN: Status 578 * 579 * DESCRIPTION: Read from the specified two-part ACPI register (such as PM1 A/B) 580 * 581 ******************************************************************************/ 582 583 static acpi_status 584 acpi_hw_read_multiple(u32 *value, 585 struct acpi_generic_address *register_a, 586 struct acpi_generic_address *register_b) 587 { 588 u32 value_a = 0; 589 u32 value_b = 0; 590 acpi_status status; 591 592 /* The first register is always required */ 593 594 status = acpi_hw_read(&value_a, register_a); 595 if (ACPI_FAILURE(status)) { 596 return (status); 597 } 598 599 /* Second register is optional */ 600 601 if (register_b->address) { 602 status = acpi_hw_read(&value_b, register_b); 603 if (ACPI_FAILURE(status)) { 604 return (status); 605 } 606 } 607 608 /* 609 * OR the two return values together. No shifting or masking is necessary, 610 * because of how the PM1 registers are defined in the ACPI specification: 611 * 612 * "Although the bits can be split between the two register blocks (each 613 * register block has a unique pointer within the FADT), the bit positions 614 * are maintained. The register block with unimplemented bits (that is, 615 * those implemented in the other register block) always returns zeros, 616 * and writes have no side effects" 617 */ 618 *value = (value_a | value_b); 619 return (AE_OK); 620 } 621 622 /****************************************************************************** 623 * 624 * FUNCTION: acpi_hw_write_multiple 625 * 626 * PARAMETERS: value - The value to write 627 * register_a - First ACPI register (required) 628 * register_b - Second ACPI register (optional) 629 * 630 * RETURN: Status 631 * 632 * DESCRIPTION: Write to the specified two-part ACPI register (such as PM1 A/B) 633 * 634 ******************************************************************************/ 635 636 static acpi_status 637 acpi_hw_write_multiple(u32 value, 638 struct acpi_generic_address *register_a, 639 struct acpi_generic_address *register_b) 640 { 641 acpi_status status; 642 643 /* The first register is always required */ 644 645 status = acpi_hw_write(value, register_a); 646 if (ACPI_FAILURE(status)) { 647 return (status); 648 } 649 650 /* 651 * Second register is optional 652 * 653 * No bit shifting or clearing is necessary, because of how the PM1 654 * registers are defined in the ACPI specification: 655 * 656 * "Although the bits can be split between the two register blocks (each 657 * register block has a unique pointer within the FADT), the bit positions 658 * are maintained. The register block with unimplemented bits (that is, 659 * those implemented in the other register block) always returns zeros, 660 * and writes have no side effects" 661 */ 662 if (register_b->address) { 663 status = acpi_hw_write(value, register_b); 664 } 665 666 return (status); 667 } 668 669 #endif /* !ACPI_REDUCED_HARDWARE */ 670