ia64/xen-unstable
changeset 19549:573e6673e9e0
cpuidle: Enable hpet broadcast by default
And stop legacy hpet broadcast and limit max C-state to shallower
state if RTC interrupts are enabled.
Signed-off-by: Wei Gang <gang.wei@intel.com>
Signed-off-by: Tian Kevin <kevin.tian@intel.com>
And stop legacy hpet broadcast and limit max C-state to shallower
state if RTC interrupts are enabled.
Signed-off-by: Wei Gang <gang.wei@intel.com>
Signed-off-by: Tian Kevin <kevin.tian@intel.com>
author | Keir Fraser <keir.fraser@citrix.com> |
---|---|
date | Wed Apr 15 15:47:25 2009 +0100 (2009-04-15) |
parents | 3e64dfebabd7 |
children | b14dc215dd19 |
files | xen/arch/x86/acpi/cpu_idle.c xen/arch/x86/hpet.c xen/arch/x86/traps.c xen/include/asm-x86/hpet.h |
line diff
1.1 --- a/xen/arch/x86/acpi/cpu_idle.c Wed Apr 15 15:38:57 2009 +0100 1.2 +++ b/xen/arch/x86/acpi/cpu_idle.c Wed Apr 15 15:47:25 2009 +0100 1.3 @@ -221,8 +221,8 @@ static void acpi_processor_idle(void) 1.4 return; 1.5 } 1.6 1.7 - next_state = power ? cpuidle_current_governor->select(power) : -1; 1.8 - if ( next_state > 0 ) 1.9 + if ( max_cstate > 0 && power && 1.10 + (next_state = cpuidle_current_governor->select(power)) > 0 ) 1.11 { 1.12 cx = &power->states[next_state]; 1.13 if ( power->flags.bm_check && acpi_idle_bm_check() 1.14 @@ -853,3 +853,18 @@ int pmstat_reset_cx_stat(uint32_t cpuid) 1.15 return 0; 1.16 } 1.17 1.18 +void cpuidle_disable_deep_cstate(void) 1.19 +{ 1.20 + if ( max_cstate > 1 ) 1.21 + { 1.22 + if ( local_apic_timer_c2_ok ) 1.23 + max_cstate = 2; 1.24 + else 1.25 + max_cstate = 1; 1.26 + } 1.27 + 1.28 + mb(); 1.29 + 1.30 + hpet_disable_legacy_broadcast(); 1.31 +} 1.32 +
2.1 --- a/xen/arch/x86/hpet.c Wed Apr 15 15:38:57 2009 +0100 2.2 +++ b/xen/arch/x86/hpet.c Wed Apr 15 15:47:25 2009 +0100 2.3 @@ -22,8 +22,10 @@ 2.4 2.5 #define MAX_HPET_NUM 32 2.6 2.7 -#define HPET_EVT_USED_BIT 2 2.8 +#define HPET_EVT_USED_BIT 0 2.9 #define HPET_EVT_USED (1 << HPET_EVT_USED_BIT) 2.10 +#define HPET_EVT_DISABLE_BIT 1 2.11 +#define HPET_EVT_DISALBE (1 << HPET_EVT_DISABLE_BIT) 2.12 2.13 struct hpet_event_channel 2.14 { 2.15 @@ -53,8 +55,11 @@ unsigned long hpet_address; 2.16 2.17 void msi_compose_msg(struct pci_dev *pdev, int vector, struct msi_msg *msg); 2.18 2.19 -/* force_hpet_broadcast: if true, force using hpet_broadcast to fix lapic stop 2.20 - issue for deep C state with pit disabled */ 2.21 +/* 2.22 + * force_hpet_broadcast: by default legacy hpet broadcast will be stopped 2.23 + * if RTC interrupts are enabled. Enable this option if want to always enable 2.24 + * legacy hpet broadcast for deep C state 2.25 + */ 2.26 int force_hpet_broadcast; 2.27 boolean_param("hpetbroadcast", force_hpet_broadcast); 2.28 2.29 @@ -114,6 +119,9 @@ static int reprogram_hpet_evt_channel( 2.30 int64_t delta; 2.31 int ret; 2.32 2.33 + if ( ch->flags & HPET_EVT_DISALBE ) 2.34 + return 0; 2.35 + 2.36 if ( unlikely(expire < 0) ) 2.37 { 2.38 printk(KERN_DEBUG "reprogram: expire < 0\n"); 2.39 @@ -483,6 +491,32 @@ static void hpet_detach_channel_share(in 2.40 static void (*hpet_attach_channel)(int cpu, struct hpet_event_channel *ch); 2.41 static void (*hpet_detach_channel)(int cpu); 2.42 2.43 +#include <asm/mc146818rtc.h> 2.44 +void cpuidle_disable_deep_cstate(void); 2.45 + 2.46 +void (*pv_rtc_handler)(unsigned int port, uint8_t value); 2.47 + 2.48 +static void handle_rtc_once(unsigned int port, uint8_t value) 2.49 +{ 2.50 + static int index; 2.51 + 2.52 + if ( port == 0x70 ) 2.53 + { 2.54 + index = value; 2.55 + return; 2.56 + } 2.57 + 2.58 + if ( index != RTC_REG_B ) 2.59 + return; 2.60 + 2.61 + /* RTC Reg B, contain PIE/AIE/UIE */ 2.62 + if ( value & (RTC_PIE | RTC_AIE | RTC_UIE ) ) 2.63 + { 2.64 + cpuidle_disable_deep_cstate(); 2.65 + pv_rtc_handler = NULL; 2.66 + } 2.67 +} 2.68 + 2.69 void hpet_broadcast_init(void) 2.70 { 2.71 u64 hpet_rate; 2.72 @@ -526,8 +560,11 @@ void hpet_broadcast_init(void) 2.73 return; 2.74 } 2.75 2.76 + if ( legacy_hpet_event.flags & HPET_EVT_DISALBE ) 2.77 + return; 2.78 + 2.79 hpet_id = hpet_read32(HPET_ID); 2.80 - if ( !(hpet_id & HPET_ID_LEGSUP) || !force_hpet_broadcast ) 2.81 + if ( !(hpet_id & HPET_ID_LEGSUP) ) 2.82 return; 2.83 2.84 /* Start HPET legacy interrupts */ 2.85 @@ -555,6 +592,32 @@ void hpet_broadcast_init(void) 2.86 2.87 for_each_cpu(i) 2.88 per_cpu(cpu_bc_channel, i) = &legacy_hpet_event; 2.89 + 2.90 + if ( !force_hpet_broadcast ) 2.91 + pv_rtc_handler = handle_rtc_once; 2.92 +} 2.93 + 2.94 +void hpet_disable_legacy_broadcast(void) 2.95 +{ 2.96 + u32 cfg; 2.97 + 2.98 + spin_lock_irq(&legacy_hpet_event.lock); 2.99 + 2.100 + legacy_hpet_event.flags |= HPET_EVT_DISALBE; 2.101 + 2.102 + /* disable HPET T0 */ 2.103 + cfg = hpet_read32(HPET_T0_CFG); 2.104 + cfg &= ~HPET_TN_ENABLE; 2.105 + hpet_write32(cfg, HPET_T0_CFG); 2.106 + 2.107 + /* Stop HPET legacy interrupts */ 2.108 + cfg = hpet_read32(HPET_CFG); 2.109 + cfg &= ~HPET_CFG_LEGACY; 2.110 + hpet_write32(cfg, HPET_CFG); 2.111 + 2.112 + spin_unlock_irq(&legacy_hpet_event.lock); 2.113 + 2.114 + smp_send_event_check_mask(cpu_online_map); 2.115 } 2.116 2.117 void hpet_broadcast_enter(void)
3.1 --- a/xen/arch/x86/traps.c Wed Apr 15 15:38:57 2009 +0100 3.2 +++ b/xen/arch/x86/traps.c Wed Apr 15 15:47:25 2009 +0100 3.3 @@ -1551,6 +1551,8 @@ static uint32_t guest_io_read( 3.4 return data; 3.5 } 3.6 3.7 +extern void (*pv_rtc_handler)(unsigned int port, uint8_t value); 3.8 + 3.9 static void guest_io_write( 3.10 unsigned int port, unsigned int bytes, uint32_t data, 3.11 struct vcpu *v, struct cpu_user_regs *regs) 3.12 @@ -1565,6 +1567,8 @@ static void guest_io_write( 3.13 outb((uint8_t)data, port); 3.14 if ( pv_post_outb_hook ) 3.15 pv_post_outb_hook(port, (uint8_t)data); 3.16 + if ( ((port == 0x71) || (port == 0x70)) && pv_rtc_handler ) 3.17 + pv_rtc_handler(port, (uint8_t)data); 3.18 break; 3.19 case 2: 3.20 outw((uint16_t)data, port); 3.21 @@ -1936,6 +1940,8 @@ static int emulate_privileged_op(struct 3.22 io_emul(regs); 3.23 if ( (op_bytes == 1) && pv_post_outb_hook ) 3.24 pv_post_outb_hook(port, regs->eax); 3.25 + if ( ((port == 0x71) || (port == 0x70)) && pv_rtc_handler ) 3.26 + pv_rtc_handler(port, regs->eax); 3.27 } 3.28 else 3.29 {
4.1 --- a/xen/include/asm-x86/hpet.h Wed Apr 15 15:38:57 2009 +0100 4.2 +++ b/xen/include/asm-x86/hpet.h Wed Apr 15 15:47:25 2009 +0100 4.3 @@ -78,5 +78,6 @@ void hpet_broadcast_init(void); 4.4 void hpet_broadcast_enter(void); 4.5 void hpet_broadcast_exit(void); 4.6 int hpet_broadcast_is_available(void); 4.7 +void hpet_disable_legacy_broadcast(void); 4.8 4.9 #endif /* __X86_HPET_H__ */