📄 hwcpu32.c
字号:
/**************************************************************************** * * FUNCTION: Acpi_hw_get_cx_info * * PARAMETERS: Cx_states - Information (latencies) on all Cx states * * RETURN: Status of function * * DESCRIPTION: This function is called both to initialize Cx handling * and retrieve the current Cx information (latency values). * ****************************************************************************/ACPI_STATUSacpi_hw_get_cx_info ( u32 cx_states[]){ u8 SMP_system = FALSE; if (!cx_states) { return(AE_BAD_PARAMETER); } /* * TBD: [Unhandled] need to init SMP_system using info from the MAPIC * table. */ /* * Set Defaults: * ------------- * C0 and C1 support is implied (but what about that PROC_C1 register * in the FADT?!?!). Set C2/C3 to max. latency (not supported until * proven otherwise). */ cx_states[0] = 0; cx_states[1] = 0; cx_states[2] = MAX_CX_STATE_LATENCY; cx_states[3] = MAX_CX_STATE_LATENCY; /* * C2 Supported? * ------------- * We're only supporting C2 when the latency is <= 100 microseconds, * and on SMP systems when P_LVL2_UP (which indicates C2 only on UP) * is not set. */ if (acpi_gbl_FADT->plvl2_lat <= 100) { if (!SMP_system) { acpi_hw_cx_handlers[2] = acpi_hw_enter_c2; cx_states[2] = acpi_gbl_FADT->plvl2_lat; } else if (!acpi_gbl_FADT->plvl2_up) { acpi_hw_cx_handlers[2] = acpi_hw_enter_c2; cx_states[2] = acpi_gbl_FADT->plvl2_lat; } } /* * C3 Supported? * ------------- * We're only supporting C3 on UP systems when the latency is * <= 1000 microseconds and that include the ability to disable * Bus Mastering while in C3 (ARB_DIS) but allows Bus Mastering * requests to wake the system from C3 (BM_RLD). Note his method * of maintaining cache coherency (disabling of bus mastering) * cannot be used on SMP systems, and flushing caches (e.g. WBINVD) * is simply too costly (at this time). */ if (acpi_gbl_FADT->plvl3_lat <= 1000) { if (!SMP_system && (acpi_gbl_FADT->Xpm2_cnt_blk.address && acpi_gbl_FADT->pm2_cnt_len)) { acpi_hw_cx_handlers[3] = acpi_hw_enter_c3; cx_states[3] = acpi_gbl_FADT->plvl3_lat; } } return(AE_OK);}/**************************************************************************** * * FUNCTION: Acpi_hw_get_cx_handler * * PARAMETERS: State - the Cx state * Handler - pointer to location for the returned handler * * RETURN: Status of function * * DESCRIPTION: This function is called to get an installed Cx state handler. * ****************************************************************************/ACPI_STATUSacpi_hw_get_cx_handler ( u32 cx_state, ACPI_C_STATE_HANDLER *handler){ if ((cx_state == 0) || (cx_state >= MAX_CX_STATES) || !handler) { return(AE_BAD_PARAMETER); } *handler = acpi_hw_cx_handlers[cx_state]; return(AE_OK);}/**************************************************************************** * * FUNCTION: Acpi_hw_set_cx_handler * * PARAMETERS: Cx_state - the Cx state * Handler - new Cx state handler * * RETURN: Status of function * * DESCRIPTION: This function is called to install a new Cx state handler. * ****************************************************************************/ACPI_STATUSacpi_hw_set_cx_handler ( u32 cx_state, ACPI_C_STATE_HANDLER handler){ if ((cx_state == 0) || (cx_state >= MAX_CX_STATES) || !handler) { return(AE_BAD_PARAMETER); } acpi_hw_cx_handlers[cx_state] = handler; return(AE_OK);}/************************************************************************** * * FUNCTION: Acpi_hw_local_pow * * PARAMETERS: x,y operands * * RETURN: result * * DESCRIPTION: Compute x ^ y * *************************************************************************/NATIVE_UINTacpi_hw_local_pow ( NATIVE_UINT x, NATIVE_UINT y){ NATIVE_UINT i; NATIVE_UINT result = 1; for (i = 0; i < y; i++) { result = result * x; } return (result);}/************************************************************************** * * FUNCTION: Acpi_hw_enable_throttling * * PARAMETERS: Pblk_address - Address of Pcnt (Processor Control) * register * * RETURN: none * * DESCRIPTION: Enable throttling by setting the THT_EN bit. * *************************************************************************/voidacpi_hw_enable_throttling ( ACPI_IO_ADDRESS pblk_address){ u32 pblk_value; pblk_value = acpi_os_in32 (pblk_address); pblk_value = pblk_value | BIT_4; acpi_os_out32 (pblk_address, pblk_value); return;}/************************************************************************** * * FUNCTION: Acpi_hw_disable_throttling * * PARAMETERS: Pblk_address - Address of Pcnt (Processor Control) * register * * RETURN: none * * DESCRIPTION:Disable throttling by clearing the THT_EN bit * *************************************************************************/voidacpi_hw_disable_throttling ( ACPI_IO_ADDRESS pblk_address){ u32 pblk_value; pblk_value = acpi_os_in32 (pblk_address); pblk_value = pblk_value & (~(u32)BIT_4); acpi_os_out32 (pblk_address, pblk_value); return;}/************************************************************************** * * FUNCTION: Acpi_hw_get_duty_cycle * * PARAMETERS: Duty_offset Pcnt register duty cycle field offset * Pblk_address Pcnt register address in chipset * Num_throttle_states # of CPU throttle states this system * supports * * RETURN: none * * DESCRIPTION: Get the duty cycle from the chipset * *************************************************************************/u32acpi_hw_get_duty_cycle ( u8 duty_offset, ACPI_IO_ADDRESS pblk_address, u32 num_throttle_states){ NATIVE_UINT index; u32 duty32_value; u32 pcnt_mask_off_duty_field; /* * Use Num_throttle_states - 1 as mask [ex. 8 - 1 = 7 (Fh)] * and then shift it into the right position */ pcnt_mask_off_duty_field = num_throttle_states - 1; /* * Read in the current value from the port */ duty32_value = acpi_os_in32 ((ACPI_IO_ADDRESS) pblk_address); /* * Shift the the value to LSB */ for (index = 0; index < (NATIVE_UINT) duty_offset; index++) { duty32_value = duty32_value >> 1; } /* * Get the duty field only */ duty32_value = duty32_value & pcnt_mask_off_duty_field; return ((u32) duty32_value);}/************************************************************************** * * FUNCTION: Acpi_hw_program_duty_cycle * * PARAMETERS: Duty_offset Pcnt register duty cycle field offset * Duty_cycle duty cycle to program into chipset * Pblk_address Pcnt register address in chipset * Num_throttle_states # of CPU throttle states this system * supports * * RETURN: none * * DESCRIPTION: Program chipset with specified duty cycle by bit-shifting the * duty cycle bits to the appropriate offset, reading the duty * cycle register, OR-ing in the duty cycle, and writing it to * the Pcnt register. * *************************************************************************/voidacpi_hw_program_duty_cycle ( u8 duty_offset, u32 duty_cycle, ACPI_IO_ADDRESS pblk_address, u32 num_throttle_states){ NATIVE_UINT index; u32 duty32_value; u32 pcnt_mask_off_duty_field; u32 port_value; /* * valid Duty_cycle passed */ duty32_value = duty_cycle; /* * use Num_throttle_states - 1 as mask [ex. 8 - 1 = 7 (Fh)] * and then shift it into the right position */ pcnt_mask_off_duty_field = num_throttle_states - 1; /* * Shift the mask */ for (index = 0; index < (NATIVE_UINT) duty_offset; index++) { pcnt_mask_off_duty_field = pcnt_mask_off_duty_field << 1; duty32_value = duty32_value << 1; } /* * Read in the current value from the port */ port_value = acpi_os_in32 ((ACPI_IO_ADDRESS) pblk_address); /* * Mask off the duty field so we don't OR in junk! */ port_value = port_value & (~pcnt_mask_off_duty_field); /* * OR in the bits we want to write out to the port */ port_value = (port_value | duty32_value) & (~(u32)BIT_4); /* * write it to the port */ acpi_os_out32 ((ACPI_IO_ADDRESS) pblk_address, port_value); return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -