On Mon, Nov 25, 2013 at 9:13 PM, Rob Herring <robherring2@xxxxxxxxx> wrote: > On Sat, Nov 23, 2013 at 2:41 AM, Anup Patel <anup@xxxxxxxxxxxxxx> wrote: >> On Wed, Nov 20, 2013 at 4:28 PM, Marc Zyngier <marc.zyngier@xxxxxxx> wrote: >>> [dropping <patches@xxxxxxx> from the CC list, as someone seems to have >>> tripped on the config file, and I'm tired of getting bounces] >>> >>> Feng, >>> >>> On 19/11/13 21:42, Feng Kan wrote: >>>> The GIC-400 implementation allows for FIQ and IRQ bypass. In the >>>> X-Gene implementation, the FIQ bypass must be enabled at all time. >>>> Otherwise, some PPI will appear as FIQ and cause kernel problem. >>> >>> How comes? Are only PPIs affected? When you say "some PPIs", can you be >>> more specific? >>> >>>> Signed-off-by: Feng Kan <fkan@xxxxxxx> >>>> --- >>>> drivers/irqchip/irq-gic.c | 15 +++++++++++---- >>>> include/linux/irqchip/arm-gic.h | 4 ++-- >>>> 2 files changed, 13 insertions(+), 6 deletions(-) >>>> >>>> diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c >>>> index d0e9480..aa7342e 100644 >>>> --- a/drivers/irqchip/irq-gic.c >>>> +++ b/drivers/irqchip/irq-gic.c >>>> @@ -65,6 +65,7 @@ struct gic_chip_data { >>>> #endif >>>> struct irq_domain *domain; >>>> unsigned int gic_irqs; >>>> + unsigned int bypass_flag; >>>> #ifdef CONFIG_GIC_NON_BANKED >>>> void __iomem *(*get_base)(union gic_base *); >>>> #endif >>>> @@ -450,7 +451,7 @@ 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(gic->bypass_flag | 1, base + GIC_CPU_CTRL); >>>> } >>>> >>>> void gic_cpu_if_down(void) >>>> @@ -591,7 +592,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(gic_data[gic_nr].bypass_flag | 1, cpu_base + GIC_CPU_CTRL); >>>> } >>>> >>>> static int gic_notifier(struct notifier_block *self, unsigned long cmd, void *v) >>>> @@ -733,7 +734,8 @@ const struct irq_domain_ops gic_irq_domain_ops = { >>>> >>>> void __init gic_init_bases(unsigned int gic_nr, int irq_start, >>>> void __iomem *dist_base, void __iomem *cpu_base, >>>> - u32 percpu_offset, struct device_node *node) >>>> + u32 percpu_offset, u32 bypass_val, >>>> + struct device_node *node) >>>> { >>>> irq_hw_number_t hwirq_base; >>>> struct gic_chip_data *gic; >>>> @@ -821,6 +823,7 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start, >>>> >>>> set_handle_irq(gic_handle_irq); >>>> >>>> + gic->bypass_flag = (bypass_val & 0xf) << 4; >>> >>> Beware, the top 2 bits are reserved on GICv1, and shouldn't be messed with. >>> >>>> gic_chip.flags |= gic_arch_extn.flags; >>>> gic_dist_init(gic); >>>> gic_cpu_init(gic); >>>> @@ -835,6 +838,7 @@ int __init gic_of_init(struct device_node *node, struct device_node *parent) >>>> void __iomem *cpu_base; >>>> void __iomem *dist_base; >>>> u32 percpu_offset; >>>> + u32 bypass_val; >>>> int irq; >>>> >>>> if (WARN_ON(!node)) >>>> @@ -849,7 +853,10 @@ int __init gic_of_init(struct device_node *node, struct device_node *parent) >>>> if (of_property_read_u32(node, "cpu-offset", &percpu_offset)) >>>> percpu_offset = 0; >>>> >>>> - gic_init_bases(gic_cnt, -1, dist_base, cpu_base, percpu_offset, node); >>>> + if (of_property_read_u32(node, "bypass-flags", &bypass_val)) >>>> + bypass_val = 0; >>> >>> [adding Mark on Cc, so he can comment on the DT parts] >>> >>> Where's the DT documentation update? Also, as this is an >>> implementation-specific quirk, you should consider using a separate >>> compatible string and move the handling of this issue into some X-Gene >>> specific code. >> >> Adding separate compatible string for X-Gene specific GIC will break >> VGIC code for X-Gene because VGIC code looks for DT node compatible >> to "arm,cortex-a15-gic". We don't want to break currently working VGIC >> code for X-Gene. >> >> The Legacy-IRQ bypass disable and Legacy-FIQ bypass disable is a >> feature of GIC-400 and its not X-Gene specific. The only difference in X-Gene >> is that we use PPI31 (Legacy-IRQ) for timer and PPI28 (Legacy-FIQ) for perf >> event. The issue is that IRQBypDisGrp0, FIQBypDisGrp0, IRQBypDisGrp1 >> and FIQBypDisGrp1 bits are 0 by default and for X-Gene we need to set >> these bits to 1 so that GIC-400 does not bypass PPI31 (Legacy-IRQ) and >> PPI28 (Legacy-FIQ). >> >> We should have more cleaner and optional device tree binding for GIC >> which can help us set IRQBypDisGrp0, FIQBypDisGrp0, IRQBypDisGrp1 >> and FIQBypDisGrp1 bits for X-Gene. > > IIRC, all these bits are secure mode only (or only a subset are > banked). Whether an SoC supports secure mode or not, the current > policy for the kernel is to do any secure mode setup in firmware or > bootloader. Group0 are secure interrupts and Group1 are non-secure interrupts. Does this mean we should only touch IRQBypDisGrp1 and FIQBypDisGrp1 bits from kernel ?? > > Rob -- Anup _______________________________________________ kvmarm mailing list kvmarm@xxxxxxxxxxxxxxxxxxxxx https://lists.cs.columbia.edu/cucslists/listinfo/kvmarm