This is the mail archive of the
ecos-discuss@sources.redhat.com
mailing list for the eCos project.
Re: SH1 port of eCos
- To: Jonathan Larmour <jlarmour at redhat dot com>
- Subject: Re: [ECOS] SH1 port of eCos
- From: Aaron Passey <aaronp at lek dot ugcs dot caltech dot edu>
- Date: Mon, 15 Jan 2001 20:10:35 -0800
- Cc: Jesper Skov <jskov at redhat dot com>, ecos-discuss at sources dot redhat dot com
Yes, this is exactly what I was thinking when I mentioned saving a little
bit of state then jumping to the main interrupt handler. There is a
problem with the current organization of the SH saved registers if I want
to do this. The general purpose regs are the last things saved on entry to
an interrupt. If I change the order, I could reduce the amount of code in
each instantiation of the "INTERRUPT" macro.
On the SH1, an interrupt entry would look something like (this is
completely off the top of my head):
.macro INTERRUPT
// SR and PC already saved on the stack
.org vectors + (12*VECTOR)
add #-4, r15 // save a spot for r15(SP)
mov.l r14,@-r15 // save a scratch register
bra interrupt
mov $vec_ ## VECTOR,r14 // store vector for exception handler
$vec_ ## VECTOR: // how do you concatenate?
.long exception_table + (VECTOR << 2)
.set VECTOR, VECTOR+1
.endm
FUNC_START(interrupt)
mov.l r13,@-r15 // save rest of regs
// ...
mov.l r0,@-r15
sts.l pr,@-r15
sts.l mach,@-r15
sts.l macl,@-r15
// fixup saved stack pointer here
// do all the rest of the interrupt code here
mov.l $restore_state, r0
lds r0,pr
jmp r14 // jump to C exception handler
nop
$restore_state:
.long restore_state
The stack frame would now look like:
cyg_uint32 mach; // Multiply and accumulate - high
cyg_uint32 macl; // Multiply and accumulate - low
cyg_uint32 pr; // Procedure Reg
cyg_uint32 r[16]; // Data regs
cyg_uint32 pc; // Program Counter
cyg_uint32 sr; // Status Reg
And each "INTERRUPT" entry is 12 bytes. If instead, I did the easy save
everything macro that jumps directly to the C ISR, I'd probably use maybe
100 or so bytes for each and they'd end up a slight bit faster.
All of this, unfortunately, is much messier than what is currently there
for the SH3. I don't see any way to do this nicely.
Aaron
> Aaron Passey wrote:
> > You have one nice interrupt routine and another exception routine. I need
> > potentially 256 copies of this routine. I could do this with a bunch of
> > macros and a lot of code duplication (not pretty) or possibly have a macro
> > that saves a little bit of state, calls another routine to save the rest,
> > and then jumps to the right ISR. I have to think about this a little bit
> > more.
>
> I don't know the details here, but I think certain GAS constructs may be
> useful in this, e.g. paraphrased from the v850 vectors.S
>
> .macro INTERRUPT
> .org reset_vector+(0x0010*VECTOR)
> addi -CYGARC_EXCEPTION_FRAME_SIZE,sp,sp
> st.w r1,CYGARC_REG_R1[sp]
> movea VECTOR,r0,r1
> jr exception
> .set VECTOR, VECTOR+1
> .endm
>
> and then later:
>
> .set VECTOR, 8
> .rept CYGNUM_HAL_ISR_COUNT
> INTERRUPT
> .endr
>
> Do you see what this does and how it does it? A small preamble that
> identifies the vector in a register, followed by a jump. And all contained
> in a macro in a way that is clean, even though CYGNUM_HAL_ISR_COUNT is very
> large on the v850, like the SH1.
>
> Jifl
> --
> Red Hat, Rustat House, Clifton Road, Cambridge, UK. Tel: +44 (1223) 271062
> Un cheval, pas du glue. Pas du cheval, beaucoup du glue. || Opinions==mine