Mon Jul 20 13:30:41 2020 UTC ()
Fix confusion between ipi bitmask and mbox register bit assignments.


(jmcneill)
diff -r1.18 -r1.19 src/sys/arch/mips/cavium/octeon_intr.c

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

--- src/sys/arch/mips/cavium/octeon_intr.c 2020/07/17 21:59:30 1.18
+++ src/sys/arch/mips/cavium/octeon_intr.c 2020/07/20 13:30:41 1.19
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: octeon_intr.c,v 1.18 2020/07/17 21:59:30 jmcneill Exp $ */ 1/* $NetBSD: octeon_intr.c,v 1.19 2020/07/20 13:30:41 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.18 2020/07/17 21:59:30 jmcneill Exp $"); 47__KERNEL_RCSID(0, "$NetBSD: octeon_intr.c,v 1.19 2020/07/20 13:30:41 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>
@@ -166,27 +166,27 @@ struct octeon_intrhand ipi_intrhands[2]  @@ -166,27 +166,27 @@ struct octeon_intrhand ipi_intrhands[2]
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 175
176#define OCTEON_IPI_SCHED(n) __BIT((n) + 0) 176#define OCTEON_IPI_SCHED(n) __BIT((n) + 0)
177#define OCTEON_IPI_HIGH(n) __BIT((n) + 16) 177#define OCTEON_IPI_HIGH(n) __BIT((n) + 16)
178 178
179static uint64_t octeon_ipi_mask[NIPIS] = { 179static uint32_t octeon_ipi_mbox_mask[NIPIS] = {
180 [IPI_NOP] = OCTEON_IPI_SCHED(IPI_NOP), 180 [IPI_NOP] = OCTEON_IPI_SCHED(IPI_NOP),
181 [IPI_AST] = OCTEON_IPI_SCHED(IPI_AST), 181 [IPI_AST] = OCTEON_IPI_SCHED(IPI_AST),
182 [IPI_SHOOTDOWN] = OCTEON_IPI_SCHED(IPI_SHOOTDOWN), 182 [IPI_SHOOTDOWN] = OCTEON_IPI_SCHED(IPI_SHOOTDOWN),
183 [IPI_SYNCICACHE] = OCTEON_IPI_SCHED(IPI_SYNCICACHE), 183 [IPI_SYNCICACHE] = OCTEON_IPI_SCHED(IPI_SYNCICACHE),
184 [IPI_KPREEMPT] = OCTEON_IPI_SCHED(IPI_KPREEMPT), 184 [IPI_KPREEMPT] = OCTEON_IPI_SCHED(IPI_KPREEMPT),
185 [IPI_SUSPEND] = OCTEON_IPI_HIGH(IPI_SUSPEND), 185 [IPI_SUSPEND] = OCTEON_IPI_HIGH(IPI_SUSPEND),
186 [IPI_HALT] = OCTEON_IPI_HIGH(IPI_HALT), 186 [IPI_HALT] = OCTEON_IPI_HIGH(IPI_HALT),
187 [IPI_XCALL] = OCTEON_IPI_HIGH(IPI_XCALL), 187 [IPI_XCALL] = OCTEON_IPI_HIGH(IPI_XCALL),
188 [IPI_GENERIC] = OCTEON_IPI_HIGH(IPI_GENERIC), 188 [IPI_GENERIC] = OCTEON_IPI_HIGH(IPI_GENERIC),
189 [IPI_WDOG] = OCTEON_IPI_HIGH(IPI_WDOG), 189 [IPI_WDOG] = OCTEON_IPI_HIGH(IPI_WDOG),
190}; 190};
191#endif 191#endif
192 192
@@ -506,36 +506,41 @@ octeon_iointr(int ipl, vaddr_t pc, uint3 @@ -506,36 +506,41 @@ octeon_iointr(int ipl, vaddr_t pc, uint3
506 } 506 }
507 } 507 }
508 KDASSERT(mips_cp0_status_read() & MIPS_SR_INT_IE); 508 KDASSERT(mips_cp0_status_read() & MIPS_SR_INT_IE);
509} 509}
510 510
511#ifdef MULTIPROCESSOR 511#ifdef MULTIPROCESSOR
512__CTASSERT(NIPIS < 16); 512__CTASSERT(NIPIS < 16);
513 513
514int 514int
515octeon_ipi_intr(void *arg) 515octeon_ipi_intr(void *arg)
516{ 516{
517 struct cpu_info * const ci = curcpu(); 517 struct cpu_info * const ci = curcpu();
518 struct cpu_softc * const cpu = ci->ci_softc; 518 struct cpu_softc * const cpu = ci->ci_softc;
519 uint32_t ipi_mask = (uintptr_t) arg; 519 uint32_t mbox_mask = (uintptr_t) arg;
 520 uint32_t ipi_mask;
520 521
521 KASSERTMSG((ipi_mask & __BITS(31,16)) == 0 || ci->ci_cpl >= IPL_SCHED, 522 KASSERTMSG((mbox_mask & __BITS(31,16)) == 0 || ci->ci_cpl >= IPL_SCHED,
522 "ipi_mask %#"PRIx32" cpl %d", ipi_mask, ci->ci_cpl); 523 "mbox_mask %#"PRIx32" cpl %d", mbox_mask, ci->ci_cpl);
523 524
524 ipi_mask &= mips3_ld(cpu->cpu_mbox_set); 525 mbox_mask &= mips3_ld(cpu->cpu_mbox_set);
525 if (ipi_mask == 0) 526 if (mbox_mask == 0)
526 return 0; 527 return 0;
527 528
528 mips3_sd(cpu->cpu_mbox_clr, ipi_mask); 529 mips3_sd(cpu->cpu_mbox_clr, mbox_mask);
 530
 531 ipi_mask = mbox_mask;
 532 if (ci->ci_cpl >= IPL_SCHED)
 533 ipi_mask >>= 16;
529 534
530 KASSERT(ipi_mask < __BIT(NIPIS)); 535 KASSERT(ipi_mask < __BIT(NIPIS));
531 536
532#if NWDOG > 0 537#if NWDOG > 0
533 // Handle WDOG requests ourselves. 538 // Handle WDOG requests ourselves.
534 if (ipi_mask & __BIT(IPI_WDOG)) { 539 if (ipi_mask & __BIT(IPI_WDOG)) {
535 softint_schedule(cpu->cpu_wdog_sih); 540 softint_schedule(cpu->cpu_wdog_sih);
536 atomic_and_64(&ci->ci_request_ipis, ~__BIT(IPI_WDOG)); 541 atomic_and_64(&ci->ci_request_ipis, ~__BIT(IPI_WDOG));
537 ipi_mask &= ~__BIT(IPI_WDOG); 542 ipi_mask &= ~__BIT(IPI_WDOG);
538 ci->ci_evcnt_per_ipi[IPI_WDOG].ev_count++; 543 ci->ci_evcnt_per_ipi[IPI_WDOG].ev_count++;
539 if (__predict_true(ipi_mask == 0)) 544 if (__predict_true(ipi_mask == 0))
540 return 1; 545 return 1;
541 } 546 }
@@ -563,22 +568,23 @@ octeon_send_ipi(struct cpu_info *ci, int @@ -563,22 +568,23 @@ octeon_send_ipi(struct cpu_info *ci, int
563 CPU_INFO_ITERATOR cii; 568 CPU_INFO_ITERATOR cii;
564 for (CPU_INFO_FOREACH(cii, ci)) { 569 for (CPU_INFO_FOREACH(cii, ci)) {
565 if (ci != curcpu()) { 570 if (ci != curcpu()) {
566 octeon_send_ipi(ci, req); 571 octeon_send_ipi(ci, req);
567 } 572 }
568 } 573 }
569 return 0; 574 return 0;
570 } 575 }
571 KASSERT(cold || ci->ci_softc != NULL); 576 KASSERT(cold || ci->ci_softc != NULL);
572 if (ci->ci_softc == NULL) 577 if (ci->ci_softc == NULL)
573 return -1; 578 return -1;
574 579
575 struct cpu_softc * const cpu = ci->ci_softc; 580 struct cpu_softc * const cpu = ci->ci_softc;
576 const uint64_t ipi_mask = octeon_ipi_mask[req]; 581 const uint32_t mbox_mask = octeon_ipi_mbox_mask[req];
 582 const uint32_t ipi_mask = __BIT(req);
577 583
578 atomic_or_64(&ci->ci_request_ipis, ipi_mask); 584 atomic_or_64(&ci->ci_request_ipis, ipi_mask);
579 585
580 mips3_sd(cpu->cpu_mbox_set, ipi_mask); 586 mips3_sd(cpu->cpu_mbox_set, mbox_mask);
581 587
582 return 0; 588 return 0;
583} 589}
584#endif /* MULTIPROCESSOR */ 590#endif /* MULTIPROCESSOR */