Subject: Serious [T]MSCP on UNIBUS system bug (+fix) Index: sys/pdp/machdep2.c 2.11BSD Description: There is a serious (fatal) bug in the allocation of the out of kernel [T]MSCP command packet arena on UNIBUS systems. Q-bus systems (11/53,73,83,93) do not suffer from the consequences of this bug, but UNIBUS (11/44,70,84) systems will crash when a TMSCP or MSCP driver is present in the kernel. Repeat-By: You really don't want to. Best to simply examine machdep2.c. Fix: The patch below will fix the bug. The problem was that a UMR was being allocated to map the [T]MSCP command packet arena before ubinit() has been called to initialize the UMR map structure. This patch leaves the memory allocation where it was, the UMR allocation is moved to the end of the ubinit() routine just after the UMRs have been free()'d into the UMR map structure. -------------------------------------------------------------------------- *** /sys/pdp/machdep2.c.old Thu Jun 6 01:50:37 1991 --- /sys/pdp/machdep2.c Sun Nov 17 12:20:10 1991 *************** *** 181,213 **** #if NRAC > 0 || NTMSCP > 0 { - register int s, first; - register struct ubmap *ubp; - long paddr; - if ((_iobase = malloc(coremap, btoc(_iosize))) == 0) panic("_iobase"); maxmem -= btoc(_iosize); - #ifdef UNIBUS_MAP - if (ubmap) { - _iostart = _iobase; - s = (int)btoub(_iosize); - /* - * this early in the system's life there had better be a UMR or two - * available!! - */ - first = malloc(ub_map, s); - _ioumr = (ubadr_t)first << 13; - ubp = &UBMAP[first]; - paddr = ctob((ubadr_t)_iostart); - while (s--) { - ubp->ub_lo = loint(paddr); - ubp->ub_hi = hiint(paddr); - ubp++; - paddr += (ubadr_t)UBPAGE; - } - } - #endif UNIBUS_MAP } #endif NRAC --- 181,189 ---- *************** *** 325,336 **** /* * Re-initialize the Unibus map registers to statically map * the clists and buffers. Free the remaining registers for ! * physical I/O. */ ubinit() { register int i, ub_nreg; long paddr; if (!ubmap) return; --- 301,313 ---- /* * Re-initialize the Unibus map registers to statically map * the clists and buffers. Free the remaining registers for ! * physical I/O. At this time the [T]MSCP arena is also mapped. */ ubinit() { register int i, ub_nreg; long paddr; + register struct ubmap *ubp; if (!ubmap) return; *************** *** 363,370 **** #else mfree(ub_map, 31 - ub_nreg - 1, 1 + ub_nreg); #endif } ! #endif int waittime = -1; --- 340,368 ---- #else mfree(ub_map, 31 - ub_nreg - 1, 1 + ub_nreg); #endif + + /* + * this early in the system's life there had better be a UMR or two + * available!! N.B. This was moved from where the [T]MSCP memory was + * allocated because at that point the UMR map was not initialized. + */ + + #if NRAC > 0 || NTMSCP > 0 + _iostart = _iobase; + i = (int)btoub(_iosize); + ub_nreg = malloc(ub_map, i); + _ioumr = (ubadr_t)ub_nreg << 13; + ubp = &UBMAP[ub_nreg]; + paddr = ctob((ubadr_t)_iostart); + while (i--) { + ubp->ub_lo = loint(paddr); + ubp->ub_hi = hiint(paddr); + ubp++; + paddr += (ubadr_t)UBPAGE; + } + #endif NRAC } ! #endif UNIBUS_MAP int waittime = -1;