|
|
Power 6/32 Unix version 1.21
# # reserved operand event test # # includes mtpr,mfpr,&rei # # R7 = which instruction is testing # 1 - MTPR # 2 - MFPR # 3 - REI # R3 = PC that force fault # R0 = error code # 1 : expected reserved operand fault didnot happen # 2 : error in PC pushed on stack # R1 = actual, R2 = expected # 3 : error in PSL pushed on stack # R1 = actual, R2 = expected # 4 : Too many parameters pushed on the stack # 5 : REI did not catch bad PC/PSL on the stack # .set N_EXIST_PR,255 .globl _roprnd_evt _roprnd_evt: .word 0x1fff mtpr $31,$IPL /* disable interrupts */ movab (sp),_savvec0 /* Save current SP (ISP) */ mtpr _savvec0,$ISP /* Set ISP = current SP */ mfpr $KSP,_savvec9 /* Save kernal stack pointer */ mfpr $USP,_savveca /* Save user stack pointer */ movl _scb+ROVEC,_savvec2 /* Save vector of Resr. oprd fault */ movab ropflt1,_scb+ROVEC /* Set new vector */ movl $-1,-(sp) /* Push marker on stack */ movl _scb+PINSTVEC,_savvec3 movpsl r1 /* If PSL_MODE != Kernel then */ bitl $0x01000000,r1 /* change to Kernel mode by */ beql 1f /* executing a privilege inst. */ movab tempvec,_scb+PINSTVEC /* as HALT */ halt .align 2 tempvec: addl2 $8,sp /* Get rid of trash on the stack */ movl _savvec3,_scb+PINSTVEC /* Restore original vector */ # # We are running in Kernel mode; Interrupt stack # MTPR to non existent privileged register */ # 1: movl $0,r11 /* Set flag to be checked in event handler */ movab mfprt,r6 /* R6 = return address after exception */ movab mtprt,r5 /* R5 = expected PC on stack after fault */ movl r5,r3 movl $1,r7 /* R7 = 1; testing MTPR */ movpsl r4 /* R4 = expected PSL */ mtprt: mtpr $0,$N_EXIST_PR /* Should cause reserved operand fault !! */ movl $1,r0 /* R0 = error code; expected reserved */ jmp *badrtn /* operand fault did not happen */ .align 2 /* Event handler for reserved oprd. fault */ ropflt1: movl (sp)+,r1 /* R1 = actual PC from stack */ movl r5,r2 /* R5 = expected PC */ cmpl r1,r2 beql 1f movl $2,r0 /* R0 = error code; PC saved on stack */ jmp *badrtn /* not equal to expexted PC */ /* R1 = actual; R2 = expected */ 1: movl (sp)+,r1 /* R1 = actual PSL from stack */ movl r4,r2 /* R2 = expected PSL */ cmpl r2,r1 /* Are they the same ? */ beql 1f movl $3,r0 /* Error in PSL !! */ jmp *badrtn 1: cmpl $1,r11 /* Is fault caused by REI or MTPR ? */ bneq 1f /* Skip this part if come here from MTPR */ movl (sp)+,r10 /* REI fault : get rid of PC,PSL on the */ movl (sp)+,r10 /* stack then check for marker */ 1: cmpl $-1,(sp) /* Is SP pointing at the marker on SP ? */ beql 1f movl $4,r0 /* If not then error : pushed too many */ jmp *badrtn /* parameters on SP after fault .. */ 1: movpsl r1 /* Get ready to return from fault */ movl r1,-(sp) /* Push current PSL on stack */ movl r6,-(sp) /* R6 = addr to return to */ rei halt /* Should never come here !!!! */ # # # MFPR from non existent privileged register # mfprt: movl $2,r7 /* R7 = 2; testing MFPR */ movab reit,r6 /* Set R6 = return adddress after fault */ movab mfprt0,r5 /* R5 = expected PC on stack */ movl r5,r3 movpsl r4 /* R4 = expected PSL */ mfprt0: mfpr $N_EXIST_PR,r10 /* Should cause resr. oprd. fault .. */ movl $1,r0 /* Error; expected fault did not happen */ jmp *badrtn # # REI with illegal PSL on the stack : PSL_IS on and PSL_MODE is User # reit: movl $3,r7 /* R7 = 3; testing REI */ movab reit1,r6 /* R6 = return address after exception */ movab reita,r5 /* R5 = expected PC on SP */ movl r5,r3 movl $0x05000000,r1 /* Push PSL on stack; PSL_IS on and */ movl r1,-(sp) /* and PSL_MODE = User */ movab reierr,-(sp) /* PC if REI doesn't catch bad PSL */ movl $1,r11 /* Set flag to be checked in event handler */ reita: rei /* should cause reserved opr. fault */ movl $1,r0 /* Error; expected fault did not happen */ jmp *badrtn /* Should never come here .. */ # # REI with illegal PSL on the stack : PSL_IS on and PSL_IPL = 0 # reit1: movab reit2,r6 /* R6 = return address after exception */ movab reit1a,r5 /* R5 = expected PC on stack */ movl r5,r3 movl $0x04000000,r1 /* Set PSL, PC on stack for REI */ movl r1,-(sp) movab reierr,-(sp) /* PC if REI doesn't catch bad PSL */ reit1a: rei /* Should cause fault */ movl $1,r0 /* Error; expected fault did not happen */ jmp *badrtn /* Should never come here .. */ # # REI with illegal PSL on the stack : PSL_IS off,PSL_IPL > 0 # and PSL_MODE = User # reit2: movab reit3,r6 /* R6 = return address after exception */ movab reit2a,r5 /* R5 = expected PC on stack */ movl r5,r3 movl $0x010f0000,r1 /* Set PSL, PC on stack for REI */ movl r1,-(sp) movab reierr,-(sp) /* PC if REI doesn't catch bad PSl */ reit2a: rei /* Should cause fault */ movl $1,r0 /* Error; expected fault did not happen */ jmp *badrtn /* Should never come here .. */ reit3: movpsl r1 bitl $0x04000000,r1 beql 1f /* If IS is ON, turn it off by */ andl2 $0xfbffffff,r1 /* using REI */ movl r1,-(sp) movab 1f,-(sp) rei jmp *badrtn # # REI with illegal PSL on the stack : PSL_IS is off ; Try to switch # to Interrupt stack by REI # 1: /* Current PSL_IS is OFF */ movl $-1,-(sp) /* push marker on stack (kernal stack) */ movab reit4,r6 /* R6 = return address after exception */ movab reit3a,r5 /* R5 = expected PC on stack */ movl r5,r3 movl $0x04000000,r1 /* Set PSL, PC on stack for REI */ movl r1,-(sp) movab reierr,-(sp) /* PC if REI doesn't catch bad PSL */ movpsl r4 reit3a: rei /* Should cause fault */ movl $1,r0 /* Error; expected fault did not happen */ jmp *badrtn /* Should never come here .. */ # # REI with illegal PSL on the stack : Current PSL_IPL is smaller # than PSL_IPL on stack # reit4: movab reit5,r6 /* R6 = return address after exception */ movab reit4a,r5 /* R5 = expected PC on stack */ movl r5,r3 mtpr $0x10,$IPL /* Set current PSL_IPL = 0x10 */ movpsl r4 movl $0x00180001,r1 /* Set PSL_IPL (on stack) to 0x18 */ movl r1,-(sp) movab reierr,-(sp) /* PC if REI doesn't catch bad PSL */ reit4a: rei /* Should cause fault */ movl $1,r0 /* Error; expected fault did not happen */ jmp *badrtn /* Should never come here .. */ # # reit5: movl $0x01000000,-(sp) /* Set up PSL, PC to use REI to */ movab usrmd,-(sp) /* switch to User mode */ rei jmp *badrtn # # REI with illegal PSL on the stack : Try to switch from USER to # KERNEL mode by REI # usrmd: /* We now running in User mode */ movab reit6,r6 /* R6 = return address after exception */ movab reit5a,r5 /* R5 = expected PC on stack */ movl r5,r3 movl $0x00000000,r1 /* Set up PSL, PC for REI */ movl r1,-(sp) movab reierr,-(sp) /* PC if REI doesn't catch bad PSL */ clrl r11 /* Clear flag */ movpsl r4 reit5a: rei /* Should cause fault */ movl $1,r0 jmp *badrtn /* Should never come here .. */ # # # reit6: movl _savvec3,_scb+PINSTVEC /* Restore vectors */ movl _savvec2,_scb+ROVEC pushl $0 /* Push dummy PSL,PC on stack */ pushl $0 mtpr $31,$IPL /* Reset IPL to HIGH */ svpctx /* Switch to ISP */ btisp: movl _savvec0,sp /* Restore SP */ mtpr _savvec0,$ISP /* Restore ISP */ mtpr _savvec9,$KSP /* Restore KSP */ mtpr _savveca,$USP /* Restore USP */ ret # # # reierr: movl $5,r0 jmp *badrtn /* REI error - REI did not catch illegal PSL*/ /* on the stack !*/
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.