Fri Jul 17 19:40:47 2020 UTC ()
Simplify IPI handling and change IPLs of IPI_HALT, IPI_XCALL, and
IPI_GENERIC from IPL_SCHED to IPL_HIGH.


(jmcneill)
diff -r1.16 -r1.17 src/sys/arch/mips/cavium/octeon_intr.c

cvs diff -r1.16 -r1.17 src/sys/arch/mips/cavium/octeon_intr.c (expand / switch to unified diff)

--- src/sys/arch/mips/cavium/octeon_intr.c 2020/07/17 17:57:16 1.16
+++ src/sys/arch/mips/cavium/octeon_intr.c 2020/07/17 19:40:47 1.17
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: octeon_intr.c,v 1.16 2020/07/17 17:57:16 jmcneill Exp $ */ 1/* $NetBSD: octeon_intr.c,v 1.17 2020/07/17 19:40:47 jmcneill Exp $ */
2/* 2/*
3 * Copyright 2001, 2002 Wasabi Systems, Inc. 3 * Copyright 2001, 2002 Wasabi Systems, Inc.
4 * All rights reserved. 4 * All rights reserved.
5 * 5 *
6 * Written by Jason R. Thorpe and Simon Burge for Wasabi Systems, Inc. 6 * Written by Jason R. Thorpe and Simon Burge for Wasabi Systems, Inc.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
@@ -34,27 +34,27 @@ @@ -34,27 +34,27 @@
34 * POSSIBILITY OF SUCH DAMAGE. 34 * POSSIBILITY OF SUCH DAMAGE.
35 */ 35 */
36 36
37/* 37/*
38 * Platform-specific interrupt support for the MIPS Malta. 38 * Platform-specific interrupt support for the MIPS Malta.
39 */ 39 */
40 40
41#include "opt_multiprocessor.h" 41#include "opt_multiprocessor.h"
42 42
43#include "cpunode.h" 43#include "cpunode.h"
44#define __INTR_PRIVATE 44#define __INTR_PRIVATE
45 45
46#include <sys/cdefs.h> 46#include <sys/cdefs.h>
47__KERNEL_RCSID(0, "$NetBSD: octeon_intr.c,v 1.16 2020/07/17 17:57:16 jmcneill Exp $"); 47__KERNEL_RCSID(0, "$NetBSD: octeon_intr.c,v 1.17 2020/07/17 19:40:47 jmcneill Exp $");
48 48
49#include <sys/param.h> 49#include <sys/param.h>
50#include <sys/cpu.h> 50#include <sys/cpu.h>
51#include <sys/systm.h> 51#include <sys/systm.h>
52#include <sys/device.h> 52#include <sys/device.h>
53#include <sys/intr.h> 53#include <sys/intr.h>
54#include <sys/kernel.h> 54#include <sys/kernel.h>
55#include <sys/kmem.h> 55#include <sys/kmem.h>
56#include <sys/atomic.h> 56#include <sys/atomic.h>
57 57
58#include <lib/libkern/libkern.h> 58#include <lib/libkern/libkern.h>
59 59
60#include <mips/locore.h> 60#include <mips/locore.h>
@@ -162,26 +162,42 @@ struct octeon_intrhand ipi_intrhands[2]  @@ -162,26 +162,42 @@ struct octeon_intrhand ipi_intrhands[2]
162 [0] = { 162 [0] = {
163 .ih_func = octeon_ipi_intr, 163 .ih_func = octeon_ipi_intr,
164 .ih_arg = (void *)(uintptr_t)__BITS(15,0), 164 .ih_arg = (void *)(uintptr_t)__BITS(15,0),
165 .ih_irq = CIU_INT_MBOX_15_0, 165 .ih_irq = CIU_INT_MBOX_15_0,
166 .ih_ipl = IPL_SCHED, 166 .ih_ipl = IPL_SCHED,
167 }, 167 },
168 [1] = { 168 [1] = {
169 .ih_func = octeon_ipi_intr, 169 .ih_func = octeon_ipi_intr,
170 .ih_arg = (void *)(uintptr_t)__BITS(31,16), 170 .ih_arg = (void *)(uintptr_t)__BITS(31,16),
171 .ih_irq = CIU_INT_MBOX_31_16, 171 .ih_irq = CIU_INT_MBOX_31_16,
172 .ih_ipl = IPL_HIGH, 172 .ih_ipl = IPL_HIGH,
173 }, 173 },
174}; 174};
 175
 176#define OCTEON_IPI_SCHED(n) __BIT((n) + 0)
 177#define OCTEON_IPI_HIGH(n) __BIT((n) + 16)
 178
 179static uint64_t octeon_ipi_mask[NIPIS] = {
 180 [IPI_NOP] = OCTEON_IPI_SCHED(IPI_NOP),
 181 [IPI_AST] = OCTEON_IPI_SCHED(IPI_AST),
 182 [IPI_SHOOTDOWN] = OCTEON_IPI_SCHED(IPI_SHOOTDOWN),
 183 [IPI_SYNCICACHE] = OCTEON_IPI_SCHED(IPI_SYNCICACHE),
 184 [IPI_KPREEMPT] = OCTEON_IPI_SCHED(IPI_KPREEMPT),
 185 [IPI_SUSPEND] = OCTEON_IPI_HIGH(IPI_SUSPEND),
 186 [IPI_HALT] = OCTEON_IPI_HIGH(IPI_HALT),
 187 [IPI_XCALL] = OCTEON_IPI_HIGH(IPI_XCALL),
 188 [IPI_GENERIC] = OCTEON_IPI_HIGH(IPI_GENERIC),
 189 [IPI_WDOG] = OCTEON_IPI_HIGH(IPI_WDOG),
 190};
