ipi_latte.c revision 1.1
11.1Sjmcneill/* $NetBSD: ipi_latte.c,v 1.1 2026/01/09 22:54:28 jmcneill Exp $ */
21.1Sjmcneill
31.1Sjmcneill/*-
41.1Sjmcneill * Copyright (c) 2025 Jared McNeill <jmcneill@invisible.ca>
51.1Sjmcneill * All rights reserved.
61.1Sjmcneill *
71.1Sjmcneill * Redistribution and use in source and binary forms, with or without
81.1Sjmcneill * modification, are permitted provided that the following conditions
91.1Sjmcneill * are met:
101.1Sjmcneill * 1. Redistributions of source code must retain the above copyright
111.1Sjmcneill *    notice, this list of conditions and the following disclaimer.
121.1Sjmcneill * 2. Redistributions in binary form must reproduce the above copyright
131.1Sjmcneill *    notice, this list of conditions and the following disclaimer in the
141.1Sjmcneill *    documentation and/or other materials provided with the distribution.
151.1Sjmcneill *
161.1Sjmcneill * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
171.1Sjmcneill * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
181.1Sjmcneill * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
191.1Sjmcneill * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
201.1Sjmcneill * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
211.1Sjmcneill * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
221.1Sjmcneill * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
231.1Sjmcneill * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
241.1Sjmcneill * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
251.1Sjmcneill * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
261.1Sjmcneill * POSSIBILITY OF SUCH DAMAGE.
271.1Sjmcneill */
281.1Sjmcneill
291.1Sjmcneill/*
301.1Sjmcneill * Latte inter-processor interrupt support.
311.1Sjmcneill */
321.1Sjmcneill
331.1Sjmcneill#include <sys/cdefs.h>
341.1Sjmcneill__KERNEL_RCSID(0, "$NetBSD: ipi_latte.c,v 1.1 2026/01/09 22:54:28 jmcneill Exp $");
351.1Sjmcneill
361.1Sjmcneill#include "opt_multiprocessor.h"
371.1Sjmcneill
381.1Sjmcneill#include <sys/param.h>
391.1Sjmcneill#include <sys/kernel.h>
401.1Sjmcneill#include <sys/atomic.h>
411.1Sjmcneill#include <sys/cpu.h>
421.1Sjmcneill#include <powerpc/pic/ipivar.h>
431.1Sjmcneill#include <powerpc/include/spr.h>
441.1Sjmcneill#include <powerpc/include/oea/spr.h>
451.1Sjmcneill#include <machine/pio.h>
461.1Sjmcneill#include <machine/wiiu.h>
471.1Sjmcneill#include "ipi_latte.h"
481.1Sjmcneill
491.1Sjmcneill#ifdef MULTIPROCESSOR
501.1Sjmcneill
511.1Sjmcneillextern struct ipi_ops ipiops;
521.1Sjmcneill
531.1Sjmcneillstatic void
541.1Sjmcneillipi_latte_send_ipi(cpuid_t target, uint32_t mesg)
551.1Sjmcneill{
561.1Sjmcneill	struct cpu_info *ci = curcpu();
571.1Sjmcneill	struct cpu_info *dst_ci;
581.1Sjmcneill	uint32_t scr_mask = 0;
591.1Sjmcneill	int n;
601.1Sjmcneill
611.1Sjmcneill	if (target == IPI_DST_ALL || target == IPI_DST_NOTME) {
621.1Sjmcneill		for (n = 0; n < ncpu; n++) {
631.1Sjmcneill			dst_ci = cpu_lookup(n);
641.1Sjmcneill			if (target == IPI_DST_ALL || dst_ci != ci) {
651.1Sjmcneill				atomic_or_32(&dst_ci->ci_pending_ipis, mesg);
661.1Sjmcneill				scr_mask |= SPR_SCR_IPI_PEND(n);
671.1Sjmcneill			}
681.1Sjmcneill		}
691.1Sjmcneill	} else {
701.1Sjmcneill		dst_ci = cpu_lookup(target);
711.1Sjmcneill		atomic_or_32(&dst_ci->ci_pending_ipis, mesg);
721.1Sjmcneill		scr_mask |= SPR_SCR_IPI_PEND(target);
731.1Sjmcneill	}
741.1Sjmcneill
751.1Sjmcneill	mtspr(SPR_SCR, mfspr(SPR_SCR) | scr_mask);
761.1Sjmcneill}
771.1Sjmcneill
781.1Sjmcneillstatic void
791.1Sjmcneillipi_latte_establish_ipi(int type, int level, void *ih_args)
801.1Sjmcneill{
811.1Sjmcneill	char name[INTRDEVNAMEBUF];
821.1Sjmcneill	int n;
831.1Sjmcneill
841.1Sjmcneill	for (n = 0; n < uimin(3, CPU_MAXNUM); n++) {
851.1Sjmcneill		snprintf(name, sizeof(name), "IPI cpu%u", n);
861.1Sjmcneill		intr_establish_xname(WIIU_PI_IRQ_MB_CPU(n), type, level,
871.1Sjmcneill		    ipi_intr, ih_args, name);
881.1Sjmcneill	}
891.1Sjmcneill}
901.1Sjmcneill
911.1Sjmcneillvoid
921.1Sjmcneillipi_latte_init(void)
931.1Sjmcneill{
941.1Sjmcneill	ipiops.ppc_send_ipi = ipi_latte_send_ipi;
951.1Sjmcneill	ipiops.ppc_establish_ipi = ipi_latte_establish_ipi;
961.1Sjmcneill}
971.1Sjmcneill
981.1Sjmcneill#endif /* !MULTIPROCESSOR */
99