pens.
Mike
From: Mike Pumford <mpumford%mudcovered.org.uk@localhost>
Date: Sat, 7 Apr 2018 15:03:42 +0000 (+0100)
Subject: Add real delay implementation using iomd timer.
X-Git-Url: https://excalibur.mudcovered.org.uk/cgi-bin/gitweb.cgi?p=netbsd%2Fsys;a=commitdiff_plain;h=1f3f93d7af7663d1a6ee484b73925b73aa392692
Add real delay implementation using iomd timer.
Move iomd in config so its the first to attach.
Move iomd timer init to iomd_clock driver.
Make delay use timer if set up
---
diff --git a/arch/acorn32/conf/files.acorn32 b/arch/acorn32/conf/files.acorn32
index ec3f6b40..251d5191 100644
--- a/arch/acorn32/conf/files.acorn32
+++ b/arch/acorn32/conf/files.acorn32
@@ -14,6 +14,11 @@ defflag IRQSTATS
#
include "dev/ata/files.ata"
+# Include IOMD support
+# First so that the IOMD is set up before all the devices that use its
+# resources (like the interrupt controller and clock)
+include "arch/arm/iomd/files.iomd"
+
# PIOC (Peripheral IO Controller) device
# parent to wdc, fdc, com and lpt
device pioc { [offset = -1], [dack = -1], [irq = -1] }
@@ -46,9 +51,6 @@ file arch/acorn32/mainbus/com_pioc.c com_pioc
# Memory disk driver
file arch/acorn32/dev/md_hooks.c md & memory_disk_hooks
-# Include IOMD support
-include "arch/arm/iomd/files.iomd"
-
# Podule bus device
include "dev/podulebus/files.podulebus"
diff --git a/arch/arm/iomd/iomd_clock.c b/arch/arm/iomd/iomd_clock.c
index a372c307..e31cebdd 100644
--- a/arch/arm/iomd/iomd_clock.c
+++ b/arch/arm/iomd/iomd_clock.c
@@ -142,10 +142,24 @@ clockattach(device_t parent, device_t self, void *aux)
sc->sc_iot = ca->ca_iot;
sc->sc_ioh = ca->ca_ioh; /* This is a handle for the whole IOMD */
- clock_sc = sc;
mutex_init(&tmr_lock, MUTEX_DEFAULT, IPL_CLOCK);
- /* Cannot do anything until cpu_initclocks() has been called */
+ /* Set up countdown timer for delay() */
+
+ timer0_count = TIMER_FREQUENCY / hz;
+
+ bus_space_write_1(sc->sc_iot, sc->sc_ioh,
+ IOMD_T0LOW, (timer0_count >> 0) & 0xff);
+ bus_space_write_1(sc->sc_iot, sc->sc_ioh,
+ IOMD_T0HIGH, (timer0_count >>8) & 0xff);
+
+ /* reload the counter */
+
+ bus_space_write_1(sc->sc_iot, sc->sc_ioh,
+ IOMD_T0GO, 0);
+
+ /* Leave the rest of our setup for cpu_initclocks() */
+ clock_sc = sc;
aprint_normal("\n");
}
@@ -270,18 +284,6 @@ cpu_initclocks(void)
aprint_normal("clock: hz=%d stathz = %d profhz = %d\n", hz, stathz, profhz);
- timer0_count = TIMER_FREQUENCY / hz;
-
- bus_space_write_1(clock_sc->sc_iot, clock_sc->sc_ioh,
- IOMD_T0LOW, (timer0_count >> 0) & 0xff);
- bus_space_write_1(clock_sc->sc_iot, clock_sc->sc_ioh,
- IOMD_T0HIGH, (timer0_count >>8) & 0xff);
-
- /* reload the counter */
-
- bus_space_write_1(clock_sc->sc_iot, clock_sc->sc_ioh,
- IOMD_T0GO, 0);
-
clockirq = intr_claim(IRQ_TIMER0, IPL_CLOCK, "tmr0 hard clk",
clockhandler, 0);
@@ -343,28 +345,75 @@ static u_int iomd_timecounter0_get(struct timecounter *tc)
/*
- * Estimated loop for n microseconds
+ * Delay routine using iomd countdown timer.
+ * Also provides an estimated implementation in case it gets called
+ * before the countdown timer is set up
*/
-/* Need to re-write this to use the timers */
-
-/* One day soon I will actually do this */
-
int delaycount = 100;
void
delay(u_int n)
{
- volatile u_int n2;
- volatile u_int i;
-
- if (n == 0) return;
- n2 = n;
- while (n2-- > 0) {
- if (cputype == CPU_ID_SA110) /* XXX - Seriously gross hack */
- for (i = delaycount; --i;);
- else
- for (i = 8; --i;);
+ if (clock_sc) {
+ int s;
+ u_int last;
+ u_int cur;
+ u_int acc = 0;
+ /* Adjust the delay count to a tick count */
+ n *= TICKS_PER_MICROSECOND;
+
+ /*
+ * Latch the current value of the timer and then read it.
+ * This guarantees an atomic reading of the time.
+ */
+ s = splhigh();
+ bus_space_write_1(clock_sc->sc_iot, clock_sc->sc_ioh,
+ IOMD_T0LATCH, 0);
+
+ last = bus_space_read_1(clock_sc->sc_iot, clock_sc->sc_ioh,
+ IOMD_T0LOW);
+ last += (bus_space_read_1(clock_sc->sc_iot, clock_sc->sc_ioh,
+ IOMD_T0HIGH) <<8);
+ splx(s);
+ /* IOMD timer is countdown. So normally last > cur &
+ * last - cur is our delta. If the timer wraps while we
+ * are polling result will be cur <= last in this case we
+ * need timer0_count - cur + last for the interval as the
+ * interval is from last down to 0 and then from timer0_count
+ * down to cur.
+ */
+ while (acc <n) {
+ s = splhigh();
+ bus_space_write_1(clock_sc->sc_iot, clock_sc->sc_ioh,
+ IOMD_T0LATCH, 0);
+
+ cur = bus_space_read_1(clock_sc->sc_iot,
+ clock_sc->sc_ioh, IOMD_T0LOW);
+ cur += (bus_space_read_1(clock_sc->sc_iot,
+ clock_sc->sc_ioh, IOMD_T0HIGH) <<8);
+
+ splx(s);
+ if (cur > last)
+ acc += timer0_count - cur + last;
+ else
+ acc += last - cur;
+ /* Update our last time */
+ last = cur;
+ }
+ }
+ else {
+ volatile u_int n2;
+ volatile u_int i;
+
+ if (n == 0) return;
+ n2 = n;
+ while (n2-- > 0) {
+ if (cputype == CPU_ID_SA110) /* XXX - Seriously gross hack */
+ for (i = delaycount; --i;);
+ else
+ for (i = 8; --i;);
+ }
}
}
From: Mike Pumford <mpumford%mudcovered.org.uk@localhost>
Date: Sat, 7 Apr 2018 14:32:17 +0000 (+0100)
Subject: Make acorn32 boot again
X-Git-Url: https://excalibur.mudcovered.org.uk/cgi-bin/gitweb.cgi?p=netbsd%2Fsys;a=commitdiff_plain;h=4abf83162792d3ab369afb7fccdd076accf4400e
Make acorn32 boot again
- Make IRQ name area writable so it can be updated as irqs are registered
- When writing new IRQ name make sure its in the fixed format expected
by vmstat
---
diff --git a/arch/arm/iomd/iomd_irq.S b/arch/arm/iomd/iomd_irq.S
index 904ad8dc..08215800 100644
--- a/arch/arm/iomd/iomd_irq.S
+++ b/arch/arm/iomd/iomd_irq.S
@@ -412,7 +412,7 @@ Lirqhandlers:
#ifdef IRQSTATS
/* These symbols are used by vmstat */
- .section .rodata
+ .section .data
.global _C_LABEL(_intrnames)
_C_LABEL(_intrnames):
diff --git a/arch/arm/iomd/iomd_irqhandler.c b/arch/arm/iomd/iomd_irqhandler.c
index 550951fe..382ccbc3 100644
--- a/arch/arm/iomd/iomd_irqhandler.c
+++ b/arch/arm/iomd/iomd_irqhandler.c
@@ -180,7 +180,9 @@ irq_claim(int irq, irqhandler_t *handler)
/* Get the interrupt name from the head of the list */
char *iptr = _intrnames + (irq * 14);
if (handler->ih_name) {
- strlcpy(iptr, handler->ih_name, 14);
+ /* kvm code expects these to be padded to the
+ * field length (13 chars + \0 in our case) */
+ snprintf(iptr, 14, "%-13.13s", handler->ih_name );
} else {
snprintf(iptr, 14, "irq %2d ", irq);
}
@@ -290,7 +292,9 @@ irq_release(int irq, irqhandler_t *handler)
/* Get the interrupt name from the head of the list */
char *iptr = _intrnames + (irq * 14);
if (irqhandlers[irq] && irqhandlers[irq]->ih_name) {
- strlcpy(iptr, irqhandlers[irq]->ih_name, 14);
+ /* kvm code expects these to be padded to the
+ * field length (13 chars + \0 in our case) */
+ snprintf(iptr, 14, "%-13.13s", handler->ih_name );
} else {
snprintf(iptr, 14, "irq %2d ", irq);
}