SIMH/Vax versus OpenBSD 3.3
This article is obsolete, there’s a much simpler solution involving a parameter in the SIMH config file.
Can somebody shed some light on how to get OpenBSD 3.3/vax to run flawlessly on simh? The initial install to disk goes well according to the Vax installation instructions, but the (generic) kernel that boots off the disk can’t mount the root filesystem. Since this problem can be worked around by debugging output in the kernel, it’s almost certainly an issue of a lost interrupt due to emulation timing issues. See below for details.
I’m using the following simh config file:
load -r ka655.bin ; system disk set rq0 ra92 at rq0 ra0.disk ; boot floppy ;set rq1 floppy at rq1 floppy33.fs ; distribution on "CDROM" set rq2 cdrom at rq2 vax.iso ; qe0 set xq mac=08-00-2B-C0-01-EE at xq0 eth0
After booting off the floppy (">>> boot dua1:") and following the installation instructions, OpenBSD installs to rq0. When booting off this disk, the kernel drops into the debugger because it can’t mount the root filesystem. To get a working OpenBSD system, it’s possible to boot off the floppy again, mount the very filesystems, and chroot.
# mount /dev/ra0a /mnt # mount /dev/ra0d /mnt/usr # cd /mnt # ./usr/sbin/chroot /mnt # swapon /dev/ra0b
Please note that when booting off the floppy, there are no problems whatsoever in accessing ra0 (rq0). After recompiling the Vax generic kernel, it
becomes apparent that the kernel fails is arch/vax/mscp/mscp_disk.c, rx_putonline().
/*
* (Try to) put the drive online. This is done the first time the
* drive is opened, or if it har fallen offline.
*/
int
rx_putonline(rx)
struct rx_softc *rx;
{
struct mscp *mp;
struct mscp_softc *mi = (struct mscp_softc *)rx->ra_dev.dv_parent;
volatile int i;
printf("DEBUG: Entered rx_putonline\n");
rx->ra_state = DK_CLOSED;
mp = mscp_getcp(mi, MSCP_WAIT);
mp->mscp_opcode = M_OP_ONLINE;
mp->mscp_unit = rx->ra_hwunit;
mp->mscp_cmdref = 1;
*mp->mscp_addr |= MSCP_OWN | MSCP_INT;
/* Poll away */
i = bus_space_read_2(mi->mi_iot, mi->mi_iph, 0);
if (tsleep(&rx->ra_dev.dv_unit, PRIBIO, "rxonline", 100*100))
rx->ra_state = DK_CLOSED;
if (rx->ra_state == DK_CLOSED)
return MSCP_FAILED;
return MSCP_DONE;
}
Without the debug printf highlighted in red, the process times out on tsleep(). However, the interrupt handler calls rronline() in the same source file. With the debug statement, however, the kernel will boot at the price of a nuisance message on the console. All of this hints at an emulation timing issue; either the interrupt is delivered before the driver enters tsleep() or the timeout
isn’t long enough.
I haven’t had success in tuning simh’s emulation parameters (rq_delay) to solve this issue. When comparing the drivers with 4.3BSD, it is also apparent that the 4.3BSD code is much more conservative about putting disk units online. Specifically, the code in vaxuba/uda.c actively polls the return status to be updated by the interrupt handler.
In summary, I’d like to hear if others experience the same problem or not. It’s not clear to me whether it is more appropriate to fix simh or OpenBSD.
