colinux64/patch/timer-2.6.33.diff
2025-02-13 19:09:34 -07:00

256 lines
6.1 KiB
Diff
Executable File

Index: linux-2.6.33-source/arch/x86/lib/Makefile
===================================================================
--- linux-2.6.33-source.orig/arch/x86/lib/Makefile
+++ linux-2.6.33-source/arch/x86/lib/Makefile
@@ -16,7 +16,11 @@
obj-$(CONFIG_SMP) += msr-smp.o cache-smp.o
+ifdef CONFIG_COOPERATIVE
+lib-y := delay_cooperative.o
+else
lib-y := delay.o
+endif
lib-y += thunk_$(BITS).o
lib-y += usercopy_$(BITS).o getuser.o putuser.o
lib-y += memcpy_$(BITS).o
Index: linux-2.6.33-source/arch/x86/kernel/timer_cooperative.c
===================================================================
--- /dev/null
+++ linux-2.6.33-source/arch/x86/kernel/timer_cooperative.c
@@ -0,0 +1,142 @@
+/*
+ * Cooperative mode timer.
+ *
+ * Dan Aloni <da-x@colinux.org>, 2003-2004 (C).
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+
+#include <asm/timer.h>
+#include <asm/delay.h>
+
+#include <linux/clockchips.h>
+#include <linux/clocksource.h>
+#include <linux/cooperative.h>
+#include <linux/cooperative_internal.h>
+
+#define CO_CLOCK_SHIFT 20
+
+/* FSEC = 10^-15
+ NSEC = 10^-9 */
+#define FSEC_PER_NSEC 1000000
+
+/* 100Hz is fix from damons 10ms setup */
+#define CO_HOST_HZ 100
+
+unsigned int cpu_khz;
+EXPORT_SYMBOL(cpu_khz);
+
+/*
+ * Functions copied from time.c
+ */
+unsigned long profile_pc(struct pt_regs *regs)
+{
+ unsigned long pc = instruction_pointer(regs);
+
+ return pc;
+}
+EXPORT_SYMBOL(profile_pc);
+
+/* Read system date and clock at startup */
+void read_persistent_clock(struct timespec *ts)
+{
+ unsigned long flags;
+
+ co_passage_page_assert_valid();
+
+ co_passage_page_acquire(&flags);
+ co_passage_page->operation = CO_OPERATION_GET_TIME;
+ co_switch_wrapper();
+ ts->tv_sec = co_passage_page->params[0];
+ ts->tv_nsec = 0;
+ co_passage_page_release(flags);
+}
+
+/* need by ntp.c */
+int update_persistent_clock(struct timespec now)
+{
+ return 0;
+}
+
+
+/*
+ * Clock source related code, based on arch/arm/mach-omap1/time.c
+ */
+
+static cycle_t query_host_highprec_time(struct clocksource *cs)
+{
+ unsigned long flags;
+ unsigned long long this_time;
+
+ co_passage_page_assert_valid();
+
+ co_passage_page_acquire(&flags);
+ co_passage_page->operation = CO_OPERATION_GET_HIGH_PREC_TIME;
+ co_switch_wrapper();
+ this_time = *(unsigned long long *)(&co_passage_page->params[0]);
+ co_passage_page_release(flags);
+
+ return this_time;
+}
+
+static struct clocksource co_clocksource = {
+ .name = "cooperative",
+ .rating = 450,
+ .read = query_host_highprec_time,
+ .mask = CLOCKSOURCE_MASK(64),
+ .shift = CO_CLOCK_SHIFT,
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+
+static void co_timer_setup(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+}
+
+struct clock_event_device co_clockevent = {
+ .name = "clock",
+ .features = CLOCK_EVT_FEAT_PERIODIC,
+ .set_mode = co_timer_setup,
+ .shift = CO_CLOCK_SHIFT,
+};
+
+static irqreturn_t co_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = &co_clockevent;
+
+ evt->event_handler(evt);
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction co_timer_irq = {
+ .name = "timer",
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = co_timer_interrupt,
+};
+
+extern void (*late_time_init)(void);
+static void __init co_register_timer(void)
+{
+ setup_irq(TIMER_IRQ, &co_timer_irq);
+}
+
+void __init time_init(void)
+{
+ u64 tmp;
+
+ tmp = (u64)CO_HOST_HZ << CO_CLOCK_SHIFT;
+ do_div(tmp, FSEC_PER_NSEC);
+ co_clockevent.mult = (u32)tmp;
+
+ co_clocksource.mult = clocksource_hz2mult(CO_HOST_HZ, CO_CLOCK_SHIFT);
+ co_clockevent.cpumask = cpumask_of(0);
+
+ clockevents_register_device(&co_clockevent);
+ late_time_init = co_register_timer;
+
+ cpu_khz = co_boot_params.co_cpu_khz;
+}
Index: linux-2.6.33-source/arch/x86/include/asm/delay.h
===================================================================
--- linux-2.6.33-source.orig/arch/x86/include/asm/delay.h
+++ linux-2.6.33-source/arch/x86/include/asm/delay.h
@@ -26,6 +26,8 @@
((n) > 20000 ? __bad_ndelay() : __const_udelay((n) * 5ul)) : \
__ndelay(n))
+#ifndef CONFIG_COOPERATIVE
void use_tsc_delay(void);
+#endif
#endif /* _ASM_X86_DELAY_H */
Index: linux-2.6.33-source/arch/x86/include/asm/timex.h
===================================================================
--- linux-2.6.33-source.orig/arch/x86/include/asm/timex.h
+++ linux-2.6.33-source/arch/x86/include/asm/timex.h
@@ -7,6 +7,8 @@
/* Assume we use the PIT time source for the clock tick */
#define CLOCK_TICK_RATE PIT_TICK_RATE
+#ifndef CONFIG_COOPERATIVE
#define ARCH_HAS_READ_CURRENT_TIMER
+#endif /* !CONFIG_COOPERATIVE */
#endif /* _ASM_X86_TIMEX_H */
Index: linux-2.6.33-source/arch/x86/include/asm/msr.h
===================================================================
--- linux-2.6.33-source.orig/arch/x86/include/asm/msr.h
+++ linux-2.6.33-source/arch/x86/include/asm/msr.h
@@ -113,7 +113,12 @@
return err;
}
+#ifdef CONFIG_COOPERATIVE
+/* FIXME: */
+#define native_read_tsc() 0
+#else
extern unsigned long long native_read_tsc(void);
+#endif
extern int native_rdmsr_safe_regs(u32 regs[8]);
extern int native_wrmsr_safe_regs(u32 regs[8]);
Index: linux-2.6.33-source/arch/x86/lib/delay_cooperative.c
===================================================================
--- /dev/null
+++ linux-2.6.33-source/arch/x86/lib/delay_cooperative.c
@@ -0,0 +1,44 @@
+/*
+ * Delay Loops for coLinux
+ *
+ * The __delay function is not very precise under coLinux.
+ */
+
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/timex.h>
+#include <linux/preempt.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+
+#include <asm/processor.h>
+#include <asm/delay.h>
+#include <asm/timer.h>
+
+void __delay(unsigned long loops)
+{
+ struct timespec tv;
+
+ /*
+ * A bogos delay loop for creating BogoMIPS...
+ */
+
+ loops = loops / 0x10000;
+ while (loops--)
+ read_persistent_clock(&tv);
+}
+EXPORT_SYMBOL(__delay);
+
+void __const_udelay(unsigned long xloops)
+{
+ int d0;
+
+ xloops *= 4;
+ asm("mull %%edx"
+ :"=d" (xloops), "=&a" (d0)
+ :"1" (xloops), "0"
+ (cpu_data(raw_smp_processor_id()).loops_per_jiffy * (HZ/4)));
+
+ __delay(++xloops);
+}
+EXPORT_SYMBOL(__const_udelay);