2014-02-28 17:03:33

by Tim Sander

[permalink] [raw]
Subject: FIQ on xilinx cortex a9 zynq

Hi

I am currently trying to get the FIQ interrupt working with linux. I want to
have the FIQ to have an interrupt which is not masked by linux and gives the
lowest irq latencys the hardware can deliver.

In the case of the xilinx zynx i have seen that the ICCICR register enables
the FIQ via the fittingly named config bit FiqEn. Enabling this bit "as is" does
not seem to work as the kernel works in secure mode and thus all interrupts
delivered suddenly are delivered in FIQ context which is obviously not a good
idea.

So i tried to switch all interrupts to the non-secure mode:
Disable the interrupts in ICCICR register, set all interrupt security
registers to 0xffffffff which means non-secure mode.

The register values after that looked like that which is slighly irritating
for the ICDISR0 case:
ICDISR0:f800ffff
ICDISR1:ffffffff
ICDISR2:ffffffff
Set the ICCICR register to 0x17 (SBPR,AckCtl,EnableNS,EnableS).
But still the kernel locks up when doing this.

One cause would be that in driver/irqchips/irq-gic.c the first bit in ICCICR is
used to switch the interrupts off. Now it should be the second bit as they where
shifted to the non-secure mode.

I tried the following patch which should switch both the non-secure and the
secure images but still this locked the kernel up:
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index 5e7f810..a05a126 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -467,13 +467,14 @@ static void gic_cpu_init(struct gic_chip_data *gic)
writel_relaxed(0xa0a0a0a0, dist_base + GIC_DIST_PRI + i * 4 / 4);

writel_relaxed(0xf0, base + GIC_CPU_PRIMASK);
- writel_relaxed(1, base + GIC_CPU_CTRL);
+
+ writel_relaxed(readl(base + GIC_CPU_CTRL)|3, base + GIC_CPU_CTRL);
}

void gic_cpu_if_down(void)
{
void __iomem *cpu_base = gic_data_cpu_base(&gic_data[0]);
- writel_relaxed(0, cpu_base + GIC_CPU_CTRL);
+ writel_relaxed(readl(cpu_base + GIC_CPU_CTRL)&0xfffffffc, cpu_base + GIC_CPU_CTRL);
}

#ifdef CONFIG_CPU_PM
@@ -608,7 +609,7 @@ static void gic_cpu_restore(unsigned int gic_nr)
writel_relaxed(0xa0a0a0a0, dist_base + GIC_DIST_PRI + i * 4);

writel_relaxed(0xf0, cpu_base + GIC_CPU_PRIMASK);
- writel_relaxed(1, cpu_base + GIC_CPU_CTRL);
+ writel_relaxed(readl(cpu_base + GIC_CPU_CTRL)|3, cpu_base + GIC_CPU_CTRL);
}

static int gic_notifier(struct notifier_block *self, unsigned long cmd, void *v)
----

but still the kernel locks up even if i haven't enabled the fiqen bit in ICCICR register.
So currently i am out of ideas why the kernel locks up but i am sure i have forgotten one thing
or another... :-/

It seems much harder to get the FIQ running than in the "good ol' days" without TrustZone.

Best regards
Tim


2014-04-01 13:27:06

by Michal Simek

[permalink] [raw]
Subject: Re: FIQ on xilinx cortex a9 zynq

Hi Tim,

On 02/28/2014 05:53 PM, Tim Sander wrote:
> Hi
>
> I am currently trying to get the FIQ interrupt working with linux. I want to
> have the FIQ to have an interrupt which is not masked by linux and gives the
> lowest irq latencys the hardware can deliver.
>
> In the case of the xilinx zynx i have seen that the ICCICR register enables
> the FIQ via the fittingly named config bit FiqEn. Enabling this bit "as is" does
> not seem to work as the kernel works in secure mode and thus all interrupts
> delivered suddenly are delivered in FIQ context which is obviously not a good
> idea.

yes. I don't know why but Linux on Zynq in secure mode.
As I mentioned in u-boot thread there is secure monitor available
here https://github.com/serngawy/OpenVirtualization
where Linux is switched to non-secure mode.
Unfortunately this secure monitor is not done in nice way
but at least it proved that Linux can run in non secure mode.

Regarding GIC setup here should be experts to tell you how to do it.
If you need some help to get Linux running on Zynq in non secure mode
please ping me we can look at it. I tried it some months ago.

Thanks,
Michal

--
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: http://www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Microblaze cpu - http://www.monstr.eu/fdt/
Maintainer of Linux kernel - Xilinx Zynq ARM architecture
Microblaze U-BOOT custodian and responsible for u-boot arm zynq platform



Attachments:
signature.asc (263.00 B)
OpenPGP digital signature