SIMH V3.7-0 patch for 32V, 3BSD and 4.0BSD

This patch consists of mutually independent three parts.

1) PDP11/pdp11_rp.c

UNIX boot program you have to key in from the console just sets up
registers for DMA data access and do not loop-wait for its completion.
This code fails to complete DMA I/O under simh, because the whole simh
stops when the CPU stops. I made it work by
tape/disk-DMA-I/O's-are-immediately-done solution. This may cause some
odd timing problem. 

For TE16 we need no patch. Just set the time register to 0:
d tu time 0

For RP06 we have two registers stime and rtime, which cannot be set to
zero, so I patched the code to make it enabled to be set to zero. Now
we can do the following:
d rp stime 0
d rp rtime 0

We need these kluges only when you boot by the key-in boot programs.

To achieve proper solution SIMH's event model should be changed to
process no-residential event after the CPU stops. 

2) PDP11/pdp11_tu.c

The tdcopy (tape-to-disk copy) fails.

From "TM03 Magnetic Tape Formatter Technical Manual", EK-0TM03-TM-002,
Table 2-4 Error Register Bit Indicators:
>Bit Position: 09
>Name: Frame Count Error (FCE)
>Description: Indicates that a space operation has terminated and the
>frame counter is not cleared. Also asserted when the Massbus
>controller fails to negate RUN when the TM03 asserts EBL.

Semantically, the word "and" in the middle of the first sentence
should mean not enumeration but logical restriction. 

3) VAX/vax780_defs.h, vax_cpu1.c, vax_mmu.c and vaxmod_defs.h

This part needs rather lengthy explanation.

Under simh version 3.7-0 without this patch 32V generates a trap
during boot. 

>VAX780 simulator V3.7-0
>Command not allowed
>TU: creating new file
>
>HALT instruction, PC: 00030037 (HALT)
>
>file : unix
>
>
>
>
>TRAP FROM KERNAL MODE
>
>
>HALT instruction, PC: 8000043B (HALT)

(Of cource "Kernal" is a 32V specific missspelling of "Kernel". It is
quite interesting that Commodore's "KERNAL" OS is named after the same
kind of misspelling.)

I could easily locate the source of this trap in
/usr/src/sys/sys/locore.s:
>start:
>        .word   0x0000
>        mtpr    $HIGH,$IPL              # no interrupts yet
>        mtpr    $Scbbase,$SCBB  # set SCBB
>        mtpr    $_Sysmap,$SBR   # set SBR
>        mtpr    $Syssize,$SLR   # set SLR
>        mtpr    $_Sysmap,$P0BR  # set temp P0BR
>        mtpr    $Syssize,$P0LR  # set temp P0LR

Scbbase is 0x80000000 and _Sysmap is 0x8000b76c. Moving these values
to SCBB or SBR causes SIMH generate Reserved Operand Fault. Hmm, I
tried some investigation, and shortly found the answer from "VAX
Architecture Reference Manual", chapter 8 "Privileged Registers",
section "MTPR Move To Processor Register":
>Notes:
>3. The operation of the processor is UNDEFINED after execution of MTPR
>to a read-only register, MTPR to a nonexistent register, MTPR of a
>non-zero value to an MBZ field, or MTPR of a reserved value to a
>register. The preferred implementation is to cause reserved-operand
>fault.

So SIMH conforms "the preferred implementation", but VAX-11/780
certainly did not.  I first simply masked bit 31 and the 32V kernel
now smoothly started. But things were not so easy. When I tried to see
processes, another trap occured and the system stopped. 

>VAX780 simulator V3.7-0
>
>HALT instruction, PC: 00030037 (HALT)
>
>file : unix
>
>RESTRICTED RIGHTS
>USE, DUPLICATION OR DISCLOSURE IS
>SUBJECT TO RESTRICTION STATED IN YOUR
>CONTRACT WITH WESTERN ELECTRIC COMPANY INC.
>
>real mem  = 8323072
>Warning: more page-frames than allocated in bit map
>   Only 2048 of 16256 used. (Increase PHYSPAGES)
>avail mem = 939008
># ps
>
>
>
>TRAP FROM KERNAL MODE
>
>
>HALT instruction, PC: 8000043B (HALT)

I traced to find that the source of the trap is once in function
kernacc of locore.s. Kernacc checks whether the user has a permission
to access a data region by accessing PTEs explicitly. In this case, ps
wants to access the process structure located in kernel memory.

>_kernacc:
>        .word   0x0000
>
>        movl    4(ap),r0        # virtual address
>        bbcc    $31,r0,kacc1
>        mfpr    $SBR,r2 # address and length of page table (system)
>        mfpr    $SLR,r3
(snip)
>	movl	(r2)[r0],r1

SBR is 0x0000b76c and it is the physical address of the beginning of
the system page table. But kernacc accesses virtual address
0x00000b76c to cause a trap. Correct virtual address of the beginning
of the system page table is 0x80000b76c. Another inspection is
required. I found in "VAX11/780 HARDWARE HANDBOOK 1979-80" that bits
31, 30, 1 and 0 of SBR are MBZ (p. 110) and bits 31, 10 and 8 to 0 of
SCBB Register are MBZ (p. 88). MBZ is "must be zero", so these bits
must be zero, which cause a trap.

