2 /*******************************************************************************
4 * Module Name: hwregs - Read/write access functions for the various ACPI
5 * control and status registers.
8 ******************************************************************************/
11 * Copyright (C) 2000, 2001 R. Byron Moore
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.
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.
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
31 #define _COMPONENT ACPI_HARDWARE
32 MODULE_NAME ("hwregs")
35 /* This matches the #defines in actypes.h. */
37 NATIVE_CHAR
*sleep_state_table
[] = {"\\_S0_","\\_S1_","\\_S2_","\\_S3_",
38 "\\_S4_","\\_S5_","\\_S4_b"};
41 /*******************************************************************************
43 * FUNCTION: Acpi_hw_get_bit_shift
45 * PARAMETERS: Mask - Input mask to determine bit shift from.
46 * Must have at least 1 bit set.
48 * RETURN: Bit location of the lsb of the mask
50 * DESCRIPTION: Returns the bit number for the low order bit that's set.
52 ******************************************************************************/
55 acpi_hw_get_bit_shift (
60 for (shift
= 0; ((mask
>> shift
) & 1) == 0; shift
++) { ; }
66 /*******************************************************************************
68 * FUNCTION: Acpi_hw_clear_acpi_status
74 * DESCRIPTION: Clears all fixed and general purpose status bits
76 ******************************************************************************/
79 acpi_hw_clear_acpi_status (void)
85 acpi_cm_acquire_mutex (ACPI_MTX_HARDWARE
);
87 acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK
, PM1_STS
, ALL_FIXED_STS_BITS
);
90 if (ACPI_VALID_ADDRESS (acpi_gbl_FADT
->Xpm1b_evt_blk
.address
)) {
91 acpi_os_out16 ((ACPI_IO_ADDRESS
) ACPI_GET_ADDRESS (acpi_gbl_FADT
->Xpm1b_evt_blk
.address
),
92 (u16
) ALL_FIXED_STS_BITS
);
95 /* now clear the GPE Bits */
97 if (acpi_gbl_FADT
->gpe0blk_len
) {
98 gpe_length
= (u16
) DIV_2 (acpi_gbl_FADT
->gpe0blk_len
);
100 for (index
= 0; index
< gpe_length
; index
++) {
101 acpi_os_out8 ((ACPI_IO_ADDRESS
) (ACPI_GET_ADDRESS (acpi_gbl_FADT
->Xgpe0blk
.address
) + index
),
106 if (acpi_gbl_FADT
->gpe1_blk_len
) {
107 gpe_length
= (u16
) DIV_2 (acpi_gbl_FADT
->gpe1_blk_len
);
109 for (index
= 0; index
< gpe_length
; index
++) {
110 acpi_os_out8 ((ACPI_IO_ADDRESS
) (ACPI_GET_ADDRESS (acpi_gbl_FADT
->Xgpe1_blk
.address
) + index
),
115 acpi_cm_release_mutex (ACPI_MTX_HARDWARE
);
120 /*******************************************************************************
122 * FUNCTION: Acpi_hw_obtain_sleep_type_register_data
124 * PARAMETERS: Sleep_state - Numeric state requested
125 * *Slp_Typ_a - Pointer to byte to receive SLP_TYPa value
126 * *Slp_Typ_b - Pointer to byte to receive SLP_TYPb value
128 * RETURN: Status - ACPI status
130 * DESCRIPTION: Acpi_hw_obtain_sleep_type_register_data() obtains the SLP_TYP and
131 * SLP_TYPb values for the sleep state requested.
133 ******************************************************************************/
136 acpi_hw_obtain_sleep_type_register_data (
141 ACPI_STATUS status
= AE_OK
;
142 ACPI_OPERAND_OBJECT
*obj_desc
;
146 * Validate parameters
149 if ((sleep_state
> ACPI_S_STATES_MAX
) ||
150 !slp_typ_a
|| !slp_typ_b
) {
151 return (AE_BAD_PARAMETER
);
155 * Acpi_evaluate the namespace object containing the values for this state
158 status
= acpi_ns_evaluate_by_name (sleep_state_table
[sleep_state
], NULL
, &obj_desc
);
159 if (ACPI_FAILURE (status
)) {
164 REPORT_ERROR (("Missing Sleep State object\n"));
165 return (AE_NOT_EXIST
);
169 * We got something, now ensure it is correct. The object must
170 * be a package and must have at least 2 numeric values as the
174 /* Even though Acpi_evaluate_object resolves package references,
175 * Ns_evaluate dpesn't. So, we do it here.
177 status
= acpi_cm_resolve_package_references(obj_desc
);
179 if (obj_desc
->package
.count
< 2) {
180 /* Must have at least two elements */
182 REPORT_ERROR (("Sleep State package does not have at least two elements\n"));
186 else if (((obj_desc
->package
.elements
[0])->common
.type
!=
187 ACPI_TYPE_INTEGER
) ||
188 ((obj_desc
->package
.elements
[1])->common
.type
!=
189 ACPI_TYPE_INTEGER
)) {
192 REPORT_ERROR (("Sleep State package elements are not both of type Number\n"));
198 * Valid _Sx_ package size, type, and value
200 *slp_typ_a
= (u8
) (obj_desc
->package
.elements
[0])->integer
.value
;
202 *slp_typ_b
= (u8
) (obj_desc
->package
.elements
[1])->integer
.value
;
207 acpi_cm_remove_reference (obj_desc
);
213 /*******************************************************************************
215 * FUNCTION: Acpi_hw_register_bit_access
217 * PARAMETERS: Read_write - Either ACPI_READ or ACPI_WRITE.
218 * Use_lock - Lock the hardware
219 * Register_id - index of ACPI Register to access
220 * Value - (only used on write) value to write to the
221 * Register. Shifted all the way right.
223 * RETURN: Value written to or read from specified Register. This value
224 * is shifted all the way right.
226 * DESCRIPTION: Generic ACPI Register read/write function.
228 ******************************************************************************/
231 acpi_hw_register_bit_access (
232 NATIVE_UINT read_write
,
235 ...) /* Value (only used on write) */
237 u32 register_value
= 0;
242 if (read_write
== ACPI_WRITE
) {
245 va_start (marker
, register_id
);
246 value
= va_arg (marker
, u32
);
250 if (ACPI_MTX_LOCK
== use_lock
) {
251 acpi_cm_acquire_mutex (ACPI_MTX_HARDWARE
);
255 * Decode the Register ID
256 * Register id = Register block id | bit id
258 * Check bit id to fine locate Register offset.
259 * check Mask to determine Register offset, and then read-write.
262 switch (REGISTER_BLOCK_ID(register_id
)) {
265 switch (register_id
) {
279 mask
= PWRBTN_STS_MASK
;
283 mask
= SLPBTN_STS_MASK
;
299 register_value
= acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK
, PM1_STS
);
301 if (read_write
== ACPI_WRITE
) {
303 * Status Registers are different from the rest. Clear by
304 * writing 1, writing 0 has no effect. So, the only relevent
305 * information is the single bit we're interested in, all
306 * others should be written as 0 so they will be left
310 value
<<= acpi_hw_get_bit_shift (mask
);
314 acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK
, PM1_STS
, (u16
) value
);
325 switch (register_id
) {
335 mask
= PWRBTN_EN_MASK
;
339 mask
= SLPBTN_EN_MASK
;
351 register_value
= acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK
, PM1_EN
);
353 if (read_write
== ACPI_WRITE
) {
354 register_value
&= ~mask
;
355 value
<<= acpi_hw_get_bit_shift (mask
);
357 register_value
|= value
;
359 acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK
, PM1_EN
, (u16
) register_value
);
367 switch (register_id
) {
382 mask
= SLP_TYPE_X_MASK
;
396 * Read the PM1 Control register.
397 * Note that at this level, the fact that there are actually TWO
398 * registers (A and B) and that B may not exist, are abstracted.
400 register_value
= acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK
, PM1_CONTROL
);
402 if (read_write
== ACPI_WRITE
) {
403 register_value
&= ~mask
;
404 value
<<= acpi_hw_get_bit_shift (mask
);
406 register_value
|= value
;
409 * SLP_TYPE_x Registers are written differently
410 * than any other control Registers with
411 * respect to A and B Registers. The value
412 * for A may be different than the value for B
414 * Therefore, pass the Register_id, not just generic PM1_CONTROL,
415 * because we need to do different things. Yuck.
418 acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK
,
419 register_id
, (u16
) register_value
);
426 switch (register_id
) {
436 register_value
= acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK
, PM2_CONTROL
);
438 if (read_write
== ACPI_WRITE
) {
439 register_value
&= ~mask
;
440 value
<<= acpi_hw_get_bit_shift (mask
);
442 register_value
|= value
;
444 acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK
,
445 PM2_CONTROL
, (u8
) (register_value
));
453 register_value
= acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK
,
463 /* Determine the bit to be accessed
467 * +--------+--------+--------+--------+
468 * | gpe_block_id | gpe_bit_number |
469 * +--------+--------+--------+--------+
471 * gpe_block_id is one of GPE[01]_EN_BLOCK and GPE[01]_STS_BLOCK
472 * gpe_bit_number is relative from the gpe_block (0x00~0xFF)
475 mask
= REGISTER_BIT_ID(register_id
); /* gpe_bit_number */
476 register_id
= REGISTER_BLOCK_ID(register_id
) | (mask
>> 3);
477 mask
= acpi_gbl_decode_to8bit
[mask
% 8];
480 * The base address of the GPE 0 Register Block
481 * Plus 1/2 the length of the GPE 0 Register Block
482 * The enable Register is the Register following the Status Register
483 * and each Register is defined as 1/2 of the total Register Block
487 * This sets the bit within Enable_bit that needs to be written to
488 * the Register indicated in Mask to a 1, all others are 0
491 /* Now get the current Enable Bits in the selected Reg */
493 register_value
= acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK
, register_id
);
494 if (read_write
== ACPI_WRITE
) {
495 register_value
&= ~mask
;
496 value
<<= acpi_hw_get_bit_shift (mask
);
498 register_value
|= value
;
500 /* This write will put the Action state into the General Purpose */
501 /* Enable Register indexed by the value in Mask */
503 acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK
,
504 register_id
, (u8
) register_value
);
505 register_value
= acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK
, register_id
);
511 case PROCESSOR_BLOCK
:
519 if (ACPI_MTX_LOCK
== use_lock
) {
520 acpi_cm_release_mutex (ACPI_MTX_HARDWARE
);
524 register_value
&= mask
;
525 register_value
>>= acpi_hw_get_bit_shift (mask
);
527 return (register_value
);
531 /******************************************************************************
533 * FUNCTION: Acpi_hw_register_read
535 * PARAMETERS: Use_lock - Mutex hw access.
536 * Register_id - Register_iD + Offset.
538 * RETURN: Value read or written.
540 * DESCRIPTION: Acpi register read function. Registers are read at the
543 ******************************************************************************/
546 acpi_hw_register_read (
553 if (ACPI_MTX_LOCK
== use_lock
) {
554 acpi_cm_acquire_mutex (ACPI_MTX_HARDWARE
);
558 switch (REGISTER_BLOCK_ID(register_id
)) {
559 case PM1_STS
: /* 16-bit access */
561 value
= acpi_hw_low_level_read (16, &acpi_gbl_FADT
->Xpm1a_evt_blk
, 0);
562 value
|= acpi_hw_low_level_read (16, &acpi_gbl_FADT
->Xpm1b_evt_blk
, 0);
566 case PM1_EN
: /* 16-bit access*/
568 bank_offset
= DIV_2 (acpi_gbl_FADT
->pm1_evt_len
);
569 value
= acpi_hw_low_level_read (16, &acpi_gbl_FADT
->Xpm1a_evt_blk
, bank_offset
);
570 value
|= acpi_hw_low_level_read (16, &acpi_gbl_FADT
->Xpm1b_evt_blk
, bank_offset
);
574 case PM1_CONTROL
: /* 16-bit access */
576 value
= acpi_hw_low_level_read (16, &acpi_gbl_FADT
->Xpm1a_cnt_blk
, 0);
577 value
|= acpi_hw_low_level_read (16, &acpi_gbl_FADT
->Xpm1b_cnt_blk
, 0);
581 case PM2_CONTROL
: /* 8-bit access */
583 value
= acpi_hw_low_level_read (8, &acpi_gbl_FADT
->Xpm2_cnt_blk
, 0);
587 case PM_TIMER
: /* 32-bit access */
589 value
= acpi_hw_low_level_read (32, &acpi_gbl_FADT
->Xpm_tmr_blk
, 0);
593 case GPE0_STS_BLOCK
: /* 8-bit access */
595 value
= acpi_hw_low_level_read (8, &acpi_gbl_FADT
->Xgpe0blk
, 0);
599 case GPE0_EN_BLOCK
: /* 8-bit access */
601 bank_offset
= DIV_2 (acpi_gbl_FADT
->gpe0blk_len
);
602 value
= acpi_hw_low_level_read (8, &acpi_gbl_FADT
->Xgpe0blk
, bank_offset
);
606 case GPE1_STS_BLOCK
: /* 8-bit access */
608 value
= acpi_hw_low_level_read (8, &acpi_gbl_FADT
->Xgpe1_blk
, 0);
612 case GPE1_EN_BLOCK
: /* 8-bit access */
614 bank_offset
= DIV_2 (acpi_gbl_FADT
->gpe1_blk_len
);
615 value
= acpi_hw_low_level_read (8, &acpi_gbl_FADT
->Xgpe1_blk
, bank_offset
);
619 case SMI_CMD_BLOCK
: /* 8bit */
621 value
= (u32
) acpi_os_in8 (acpi_gbl_FADT
->smi_cmd
);
631 if (ACPI_MTX_LOCK
== use_lock
) {
632 acpi_cm_release_mutex (ACPI_MTX_HARDWARE
);
639 /******************************************************************************
641 * FUNCTION: Acpi_hw_register_write
643 * PARAMETERS: Use_lock - Mutex hw access.
644 * Register_id - Register_iD + Offset.
646 * RETURN: Value read or written.
648 * DESCRIPTION: Acpi register Write function. Registers are written at the
651 ******************************************************************************/
654 acpi_hw_register_write (
662 if (ACPI_MTX_LOCK
== use_lock
) {
663 acpi_cm_acquire_mutex (ACPI_MTX_HARDWARE
);
667 switch (REGISTER_BLOCK_ID (register_id
)) {
668 case PM1_STS
: /* 16-bit access */
670 acpi_hw_low_level_write (16, value
, &acpi_gbl_FADT
->Xpm1a_evt_blk
, 0);
671 acpi_hw_low_level_write (16, value
, &acpi_gbl_FADT
->Xpm1b_evt_blk
, 0);
675 case PM1_EN
: /* 16-bit access*/
677 bank_offset
= DIV_2 (acpi_gbl_FADT
->pm1_evt_len
);
678 acpi_hw_low_level_write (16, value
, &acpi_gbl_FADT
->Xpm1a_evt_blk
, bank_offset
);
679 acpi_hw_low_level_write (16, value
, &acpi_gbl_FADT
->Xpm1b_evt_blk
, bank_offset
);
683 case PM1_CONTROL
: /* 16-bit access */
685 acpi_hw_low_level_write (16, value
, &acpi_gbl_FADT
->Xpm1a_cnt_blk
, 0);
686 acpi_hw_low_level_write (16, value
, &acpi_gbl_FADT
->Xpm1b_cnt_blk
, 0);
690 case PM1_a_CONTROL
: /* 16-bit access */
692 acpi_hw_low_level_write (16, value
, &acpi_gbl_FADT
->Xpm1a_cnt_blk
, 0);
696 case PM1_b_CONTROL
: /* 16-bit access */
698 acpi_hw_low_level_write (16, value
, &acpi_gbl_FADT
->Xpm1b_cnt_blk
, 0);
702 case PM2_CONTROL
: /* 8-bit access */
704 acpi_hw_low_level_write (8, value
, &acpi_gbl_FADT
->Xpm2_cnt_blk
, 0);
708 case PM_TIMER
: /* 32-bit access */
710 acpi_hw_low_level_write (32, value
, &acpi_gbl_FADT
->Xpm_tmr_blk
, 0);
714 case GPE0_STS_BLOCK
: /* 8-bit access */
716 acpi_hw_low_level_write (8, value
, &acpi_gbl_FADT
->Xgpe0blk
, 0);
720 case GPE0_EN_BLOCK
: /* 8-bit access */
722 bank_offset
= DIV_2 (acpi_gbl_FADT
->gpe0blk_len
);
723 acpi_hw_low_level_write (8, value
, &acpi_gbl_FADT
->Xgpe0blk
, bank_offset
);
727 case GPE1_STS_BLOCK
: /* 8-bit access */
729 acpi_hw_low_level_write (8, value
, &acpi_gbl_FADT
->Xgpe1_blk
, 0);
733 case GPE1_EN_BLOCK
: /* 8-bit access */
735 bank_offset
= DIV_2 (acpi_gbl_FADT
->gpe1_blk_len
);
736 acpi_hw_low_level_write (8, value
, &acpi_gbl_FADT
->Xgpe1_blk
, bank_offset
);
740 case SMI_CMD_BLOCK
: /* 8bit */
742 /* For 2.0, SMI_CMD is always in IO space */
743 /* TBD: what about 1.0? 0.71? */
745 acpi_os_out8 (acpi_gbl_FADT
->smi_cmd
, (u8
) value
);
755 if (ACPI_MTX_LOCK
== use_lock
) {
756 acpi_cm_release_mutex (ACPI_MTX_HARDWARE
);
763 /******************************************************************************
765 * FUNCTION: Acpi_hw_low_level_read
767 * PARAMETERS: Register - GAS register structure
768 * Offset - Offset from the base address in the GAS
769 * Width - 8, 16, or 32
773 * DESCRIPTION: Read from either memory, IO, or PCI config space.
775 ******************************************************************************/
778 acpi_hw_low_level_read (
784 ACPI_PHYSICAL_ADDRESS mem_address
;
785 ACPI_IO_ADDRESS io_address
;
791 * Must have a valid pointer to a GAS structure, and
792 * a non-zero address within
795 (!ACPI_VALID_ADDRESS (reg
->address
))) {
801 * Three address spaces supported:
802 * Memory, Io, or PCI config.
805 switch (reg
->address_space_id
) {
806 case ADDRESS_SPACE_SYSTEM_MEMORY
:
808 mem_address
= (ACPI_PHYSICAL_ADDRESS
) (ACPI_GET_ADDRESS (reg
->address
) + offset
);
812 value
= acpi_os_mem_in8 (mem_address
);
815 value
= acpi_os_mem_in16 (mem_address
);
818 value
= acpi_os_mem_in32 (mem_address
);
824 case ADDRESS_SPACE_SYSTEM_IO
:
826 io_address
= (ACPI_IO_ADDRESS
) (ACPI_GET_ADDRESS (reg
->address
) + offset
);
830 value
= acpi_os_in8 (io_address
);
833 value
= acpi_os_in16 (io_address
);
836 value
= acpi_os_in32 (io_address
);
842 case ADDRESS_SPACE_PCI_CONFIG
:
844 pci_dev_func
= ACPI_PCI_DEVFUN (ACPI_GET_ADDRESS (reg
->address
));
845 pci_register
= ACPI_PCI_REGISTER (ACPI_GET_ADDRESS (reg
->address
)) + offset
;
849 acpi_os_read_pci_cfg_byte (0, pci_dev_func
, pci_register
, (u8
*) &value
);
852 acpi_os_read_pci_cfg_word (0, pci_dev_func
, pci_register
, (u16
*) &value
);
855 acpi_os_read_pci_cfg_dword (0, pci_dev_func
, pci_register
, (u32
*) &value
);
865 /******************************************************************************
867 * FUNCTION: Acpi_hw_low_level_write
869 * PARAMETERS: Width - 8, 16, or 32
870 * Value - To be written
871 * Register - GAS register structure
872 * Offset - Offset from the base address in the GAS
877 * DESCRIPTION: Read from either memory, IO, or PCI config space.
879 ******************************************************************************/
882 acpi_hw_low_level_write (
888 ACPI_PHYSICAL_ADDRESS mem_address
;
889 ACPI_IO_ADDRESS io_address
;
895 * Must have a valid pointer to a GAS structure, and
896 * a non-zero address within
899 (!ACPI_VALID_ADDRESS (reg
->address
))) {
905 * Three address spaces supported:
906 * Memory, Io, or PCI config.
909 switch (reg
->address_space_id
) {
910 case ADDRESS_SPACE_SYSTEM_MEMORY
:
912 mem_address
= (ACPI_PHYSICAL_ADDRESS
) (ACPI_GET_ADDRESS (reg
->address
) + offset
);
916 acpi_os_mem_out8 (mem_address
, (u8
) value
);
919 acpi_os_mem_out16 (mem_address
, (u16
) value
);
922 acpi_os_mem_out32 (mem_address
, (u32
) value
);
928 case ADDRESS_SPACE_SYSTEM_IO
:
930 io_address
= (ACPI_IO_ADDRESS
) (ACPI_GET_ADDRESS (reg
->address
) + offset
);
934 acpi_os_out8 (io_address
, (u8
) value
);
937 acpi_os_out16 (io_address
, (u16
) value
);
940 acpi_os_out32 (io_address
, (u32
) value
);
946 case ADDRESS_SPACE_PCI_CONFIG
:
948 pci_dev_func
= ACPI_PCI_DEVFUN (ACPI_GET_ADDRESS (reg
->address
));
949 pci_register
= ACPI_PCI_REGISTER (ACPI_GET_ADDRESS (reg
->address
)) + offset
;
953 acpi_os_write_pci_cfg_byte (0, pci_dev_func
, pci_register
, (u8
) value
);
956 acpi_os_write_pci_cfg_word (0, pci_dev_func
, pci_register
, (u16
) value
);
959 acpi_os_write_pci_cfg_dword (0, pci_dev_func
, pci_register
, (u32
) value
);