|
|
Power 6/32 Unix version 1.2b
# # # *arithmetic exception evnt test # *divide by zero & integer overflow # *divl2,divl3,ediv # *are tested. # # R3 = PC that failed # R0 = error code # 1 - Expected fault did not happen # R1 = current PSL # 2 - PSL_V bit is not set # R1 = current PSL # 3 - Unexpected arithmetic fault # R1 = error code, R2 = actual PC on the stack # 4 - Wrong error code on the stack # R1 = actual, R2 = expected # 5 - Error in PC pushed on the stack # R1 = actual, R2 = expected # 6 - Error in PSL pushed on the stack # R1 = actual, R2 = expected # 7 - Too many parameters pushed on the stack # 8 - PSL_V on the stack is not reset # R1 = PSL on the stack .globl _arith_evt _arith_evt: .word 0x1fff mtpr $31,$IPL /* Set IPL to HIGH */ movab (sp),_savvec0 /* Save current SP */ mtpr _savvec0,$ISP /* Set ISP = current SP */ movl _scb+ARITHVEC,_savvec2 /* Save arith. fault vector */ movab arthflt,_scb+ARITHVEC /* Set new vector */ movl $-1,-(sp) /* Push marker on stack */ movab _pcb0,r1 mtpr r1,$PCBB /* Set PCBB */ movab (sp),_pcb0 /* Set KSP in PCB0 */ movab (sp),_pcb0+4 /* Set USP in PCB0 */ movpsl r1 /* If not KERNEL mode, then */ bitl $0x01000000,r1 /* force KERNEL mode */ beql 1f movl _scb+PINSTVEC,_savvec3 movab forckmd,_scb+PINSTVEC halt /* HALT in USER mode to force */ /* KERNEL mode */ .align 2 forckmd: addl2 $8,sp /*get rid of trash on the stack */ movl _savvec3,_scb+PINSTVEC /*restore vector */ # # We are now running in KERNEL mode; IPL = 0x1f # try to force PSW_V bit set without causing fault # by dividing MAX. negative no by -1 1: bicpsw $0x3f /* Disable overflow event (PSW) */ movab epc2,r3 /* R5 = expected PC */ movl $-1,r4 /* R4 = -1; Donot expect fault */ movl $0x80000000,r8 clrl r9 epc2: divl2 $-1,r8 /* Should not get overflow exception */ movpsl r1 bitl $2,r1 /* Check if PSW_V bit is on */ bneq 1f movl $2,r0 /* Error : PSW_V not set */ jmp *badrtn # # We are now running in KERNEL mode; IPL = 0x1f # forcing arithmetic fault by dividing by 0 # 1: movl $0x300,r0 /* R0 = error code */ bicpsw $0x3f /* Reset PSW */ bispsw $0x20 /* Enable Overflow fault (in PSW) */ movab epc3,r5 /* R5 = expected PC */ movl r5,r3 /* R3 = PC that failed */ movab pc4,r6 /* R6 = return addr from evt handler */ movl $2,r4 /* R4 = expected error code on SP */ movl $0x80000000,r8 /* divide by zero exception */ clrl r9 movpsl r7 /* R7 = expected PSL */ epc3: divl2 $0,r8 /* Should cause fault .. */ movpsl r1 movl $1,r0 /* Error : No fault happen */ jmp *badrtn # # forcing arithmetic fault (int. overflow) by dividing # MAX negative no. by -1 # pc4: movab epc4,r5 /* R5 = expected PC; next inst. */ movab epc40,r3 /* R3 = PC that failed */ movab pc5,r6 /* R6 = return addr from evt handler */ movl $1,r4 /* R4 = expected code on stack */ movl $0x80000000,r8 clrl r9 epc40: divl2 $-1,r8 /* Should get overflow exception */ epc4: movpsl r1 /* R7 = expected PSL */ movl $1,r0 /* Error : No fault happen */ jmp *badrtn # # forcing arithmetic fault (int. overflow) by dividing # MAX negative no. by 0 (using DIVL3) # pc5: movl $0x500,r0 /* R0 = error code */ movab epc5,r5 /* R5 = expected PC */ movl r5,r3 movab pc6,r6 /* R6 = return addr from evt handler */ movl $2,r4 /* R4 = expected error code on stack */ movl $0x80000000,r8 clrl r9 movpsl r7 /* R7 = expected PSL */ epc5: divl3 $0,r8,r9 /* Should cause fault .. */ movpsl r1 movl $1,r0 /* Error : No fault happen */ jmp *badrtn # # forcing arithmetic fault (int. overflow) by dividing # MAX negative no. by -1 (using DIVL3) # pc6: movl $0x600,r0 /* R0 = error code */ bicpsw $0x3f /* Clear PSW */ bispsw $0x20 /* Enable overflow exception */ movab epc6,r5 /* R5 = expected PC */ movab epc60,r3 movab pc11,r6 /* R7 = return addr from evt handler */ movl $1,r4 /* R4 = expected error code on stack */ movl $0x80000000,r8 clrl r9 movpsl r7 /* R7 = expected PSL */ epc60: divl3 $-1,r8,r9 /* Should get overflow exception */ epc6: movpsl r1 movl $1,r0 /* Error : No fault happen */ jmp *badrtn # # forcing arithmetic fault (int. overflow) by dividing # MAX negative no. by 0 (using EDIV) # pc11: movl $0xb00,r0 /* R0 = error code */ movab epc11,r5 /* R5 = expected PC */ movl r5,r3 movab pc12,r6 /* R6 = return addr from evt handler*/ movl $2,r4 /* R4 = expected code on stack */ movl $0x80000000,r8 clrl r10 clrl r9 movpsl r7 /* R7 = expected PSL */ epc11: ediv $0,r8,r9,r10 /* Should cause fault .. */ movpsl r1 movl $1,r0 /* Error : No fault happen */ jmp *badrtn # # forcing arithmetic fault (int. overflow) by dividing # MAX negative no. by -1 (using EDIV) # pc12: movl $0xc00,r0 /* R0 = error code */ bispsw $0x20 /* Enable overflow exception */ movab epc12,r5 /* R5 = expected PC */ movab epc120,r3 movab eee,r6 /* R6 = return addr from evt handler*/ movl $1,r4 /* R4 = expected code on stack */ movl $0x80000000,r8 clrl r9 clrl r10 movpsl r7 /* R7 = expected PSL */ epc120: ediv $-1,r8,r9,r10 /* Should get overflow exception */ epc12: movpsl r1 movl $1,r0 /* Error : No fault happen */ jmp *badrtn # # ********************************** # Event handler for arithmetic fault # ********************************** .align 2 arthflt: cmpl $-1,r4 /* Is fault expected ? */ bneq 1f /* if YES then skip to 1f */ movl $3,r0 /* Error : exception not expected */ movl (sp)+,r1 /* R1 = fault type */ movl (sp),r2 /* R2 = PC on the stack */ jmp *badrtn 1: movl (sp)+,r1 /* Get actual error code from stack */ movl r4,r2 /* R2 = expected error code */ cmpl r1,r2 beql 1f movl $4,r0 /* Error : wrong error code on stack */ jmp *badrtn 1: movl (sp)+,r1 /* R1 = actual PC pop from stack */ movl r5,r2 /* R5 = expected PC */ cmpl r1,r2 beql 1f movl $5,r0 /* Error : wrong PC on stack */ jmp *badrtn /* R1 = actual; R2 = expected */ # 1: movl (sp)+,r1 /* R1 = actual PSL pop from stack */ andl2 $0xfffffff0,r1 /* Mask out PSW flags */ andl3 $0xfffffff0,r7,r2 /* R2 = actual PSL */ cmpl r2,r1 beql 1f movl $6,r0 /* Error : wrong PSL on stack */ jmp *badrtn # 1: cmpl $-1,(sp) /* SP should point at the marker */ beql 1f movl $7,r0 /* Error : too many lgwords pushed on SP */ jmp *badrtn # 1: bitl $2,r1 /* Check if PSL_V on stack is reset */ beql 1f movl $8,r0 /* Error : PSL_V on SP is not OFF */ jmp *badrtn # 1: movl r1,-(sp) /* Set up PSL, PC to return from fault */ movl r6,-(sp) rei halt /* Should never come here */ # # *************************** # All done; return to monitor # eee: mtpr $31,$IPL movl _savvec0,sp /* Restore stack, vector */ movl _savvec2,_scb+ARITHVEC ret
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.