ChangeSet 1.1327.1.20, 2005/05/02 11:36:28-06:00, djm@xxxxxxxxxxxxxxx
Last round of cleanup: Forgot a new file
xentime.c | 204 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 204 insertions(+)
diff -Nru a/xen/arch/ia64/xentime.c b/xen/arch/ia64/xentime.c
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/xen/arch/ia64/xentime.c 2005-05-03 04:09:28 -04:00
@@ -0,0 +1,204 @@
+/*
+ * xen/arch/ia64/time.c
+ *
+ * Copyright (C) 2005 Hewlett-Packard Co
+ * Dan Magenheimer <dan.magenheimer@xxxxxx>
+ */
+
+#include <linux/config.h>
+
+#include <linux/cpu.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/profile.h>
+#include <linux/sched.h>
+#include <linux/time.h>
+#include <linux/interrupt.h>
+#include <linux/efi.h>
+#include <linux/profile.h>
+#include <linux/timex.h>
+
+#include <asm/machvec.h>
+#include <asm/delay.h>
+#include <asm/hw_irq.h>
+#include <asm/ptrace.h>
+#include <asm/sal.h>
+#include <asm/sections.h>
+#include <asm/system.h>
+#ifdef XEN
+#include <linux/jiffies.h> // not included by xen/sched.h
+#endif
+
+#define TIME_KEEPER_ID 0
+extern unsigned long wall_jiffies;
+
+static s_time_t stime_irq; /* System time at last 'time update' */
+
+unsigned long domain0_ready = 0;
+
+static inline u64 get_time_delta(void)
+{
+ return ia64_get_itc();
+}
+
+s_time_t get_s_time(void)
+{
+ s_time_t now;
+ unsigned long flags;
+
+ read_lock_irqsave(&xtime_lock, flags);
+
+ now = stime_irq + get_time_delta();
+
+ /* Ensure that the returned system time is monotonically increasing. */
+ {
+ static s_time_t prev_now = 0;
+ if ( unlikely(now < prev_now) )
+ now = prev_now;
+ prev_now = now;
+ }
+
+ read_unlock_irqrestore(&xtime_lock, flags);
+
+ return now;
+}
+
+void update_dom_time(struct exec_domain *ed)
+{
+// FIXME: implement this?
+// printf("update_dom_time: called, not implemented, skipping\n");
+ return;
+}
+
+/* Set clock to <secs,usecs> after 00:00:00 UTC, 1 January, 1970. */
+void do_settime(unsigned long secs, unsigned long usecs, u64 system_time_base)
+{
+// FIXME: Should this be do_settimeofday (from linux)???
+ printf("do_settime: called, not implemented, stopping\n");
+ dummy();
+}
+
+irqreturn_t
+xen_timer_interrupt (int irq, void *dev_id, struct pt_regs *regs)
+{
+ unsigned long new_itm;
+
+#ifndef XEN
+ if (unlikely(cpu_is_offline(smp_processor_id()))) {
+ return IRQ_HANDLED;
+ }
+#endif
+#ifdef XEN
+ if (current->domain == dom0) {
+ // FIXME: there's gotta be a better way of doing this...
+ // We have to ensure that domain0 is launched before we
+ // call vcpu_timer_expired on it
+ //domain0_ready = 1; // moved to xensetup.c
+ current->vcpu_info->arch.pending_interruption = 1;
+ }
+ if (domain0_ready && vcpu_timer_expired(dom0->exec_domain[0])) {
+ vcpu_pend_timer(dom0->exec_domain[0]);
+ //vcpu_set_next_timer(dom0->exec_domain[0]);
+ domain_wake(dom0->exec_domain[0]);
+ }
+ if (!is_idle_task(current->domain) && current->domain != dom0) {
+ if (vcpu_timer_expired(current)) {
+ vcpu_pend_timer(current);
+ // ensure another timer interrupt happens even if
domain doesn't
+ vcpu_set_next_timer(current);
+ domain_wake(current);
+ }
+ }
+ raise_actimer_softirq();
+#endif
+
+#ifndef XEN
+ platform_timer_interrupt(irq, dev_id, regs);
+#endif
+
+ new_itm = local_cpu_data->itm_next;
+
+ if (!time_after(ia64_get_itc(), new_itm))
+#ifdef XEN
+ return;
+#else
+ printk(KERN_ERR "Oops: timer tick before it's due
(itc=%lx,itm=%lx)\n",
+ ia64_get_itc(), new_itm);
+#endif
+
+#ifdef XEN
+// printf("GOT TO HERE!!!!!!!!!!!\n");
+ //while(1);
+#else
+ profile_tick(CPU_PROFILING, regs);
+#endif
+
+ while (1) {
+#ifndef XEN
+ update_process_times(user_mode(regs));
+#endif
+
+ new_itm += local_cpu_data->itm_delta;
+
+ if (smp_processor_id() == TIME_KEEPER_ID) {
+ /*
+ * Here we are in the timer irq handler. We have irqs
locally
+ * disabled, but we don't know if the timer_bh is
running on
+ * another CPU. We need to avoid to SMP race by
acquiring the
+ * xtime_lock.
+ */
+#ifdef TURN_ME_OFF_FOR_NOW_IA64_XEN
+ write_seqlock(&xtime_lock);
+#endif
+#ifdef TURN_ME_OFF_FOR_NOW_IA64_XEN
+ do_timer(regs);
+#endif
+ local_cpu_data->itm_next = new_itm;
+#ifdef TURN_ME_OFF_FOR_NOW_IA64_XEN
+ write_sequnlock(&xtime_lock);
+#endif
+ } else
+ local_cpu_data->itm_next = new_itm;
+
+ if (time_after(new_itm, ia64_get_itc()))
+ break;
+ }
+
+ do {
+ /*
+ * If we're too close to the next clock tick for
+ * comfort, we increase the safety margin by
+ * intentionally dropping the next tick(s). We do NOT
+ * update itm.next because that would force us to call
+ * do_timer() which in turn would let our clock run
+ * too fast (with the potentially devastating effect
+ * of losing monotony of time).
+ */
+ while (!time_after(new_itm, ia64_get_itc() +
local_cpu_data->itm_delta/2))
+ new_itm += local_cpu_data->itm_delta;
+//#ifdef XEN
+// vcpu_set_next_timer(current);
+//#else
+//printf("***** timer_interrupt: Setting itm to %lx\n",new_itm);
+ ia64_set_itm(new_itm);
+//#endif
+ /* double check, in case we got hit by a (slow) PMI: */
+ } while (time_after_eq(ia64_get_itc(), new_itm));
+ return IRQ_HANDLED;
+}
+
+static struct irqaction xen_timer_irqaction = {
+ .handler = xen_timer_interrupt,
+#ifndef XEN
+ .flags = SA_INTERRUPT,
+#endif
+ .name = "timer"
+};
+
+void __init
+xen_time_init (void)
+{
+ register_percpu_irq(IA64_TIMER_VECTOR, &xen_timer_irqaction);
+ ia64_init_itm();
+}
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|