forked from Imagelibrary/rtems
Statically initialize the interrupt stack area
(_Configuration_Interrupt_stack_area_begin,
_Configuration_Interrupt_stack_area_end, and
_Configuration_Interrupt_stack_size) via <rtems/confdefs.h>. Place the
interrupt stack area in a special section ".rtemsstack.interrupt". Let
BSPs define the optimal placement of this section in their linker
command files (e.g. in a fast on-chip memory).
This change makes makes the CPU_HAS_SOFTWARE_INTERRUPT_STACK and
CPU_HAS_HARDWARE_INTERRUPT_STACK CPU port defines superfluous, since the
low level initialization code has all information available via global
symbols.
This change makes the CPU_ALLOCATE_INTERRUPT_STACK CPU port define
superfluous, since the interrupt stacks are allocated by confdefs.h for
all architectures. There is no need for BSP-specific linker command
file magic (except the section placement), see previous ARM linker
command file as a bad example.
Remove _CPU_Install_interrupt_stack(). Initialize the hardware
interrupt stack in _CPU_Initialize() if necessary (e.g.
m68k_install_interrupt_stack()).
The optional _CPU_Interrupt_stack_setup() is still useful to customize
the registration of the interrupt stack area in the per-CPU information.
The initialization stack can reuse the interrupt stack, since
* interrupts are disabled during the sequential system initialization,
and
* the boot_card() function does not return.
This stack resuse saves memory.
Changes per architecture:
arm:
* Mostly replace the linker symbol based configuration of stacks with
the standard <rtems/confdefs.h> configuration via
CONFIGURE_INTERRUPT_STACK_SIZE. The size of the FIQ, ABT and UND
mode stack is still defined via linker symbols. These modes are
rarely used in applications and the default values provided by the
BSP should be sufficient in most cases.
* Remove the bsp_processor_count linker symbol hack used for the SMP
support. This is possible since the interrupt stack area is now
allocated by the linker and not allocated from the heap. This makes
some configure.ac stuff obsolete. Remove the now superfluous BSP
variants altcycv_devkit_smp and realview_pbx_a9_qemu_smp.
bfin:
* Remove unused magic linker command file allocation of initialization
stack. Maybe a previous linker command file copy and paste problem?
In the start.S the initialization stack is set to a hard coded value.
lm32, m32c, mips, nios2, riscv, sh, v850:
* Remove magic linker command file allocation of initialization stack.
Reuse interrupt stack for initialization stack.
m68k:
* Remove magic linker command file allocation of initialization stack.
Reuse interrupt stack for initialization stack.
powerpc:
* Remove magic linker command file allocation of initialization stack.
Reuse interrupt stack for initialization stack.
* Used dedicated memory region (REGION_RTEMSSTACK) for the interrupt
stack on BSPs using the shared linkcmds.base (replacement for
REGION_RWEXTRA).
sparc:
* Remove the hard coded initialization stack. Use the interrupt stack
for the initialization stack on the boot processor. This saves
16KiB of RAM.
Update #3459.
658 lines
15 KiB
ArmAsm
658 lines
15 KiB
ArmAsm
/*
|
|
* This file contains a customized MIPS exception handler.
|
|
* It hooks into the exception handler present in the resident
|
|
* PMON debug monitor.
|
|
*/
|
|
|
|
/*
|
|
* Author: Bruce Robinson
|
|
*
|
|
* This code was derived from cpu_asm.S with the following copyright:
|
|
*
|
|
* COPYRIGHT (c) 1996 by Transition Networks Inc.
|
|
*
|
|
* To anyone who acknowledges that this file is provided "AS IS"
|
|
* without any express or implied warranty:
|
|
* permission to use, copy, modify, and distribute this file
|
|
* for any purpose is hereby granted without fee, provided that
|
|
* the above copyright notice and this notice appears in all
|
|
* copies, and that the name of Transition Networks not be used in
|
|
* advertising or publicity pertaining to distribution of the
|
|
* software without specific, written prior permission.
|
|
* Transition Networks makes no representations about the suitability
|
|
* of this software for any purpose.
|
|
*
|
|
* Derived from c/src/exec/score/cpu/no_cpu/cpu_asm.s:
|
|
*
|
|
* COPYRIGHT (c) 1989-2010.
|
|
* On-Line Applications Research Corporation (OAR).
|
|
*
|
|
* The license and distribution terms for this file may be
|
|
* found in the file LICENSE in this distribution or at
|
|
* http://www.rtems.org/license/LICENSE.
|
|
*/
|
|
|
|
#include <bspopts.h>
|
|
#include <rtems/asm.h>
|
|
#include <rtems/score/percpu.h>
|
|
#include <rtems/mips/iregdef.h>
|
|
#include <rtems/mips/idtcpu.h>
|
|
#if BSP_HAS_USC320
|
|
#include <usc.h>
|
|
#endif
|
|
|
|
#if __mips == 3
|
|
/* 64 bit register operations */
|
|
#define NOP nop
|
|
#define ADD dadd
|
|
#define STREG sd
|
|
#define LDREG ld
|
|
#define ADDU addu
|
|
#define ADDIU addiu
|
|
#define STREGC1 sdc1
|
|
#define LDREGC1 ldc1
|
|
#define R_SZ 8
|
|
#define F_SZ 8
|
|
#define SZ_INT 8
|
|
#define SZ_INT_POW2 3
|
|
|
|
/* XXX if we don't always want 64 bit register ops, then another ifdef */
|
|
|
|
#elif __mips == 1
|
|
/* 32 bit register operations*/
|
|
#define NOP nop
|
|
#define ADD add
|
|
#define STREG sw
|
|
#define LDREG lw
|
|
#define ADDU add
|
|
#define ADDIU addi
|
|
#define STREGC1 swc1
|
|
#define LDREGC1 lwc1
|
|
#define R_SZ 4
|
|
#define F_SZ 4
|
|
#define SZ_INT 4
|
|
#define SZ_INT_POW2 2
|
|
#else
|
|
#error "mips assembly: what size registers do I deal with?"
|
|
#endif
|
|
|
|
|
|
#define ISR_VEC_SIZE 4
|
|
#define EXCP_STACK_SIZE (NREGS*R_SZ)
|
|
|
|
.extern _Thread_Dispatch
|
|
|
|
/* void __ISR_Handler()
|
|
*
|
|
* This routine provides the RTEMS interrupt management.
|
|
*
|
|
*/
|
|
|
|
#if 0
|
|
void _ISR_Handler()
|
|
{
|
|
/*
|
|
* This discussion ignores a lot of the ugly details in a real
|
|
* implementation such as saving enough registers/state to be
|
|
* able to do something real. Keep in mind that the goal is
|
|
* to invoke a user's ISR handler which is written in C and
|
|
* uses a certain set of registers.
|
|
*
|
|
* Also note that the exact order is to a large extent flexible.
|
|
* Hardware will dictate a sequence for a certain subset of
|
|
* _ISR_Handler while requirements for setting
|
|
*/
|
|
|
|
/*
|
|
* At entry to "common" _ISR_Handler, the vector number must be
|
|
* available. On some CPUs the hardware puts either the vector
|
|
* number or the offset into the vector table for this ISR in a
|
|
* known place. If the hardware does not give us this information,
|
|
* then the assembly portion of RTEMS for this port will contain
|
|
* a set of distinct interrupt entry points which somehow place
|
|
* the vector number in a known place (which is safe if another
|
|
* interrupt nests this one) and branches to _ISR_Handler.
|
|
*
|
|
*/
|
|
#endif
|
|
FRAME(bsp_ISR_Handler,sp,0,ra)
|
|
.set noreorder
|
|
|
|
#if 0
|
|
/* Activate TX49xx PIO19 signal for diagnostics */
|
|
lui k0,0xff1f
|
|
ori k0,k0,0xf500
|
|
lw k0,(k0)
|
|
lui k1,0x8
|
|
or k1,k1,k0
|
|
lui k0,0xff1f
|
|
ori k0,k0,0xf500
|
|
sw k1,(k0)
|
|
#endif
|
|
mfc0 k0,C0_CAUSE /* Determine if an interrupt generated this exception */
|
|
nop
|
|
and k1,k0,CAUSE_EXCMASK
|
|
beq k1,zero,_chk_int /* If so, branch to service here */
|
|
nop
|
|
la k0,_int_esr_link /* Otherwise, jump to next exception handler in PMON exception chain */
|
|
lw k0,(k0)
|
|
lw k0,4(k0)
|
|
j k0
|
|
nop
|
|
_chk_int:
|
|
mfc0 k1,C0_SR
|
|
nop
|
|
and k0,k1
|
|
#if HAS_RM52xx
|
|
and k0,CAUSE_IPMASK
|
|
#elif HAS_TX49xx
|
|
and k0,(SR_IBIT1 | SR_IBIT2 | SR_IBIT3)
|
|
#endif
|
|
/* external interrupt not enabled, ignore */
|
|
beq k0,zero,_ISR_Handler_quick_exit
|
|
nop
|
|
|
|
/* For debugging interrupts, clear EXL to allow breakpoints */
|
|
#if 0
|
|
MFC0 k0, C0_SR
|
|
#if __mips == 3
|
|
li k1,SR_EXL /* Clear EXL and Set IE to enable interrupts */
|
|
not k1
|
|
and k0,k1
|
|
li k1,SR_IE
|
|
#elif __mips == 1
|
|
li k1,SR_IEC
|
|
#endif
|
|
or k0, k1
|
|
mtc0 k0, C0_SR
|
|
NOP
|
|
#endif
|
|
|
|
|
|
/*
|
|
* save some or all context on stack
|
|
* may need to save some special interrupt information for exit
|
|
*/
|
|
|
|
/* Q: _ISR_Handler, not using IDT/SIM ...save extra regs? */
|
|
|
|
/* wastes a lot of stack space for context?? */
|
|
ADDIU sp,sp,-EXCP_STACK_SIZE
|
|
|
|
STREG ra, R_RA*R_SZ(sp) /* store ra on the stack */
|
|
STREG v0, R_V0*R_SZ(sp)
|
|
STREG v1, R_V1*R_SZ(sp)
|
|
STREG a0, R_A0*R_SZ(sp)
|
|
STREG a1, R_A1*R_SZ(sp)
|
|
STREG a2, R_A2*R_SZ(sp)
|
|
STREG a3, R_A3*R_SZ(sp)
|
|
STREG t0, R_T0*R_SZ(sp)
|
|
STREG t1, R_T1*R_SZ(sp)
|
|
STREG t2, R_T2*R_SZ(sp)
|
|
STREG t3, R_T3*R_SZ(sp)
|
|
STREG t4, R_T4*R_SZ(sp)
|
|
STREG t5, R_T5*R_SZ(sp)
|
|
STREG t6, R_T6*R_SZ(sp)
|
|
STREG t7, R_T7*R_SZ(sp)
|
|
mflo t0
|
|
STREG t8, R_T8*R_SZ(sp)
|
|
STREG t0, R_MDLO*R_SZ(sp)
|
|
STREG t9, R_T9*R_SZ(sp)
|
|
mfhi t0
|
|
STREG gp, R_GP*R_SZ(sp)
|
|
STREG t0, R_MDHI*R_SZ(sp)
|
|
STREG fp, R_FP*R_SZ(sp)
|
|
|
|
.set noat
|
|
STREG AT, R_AT*R_SZ(sp)
|
|
.set at
|
|
|
|
mfc0 t0,C0_SR
|
|
dmfc0 t1,C0_EPC
|
|
STREG t0,R_SR*R_SZ(sp)
|
|
STREG t1,R_EPC*R_SZ(sp)
|
|
|
|
/*
|
|
*
|
|
* if ( _ISR_Nest_level == 0 )
|
|
* switch to software interrupt stack
|
|
*/
|
|
|
|
/*
|
|
* _ISR_Nest_level++;
|
|
*/
|
|
lw t0,ISR_NEST_LEVEL
|
|
NOP
|
|
add t0,t0,1
|
|
sw t0,ISR_NEST_LEVEL
|
|
/*
|
|
* _Thread_Dispatch_disable_level++;
|
|
*/
|
|
lw t1,THREAD_DISPATCH_DISABLE_LEVEL
|
|
NOP
|
|
add t1,t1,1
|
|
sw t1,THREAD_DISPATCH_DISABLE_LEVEL
|
|
|
|
/* DEBUG - Add the following code to disable interrupts and clear
|
|
* EXL in status register, this will allow memory
|
|
* exceptions to occur while servicing the current interrupt
|
|
*/
|
|
#if 0
|
|
/* Disable interrupts from internal interrupt controller */
|
|
li t0,~CAUSE_IP2_MASK
|
|
mfc0 t1,C0_SR
|
|
nop
|
|
and t1,t0
|
|
mtc0 t1,C0_SR
|
|
nop
|
|
/* Clear EXL in status register to allow memory exceptions to occur */
|
|
li t0,~SR_EXL
|
|
mfc0 t1,C0_SR
|
|
nop
|
|
and t1,t0
|
|
mtc0 t1,C0_SR
|
|
nop
|
|
#endif
|
|
|
|
/*
|
|
* Call the CPU model or BSP specific routine to decode the
|
|
* interrupt source and actually vector to device ISR handlers.
|
|
*/
|
|
move a0,sp
|
|
jal mips_vector_isr_handlers
|
|
NOP
|
|
|
|
/* Add the following code to disable interrupts (see DEBUG above) */
|
|
#if 0
|
|
li t0,SR_EXL /* Set EXL to hold off interrupts */
|
|
mfc0 t1,C0_SR
|
|
nop
|
|
or t1,t0
|
|
mtc0 t1,C0_SR
|
|
nop
|
|
/* Enable interrupts from internal interrupt controller */
|
|
li t0,CAUSE_IP2_MASK
|
|
mfc0 t1,C0_SR
|
|
nop
|
|
or t1,t0
|
|
mtc0 t1,C0_SR
|
|
nop
|
|
#endif
|
|
|
|
_ISR_Handler_cleanup:
|
|
|
|
/*
|
|
* --_ISR_Nest_level;
|
|
*/
|
|
lw t2,ISR_NEST_LEVEL
|
|
NOP
|
|
add t2,t2,-1
|
|
sw t2,ISR_NEST_LEVEL
|
|
/*
|
|
* --_Thread_Dispatch_disable_level;
|
|
*/
|
|
lw t1,THREAD_DISPATCH_DISABLE_LEVEL
|
|
NOP
|
|
add t1,t1,-1
|
|
sw t1,THREAD_DISPATCH_DISABLE_LEVEL
|
|
/*
|
|
* if ( _Thread_Dispatch_disable_level || _ISR_Nest_level )
|
|
* goto the label "exit interrupt (simple case)"
|
|
*/
|
|
or t0,t2,t1
|
|
bne t0,zero,_ISR_Handler_exit
|
|
NOP
|
|
|
|
|
|
/*
|
|
* restore stack
|
|
*
|
|
* if ( !_Thread_Dispatch_necessary )
|
|
* goto the label "exit interrupt (simple case)"
|
|
*/
|
|
lb t0,DISPATCH_NEEDED
|
|
NOP
|
|
or t0,t0,t0
|
|
beq t0,zero,_ISR_Handler_exit
|
|
NOP
|
|
|
|
/*
|
|
** Turn on interrupts before entering Thread_Dispatch which
|
|
** will run for a while, thus allowing new interrupts to
|
|
** be serviced. Observe the Thread_Dispatch_disable_level interlock
|
|
** that prevents recursive entry into Thread_Dispatch.
|
|
*/
|
|
|
|
mfc0 t0, C0_SR
|
|
#if __mips == 3
|
|
li t1,SR_EXL /* Clear EXL and Set IE to enable interrupts */
|
|
not t1
|
|
and t0,t1
|
|
li t1,SR_IE
|
|
#elif __mips == 1
|
|
li t1,SR_IEC
|
|
#endif
|
|
or t0, t1
|
|
mtc0 t0, C0_SR
|
|
NOP
|
|
|
|
/* save off our stack frame so the context switcher can get to it */
|
|
la t0,__exceptionStackFrame
|
|
STREG sp,(t0)
|
|
|
|
jal _Thread_Dispatch
|
|
NOP
|
|
|
|
/* and make sure its clear in case we didn't dispatch. if we did, its
|
|
** already cleared */
|
|
la t0,__exceptionStackFrame
|
|
STREG zero,(t0)
|
|
NOP
|
|
|
|
/*
|
|
** turn interrupts back off while we restore context so
|
|
** a badly timed interrupt won't accidentally mess things up
|
|
*/
|
|
mfc0 t0, C0_SR
|
|
#if __mips == 3
|
|
li t1,SR_IE /* Clear IE first (recommended) */
|
|
not t1
|
|
and t0,t1
|
|
mtc0 t0, C0_SR
|
|
li t1,SR_EXL | SR_IE /* Set EXL and IE, this puts status register bits back to interrupted state */
|
|
or t0,t1
|
|
#elif __mips == 1
|
|
/* ints off, current & prev kernel mode on (kernel mode enabled is bit clear..argh!) */
|
|
li t1,SR_IEC | SR_KUP | SR_KUC
|
|
not t1
|
|
and t0, t1
|
|
#endif
|
|
mtc0 t0, C0_SR
|
|
NOP
|
|
|
|
/*
|
|
* prepare to get out of interrupt
|
|
* return from interrupt (maybe to _ISR_Dispatch)
|
|
*
|
|
* LABEL "exit interrupt (simple case):"
|
|
* prepare to get out of interrupt
|
|
* return from interrupt
|
|
*/
|
|
|
|
_ISR_Handler_exit:
|
|
|
|
/* restore interrupt context from stack */
|
|
LDREG t8, R_MDLO*R_SZ(sp)
|
|
LDREG t0, R_T0*R_SZ(sp)
|
|
mtlo t8
|
|
LDREG t8, R_MDHI*R_SZ(sp)
|
|
LDREG t1, R_T1*R_SZ(sp)
|
|
mthi t8
|
|
LDREG t2, R_T2*R_SZ(sp)
|
|
LDREG t3, R_T3*R_SZ(sp)
|
|
LDREG t4, R_T4*R_SZ(sp)
|
|
LDREG t5, R_T5*R_SZ(sp)
|
|
LDREG t6, R_T6*R_SZ(sp)
|
|
LDREG t7, R_T7*R_SZ(sp)
|
|
LDREG t8, R_T8*R_SZ(sp)
|
|
LDREG t9, R_T9*R_SZ(sp)
|
|
LDREG gp, R_GP*R_SZ(sp)
|
|
LDREG fp, R_FP*R_SZ(sp)
|
|
LDREG ra, R_RA*R_SZ(sp)
|
|
LDREG a0, R_A0*R_SZ(sp)
|
|
LDREG a1, R_A1*R_SZ(sp)
|
|
LDREG a2, R_A2*R_SZ(sp)
|
|
LDREG a3, R_A3*R_SZ(sp)
|
|
LDREG v1, R_V1*R_SZ(sp)
|
|
LDREG v0, R_V0*R_SZ(sp)
|
|
|
|
LDREG k1, R_EPC*R_SZ(sp)
|
|
mtc0 k1,C0_EPC
|
|
|
|
.set noat
|
|
LDREG AT, R_AT*R_SZ(sp)
|
|
.set at
|
|
|
|
ADDIU sp,sp,EXCP_STACK_SIZE
|
|
|
|
_ISR_Handler_quick_exit:
|
|
eret
|
|
nop
|
|
|
|
|
|
#if BSP_HAS_USC320
|
|
/* Interrupts from USC320 are serviced here */
|
|
.global USC_isr
|
|
.extern Clock_isr
|
|
USC_isr:
|
|
/* check if it's a USC320 heartbeat interrupt */
|
|
la k0,INT_STAT /* read INT_STAT register */
|
|
lw k0,(k0)
|
|
nop /* reading from external device */
|
|
sll k0,(31-21) /* test bit 21 (HBI) */
|
|
|
|
bgez k0,USC_isr2 /* branch if not a heartbeat interrupt */
|
|
NOP
|
|
|
|
/* clear the heartbeat interrupt */
|
|
la k0,INT_STAT
|
|
li t0,HBI_MASK
|
|
sw t0,(k0)
|
|
/* wait for interrupt to clear */
|
|
USC_isr1:
|
|
la k0,INT_STAT /* read INT_STAT register */
|
|
lw k0,(k0)
|
|
nop /* reading from external device */
|
|
sll k0,(31-21) /* test bit 21 (HBI) */
|
|
bltz k0,USC_isr1 /* branch if bit set */
|
|
nop
|
|
j Clock_isr /* Jump to clock isr */
|
|
nop
|
|
USC_isr2:
|
|
j ra /* no serviceable interrupt, return without doing anything */
|
|
nop
|
|
#endif
|
|
|
|
#if 0
|
|
.global int7_isr
|
|
.extern Interrupt_7_isr
|
|
int7_isr:
|
|
/* Verify interrupt is from Timer */
|
|
la k0,IRCS /* read Interrupt Current Status register */
|
|
lw k0,(k0)
|
|
nop /* reading from external device */
|
|
li k1,IRCS_CAUSE_MASK
|
|
and k0,k0,k1 /* isolate interrupt cause */
|
|
|
|
li k1,INT7INT /* test for interrupt 7 */
|
|
subu k1,k0,k1
|
|
beq k1,zero,int7_isr1
|
|
nop
|
|
j ra /* interrupt 7 no longer valid, return without doing anything */
|
|
nop
|
|
int7_isr1:
|
|
j Interrupt_7_isr /* Jump to Interrupt 7 isr */
|
|
nop
|
|
#endif
|
|
|
|
.set reorder
|
|
|
|
ENDFRAME(bsp_ISR_Handler)
|
|
|
|
|
|
FRAME(_BRK_Handler,sp,0,ra)
|
|
.set noreorder
|
|
|
|
#if BSP_HAS_USC320
|
|
la k0,INT_CFG3 /* Disable heartbeat interrupt in USC320, it interferes with PMON exception handler */
|
|
lw k1,(k0)
|
|
li k0,~HBI_MASK
|
|
and k1,k1,k0
|
|
la k0,INT_CFG3
|
|
sw k1,(k0)
|
|
#endif
|
|
|
|
la k0,_brk_esr_link /* Jump to next exception handler in PMON exception chain */
|
|
lw k0,(k0)
|
|
lw k0,4(k0)
|
|
j k0
|
|
nop
|
|
|
|
.set reorder
|
|
ENDFRAME(_BRK_Handler)
|
|
|
|
|
|
/**************************************************************************
|
|
**
|
|
** init_exc_vecs() - moves the exception code into the addresses
|
|
** reserved for exception vectors
|
|
**
|
|
** UTLB Miss exception vector at address 0x80000000
|
|
**
|
|
** General exception vector at address 0x80000080
|
|
**
|
|
** RESET exception vector is at address 0xbfc00000
|
|
**
|
|
***************************************************************************/
|
|
|
|
FRAME(init_exc_vecs,sp,0,ra)
|
|
.set noreorder
|
|
|
|
.extern mon_onintr
|
|
|
|
/* Install interrupt handler in PMON exception handling chain */
|
|
|
|
addiu sp,sp,-8
|
|
sw ra,(sp) /* Save ra contents on stack */
|
|
move a0,zero
|
|
la a1,_int_esr_link
|
|
jal mon_onintr /* Make PMON system call to install interrupt exception handler */
|
|
nop
|
|
li a0,9
|
|
la a1,_brk_esr_link
|
|
jal mon_onintr /* Make PMON system call to install break exception handler */
|
|
nop
|
|
lw ra,(sp)
|
|
addiu sp,sp,8 /* Restore ra contents from stack */
|
|
j ra
|
|
nop
|
|
|
|
.set reorder
|
|
ENDFRAME(init_exc_vecs)
|
|
|
|
|
|
#if 0 /* Unused code below */
|
|
|
|
/*************************************************************
|
|
* enable_int7(ints)
|
|
* Enable interrupt 7
|
|
*/
|
|
FRAME(enable_int7,sp,0,ra)
|
|
.set noreorder
|
|
|
|
la t0,IRDM1 # Set interrupt controller detection mode (bits 2-3 = 0 for int 7 active low)
|
|
li t1,0x0
|
|
sw t1,(t0)
|
|
|
|
la t0,IRLVL4 # Set interrupt controller level (bit 8-10 = 2 for int 7 at level 2)
|
|
li t1,0x200
|
|
sw t1,(t0)
|
|
|
|
la t0,IRMSK # Set interrupt controller mask
|
|
li t1,0x0
|
|
sw t1,(t0)
|
|
|
|
la t0,IRDEN # Enable interrupts from controller
|
|
li t1,0x1
|
|
sw t1,(t0)
|
|
|
|
j ra
|
|
nop
|
|
.set reorder
|
|
ENDFRAME(enable_int7)
|
|
|
|
/*************************************************************
|
|
* disable_int7(ints)
|
|
* Disable interrupt 7
|
|
*/
|
|
FRAME(disable_int7,sp,0,ra)
|
|
.set noreorder
|
|
|
|
la t0,IRLVL4 # Set interrupt controller level (bit 8-10 = 0 to diasble int 7)
|
|
li t1,0x200
|
|
sw t1,(t0)
|
|
|
|
j ra
|
|
nop
|
|
.set reorder
|
|
ENDFRAME(disable_int7)
|
|
#endif
|
|
|
|
/*************************************************************
|
|
* exception:
|
|
* Diagnostic code that can be hooked to PMON interrupt handler.
|
|
* Generates pulse on PIO22 pin.
|
|
* Called from _exception code in PMON (see mips.s of PMON).
|
|
* Return address is located in k1.
|
|
*/
|
|
FRAME(tx49xxexception,sp,0,ra)
|
|
.set noreorder
|
|
la k0,k1tmp
|
|
sw k1,(k0)
|
|
|
|
/* Activate TX49xx PIO22 signal for diagnostics */
|
|
lui k0,0xff1f
|
|
ori k0,k0,0xf500
|
|
lw k0,(k0)
|
|
lui k1,0x40
|
|
or k1,k1,k0
|
|
lui k0,0xff1f
|
|
ori k0,k0,0xf500
|
|
sw k1,(k0)
|
|
nop
|
|
|
|
/* De-activate TX49xx PIO22 signal for diagnostics */
|
|
lui k0,0xff1f
|
|
ori k0,k0,0xf500
|
|
lw k0,(k0)
|
|
lui k1,0x40
|
|
not k1
|
|
and k1,k1,k0
|
|
lui k0,0xff1f
|
|
ori k0,k0,0xf500
|
|
sw k1,(k0)
|
|
nop
|
|
|
|
la k0,k1tmp
|
|
lw k1,(k0)
|
|
j k1
|
|
.set reorder
|
|
ENDFRAME(tx49xxexception)
|
|
|
|
|
|
|
|
|
|
.data
|
|
|
|
k1tmp: .word 0 /* Temporary strage for K1 during interrupt service */
|
|
|
|
/*************************************************************
|
|
*
|
|
* Exception handler links, used in PMON exception handler chains
|
|
*/
|
|
/* Interrupt exception service routine link */
|
|
.global _int_esr_link
|
|
_int_esr_link:
|
|
.word 0
|
|
.word bsp_ISR_Handler
|
|
|
|
/* Break exception service routine link */
|
|
.global _brk_esr_link
|
|
_brk_esr_link:
|
|
.word 0
|
|
.word _BRK_Handler
|
|
|
|
|
|
|
|
|