Module: xenomai-2.6 Branch: master Commit: 242a6e49e0fb3c73bb41a4613f547b98c39c24af URL: http://git.xenomai.org/?p=xenomai-2.6.git;a=commit;h=242a6e49e0fb3c73bb41a4613f547b98c39c24af
Author: Gilles Chanteperdrix <gilles.chanteperd...@xenomai.org> Date: Sat Jul 5 13:46:17 2014 +0200 hal/x86: add C1E state workaround --- include/asm-x86/Makefile.am | 3 +- include/asm-x86/c1e.h | 43 +++++++++++++++++++++++ include/asm-x86/hal_32.h | 2 ++ include/asm-x86/hal_64.h | 2 ++ ksrc/arch/x86/Makefile | 2 +- ksrc/arch/x86/c1e.c | 82 +++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 132 insertions(+), 2 deletions(-) diff --git a/include/asm-x86/Makefile.am b/include/asm-x86/Makefile.am index 2533c81..982a978 100644 --- a/include/asm-x86/Makefile.am +++ b/include/asm-x86/Makefile.am @@ -3,10 +3,11 @@ includesubdir = $(includedir)/asm-x86 includesub_HEADERS = \ arith_32.h \ arith_64.h \ - arith.h \ + arith.h \ atomic.h \ atomic_asm.h \ calibration.h \ + c1e.h \ features_32.h \ features_64.h \ features.h \ diff --git a/include/asm-x86/c1e.h b/include/asm-x86/c1e.h new file mode 100644 index 0000000..da15661 --- /dev/null +++ b/include/asm-x86/c1e.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2014 Gilles Chanteperdrix <gilles.chanteperd...@xenomai.org>. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#ifndef C1E_H +#define C1E_H + +#include <linux/version.h> + +#ifndef __KERNEL__ +#error "Pure kernel header included from user-space!" +#endif + +#ifndef _XENO_ASM_X86_HAL_H +#error "please don't include asm/c1e.h directly" +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0) + +static inline void rthal_c1e_disable(void) +{ +} + +#else + +void rthal_c1e_disable(void); + +#endif + +#endif /* C1E_H */ diff --git a/include/asm-x86/hal_32.h b/include/asm-x86/hal_32.h index 480fcf2..ec5bbdd 100644 --- a/include/asm-x86/hal_32.h +++ b/include/asm-x86/hal_32.h @@ -94,6 +94,7 @@ static inline __attribute_const__ unsigned long ffnz(unsigned long ul) #include <asm/msr.h> #include <asm/xenomai/atomic.h> #include <asm/xenomai/smi.h> +#include <asm/xenomai/c1e.h> #ifdef CONFIG_IPIPE_CORE #define RTHAL_TIMER_IRQ __ipipe_hrtimer_irq @@ -124,6 +125,7 @@ static inline __attribute_const__ unsigned long ffnz(unsigned long ul) static inline void rthal_grab_control(void) { + rthal_c1e_disable(); rthal_smi_init(); rthal_smi_disable(); } diff --git a/include/asm-x86/hal_64.h b/include/asm-x86/hal_64.h index 867f5ff..f37678d 100644 --- a/include/asm-x86/hal_64.h +++ b/include/asm-x86/hal_64.h @@ -51,6 +51,7 @@ static inline __attribute_const__ unsigned long ffnz(unsigned long ul) #include <asm/msr.h> #include <asm/xenomai/atomic.h> #include <asm/xenomai/smi.h> +#include <asm/xenomai/c1e.h> #ifdef CONFIG_IPIPE_CORE #define RTHAL_TIMER_IRQ __ipipe_hrtimer_irq @@ -69,6 +70,7 @@ static inline __attribute_const__ unsigned long ffnz(unsigned long ul) static inline void rthal_grab_control(void) { + rthal_c1e_disable(); rthal_smi_init(); rthal_smi_disable(); } diff --git a/ksrc/arch/x86/Makefile b/ksrc/arch/x86/Makefile index e0070b5..71185a9 100644 --- a/ksrc/arch/x86/Makefile +++ b/ksrc/arch/x86/Makefile @@ -10,7 +10,7 @@ endif obj-$(CONFIG_XENOMAI) += xeno_hal.o -xeno_hal-y := hal_$(X86_MODE).o hal-common.o usercopy_$(X86_MODE).o smi.o +xeno_hal-y := hal_$(X86_MODE).o hal-common.o usercopy_$(X86_MODE).o smi.o c1e.o EXTRA_CFLAGS += -D__IN_XENOMAI__ -Iinclude/xenomai diff --git a/ksrc/arch/x86/c1e.c b/ksrc/arch/x86/c1e.c new file mode 100644 index 0000000..a5bdc34 --- /dev/null +++ b/ksrc/arch/x86/c1e.c @@ -0,0 +1,82 @@ +/* + * Disable Intel automatic promotion to C1E mode. + * Lifted from drivers/idle/intel_idle.c + * Copyright (c) 2013, Intel Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#include <linux/smp.h> +#include <asm/xenomai/hal.h> + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0) + +#include <asm/processor.h> +#include <asm/cpu_device_id.h> +#include <asm/msr.h> + +#ifndef MSR_IA32_POWER_CTL +#define MSR_IA32_POWER_CTL 0x000001fc +#endif + +#define ICPU(model) \ + { X86_VENDOR_INTEL, 6, model, X86_FEATURE_MWAIT, 1UL } + +static const struct x86_cpu_id c1e_ids[] = { + ICPU(0x1a), + ICPU(0x1e), + ICPU(0x1f), + ICPU(0x25), + ICPU(0x2c), + ICPU(0x2e), + ICPU(0x2f), + ICPU(0x2a), + ICPU(0x2d), + ICPU(0x3a), + ICPU(0x3e), + ICPU(0x3c), + ICPU(0x3f), + ICPU(0x45), + ICPU(0x46), + ICPU(0x4D), + {} +}; + +#undef ICPU + +static void c1e_promotion_disable(void *dummy) +{ + unsigned long long msr_bits; + + rdmsrl(MSR_IA32_POWER_CTL, msr_bits); + msr_bits &= ~0x2; + wrmsrl(MSR_IA32_POWER_CTL, msr_bits); +} + +void rthal_c1e_disable(void) +{ + const struct x86_cpu_id *id; + + id = x86_match_cpu(c1e_ids); + if (id) { + printk("Xenomai: disabling automatic C1E state promotion on Intel processor\n"); + /* + * cpu uses C1E, disable this feature (copied from + * intel_idle driver) + */ + on_each_cpu(c1e_promotion_disable, NULL, 1); + } +} + +#endif _______________________________________________ Xenomai-git mailing list Xenomai-git@xenomai.org http://www.xenomai.org/mailman/listinfo/xenomai-git