1
0
mirror of https://github.com/wfjm/w11.git synced 2026-01-12 00:43:01 +00:00

pdp11_sequencer BUGFIX: restore PSW after vector push abort

- rtl/w11a/pdp11_sequencer.vhd: BUGFIX: restore PSW after vector push abort
- tools
  - tcode/cpu_details.mac: add A3.6, verify PSW after vector push abort
  - tcode/cpu_mmu.mac: D2.1: verify PSW
  - gwstart/lib/dpath.tcl: added, show dpath basics
This commit is contained in:
wfjm 2023-03-23 10:21:21 +01:00
parent 5d8c065ee4
commit 12ada8fbf7
7 changed files with 130 additions and 12 deletions

View File

@ -50,6 +50,10 @@ The full set of tests is only run for tagged releases.
- tcl/rw11/shell_egd.tcl: add ODX format options for .e command
### Bug Fixes
- rtl/w11a
- pdp11_sequencer:
- BUGFIX: restore PSW after vector push abort, see
[ECO-041](ECO-041-vpush_abort_psw.md)
- tools/bin/asm-11
- BUGFIX: fix directly nested .if behavior
- tools/tcode

View File

@ -47,3 +47,7 @@ first entry.
This deficit had no impact on OS operation and had therefore low priority.
However, the goal of the w11 is to be an as precise as feasible replica of
the 11/70, and it was overdue to fix this.
### Note 2023-03-22
This fixed only part of the problem, see [ECO-041](ECO-041-vpush_abort_psw.md)
for the full solution.

View File

@ -0,0 +1,39 @@
# ECO-041: Get correct `PSW` after vector push abort (2023-03-22)
### Scope
- [ECO-036](ECO-036-vpush_abort_ps.md) fixed only part of the problem
- affects: all w11a systems
### Symptom summary
The tcode [cpu_mmu.mac](../tools/tcode/cpu_mmu.mac) failed in test D2.1 when
running on the E11 simulator while it happily executed on w11.
### Analysis
The changes done in [ECO-036](ECO-036-vpush_abort_ps.md) ensured that the
correct `PS` was saved on the stack. But they did not restore the `PSW` of
the CPU. The vector flow has therefore
- loaded the `PSW` with current mode = supervisor in the initial PIRQ
vector fetch
- was aborted during a vector push
- loaded again the `PSW` in the following MMU vector fetch. Because the `PSW`
wasn't rolled back, the current mode was still supervisor, which now became
the previous mode, the only field not taken from the new `PS`.
The previous mode in the `PSW` should, of course, reflect the current mode
active before the first entry in the vector flow. In the test D2.1 this is
kernel mode.
### Fixes
The states `s_vec_pushps_w` and `s_vec_pushpc_w` now restore the `PSW`
when an abort is detected. This also ensures that the correct `PS` is
saved when the vector flow is re-entered. The special handling in
`do_start_vec` that was introduced in [ECO-036](ECO-036-vpush_abort_ps.md)
was removed.
### Hindsight
This bug was first discovered by cross-checking with the E11 simulator.
cpu_mmu.mac test D2.1 failed under E11 and worked on w11. The reason was that
the test was faulty too and expected that the `PSW` previous mode is already
the mode of the failed stack push. So a bug in the test hid a bug in the CPU.
Great to have a second PDP-11 simulator which provides a very close 11/70
replica. That helps to avoid such double errors in the future.

View File

