mips exception handling - help needed

gregory.menke at gsfc.nasa.gov gregory.menke at gsfc.nasa.gov
Mon Jan 12 14:41:14 UTC 2004


Joel Sherrill writes:
 > durai wrote:
 > > Hi,
 > > I am working in a mips processor which doesnt implement some instructions
 > > (lwl,lwr etc) and I wanted to emulate this instructions is exception
 > > handler.
 > > 
 > > I am having a exception handler in linux with the following format.
 > > ----------------------------------------------------------------------------
 > > --------------------------
 > > void do_ri( struct pt_regs *regs )
 > > {
 > > 
 > > ....
 > > .....
 > >  branchDelay = ( ( 0 != ( regs->cp0_cause & CAUSEF_BD ) ) ||   (
 > > isJumpInstruction( regs->cp0_epc ) ) );
 > > ......
 > > ........
 > >  /*
 > >       =====================================
 > >       Get the instruction that caused this
 > >       interrupt:
 > >       =====================================
 > >     */
 > >     inst = *((unsigned long *)(regs->cp0_epc) + ( branchDelay ? 1 : 0 ));
 > > 
 > > //emulate the instruction
 > > 
 > > .............
 > > }
 > > ----------------------------------------------------------------------------
 > > --------------------------
 > 
 > I think you are trying to implement either an instruction not
 > implemented or an unaligned access exception handler.  You are
 > trying to emulate an instruction (or subset of an instruction)
 > that is not implemented in hardware.  Right?
 > 
 > > How can I  implement that handler in RTEMS? to be more precise, I wanted to
 > > know how to access the processor registers inside my exception handler, also
 > > i wanted to know whether  the processor registers will be saved before
 > > calling my exception handler. Will it be possible to to store the processor
 > > registers before calling the exception handler, because i have to get the
 > > instruction opcode from the stored registers and emulate it.
 > 
 > I am looking at c/src/lib/libcpu/mips/tx39/vectorisrs/vectorisrs.c which
 > is the routine responsible for vectoring exceptions.  It is passed an
 > interrupt stack frame (ISF) which is really the exception registers on
 > the stack.  See cpukit/score/mips/cpu_asm.S.  So it should be fairly
 > trivial to continue to pass the ISF down to an instruction emulator
 > routine which patches the stack frame.
 > 
 > I would read the code in cpu_asm.S very carefully to make sure you
 > interoperating with it correctly.

The stack frame and vector are passed to the interrupt vector routine.
The stack frame itself is not completely filled out, but all the
important registers are there.  All the registers that are filled in
are restored from the stack frame struct, so any register changes can
be accomplished by just setting the struct field- but only for those
registers that the interrupt service routine uses.  All other
registers can be modified as required in the vector.

As far as fetching the opcode which caused the exception, the stack
frame contains the EPC register, which will get you there.  If you're
trying to modify some of the core processor registers, there are C
macros to handle many of them in
cpukit/score/cpu/mips/rtems/score/mips.h- you can easily adapt them to
any of the other cp0 (or other cp) registers.

As Joel said, cpu_asm.S is where the interrupt and exception code is.

cpukit/score/cpu/mips/rtems/score/cpu.h has the stack frame
definition.


Gregm





More information about the users mailing list