mirror of
https://github.com/wfjm/w11.git
synced 2026-01-13 15:37:43 +00:00
1647 lines
63 KiB
Plaintext
1647 lines
63 KiB
Plaintext
; $Id: cpu_details.mac 1332 2022-12-21 11:56:32Z mueller $
|
|
; SPDX-License-Identifier: GPL-3.0-or-later
|
|
; Copyright 2022- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
|
;
|
|
; Revision History:
|
|
; Date Rev Version Comment
|
|
; 2022-12-10 1329 1.0 Initial version
|
|
; 2022-07-18 1259 0.1 First draft
|
|
;
|
|
; Test CPU details
|
|
; Section A: CPU registers
|
|
; Section B: stress tests
|
|
; Section C: 11/70 specifics
|
|
;
|
|
.include |lib/tcode_std_base.mac|
|
|
.include |lib/defs_mmu.mac|
|
|
;
|
|
; Preface: set up MMU for kernel mode (for some tests) =======================
|
|
;
|
|
mov #kipdr,r0
|
|
mov #<127.*md.plf>!md.arw,r1 ; plf=127; ed=0(up); acf=6(w/r)
|
|
mov r1,(r0)+ ; kipdr0
|
|
mov r1,(r0)+ ; kipdr1
|
|
mov r1,(r0)+ ; kipdr2
|
|
mov r1,(r0)+ ; kipdr3
|
|
mov r1,(r0)+ ; kipdr4
|
|
mov r1,(r0)+ ; kipdr5
|
|
mov r1,(r0)+ ; kipdr6
|
|
mov r1,(r0)+ ; kipdr7
|
|
mov #kipar,r0
|
|
mov #000000,(r0)+ ; kipar0 000000 base
|
|
mov #000200,(r0)+ ; kipar1 020000 base
|
|
mov #000400,(r0)+ ; kipar2 040000 base
|
|
mov #000600,(r0)+ ; kipar3 060000 base
|
|
mov #001000,(r0)+ ; kipar4 100000 base
|
|
mov #001200,(r0)+ ; kipar5 120000 base
|
|
mov #001400,(r0)+ ; kipar6 140000 base
|
|
mov #177600,(r0)+ ; kipar7 (map I/O page)
|
|
;
|
|
; some useful definitions
|
|
kipdr5 = kipdr+12
|
|
kipdr6 = kipdr+14
|
|
kipar6 = kipar+14
|
|
p6base = <6*20000> ; page 6
|
|
;
|
|
; Section A: CPU registers ===================================================
|
|
; A1 PIRQ
|
|
; A1.1 PIRQ + spl
|
|
; A1.2 PIRQ and immediate interrupt
|
|
; A2 CPUERR
|
|
; A2.1 CPUERR cp.hlt
|
|
; A2.2 CPUERR cp.odd
|
|
; A2.3 CPUERR cp.nxm
|
|
; A2.4 CPUERR cp.iot
|
|
; A2.5 CPUERR cp.ysv
|
|
; A2.6 CPUERR cp.rsv
|
|
; A2.7 CPUERR cp.odd + stack error
|
|
; A2.8 CPUERR cp.nxm + stack error
|
|
; A2.9 CPUERR cp.ito + stack error
|
|
; A2.10 CPUERR mmu abort + stack error
|
|
; A3 STKLIM + stack traps and aborts
|
|
; A3.1 STKLIM write/read test
|
|
; A3.2 yellow trap + red abort boundary
|
|
; part 1: sequence of yellow traps and a final red stack abort
|
|
; part 2: check that red zone does not have yellow islands
|
|
; part 3: check red zone PSW protection
|
|
; A3.3 stack trap conditions
|
|
; part 1: test instructions that should trap
|
|
; 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)
|
|
; part 2: PSW(11) - register set
|
|
; part 3: PSW(cm) and stack registers
|
|
; A4.2 PSW write/read via RTI/RTT
|
|
; part 1: from cm=0,rset=0: set cm=11 and rset=1 (fine!)
|
|
; part 2: from cm=s,rset=1 mode: set cm=0 and rset=0 (fail!)
|
|
; part 3: from cm=s,rset=0 mode: set cm=u and rset=1 (fine!)
|
|
; part 4: from cm=u,rset=1 mode: set cm=0 and rset=0 (fail!)
|
|
; A4.3 RTI/RTT tbit basics
|
|
; part 1: tbit after RTI
|
|
; part 2: tbit after RTT
|
|
; A4.4 Test A4.4 -- tbit trace tests
|
|
; part 1: simple instruction sequence
|
|
; part 2: tracing of trap instructions (EMT tested)
|
|
; part 3: tbit vs interrupt precedence (via PIRQ)
|
|
; part 4: traced WAIT and tbit
|
|
; part 5: WAIT and SPL in user mode
|
|
; part 6: tbit trap after continuation over s_idle
|
|
; part 7: no tbit trap after an abort
|
|
;
|
|
; Test A1: PIRQ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
; This sub-section verifies operation of PIRQ register
|
|
;
|
|
; Test A1.1 -- PIRQ + spl ++++++++++++++++++++++++++++++++++++++++++++
|
|
; This test will exercise all 7 pirq interrupt levels:
|
|
; set 1+3 -> handle 3, set 7
|
|
; -> handle 7, set 6+4
|
|
; -> handle 6
|
|
; -> handle 4, set 5+2
|
|
; -> handle 5
|
|
; -> handle 2
|
|
; -> handle 1
|
|
;
|
|
; some useful definitions
|
|
pi.r00=bit08 ; pir 0 bit
|
|
pi.r01=bit09 ; pir 1 bit
|
|
pi.r02=bit10 ; pir 2 bit
|
|
pi.r03=bit11 ; pir 3 bit
|
|
pi.r04=bit12 ; pir 4 bit
|
|
pi.r05=bit13 ; pir 5 bit
|
|
pi.r06=bit14 ; pir 6 bit
|
|
pi.r07=bit15 ; pir 7 bit
|
|
pi.n00=0. ; lsb for no pir pending
|
|
pi.n01=1*042 ; lsb for pir 1 next
|
|
pi.n02=2*042 ; lsb for pir 2 next
|
|
pi.n03=3*042 ; lsb for pir 3 next
|
|
pi.n04=4*042 ; lsb for pir 4 next
|
|
pi.n05=5*042 ; lsb for pir 5 next
|
|
pi.n06=6*042 ; lsb for pir 6 next
|
|
pi.n07=7*042 ; lsb for pir 7 next
|
|
;
|
|
ta0101: mov #1000$,v..pir ; set up handler
|
|
mov #cp.pr7,v..pir+2 ; which runs at pr7
|
|
mov #cp.pir,r3 ; ptr to PIRQ
|
|
mov #cp.psw,r4 ; ptr to PSW
|
|
mov #1200$,r5 ; ptr to check data
|
|
clr 1300$ ; clear nesting counter
|
|
;
|
|
spl 7 ; lockout interrupts
|
|
bisb #bit01,1(r3) ; set PIRQ 1
|
|
hcmpeq (r3),#<pi.r01!pi.n01> ; check set 1
|
|
bisb #bit03,1(r3) ; set PIRQ 3
|
|
hcmpeq (r3),#<pi.r01!pi.r03!pi.n03> ; check set 1+3
|
|
spl 2
|
|
nop ; allow interrupts to happen
|
|
spl 0
|
|
nop ; allow interrupts to happen
|
|
htsteq (r3) ; PIRQ should clear now
|
|
mov #v..pir+2,v..pir; restore pirq vector catcher
|
|
clr v..pir+2
|
|
jmp 9999$
|
|
;
|
|
; PIRQ interrupt handler
|
|
; - it starts at pr7 from the vector
|
|
; - quickly lowers the priority to what is currently processed
|
|
; - new pirq bits are set at lowered priority
|
|
; - that leads to nested interrupts (tracked by a level counter)
|
|
;
|
|
1000$: inc 1300$ ; up level counter
|
|
mov (r3),r0 ; get PIRQ value
|
|
hcmpeq 1300$,(r5)+ ; check nesting level
|
|
hcmpeq r0,(r5)+ ; check pirq value
|
|
movb r0,(r4) ; PSW=PIRQ (sets priority)
|
|
bic #177761,r0 ; mask out index bits
|
|
mov r0,r1 ; r0 is word index (pri*2)
|
|
asr r1 ; r1 is byte index (pri*1)
|
|
mov #pi.r00,r2
|
|
ash r1,r2 ; r2 = pi.r00 <<(pri)
|
|
bic r2,(r3) ; clear current level in pirq
|
|
bis 1100$(r0),(r3) ; trigger new pirqs
|
|
nop ; allow nested interrupts to happen
|
|
nop ;
|
|
dec 1300$ ; down level counter
|
|
rti
|
|
;
|
|
; table with new pirqs triggered at a level
|
|
1100$: .word 0 ; new pirq @ level 0
|
|
.word 0 ; new pirq @ level 1
|
|
.word 0 ; new pirq @ level 2
|
|
.word pi.r07 ; new pirq @ level 3 -> 7
|
|
.word pi.r05!pi.r02 ; new pirq @ level 4 -> 5+2
|
|
.word 0 ; new pirq @ level 5
|
|
.word 0 ; new pirq @ level 6
|
|
.word pi.r06!pi.r04 ; new pirq @ level 7 -> 6+4
|
|
;
|
|
; table with expected values of pirq register in interrupt sequence
|
|
1200$: .word 1,pi.r01!pi.r03!pi.n03 ; set 1+3 -> handle 3, set 7
|
|
.word 2,pi.r01!pi.r07!pi.n07 ; set 1+7 -> handle 7, set 6+4
|
|
.word 2,pi.r01!pi.r04!pi.r06!pi.n06 ; set 1+4+6 -> handle 6
|
|
.word 2,pi.r01!pi.r04!pi.n04 ; set 1+4 -> handle 4, set 5+2
|
|
.word 3,pi.r01!pi.r02!pi.r05!pi.n05 ; set 1+2+5 -> handle 5
|
|
.word 1,pi.r01!pi.r02!pi.n02 ; set 1+2 -> handle 2
|
|
.word 1,pi.r01!pi.n01 ; set 1 -> handle 1
|
|
; nesting level counter
|
|
1300$: .word 0
|
|
;
|
|
9999$: iot ; end of test A1.1
|
|
;
|
|
; Test A1.2 -- PIRQ and immediate interrupt ++++++++++++++++++++++++++
|
|
; This test verifies that an interrupt is taken immediately after the
|
|
; write of the PIRQ register
|
|
;
|
|
ta0102: spl 0 ; ensure execution at PR0
|
|
mov #1000$,v..pir ; set up handler
|
|
mov #cp.pr7,v..pir+2 ; which runs at pr7
|
|
mov #pi.r03,cp.pir ; request PIRQ 3
|
|
halt ; halt if not taken immediatly
|
|
;
|
|
1000$: clr cp.pir ; cancel all PIRQ levels
|
|
mov #1100$,(sp) ; continue
|
|
rti
|
|
;
|
|
1100$: mov #v..pir+2,v..pir; restore pirq vector catcher
|
|
clr v..pir+2
|
|
;
|
|
9999$: iot ; end of test A1.2
|
|
;
|
|
; Test A2: CPUERR +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
; This sub-section verifies operation of CPUERR register
|
|
;
|
|
; setup for all A2.* tests
|
|
mov #cp.err,r0 ; ptr tp CPUERR
|
|
mov #vhugen,v..iit ; set iit handler
|
|
clr v..iit+2 ; pr0 kernel
|
|
;
|
|
; Test A2.1 -- CPUERR cp.hlt +++++++++++++++++++++++++++++++++++++++++
|
|
; Test cp.hlt: halt in non-kernel mode
|
|
;
|
|
ta0201: mov #177777,(r0) ; clear CPUERR (any write should)
|
|
htsteq (r0) ; ensure that CPUERR is zero
|
|
;
|
|
mov #4000$,r2 ; mode list (user,supervisor)
|
|
mov #2,r3 ; number of modes
|
|
;
|
|
1000$: clr r1 ; clear tracer
|
|
mov #3000$,vhustp ; continuation address
|
|
push (r2)+ ; frame: psw
|
|
push #2000$ ; frame: address
|
|
rti ; start user mode code
|
|
halt
|
|
;
|
|
2000$: inc r1 ; proof of execution
|
|
halt ; that will abort
|
|
inc r1
|
|
tst @#001 ; that must abort
|
|
;
|
|
3000$: hcmpeq r1,#1 ; check tracer
|
|
hcmpeq (r0),#cp.hlt ; check CPUERR
|
|
mov #cp.rsv,(r0) ; clear CPUERR (any write should)
|
|
htsteq (r0) ; check CPUERR
|
|
;
|
|
sob r3,1000$ ; go for next mode
|
|
;
|
|
br 9999$
|
|
;
|
|
4000$: .word <cp.cmu!cp.pmu> ; user mode
|
|
.word <cp.cms!cp.pms> ; supervisor mode
|
|
;
|
|
9999$: iot ; end of test A2.1
|
|
;
|
|
; Test A2.2 -- CPUERR cp.odd +++++++++++++++++++++++++++++++++++++++++
|
|
; Test cp.odd: odd address error abort
|
|
;
|
|
ta0202: mov #1000$,vhustp ; continuation address
|
|
tst @#001 ; odd address access
|
|
halt
|
|
1000$: hcmpeq (r0),#cp.odd ; check CPUERR
|
|
clr (r0) ; clear CPUERR (any write should)
|
|
htsteq (r0) ; check CPUERR
|
|
;
|
|
9999$: iot ; end of test A2.2
|
|
;
|
|
; Test A2.3 -- CPUERR cp.nxm +++++++++++++++++++++++++++++++++++++++++
|
|
; Test cp.nxm: non-existent memory abort
|
|
; Use unibus map address space (248kB) below the I/O page, the w11
|
|
; will return a non-existent memory abort even in a maximum memory
|
|
; configuration.
|
|
;
|
|
ta0203: cmpb systyp,#sy.e11 ; e11 V7.3 return wrong CPUERR value
|
|
beq 9999$
|
|
push kipar6 ; save kipar6
|
|
mov #177400,kipar6
|
|
mov #m3.e22,mmr3 ; 22-bit mode
|
|
mov #m0.ena,mmr0 ; enable mmu ;! MMU 22
|
|
;
|
|
mov #1000$,vhustp ; continuation address
|
|
tst p6base ; access non-existing memory
|
|
halt
|
|
1000$: hcmpeq (r0),#cp.nxm ; check CPUERR
|
|
com (r0) ; clear CPUERR (any write should)
|
|
htsteq (r0) ; check CPUERR
|
|
;
|
|
reset ; disable mmu ;! MMU off
|
|
pop kipar6 ; restore kipar6
|
|
9999$: iot ; end of test A2.3
|
|
;
|
|
; Test A2.4 -- CPUERR cp.ito +++++++++++++++++++++++++++++++++++++++++
|
|
; Test cp.ito: unibus timeout abort
|
|
; Use first address in I/O page (160000), always unused in w11
|
|
;
|
|
ta0204: mov #1000$,vhustp ; continuation address
|
|
tst @#160000 ; access non-existing unibus device
|
|
halt
|
|
1000$: hcmpeq (r0),#cp.ito ; check CPUERR
|
|
clr (r0) ; clear CPUERR (any write should)
|
|
htsteq (r0) ; check CPUERR
|
|
;
|
|
9999$: iot ; end of test A2.4
|
|
;
|
|
; Test A2.5 -- CPUERR cp.ysv +++++++++++++++++++++++++++++++++++++++++
|
|
; Test cp.ysv: yellow stack trap
|
|
; Since stack is still usable after the trap, the vhugen handler can be used.
|
|
;
|
|
ta0205: cmpb systyp,#sy.e11 ; e11 V7.3 doesnt trap, runs on hold
|
|
beq 9999$
|
|
mov #1000$,vhustp ; continuation address
|
|
mov #400,sp
|
|
clr -(sp) ; should trap (not abort)
|
|
halt ; not executed, handler continues at 1000$
|
|
1000$: hcmpeq (r0),#cp.ysv ; check CPUERR
|
|
clr (r0) ; clear CPUERR (any write should)
|
|
htsteq (r0) ; check CPUERR
|
|
;
|
|
mov #stack,sp
|
|
9999$: iot ; end of test A2.5
|
|
;
|
|
; Test A2.6 -- CPUERR cp.rsv +++++++++++++++++++++++++++++++++++++++++
|
|
; Test cp.rsv: red stack trap - simple low stack case
|
|
;
|
|
ta0206: cmpb systyp,#sy.e11 ; e11 V7.3 doesnt abort, runs on hold
|
|
beq 9999$
|
|
mov #1000$,v..iit ; setup direct iit handler
|
|
mov #340,sp
|
|
clr -(sp) ; should abort (not trap)
|
|
halt
|
|
1000$: htsteq sp ; check SP=0
|
|
hcmpeq (r0),#cp.rsv ; check CPUERR
|
|
clr (r0) ; clear CPUERR (any write should)
|
|
htsteq (r0) ; check CPUERR
|
|
mov #stack,sp ; restore stack
|
|
;
|
|
9999$: iot ; end of test A2.6
|
|
;
|
|
; Test A2.7 -- CPUERR cp.odd + stack error +++++++++++++++++++++++++++
|
|
; Test cp.odd: fatal stack error after odd stack
|
|
;
|
|
ta0207: cmpb systyp,#sy.e11 ; e11 V7.3 pushes to odd stack, abort after halt
|
|
beq 9999$
|
|
cmpb systyp,#sy.sih ; SimH uses J11 semantics
|
|
bne 100$
|
|
mov #<cp.rsv+cp.odd>,1010$+2 ; and sets rsv for all stack errors
|
|
;
|
|
100$: mov #1000$,v..iit ; setup direct iit handler
|
|
mov #stack-1,sp
|
|
clr -(sp) ; odd-address abort, fatal stack error
|
|
halt
|
|
1000$: htsteq sp ; check SP=0
|
|
1010$: hcmpeq (r0),#<cp.rsv+cp.odd> ; check CPUERR
|
|
clr (r0) ; clear CPUERR (any write should)
|
|
htsteq (r0) ; check CPUERR
|
|
mov #stack,sp ; restore stack
|
|
;
|
|
9999$: iot ; end of test A2.7
|
|
;
|
|
; Test A2.8 -- CPUERR cp.nxm + stack error +++++++++++++++++++++++++++
|
|
; Test cp.nxm: fatal stack error after non-existent memory abort
|
|
; Setup like in A2.3, put stack at p6base+4
|
|
;
|
|
ta0208: cmpb systyp,#sy.e11 ; e11 V7.3 pushes to bad stack, abort after halt
|
|
beq 9999$
|
|
cmpb systyp,#sy.sih ; SimH uses J11 semantics
|
|
bne 100$
|
|
mov #<cp.rsv+cp.nxm>,1010$+2 ; and sets rsv for all stack errors
|
|
;
|
|
100$: mov #1000$,v..iit ; setup direct iit handler
|
|
mov #177400,kipar6
|
|
mov #m3.e22,mmr3 ; 22-bit mode
|
|
mov #m0.ena,mmr0 ; enable mmu ;! MMU 22
|
|
;
|
|
mov #p6base+4,sp ; stack in non-existing memory
|
|
clr -(sp) ; non-existing memory, fatal stack error
|
|
halt
|
|
1000$: htsteq sp ; check SP=0
|
|
1010$: hcmpeq (r0),#<cp.rsv+cp.nxm> ; check CPUERR
|
|
clr (r0) ; clear CPUERR (any write should)
|
|
htsteq (r0) ; check CPUERR
|
|
mov #stack,sp ; restore stack
|
|
;
|
|
reset ;! MMU off
|
|
mov #001400,kipar6 ; restore kipar6
|
|
;
|
|
9999$: iot ; end of test A2.8
|
|
;
|
|
; Test A2.9 -- CPUERR cp.ito + stack error +++++++++++++++++++++++++++
|
|
; Test cp.ito: fatal stack error after unibus timeout
|
|
; Setup like in A2.4, put stack at 160004
|
|
;
|
|
ta0209: cmpb systyp,#sy.e11 ; e11 V7.3 pushes to bad stack, abort after halt
|
|
beq 9999$
|
|
cmpb systyp,#sy.sih ; SimH uses J11 semantics
|
|
bne 100$
|
|
mov #<cp.rsv+cp.ito>,1010$+2 ; and sets rsv for all stack errors
|
|
;
|
|
100$: mov #1000$,v..iit ; setup direct iit handler
|
|
mov #160004,sp ; stack at non-existing unibus device
|
|
clr -(sp) ; non-existing memory, fatal stack error
|
|
halt
|
|
1000$: htsteq sp ; check SP=0
|
|
1010$: hcmpeq (r0),#<cp.rsv+cp.ito> ; check CPUERR
|
|
clr (r0) ; clear CPUERR (any write should)
|
|
htsteq (r0) ; check CPUERR
|
|
mov #stack,sp ; restore stack
|
|
;
|
|
9999$: iot ; end of test A2.9
|
|
;
|
|
; Test A2.10 -- CPUERR mmu abort + stack error +++++++++++++++++++++++
|
|
; Test cp.rsv: fatal stack error after mmu abort
|
|
; Set kernel I page 6 to non-resident
|
|
;
|
|
ta0210: cmpb systyp,#sy.sih ; SimH uses J11 semantics
|
|
bne 100$
|
|
mov #cp.rsv,1010$+2 ; and sets rsv for all stack errors
|
|
;
|
|
100$: mov #1000$,v..iit ; setup direct iit handler
|
|
clr kipdr6 ; set non-resident
|
|
mov #m3.e22,mmr3 ; 22-bit mode
|
|
mov #m0.ena,mmr0 ; enable mmu ;! MMU 22
|
|
;
|
|
mov #p6base+4,sp ; stack in non-resident memory
|
|
clr -(sp) ; MMU abort, fatal stack error
|
|
halt
|
|
1000$: htsteq sp ; check SP=0
|
|
1010$: hcmpeq (r0),#cp.rsv ; check CPUERR
|
|
clr (r0) ; clear CPUERR (any write should)
|
|
htsteq (r0) ; check CPUERR
|
|
mov #stack,sp ; restore stack
|
|
;
|
|
reset ;! MMU off
|
|
mov kipdr5,kipdr6 ; restore kipdr6 (default kipdr are identical)
|
|
;
|
|
9999$: iot ; end of test A2.10
|
|
;
|
|
; -----------------------------------------------
|
|
; end of A2.* tests, restore iit handler
|
|
mov v..iit+2,v..iit ; restore iit handler
|
|
;
|
|
; Test A3: STKLIM + stack traps and aborts ++++++++++++++++++++++++++++++++++
|
|
; This sub-section verifies operation of STKLIM register,
|
|
; the yellow stack trap, and the red stack abort functionality.
|
|
;
|
|
; Test A3.1 -- STKLIM write/read test ++++++++++++++++++++++++++++++++
|
|
; STKLIM is a 16 bit register, upper byte is retained, lower reads always 0
|
|
;
|
|
ta0301:
|
|
;
|
|
; part 1: word access ------------------------------------------------
|
|
;
|
|
mov #1000$,r0 ; ptr to value list
|
|
mov #<1010$-1000$>/2,r1 ; # of values
|
|
mov #377,r2 ; LSB byte mask
|
|
mov #cp.slr,r3 ; ptr to STKLIM
|
|
;
|
|
100$: mov (r0)+,r4 ; get value
|
|
mov r4,(r3) ; load STKLIM
|
|
bic r2,r4 ; clear LSB
|
|
hcmpeq r4,(r3) ; read and ckeck STKLIM
|
|
sob r1,100$ ; go for next STKLIM value
|
|
br 2000$
|
|
;
|
|
1000$: .word ^b0101010101010101
|
|
.word ^b1010101010101010
|
|
.word ^b0000000011001100 ; STKLIM = 0 at end of test
|
|
1010$:
|
|
;
|
|
; part 2: byte access ------------------------------------------------
|
|
;
|
|
2000$: movb #7,1(r3) ; write MSB
|
|
hcmpeq #3400,(r3) ; check MSB written
|
|
movb #70,(r3) ; write LSB
|
|
hcmpeq #3400,(r3) ; check MSB unchanged
|
|
clr (r3) ; STKLIM to default
|
|
;
|
|
9999$: iot ; end of test A3.1
|
|
;
|
|
; Test A3.2 -- yellow trap + red abort boundary ++++++++++++++++++++++
|
|
;
|
|
ta0302:
|
|
;
|
|
; part 1: sequence of yellow traps and a final red stack abort -------
|
|
; Verifies that push to STKLIM+376 to STKLIM+344 causes a yellow stack
|
|
; trap and a push to STKLIM+342 succeeds, but the yellow stack trap flow
|
|
; fails and causes a red stack trap. Done for
|
|
; 0 yellow below 000400
|
|
; 1400 yellow below 002000
|
|
; 157400 yellow below 156000
|
|
;
|
|
; Note: SimH has simplified stack limit testing in vector flows.
|
|
; The stack is checked at end of flow. SimH will happily
|
|
; do yellow trap after push to +342 and write into +336.
|
|
; This part is therefore skipped for SimH
|
|
;
|
|
cmpb systyp,#sy.sih ; on SimH ?
|
|
bne 10$ ; if not, execute
|
|
jmp 2000$ ; if yes, skip
|
|
;
|
|
10$: mov #1200$,r0 ; ptr to value list
|
|
mov #<1210$-1200$>/2,r1 ; # of values
|
|
mov #1000$,v..iit ; set up iit handler
|
|
mov #cp.pr3,v..iit+2 ; use pr3 as handler signature
|
|
;
|
|
100$: spl 6 ; use pr6 as code signature
|
|
mov (r0)+,r5 ; get value
|
|
mov r5,cp.slr ; load STKLIM
|
|
clr 336(r5) ; clear word on red boundary
|
|
mov r5,sp ; load SP
|
|
add #400,sp ; to yellow boundary
|
|
clr r2 ; clear yellow trap counter
|
|
mov #1.,-(sp) ; push to STKLIM+376 -> trap
|
|
mov #2.,-(sp) ; push to STKLIM+374 -> trap
|
|
mov #3.,-(sp) ; push to STKLIM+372 -> trap
|
|
mov #4.,-(sp) ; push to STKLIM+370 -> trap
|
|
mov #5.,-(sp) ; push to STKLIM+366 -> trap
|
|
mov #6.,-(sp) ; push to STKLIM+364 -> trap
|
|
mov #7.,-(sp) ; push to STKLIM+362 -> trap
|
|
mov #8.,-(sp) ; push to STKLIM+360 -> trap
|
|
mov #9.,-(sp) ; push to STKLIM+356 -> trap
|
|
mov #10.,-(sp) ; push to STKLIM+354 -> trap
|
|
mov #11.,-(sp) ; push to STKLIM+352 -> trap
|
|
mov #12.,-(sp) ; push to STKLIM+350 -> trap
|
|
mov #13.,-(sp) ; push to STKLIM+346 -> trap
|
|
mov #14.,-(sp) ; push to STKLIM+344 -> trap
|
|
mov #15.,-(sp) ; push to STKLIM+342 -> try trap->abort
|
|
200$: halt
|
|
halt
|
|
;
|
|
1000$: tst sp ; red abort seen ?
|
|
beq 1010$ ; if yes, check status
|
|
inc r2 ; if no, got for next push
|
|
rti
|
|
;
|
|
1010$: hcmpeq #14.,r2 ; all traps taken ?
|
|
hcmpeq #13.,346(r5) ; check 13th push
|
|
hcmpeq #14.,344(r5) ; check 14th push
|
|
hcmpeq #15.,342(r5) ; check 15th push (was done)
|
|
hcmpeq #cp.pr6,340(r5) ; saved PS of attempted yellow trap
|
|
htsteq 336(r5) ; red zone border clean ?
|
|
;; hcmpeq #cp.pr6,@#2 ; saved PS of red abort (w11 not yet!)
|
|
;; hcmpeq #200$,@#0 ; saved PC of red abort (e11 not yet!)
|
|
dec r1 ; too far for sob
|
|
beq 1020$
|
|
jmp 100$ ; go for next STKLIM value
|
|
;
|
|
1020$: clr cp.slr ; STKLIM to default
|
|
mov #stack,sp ; SP to default
|
|
mov #v..iit+2,v..iit ; v..iit to catcher
|
|
clr v..iit+2
|
|
spl 0 ; prio to default
|
|
br 2000$
|
|
;
|
|
1200$: .word 000000
|
|
.word 001400
|
|
.word 157400
|
|
1210$:
|
|
;
|
|
; part 2: check that red zone does not have yellow islands -----------
|
|
;
|
|
2000$: cmpb systyp,#sy.e11 ; on e11 ?
|
|
beq 3000$ ; if yes skip, e11 still buggy here
|
|
;
|
|
mov #2300$,r0 ; ptr to values
|
|
mov #<2310$-2300$>/2,r1 ; # of values
|
|
mov #2200$,v..iit ; set up iit handler
|
|
mov #1400,cp.slr ; set yellow limit to 1776
|
|
;
|
|
2100$: mov (r0)+,sp ; set SP to test value
|
|
clr -(sp) ; expect red abort, not yellow trap
|
|
halt
|
|
;
|
|
2200$: htsteq sp ; check SP=0
|
|
sob r1,2100$
|
|
;
|
|
clr cp.slr ; STKLIM to default
|
|
mov #stack,sp ; SP to default
|
|
mov #v..iit+2,v..iit ; v..iit to catcher
|
|
clr v..iit+2
|
|
br 3000$
|
|
;
|
|
2300$: .word 001400 ; probe 1376 (possible yellow mirror)
|
|
.word 001340 ; probe 1336
|
|
.word 001000 ; probe 0776 (possible yellow mirror)
|
|
.word 000400 ; probe 0376 (possible yellow mirror)
|
|
2310$:
|
|
;
|
|
; part 3: check red zone PSW protection ------------------------------
|
|
; push to 177776 should also cause a red stack abort
|
|
;
|
|
3000$: tstb systyp ; only done in w11
|
|
ble 9999$
|
|
;
|
|
mov #1400,cp.slr ; set STKLIM
|
|
mov #1300,sp ; SP deep in red zone
|
|
mov #3100$,v..iit ; set up iit handler
|
|
clr -(sp) ; expect red abort
|
|
halt
|
|
3100$: htsteq sp ; check SP=0, on emergency stack
|
|
mov #3200$,v..iit ; set up iit handler
|
|
clr -(sp) ; expect red abort again
|
|
halt
|
|
3200$: htsteq sp ; check SP=0 because of PSW protection
|
|
clr cp.slr ; STKLIM to default
|
|
mov #stack,sp ; SP to default
|
|
mov #v..iit+2,v..iit ; v..iit to catcher
|
|
;
|
|
9999$: iot ; end of test A3.2
|
|
;
|
|
; Test A3.3 -- stack trap conditions +++++++++++++++++++++++++++++++++
|
|
; Verifies that mode 1,2,4,6 trap for dstw flows and dstr when rmw
|
|
; Verifies that mode 3,5,7 writes do not trap
|
|
; Verifies that mode 1-7 reads do not trap
|
|
; Verifies that implict pushes (JSR,MFPI) trap
|
|
; Verifies that vector push of trap instructions (EMT,TRAP tested) traps
|
|
; Verifies that vector push of an interrupt (PIRQ tested) traps
|
|
; Notes:
|
|
; - dstw (mov,clr,..) and dstr (add,bis,...) flows write to stack -> test both
|
|
; - inspired by eqkce0 test 041 that verifies do/dont trap instruction cases
|
|
; - SimH and e11 currently do not support full 11/70 mode semantics
|
|
;
|
|
ta0303: tstb systyp ; skip if not on w11
|
|
bge 100$
|
|
jmp 9999$
|
|
;
|
|
100$: mov #1400,cp.slr ; set yellow limit to 1776
|
|
;
|
|
; part 1: test instructions that should trap -------------------------
|
|
;
|
|
mov #1000$,v..iit ; set up iit handler
|
|
clr v..iit+2
|
|
mov #1100$,v..emt ; set up emt handler
|
|
clr v..emt+2
|
|
mov #1200$,v..trp ; set up trap handler
|
|
clr v..trp+2
|
|
clr r2 ; clear trap counter
|
|
;
|
|
; dstw mode 1,2,4,6
|
|
mov #1000,-(sp) ; dstw mode 4: SP now 1776 (1)
|
|
clr -(sp) ; dstw mode 4: SP now 1774 (2)
|
|
mov (sp),(sp) ; dstw mode 1: SP now 1774 (3)
|
|
clr (sp) ; dstw mode 1: SP now 1774 (4)
|
|
mov (sp),(sp)+ ; dstw mode 2: SP now 1776 (5)
|
|
clr 0(sp) ; dstw mode 6: SP now 1776 (6)
|
|
mov (sp),0(sp) ; dstw mode 6: SP now 1776 (7)
|
|
; implied push
|
|
jsr pc,1300$ ; implied push: SP now 1176 (8)
|
|
mfpi r0 ; implied push: SP now 1774 (9)
|
|
; trap instrunctions
|
|
emt 100 ; trap push: SP now 1174 (10)
|
|
trap 200 ; trap push: SP now 1174 (11)
|
|
; dstr mode 1,2,4,6 when rmw
|
|
add (sp),(sp) ; dstr mode 1: SP now 1174 (12)
|
|
bis (sp),-(sp) ; dstr mode 4: SP now 1172 (13)
|
|
incb (sp)+ ; dstr mode 2: SP now 1174 (14)
|
|
dec 0(sp) ; dstr mode 6: SP now 1174 (15)
|
|
;
|
|
br 1500$
|
|
;
|
|
1000$: htstne sp ; no red stack aborts expected
|
|
inc r2
|
|
rti
|
|
;
|
|
1100$: rti ; dummy emt handler
|
|
1200$: rti ; dummy trap handler
|
|
1300$: rts pc ; dummy routine
|
|
;
|
|
1500$: hcmpeq #15.,r2 ; all traps taken ?
|
|
mov #v..iit+2,v..iit ; v..iit to catcher
|
|
mov #v..emt+2,v..emt ; v..emt to catcher
|
|
mov #v..trp+2,v..trp ; v..trp to catcher
|
|
;
|
|
; part 2: test instructions that should not trap ---------------------
|
|
;
|
|
2000$: mov #stack-2,r2 ; in yellow zone
|
|
mov r2,(r2) ; load on stack (not using SP)
|
|
mov r2,sp ; SP in yellow zone
|
|
; dstw mode 3,5,7
|
|
mov (sp)+,@-(sp) ; dstw mode 5: SP now 1176
|
|
mov @0(sp),@(sp)+ ; dstw mode 3: SP now 1200
|
|
mov -(sp),@0(sp) ; dstw mode 7: SP now 1176
|
|
; dstr mode 3,5,7 when rmw
|
|
bis (sp)+,@-(sp) ; dstw mode 5: SP now 1176
|
|
bis @0(sp),@(sp)+ ; dstw mode 3: SP now 1200
|
|
bis -(sp),@0(sp) ; dstw mode 7: SP now 1176
|
|
; dstr mode 1,2,4,6 in read-only
|
|
tst (sp) ; dstr mode 1: SP now 1176
|
|
cmp (sp),-(sp) ; dstr mode 4: SP now 1174
|
|
cmp (sp),(sp)+ ; dstr mode 2: SP now 1176
|
|
cmp (sp),0(sp) ; dstr mode 6: SP now 1176
|
|
; dstr mode 3,5,7 in read-only
|
|
cmp (sp),@(sp)+ ; dstr mode 3: SP now 1200
|
|
cmp (sp),@-(sp) ; dstr mode 5: SP now 1176
|
|
cmp (sp),@0(sp) ; dstr mode 7: SP now 1176
|
|
; check that EA is compared against STKLIM
|
|
clr sp
|
|
mov @#2000,2000(sp) ; SP=0, EA=2000 -> no trap
|
|
;
|
|
; part 3: test that interrupt (from PIRQ) vector push traps ----------
|
|
; Triggers 3 PIRQ interrupts at PR1, PR3, and PR6.
|
|
; The PIRQ interrupt vector push will issue a ysv trap.
|
|
; That trap executes before the first instruction of the pir handler.
|
|
; The iit handler must therefore execute at PR7 to lockout interrupts.
|
|
; When the iit handler returns, the pir hander will execute.
|
|
;
|
|
3000$: mov #3100$,v..iit ; set up iit handler
|
|
mov #cp.pr7,v..iit+2 ; lockout interrupts !
|
|
mov #3200$,v..pir ; set up pir handler
|
|
mov #cp.pr7,v..pir+2 ; lockout interrupts
|
|
mov #stack,sp ; SP to default (STKLIM still 1400)
|
|
clr r2 ; clear trap counter
|
|
mov #cp.pir,r3 ; ptr to cp.pir
|
|
mov #3500$,r5 ; ptr to probe data
|
|
;
|
|
spl 0
|
|
movb #bit06!bit03!bit01,1(r3) ; request PIRQ 6+3+1
|
|
nop
|
|
br 3900$
|
|
;
|
|
; iit handler
|
|
3100$: htstne sp ; no red stack aborts expected
|
|
hcmpeq #177777,(r5)+ ; check state
|
|
inc r2
|
|
rti
|
|
;
|
|
; pir handler
|
|
3200$: mov (r3),r0 ; get PIRQ
|
|
bic #177761,r0 ; mask out index bits (is pri*2)
|
|
asr r0 ; now pri*1
|
|
hcmpeq r0,(r5)+ ; check state
|
|
mov #pi.r00,r1
|
|
ash r0,r1 ; pi.r00 <<(pri)
|
|
bic r1,(r3) ; clear PIRQ request
|
|
rti
|
|
;
|
|
; state check data
|
|
3500$: .word 177777,6. ; iit marker + pr6 pirq
|
|
.word 177777,3. ; iit marker + pr3 pirq
|
|
.word 177777,1. ; iit marker + pr1 pirq
|
|
;
|
|
3900$: hcmpeq #3.,r2 ; all traps taken ?
|
|
mov #v..iit+2,v..iit ; v..iit to catcher
|
|
clr v..iit+2
|
|
mov #v..pir+2,v..pir ; v..pir to catcher
|
|
clr v..pir+2
|
|
;
|
|
; final cleanup
|
|
clr cp.slr ; STKLIM to default
|
|
mov #stack,sp ; SP to default
|
|
;
|
|
9999$: iot ; end of test A3.3
|
|
;
|
|
; Test A3.4 -- red stack abort conditions ++++++++++++++++++++++++++++
|
|
; Verifies that instruction writes abort
|
|
; Verifies that implict pushes (JSR,MFPI) abort
|
|
; Verifies that vector push after trap instructions and interrupts abort
|
|
; Abort on 1st and 2nd push is tested.
|
|
;
|
|
ta0304:
|
|
mov #1000$,v..iit ; set up iit handler
|
|
mov #cp.pr7,v..iit+2 ; lockout interrupts !
|
|
mov #1400,cp.slr ; yellow <=1776 and red <= 1736
|
|
clr @#1736 ; ensure top red word zero
|
|
clr cp.err ; clear CPUERR
|
|
;
|
|
; dstw flow
|
|
mov #1740,sp ; SP at red border
|
|
mov #100$,r5
|
|
mov #123456,-(sp)
|
|
halt
|
|
;
|
|
; dstr flow (rmw)
|
|
100$: mov #200$,r5
|
|
add (sp),-(sp)
|
|
halt
|
|
;
|
|
; implicit push instructions
|
|
200$: mov #300$,r5
|
|
jsr pc,210$
|
|
halt
|
|
210$: halt
|
|
;
|
|
300$: mov #400$,r5
|
|
mfpi r0
|
|
halt
|
|
;
|
|
; vector flow abort in 2nd push, 1st push in yellow (use EMT for test)
|
|
; Note: SimH scribbles into red zone, therefore test skipped for SimH
|
|
400$: cmpb systyp,#sy.sih ; skip section on SimH
|
|
beq 500$
|
|
mov sp,r0
|
|
mov #123456,(r0)+ ; write marker to 1740, r0 to avoid ysv
|
|
mov r0,sp ; SP now 1402 -> abort on 2nd push
|
|
mov #cp.pr3,cp.psw ; set pr3 as marker
|
|
mov #420$,r5 ; leaves NZVC = 0000
|
|
emt 100
|
|
410$: halt
|
|
420$: hcmpeq #cp.pr3,@#1740 ; check that PS written
|
|
;
|
|
; vector flow abort in 1st push (use PIRQ for test)
|
|
500$: spl 0
|
|
mov #600$,r5
|
|
mov #pi.r04,cp.pir ; request PIRQ 4
|
|
halt
|
|
600$: clr cp.pir
|
|
br 9000$
|
|
;
|
|
1000$: htsteq sp ; check SP=0
|
|
htsteq @#1736 ; check stack clean
|
|
hcmpeq #cp.rsv,cp.err ; check CPUERR.rsv (and no ysv)
|
|
clr cp.err ; clear CPUERR
|
|
mov #1740,sp ; restore SP
|
|
jmp (r5) ; continue
|
|
;
|
|
9000$: clr cp.slr ; STKLIM to default
|
|
mov #v..iit+2,v..iit ; v..iit to catcher
|
|
clr v..iit+2
|
|
mov #stack,sp ; SP to default
|
|
spl 0 ; back to PR0
|
|
;
|
|
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.
|
|
;
|
|
; helper macro for JMP via RTI with new PS,PC
|
|
.macro rtijmp,newps,newpc
|
|
push2 newps,newpc
|
|
rti
|
|
halt
|
|
.endm
|
|
;
|
|
; helper macro for JMP via RTT with new PS,PC
|
|
.macro rttjmp,newps,newpc
|
|
push2 newps,newpc
|
|
rtt
|
|
halt
|
|
.endm
|
|
;
|
|
; helper macro for trace area check setup
|
|
.macro htinit,buf,nent
|
|
hcmpeq #buf+<4*nent>,r5
|
|
mov #buf,r5
|
|
.endm
|
|
;
|
|
; helper macro for trace area check entry
|
|
.macro htitem,tvec,tadr
|
|
hcmpeq tvec,(r5)+
|
|
hcmpeq tadr,(r5)+
|
|
.endm
|
|
;
|
|
; Test A4.1 -- PSW direct write/read test ++++++++++++++++++++++++++++
|
|
;
|
|
ta0401:
|
|
;
|
|
; part 1: all bits except register set (cp.ars) ----------------------
|
|
;
|
|
mov #cp.psw,r0 ; ptr to PSW
|
|
mov #200$,r1 ; ptr to data
|
|
mov #cpnzvc,r2 ; NZVC mask
|
|
100$: mov (r1)+,r3 ; next value
|
|
beq 2000$ ; if 0 end of test
|
|
mov r3,(r0) ; write PSW
|
|
mov (r0),r3 ; read PSW
|
|
bic r2,r3 ; clear NZVC
|
|
cmp (r1)+,r3 ; check value
|
|
beq 100$
|
|
clr (r0) ; if error force kernel
|
|
halt ; and halt
|
|
;
|
|
200$: .word cp.t,0 ; tbit (not direct writable)
|
|
.word cp.pr7,cp.pr7 ; prio bits
|
|
.word bit10!bit09!bit08,0 ; bit 10:8 unused
|
|
.word bit12,bit12 ; pm(0)
|
|
.word bit13,bit13 ; pm(1)
|
|
.word bit14,bit14 ; cm(0)
|
|
.word bit15,bit15 ; cm(1)
|
|
.word 0
|
|
;
|
|
; part 2: PSW(11) - register set -------------------------------------
|
|
;
|
|
2000$: mov #1000,r0 ; write to set 0
|
|
mov #1001,r1
|
|
mov #1002,r2
|
|
mov #1003,r3
|
|
mov #1004,r4
|
|
mov #1005,r5
|
|
mov #cp.ars,cp.psw ; select set 1
|
|
hbitne #cp.ars,cp.psw ; check PSW write
|
|
mov #1010,r0 ; write to set 1
|
|
mov #1011,r1
|
|
mov #1012,r2
|
|
mov #1013,r3
|
|
mov #1014,r4
|
|
mov #1015,r5
|
|
clr cp.psw ; select set 0
|
|
hbiteq #cp.ars,cp.psw ; check PSW write
|
|
hcmpeq #1000,r0 ; check set 0
|
|
hcmpeq #1001,r1
|
|
hcmpeq #1002,r2
|
|
hcmpeq #1003,r3
|
|
hcmpeq #1004,r4
|
|
hcmpeq #1005,r5
|
|
mov #cp.ars,cp.psw ; select set 1
|
|
hcmpeq #1010,r0 ; check set 0
|
|
hcmpeq #1011,r1
|
|
hcmpeq #1012,r2
|
|
hcmpeq #1013,r3
|
|
hcmpeq #1014,r4
|
|
hcmpeq #1015,r5
|
|
clr cp.psw ; select set 0
|
|
;
|
|
; part 3: PSW(cm) and stack registers --------------------------------
|
|
;
|
|
mov #cp.psw,r0 ; ptr to PSW
|
|
clr (r0) ; cm=k
|
|
mov #0006,sp
|
|
mov #cp.cms,(r0) ; cm=s
|
|
mov #0106,sp
|
|
mov #cp.cmu,(r0) ; cm=u
|
|
mov #1106,sp
|
|
clr (r0) ; cm=k
|
|
hcmpeq #0006,sp ; check
|
|
mov #cp.cms,(r0) ; cm=s
|
|
mov sp,r1
|
|
mov #cp.cmu,(r0) ; cm=u
|
|
mov sp,r2
|
|
clr (r0) ; cm=k
|
|
hcmpeq #0106,r1 ; check in kernel to allow halt
|
|
hcmpeq #1106,r2 ; check in kernel to allow halt
|
|
;
|
|
clr (r0)
|
|
mov #stack,sp
|
|
;
|
|
9999$: iot ; end of test A4.1
|
|
;
|
|
; Test A4.2 -- PSW write/read via RTI/RTT ++++++++++++++++++++++++++++
|
|
; Verifies cm and rset priviledge escalation protection
|
|
;
|
|
ta0402:
|
|
;
|
|
; part 1: from cm=0,rset=0: set cm=11 and rset=1 (fine!) -------------
|
|
;
|
|
rtijmp #cp.cmu!cp.ars,#1200$ ; new PS cm=u and rs=1
|
|
;
|
|
1100$: .word 0 ; saved PS
|
|
;
|
|
1200$: mov cp.psw,1100$ ; save PS (use memory, rset=1!)
|
|
clr cp.psw ; back to kernel
|
|
mov #stack,sp ; restore stack
|
|
bic #cpnzvc,1100$ ; discard NZVC
|
|
hcmpeq #cp.cmu!cp.ars,1100$ ; check expected PS
|
|
;
|
|
; part 2: from cm=s,rset=1 mode: set cm=0 and rset=0 (fail!) ---------
|
|
;
|
|
rtijmp #cp.cms!cp.ars,#2200$ ; PS cm=s and rs=1
|
|
;
|
|
.word 0,0 ; temporary stack
|
|
2100$: .word 0 ; 1st saved PS
|
|
2110$: .word 0 ; 2nd saved PS
|
|
;
|
|
; now in supervisor mode, try sneak to cm=k and rs=0
|
|
2200$: mov cp.psw,2100$ ; save PS
|
|
mov #2100$,sp ; set up stack
|
|
rtijmp #0,#2300$ ; new PS cm=k and rs=0
|
|
;
|
|
; lands here after rti from cm=s -> still in cm=s
|
|
2300$: mov cp.psw,2110$ ; save PS
|
|
clr cp.psw ; back to kernel
|
|
mov #stack,sp ; restore stack
|
|
bic #cpnzvc,2100$ ; discard NZVC
|
|
hcmpeq #cp.cms!cp.ars,2100$ ; check expected 1st PS
|
|
bic #cpnzvc,2110$ ; discard NZVC
|
|
hcmpeq #cp.cms!cp.ars,2110$ ; check expected 2nd PS (same !)
|
|
;
|
|
; part 3: from cm=s,rset=0 mode: set cm=u and rset=1 (fine!) ---------
|
|
;
|
|
rtijmp #cp.cms,#3200$ ; PS cm=s and rs=0
|
|
;
|
|
.word 0,0 ; temporary stack
|
|
3100$: .word 0 ; 1st saved PS
|
|
3110$: .word 0 ; 2nd saved PS
|
|
;
|
|
; now in supervisor mode, continue to cm=u and rs=1
|
|
3200$: mov cp.psw,3100$ ; save PS
|
|
mov #3100$,sp ; set up stack
|
|
rtijmp #cp.cmu!cp.ars,#3300$ ; new PS cm=u and rs=1
|
|
;
|
|
; lands here after rti from cm=s -> now cm=u
|
|
3300$: mov cp.psw,3110$ ; save PS
|
|
clr cp.psw ; back to kernel
|
|
mov #stack,sp ; restore stack
|
|
bic #cpnzvc,3100$ ; discard NZVC
|
|
hcmpeq #cp.cms,3100$ ; check expected 1st PS
|
|
bic #cpnzvc,2110$ ; discard NZVC
|
|
hcmpeq #cp.cmu!cp.ars,3110$ ; check expected 2nd PS (now user)
|
|
;
|
|
; part 4: from cm=u,rset=1 mode: set cm=0 and rset=0 (fail!) ---------
|
|
;
|
|
rtijmp #cp.cmu!cp.ars,#4200$ ; PS cm=u and rs=1
|
|
;
|
|
.word 0,0 ; temporary stack
|
|
4100$: .word 0 ; 1st saved PS
|
|
4110$: .word 0 ; 2nd saved PS
|
|
;
|
|
; now in user mode, try sneak to cm=k and rs=0
|
|
4200$: mov cp.psw,4100$ ; save PS
|
|
mov #4100$,sp ; set up stack
|
|
rtijmp #0,#4300$ ; new PS cm=k and rs=0
|
|
;
|
|
; lands here after rti from cm=u -> still in cm=u
|
|
4300$: mov cp.psw,4110$ ; save PS
|
|
clr cp.psw ; back to kernel
|
|
mov #stack,sp ; restore stack
|
|
bic #cpnzvc,4100$ ; discard NZVC
|
|
hcmpeq #cp.cmu!cp.ars,4100$ ; check expected 1st PS
|
|
bic #cpnzvc,4110$ ; discard NZVC
|
|
hcmpeq #cp.cmu!cp.ars,4110$ ; check expected 2nd PS (same !)
|
|
;
|
|
9999$: iot ; end of test A4.2
|
|
;
|
|
; Test A4.3 -- RTI/RTT tbit basics +++++++++++++++++++++++++++++++++++
|
|
; Verifies that tbit trap comes immediately after RTI and delayed after RTT
|
|
;
|
|
ta0403:
|
|
;
|
|
; part 1: tbit after RTI ---------------------------------------------
|
|
;
|
|
mov #200$,v..bpt
|
|
rtijmp #cp.t,#100$ ; PS: tbit; PC 100$
|
|
100$: nop ; should not execute
|
|
halt
|
|
;
|
|
; here in local BPT handler
|
|
200$: hcmpeq #stack-4,sp ; check single frame
|
|
hcmpeq #100$,(sp) ; check saved PC before nop
|
|
mov #stack,sp ; restore
|
|
mov #v..bpt+2,v..bpt
|
|
;
|
|
; part 2: tbit after RTT ---------------------------------------------
|
|
;
|
|
2000$: mov #2200$,v..bpt
|
|
rttjmp #cp.t,#2100$ ; PS: tbit; PC 2100$
|
|
2100$: nop ; should execute
|
|
halt
|
|
;
|
|
; here in local BPT handler
|
|
2200$: hcmpeq #stack-4,sp ; check single frame
|
|
hcmpeq #2100$+2,(sp) ; check saved PC after nop
|
|
mov #stack,sp ; restore
|
|
mov #v..bpt+2,v..bpt
|
|
;
|
|
9999$: iot ; end of test A4.3
|
|
;
|
|
; Test A4.4 -- tbit trace tests ++++++++++++++++++++++++++++++++++++++
|
|
;
|
|
ta0404: mov #vhtbpt,v..bpt ; BPT handler
|
|
mov #cp.pr7,v..bpt+2 ; run at PR7 (lockout PIRQ)
|
|
mov #vhtemt,v..emt ; EMT handler
|
|
clr v..emt+2 ; run at PR0 (no PIRQ competion)
|
|
mov #vhtpir,v..pir ; PIRQ handler
|
|
mov #cp.pr7,v..pir+2 ; run at PR7 (lockout PIRQ)
|
|
mov #vhttrp,v..trp ; TRAP handler
|
|
clr v..trp+2 ; run at PR0 (no PIRQ competion)
|
|
;
|
|
; part 1: simple instruction sequence --------------------------------
|
|
; Checks that trace traps are taken instructions which allow prefetch
|
|
; and that the destination PC is saved for flow control instructions.
|
|
;
|
|
mov #1200$,r5
|
|
mov #1300$,vhtend
|
|
rtijmp #cp.t,#1100$ ; RTI used to see bpt before 1st inst
|
|
;
|
|
1100$: inc r0 ; 1st inst, shouldnt prefetch
|
|
1110$: dec r0 ; 2nd inst, shouldnt prefetch
|
|
1120$: cmp #1,#2 ; 3rd inst
|
|
1130$: bne 1160$ ; 4th inst
|
|
halt
|
|
1140$: return ; 6th inst
|
|
halt
|
|
1150$: jmp 1180$ ; 8th inst
|
|
halt
|
|
1160$: call 1140$ ; 5th inst
|
|
1170$: br 1150$ ; 7th inst
|
|
1180$: trap 100 ; 9th inst
|
|
1190$:
|
|
;
|
|
1200$: .word 0,0
|
|
.word 0,0
|
|
.word 0,0
|
|
.word 0,0
|
|
.word 0,0
|
|
.word 0,0
|
|
.word 0,0
|
|
.word 0,0
|
|
.word 0,0
|
|
.word 0,0
|
|
.word -1,-1
|
|
;
|
|
1300$: htinit 1200$,10. ; expect 10 items
|
|
htitem #014,#1100$ ; bpt before inc
|
|
htitem #014,#1110$ ; bpt after inc
|
|
htitem #014,#1120$ ; bpt after dec
|
|
htitem #014,#1130$ ; bpt after cmp
|
|
htitem #014,#1160$ ; bpt after bne (PC is bne target)
|
|
htitem #014,#1140$ ; bpt after jsr (PC is jsr target)
|
|
htitem #014,#1170$ ; bpt after rts (PC is rts target)
|
|
htitem #014,#1150$ ; bpt after br (PC is br target)
|
|
htitem #014,#1180$ ; bpt after jmp (PC is jmp target)
|
|
htitem #036,#1190$ ; final trap
|
|
;
|
|
; part 2: tracing of trap instructions (EMT tested) ------------------
|
|
;
|
|
2000$: mov #2200$,r5
|
|
mov #2300$,vhtend
|
|
rttjmp #cp.t,#2100$ ; RTT used, no before BPT
|
|
;
|
|
2100$: dec r0
|
|
2110$: emt 100
|
|
2120$: nop
|
|
2130$: trap 100
|
|
2140$:
|
|
;
|
|
2200$: .word 0,0
|
|
.word 0,0
|
|
.word 0,0
|
|
.word 0,0
|
|
.word 0,0
|
|
.word -1,-1
|
|
;
|
|
2300$: htinit 2200$,5. ; expect 5 items
|
|
htitem #014,#2110$ ; bpt after dec
|
|
htitem #032,#2120$ ; emt (with return address)
|
|
htitem #014,#2120$ ; bpt after emt (taken after emt)
|
|
htitem #014,#2130$ ; bpt after nop
|
|
htitem #036,#2140$ ; final trap
|
|
;
|
|
; part 3: tbit vs interrupt precedence (via PIRQ) --------------------
|
|
; Checks that interrupt has precedence over tbit traps.
|
|
; Skipped on SimH which implements J11 precedence (tbit over interrupt).
|
|
;
|
|
3000$: cmpb systyp,#sy.sih ; skip on SimH (different service order)
|
|
beq 4000$
|
|
cmpb systyp,#sy.e11 ; skip on e11 (different service order)
|
|
beq 4000$
|
|
;
|
|
3001$: mov #3200$,r5
|
|
mov #3300$,vhtend
|
|
rttjmp #cp.t,#3100$
|
|
;
|
|
3100$: movb #bit01,cp.pir+1 ; request PIRQ 1
|
|
3110$: trap 100
|
|
3120$:
|
|
;
|
|
3200$: .word 0,0
|
|
.word 0,0
|
|
.word 0,0
|
|
.word 0,0
|
|
.word 0,0
|
|
.word -1,-1
|
|
;
|
|
3300$: htinit 3200$,3. ; expect 3 items
|
|
htitem #240,#3110$ ; pirq (with return address)
|
|
htitem #014,#3110$ ; bpt after movb
|
|
htitem #036,#3120$ ; final trap
|
|
;
|
|
; part 4: traced WAIT and tbit ---------------------------------------
|
|
; Checks that traced WAIT does not produce tbit trap.
|
|
; Checks that SPL does not produce a tbit trap.
|
|
; Skipped on SimH which implements J11 semantics for SPL, WAIT, precedence.
|
|
;
|
|
4000$: cmpb systyp,#sy.sih ; skip on SimH
|
|
beq 5000$
|
|
cmpb systyp,#sy.e11 ; skip on e11 (for precedence)
|
|
beq 5000$
|
|
;
|
|
4001$: mov #4200$,r5
|
|
mov #4300$,vhtend
|
|
rttjmp #cp.t+cp.pr7,#4100$ ; enable tbit, block interrupts
|
|
;
|
|
4100$: movb #bit05,cp.pir+1 ; request PIRQ 5
|
|
4110$: spl 4 ; allow interrupts, not traced !!
|
|
wait ; also not traced !!
|
|
4120$: trap 100
|
|
4130$:
|
|
;
|
|
4200$: .word 0,0
|
|
.word 0,0
|
|
.word 0,0
|
|
.word 0,0
|
|
.word -1,-1
|
|
;
|
|
4300$: htinit 4200$,4. ; expect 4 items
|
|
htitem #014,#4110$ ; bpt after movb
|
|
htitem #240,#4120$ ; pirq (with return address)
|
|
htitem #014,#4120$ ; bpt after wait
|
|
htitem #036,#4130$ ; final trap
|
|
;
|
|
; part 5: WAIT and SPL in user mode ----------------------------------
|
|
; Checks that WAIT and SPL in user mode are traced (are nop)
|
|
;
|
|
5000$: mov #5200$,r5
|
|
mov #5300$,vhtend
|
|
rttjmp #cp.cmu+cp.t,#5100$ ; user mode, enable tbit
|
|
;
|
|
5100$: wait
|
|
5110$: spl 7
|
|
5120$: trap 100
|
|
5130$:
|
|
;
|
|
5200$: .word 0,0
|
|
.word 0,0
|
|
.word 0,0
|
|
.word -1,-1
|
|
;
|
|
5300$: htinit 5200$,3. ; expect 3 items
|
|
htitem #014,#5110$ ; bpt after wait
|
|
htitem #014,#5120$ ; bpt after spl
|
|
htitem #036,#5130$ ; final trap
|
|
;
|
|
; part 6: tbit trap after continuation over s_idle -------------------
|
|
; Checks instructions that complete via s_idle are properly traced
|
|
; Four instructions branch at completion to s_idle
|
|
; WAIT s_op_wait (after interrupt)
|
|
; RESET s_op_reset
|
|
; MOV/CLR s_opg_gen if is_dstw_pc
|
|
;
|
|
6000$: mov #137,@#0 ; write jmp @#6130$ to location 0,2
|
|
mov #6130$,@#2
|
|
;
|
|
mov #6200$,r5
|
|
mov #6300$,vhtend
|
|
rttjmp #cp.t,#6100$ ; enable tbit
|
|
;
|
|
6100$: reset
|
|
6110$: mov #6120$,pc
|
|
halt
|
|
6120$: clr pc ; continue via jmp @#6130$ at 0,2
|
|
halt
|
|
6130$: trap 100
|
|
6140$:
|
|
;
|
|
6200$: .word 0,0
|
|
.word 0,0
|
|
.word 0,0
|
|
.word 0,0
|
|
.word 0,0
|
|
.word -1,-1
|
|
;
|
|
6300$: htinit 6200$,5. ; expect 5 items
|
|
htitem #014,#6110$ ; bpt after reset
|
|
htitem #014,#6120$ ; bpt after mov
|
|
htitem #014,#0 ; bpt after clr
|
|
htitem #014,#6130$ ; bpt after jmp
|
|
htitem #036,#6140$ ; final trap
|
|
;
|
|
clr @#0
|
|
clr @#2
|
|
;
|
|
; part 7: no tbit trap after an abort --------------------------------
|
|
; Checks that an aborted instruction doesnt tbit trap.
|
|
; Uses a bus timeout as abort reason (access to 160000).
|
|
;
|
|
7000$: mov #7300$,v..iit ; setup local vector 4 handler
|
|
mov #7200$,r5
|
|
rttjmp #cp.t,#7100$ ; enable tbit
|
|
;
|
|
7100$: clr cp.err ; clear CPUERR (will trace trap)
|
|
7110$: clr @#160000 ; will fail
|
|
halt
|
|
;
|
|
7200$: .word 0,0
|
|
.word -1,-1
|
|
;
|
|
7300$: mov #stack,sp ; discard frame
|
|
hcmpeq #cp.ito,cp.err ; check CPUERR
|
|
htinit 7200$,1. ; expect 1 item
|
|
htitem #014,#7110$ ; bpt after 1st clr
|
|
;
|
|
mov #v..iit+2,v..iit ; restore
|
|
|
|
; restore ------------------------------------------------------------
|
|
;
|
|
mov #v..bpt+2,v..bpt ; restore v..bpt to catcher
|
|
clr v..bpt+2
|
|
mov #v..emt+2,v..emt ; restore v..emt to catcher
|
|
clr v..emt+2
|
|
mov #v..pir+2,v..pir ; restore v..pir to catcher
|
|
clr v..pir+2
|
|
mov #v..trp+2,v..trp ; restore v..trp to catcher
|
|
clr v..trp+2
|
|
;
|
|
9999$: iot ; end of test A4.4
|
|
;
|
|
; Section B: Stress tests ====================================================
|
|
; B1 address mode torture tests
|
|
; B1.1 src-dst update hazards with (r0)+,(r0)
|
|
; B1.2 (pc)+ as destination
|
|
; B1.3 pc as destination in clr, mov, and add
|
|
; B2 pipeline torture tests
|
|
; B2.1 self-modifying code, use (pc), -(pc)
|
|
; B2.2 self-modifying code, use (pc) case 2
|
|
;
|
|
; Test B1: address mode torture tests +++++++++++++++++++++++++++++++++++++++
|
|
; This sub-section tests peculiar address node usage
|
|
;
|
|
; Test B1.1 -- src-dst update hazards with (r0)+,(r0) ++++++++++++++++
|
|
;
|
|
tb0101: mov #2,r5
|
|
100$: mov #1000$,r0
|
|
mov #1110$,r1
|
|
push 1000$+2 ; save data that will change
|
|
push 1000$+6
|
|
push 1100$+0
|
|
push 1100$+4
|
|
;
|
|
mov (r0)+,(r0)+ ; mov 111 over 222
|
|
add (r0)+,(r0)+ ; add 333 to 444
|
|
mov -(r1),-(r1) ; mov 444 over 333
|
|
add -(r1),-(r1) ; add 222 to 111
|
|
;
|
|
hcmpeq 1000$+2,#000111
|
|
hcmpeq 1000$+6,#000777
|
|
hcmpeq 1100$+4,#000444
|
|
hcmpeq 1100$+0,#000333
|
|
;
|
|
pop 1100$+4 ; restore data
|
|
pop 1100$+0
|
|
pop 1000$+6
|
|
pop 1000$+2
|
|
sob r5,100$
|
|
jmp 9999$
|
|
;
|
|
1000$: .word 000111 ; data for (r0)+ part
|
|
.word 000222
|
|
.word 000333
|
|
.word 000444
|
|
;
|
|
1100$: .word 000111 ; data for -(r0) part
|
|
.word 000222
|
|
.word 000333
|
|
.word 000444
|
|
1110$:
|
|
;
|
|
9999$: iot ; end of test B1.1
|
|
;
|
|
; Test B1.2 -- (pc)+ as destination ++++++++++++++++++++++++++++++++++
|
|
;
|
|
tb0102: mov #2,r5
|
|
100$: push 1000$+4 ; save data that will change
|
|
push 1100$+4
|
|
push 1200$+2
|
|
;
|
|
clr r0
|
|
1000$: mov #1,#0 ; (pc)+,(pc)+: write #1 over #0
|
|
1100$: add #1,#2 ; (pc)+,(pc)+: add #1 to #2
|
|
mov 1000$+4,1200$+2 ; -14(pc),2(pc): dst of mov -> src of add
|
|
1200$: add #0,r0 ; add #1(!) to r0
|
|
;
|
|
hcmpeq 1000$+4,#1
|
|
hcmpeq 1100$+4,#3
|
|
hcmpeq r0,#1
|
|
;
|
|
pop 1200$+2 ; restore data
|
|
pop 1100$+4
|
|
pop 1000$+4
|
|
sob r5,100$
|
|
;
|
|
9999$: iot ; end of test B1.2
|
|
;
|
|
; Test B1.3 -- pc as destination in clr, mov, and add ++++++++++++++++
|
|
;
|
|
tb0103: mov #000137,@#0 ; setup jmp 1000$ at mem(0)
|
|
mov #1000$,@#2
|
|
clr pc
|
|
halt
|
|
halt
|
|
halt
|
|
1000$: mov #1100$,pc
|
|
halt
|
|
halt
|
|
halt
|
|
1100$: clr r0
|
|
add #4,pc ; skip two instructions
|
|
inc r0
|
|
inc r0
|
|
inc r0 ; lands here
|
|
inc r0
|
|
hcmpeq r0,#2
|
|
;
|
|
clr @#0 ; remove jmp 1000$ at mem(0)
|
|
clr @#2
|
|
;
|
|
9999$: iot ; end of test B1.3
|
|
;
|
|
; Test B2: pipeline torture tests +++++++++++++++++++++++++++++++++++++++++++
|
|
; This sub-section tests self-modifying code
|
|
;
|
|
; Test B2.1 -- self-modifying code, use (pc), -(pc) ++++++++++++++++++
|
|
;
|
|
tb0201: mov #2,r5
|
|
100$: mov 1000$,-(sp)
|
|
mov 1100$,-(sp)
|
|
;
|
|
clr r0
|
|
clr r1
|
|
clr r2
|
|
mov #005201,r3 ; r3= inc r1
|
|
mov #005202,r4 ; r4= inc r2
|
|
;
|
|
inc r0
|
|
mov r3,(pc) ; will overwrite next instruction
|
|
1000$: halt ; will be overwritten with 'inc r1'
|
|
inc r0
|
|
1100$: mov r4,-(pc) ; will overwrite itself and re-execute(!)
|
|
inc r0
|
|
;
|
|
hcmpeq r0,#3 ; 3 inc r0 in code
|
|
hcmpeq r1,#1 ; check that 'inc r1' was executed
|
|
hcmpeq r2,#1 ; check that 'inc r2' was executed
|
|
;
|
|
mov (sp)+,1100$
|
|
mov (sp)+,1000$
|
|
sob r5,100$
|
|
;
|
|
9999$: iot ; end of test B2.1
|
|
;
|
|
; Test B2.2 -- self-modifying code, use (pc) case 2 ++++++++++++++++++
|
|
; Was insprired by KDJ11A.MAC (J11 is indeed pipelined)
|
|
;
|
|
tb0202: mov #2,r5
|
|
100$: mov 1000$,-(sp)
|
|
mov 1100$,-(sp)
|
|
mov 1200$,-(sp)
|
|
;
|
|
mov #1999$,r1
|
|
clr r2
|
|
;
|
|
mov #005202,(pc) ; will replace jmp (r1) with 'inc r2'
|
|
1000$: jmp (r1)
|
|
mov #005202,(pc) ; will replace jmp (r1) with 'inc r2'
|
|
1100$: jmp (r1)
|
|
mov #005202,(pc) ; will replace jmp (r1) with 'inc r2'
|
|
1200$: jmp (r1)
|
|
;
|
|
hcmpeq r2,#3 ; check that 'inc r2' was executed
|
|
;
|
|
mov (sp)+,1200$
|
|
mov (sp)+,1100$
|
|
mov (sp)+,1000$
|
|
sob r5,100$
|
|
jmp 9999$
|
|
;
|
|
1999$: halt ; halt as target for 'jmp (r1)'
|
|
;
|
|
9999$: iot ; end of test B2.2
|
|
;
|
|
; Section C: 11/70 specifics =================================================
|
|
; C1 Implementation differences
|
|
; C1.1 Register used as source and changed in dst flow
|
|
; C1.2 PC used as source
|
|
; C1.3 Registers accessible via 177700-1777717
|
|
;
|
|
; Test C1: Implementation differences +++++++++++++++++++++++++++++++++++++++
|
|
; This sub-section verifies that w11 shows 11/70 behavior in cases
|
|
; were J11 and other CPU models show different behavior
|
|
;
|
|
; Test C1.1 -- Register used as source and changed in dst flow +++++++
|
|
; OPR R,(R)+ : incremented before {J11} or after {70} use as source
|
|
; OPR R,-(R) : decremented before {J11} or after {70} use as source
|
|
;
|
|
tc0101: mov #1000$,r4
|
|
mov r4,(r4)+
|
|
hcmpeq 1000$,#1000$ ; check r4 prior inc stored
|
|
mov r4,-(r4)
|
|
hcmpeq 1000$,#1000$+2 ; check r4 prior dec stored
|
|
br 9999$
|
|
;
|
|
1000$: .word 0
|
|
;
|
|
9999$: iot ; end of test C1.1
|
|
;
|
|
; Test C1.2 -- PC used as source +++++++++++++++++++++++++++++++++++++
|
|
; OPR PC,A(R) : store PC+2 {70} or PC+4 {J11}
|
|
;
|
|
tc0102: mov #1000$,r4
|
|
100$: mov pc,0(r4)
|
|
hcmpeq 1000$,#100$+2 ; check pc after fetch stored
|
|
br 9999$
|
|
;
|
|
1000$: .word 0
|
|
;
|
|
9999$: iot ; end of test C1.2
|
|
;
|
|
; Test C1.3 -- Registers accessible via 177700-1777717 +++++++++++++++
|
|
; CPU access to 177700-177717 (regs) timesout {70,J11} or not {05,10}
|
|
;
|
|
tc0103: mov #vhugen,v..iit ; set iit handler
|
|
clr v..iit+2 ; pr0 kernel
|
|
;
|
|
mov #1000$,vhustp ; continuation address
|
|
tst @#177700 ; should fail
|
|
halt
|
|
;
|
|
1000$: mov #1100$,vhustp ; continuation address
|
|
tst @#177716 ; should fail
|
|
halt
|
|
;
|
|
1100$: mov v..iit+2,v..iit ; restore iit handler
|
|
;
|
|
9999$: iot ; end of test C1.3
|
|
;
|
|
; END OF ALL TESTS - loop closure ============================================
|
|
;
|
|
mov tstno,r0 ; hack, for easy monitoring ...
|
|
hcmpeq tstno,#29. ; all tests done ?
|
|
;
|
|
jmp loop
|
|
;
|
|
; kernel handlers ============================================================
|
|
;
|
|
; vhugen - generic handler for expected traps/abort ++++++++++++++++++++++++++
|
|
; the continution address must be written to vhustp
|
|
; execution will reset vhustp to a catcher value
|
|
; --> vhustp must be set for each execution
|
|
;
|
|
vhugen: add #4,sp ; discard vector frame
|
|
mov vhustp,100$ ; set up return address
|
|
mov #vhuhlt,vhustp ; reset stop address by catcher
|
|
jmp @100$ ; end return to continuation address
|
|
100$: .word 0
|
|
vhustp: .word vhuhlt
|
|
vhuhlt: halt
|
|
;
|
|
; vhtbpt - handler for BPT tracing +++++++++++++++++++++++++++++++++++++++++++
|
|
; Writes signature to data area (ptr in r5).
|
|
; Signature is vector address + return PC (PC to test proper context).
|
|
;
|
|
vhtbpt: htstge (r5) ; r5 at fence ?
|
|
mov #014,(r5)+ ; track BPT vector
|
|
mov (sp),(r5)+ ; track PC
|
|
rtt ; end with RTT (!)
|
|
;
|
|
; vhtemt - handler for EMT tracing +++++++++++++++++++++++++++++++++++++++++++
|
|
; Writes signature to data area (ptr in r5).
|
|
; Signature is vector address + return PC (PC to test proper context).
|
|
;
|
|
vhtemt: htstge (r5) ; r5 at fence ?
|
|
mov #032,(r5)+ ; track EMT vector
|
|
mov (sp),(r5)+ ; track PC
|
|
rti
|
|
;
|
|
; vhtpir - handler for PIRQ interrupt tracing ++++++++++++++++++++++++++++++++
|
|
; Writes signature to data area (ptr in r5).
|
|
; Signature is vector address + return PC (PC to test proper context).
|
|
; Clears all PIRQ requests to prevent interrupt loop.
|
|
;
|
|
vhtpir: htstge (r5) ; r5 at fence ?
|
|
clr cp.pir ; clear all PIRQ interrupts
|
|
mov #240,(r5)+ ; track PIRQ vector
|
|
mov (sp),(r5)+ ; track PC
|
|
rti
|
|
;
|
|
; vhttrp - handler for TRAP, ends tracing ++++++++++++++++++++++++++++++++++++
|
|
; Writes signature to data area (ptr in r5).
|
|
; Returns to address stored in vhtend
|
|
; vhtend must be set for each execution
|
|
;
|
|
vhttrp: htstge (r5) ; r5 at fence ?
|
|
mov #036,(r5)+ ; track TRAP vector
|
|
mov (sp),(r5)+ ; track PC
|
|
mov vhtend,100$ ; remember vhtend
|
|
mov #200$,vhtend ; restore blocker
|
|
mov #stack,sp ; restore stack
|
|
jmp @100$ ; return or block
|
|
100$: .word 200$ ; value of vhtend at entry
|
|
200$: halt ; blocker
|
|
vhtend: .word 0 ; registered return address
|
|
;
|
|
.end start
|