1 2/******************************************************************************* 3 * 4 * Module Name: hwregs - Read/write access functions for the various ACPI 5 * control and status registers. 6 * $Revision: 1.1.1.1 $ 7 * 8 ******************************************************************************/ 9 10/* 11 * Copyright (C) 2000, 2001 R. Byron Moore 12 * 13 * This program is free software; you can redistribute it and/or modify 14 * it under the terms of the GNU General Public License as published by 15 * the Free Software Foundation; either version 2 of the License, or 16 * (at your option) any later version. 17 * 18 * This program is distributed in the hope that it will be useful, 19 * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 * GNU General Public License for more details. 22 * 23 * You should have received a copy of the GNU General Public License 24 * along with this program; if not, write to the Free Software 25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 26 */ 27 28 29#include "acpi.h" 30#include "achware.h" 31#include "acnamesp.h" 32 33#define _COMPONENT ACPI_HARDWARE 34 MODULE_NAME ("hwregs") 35 36 37/******************************************************************************* 38 * 39 * FUNCTION: Acpi_hw_get_bit_shift 40 * 41 * PARAMETERS: Mask - Input mask to determine bit shift from. 42 * Must have at least 1 bit set. 43 * 44 * RETURN: Bit location of the lsb of the mask 45 * 46 * DESCRIPTION: Returns the bit number for the low order bit that's set. 47 * 48 ******************************************************************************/ 49 50u32 51acpi_hw_get_bit_shift ( 52 u32 mask) 53{ 54 u32 shift; 55 56 57 FUNCTION_TRACE ("Hw_get_bit_shift"); 58 59 60 for (shift = 0; ((mask >> shift) & 1) == 0; shift++) { ; } 61 62 return_VALUE (shift); 63} 64 65 66/******************************************************************************* 67 * 68 * FUNCTION: Acpi_hw_clear_acpi_status 69 * 70 * PARAMETERS: none 71 * 72 * RETURN: none 73 * 74 * DESCRIPTION: Clears all fixed and general purpose status bits 75 * 76 ******************************************************************************/ 77 78void 79acpi_hw_clear_acpi_status (void) 80{ 81 u16 gpe_length; 82 u16 index; 83 84 85 FUNCTION_TRACE ("Hw_clear_acpi_status"); 86 87 88 ACPI_DEBUG_PRINT ((ACPI_DB_IO, "About to write %04X to %04X\n", 89 ALL_FIXED_STS_BITS, 90 (u16) ACPI_GET_ADDRESS (acpi_gbl_FADT->Xpm1a_evt_blk.address))); 91 92 93 acpi_ut_acquire_mutex (ACPI_MTX_HARDWARE); 94 95 acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, PM1_STS, ALL_FIXED_STS_BITS); 96 97 98 if (ACPI_VALID_ADDRESS (acpi_gbl_FADT->Xpm1b_evt_blk.address)) { 99 acpi_os_write_port ((ACPI_IO_ADDRESS) 100 ACPI_GET_ADDRESS (acpi_gbl_FADT->Xpm1b_evt_blk.address), 101 ALL_FIXED_STS_BITS, 16); 102 } 103 104 /* now clear the GPE Bits */ 105 106 if (acpi_gbl_FADT->gpe0blk_len) { 107 gpe_length = (u16) DIV_2 (acpi_gbl_FADT->gpe0blk_len); 108 109 for (index = 0; index < gpe_length; index++) { 110 acpi_os_write_port ((ACPI_IO_ADDRESS) ( 111 ACPI_GET_ADDRESS (acpi_gbl_FADT->Xgpe0blk.address) + index), 112 0xFF, 8); 113 } 114 } 115 116 if (acpi_gbl_FADT->gpe1_blk_len) { 117 gpe_length = (u16) DIV_2 (acpi_gbl_FADT->gpe1_blk_len); 118 119 for (index = 0; index < gpe_length; index++) { 120 acpi_os_write_port ((ACPI_IO_ADDRESS) ( 121 ACPI_GET_ADDRESS (acpi_gbl_FADT->Xgpe1_blk.address) + index), 122 0xFF, 8); 123 } 124 } 125 126 acpi_ut_release_mutex (ACPI_MTX_HARDWARE); 127 return_VOID; 128} 129 130 131/******************************************************************************* 132 * 133 * FUNCTION: Acpi_hw_obtain_sleep_type_register_data 134 * 135 * PARAMETERS: Sleep_state - Numeric state requested 136 * *Slp_Typ_a - Pointer to byte to receive SLP_TYPa value 137 * *Slp_Typ_b - Pointer to byte to receive SLP_TYPb value 138 * 139 * RETURN: Status - ACPI status 140 * 141 * DESCRIPTION: Acpi_hw_obtain_sleep_type_register_data() obtains the SLP_TYP and 142 * SLP_TYPb values for the sleep state requested. 143 * 144 ******************************************************************************/ 145 146acpi_status 147acpi_hw_obtain_sleep_type_register_data ( 148 u8 sleep_state, 149 u8 *slp_typ_a, 150 u8 *slp_typ_b) 151{ 152 acpi_status status = AE_OK; 153 acpi_operand_object *obj_desc; 154 155 156 FUNCTION_TRACE ("Hw_obtain_sleep_type_register_data"); 157 158 159 /* 160 * Validate parameters 161 */ 162 if ((sleep_state > ACPI_S_STATES_MAX) || 163 !slp_typ_a || !slp_typ_b) { 164 return_ACPI_STATUS (AE_BAD_PARAMETER); 165 } 166 167 /* 168 * Acpi_evaluate the namespace object containing the values for this state 169 */ 170 status = acpi_ns_evaluate_by_name ((NATIVE_CHAR *) acpi_gbl_db_sleep_states[sleep_state], 171 NULL, &obj_desc); 172 if (ACPI_FAILURE (status)) { 173 return_ACPI_STATUS (status); 174 } 175 176 if (!obj_desc) { 177 REPORT_ERROR (("Missing Sleep State object\n")); 178 return_ACPI_STATUS (AE_NOT_EXIST); 179 } 180 181 /* 182 * We got something, now ensure it is correct. The object must 183 * be a package and must have at least 2 numeric values as the 184 * two elements 185 */ 186 187 /* Even though Acpi_evaluate_object resolves package references, 188 * Ns_evaluate dpesn't. So, we do it here. 189 */ 190 status = acpi_ut_resolve_package_references(obj_desc); 191 192 if (obj_desc->package.count < 2) { 193 /* Must have at least two elements */ 194 195 REPORT_ERROR (("Sleep State package does not have at least two elements\n")); 196 status = AE_ERROR; 197 } 198 199 else if (((obj_desc->package.elements[0])->common.type != 200 ACPI_TYPE_INTEGER) || 201 ((obj_desc->package.elements[1])->common.type != 202 ACPI_TYPE_INTEGER)) { 203 /* Must have two */ 204 205 REPORT_ERROR (("Sleep State package elements are not both of type Number\n")); 206 status = AE_ERROR; 207 } 208 209 else { 210 /* 211 * Valid _Sx_ package size, type, and value 212 */ 213 *slp_typ_a = (u8) (obj_desc->package.elements[0])->integer.value; 214 215 *slp_typ_b = (u8) (obj_desc->package.elements[1])->integer.value; 216 } 217 218 219 if (ACPI_FAILURE (status)) { 220 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Bad Sleep object %p type %X\n", 221 obj_desc, obj_desc->common.type)); 222 } 223 224 acpi_ut_remove_reference (obj_desc); 225 226 return_ACPI_STATUS (status); 227} 228 229 230/******************************************************************************* 231 * 232 * FUNCTION: Acpi_hw_register_bit_access 233 * 234 * PARAMETERS: Read_write - Either ACPI_READ or ACPI_WRITE. 235 * Use_lock - Lock the hardware 236 * Register_id - index of ACPI Register to access 237 * Value - (only used on write) value to write to the 238 * Register. Shifted all the way right. 239 * 240 * RETURN: Value written to or read from specified Register. This value 241 * is shifted all the way right. 242 * 243 * DESCRIPTION: Generic ACPI Register read/write function. 244 * 245 ******************************************************************************/ 246 247u32 248acpi_hw_register_bit_access ( 249 NATIVE_UINT read_write, 250 u8 use_lock, 251 u32 register_id, 252 ...) /* Value (only used on write) */ 253{ 254 u32 register_value = 0; 255 u32 mask = 0; 256 u32 value = 0; 257 va_list marker; 258 259 260 FUNCTION_TRACE ("Hw_register_bit_access"); 261 262 263 if (read_write == ACPI_WRITE) { 264 va_start (marker, register_id); 265 value = va_arg (marker, u32); 266 va_end (marker); 267 } 268 269 if (ACPI_MTX_LOCK == use_lock) { 270 acpi_ut_acquire_mutex (ACPI_MTX_HARDWARE); 271 } 272 273 /* 274 * Decode the Register ID 275 * Register id = Register block id | bit id 276 * 277 * Check bit id to fine locate Register offset. 278 * Check Mask to determine Register offset, and then read-write. 279 */ 280 switch (REGISTER_BLOCK_ID (register_id)) { 281 case PM1_STS: 282 283 switch (register_id) { 284 case TMR_STS: 285 mask = TMR_STS_MASK; 286 break; 287 288 case BM_STS: 289 mask = BM_STS_MASK; 290 break; 291 292 case GBL_STS: 293 mask = GBL_STS_MASK; 294 break; 295 296 case PWRBTN_STS: 297 mask = PWRBTN_STS_MASK; 298 break; 299 300 case SLPBTN_STS: 301 mask = SLPBTN_STS_MASK; 302 break; 303 304 case RTC_STS: 305 mask = RTC_STS_MASK; 306 break; 307 308 case WAK_STS: 309 mask = WAK_STS_MASK; 310 break; 311 312 default: 313 mask = 0; 314 break; 315 } 316 317 register_value = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, PM1_STS); 318 319 if (read_write == ACPI_WRITE) { 320 /* 321 * Status Registers are different from the rest. Clear by 322 * writing 1, writing 0 has no effect. So, the only relevent 323 * information is the single bit we're interested in, all 324 * others should be written as 0 so they will be left 325 * unchanged 326 */ 327 value <<= acpi_hw_get_bit_shift (mask); 328 value &= mask; 329 330 if (value) { 331 acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, PM1_STS, 332 (u16) value); 333 register_value = 0; 334 } 335 } 336 337 break; 338 339 340 case PM1_EN: 341 342 switch (register_id) { 343 case TMR_EN: 344 mask = TMR_EN_MASK; 345 break; 346 347 case GBL_EN: 348 mask = GBL_EN_MASK; 349 break; 350 351 case PWRBTN_EN: 352 mask = PWRBTN_EN_MASK; 353 break; 354 355 case SLPBTN_EN: 356 mask = SLPBTN_EN_MASK; 357 break; 358 359 case RTC_EN: 360 mask = RTC_EN_MASK; 361 break; 362 363 default: 364 mask = 0; 365 break; 366 } 367 368 register_value = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, PM1_EN); 369 370 if (read_write == ACPI_WRITE) { 371 register_value &= ~mask; 372 value <<= acpi_hw_get_bit_shift (mask); 373 value &= mask; 374 register_value |= value; 375 376 acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, PM1_EN, (u16) register_value); 377 } 378 379 break; 380 381 382 case PM1_CONTROL: 383 384 switch (register_id) { 385 case SCI_EN: 386 mask = SCI_EN_MASK; 387 break; 388 389 case BM_RLD: 390 mask = BM_RLD_MASK; 391 break; 392 393 case GBL_RLS: 394 mask = GBL_RLS_MASK; 395 break; 396 397 case SLP_TYPE_A: 398 case SLP_TYPE_B: 399 mask = SLP_TYPE_X_MASK; 400 break; 401 402 case SLP_EN: 403 mask = SLP_EN_MASK; 404 break; 405 406 default: 407 mask = 0; 408 break; 409 } 410 411 412 /* 413 * Read the PM1 Control register. 414 * Note that at this level, the fact that there are actually TWO 415 * registers (A and B) and that B may not exist, are abstracted. 416 */ 417 register_value = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, PM1_CONTROL); 418 419 ACPI_DEBUG_PRINT ((ACPI_DB_IO, "PM1 control: Read %X\n", register_value)); 420 421 if (read_write == ACPI_WRITE) { 422 register_value &= ~mask; 423 value <<= acpi_hw_get_bit_shift (mask); 424 value &= mask; 425 register_value |= value; 426 427 /* 428 * SLP_TYPE_x Registers are written differently 429 * than any other control Registers with 430 * respect to A and B Registers. The value 431 * for A may be different than the value for B 432 * 433 * Therefore, pass the Register_id, not just generic PM1_CONTROL, 434 * because we need to do different things. Yuck. 435 */ 436 acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, register_id, 437 (u16) register_value); 438 } 439 break; 440 441 442 case PM2_CONTROL: 443 444 switch (register_id) { 445 case ARB_DIS: 446 mask = ARB_DIS_MASK; 447 break; 448 449 default: 450 mask = 0; 451 break; 452 } 453 454 register_value = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, PM2_CONTROL); 455 456 ACPI_DEBUG_PRINT ((ACPI_DB_IO, "PM2 control: Read %X from %8.8X%8.8X\n", 457 register_value, HIDWORD(acpi_gbl_FADT->Xpm2_cnt_blk.address), 458 LODWORD(acpi_gbl_FADT->Xpm2_cnt_blk.address))); 459 460 if (read_write == ACPI_WRITE) { 461 register_value &= ~mask; 462 value <<= acpi_hw_get_bit_shift (mask); 463 value &= mask; 464 register_value |= value; 465 466 ACPI_DEBUG_PRINT ((ACPI_DB_IO, "About to write %04X to %8.8X%8.8X\n", 467 register_value, 468 HIDWORD(acpi_gbl_FADT->Xpm2_cnt_blk.address), 469 LODWORD(acpi_gbl_FADT->Xpm2_cnt_blk.address))); 470 471 acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, 472 PM2_CONTROL, (u8) (register_value)); 473 } 474 break; 475 476 477 case PM_TIMER: 478 479 mask = TMR_VAL_MASK; 480 register_value = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, 481 PM_TIMER); 482 ACPI_DEBUG_PRINT ((ACPI_DB_IO, "PM_TIMER: Read %X from %8.8X%8.8X\n", 483 register_value, 484 HIDWORD(acpi_gbl_FADT->Xpm_tmr_blk.address), 485 LODWORD(acpi_gbl_FADT->Xpm_tmr_blk.address))); 486 487 break; 488 489 490 case GPE1_EN_BLOCK: 491 case GPE1_STS_BLOCK: 492 case GPE0_EN_BLOCK: 493 case GPE0_STS_BLOCK: 494 495 /* Determine the bit to be accessed 496 * 497 * (u32) Register_id: 498 * 31 24 16 8 0 499 * +--------+--------+--------+--------+ 500 * | gpe_block_id | gpe_bit_number | 501 * +--------+--------+--------+--------+ 502 * 503 * gpe_block_id is one of GPE[01]_EN_BLOCK and GPE[01]_STS_BLOCK 504 * gpe_bit_number is relative from the gpe_block (0x00~0xFF) 505 */ 506 mask = REGISTER_BIT_ID(register_id); /* gpe_bit_number */ 507 register_id = REGISTER_BLOCK_ID(register_id) | (mask >> 3); 508 mask = acpi_gbl_decode_to8bit [mask % 8]; 509 510 /* 511 * The base address of the GPE 0 Register Block 512 * Plus 1/2 the length of the GPE 0 Register Block 513 * The enable Register is the Register following the Status Register 514 * and each Register is defined as 1/2 of the total Register Block 515 */ 516 517 /* 518 * This sets the bit within Enable_bit that needs to be written to 519 * the Register indicated in Mask to a 1, all others are 0 520 */ 521 522 /* Now get the current Enable Bits in the selected Reg */ 523 524 register_value = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, register_id); 525 ACPI_DEBUG_PRINT ((ACPI_DB_IO, "GPE Enable bits: Read %X from %X\n", 526 register_value, register_id)); 527 528 if (read_write == ACPI_WRITE) { 529 register_value &= ~mask; 530 value <<= acpi_hw_get_bit_shift (mask); 531 value &= mask; 532 register_value |= value; 533 534 /* 535 * This write will put the Action state into the General Purpose 536 * Enable Register indexed by the value in Mask 537 */ 538 ACPI_DEBUG_PRINT ((ACPI_DB_IO, "About to write %04X to %04X\n", 539 register_value, register_id)); 540 acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, register_id, 541 (u8) register_value); 542 register_value = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, 543 register_id); 544 } 545 break; 546 547 548 case SMI_CMD_BLOCK: 549 case PROCESSOR_BLOCK: 550 551 /* Not used by any callers at this time - therefore, not implemented */ 552 553 default: 554 555 mask = 0; 556 break; 557 } 558 559 if (ACPI_MTX_LOCK == use_lock) { 560 acpi_ut_release_mutex (ACPI_MTX_HARDWARE); 561 } 562 563 564 register_value &= mask; 565 register_value >>= acpi_hw_get_bit_shift (mask); 566 567 ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Register I/O: returning %X\n", register_value)); 568 return_VALUE (register_value); 569} 570 571 572/****************************************************************************** 573 * 574 * FUNCTION: Acpi_hw_register_read 575 * 576 * PARAMETERS: Use_lock - Mutex hw access. 577 * Register_id - Register_iD + Offset. 578 * 579 * RETURN: Value read or written. 580 * 581 * DESCRIPTION: Acpi register read function. Registers are read at the 582 * given offset. 583 * 584 ******************************************************************************/ 585 586u32 587acpi_hw_register_read ( 588 u8 use_lock, 589 u32 register_id) 590{ 591 u32 value = 0; 592 u32 bank_offset; 593 594 595 FUNCTION_TRACE ("Hw_register_read"); 596 597 598 if (ACPI_MTX_LOCK == use_lock) { 599 acpi_ut_acquire_mutex (ACPI_MTX_HARDWARE); 600 } 601 602 603 switch (REGISTER_BLOCK_ID(register_id)) { 604 case PM1_STS: /* 16-bit access */ 605 606 value = acpi_hw_low_level_read (16, &acpi_gbl_FADT->Xpm1a_evt_blk, 0); 607 value |= acpi_hw_low_level_read (16, &acpi_gbl_FADT->Xpm1b_evt_blk, 0); 608 break; 609 610 611 case PM1_EN: /* 16-bit access*/ 612 613 bank_offset = DIV_2 (acpi_gbl_FADT->pm1_evt_len); 614 value = acpi_hw_low_level_read (16, &acpi_gbl_FADT->Xpm1a_evt_blk, bank_offset); 615 value |= acpi_hw_low_level_read (16, &acpi_gbl_FADT->Xpm1b_evt_blk, bank_offset); 616 break; 617 618 619 case PM1_CONTROL: /* 16-bit access */ 620 621 value = acpi_hw_low_level_read (16, &acpi_gbl_FADT->Xpm1a_cnt_blk, 0); 622 value |= acpi_hw_low_level_read (16, &acpi_gbl_FADT->Xpm1b_cnt_blk, 0); 623 break; 624 625 626 case PM2_CONTROL: /* 8-bit access */ 627 628 value = acpi_hw_low_level_read (8, &acpi_gbl_FADT->Xpm2_cnt_blk, 0); 629 break; 630 631 632 case PM_TIMER: /* 32-bit access */ 633 634 value = acpi_hw_low_level_read (32, &acpi_gbl_FADT->Xpm_tmr_blk, 0); 635 break; 636 637 638 /* 639 * For the GPE? Blocks, the lower word of Register_id contains the 640 * byte offset for which to read, as each part of each block may be 641 * several bytes long. 642 */ 643 case GPE0_STS_BLOCK: /* 8-bit access */ 644 645 bank_offset = REGISTER_BIT_ID(register_id); 646 value = acpi_hw_low_level_read (8, &acpi_gbl_FADT->Xgpe0blk, bank_offset); 647 break; 648 649 case GPE0_EN_BLOCK: /* 8-bit access */ 650 651 bank_offset = DIV_2 (acpi_gbl_FADT->gpe0blk_len) + REGISTER_BIT_ID(register_id); 652 value = acpi_hw_low_level_read (8, &acpi_gbl_FADT->Xgpe0blk, bank_offset); 653 break; 654 655 case GPE1_STS_BLOCK: /* 8-bit access */ 656 657 bank_offset = REGISTER_BIT_ID(register_id); 658 value = acpi_hw_low_level_read (8, &acpi_gbl_FADT->Xgpe1_blk, bank_offset); 659 break; 660 661 case GPE1_EN_BLOCK: /* 8-bit access */ 662 663 bank_offset = DIV_2 (acpi_gbl_FADT->gpe1_blk_len) + REGISTER_BIT_ID(register_id); 664 value = acpi_hw_low_level_read (8, &acpi_gbl_FADT->Xgpe1_blk, bank_offset); 665 break; 666 667 case SMI_CMD_BLOCK: /* 8bit */ 668 669 acpi_os_read_port (acpi_gbl_FADT->smi_cmd, &value, 8); 670 break; 671 672 default: 673 /* Value will be returned as 0 */ 674 break; 675 } 676 677 678 if (ACPI_MTX_LOCK == use_lock) { 679 acpi_ut_release_mutex (ACPI_MTX_HARDWARE); 680 } 681 682 return_VALUE (value); 683} 684 685 686/****************************************************************************** 687 * 688 * FUNCTION: Acpi_hw_register_write 689 * 690 * PARAMETERS: Use_lock - Mutex hw access. 691 * Register_id - Register_iD + Offset. 692 * 693 * RETURN: Value read or written. 694 * 695 * DESCRIPTION: Acpi register Write function. Registers are written at the 696 * given offset. 697 * 698 ******************************************************************************/ 699 700void 701acpi_hw_register_write ( 702 u8 use_lock, 703 u32 register_id, 704 u32 value) 705{ 706 u32 bank_offset; 707 708 709 FUNCTION_TRACE ("Hw_register_write"); 710 711 712 if (ACPI_MTX_LOCK == use_lock) { 713 acpi_ut_acquire_mutex (ACPI_MTX_HARDWARE); 714 } 715 716 717 switch (REGISTER_BLOCK_ID (register_id)) { 718 case PM1_STS: /* 16-bit access */ 719 720 acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1a_evt_blk, 0); 721 acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1b_evt_blk, 0); 722 break; 723 724 725 case PM1_EN: /* 16-bit access*/ 726 727 bank_offset = DIV_2 (acpi_gbl_FADT->pm1_evt_len); 728 acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1a_evt_blk, bank_offset); 729 acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1b_evt_blk, bank_offset); 730 break; 731 732 733 case PM1_CONTROL: /* 16-bit access */ 734 735 acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1a_cnt_blk, 0); 736 acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1b_cnt_blk, 0); 737 break; 738 739 740 case PM1A_CONTROL: /* 16-bit access */ 741 742 acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1a_cnt_blk, 0); 743 break; 744 745 746 case PM1B_CONTROL: /* 16-bit access */ 747 748 acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1b_cnt_blk, 0); 749 break; 750 751 752 case PM2_CONTROL: /* 8-bit access */ 753 754 acpi_hw_low_level_write (8, value, &acpi_gbl_FADT->Xpm2_cnt_blk, 0); 755 break; 756 757 758 case PM_TIMER: /* 32-bit access */ 759 760 acpi_hw_low_level_write (32, value, &acpi_gbl_FADT->Xpm_tmr_blk, 0); 761 break; 762 763 764 case GPE0_STS_BLOCK: /* 8-bit access */ 765 766 bank_offset = REGISTER_BIT_ID(register_id); 767 acpi_hw_low_level_write (8, value, &acpi_gbl_FADT->Xgpe0blk, bank_offset); 768 break; 769 770 771 case GPE0_EN_BLOCK: /* 8-bit access */ 772 773 bank_offset = DIV_2 (acpi_gbl_FADT->gpe0blk_len) + REGISTER_BIT_ID(register_id); 774 acpi_hw_low_level_write (8, value, &acpi_gbl_FADT->Xgpe0blk, bank_offset); 775 break; 776 777 778 case GPE1_STS_BLOCK: /* 8-bit access */ 779 780 bank_offset = REGISTER_BIT_ID(register_id); 781 acpi_hw_low_level_write (8, value, &acpi_gbl_FADT->Xgpe1_blk, bank_offset); 782 break; 783 784 785 case GPE1_EN_BLOCK: /* 8-bit access */ 786 787 bank_offset = DIV_2 (acpi_gbl_FADT->gpe1_blk_len) + REGISTER_BIT_ID(register_id); 788 acpi_hw_low_level_write (8, value, &acpi_gbl_FADT->Xgpe1_blk, bank_offset); 789 break; 790 791 792 case SMI_CMD_BLOCK: /* 8bit */ 793 794 /* For 2.0, SMI_CMD is always in IO space */ 795 /* TBD: what about 1.0? 0.71? */ 796 797 acpi_os_write_port (acpi_gbl_FADT->smi_cmd, value, 8); 798 break; 799 800 801 default: 802 value = 0; 803 break; 804 } 805 806 807 if (ACPI_MTX_LOCK == use_lock) { 808 acpi_ut_release_mutex (ACPI_MTX_HARDWARE); 809 } 810 811 return_VOID; 812} 813 814 815/****************************************************************************** 816 * 817 * FUNCTION: Acpi_hw_low_level_read 818 * 819 * PARAMETERS: Register - GAS register structure 820 * Offset - Offset from the base address in the GAS 821 * Width - 8, 16, or 32 822 * 823 * RETURN: Value read 824 * 825 * DESCRIPTION: Read from either memory, IO, or PCI config space. 826 * 827 ******************************************************************************/ 828 829u32 830acpi_hw_low_level_read ( 831 u32 width, 832 acpi_generic_address *reg, 833 u32 offset) 834{ 835 u32 value = 0; 836 ACPI_PHYSICAL_ADDRESS mem_address; 837 ACPI_IO_ADDRESS io_address; 838 acpi_pci_id pci_id; 839 u16 pci_register; 840 841 842 FUNCTION_ENTRY (); 843 844 845 /* 846 * Must have a valid pointer to a GAS structure, and 847 * a non-zero address within 848 */ 849 if ((!reg) || 850 (!ACPI_VALID_ADDRESS (reg->address))) { 851 return 0; 852 } 853 854 855 /* 856 * Three address spaces supported: 857 * Memory, Io, or PCI config. 858 */ 859 switch (reg->address_space_id) { 860 case ACPI_ADR_SPACE_SYSTEM_MEMORY: 861 862 mem_address = (ACPI_PHYSICAL_ADDRESS) (ACPI_GET_ADDRESS (reg->address) + offset); 863 864 acpi_os_read_memory (mem_address, &value, width); 865 break; 866 867 868 case ACPI_ADR_SPACE_SYSTEM_IO: 869 870 io_address = (ACPI_IO_ADDRESS) (ACPI_GET_ADDRESS (reg->address) + offset); 871 872 acpi_os_read_port (io_address, &value, width); 873 break; 874 875 876 case ACPI_ADR_SPACE_PCI_CONFIG: 877 878 pci_id.segment = 0; 879 pci_id.bus = 0; 880 pci_id.device = ACPI_PCI_DEVICE (ACPI_GET_ADDRESS (reg->address)); 881 pci_id.function = ACPI_PCI_FUNCTION (ACPI_GET_ADDRESS (reg->address)); 882 pci_register = (u16) (ACPI_PCI_REGISTER (ACPI_GET_ADDRESS (reg->address)) + offset); 883 884 acpi_os_read_pci_configuration (&pci_id, pci_register, &value, width); 885 break; 886 } 887 888 return value; 889} 890 891 892/****************************************************************************** 893 * 894 * FUNCTION: Acpi_hw_low_level_write 895 * 896 * PARAMETERS: Width - 8, 16, or 32 897 * Value - To be written 898 * Register - GAS register structure 899 * Offset - Offset from the base address in the GAS 900 * 901 * 902 * RETURN: Value read 903 * 904 * DESCRIPTION: Read from either memory, IO, or PCI config space. 905 * 906 ******************************************************************************/ 907 908void 909acpi_hw_low_level_write ( 910 u32 width, 911 u32 value, 912 acpi_generic_address *reg, 913 u32 offset) 914{ 915 ACPI_PHYSICAL_ADDRESS mem_address; 916 ACPI_IO_ADDRESS io_address; 917 acpi_pci_id pci_id; 918 u16 pci_register; 919 920 921 FUNCTION_ENTRY (); 922 923 924 /* 925 * Must have a valid pointer to a GAS structure, and 926 * a non-zero address within 927 */ 928 if ((!reg) || 929 (!ACPI_VALID_ADDRESS (reg->address))) { 930 return; 931 } 932 933 934 /* 935 * Three address spaces supported: 936 * Memory, Io, or PCI config. 937 */ 938 switch (reg->address_space_id) { 939 case ACPI_ADR_SPACE_SYSTEM_MEMORY: 940 941 mem_address = (ACPI_PHYSICAL_ADDRESS) (ACPI_GET_ADDRESS (reg->address) + offset); 942 943 acpi_os_write_memory (mem_address, value, width); 944 break; 945 946 947 case ACPI_ADR_SPACE_SYSTEM_IO: 948 949 io_address = (ACPI_IO_ADDRESS) (ACPI_GET_ADDRESS (reg->address) + offset); 950 951 acpi_os_write_port (io_address, value, width); 952 break; 953 954 955 case ACPI_ADR_SPACE_PCI_CONFIG: 956 957 pci_id.segment = 0; 958 pci_id.bus = 0; 959 pci_id.device = ACPI_PCI_DEVICE (ACPI_GET_ADDRESS (reg->address)); 960 pci_id.function = ACPI_PCI_FUNCTION (ACPI_GET_ADDRESS (reg->address)); 961 pci_register = (u16) (ACPI_PCI_REGISTER (ACPI_GET_ADDRESS (reg->address)) + offset); 962 963 acpi_os_write_pci_configuration (&pci_id, pci_register, value, width); 964 break; 965 } 966} 967