1
0
mirror of https://github.com/wfjm/w11.git synced 2026-03-10 12:58:23 +00:00

pdp11_sequencer: BUGFIX: correct ysv flow implementation

- rtl/w11a
  - pdp11.vhd: rename, eg srv->ser; drop trap_done; add in_vecysv
  - pdp11_sequencer: renames; BUGFIX: correct ysv flow implementation
  - pdp11_vmbox.vhd: rename some rsv->ser; remove obsolete trap_done
- tools/tbench/w11a/test_w11a_cpuerr.tcl: removed, all in cpu_details.mac
- tools/tcl/rw11/defs.tcl: renames
- tools/tcode/cpu_details.mac: expand A3.3, add A3.4
This commit is contained in:
wfjm
2022-11-23 08:46:12 +01:00
parent b5189053d3
commit 40608e35fe
8 changed files with 201 additions and 288 deletions

View File

@@ -32,11 +32,18 @@ The full set of tests is only run for tagged releases.
- tools changes
- tools/bin
- tmuconv: add -t_ru06 and -t_flow
- tools/tcode
- cpu_details.mac: significantly expanded
- firmware changes
- pdp11.vhd: rename, eg srv->ser; drop trap_done; add in_vecysv
- pdp11_vmbox.vhd: rename some rsv->ser; remove obsolete trap_done
- general changes
- rename _gpr to _gr, use 'general registers' not 'general purpose registers'
### Bug Fixes
- rtl/w11a
- pdp11_sequencer: BUGFIX: use is_kstackdst1246 also in dstr flow
- pdp11_sequencer:
- BUGFIX: use is_kstackdst1246 also in dstr flow
- BUGFIX: correct ysv flow implementation
- pdp11_vmbox: BUGFIX: correct red/yellow zone boundary
<!-- --------------------------------------------------------------------- -->

View File

@@ -1,4 +1,4 @@
-- $Id: pdp11.vhd 1310 2022-10-27 16:15:50Z mueller $
-- $Id: pdp11.vhd 1320 2022-11-22 18:52:59Z mueller $
-- SPDX-License-Identifier: GPL-3.0-or-later
-- Copyright 2006-2022 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
--
@@ -11,6 +11,8 @@
--
-- Revision History:
-- Date Rev Version Comment
-- 2022-11-21 1320 1.6.16 rename some rsv->ser and cpustat_type trap_->treq_;
-- remove vm_cntl_type.trap_done; add in_vecysv;
-- 2022-10-25 1309 1.6.15 rename _gpr -> _gr
-- 2022-10-03 1301 1.6.14 add decode_stat_type.is_dstpcmode1
-- 2022-08-13 1279 1.6.13 ssr->mmr rename
@@ -352,7 +354,7 @@ package pdp11 is
constant c_cpurust_hbpt : slv4 := "0110"; -- cpu had hardware bpt
constant c_cpurust_runs : slv4 := "0111"; -- cpu running
constant c_cpurust_vecfet : slv4 := "1000"; -- vector fetch error halt
constant c_cpurust_recrsv : slv4 := "1001"; -- recursive red-stack halt
constant c_cpurust_recser : slv4 := "1001"; -- recursive stack error halt
constant c_cpurust_sfail : slv4 := "1100"; -- sequencer failure
constant c_cpurust_vfail : slv4 := "1101"; -- vmbox failure
@@ -376,11 +378,12 @@ package pdp11 is
breset : slbit; -- BRESET pulse
intack : slbit; -- INT_ACK pulse
intvect : slv9_2; -- current interrupt vector
trap_mmu : slbit; -- mmu trace trap pending
trap_ysv : slbit; -- ysv trap pending
treq_mmu : slbit; -- mmu trap requested
treq_ysv : slbit; -- ysv trap requested
prefdone : slbit; -- prefetch done
do_grwe : slbit; -- pending gr_we
do_intrsv : slbit; -- active rsv interrupt sequence
in_vecser : slbit; -- in fatal stack error vector flow
in_vecysv : slbit; -- in ysv trap flow
end record cpustat_type;
constant cpustat_init : cpustat_type := (
@@ -392,8 +395,8 @@ package pdp11 is
'0', -- waitsusp
'0','0','0','0', -- itimer,creset,breset,intack
(others=>'0'), -- intvect
'0','0','0', -- trap_(mmu|ysv), prefdone
'0','0' -- do_grwe, do_intrsv
'0','0','0', -- treq_(mmu|ysv), prefdone
'0','0','0' -- do_grwe, in_vec(ser|ysv)
);
type cpuerr_type is record -- CPU error register
@@ -415,15 +418,14 @@ package pdp11 is
bytop : slbit; -- byte operation
dspace : slbit; -- dspace operation
kstack : slbit; -- access through kernel stack
intrsv : slbit; -- active rsv interrupt sequence
vecser : slbit; -- in fatal stack error vector flow
mode : slv2; -- mode
trap_done : slbit; -- mmu trap taken (to set mmr0 bit)
end record vm_cntl_type;
constant vm_cntl_init : vm_cntl_type := (
'0','0','0','0', -- req, wacc, macc,cacc
'0','0','0', -- bytop, dspace, kstack
'0',"00",'0' -- intrsv, mode, trap_done
'0',"00" -- vecser, mode
);
type vm_stat_type is record -- virt memory status port
@@ -436,7 +438,7 @@ package pdp11 is
err_iobto : slbit; -- abort: non-existing I/O resource
err_rsv : slbit; -- abort: red stack violation
trap_ysv : slbit; -- trap: yellow stack violation
trap_mmu : slbit; -- trap: mmu trace trap
trap_mmu : slbit; -- trap: mmu trap
end record vm_stat_type;
constant vm_stat_init : vm_stat_type := (others=>'0');

