| @@ -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 | |
| | | 179 | static 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 | |
177 | struct octeon_intrhand *octciu_intrs[NIRQS] = { | | 193 | struct 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 | |
184 | kmutex_t octeon_intr_lock; | | 200 | kmutex_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 */ |