This is the mail archive of the ecos-patches@sources.redhat.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [ECOS] Possible loss of PowerPC mpc8xx Interrupts


On Thu, 2003-05-22 at 20:38, Jonathan Larmour wrote:
> [ Excuse my top posting - it's a one-off ]
> 
> Looks right to me. I'll check this in tomorrow unless someone (Hi Gary 
> :-)) objects.
> 

When you look at this, please check all of the macros.  They were
all done the same way and if one's wrong, they all very well may be.

I do think that the observation below is correct, BTW.

> Jifl
> 
> Retallack, Mark (Poole) wrote:
> > We have found a problem that could cause the loss of edge triggered
> > interrupts.
> > 
> > The following section of code is from the
> > \hal\powerpc\mpc8xx\current\include\var_initr.h file, in function
> > cyg_hal_interrupt_acknowledge:
> > 
> >     case CYGNUM_HAL_INTERRUPT_SIU_IRQ0 ... CYGNUM_HAL_INTERRUPT_SIU_LVL7:
> >     {
> >         // SIU interrupt vectors
> >         cyg_uint32 sipend;
> > 
> >         // When IRQx is configured as an edge interrupt it needs to be
> >         // cleared. Write to INTx and IRQ/level bits are ignore so
> >         // it's safe to do always.
> >         HAL_READ_UINT32 (CYGARC_REG_IMM_SIPEND, sipend);
> >         sipend |= (((cyg_uint32) CYGARC_REG_IMM_SIPEND_IRQ0) 
> >                    >> (vector - CYGNUM_HAL_INTERRUPT_SIU_IRQ0));
> >         HAL_WRITE_UINT32 (CYGARC_REG_IMM_SIPEND, sipend);
> >         break;
> >     }
> > 
> > In the MPC850 user manual, it states that:
> > 
> > 	"If an IRQ pin is defined as an edge interrupt, the corresponding
> > bit being set indicates that a falling edge was detected on the line and are
> > reset by writing ones to them."
> > 
> > This means that if an edge triggered interrupt comes in just after another
> > interrupt (while the first interrupt is executing) and the
> > cyg_hal_interrupt_acknowledge function is called, the second interrupt will
> > be lost and will nether be serviced.
> > 
> > The HAL_READ_UINT32 will read the SIPEND register which will contain two
> > bits that are set (one for each interrupt) this will then be written back to
> > the SIPEND register and will clear both interrupts. 
> > 
> > A better solution could be to use:
> > 
> >         sipend = (((cyg_uint32) CYGARC_REG_IMM_SIPEND_IRQ0) 
> >                    >> (vector - CYGNUM_HAL_INTERRUPT_SIU_IRQ0));
> >         HAL_WRITE_UINT32 (CYGARC_REG_IMM_SIPEND, sipend);
> > 
> > Is this correct are am I just using the cyg_hal_interrupt_acknowledge
> > incorrectly? 
-- 
Gary Thomas <gary@mlbassoc.com>
MLB Associates


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]