📄 hwregs.c
字号:
*/
/*
* This sets the bit within Enable_bit that needs to be written to
* the Register indicated in Mask to a 1, all others are 0
*/
/* Now get the current Enable Bits in the selected Reg */
register_value = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, register_id);
if (read_write == ACPI_WRITE) {
register_value &= ~mask;
value <<= acpi_hw_get_bit_shift (mask);
value &= mask;
register_value |= value;
/* This write will put the Action state into the General Purpose */
/* Enable Register indexed by the value in Mask */
acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK,
register_id, (u8) register_value);
register_value = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, register_id);
}
break;
case SMI_CMD_BLOCK:
case PROCESSOR_BLOCK:
/* not used */
default:
mask = 0;
break;
}
if (ACPI_MTX_LOCK == use_lock) {
acpi_cm_release_mutex (ACPI_MTX_HARDWARE);
}
register_value &= mask;
register_value >>= acpi_hw_get_bit_shift (mask);
return (register_value);
}
/******************************************************************************
*
* FUNCTION: Acpi_hw_register_read
*
* PARAMETERS: Use_lock - Mutex hw access.
* Register_id - Register_iD + Offset.
*
* RETURN: Value read or written.
*
* DESCRIPTION: Acpi register read function. Registers are read at the
* given offset.
*
******************************************************************************/
u32
acpi_hw_register_read (
u8 use_lock,
u32 register_id)
{
u32 value = 0;
u32 bank_offset;
if (ACPI_MTX_LOCK == use_lock) {
acpi_cm_acquire_mutex (ACPI_MTX_HARDWARE);
}
switch (REGISTER_BLOCK_ID(register_id)) {
case PM1_STS: /* 16-bit access */
value = acpi_hw_low_level_read (16, &acpi_gbl_FADT->Xpm1a_evt_blk, 0);
value |= acpi_hw_low_level_read (16, &acpi_gbl_FADT->Xpm1b_evt_blk, 0);
break;
case PM1_EN: /* 16-bit access*/
bank_offset = DIV_2 (acpi_gbl_FADT->pm1_evt_len);
value = acpi_hw_low_level_read (16, &acpi_gbl_FADT->Xpm1a_evt_blk, bank_offset);
value |= acpi_hw_low_level_read (16, &acpi_gbl_FADT->Xpm1b_evt_blk, bank_offset);
break;
case PM1_CONTROL: /* 16-bit access */
value = acpi_hw_low_level_read (16, &acpi_gbl_FADT->Xpm1a_cnt_blk, 0);
value |= acpi_hw_low_level_read (16, &acpi_gbl_FADT->Xpm1b_cnt_blk, 0);
break;
case PM2_CONTROL: /* 8-bit access */
value = acpi_hw_low_level_read (8, &acpi_gbl_FADT->Xpm2_cnt_blk, 0);
break;
case PM_TIMER: /* 32-bit access */
value = acpi_hw_low_level_read (32, &acpi_gbl_FADT->Xpm_tmr_blk, 0);
break;
case GPE0_STS_BLOCK: /* 8-bit access */
value = acpi_hw_low_level_read (8, &acpi_gbl_FADT->Xgpe0blk, 0);
break;
case GPE0_EN_BLOCK: /* 8-bit access */
bank_offset = DIV_2 (acpi_gbl_FADT->gpe0blk_len);
value = acpi_hw_low_level_read (8, &acpi_gbl_FADT->Xgpe0blk, bank_offset);
break;
case GPE1_STS_BLOCK: /* 8-bit access */
value = acpi_hw_low_level_read (8, &acpi_gbl_FADT->Xgpe1_blk, 0);
break;
case GPE1_EN_BLOCK: /* 8-bit access */
bank_offset = DIV_2 (acpi_gbl_FADT->gpe1_blk_len);
value = acpi_hw_low_level_read (8, &acpi_gbl_FADT->Xgpe1_blk, bank_offset);
break;
case SMI_CMD_BLOCK: /* 8bit */
value = (u32) acpi_os_in8 (acpi_gbl_FADT->smi_cmd);
break;
default:
value = 0;
break;
}
if (ACPI_MTX_LOCK == use_lock) {
acpi_cm_release_mutex (ACPI_MTX_HARDWARE);
}
return (value);
}
/******************************************************************************
*
* FUNCTION: Acpi_hw_register_write
*
* PARAMETERS: Use_lock - Mutex hw access.
* Register_id - Register_iD + Offset.
*
* RETURN: Value read or written.
*
* DESCRIPTION: Acpi register Write function. Registers are written at the
* given offset.
*
******************************************************************************/
void
acpi_hw_register_write (
u8 use_lock,
u32 register_id,
u32 value)
{
u32 bank_offset;
if (ACPI_MTX_LOCK == use_lock) {
acpi_cm_acquire_mutex (ACPI_MTX_HARDWARE);
}
switch (REGISTER_BLOCK_ID (register_id)) {
case PM1_STS: /* 16-bit access */
acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1a_evt_blk, 0);
acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1b_evt_blk, 0);
break;
case PM1_EN: /* 16-bit access*/
bank_offset = DIV_2 (acpi_gbl_FADT->pm1_evt_len);
acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1a_evt_blk, bank_offset);
acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1b_evt_blk, bank_offset);
break;
case PM1_CONTROL: /* 16-bit access */
acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1a_cnt_blk, 0);
acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1b_cnt_blk, 0);
break;
case PM1_a_CONTROL: /* 16-bit access */
acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1a_cnt_blk, 0);
break;
case PM1_b_CONTROL: /* 16-bit access */
acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1b_cnt_blk, 0);
break;
case PM2_CONTROL: /* 8-bit access */
acpi_hw_low_level_write (8, value, &acpi_gbl_FADT->Xpm2_cnt_blk, 0);
break;
case PM_TIMER: /* 32-bit access */
acpi_hw_low_level_write (32, value, &acpi_gbl_FADT->Xpm_tmr_blk, 0);
break;
case GPE0_STS_BLOCK: /* 8-bit access */
acpi_hw_low_level_write (8, value, &acpi_gbl_FADT->Xgpe0blk, 0);
break;
case GPE0_EN_BLOCK: /* 8-bit access */
bank_offset = DIV_2 (acpi_gbl_FADT->gpe0blk_len);
acpi_hw_low_level_write (8, value, &acpi_gbl_FADT->Xgpe0blk, bank_offset);
break;
case GPE1_STS_BLOCK: /* 8-bit access */
acpi_hw_low_level_write (8, value, &acpi_gbl_FADT->Xgpe1_blk, 0);
break;
case GPE1_EN_BLOCK: /* 8-bit access */
bank_offset = DIV_2 (acpi_gbl_FADT->gpe1_blk_len);
acpi_hw_low_level_write (8, value, &acpi_gbl_FADT->Xgpe1_blk, bank_offset);
break;
case SMI_CMD_BLOCK: /* 8bit */
/* For 2.0, SMI_CMD is always in IO space */
/* TBD: what about 1.0? 0.71? */
acpi_os_out8 (acpi_gbl_FADT->smi_cmd, (u8) value);
break;
default:
value = 0;
break;
}
if (ACPI_MTX_LOCK == use_lock) {
acpi_cm_release_mutex (ACPI_MTX_HARDWARE);
}
return;
}
/******************************************************************************
*
* FUNCTION: Acpi_hw_low_level_read
*
* PARAMETERS: Register - GAS register structure
* Offset - Offset from the base address in the GAS
* Width - 8, 16, or 32
*
* RETURN: Value read
*
* DESCRIPTION: Read from either memory, IO, or PCI config space.
*
******************************************************************************/
u32
acpi_hw_low_level_read (
u32 width,
ACPI_GAS *reg,
u32 offset)
{
u32 value = 0;
ACPI_PHYSICAL_ADDRESS mem_address;
ACPI_IO_ADDRESS io_address;
u32 pci_register;
u32 pci_dev_func;
/*
* Must have a valid pointer to a GAS structure, and
* a non-zero address within
*/
if ((!reg) ||
(!ACPI_VALID_ADDRESS (reg->address))) {
return 0;
}
/*
* Three address spaces supported:
* Memory, Io, or PCI config.
*/
switch (reg->address_space_id) {
case ADDRESS_SPACE_SYSTEM_MEMORY:
mem_address = (ACPI_PHYSICAL_ADDRESS) (ACPI_GET_ADDRESS (reg->address) + offset);
switch (width) {
case 8:
value = acpi_os_mem_in8 (mem_address);
break;
case 16:
value = acpi_os_mem_in16 (mem_address);
break;
case 32:
value = acpi_os_mem_in32 (mem_address);
break;
}
break;
case ADDRESS_SPACE_SYSTEM_IO:
io_address = (ACPI_IO_ADDRESS) (ACPI_GET_ADDRESS (reg->address) + offset);
switch (width) {
case 8:
value = acpi_os_in8 (io_address);
break;
case 16:
value = acpi_os_in16 (io_address);
break;
case 32:
value = acpi_os_in32 (io_address);
break;
}
break;
case ADDRESS_SPACE_PCI_CONFIG:
pci_dev_func = ACPI_PCI_DEVFUN (ACPI_GET_ADDRESS (reg->address));
pci_register = ACPI_PCI_REGISTER (ACPI_GET_ADDRESS (reg->address)) + offset;
switch (width) {
case 8:
acpi_os_read_pci_cfg_byte (0, pci_dev_func, pci_register, (u8 *) &value);
break;
case 16:
acpi_os_read_pci_cfg_word (0, pci_dev_func, pci_register, (u16 *) &value);
break;
case 32:
acpi_os_read_pci_cfg_dword (0, pci_dev_func, pci_register, (u32 *) &value);
break;
}
break;
}
return value;
}
/******************************************************************************
*
* FUNCTION: Acpi_hw_low_level_write
*
* PARAMETERS: Width - 8, 16, or 32
* Value - To be written
* Register - GAS register structure
* Offset - Offset from the base address in the GAS
*
*
* RETURN: Value read
*
* DESCRIPTION: Read from either memory, IO, or PCI config space.
*
******************************************************************************/
void
acpi_hw_low_level_write (
u32 width,
u32 value,
ACPI_GAS *reg,
u32 offset)
{
ACPI_PHYSICAL_ADDRESS mem_address;
ACPI_IO_ADDRESS io_address;
u32 pci_register;
u32 pci_dev_func;
/*
* Must have a valid pointer to a GAS structure, and
* a non-zero address within
*/
if ((!reg) ||
(!ACPI_VALID_ADDRESS (reg->address))) {
return;
}
/*
* Three address spaces supported:
* Memory, Io, or PCI config.
*/
switch (reg->address_space_id) {
case ADDRESS_SPACE_SYSTEM_MEMORY:
mem_address = (ACPI_PHYSICAL_ADDRESS) (ACPI_GET_ADDRESS (reg->address) + offset);
switch (width) {
case 8:
acpi_os_mem_out8 (mem_address, (u8) value);
break;
case 16:
acpi_os_mem_out16 (mem_address, (u16) value);
break;
case 32:
acpi_os_mem_out32 (mem_address, (u32) value);
break;
}
break;
case ADDRESS_SPACE_SYSTEM_IO:
io_address = (ACPI_IO_ADDRESS) (ACPI_GET_ADDRESS (reg->address) + offset);
switch (width) {
case 8:
acpi_os_out8 (io_address, (u8) value);
break;
case 16:
acpi_os_out16 (io_address, (u16) value);
break;
case 32:
acpi_os_out32 (io_address, (u32) value);
break;
}
break;
case ADDRESS_SPACE_PCI_CONFIG:
pci_dev_func = ACPI_PCI_DEVFUN (ACPI_GET_ADDRESS (reg->address));
pci_register = ACPI_PCI_REGISTER (ACPI_GET_ADDRESS (reg->address)) + offset;
switch (width) {
case 8:
acpi_os_write_pci_cfg_byte (0, pci_dev_func, pci_register, (u8) value);
break;
case 16:
acpi_os_write_pci_cfg_word (0, pci_dev_func, pci_register, (u16) value);
break;
case 32:
acpi_os_write_pci_cfg_dword (0, pci_dev_func, pci_register, (u32) value);
break;
}
break;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -