622 lines
15 KiB
ArmAsm
622 lines
15 KiB
ArmAsm
/* #pragma comment(exestr, "@(#) NEC(MIPS) r94anmi.s 1.2 95/10/17 01:19:11" ) */
|
||
//
|
||
// TITLE("R94A NMI routine")
|
||
//++
|
||
//
|
||
// Copyright (c) 1995 NEC Corporation
|
||
//
|
||
// Module Name:
|
||
//
|
||
// r94anmi.s
|
||
//
|
||
// Abstract:
|
||
//
|
||
// This routine support for dump switch.
|
||
//
|
||
// Author:
|
||
//
|
||
// Akitoshi Kuriyama (NEC Software Kobe,Inc)
|
||
//
|
||
// Environment:
|
||
//
|
||
// Kernel mode only.
|
||
//
|
||
// R4400 based only.
|
||
//
|
||
// Revision History:
|
||
//
|
||
// kuriyama@oa2.kbnes.nec.co.jp Sun Oct 15 20:11:38 JST 1995
|
||
// - new code for J94D (!_MRCDUMP_ _MRCPOWER_ compile option need)
|
||
//
|
||
//--
|
||
#include "halmips.h"
|
||
|
||
SBTTL("NMI dispatch routine")
|
||
//++
|
||
//
|
||
// VOID
|
||
// HalpNMIDispatch (
|
||
// VOID
|
||
// )
|
||
//
|
||
// Routine Description:
|
||
//
|
||
// This function was called by firmware when NMI occuerd.
|
||
//
|
||
// Arguments:
|
||
//
|
||
// none.
|
||
//
|
||
// Return Value:
|
||
//
|
||
// none.
|
||
//
|
||
//--
|
||
|
||
LEAF_ENTRY(HalpNMIDispatch)
|
||
|
||
.set noreorder
|
||
.set noat
|
||
|
||
//
|
||
// Save temporary Registers for use.
|
||
// save area shoud have for every processros.
|
||
//
|
||
|
||
li k0,0xffffc070 // get processor number.
|
||
lw k0,(k0) //
|
||
bne k0,zero,10f //
|
||
nop // fill
|
||
|
||
la k1,HalpNMISave0 // set save address.
|
||
j 20f //
|
||
nop // fill
|
||
|
||
10:
|
||
la k1,HalpNMISave1 // set save address.
|
||
nop // 1 cycle hazzerd
|
||
|
||
20:
|
||
sw AT,0x0(k1) // register save.
|
||
sw v0,0x4(k1) //
|
||
sw v1,0x8(k1) //
|
||
sw a0,0xc(k1) //
|
||
sw a1,0x10(k1) //
|
||
sw a2,0x14(k1) //
|
||
sw a3,0x18(k1) //
|
||
sw t0,0x1c(k1) //
|
||
sw t1,0x20(k1) //
|
||
sw t2,0x24(k1) //
|
||
sw t3,0x28(k1) //
|
||
sw t4,0x2c(k1) //
|
||
sw t5,0x30(k1) //
|
||
sw t6,0x34(k1) //
|
||
sw t7,0x38(k1) //
|
||
sw t8,0x3c(k1) //
|
||
sw t9,0x40(k1) //
|
||
sw gp,0x44(k1) //
|
||
sw sp,0x48(k1) //
|
||
sw s8,0x4c(k1) //
|
||
sw ra,0x50(k1) //
|
||
mfc0 k0,psr //
|
||
nop //
|
||
nop //
|
||
sw k0,0x54(k1) //
|
||
nop //
|
||
mfc0 k0,cause //
|
||
nop //
|
||
nop //
|
||
sw k0,0x58(k1) //
|
||
nop //
|
||
mfc0 k0,epc //
|
||
nop //
|
||
nop //
|
||
sw k0,0x5c(k1) //
|
||
nop //
|
||
mfc0 k0,errorepc //
|
||
nop //
|
||
nop //
|
||
sw k0,0x60(k1) //
|
||
nop //
|
||
mfc0 k0,cacheerr //
|
||
nop //
|
||
nop //
|
||
sw k0,0x64(k1) //
|
||
|
||
sdc1 f0,0x68(k1) //
|
||
|
||
//
|
||
// Set Dump Switch Status register to tlb fixed entry
|
||
//
|
||
|
||
li t0,4 // set index 4(hurricane register)
|
||
li t1,0x80012 << 6 // set MRC register
|
||
li t2,0x8000e << 6 // set Self-Test address
|
||
|
||
mfc0 t3,index // save tlb registers
|
||
mfc0 t4,entryhi //
|
||
mfc0 t5,entrylo0 //
|
||
mfc0 t6,entrylo1 //
|
||
mfc0 t7,pagemask //
|
||
mtc0 t0,index //
|
||
nop
|
||
nop
|
||
nop
|
||
|
||
tlbr // read index 4 tlb
|
||
nop
|
||
nop
|
||
nop
|
||
nop
|
||
|
||
mfc0 t8,entrylo0 // Get entrylo0
|
||
mfc0 t9,entrylo1 // Get entrylo1
|
||
nop
|
||
nop
|
||
nop
|
||
or t1,t8,t1 // set MRC address
|
||
or t2,t8,t2 // set Self-test address
|
||
nop
|
||
|
||
mtc0 t1,entrylo0 // set MRC to tlb 4 0
|
||
mtc0 t2,entrylo1 // set Self-test to tlb 4 1
|
||
nop //
|
||
nop //
|
||
nop //
|
||
nop //
|
||
|
||
tlbwi // write to tlb entry
|
||
nop //
|
||
nop //
|
||
nop //
|
||
nop //
|
||
|
||
//
|
||
// read dump status
|
||
//
|
||
|
||
#if defined(_MRCDUMP_)
|
||
|
||
li t1,0xffffc108 // load MRC Mode value
|
||
|
||
#else // SELFTEST DUMP
|
||
|
||
li t1,0xffffd000 // load Self-Test value
|
||
|
||
li k0,0x1b // set dash
|
||
sb k0,(t1) // display led
|
||
sync
|
||
|
||
#endif // _MRCDUMP_
|
||
|
||
lb k0,(t1) // load Dump switch status.
|
||
nop //
|
||
lb k0,(t1) // wait
|
||
nop //
|
||
|
||
//
|
||
// Check dump status
|
||
//
|
||
|
||
li t1,2 // check for dump switch
|
||
and k0,k0,t1 //
|
||
|
||
#if defined(_MRCDUMP_)
|
||
beq k0,zero,30f // if 0 dump swith was not pressed
|
||
#else // _MRCDUMP_
|
||
bne k0,zero,30f // if 0 dump swith was pressed
|
||
#endif // _MRCDUMP_
|
||
nop //
|
||
|
||
#if !defined(_MRCDUMP_)
|
||
li t1,0xffffd000 // set dump switch status address
|
||
li t2,0x1b // display LED dash
|
||
sb t2,(t1) //
|
||
sync //
|
||
#endif // not _MRCDUMP_
|
||
|
||
//
|
||
// enable powoff NMI
|
||
//
|
||
|
||
#if defined(_MRCPOWER_)
|
||
li t1,0xffffc108 //
|
||
li t0,0x82 //
|
||
nop //
|
||
sb t0,(t1) //
|
||
nop //
|
||
li t0,0x80 //
|
||
nop //
|
||
sb t0,(t1) //
|
||
nop //
|
||
li t0,0x02 //
|
||
nop //
|
||
sb t0,(t1) //
|
||
nop //
|
||
#endif // _MRCPOWER_
|
||
|
||
//
|
||
// restore tlb 4 entry
|
||
//
|
||
|
||
mtc0 t8,entrylo0 // restore tlb 4 0
|
||
mtc0 t9,entrylo1 // restore tlb 4 1
|
||
nop //
|
||
nop //
|
||
nop //
|
||
nop //
|
||
|
||
tlbwi // write to tlb entry
|
||
nop //
|
||
nop //
|
||
nop //
|
||
nop //
|
||
|
||
//
|
||
// restore tlb registers
|
||
//
|
||
mtc0 t3,index //
|
||
mtc0 t4,entryhi //
|
||
mtc0 t5,entrylo0 //
|
||
mtc0 t6,entrylo1 //
|
||
mtc0 t7,pagemask //
|
||
|
||
#if !defined(_MRCDUMP_)
|
||
la k0,0xffffc5b8 // get NEC I/O port value
|
||
lb t0,(k0) //
|
||
nop // 1 cycle hazzerd
|
||
li t1,0xfd // clear dump enable bit
|
||
and t0,t0,t1
|
||
sb t0,(k0) // set NEC I/O port value
|
||
#endif // not _MRCDUMP_
|
||
|
||
//
|
||
// set NMI flag 1
|
||
//
|
||
|
||
la t2,HalpNMIFlag // set NMI flag address
|
||
li t3,0xa0000000 // set KSEG1_BASE
|
||
or t2,t2,t3 //
|
||
li t3,1 //
|
||
sw t3,(t2) // set NMI flag 1
|
||
|
||
//
|
||
// set dump flag 1
|
||
//
|
||
|
||
la t2,HalpDumpNMIFlag // set Dump NMI flag address
|
||
li t3,0xa0000000 // set KSEG1_BASE
|
||
or t2,t2,t3 //
|
||
li t3,1 //
|
||
sw t3,(t2) // set NMI flag 1
|
||
|
||
//
|
||
// clear psr BEV bit
|
||
//
|
||
|
||
mfc0 t0,psr // get psr
|
||
li t2,0xffbfffff // clear BEV bit
|
||
nop // fill
|
||
nop // fill
|
||
and t0,t0,t2 //
|
||
nop //
|
||
mtc0 t0,psr // set psr
|
||
|
||
lw t0,0x1c(k1) // restore temporary registers
|
||
lw t1,0x20(k1) //
|
||
lw t2,0x24(k1) //
|
||
lw t3,0x28(k1) //
|
||
lw t4,0x2c(k1) //
|
||
lw t5,0x30(k1) //
|
||
lw t6,0x34(k1) //
|
||
lw t7,0x38(k1) //
|
||
lw t8,0x3c(k1) //
|
||
lw t9,0x40(k1) //
|
||
lw AT,0x0(k1) //
|
||
|
||
eret // return to error epc
|
||
nop // errata
|
||
nop //
|
||
nop //
|
||
eret //
|
||
nop //
|
||
|
||
30:
|
||
|
||
//
|
||
// No Dump Switch.
|
||
//
|
||
// Check Power Switch
|
||
|
||
#if defined(_MRCPOWER_)
|
||
li t1,0xffffc108
|
||
nop
|
||
li t0,0x02
|
||
nop
|
||
sb t0,(t1)
|
||
nop
|
||
|
||
#endif // _MRCPOWER_
|
||
|
||
mtc0 t8,entrylo0 // restore tlb 4
|
||
mtc0 t9,entrylo1 // restore tlb 4
|
||
nop //
|
||
nop //
|
||
nop //
|
||
nop //
|
||
|
||
tlbwi // write to tlb entry
|
||
nop //
|
||
nop //
|
||
nop //
|
||
nop //
|
||
|
||
mtc0 t3,index // restore tlb registers
|
||
mtc0 t4,entryhi //
|
||
mtc0 t5,entrylo0 //
|
||
mtc0 t6,entrylo1 //
|
||
mtc0 t7,pagemask //
|
||
|
||
|
||
//
|
||
// set NMI flag 1
|
||
//
|
||
la t2,HalpNMIFlag // set NMI flag address
|
||
li t3,0xa0000000 // set KSEG1_BASE
|
||
or t2,t2,t3 //
|
||
li t3,1 //
|
||
sw t3,(t2) // set NMI flag 1
|
||
|
||
// S003 +++
|
||
li t1,0xffffc078 // check NMI source
|
||
lw t0,(t1) // check NMI source
|
||
nop //
|
||
beq t0,zero,40f //
|
||
nop //
|
||
li t1,0xffffc020
|
||
nop
|
||
ldc1 f0,(t1) // clear processor invalid
|
||
nop
|
||
sdc1 f0,0x70(k1) // save processor invalid
|
||
40:
|
||
// S003 ---
|
||
|
||
mfc0 t0,psr // get psr
|
||
li t2,0xffbfffff // clear BEV bit
|
||
nop // fill
|
||
nop // fill
|
||
and t0,t0,t2 //
|
||
nop //
|
||
mtc0 t0,psr // set psr
|
||
|
||
lw t0,0x1c(k1) // restore temporary registers
|
||
lw t1,0x20(k1) //
|
||
lw t2,0x24(k1) //
|
||
lw t3,0x28(k1) //
|
||
lw t4,0x2c(k1) //
|
||
lw t5,0x30(k1) //
|
||
lw t6,0x34(k1) //
|
||
lw t7,0x38(k1) //
|
||
lw t8,0x3c(k1) //
|
||
lw t9,0x40(k1) //
|
||
lw AT,0x0(k1) //
|
||
ldc1 f0,0x68(k1) //
|
||
nop
|
||
|
||
eret // return to errorepc
|
||
nop // errata
|
||
nop //
|
||
nop //
|
||
eret //
|
||
nop //
|
||
|
||
// L001 ---
|
||
|
||
.set at
|
||
.set reorder
|
||
|
||
.end HalpNMIDispatch
|
||
|
||
// Start M008
|
||
SBTTL("Software Power Off")
|
||
//++
|
||
//
|
||
// VOID
|
||
// HalpPowOffNMIDispatch (
|
||
// VOID
|
||
// )
|
||
//
|
||
// Routine Description:
|
||
//
|
||
// This function was called by firmware when NMI occuerd.
|
||
//
|
||
// Arguments:
|
||
//
|
||
// none.
|
||
//
|
||
// Return Value:
|
||
//
|
||
// none.
|
||
//
|
||
//--
|
||
|
||
LEAF_ENTRY(HalpPowOffNMIDispatch)
|
||
|
||
.set noat
|
||
.set noreorder
|
||
|
||
//
|
||
// Save temporary Registers for use.
|
||
// save area shoud have for every processros.
|
||
//
|
||
|
||
li k0,0xffffc070 // get processor number.
|
||
lw k0,(k0) //
|
||
bne k0,zero,60f //
|
||
nop // fill
|
||
|
||
la k1,HalpNMISave0 // set save address.
|
||
j 70f //
|
||
nop // fill
|
||
|
||
60:
|
||
la k1,HalpNMISave1 // set save address.
|
||
nop // 1 cycle hazzerd
|
||
|
||
70:
|
||
sw t0,0(k1) // save temporary registers
|
||
sw t1,4(k1) //
|
||
sw t2,8(k1) //
|
||
sw t3,12(k1) //
|
||
sw t4,16(k1) //
|
||
sw t5,20(k1) //
|
||
sw t6,24(k1) //
|
||
sw t7,28(k1) //
|
||
sw AT,32(k1) //
|
||
|
||
//
|
||
// Set Power Switch Status register to tlb fixed entry
|
||
//
|
||
li t0,4 // set index 4(hurricane register)
|
||
|
||
li t1,0x80012 << 6 // set MRC register
|
||
|
||
mfc0 t3,index // save tlb registers
|
||
mfc0 t4,entryhi //
|
||
mfc0 t5,entrylo0 //
|
||
mfc0 t6,entrylo1 //
|
||
mfc0 t7,pagemask //
|
||
mtc0 t0,index //
|
||
nop
|
||
nop
|
||
nop
|
||
|
||
tlbr // read index 4 tlb
|
||
nop
|
||
nop
|
||
nop
|
||
nop
|
||
|
||
mfc0 t2,entrylo0 // set Self-test address to tlb
|
||
nop
|
||
nop
|
||
nop
|
||
or t1,t2,t1
|
||
nop
|
||
|
||
mtc0 t1,entrylo0 // set Self-Test to tlb 4
|
||
nop //
|
||
nop //
|
||
nop //
|
||
nop //
|
||
|
||
tlbwi // write to tlb entry
|
||
nop //
|
||
nop //
|
||
nop //
|
||
nop //
|
||
|
||
li t1,0xffffc100 // load MRC Int value
|
||
|
||
nop
|
||
lb k0,(t1) // load Interrupt status.
|
||
nop
|
||
lb k0,(t1) // wait
|
||
nop
|
||
|
||
li t0,0x01 // set clear value
|
||
sb t0,(t1) // clear OffSw bit
|
||
|
||
li t1,0x4 // check for OffSw switch
|
||
nop //
|
||
and k0,k0,t1 //
|
||
|
||
beq k0,zero,80f // 0 means Power switch was not pressed
|
||
nop //
|
||
|
||
li t1,0xffffc130 // load MRC Software PowerOff Register
|
||
|
||
nop
|
||
|
||
lb t0,0x1 // set PowerOff Value
|
||
|
||
90:
|
||
sb t0,(t1) // write PowerOff bit
|
||
beq zero,zero,90b
|
||
nop
|
||
|
||
eret
|
||
nop
|
||
nop
|
||
nop
|
||
eret
|
||
nop
|
||
80:
|
||
|
||
//
|
||
// No Power Switch.
|
||
//
|
||
|
||
mtc0 t2,entrylo0 // restore tlb 4
|
||
nop //
|
||
nop //
|
||
nop //
|
||
nop //
|
||
|
||
tlbwi // write to tlb entry
|
||
nop //
|
||
nop //
|
||
nop //
|
||
nop //
|
||
|
||
mtc0 t3,index // restore tlb registers
|
||
mtc0 t4,entryhi //
|
||
mtc0 t5,entrylo0 //
|
||
mtc0 t6,entrylo1 //
|
||
mtc0 t7,pagemask //
|
||
|
||
|
||
la t2,HalpNMIFlag // set NMI flag address
|
||
li t3,0xa0000000 // set KSEG1_BASE
|
||
or t2,t2,t3 //
|
||
li t3,1 //
|
||
sw t3,(t2) // set NMI flag 1
|
||
|
||
lw t0,0xffffc078 // check NMI source
|
||
nop //
|
||
beq t0,zero,45f //
|
||
nop //
|
||
lw t0,0xffffc020 // clear processor invalid
|
||
45:
|
||
|
||
mfc0 t0,psr // get psr
|
||
li t2,0xffbfffff // clear BEV bit
|
||
nop // fill
|
||
nop // fill
|
||
and t0,t0,t2 //
|
||
nop //
|
||
mtc0 t0,psr // set psr
|
||
|
||
lw t0,0(k1) // restore temporary registers
|
||
lw t1,4(k1) //
|
||
lw t2,8(k1) //
|
||
lw t3,12(k1) //
|
||
lw t4,16(k1) //
|
||
lw t5,20(k1) //
|
||
lw t6,24(k1) //
|
||
lw t7,28(k1) //
|
||
lw AT,32(k1) //
|
||
|
||
eret // return to errorepc
|
||
nop // errata
|
||
nop //
|
||
nop //
|
||
eret //
|
||
nop //
|
||
|
||
.set reorder
|
||
.set at
|
||
|
||
.end HalpPowOffNMIDispatch
|
||
// End M008
|