177 lines
4.0 KiB
ArmAsm
177 lines
4.0 KiB
ArmAsm
// "@(#) NEC r98ipint.s 1.5 94/10/11 23:04:02"
|
|
// TITLE("Interprocessor Interrupts")
|
|
//++
|
|
//
|
|
//
|
|
// Module Name:
|
|
//
|
|
// r98ipint.s
|
|
//
|
|
// Abstract:
|
|
//
|
|
// This module implements the code necessary to field and process the
|
|
// interprocessor interrupts on a r98
|
|
//
|
|
// Author:
|
|
//
|
|
//
|
|
// Environment:
|
|
//
|
|
// Kernel mode only.
|
|
//
|
|
// Revision History:
|
|
//
|
|
//
|
|
// S001 94.6/13 T.Samezima
|
|
//
|
|
// Del Compile err
|
|
//
|
|
// S002 94.7/14 T.Samezima
|
|
//
|
|
// Chg define register base address
|
|
// change register access from 8byte access to 4byte access
|
|
//
|
|
// S003 94.7/20 T.Samezima
|
|
//
|
|
// Del Compile err del
|
|
//
|
|
// S004 94.10/11 T.Samezima
|
|
//
|
|
// Fix Version Up at build807
|
|
//
|
|
//
|
|
//--
|
|
|
|
#include "halmips.h"
|
|
#include "r98def.h"
|
|
//#include "r98reg.h" // S001
|
|
|
|
// Start S002
|
|
//
|
|
// Define interrupt control registers base
|
|
//
|
|
|
|
#define PMC_BASE PMC_PHYSICAL_BASE1+PMC_LOCAL_OFFSET+KSEG1_BASE
|
|
// End S002
|
|
|
|
|
|
SBTTL("Interprocessor Interrupt")
|
|
//++
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// This routine is entered as the result of an interprocessor interrupt.
|
|
// Its function is to acknowledge the interrupt and transfer control to
|
|
// the standard system routine to process interprocessor requrests.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// s8 - Supplies a pointer to a trap frame.
|
|
//
|
|
// Return Value:
|
|
//
|
|
// None.
|
|
//
|
|
//--
|
|
|
|
.struct 0
|
|
IiArgs: .space 4 * 4 // saved arguments
|
|
.space 3 * 4 // fill
|
|
IiRa: .space 4 // saved return address
|
|
IiFrameLength: //
|
|
|
|
NESTED_ENTRY(HalpIpiInterrupt, IiFrameLength, zero)
|
|
|
|
subu sp,sp,IiFrameLength // allocate stack frame
|
|
sw ra,IiRa(sp) // save return address
|
|
|
|
PROLOGUE_END
|
|
|
|
// Start S002
|
|
// mfc1 t5,f0 // save f0 register
|
|
// sw t5,IiF0(sp) //
|
|
// mfc1 t6,f1 // save f1 register
|
|
// sw t6,IiF1(sp) //
|
|
// End S002
|
|
|
|
li t7,PMC_BASE // get register address // S002
|
|
|
|
// Start S002
|
|
lw t0,0x0(t7) // get upper 32bit of IPR register
|
|
|
|
// ldc1 f0,0x0(t7) // read IPR register
|
|
// mfc1 t0,f0 // get upper 32bit of IPR register
|
|
|
|
10: lw t1,0x8(t7) // get upper 32bit of MKR register
|
|
|
|
// ldc1 f0,0x8(t7) // read MKR register
|
|
// mfc1 t1,f0 // get upper 32bit of MKR register
|
|
// End S002
|
|
|
|
and t1,t0,t1 // calculate upper 32bit of 'IPR & MKR'
|
|
andi t2,t1,IPR_IPI0_BIT_HIGH // check IPI0 bit
|
|
bne t2,zero,20f // if not eq, ip interrupt from processor0
|
|
andi t2,t1,IPR_IPI1_BIT_HIGH // check IPI1 bit
|
|
bne t2,zero,20f // if not eq, ip interrupt from processor1
|
|
andi t2,t1,IPR_IPI2_BIT_HIGH // check IPI2 bit
|
|
bne t2,zero,20f // if not eq, ip interrupt from processor2
|
|
andi t2,t1,IPR_IPI3_BIT_HIGH // check IPI3 bit
|
|
bne t2,zero,20f // if not eq, ip interrupt from processor3
|
|
|
|
//
|
|
// Unknown interrupt.
|
|
//
|
|
|
|
li t4,MKR_INT4_ENABLE_HIGH // make argument
|
|
and a0,t1,t4 //
|
|
and a1,zero,a1 //
|
|
jal HalpUnknownInterrupt // call unknown interrupt handler
|
|
b 30f
|
|
|
|
//
|
|
// Interprocessor interrupt.
|
|
//
|
|
|
|
// Start S002
|
|
20: sw t2,0x10(t7) // set IPRR register
|
|
sw zero,0x14(t7) //
|
|
|
|
// mtc1 t2,f0 // set IPRR register
|
|
// mtc1 zero,f1 //
|
|
// sdc1 f0,0x10(t7) //
|
|
// End S002
|
|
|
|
lw t1,__imp_KeIpiInterrupt // process interprocessor requests // S004
|
|
jal t1 // // S004
|
|
|
|
//
|
|
// check other interrupt.
|
|
//
|
|
|
|
30: li t7,PMC_BASE // get register address // S002
|
|
// Start S002
|
|
lw t0,0x0(t7) // get upper 32bit of IPR register
|
|
// ldc1 f0,0x0(t7) // read IPR register
|
|
// mfc1 t0,f0 // get upper 32bit of IPR register
|
|
// End S002
|
|
andi t1,t0,MKR_INT4_ENABLE_HIGH // check interrupt of int4 level
|
|
bne t1,zero,10b // if neq, occur new interrupt.
|
|
|
|
READ_CAUSE_REGISTER(t2) // get cause // S002
|
|
|
|
andi t3,t2,1 << (CAUSE_INTPEND + IPI_LEVEL - 1 ) // check interrupt
|
|
bne t3,zero,30b // if neq, check new interrupt
|
|
|
|
// Start S003
|
|
// lw t0,IiF0(sp) // restore f0 register
|
|
// mtc1 t0,f0 //
|
|
// lw t1,IiF1(sp) // restore f1 register
|
|
// mtc1 t1,f1 //
|
|
// End S003
|
|
|
|
lw ra,IiRa(sp) // save return address
|
|
addu sp,sp,IiFrameLength // deallocate stack frame
|
|
j ra // return
|
|
|
|
.end HalpIpiInterrupt
|