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 - 2015, 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 "acevents.h" 48 49#define _COMPONENT ACPI_HARDWARE 50ACPI_MODULE_NAME("hwregs") 51 52#if (!ACPI_REDUCED_HARDWARE) 53/* Local Prototypes */ 54static acpi_status 55acpi_hw_read_multiple(u32 *value, 56 struct acpi_generic_address *register_a, 57 struct acpi_generic_address *register_b); 58 59static acpi_status 60acpi_hw_write_multiple(u32 value, 61 struct acpi_generic_address *register_a, 62 struct acpi_generic_address *register_b); 63 64#endif /* !ACPI_REDUCED_HARDWARE */ 65 66/****************************************************************************** 67 * 68 * FUNCTION: acpi_hw_validate_register 69 * 70 * PARAMETERS: reg - GAS register structure 71 * max_bit_width - Max bit_width supported (32 or 64) 72 * address - Pointer to where the gas->address 73 * is returned 74 * 75 * RETURN: Status 76 * 77 * DESCRIPTION: Validate the contents of a GAS register. Checks the GAS 78 * pointer, Address, space_id, bit_width, and bit_offset. 79 * 80 ******************************************************************************/ 81 82acpi_status 83acpi_hw_validate_register(struct acpi_generic_address *reg, 84 u8 max_bit_width, u64 *address) 85{ 86 87 /* Must have a valid pointer to a GAS structure */ 88 89 if (!reg) { 90 return (AE_BAD_PARAMETER); 91 } 92 93 /* 94 * Copy the target address. This handles possible alignment issues. 95 * Address must not be null. A null address also indicates an optional 96 * ACPI register that is not supported, so no error message. 97 */ 98 ACPI_MOVE_64_TO_64(address, ®->address); 99 if (!(*address)) { 100 return (AE_BAD_ADDRESS); 101 } 102 103 /* Validate the space_ID */ 104 105 if ((reg->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) && 106 (reg->space_id != ACPI_ADR_SPACE_SYSTEM_IO)) { 107 ACPI_ERROR((AE_INFO, 108 "Unsupported address space: 0x%X", reg->space_id)); 109 return (AE_SUPPORT); 110 } 111 112 /* Validate the bit_width */ 113 114 if ((reg->bit_width != 8) && 115 (reg->bit_width != 16) && 116 (reg->bit_width != 32) && (reg->bit_width != max_bit_width)) { 117 ACPI_ERROR((AE_INFO, 118 "Unsupported register bit width: 0x%X", 119 reg->bit_width)); 120 return (AE_SUPPORT); 121 } 122 123 /* Validate the bit_offset. Just a warning for now. */ 124 125 if (reg->bit_offset != 0) { 126 ACPI_WARNING((AE_INFO, 127 "Unsupported register bit offset: 0x%X", 128 reg->bit_offset)); 129 } 130 131 return (AE_OK); 132} 133 134/****************************************************************************** 135 * 136 * FUNCTION: acpi_hw_read 137 * 138 * PARAMETERS: value - Where the value is returned 139 * reg - GAS register structure 140 * 141 * RETURN: Status 142 * 143 * DESCRIPTION: Read from either memory or IO space. This is a 32-bit max 144 * version of acpi_read, used internally since the overhead of 145 * 64-bit values is not needed. 146 * 147 * LIMITATIONS: <These limitations also apply to acpi_hw_write> 148 * bit_width must be exactly 8, 16, or 32. 149 * space_ID must be system_memory or system_IO. 150 * bit_offset and access_width are currently ignored, as there has 151 * not been a need to implement these. 152 * 153 ******************************************************************************/ 154 155acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg) 156{ 157 u64 address; 158 u64 value64; 159 acpi_status status; 160 161 ACPI_FUNCTION_NAME(hw_read); 162 163 /* Validate contents of the GAS register */ 164 165 status = acpi_hw_validate_register(reg, 32, &address); 166 if (ACPI_FAILURE(status)) { 167 return (status); 168 } 169 170 /* Initialize entire 32-bit return value to zero */ 171 172 *value = 0; 173 174 /* 175 * Two address spaces supported: Memory or IO. PCI_Config is 176 * not supported here because the GAS structure is insufficient 177 */ 178 if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { 179 status = acpi_os_read_memory((acpi_physical_address) 180 address, &value64, reg->bit_width); 181 182 *value = (u32)value64; 183 } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ 184 185 status = acpi_hw_read_port((acpi_io_address) 186 address, value, reg->bit_width); 187 } 188 189 ACPI_DEBUG_PRINT((ACPI_DB_IO, 190 "Read: %8.8X width %2d from %8.8X%8.8X (%s)\n", 191 *value, reg->bit_width, ACPI_FORMAT_UINT64(address), 192 acpi_ut_get_region_name(reg->space_id))); 193 194 return (status); 195} 196 197/****************************************************************************** 198 * 199 * FUNCTION: acpi_hw_write 200 * 201 * PARAMETERS: value - Value to be written 202 * reg - GAS register structure 203 * 204 * RETURN: Status 205 * 206 * DESCRIPTION: Write to either memory or IO space. This is a 32-bit max 207 * version of acpi_write, used internally since the overhead of 208 * 64-bit values is not needed. 209 * 210 ******************************************************************************/ 211 212acpi_status acpi_hw_write(u32 value, struct acpi_generic_address *reg) 213{ 214 u64 address; 215 acpi_status status; 216 217 ACPI_FUNCTION_NAME(hw_write); 218 219 /* Validate contents of the GAS register */ 220 221 status = acpi_hw_validate_register(reg, 32, &address); 222 if (ACPI_FAILURE(status)) { 223 return (status); 224 } 225 226 /* 227 * Two address spaces supported: Memory or IO. PCI_Config is 228 * not supported here because the GAS structure is insufficient 229 */ 230 if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { 231 status = acpi_os_write_memory((acpi_physical_address) 232 address, (u64)value, 233 reg->bit_width); 234 } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ 235 236 status = acpi_hw_write_port((acpi_io_address) 237 address, value, reg->bit_width); 238 } 239 240 ACPI_DEBUG_PRINT((ACPI_DB_IO, 241 "Wrote: %8.8X width %2d to %8.8X%8.8X (%s)\n", 242 value, reg->bit_width, ACPI_FORMAT_UINT64(address), 243 acpi_ut_get_region_name(reg->space_id))); 244 245 return (status); 246} 247 248#if (!ACPI_REDUCED_HARDWARE) 249/******************************************************************************* 250 * 251 * FUNCTION: acpi_hw_clear_acpi_status 252 * 253 * PARAMETERS: None 254 * 255 * RETURN: Status 256 * 257 * DESCRIPTION: Clears all fixed and general purpose status bits 258 * 259 ******************************************************************************/ 260 261acpi_status acpi_hw_clear_acpi_status(void) 262{ 263 acpi_status status; 264 acpi_cpu_flags lock_flags = 0; 265 266 ACPI_FUNCTION_TRACE(hw_clear_acpi_status); 267 268 ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %04X to %8.8X%8.8X\n", 269 ACPI_BITMASK_ALL_FIXED_STATUS, 270 ACPI_FORMAT_UINT64(acpi_gbl_xpm1a_status.address))); 271 272 lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); 273 274 /* Clear the fixed events in PM1 A/B */ 275 276 status = acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS, 277 ACPI_BITMASK_ALL_FIXED_STATUS); 278 279 acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags); 280 281 if (ACPI_FAILURE(status)) { 282 goto exit; 283 } 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 289exit: 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 305struct 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 335acpi_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 ******************************************************************************/ 367acpi_status acpi_hw_register_read(u32 register_id, u32 *return_value) 368{ 369 u32 value = 0; 370 acpi_status status; 371 372 ACPI_FUNCTION_TRACE(hw_register_read); 373 374 switch (register_id) { 375 case ACPI_REGISTER_PM1_STATUS: /* PM1 A/B: 16-bit access each */ 376 377 status = acpi_hw_read_multiple(&value, 378 &acpi_gbl_xpm1a_status, 379 &acpi_gbl_xpm1b_status); 380 break; 381 382 case ACPI_REGISTER_PM1_ENABLE: /* PM1 A/B: 16-bit access each */ 383 384 status = acpi_hw_read_multiple(&value, 385 &acpi_gbl_xpm1a_enable, 386 &acpi_gbl_xpm1b_enable); 387 break; 388 389 case ACPI_REGISTER_PM1_CONTROL: /* PM1 A/B: 16-bit access each */ 390 391 status = acpi_hw_read_multiple(&value, 392 &acpi_gbl_FADT. 393 xpm1a_control_block, 394 &acpi_gbl_FADT. 395 xpm1b_control_block); 396 397 /* 398 * Zero the write-only bits. From the ACPI specification, "Hardware 399 * Write-Only Bits": "Upon reads to registers with write-only bits, 400 * software masks out all write-only bits." 401 */ 402 value &= ~ACPI_PM1_CONTROL_WRITEONLY_BITS; 403 break; 404 405 case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ 406 407 status = 408 acpi_hw_read(&value, &acpi_gbl_FADT.xpm2_control_block); 409 break; 410 411 case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ 412 413 status = acpi_hw_read(&value, &acpi_gbl_FADT.xpm_timer_block); 414 break; 415 416 case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ 417 418 status = 419 acpi_hw_read_port(acpi_gbl_FADT.smi_command, &value, 8); 420 break; 421 422 default: 423 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 462acpi_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 each */ 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 * Perform a read first to preserve certain bits (per ACPI spec) 498 * Note: This includes SCI_EN, we never want to change this bit 499 */ 500 status = acpi_hw_read_multiple(&read_value, 501 &acpi_gbl_FADT. 502 xpm1a_control_block, 503 &acpi_gbl_FADT. 504 xpm1b_control_block); 505 if (ACPI_FAILURE(status)) { 506 goto exit; 507 } 508 509 /* Insert the bits to be preserved */ 510 511 ACPI_INSERT_BITS(value, ACPI_PM1_CONTROL_PRESERVED_BITS, 512 read_value); 513 514 /* Now we can write the data */ 515 516 status = acpi_hw_write_multiple(value, 517 &acpi_gbl_FADT. 518 xpm1a_control_block, 519 &acpi_gbl_FADT. 520 xpm1b_control_block); 521 break; 522 523 case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ 524 /* 525 * For control registers, all reserved bits must be preserved, 526 * as per the ACPI spec. 527 */ 528 status = 529 acpi_hw_read(&read_value, 530 &acpi_gbl_FADT.xpm2_control_block); 531 if (ACPI_FAILURE(status)) { 532 goto exit; 533 } 534 535 /* Insert the bits to be preserved */ 536 537 ACPI_INSERT_BITS(value, ACPI_PM2_CONTROL_PRESERVED_BITS, 538 read_value); 539 540 status = 541 acpi_hw_write(value, &acpi_gbl_FADT.xpm2_control_block); 542 break; 543 544 case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ 545 546 status = acpi_hw_write(value, &acpi_gbl_FADT.xpm_timer_block); 547 break; 548 549 case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ 550 551 /* SMI_CMD is currently always in IO space */ 552 553 status = 554 acpi_hw_write_port(acpi_gbl_FADT.smi_command, value, 8); 555 break; 556 557 default: 558 559 ACPI_ERROR((AE_INFO, "Unknown Register ID: 0x%X", register_id)); 560 status = AE_BAD_PARAMETER; 561 break; 562 } 563 564exit: 565 return_ACPI_STATUS(status); 566} 567 568/****************************************************************************** 569 * 570 * FUNCTION: acpi_hw_read_multiple 571 * 572 * PARAMETERS: value - Where the register value is returned 573 * register_a - First ACPI register (required) 574 * register_b - Second ACPI register (optional) 575 * 576 * RETURN: Status 577 * 578 * DESCRIPTION: Read from the specified two-part ACPI register (such as PM1 A/B) 579 * 580 ******************************************************************************/ 581 582static acpi_status 583acpi_hw_read_multiple(u32 *value, 584 struct acpi_generic_address *register_a, 585 struct acpi_generic_address *register_b) 586{ 587 u32 value_a = 0; 588 u32 value_b = 0; 589 acpi_status status; 590 591 /* The first register is always required */ 592 593 status = acpi_hw_read(&value_a, register_a); 594 if (ACPI_FAILURE(status)) { 595 return (status); 596 } 597 598 /* Second register is optional */ 599 600 if (register_b->address) { 601 status = acpi_hw_read(&value_b, register_b); 602 if (ACPI_FAILURE(status)) { 603 return (status); 604 } 605 } 606 607 /* 608 * OR the two return values together. No shifting or masking is necessary, 609 * because of how the PM1 registers are defined in the ACPI specification: 610 * 611 * "Although the bits can be split between the two register blocks (each 612 * register block has a unique pointer within the FADT), the bit positions 613 * are maintained. The register block with unimplemented bits (that is, 614 * those implemented in the other register block) always returns zeros, 615 * and writes have no side effects" 616 */ 617 *value = (value_a | value_b); 618 return (AE_OK); 619} 620 621/****************************************************************************** 622 * 623 * FUNCTION: acpi_hw_write_multiple 624 * 625 * PARAMETERS: value - The value to write 626 * register_a - First ACPI register (required) 627 * register_b - Second ACPI register (optional) 628 * 629 * RETURN: Status 630 * 631 * DESCRIPTION: Write to the specified two-part ACPI register (such as PM1 A/B) 632 * 633 ******************************************************************************/ 634 635static acpi_status 636acpi_hw_write_multiple(u32 value, 637 struct acpi_generic_address *register_a, 638 struct acpi_generic_address *register_b) 639{ 640 acpi_status status; 641 642 /* The first register is always required */ 643 644 status = acpi_hw_write(value, register_a); 645 if (ACPI_FAILURE(status)) { 646 return (status); 647 } 648 649 /* 650 * Second register is optional 651 * 652 * No bit shifting or clearing is necessary, because of how the PM1 653 * registers are defined in the ACPI specification: 654 * 655 * "Although the bits can be split between the two register blocks (each 656 * register block has a unique pointer within the FADT), the bit positions 657 * are maintained. The register block with unimplemented bits (that is, 658 * those implemented in the other register block) always returns zeros, 659 * and writes have no side effects" 660 */ 661 if (register_b->address) { 662 status = acpi_hw_write(value, register_b); 663 } 664 665 return (status); 666} 667 668#endif /* !ACPI_REDUCED_HARDWARE */ 669