|
|
Power 6/32 Unix version 1.21
# # privileged instructions event test # # # halt ,ldpxtx,svpctx,mtpr,mfpr in user mode # # *** WARNING : # halt instruction in user mode better create privileged instr # fault, otherwise expect unpredictable results. # # R7 = PC that failed # R0 = error code # 1 : Failed to REI to user # 2 : Expected fault didnot happen # 3 : Error in PC pushed on the stack # R1 = actual, R2 = expected # 4 : Error in PSL pushed on the stack # R1 = actual, R2 = expected # 5 : Error in current PSL after taking fault # R1 = actual, R2 = expected # .globl _prv_evt _prv_evt: .word 0x1fff mtpr $31,$IPL /* Set IPL to HIGH */ movab (sp),_savvec0 /* Save current SP */ mtpr _savvec0,$ISP /* Set ISP to current SP */ mfpr $KSP,_savvec9 /* Save kernal stack pointer */ mfpr $USP,_savveca /* Save user stack pointer */ movl _scb+PINSTVEC,_savvec2 /* Save priv. inst. fault vector */ movab vecvec4,_scb+PINSTVEC /* Sew new vector */ # # go to User mode # umode: movl $0x01000000,-(sp) /* Set PSL on stack; User mode */ movab ldctx,-(sp) /* Set PC for REI */ clrl r5 /* R5 used as flags to be */ /* checked in event handler */ rei /* REI to User mode */ movl $1,r0 /* REI failed ! R0 = error code */ jmp *badrtn # # We are now in User mode ; try to execute LDPCTX in User mode # ldctx: movab svctx,rtnxt /* Set return address for fault handler */ movab ldpc,exp_pc /* Set expected PC */ movl exp_pc,r7 movpsl r3 /* R3 = current PSL */ ldpc: ldpctx /* Should cause priv. inst. fault */ incl r5 /* Should never come here; set flag */ movl $2,r0 /* Expected fault did not happen !! */ jmp *badrtn /* R0 = error code */ # # Come back here from event handler # still in User mode; try to execute SVPCTX in User mode # svctx: movab prvmt,rtnxt /* Set return address for fault handler */ movab svpc,exp_pc /* Set expected PC */ movl exp_pc,r7 movpsl r3 /* R3 = current PSL */ svpc: ldpctx /* Should cause priv. inst. fault */ incl r5 /* Should never come here; set flag */ movl $2,r0 /* Expected fault did not happen !! */ jmp *badrtn /* R0 = error code */ # # Come back here from event handler # still in User mode; try to execute MTPR in User mode # prvmt: movab prvmf,rtnxt /* Set return address for fault handler */ movab pmtpr,exp_pc /* Set expected PC */ movl exp_pc,r7 movpsl r3 /* R3 = current PSL */ pmtpr: mtpr _pcb0,$PCBB /* Try MTPR instruction */ incl r5 /* Should never come here; set flag */ movl $2,r0 /* Expected fault did not happen !! */ jmp *badrtn /* R0 = error code */ # # Come back here from event handler # still in User mode; try to execute MFPR in User mode # prvmf: movab prvhlt,rtnxt /* Set return address for fault handler */ movab pmfpr,exp_pc /* Set expected PC */ movl exp_pc,r7 movpsl r3 pmfpr: mfpr $PCBB,r8 /* Try MFPR */ incl r5 /* Should never come here; set flag */ movl $2,r0 /* Expected fault did not happen !! */ jmp *badrtn /* R0 = error code */ # # Come back here from event handler # still in User mode; try to execute HALT in User mode # prvhlt: clrl rtnxt /* Last test : return */ movab phlt,exp_pc /* Set expected PC */ movl exp_pc,r7 movpsl r3 phlt: halt /* Try HALT instruction */ incl r5 /* Should never come here; set flag */ movl $2,r0 /* Expected fault did not happen !! */ jmp *badrtn /* R0 = error code */ # # Event handler for privilege inst. fault # .align 2 vecvec4: cmpl $0,r5 /* Check flag; no fault in User mode ? */ beql 1f /* If yes fall thru else skip */ jmp *badrtn /* Error : no fault in User mode */ # # Check parameters pushed on stack # 1: movl (sp)+,r1 /* R1 = actual PC pop from stack */ movl exp_pc,r2 /* R2 = expected PC */ cmpl r1,r2 beql 1f movl $3,r0 /* R0 = error code; wrong PC on stack */ jmp *badrtn /* R1 = actual; R2 = expected */ 1: movl (sp)+,r1 /* R1 = actual PSL pop from stack */ andl2 $0xffffff00,r1 /* mask out PSW flags */ movl $0x01000000,r2 /* R2 = expected PSl */ cmpl r1,r2 beql 1f movl $4,r0 /* R0 = error code; wrong PSL on stack */ jmp *badrtn /* R1= actual; R2 = expected */ 1: movpsl r1 /* R1 = current PSL (afer fault) */ andl2 $0x051f0000,r1 /* Mask out PSW flags */ movl $0,r2 /* R2 = expected current PSL */ cmpl r1,r2 beql nxt movl $5,r0 /* R0 = error code; wrong current PSL */ jmp *badrtn /* R1 = actual; R2 = expected */ # # All checked out; get ready to return to test or monitor # nxt: movl rtnxt,r9 /* R9 = return address */ cmpl $0,r9 /* last test ? */ jeql lastst /* If yes then get out */ movl $0x01000000,-(sp) /* Push PSL, PC on stack for REI */ movl r9,-(sp) /* to return */ rei halt /* Should never come here */ lastst: /* All done,return to monitor */ movl _savvec2,_scb+PINSTVEC mtpr _savvec0,$ISP /* restore interrupt stack pointer */ mtpr _savvec9,$KSP /* restore interrupt kernal pointer */ mtpr _savveca,$USP /* restore interrupt user pointer */ pushl $0 /* Push dummy PC, PSL on stack */ pushl $0 /* We are now still on Kernel stack */ mtpr $31,$IPL svpctx /* This will switch back to ISP */ nxtpc: ret .align 2 rtnxt: .long 0 /* Contain return address from fault handler */ exp_pc: .long 0 /* Contain expected PC to be checked in fault handler */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.