Home | History | Annotate | Line # | Download | only in powerpc
      1 /*	$NetBSD: softint_machdep.c,v 1.4 2020/01/08 17:38:42 ad Exp $	*/
      2 /*-
      3  * Copyright (c) 2010, 2011 The NetBSD Foundation, Inc.
      4  * All rights reserved.
      5  *
      6  * This code is derived from software contributed to The NetBSD Foundation
      7  * by Raytheon BBN Technologies Corp and Defense Advanced Research Projects
      8  * Agency and which was developed by Matt Thomas of 3am Software Foundry.
      9  *
     10  * This material is based upon work supported by the Defense Advanced Research
     11  * Projects Agency and Space and Naval Warfare Systems Center, Pacific, under
     12  * Contract No. N66001-09-C-2073.
     13  * Approved for Public Release, Distribution Unlimited
     14  *
     15  * Redistribution and use in source and binary forms, with or without
     16  * modification, are permitted provided that the following conditions
     17  * are met:
     18  * 1. Redistributions of source code must retain the above copyright
     19  *    notice, this list of conditions and the following disclaimer.
     20  * 2. Redistributions in binary form must reproduce the above copyright
     21  *    notice, this list of conditions and the following disclaimer in the
     22  *    documentation and/or other materials provided with the distribution.
     23  *
     24  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     25  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     26  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     27  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     28  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     29  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     30  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     31  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     32  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     33  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     34  * POSSIBILITY OF SUCH DAMAGE.
     35  */
     36 
     37 #define __INTR_PRIVATE
     38 
     39 #include <sys/param.h>
     40 #include <sys/intr.h>
     41 #include <sys/cpu.h>
     42 #include <sys/atomic.h>
     43 
     44 #ifdef __HAVE_FAST_SOFTINTS
     45 #include <powerpc/softint.h>
     46 
     47 __CTASSERT(IPL_NONE < IPL_SOFTCLOCK);
     48 __CTASSERT(IPL_SOFTCLOCK < IPL_SOFTBIO);
     49 __CTASSERT(IPL_SOFTBIO < IPL_SOFTNET);
     50 __CTASSERT(IPL_SOFTNET < IPL_SOFTSERIAL);
     51 __CTASSERT(IPL_SOFTSERIAL < IPL_VM);
     52 __CTASSERT(IPL_SOFTSERIAL < sizeof(uint32_t)*2);
     53 
     54 static inline void
     55 softint_deliver(struct cpu_info *ci, int ipl)
     56 {
     57 	const int si_level = IPL2SOFTINT(ipl);
     58 	KASSERT(ci->ci_data.cpu_softints & (1 << ipl));
     59 	ci->ci_data.cpu_softints ^= 1 << ipl;
     60 	softint_fast_dispatch(ci->ci_softlwps[si_level], ipl);
     61 	KASSERTMSG(ci->ci_cpl == IPL_HIGH,
     62 	    "%s: cpl (%d) != HIGH", __func__, ci->ci_cpl);
     63 }
     64 
     65 void
     66 powerpc_softint(struct cpu_info *ci, int old_ipl, vaddr_t pc)
     67 {
     68 	const u_int softint_mask = (IPL_SOFTMASK << old_ipl) & IPL_SOFTMASK;
     69 	u_int softints;
     70 
     71 	KASSERTMSG(ci->ci_idepth == -1,
     72 	    "%s: cpu%u: idepth (%d) != -1", __func__,
     73 	     cpu_index(ci), ci->ci_idepth);
     74 	KASSERT(ci->ci_mtx_count == 0);
     75 	KASSERT(ci->ci_cpl == IPL_HIGH);
     76 	while ((softints = (ci->ci_data.cpu_softints & softint_mask)) != 0) {
     77 		KASSERT(old_ipl < IPL_SOFTSERIAL);
     78 		if (softints & (1 << IPL_SOFTSERIAL)) {
     79 			softint_deliver(ci, IPL_SOFTSERIAL);
     80 			continue;
     81 		}
     82 		KASSERT(old_ipl < IPL_SOFTNET);
     83 		if (softints & (1 << IPL_SOFTNET)) {
     84 			softint_deliver(ci, IPL_SOFTNET);
     85 			continue;
     86 		}
     87 		KASSERT(old_ipl < IPL_SOFTBIO);
     88 		if (softints & (1 << IPL_SOFTBIO)) {
     89 			softint_deliver(ci, IPL_SOFTBIO);
     90 			continue;
     91 		}
     92 		KASSERT(old_ipl < IPL_SOFTCLOCK);
     93 		if (softints & (1 << IPL_SOFTCLOCK)) {
     94 			softint_deliver(ci, IPL_SOFTCLOCK);
     95 			continue;
     96 		}
     97 #ifdef __HAVE_PREEMPTION
     98 		KASSERT(old_ipl == IPL_NONE);
     99 		KASSERT(softints == (1 << IPL_NONE));
    100 		ci->ci_data.cpu_softints ^= (1 << IPL_NONE);
    101 		kpreempt(pc);
    102 #endif
    103 	}
    104 }
    105 
    106 void
    107 powerpc_softint_init_md(lwp_t *l, u_int si_level, uintptr_t *machdep_p)
    108 {
    109 	struct cpu_info * const ci = l->l_cpu;
    110 
    111 	*machdep_p = 1 << SOFTINT2IPL(si_level);
    112 	KASSERT(*machdep_p & IPL_SOFTMASK);
    113 	ci->ci_softlwps[si_level] = l;
    114 }
    115 
    116 void
    117 powerpc_softint_trigger(uintptr_t machdep)
    118 {
    119 	struct cpu_info * const ci = curcpu();
    120 
    121 	atomic_or_uint(&ci->ci_data.cpu_softints, machdep);
    122 }
    123 
    124 #endif /* __HAVE_FAST_SOFTINTS */
    125