/* $NetBSD: softint_machdep.c,v 1.3 2011/09/27 01:02:36 jym Exp $ */ /*- * Copyright (c) 2010, 2011 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation * by Raytheon BBN Technologies Corp and Defense Advanced Research Projects * Agency and which was developed by Matt Thomas of 3am Software Foundry. * * This material is based upon work supported by the Defense Advanced Research * Projects Agency and Space and Naval Warfare Systems Center, Pacific, under * Contract No. N66001-09-C-2073. * Approved for Public Release, Distribution Unlimited * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #define __INTR_PRIVATE #include #include #include #include #ifdef __HAVE_FAST_SOFTINTS #include __CTASSERT(IPL_NONE < IPL_SOFTCLOCK); __CTASSERT(IPL_SOFTCLOCK < IPL_SOFTBIO); __CTASSERT(IPL_SOFTBIO < IPL_SOFTNET); __CTASSERT(IPL_SOFTNET < IPL_SOFTSERIAL); __CTASSERT(IPL_SOFTSERIAL < IPL_VM); __CTASSERT(IPL_SOFTSERIAL < sizeof(uint32_t)*2); static inline void softint_deliver(struct cpu_info *ci, int ipl) { const int si_level = IPL2SOFTINT(ipl); KASSERT(ci->ci_data.cpu_softints & (1 << ipl)); ci->ci_data.cpu_softints ^= 1 << ipl; softint_fast_dispatch(ci->ci_softlwps[si_level], ipl); KASSERT(ci->ci_softlwps[si_level]->l_ctxswtch == 0); KASSERTMSG(ci->ci_cpl == IPL_HIGH, "%s: cpl (%d) != HIGH", __func__, ci->ci_cpl); } void powerpc_softint(struct cpu_info *ci, int old_ipl, vaddr_t pc) { const u_int softint_mask = (IPL_SOFTMASK << old_ipl) & IPL_SOFTMASK; u_int softints; KASSERTMSG(ci->ci_idepth == -1, "%s: cpu%u: idepth (%d) != -1", __func__, cpu_index(ci), ci->ci_idepth); KASSERT(ci->ci_mtx_count == 0); KASSERT(ci->ci_cpl == IPL_HIGH); while ((softints = (ci->ci_data.cpu_softints & softint_mask)) != 0) { KASSERT(old_ipl < IPL_SOFTSERIAL); if (softints & (1 << IPL_SOFTSERIAL)) { softint_deliver(ci, IPL_SOFTSERIAL); continue; } KASSERT(old_ipl < IPL_SOFTNET); if (softints & (1 << IPL_SOFTNET)) { softint_deliver(ci, IPL_SOFTNET); continue; } KASSERT(old_ipl < IPL_SOFTBIO); if (softints & (1 << IPL_SOFTBIO)) { softint_deliver(ci, IPL_SOFTBIO); continue; } KASSERT(old_ipl < IPL_SOFTCLOCK); if (softints & (1 << IPL_SOFTCLOCK)) { softint_deliver(ci, IPL_SOFTCLOCK); continue; } #ifdef __HAVE_PREEMPTION KASSERT(old_ipl == IPL_NONE); KASSERT(softints == (1 << IPL_NONE)); ci->ci_data.cpu_softints ^= (1 << IPL_NONE); kpreempt(pc); #endif } } void powerpc_softint_init_md(lwp_t *l, u_int si_level, uintptr_t *machdep_p) { struct cpu_info * const ci = l->l_cpu; *machdep_p = 1 << SOFTINT2IPL(si_level); KASSERT(*machdep_p & IPL_SOFTMASK); ci->ci_softlwps[si_level] = l; } void powerpc_softint_trigger(uintptr_t machdep) { struct cpu_info * const ci = curcpu(); atomic_or_uint(&ci->ci_data.cpu_softints, machdep); } #endif /* __HAVE_FAST_SOFTINTS */