// // TITLE("Interrupts service routine") //++ // // Copyright (c) 1994 Kobe NEC Software // // Module Name: // // rxint.s // // Abstract: // // // Author: // // // Environment: // // Kernel mode only. // // Revision History: // // //-- #include "halmips.h" #include "r98bdef.h" SBTTL("HalpNmiHandler") //++ // K001 // Routine Description: // // This routine is reset status Register on NMI. // Return from this function EIF Interrupt Occur!! // Argments: // // None. // // Return Value: // // None. // //-- LEAF_ENTRY(HalpNmiHandler) .set noat .set noreorder // // // reset NMIR register, set NMI flag and save CPU register. // li k0,0xb9800388 // Set Colombs STSR local address li k1,0x08080000 // Disable NMI sw k1,0x0(k0) // store value la k0,HalpSvpAlive // SVP check lw k1,0x0(k0) nop beq k1,zero,10f nop la k0,HalpLogLock 3: ll k1,0(k0) // get current lock value bne zero,k1,3b // if ne, spin lock owned nop li k1,0x1 sc k1,0(k0) // set spin lock owned beq zero,k1,3b // if eq, store conditional failure nop la k0,HalpSvpGlobal // NMI clear lw k1,0x0(k0) li k0,0x80 sb k0,0x42(k1) sync nop nop nop nop nop nop nop la k0,HalpSvpWindow2 // Nmi para clear lw k1,0x0(k0) lb k0,0xe6(k1) sync la k0,HalpSvpGlobal //Svp EIF MASK lw k1,0x0(k0) sb zero,0x49(k1) sync nop nop nop nop nop nop lb k0,0x58(k1) // Windows2 write lock la k1,HalpNmiSvp sw k0,0x0(k1) sync la k0,HalpSvpGlobal lw k1,0x0(k0) li k0,0xff sb k0,0x58(k1) sync nop nop nop nop nop nop la k0,HalpSvpWindow2 // Nmi para clear lw k1,0x0(k0) 4: sb zero,0xe6(k1) sync nop nop nop nop nop nop nop lb k0,0xe6(k1) bne zero,k0,4b nop la k0,HalpNmiSvp // Svp Window2 lock lw k1,0x0(k0) la k0,HalpSvpGlobal lw k0,0x0(k0) nop sb k1,0x58(k0) sync nop nop nop nop nop nop la k0,HalpLogLock // ZERO CLEAR sw zero,0x0(k0) nop // spinlock // lw t0,KiPcr + PcCurrentThread(zero) // get address of current thread #if 0 la k0,HalpLogLock 5: ll k1,0(k0) // get current lock value bne zero,k1,5b // if ne, spin lock owned nop li k1,0x1 sc k1,0(k0) // set spin lock owned beq zero,k1,5b // if eq, store conditional failure nop #endif // // Check it DUMP Key or Power SW // To Checked Interrupt cause SetUp MRCMODE to PowerSW Interrupt mode. // 10: li k0, 0xbf0f0000 //LBCTL addr lb k0, (k0) li k1, 0x40 and k1,k0,k1 bne zero,k1,10b nop // // Local Device Lock Complete // #if 1 //SVP // // when EXTNMI happend. which NMI DUMP Key or SVP // li k0, 0xbf0f0018 //LBADH addr li k1, 0x02 //MRCMODE Hi sb k1, (k0) li k0, 0xbf0f0010 //LBADL addr li k1, 0x08 //MRCMODE li sb k1, (k0) li k0, 0xbf0f0000 //LBCTL addr li k1, 0x18 //Read Command sb k1, (k0) 99: li k0, 0xbf0f0000 //LBCTL addr lb k1, (k0) //LBCTL read li k0, 0x10 //CMD Bit and k1,k0,k1 bne zero,k1, 99b nop li k0, 0xbf0f0020 //LBDT addr lb k0, (k0) //Read MRMODE Register Value li k1,0x2 //MRCMODE register DUMP Bit and k1,k0,k1 bne zero,k1,Dump // if neq --> dump key nop nop // Save CPU Register Context // // #if 0 li k0,0xb9800310 // get Colombs REVR Local Address lw k0 ,0x0(k0) // get value li k1,0x03000000 // NODE Bit Mask. But low 2 bit only and k0,k0,k1 // Get NODE Bit Only srl k0,k0,17 // shift right 17(23 - 6) bit for offset la k1,HalpNmiSvp // get performance counter address addu k0,k0,k1 // compute address of nmi buffer lw k1,0x0(k0) addi k1,k1,1 sw k1,0x0(k0) nop nop //#endif la k0,HalpSvpAlive // SVP check lw k1,0x0(k0) nop beq k1,zero,5f nop la k0,HalpLogLock 3: ll k1,0(k0) // get current lock value bne zero,k1,3b // if ne, spin lock owned nop li k1,0x1 sc k1,0(k0) // set spin lock owned beq zero,k1,3b // if eq, store conditional failure nop la k0,HalpSvpGlobal //Svp Windows2 lock lb k1,0x58(k0) la k0,HalpNmiSvp sb k1,0x0(k0) sync la k0,HalpSvpGlobal li k1,0xff sb k1,0x58(k0) sync la k0,HalpSvpWindow2 // Nmi para clear lb k1,0xe6(k1) sb zero,0xe6(k0) sync la k0,HalpNmiSvp // Svp Window2 lock lb k1,0x0(k0) la k0,HalpSvpGlobal sb k1,0x58(k0) sync la k0,HalpLogLock // ZERO CLEAR sw zero,0x0(k0) nop #endif j 25f nop Dump: #endif la k0,HalpDumpFlag li k1,0x01 sw k1,0x0(k0) li k0, 0xbf0f0018 //LBADH addr li k1, 0x02 //MRCMODE Addr Hi sb k1, (k0) li k0, 0xbf0f0010 //LBADL addr li k1, 0x08 //MRCMODE Addr li sb k1, (k0) li k0, 0xbf0f0020 //LBDT addr li k1, 0x80 // sb k1, (k0) // li k0, 0xbf0f0000 //LBCTL addr li k1, 0x10 //Write Command sb k1, (k0) 20: li k0, 0xbf0f0000 //LBCTL addr lb k1, (k0) //LBCTL read li k0, 0x10 //CMD Bit and k1,k0,k1 bne zero,k1, 20b nop 25: // // MRCMODE Setuped to MRCINT mode. // So Check DUMP Key or Power Switch li k0, 0xbf0f0018 //LBADH addr li k1, 0x02 //MRCINT Hi sb k1, (k0) li k0, 0xbf0f0010 //LBADL addr li k1, 0x00 //MRCINT li sb k1, (k0) li k0, 0xbf0f0000 //LBCTL addr li k1, 0x18 //Read Command sb k1, (k0) 50: li k0, 0xbf0f0000 //LBCTL addr lb k1, (k0) //LBCTL read li k0, 0x10 //CMD Bit and k1,k0,k1 bne zero,k1, 50b nop li k0, 0xbf0f0020 //LBDT addr lb k0, (k0) //Read MRCINT Register Value li k1,0x4 //MRCINT register OFFSW Bit and k1,k0,k1 beq zero,k1,DumpKey // if eq --> Not Power SW. it is DUMP Key. nop nop #if DBG li k0,0xb9800310 // get Colombs REVR Local Address lw k1 ,0x0(k0) // get value li k0,0x03000000 // NODE Bit Mask. But low 2 bit only and k0,k0,k1 // Get NODE Bit Only srl k1,k0,22 // shift right 24>> <<2 bit for offset la k0,HalpResetCount // get address addu k0,k0,k1 // compute address of nmihappend buffer lw k1,0x0(k0) addi k1,k1,1 sw k1,0x0(k0) nop #endif // // This Is Power Switch NMI so Power down. // resetloop: li k0, 0xbf0f0018 //LBADH addr li k1, 0x02 //Power S/W Hi sb k1, (k0) li k0, 0xbf0f0010 //LBADL addr li k1, 0x30 //Power S/W li sb k1, (k0) li k0, 0xbf0f0020 //LBDT addr li k1, 0x01 //Set Power SW OFF sb k1, (k0) li k0, 0xbf0f0000 //LBCTL addr li k1, 0x10 //Write Command sb k1, (k0) poll6: li k0, 0xbf0f0000 //LBCTL addr lb k1, (k0) //LBCTL read li k0, 0x10 //CMD Bit and k1,k0,k1 bne zero,k1, poll6 nop j resetloop nop nop // // This Is DUMP KEY NMI // DumpKey: // // Early time I was crashed ? // li k0,0xb9800310 // get Colombs REVR Local Address lw k1 ,0x0(k0) // get value li k0,0x03000000 // NODE Bit Mask. But low 2 bit only and k0,k0,k1 // Get NODE Bit Only srl k1,k0,22 // shift right 24>> <<2 bit for offset la k0,HalpNMIHappend // get address addu k0,k0,k1 // compute address of nmihappend buffer lw k1,0x0(k0) nop nop beq zero,k1,doeif //if eq it was first time dump key. nop nop // // Setup DUMP Key And Power Key to NMI // li k0, 0xbf0f0018 //LBADH addr li k1, 0x02 //MRCMODE Hi sb k1, (k0) li k0, 0xbf0f0010 //LBADL addr li k1, 0x08 //MRCMODE li sb k1, (k0) li k0, 0xbf0f0020 //LBDT addr li k1, 0x0 //DUMP KEY Reset. sb k1, (k0) // li k0, 0xbf0f0000 //LBCTL addr li k1, 0x10 //Write Command sb k1, (k0) 34: li k0, 0xbf0f0000 //LBCTL addr lb k1, (k0) //LBCTL read li k0, 0x10 //CMD Bit and k1,k0,k1 bne zero,k1, 34b nop #if DBG li k0,0xb9800310 // get Colombs REVR Local Address lw k1 ,0x0(k0) // get value li k0,0x03000000 // NODE Bit Mask. But low 2 bit only and k0,k0,k1 // Get NODE Bit Only srl k1,k0,22 // shift right 24>> <<2 bit for offset la k0,HalpNMISecond // get address addu k0,k0,k1 // compute address of nmihappend buffer lw k1,0x0(k0) addi k1,k1,1 sw k1,0x0(k0) #endif nomakeeif: // // UnLock // li k0, 0xbf0f0000 //LBCTL addr li k1, 0x80 // sb k1, (k0) nop nop // CHIPSet Reset // This version implement of EXNMI Only. // // li k0,0xb9800038 // get Colombs NMIRST Local Address li k1,0xf // Bit Reset sw k1,(k0) // reset nmi li k0,0xb9800388 // Set Colombs STSR local address li k1,0x00080000 // Enable NMI sw k1,0x0(k0) // store value nop // CPU Reset. // This is a test code. // We must clear BEV bit of psr register. // mfc0 k1,psr // get psr li k0,0xffbfffff // clear BEV bit nop // fill nop // fill and k1,k1,k0 // nop // nop // mtc0 k1,psr // set psr nop // fill nop // nop // nop eret // return to errorepc nop nop nop eret // errata nop // This Is First NMI By DUMP Key. // Save CPU Context. And Markd. // And Make EIF!! // doeif: addi k1, k1, 0x1 // mark set. nop sw k1, 0x0(k0) // HalpNMIHappend[NODE] = 1 nop // // MRCMODE Register Set Up For Next NMI (DumpKey and PoeHwerSW) // #if 0 // // MRCINT Clear // nop li k0, 0xbf0f0018 //LBADH addr li k1, 0x02 //MRCINT Hi sb k1, (k0) li k0, 0xbf0f0010 //LBADL addr li k1, 0x00 //MRCINT li sb k1, (k0) li k0, 0xbf0f0020 //LBDT addr li k1, 0x0 //Reset PowerOff Interrupt sb k1, (k0) li k0, 0xbf0f0000 //LBCTL addr li k1, 0x10 //Write Command sb k1, (k0) 250: li k0, 0xbf0f0000 //LBCTL addr lb k1, (k0) //LBCTL read li k0, 0x10 //CMD Bit and k1,k0,k1 bne zero,k1, 250b nop #endif // // Reset NMI // li k0, 0xbf0f0018 //LBADH addr li k1, 0x02 //MRCMODE Hi sb k1, (k0) li k0, 0xbf0f0010 //LBADL addr li k1, 0x08 //MRCMODE li sb k1, (k0) li k0, 0xbf0f0020 //LBDT addr li k1, 0x0 //DUMP KEY Reset. sb k1, (k0) // li k0, 0xbf0f0000 //LBCTL addr li k1, 0x10 //Write Command sb k1, (k0) 64: li k0, 0xbf0f0000 //LBCTL addr lb k1, (k0) //LBCTL read li k0, 0x10 //CMD Bit and k1,k0,k1 bne zero,k1, 64b nop #if 0 // // SetUp NMIFlag for rxeif.c // la k0,HalpNMIFlag // set NMI flag address li k1,0xb9800030 // set Colombs NMIR local address lw k1,(k1) // get NMIR register value // // N.B NMIR register high 16 bit is RFU. // so used s/w flag for Hal. sw k1,(k0) // store NMIR regiser value to HalpNmiFlag // // UnLock Local Device // li k0, 0xbf0f0000 //LBCTL addr li k1, 0x80 // sb k1, (k0) #endif // Save CPU Register Context // // li k0,0xb9800310 // get Colombs REVR Local Address lw k0 ,0x0(k0) // get value li k1,0x03000000 // NODE Bit Mask. But low 2 bit only and k0,k0,k1 // Get NODE Bit Only srl k0,k0,16 // shift right 16(23 - 5) bit for offset la k1,HalpNMIBuf // get performance counter address addu k0,k0,k1 // compute address of nmi buffer // sw at,0x0(k0) // register save.0 sw v0,0x4(k0) // 1 sw v1,0x8(k0) // 2 sw a0,0xc(k0) // 3 sw a1,0x10(k0) // 4 sw a2,0x14(k0) // 5 sw a3,0x18(k0) // 6 sw t0,0x1c(k0) // 7 sw t1,0x20(k0) // 8 sw t2,0x24(k0) // 9 sw t3,0x28(k0) // 10 sw t4,0x2c(k0) // 11 sw t5,0x30(k0) // 12 sw t6,0x34(k0) // 13 sw t7,0x38(k0) // 14 sw t8,0x3c(k0) // 15 sw t9,0x40(k0) // 16 sw gp,0x44(k0) // 17 sw sp,0x48(k0) // 18 sw s8,0x4c(k0) // 19 sw ra,0x50(k0) // 20 mfc0 k1,psr // 21 sw k1,0x54(k0) // mfc0 k1,cause // 22 sw k1,0x58(k0) // mfc0 k1,epc // 23 sw k1,0x5c(k0) // mfc0 k1,errorepc // 24 sw k1,0x60(k0) // #if 1 //ras sw s0,0x64(k0) // 25 sw s1,0x68(k0) // 26 sw s2,0x6c(k0) // 27 sw s3,0x70(k0) // 28 sw s4,0x74(k0) // 29 sw s5,0x78(k0) // 30 sw s6,0x7c(k0) // 31 sw s7,0x80(k0) // 32 mfc0 k1,entrylo0 // sw k1,0x84(k0) // 33 mfc0 k1,entrylo1 // sw k1,0x88(k0) // 34 mfc0 k1,badvaddr // sw k1,0x8c(k0) // 35 mfc0 k1,entryhi sw k1,0x90(k0) // 36 mfc0 k1,pagemask sw k1,0x94(k0) // 37 mfc0 k1,prid sw k1,0x98(k0) // 38 mfc0 k1,config sw k1,0x9c(k0) // 39 mfc0 k1,lladdr sw k1,0xa0(k0) // 40 mfc0 k1,watchlo sw k1,0xa4(k0) // 41 mfc0 k1,watchhi sw k1,0xa8(k0) // 42 mfc0 k1,$20 //xcontext sw k1,0xac(k0) // 43 mfc0 k1,ecc sw k1,0xb0(k0) // 44 mfc0 k1,cacheerr sw k1,0xb4(k0) // 45 mfc0 k1,taglo sw k1,0xb8(k0) // 46 mfc0 k1,taghi sw k1,0xbc(k0) // 47 #endif #if 0 // // Copy CPU state to NvRAM. // li t0,0xb9800388 // Set Colombs STSR local address li t1,0x00040000 // Enable write to NvRam sw t1,0x0(t0) // store value li t0,0xb9800310 // get Colombs REVR Local Address lw t0,0x0(t0) // get value li t1,0x03000000 // NODE Bit Mask. But low 2 bit only and t0,t0,t1 // Get NODE Bit Only srl t0,t0,16 // shift right 16(23 - 5) bit for offset li t1,0xbf09dc00 addu t0,t0,t1 // compute address of nmi buffer move t1,k0 // src address li t2,0x100 // calc end address addu t2,t2,t0 cploop: lb t3,0(t1) addiu t1,t1,1 sb t3,0(t0) addiu t0,t0,1 bne t2,t0,cploop nop lw t0,0x1c(k0) // 7 lw t1,0x20(k0) // 8 lw t2,0x24(k0) // 9 lw t3,0x28(k0) // 10 #endif #if 1 // // SetUp NMIFlag for rxeif.c // la k0,HalpNMIFlag // set NMI flag address lw k1,(k0) // get HalpNmiFlag bne zero,k1, nomakeeif nop li k1,0xb9800030 // set Colombs NMIR local address lw k1,(k1) // get NMIR register value // // N.B NMIR register high 16 bit is RFU. // so used s/w flag for Hal. sw k1,(k0) // store NMIR regiser value to HalpNmiFlag #endif // // UnLock // li k0, 0xbf0f0000 //LBCTL addr li k1, 0x80 // sb k1, (k0) // CHIPSet Reset // This version implement of EXNMI Only. // // li k0,0xb9800038 // get Colombs NMIRST Local Address li k1,0xf // Bit Reset sw k1,(k0) // reset nmi li k0,0xb9800388 // Set Colombs STSR local address li k1,0x00080000 // Enable NMI sw k1,0x0(k0) // store value nop // CPU Reset. // This is a test code. // We must clear BEV bit of psr register. // mfc0 k1,psr // get psr li k0,0xffbfffff // clear BEV bit nop // fill nop // fill and k1,k1,k0 // nop // nop // mtc0 k1,psr // set psr nop // fill nop // nop // // // Do EIF to Myself. // // li k0,0xb9800310 // get Colombs REVR Local Address lw k0 ,0x0(k0) // get value li k1,0x03000000 // NODE Bit Mask. node 4-7 and k0,k0,k1 // Get NODE Bit Only (lower 3 Bit Only) srl k0,k0,24 // Convert CPU number li k1,0x00080000 // Node 4 set srl k1,k1,k0 // make Node Bit (NODE 4 >> CpuNumber) li k0,0x82000000 // OP bit And Atlantic code 0x2 = EIF or k1,k1,k0 // make OP Bit And CODE And NODE li k0,0xb9800580 // get Colombs IntIR Local Address sw k1,(k0) // nop nop eret // return to errorepc nop nop nop eret // errata nop nop // for interrupt cache aligned line nop nop nop nop .set at .set reorder .end HalpNmiHandler SBTTL("Int 1 Interrupt") //++ // // Routine Description: // // This routine is enterd as the result of an Int 1 interrupt. // // Argments: // // s8 - Supplies a pointer to a trap frame. // // Return Value: // // None. // //-- LEAF_ENTRY(HalpInt1Dispatch) move a0,s8 // trap frame li a1,0x1 // Interrupt is INT1 j HalpGeneralDispatch .end SBTTL("Int 2 Interrupt") //++ // // Routine Description: // // This routine is enterd as the result of an Int 2 interrupt. // // Argments: // // s8 - Supplies a pointer to a trap frame. // // Return Value: // // None. // //-- LEAF_ENTRY(HalpInt2Dispatch) move a0,s8 // trap frame li a1,0x2 // Interrupt is INT2 j HalpGeneralDispatch .end SBTTL("Int 3 Interrupt") //++ // // Routine Description: // // This routine is enterd as the result of an Int 3 interrupt. // // Argments: // // s8 - Supplies a pointer to a trap frame. // // Return Value: // // None. // //-- LEAF_ENTRY(HalpInt3Dispatch) move a0,s8 // trap frame li a1,0x3 // Interrupt is INT3 j HalpGeneralDispatch .end SBTTL("Int 4 Interrupt") //++ // // Routine Description: // // This routine is enterd as the result of an Int 4 interrupt. // // This routine checks for IPI interrupt. The IPI interrupt is // ip[5] on the R98B and ip[6] on the R98A. So this routine // reads the cause register to determine correct dispatch function // // CAVEAT: This is an R98B specific routine. It is only // called on an R98B. // CAVEAT: This routine is only used on NT 4.0 because Nt3.51 does // not have SYNC IRQL // Argments: // // s8 - Supplies a pointer to a trap frame. // // Return Value: // // None. // //-- #if defined(NT_40) // // SYNCH Level must enable IPI on R98B. // Sync level enable IPI on R98A . // But on R98B, Sync level disable IPI. // So, on R98B, we need to change Irql mask table. // Hal determines IPI or EIF here. // Because when IPI occured, HAl returns same IRQL value from EIF. // v-masank@microsoft.com 5/11/96 // Thanks for samejima's comments // I change that following function is for R98B only. // Because R98A does not need following function. // v-masank@microsoft.com 5/21/96 // LEAF_ENTRY(HalpT5Int4Dispatch) move a0,s8 // trap frame READ_CAUSE_REGISTER(t0) // Read Cause register and t0,t0,0x00004000 // INT4 ? bne t0,zero,10f // ne INT4 li a1,0x3 // INT3 j HalpGeneralDispatch 10: li a1,0x4 // Interrupt is INT4 j HalpGeneralDispatch .end #endif //++ // // Routine Description: // // This routine is enterd as the result of an Int 4 interrupt. // // CAVEAT: This routine used by R98A on NT 3.51 and NT4.0 // This routine used by R98B on NT 3.51 // // CAVEAT: This routine is only used on NT 3.51 because Nt3.51 does // not have SYNC IRQL // Argments: // // s8 - Supplies a pointer to a trap frame. // // Return Value: // // None. // //-- LEAF_ENTRY(HalpInt4Dispatch) move a0,s8 // trap frame li a1,0x4 // Interrupt is INT4 j HalpGeneralDispatch .end SBTTL("Read Cause Register") //++ // S005 // Routine Description: // // This routine is get of cause register // // Argments: // // None. // // Return Value: // // cause rezister value. // //-- LEAF_ENTRY(HalpGetCause) READ_CAUSE_REGISTER(v0) j ra // return .end HalpGetCause SBTTL("Int 0 Interrupt") //++ // // Routine Description: // // This routine is enterd as the result of an Int 1 interrupt. // // Argments: // // s8 - Supplies a pointer to a trap frame. // // Return Value: // // None. // //-- LEAF_ENTRY(HalpInt0Dispatch) move a0,s8 // trap frame li a1,0x0 // Interrupt is INT0 j HalpGeneralDispatch .end SBTTL("Int 5 Interrupt") //++ // // Routine Description: // // This routine is enterd as the result of an Int 1 interrupt. // // Argments: // // s8 - Supplies a pointer to a trap frame. // // Return Value: // // None. // //-- LEAF_ENTRY(HalpInt5Dispatch) move a0,s8 // trap frame li a1,0x5 // Interrupt is INT5 j HalpGeneralDispatch .end //#if 0 // I use following function for performance. // v-masank@microsoft.com 5/21/96 //++ SBTTL("Read Large Register") // // Routine Description: // // This routine is read of large register // // Argments: // // a0 - Virtual address // // a1 - pointer to buffer of large register // // Return Value: // // None. // //-- LEAF_ENTRY(HalpReadLargeRegister) #if !defined(NT_40) lw t2,0x0(a0) // get register(upper) lw t3,0x4(a0) // get register(lower) sw t2,0x0(a1) // set upper register value sw t3,0x4(a1) // set lower register value #else ld t2,0x0(a0) // get register sd t2,0x0(a1) // set register #endif j ra // return .end HalpReadLargeRegister SBTTL("Write Large Register") //++ // // Routine Description: // // This routine is write of large register // // Argments: // // a0 - Virtual address // // a1 - pointer to value of large register // // Return Value: // // None. // //-- LEAF_ENTRY(HalpWriteLargeRegister) #if !defined(NT_40) lw t2,0x0(a1) // load register value lw t3,0x4(a1) // sw t2,0x0(a0) // set register value sw t3,0x4(a0) // #else ld t2,0x0(a1) sd t2,0x0(a0) #endif sync // j ra // return .end HalpWriteLargeRegister //#endif // S005 vvv SBTTL("Read Physical Address") //++ // // Routine Description: // // This routine is read of physical address. // // Argments: // // a0 - Physical address // // Return Value: // // read data. // //-- LEAF_ENTRY(HalpReadPhysicalAddr) li t1,0x90000000 .set noreorder .set noat li t6,1 << PSR_CU1 // disable interrupt ori t6,t6,1 << PSR_KX // use 64bit address mode mfc0 t7,psr // mtc0 t6,psr // nop nop .set at .set reorder and t0,zero,zero dsll t0,t1,32 // shift entry address to upper 32-bits or t0,t0,a0 // make access address lw v0,0(t0) .set noreorder .set noat mtc0 t7,psr // enable interrupt nop .set at .set reorder j ra // return .end HalpReadPhysicalAddress // S005 ^^^ // S006 vvv SBTTL("Write Physical Address") //++ // // Routine Description: // // This routine is Write of physical address. // // Argments: // // a0 - Physical address // // a1 - Write Data // // Return Value: // // None. // //-- LEAF_ENTRY(HalpWritePhysicalAddr) li t1,0x90000000 .set noreorder .set noat li t6,1 << PSR_CU1 // disable interrupt ori t6,t6,1 << PSR_KX // use 64bit address mode mfc0 t7,psr // mtc0 t6,psr // nop nop .set at .set reorder and t0,zero,zero dsll t0,t1,32 // shift entry address to upper 32-bits or t0,t0,a0 // make access address sw a1,0(t0) .set noreorder .set noat mtc0 t7,psr // enable interrupt nop .set at .set reorder j ra // return .end HalpWritePhysicalAddress SBTTL("Read And Write Physical Address") //++ // // Routine Description: // // This routine is read and write of physical address. // // Argments: // // a0 - Physical address // // Return Value: // // read data. // //-- LEAF_ENTRY(HalpReadAndWritePhysicalAddr) li t1,0x90000000 .set noreorder .set noat li t6,1 << PSR_CU1 // disable interrupt ori t6,t6,1 << PSR_KX // use 64bit address mode mfc0 t7,psr // mtc0 t6,psr // nop nop .set at .set reorder and t0,zero,zero dsll t0,t1,32 // shift entry address to upper 32-bits or t0,t0,a0 // make access address lw v0,0(t0) sw v0,0(t0) .set noreorder .set noat mtc0 t7,psr // enable interrupt nop .set at .set reorder j ra // return .end HalpReadAndWritePhysicalAddress // S006 ^^^ #if 0 //koredmo ugoku kedo waikomi disable ha amari yokuarimasenn.... //++ // // VOID // READ_REGISTER_ULONGLONG ( // IN PLARGE_INTEGER RegisterAddress, // IN PVOID Variable // ) // // Routine Description: // // 64-bit register read function. // // Arguments: // // RegisterAddress (a0) - Supplies a pointer to the destination address of // the move operation. // // Variable (a1) - Supplies a pointer to the source address of the move // operation. // // Return Value: // // None. // // Destination and Source must be 8-byte aligned. // //-- #if 1 .struct 0 sv1f0: .space 4*2 Length1F0: NESTED_ENTRY(READ_REGISTER_ULONGLONG, Length1F0, zero) subu sp,sp,Length1F0 // allocate stack frame DISABLE_INTERRUPTS(t7) // disable interrupts sdc1 f0,sv1f0(sp) // f0 save #else LEAF_ENTRY(READ_REGISTER_ULONGLONG) #endif ldc1 f0,0(a0) // move 8-byte block sdc1 f0,0(a1) // #if 1 ldc1 f0,sv1f0(sp) // f0 resume addu sp,sp,Length1F0 // deallocate stack frame ENABLE_INTERRUPTS(t7) // enable interrupts #endif sync // synchronize read j ra // return .end READ_REGISTER_ULONGLONG //++ // // VOID // WRITE_REGISTER_ULONGLONG ( // IN PLARGE_INTEGER RegisterAddress, // IN PVOID Variable // ) // // Routine Description: // // 64-bit I/O space register write function. // // Arguments: // // RegisterAddress (a0) - Supplies a pointer to the destination address of // the move operation. // // Variable (a1) - Supplies a pointer to the source address of the move // operation. // // Return Value: // // None. // // Destination and Source must be 8-byte aligned. // //-- #if 1 .struct 0 sv2f0: .space 4*2 Length2F0: NESTED_ENTRY(WRITE_REGISTER_ULONGLONG, Length2F0, zero) subu sp,sp,Length2F0 // allocate stack frame DISABLE_INTERRUPTS(t7) // disable interrupts sdc1 f0,sv2f0(sp) // f0 save #else LEAF_ENTRY(WRITE_REGISTER_ULONGLONG) #endif ldc1 f0,0(a1) // move 8-byte block sdc1 f0,0(a0) // #if 1 ldc1 f0,sv2f0(sp) // f0 resume addu sp,sp,Length2F0 // deallocate stack frame ENABLE_INTERRUPTS(t7) // enable interrupts #endif sync // synchronize write j ra // return .end WRITE_REGISTER_ULONGLONG #else //korede warikomi ha enable no mama syori dekimasu. // // // // .struct 0 CiArgs: .space 4 * 4 // saved arguments .space 3 * 4 // fill Rt7: .space 4 Rt8: .space 4 LengthRtN: NESTED_ENTRY(READ_REGISTER_ULONGLONG, LengthRtN, zero) // DISABLE_INTERRUPTS(t9) // disable interrupts subu sp,sp,LengthRtN // allocate stack frame PROLOGUE_END sw t7,Rt7(sp) sw t8,Rt8(sp) lw t7,0x0(a0) lw t8,0x4(a0) sw t7,0x0(a1) sw t8,0x4(a1) lw t7,Rt7(sp) lw t8,Rt8(sp) addu sp,sp,LengthRtN // deallocate stack frame // ENABLE_INTERRUPTS(t9) // enable interrupts sync // synchronize read j ra // return .end READ_REGISTER_ULONGLONG // // // // .struct 0 DiArgs: .space 4 * 4 // saved arguments .space 3 * 4 // fill Wt7: .space 4 Wt8: .space 4 LengthWtN: NESTED_ENTRY(WRITE_REGISTER_ULONGLONG, LengthWtN, zero) // DISABLE_INTERRUPTS(t9) // disable interrupts subu sp,sp,LengthWtN // allocate stack frame PROLOGUE_END sw t7,Wt7(sp) sw t8,Wt8(sp) lw t7,0x0(a1) lw t8,0x4(a1) sw t7,0x0(a0) sw t8,0x4(a0) lw t7,Wt7(sp) lw t8,Wt8(sp) addu sp,sp,LengthWtN // deallocate stack frame // ENABLE_INTERRUPTS(t9) // enable interrupts sync // synchronize read j ra // return .end WRITE_REGISTER_ULONGLONG #endif SBTTL("T5 Int 5 Interrupt") // // On the R98B (r10k) this hardware interrupt is for the internal timer // interrupt. This is not used for the PROFILE interrupt on the R98B // // // InternalTimer interrupt does not use for profile interrupt. // So,Here is only clear internal interrupt. // v-masank@microsoft.com LEAF_ENTRY(HalpT5Int5Dispatch) .set noreorder .set noat // mfc0 t1,count // get current count value mfc0 t0,compare // get current comparison value // addu t1,t1,8 // factor in lost cycles // subu t1,t1,t0 // compute initial count value mtc0 t0,compare // dismiss interrupt nop nop .set at .set reorder move a0,s8 // trap frame li a1,0x5 // Interrupt is INT5 j HalpGeneralDispatch .end HalpT5Int5Dispatch