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
33 #define _COMPONENT ACPI_HARDWARE
34 MODULE_NAME ("hwregs")
37 /* This matches the #defines in actypes.h. */
39 NATIVE_CHAR
*sleep_state_table
[] = {"\\_S0_","\\_S1_","\\_S2_","\\_S3_",
40 "\\_S4_","\\_S5_","\\_S4_b"};
43 /*******************************************************************************
45 * FUNCTION: Acpi_hw_get_bit_shift
47 * PARAMETERS: Mask - Input mask to determine bit shift from.
48 * Must have at least 1 bit set.
50 * RETURN: Bit location of the lsb of the mask
52 * DESCRIPTION: Returns the bit number for the low order bit that's set.
54 ******************************************************************************/
57 acpi_hw_get_bit_shift (
62 for (shift
= 0; ((mask
>> shift
) & 1) == 0; shift
++) { ; }
68 /*******************************************************************************
70 * FUNCTION: Acpi_hw_clear_acpi_status
76 * DESCRIPTION: Clears all fixed and general purpose status bits
78 ******************************************************************************/
81 acpi_hw_clear_acpi_status (void)
87 acpi_cm_acquire_mutex (ACPI_MTX_HARDWARE
);
89 acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK
, PM1_STS
, ALL_FIXED_STS_BITS
);
92 if (ACPI_VALID_ADDRESS (acpi_gbl_FADT
->Xpm1b_evt_blk
.address
)) {
93 acpi_os_out16 ((ACPI_IO_ADDRESS
) ACPI_GET_ADDRESS (acpi_gbl_FADT
->Xpm1b_evt_blk
.address
),
94 (u16
) ALL_FIXED_STS_BITS
);
97 /* now clear the GPE Bits */
99 if (acpi_gbl_FADT
->gpe0blk_len
) {
100 gpe_length
= (u16
) DIV_2 (acpi_gbl_FADT
->gpe0blk_len
);
102 for (index
= 0; index
< gpe_length
; index
++) {
103 acpi_os_out8 ((ACPI_IO_ADDRESS
) (ACPI_GET_ADDRESS (acpi_gbl_FADT
->Xgpe0blk
.address
) + index
),
108 if (acpi_gbl_FADT
->gpe1_blk_len
) {
109 gpe_length
= (u16
) DIV_2 (acpi_gbl_FADT
->gpe1_blk_len
);
111 for (index
= 0; index
< gpe_length
; index
++) {
112 acpi_os_out8 ((ACPI_IO_ADDRESS
) (ACPI_GET_ADDRESS (acpi_gbl_FADT
->Xgpe1_blk
.address
) + index
),
117 acpi_cm_release_mutex (ACPI_MTX_HARDWARE
);
122 /*******************************************************************************
124 * FUNCTION: Acpi_hw_obtain_sleep_type_register_data
126 * PARAMETERS: Sleep_state - Numeric state requested
127 * *Slp_Typ_a - Pointer to byte to receive SLP_TYPa value
128 * *Slp_Typ_b - Pointer to byte to receive SLP_TYPb value
130 * RETURN: Status - ACPI status
132 * DESCRIPTION: Acpi_hw_obtain_sleep_type_register_data() obtains the SLP_TYP and
133 * SLP_TYPb values for the sleep state requested.
135 ******************************************************************************/
138 acpi_hw_obtain_sleep_type_register_data (
143 ACPI_STATUS status
= AE_OK
;
144 ACPI_OPERAND_OBJECT
*obj_desc
;
148 * Validate parameters
151 if ((sleep_state
> ACPI_S_STATES_MAX
) ||
152 !slp_typ_a
|| !slp_typ_b
) {
153 return (AE_BAD_PARAMETER
);
157 * Acpi_evaluate the namespace object containing the values for this state
160 status
= acpi_ns_evaluate_by_name (sleep_state_table
[sleep_state
], NULL
, &obj_desc
);
161 if (ACPI_FAILURE (status
)) {
166 REPORT_ERROR (("Missing Sleep State object\n"));
167 return (AE_NOT_EXIST
);
171 * We got something, now ensure it is correct. The object must
172 * be a package and must have at least 2 numeric values as the
176 /* Even though Acpi_evaluate_object resolves package references,
177 * Ns_evaluate dpesn't. So, we do it here.
179 status
= acpi_cm_resolve_package_references(obj_desc
);
181 if (obj_desc
->package
.count
< 2) {
182 /* Must have at least two elements */
184 REPORT_ERROR (("Sleep State package does not have at least two elements\n"));
188 else if (((obj_desc
->package
.elements
[0])->common
.type
!=
189 ACPI_TYPE_INTEGER
) ||
190 ((obj_desc
->package
.elements
[1])->common
.type
!=
191 ACPI_TYPE_INTEGER
)) {
194 REPORT_ERROR (("Sleep State package elements are not both of type Number\n"));
200 * Valid _Sx_ package size, type, and value
202 *slp_typ_a
= (u8
) (obj_desc
->package
.elements
[0])->integer
.value
;
204 *slp_typ_b
= (u8
) (obj_desc
->package
.elements
[1])->integer
.value
;
209 acpi_cm_remove_reference (obj_desc
);
215 /*******************************************************************************
217 * FUNCTION: Acpi_hw_register_bit_access
219 * PARAMETERS: Read_write - Either ACPI_READ or ACPI_WRITE.
220 * Use_lock - Lock the hardware
221 * Register_id - index of ACPI Register to access
222 * Value - (only used on write) value to write to the
223 * Register. Shifted all the way right.
225 * RETURN: Value written to or read from specified Register. This value
226 * is shifted all the way right.
228 * DESCRIPTION: Generic ACPI Register read/write function.
230 ******************************************************************************/
233 acpi_hw_register_bit_access (
234 NATIVE_UINT read_write
,
237 ...) /* Value (only used on write) */
239 u32 register_value
= 0;
244 if (read_write
== ACPI_WRITE
) {
247 va_start (marker
, register_id
);
248 value
= va_arg (marker
, u32
);
252 if (ACPI_MTX_LOCK
== use_lock
) {
253 acpi_cm_acquire_mutex (ACPI_MTX_HARDWARE
);
257 * Decode the Register ID
258 * Register id = Register block id | bit id
260 * Check bit id to fine locate Register offset.
261 * check Mask to determine Register offset, and then read-write.
264 switch (REGISTER_BLOCK_ID(register_id
)) {
267 switch (register_id
) {
281 mask
= PWRBTN_STS_MASK
;
285 mask
= SLPBTN_STS_MASK
;
301 register_value
= acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK
, PM1_STS
);
303 if (read_write
== ACPI_WRITE
) {
305 * Status Registers are different from the rest. Clear by
306 * writing 1, writing 0 has no effect. So, the only relevent
307 * information is the single bit we're interested in, all
308 * others should be written as 0 so they will be left
312 value
<<= acpi_hw_get_bit_shift (mask
);
316 acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK
, PM1_STS
, (u16
) value
);
327 switch (register_id
) {
337 mask
= PWRBTN_EN_MASK
;
341 mask
= SLPBTN_EN_MASK
;
353 register_value
= acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK
, PM1_EN
);
355 if (read_write
== ACPI_WRITE
) {
356 register_value
&= ~mask
;
357 value
<<= acpi_hw_get_bit_shift (mask
);
359 register_value
|= value
;
361 acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK
, PM1_EN
, (u16
) register_value
);
369 switch (register_id
) {
384 mask
= SLP_TYPE_X_MASK
;
398 * Read the PM1 Control register.
399 * Note that at this level, the fact that there are actually TWO
400 * registers (A and B) and that B may not exist, are abstracted.
402 register_value
= acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK
, PM1_CONTROL
);
404 if (read_write
== ACPI_WRITE
) {
405 register_value
&= ~mask
;
406 value
<<= acpi_hw_get_bit_shift (mask
);
408 register_value
|= value
;
411 * SLP_TYPE_x Registers are written differently
412 * than any other control Registers with
413 * respect to A and B Registers. The value
414 * for A may be different than the value for B
416 * Therefore, pass the Register_id, not just generic PM1_CONTROL,
417 * because we need to do different things. Yuck.
420 acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK
,
421 register_id
, (u16
) register_value
);
428 switch (register_id
) {
438 register_value
= acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK
, PM2_CONTROL
);
440 if (read_write
== ACPI_WRITE
) {
441 register_value
&= ~mask
;
442 value
<<= acpi_hw_get_bit_shift (mask
);
444 register_value
|= value
;
446 acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK
,
447 PM2_CONTROL
, (u8
) (register_value
));
455 register_value
= acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK
,
465 /* Determine the bit to be accessed
469 * +--------+--------+--------+--------+
470 * | gpe_block_id | gpe_bit_number |
471 * +--------+--------+--------+--------+
473 * gpe_block_id is one of GPE[01]_EN_BLOCK and GPE[01]_STS_BLOCK
474 * gpe_bit_number is relative from the gpe_block (0x00~0xFF)
477 mask
= REGISTER_BIT_ID(register_id
); /* gpe_bit_number */
478 register_id
= REGISTER_BLOCK_ID(register_id
) | (mask
>> 3);
479 mask
= acpi_gbl_decode_to8bit
[mask
% 8];
482 * The base address of the GPE 0 Register Block
483 * Plus 1/2 the length of the GPE 0 Register Block
484 * The enable Register is the Register following the Status Register
485 * and each Register is defined as 1/2 of the total Register Block
489 * This sets the bit within Enable_bit that needs to be written to
490 * the Register indicated in Mask to a 1, all others are 0
493 /* Now get the current Enable Bits in the selected Reg */
495 register_value
= acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK
, register_id
);
496 if (read_write
== ACPI_WRITE
) {
497 register_value
&= ~mask
;
498 value
<<= acpi_hw_get_bit_shift (mask
);
500 register_value
|= value
;
502 /* This write will put the Action state into the General Purpose */
503 /* Enable Register indexed by the value in Mask */
505 acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK
,
506 register_id
, (u8
) register_value
);
507 register_value
= acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK
, register_id
);
513 case PROCESSOR_BLOCK
:
521 if (ACPI_MTX_LOCK
== use_lock
) {
522 acpi_cm_release_mutex (ACPI_MTX_HARDWARE
);
526 register_value
&= mask
;
527 register_value
>>= acpi_hw_get_bit_shift (mask
);
529 return (register_value
);
533 /******************************************************************************
535 * FUNCTION: Acpi_hw_register_read
537 * PARAMETERS: Use_lock - Mutex hw access.
538 * Register_id - Register_iD + Offset.
540 * RETURN: Value read or written.
542 * DESCRIPTION: Acpi register read function. Registers are read at the
545 ******************************************************************************/
548 acpi_hw_register_read (
555 if (ACPI_MTX_LOCK
== use_lock
) {
556 acpi_cm_acquire_mutex (ACPI_MTX_HARDWARE
);
560 switch (REGISTER_BLOCK_ID(register_id
)) {
561 case PM1_STS
: /* 16-bit access */
563 value
= acpi_hw_low_level_read (16, &acpi_gbl_FADT
->Xpm1a_evt_blk
, 0);
564 value
|= acpi_hw_low_level_read (16, &acpi_gbl_FADT
->Xpm1b_evt_blk
, 0);
568 case PM1_EN
: /* 16-bit access*/
570 bank_offset
= DIV_2 (acpi_gbl_FADT
->pm1_evt_len
);
571 value
= acpi_hw_low_level_read (16, &acpi_gbl_FADT
->Xpm1a_evt_blk
, bank_offset
);
572 value
|= acpi_hw_low_level_read (16, &acpi_gbl_FADT
->Xpm1b_evt_blk
, bank_offset
);
576 case PM1_CONTROL
: /* 16-bit access */
578 value
= acpi_hw_low_level_read (16, &acpi_gbl_FADT
->Xpm1a_cnt_blk
, 0);
579 value
|= acpi_hw_low_level_read (16, &acpi_gbl_FADT
->Xpm1b_cnt_blk
, 0);
583 case PM2_CONTROL
: /* 8-bit access */
585 value
= acpi_hw_low_level_read (8, &acpi_gbl_FADT
->Xpm2_cnt_blk
, 0);
589 case PM_TIMER
: /* 32-bit access */
591 value
= acpi_hw_low_level_read (32, &acpi_gbl_FADT
->Xpm_tmr_blk
, 0);
595 case GPE0_STS_BLOCK
: /* 8-bit access */
597 value
= acpi_hw_low_level_read (8, &acpi_gbl_FADT
->Xgpe0blk
, 0);
601 case GPE0_EN_BLOCK
: /* 8-bit access */
603 bank_offset
= DIV_2 (acpi_gbl_FADT
->gpe0blk_len
);
604 value
= acpi_hw_low_level_read (8, &acpi_gbl_FADT
->Xgpe0blk
, bank_offset
);
608 case GPE1_STS_BLOCK
: /* 8-bit access */
610 value
= acpi_hw_low_level_read (8, &acpi_gbl_FADT
->Xgpe1_blk
, 0);
614 case GPE1_EN_BLOCK
: /* 8-bit access */
616 bank_offset
= DIV_2 (acpi_gbl_FADT
->gpe1_blk_len
);
617 value
= acpi_hw_low_level_read (8, &acpi_gbl_FADT
->Xgpe1_blk
, bank_offset
);
621 case SMI_CMD_BLOCK
: /* 8bit */
623 value
= (u32
) acpi_os_in8 (acpi_gbl_FADT
->smi_cmd
);
633 if (ACPI_MTX_LOCK
== use_lock
) {
634 acpi_cm_release_mutex (ACPI_MTX_HARDWARE
);
641 /******************************************************************************
643 * FUNCTION: Acpi_hw_register_write
645 * PARAMETERS: Use_lock - Mutex hw access.
646 * Register_id - Register_iD + Offset.
648 * RETURN: Value read or written.
650 * DESCRIPTION: Acpi register Write function. Registers are written at the
653 ******************************************************************************/
656 acpi_hw_register_write (
664 if (ACPI_MTX_LOCK
== use_lock
) {
665 acpi_cm_acquire_mutex (ACPI_MTX_HARDWARE
);
669 switch (REGISTER_BLOCK_ID (register_id
)) {
670 case PM1_STS
: /* 16-bit access */
672 acpi_hw_low_level_write (16, value
, &acpi_gbl_FADT
->Xpm1a_evt_blk
, 0);
673 acpi_hw_low_level_write (16, value
, &acpi_gbl_FADT
->Xpm1b_evt_blk
, 0);
677 case PM1_EN
: /* 16-bit access*/
679 bank_offset
= DIV_2 (acpi_gbl_FADT
->pm1_evt_len
);
680 acpi_hw_low_level_write (16, value
, &acpi_gbl_FADT
->Xpm1a_evt_blk
, bank_offset
);
681 acpi_hw_low_level_write (16, value
, &acpi_gbl_FADT
->Xpm1b_evt_blk
, bank_offset
);
685 case PM1_CONTROL
: /* 16-bit access */
687 acpi_hw_low_level_write (16, value
, &acpi_gbl_FADT
->Xpm1a_cnt_blk
, 0);
688 acpi_hw_low_level_write (16, value
, &acpi_gbl_FADT
->Xpm1b_cnt_blk
, 0);
692 case PM1_a_CONTROL
: /* 16-bit access */
694 acpi_hw_low_level_write (16, value
, &acpi_gbl_FADT
->Xpm1a_cnt_blk
, 0);
698 case PM1_b_CONTROL
: /* 16-bit access */
700 acpi_hw_low_level_write (16, value
, &acpi_gbl_FADT
->Xpm1b_cnt_blk
, 0);
704 case PM2_CONTROL
: /* 8-bit access */
706 acpi_hw_low_level_write (8, value
, &acpi_gbl_FADT
->Xpm2_cnt_blk
, 0);
710 case PM_TIMER
: /* 32-bit access */
712 acpi_hw_low_level_write (32, value
, &acpi_gbl_FADT
->Xpm_tmr_blk
, 0);
716 case GPE0_STS_BLOCK
: /* 8-bit access */
718 acpi_hw_low_level_write (8, value
, &acpi_gbl_FADT
->Xgpe0blk
, 0);
722 case GPE0_EN_BLOCK
: /* 8-bit access */
724 bank_offset
= DIV_2 (acpi_gbl_FADT
->gpe0blk_len
);
725 acpi_hw_low_level_write (8, value
, &acpi_gbl_FADT
->Xgpe0blk
, bank_offset
);
729 case GPE1_STS_BLOCK
: /* 8-bit access */
731 acpi_hw_low_level_write (8, value
, &acpi_gbl_FADT
->Xgpe1_blk
, 0);
735 case GPE1_EN_BLOCK
: /* 8-bit access */
737 bank_offset
= DIV_2 (acpi_gbl_FADT
->gpe1_blk_len
);
738 acpi_hw_low_level_write (8, value
, &acpi_gbl_FADT
->Xgpe1_blk
, bank_offset
);
742 case SMI_CMD_BLOCK
: /* 8bit */
744 /* For 2.0, SMI_CMD is always in IO space */
745 /* TBD: what about 1.0? 0.71? */
747 acpi_os_out8 (acpi_gbl_FADT
->smi_cmd
, (u8
) value
);
757 if (ACPI_MTX_LOCK
== use_lock
) {
758 acpi_cm_release_mutex (ACPI_MTX_HARDWARE
);
765 /******************************************************************************
767 * FUNCTION: Acpi_hw_low_level_read
769 * PARAMETERS: Register - GAS register structure
770 * Offset - Offset from the base address in the GAS
771 * Width - 8, 16, or 32
775 * DESCRIPTION: Read from either memory, IO, or PCI config space.
777 ******************************************************************************/
780 acpi_hw_low_level_read (
786 ACPI_PHYSICAL_ADDRESS mem_address
;
787 ACPI_IO_ADDRESS io_address
;
793 * Must have a valid pointer to a GAS structure, and
794 * a non-zero address within
797 (!ACPI_VALID_ADDRESS (reg
->address
))) {
803 * Three address spaces supported:
804 * Memory, Io, or PCI config.
807 switch (reg
->address_space_id
) {
808 case ADDRESS_SPACE_SYSTEM_MEMORY
:
810 mem_address
= (ACPI_PHYSICAL_ADDRESS
) (ACPI_GET_ADDRESS (reg
->address
) + offset
);
814 value
= acpi_os_mem_in8 (mem_address
);
817 value
= acpi_os_mem_in16 (mem_address
);
820 value
= acpi_os_mem_in32 (mem_address
);
826 case ADDRESS_SPACE_SYSTEM_IO
:
828 io_address
= (ACPI_IO_ADDRESS
) (ACPI_GET_ADDRESS (reg
->address
) + offset
);
832 value
= acpi_os_in8 (io_address
);
835 value
= acpi_os_in16 (io_address
);
838 value
= acpi_os_in32 (io_address
);
844 case ADDRESS_SPACE_PCI_CONFIG
:
846 pci_dev_func
= ACPI_PCI_DEVFUN (ACPI_GET_ADDRESS (reg
->address
));
847 pci_register
= ACPI_PCI_REGISTER (ACPI_GET_ADDRESS (reg
->address
)) + offset
;
851 acpi_os_read_pci_cfg_byte (0, pci_dev_func
, pci_register
, (u8
*) &value
);
854 acpi_os_read_pci_cfg_word (0, pci_dev_func
, pci_register
, (u16
*) &value
);
857 acpi_os_read_pci_cfg_dword (0, pci_dev_func
, pci_register
, (u32
*) &value
);
867 /******************************************************************************
869 * FUNCTION: Acpi_hw_low_level_write
871 * PARAMETERS: Width - 8, 16, or 32
872 * Value - To be written
873 * Register - GAS register structure
874 * Offset - Offset from the base address in the GAS
879 * DESCRIPTION: Read from either memory, IO, or PCI config space.
881 ******************************************************************************/
884 acpi_hw_low_level_write (
890 ACPI_PHYSICAL_ADDRESS mem_address
;
891 ACPI_IO_ADDRESS io_address
;
897 * Must have a valid pointer to a GAS structure, and
898 * a non-zero address within
901 (!ACPI_VALID_ADDRESS (reg
->address
))) {
907 * Three address spaces supported:
908 * Memory, Io, or PCI config.
911 switch (reg
->address_space_id
) {
912 case ADDRESS_SPACE_SYSTEM_MEMORY
:
914 mem_address
= (ACPI_PHYSICAL_ADDRESS
) (ACPI_GET_ADDRESS (reg
->address
) + offset
);
918 acpi_os_mem_out8 (mem_address
, (u8
) value
);
921 acpi_os_mem_out16 (mem_address
, (u16
) value
);
924 acpi_os_mem_out32 (mem_address
, (u32
) value
);
930 case ADDRESS_SPACE_SYSTEM_IO
:
932 io_address
= (ACPI_IO_ADDRESS
) (ACPI_GET_ADDRESS (reg
->address
) + offset
);
936 acpi_os_out8 (io_address
, (u8
) value
);
939 acpi_os_out16 (io_address
, (u16
) value
);
942 acpi_os_out32 (io_address
, (u32
) value
);
948 case ADDRESS_SPACE_PCI_CONFIG
:
950 pci_dev_func
= ACPI_PCI_DEVFUN (ACPI_GET_ADDRESS (reg
->address
));
951 pci_register
= ACPI_PCI_REGISTER (ACPI_GET_ADDRESS (reg
->address
)) + offset
;
955 acpi_os_write_pci_cfg_byte (0, pci_dev_func
, pci_register
, (u8
) value
);
958 acpi_os_write_pci_cfg_word (0, pci_dev_func
, pci_register
, (u16
) value
);
961 acpi_os_write_pci_cfg_dword (0, pci_dev_func
, pci_register
, (u32
) value
);