This patch exploits the reworked ipipe_request_tickdev API that will be
posted in a separate series. This way we can overcome the inaccuracy of
Xenomai's current APIC timer frequency calibration. For
!CONFIG_GENERIC_CLOCKEVENTS, the patch tries to obtain the frequency via
the intermediate IPIPE_APIC_TIMER_FREQ API that will be provided on
x86_64 only up to and including kernel 2.6.23 (later x86-kernels will be
fully CLOCKEVENTS-based). We may also consider backporting that API to
2.6.20-i386.

Note that the user is still able to override the timer frequency via the
related nucleus modules parameter.

Jan
---
 include/asm-x86/hal.h      |   30 ++++++++++++++++++++++++++++++
 ksrc/arch/x86/hal-shared.c |   15 +++++++++++----
 ksrc/arch/x86/hal_32.c     |   22 +++++++++++-----------
 ksrc/arch/x86/hal_64.c     |    3 ---
 4 files changed, 52 insertions(+), 18 deletions(-)

Index: xenomai/include/asm-x86/hal.h
===================================================================
--- xenomai.orig/include/asm-x86/hal.h
+++ xenomai/include/asm-x86/hal.h
@@ -1,6 +1,36 @@
+/**
+ * @ingroup hal
+ * @file
+ *
+ * Copyright (C) 2007 Philippe Gerum <[EMAIL PROTECTED]>.
+ *
+ * Xenomai 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.
+ *
+ * Xenomai 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 Xenomai; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
 #ifndef _XENO_ASM_X86_HAL_H
 #define _XENO_ASM_X86_HAL_H
 
+#include <linux/ipipe.h>
+
+#ifndef IPIPE_APIC_TIMER_FREQ
+# define RTHAL_COMPAT_TIMERFREQ		(apic_read(APIC_TMICT) * HZ)
+#else
+# define RTHAL_COMPAT_TIMERFREQ		IPIPE_APIC_TIMER_FREQ
+#endif
+
 enum rthal_ktimer_mode { /* <!> Must follow enum clock_event_mode */
 	KTIMER_MODE_UNUSED = 0,
 	KTIMER_MODE_SHUTDOWN,
Index: xenomai/ksrc/arch/x86/hal-shared.c
===================================================================
--- xenomai.orig/ksrc/arch/x86/hal-shared.c
+++ xenomai/ksrc/arch/x86/hal-shared.c
@@ -132,9 +132,11 @@ int rthal_timer_request(
 	/* This code works both for UP+LAPIC and SMP configurations. */
 
 #ifdef CONFIG_GENERIC_CLOCKEVENTS
-	err = ipipe_request_tickdev("lapic", mode_emul, tick_emul, cpu);
+	unsigned long tick_freq;
+	int res = ipipe_request_tickdev("lapic", mode_emul, tick_emul, cpu,
+					&tick_freq);
 
-	switch (err) {
+	switch (res) {
 	case CLOCK_EVT_MODE_PERIODIC:
 		/* oneshot tick emulation callback won't be used, ask
 		 * the caller to start an internal timer for emulating
@@ -156,10 +158,12 @@ int rthal_timer_request(
 		return -ENODEV;
 
 	default:
-		return err;
+		return res;
 	}
+	rthal_ktimer_saved_mode = res;
 
-	rthal_ktimer_saved_mode = err;
+	if (rthal_timerfreq_arg == 0)
+		rthal_tunables.timer_freq = tick_freq;
 #else /* !CONFIG_GENERIC_CLOCKEVENTS */
 	/*
 	 * When the local APIC is enabled for kernels lacking generic
@@ -170,6 +174,9 @@ int rthal_timer_request(
 	 */
 	tickval = 0;
 	rthal_ktimer_saved_mode = KTIMER_MODE_PERIODIC;
+
+	if (rthal_timerfreq_arg == 0)
+		rthal_tunables.timer_freq = RTHAL_COMPAT_TIMERFREQ;
 #endif /* !CONFIG_GENERIC_CLOCKEVENTS */
 
 	/*
Index: xenomai/ksrc/arch/x86/hal_32.c
===================================================================
--- xenomai.orig/ksrc/arch/x86/hal_32.c
+++ xenomai/ksrc/arch/x86/hal_32.c
@@ -240,9 +240,11 @@ int rthal_timer_request(
 	int tickval, err;
 
 #ifdef CONFIG_GENERIC_CLOCKEVENTS
-	err = ipipe_request_tickdev("pit", mode_emul, tick_emul, cpu);
+	unsigned long tick_freq;
+	int res = ipipe_request_tickdev("pit", mode_emul, tick_emul, cpu,
+					&tick_freq);
 
-	switch (err) {
+	switch (res) {
 	case CLOCK_EVT_MODE_PERIODIC:
 		/* oneshot tick emulation callback won't be used, ask
 		 * the caller to start an internal timer for emulating
@@ -264,10 +266,12 @@ int rthal_timer_request(
 		return -ENOSYS;
 
 	default:
-		return err;
+		return res;
 	}
+	rthal_ktimer_saved_mode = res;
 
-	rthal_ktimer_saved_mode = err;
+	if (rthal_timerfreq_arg == 0)
+		rthal_tunables.timer_freq = tick_freq;
 #else /* !CONFIG_GENERIC_CLOCKEVENTS */
 	/*
 	 * Out caller has to to emulate the periodic host tick by its
@@ -275,6 +279,9 @@ int rthal_timer_request(
 	 */
 	tickval = 1000000000UL / HZ;
 	rthal_ktimer_saved_mode = KTIMER_MODE_PERIODIC;
+
+	if (rthal_timerfreq_arg == 0)
+		rthal_tunables.timer_freq = CLOCK_TICK_RATE;
 #endif /* !CONFIG_GENERIC_CLOCKEVENTS */
 
 	/*
@@ -394,13 +401,6 @@ int rthal_arch_init(void)
 	rthal_setup_8254_tsc();
 #endif /* CONFIG_X86_TSC */
 
-	if (rthal_timerfreq_arg == 0)
-#ifdef CONFIG_X86_LOCAL_APIC
-		rthal_timerfreq_arg = apic_read(APIC_TMICT) * HZ;
-#else /* !CONFIG_X86_LOCAL_APIC */
-		rthal_timerfreq_arg = CLOCK_TICK_RATE;
-#endif /* CONFIG_X86_LOCAL_APIC */
-
 	return 0;
 }
 
Index: xenomai/ksrc/arch/x86/hal_64.c
===================================================================
--- xenomai.orig/ksrc/arch/x86/hal_64.c
+++ xenomai/ksrc/arch/x86/hal_64.c
@@ -79,9 +79,6 @@ int rthal_arch_init(void)
 		/* FIXME: 4Ghz barrier is close... */
 		rthal_cpufreq_arg = rthal_get_cpufreq();
 
-	if (rthal_timerfreq_arg == 0)
-		rthal_timerfreq_arg = apic_read(APIC_TMICT) * HZ;
-
 	return 0;
 }
 

Attachment: signature.asc
Description: OpenPGP digital signature

_______________________________________________
Xenomai-core mailing list
Xenomai-core@gna.org
https://mail.gna.org/listinfo/xenomai-core

Reply via email to