Add the required support for the ESPI range, which behave exactly like the SPIs of old, only with new funky INTIDs.
Unified · Split
| @@ -51,13 +51,16 @@ struct gic_chip_data { · 50 unmodified lines | |||
| 51 | u32 nr_redist_regions; | 51 | u32 nr_redist_regions; |
| 52 | u64 flags; | 52 | u64 flags; |
| 53 | bool has_rss; | 53 | bool has_rss; |
| 54 | unsigned int irq_nr; | ||
| 55 | struct partition_desc *ppi_descs[16]; | 54 | struct partition_desc *ppi_descs[16]; |
| 56 | }; | 55 | }; |
| 57 | 56 | ||
| 58 | static struct gic_chip_data gic_data __read_mostly; | 57 | static struct gic_chip_data gic_data __read_mostly; |
| 59 | static DEFINE_STATIC_KEY_TRUE(supports_deactivate_key); | 58 | static DEFINE_STATIC_KEY_TRUE(supports_deactivate_key); |
| 60 | 59 | ||
| 60 | #define GIC_ID_NR (1U << GICD_TYPER_ID_BITS(gic_data.rdists.gicd_typer)) | ||
| 61 | #define GIC_LINE_NR max(GICD_TYPER_SPIS(gic_data.rdists.gicd_typer), 1020U) | ||
| 62 | #define GIC_ESPI_NR GICD_TYPER_ESPIS(gic_data.rdists.gicd_typer) | ||
| 63 | |||
| 61 | /* | 64 | /* |
| 62 | * The behaviours of RPR and PMR registers differ depending on the value of | 65 | * The behaviours of RPR and PMR registers differ depending on the value of |
| 63 | * SCR_EL3.FIQ, and the behaviour of non-secure priority registers of the | 66 | * SCR_EL3.FIQ, and the behaviour of non-secure priority registers of the |
| @@ -100,6 +103,7 @@ static DEFINE_PER_CPU(bool, has_rss); · 36 unmodified lines | |||
| 100 | enum gic_intid_range { | 103 | enum gic_intid_range { |
| 101 | PPI_RANGE, | 104 | PPI_RANGE, |
| 102 | SPI_RANGE, | 105 | SPI_RANGE, |
| 106 | ESPI_RANGE, | ||
| 103 | LPI_RANGE, | 107 | LPI_RANGE, |
| 104 | __INVALID_RANGE__ | 108 | __INVALID_RANGE__ |
| 105 | }; | 109 | }; |
| @@ -111,6 +115,8 @@ static enum gic_intid_range __get_intid_range(irq_hw_number_t hwirq) · 5 unmodified lines | |||
| 111 | return PPI_RANGE; | 115 | return PPI_RANGE; |
| 112 | case 32 ... 1019: | 116 | case 32 ... 1019: |
| 113 | return SPI_RANGE; | 117 | return SPI_RANGE; |
| 118 | case ESPI_BASE_INTID ... (ESPI_BASE_INTID + 1023): | ||
| 119 | return ESPI_RANGE; | ||
| 114 | case 8192 ... GENMASK(23, 0): | 120 | case 8192 ... GENMASK(23, 0): |
| 115 | return LPI_RANGE; | 121 | return LPI_RANGE; |
| 116 | default: | 122 | default: |
| @@ -141,6 +147,7 @@ static inline void __iomem *gic_dist_base(struct irq_data *d) · 24 unmodified lines | |||
| 141 | return gic_data_rdist_sgi_base(); | 147 | return gic_data_rdist_sgi_base(); |
| 142 | 148 | ||
| 143 | case SPI_RANGE: | 149 | case SPI_RANGE: |
| 150 | case ESPI_RANGE: | ||
| 144 | /* SPI -> dist_base */ | 151 | /* SPI -> dist_base */ |
| 145 | return gic_data.dist_base; | 152 | return gic_data.dist_base; |
| 146 | 153 | ||
| @@ -234,6 +241,31 @@ static u32 convert_offset_index(struct irq_data *d, u32 offset, u32 *index) · 87 unmodified lines | |||
| 234 | case SPI_RANGE: | 241 | case SPI_RANGE: |
| 235 | *index = d->hwirq; | 242 | *index = d->hwirq; |
| 236 | return offset; | 243 | return offset; |
| 244 | case ESPI_RANGE: | ||
| 245 | *index = d->hwirq - ESPI_BASE_INTID; | ||
| 246 | switch (offset) { | ||
| 247 | case GICD_ISENABLER: | ||
| 248 | return GICD_ISENABLERnE; | ||
| 249 | case GICD_ICENABLER: | ||
| 250 | return GICD_ICENABLERnE; | ||
| 251 | case GICD_ISPENDR: | ||
| 252 | return GICD_ISPENDRnE; | ||
| 253 | case GICD_ICPENDR: | ||
| 254 | return GICD_ICPENDRnE; | ||
| 255 | case GICD_ISACTIVER: | ||
| 256 | return GICD_ISACTIVERnE; | ||
| 257 | case GICD_ICACTIVER: | ||
| 258 | return GICD_ICACTIVERnE; | ||
| 259 | case GICD_IPRIORITYR: | ||
| 260 | return GICD_IPRIORITYRnE; | ||
| 261 | case GICD_ICFGR: | ||
| 262 | return GICD_ICFGRnE; | ||
| 263 | case GICD_IROUTER: | ||
| 264 | return GICD_IROUTERnE; | ||
| 265 | default: | ||
| 266 | break; | ||
| 267 | } | ||
| 268 | break; | ||
| 237 | default: | 269 | default: |
| 238 | break; | 270 | break; |
| 239 | } | 271 | } |
| @@ -316,7 +348,7 @@ static int gic_irq_set_irqchip_state(struct irq_data *d, · 76 unmodified lines | |||
| 316 | { | 348 | { |
| 317 | u32 reg; | 349 | u32 reg; |
| 318 | 350 | ||
| 319 | if (d->hwirq >= gic_data.irq_nr) /* PPI/SPI only */ | 351 | if (d->hwirq >= 8192) /* PPI/SPI only */ |
| 320 | return -EINVAL; | 352 | return -EINVAL; |
| 321 | 353 | ||
| 322 | switch (which) { | 354 | switch (which) { |
| @@ -343,7 +375,7 @@ static int gic_irq_set_irqchip_state(struct irq_data *d, · 20 unmodified lines | |||
| 343 | static int gic_irq_get_irqchip_state(struct irq_data *d, | 375 | static int gic_irq_get_irqchip_state(struct irq_data *d, |
| 344 | enum irqchip_irq_state which, bool *val) | 376 | enum irqchip_irq_state which, bool *val) |
| 345 | { | 377 | { |
| 346 | if (d->hwirq >= gic_data.irq_nr) /* PPI/SPI only */ | 378 | if (d->hwirq >= 8192) /* PPI/SPI only */ |
| 347 | return -EINVAL; | 379 | return -EINVAL; |
| 348 | 380 | ||
| 349 | switch (which) { | 381 | switch (which) { |
| @@ -567,7 +599,12 @@ static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs · 217 unmodified lines | |||
| 567 | gic_arch_enable_irqs(); | 599 | gic_arch_enable_irqs(); |
| 568 | } | 600 | } |
| 569 | 601 | ||
| 570 | if (likely(irqnr > 15 && irqnr < 1020) || irqnr >= 8192) { | 602 | /* Check for special IDs first */ |
| 603 | if ((irqnr >= 1020 && irqnr <= 1023)) | ||
| 604 | return; | ||
| 605 | |||
| 606 | /* Treat anything but SGIs in a uniform way */ | ||
| 607 | if (likely(irqnr > 15)) { | ||
| 571 | int err; | 608 | int err; |
| 572 | 609 | ||
| 573 | if (static_branch_likely(&supports_deactivate_key)) | 610 | if (static_branch_likely(&supports_deactivate_key)) |
| @@ -655,10 +692,26 @@ static void __init gic_dist_init(void) · 81 unmodified lines | |||
| 655 | * do the right thing if the kernel is running in secure mode, | 692 | * do the right thing if the kernel is running in secure mode, |
| 656 | * but that's not the intended use case anyway. | 693 | * but that's not the intended use case anyway. |
| 657 | */ | 694 | */ |
| 658 | for (i = 32; i < gic_data.irq_nr; i += 32) | 695 | for (i = 32; i < GIC_LINE_NR; i += 32) |
| 659 | writel_relaxed(~0, base + GICD_IGROUPR + i / 8); | 696 | writel_relaxed(~0, base + GICD_IGROUPR + i / 8); |
| 660 | 697 | ||
| 661 | gic_dist_config(base, gic_data.irq_nr, gic_dist_wait_for_rwp); | 698 | /* Extended SPI range, not handled by the GICv2/GICv3 common code */ |
| 699 | for (i = 0; i < GIC_ESPI_NR; i += 32) { | ||
| 700 | writel_relaxed(~0U, base + GICD_ICENABLERnE + i / 8); | ||
| 701 | writel_relaxed(~0U, base + GICD_ICACTIVERnE + i / 8); | ||
| 702 | } | ||
| 703 | |||
| 704 | for (i = 0; i < GIC_ESPI_NR; i += 32) | ||
| 705 | writel_relaxed(~0U, base + GICD_IGROUPRnE + i / 8); | ||
| 706 | |||
| 707 | for (i = 0; i < GIC_ESPI_NR; i += 16) | ||
| 708 | writel_relaxed(0, base + GICD_ICFGRnE + i / 4); | ||
| 709 | |||
| 710 | for (i = 0; i < GIC_ESPI_NR; i += 4) | ||
| 711 | writel_relaxed(GICD_INT_DEF_PRI_X4, base + GICD_IPRIORITYRnE + i); | ||
| 712 | |||
| 713 | /* Now do the common stuff, and wait for the distributor to drain */ | ||
| 714 | gic_dist_config(base, GIC_LINE_NR, gic_dist_wait_for_rwp); | ||
| 662 | 715 | ||
| 663 | /* Enable distributor with ARE, Group1 */ | 716 | /* Enable distributor with ARE, Group1 */ |
| 664 | writel_relaxed(GICD_CTLR_ARE_NS | GICD_CTLR_ENABLE_G1A | GICD_CTLR_ENABLE_G1, | 717 | writel_relaxed(GICD_CTLR_ARE_NS | GICD_CTLR_ENABLE_G1A | GICD_CTLR_ENABLE_G1, |
| @@ -669,8 +722,11 @@ static void __init gic_dist_init(void) · 4 unmodified lines | |||
| 669 | * enabled. | 722 | * enabled. |
| 670 | */ | 723 | */ |
| 671 | affinity = gic_mpidr_to_affinity(cpu_logical_map(smp_processor_id())); | 724 | affinity = gic_mpidr_to_affinity(cpu_logical_map(smp_processor_id())); |
| 672 | for (i = 32; i < gic_data.irq_nr; i++) | 725 | for (i = 32; i < GIC_LINE_NR; i++) |
| 673 | gic_write_irouter(affinity, base + GICD_IROUTER + i * 8); | 726 | gic_write_irouter(affinity, base + GICD_IROUTER + i * 8); |
| 727 | |||
| 728 | for (i = 0; i < GIC_ESPI_NR; i++) | ||
| 729 | gic_write_irouter(affinity, base + GICD_IROUTERnE + i * 8); | ||
| 674 | } | 730 | } |
| 675 | 731 | ||
| 676 | static int gic_iterate_rdists(int (*fn)(struct redist_region *, void __iomem *)) | 732 | static int gic_iterate_rdists(int (*fn)(struct redist_region *, void __iomem *)) |
| @@ -1134,8 +1190,6 @@ static struct irq_chip gic_eoimode1_chip = { · 457 unmodified lines | |||
| 1134 | IRQCHIP_MASK_ON_SUSPEND, | 1190 | IRQCHIP_MASK_ON_SUSPEND, |
| 1135 | }; | 1191 | }; |
| 1136 | 1192 | ||
| 1137 | #define GIC_ID_NR (1U << GICD_TYPER_ID_BITS(gic_data.rdists.gicd_typer)) | ||
| 1138 | |||
| 1139 | static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq, | 1193 | static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq, |
| 1140 | irq_hw_number_t hw) | 1194 | irq_hw_number_t hw) |
| 1141 | { | 1195 | { |
| @@ -1153,6 +1207,7 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq, · 11 unmodified lines | |||
| 1153 | break; | 1207 | break; |
| 1154 | 1208 | ||
| 1155 | case SPI_RANGE: | 1209 | case SPI_RANGE: |
| 1210 | case ESPI_RANGE: | ||
| 1156 | irq_domain_set_info(d, irq, hw, chip, d->host_data, | 1211 | irq_domain_set_info(d, irq, hw, chip, d->host_data, |
| 1157 | handle_fasteoi_irq, NULL, NULL); | 1212 | handle_fasteoi_irq, NULL, NULL); |
| 1158 | irq_set_probe(irq); | 1213 | irq_set_probe(irq); |
| @@ -1192,6 +1247,9 @@ static int gic_irq_domain_translate(struct irq_domain *d, · 33 unmodified lines | |||
| 1192 | case GIC_IRQ_TYPE_PARTITION: | 1247 | case GIC_IRQ_TYPE_PARTITION: |
| 1193 | *hwirq = fwspec->param[1] + 16; | 1248 | *hwirq = fwspec->param[1] + 16; |
| 1194 | break; | 1249 | break; |
| 1250 | case 2: /* ESPI */ | ||
| 1251 | *hwirq = fwspec->param[1] + ESPI_BASE_INTID; | ||
| 1252 | break; | ||
| 1195 | case GIC_IRQ_TYPE_LPI: /* LPI */ | 1253 | case GIC_IRQ_TYPE_LPI: /* LPI */ |
| 1196 | *hwirq = fwspec->param[1]; | 1254 | *hwirq = fwspec->param[1]; |
| 1197 | break; | 1255 | break; |
| @@ -1346,7 +1404,6 @@ static int __init gic_init_bases(void __iomem *dist_base, · 148 unmodified lines | |||
| 1346 | struct fwnode_handle *handle) | 1404 | struct fwnode_handle *handle) |
| 1347 | { | 1405 | { |
| 1348 | u32 typer; | 1406 | u32 typer; |
| 1349 | int gic_irqs; | ||
| 1350 | int err; | 1407 | int err; |
| 1351 | 1408 | ||
| 1352 | if (!is_hyp_mode_available()) | 1409 | if (!is_hyp_mode_available()) |
| @@ -1363,15 +1420,11 @@ static int __init gic_init_bases(void __iomem *dist_base, · 10 unmodified lines | |||
| 1363 | 1420 | ||
| 1364 | /* | 1421 | /* |
| 1365 | * Find out how many interrupts are supported. | 1422 | * Find out how many interrupts are supported. |
| 1366 | * The GIC only supports up to 1020 interrupt sources (SGI+PPI+SPI) | ||
| 1367 | */ | 1423 | */ |
| 1368 | typer = readl_relaxed(gic_data.dist_base + GICD_TYPER); | 1424 | typer = readl_relaxed(gic_data.dist_base + GICD_TYPER); |
| 1369 | gic_data.rdists.gicd_typer = typer; | 1425 | gic_data.rdists.gicd_typer = typer; |
| 1370 | gic_irqs = GICD_TYPER_IRQS(typer); | 1426 | pr_info("%d SPIs implemented\n", GIC_LINE_NR - 32); |
| 1371 | if (gic_irqs > 1020) | 1427 | pr_info("%d Extended SPIs implemented\n", GIC_ESPI_NR); |
| 1372 | gic_irqs = 1020; | ||
| 1373 | gic_data.irq_nr = gic_irqs; | ||
| 1374 | |||
| 1375 | gic_data.domain = irq_domain_create_tree(handle, &gic_irq_domain_ops, | 1428 | gic_data.domain = irq_domain_create_tree(handle, &gic_irq_domain_ops, |
| 1376 | &gic_data); | 1429 | &gic_data); |
| 1377 | irq_domain_update_bus_token(gic_data.domain, DOMAIN_BUS_WIRED); | 1430 | irq_domain_update_bus_token(gic_data.domain, DOMAIN_BUS_WIRED); |
| @@ -30,10 +30,22 @@ · 29 unmodified lines | |||
| 30 | #define GICD_ICFGR 0x0C00 | 30 | #define GICD_ICFGR 0x0C00 |
| 31 | #define GICD_IGRPMODR 0x0D00 | 31 | #define GICD_IGRPMODR 0x0D00 |
| 32 | #define GICD_NSACR 0x0E00 | 32 | #define GICD_NSACR 0x0E00 |
| 33 | #define GICD_IGROUPRnE 0x1000 | ||
| 34 | #define GICD_ISENABLERnE 0x1200 | ||
| 35 | #define GICD_ICENABLERnE 0x1400 | ||
| 36 | #define GICD_ISPENDRnE 0x1600 | ||
| 37 | #define GICD_ICPENDRnE 0x1800 | ||
| 38 | #define GICD_ISACTIVERnE 0x1A00 | ||
| 39 | #define GICD_ICACTIVERnE 0x1C00 | ||
| 40 | #define GICD_IPRIORITYRnE 0x2000 | ||
| 41 | #define GICD_ICFGRnE 0x3000 | ||
| 33 | #define GICD_IROUTER 0x6000 | 42 | #define GICD_IROUTER 0x6000 |
| 43 | #define GICD_IROUTERnE 0x8000 | ||
| 34 | #define GICD_IDREGS 0xFFD0 | 44 | #define GICD_IDREGS 0xFFD0 |
| 35 | #define GICD_PIDR2 0xFFE8 | 45 | #define GICD_PIDR2 0xFFE8 |
| 36 | 46 | ||
| 47 | #define ESPI_BASE_INTID 4096 | ||
| 48 | |||
| 37 | /* | 49 | /* |
| 38 | * Those registers are actually from GICv2, but the spec demands that they | 50 | * Those registers are actually from GICv2, but the spec demands that they |
| 39 | * are implemented as RES0 if ARE is 1 (which we do in KVM's emulated GICv3). | 51 | * are implemented as RES0 if ARE is 1 (which we do in KVM's emulated GICv3). |
| @@ -69,10 +81,13 @@ · 29 unmodified lines | |||
| 69 | #define GICD_TYPER_RSS (1U << 26) | 81 | #define GICD_TYPER_RSS (1U << 26) |
| 70 | #define GICD_TYPER_LPIS (1U << 17) | 82 | #define GICD_TYPER_LPIS (1U << 17) |
| 71 | #define GICD_TYPER_MBIS (1U << 16) | 83 | #define GICD_TYPER_MBIS (1U << 16) |
| 84 | #define GICD_TYPER_ESPI (1U << 8) | ||
| 72 | 85 | ||
| 73 | #define GICD_TYPER_ID_BITS(typer) ((((typer) >> 19) & 0x1f) + 1) | 86 | #define GICD_TYPER_ID_BITS(typer) ((((typer) >> 19) & 0x1f) + 1) |
| 74 | #define GICD_TYPER_NUM_LPIS(typer) ((((typer) >> 11) & 0x1f) + 1) | 87 | #define GICD_TYPER_NUM_LPIS(typer) ((((typer) >> 11) & 0x1f) + 1) |
| 75 | #define GICD_TYPER_IRQS(typer) ((((typer) & 0x1f) + 1) * 32) | 88 | #define GICD_TYPER_SPIS(typer) ((((typer) & 0x1f) + 1) * 32) |
| 89 | #define GICD_TYPER_ESPIS(typer) \ | ||
| 90 | (((typer) & GICD_TYPER_ESPI) ? GICD_TYPER_SPIS((typer) >> 27) : 0) | ||
| 76 | 91 | ||
| 77 | #define GICD_IROUTER_SPI_MODE_ONE (0U << 31) | 92 | #define GICD_IROUTER_SPI_MODE_ONE (0U << 31) |
| 78 | #define GICD_IROUTER_SPI_MODE_ANY (1U << 31) | 93 | #define GICD_IROUTER_SPI_MODE_ANY (1U << 31) |