mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
xen/arm: gic: GICv2 & GICv3 only supports 1020 physical interrupts
GICD_TYPER.ITLinesNumber can encode up to 1024 interrupts. Although, IRQ 1020-1023 are reserved for special purpose. The result is used by the callers of gic_number_lines in order to check the validity of an IRQ. Signed-off-by: Julien Grall <julien.grall@linaro.org> Acked-by: Ian Campbell <ian.campbell@citrix.com> Cc: Frediano Ziglio <frediano.ziglio@huawei.com> Cc: Zoltan Kiss <zoltan.kiss@huawei.com>
This commit is contained in:
1 parent
e7153f3775
commit
2fd01bece8
2 files changed
+20
-12
No files matched your search
+10
-6
@@ -256,6 +256,7 @@ static void __init gicv2_dist_init(void)
|
||||
uint32_t type;
|
||||
uint32_t cpumask;
|
||||
uint32_t gic_cpus;
|
||||
unsigned int nr_lines;
|
||||
int i;
|
||||
|
||||
cpumask = readl_gicd(GICD_ITARGETSR) & 0xff;
|
||||
@@ -266,31 +267,34 @@ static void __init gicv2_dist_init(void)
|
||||
writel_gicd(0, GICD_CTLR);
|
||||
|
||||
type = readl_gicd(GICD_TYPER);
|
||||
gicv2_info.nr_lines = 32 * ((type & GICD_TYPE_LINES) + 1);
|
||||
nr_lines = 32 * ((type & GICD_TYPE_LINES) + 1);
|
||||
gic_cpus = 1 + ((type & GICD_TYPE_CPUS) >> 5);
|
||||
printk("GICv2: %d lines, %d cpu%s%s (IID %8.8x).\n",
|
||||
gicv2_info.nr_lines, gic_cpus, (gic_cpus == 1) ? "" : "s",
|
||||
nr_lines, gic_cpus, (gic_cpus == 1) ? "" : "s",
|
||||
(type & GICD_TYPE_SEC) ? ", secure" : "",
|
||||
readl_gicd(GICD_IIDR));
|
||||
|
||||
/* Default all global IRQs to level, active low */
|
||||
for ( i = 32; i < gicv2_info.nr_lines; i += 16 )
|
||||
for ( i = 32; i < nr_lines; i += 16 )
|
||||
writel_gicd(0x0, GICD_ICFGR + (i / 16) * 4);
|
||||
|
||||
/* Route all global IRQs to this CPU */
|
||||
for ( i = 32; i < gicv2_info.nr_lines; i += 4 )
|
||||
for ( i = 32; i < nr_lines; i += 4 )
|
||||
writel_gicd(cpumask, GICD_ITARGETSR + (i / 4) * 4);
|
||||
|
||||
/* Default priority for global interrupts */
|
||||
for ( i = 32; i < gicv2_info.nr_lines; i += 4 )
|
||||
for ( i = 32; i < nr_lines; i += 4 )
|
||||
writel_gicd(GIC_PRI_IRQ << 24 | GIC_PRI_IRQ << 16 |
|
||||
GIC_PRI_IRQ << 8 | GIC_PRI_IRQ,
|
||||
GICD_IPRIORITYR + (i / 4) * 4);
|
||||
|
||||
/* Disable all global interrupts */
|
||||
for ( i = 32; i < gicv2_info.nr_lines; i += 32 )
|
||||
for ( i = 32; i < nr_lines; i += 32 )
|
||||
writel_gicd(~0x0, GICD_ICENABLER + (i / 32) * 4);
|
||||
|
||||
/* Only 1020 interrupts are supported */
|
||||
gicv2_info.nr_lines = min(1020U, nr_lines);
|
||||
|
||||
/* Turn on the distributor */
|
||||
writel_gicd(GICD_CTL_ENABLE, GICD_CTLR);
|
||||
}
|
||||
|
||||
+10
-6
@@ -528,23 +528,24 @@ static void __init gicv3_dist_init(void)
|
||||
uint32_t type;
|
||||
uint32_t priority;
|
||||
uint64_t affinity;
|
||||
unsigned int nr_lines;
|
||||
int i;
|
||||
|
||||
/* Disable the distributor */
|
||||
writel_relaxed(0, GICD + GICD_CTLR);
|
||||
|
||||
type = readl_relaxed(GICD + GICD_TYPER);
|
||||
gicv3_info.nr_lines = 32 * ((type & GICD_TYPE_LINES) + 1);
|
||||
nr_lines = 32 * ((type & GICD_TYPE_LINES) + 1);
|
||||
|
||||
printk("GICv3: %d lines, (IID %8.8x).\n",
|
||||
gicv3_info.nr_lines, readl_relaxed(GICD + GICD_IIDR));
|
||||
nr_lines, readl_relaxed(GICD + GICD_IIDR));
|
||||
|
||||
/* Default all global IRQs to level, active low */
|
||||
for ( i = NR_GIC_LOCAL_IRQS; i < gicv3_info.nr_lines; i += 16 )
|
||||
for ( i = NR_GIC_LOCAL_IRQS; i < nr_lines; i += 16 )
|
||||
writel_relaxed(0, GICD + GICD_ICFGR + (i / 16) * 4);
|
||||
|
||||
/* Default priority for global interrupts */
|
||||
for ( i = NR_GIC_LOCAL_IRQS; i < gicv3_info.nr_lines; i += 4 )
|
||||
for ( i = NR_GIC_LOCAL_IRQS; i < nr_lines; i += 4 )
|
||||
{
|
||||
priority = (GIC_PRI_IRQ << 24 | GIC_PRI_IRQ << 16 |
|
||||
GIC_PRI_IRQ << 8 | GIC_PRI_IRQ);
|
||||
@@ -552,7 +553,7 @@ static void __init gicv3_dist_init(void)
|
||||
}
|
||||
|
||||
/* Disable all global interrupts */
|
||||
for ( i = NR_GIC_LOCAL_IRQS; i < gicv3_info.nr_lines; i += 32 )
|
||||
for ( i = NR_GIC_LOCAL_IRQS; i < nr_lines; i += 32 )
|
||||
writel_relaxed(0xffffffff, GICD + GICD_ICENABLER + (i / 32) * 4);
|
||||
|
||||
gicv3_dist_wait_for_rwp();
|
||||
@@ -566,8 +567,11 @@ static void __init gicv3_dist_init(void)
|
||||
/* Make sure we don't broadcast the interrupt */
|
||||
affinity &= ~GICD_IROUTER_SPI_MODE_ANY;
|
||||
|
||||
for ( i = NR_GIC_LOCAL_IRQS; i < gicv3_info.nr_lines; i++ )
|
||||
for ( i = NR_GIC_LOCAL_IRQS; i < nr_lines; i++ )
|
||||
writeq_relaxed(affinity, GICD + GICD_IROUTER + i * 8);
|
||||
|
||||
/* Only 1020 interrupts are supported */
|
||||
gicv3_info.nr_lines = min(1020U, nr_lines);
|
||||
}
|
||||
|
||||
static int gicv3_enable_redist(void)
|
||||
|
||||