Interrupt Layer Initialisation

This topic describes how to implement the Asic::Init1() and Asic::Init3() functions to initialise interrupts.

In first phase initialisation

During first phase initialisation of start-up, the kernel calls the ASSP's implementation of Asic::Init1(). For the template reference board, where the ASSP is split into a common, ASSP layer and a device-specific (variant) layer, interrupt handling is initialised in the ASSP layer, specifically in TemplateAssp::Init1(), defined in ...\template_assp\template_assp_priv.h, and implemented in ...\template_assp\assp.cpp.

Note that interrupts are disabled during first phase initialisation.

Within your implementation of Init1(), do the following:

  • Initialise the ISR table.

    It is useful to initialise the ISR table so that each interrupt is bound, by default, to the Spurious interrupts handler, with the 32-bit parameter taking the interrupt number.

    For example,

    ...
    const TInt KInterruptSourceCount = 32;
    SInterruptHandler IsrHandlers[KInterruptSourceCount];
    ...
    
    for( TInt i = 0; i < KInterruptSourceCount; ++i )
        {
        IsrHandlers[i].iIsr = SpuriousHandler;
        IsrHandlers[i].iPtr = (TAny*)i;
        }

    where the spurious interrupt handler function might be implemented as:

    void SpuriousHandler(TAny* aId)
        {
           Kern::Fault("SpuriousInt", (TInt)aId);    // handle unexpected interrupt.
        }
    

    On the template reference board, the ISR table is initialised by TemplateInterrupt::Init1() in ...\template_assp\interrupts.cpp, and this is called by TemplateAssp::Init1().

  • Register the dispatcher functions. The Symbian platform kernel needs to know the location of the IRQ and FIQ dispatchers. It provides the two functions: Arm::SetIrqHandler() and Arm::SetFiqHandler(), which the Variant layer must call, passing the addresses of the IRQ and FIQ dispatchers.

    On the template reference board, the registration is done by TemplateInterrupt::Init1() in ...\template_assp\interrupts.cpp.

    void TemplateInterrupt::Init1()
        {
         //
         // need to hook the ARM IRQ and FIQ handlers as early as possible
         // and disable and clear all interrupt sources
         //
         ... 
         DisableAndClearAll();
         Arm::SetIrqHandler((TLinAddr)TemplateInterrupt::IrqDispatch);
         Arm::SetFiqHandler((TLinAddr)TemplateInterrupt::FiqDispatch);
        }
    
  • Bind any ISRs that handle chained or pseudo interrupts

In third phase initialisation

During third phase initialisation of start-up, the kernel calls the ASSP's implementation of Asic::Init3().

Note that interrupts are enabled during third phase initialisation.

Within your implementation of Init3(), if you need to, call Interrupt::Enable() on any of the interrupt sources that are bound to a chained or pseudo ISR dispatcher. You don't need to do this if you are enabling and disabling the main interrupt on demand as the chained or pseudo-interrupts are enabled and disabled.