From 3318f99276ff1dc93c5bf2e0992576f0b92dfeef Mon Sep 17 00:00:00 2001 From: wfjm Date: Wed, 11 Jan 2023 17:31:21 +0100 Subject: [PATCH] BUGFIX: handle CPUERR.rsv correctly - rtl/w11a - pdp11.vhd: vm_stat_type: add err_ser - pdp11_sequencer.vhd: BUGFIX: handle CPUERR.rsv correctly - pdp11_vmbox.vhd: use err_ser to indicate fatal stack error - tools/tcode/cpu_details.mac: update A2.7-10 --- doc/CHANGELOG.md | 2 + doc/ECO-040-cpuerr_rsv.md | 58 +++++++++++++++++++++++++ doc/simh_diff_cpuerr_rsv.md | 27 ++++++++++++ doc/simh_diff_summary.md | 1 + rtl/sys_gen/w11a/cmoda7/sys_w11a_c7.vhd | 3 +- rtl/w11a/pdp11.vhd | 4 +- rtl/w11a/pdp11_sequencer.vhd | 10 +++-- rtl/w11a/pdp11_vmbox.vhd | 14 +++--- tools/tcode/cpu_details.mac | 12 ++--- 9 files changed, 113 insertions(+), 18 deletions(-) create mode 100644 doc/ECO-040-cpuerr_rsv.md create mode 100644 doc/simh_diff_cpuerr_rsv.md diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 28f091a2..ed6daf59 100644 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -82,6 +82,8 @@ The full set of tests is only run for tagged releases. [ECO-036](ECO-036-vpush_abort_ps.md) - BUGFIX: cc state unchanged after abort, see [ECO-039](ECO-039-cc_and_aborts.md) + - BUGFIX: handle CPUERR.rsv correctly, see + [ECO-040](ECO-040-cpuerr_rsv.md) - pdp11_vmbox: - BUGFIX: correct red/yellow zone boundary, see [ECO-035](ECO-035-stklim-tbit-fixes.md) diff --git a/doc/ECO-040-cpuerr_rsv.md b/doc/ECO-040-cpuerr_rsv.md new file mode 100644 index 00000000..b750cef4 --- /dev/null +++ b/doc/ECO-040-cpuerr_rsv.md @@ -0,0 +1,58 @@ +# ECO-040: fix CPUERR register rsv flag behavior (2023-01-11) + +### Scope +- was in w11a since 2008 +- affects: all w11a systems + +### Background +The `CPUERR` register in an 11/70 has 6 flags that allow the cause of vector 4 +abort to be determined. The bit 2 is referred to as _'Red Zone Stack Limit'_ +in the 11/70 documentation. It is set when a stack limit error is detected. +Other address errors that escalate to a fatal stack error do not set this bit. +That leads to the `CPUERR` settings: + +| Condition | `hlt` | `odd` | `nxm` | `ito` | `ysv` | `rsv` | +| :-------------------- | :---: | :---: | :---: | :---: | :---: | :---: | +| odd address on kstack | 0 | 1 | 0 | 0 | 0 | 0 | +| nxm abort on kstack | 0 | 0 | 1 | 0 | 0 | 0 | +| ito abort on kstack | 0 | 0 | 0 | 1 | 0 | 0 | +| MMU abort on kstack | 0 | 0 | 0 | 0 | 0 | 0 | +| yellow zone trap | 0 | 0 | 0 | 0 | 1 | 0 | +| red zone abort | 0 | 0 | 0 | 0 | 0 | 1 | + +The `CPUERR` register in the J11 has the same function, bit 2 has the very +similar name _'Red Stack Trap'_, and is set whenever a fatal stack error is +detected, and thus also when other address errors escalate to a fatal stack +error. That leads to different `CPUERR` settings: + +| Condition | `hlt` | `odd` | `nxm` | `ito` | `ysv` | `rsv` | +| :-------------------- | :---: | :---: | :---: | :---: | :---: | :---: | +| odd address on kstack | 0 | 1 | 0 | 0 | 0 | 1 | +| nxm abort on kstack | 0 | 0 | 1 | 0 | 0 | 1 | +| ito abort on kstack | 0 | 0 | 0 | 1 | 0 | 1 | +| MMU abort on kstack | 0 | 0 | 0 | 0 | 0 | 1 | +| yellow zone trap | 0 | 0 | 0 | 0 | 1 | 0 | +| red zone abort | 0 | 0 | 0 | 0 | 0 | 1 | + +The key differences are: +- on an 11/70, an escalated MMU kernel stack abort will not set any + `CPUERR` bits. +- on a J11, every stack error that causes an emergency stack will set the + `rsv` bit. + +### Symptom summary +The w11 implementation followed the SimH implementation that implements the +J11 behavior. This was discovered in a code review, no xxdp tests verify +`CPUERR` response in these cases. + +### Analysis +None. + +### Fixes +- add an additional return flag `err_ser` to `vm_stat_type` +- set `err_ser` in `pdp11_vmbox` for all fatal stack error conditions +- use `err_ser` in `pdp11_sequencer` to detect vector 4 and emergency stack +- use `err_rsv` in `pdp11_sequencer` to set the corresponding `CPUERR` flag. + +### Hindsight +None. diff --git a/doc/simh_diff_cpuerr_rsv.md b/doc/simh_diff_cpuerr_rsv.md new file mode 100644 index 00000000..fc40ec16 --- /dev/null +++ b/doc/simh_diff_cpuerr_rsv.md @@ -0,0 +1,27 @@ +## Known differences between SimH, 11/70, and w11a + +### SimH: `CPUERR.rsv` has J11 behavior + +The `CPUERR` register in an 11/70 and the J11 has 6 flags that allow the cause +of vector 4 abort to be determined. +For an 11/70, the bit 2 is referred to as _'Red Zone Stack Limit'_ in the +documentation. It is set when a stack limit error is detected. +Other address errors that escalate to a fatal stack error do not set this bit. + +For a J11, bit 2 has the very similar name _'Red Stack Trap'_, and is set +whenever a fatal stack error is detected, and thus also when other address +errors escalate to a fatal stack error. + +The key differences are: +- on an 11/70, an escalated MMU kernel stack abort will not set any + `CPUERR` bits. +- on a J11, every stack error that causes an emergency stack will set the + `rsv` bit. + +SimH implements the J11 behavior also in 11/70 mode. + +w11 implements the 11/70 behavior. This is verified in a +[tcode](../tools/tcode/README.md), the test is modified when executed on SimH +(see [cpu_details.mac](../tools/tcode/cpu_details.mac) test A2.7-10). + +Tested with SimH V3.12-3. diff --git a/doc/simh_diff_summary.md b/doc/simh_diff_summary.md index f99311ad..719bb9ca 100644 --- a/doc/simh_diff_summary.md +++ b/doc/simh_diff_summary.md @@ -18,6 +18,7 @@ ones are listed here: - [SimH: stack limit check and addressing modes](simh_diff_stklim_amode.md) - [SimH: stack limit check and vector push aborts](simh_diff_stklim_vpush.md) - [SimH: Red stack zone PSW protection](simh_diff_red_psw.md) + - [SimH: `CPUERR.rsv` has J11 behavior](simh_diff_cpuerr_rsv.md) - [SimH: No unconditional instruction fetch after stack error abort](simh_diff_ser_forced_fetch.md) - instruction abort handling - [SimH: condition codes are not always unchanged after an abort](simh_diff_cc_and_aborts.md) diff --git a/rtl/sys_gen/w11a/cmoda7/sys_w11a_c7.vhd b/rtl/sys_gen/w11a/cmoda7/sys_w11a_c7.vhd index 37e720e1..58e81362 100644 --- a/rtl/sys_gen/w11a/cmoda7/sys_w11a_c7.vhd +++ b/rtl/sys_gen/w11a/cmoda7/sys_w11a_c7.vhd @@ -1,4 +1,4 @@ --- $Id: sys_w11a_c7.vhd 1342 2023-01-02 15:18:19Z mueller $ +-- $Id: sys_w11a_c7.vhd 1349 2023-01-11 14:52:42Z mueller $ -- SPDX-License-Identifier: GPL-3.0-or-later -- Copyright 2017-2023 by Walter F.J. Mueller -- @@ -28,6 +28,7 @@ -- -- Synthesized: -- Date Rev viv Target flop lutl lutm bram slic +-- 2023-01-11 1349 2022.1 xc7a35t-1 3451 6019 279 50.0 2006 -- 2023-01-02 1342 2022.1 xc7a35t-1 3434 6005 279 50.0 1969 -- 2022-12-31 1340 2022.1 xc7a35t-1 3450 6018 279 50.0 1986 -- 2022-12-27 1339 2022.1 xc7a35t-1 3454 6026 279 50.0 2013 diff --git a/rtl/w11a/pdp11.vhd b/rtl/w11a/pdp11.vhd index 7d8cc393..bbda8e22 100644 --- a/rtl/w11a/pdp11.vhd +++ b/rtl/w11a/pdp11.vhd @@ -1,4 +1,4 @@ --- $Id: pdp11.vhd 1348 2023-01-08 13:33:01Z mueller $ +-- $Id: pdp11.vhd 1349 2023-01-11 14:52:42Z mueller $ -- SPDX-License-Identifier: GPL-3.0-or-later -- Copyright 2006-2023 by Walter F.J. Mueller -- @@ -11,6 +11,7 @@ -- -- Revision History: -- Date Rev Version Comment +-- 2023-01-11 1349 1.5.24 vm_stat_type: add err_ser -- 2023-01-08 1348 1.5.23 _tmu,_tmu_sb: add port DM_STAT_SE -- 2022-12-27 1339 1.5.22 _sequencer: rm PC port; _dpath: rm PCOUT port -- 2022-12-12 1330 1.5.21 dm_stat_se_type: rename vfetch -> vstart; @@ -452,6 +453,7 @@ package pdp11 is err_nxm : slbit; -- abort: non-existing memory err_iobto : slbit; -- abort: non-existing I/O resource err_rsv : slbit; -- abort: red stack violation + err_ser : slbit; -- abort: fatal stack error trap_ysv : slbit; -- trap: yellow stack violation trap_mmu : slbit; -- trap: mmu trap end record vm_stat_type; diff --git a/rtl/w11a/pdp11_sequencer.vhd b/rtl/w11a/pdp11_sequencer.vhd index 042bfb2a..09700308 100644 --- a/rtl/w11a/pdp11_sequencer.vhd +++ b/rtl/w11a/pdp11_sequencer.vhd @@ -1,4 +1,4 @@ --- $Id: pdp11_sequencer.vhd 1343 2023-01-02 18:03:39Z mueller $ +-- $Id: pdp11_sequencer.vhd 1349 2023-01-11 14:52:42Z mueller $ -- SPDX-License-Identifier: GPL-3.0-or-later -- Copyright 2006-2023 by Walter F.J. Mueller -- @@ -13,6 +13,7 @@ -- -- Revision History: -- Date Rev Version Comment +-- 2023-01-11 1349 1.6.28 BUGFIX: handle CPUERR.rsv correctly -- 2023-01-02 1342 1.6.27 BUGFIX: cc state unchanged after abort -- 2022-12-26 1337 1.6.26 tbit logic overhaul 2, now fully 11/70 compatible -- 2022-12-12 1330 1.6.25 implement MMR0,MMR2 instruction complete @@ -2393,7 +2394,7 @@ begin when s_vmerr => -- ----------------------------------- nstate := s_cpufail; - -- setup for R_VMSTAT.err_rsv='1' + -- setup for R_VMSTAT.err_ser='1' ndpcntl.ounit_azero := '1'; -- OUNIT A = 0 ndpcntl.ounit_const := "000000100"; -- emergency stack pointer ndpcntl.ounit_bsel := c_ounit_bsel_const; -- OUNIT B=const(vector) @@ -2416,7 +2417,7 @@ begin nstate := s_idle; elsif R_VMSTAT.err = '1' then -- normal vm errors - if R_VMSTAT.err_rsv = '1' then + if R_VMSTAT.err_ser = '1' then nstatus.in_vecser := '1'; -- signal start of ser flow nstatus.in_vecysv := '0'; -- cancel ysv flow ndpcntl.gr_we := '1'; @@ -2427,8 +2428,9 @@ begin ncpuerr.nxm := '1'; elsif R_VMSTAT.err_iobto = '1' then ncpuerr.iobto := '1'; + elsif R_VMSTAT.err_rsv = '1' then + ncpuerr.rsv := '1'; end if; - ncpuerr.rsv := '1'; nstate := s_abort_4; elsif R_VMSTAT.err_odd = '1' then diff --git a/rtl/w11a/pdp11_vmbox.vhd b/rtl/w11a/pdp11_vmbox.vhd index b5b52ff9..6eef612a 100644 --- a/rtl/w11a/pdp11_vmbox.vhd +++ b/rtl/w11a/pdp11_vmbox.vhd @@ -1,6 +1,6 @@ --- $Id: pdp11_vmbox.vhd 1331 2022-12-18 11:55:47Z mueller $ +-- $Id: pdp11_vmbox.vhd 1349 2023-01-11 14:52:42Z mueller $ -- SPDX-License-Identifier: GPL-3.0-or-later --- Copyright 2006-2022 by Walter F.J. Mueller +-- Copyright 2006-2023 by Walter F.J. Mueller -- ------------------------------------------------------------------------------ -- Module Name: pdp11_vmbox - syn @@ -18,6 +18,7 @@ -- -- Revision History: -- Date Rev Version Comment +-- 2022-01-11 1349 1.6.11 use err_ser to indicate fatal stack error -- 2022-12-17 1331 1.6.10 BUGFIX: request mmu trap also on ib accesses -- 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 @@ -429,14 +430,14 @@ begin if r.bytop='0' and r.paddr(0)='1' then -- odd address ? ivm_stat.err := '1'; ivm_stat.err_odd := '1'; - ivm_stat.err_rsv := r.kstack; -- escalate to rsv if kstack + ivm_stat.err_ser := r.kstack; -- escalate to ser if kstack iem_mreq.cancel := '1'; -- cancel pending mem request n.state := s_idle; elsif r.vaok = '0' then -- MMU abort ? ivm_stat.err := '1'; ivm_stat.err_mmu := '1'; - ivm_stat.err_rsv := r.kstack; -- escalate to rsv if kstack + ivm_stat.err_ser := r.kstack; -- escalate to ser if kstack iem_mreq.cancel := '1'; -- cancel pending mem request n.state := s_idle; @@ -468,7 +469,7 @@ begin if unsigned(r.paddr(21 downto 6)) > sys_conf_mem_losize then ivm_stat.err := '1'; ivm_stat.err_nxm := '1'; - ivm_stat.err_rsv := r.kstack; -- escalate to rsv if kstack + ivm_stat.err_ser := r.kstack; -- escalate to ser if kstack iem_mreq.cancel := '1'; -- cancel pending mem request n.state := s_idle; @@ -606,12 +607,13 @@ begin when s_errrsv => -- s_errrsv: red stack violation ----- ivm_stat.err := '1'; ivm_stat.err_rsv := '1'; + ivm_stat.err_ser := '1'; -- an rsv is always a ser n.state := s_idle; when s_errib => -- s_errib: ibus error handler ------- ivm_stat.err := '1'; ivm_stat.err_iobto := '1'; - ivm_stat.err_rsv := r.kstack; -- escalate to rsv if kstack + ivm_stat.err_ser := r.kstack; -- escalate to ser if kstack n.state := s_idle; when others => null; diff --git a/tools/tcode/cpu_details.mac b/tools/tcode/cpu_details.mac index 22752f68..48b69660 100644 --- a/tools/tcode/cpu_details.mac +++ b/tools/tcode/cpu_details.mac @@ -1,10 +1,10 @@ -; $Id: cpu_details.mac 1346 2023-01-06 12:56:08Z mueller $ +; $Id: cpu_details.mac 1349 2023-01-11 14:52:42Z mueller $ ; SPDX-License-Identifier: GPL-3.0-or-later ; Copyright 2022-2023 by Walter F.J. Mueller ; ; Revision History: ; Date Rev Version Comment -; 2023-01-06 1346 1.0 Initial version +; 2023-01-11 1349 1.0 Initial version ; 2022-07-18 1259 0.1 First draft ; ; Test CPU details @@ -357,7 +357,7 @@ ta0207: cmpb systyp,#sy.e11 ; e11 V7.3 pushes to odd stack, abort after halt clr -(sp) ; odd-address abort, fatal stack error halt 1000$: htsteq sp ; check SP=0 -1010$: hcmpeq (r0),# ; check CPUERR +1010$: hcmpeq (r0),#cp.odd ; check CPUERR clr (r0) ; clear CPUERR (any write should) htsteq (r0) ; check CPUERR mov #stack,sp ; restore stack @@ -383,7 +383,7 @@ ta0208: cmpb systyp,#sy.e11 ; e11 V7.3 pushes to bad stack, abort after halt clr -(sp) ; non-existing memory, fatal stack error halt 1000$: htsteq sp ; check SP=0 -1010$: hcmpeq (r0),# ; check CPUERR +1010$: hcmpeq (r0),#cp.nxm ; check CPUERR clr (r0) ; clear CPUERR (any write should) htsteq (r0) ; check CPUERR mov #stack,sp ; restore stack @@ -408,7 +408,7 @@ ta0209: cmpb systyp,#sy.e11 ; e11 V7.3 pushes to bad stack, abort after halt clr -(sp) ; non-existing memory, fatal stack error halt 1000$: htsteq sp ; check SP=0 -1010$: hcmpeq (r0),# ; check CPUERR +1010$: hcmpeq (r0),#cp.ito ; check CPUERR clr (r0) ; clear CPUERR (any write should) htsteq (r0) ; check CPUERR mov #stack,sp ; restore stack @@ -432,7 +432,7 @@ ta0210: cmpb systyp,#sy.sih ; SimH uses J11 semantics clr -(sp) ; MMU abort, fatal stack error halt 1000$: htsteq sp ; check SP=0 -1010$: hcmpeq (r0),#cp.rsv ; check CPUERR +1010$: hcmpeq (r0),#0 ; check CPUERR (none set on w11) clr (r0) ; clear CPUERR (any write should) htsteq (r0) ; check CPUERR mov #stack,sp ; restore stack