From 3bd23c9cd49195cb55f522351f9f3b1831b29b71 Mon Sep 17 00:00:00 2001 From: wfjm Date: Sat, 3 Sep 2022 09:12:51 +0200 Subject: [PATCH] FIX: pdp11_mmu_mmr12: MMR1 write logic fix Closes #24 --- doc/CHANGELOG.md | 7 ++++-- doc/ECO-032-MMR1_fix.md | 41 ++++++++++++++++++++++++++++++++++++ doc/README_known_issues.md | 17 +++++++++++++++ rtl/w11a/pdp11_mmu_mmr12.vhd | 19 ++++++----------- 4 files changed, 70 insertions(+), 14 deletions(-) create mode 100644 doc/ECO-032-MMR1_fix.md diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 33be9af8..09d62a1b 100644 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -73,8 +73,11 @@ The full set of tests is only run for tagged releases. - removed designs (drop Atlys) - rtl/sys_gen/tst_rlink_cuff/atlys/sys_tst_rlink_cuff_atlys - rtl/sys_gen/tst_snhumanio/atlys/sys_tst_snhumanio_atlys - - rtl/w11a/pdp11_psr: handle pm protection like cm, for details see - [ECO-031](ECO-031-PSW_protection.md) + - rtl/w11a + - pdp11_psr: handle pm protection like cm, see + [ECO-031](ECO-031-PSW_protection.md) + - pdp11_mmu_mmr1: MMR1 write logic fix, see + [ECO-032](ECO-032-MMR1_fix.md) - general changes - segment -< page rename - DEC used in early documents 'segment', later on 'page' for the MMU object diff --git a/doc/ECO-032-MMR1_fix.md b/doc/ECO-032-MMR1_fix.md new file mode 100644 index 00000000..c425d207 --- /dev/null +++ b/doc/ECO-032-MMR1_fix.md @@ -0,0 +1,41 @@ +# ECO-032: `MMR1` write logic fix (2022-09-02) + +### Scope +- was in w11a since 2009 +- affects: all w11a systems + +### Symptom summary +Test 12 @ 042056 of ekbee1 expects after a +``` + mov #100000,@#mmr0 +``` +which sets an error bit in `MMR0` and thus freezes `MMR1`. +`MMR1` contains 013427 (00010 111 00010 111) (+2,r7;+2,r7). +w11a has 000047 (00000 000 00100 111) (--,--;+4,r7). + +### Background +`MMM1` holds the information to roll back changed registers in case of an +MMU abort. For this purpose, it doesn't matter whether the changes for a +register are lumped up or stored separately. Both possibilities fulfill +the requirements. + +### Analysis +The 11/70 Technical manual clearly states that there is an additional state +that counts the write accesses to `MMR1`. This ensures that each of the two +logged accesses end up in separate bytes (byte 0 filled first). + +The w11a added changes and only used byte 1 when the register number +differed. SimH doesn't use a state bit, it writes to the upper byte +when the lower byte is non-zero +``` + #define calc_MMR1(val) ((reg_mods)? (((val) << 8) | reg_mods): (val)) +``` + +### Fixes +- remove adder logic in pdp11_mmu_mmr1 +- use SimH logic, write to upper half if lower != 0 +- that's functionally equivalent to the 11/70 logic but saves a state bit + +### Hindsight +Took 13 years to fix. No OS depends on this detail, only test codes +will probe the difference. diff --git a/doc/README_known_issues.md b/doc/README_known_issues.md index 21a6f0c5..b6651f8c 100644 --- a/doc/README_known_issues.md +++ b/doc/README_known_issues.md @@ -2,6 +2,23 @@ The case id indicates the release when the issue was first recognized. +### V0.791-1 {[issue #33](https://github.com/wfjm/w11/issues/33)} -- MMU: PDR A bit is set for every access + +The `PDR` `A` bit is described in the Technical Manual as +> A bit (bit 7) - This bit is used by software to determine whether or not +> any accesses to this page met the trap condition specified by the Access +> Control Field (ACF). (A = I is affirmative). The A bit is used in the +> process of gathering Memory Management statistics. + +It is set when the page `ACF` enables an MMU trap, thus for +- ACF=1 and read access +- ACF=4 and any access +- ACF=5 and write access + +The w11 currently sets the 'A' bit on any non-aborted access regardless of the ACF value. + +No practical impact, the 'A' bit in `PDR` is a 11/45 11/70 only feature and not used in OS software. + ### V0.79-2 {[issue #30](https://github.com/wfjm/w11/issues/30)} -- SimH scmd files fail on current 4.* version; only 3.* supported The SimH scmd scripts were originally developed for SimH 3.8, and worked for diff --git a/rtl/w11a/pdp11_mmu_mmr12.vhd b/rtl/w11a/pdp11_mmu_mmr12.vhd index e21e33c5..08ce7f4b 100644 --- a/rtl/w11a/pdp11_mmu_mmr12.vhd +++ b/rtl/w11a/pdp11_mmu_mmr12.vhd @@ -1,4 +1,4 @@ --- $Id: pdp11_mmu_mmr12.vhd 1279 2022-08-14 08:02:21Z mueller $ +-- $Id: pdp11_mmu_mmr12.vhd 1291 2022-09-03 07:00:27Z 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-08-30 1291 1.2.4 use ra_delta to steer mmr1 updates -- 2022-08-13 1279 1.2.3 ssr->mmr rename -- 2011-11-18 427 1.2.2 now numeric_std clean -- 2010-10-23 335 1.2.1 use ib_sel @@ -122,7 +123,6 @@ begin variable nmmr1 : mmu_mmr1_type := mmu_mmr1_init; variable nmmr2 : slv16 := (others=>'0'); variable delta : slv5 := (others=>'0'); - variable use_rb : slbit := '0'; begin @@ -130,11 +130,6 @@ begin nmmr2 := R_MMR2; delta := "0" & MONI.delta; - use_rb := '0'; - if MONI.regnum/=nmmr1.ra_num and unsigned(nmmr1.ra_delta)/=0 then - use_rb := '1'; - end if; - if CRESET = '1' then nmmr1 := mmu_mmr1_init; nmmr2 := (others=>'0'); @@ -157,19 +152,19 @@ begin nmmr2 := MONI.pc; elsif MONI.regmod = '1' then - if use_rb = '0' then + if R_MMR1.ra_delta = "00000" then nmmr1.ra_num := MONI.regnum; if MONI.isdec = '0' then - nmmr1.ra_delta := slv(signed(nmmr1.ra_delta) + signed(delta)); + nmmr1.ra_delta := delta; else - nmmr1.ra_delta := slv(signed(nmmr1.ra_delta) - signed(delta)); + nmmr1.ra_delta := slv(-signed(delta)); end if; else nmmr1.rb_num := MONI.regnum; if MONI.isdec = '0' then - nmmr1.rb_delta := slv(signed(nmmr1.rb_delta) + signed(delta)); + nmmr1.rb_delta := delta; else - nmmr1.rb_delta := slv(signed(nmmr1.rb_delta) - signed(delta)); + nmmr1.rb_delta := slv(-signed(delta)); end if; end if; end if;