Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/alpha/alpha Provide an alternate delay function tha...
details: https://anonhg.NetBSD.org/src/rev/00dfd2966ffb
branches: trunk
changeset: 1014804:00dfd2966ffb
user: thorpej <thorpej%NetBSD.org@localhost>
date: Sat Oct 03 17:32:49 2020 +0000
description:
Provide an alternate delay function that uses the Qemu get-time hypercall.
diffstat:
sys/arch/alpha/alpha/qemu.c | 53 +++++++++++++++++++++++++++++++++++++++-----
1 files changed, 46 insertions(+), 7 deletions(-)
diffs (95 lines):
diff -r 548eeed95341 -r 00dfd2966ffb sys/arch/alpha/alpha/qemu.c
--- a/sys/arch/alpha/alpha/qemu.c Sat Oct 03 17:31:46 2020 +0000
+++ b/sys/arch/alpha/alpha/qemu.c Sat Oct 03 17:32:49 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: qemu.c,v 1.2 2020/09/29 01:33:00 thorpej Exp $ */
+/* $NetBSD: qemu.c,v 1.3 2020/10/03 17:32:49 thorpej Exp $ */
/*-
* Copyright (c) 2020 The NetBSD Foundation, Inc.
@@ -56,8 +56,10 @@
struct timecounter sc_tc;
};
-static u_int
-qemu_get_timecount(struct timecounter * const tc __unused)
+static unsigned long qemu_nsec_per_tick __read_mostly = (unsigned long)-1;
+
+static inline unsigned long
+qemu_get_vmtime(void)
{
register unsigned long v0 __asm("$0");
register unsigned long a0 __asm("$16") = 7; /* Qemu get-time */
@@ -67,7 +69,41 @@
: "i"(PAL_cserve)
: "$17", "$18", "$19", "$20", "$21");
- return (u_int)v0;
+ return v0;
+}
+
+static void
+qemu_delay(unsigned long usec)
+{
+ /* Get starting point. */
+ const unsigned long base = qemu_get_vmtime();
+
+ /* convert request from usec to nsec */
+ const unsigned long nsec = usec * 1000;
+ KASSERT(nsec > usec);
+
+ /* Figure out finish line. */
+ const unsigned long finished = base + nsec;
+ KASSERT(finished > base);
+
+ unsigned long now;
+
+ /* Spin until we're finished. */
+ while ((now = qemu_get_vmtime()) < finished) {
+ /*
+ * If we have more than one clock tick worth of spinning
+ * to do, when use WTINT to wait at a low power state.
+ */
+ if (finished - now > qemu_nsec_per_tick) {
+ alpha_pal_wtint(0);
+ }
+ }
+}
+
+static u_int
+qemu_get_timecount(struct timecounter * const tc __unused)
+{
+ return (u_int)qemu_get_vmtime();
}
static inline void
@@ -82,8 +118,6 @@
: "$0", "$18", "$19", "$20", "$21");
}
-static unsigned long qemu_nsec_per_tick __read_mostly;
-
static void
qemu_hardclock(struct clockframe * const framep)
{
@@ -102,7 +136,7 @@
qemu_clock_init(void * const v __unused)
{
/* First-time initialization... */
- if (qemu_nsec_per_tick == 0) {
+ if (qemu_nsec_per_tick == (unsigned long)-1) {
KASSERT(CPU_IS_PRIMARY(curcpu()));
qemu_nsec_per_tick = 1000000000UL / hz;
@@ -175,6 +209,11 @@
* Qemu's PALcode implements WTINT; use it to save host cycles.
*/
cpu_idle_fn = cpu_idle_wtint;
+
+ /*
+ * Use Qemu's "VM time" hypercall to implement delay().
+ */
+ alpha_delay_fn = qemu_delay;
}
CFATTACH_DECL_NEW(qemu, sizeof(struct qemu_softc),
Home |
Main Index |
Thread Index |
Old Index