How to get interrupts available in OAL? RRS feed

  • Question

  • Hi,

    I have noticed that interrupts get only available in my BSP when the Kernel starts rescheduling threads:

    PID:00400003 TID:00000016 CPU 2 started, ready to reschedule, ppcb = fffd9800

    But they are not available before that. I am sending IPI and g_pOemGlobal->pfnSendIpi is called only after the line above. It is not only about IPI I also have exactly the same situation with SPI interrupts. For some reason I can send IPI before Kernel starts e.g. in startup.s. But in OAL I cannot do this. So it seems that kernel somehow enables all the interrupts. In OAL I don't have anything that could possibly disable interrupts (at least explicitly). What does the kernel use to enable interrupts? Maybe there is something that I missing in my interrupts intitialization routine? Any ideas?

    My BSP is based on ARMv7 template.


    Monday, December 5, 2011 11:57 AM

All replies

  • It's logical when you think about it; the kernel has to schedule your IST (which is nothing more than a thread) so of course the scheduler has to be available and started. Early on in the OAL you'll have to do it with polling, no interrupts yet.

    It may be better to tell us what you are trying to accomplish, there may be better ways to reach your goal.

    Good luck,

    Michel Verhagen, eMVP
    Check out my blog:

    Microsoft Embedded Partner
    Consultancy, training and development services.
    Monday, December 5, 2011 9:09 PM
  • First I tried to send SGI (Software generated interrupt) to the second core to wake it up from the WFI (Wait for interrupt) state. I could do it only in startup.s before calling KernelStart or after the scheduler started but not in OAL. I think it is better to do all the initialization of the 2nd core in OAL. But interrupts are not available there therefore I have moved part of the initialization routine to startup.s (which is not good). Now I am trying to implement cache functions for multi-core system. I am using NKSendInterProcessorInterrupt function to perform certain operations on the other core. This function doesn't seem to work in OAL (I suppose because of disabled interrupts or for some other weird reason). But when I try to use this function later (as an experiment) after the scheduler started it works fine (it calls g_pOemGlobal->pfnSendIpi and subsequently g_pOemGlobal->pfnIpiHandler is called on the other core). The problem is that OEMCacheRangeFlush is called very frequently in OAL and it fails to send an IPI there.

    Any ideas?


    • Edited by Jker Tuesday, December 6, 2011 12:42 AM
    Tuesday, December 6, 2011 12:36 AM
  • The message you saw is printed out by MpStartContinue (private\winceos\COREOS\nk\kernel\arm\mdarm.c).
    And in NKSendInterProcessorInterrupt (nk\kernel\kcalls.c), it only issue IPI when g_nCpuReady > 1, therefore, before the MP initialized the pfnIpiHandler is not available.
    If you still need to send IPI in OEMInit, perhaps you need to write the interrupt controller to generate SGI to wake up the secondary processor from WFI. And after the secondary processor wakeup, besides to complete the routine it need to perform, you may need to clear the interrupt on GIC cpu interface (assume you are using GIC, yes?), so it can honor subsequent interrupts request.
    Maybe you could tell us what kind of operation you want to perform in OAL init?


    Tuesday, December 6, 2011 7:57 PM
  • Well, the main problem is that it just hangs before scheduling the first thread. I am trying to figure out possible reasons for that.
    So far what I have noticed that it hangs only after the second core sends the SECOND interrupt.
    So I have done the following experiment to confirm it:
    1. In OEMInterruptHandler:
       OUTREG32(&s_pIntrCPURegs->EOI, status & 0x3FF );//acknoledge the interrupt 
       if(irq==0)return SYSINTR_IPI;
       if (irq==1)return SYSINTR_NOP;
    2. Then in infinite loop I send irq=1, which is handled as SYSINTR_NOP
    If I send IPIs in infinite loop from Core 0 to Core 0 I receive interrupts contiously at Core 0.
    If I send IPIs in infinite loop from Core 0 to Core 1 I receive interrupts contiously at Core 1.
    If I send IPIs in infinite loop from Core 1 to Core 1 I receive only 1 interrupt at Core 1.
    If I send IPIs in infinite loop from Core 1 to Core 0 I receive only 1 interrupt at Core 0.
    So it seems that it is something wrong indeed with the second core. But it is not interrupt handling it is interrupt sending.
    The GIC is configured in the same way for both cores. This one leaves me clueless. Any ideas?
    • Edited by Jker Wednesday, December 7, 2011 1:11 PM
    Wednesday, December 7, 2011 1:10 PM
  • Before the initialization (NKMpStart and MpStartContinue) of secondary processor(s), many important system resource is not yet initialized, such as stack in different mode and especially the PCB (Processor Control Block, refer to private\winceos\COREOS\nk\inc\nkarm.h for the definition).
    As PCB record per processor information and is widely used in the whole kernel, so basically try to running and OS code before kernel initialize secondary CPU can result unexpected result.
    So if you definitely need to send IPI or run any code on secondary CPU in OEMInit, then you are on your own.
    Since kernel not yet initialize second CPU, one should never use standard API to send out IPI but use own mechanism and your own interrupt Hadlee. ie. should never allow secondary CPU flows to kernel's IRQ handler at this point.
    Wednesday, December 7, 2011 9:43 PM