ipi_latte.c revision 1.1
1/* $NetBSD: ipi_latte.c,v 1.1 2026/01/09 22:54:28 jmcneill Exp $ */
2
3/*-
4 * Copyright (c) 2025 Jared McNeill <jmcneill@invisible.ca>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/*
30 * Latte inter-processor interrupt support.
31 */
32
33#include <sys/cdefs.h>
34__KERNEL_RCSID(0, "$NetBSD: ipi_latte.c,v 1.1 2026/01/09 22:54:28 jmcneill Exp $");
35
36#include "opt_multiprocessor.h"
37
38#include <sys/param.h>
39#include <sys/kernel.h>
40#include <sys/atomic.h>
41#include <sys/cpu.h>
42#include <powerpc/pic/ipivar.h>
43#include <powerpc/include/spr.h>
44#include <powerpc/include/oea/spr.h>
45#include <machine/pio.h>
46#include <machine/wiiu.h>
47#include "ipi_latte.h"
48
49#ifdef MULTIPROCESSOR
50
51extern struct ipi_ops ipiops;
52
53static void
54ipi_latte_send_ipi(cpuid_t target, uint32_t mesg)
55{
56	struct cpu_info *ci = curcpu();
57	struct cpu_info *dst_ci;
58	uint32_t scr_mask = 0;
59	int n;
60
61	if (target == IPI_DST_ALL || target == IPI_DST_NOTME) {
62		for (n = 0; n < ncpu; n++) {
63			dst_ci = cpu_lookup(n);
64			if (target == IPI_DST_ALL || dst_ci != ci) {
65				atomic_or_32(&dst_ci->ci_pending_ipis, mesg);
66				scr_mask |= SPR_SCR_IPI_PEND(n);
67			}
68		}
69	} else {
70		dst_ci = cpu_lookup(target);
71		atomic_or_32(&dst_ci->ci_pending_ipis, mesg);
72		scr_mask |= SPR_SCR_IPI_PEND(target);
73	}
74
75	mtspr(SPR_SCR, mfspr(SPR_SCR) | scr_mask);
76}
77
78static void
79ipi_latte_establish_ipi(int type, int level, void *ih_args)
80{
81	char name[INTRDEVNAMEBUF];
82	int n;
83
84	for (n = 0; n < uimin(3, CPU_MAXNUM); n++) {
85		snprintf(name, sizeof(name), "IPI cpu%u", n);
86		intr_establish_xname(WIIU_PI_IRQ_MB_CPU(n), type, level,
87		    ipi_intr, ih_args, name);
88	}
89}
90
91void
92ipi_latte_init(void)
93{
94	ipiops.ppc_send_ipi = ipi_latte_send_ipi;
95	ipiops.ppc_establish_ipi = ipi_latte_establish_ipi;
96}
97
98#endif /* !MULTIPROCESSOR */
99