NT4/private/ntos/nthals/halr98mp/mips/r98int.s

523 lines
9.6 KiB
ArmAsm
Raw Normal View History

2001-01-01 00:00:00 +01:00
// "@(#) NEC r98int.s 1.14 95/06/19 11:35:43"
// TITLE("Interrupts service routine")
//++
//
// Copyright (c) 1994 Kobe NEC Software
//
// Module Name:
//
// r98int.s
//
// Abstract:
//
//
// Author:
//
//
// Environment:
//
// Kernel mode only.
//
// Revision History:
//
// S001 '94.6/03 T.Samezima
//
// Del iRSF interrupt clear
//
//**************************************************************
//
// S002 94.6/13 T.Samezima
//
// Del Compile err
//
//**************************************************************
//
// S003 94.7/15 T.Samezima
//
// Chg change register access from 8byte access to 4byte access
//
//**************************************************************
//
// S004 94.7/20 T.Samezima
//
// Del Compile err
// K001 94/10/11 N.Kugimoto
// Add.chg HalpNmiHandler() from r98hwsup.c and chg
//
// S005 94/01/15 T.Samezima
// Add HalpReadPhysicalAddr()
//
// S006 94/01/24 T.Samezima
// Add HalpWritePhysicalAddr(),HalpReadAndWritePhysicalAddr(),
//
// S007 94/03/10-17 T.Samezima
// Chg HalpNMIHandler().
//
// A002 1995/6/17 ataka@oa2.kb.nec.co.jp
// - resolve compile error or logic error?
//--
#include "halmips.h"
#include "r98def.h"
SBTTL("Timer Interrupt")
//++
//
// Routine Description:
//
// This routine is enterd as the result of an timer interrupt.
//
// Argments:
//
// s8 - Supplies a pointer to a trap frame.
//
// Return Value:
//
// None.
//
//--
LEAF_ENTRY(HalpTimerDispatch)
move a0,s8
j HalpTimerScDispatch
.end HalpTimerDispatch
SBTTL("Read Large Register")
//++
//
// Routine Description:
//
// This routine is read of large register
//
// Argments:
//
// a0 - Virtual address
//
// a1 - pointer to buffer of upper 32bit large register
//
// a2 - pointer to buffer of lower 32bit large register
//
// Return Value:
//
// None.
//
//--
LEAF_ENTRY(HalpReadLargeRegister)
// Start S003
#if 0
DISABLE_INTERRUPTS(t7) // disable interrupts
mfc1 t0,f0 // save f0 register
mfc1 t1,f1 // save f1 register
ldc1 f0,0x0(a0) // read register
mfc1 t2,f0 // get register(upper)
mfc1 t3,f1 // get register(lower)
#endif
lw t2,0x0(a0) // get register(upper)
lw t3,0x4(a0) // get register(lower)
sw t2,0x0(a1) // set upper register value
sw t3,0x0(a2) // set lower register value
#if 0
mtc1 t0,f0 // restore f0 register
mtc1 t1,f1 // restore f1 register
sync //
ENABLE_INTERRUPTS(t7) // enable interrupts
#endif
// End S003
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 upper 32bit of large register
//
// a2 - pointer to value of lower 32bit of large register
//
// Return Value:
//
// None.
//
//--
LEAF_ENTRY(HalpWriteLargeRegister)
// Start S003
#if 0
DISABLE_INTERRUPTS(t7) // disable interrupts
mfc1 t0,f0 // save f0 register
mfc1 t1,f1 // save f1 register
#endif
lw t2,0x0(a1) // load upper register value
lw t3,0x0(a2) // load lower register value
sw t2,0x0(a0) // set upper register value
sw t3,0x4(a0) // set lower register value
#if 0
mtc1 t2,f0 // set register(upper)
mtc1 t3,f1 // set register(lower)
sdc1 f0,0x0(a0) // write register
mtc1 t0,f0 // restore f0 register
mtc1 t1,f1 // restore f1 register
#endif
sync //
// ENABLE_INTERRUPTS(t7) // enable interrupts
// End S003
j ra // return
.end HalpWriteLargeRegister
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
// 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 ^^^
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
// S007 vvv
//
// reset NMIR register, set NMI flag and save CPU register.
//
li k0,0xb9980308 // Set STSR address
li k1,0x08080000 // Disable NMI
sw k1,0x0(k0) //
la k0,HalpNMIFlag // set NMI flag address
// li k1,0xa0000000 // KSEG1_ACCESS
// or k0,k0,k1 //
li k1,0xb9980030 // set NMIR address
lw k1,(k1) // get NMIR register
addi k1,k1,1 // set NMI flag
sw k1,(k0) //
li k1,0xb8c80000 // Reset NMI
sb zero,0x0(k1) //
#if 1
// lw k0,KiPcr + PcPrcb(zero) // get current processor block address
// la k1,HalpNMIBuf // get performance counter address
// lbu k0,PbNumber(k0) // get processor number
// sll k0,k0,7 // compute address of nmi buffer
// addu k0,k0,k1 //
li k0,0xb9980300 // get CNFG Register Addr of PMC
li k1,0x00007000 // Mask Node Of CPU0-CPU3
lw k0 ,0x0(k0) // get value of etc of PMC
and k0,k0,k1 // get value of NODE
la k1,HalpNMIBuf // get performance counter address
srl k0,k0,5 // shift right 7 bit for offset
addu k0,k0,k1 // compute address of nmi buffer
// sw at,0x0(k0) // register save.
sw v0,0x4(k0) //
sw v1,0x8(k0) //
sw a0,0xc(k0) //
sw a1,0x10(k0) //
sw a2,0x14(k0) //
sw a3,0x18(k0) //
sw t0,0x1c(k0) //
sw t1,0x20(k0) //
sw t2,0x24(k0) //
sw t3,0x28(k0) //
sw t4,0x2c(k0) //
sw t5,0x30(k0) //
sw t6,0x34(k0) //
sw t7,0x38(k0) //
sw t8,0x3c(k0) //
sw t9,0x40(k0) //
sw gp,0x44(k0) //
sw sp,0x48(k0) //
sw s8,0x4c(k0) //
sw ra,0x50(k0) //
.set noreorder
mfc0 k1,psr //
sw k1,0x54(k0) //
mfc0 k1,cause //
sw k1,0x58(k0) //
mfc0 k1,epc //
sw k1,0x5c(k0) //
mfc0 k1,errorepc //
sw k1,0x60(k0) //
.set reorder
#endif
li k0,0xb9980038 // set NMIRST address
li k1,0x8 // it is DUMP Key NMI
sw k1,(k0) // reset nmi
.set noreorder // A002
nop
//
// This is a test code.
// We must clear BEV bit of psr register.
//
mfc0 k1,psr // get psr
li k0,0xffafffff // BEV bit clear
nop // fill
and k1,k1,k0 //
nop //
mtc0 k1,psr // set psr
nop // fill
nop //
nop //
// li k0,0xb9980308 // Read STSR Register
// lw k1,(k0) //
// or k1,k1,0x80800000// make eif
// sw k1,(k0) //
// nop
li k0,0xb9980100 // IntIR Register addr
li k1,0x0082f000 // Do eif to CPU0 only.
sw k1,(k0) //
nop
eret // return to errorepc
nop
nop
nop
eret // errata
nop
#if 0
mfc0 k0,epc // As if behave No Nmi
nop
nop
j k0 // As if behave No Nmi.
#endif // I Hope EIF Interrut
// Occur later!!.
//
// S007 ^^^
.set at
.set reorder
.end HalpNmiHandler