// VMemExtra.bcpl. virtual memory package debugging // Last modified May 25, 1983 11:21 AM by Bill van Melle // Last modified June 25, 1982 2:42 PM by Bill van Melle // Last modified March 29, 1982 2:56 PM by Bill van Melle get "LispBcpl.decl" get "Stats.decl" get "VMem.decl" external [ // defined here CheckMap; MapCheck1; MapCheck2; PrintPageTable // OS procedures Endofs; Gets; Resets Random // Other procs used BP; VP; VP2; Bytes2; MkSmallPos // Raid procs Ws; Wo; Wn; Wc; CRLF; RaidReset; PrintPtr; RAIDCode; GetFXP // Statics keys @lvNIL; @lvKT insideRaid; EmulatorSpace; LastRealPageNo crCount; @RMSK // Other external VMem procs (from VmemA.asm) ReadFlags // (VP) -> oldflags ReadRP // (VP) -> RP SetFlags // (VP, RP, flags) ] let CheckMap() be [ Ws (" for ") switchon Gets(keys) into [ case $C: case $c: [ Ws ("Consistency*N") MapCheck0() return ] case $R: case $r: [ Ws ("at Random*N") MapCheck2() return ] case $S: case $s: [ Ws ("Swap buffer*N") MapCheck1() return ] case $?:[ Ws ("*NConsistency, Swapbuffer, Random*N Check Map") endcase ] default: Ws ("??") Resets(keys) ] ] repeat and MapCheck0() be [ let errorcnt = 0 // first test that every vp in Bpt maps to the // real page we think it does for i = 1 to BptSize-1 do [ let bp = BP(i) // entry in Bpt if bp>>BPT.STATE ls EMPTY then [ let rp = ReadRP (bp>>BPT.VP) if rp ne (i + RPoffset) then [ MapError (bp>>BPT.VP, i+RPoffset, rp) errorcnt = errorcnt+1 ] ] ] // now for all 2↑14 virtual pages, check that those // that are non-vacant map to what we say they do for seg = 0 to LastVirtualPage<<VP.segment do test seg eq EmulatorSpace ifso for p = 0 to PagesPerSegment-1 do [ // emulator pages are not in Bpt, // but implicitly map to self let vp = Bytes2 (EmulatorSpace, p) test (ReadFlags (vp) & VACANT) eq VACANT ifso [ CRLF() Ws ("Error: Emulator page ") Wo (p) Ws (" is marked vacant") errorcnt = errorcnt+1 ] ifnot [ let rp = ReadRP (vp) let myrp = p + RPoffset - (PagesPerSegment-1) // because RPoffset = realpage0+PagesPerSegment-1 if rp ne myrp then [ MapError (vp, myrp, rp) errorcnt = errorcnt+1 ] ] ] ifnot for p = 0 to PagesPerSegment-1 do [ let vp = Bytes2(seg, p) let flags = ReadFlags (vp) if (ReadFlags (vp) & VACANT) ne VACANT then [ let rp = ReadRP(vp) let bp = BP(rp-RPoffset) if bp>>BPT.VP ne vp then [ MapError2 (vp, rp, bp>>BPT.VP) errorcnt = errorcnt+1 ] ] ] CRLF() Wn (errorcnt, 10) Ws (" errors detected") CRLF() ] and MapError (vp, myrp, maprp) be [ CRLF() Ws ("Error for virtual page ") Wo (vp); CRLF() Ws (" Fault software says real page = ") Wo (myrp) Ws (", hardware map says ") Wo (maprp) ] and MapError2 (vp, maprp, myvp) be [ CRLF() Ws ("Error for virtual page ") Wo (vp); CRLF() Ws (" Hardware says real page = ") Wo (maprp) Ws (", software map says that page") test myvp ls LastVirtualPage ifso [ Ws (" belongs to vp "); Wo (myvp) ] ifnot Ws ( myvp eq (EMPTY lshift 8) ? " is empty", myvp eq (UNAVAIL lshift 8) ? " is unavailable", " is confused") ] and MapCheck1 () be [ Ws ("*NTesting MAP for swap buffer page") let thous = 0 let NErrors = 0 [ for J = 1 to 10 do [ for I = 1 to 1000 do [ let rp = Random() & #7777 SetFlags(BufVp, rp, OCCUPIED) let newrp = ReadRP(BufVp) if newrp ne rp then [ CRLF(); Ws ("Wrote "); Wo(rp) Ws (", read "); Wo(newrp); NErrors = NErrors+1 ] ] Ws(".") ] thous = thous+1 crCount = 1 // inhibit scroll holding Wn (thous, 10) if NErrors then [ Ws("!"); Wn(NErrors, 10) ] ] repeatwhile (Endofs(keys)) % (Gets(keys) eq #40) // do until keyboard input, not space SetFlags(BufVp, BufRP, OCCUPIED) CRLF() Wn (NErrors) Ws (" errors detected") CRLF() ] and MapCheck2 () be [ Ws ("*NTesting MAP at random") let thous = 0 let NErrors = 0 [ for J = 1 to 10 do [ for I = 1 to 1000 do [ let vp = Random() & #37777 if ((vp rshift 8) eq EmulatorSpace) & (vp ne BufVp) then loop // don't remap emulator pages: could kill us let oldrp = ReadRP(vp) let oldflags = ReadFlags(vp) let rp = Random() & #7777 SetFlags(vp, rp, OCCUPIED) let newrp = ReadRP(vp) if newrp ne rp then [ Ws ("*NWrote "); Wo(rp) Ws (", read "); Wo(newrp); NErrors = NErrors+1 ] SetFlags (vp, oldrp, oldflags) ] Ws(".") ] crCount = 1 // inhibit scroll holding thous = thous+1 Wn (thous, 10) if NErrors then [ Ws("!"); Wn(NErrors, 10) ] ] repeatwhile (Endofs(keys)) % (Gets(keys) eq #40) // do until keyboard input, not space CRLF() Wn (NErrors) Ws (" errors detected") CRLF() ] and PrintPageTable() be [ let oldstate, start = 0, 0 let n = RPoffset let bp = Bpt // start of page table: dummy entry Ws ("Real pg virtual page flags") CRLF() [ n = n+1 bp = bp+3 // 3 words per entry let state = bp>>BPT.STATE if oldstate & ((state ne oldstate) % (n ge LastRealPageNo)) then [ Wo (start) // show range of pages if start ne n-1 then [ Ws(" thru "); Wo(n-1) ] Ws (oldstate eq EMPTY? " empty", " unavailable") CRLF() oldstate, start = 0, 0 ] if n ge LastRealPageNo then break test state ge EMPTY ifso [ // no vp here, collapse maybe if oldstate eq 0 then [ oldstate = state; start = n ] ] ifnot [ Wo(n); Wc($*S) let vp = bp>>BPT.VP Wo(vp); Ws (" ("); Wo(vp rshift 8, true); Wc($,) // translate to seg, page# Wo(vp & RMSK, true); Ws (") "); Wc(9) if bp>>BPT.LOCK then Ws (" locked") let flags = ReadFlags(vp) if (flags & REFbit) ne 0 then Ws (" ref") if (flags & DIRTYbit) ne 0 then Ws (" dirty") CRLF() ] ] repeat ]