1
0
mirror of https://github.com/wfjm/w11.git synced 2026-01-13 07:29:58 +00:00

FIX: pdp11_mmu_mmr12: MMR1 write logic fix

Closes #24
This commit is contained in:
wfjm 2022-09-03 09:12:51 +02:00
parent 058f88b9a0
commit 3bd23c9cd4
4 changed files with 70 additions and 14 deletions

View File

@ -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

41
doc/ECO-032-MMR1_fix.md Normal file
View File

@ -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.

View File

@ -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

View File

@ -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 <W.F.J.Mueller@gsi.de>
--
@ -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;