diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index a20853fd..a47c149a 100644 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -57,6 +57,8 @@ The full set of tests is only run for tagged releases. ### Bug Fixes - rtl/w11a - pdp11_sequencer: + - BUGFIX: get correct PS after vector push abort, see + [ECO-036](ECO-036-vpush_abort_ps.md) - BUGFIX: use is_kstackdst1246 also in dstr flow, see [ECO-035](ECO-035-stklim-tbit-fixes.md) - BUGFIX: correct ysv flow implementation, see diff --git a/doc/ECO-036-vpush_abort_ps.md b/doc/ECO-036-vpush_abort_ps.md new file mode 100644 index 00000000..c9537f56 --- /dev/null +++ b/doc/ECO-036-vpush_abort_ps.md @@ -0,0 +1,49 @@ +# ECO-036: Get correct PS after vector push abort (2022-12-11) + +### Scope +- was in w11a since 2009 +- affects: all w11a systems + +### Symptom summary +Test 124 of `ekbee1` fails with +``` + SSRA PS RESTORE(1) DOESN'T GET TO RACK E63 + OR E63(5) BAD + ERRORPC TEST NUMBER + 077344 000124 +``` + +### Analysis +The test makes page 6 non-resident, sets `SP` to a location in page 6, and +executes a `TRAP` instruction. The `TRAP` vector flow fails at the 1st stack +push, a fatal error is detected, an emergency stack is set up (`SP` := 4) +and a vector 4 flow is started. On an 11/70, such a restarted vector flow +will push the `PS` and `PC` seen at the entry of the initial aborted vector +flow, and therefore restore the `PS` which was already overwritten by the +value read during the vector fetch phase of the initial vector flow. + +The w11 did not perform such a recovery and pushed the `PS` fetched in the +initial vector flow. Correct handling of this case is essential for the `MMR0` +instruction complete functionality, which is not yet available but will be +implemented in a later release. + +### Fixes +The 11/70 uses a microcode branch and dedicated states to recover `PS` in the +case of re-entry into the vector flow. + +w11 uses a new `cpu_state` flag `in_vecflow` instead. +The current `PS` is saved in register `DTMP` when a vector flow is started +with `do_start_vec`, and later read from `DTMP` in state `s_vec_pushps` when +the first vector push is started. `do_start_vec` is executed in the states +that start a vector flow with a branch to `s_vec_getpc`. + +The new state flag `in_vecflow` is set in the state `s_vec_getpc` and cleared +in `s_vec_pushpc_w` when the last push was successful. +In `do_start_vec`, the `PS` is only written to `DTMP` when `in_vecflow` is not +set. The pushed `PS` in a re-entered vector flow comes therefore from the +first entry. + +### Hindsight +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. diff --git a/doc/simh_diff_mmu_nxm_prio.md b/doc/simh_diff_mmu_nxm_prio.md index c107df81..f966af8f 100644 --- a/doc/simh_diff_mmu_nxm_prio.md +++ b/doc/simh_diff_mmu_nxm_prio.md @@ -10,7 +10,8 @@ In the KB11-C processor, the NXM condition is handled before the MMU condition. This leads to the surprising situation that the access is aborted with a vector 4 flow rather than a vector 250 flow. -SimH verifies the MMU abort condition first. xxdp `ekbee1` test 122 verifies the 11/70 behavior and is patched. +SimH verifies the MMU abort condition first. xxdp `ekbee1` test 122 verifies +the 11/70 behavior and is patched. w11 also doesn't support this behavior, this is documented as [w11 known difference](w11a_diff_70_mmu_nxm_prio.md). diff --git a/doc/simh_diff_stklim.md b/doc/simh_diff_stklim_amode.md similarity index 95% rename from doc/simh_diff_stklim.md rename to doc/simh_diff_stklim_amode.md index 8de13dac..c54d9ab5 100644 --- a/doc/simh_diff_stklim.md +++ b/doc/simh_diff_stklim_amode.md @@ -1,6 +1,6 @@ ## Known differences between SimH, 11/70, and w11a -### SimH: stack limit check uses J11 behavior +### SimH: stack limit check and addressing modes The stack limit check is implemented slightly differenly on all models that support it. All models check the stack limit only in kernel mode for specifiers diff --git a/doc/simh_diff_stklim_vpush.md b/doc/simh_diff_stklim_vpush.md new file mode 100644 index 00000000..ddf8abef --- /dev/null +++ b/doc/simh_diff_stklim_vpush.md @@ -0,0 +1,31 @@ +## Known differences between SimH, 11/70, and w11a + +### SimH: stack limit check and vector push aborts + +In a vector flow, the 11/70 performs an individual stack limit check for the +PS push and the PC push. Therefore, a vector flow can be aborted on the first +or the second push, the red zone is never written. +In case of a stack limit abort during a vector flow, the PS is restored to +the value at the entry of the vector flow, an emergency stack is set up, +and a vector 4 flow is started that will save the PS and PC values present +at the beginning of the aborted vector flow. + +SimH implements a substantially different behavior for all PDP-11 models. +A stack limit violation is checked at the end of the vector flow, after the +writes have been performed and one or two values have been potentially written +into the red zone. An emergency stack is set up and a vector 4 flow is started +that will save the PS and PC values taken read in beginning of the aborted +vector flow. +The [tcode](../tools/tcode/README.md) +[cpu_details](../tools/tcode/cpu_details.mac) test A3.5 verifies the 11/70 +behaviour and is skipped when executed on SimH. + +**Note**: The SimH behavior for vector push aborts caused by an MMU abort is +different. These aborts are detected before the actual write, and the vector +flow handling of the abort saves the PS and PC values present at the beginning +of the initial vector flow. This occurs both for a vector 240 flow when a push +to a non-kernel stack failed, and a vector 4 flow when a push to kernel stack +failed and is converted to a fatal stack error. In these cases, SimH +implements the 11/70 behavior. + +The w11 correctly implements the 11/70 behavior in all cases. diff --git a/doc/simh_diff_summary.md b/doc/simh_diff_summary.md index 6e7db43f..ae63e97b 100644 --- a/doc/simh_diff_summary.md +++ b/doc/simh_diff_summary.md @@ -11,7 +11,8 @@ for all PDP-11 models, and also when `set cpu 11/70` is configured. Test codes are sometimes sensitive to those details, so the most relevant ones are listed here: - [SimH: State of N and Z and registers after a `DIV` abort with `V=1`](simh_diff_div_after_v1.md) -- [SimH: stack limit check uses J11 behavior](simh_diff_stklim.md) +- [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: trap and interrupt service order has J11 behavior](simh_diff_service-order.md) - [SimH: traced `WAIT` has J11 behavior](simh_diff_traced-wait.md) diff --git a/doc/w11a_diff_70_mmu_stklim_prio.md b/doc/w11a_diff_70_mmu_stklim_prio.md new file mode 100644 index 00000000..45cc2b32 --- /dev/null +++ b/doc/w11a_diff_70_mmu_stklim_prio.md @@ -0,0 +1,23 @@ +## Known differences between w11a and KB11-C (11/70) + +### `MMR0` abort flags are set when stack limit abort done + +Let's assume a case where two aborts are present: +- the MMU rejects the access, e.g. because the page is non-resident +- the access is a kernel stack write and violates the stack limit + +Both checks run in parallel in hardware. The MMU logic uses the access control +field and the page length field to check whether access is allowed. +And the effective address is compared with the stack limit. + +In the KB11-C processor, the `MMR0` abort bits are not set in case of a red +zone stack abort. The case described above leads to a vector 4, as it should +be, and does not set an abort bit in `MMR0`. + +The w11 does not implement this suppression, the MMU logic and the stack limit +check logic are independent. The case described above leads to a vector 4, +but also sets an abort bit in `MMR0`. + +The `ekbee1` diagnostic tests this behavior in test 122. This test is +modified when executed on w11 +(see [patch](../tools/xxdp/ekbee1_patch_w11a.tcl)). diff --git a/doc/w11a_diff_70_red_stack_abort.md b/doc/w11a_diff_70_red_stack_abort.md deleted file mode 100644 index 33ef4daf..00000000 --- a/doc/w11a_diff_70_red_stack_abort.md +++ /dev/null @@ -1,16 +0,0 @@ -## Known differences between w11a and KB11-C (11/70) - -### 'fatal stack errors' lose PSW, a 0 is pushed onto the stack - -The 11/70, together with the 11/45, has the most elaborate stack protection -system of all PDP-11 models. A stack push via kernel stack is aborted when the -stack pointer is in the 'red zone' 16 words below the stack limit. - -This is considered a 'fatal stack error', other cases are aborts due to odd -address, non-existing memory or MMU aborts. In case of a 'fatal stack error' -an emergency stack is set up, `SP` is set to 4, and PSW and PC are stored. - -The w11a loses the PSW, a 0 is pushed. - -'fatal stack errors' are never recovered, all OS treat them as fatal errors. -This difference is therefore considered an acceptable implementation difference. diff --git a/doc/w11a_known_differences.md b/doc/w11a_known_differences.md index 18d2101a..84b568c3 100644 --- a/doc/w11a_known_differences.md +++ b/doc/w11a_known_differences.md @@ -6,7 +6,6 @@ The issues of the w11 CPU and systems are listed in a separate document ### Known differences between w11a and KB11-C (11/70) - [Instruction fetch after `SPL`](w11a_diff_70_spl_bug.md) -- ['fatal stack errors' lose PSW](w11a_diff_70_red_stack_abort.md) - [Stack limit checks done independent of register set](w11a_diff_70_stklim_rset.md) - ['instruction completed flag' in `MMR0` is not implemented](w11a_diff_70_instruction_complete.md) - [`CLR` and `SXT` do a write](w11a_diff_70_clr_sxt_write.md) @@ -14,6 +13,7 @@ The issues of the w11 CPU and systems are listed in a separate document - [18-bit UNIBUS address space not mapped](w11a_diff_70_unibus_mapping.md) - [MMU traps not suppressed when MMU register accessed](w11a_diff_70_mmu_trap_suppression.md) - [MMU aborts have priority over NXM aborts](w11a_diff_70_mmu_nxm_prio.md) +- [`MMR0` abort flags are set when stack limit abort done](w11a_diff_70_mmu_stklim_prio.md) All points relate to very 11/70 specific behavior, no operating system depends on them, therefore they are considered acceptable implementation diff --git a/rtl/w11a/pdp11.vhd b/rtl/w11a/pdp11.vhd index d5099d3c..7a66df2d 100644 --- a/rtl/w11a/pdp11.vhd +++ b/rtl/w11a/pdp11.vhd @@ -1,4 +1,4 @@ --- $Id: pdp11.vhd 1325 2022-12-07 11:52:36Z mueller $ +-- $Id: pdp11.vhd 1329 2022-12-11 17:28:28Z mueller $ -- SPDX-License-Identifier: GPL-3.0-or-later -- Copyright 2006-2022 by Walter F.J. Mueller -- @@ -11,6 +11,7 @@ -- -- Revision History: -- Date Rev Version Comment +-- 2022-12-10 1329 1.5.20 add cpustat_type in_vecflow -- 2022-12-05 1324 1.5.19 add cpustat_type treq_tbit and resetcnt; -- use op_rti rather op_rtt; -- 2022-11-29 1323 1.5.18 rename cpuerr_type adderr->oddadr, mmu_mmr0_type @@ -390,8 +391,9 @@ package pdp11 is treq_tbit : slbit; -- tbit trap requested prefdone : slbit; -- prefetch done do_grwe : slbit; -- pending gr_we - in_vecser : slbit; -- in fatal stack error vector flow - in_vecysv : slbit; -- in ysv trap flow + in_vecflow : slbit; -- in vector flow + 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 := ( @@ -404,7 +406,7 @@ package pdp11 is '0','0','0','0','0', -- itimer,creset,breset,intack,intpend (others=>'0'),"111", -- intvect,resetcnt '0','0','0','0', -- treq_(mmu|ysv|tbit), prefdone - '0','0','0' -- do_grwe, in_vec(ser|ysv) + '0','0','0','0' -- do_grwe, in_vec(flow|ser|ysv) ); type cpuerr_type is record -- CPU error register diff --git a/rtl/w11a/pdp11_sequencer.vhd b/rtl/w11a/pdp11_sequencer.vhd index 1eae24ee..5fa56881 100644 --- a/rtl/w11a/pdp11_sequencer.vhd +++ b/rtl/w11a/pdp11_sequencer.vhd @@ -1,4 +1,4 @@ --- $Id: pdp11_sequencer.vhd 1325 2022-12-07 11:52:36Z mueller $ +-- $Id: pdp11_sequencer.vhd 1329 2022-12-11 17:28:28Z mueller $ -- SPDX-License-Identifier: GPL-3.0-or-later -- Copyright 2006-2022 by Walter F.J. Mueller -- @@ -13,6 +13,7 @@ -- -- Revision History: -- Date Rev Version Comment +-- 2022-12-10 1329 1.6.24 BUGFIX: get 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 @@ -590,7 +591,7 @@ begin pvector : in slv9_2) is begin pndpcntl.dtmp_sel := c_dpath_dtmp_psw; -- DTMP = PSW - pndpcntl.dtmp_we := '1'; + pndpcntl.dtmp_we := not R_STATUS.in_vecflow; -- save PS on first entry pndpcntl.ounit_azero := '1'; -- OUNIT A = 0 pndpcntl.ounit_const := pvector & "00"; -- vector pndpcntl.ounit_bsel := c_ounit_bsel_const;-- OUNIT B=const(vector) @@ -789,6 +790,9 @@ begin nstatus.treq_mmu := '0'; -- cancel trap requests nstatus.treq_ysv := '0'; nstatus.treq_tbit := '0'; + nstatus.in_vecflow := '0'; -- cancel in_* flags + nstatus.in_vecser := '0'; + nstatus.in_vecysv := '0'; nstatus.cpurust := c_cpurust_init; end if; nstate := s_idle; @@ -2216,6 +2220,7 @@ begin when s_vec_getpc => -- ----------------------------------- idm_vfetch := '1'; -- signal vfetch + nstatus.in_vecflow := '1'; -- signal vector flow nstatus.treq_tbit := '0'; -- cancel pending tbit request nvmcntl.mode := c_psw_kmode; -- fetch PC from kernel D space do_memread_srcinc(nstate, ndpcntl, nvmcntl, s_vec_getpc_w, nmmumoni); @@ -2319,8 +2324,9 @@ begin nstate := s_vec_pushpc_w; do_memcheck(nstate, nstatus, imemok); if imemok then - nstatus.in_vecser := '0'; -- signal end of ser flow - nstatus.in_vecysv := '0'; -- signal end of ysv flow + nstatus.in_vecflow := '0'; -- signal end vector flow + 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); -- ??? diff --git a/tools/tcode/cpu_basics.mac b/tools/tcode/cpu_basics.mac index a2b6ddba..8e583877 100644 --- a/tools/tcode/cpu_basics.mac +++ b/tools/tcode/cpu_basics.mac @@ -1,4 +1,4 @@ -; $Id: cpu_basics.mac 1325 2022-12-07 11:52:36Z mueller $ +; $Id: cpu_basics.mac 1329 2022-12-11 17:28:28Z mueller $ ; SPDX-License-Identifier: GPL-3.0-or-later ; Copyright 2015-2022 by Walter F.J. Mueller ; diff --git a/tools/tcode/cpu_details.mac b/tools/tcode/cpu_details.mac index e5a39556..2cdca046 100644 --- a/tools/tcode/cpu_details.mac +++ b/tools/tcode/cpu_details.mac @@ -1,10 +1,10 @@ -; $Id: cpu_details.mac 1325 2022-12-07 11:52:36Z mueller $ +; $Id: cpu_details.mac 1329 2022-12-11 17:28:28Z mueller $ ; SPDX-License-Identifier: GPL-3.0-or-later ; Copyright 2022- by Walter F.J. Mueller ; ; Revision History: ; Date Rev Version Comment -; 2022-12-06 1324 1.0 Initial version +; 2022-12-10 1329 1.0 Initial version ; 2022-07-18 1259 0.1 First draft ; ; Test CPU details @@ -69,6 +69,7 @@ ; 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 ; A4 PSW + tbit traps ; A4.1 PSW direct write/read test ; part 1: all bits except register set (cp.ars) @@ -819,6 +820,72 @@ ta0304: ; 9999$: iot ; end of test A3.4 ; +; Test A3.5 -- vector push abort recovery ++++++++++++++++++++++++++++ +; 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. +; Test abort on 2nd and 1st push after a TRAP instruction. +; Skipped on SimH that has different vector flow stack limit check logic. +; See also cpu_mmu tests C2.5,C2.6, they check vector push abort by mmu. +; +ta0305: cmpb systyp,#sy.sih ; skip in SimH (different stklim logic) + beq 9999$ +; + mov #200$,v..iit ; set up iit handler + mov #cp.pr5!cp0z0c,v..iit+2 ; use PR5+0Z0C as signature iit + mov #110$,v..trp ; set up TRAP handler (catcher) + mov #cp.pr6!cpn0v0,v..trp+2 ; use PR6+N0V0 as signature trp + mov #1400,cp.slr ; yellow <=1776 and red <= 1736 +; +; on abort 2nd push ------------------------------ + mov #1742,sp ; 2nd push will fail + spl 3 ; use PR3 as signature code + ccc ; clear all ccs + trap 100 ; will fail +100$: halt ; label after trap +110$: halt ; trap catcher +; +200$: htsteq sp ; check emergency stack done + hcmpeq (sp),#100$ ; PC: return after trap + hcmpeq 2(sp),#cp.pr3 ; PS: should be code signature +; +; on abort 1st push ------------------------------ + mov #400$,v..iit ; set up iit handler + mov #1740,sp ; 1st push will fail + spl 4 ; use PR4 as signature code + ccc ; clear all ccs + sec ; and set C + trap 200 ; will fail +300$: halt +; +400$: htsteq sp ; check emergency stack done + 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 ---- + clr cp.slr ; STKLIM to default + mov #600$,v..trp ; set up TRAP handler (continuation) + mov #stack,sp ; 1st push will fail + spl 2 ; use PR2 as signature code + ccc ; clear all ccs + sez ; and set z + trap 300 ; will fail +500$: halt +; +600$: hcmpeq #stack-4,sp ; check stack, 1 frame + hcmpeq (sp),#500$ ; PC: return after trap + hcmpeq 2(sp),#cp.pr2!cp0z00 ; PS: should be code signature +; +; restore + mov #v..iit+2,v..iit ; v..iit to catcher + clr v..iit+2 + mov #v..trp+2,v..trp ; v..trp to catcher + clr v..trp+2 + mov #stack,sp ; SP to default + spl 0 ; back to PR0 +; +9999$: iot ; end of test A3.5 +; ; Test A4: PSW + tbit traps +++++++++++++++++++++++++++++++++++++++++++++++++ ; This sub-section verifies operation of PSW register and tbit traps. ; @@ -1512,7 +1579,7 @@ tc0103: mov #vhugen,v..iit ; set iit handler ; END OF ALL TESTS - loop closure ============================================ ; mov tstno,r0 ; hack, for easy monitoring ... - hcmpeq tstno,#28. ; all tests done ? + hcmpeq tstno,#29. ; all tests done ? ; jmp loop ; diff --git a/tools/tcode/cpu_eis.mac b/tools/tcode/cpu_eis.mac index fc6d028b..53e416b3 100644 --- a/tools/tcode/cpu_eis.mac +++ b/tools/tcode/cpu_eis.mac @@ -1,4 +1,4 @@ -; $Id: cpu_eis.mac 1314 2022-11-09 10:55:29Z mueller $ +; $Id: cpu_eis.mac 1329 2022-12-11 17:28:28Z mueller $ ; SPDX-License-Identifier: GPL-3.0-or-later ; Copyright 2022- by Walter F.J. Mueller ; diff --git a/tools/tcode/cpu_mmu.mac b/tools/tcode/cpu_mmu.mac index 5266b26d..388a2e4b 100644 --- a/tools/tcode/cpu_mmu.mac +++ b/tools/tcode/cpu_mmu.mac @@ -1,4 +1,4 @@ -; $Id: cpu_mmu.mac 1324 2022-12-01 11:24:20Z mueller $ +; $Id: cpu_mmu.mac 1329 2022-12-11 17:28:28Z mueller $ ; SPDX-License-Identifier: GPL-3.0-or-later ; Copyright 2022- by Walter F.J. Mueller ; @@ -39,10 +39,13 @@ sipdr0 = sipdr+ 0 sipar0 = sipar+ 0 + sipdr6 = sipdr+14 + sipar6 = sipar+14 sipdr7 = sipdr+16 sipar7 = sipar+16 kipdr0 = kipdr+ 0 + kipar0 = kipar+ 0 kdpdr0 = kdpdr+ 0 kipdr5 = kipdr+12 kipdr6 = kipdr+14 @@ -713,6 +716,9 @@ tb0402: tstb systyp ; skip if not on w11 ; part 1: JSR, MFPI, MFPD (push) ; part 2: RTS, MTPI, MTPD (pop) ; C2.4 mmu abort vs nxm abort +; C2.5 mmu abort in vector flow - kernel mode +; C2.6 mmu abort in vector flow - supervisor mode +; C2.7 mmu abort plus stack limit abort ; ; Test C1: ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; Verify MMU response in mmr1 after a write to that fakes an abort @@ -1339,7 +1345,176 @@ tc0204: mov cp.los,kipar6 ; map begin of non-existent memory ; 9999$: iot ; end of test C2.4 ; +; Test C2.5 -- mmu abort in vector flow - kernel mode ++++++++++++++++ +; Verifies the MMU abort after the 2nd and 1st push in a vector flow. +; When the handler runs in kernel mode, the vector pushes are to kernel +; stack, and this results in a fatal stack error with an emergency stack +; and a vector 4 flow. +; Tested with a TRAP instruction, page 5 made non-resident, and the +; stack located at begin of page 6. +; Verify that PS and PC at the beginning of the failed vector flow are saved. +; See also cpu_details test A3.5, checks vector push abort by stklim. +; +tc0205: mov #<127.*md.plf>,kipdr5 ; page 5 non-resident (afc=0) + mov #m0.ena,mmr0 ; enable mmu ;! MMU 18 + mov #200$,v..iit ; iit handler + mov #cp.pr1!cp000c,v..iit+2 ; use PR1+000C as signature iit + mov #110$,v..mmu ; mmu handler (catcher) + mov #cp.pr2!cp00v0,v..mmu+2 ; use PR2+00V0 as signature mmu + mov #120$,v..trp ; trap handler (catcher) + mov #cp.pr3!cp0z00,v..trp+2 ; use PR3+0Z00 as signature trp +; +; abort on 2nd push + mov #p6base+2,sp ; 2nd push will fail + spl 4 + ccc + trap 100 +100$: halt ; label after trap +110$: halt ; mmu catcher +120$: halt ; trap catcher +; +200$: htsteq sp ; check emergency stack done + hcmpeq (sp),#100$ ; PC: return after trap + hcmpeq 2(sp),#cp.pr4 ; PS: should be code signature +; +; abort on 1st push + mov #400$,v..iit ; set up iit handler + mov #p6base,sp ; 1st push will fail + spl 5 + scc + trap 200 +300$: halt ; label after trap +; +400$: htsteq sp ; check emergency stack done + hcmpeq (sp),#300$ ; PC: return after trap + hcmpeq 2(sp),#cp.pr5!cpnzvc ; PS: should be code signature +; +; restore + reset ; mmu off ;! MMU off + mov #<127.*md.plf>!md.arw,kipdr5 ; reset kipdr5 + mov #v..iit+2,v..iit ; v..iit to catcher + clr v..iit+2 + mov #v..mmu+2,v..mmu ; v..mmu to catcher + clr v..mmu+2 + mov #v..trp+2,v..trp ; v..trp to catcher + clr v..trp+2 + mov #stack,sp ; SP to default + spl 0 ; back to PR0 +; +9999$: iot ; end of test C2.5 +; +; Test C2.6 -- mmu abort in vector flow - supervisor mode ++++++++++++ +; Verifies the MMU abort after the 2nd and 1st push in a vector flow. +; When the handler is not in kernel mode a normal mmu vector 240 flow +; is started. The mmu handler runs in kernel mode with a valid stack. +; Tested with supervisor page 0+6+7 mapped 1-to-1, page 5 set non-resident, +; and a PIRQ handler in supervisor space. +; Verify that PS and PC at the beginning of the failed vector flow are saved. +; Test inspired by ekbee1 test 124. +; +tc0206: mov kipdr0,sipdr0 ; super page 0 1-to-1 + mov kipar0,sipar0 + mov kipdr6,sipdr6 ; super page 6 1-to-1 + mov kipar6,sipar6 + mov kipdr7,sipdr7 ; super page 7 1-to-1 + mov kipar7,sipar7 + mov #m0.ena,mmr0 ; enable mmu ;! MMU 18 + mov #200$,v..mmu ; mmu handler + mov #cp.pr7!cp000c,v..mmu+2 ; use PR7+000C as signature mmu + mov #110$,v..pir ; PIRQ handler (catcher in supervisor) + mov #cp.cms!cp.pr6!cp00v0,v..pir+2 ; use PR6+00V0 as signature pir +; +; abort on 2nd push ------------------------------ + mov #stack,sp ; set kernel SP + mov #cp.cms!cp.pr7,cp.psw ; switch to supervisor mode, PR7 + mov #p6base+2,sp ; set supervisor SP, 2nd push will fail + movb #bit04,cp.pir+1 ; request PIRQ 4 + ccc + mov #cp.cms!cp.pr1,cp.psw ; to prio PR1 -> trigger PRIQ interrupt +100$: halt ; label after mov +110$: halt ; PIRQ catcher +; +200$: hcmpeq cp.psw,#cp.pms!cp.pr7!cp000c ; MMU handler, in kernel mode + clr cp.pir ; cancel PIRQ + hcmpeq sp,#stack-4 ; check stack, 1 frame + hcmpeq (sp),#100$ ; PC: return after mov + hcmpeq 2(sp),#cp.cms!cp.pr1 ; PS: should be code signature +; +; abort on 1st push ------------------------------ + mov #400$,v..mmu ; mmu handler + mov #stack,sp ; set kernel SP + mov #cp.cms!cp.pr7,cp.psw ; switch to supervisor mode, PR7 + mov #p6base,sp ; set supervisor SP, 1st push will fail + movb #bit05,cp.pir+1 ; request PIRQ 5 + ccc + mov #cp.cms!cp.pr2,cp.psw ; to prio PR2 -> trigger PRIQ interrupt +300$: halt ; label after mov +; +400$: hcmpeq cp.psw,#cp.pms!cp.pr7!cp000c ; MMU handler, in kernel mode + clr cp.pir ; cancel PIRQ + hcmpeq sp,#stack-4 ; check stack, 1 frame + hcmpeq (sp),#300$ ; PC: return after mov + hcmpeq 2(sp),#cp.cms!cp.pr2 ; PS: should be code signature +; +; restore ---------------------------------------- + clr cp.psw ; to kernel + reset ; mmu off ;! MMU off + clr sipdr0 + clr sipar0 + clr sipdr6 + clr sipar6 + clr sipdr7 + clr sipar7 + mov #v..mmu+2,v..mmu ; v..mmu to catcher + clr v..mmu+2 + mov #v..pir+2,v..pir ; v..pir to catcher + clr v..pir+2 + mov #stack,sp ; SP to default +; +9999$: iot ; end of test C2.6 +; +; Test C2.7 -- mmu abort plus stack limit abort ++++++++++++++++++++++ +; Consider an instruction that is aborted due to red stack violation an the +; destination address would cause an MMU abort. Tested in ekbee1 test 122 +; 2nd part. The 11/70 and the simulators take a vector 4 and do not set MMR0 +; abort bits. The w11 also takes a vector 4 but will set MMR0 abort bits. +; Verify this w11 specific behavior. +; +tc0207: tstb systyp ; skip if not on w11 + blt 9999$ +; + mov #<127.*md.plf>,kipdr6 ; page 6 non-resident (afc=0) + mov #m0.ena,mmr0 ; enable mmu ;! MMU 18 + mov #200$,v..iit ; iit handler + mov #cp.pr1!cp000c,v..iit+2 ; use PR1+000C as signature iit + mov #110$,v..mmu ; mmu handler (catcher) + mov #cp.pr2!cp00v0,v..mmu+2 ; use PR2+00V0 as signature mmu + mov #p6base,cp.slr ; red zone at 140340 + mov #p6base+336,sp ; in red zone + spl 4 + ccc + inc (sp) ; fails (use inc to avoid dstw cc issue) +100$: halt ; label after clr +110$: halt ; mmu catcher +; +200$: htsteq sp ; check emergency stack done + hcmpeq (sp),#100$ ; PC: return after trap + hcmpeq 2(sp),#cp.pr4 ; PS: should be code signature + hcmpeq #m0.anr!<6*m0.pno>!m0.ena,mmr0 ; check mmr0, expect abort +; + reset ; mmu off ;! MMU off + mov #stack,sp ; SP to default + mov #<127.*md.plf>!md.arw,kipdr6 ; reset kipdr6 + mov #v..iit+2,v..iit ; v..iit to catcher + clr v..iit+2 + mov #v..mmu+2,v..mmu ; v..mmu to catcher + clr v..mmu+2 + spl 0 ; back to PR0 +; +9999$: iot ; end of test C2.7 +; ; Section D: mmr2+mmr1+mmr0 register, abort recovery ========================= +; D1 code in user mode with D space, simulated SP extend ; ; Test D1: ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; @@ -2001,7 +2176,7 @@ tf0102: mov #154345,@#p6base ; inititialize target ;; END OF ALL TESTS - loop closure ============================================ ; mov tstno,r0 ; hack, for easy monitoring ... - hcmpeq tstno,#23. ; all tests done ? + hcmpeq tstno,#26. ; all tests done ? ; jmp loop ; diff --git a/tools/tcode/cpu_selftest.mac b/tools/tcode/cpu_selftest.mac index 5ed727c9..4bd3a6dc 100644 --- a/tools/tcode/cpu_selftest.mac +++ b/tools/tcode/cpu_selftest.mac @@ -1,4 +1,4 @@ -; $Id: cpu_selftest.mac 1262 2022-07-25 09:44:55Z mueller $ +; $Id: cpu_selftest.mac 1329 2022-12-11 17:28:28Z mueller $ ; SPDX-License-Identifier: GPL-3.0-or-later ; Copyright 2022- by Walter F.J. Mueller ; diff --git a/tools/xxdp/ekbbf0_README.md b/tools/xxdp/ekbbf0_README.md index cf94cd52..d17583cf 100644 --- a/tools/xxdp/ekbbf0_README.md +++ b/tools/xxdp/ekbbf0_README.md @@ -27,7 +27,12 @@ END PASS # 2 TOTAL ERRORS SINCE LAST REPORT 0 ``` ### w11 remarks -Requires [patch](ekbbf0_patch_w11a.tcl). +Requires [patch](ekbbf0_patch_w11a.tcl). Still one diagnostic +``` + RACF E8 BAD + ERRORPC TEST NUMBER + 006122 000002 +``` ### SimH remarks (tested with V3.12-3 RC2) Requires [patch](ekbbf0_patch_1170.scmd). diff --git a/tools/xxdp/ekbee1_README.md b/tools/xxdp/ekbee1_README.md index 056d3d6c..2949a807 100644 --- a/tools/xxdp/ekbee1_README.md +++ b/tools/xxdp/ekbee1_README.md @@ -23,17 +23,7 @@ END PASS # 2 TOTAL ERRORS SINCE LAST REPORT 0 ``` ### w11 remarks -Requires [patch](ekbee1_patch_w11a.tcl). Still two diagnostics -``` - TMCE KT BEND DOESN'T GO LOW ON TMCD SL RED - ERRORPC TEST NUMBER - 076414 000122 - - SSRA PS RESTORE(1) DOESN'T GET TO RACK E63 - OR E63(5) BAD - ERRORPC TEST NUMBER - 077344 000124 -``` +Requires [patch](ekbee1_patch_w11a.tcl). ### SimH remarks (tested with V3.12-3 RC2) Requires [patch](ekbee1_patch_1170.scmd). diff --git a/tools/xxdp/ekbee1_patch_1170.scmd b/tools/xxdp/ekbee1_patch_1170.scmd index 9c6b2bc2..127b507c 100644 --- a/tools/xxdp/ekbee1_patch_1170.scmd +++ b/tools/xxdp/ekbee1_patch_1170.scmd @@ -1,4 +1,4 @@ -; $Id: ekbee1_patch_1170.scmd 1323 2022-12-01 08:00:41Z mueller $ +; $Id: ekbee1_patch_1170.scmd 1329 2022-12-11 17:28:28Z mueller $ ; SPDX-License-Identifier: GPL-3.0-or-later ; Copyright 2022- by Walter F.J. Mueller ; @@ -74,19 +74,20 @@ dep 056540 057120 ; Tests MMU vs NXM,ODD,RED behavior ; The 1st part tests NXM vs MMU. On a KB11-C handles NXM earlier then MMU (!) ; On a KB11-E MMU takes precedence (as one expects and SimH, e11, and w11 do). -; Patch the test such that is checks KB11-E behavior (beq 20$ -> nop) +; It is tempting to patch the code such that KB11-E behavior is tested. But +; that code path is buggy, doesn't clear MMR0, and causes a followup error in +; the following test (at 076414) because MMR0 isn't cleared. Therefore, the +; patch just inhibits the error print, and MMR0 is cleared afterwards. ; -dep 076224 000240 +dep 076300 000240 ; ; The 2nd part tests RED vs MMU. On a 11/70 the MMR0 abort bits are not set ; in case of a stack in a non-resident page with an address below STKLIM. ; Simh, e11, and w11 do set the MMR0 abort bit, and take a fatal stack error. -; Patch test to -; - change instruction under test 'clr (sp) -> clr -(sp)' -; - ignore that (beq 10$ -> br 10$). And change 'clr (sp) +; Patch test to change instruction under test 'clr (sp) -> clr -(sp)' so that +; the condition is really tested. ; dep 076366 005046 -dep 076376 000407 ; ; AP: skip test 123: SL register comparator test 2 --------------------------- ; Prints message title, but no failed combinations @@ -102,5 +103,5 @@ dep 076666 012646 ; HP: skip test 071: MMR2 pattern test --------------------------------------- ; this test tries all PC's in user mode --> skip to ease setting breakpoints ; -;; dep 057532 000137 -;; dep 057534 057766 +dep 057532 000137 +dep 057534 057766 diff --git a/tools/xxdp/ekbee1_patch_w11a.tcl b/tools/xxdp/ekbee1_patch_w11a.tcl index 7444c178..d09f7d4e 100644 --- a/tools/xxdp/ekbee1_patch_w11a.tcl +++ b/tools/xxdp/ekbee1_patch_w11a.tcl @@ -1,4 +1,4 @@ -# $Id: ekbee1_patch_w11a.tcl 1324 2022-12-01 11:24:20Z mueller $ +# $Id: ekbee1_patch_w11a.tcl 1329 2022-12-11 17:28:28Z mueller $ # SPDX-License-Identifier: GPL-3.0-or-later # Copyright 2022- by Walter F.J. Mueller # @@ -69,6 +69,24 @@ dep 055406 055554 dep 056536 000137 dep 056540 057120 # +# AP: patch test 122: KT BEND ------------------------------------------------ +# Tests MMU vs NXM,ODD,RED behavior +# The 1st part tests NXM vs MMU. On a KB11-C handles NXM earlier then MMU (!) +# On a KB11-E MMU takes precedence (as one expects and SimH, e11, and w11 do). +# It is tempting to patch the code such that KB11-E behavior is tested. But +# that code path is buggy, doesn't clear MMR0, and causes a followup error in +# the following test (at 076414) because MMR0 isn't cleared. Therefore, the +# patch just inhibits the error print, and MMR0 is cleared afterwards. +# +dep 076300 000240 +# +# The 2nd part tests RED vs MMU. On a 11/70 the MMR0 abort bits are not set +# in case of a stack in a non-resident page with an address below STKLIM. +# w11 does set the MMR0 abort bit, and take a fatal stack error. +# Patch test to ignore that (beq 10$ -> br 10$) MMR0 abort bit is set. +# MMR0 is re-written at 76444 in the following test. +# +dep 076376 000407 # # HACKS and DEBUG #