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 - 2007, R. Byron Moore 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 <acpi/acnamesp.h> 48#include <acpi/acevents.h> 49 50#define _COMPONENT ACPI_HARDWARE 51ACPI_MODULE_NAME("hwregs") 52 53/******************************************************************************* 54 * 55 * FUNCTION: acpi_hw_clear_acpi_status 56 * 57 * PARAMETERS: None 58 * 59 * RETURN: None 60 * 61 * DESCRIPTION: Clears all fixed and general purpose status bits 62 * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED 63 * 64 ******************************************************************************/ 65acpi_status acpi_hw_clear_acpi_status(void) 66{ 67 acpi_status status; 68 acpi_cpu_flags lock_flags = 0; 69 70 ACPI_FUNCTION_TRACE(hw_clear_acpi_status); 71 72 ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %04X to %04X\n", 73 ACPI_BITMASK_ALL_FIXED_STATUS, 74 (u16) acpi_gbl_FADT.xpm1a_event_block.address)); 75 76 lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); 77 78 status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, 79 ACPI_REGISTER_PM1_STATUS, 80 ACPI_BITMASK_ALL_FIXED_STATUS); 81 if (ACPI_FAILURE(status)) { 82 goto unlock_and_exit; 83 } 84 85 /* Clear the fixed events */ 86 87 if (acpi_gbl_FADT.xpm1b_event_block.address) { 88 status = 89 acpi_hw_low_level_write(16, ACPI_BITMASK_ALL_FIXED_STATUS, 90 &acpi_gbl_FADT.xpm1b_event_block); 91 if (ACPI_FAILURE(status)) { 92 goto unlock_and_exit; 93 } 94 } 95 96 /* Clear the GPE Bits in all GPE registers in all GPE blocks */ 97 98 status = acpi_ev_walk_gpe_list(acpi_hw_clear_gpe_block); 99 100 unlock_and_exit: 101 acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags); 102 return_ACPI_STATUS(status); 103} 104 105/******************************************************************************* 106 * 107 * FUNCTION: acpi_get_sleep_type_data 108 * 109 * PARAMETERS: sleep_state - Numeric sleep state 110 * *sleep_type_a - Where SLP_TYPa is returned 111 * *sleep_type_b - Where SLP_TYPb is returned 112 * 113 * RETURN: Status - ACPI status 114 * 115 * DESCRIPTION: Obtain the SLP_TYPa and SLP_TYPb values for the requested sleep 116 * state. 117 * 118 ******************************************************************************/ 119 120acpi_status 121acpi_get_sleep_type_data(u8 sleep_state, u8 * sleep_type_a, u8 * sleep_type_b) 122{ 123 acpi_status status = AE_OK; 124 struct acpi_evaluate_info *info; 125 126 ACPI_FUNCTION_TRACE(acpi_get_sleep_type_data); 127 128 /* Validate parameters */ 129 130 if ((sleep_state > ACPI_S_STATES_MAX) || !sleep_type_a || !sleep_type_b) { 131 return_ACPI_STATUS(AE_BAD_PARAMETER); 132 } 133 134 /* Allocate the evaluation information block */ 135 136 info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info)); 137 if (!info) { 138 return_ACPI_STATUS(AE_NO_MEMORY); 139 } 140 141 info->pathname = 142 ACPI_CAST_PTR(char, acpi_gbl_sleep_state_names[sleep_state]); 143 144 /* Evaluate the namespace object containing the values for this state */ 145 146 status = acpi_ns_evaluate(info); 147 if (ACPI_FAILURE(status)) { 148 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 149 "%s while evaluating SleepState [%s]\n", 150 acpi_format_exception(status), 151 info->pathname)); 152 153 goto cleanup; 154 } 155 156 /* Must have a return object */ 157 158 if (!info->return_object) { 159 ACPI_ERROR((AE_INFO, "No Sleep State object returned from [%s]", 160 info->pathname)); 161 status = AE_NOT_EXIST; 162 } 163 164 /* It must be of type Package */ 165 166 else if (ACPI_GET_OBJECT_TYPE(info->return_object) != ACPI_TYPE_PACKAGE) { 167 ACPI_ERROR((AE_INFO, 168 "Sleep State return object is not a Package")); 169 status = AE_AML_OPERAND_TYPE; 170 } 171 172 /* 173 * The package must have at least two elements. NOTE (March 2005): This 174 * goes against the current ACPI spec which defines this object as a 175 * package with one encoded DWORD element. However, existing practice 176 * by BIOS vendors seems to be to have 2 or more elements, at least 177 * one per sleep type (A/B). 178 */ 179 else if (info->return_object->package.count < 2) { 180 ACPI_ERROR((AE_INFO, 181 "Sleep State return package does not have at least two elements")); 182 status = AE_AML_NO_OPERAND; 183 } 184 185 /* The first two elements must both be of type Integer */ 186 187 else if ((ACPI_GET_OBJECT_TYPE(info->return_object->package.elements[0]) 188 != ACPI_TYPE_INTEGER) || 189 (ACPI_GET_OBJECT_TYPE(info->return_object->package.elements[1]) 190 != ACPI_TYPE_INTEGER)) { 191 ACPI_ERROR((AE_INFO, 192 "Sleep State return package elements are not both Integers (%s, %s)", 193 acpi_ut_get_object_type_name(info->return_object-> 194 package.elements[0]), 195 acpi_ut_get_object_type_name(info->return_object-> 196 package.elements[1]))); 197 status = AE_AML_OPERAND_TYPE; 198 } else { 199 /* Valid _Sx_ package size, type, and value */ 200 201 *sleep_type_a = (u8) 202 (info->return_object->package.elements[0])->integer.value; 203 *sleep_type_b = (u8) 204 (info->return_object->package.elements[1])->integer.value; 205 } 206 207 if (ACPI_FAILURE(status)) { 208 ACPI_EXCEPTION((AE_INFO, status, 209 "While evaluating SleepState [%s], bad Sleep object %p type %s", 210 info->pathname, info->return_object, 211 acpi_ut_get_object_type_name(info-> 212 return_object))); 213 } 214 215 acpi_ut_remove_reference(info->return_object); 216 217 cleanup: 218 ACPI_FREE(info); 219 return_ACPI_STATUS(status); 220} 221 222ACPI_EXPORT_SYMBOL(acpi_get_sleep_type_data) 223 224/******************************************************************************* 225 * 226 * FUNCTION: acpi_hw_get_register_bit_mask 227 * 228 * PARAMETERS: register_id - Index of ACPI Register to access 229 * 230 * RETURN: The bitmask to be used when accessing the register 231 * 232 * DESCRIPTION: Map register_id into a register bitmask. 233 * 234 ******************************************************************************/ 235struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id) 236{ 237 ACPI_FUNCTION_ENTRY(); 238 239 if (register_id > ACPI_BITREG_MAX) { 240 ACPI_ERROR((AE_INFO, "Invalid BitRegister ID: %X", 241 register_id)); 242 return (NULL); 243 } 244 245 return (&acpi_gbl_bit_register_info[register_id]); 246} 247 248/******************************************************************************* 249 * 250 * FUNCTION: acpi_get_register 251 * 252 * PARAMETERS: register_id - ID of ACPI bit_register to access 253 * return_value - Value that was read from the register 254 * 255 * RETURN: Status and the value read from specified Register. Value 256 * returned is normalized to bit0 (is shifted all the way right) 257 * 258 * DESCRIPTION: ACPI bit_register read function. 259 * 260 ******************************************************************************/ 261 262acpi_status acpi_get_register(u32 register_id, u32 * return_value) 263{ 264 u32 register_value = 0; 265 struct acpi_bit_register_info *bit_reg_info; 266 acpi_status status; 267 268 ACPI_FUNCTION_TRACE(acpi_get_register); 269 270 /* Get the info structure corresponding to the requested ACPI Register */ 271 272 bit_reg_info = acpi_hw_get_bit_register_info(register_id); 273 if (!bit_reg_info) { 274 return_ACPI_STATUS(AE_BAD_PARAMETER); 275 } 276 277 /* Read from the register */ 278 279 status = acpi_hw_register_read(ACPI_MTX_LOCK, 280 bit_reg_info->parent_register, 281 ®ister_value); 282 283 if (ACPI_SUCCESS(status)) { 284 285 /* Normalize the value that was read */ 286 287 register_value = 288 ((register_value & bit_reg_info->access_bit_mask) 289 >> bit_reg_info->bit_position); 290 291 *return_value = register_value; 292 293 ACPI_DEBUG_PRINT((ACPI_DB_IO, "Read value %8.8X register %X\n", 294 register_value, 295 bit_reg_info->parent_register)); 296 } 297 298 return_ACPI_STATUS(status); 299} 300 301ACPI_EXPORT_SYMBOL(acpi_get_register) 302 303/******************************************************************************* 304 * 305 * FUNCTION: acpi_set_register 306 * 307 * PARAMETERS: register_id - ID of ACPI bit_register to access 308 * Value - (only used on write) value to write to the 309 * Register, NOT pre-normalized to the bit pos 310 * 311 * RETURN: Status 312 * 313 * DESCRIPTION: ACPI Bit Register write function. 314 * 315 ******************************************************************************/ 316acpi_status acpi_set_register(u32 register_id, u32 value) 317{ 318 u32 register_value = 0; 319 struct acpi_bit_register_info *bit_reg_info; 320 acpi_status status; 321 acpi_cpu_flags lock_flags; 322 323 ACPI_FUNCTION_TRACE_U32(acpi_set_register, register_id); 324 325 /* Get the info structure corresponding to the requested ACPI Register */ 326 327 bit_reg_info = acpi_hw_get_bit_register_info(register_id); 328 if (!bit_reg_info) { 329 ACPI_ERROR((AE_INFO, "Bad ACPI HW RegisterId: %X", 330 register_id)); 331 return_ACPI_STATUS(AE_BAD_PARAMETER); 332 } 333 334 lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); 335 336 /* Always do a register read first so we can insert the new bits */ 337 338 status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK, 339 bit_reg_info->parent_register, 340 ®ister_value); 341 if (ACPI_FAILURE(status)) { 342 goto unlock_and_exit; 343 } 344 345 /* 346 * Decode the Register ID 347 * Register ID = [Register block ID] | [bit ID] 348 * 349 * Check bit ID to fine locate Register offset. 350 * Check Mask to determine Register offset, and then read-write. 351 */ 352 switch (bit_reg_info->parent_register) { 353 case ACPI_REGISTER_PM1_STATUS: 354 355 /* 356 * Status Registers are different from the rest. Clear by 357 * writing 1, and writing 0 has no effect. So, the only relevant 358 * information is the single bit we're interested in, all others should 359 * be written as 0 so they will be left unchanged. 360 */ 361 value = ACPI_REGISTER_PREPARE_BITS(value, 362 bit_reg_info->bit_position, 363 bit_reg_info-> 364 access_bit_mask); 365 if (value) { 366 status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, 367 ACPI_REGISTER_PM1_STATUS, 368 (u16) value); 369 register_value = 0; 370 } 371 break; 372 373 case ACPI_REGISTER_PM1_ENABLE: 374 375 ACPI_REGISTER_INSERT_VALUE(register_value, 376 bit_reg_info->bit_position, 377 bit_reg_info->access_bit_mask, 378 value); 379 380 status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, 381 ACPI_REGISTER_PM1_ENABLE, 382 (u16) register_value); 383 break; 384 385 case ACPI_REGISTER_PM1_CONTROL: 386 387 /* 388 * Write the PM1 Control register. 389 * Note that at this level, the fact that there are actually TWO 390 * registers (A and B - and B may not exist) is abstracted. 391 */ 392 ACPI_DEBUG_PRINT((ACPI_DB_IO, "PM1 control: Read %X\n", 393 register_value)); 394 395 ACPI_REGISTER_INSERT_VALUE(register_value, 396 bit_reg_info->bit_position, 397 bit_reg_info->access_bit_mask, 398 value); 399 400 status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, 401 ACPI_REGISTER_PM1_CONTROL, 402 (u16) register_value); 403 break; 404 405 case ACPI_REGISTER_PM2_CONTROL: 406 407 status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK, 408 ACPI_REGISTER_PM2_CONTROL, 409 ®ister_value); 410 if (ACPI_FAILURE(status)) { 411 goto unlock_and_exit; 412 } 413 414 ACPI_DEBUG_PRINT((ACPI_DB_IO, 415 "PM2 control: Read %X from %8.8X%8.8X\n", 416 register_value, 417 ACPI_FORMAT_UINT64(acpi_gbl_FADT. 418 xpm2_control_block. 419 address))); 420 421 ACPI_REGISTER_INSERT_VALUE(register_value, 422 bit_reg_info->bit_position, 423 bit_reg_info->access_bit_mask, 424 value); 425 426 ACPI_DEBUG_PRINT((ACPI_DB_IO, 427 "About to write %4.4X to %8.8X%8.8X\n", 428 register_value, 429 ACPI_FORMAT_UINT64(acpi_gbl_FADT. 430 xpm2_control_block. 431 address))); 432 433 status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, 434 ACPI_REGISTER_PM2_CONTROL, 435 (u8) (register_value)); 436 break; 437 438 default: 439 break; 440 } 441 442 unlock_and_exit: 443 444 acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags); 445 446 /* Normalize the value that was read */ 447 448 ACPI_DEBUG_EXEC(register_value = 449 ((register_value & bit_reg_info->access_bit_mask) >> 450 bit_reg_info->bit_position)); 451 452 ACPI_DEBUG_PRINT((ACPI_DB_IO, 453 "Set bits: %8.8X actual %8.8X register %X\n", value, 454 register_value, bit_reg_info->parent_register)); 455 return_ACPI_STATUS(status); 456} 457 458ACPI_EXPORT_SYMBOL(acpi_set_register) 459 460/****************************************************************************** 461 * 462 * FUNCTION: acpi_hw_register_read 463 * 464 * PARAMETERS: use_lock - Lock hardware? True/False 465 * register_id - ACPI Register ID 466 * return_value - Where the register value is returned 467 * 468 * RETURN: Status and the value read. 469 * 470 * DESCRIPTION: Read from the specified ACPI register 471 * 472 ******************************************************************************/ 473acpi_status 474acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value) 475{ 476 u32 value1 = 0; 477 u32 value2 = 0; 478 acpi_status status; 479 acpi_cpu_flags lock_flags = 0; 480 481 ACPI_FUNCTION_TRACE(hw_register_read); 482 483 if (ACPI_MTX_LOCK == use_lock) { 484 lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); 485 } 486 487 switch (register_id) { 488 case ACPI_REGISTER_PM1_STATUS: /* 16-bit access */ 489 490 status = 491 acpi_hw_low_level_read(16, &value1, 492 &acpi_gbl_FADT.xpm1a_event_block); 493 if (ACPI_FAILURE(status)) { 494 goto unlock_and_exit; 495 } 496 497 /* PM1B is optional */ 498 499 status = 500 acpi_hw_low_level_read(16, &value2, 501 &acpi_gbl_FADT.xpm1b_event_block); 502 value1 |= value2; 503 break; 504 505 case ACPI_REGISTER_PM1_ENABLE: /* 16-bit access */ 506 507 status = 508 acpi_hw_low_level_read(16, &value1, &acpi_gbl_xpm1a_enable); 509 if (ACPI_FAILURE(status)) { 510 goto unlock_and_exit; 511 } 512 513 /* PM1B is optional */ 514 515 status = 516 acpi_hw_low_level_read(16, &value2, &acpi_gbl_xpm1b_enable); 517 value1 |= value2; 518 break; 519 520 case ACPI_REGISTER_PM1_CONTROL: /* 16-bit access */ 521 522 status = 523 acpi_hw_low_level_read(16, &value1, 524 &acpi_gbl_FADT.xpm1a_control_block); 525 if (ACPI_FAILURE(status)) { 526 goto unlock_and_exit; 527 } 528 529 status = 530 acpi_hw_low_level_read(16, &value2, 531 &acpi_gbl_FADT.xpm1b_control_block); 532 value1 |= value2; 533 break; 534 535 case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ 536 537 status = 538 acpi_hw_low_level_read(8, &value1, 539 &acpi_gbl_FADT.xpm2_control_block); 540 break; 541 542 case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ 543 544 status = 545 acpi_hw_low_level_read(32, &value1, 546 &acpi_gbl_FADT.xpm_timer_block); 547 break; 548 549 case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ 550 551 status = 552 acpi_os_read_port(acpi_gbl_FADT.smi_command, &value1, 8); 553 break; 554 555 default: 556 ACPI_ERROR((AE_INFO, "Unknown Register ID: %X", register_id)); 557 status = AE_BAD_PARAMETER; 558 break; 559 } 560 561 unlock_and_exit: 562 if (ACPI_MTX_LOCK == use_lock) { 563 acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags); 564 } 565 566 if (ACPI_SUCCESS(status)) { 567 *return_value = value1; 568 } 569 570 return_ACPI_STATUS(status); 571} 572 573/****************************************************************************** 574 * 575 * FUNCTION: acpi_hw_register_write 576 * 577 * PARAMETERS: use_lock - Lock hardware? True/False 578 * register_id - ACPI Register ID 579 * Value - The value to write 580 * 581 * RETURN: Status 582 * 583 * DESCRIPTION: Write to the specified ACPI register 584 * 585 * NOTE: In accordance with the ACPI specification, this function automatically 586 * preserves the value of the following bits, meaning that these bits cannot be 587 * changed via this interface: 588 * 589 * PM1_CONTROL[0] = SCI_EN 590 * PM1_CONTROL[9] 591 * PM1_STATUS[11] 592 * 593 * ACPI References: 594 * 1) Hardware Ignored Bits: When software writes to a register with ignored 595 * bit fields, it preserves the ignored bit fields 596 * 2) SCI_EN: OSPM always preserves this bit position 597 * 598 ******************************************************************************/ 599 600acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value) 601{ 602 acpi_status status; 603 acpi_cpu_flags lock_flags = 0; 604 u32 read_value; 605 606 ACPI_FUNCTION_TRACE(hw_register_write); 607 608 if (ACPI_MTX_LOCK == use_lock) { 609 lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); 610 } 611 612 switch (register_id) { 613 case ACPI_REGISTER_PM1_STATUS: /* 16-bit access */ 614 615 /* Perform a read first to preserve certain bits (per ACPI spec) */ 616 617 status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK, 618 ACPI_REGISTER_PM1_STATUS, 619 &read_value); 620 if (ACPI_FAILURE(status)) { 621 goto unlock_and_exit; 622 } 623 624 /* Insert the bits to be preserved */ 625 626 ACPI_INSERT_BITS(value, ACPI_PM1_STATUS_PRESERVED_BITS, 627 read_value); 628 629 /* Now we can write the data */ 630 631 status = 632 acpi_hw_low_level_write(16, value, 633 &acpi_gbl_FADT.xpm1a_event_block); 634 if (ACPI_FAILURE(status)) { 635 goto unlock_and_exit; 636 } 637 638 /* PM1B is optional */ 639 640 status = 641 acpi_hw_low_level_write(16, value, 642 &acpi_gbl_FADT.xpm1b_event_block); 643 break; 644 645 case ACPI_REGISTER_PM1_ENABLE: /* 16-bit access */ 646 647 status = 648 acpi_hw_low_level_write(16, value, &acpi_gbl_xpm1a_enable); 649 if (ACPI_FAILURE(status)) { 650 goto unlock_and_exit; 651 } 652 653 /* PM1B is optional */ 654 655 status = 656 acpi_hw_low_level_write(16, value, &acpi_gbl_xpm1b_enable); 657 break; 658 659 case ACPI_REGISTER_PM1_CONTROL: /* 16-bit access */ 660 661 /* 662 * Perform a read first to preserve certain bits (per ACPI spec) 663 */ 664 status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK, 665 ACPI_REGISTER_PM1_CONTROL, 666 &read_value); 667 if (ACPI_FAILURE(status)) { 668 goto unlock_and_exit; 669 } 670 671 /* Insert the bits to be preserved */ 672 673 ACPI_INSERT_BITS(value, ACPI_PM1_CONTROL_PRESERVED_BITS, 674 read_value); 675 676 /* Now we can write the data */ 677 678 status = 679 acpi_hw_low_level_write(16, value, 680 &acpi_gbl_FADT.xpm1a_control_block); 681 if (ACPI_FAILURE(status)) { 682 goto unlock_and_exit; 683 } 684 685 status = 686 acpi_hw_low_level_write(16, value, 687 &acpi_gbl_FADT.xpm1b_control_block); 688 break; 689 690 case ACPI_REGISTER_PM1A_CONTROL: /* 16-bit access */ 691 692 status = 693 acpi_hw_low_level_write(16, value, 694 &acpi_gbl_FADT.xpm1a_control_block); 695 break; 696 697 case ACPI_REGISTER_PM1B_CONTROL: /* 16-bit access */ 698 699 status = 700 acpi_hw_low_level_write(16, value, 701 &acpi_gbl_FADT.xpm1b_control_block); 702 break; 703 704 case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ 705 706 status = 707 acpi_hw_low_level_write(8, value, 708 &acpi_gbl_FADT.xpm2_control_block); 709 break; 710 711 case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ 712 713 status = 714 acpi_hw_low_level_write(32, value, 715 &acpi_gbl_FADT.xpm_timer_block); 716 break; 717 718 case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ 719 720 /* SMI_CMD is currently always in IO space */ 721 722 status = 723 acpi_os_write_port(acpi_gbl_FADT.smi_command, value, 8); 724 break; 725 726 default: 727 status = AE_BAD_PARAMETER; 728 break; 729 } 730 731 unlock_and_exit: 732 if (ACPI_MTX_LOCK == use_lock) { 733 acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags); 734 } 735 736 return_ACPI_STATUS(status); 737} 738 739/****************************************************************************** 740 * 741 * FUNCTION: acpi_hw_low_level_read 742 * 743 * PARAMETERS: Width - 8, 16, or 32 744 * Value - Where the value is returned 745 * Reg - GAS register structure 746 * 747 * RETURN: Status 748 * 749 * DESCRIPTION: Read from either memory or IO space. 750 * 751 ******************************************************************************/ 752 753acpi_status 754acpi_hw_low_level_read(u32 width, u32 * value, struct acpi_generic_address *reg) 755{ 756 u64 address; 757 acpi_status status; 758 759 ACPI_FUNCTION_NAME(hw_low_level_read); 760 761 /* 762 * Must have a valid pointer to a GAS structure, and 763 * a non-zero address within. However, don't return an error 764 * because the PM1A/B code must not fail if B isn't present. 765 */ 766 if (!reg) { 767 return (AE_OK); 768 } 769 770 /* Get a local copy of the address. Handles possible alignment issues */ 771 772 ACPI_MOVE_64_TO_64(&address, ®->address); 773 if (!address) { 774 return (AE_OK); 775 } 776 *value = 0; 777 778 /* 779 * Two address spaces supported: Memory or IO. 780 * PCI_Config is not supported here because the GAS struct is insufficient 781 */ 782 switch (reg->space_id) { 783 case ACPI_ADR_SPACE_SYSTEM_MEMORY: 784 785 status = acpi_os_read_memory((acpi_physical_address) address, 786 value, width); 787 break; 788 789 case ACPI_ADR_SPACE_SYSTEM_IO: 790 791 status = 792 acpi_os_read_port((acpi_io_address) address, value, width); 793 break; 794 795 default: 796 ACPI_ERROR((AE_INFO, 797 "Unsupported address space: %X", reg->space_id)); 798 return (AE_BAD_PARAMETER); 799 } 800 801 ACPI_DEBUG_PRINT((ACPI_DB_IO, 802 "Read: %8.8X width %2d from %8.8X%8.8X (%s)\n", 803 *value, width, ACPI_FORMAT_UINT64(address), 804 acpi_ut_get_region_name(reg->space_id))); 805 806 return (status); 807} 808 809/****************************************************************************** 810 * 811 * FUNCTION: acpi_hw_low_level_write 812 * 813 * PARAMETERS: Width - 8, 16, or 32 814 * Value - To be written 815 * Reg - GAS register structure 816 * 817 * RETURN: Status 818 * 819 * DESCRIPTION: Write to either memory or IO space. 820 * 821 ******************************************************************************/ 822 823acpi_status 824acpi_hw_low_level_write(u32 width, u32 value, struct acpi_generic_address * reg) 825{ 826 u64 address; 827 acpi_status status; 828 829 ACPI_FUNCTION_NAME(hw_low_level_write); 830 831 /* 832 * Must have a valid pointer to a GAS structure, and 833 * a non-zero address within. However, don't return an error 834 * because the PM1A/B code must not fail if B isn't present. 835 */ 836 if (!reg) { 837 return (AE_OK); 838 } 839 840 /* Get a local copy of the address. Handles possible alignment issues */ 841 842 ACPI_MOVE_64_TO_64(&address, ®->address); 843 if (!address) { 844 return (AE_OK); 845 } 846 847 /* 848 * Two address spaces supported: Memory or IO. 849 * PCI_Config is not supported here because the GAS struct is insufficient 850 */ 851 switch (reg->space_id) { 852 case ACPI_ADR_SPACE_SYSTEM_MEMORY: 853 854 status = acpi_os_write_memory((acpi_physical_address) address, 855 value, width); 856 break; 857 858 case ACPI_ADR_SPACE_SYSTEM_IO: 859 860 status = acpi_os_write_port((acpi_io_address) address, value, 861 width); 862 break; 863 864 default: 865 ACPI_ERROR((AE_INFO, 866 "Unsupported address space: %X", reg->space_id)); 867 return (AE_BAD_PARAMETER); 868 } 869 870 ACPI_DEBUG_PRINT((ACPI_DB_IO, 871 "Wrote: %8.8X width %2d to %8.8X%8.8X (%s)\n", 872 value, width, ACPI_FORMAT_UINT64(address), 873 acpi_ut_get_region_name(reg->space_id))); 874 875 return (status); 876} 877