1 /* $NetBSD: softint_machdep.c,v 1.3 2023/05/07 12:41:49 skrll Exp $ */ 2 3 /*- 4 * Copyright (c) 2014 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Matt Thomas of 3am Software Foundry. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #include <sys/cdefs.h> 33 34 __RCSID("$NetBSD: softint_machdep.c,v 1.3 2023/05/07 12:41:49 skrll Exp $"); 35 36 #define __INTR_PRIVATE 37 38 #include <sys/param.h> 39 #include <sys/intr.h> 40 41 #include <riscv/locore.h> 42 43 #ifdef __HAVE_FAST_SOFTINTS 44 45 #define SOFTINT2IPLMAP \ 46 (((IPL_SOFTSERIAL - IPL_SOFTCLOCK) << (SOFTINT_SERIAL * 4)) | \ 47 ((IPL_SOFTNET - IPL_SOFTCLOCK) << (SOFTINT_NET * 4)) | \ 48 ((IPL_SOFTBIO - IPL_SOFTCLOCK) << (SOFTINT_BIO * 4)) | \ 49 ((IPL_SOFTCLOCK - IPL_SOFTCLOCK) << (SOFTINT_CLOCK * 4))) 50 #define SOFTINT2IPL(l) ((SOFTINT2IPLMAP >> ((l) * 4)) & 0x0f) 51 52 /* 53 * This returns a mask of softint IPLs that be dispatch at <ipl> 54 * SOFTIPLMASK(IPL_NONE) = 0x0000000f 55 * SOFTIPLMASK(IPL_SOFTCLOCK) = 0x0000000e 56 * SOFTIPLMASK(IPL_SOFTBIO) = 0x0000000c 57 * SOFTIPLMASK(IPL_SOFTNET) = 0x00000008 58 * SOFTIPLMASK(IPL_SOFTSERIAL) = 0x00000000 59 */ 60 #define SOFTIPLMASK(ipl) ((0x0f << (ipl)) & 0x0f) 61 62 void softint_switch(lwp_t *, int); 63 64 void 65 softint_trigger(uintptr_t mask) 66 { 67 curcpu()->ci_softints |= mask; 68 } 69 70 void 71 softint_init_md(lwp_t *l, u_int level, uintptr_t *machdep) 72 { 73 lwp_t ** lp = &l->l_cpu->ci_softlwps[level]; 74 KASSERT(*lp == NULL || *lp == l); 75 *lp = l; 76 *machdep = 1 << SOFTINT2IPL(level); 77 KASSERT(level != SOFTINT_CLOCK || *machdep == (1 << (IPL_SOFTCLOCK - IPL_SOFTCLOCK))); 78 KASSERT(level != SOFTINT_BIO || *machdep == (1 << (IPL_SOFTBIO - IPL_SOFTCLOCK))); 79 KASSERT(level != SOFTINT_NET || *machdep == (1 << (IPL_SOFTNET - IPL_SOFTCLOCK))); 80 KASSERT(level != SOFTINT_SERIAL || *machdep == (1 << (IPL_SOFTSERIAL - IPL_SOFTCLOCK))); 81 } 82 83 void 84 softint_deliver(void) 85 { 86 struct cpu_info * const ci = curcpu(); 87 const int opl = ci->ci_cpl; 88 const uint32_t softiplmask = SOFTIPLMASK(opl); 89 90 splhigh(); 91 for (;;) { 92 u_int softints = ci->ci_softints & softiplmask; 93 KASSERT((softints != 0) == ((ci->ci_softints >> opl) != 0)); 94 KASSERT(opl == IPL_NONE || (softints & (1 << (opl - IPL_SOFTCLOCK))) == 0); 95 if (softints == 0) { 96 splx(opl); 97 return; 98 } 99 #define DOSOFTINT(n) \ 100 if (ci->ci_softints & (1 << (IPL_SOFT ## n - IPL_SOFTCLOCK))) { \ 101 ci->ci_softints &= \ 102 ~(1 << (IPL_SOFT ## n - IPL_SOFTCLOCK)); \ 103 cpu_fast_switchto(ci->ci_softlwps[SOFTINT_ ## n], \ 104 IPL_SOFT ## n); \ 105 continue; \ 106 } 107 DOSOFTINT(SERIAL); 108 DOSOFTINT(NET); 109 DOSOFTINT(BIO); 110 DOSOFTINT(CLOCK); 111 panic("dosoftints wtf (softints=%u?, ipl=%d)", softints, opl); 112 } 113 } 114 #endif /* __HAVE_FAST_SOFTINTS */ 115