aboutsummaryrefslogtreecommitdiff
path: root/dev/interrupt/arm_gic/arm_gic.c
diff options
context:
space:
mode:
Diffstat (limited to 'dev/interrupt/arm_gic/arm_gic.c')
-rw-r--r--dev/interrupt/arm_gic/arm_gic.c25
1 files changed, 13 insertions, 12 deletions
diff --git a/dev/interrupt/arm_gic/arm_gic.c b/dev/interrupt/arm_gic/arm_gic.c
index ba29ad17..c38decff 100644
--- a/dev/interrupt/arm_gic/arm_gic.c
+++ b/dev/interrupt/arm_gic/arm_gic.c
@@ -388,15 +388,20 @@ static status_t arm_gic_set_priority_locked(u_int irq, uint8_t priority)
status_t arm_gic_sgi(u_int irq, u_int flags, u_int cpu_mask)
{
+ if (irq >= 16) {
+ return ERR_INVALID_ARGS;
+ }
+
#if GIC_VERSION > 2
- /* This assumes that all CPUs are in the same cluster */
- u_int val = ((irq & 0xf) << 24) | (cpu_mask & 0xffff);
+ for (size_t cpu = 0; cpu < SMP_MAX_CPUS; cpu++) {
+ if (!((cpu_mask >> cpu) & 1)) {
+ continue;
+ }
- if (irq >= (1U << 16))
- return ERR_INVALID_ARGS;
+ uint64_t val = arm_gicv3_sgir_val(irq, cpu);
- LTRACEF("GICC_PRIMARY_SGIR: %x\n", val);
- GICCREG_WRITE(0, GICC_PRIMARY_SGIR, val);
+ GICCREG_WRITE(0, GICC_PRIMARY_SGIR, val);
+ }
#else /* else GIC_VERSION > 2 */
@@ -406,9 +411,6 @@ status_t arm_gic_sgi(u_int irq, u_int flags, u_int cpu_mask)
((flags & ARM_GIC_SGI_FLAG_NS) ? (1U << 15) : 0) |
(irq & 0xf);
- if (irq >= 16)
- return ERR_INVALID_ARGS;
-
LTRACEF("GICD_SGIR: %x\n", val);
GICDREG_WRITE(0, GICD_SGIR, val);
@@ -695,13 +697,12 @@ status_t sm_intc_fiq_enter(void)
if (irq >= 1020) {
#if ARM_GIC_USE_DOORBELL_NS_IRQ
uint cpu = arch_curr_cpu_num();
- uint cpu_mask = 1U << cpu;
- u_int val = (ARM_GIC_DOORBELL_IRQ << 24) | (cpu_mask & 0xffff);
+ uint64_t val = arm_gicv3_sgir_val(ARM_GIC_DOORBELL_IRQ, cpu);
GICCREG_WRITE(0, icc_igrpen1_el1, 0); /* Disable secure Group 1 */
if (doorbell_enabled) {
- LTRACEF("GICD_SGIR: %x\n", val);
+ LTRACEF("GICD_SGIR: %llx\n", val);
GICCREG_WRITE(0, icc_asgi1r_el1, val);
}
#else