Port-acorn32 archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Booting on RiscPC



On 25/03/2019 21:22, Mike Pumford wrote:
On 25/03/2019 19:09, Mike Pumford wrote:
I'm in the process of setting up a more up to date current tree for myself where I'll apply these patches and see what happens.

Well I got a kernel with patches booting and got the same division by zero panic you did. However I had a working keyboard so was able to get a backtrace.

Division by zero is in statclock (called from hardclock().

There also seems to be something really bad in the podule detection code as it didn't pick up any of the podules properly. :(

I'll keep on diggind and see if I can work it out.

Well the good new is that I've got a booting kernel.

You need an updated version of the timerfix.patch (attached). Division by zero was in setstatclockrate() and has been there forever.

The podule problem is a lot more awkward to solve as it relates to the fact that NetBSD-current now uses GCC 7. GCC7 has dropped support for the armv3 instruction set which means that the underlying compiler architecture has changed for acorn32. Whilst the strongARM is a v4 instruction set CPU there is a hardware issue on the RiscPC that stops the ldrh instruction from working. This meant that the podule identification code was losing the top byte of the podule vendor/device IDs.

build.sh can be persuaded to revert to GCC 6. To do this you need to set the environment:
HAVE_GCC=6

You also need to add '-a arm' to the build.sh options when building things.

These force build.sh to use gcc.old rather than gcc and to select the armv3 backend. This may make it very difficult for the acorn32 port to continue to exist as its going to require local patches to gcc to keep things going.

If we can persuade gcc7 not not generate ldrh but otherwise be armv4 it might be workable but thats way outside my skillset. :(

Mike
Index: sys/arch/arm/iomd/iomd_clock.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arm/iomd/iomd_clock.c,v
retrieving revision 1.29
diff -u -r1.29 iomd_clock.c
--- sys/arch/arm/iomd/iomd_clock.c	18 May 2012 21:09:50 -0000	1.29
+++ sys/arch/arm/iomd/iomd_clock.c	26 Mar 2019 20:17:27 -0000
@@ -142,12 +142,29 @@
 	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");
+	/* Init timecounter early */
+	tc_init(&iomd_timecounter);
+
 }
 
 
@@ -216,20 +233,21 @@
 setstatclockrate(int newhz)
 {
 	int count;
-    
-	count = TIMER_FREQUENCY / newhz;
-
-	aprint_normal("Setting statclock to %dHz (%d ticks)\n", newhz, count);
-
-	bus_space_write_1(clock_sc->sc_iot, clock_sc->sc_ioh,
-	    IOMD_T1LOW, (count >> 0) & 0xff);
-	bus_space_write_1(clock_sc->sc_iot, clock_sc->sc_ioh,
-	    IOMD_T1HIGH, (count >> 8) & 0xff);
-
-	/* reload the counter */
-
-	bus_space_write_1(clock_sc->sc_iot, clock_sc->sc_ioh,
-	    IOMD_T1GO, 0);
+	if ( newhz ) {
+		count = TIMER_FREQUENCY / newhz;
+		
+		aprint_normal("Setting statclock to %dHz (%d ticks)\n", newhz, count);
+		
+		bus_space_write_1(clock_sc->sc_iot, clock_sc->sc_ioh,
+				  IOMD_T1LOW, (count >> 0) & 0xff);
+		bus_space_write_1(clock_sc->sc_iot, clock_sc->sc_ioh,
+				  IOMD_T1HIGH, (count >> 8) & 0xff);
+		
+		/* reload the counter */
+		
+		bus_space_write_1(clock_sc->sc_iot, clock_sc->sc_ioh,
+				  IOMD_T1GO, 0);
+	}
 }
 
 
@@ -270,18 +288,6 @@
 
 	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);
 
@@ -300,7 +306,6 @@
 #ifdef DIAGNOSTIC
 	checkdelay();
 #endif
-	tc_init(&iomd_timecounter);
 }
 
 
@@ -343,28 +348,75 @@
 
 
 /*
- * 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;);
+		}
 	}
 }
 
Index: sys/arch/acorn32/conf/files.acorn32
===================================================================
RCS file: /cvsroot/src/sys/arch/acorn32/conf/files.acorn32,v
retrieving revision 1.29
diff -u -r1.29 files.acorn32
--- sys/arch/acorn32/conf/files.acorn32	17 Jan 2009 22:56:34 -0000	1.29
+++ sys/arch/acorn32/conf/files.acorn32	26 Mar 2019 20:17:27 -0000
@@ -14,6 +14,11 @@
 #
 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 @@
 # 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"
 


Home | Main Index | Thread Index | Old Index