NT4/private/ntos/nthals/halr98b/mips/rxint.s
2020-09-30 17:12:29 +02:00

1565 lines
38 KiB
ArmAsm

//
// 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