xref: /netbsd-src/sys/arch/powerpc/pic/ipi.c (revision 3969ec72439319ca33f15191ddc17f2e336317e2)
1*3969ec72Srin /* $NetBSD: ipi.c,v 1.16 2020/07/06 11:01:24 rin Exp $ */
2d974db0aSgarbled /*-
3d974db0aSgarbled  * Copyright (c) 2007 The NetBSD Foundation, Inc.
4d974db0aSgarbled  * All rights reserved.
5d974db0aSgarbled  *
6d974db0aSgarbled  * This code is derived from software contributed to The NetBSD Foundation
7d974db0aSgarbled  * by Tim Rightnour
8d974db0aSgarbled  *
9d974db0aSgarbled  * Redistribution and use in source and binary forms, with or without
10d974db0aSgarbled  * modification, are permitted provided that the following conditions
11d974db0aSgarbled  * are met:
12d974db0aSgarbled  * 1. Redistributions of source code must retain the above copyright
13d974db0aSgarbled  *    notice, this list of conditions and the following disclaimer.
14d974db0aSgarbled  * 2. Redistributions in binary form must reproduce the above copyright
15d974db0aSgarbled  *    notice, this list of conditions and the following disclaimer in the
16d974db0aSgarbled  *    documentation and/or other materials provided with the distribution.
17d974db0aSgarbled  *
18d974db0aSgarbled  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
19d974db0aSgarbled  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20d974db0aSgarbled  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21d974db0aSgarbled  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
22d974db0aSgarbled  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23d974db0aSgarbled  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24d974db0aSgarbled  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25d974db0aSgarbled  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26d974db0aSgarbled  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27d974db0aSgarbled  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28d974db0aSgarbled  * POSSIBILITY OF SUCH DAMAGE.
29d974db0aSgarbled  */
30d974db0aSgarbled 
31d974db0aSgarbled #include <sys/cdefs.h>
32*3969ec72Srin __KERNEL_RCSID(0, "$NetBSD: ipi.c,v 1.16 2020/07/06 11:01:24 rin Exp $");
33d974db0aSgarbled 
3416031f7dSrin #ifdef _KERNEL_OPT
35d974db0aSgarbled #include "opt_multiprocessor.h"
3616031f7dSrin #endif
37d974db0aSgarbled 
38d974db0aSgarbled #include <sys/param.h>
39d974db0aSgarbled #include <sys/kernel.h>
40f66e2cf3Srmind #include <sys/xcall.h>
418011b285Srmind #include <sys/ipi.h>
4201fd9255Smatt #include <sys/atomic.h>
4301fd9255Smatt #include <sys/cpu.h>
44d974db0aSgarbled 
45bc7ec336Smatt #include <powerpc/psl.h>
46bc7ec336Smatt 
47bc7ec336Smatt #include <powerpc/pic/picvar.h>
48bc7ec336Smatt #include <powerpc/pic/ipivar.h>
49d974db0aSgarbled 
50d974db0aSgarbled #ifdef MULTIPROCESSOR
51d974db0aSgarbled 
52d974db0aSgarbled struct ipi_ops ipiops;
53d974db0aSgarbled 
54d974db0aSgarbled /* Process an actual IPI */
55d974db0aSgarbled 
56d974db0aSgarbled int
ipi_intr(void * v)5701fd9255Smatt ipi_intr(void *v)
58d974db0aSgarbled {
5901fd9255Smatt 	struct cpu_info * const ci = curcpu();
6001fd9255Smatt 	int cpu_id = cpu_index(ci);
61d974db0aSgarbled 	int msr;
6201fd9255Smatt 	uint32_t ipi;
63d974db0aSgarbled 
6401fd9255Smatt 	ci->ci_ev_ipi.ev_count++;
6501fd9255Smatt 	ipi = atomic_swap_32(&ci->ci_pending_ipis, 0);
66d974db0aSgarbled 
6701fd9255Smatt 	if (ipi == IPI_NOMESG)
68d974db0aSgarbled 		return 1;
69d974db0aSgarbled 
7001fd9255Smatt 	if (ipi & IPI_XCALL)
711840edb9Srmind 		xc_ipi_handler();
721840edb9Srmind 
738011b285Srmind 	if (ipi & IPI_GENERIC)
748011b285Srmind 		ipi_cpu_handler();
758011b285Srmind 
76ef2e796fSnonaka 	if (ipi & IPI_SUSPEND)
77ef2e796fSnonaka 		cpu_pause(NULL);
78ef2e796fSnonaka 
79b1bd2e89Sad 	if (ipi & IPI_AST)
8057eb66c6Sad 		ci->ci_onproc->l_md.md_astpending = 1;
81b1bd2e89Sad 
8201fd9255Smatt 	if (ipi & IPI_HALT) {
83ef2e796fSnonaka 		struct cpuset_info * const csi = &cpuset_info;
84d974db0aSgarbled 		aprint_normal("halting CPU %d\n", cpu_id);
85ef2e796fSnonaka 		kcpuset_set(csi->cpus_halted, cpu_id);
86d974db0aSgarbled 		msr = (mfmsr() & ~PSL_EE) | PSL_POW;
87d974db0aSgarbled 		for (;;) {
88d974db0aSgarbled 			__asm volatile ("sync; isync");
89d974db0aSgarbled 			mtmsr(msr);
90d974db0aSgarbled 		}
91d974db0aSgarbled 	}
921840edb9Srmind 
93d974db0aSgarbled 	return 1;
94d974db0aSgarbled }
95d974db0aSgarbled #endif /*MULTIPROCESSOR*/
96