From: <stefano.stabellini@eu.citrix.com>
To: xen-devel@lists.xensource.com
Cc: Tim.Deegan@citrix.com, Ian Campbell <ian.campbell@citrix.com>,
JBeulich@suse.com, stefano.stabellini@eu.citrix.com
Subject: [PATCH v4 21/25] arm: driver for the generic timer for ARMv7
Date: Mon, 9 Jan 2012 17:59:57 +0000 [thread overview]
Message-ID: <1326132001-21251-21-git-send-email-stefano.stabellini@eu.citrix.com> (raw)
In-Reply-To: <alpine.DEB.2.00.1201091752280.3150@kaball-desktop>
From: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Driver for the generic timer for ARMv7 with virtualization extensions.
Currently it is based on the kernel timer rather than the hypervisor timer
because the latter does not work correctly on our test environment.
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Signed-off-by: Tim Deegan <Tim.Deegan@citrix.com>
---
xen/arch/arm/time.c | 181 ++++++++++++++++++++++++++++++++++++++++++++
xen/include/asm-arm/time.h | 26 ++++++
2 files changed, 207 insertions(+), 0 deletions(-)
create mode 100644 xen/arch/arm/time.c
create mode 100644 xen/include/asm-arm/time.h
diff --git a/xen/arch/arm/time.c b/xen/arch/arm/time.c
new file mode 100644
index 0000000..13c1254
--- /dev/null
+++ b/xen/arch/arm/time.c
@@ -0,0 +1,181 @@
+/*
+ * xen/arch/arm/time.c
+ *
+ * Time and timer support, using the ARM Generic Timer interfaces
+ *
+ * Tim Deegan <tim@xen.org>
+ * Copyright (c) 2011 Citrix Systems.
+ *
+ * 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.
+ */
+
+#include <xen/config.h>
+#include <xen/console.h>
+#include <xen/init.h>
+#include <xen/irq.h>
+#include <xen/lib.h>
+#include <xen/mm.h>
+#include <xen/softirq.h>
+#include <xen/time.h>
+#include <asm/system.h>
+
+/* Unfortunately the hypervisor timer interrupt appears to be buggy */
+#define USE_HYP_TIMER 0
+
+/* For fine-grained timekeeping, we use the ARM "Generic Timer", a
+ * register-mapped time source in the SoC. */
+static uint32_t __read_mostly cntfrq; /* Ticks per second */
+static uint64_t __read_mostly boot_count; /* Counter value at boot time */
+
+/*static inline*/ s_time_t ticks_to_ns(uint64_t ticks)
+{
+ return muldiv64(ticks, SECONDS(1), cntfrq);
+}
+
+/*static inline*/ uint64_t ns_to_ticks(s_time_t ns)
+{
+ return muldiv64(ns, cntfrq, SECONDS(1));
+}
+
+/* TODO: On a real system the firmware would have set the frequency in
+ the CNTFRQ register. Also we'd need to use devicetree to find
+ the RTC. When we've seen some real systems, we can delete this.
+static uint32_t calibrate_timer(void)
+{
+ uint32_t sec;
+ uint64_t start, end;
+ paddr_t rtc_base = 0x1C170000ull;
+ volatile uint32_t *rtc;
+
+ ASSERT(!local_irq_is_enabled());
+ set_fixmap(FIXMAP_MISC, rtc_base >> PAGE_SHIFT, DEV_SHARED);
+ rtc = (uint32_t *) FIXMAP_ADDR(FIXMAP_MISC);
+
+ printk("Calibrating timer against RTC...");
+ // Turn on the RTC
+ rtc[3] = 1;
+ // Wait for an edge
+ sec = rtc[0] + 1;
+ do {} while ( rtc[0] != sec );
+ // Now time a few seconds
+ start = READ_CP64(CNTPCT);
+ do {} while ( rtc[0] < sec + 32 );
+ end = READ_CP64(CNTPCT);
+ printk("done.\n");
+
+ clear_fixmap(FIXMAP_MISC);
+ return (end - start) / 32;
+}
+*/
+
+/* Set up the timer on the boot CPU */
+int __init init_xen_time(void)
+{
+ /* Check that this CPU supports the Generic Timer interface */
+ if ( (READ_CP32(ID_PFR1) & ID_PFR1_GT_MASK) != ID_PFR1_GT_v1 )
+ panic("CPU does not support the Generic Timer v1 interface.\n");
+
+ cntfrq = READ_CP32(CNTFRQ);
+ boot_count = READ_CP64(CNTPCT);
+ printk("Using generic timer at %"PRIu32" Hz\n", cntfrq);
+
+ return 0;
+}
+
+/* Return number of nanoseconds since boot */
+s_time_t get_s_time(void)
+{
+ uint64_t ticks = READ_CP64(CNTPCT) - boot_count;
+ return ticks_to_ns(ticks);
+}
+
+/* Set the timer to wake us up at a particular time.
+ * Timeout is a Xen system time (nanoseconds since boot); 0 disables the timer.
+ * Returns 1 on success; 0 if the timeout is too soon or is in the past. */
+int reprogram_timer(s_time_t timeout)
+{
+ uint64_t deadline;
+
+ if ( timeout == 0 )
+ {
+#if USE_HYP_TIMER
+ WRITE_CP32(0, CNTHP_CTL);
+#else
+ WRITE_CP32(0, CNTP_CTL);
+#endif
+ return 1;
+ }
+
+ deadline = ns_to_ticks(timeout) + boot_count;
+#if USE_HYP_TIMER
+ WRITE_CP64(deadline, CNTHP_CVAL);
+ WRITE_CP32(CNTx_CTL_ENABLE, CNTHP_CTL);
+#else
+ WRITE_CP64(deadline, CNTP_CVAL);
+ WRITE_CP32(CNTx_CTL_ENABLE, CNTP_CTL);
+#endif
+ isb();
+
+ /* No need to check for timers in the past; the Generic Timer fires
+ * on a signed 63-bit comparison. */
+ return 1;
+}
+
+/* Handle the firing timer */
+static void timer_interrupt(int irq, void *dev_id, struct cpu_user_regs *regs)
+{
+ if ( irq == 26 && READ_CP32(CNTHP_CTL) & CNTx_CTL_PENDING )
+ {
+ /* Signal the generic timer code to do its work */
+ raise_softirq(TIMER_SOFTIRQ);
+ /* Disable the timer to avoid more interrupts */
+ WRITE_CP32(0, CNTHP_CTL);
+ }
+
+ if (irq == 30 && READ_CP32(CNTP_CTL) & CNTx_CTL_PENDING )
+ {
+ /* Signal the generic timer code to do its work */
+ raise_softirq(TIMER_SOFTIRQ);
+ /* Disable the timer to avoid more interrupts */
+ WRITE_CP32(0, CNTP_CTL);
+ }
+}
+
+/* Set up the timer interrupt on this CPU */
+void __cpuinit init_timer_interrupt(void)
+{
+ /* Sensible defaults */
+ WRITE_CP64(0, CNTVOFF); /* No VM-specific offset */
+ WRITE_CP32(0, CNTKCTL); /* No user-mode access */
+#if USE_HYP_TIMER
+ /* Let the VMs read the physical counter and timer so they can tell time */
+ WRITE_CP32(CNTHCTL_PA|CNTHCTL_TA, CNTHCTL);
+#else
+ /* Cannot let VMs access physical counter if we are using it */
+ WRITE_CP32(0, CNTHCTL);
+#endif
+ WRITE_CP32(0, CNTP_CTL); /* Physical timer disabled */
+ WRITE_CP32(0, CNTHP_CTL); /* Hypervisor's timer disabled */
+ isb();
+
+ /* XXX Need to find this IRQ number from devicetree? */
+ request_irq(26, timer_interrupt, 0, "hyptimer", NULL);
+ request_irq(30, timer_interrupt, 0, "phytimer", NULL);
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/include/asm-arm/time.h b/xen/include/asm-arm/time.h
new file mode 100644
index 0000000..8cc9e78
--- /dev/null
+++ b/xen/include/asm-arm/time.h
@@ -0,0 +1,26 @@
+#ifndef __ARM_TIME_H__
+#define __ARM_TIME_H__
+
+typedef unsigned long cycles_t;
+
+static inline cycles_t get_cycles (void)
+{
+ return 0;
+}
+
+struct tm;
+struct tm wallclock_time(void);
+
+
+/* Set up the timer interrupt on this CPU */
+extern void __cpuinit init_timer_interrupt(void);
+
+#endif /* __ARM_TIME_H__ */
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
--
1.7.2.5
next prev parent reply other threads:[~2012-01-09 17:59 UTC|newest]
Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-01-09 17:58 [PATCH v4 00/25] xen: ARMv7 with virtualization extensions Stefano Stabellini
2012-01-09 17:59 ` [PATCH v4 01/25] Move cpufreq option parsing to cpufreq.c stefano.stabellini
2012-01-09 17:59 ` [PATCH v4 02/25] Include some header files that are not automatically included on all archs stefano.stabellini
2012-01-09 17:59 ` [PATCH v4 03/25] A collection of fixes to Xen common files stefano.stabellini
2012-01-09 17:59 ` [PATCH v4 04/25] xen: implement an signed 64 bit division helper function stefano.stabellini
2012-01-10 17:15 ` Ian Jackson
2012-01-09 17:59 ` [PATCH v4 05/25] Introduce clear_user and clear_guest stefano.stabellini
2012-01-09 17:59 ` [PATCH v4 06/25] libelf-loader: introduce elf_load_image stefano.stabellini
2012-01-10 10:02 ` Jan Beulich
2012-01-10 13:49 ` Stefano Stabellini
2012-01-09 17:59 ` [PATCH v4 07/25] xen/common/Makefile: introduce HAS_CPUFREQ, HAS_PCI, HAS_PASSTHROUGH, HAS_NS16550, HAS_KEXEC stefano.stabellini
2012-01-09 17:59 ` [PATCH v4 08/25] arm: compile tmem stefano.stabellini
2012-01-09 17:59 ` [PATCH v4 09/25] arm: header files stefano.stabellini
2012-01-09 17:59 ` [PATCH v4 10/25] arm: bit manipulation, copy and division libraries stefano.stabellini
2012-01-10 8:32 ` Ian Campbell
2012-01-10 11:22 ` Stefano Stabellini
2012-01-10 11:29 ` Ian Campbell
2012-01-09 17:59 ` [PATCH v4 11/25] arm: entry.S and head.S stefano.stabellini
2012-01-09 17:59 ` [PATCH v4 12/25] arm: domain stefano.stabellini
2012-01-09 17:59 ` [PATCH v4 13/25] arm: domain_build stefano.stabellini
2012-01-09 18:29 ` David Vrabel
2012-01-10 9:01 ` Ian Campbell
2012-01-10 11:18 ` Stefano Stabellini
2012-01-09 17:59 ` [PATCH v4 14/25] arm: driver for CoreLink GIC-400 Generic Interrupt Controller stefano.stabellini
2012-01-10 10:04 ` Ian Campbell
2012-01-10 11:13 ` Stefano Stabellini
2012-01-09 17:59 ` [PATCH v4 15/25] arm: mmio handlers stefano.stabellini
2012-01-09 17:59 ` [PATCH v4 16/25] arm: irq stefano.stabellini
2012-01-09 17:59 ` [PATCH v4 17/25] arm: mm and p2m stefano.stabellini
2012-01-09 17:59 ` [PATCH v4 19/25] arm: early setup code stefano.stabellini
2012-01-09 17:59 ` [PATCH v4 20/25] arm: shutdown, smp and smpboot stefano.stabellini
2012-01-09 17:59 ` stefano.stabellini [this message]
2012-01-09 17:59 ` [PATCH v4 22/25] arm: trap handlers stefano.stabellini
2012-01-09 17:59 ` [PATCH v4 23/25] arm: vgic emulation stefano.stabellini
2012-01-09 18:25 ` David Vrabel
2012-01-10 9:00 ` Ian Campbell
2012-01-10 11:17 ` Stefano Stabellini
2012-01-09 18:00 ` [PATCH v4 24/25] arm: vtimer stefano.stabellini
2012-01-09 18:00 ` [PATCH v4 25/25] arm: makefiles stefano.stabellini
2012-01-10 10:06 ` [PATCH v4 00/25] xen: ARMv7 with virtualization extensions Jan Beulich
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1326132001-21251-21-git-send-email-stefano.stabellini@eu.citrix.com \
--to=stefano.stabellini@eu.citrix.com \
--cc=JBeulich@suse.com \
--cc=Tim.Deegan@citrix.com \
--cc=ian.campbell@citrix.com \
--cc=xen-devel@lists.xensource.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).