Module Name: src Committed By: jmcneill Date: Thu Jul 16 21:33:50 UTC 2020
Modified Files: src/sys/arch/mips/cavium: octeon_intr.c octeonvar.h Log Message: Support 128 IRQs instead of 64. This is icky and needs to be cleaned up. To generate a diff of this commit: cvs rdiff -u -r1.14 -r1.15 src/sys/arch/mips/cavium/octeon_intr.c cvs rdiff -u -r1.13 -r1.14 src/sys/arch/mips/cavium/octeonvar.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/mips/cavium/octeon_intr.c diff -u src/sys/arch/mips/cavium/octeon_intr.c:1.14 src/sys/arch/mips/cavium/octeon_intr.c:1.15 --- src/sys/arch/mips/cavium/octeon_intr.c:1.14 Tue Jun 23 05:14:39 2020 +++ src/sys/arch/mips/cavium/octeon_intr.c Thu Jul 16 21:33:50 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: octeon_intr.c,v 1.14 2020/06/23 05:14:39 simonb Exp $ */ +/* $NetBSD: octeon_intr.c,v 1.15 2020/07/16 21:33:50 jmcneill Exp $ */ /* * Copyright 2001, 2002 Wasabi Systems, Inc. * All rights reserved. @@ -44,7 +44,7 @@ #define __INTR_PRIVATE #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: octeon_intr.c,v 1.14 2020/06/23 05:14:39 simonb Exp $"); +__KERNEL_RCSID(0, "$NetBSD: octeon_intr.c,v 1.15 2020/07/16 21:33:50 jmcneill Exp $"); #include <sys/param.h> #include <sys/cpu.h> @@ -80,7 +80,7 @@ static const struct ipl_sr_map octeon_ip }, }; -const char * const octeon_intrnames[NIRQS] = { +const char * octeon_intrnames[NIRQS] = { "workq 0", "workq 1", "workq 2", @@ -191,6 +191,8 @@ struct cpu_softc octeon_cpu0_softc = { .cpu_int1_sum0 = X(CIU_INT1_SUM0), .cpu_int2_sum0 = X(CIU_INT4_SUM0), + .cpu_int_sum1 = X(CIU_INT_SUM1), + .cpu_int0_en0 = X(CIU_INT0_EN0), .cpu_int1_en0 = X(CIU_INT1_EN0), .cpu_int2_en0 = X(CIU_INT4_EN00), @@ -217,6 +219,8 @@ struct cpu_softc octeon_cpu1_softc = { .cpu_int1_sum0 = X(CIU_INT3_SUM0), .cpu_int2_sum0 = X(CIU_INT4_SUM1), + .cpu_int_sum1 = X(CIU_INT_SUM1), + .cpu_int0_en0 = X(CIU_INT2_EN0), .cpu_int1_en0 = X(CIU_INT3_EN0), .cpu_int2_en0 = X(CIU_INT4_EN10), @@ -344,15 +348,17 @@ octeon_intr_init(struct cpu_info *ci) mips3_sd(cpu->cpu_int32_en, 0); - mips3_sd(cpu->cpu_int0_en1, 0); // WDOG IPL2 - mips3_sd(cpu->cpu_int1_en1, 0); // WDOG IPL3 - mips3_sd(cpu->cpu_int2_en1, 0); // WDOG IPL4 + mips3_sd(cpu->cpu_int0_en1, cpu->cpu_int0_enable1); + mips3_sd(cpu->cpu_int1_en1, cpu->cpu_int1_enable1); + mips3_sd(cpu->cpu_int2_en1, cpu->cpu_int2_enable1); #ifdef MULTIPROCESSOR mips3_sd(cpu->cpu_mbox_clr, __BITS(31,0)); #endif - for (size_t i = 0; i < NIRQS; i++) { + for (int i = 0; i < NIRQS; i++) { + if (octeon_intrnames[i] == NULL) + octeon_intrnames[i] = kmem_asprintf("irq %d", i); evcnt_attach_dynamic(&cpu->cpu_intr_evs[i], EVCNT_TYPE_INTR, NULL, xname, octeon_intrnames[i]); } @@ -411,7 +417,8 @@ octeon_intr_establish(int irq, int ipl, /* * Now enable it. */ - const uint64_t irq_mask = __BIT(irq); + const int bank = irq / 64; + const uint64_t irq_mask = __BIT(irq % 64); struct cpu_softc * const cpu0 = &octeon_cpu0_softc; #if MULTIPROCESSOR struct cpu_softc * const cpu1 = &octeon_cpu1_softc; @@ -419,27 +426,51 @@ octeon_intr_establish(int irq, int ipl, switch (ipl) { case IPL_VM: - cpu0->cpu_int0_enable0 |= irq_mask; - mips3_sd(cpu0->cpu_int0_en0, cpu0->cpu_int0_enable0); + if (bank == 0) { + cpu0->cpu_int0_enable0 |= irq_mask; + mips3_sd(cpu0->cpu_int0_en0, cpu0->cpu_int0_enable0); + } else { + cpu0->cpu_int0_enable1 |= irq_mask; + mips3_sd(cpu0->cpu_int0_en1, cpu0->cpu_int0_enable1); + } break; case IPL_SCHED: - cpu0->cpu_int1_enable0 |= irq_mask; - mips3_sd(cpu0->cpu_int1_en0, cpu0->cpu_int1_enable0); + if (bank == 0) { + cpu0->cpu_int1_enable0 |= irq_mask; + mips3_sd(cpu0->cpu_int1_en0, cpu0->cpu_int1_enable0); +#ifdef MULTIPROCESSOR + cpu1->cpu_int1_enable0 = cpu0->cpu_int1_enable0; + mips3_sd(cpu1->cpu_int1_en0, cpu1->cpu_int1_enable0); +#endif + } else { + cpu0->cpu_int1_enable1 |= irq_mask; + mips3_sd(cpu0->cpu_int1_en1, cpu0->cpu_int1_enable1); #ifdef MULTIPROCESSOR - cpu1->cpu_int1_enable0 = cpu0->cpu_int1_enable0; - mips3_sd(cpu1->cpu_int1_en0, cpu1->cpu_int1_enable0); + cpu1->cpu_int1_enable1 = cpu0->cpu_int1_enable1; + mips3_sd(cpu1->cpu_int1_en1, cpu1->cpu_int1_enable1); #endif + } + break; case IPL_DDB: case IPL_HIGH: - cpu0->cpu_int2_enable0 |= irq_mask; - mips3_sd(cpu0->cpu_int2_en0, cpu0->cpu_int2_enable0); + if (bank == 0) { + cpu0->cpu_int2_enable0 |= irq_mask; + mips3_sd(cpu0->cpu_int2_en0, cpu0->cpu_int2_enable0); +#ifdef MULTIPROCESSOR + cpu1->cpu_int2_enable0 = cpu0->cpu_int2_enable0; + mips3_sd(cpu1->cpu_int2_en0, cpu1->cpu_int2_enable0); +#endif + } else { + cpu0->cpu_int2_enable1 |= irq_mask; + mips3_sd(cpu0->cpu_int2_en1, cpu0->cpu_int2_enable1); #ifdef MULTIPROCESSOR - cpu1->cpu_int2_enable0 = cpu0->cpu_int2_enable0; - mips3_sd(cpu1->cpu_int2_en0, cpu1->cpu_int2_enable0); + cpu1->cpu_int2_enable1 = cpu0->cpu_int2_enable1; + mips3_sd(cpu1->cpu_int2_en1, cpu1->cpu_int2_enable1); #endif + } break; } @@ -460,7 +491,8 @@ octeon_intr_disestablish(void *cookie) /* * First disable it. */ - const uint64_t irq_mask = ~__BIT(irq); + const int bank = irq / 64; + const uint64_t irq_mask = ~__BIT(irq % 64); struct cpu_softc * const cpu0 = &octeon_cpu0_softc; #if MULTIPROCESSOR struct cpu_softc * const cpu1 = &octeon_cpu1_softc; @@ -468,27 +500,50 @@ octeon_intr_disestablish(void *cookie) switch (ipl) { case IPL_VM: - cpu0->cpu_int0_enable0 &= ~irq_mask; - mips3_sd(cpu0->cpu_int0_en0, cpu0->cpu_int0_enable0); + if (bank == 0) { + cpu0->cpu_int0_enable0 &= ~irq_mask; + mips3_sd(cpu0->cpu_int0_en0, cpu0->cpu_int0_enable0); + } else { + cpu0->cpu_int0_enable1 &= ~irq_mask; + mips3_sd(cpu0->cpu_int0_en1, cpu0->cpu_int0_enable1); + } break; case IPL_SCHED: - cpu0->cpu_int1_enable0 &= ~irq_mask; - mips3_sd(cpu0->cpu_int1_en0, cpu0->cpu_int1_enable0); + if (bank == 0) { + cpu0->cpu_int1_enable0 &= ~irq_mask; + mips3_sd(cpu0->cpu_int1_en0, cpu0->cpu_int1_enable0); +#ifdef MULTIPROCESSOR + cpu1->cpu_int1_enable0 = cpu0->cpu_int1_enable0; + mips3_sd(cpu1->cpu_int1_en0, cpu1->cpu_int1_enable0); +#endif + } else { + cpu0->cpu_int1_enable1 &= ~irq_mask; + mips3_sd(cpu0->cpu_int1_en1, cpu0->cpu_int1_enable1); #ifdef MULTIPROCESSOR - cpu1->cpu_int1_enable0 = cpu0->cpu_int1_enable0; - mips3_sd(cpu1->cpu_int1_en0, cpu1->cpu_int1_enable0); + cpu1->cpu_int1_enable1 = cpu0->cpu_int1_enable1; + mips3_sd(cpu1->cpu_int1_en1, cpu1->cpu_int1_enable1); #endif + } break; case IPL_DDB: case IPL_HIGH: - cpu0->cpu_int2_enable0 &= ~irq_mask; - mips3_sd(cpu0->cpu_int2_en0, cpu0->cpu_int2_enable0); + if (bank == 0) { + cpu0->cpu_int2_enable0 &= ~irq_mask; + mips3_sd(cpu0->cpu_int2_en0, cpu0->cpu_int2_enable0); +#ifdef MULTIPROCESSOR + cpu1->cpu_int2_enable0 = cpu0->cpu_int2_enable0; + mips3_sd(cpu1->cpu_int2_en0, cpu1->cpu_int2_enable0); +#endif + } else { + cpu0->cpu_int2_enable1 &= ~irq_mask; + mips3_sd(cpu0->cpu_int2_en1, cpu0->cpu_int2_enable1); #ifdef MULTIPROCESSOR - cpu1->cpu_int2_enable0 = cpu0->cpu_int2_enable0; - mips3_sd(cpu1->cpu_int2_en0, cpu1->cpu_int2_enable0); + cpu1->cpu_int2_enable1 = cpu0->cpu_int2_enable1; + mips3_sd(cpu1->cpu_int2_en1, cpu1->cpu_int2_enable1); #endif + } break; } @@ -507,43 +562,52 @@ octeon_iointr(int ipl, vaddr_t pc, uint3 { struct cpu_info * const ci = curcpu(); struct cpu_softc * const cpu = ci->ci_softc; + int bank; KDASSERT(mips_cp0_status_read() & MIPS_SR_INT_IE); KASSERT((ipending & ~MIPS_INT_MASK) == 0); KASSERT(ipending & MIPS_HARD_INT_MASK); - uint64_t hwpend = 0; + uint64_t hwpend[2] = { 0, 0 }; + + const uint64_t sum1 = mips3_ld(cpu->cpu_int_sum1); if (ipending & MIPS_INT_MASK_2) { - hwpend = mips3_ld(cpu->cpu_int2_sum0) + hwpend[0] = mips3_ld(cpu->cpu_int2_sum0) & cpu->cpu_int2_enable0; + hwpend[1] = sum1 & cpu->cpu_int2_enable1; } else if (ipending & MIPS_INT_MASK_1) { - hwpend = mips3_ld(cpu->cpu_int1_sum0) + hwpend[0] = mips3_ld(cpu->cpu_int1_sum0) & cpu->cpu_int1_enable0; + hwpend[1] = sum1 & cpu->cpu_int1_enable1; } else if (ipending & MIPS_INT_MASK_0) { - hwpend = mips3_ld(cpu->cpu_int0_sum0) + hwpend[0] = mips3_ld(cpu->cpu_int0_sum0) & cpu->cpu_int0_enable0; + hwpend[1] = sum1 & cpu->cpu_int0_enable1; } else { panic("octeon_iointr: unexpected ipending %#x", ipending); } - while (hwpend != 0) { - const int irq = ffs64(hwpend) - 1; - hwpend &= ~__BIT(irq); - - struct octeon_intrhand * const ih = octciu_intrs[irq]; - cpu->cpu_intr_evs[irq].ev_count++; - if (__predict_true(ih != NULL)) { -#ifdef MULTIPROCESSOR - if (ipl == IPL_VM) { - KERNEL_LOCK(1, NULL); -#endif - (*ih->ih_func)(ih->ih_arg); -#ifdef MULTIPROCESSOR - KERNEL_UNLOCK_ONE(NULL); - } else { - (*ih->ih_func)(ih->ih_arg); - } + for (bank = 0; bank <= 1; bank++) { + while (hwpend[bank] != 0) { + const int bit = ffs64(hwpend[bank]) - 1; + const int irq = (bank * 64) + bit; + hwpend[bank] &= ~__BIT(bit); + + struct octeon_intrhand * const ih = octciu_intrs[irq]; + cpu->cpu_intr_evs[irq].ev_count++; + if (__predict_true(ih != NULL)) { +#ifdef MULTIPROCESSOR + if (ipl == IPL_VM) { + KERNEL_LOCK(1, NULL); +#endif + (*ih->ih_func)(ih->ih_arg); +#ifdef MULTIPROCESSOR + KERNEL_UNLOCK_ONE(NULL); + } else { + (*ih->ih_func)(ih->ih_arg); + } #endif - KDASSERT(mips_cp0_status_read() & MIPS_SR_INT_IE); + KDASSERT(mips_cp0_status_read() & MIPS_SR_INT_IE); + } } } KDASSERT(mips_cp0_status_read() & MIPS_SR_INT_IE); Index: src/sys/arch/mips/cavium/octeonvar.h diff -u src/sys/arch/mips/cavium/octeonvar.h:1.13 src/sys/arch/mips/cavium/octeonvar.h:1.14 --- src/sys/arch/mips/cavium/octeonvar.h:1.13 Tue Jun 23 05:15:33 2020 +++ src/sys/arch/mips/cavium/octeonvar.h Thu Jul 16 21:33:50 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: octeonvar.h,v 1.13 2020/06/23 05:15:33 simonb Exp $ */ +/* $NetBSD: octeonvar.h,v 1.14 2020/07/16 21:33:50 jmcneill Exp $ */ /*- * Copyright (c) 2001 The NetBSD Foundation, Inc. @@ -77,7 +77,7 @@ struct octeon_config { int mc_mallocsafe; }; -#define NIRQS 64 +#define NIRQS 128 struct cpu_softc { struct cpu_info *cpu_ci; @@ -86,6 +86,8 @@ struct cpu_softc { uint64_t cpu_int1_sum0; uint64_t cpu_int2_sum0; + uint64_t cpu_int_sum1; + uint64_t cpu_int0_en0; uint64_t cpu_int1_en0; uint64_t cpu_int2_en0; @@ -102,6 +104,10 @@ struct cpu_softc { uint64_t cpu_int1_enable0; uint64_t cpu_int2_enable0; + uint64_t cpu_int0_enable1; + uint64_t cpu_int1_enable1; + uint64_t cpu_int2_enable1; + void *cpu_wdog_sih; // wdog softint handler uint64_t cpu_wdog; uint64_t cpu_pp_poke;