@ -1,4 +1,4 @@
-- $Id: pdp11_sequencer.vhd 1349 2023-01-11 14:52:42Z mueller $
-- $Id: pdp11_sequencer.vhd 1384 2023-03-22 07:35:32Z mueller $
-- SPDX-License-Identifier: GPL-3.0-or-later
-- Copyright 2006-2023 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
--
@ -13,11 +13,12 @@
--
-- Revision History:
-- Date Rev Version Comment
-- 2023-03-21 1384 1.6.29 BUGFIX: restore PSW after vector push abort
-- 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
-- 2022-12-10 1329 1.6.24 BUGFIX: get correct PS after vector push abort
-- 2022-12-10 1329 1.6.24 BUGFIX: store correct PS after vector push abort
-- 2022-12-05 1324 1.6.23 tbit logic overhaul; use treq_tbit; cleanups
-- use resetcnt for 8 cycle RESET wait
-- 2022-11-29 1323 1.6.22 rename adderr -> oddadr, don't set after err_mmu
@ -593,7 +594,7 @@ begin
pvector : in slv9_2) is
begin
pndpcntl.dtmp_sel := c_dpath_dtmp_psw; -- DTMP = PSW
pndpcntl.dtmp_we := not R_STATUS.in_vecflow; -- save PS on first entry
pndpcntl.dtmp_we := '1'; -- save PS
pndpcntl.ounit_azero := '1'; -- OUNIT A = 0
pndpcntl.ounit_const := pvector & "00"; -- vector
pndpcntl.ounit_bsel := c_ounit_bsel_const;-- OUNIT B=const(vector)
@ -2303,6 +2304,12 @@ begin
nstate := s_vec_pushps_w;
do_memcheck(nstate, nstatus, imemok);
if VM_STAT.err = '1' then -- if err restore PS from DTMP
ndpcntl.ounit_asel := c_ounit_asel_dtmp; -- OUNIT A=DTMP
ndpcntl.ounit_const := "000000000"; -- OUNIT const=0
ndpcntl.psr_func := c_psr_func_wall; -- write all fields
ndpcntl.psr_we := '1'; -- re-store PS from DTMP
end if;
if imemok then
ndpcntl.dsrc_we := '1'; -- update DSRC
ndpcntl.gr_we := '1'; -- update SP too
@ -2330,6 +2337,12 @@ begin
nstate := s_vec_pushpc_w;
do_memcheck(nstate, nstatus, imemok);
if VM_STAT.err = '1' then -- if err restore PS from DTMP
ndpcntl.ounit_asel := c_ounit_asel_dtmp; -- OUNIT A=DTMP
ndpcntl.ounit_const := "000000000"; -- OUNIT const=0
ndpcntl.psr_func := c_psr_func_wall; -- write all fields
ndpcntl.psr_we := '1'; -- re-store PS from DTMP
end if;
if imemok then
nstatus.treq_tbit := PSW.tflag; -- copy PSW.tflag to treq_bit
nstatus.in_vecflow := '0'; -- signal end vector flow
@ -2448,7 +2461,7 @@ begin
do_start_vec(nstate, ndpcntl, lvector);
end if;
end if;
when s_cpufail => -- -----------------------------------
nstatus.cpugo := '0';
nstatus.cpurust := c_cpurust_sfail;

View File

@ -0,0 +1,17 @@
# $Id: dpath.tcl 1384 2023-03-22 07:35:32Z mueller $
# SPDX-License-Identifier: GPL-3.0-or-later
# Copyright 2023- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
#
# pdp11_dpath basics
#
gwaddcom "dpath"
gwaddsig {**.dpath.clk}
gwaddsig {**.dpath.cntl.dsrc_we}
gwaddsig {**.dpath.cntl.dsrc_sel}
gwaddsig -oct {**.dpath.r_dsrc}
gwaddsig {**.dpath.cntl.ddst_we}
gwaddsig {**.dpath.cntl.ddst_sel}
gwaddsig -oct {**.dpath.r_ddst}
gwaddsig {**.dpath.cntl.dtmp_we}
gwaddsig {**.dpath.cntl.dtmp_sel}
gwaddsig -oct {**.dpath.r_dtmp}

View File

