[ECOS] 80312 hal support for Intel XScale board

Richard Wicks rich@accetnetwork.com
Wed Oct 17 16:26:00 GMT 2001


On Tuesday 16 October 2001 02:39 pm, Jonathan Larmour wrote:
> Richard Wicks wrote:
> > On Tuesday 16 October 2001 05:01 am, Mark Salter wrote:
> > > >>>>> Richard Wicks writes:
> > > >
> > > > Hello,
> > > > I think I've found some bugs with the hal support with the Intel
> > > > XScale board.
> > >
> > > ...
> > >
> > > > According to the documentation* of the 80312 chip, in section 6.8.5
> > > > this UNmasks the interrupt rather than masking it.  There is a
> > > > similar problem with hal_interrupt_unmask.  In fact, I think nearly
> > > > all calls to hal_interrupt_mask() actually unmask the interrupt and
> > > > nearly all calls to hal_interrupt_unmask() actually mask the
> > > > interrupt.
> > >
> > > Looks like you're right. The only interrupts that we've tested are the
> > > ethernet and serial.
>
> Richard, would you care to submit a patch (generated using cvs diff -u, and
> with a ChangeLog entry to get your name in lights)? That's the clearest,
> least ambiguous way to get a fix in!

Oh boy.  Fame.  Not as good as money but - here they are.  Two files 
modified.  The changelog entry is at the end.

$cvs diff -u hal_iq80310.h
Index: hal_iq80310.h
===================================================================
RCS file: 
/cvs/ecos/ecos/packages/hal/arm/iq80310/current/include/hal_iq80310.h,v
retrieving revision 1.2
diff -u -r1.2 hal_iq80310.h
--- hal_iq80310.h       2001/08/17 16:37:36     1.2
+++ hal_iq80310.h       2001/10/17 23:06:26
@@ -507,6 +507,7 @@
 #  define NISR_BIU  0x800
 
 #define PIRSR_REG ((volatile cyg_uint32 *)PIRSR_ADDR)
+#define IDR_REG   ((volatile cyg_uint32 *)IDR_ADDR)
 #define IISR_REG  ((volatile cyg_uint32 *)IISR_ADDR)
 #define IIMR_REG  ((volatile cyg_uint32 *)IIMR_ADDR)
 #define OISR_REG  ((volatile cyg_uint32 *)OISR_ADDR)

$ cvs diff -u iq80310_misc.c
Index: iq80310_misc.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/arm/iq80310/current/src/iq80310_misc.c,v
retrieving revision 1.4
diff -u -r1.4 iq80310_misc.c
--- iq80310_misc.c      2001/09/12 00:59:21     1.4
+++ iq80310_misc.c      2001/10/17 23:07:07
@@ -536,6 +536,17 @@
     cyg_uint32 sources;
     int i, isr_ret;

+    // check doorbell interrupt first
+    // NOTE: this probably should be fixed.  It appears that when
+    //       the doorbell int is enabled an unhandled interrupt with XINT3
+    //       causes an early exit from this routine and the interrupt
+    //       never is cleared.  As a result, the interrupt stays low
+    //       and the board locks up.
+    if ((*IISR_REG) & (1<<2)) {
+      isr_ret = hal_call_isr (CYGNUM_HAL_INTERRUPT_DOORBELL);
+      CYG_ASSERT (isr_ret & CYG_ISR_HANDLED, "Interrupt not handled");
+    }
+
     // Check XINT3
     sources = *X3ISR_REG & ~(*X3MASK_REG);
     for (i = 0; i < 5; i++) {
@@ -743,7 +754,7 @@
         *ICR_REG &= ~(1<<(vector - CYGNUM_HAL_INTERRUPT_I2C_TX_EMPTY));
        return;
     case CYGNUM_HAL_INTERRUPT_MESSAGE_0 ... 
CYGNUM_HAL_INTERRUPT_INDEX_REGISTER:
-        *IIMR_REG &= ~(1<<(vector - CYGNUM_HAL_INTERRUPT_MESSAGE_0));
+        *IIMR_REG |= (1<<(vector - CYGNUM_HAL_INTERRUPT_MESSAGE_0));
        return;
     case CYGNUM_HAL_INTERRUPT_BIST:
         *ATUCR_REG &= ~(1<<3);
@@ -835,7 +846,7 @@
         *ICR_REG |= (1<<(vector - CYGNUM_HAL_INTERRUPT_I2C_TX_EMPTY));
        return;
     case CYGNUM_HAL_INTERRUPT_MESSAGE_0 ... 
CYGNUM_HAL_INTERRUPT_INDEX_REGISTER:
-        *IIMR_REG |= (1<<(vector - CYGNUM_HAL_INTERRUPT_MESSAGE_0));
+        *IIMR_REG &= ~(1<<(vector - CYGNUM_HAL_INTERRUPT_MESSAGE_0));
        return;
     case CYGNUM_HAL_INTERRUPT_BIST:
         *ATUCR_REG |= (1<<3);
@@ -892,6 +903,10 @@
             : "r"(submask)
             : "r1"
             );
+        break;
+    case CYGNUM_HAL_INTERRUPT_DOORBELL     :
+        // clear all interrupts, ignoring which particular doorbell fired.
+        *IDR_REG = 0xFFFFFFFF;
         break;
     case CYGNUM_HAL_INTERRUPT_BCU_INTERRUPT:
     case CYGNUM_HAL_INTERRUPT_NIRQ         :

Changelog entry follows:
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* Fixed masking and unmasking of doorbell interrupt for 80312 chip.
* Fixed hal_interrupt_acknowledge() to clear doorbell interrupt correctly
* Modified interrupt handler to properly handle the installed vector.

NOTE: There may be a problem with enabling ECCR interrupts.  I have masked
those interrupts in my code to make it work properly.  You may have to do
the same.  I'll track that problem down if I can find the time if it actually
is a problem and not some bug in my code.  The ECCR interrupts are enabled by 
the hal by default.

The doorbell vector is "CYGNUM_HAL_INTERRUPT_DOORBELL"

Documentation on the 80312 chip can be found at intel's website, document
#273410.  Last I looked, you could find it at the following url:

http://developer.intel.com/design/IIO/manuals/273410.htm

If you run into problems or noticed I've screwed up, you can email me at
rich.at.navosha.dot.com to yell at me or ask me questions.
-Richard Wicks
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

> > For your convenience, I've included a small piece of C code you can use
> > to send a doorbell interrupt to the XScale board.  It's a Linux module
> > that maps the ATU and then sends a doorbell interrupt on the FIQ# line to
> > the 80200 processor.
>
> It's unlikely we'll have time to look to this level of detail
> unfortunately.

If I can get time I'll see if I cannot spend more time on it since I'm 
already half way there.

> Jifl

-rich



More information about the Ecos-discuss mailing list