View File

@@ -1,4 +1,4 @@
-- $Id: pdp11_sequencer.vhd 1316 2022-11-18 15:26:40Z mueller $
-- $Id: pdp11_sequencer.vhd 1320 2022-11-22 18:52:59Z mueller $
-- SPDX-License-Identifier: GPL-3.0-or-later
-- Copyright 2006-2022 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
--
@@ -13,6 +13,9 @@
--
-- Revision History:
-- Date Rev Version Comment
-- 2022-11-21 1320 1.6.19 rename some rsv->ser and cpustat_type trap_->treq_;
-- remove vm_cntl_type.trap_done;
-- BUGFIX: correct ysv flow implementation
-- 2022-11-18 1316 1.6.18 BUGFIX: use is_kstackdst1246 also in dstr flow
-- 2022-10-29 1312 1.6.17 rename s_int_* -> s_vec_*, s_trap_* -> s_abort_*
-- 2022-10-25 1309 1.6.16 rename _gpr -> _gr
@@ -461,11 +464,11 @@ begin
if VM_STAT.ack = '1' then
pmok := true;
if VM_STAT.trap_mmu = '1' then -- remember trap_mmu, may happen on any
pnstatus.trap_mmu := '1'; -- memory access of an instruction
pnstatus.treq_mmu := '1'; -- memory access of an instruction
end if;
if VM_STAT.trap_ysv = '1' then -- remember trap_ysv (on any access)
if R_CPUERR.ysv = '0' then -- ysv trap when cpuerr not yet set
pnstatus.trap_ysv := '1';
if VM_STAT.trap_ysv = '1' then -- remember trap_ysv (on final writes)
if R_STATUS.in_vecysv = '0' then -- trap when not in ysv vector flow
pnstatus.treq_ysv := '1';
end if;
end if;
elsif VM_STAT.err='1' or VM_STAT.fail='1' then
@@ -536,8 +539,8 @@ begin
pnmmumoni.idone := '1';
if unsigned(INT_PRI) > unsigned(PSW.pri) then
pnstate := s_idle;
elsif R_STATUS.trap_mmu='1' or pnstatus.trap_mmu='1' or
R_STATUS.trap_ysv='1' or pnstatus.trap_ysv='1' or
elsif R_STATUS.treq_mmu='1' or pnstatus.treq_mmu='1' or
R_STATUS.treq_ysv='1' or pnstatus.treq_ysv='1' or
PSW.tflag='1' then
pnstate := s_trap_disp;
elsif R_STATUS.cpugo='1' and -- running
@@ -560,8 +563,8 @@ begin
pnmmumoni.idone := '1';
if unsigned(INT_PRI) > unsigned(PSW.pri) then
pnstate := s_idle;
elsif R_STATUS.trap_mmu='1' or pnstatus.trap_mmu='1' or
R_STATUS.trap_ysv='1' or pnstatus.trap_ysv='1' or
elsif R_STATUS.treq_mmu='1' or pnstatus.treq_mmu='1' or
R_STATUS.treq_ysv='1' or pnstatus.treq_ysv='1' or
PSW.tflag='1' then
pnstate := s_trap_disp;
elsif R_STATUS.cpugo='1' and -- running
@@ -658,7 +661,7 @@ begin
nvmcntl := vm_cntl_init;
nvmcntl.dspace := '1'; -- DEFAULT
nvmcntl.mode := PSW.cmode; -- DEFAULT
nvmcntl.intrsv := R_STATUS.do_intrsv; -- DEFAULT
nvmcntl.vecser := R_STATUS.in_vecser; -- DEFAULT
ndpcntl := dpath_cntl_init;
ndpcntl.gr_asrc := SRCREG; -- DEFAULT
@@ -886,8 +889,8 @@ begin
ndpcntl.dres_sel := c_dpath_res_vmdout; -- DRES = VMDOUT
if (VM_STAT.ack or VM_STAT.err or VM_STAT.fail)='1' then
nstatus.cmdack := '1';
nstatus.trap_ysv := '0'; -- suppress traps on console
nstatus.trap_mmu := '0';
nstatus.treq_ysv := '0'; -- suppress traps on console
nstatus.treq_mmu := '0';
nstatus.cmdmerr := VM_STAT.err or VM_STAT.fail;
nstate := s_idle;
end if;
@@ -897,8 +900,8 @@ begin
nstate := s_cp_memw_w;
if (VM_STAT.ack or VM_STAT.err or VM_STAT.fail)='1' then
nstatus.cmdack := '1';
nstatus.trap_ysv := '0'; -- suppress traps on console
nstatus.trap_mmu := '0';
nstatus.treq_ysv := '0'; -- suppress traps on console
nstatus.treq_mmu := '0';
nstatus.cmdmerr := VM_STAT.err or VM_STAT.fail;
nstate := s_idle;
end if;
@@ -2157,17 +2160,17 @@ begin
do_start_vec(nstate, ndpcntl, lvector);
when s_trap_disp => -- -----------------------------------
if R_STATUS.trap_mmu = '1' then
nvmcntl.trap_done := '1'; -- mmu trap taken: set mmr0 trap bit
if R_STATUS.treq_mmu = '1' then -- mmu trap requested ?
lvector := "0101010"; -- mmu trap: vector (250)
elsif R_STATUS.trap_ysv = '1' then
elsif R_STATUS.treq_ysv = '1' then -- ysv trap requested ?
lvector := "0000001"; -- ysv trap: vector (4)
ncpuerr.ysv := '1';
nstatus.in_vecysv := '1'; -- signal start of ysv vector flow
else
lvector := "0000011"; -- trace trap: vector (14)
end if;
nstatus.trap_mmu := '0'; -- clear pending trap flags
nstatus.trap_ysv := '0'; --
nstatus.treq_mmu := '0'; -- clear trap request flags
nstatus.treq_ysv := '0'; --
do_start_vec(nstate, ndpcntl, lvector);
when s_int_ext => -- -----------------------------------
@@ -2280,7 +2283,8 @@ begin
nstate := s_vec_pushpc_w;
do_memcheck(nstate, nstatus, imemok);
if imemok then
nstatus.do_intrsv := '0'; -- signal end of rsv
nstatus.in_vecser := '0'; -- signal end of ser flow
nstatus.in_vecysv := '0'; -- signal end of ysv flow
ndpcntl.gr_we := '1'; -- load new PC
idm_pcload := '1'; -- signal flow change
do_fork_next(nstate, nstatus, nmmumoni); -- ???
@@ -2347,21 +2351,23 @@ begin
ndpcntl.gr_mode := c_psw_kmode; -- set kmode SP to 4
ndpcntl.gr_adst := c_gr_sp;
nstatus.trap_mmu :='0'; -- drop pending mmu trap
nstatus.treq_mmu := '0'; -- cancel mmu trap request
nstatus.treq_ysv := '0'; -- cancel ysv trap request
if R_VMSTAT.fail = '1' then -- vmbox failure
nstatus.cpugo := '0'; -- halt cpu
nstatus.cpurust := c_cpurust_vfail;
nstate := s_idle;
elsif R_STATUS.do_intrsv = '1' then -- double error
elsif R_STATUS.in_vecser = '1' then -- double fatal stack error
nstatus.cpugo := '0'; -- give up, HALT cpu
nstatus.cpurust := c_cpurust_recrsv;
nstatus.cpurust := c_cpurust_recser;
nstate := s_idle;
elsif R_VMSTAT.err = '1' then -- normal vm errors
if R_VMSTAT.err_rsv = '1' then
nstatus.do_intrsv := '1'; -- signal start of rsv
nstatus.in_vecser := '1'; -- signal start of ser flow
nstatus.in_vecysv := '0'; -- cancel ysv flow
ndpcntl.gr_we := '1';
if R_VMSTAT.err_odd='1' or R_VMSTAT.err_mmu='1' then

View File

@@ -1,4 +1,4 @@
-- $Id: pdp11_vmbox.vhd 1317 2022-11-19 15:33:42Z mueller $
-- $Id: pdp11_vmbox.vhd 1320 2022-11-22 18:52:59Z mueller $
-- SPDX-License-Identifier: GPL-3.0-or-later
-- Copyright 2006-2022 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
--
@@ -18,6 +18,7 @@
--
-- Revision History:
-- Date Rev Version Comment
-- 2022-11-21 1320 1.6.9 rename some rsv->ser; remove obsolete trap_done;
-- 2022-11-18 1317 1.6.8 BUGFIX: correct red/yellow zone boundary
-- 2019-06-22 1170 1.6.7 support membe for em cacc access
-- 2016-05-22 767 1.6.6 don't init N_REGS (vivado fix for fsm inference)
@@ -119,7 +120,7 @@ architecture syn of pdp11_vmbox is
kstack : slbit; -- access through kernel stack
ysv : slbit; -- yellow stack violation detected
vaok : slbit; -- virtual address valid (from MMU)
trap_mmu : slbit; -- mmu trace trap requested
trap_mmu : slbit; -- mmu trap requested
mdin : slv16; -- data input (memory order)
paddr : slv22; -- physical address register
paddr_iopage : slv9; -- iopage base (upper 9 bits of paddr)
@@ -384,7 +385,6 @@ begin
immu_cntl.cacc := VM_CNTL.cacc;
immu_cntl.dspace := VM_CNTL.dspace;
immu_cntl.mode := VM_CNTL.mode;
immu_cntl.trap_done := VM_CNTL.trap_done;
case r.state is
when s_idle => -- s_idle: wait for vm_cntl request --
@@ -409,14 +409,14 @@ begin
if VM_CNTL.wacc='1' and VM_CNTL.macc='1' then
n.state := s_fail;
elsif VM_CNTL.kstack='1' and VM_CNTL.intrsv='0' and
elsif VM_CNTL.kstack='1' and VM_CNTL.vecser='0' and
is_stackred='1' then
n.state := s_errrsv;
else
iem_mreq.req := '1';
iem_mreq.we := VM_CNTL.wacc;
if VM_CNTL.kstack='1'and VM_CNTL.intrsv='0' then
if VM_CNTL.kstack='1' and VM_CNTL.vecser='0' then
n.ysv := is_stackyellow;
end if;
n.state := s_mem_w;

View File

@@ -1,223 +0,0 @@
# $Id: test_w11a_cpuerr.tcl 1272 2022-08-07 17:37:51Z mueller $
# SPDX-License-Identifier: GPL-3.0-or-later
# Copyright 2016-2022 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
#
# Revision History:
# Date Rev Version Comment
# 2022-08-06 1272 1.0.1 ssr->mmr rename
# 2016-12-27 831 1.0 Initial version
#
# Test cpuerr register
#
# ----------------------------------------------------------------------------
rlc log "test_w11a_cpuerr: test cpuerr register"
rlc log " test basic CPUERR semantics"
$cpu ldasm -lst lst -sym sym {
.include |lib/defs_cpu.mac|
.include |lib/defs_reg70.mac|
.include |lib/defs_mmu.mac|
;
.include |lib/vec_cpucatch.mac|
;
. = 1000
stack:
start:
;
; test 001: first test that any write will clear cpuerr ----------------------
; that test also conveniently erases any pre-history
;
mov #177777,@#cpuerr ; clear cpuerr
mov #001,(r5)+ ; tag
mov @#cpuerr,(r5)+ ; val
;
; test 002: odd address abort, will set bit cp.aer ---------------------------
;
mov @#v..iit,saviit ; save old handler
mov #h.iit,@#v..iit ; setup handler
mov #t.002,r4 ; setup continuation address
mov #1,r0 ; r0 points to odd address
tst (r0) ; access
; !! will trap to 004 and set 000100 !!
halt ; blocker
t.002:
;
; test 003: clear cpuerr again (now it's really set) -------------------------
;
mov #177777,@#cpuerr ; clear cpuerr
mov #003,(r5)+ ; tag
mov @#cpuerr,(r5)+ ; val
;
; test 004: non-existent memory abort, will set bit cp.nxm -------------------
;
; The address space just below the I/O page is never accessible in the
; w11 (the 11/70 has ubmap window in this addess space).
; So setup MMU kernel I space AR(6) to point to the 8 kbyte below I/O page
; don't clear CPUERR at end of test !
;
jsr pc, mminki ; init MMU, kernel I space only
mov #177400,@#kipar+014 ; kipar(6): to page below I/O page
mov #m3.e22,@#mmr3 ; enable 22bit
mov #m0.ena,@#mmr0 ; enable MMU
;
mov #t.004,r4 ; setup continuation address
mov #140000,r0 ; r0 points to non-existent memory
tst (r0) ; access
; !! will trap to 004 and set 000040 !!
halt ; blocker
t.004: clr @#mmr0 ; disable MMU
;
; test 005: I/O bus timeout abort; will set bit cp.ito -----------------------
;
; The lowest I/O page address 160000 not occupied by a device in the w11.
; Since CPUERR wasn't cleared after previous test the error bits will
; accumulate
;
mov #t.005,r4 ; setup continuation address
mov #160000,r0 ; r0 points to non-existent device
tst (r0) ; access
; !! will trap to 004 and set 000020 !!
halt ; blocker
t.005:
;
; test 006: HALT in user mode; will set bit cp.hlt ---------------------------
;
mov #h.hlt,@#v..iit ; setup handler
mov #cp.cmu!cp.pmu,@#cp.psw ; psw: cmode=pmode=11 (user)
mov #t.006,r4 ; setup continuation address
1$: halt
br 1$ ; blocker
t.006:
; clear cpuerr again
mov #177777,@#cpuerr ; clear cpuerr
mov #006,(r5)+ ; tag
mov @#cpuerr,(r5)+ ; val
;
; test 007: yellow stack trap; will set bit cp.ysv ---------------------------
;
mov #h.iit,@#v..iit ; setup handler
mov #t.007,r4 ; setup continuation address
mov #000400,sp ; set stack into 'yellow' zone
clr -(sp) ; and push to stack
; push will be done plus a trap !
t.007:
;
; test 010: 2nd yellow stack trap with CPUERR set should *not* trap ----------
;
mov saviit,@#v..iit ; restore blocker handler
clr -(sp) ; and push to stack
; push will be done and no trap !
mov #010,(r5)+ ; tag
mov sp,(r5)+ ; val
; clear cpuerr again
mov #177777,@#cpuerr ; clear cpuerr
mov #010,(r5)+ ; tag
mov @#cpuerr,(r5)+ ; val
;
; test 011: red stack trap from odd stack; will set bit cp.aer and cp.rsv ----
;
mov #h.rsv,@#v..iit ; setup handler (will also reset stack)
mov #t.011,r4 ; setup continuation address
mov #001001,sp ; set stack odd kernel stack
clr -(sp) ; and push to stack
; cause 'red stack' and set SP=004
t.011:
; clear cpuerr again
mov #177777,@#cpuerr ; clear cpuerr
mov #011,(r5)+ ; tag
mov @#cpuerr,(r5)+ ; val
;
; end of tests ---------------------------------------------------------------
;
halt
stop:
;
h.iit: mov r4,(r5)+ ; tag
mov @#cpuerr,(r5)+ ; val
mov r4,(sp) ; set return PC
rti
;
h.hlt: mov r4,(r5)+ ; tag
mov @#cpuerr,(r5)+ ; val
mov r4,(sp) ; set return PC
clr 2(sp) ; set return PS (kernel mode again)
rti
;
h.rsv: mov r4,(r5)+ ; tag
mov @#cpuerr,(r5)+ ; val
mov #1000,sp ; reset stack
clr -(sp) ; PS = kernel mode
mov r4,-(sp) ; PC = continuation address
rti
;
saviit: .word 0
data: .blkw 12.*2.
.word 177777
;
; support procedures
;
.include |lib/mminki.mac|
}
# puts $lst
# parray sym
# code register pre/post conditions beyond defaults
# r5 #data -> #data+12*2*2
rw11::asmrun $cpu sym r5 $sym(data)
rw11::asmwait $cpu sym
rw11::asmtreg $cpu r1 0 \
r2 0 \
r3 0 \
r5 [expr {$sym(data) + 12*2*2}] \
sp $sym(stack)
# data: tag val pairs
rw11::asmtmem $cpu $sym(data) \
[list 001 0000000 \
$sym(t.002) [regbld rw11::CPUERR adderr] \
003 0000000 \
$sym(t.004) [regbld rw11::CPUERR nxm] \
$sym(t.005) [regbld rw11::CPUERR nxm iobto] \
$sym(t.006) 0000260 \
006 0000000 \
$sym(t.007) [regbld rw11::CPUERR ysv] \
010 0000374 \
010 0000000 \
$sym(t.011) [regbld rw11::CPUERR adderr rsv] \
011 0000000 \
0177777 ]
# ----------------------------------------------------------------------------
rlc log " test basic CPUERR reset via creset"
# use minmal code to set CPUERR: odd address abort against vector catcher
$cpu ldasm -lst lst -sym sym {
. = 000004
v..iit: .word v..iit+2 ; vec 4
.word 0
stop:
;
. = 1000
stack:
start:
;
mov #1,r0 ; r0 points to odd address
tst (r0) ; access
}
rw11::asmrun $cpu sym
rw11::asmwait $cpu sym
rw11::asmtreg $cpu r1 0 \
r2 0 \
r3 0 \
r5 0 \
sp [expr $sym(stack) - 4]
# now test whether creset clears CPUERR
rw11::asmtmem $cpu $rw11::A_CPUERR [regbld rw11::CPUERR adderr]
cpu0 cp -creset
rw11::asmtmem $cpu $rw11::A_CPUERR 0

View File

@@ -1,4 +1,4 @@
# $Id: w11a_all.dat 1254 2022-07-13 06:16:19Z mueller $
# $Id: w11a_all.dat 1320 2022-11-22 18:52:59Z mueller $
#
## steering file for all w11a tests
#
@@ -14,5 +14,3 @@ test_w11a_dsta_flow.tcl
test_w11a_inst_quick.tcl
test_w11a_inst_traps.tcl
#
test_w11a_cpuerr.tcl
#

View File

@@ -1,9 +1,10 @@
# $Id: defs.tcl 1294 2022-09-07 14:21:20Z mueller $
# $Id: defs.tcl 1320 2022-11-22 18:52:59Z mueller $
# SPDX-License-Identifier: GPL-3.0-or-later
# Copyright 2014-2022 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
#
# Revision History:
# Date Rev Version Comment
# 2022-11-21 1320 1.0.11 rename RUST recrsv -> recser
# 2022-09-03 1292 1.0.10 shorter field names for MMR0,MMR1
# 2022-08-07 1273 1.0.9 ssr->mmr rename
# 2019-04-24 1138 1.0.8 add RCSR defs for KW11-L and KW11-P
@@ -32,7 +33,7 @@ namespace eval rw11 {
regdsc CP_CNTL {func 3 0}
regdsc CP_STAT {suspext 9} {suspint 8} \
{rust 7 4 "s:init:halt:reset:stop:step:susp:hbpt:runs:vecfet:recrsv:s1010:s1011:sfail:vfail:s1110:s1111"} \
{rust 7 4 "s:init:halt:reset:stop:step:susp:hbpt:runs:vecfet:recser:s1010:s1011:sfail:vfail:s1110:s1111"} \
{susp 3} {go 2} {merr 1} {err 0}
variable RUST_INIT [bvi b4 "0000"]
variable RUST_HALT [bvi b4 "0001"]
@@ -43,7 +44,7 @@ namespace eval rw11 {
variable RUST_HBPT [bvi b4 "0110"]
variable RUST_RUNS [bvi b4 "0111"]
variable RUST_VECFET [bvi b4 "1000"]
variable RUST_RECRSV [bvi b4 "1001"]
variable RUST_RECSER [bvi b4 "1001"]
variable RUST_SFAIL [bvi b4 "1100"]
variable RUST_VFAIL [bvi b4 "1101"]

View File

@@ -1,10 +1,10 @@
; $Id: cpu_details.mac 1317 2022-11-19 15:33:42Z mueller $
; $Id: cpu_details.mac 1320 2022-11-22 18:52:59Z mueller $
; SPDX-License-Identifier: GPL-3.0-or-later
; Copyright 2022- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
;
; Revision History:
; Date Rev Version Comment
; 2022-11-18 1316 1.0 Initial version
; 2022-11-22 1320 1.0 Initial version
; 2022-07-18 1259 0.1 First draft
;
; Test CPU details
@@ -76,7 +76,7 @@
pi.n06=6*042 ; lsb for pir 6 next
pi.n07=7*042 ; lsb for pir 7 next
;
ta0101: mov #1000$,v..pir ; setup handler
ta0101: mov #1000$,v..pir ; set up handler
mov #cp.pr7,v..pir+2 ; which runs at pr7
mov #cp.pir,r3 ; ptr to PIRQ
mov #cp.psw,r4 ; ptr to PSW
@@ -444,8 +444,7 @@ ta0302:
200$: halt
halt
;
1000$: clr cp.err ; HACK: clear CPUERR !!!
tst sp ; red abort seen ?
1000$: tst sp ; red abort seen ?
beq 1010$ ; if yes, check status
inc r2 ; if no, got for next push
rti
@@ -525,10 +524,13 @@ ta0302:
;
9999$: iot ; end of test A3.2
;
; Test A3.3 -- stack trap address modes ++++++++++++++++++++++++++++++
; Test A3.3 -- stack trap conditions +++++++++++++++++++++++++++++++++
; Verifies that mode 1,2,4,6 trap for dstw flows and dstr when rmw
; Verifies that mode 3,5,7 writes do not trap
; Verifies that mode 1-7 reads do not trap
; Verifies that implict pushes (JSR,MFPI) trap
; Verifies that vector push of trap instructions (EMT,TRAP tested) traps
; Verifies that vector push of an interrupt (PIRQ tested) traps
; Notes:
; - dstw (mov,clr,..) and dstr (add,bis,...) flows write to stack -> test both
; - inspired by eqkce0 test 041 that verifies do/dont trap instruction cases
@@ -538,17 +540,18 @@ ta0303: tstb systyp ; skip if not on w11
bge 100$
jmp 9999$
;
100$: mov #1000$,v..iit ; set up iit handler
100$: mov #1400,cp.slr ; set yellow limit to 1776
;
; part 1: test instructions that should trap -------------------------
;
mov #1000$,v..iit ; set up iit handler
clr v..iit+2
mov #1100$,v..emt ; set up emt handler
clr v..emt+2
mov #1200$,v..trp ; set up trap handler
clr v..trp+2
mov #1400,cp.slr ; set yellow limit to 1776
clr r2 ; clear trap counter
;
; part 1: test instructions that should trap -------------------------
;
; dstw mode 1,2,4,6
mov #1000,-(sp) ; dstw mode 4: SP now 1776 (1)
clr -(sp) ; dstw mode 4: SP now 1774 (2)
@@ -571,8 +574,7 @@ ta0303: tstb systyp ; skip if not on w11
;
br 1500$
;
1000$: clr cp.err ; HACK: clear CPUERR !!!
htstne sp ; no red stack aborts expected
1000$: htstne sp ; no red stack aborts expected
inc r2
rti
;
@@ -587,7 +589,7 @@ ta0303: tstb systyp ; skip if not on w11
;
; part 2: test instructions that should not trap ---------------------
;
mov #stack-2,r2 ; in yellow zone
2000$: mov #stack-2,r2 ; in yellow zone
mov r2,(r2) ; load on stack (not using SP)
mov r2,sp ; SP in yellow zone
; dstw mode 3,5,7
@@ -611,11 +613,130 @@ ta0303: tstb systyp ; skip if not on w11
clr sp
mov @#2000,2000(sp) ; SP=0, EA=2000 -> no trap
;
; part 3: test that interrupt (from PIRQ) vector push traps ----------
; Triggers 3 PIRQ interrupts at PR1, PR3, and PR6.
; The PIRQ interrupt vector push will issue a ysv trap.
; That trap executes before the first instruction of the pir handler.
; The iit handler must therefore execute at PR7 to lockout interrupts.
; When the iit handler returns, the pir hander will execute.
;
3000$: mov #3100$,v..iit ; set up iit handler
mov #cp.pr7,v..iit+2 ; lockout interrupts !
mov #3200$,v..pir ; set up pir handler
mov #cp.pr7,v..pir+2 ; lockout interrupts
mov #stack,sp ; SP to default (STKLIM still 1400)
clr r2 ; clear trap counter
mov #cp.pir,r3 ; ptr to cp.pir
mov #3500$,r5 ; ptr to probe data
;
spl 0
movb #bit06!bit03!bit01,1(r3) ; request PIRQ 6+3+1
nop
br 3900$
;
; iit handler
3100$: htstne sp ; no red stack aborts expected
hcmpeq #177777,(r5)+ ; check state
inc r2
rti
;
; pir handler
3200$: mov (r3),r0 ; get PIRQ
bic #177761,r0 ; mask out index bits (is pri*2)
asr r0 ; now pri*1
hcmpeq r0,(r5)+ ; check state
mov #pi.r00,r1
ash r0,r1 ; pi.r00 <<(pri)
bic r1,(r3) ; clear PIRQ request
rti
;
; state check data
3500$: .word 177777,6. ; iit marker + pr6 pirq
.word 177777,3. ; iit marker + pr3 pirq
.word 177777,1. ; iit marker + pr1 pirq
;
3900$: hcmpeq #3.,r2 ; all traps taken ?
mov #v..iit+2,v..iit ; v..iit to catcher
clr v..iit+2
mov #v..pir+2,v..pir ; v..pir to catcher
clr v..pir+2
;
; final cleanup
clr cp.slr ; STKLIM to default
mov #stack,sp ; SP to default
;
9999$: iot ; end of test A3.3
;
; Test A3.4 -- red stack abort conditions ++++++++++++++++++++++++++++
; Verifies that instruction writes abort
; Verifies that implict pushes (JSR,MFPI) abort
; Verifies that vector push after trap instructions and interrupts abort
; Abort on 1st and 2nd push is tested.
;
ta0304:
mov #1000$,v..iit ; set up iit handler
mov #cp.pr7,v..iit+2 ; lockout interrupts !
mov #1400,cp.slr ; yellow <=1776 and red <= 1736
clr @#1736 ; ensure top red word zero
clr cp.err ; clear CPUERR
;
; dstw flow
mov #1740,sp ; SP at red border
mov #100$,r5
mov #123456,-(sp)
halt
;
; dstr flow (rmw)
100$: mov #200$,r5
add (sp),-(sp)
halt
;
; implicit push instructions
200$: mov #300$,r5
jsr pc,210$
halt
210$: halt
;
300$: mov #400$,r5
mfpi r0
halt
;
; vector flow abort in 2nd push, 1st push in yellow (use EMT for test)
; Note: SimH scribbles into red zone, therefore test skipped for SimH
400$: cmpb systyp,#sy.sih ; skip section on SimH
beq 500$
mov sp,r0
mov #123456,(r0)+ ; write marker to 1740, r0 to avoid ysv
mov r0,sp ; SP now 1402 -> abort on 2nd push
mov #cp.pr3,cp.psw ; set pr3 as marker
mov #420$,r5 ; leaves NZVC = 0000
emt 100
410$: halt
420$: hcmpeq #cp.pr3,@#1740 ; check that PS written
;
; vector flow abort in 1st push (use PIRQ for test)
500$: spl 0
mov #600$,r5
mov #pi.r04,cp.pir ; request PIRQ 4
halt
600$: clr cp.pir
br 9000$
;
1000$: htsteq sp ; check SP=0
htsteq @#1736 ; check stack clean
hcmpeq #cp.rsv,cp.err ; check CPUERR.rsv (and no ysv)
clr cp.err ; clear CPUERR
mov #1740,sp ; restore SP
jmp (r5) ; continue
;
9000$: clr cp.slr ; STKLIM to default
mov #v..iit+2,v..iit ; v..iit to catcher
clr v..iit+2
mov #stack,sp ; SP to default
spl 0 ; back to PR0
;
9999$: iot ; end of test A3.4
;
; Section B: Stress tests ====================================================
;
; Test B1: address mode torture tests +++++++++++++++++++++++++++++++++++++++
@@ -826,21 +947,22 @@ tc0103: mov #vhugen,v..iit ; set iit handler
; END OF ALL TESTS - loop closure ============================================
;
mov tstno,r0 ; hack, for easy monitoring ...
hcmpeq tstno,#22. ; all tests done ?
hcmpeq tstno,#23. ; all tests done ?
;
jmp loop
;
; kernel handlers ============================================================
;
; vhugen - generic handler for expected traps/abort ++++++++++++++++++++++++++
; the kernel continution address must be written to vhustp
; the continution address must be written to vhustp
; execution will reset vhustp to a catcher value
; --> vhustp must be set for each execution
;
vhugen: tst (sp)+ ; discard one word of vector push
mov vhustp,(sp) ; set up kernel return address
vhugen: add #4,sp ; discard vector frame
mov vhustp,100$ ; set up return address
mov #vhuhlt,vhustp ; reset stop address by catcher
rts pc ; end return to continuation address
jmp @100$ ; end return to continuation address
100$: .word 0
vhustp: .word vhuhlt
vhuhlt: halt
;