/* Default priority for global interrupts */
for ( i = 32; i < gic.lines; i += 4 )
- GICD[GICD_IPRIORITYR + i / 4] = 0xa0a0a0a0;
+ GICD[GICD_IPRIORITYR + i / 4] =
+ GIC_PRI_IRQ<<24 | GIC_PRI_IRQ<<16 | GIC_PRI_IRQ<<8 | GIC_PRI_IRQ;
/* Disable all global interrupts */
for ( i = 32; i < gic.lines; i += 32 )
* be set up here with the other per-cpu state. */
GICD[GICD_ICENABLER] = 0xffff0000; /* Disable all PPI */
GICD[GICD_ISENABLER] = 0x0000ffff; /* Enable all SGI */
- /* Set PPI and SGI priorities */
- for (i = 0; i < 32; i += 4)
- GICD[GICD_IPRIORITYR + i / 4] = 0xa0a0a0a0;
+ /* Set SGI priorities */
+ for (i = 0; i < 16; i += 4)
+ GICD[GICD_IPRIORITYR + i / 4] =
+ GIC_PRI_IPI<<24 | GIC_PRI_IPI<<16 | GIC_PRI_IPI<<8 | GIC_PRI_IPI;
+ /* Set PPI priorities */
+ for (i = 16; i < 32; i += 4)
+ GICD[GICD_IPRIORITYR + i / 4] =
+ GIC_PRI_IRQ<<24 | GIC_PRI_IRQ<<16 | GIC_PRI_IRQ<<8 | GIC_PRI_IRQ;
/* Local settings: interface controller */
GICC[GICC_PMR] = 0xff; /* Don't mask by priority */
void gic_route_ppis(void)
{
/* GIC maintenance */
- gic_route_dt_irq(&gic.maintenance, cpumask_of(smp_processor_id()), 0xa0);
+ gic_route_dt_irq(&gic.maintenance, cpumask_of(smp_processor_id()),
+ GIC_PRI_IRQ);
/* Route timer interrupt */
route_timer_interrupt();
}
if ( (irq = serial_dt_irq(seridx)) == NULL )
continue;
- gic_route_dt_irq(irq, cpumask_of(smp_processor_id()), 0xa0);
+ gic_route_dt_irq(irq, cpumask_of(smp_processor_id()),
+ GIC_PRI_IRQ);
}
}
level = dt_irq_is_level_triggered(irq);
gic_set_irq_properties(irq->irq, level, cpumask_of(smp_processor_id()),
- 0xa0);
+ GIC_PRI_IRQ);
retval = __setup_irq(desc, irq->irq, action);
if (retval) {
void __cpuinit route_timer_interrupt(void)
{
gic_route_dt_irq(&timer_irq[TIMER_PHYS_NONSECURE_PPI],
- cpumask_of(smp_processor_id()), 0xa0);
+ cpumask_of(smp_processor_id()), GIC_PRI_IRQ);
gic_route_dt_irq(&timer_irq[TIMER_HYP_PPI],
- cpumask_of(smp_processor_id()), 0xa0);
+ cpumask_of(smp_processor_id()), GIC_PRI_IRQ);
gic_route_dt_irq(&timer_irq[TIMER_VIRT_PPI],
- cpumask_of(smp_processor_id()), 0xa0);
+ cpumask_of(smp_processor_id()), GIC_PRI_IRQ);
}
/* Set up the timer interrupt on this CPU */
#define GICH_LR_CPUID_SHIFT 9
#define GICH_VTR_NRLRGS 0x3f
+/*
+ * The minimum GICC_BPR is required to be in the range 0-3. We set
+ * GICC_BPR to 0 but we must expect that it might be 3. This means we
+ * can rely on premption between the following ranges:
+ * 0xf0..0xff
+ * 0xe0..0xdf
+ * 0xc0..0xcf
+ * 0xb0..0xbf
+ * 0xa0..0xaf
+ * 0x90..0x9f
+ * 0x80..0x8f
+ *
+ * Priorities within a range will not preempt each other.
+ *
+ * A GIC must support a mimimum of 16 priority levels.
+ */
+#define GIC_PRI_LOWEST 0xf0
+#define GIC_PRI_IRQ 0xa0
+#define GIC_PRI_IPI 0x90 /* IPIs must preempt normal interrupts */
+#define GIC_PRI_HIGHEST 0x80 /* Higher priorities belong to Secure-World */
+
+
#ifndef __ASSEMBLY__
#include <xen/device_tree.h>