$NetBSD: patch-au,v 1.3 2023/02/16 17:59:49 he Exp $ --- csw/netbsd.c.orig 2023-02-16 17:24:05.920061403 +0000 +++ csw/netbsd.c @@ -0,0 +1,138 @@ +/* + * netbsd.c -- context switch code for NetBSD 2. + * + * Some Makefile changes are needed to use this code. + */ + +#include + +void mpd_stk_underflow(void); +void mpd_stk_corrupted(void); + +static void startup(void (*)(void), unsigned long, unsigned long, unsigned long, unsigned long); + +#ifdef __i386__ +void pthread__i386_init(void); + +#define _setcontext_u(uc) (*_md_setcontext_u)(uc) +#define _swapcontext_u(oc,nc) (*_md_swapcontext_u)(oc,nc) + +static void mpd_setcontext_u(ucontext_t *); +static void mpd_swapcontext_u(ucontext_t *, ucontext_t *); + +void (*_md_getcontext_u) (ucontext_t *); +void (*_md_setcontext_u) (ucontext_t *) = mpd_setcontext_u; +void (*_md_swapcontext_u)(ucontext_t *, ucontext_t *) = mpd_swapcontext_u; + +static void +mpd_setcontext_u(ucontext_t *uc) { + pthread__i386_init(); + _setcontext_u(uc); +} + +static void +mpd_swapcontext_u(ucontext_t *oldc, ucontext_t *newc) { + pthread__i386_init(); + _swapcontext_u(oldc, newc); +} +#endif + +#ifdef __powerpc__ +void pthread__init(void); + +#define _setcontext_u(uc) (*_md_setcontext_u)(uc) +#define _swapcontext_u(oc,nc) (*_md_swapcontext_u)(oc,nc) + +static void mpd_setcontext_u(ucontext_t *); +static void mpd_swapcontext_u(ucontext_t *, ucontext_t *); + +void (*_md_getcontext_u) (ucontext_t *); +void (*_md_setcontext_u) (ucontext_t *) = mpd_setcontext_u; +void (*_md_swapcontext_u)(ucontext_t *, ucontext_t *) = mpd_swapcontext_u; + +static void +mpd_setcontext_u(ucontext_t *uc) { + pthread__init(); + setcontext(uc); +} + +static void +mpd_swapcontext_u(ucontext_t *oldc, ucontext_t *newc) { + pthread__init(); + swapcontext(oldc, newc); +} +#endif + + +/* + * mpd_build_context (func, buf, bufsize, arg1, arg2, arg3, arg4) + * + * Build a context that will call func(arg1,arg2,arg3,arg4) when activated + * and will catch an underflow error if func returns. We use an intermediary + * in order to catch that return. + */ +void +mpd_build_context (func, buf, bufsize, arg1, arg2, arg3, arg4) +void (*func)(); +char *buf; +int bufsize; +unsigned long arg1, arg2, arg3, arg4; +{ + ucontext_t *uc = (ucontext_t *) buf; /* put header at front of buf */ + + if (0 != getcontext(uc)) { /* initialize context */ + mpd_stk_corrupted(); + } + + uc->uc_stack.ss_sp = buf + sizeof (ucontext_t); + uc->uc_stack.ss_size = bufsize - sizeof (ucontext_t); + + makecontext (uc, startup, 5, func, arg1, arg2, arg3, arg4); + uc->uc_stack.ss_flags = 0; +} + +/* + * startup (func, a,b,c,d) -- intermediary for startup and underflow detection. + */ +static void +startup (func, arg1, arg2, arg3, arg4) +void (*func)(); +unsigned long arg1, arg2, arg3, arg4; +{ + (*func) (arg1, arg2, arg3, arg4); + mpd_stk_underflow(); +} + + + +/* + * mpd_chg_context (newctx, oldctx) -- change contexts. + */ +void +mpd_chg_context (new, old) +char *new, *old; +{ + ucontext_t *oldu, *newu; + newu = (ucontext_t *)new; + + if (old) { + oldu = (ucontext_t *)old; + _swapcontext_u(oldu, newu); + } else { + _setcontext_u(newu); + } +} + + + +/* + * mpd_check_stk (stk) -- check for stack overflow. + * + * We have no idea of how to do that, so we do nothing. + */ +void +mpd_check_stk(stk) +char *stk; +{ + /* nothing */ +}