There are two hypotheses which can lead to this situation under an
assumption that the system works deterministically i.e. we do not have
to poke our nose into hairy quantum dynamics.

Hypothesis alpha)

Bit 31 of SBR is fixed to one. Writing to it does not change its
value. Reading it returns always one. Anyway the system ignores bit
31.

Hypothesis beta)

Bit 31 of SBR is not fixed. Writing to bit 31 changes its value, and
reading it returns the written value.

Anyway the system ignores bit 31 during address translation. I have no
counter evidence against hyposesis alpha but its too unnatural, so I
implemented hyposesis beta. 

A 4.2 BSD kernel which worked in VAX-11/750 (comet) as well as
VAX-11/780 maskes bit 31 of Scbbase (now renamed to _scb) and _Sysmap
and sets bit 31 in kernacc. The SCCS log of locore.s for this change
has a comment "comet changes", which suggests that later versions of
VAX did not have this idiosyncrasy.

Thus I removed two ML_PA_TEST's from vax_cpu1.c and there remains only
one for PCBB. Since locore.s for 32V and later moves a value with bit
31 cleared to PCBB, I could remove it but I did not have to. For
simplicity, I might better remove it, but the real world tends to be
ridiculously complicated. 

I am now tackling 780 microcode to make clear how these mechanism
worked actually. 

nao at tom phyphen yam dot or dot jp

diff -ur simh.orig/PDP11/pdp11_rp.c simh/PDP11/pdp11_rp.c
--- simh.orig/PDP11/pdp11_rp.c	Fri Dec 29 11:04:10 2006
+++ simh/PDP11/pdp11_rp.c	Sun Apr  8 21:22:55 2007
@@ -415,8 +415,8 @@
     { BRDATA (EC2, rpec2, DEV_RDX, 16, RP_NUMDR) },
     { BRDATA (MR, rpmr, DEV_RDX, 16, RP_NUMDR) },
     { BRDATA (MR2, rmmr2, DEV_RDX, 16, RP_NUMDR) },
-    { DRDATA (STIME, rp_swait, 24), REG_NZ + PV_LEFT },
-    { DRDATA (RTIME, rp_rwait, 24), REG_NZ + PV_LEFT },
+    { DRDATA (STIME, rp_swait, 24), PV_LEFT },
+    { DRDATA (RTIME, rp_rwait, 24), PV_LEFT },
     { URDATA (CAPAC, rp_unit[0].capac, 10, T_ADDR_W, 0,
               RP_NUMDR, PV_LEFT | REG_HRO) },
     { FLDATA (STOP_IOE, rp_stopioe, 0) },
diff -ur simh.orig/PDP11/pdp11_tu.c simh/PDP11/pdp11_tu.c
--- simh.orig/PDP11/pdp11_tu.c	Fri Dec 29 11:16:38 2006
+++ simh/PDP11/pdp11_tu.c	Sun Apr  8 21:22:55 2007
@@ -826,7 +826,6 @@
 
     case MTSE_TMK:                                      /* end of file */
         tufs = tufs | FS_TMK;
-        tu_set_er (ER_FCE);                             /* also sets FCE */
         break;
 
     case MTSE_IOERR:                                    /* IO error */
diff -ur simh.orig/VAX/vax_cpu1.c simh/VAX/vax_cpu1.c
--- simh.orig/VAX/vax_cpu1.c	Fri Oct 27 15:47:56 2006
+++ simh/VAX/vax_cpu1.c	Sun Apr  8 21:24:49 2007
@@ -1415,7 +1415,6 @@
         break;
 
     case MT_SBR:                                        /* SBR */
-        ML_PA_TEST (val);                               /* validate */
         SBR = val & BR_MASK;                            /* lw aligned */
         zap_tb (1);                                     /* clr entire TLB */
         set_map_reg ();
@@ -1429,7 +1428,6 @@
         break;
 
     case MT_SCBB:                                       /* SCBB */
-        ML_PA_TEST (val);                               /* validate */
         SCBB = val & BR_MASK;                           /* lw aligned */
         break;
 
diff -ur simh.orig/VAX/vax_mmu.c simh/VAX/vax_mmu.c
--- simh.orig/VAX/vax_mmu.c	Wed May 10 12:42:40 2006
+++ simh/VAX/vax_mmu.c	Sun Apr  8 21:22:55 2007
@@ -501,7 +501,7 @@
 {
 d_p0br = P0BR & ~03;
 d_p1br = (P1BR - 0x800000) & ~03;                       /* VA<30> >> 7 */
-d_sbr = (SBR - 0x1000000) & ~03;                        /* VA<31> >> 7 */
+d_sbr = ((SBR & PAMASK) - 0x1000000) & ~03;                        /* VA<31> >> 7 */
 d_p0lr = (P0LR << 2);
 d_p1lr = (P1LR << 2) + 0x800000;                        /* VA<30> >> 7 */
 d_slr = (SLR << 2) + 0x1000000;                         /* VA<31> >> 7 */
