commit e7a51d39b26cd13cd2e774e015d8d40c50d78f9a Author: Kevin Bowling Date: Thu Mar 19 16:53:33 2026 -0700 octirq diff --git a/sys/arch/mips/cavium/dev/octeon_ciureg.h b/sys/arch/mips/cavium/dev/octeon_ciureg.h index 90b8b460f991..c839caf2b378 100644 --- a/sys/arch/mips/cavium/dev/octeon_ciureg.h +++ b/sys/arch/mips/cavium/dev/octeon_ciureg.h @@ -86,12 +86,14 @@ #define CIU_INT4_SUM0 UINT64_C(0x0001070000000c00) #define CIU_INT4_SUM1 UINT64_C(0x0001070000000c08) #define CIU_IP4_SUM0(n) (CIU_INT4_SUM0 + 0x8 * (n)) +#define CIU_IP4_SUM2(n) (UINT64_C(0x0001070000008c00) + 0x8 * (n)) #define CIU_INT4_EN00 UINT64_C(0x0001070000000c80) #define CIU_INT4_EN01 UINT64_C(0x0001070000000c88) #define CIU_INT4_EN10 UINT64_C(0x0001070000000c90) #define CIU_INT4_EN11 UINT64_C(0x0001070000000c98) #define CIU_IP4_EN0(n) (CIU_INT4_EN00 + 0x10 * (n)) #define CIU_IP4_EN1(n) (CIU_INT4_EN01 + 0x10 * (n)) +#define CIU_IP4_EN2(n) (UINT64_C(0x000107000000a400) + 0x8 * (n)) #define CIU_BASE UINT64_C(0x0001070000000000) diff --git a/sys/arch/mips/cavium/octeon_intr.c b/sys/arch/mips/cavium/octeon_intr.c index 333d7c5f4090..e509054fe7cf 100644 --- a/sys/arch/mips/cavium/octeon_intr.c +++ b/sys/arch/mips/cavium/octeon_intr.c @@ -230,6 +230,7 @@ octeon_intr_setup(void) cpu->cpu_ip4_sum0 = X(CIU_IP4_SUM0(cpunum)); cpu->cpu_int_sum1 = X(CIU_INT_SUM1); + cpu->cpu_int_sum2 = X(CIU_IP4_SUM2(cpunum)); cpu->cpu_ip2_en[0] = X(CIU_IP2_EN0(cpunum)); cpu->cpu_ip3_en[0] = X(CIU_IP3_EN0(cpunum)); @@ -239,6 +240,8 @@ octeon_intr_setup(void) cpu->cpu_ip3_en[1] = X(CIU_IP3_EN1(cpunum)); cpu->cpu_ip4_en[1] = X(CIU_IP4_EN1(cpunum)); + cpu->cpu_ip4_en[2] = X(CIU_IP4_EN2(cpunum)); + cpu->cpu_wdog = X(CIU_WDOG(cpunum)); cpu->cpu_pp_poke = X(CIU_PP_POKE(cpunum)); @@ -294,9 +297,13 @@ octeon_intr_init(struct cpu_info *ci) } for (bank = 0; bank < NBANKS; bank++) { - mips3_sd(cpu->cpu_ip2_en[bank], cpu->cpu_ip2_enable[bank]); - mips3_sd(cpu->cpu_ip3_en[bank], cpu->cpu_ip3_enable[bank]); - mips3_sd(cpu->cpu_ip4_en[bank], cpu->cpu_ip4_enable[bank]); + /* Octeon II/III bank 2 has no IP2/IP3 enable registers */ + if (cpu->cpu_ip2_en[bank]) + mips3_sd(cpu->cpu_ip2_en[bank], cpu->cpu_ip2_enable[bank]); + if (cpu->cpu_ip3_en[bank]) + mips3_sd(cpu->cpu_ip3_en[bank], cpu->cpu_ip3_enable[bank]); + if (cpu->cpu_ip4_en[bank]) + mips3_sd(cpu->cpu_ip4_en[bank], cpu->cpu_ip4_enable[bank]); } #ifdef MULTIPROCESSOR @@ -370,6 +377,13 @@ octeon_intr_establish(int irq, int ipl, int (*func)(void *), void *arg) const int bank = irq / 64; const uint64_t irq_mask = __BIT(irq % 64); + /* + * Bank 2 (OCTEON II/III) only has IP4 enable registers. + * Route any bank 2 interrupt to IP4 regardless of ipl. + */ + if (bank == 2) + ipl = IPL_HIGH; + switch (ipl) { case IPL_VM: cpu = &octeon_cpu_softc[0]; @@ -422,7 +436,7 @@ octeon_intr_disestablish(void *cookie) struct octeon_intrhand * const ih = cookie; struct cpu_softc *cpu; const int irq = ih->ih_irq & (NIRQS-1); - const int ipl = ih->ih_ipl; + int ipl = ih->ih_ipl; int cpunum; mutex_enter(&octeon_intr_lock); @@ -433,6 +447,10 @@ octeon_intr_disestablish(void *cookie) const int bank = irq / 64; const uint64_t irq_mask = ~__BIT(irq % 64); + /* Bank 2 only has IP4 enable registers. */ + if (bank == 2) + ipl = IPL_HIGH; + switch (ipl) { case IPL_VM: cpu = &octeon_cpu_softc[0]; @@ -484,7 +502,7 @@ octeon_iointr(int ipl, vaddr_t pc, uint32_t ipending) KDASSERT(mips_cp0_status_read() & MIPS_SR_INT_IE); KASSERT((ipending & ~MIPS_INT_MASK) == 0); KASSERT(ipending & MIPS_HARD_INT_MASK); - uint64_t hwpend[2] = { 0, 0 }; + uint64_t hwpend[NBANKS] = { 0, 0, 0 }; const uint64_t sum1 = mips3_ld(cpu->cpu_int_sum1); @@ -492,6 +510,10 @@ octeon_iointr(int ipl, vaddr_t pc, uint32_t ipending) hwpend[0] = mips3_ld(cpu->cpu_ip4_sum0) & cpu->cpu_ip4_enable[0]; hwpend[1] = sum1 & cpu->cpu_ip4_enable[1]; + /* Bank 2: OCTEON II/III only, always via IP4 */ + if (cpu->cpu_ip4_en[2]) + hwpend[2] = mips3_ld(cpu->cpu_int_sum2) + & cpu->cpu_ip4_enable[2]; } else if (ipending & MIPS_INT_MASK_1) { hwpend[0] = mips3_ld(cpu->cpu_ip3_sum0) & cpu->cpu_ip3_enable[0]; @@ -503,7 +525,7 @@ octeon_iointr(int ipl, vaddr_t pc, uint32_t ipending) } else { panic("octeon_iointr: unexpected ipending %#x", ipending); } - for (bank = 0; bank <= 1; bank++) { + for (bank = 0; bank < NBANKS; bank++) { while (hwpend[bank] != 0) { const int bit = ffs64(hwpend[bank]) - 1; const int irq = (bank * 64) + bit; diff --git a/sys/arch/mips/cavium/octeonvar.h b/sys/arch/mips/cavium/octeonvar.h index 812e01ed4d07..d056c237d057 100644 --- a/sys/arch/mips/cavium/octeonvar.h +++ b/sys/arch/mips/cavium/octeonvar.h @@ -78,8 +78,8 @@ struct octeon_config { int mc_mallocsafe; }; -#define NIRQS 128 -#define NBANKS 2 +#define NIRQS 192 +#define NBANKS 3 struct cpu_softc { struct cpu_info *cpu_ci; @@ -89,6 +89,7 @@ struct cpu_softc { uint64_t cpu_ip4_sum0; uint64_t cpu_int_sum1; + uint64_t cpu_int_sum2; uint64_t cpu_ip2_en[NBANKS]; uint64_t cpu_ip3_en[NBANKS]; @@ -230,7 +231,7 @@ void mips_cp0_cvmctl_write(uint64_t); #error unknown ABI #endif -/* +/* * Prefetch * * OCTEON_PREF normal (L1 and L2)