175#endif 191#endif
176 192
177struct octeon_intrhand *octciu_intrs[NIRQS] = { 193struct octeon_intrhand *octciu_intrs[NIRQS] = {
178#ifdef MULTIPROCESSOR 194#ifdef MULTIPROCESSOR
179 [CIU_INT_MBOX_15_0] = &ipi_intrhands[0], 195 [CIU_INT_MBOX_15_0] = &ipi_intrhands[0],
180 [CIU_INT_MBOX_31_16] = &ipi_intrhands[1], 196 [CIU_INT_MBOX_31_16] = &ipi_intrhands[1],
181#endif 197#endif
182}; 198};
183 199
184kmutex_t octeon_intr_lock; 200kmutex_t octeon_intr_lock;
185 201
186#define X(a) MIPS_PHYS_TO_XKPHYS(OCTEON_CCA_NONE, (a)) 202#define X(a) MIPS_PHYS_TO_XKPHYS(OCTEON_CCA_NONE, (a))
187 203
@@ -582,29 +598,26 @@ octeon_ipi_intr(void *arg) @@ -582,29 +598,26 @@ octeon_ipi_intr(void *arg)
582 struct cpu_info * const ci = curcpu(); 598 struct cpu_info * const ci = curcpu();
583 struct cpu_softc * const cpu = ci->ci_softc; 599 struct cpu_softc * const cpu = ci->ci_softc;
584 uint32_t ipi_mask = (uintptr_t) arg; 600 uint32_t ipi_mask = (uintptr_t) arg;
585 601
586 KASSERTMSG((ipi_mask & __BITS(31,16)) == 0 || ci->ci_cpl >= IPL_SCHED, 602 KASSERTMSG((ipi_mask & __BITS(31,16)) == 0 || ci->ci_cpl >= IPL_SCHED,
587 "ipi_mask %#"PRIx32" cpl %d", ipi_mask, ci->ci_cpl); 603 "ipi_mask %#"PRIx32" cpl %d", ipi_mask, ci->ci_cpl);
588 604
589 ipi_mask &= mips3_ld(cpu->cpu_mbox_set); 605 ipi_mask &= mips3_ld(cpu->cpu_mbox_set);
590 if (ipi_mask == 0) 606 if (ipi_mask == 0)
591 return 0; 607 return 0;
592 608
593 mips3_sd(cpu->cpu_mbox_clr, ipi_mask); 609 mips3_sd(cpu->cpu_mbox_clr, ipi_mask);
594 610
595 ipi_mask |= (ipi_mask >> 16); 
596 ipi_mask &= __BITS(15,0); 
597 
598 KASSERT(ipi_mask < __BIT(NIPIS)); 611 KASSERT(ipi_mask < __BIT(NIPIS));
599 612
600#if NWDOG > 0 613#if NWDOG > 0
601 // Handle WDOG requests ourselves. 614 // Handle WDOG requests ourselves.
602 if (ipi_mask & __BIT(IPI_WDOG)) { 615 if (ipi_mask & __BIT(IPI_WDOG)) {
603 softint_schedule(cpu->cpu_wdog_sih); 616 softint_schedule(cpu->cpu_wdog_sih);
604 atomic_and_64(&ci->ci_request_ipis, ~__BIT(IPI_WDOG)); 617 atomic_and_64(&ci->ci_request_ipis, ~__BIT(IPI_WDOG));
605 ipi_mask &= ~__BIT(IPI_WDOG); 618 ipi_mask &= ~__BIT(IPI_WDOG);
606 ci->ci_evcnt_per_ipi[IPI_WDOG].ev_count++; 619 ci->ci_evcnt_per_ipi[IPI_WDOG].ev_count++;
607 if (__predict_true(ipi_mask == 0)) 620 if (__predict_true(ipi_mask == 0))
608 return 1; 621 return 1;
609 } 622 }
610#endif 623#endif
@@ -631,24 +644,22 @@ octeon_send_ipi(struct cpu_info *ci, int @@ -631,24 +644,22 @@ octeon_send_ipi(struct cpu_info *ci, int
631 CPU_INFO_ITERATOR cii; 644 CPU_INFO_ITERATOR cii;
632 for (CPU_INFO_FOREACH(cii, ci)) { 645 for (CPU_INFO_FOREACH(cii, ci)) {
633 if (ci != curcpu()) { 646 if (ci != curcpu()) {
634 octeon_send_ipi(ci, req); 647 octeon_send_ipi(ci, req);
635 } 648 }
636 } 649 }
637 return 0; 650 return 0;
638 } 651 }
639 KASSERT(cold || ci->ci_softc != NULL); 652 KASSERT(cold || ci->ci_softc != NULL);
640 if (ci->ci_softc == NULL) 653 if (ci->ci_softc == NULL)
641 return -1; 654 return -1;
642 655
643 struct cpu_softc * const cpu = ci->ci_softc; 656 struct cpu_softc * const cpu = ci->ci_softc;
644 uint64_t ipi_mask = __BIT(req); 657 const uint64_t ipi_mask = octeon_ipi_mask[req];
645 658
646 atomic_or_64(&ci->ci_request_ipis, ipi_mask); 659 atomic_or_64(&ci->ci_request_ipis, ipi_mask);
647 if (req == IPI_SUSPEND || req == IPI_WDOG) { 
648 ipi_mask <<= 16; 
649 } 
650 660
651 mips3_sd(cpu->cpu_mbox_set, ipi_mask); 661 mips3_sd(cpu->cpu_mbox_set, ipi_mask);
 662
652 return 0; 663 return 0;
653} 664}
654#endif /* MULTIPROCESSOR */ 665#endif /* MULTIPROCESSOR */