Index: arch/arm64/arm64/cpu.c =================================================================== RCS file: /cvs/src/sys/arch/arm64/arm64/cpu.c,v diff -u -p -r1.142 cpu.c --- arch/arm64/arm64/cpu.c 1 Jul 2025 11:10:36 -0000 1.142 +++ arch/arm64/arm64/cpu.c 4 Jul 2025 02:00:08 -0000 @@ -1595,6 +1595,8 @@ cpu_attach(struct device *parent, struct } #ifdef MULTIPROCESSOR } + + cpu_xcall_establish(ci); #endif #if NKSTAT > 0 Index: arch/arm64/conf/files.arm64 =================================================================== RCS file: /cvs/src/sys/arch/arm64/conf/files.arm64,v diff -u -p -r1.74 files.arm64 --- arch/arm64/conf/files.arm64 7 Jun 2025 15:11:12 -0000 1.74 +++ arch/arm64/conf/files.arm64 4 Jul 2025 02:00:08 -0000 @@ -53,7 +53,7 @@ file arch/arm64/arm64/openprom.c openpr # mainbus files define mainbus {} -device mainbus: fdt +device mainbus: fdt, xcall attach mainbus at root file arch/arm64/dev/mainbus.c mainbus Index: arch/arm64/include/cpu.h =================================================================== RCS file: /cvs/src/sys/arch/arm64/include/cpu.h,v diff -u -p -r1.51 cpu.h --- arch/arm64/include/cpu.h 11 Feb 2025 22:27:09 -0000 1.51 +++ arch/arm64/include/cpu.h 4 Jul 2025 02:00:08 -0000 @@ -111,6 +111,7 @@ void cpu_identify_cleanup(void); #include #include #include +#include #include struct cpu_info { @@ -167,6 +168,7 @@ struct cpu_info { #ifdef MULTIPROCESSOR struct srp_hazard ci_srp_hazards[SRP_HAZARD_NUM]; + struct xcall_cpu ci_xcall; #define __HAVE_UVM_PERCPU struct uvm_pmr_cache ci_uvm; volatile int ci_flags; Index: arch/arm64/include/intr.h =================================================================== RCS file: /cvs/src/sys/arch/arm64/include/intr.h,v diff -u -p -r1.25 intr.h --- arch/arm64/include/intr.h 30 Jun 2025 14:19:20 -0000 1.25 +++ arch/arm64/include/intr.h 4 Jul 2025 02:00:08 -0000 @@ -199,6 +199,9 @@ extern void (*intr_send_ipi_func)(struct #define ARM_IPI_NOP 0 #define ARM_IPI_DDB 1 #define ARM_IPI_HALT 2 +#define ARM_IPI_XCALL 3 + +#define cpu_xcall_ipi(_ci) arm_send_ipi((_ci), ARM_IPI_XCALL) #ifdef DIAGNOSTIC /* Index: conf/files =================================================================== RCS file: /cvs/src/sys/conf/files,v diff -u -p -r1.745 files --- conf/files 23 Apr 2025 21:40:22 -0000 1.745 +++ conf/files 4 Jul 2025 02:00:10 -0000 @@ -23,6 +23,7 @@ define onewirebus {} define video {} define intrmap {} define fdt {[early = 0]} +define xcall # filesystem firmware loading attribute define firmload @@ -750,6 +751,7 @@ file kern/kern_uuid.c file kern/kern_watchdog.c !small_kernel file kern/kern_task.c file kern/kern_srp.c +file kern/kern_xcall.c xcall file kern/kern_xxx.c file kern/sched_bsd.c file kern/subr_autoconf.c Index: kern/kern_xcall.c =================================================================== RCS file: kern/kern_xcall.c diff -N kern/kern_xcall.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ kern/kern_xcall.c 4 Jul 2025 02:00:15 -0000 @@ -0,0 +1,138 @@ +/* $OpenBSD$ */ + +/* + * Copyright (c) 2025 David Gwynne + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include + +#include + +#include + +#define IPL_XCALL IPL_SOFTCLOCK + +void +cpu_xcall_init(struct xcall *xc, void (*func)(void *), void *arg) +{ + xc->xc_func = func; + xc->xc_arg = arg; + refcnt_init(&xc->xc_refs); +} + +static inline void +cpu_xcall_self(struct xcall *xc) +{ + int s; + + s = splraise(IPL_XCALL); + xc->xc_func(xc->xc_arg); + splx(s); +} + +#ifdef MULTIPROCESSOR + +static void +cpu_xcall_handler(void *arg) +{ + struct xcall_cpu *xci = arg; + struct xcall *xc; + size_t i; + + for (i = 0; i < nitems(xci->xci_xcalls); i++) { + xc = xci->xci_xcalls[i]; + if (xc != NULL) { + xci->xci_xcalls[i] = NULL; + (*xc->xc_func)(xc->xc_arg); + refcnt_rele_wake(&xc->xc_refs); + } + } +} + +void +cpu_xcall(struct cpu_info *ci, struct xcall *xc) +{ + struct xcall_cpu *xci = &ci->ci_xcall; + size_t i; + + refcnt_take(&xc->xc_refs); + + if (ci == curcpu()) { + /* execute the task immediately on the local cpu */ + cpu_xcall_self(xc); + return; + } + + for (;;) { + for (i = 0; i < nitems(xci->xci_xcalls); i++) { + if (atomic_cas_ptr(&xci->xci_xcalls[i], + NULL, xc) != NULL) + continue; + + cpu_xcall_ipi(ci); + return; + } + + CPU_BUSY_CYCLE(); + } +} + +void +cpu_xcall_wait(struct xcall *xc, const char *wmesg) +{ + refcnt_finalize(&xc->xc_refs, wmesg); +} + +void +cpu_xcall_establish(struct cpu_info *ci) +{ + struct xcall_cpu *xci = &ci->ci_xcall; + size_t i; + + for (i = 0; i < nitems(xci->xci_xcalls); i++) + xci->xci_xcalls[i] = NULL; + + xci->xci_softintr = softintr_establish(IPL_XCALL | IPL_MPSAFE, + cpu_xcall_handler, xci); +} + +void +cpu_xcall_dispatch(struct cpu_info *ci) +{ + struct xcall_cpu *xci = &ci->ci_xcall; + + softintr_schedule(xci->xci_softintr); +} + +#else /* MULTIPROCESSOR */ + +/* + * uniprocessor implementation + */ + +void +cpu_xcall(struct cpu_info *ci, struct xcall *xc) +{ + cpu_xcall_self(xc); +} + +void +cpu_xcall_wait(struct xcall *xc, const char *wmesg) +{ + /* nop - the xcall has already been run */ +} +#endif /* MULTIPROCESSOR */ Index: sys/xcall.h =================================================================== RCS file: sys/xcall.h diff -N sys/xcall.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/xcall.h 4 Jul 2025 02:00:15 -0000 @@ -0,0 +1,55 @@ +/* $OpenBSD$ */ + +/* + * Copyright (c) 2025 David Gwynne + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _SYS_XCALL_H +#define _SYS_XCALL_H + +#include + +struct xcall { + void (*xc_func)(void *); + void *xc_arg; + struct refcnt xc_refs; +}; + +/* MD code adds this to struct cpu_info as ci_xcall */ +struct xcall_cpu { + struct xcall *xci_xcalls[4]; + void *xci_softintr; +}; + +#ifdef _KERNEL + +#define XCALL_INITIALIZER(_func, _arg) { \ + .xc_func = _func, \ + .xc_arg = _arg, \ + .xc_refs = REFCNT_INITIALIZER(), \ +} + +void cpu_xcall_init(struct xcall *, void (*)(void *), void *); +void cpu_xcall(struct cpu_info *, struct xcall *); +void cpu_xcall_wait(struct xcall *, const char *); + +/* MD cpu setup calls this */ +void cpu_xcall_establish(struct cpu_info *); +/* MD ipi handler calls this */ +void cpu_xcall_dispatch(struct cpu_info *); + +#endif /* _KERNEL */ + +#endif /* _SYS_XCALL_H */