changes to the core Nios2 RTEMS IIC model

Hill, Jeff johill at lanl.gov
Tue Aug 14 19:53:22 UTC 2012


> This is very dangerous.  This may lead to infinite stack usage due to ISR
> contexts on the thread stack (e.g. spurious interrupt).

Some background information for those who are unfamiliar with
the Nios2; we reached a compromise for the Nios2 with internal 
interrupt controller (IIC) some time back in which 
_CPU_ISR_Disable/_CPU_ISR_Enable only implements two levels 
for the nios2 with IIC; they are interrupts globally enabled 
or interrupts globally disabled. This allow the score to be 
identical for Nios2 with external (EIC) and with IIC 
(Nios2 must be instantiated with one of EIC or IIC but not both).

Furthermore, in our application it is very important for 
one internal interrupt level to preempt another. For example, 
interrupts from our timing card must preempt interrupts from, 
for example, the Altera Avalon JTAG UART.

Furthermore, in the code immediately above the code Sebastian
attached in his mail I disable internal interrupts from 
the same or lower levels compared to the interrupt that 
is currently running. Below is the crux part of that 
protection. This is precisely why the driver support 
code shouldn't directly manipulate the Nios2 ienable 
register in the new interrupt model, which allows a higher 
priority interrupt to preempt a lower one. This code does
protect from infinite recursion on the interrupt stack;
we can go only 32 deep.

    uint32_t newEnbl = NIOS2_IENABLE_NO_INTERNAL_INTERRUPTS;
    if ( ipending ) {
      vector = __builtin_ctz ( ipending );
      if ( vector < CPU_INTERRUPT_NUMBER_OF_VECTORS ) {
        pHandler = _ISR_Vector_table[ vector ];
        /*
         * disable nios2 internal interrupts of equal or lower level
         * (we restore the interrupt level in the low level code
         * so that we dont explode the interrupt stack when there
         * is an unquenched interrupt source)
         *
         * Bit 0 in the ipending register has highest priority
         * and bit 31 has lowest priority.
         */
        newEnbl = ( 1u << vector ) - 1u;
      }
    }
    __builtin_wrctl ( NIOS2_CTLREG_INDEX_IENABLE, newEnbl );


> Can you implement the _Nios2_Has_internal_interrupt_controller() similar
> to this (it avoids an additional global variable):

Yes, that appears to be a better way so I will implement a patch. 

I suppose that this way of externally configuring the score could 
be used also to configure two different _CPU_ISR_Disable/_CPU_ISR_Enable 
implementations for the IIC and EIC situations; of course the runtime 
expense of actually jumping into a function instead of using am inline 
macro would be the downside, but otherwise we could implement each
function for maximum efficiency on a specific architecture. This 
function could be quite efficient if it is placed in on-chip ram by
the linker script. Time permitting, I will experiment with this, in 
a separate patch.

Jeff

> -----Original Message-----
> From: Sebastian Huber [mailto:sebastian.huber at embedded-brains.de]
> Sent: Tuesday, August 14, 2012 1:30 AM
> To: Hill, Jeff
> Cc: rtemsdev at ixo.de; ruppe at kth.se
> Subject: Re: changes to the core Nios2 RTEMS IIC model
> 
> Hello Jeff,
> 
> I didn't look at the IIC stuff at all since I was only interested in the
> EIC.
> Can you implement the _Nios2_Has_internal_interrupt_controller() similar
> to
> this (it avoids an additional global variable):
> 
> http://git.rtems.org/rtems/tree/cpukit/score/cpu/nios2/nios2-isr-set-
> level.c
> 
> On 08/14/2012 03:05 AM, Hill, Jeff wrote:
> >    if ( _ISR_Nest_level == 0) {
> > #   if( CPU_HAS_SOFTWARE_INTERRUPT_STACK == TRUE)
> >        stack_ptr = _old_stack_ptr;
> > #   endif
> >
> >      if ( !_Thread_Dispatch_in_critical_section() ) {
> >        if ( _Thread_Is_dispatch_necessary () ) {
> >          _CPU_ISR_Enable ( isrCookie );
> >          _Thread_Dispatch ();
> >          /* may have switched to another task and not return here immed.
> */
> >          _CPU_ISR_Disable ( isrCookie ); /* Keep _pairs_  of
> Enable/Disable */
> >        }
> >      }
> >    }
> 
> This is very dangerous.  This may lead to infinite stack usage due to ISR
> contexts on the thread stack (e.g. spurious interrupt).
> 
> --
> Sebastian Huber, embedded brains GmbH
> 
> Address : Obere Lagerstr. 30, D-82178 Puchheim, Germany
> Phone   : +49 89 18 90 80 79-6
> Fax     : +49 89 18 90 80 79-9
> E-Mail  : sebastian.huber at embedded-brains.de
> PGP     : Public key available on request.
> 
> Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.
> 





More information about the users mailing list