@ -1,9 +1,10 @@
; $Id: cpu_details.mac 1384 2023-03-22 07:35:32Z mueller $
; $Id: cpu_details.mac 1385 2023-03-23 08:27:44Z mueller $
; SPDX-License-Identifier: GPL-3.0-or-later
; Copyright 2022-2023 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
;
; Revision History:
; Date Rev Version Comment
; 2023-03-22 1385 1.1.3 add A3.6, verify PSW after vector push abort
; 2023-03-21 1384 1.1.2 remove e11 exemptions for A2.3, A2.5-9,
; A3.2 part 2+3; A3.3, A4.4 part 3+4;
; A4.4 part 5: skip on e11 (SPL in u mode handling)
@ -80,7 +81,8 @@
; part 2: test instructions that should not trap
; part 3: test that interrupt (from PIRQ) vector push traps
; A3.4 red stack abort conditions
; A3.5 vector push abort recovery
; A3.5 vector push abort recovery - saved PS
; A3.6 vector push abort recovery - restored PSW
; A4 PSW + tbit traps
; A4.1 PSW direct write/read test
; part 1: all bits except register set (cp.ars)
@ -806,7 +808,7 @@ ta0304: vecset v..iit,1000$,cp.pr7 ; set up iit handler, lockout interrupts
;
9999$: iot ; end of test A3.4
;
; Test A3.5 -- vector push abort recovery ++++++++++++++++++++++++++++
; Test A3.5 -- vector push abort recovery - saved PS +++++++++++++++++
; Verify that the frame pushed to the emergency stack after a vector push
; abort has the PS and PC values at entry into the initial vector flow and
; not the values read in the vector fetch of the failed vector flow.
@ -846,14 +848,14 @@ ta0305: cmpb systyp,#sy.sih ; skip on SimH (different stklim logic)
hcmpeq (sp),#300$ ; PC: return after trap
hcmpeq 2(sp),#cp.pr4!cp000c ; PS: should be code signature
;
; trap without error, checks in_vecflow reset ----
; trap without error -----------------------------
clr cp.slr ; STKLIM to default
mov #600$,v..trp ; set up TRAP handler (continuation)
mov #stack,sp ; 1st push will fail
mov #stack,sp ; SP to default
spl 2 ; use PR2 as signature code
ccc ; clear all ccs
sez ; and set z
trap 300 ; will fail
trap 300 ; will work
500$: halt
;
600$: hcmpeq #stack-4,sp ; check stack, 1 frame
@ -868,6 +870,43 @@ ta0305: cmpb systyp,#sy.sih ; skip on SimH (different stklim logic)
;
9999$: iot ; end of test A3.5
;
; Test A3.6 -- vector push abort recovery - restored PSW +++++++++++++
; Verify that the PSW is restored when a vector flow is aborted during a push.
; The previous test A3.5 checks that the correct PS is saved on stack. This
; test verifies that the PSW is restored before the new vector is fetched.
; This affects the previous mode bits because they are taken from the PSW
; at the time the new PS is fetched. To test this, PIRQ is set up with a
; handler in supervisor space and an odd SP value. That will cause a vector 4
; abort during first push. A PIRQ is requested from kernel mode. The PSW
; seen by the vector 4 handler should see a previous mode of kernel, and not
; supervisor.
; See also cpu_mmu tests C2.5,C2.6, they check vector push abort by mmu.
;
ta0306: vecset v..pir,200$,cp.cms!cp.pr6 ; set up PIRQ handler
vecset v..iit,300$,cp.pr5 ; set up iit handler
;
mov #cp.pms,cp.psw ; supervisor now previous mode
push #1777 ; use odd address
mtpi sp ; for supervisor stack
mov #cp.pr1,cp.psw ; code signature PR1, back to kernel
movb #bit04,cp.pir+1 ; request PIRQ 4
100$: halt
200$: halt ; PIRQ handler, should not be called
;
300$: hcmpeq #cp.pr5,cp.psw ; CM=PM=kernel
hcmpeq #stack-4,sp ; 1 frame pushed
hcmpeq #100$,(sp) ; saved PC
hcmpeq #cp.pr1,2(sp) ; saved PC
;
; restore
vecclr v..pir ; v..pir to catcher
vecclr v..iit ; v..iit to catcher
mov #stack,sp ; SP to default
clr cp.pir ; cancel PIRQ
clr cp.psw ; back to kernel PR0
;
9999$: iot ; end of test A3.6
; Test A4: PSW + tbit traps +++++++++++++++++++++++++++++++++++++++++++++++++
; This sub-section verifies operation of PSW register and tbit traps.
;
@ -2038,7 +2077,7 @@ tc0103: vecset v..iit,vhugen ; set iit handler, pr0 kernel
; END OF ALL TESTS - loop closure ============================================
;
mov tstno,r0 ; hack, for easy monitoring ...
hcmpeq tstno,#39. ; all tests done ?
hcmpeq tstno,#40. ; all tests done ?
;
jmp loop
;

View File

@ -1,4 +1,4 @@
; $Id: cpu_mmu.mac 1383 2023-03-20 08:19:14Z mueller $
; $Id: cpu_mmu.mac 1385 2023-03-23 08:27:44Z mueller $
; SPDX-License-Identifier: GPL-3.0-or-later
; Copyright 2022-2023 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
;
@ -1932,6 +1932,8 @@ td0201: cmpb systyp,#sy.sih ; skip on on SimH
; Note: MMR2 holds the vector address. So push PS and PC of that vector
; to kernel stack and start handler with an RTT.
;
ccc ; clear ccs before PSW check
hcmpeq #cp.pr7,cp.psw ; PSW has CM=PM=kernel
hcmpeq #m0.ale!m0.ent!m0.ico!m0.pms!<3*m0.pno>!m0.ena,r0 ; check mmr0
hcmpeq #240,mmr2 ; check mmr2: PIRQ vector
;