Inter processor Interrrupts in ARM cortex A9 ( How To write an handler for Software generated Interrupt ( ARM) in Linux? )

arm, interrupt-handling, linux-kernel

Solution

Does any one have an idea how to write a handler for SGI in Linux?

As you didn't give the Linux version, I will assume you work with the latest (or at least recent). The ARM GIC has device tree bindings. Typically, you need to specify the SGI interrupt number in a device tree node,

 ipc: ipc@address {
        compatible = "company,board-ipc"; /* Your driver */
        reg = <address range>;
        interrupts = <1 SGI 0x02>;  /* SGI is your CPU interrupt. */
        status = "enabled";
 };

The first number in the interrupt stanza denotes a PPI. The SGI will probably be between 0-15 as this is where the SGI interrupts are routed (at least on a Cortex-A5).

Then you can just use the `platform_get_irq()` in your driver to get the PPI (peripheral private interrupt). I guess that address is the shared memory (physical) where you wish to do the communications; maybe `reg` is not appropriate, but I think it will work. This area will be remapped by the Linux MMU and you can use it with,

res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
mem = devm_ioremap_resource(dev, res);

The address in the device tree above is a hex value of the physical address. The `platform_get_irq()` should return an irq number which you can use with the `request_irq()` family of functions. Just connect this to your routine.

Edit: Unfortunately, interrupts below 16 are forbidden by the Linux irq-gic.c. For example, `gic_handle_irq()`, limits handler to interrupts between 16 and 1020. If SMP is enabled, then `handle_IPI()` is called for the interrupts of interest. `gic_raise_softirq()` can be used to signal an interrupt. To handle the SGI with the current Linux, smp.c needs additional `enum ipi_msg_type` values and code to handle these in `handle_IPI()`. It looks like newer kernels (3.14+ perhaps?) may add a `set_ipi_handler()` to smp.c to make such a modification unneeded.

Problem

I read that the Software generated interrupts in ARM are used as Inter-processor interrupts. I can also see that 5 of those interrupts are already in use. I also know that ARM provides 16 Software generated interrupts. In my application i am running a bare metal application on of the ARM-cortex cores and Linux on the other. I want to communicate some data from the core running bare metal application to the core which is running Linux. I plan to copy the data to the on chip memory ( which is shared) and I will trigger a SGI on the Core ( running linux) to indicate some data is available for it to process. Now I am able to generate the SGI from the core ( running bare-metal application ). But for handling the interrupt in the linux side, I am not sure of the SGI IRQ numbers which are free and I am also not sure whether i can use the IRQ number directly ( in general SGI are from 0-15). Does any one have an idea how to write a handler for SGI in Linux? Edit: This is a re-wording of the above text, because the question was closed for SSCE reasons. The Cortex-A CPUs are used in multi-CPU systems. An ARM generic interrupt controller (GIC) monitors all global interrupts and dispatches them to a particular CPU. In order for individual CPUs to signal each other, a software generated interrupt (SGI) is sent from one core to the other; this uses peripheral private interrupts (PPI). This question is, How to implement a Linux kernel driver that can receive an SGI as a PPI?

Original source