1 2 /******************************************************************************* 3 * 4 * Module Name: hwregs - Read/write access functions for the various ACPI 5 * control and status registers. 6 * 7 ******************************************************************************/ 8 9 /* 10 * Copyright (C) 2000 - 2008, Intel Corp. 11 * All rights reserved. 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions 15 * are met: 16 * 1. Redistributions of source code must retain the above copyright 17 * notice, this list of conditions, and the following disclaimer, 18 * without modification. 19 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 20 * substantially similar to the "NO WARRANTY" disclaimer below 21 * ("Disclaimer") and any redistribution must be conditioned upon 22 * including a substantially similar Disclaimer requirement for further 23 * binary redistribution. 24 * 3. Neither the names of the above-listed copyright holders nor the names 25 * of any contributors may be used to endorse or promote products derived 26 * from this software without specific prior written permission. 27 * 28 * Alternatively, this software may be distributed under the terms of the 29 * GNU General Public License ("GPL") version 2 as published by the Free 30 * Software Foundation. 31 * 32 * NO WARRANTY 33 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 34 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 35 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 36 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 37 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 38 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 39 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 40 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 41 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 42 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 43 * POSSIBILITY OF SUCH DAMAGES. 44 */ 45 46 #include <acpi/acpi.h> 47 #include "accommon.h" 48 #include "acnamesp.h" 49 #include "acevents.h" 50 51 #define _COMPONENT ACPI_HARDWARE 52 ACPI_MODULE_NAME("hwregs") 53 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 /******************************************************************************* 66 * 67 * FUNCTION: acpi_hw_clear_acpi_status 68 * 69 * PARAMETERS: None 70 * 71 * RETURN: Status 72 * 73 * DESCRIPTION: Clears all fixed and general purpose status bits 74 * 75 ******************************************************************************/ 76 77 acpi_status acpi_hw_clear_acpi_status(void) 78 { 79 acpi_status status; 80 acpi_cpu_flags lock_flags = 0; 81 82 ACPI_FUNCTION_TRACE(hw_clear_acpi_status); 83 84 ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %04X to %8.8X%8.8X\n", 85 ACPI_BITMASK_ALL_FIXED_STATUS, 86 ACPI_FORMAT_UINT64(acpi_gbl_xpm1a_status.address))); 87 88 lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); 89 90 /* Clear the fixed events in PM1 A/B */ 91 92 status = acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS, 93 ACPI_BITMASK_ALL_FIXED_STATUS); 94 if (ACPI_FAILURE(status)) { 95 goto unlock_and_exit; 96 } 97 98 /* Clear the GPE Bits in all GPE registers in all GPE blocks */ 99 100 status = acpi_ev_walk_gpe_list(acpi_hw_clear_gpe_block, NULL); 101 102 unlock_and_exit: 103 acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags); 104 return_ACPI_STATUS(status); 105 } 106 107 /******************************************************************************* 108 * 109 * FUNCTION: acpi_hw_get_register_bit_mask 110 * 111 * PARAMETERS: register_id - Index of ACPI Register to access 112 * 113 * RETURN: The bitmask to be used when accessing the register 114 * 115 * DESCRIPTION: Map register_id into a register bitmask. 116 * 117 ******************************************************************************/ 118 119 struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id) 120 { 121 ACPI_FUNCTION_ENTRY(); 122 123 if (register_id > ACPI_BITREG_MAX) { 124 ACPI_ERROR((AE_INFO, "Invalid BitRegister ID: %X", 125 register_id)); 126 return (NULL); 127 } 128 129 return (&acpi_gbl_bit_register_info[register_id]); 130 } 131 132 /****************************************************************************** 133 * 134 * FUNCTION: acpi_hw_write_pm1_control 135 * 136 * PARAMETERS: pm1a_control - Value to be written to PM1A control 137 * pm1b_control - Value to be written to PM1B control 138 * 139 * RETURN: Status 140 * 141 * DESCRIPTION: Write the PM1 A/B control registers. These registers are 142 * different than than the PM1 A/B status and enable registers 143 * in that different values can be written to the A/B registers. 144 * Most notably, the SLP_TYP bits can be different, as per the 145 * values returned from the _Sx predefined methods. 146 * 147 ******************************************************************************/ 148 149 acpi_status acpi_hw_write_pm1_control(u32 pm1a_control, u32 pm1b_control) 150 { 151 acpi_status status; 152 153 ACPI_FUNCTION_TRACE(hw_write_pm1_control); 154 155 status = acpi_write(pm1a_control, &acpi_gbl_FADT.xpm1a_control_block); 156 if (ACPI_FAILURE(status)) { 157 return_ACPI_STATUS(status); 158 } 159 160 if (acpi_gbl_FADT.xpm1b_control_block.address) { 161 status = 162 acpi_write(pm1b_control, 163 &acpi_gbl_FADT.xpm1b_control_block); 164 } 165 return_ACPI_STATUS(status); 166 } 167 168 /****************************************************************************** 169 * 170 * FUNCTION: acpi_hw_register_read 171 * 172 * PARAMETERS: register_id - ACPI Register ID 173 * return_value - Where the register value is returned 174 * 175 * RETURN: Status and the value read. 176 * 177 * DESCRIPTION: Read from the specified ACPI register 178 * 179 ******************************************************************************/ 180 acpi_status 181 acpi_hw_register_read(u32 register_id, u32 * return_value) 182 { 183 u32 value = 0; 184 acpi_status status; 185 186 ACPI_FUNCTION_TRACE(hw_register_read); 187 188 switch (register_id) { 189 case ACPI_REGISTER_PM1_STATUS: /* PM1 A/B: 16-bit access each */ 190 191 status = acpi_hw_read_multiple(&value, 192 &acpi_gbl_xpm1a_status, 193 &acpi_gbl_xpm1b_status); 194 break; 195 196 case ACPI_REGISTER_PM1_ENABLE: /* PM1 A/B: 16-bit access each */ 197 198 status = acpi_hw_read_multiple(&value, 199 &acpi_gbl_xpm1a_enable, 200 &acpi_gbl_xpm1b_enable); 201 break; 202 203 case ACPI_REGISTER_PM1_CONTROL: /* PM1 A/B: 16-bit access each */ 204 205 status = acpi_hw_read_multiple(&value, 206 &acpi_gbl_FADT. 207 xpm1a_control_block, 208 &acpi_gbl_FADT. 209 xpm1b_control_block); 210 211 /* 212 * Zero the write-only bits. From the ACPI specification, "Hardware 213 * Write-Only Bits": "Upon reads to registers with write-only bits, 214 * software masks out all write-only bits." 215 */ 216 value &= ~ACPI_PM1_CONTROL_WRITEONLY_BITS; 217 break; 218 219 case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ 220 221 status = acpi_read(&value, &acpi_gbl_FADT.xpm2_control_block); 222 break; 223 224 case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ 225 226 status = acpi_read(&value, &acpi_gbl_FADT.xpm_timer_block); 227 break; 228 229 case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ 230 231 status = 232 acpi_hw_read_port(acpi_gbl_FADT.smi_command, &value, 8); 233 break; 234 235 default: 236 ACPI_ERROR((AE_INFO, "Unknown Register ID: %X", register_id)); 237 status = AE_BAD_PARAMETER; 238 break; 239 } 240 241 if (ACPI_SUCCESS(status)) { 242 *return_value = value; 243 } 244 245 return_ACPI_STATUS(status); 246 } 247 248 /****************************************************************************** 249 * 250 * FUNCTION: acpi_hw_register_write 251 * 252 * PARAMETERS: register_id - ACPI Register ID 253 * Value - The value to write 254 * 255 * RETURN: Status 256 * 257 * DESCRIPTION: Write to the specified ACPI register 258 * 259 * NOTE: In accordance with the ACPI specification, this function automatically 260 * preserves the value of the following bits, meaning that these bits cannot be 261 * changed via this interface: 262 * 263 * PM1_CONTROL[0] = SCI_EN 264 * PM1_CONTROL[9] 265 * PM1_STATUS[11] 266 * 267 * ACPI References: 268 * 1) Hardware Ignored Bits: When software writes to a register with ignored 269 * bit fields, it preserves the ignored bit fields 270 * 2) SCI_EN: OSPM always preserves this bit position 271 * 272 ******************************************************************************/ 273 274 acpi_status acpi_hw_register_write(u32 register_id, u32 value) 275 { 276 acpi_status status; 277 u32 read_value; 278 279 ACPI_FUNCTION_TRACE(hw_register_write); 280 281 switch (register_id) { 282 case ACPI_REGISTER_PM1_STATUS: /* PM1 A/B: 16-bit access each */ 283 /* 284 * Handle the "ignored" bit in PM1 Status. According to the ACPI 285 * specification, ignored bits are to be preserved when writing. 286 * Normally, this would mean a read/modify/write sequence. However, 287 * preserving a bit in the status register is different. Writing a 288 * one clears the status, and writing a zero preserves the status. 289 * Therefore, we must always write zero to the ignored bit. 290 * 291 * This behavior is clarified in the ACPI 4.0 specification. 292 */ 293 value &= ~ACPI_PM1_STATUS_PRESERVED_BITS; 294 295 status = acpi_hw_write_multiple(value, 296 &acpi_gbl_xpm1a_status, 297 &acpi_gbl_xpm1b_status); 298 break; 299 300 case ACPI_REGISTER_PM1_ENABLE: /* PM1 A/B: 16-bit access */ 301 302 status = acpi_hw_write_multiple(value, 303 &acpi_gbl_xpm1a_enable, 304 &acpi_gbl_xpm1b_enable); 305 break; 306 307 case ACPI_REGISTER_PM1_CONTROL: /* PM1 A/B: 16-bit access each */ 308 309 /* 310 * Perform a read first to preserve certain bits (per ACPI spec) 311 * Note: This includes SCI_EN, we never want to change this bit 312 */ 313 status = acpi_hw_read_multiple(&read_value, 314 &acpi_gbl_FADT. 315 xpm1a_control_block, 316 &acpi_gbl_FADT. 317 xpm1b_control_block); 318 if (ACPI_FAILURE(status)) { 319 goto exit; 320 } 321 322 /* Insert the bits to be preserved */ 323 324 ACPI_INSERT_BITS(value, ACPI_PM1_CONTROL_PRESERVED_BITS, 325 read_value); 326 327 /* Now we can write the data */ 328 329 status = acpi_hw_write_multiple(value, 330 &acpi_gbl_FADT. 331 xpm1a_control_block, 332 &acpi_gbl_FADT. 333 xpm1b_control_block); 334 break; 335 336 case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ 337 338 /* 339 * For control registers, all reserved bits must be preserved, 340 * as per the ACPI spec. 341 */ 342 status = 343 acpi_read(&read_value, &acpi_gbl_FADT.xpm2_control_block); 344 if (ACPI_FAILURE(status)) { 345 goto exit; 346 } 347 348 /* Insert the bits to be preserved */ 349 350 ACPI_INSERT_BITS(value, ACPI_PM2_CONTROL_PRESERVED_BITS, 351 read_value); 352 353 status = acpi_write(value, &acpi_gbl_FADT.xpm2_control_block); 354 break; 355 356 case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ 357 358 status = acpi_write(value, &acpi_gbl_FADT.xpm_timer_block); 359 break; 360 361 case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ 362 363 /* SMI_CMD is currently always in IO space */ 364 365 status = 366 acpi_hw_write_port(acpi_gbl_FADT.smi_command, value, 8); 367 break; 368 369 default: 370 ACPI_ERROR((AE_INFO, "Unknown Register ID: %X", register_id)); 371 status = AE_BAD_PARAMETER; 372 break; 373 } 374 375 exit: 376 return_ACPI_STATUS(status); 377 } 378 379 /****************************************************************************** 380 * 381 * FUNCTION: acpi_hw_read_multiple 382 * 383 * PARAMETERS: Value - Where the register value is returned 384 * register_a - First ACPI register (required) 385 * register_b - Second ACPI register (optional) 386 * 387 * RETURN: Status 388 * 389 * DESCRIPTION: Read from the specified two-part ACPI register (such as PM1 A/B) 390 * 391 ******************************************************************************/ 392 393 static acpi_status 394 acpi_hw_read_multiple(u32 *value, 395 struct acpi_generic_address *register_a, 396 struct acpi_generic_address *register_b) 397 { 398 u32 value_a = 0; 399 u32 value_b = 0; 400 acpi_status status; 401 402 /* The first register is always required */ 403 404 status = acpi_read(&value_a, register_a); 405 if (ACPI_FAILURE(status)) { 406 return (status); 407 } 408 409 /* Second register is optional */ 410 411 if (register_b->address) { 412 status = acpi_read(&value_b, register_b); 413 if (ACPI_FAILURE(status)) { 414 return (status); 415 } 416 } 417 418 /* 419 * OR the two return values together. No shifting or masking is necessary, 420 * because of how the PM1 registers are defined in the ACPI specification: 421 * 422 * "Although the bits can be split between the two register blocks (each 423 * register block has a unique pointer within the FADT), the bit positions 424 * are maintained. The register block with unimplemented bits (that is, 425 * those implemented in the other register block) always returns zeros, 426 * and writes have no side effects" 427 */ 428 *value = (value_a | value_b); 429 return (AE_OK); 430 } 431 432 /****************************************************************************** 433 * 434 * FUNCTION: acpi_hw_write_multiple 435 * 436 * PARAMETERS: Value - The value to write 437 * register_a - First ACPI register (required) 438 * register_b - Second ACPI register (optional) 439 * 440 * RETURN: Status 441 * 442 * DESCRIPTION: Write to the specified two-part ACPI register (such as PM1 A/B) 443 * 444 ******************************************************************************/ 445 446 static acpi_status 447 acpi_hw_write_multiple(u32 value, 448 struct acpi_generic_address *register_a, 449 struct acpi_generic_address *register_b) 450 { 451 acpi_status status; 452 453 /* The first register is always required */ 454 455 status = acpi_write(value, register_a); 456 if (ACPI_FAILURE(status)) { 457 return (status); 458 } 459 460 /* 461 * Second register is optional 462 * 463 * No bit shifting or clearing is necessary, because of how the PM1 464 * registers are defined in the ACPI specification: 465 * 466 * "Although the bits can be split between the two register blocks (each 467 * register block has a unique pointer within the FADT), the bit positions 468 * are maintained. The register block with unimplemented bits (that is, 469 * those implemented in the other register block) always returns zeros, 470 * and writes have no side effects" 471 */ 472 if (register_b->address) { 473 status = acpi_write(value, register_b); 474 } 475 476 return (status); 477 } 478