This is the mail archive of the
ecos-patches@sources.redhat.com
mailing list for the eCos project.
Re: [ECOS] Possible loss of PowerPC mpc8xx Interrupts
- From: Jonathan Larmour <jifl at eCosCentric dot com>
- To: eCos Patches List <ecos-patches at sources dot redhat dot com>
- Date: Tue, 24 Jun 2003 07:24:11 +0100
- Subject: Re: [ECOS] Possible loss of PowerPC mpc8xx Interrupts
- References: <F5AFBF4F39DBDD488C5B9B41D48145CC1F9302@plestcl0112.stcl.siemens.co.uk> <3ECD8992.7040208@eCosCentric.com>
Jonathan Larmour wrote:
We have found a problem that could cause the loss of edge triggered
interrupts.
[snip]
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.
So as per this, I've checked in the attached patch, which also follows
Gary's request to check the other interrupt acks in that function.
Jifl
--
eCosCentric http://www.eCosCentric.com/ The eCos and RedBoot experts
--[ "You can complain because roses have thorns, or you ]--
--[ can rejoice because thorns have roses." -Lincoln ]-- Opinions==mine
Index: ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/powerpc/mpc8xx/current/ChangeLog,v
retrieving revision 1.29
diff -u -5 -p -r1.29 ChangeLog
--- ChangeLog 16 Apr 2003 16:04:23 -0000 1.29
+++ ChangeLog 24 Jun 2003 06:22:49 -0000
@@ -1,5 +1,11 @@
+2003-06-24 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * include/var_intr.h (cyg_hal_interrupt_acknowledge): Don't
+ inadvertently clear other interrupts when acknowledging the
+ intended int. Reported by Mark Retallack.
+
2003-04-16 Gary Thomas <gary@mlbassoc.com>
* src/var_misc.c (hal_variant_init): Errata setup for MPC852T
2003-03-23 Gary Thomas <gary@mlbassoc.com>
Index: include/var_intr.h
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/powerpc/mpc8xx/current/include/var_intr.h,v
retrieving revision 1.6
diff -u -5 -p -r1.6 var_intr.h
--- include/var_intr.h 23 Mar 2003 16:22:14 -0000 1.6
+++ include/var_intr.h 24 Jun 2003 06:22:50 -0000
@@ -428,12 +428,11 @@ cyg_hal_interrupt_acknowledge ( cyg_uint
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)
+ sipend = (((cyg_uint32) CYGARC_REG_IMM_SIPEND_IRQ0)
>> (vector - CYGNUM_HAL_INTERRUPT_SIU_IRQ0));
HAL_WRITE_UINT32 (CYGARC_REG_IMM_SIPEND, sipend);
break;
}
case CYGNUM_HAL_INTERRUPT_SIU_TB_A:
@@ -441,20 +440,24 @@ cyg_hal_interrupt_acknowledge ( cyg_uint
// TimeBase A interrupt
cyg_uint16 tbscr;
HAL_READ_UINT16 (CYGARC_REG_IMM_TBSCR, tbscr);
tbscr |= CYGARC_REG_IMM_TBSCR_REFA;
+ // take care not to accidently reset potential pending REFB
+ tbscr &= ~CYGARC_REG_IMM_TBSCR_REFB;
HAL_WRITE_UINT16 (CYGARC_REG_IMM_TBSCR, tbscr);
break;
}
case CYGNUM_HAL_INTERRUPT_SIU_TB_B:
{
// TimeBase B interrupt
cyg_uint16 tbscr;
HAL_READ_UINT16 (CYGARC_REG_IMM_TBSCR, tbscr);
tbscr |= CYGARC_REG_IMM_TBSCR_REFB;
+ // take care not to accidently reset potential pending REFA
+ tbscr &= ~CYGARC_REG_IMM_TBSCR_REFA;
HAL_WRITE_UINT16 (CYGARC_REG_IMM_TBSCR, tbscr);
break;
}
case CYGNUM_HAL_INTERRUPT_SIU_PIT:
{
@@ -471,20 +474,24 @@ cyg_hal_interrupt_acknowledge ( cyg_uint
// Real Time Clock Second
cyg_uint16 rtcsc;
HAL_READ_UINT16 (CYGARC_REG_IMM_RTCSC, rtcsc);
rtcsc |= CYGARC_REG_IMM_RTCSC_SEC;
+ // take care not to accidently reset potential pending RTCSC_ALR
+ rtcsc &= ~CYGARC_REG_IMM_RTCSC_ALR;
HAL_WRITE_UINT16 (CYGARC_REG_IMM_RTCSC, rtcsc);
break;
}
case CYGNUM_HAL_INTERRUPT_SIU_RTC_ALR:
{
// Real Time Clock Alarm
cyg_uint16 rtcsc;
HAL_READ_UINT16 (CYGARC_REG_IMM_RTCSC, rtcsc);
rtcsc |= CYGARC_REG_IMM_RTCSC_ALR;
+ // take care not to accidently reset potential pending RTCSC_SEC
+ rtcsc &= ~CYGARC_REG_IMM_RTCSC_SEC;
HAL_WRITE_UINT16 (CYGARC_REG_IMM_RTCSC, rtcsc);
break;
}
// PCMCIA_A_IRQ
// PCMCIA_A_CHLVL
@@ -497,12 +504,11 @@ cyg_hal_interrupt_acknowledge ( cyg_uint
case CYGNUM_HAL_INTERRUPT_CPM_FIRST ... CYGNUM_HAL_INTERRUPT_CPM_LAST:
{
// CPM interrupts
cyg_uint32 cisr;
- HAL_READ_UINT32 (CYGARC_REG_IMM_CISR, cisr);
- cisr |= (((cyg_uint32) 0x80000000)
+ cisr = (((cyg_uint32) 0x80000000)
>> (vector - CYGNUM_HAL_INTERRUPT_CPM_FIRST));
HAL_WRITE_UINT32 (CYGARC_REG_IMM_CISR, cisr);
break;
}
default: