From: Michalis Pappas Date: Thu, 14 Sep 2023 10:07:58 +0000 (+0200) Subject: drivers/ukintctlr/gic: Define the maximum assignable IRQ number X-Git-Tag: RELEASE-0.15.0~54 X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=2dc9b161470c595d2c4bc779892973059c77be47;p=unikraft%2Funikraft.git drivers/ukintctlr/gic: Define the maximum assignable IRQ number Add `uk/intctlr/limits.h` with the maximum assignable IRQ value for GIC. Update GIC_IRQ_MAX to define the maximum assignable INTID so that it's consistent with the uk_intctlr API. Notice: Picking individual commits in this PR will break the build. Signed-off-by: Michalis Pappas Reviewed-by: Marco Schlumpp Reviewed-by: Sergiu Moga Approved-by: Razvan Deaconescu GitHub-Closes: #1103 --- diff --git a/drivers/ukintctlr/gic/gic-v2.c b/drivers/ukintctlr/gic/gic-v2.c index 595984f1b..e6278e761 100644 --- a/drivers/ukintctlr/gic/gic-v2.c +++ b/drivers/ukintctlr/gic/gic-v2.c @@ -47,11 +47,14 @@ #include #include #include +#include #include /* Max CPU interface for GICv2 */ #define GIC_MAX_CPUIF 8 +#define GIC_MAX_IRQ UK_INTCTLR_MAX_IRQ + #define GIC_CPU_REG(gdev, r) ((void *)(gdev.cpuif_mem_addr + (r))) #ifdef CONFIG_HAVE_SMP @@ -237,13 +240,13 @@ void gicv2_sgi_gen_to_self(uint32_t sgintid) /** * Set target CPU for an interrupt * - * @param irq interrupt number [GIC_SPI_BASE..GIC_MAX_IRQ-1] + * @param irq interrupt number [GIC_SPI_BASE..GIC_MAX_IRQ] * @param targetlist an 8-bit bitmap with 1 bit per CPU 0-7. A `1` bit * indicates that the SGI should be forwarded to the respective CPU */ static void gicv2_set_irq_target(uint32_t irq, uint32_t targetlist) { - UK_ASSERT(irq >= GIC_SPI_BASE && irq < GIC_MAX_IRQ); + UK_ASSERT(irq >= GIC_SPI_BASE && irq <= GIC_MAX_IRQ); UK_ASSERT(targetlist <= __U8_MAX); dist_lock(gicv2_drv); @@ -254,7 +257,7 @@ static void gicv2_set_irq_target(uint32_t irq, uint32_t targetlist) /** * Set priority for an interrupt * - * @param irq interrupt number [0..GIC_MAX_IRQ-1] + * @param irq interrupt number [0..GIC_MAX_IRQ] * @param priority priority [0..255]. The GIC implementation may not support * all levels. For example, if only 128 levels are supported every two levels * (e.g., 0 and 1) map to the same effective value. Lower values correspond @@ -262,7 +265,7 @@ static void gicv2_set_irq_target(uint32_t irq, uint32_t targetlist) */ static void gicv2_set_irq_prio(uint32_t irq, uint8_t priority) { - UK_ASSERT(irq < GIC_MAX_IRQ); + UK_ASSERT(irq <= GIC_MAX_IRQ); dist_lock(gicv2_drv); write_gicd8(GICD_IPRIORITYR(irq), priority); @@ -272,11 +275,11 @@ static void gicv2_set_irq_prio(uint32_t irq, uint8_t priority) /** * Enable an interrupt * - * @param irq interrupt number [0..GIC_MAX_IRQ-1] + * @param irq interrupt number [0..GIC_MAX_IRQ] */ static void gicv2_enable_irq(uint32_t irq) { - UK_ASSERT(irq < GIC_MAX_IRQ); + UK_ASSERT(irq <= GIC_MAX_IRQ); dist_lock(gicv2_drv); write_gicd32(GICD_ISENABLER(irq), UK_BIT(irq % GICD_I_PER_ISENABLERn)); @@ -286,11 +289,11 @@ static void gicv2_enable_irq(uint32_t irq) /** * Disable an interrupt * - * @param irq interrupt number [0..GIC_MAX_IRQ-1] + * @param irq interrupt number [0..GIC_MAX_IRQ] */ static void gicv2_disable_irq(uint32_t irq) { - UK_ASSERT(irq < GIC_MAX_IRQ); + UK_ASSERT(irq <= GIC_MAX_IRQ); dist_lock(gicv2_drv); write_gicd32(GICD_ICENABLER(irq), UK_BIT(irq % GICD_I_PER_ICENABLERn)); @@ -319,7 +322,7 @@ static void gicv2_disable_dist(void) /** * Config trigger type for an interrupt * - * @param irq interrupt number [GIC_PPI_BASE..GIC_MAX_IRQ-1] + * @param irq interrupt number [GIC_PPI_BASE..GIC_MAX_IRQ] * @param trigger trigger type (UK_INTCTLR_IRQ_TRIGGER_*) */ static @@ -327,7 +330,7 @@ void gicv2_set_irq_trigger(uint32_t irq, enum uk_intctlr_irq_trigger trigger) { uint32_t val, mask, oldmask; - UK_ASSERT(irq >= GIC_PPI_BASE && irq < GIC_MAX_IRQ); + UK_ASSERT(irq >= GIC_PPI_BASE && irq <= GIC_MAX_IRQ); UK_ASSERT(trigger == UK_INTCTLR_IRQ_TRIGGER_EDGE || trigger == UK_INTCTLR_IRQ_TRIGGER_LEVEL); @@ -376,7 +379,7 @@ static void gicv2_handle_irq(struct __regs *regs) /* Ensure interrupt processing starts only after ACK */ isb(); - if (irq < GIC_MAX_IRQ) { + if (irq <= GIC_MAX_IRQ) { uk_intctlr_irq_handle(regs, irq); gicv2_eoi_irq(stat); continue; @@ -408,7 +411,7 @@ static void gicv2_init_dist(void) /* Get the maximum number of interrupts that the GIC supports */ irq_number = GICD_TYPER_LINE_NUM(val); if (irq_number > GIC_MAX_IRQ) - irq_number = GIC_MAX_IRQ; + irq_number = GIC_MAX_IRQ + 1; uk_pr_info("GICv2 Max interrupt lines:%d\n", irq_number); /* Set all SPI's interrupt target to all CPUs */ diff --git a/drivers/ukintctlr/gic/gic-v3.c b/drivers/ukintctlr/gic/gic-v3.c index 092c56359..7dc092ccf 100644 --- a/drivers/ukintctlr/gic/gic-v3.c +++ b/drivers/ukintctlr/gic/gic-v3.c @@ -53,8 +53,11 @@ #include #include #include +#include #include +#define GIC_MAX_IRQ UK_INTCTLR_MAX_IRQ + #define GIC_RDIST_REG(gdev, r) \ ((void *)(gdev.rdist_mem_addr + (r) + \ lcpu_get_current()->idx * GICR_STRIDE)) @@ -192,11 +195,11 @@ static void gicv3_eoi_irq(uint32_t irq) /** * Enable an interrupt * - * @param irq interrupt number [0..GIC_MAX_IRQ-1] + * @param irq interrupt number [0..GIC_MAX_IRQ] */ static void gicv3_enable_irq(uint32_t irq) { - UK_ASSERT(irq < GIC_MAX_IRQ); + UK_ASSERT(irq <= GIC_MAX_IRQ); dist_lock(gicv3_drv); @@ -274,11 +277,11 @@ static void gicv3_sgi_gen(uint8_t sgintid, uint32_t cpuid) /** * Disable an interrupt * - * @param irq interrupt number [0..GIC_MAX_IRQ-1] + * @param irq interrupt number [0..GIC_MAX_IRQ] */ static void gicv3_disable_irq(uint32_t irq) { - UK_ASSERT(irq < GIC_MAX_IRQ); + UK_ASSERT(irq <= GIC_MAX_IRQ); dist_lock(gicv3_drv); @@ -295,13 +298,13 @@ static void gicv3_disable_irq(uint32_t irq) /** * Set interrupt affinity * - * @param irq interrupt number [GIC_SPI_BASE..GIC_MAX_IRQ-1] + * @param irq interrupt number [GIC_SPI_BASE..GIC_MAX_IRQ] * @param affinity target CPU affinity in 32 bits format * (AFF3|AFF2|AFF1|AFF0), as returned by get_cpu_affinity() */ static void gicv3_set_irq_affinity(uint32_t irq, uint32_t affinity) { - UK_ASSERT(irq >= GIC_SPI_BASE && irq < GIC_MAX_IRQ); + UK_ASSERT(irq >= GIC_SPI_BASE && irq <= GIC_MAX_IRQ); dist_lock(gicv3_drv); write_gicd64(GICD_IROUTER(irq), GIC_AFF_TO_ROUTER(affinity, 0)); @@ -311,7 +314,7 @@ static void gicv3_set_irq_affinity(uint32_t irq, uint32_t affinity) /** * Set priority for an interrupt * - * @param irq interrupt number [0..GIC_MAX_IRQ-1] + * @param irq interrupt number [0..GIC_MAX_IRQ] * @param priority priority [0..255]. The GIC implementation may not support * all levels. For example, if only 128 levels are supported every two levels * (e.g., 0 and 1) map to the same effective value. Lower values correspond @@ -332,7 +335,7 @@ static void gicv3_set_irq_prio(uint32_t irq, uint8_t priority) /** * Configure trigger type for an interrupt * - * @param irq interrupt number [GIC_PPI_BASE..GIC_MAX_IRQ-1] + * @param irq interrupt number [GIC_PPI_BASE..GIC_MAX_IRQ] * @param trigger trigger type (UK_INTCTLR_IRQ_TRIGGER_*) */ static @@ -340,7 +343,7 @@ void gicv3_set_irq_trigger(uint32_t irq, enum uk_intctlr_irq_trigger trigger) { uint32_t val, mask, oldmask; - UK_ASSERT(irq >= GIC_PPI_BASE && irq < GIC_MAX_IRQ); + UK_ASSERT(irq >= GIC_PPI_BASE && irq <= GIC_MAX_IRQ); UK_ASSERT(trigger == UK_INTCTLR_IRQ_TRIGGER_EDGE || trigger == UK_INTCTLR_IRQ_TRIGGER_LEVEL); @@ -461,7 +464,7 @@ static void gicv3_init_dist(void) val = read_gicd32(GICD_TYPER); irq_number = GICD_TYPER_LINE_NUM(val); if (irq_number > GIC_MAX_IRQ) - irq_number = GIC_MAX_IRQ; + irq_number = GIC_MAX_IRQ + 1; uk_pr_info("GICv3 Max interrupt lines: %d\n", irq_number); /* Check for LPI support */ @@ -522,10 +525,9 @@ static void gicv3_handle_irq(struct __regs *regs) /* Ensure interrupt processing starts only after ACK */ isb(); - if (irq < GIC_MAX_IRQ) { + if (irq <= GIC_MAX_IRQ) { uk_intctlr_irq_handle(regs, irq); gicv3_eoi_irq(stat); - continue; } diff --git a/drivers/ukintctlr/gic/include/uk/intctlr/gic.h b/drivers/ukintctlr/gic/include/uk/intctlr/gic.h index a0659f0be..6c7591a8d 100644 --- a/drivers/ukintctlr/gic/include/uk/intctlr/gic.h +++ b/drivers/ukintctlr/gic/include/uk/intctlr/gic.h @@ -43,13 +43,6 @@ #define GIC_PPI_TYPE 1 #define GIC_PPI_BASE 16 -/** - * Max supported interrupt number for GIC - * Interrupts 1020-1023 are reserved for special purposes, with 1023 being the - * spurious interrupt - */ -#define GIC_MAX_IRQ __MAX_IRQ - /** Distributor register address */ #define GIC_DIST_REG(gdev, r) ((void *)(gdev.dist_mem_addr + (r))) diff --git a/drivers/ukintctlr/gic/include/uk/intctlr/limits.h b/drivers/ukintctlr/gic/include/uk/intctlr/limits.h new file mode 100644 index 000000000..a145f7063 --- /dev/null +++ b/drivers/ukintctlr/gic/include/uk/intctlr/limits.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright (c) 2023, Unikraft GmbH and The Unikraft Authors. + * Licensed under the BSD-3-Clause License (the "License"). + * You may not use this file except in compliance with the License. + */ + +#ifndef __UK_INTCTLR_GIC_LIMITS__H__ +#define __UK_INTCTLR_GIC_LIMITS__H__ + +/** + * Max usable INTID for GIC. INTIDs 1020 - 1023 are reseverd. + */ +#define UK_INTCTLR_MAX_IRQ 1019 + +#endif /* __UK_INTCTLR_LIMITS_H__ */ diff --git a/drivers/ukintctlr/gic/ukintctlr.c b/drivers/ukintctlr/gic/ukintctlr.c index 584d6c83b..9675799d9 100644 --- a/drivers/ukintctlr/gic/ukintctlr.c +++ b/drivers/ukintctlr/gic/ukintctlr.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -46,7 +47,7 @@ static int fdt_xlat(const void *fdt, int nodeoffset, __u32 index, switch (type) { case GIC_SPI_TYPE: - UK_ASSERT((irq_num + GIC_SPI_BASE) <= UK_INTCTLR_GIC_MAX_IRQ); + UK_ASSERT((irq_num + GIC_SPI_BASE) <= UK_INTCTLR_MAX_IRQ); irq->id = irq_num + GIC_SPI_BASE; break; case GIC_PPI_TYPE: