From mboxrd@z Thu Jan 1 00:00:00 1970 From: Aaron Passey To: Jonathan Larmour Cc: Jesper Skov , ecos-discuss@sources.redhat.com Subject: Re: [ECOS] SH1 port of eCos Date: Mon, 15 Jan 2001 20:10:00 -0000 Message-id: <20010116041040.BC078D6815@lek.ugcs.caltech.edu> References: <3A63B48C.A4338AFE@redhat.com> X-SW-Source: 2001-01/msg00248.html 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