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;

Reply via email to