#include <sys/cdefs.h>
__RCSID("$NetBSD: softint_machdep.c,v 1.3 2023/05/07 12:41:49 skrll Exp $");
#define __INTR_PRIVATE
#include <sys/param.h>
#include <sys/intr.h>
#include <riscv/locore.h>
#ifdef __HAVE_FAST_SOFTINTS
#define SOFTINT2IPLMAP \
(((IPL_SOFTSERIAL - IPL_SOFTCLOCK) << (SOFTINT_SERIAL * 4)) | \
((IPL_SOFTNET - IPL_SOFTCLOCK) << (SOFTINT_NET * 4)) | \
((IPL_SOFTBIO - IPL_SOFTCLOCK) << (SOFTINT_BIO * 4)) | \
((IPL_SOFTCLOCK - IPL_SOFTCLOCK) << (SOFTINT_CLOCK * 4)))
#define SOFTINT2IPL(l) ((SOFTINT2IPLMAP >> ((l) * 4)) & 0x0f)
#define SOFTIPLMASK(ipl) ((0x0f << (ipl)) & 0x0f)
void softint_switch(lwp_t *, int);
void
softint_trigger(uintptr_t mask)
{
curcpu()->ci_softints |= mask;
}
void
softint_init_md(lwp_t *l, u_int level, uintptr_t *machdep)
{
lwp_t ** lp = &l->l_cpu->ci_softlwps[level];
KASSERT(*lp == NULL || *lp == l);
*lp = l;
*machdep = 1 << SOFTINT2IPL(level);
KASSERT(level != SOFTINT_CLOCK || *machdep == (1 << (IPL_SOFTCLOCK - IPL_SOFTCLOCK)));
KASSERT(level != SOFTINT_BIO || *machdep == (1 << (IPL_SOFTBIO - IPL_SOFTCLOCK)));
KASSERT(level != SOFTINT_NET || *machdep == (1 << (IPL_SOFTNET - IPL_SOFTCLOCK)));
KASSERT(level != SOFTINT_SERIAL || *machdep == (1 << (IPL_SOFTSERIAL - IPL_SOFTCLOCK)));
}
void
softint_deliver(void)
{
struct cpu_info * const ci = curcpu();
const int opl = ci->ci_cpl;
const uint32_t softiplmask = SOFTIPLMASK(opl);
splhigh();
for (;;) {
u_int softints = ci->ci_softints & softiplmask;
KASSERT((softints != 0) == ((ci->ci_softints >> opl) != 0));
KASSERT(opl == IPL_NONE || (softints & (1 << (opl - IPL_SOFTCLOCK))) == 0);
if (softints == 0) {
splx(opl);
return;
}
#define DOSOFTINT(n) \
if (ci->ci_softints & (1 << (IPL_SOFT ## n - IPL_SOFTCLOCK))) { \
ci->ci_softints &= \
~(1 << (IPL_SOFT ## n - IPL_SOFTCLOCK)); \
cpu_fast_switchto(ci->ci_softlwps[SOFTINT_ ## n], \
IPL_SOFT ## n); \
continue; \
}
DOSOFTINT(SERIAL);
DOSOFTINT(NET);
DOSOFTINT(BIO);
DOSOFTINT(CLOCK);
panic("dosoftints wtf (softints=%u?, ipl=%d)", softints, opl);
}
}
#endif