makecontext.c revision 1.2
11.2Sperry/* $NetBSD: makecontext.c,v 1.2 2005/12/24 21:41:01 perry Exp $ */ 21.1Schs 31.1Schs/*- 41.1Schs * Copyright (c) 2001 The NetBSD Foundation, Inc. 51.1Schs * All rights reserved. 61.1Schs * 71.1Schs * This code is derived from software contributed to The NetBSD Foundation 81.1Schs * by Klaus Klein. 91.1Schs * 101.1Schs * Redistribution and use in source and binary forms, with or without 111.1Schs * modification, are permitted provided that the following conditions 121.1Schs * are met: 131.1Schs * 1. Redistributions of source code must retain the above copyright 141.1Schs * notice, this list of conditions and the following disclaimer. 151.1Schs * 2. Redistributions in binary form must reproduce the above copyright 161.1Schs * notice, this list of conditions and the following disclaimer in the 171.1Schs * documentation and/or other materials provided with the distribution. 181.1Schs * 3. All advertising materials mentioning features or use of this software 191.1Schs * must display the following acknowledgement: 201.1Schs * This product includes software developed by the NetBSD 211.1Schs * Foundation, Inc. and its contributors. 221.1Schs * 4. Neither the name of The NetBSD Foundation nor the names of its 231.1Schs * contributors may be used to endorse or promote products derived 241.1Schs * from this software without specific prior written permission. 251.1Schs * 261.1Schs * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 271.1Schs * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 281.1Schs * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 291.1Schs * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 301.1Schs * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 311.1Schs * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 321.1Schs * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 331.1Schs * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 341.1Schs * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 351.1Schs * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 361.1Schs * POSSIBILITY OF SUCH DAMAGE. 371.1Schs */ 381.1Schs 391.1Schs#include <sys/cdefs.h> 401.1Schs#if defined(LIBC_SCCS) && !defined(lint) 411.2Sperry__RCSID("$NetBSD: makecontext.c,v 1.2 2005/12/24 21:41:01 perry Exp $"); 421.1Schs#endif 431.1Schs 441.1Schs#include <inttypes.h> 451.1Schs#include <stddef.h> 461.1Schs#include <ucontext.h> 471.1Schs#include "extern.h" 481.1Schs 491.1Schs#include <stdarg.h> 501.1Schs 511.1Schs#include <sys/types.h> 521.1Schs#include <machine/frame.h> 531.1Schs 541.1Schsvoid 551.1Schsmakecontext(ucontext_t *ucp, void (*func)(void), int argc, ...) 561.1Schs{ 571.1Schs __greg_t *gr = ucp->uc_mcontext.__gregs; 581.1Schs __greg_t *gp, rp, fp; 591.2Sperry register __greg_t dp __asm("r27"); 601.1Schs uintptr_t *sp; 611.1Schs int i; 621.1Schs va_list ap; 631.1Schs 641.1Schs void __resumecontext(void); 651.1Schs 661.1Schs /* LINTED uintptr_t is safe */ 671.1Schs sp = (uintptr_t *)ucp->uc_stack.ss_sp; 681.1Schs /* LINTED uintptr_t is safe */ 691.1Schs sp += 16; /* standard frame */ 701.1Schs sp += (argc >= 4 ? argc : 4); /* Make room for >=4 arguments. */ 711.1Schs sp = (uintptr_t *) 721.1Schs ((uintptr_t)(sp + 16) & ~0x3f); /* Align on 64-byte boundary. */ 731.1Schs 741.1Schs /* Save away the registers that we'll need. */ 751.1Schs gr[_REG_SP] = (__greg_t)sp; 761.1Schs rp = (__greg_t)__resumecontext; 771.1Schs if (rp & 2) { 781.1Schs gp = (__greg_t *)(rp & ~3); 791.1Schs rp = gp[0]; 801.1Schs sp[-8] = gp[1]; 811.1Schs } 821.1Schs gr[_REG_RP] = rp; 831.1Schs fp = (__greg_t)func; 841.1Schs if (fp & 2) { 851.1Schs gp = (__greg_t *)(fp & ~3); 861.1Schs fp = gp[0]; 871.1Schs gr[_REG_R19] = gp[1]; 881.1Schs } 891.1Schs gr[_REG_PCOQH] = fp | HPPA_PC_PRIV_USER; 901.1Schs gr[_REG_PCOQT] = (fp + 4) | HPPA_PC_PRIV_USER; 911.1Schs gr[_REG_DP] = dp; 921.1Schs 931.1Schs /* Construct argument list. */ 941.1Schs va_start(ap, argc); 951.1Schs /* Up to the first four arguments are passed in %arg0-3. */ 961.1Schs for (i = 0; i < argc && i < 4; i++) { 971.1Schs /* LINTED uintptr_t is safe */ 981.1Schs gr[_REG_ARG0 - i] = va_arg(ap, uintptr_t); 991.1Schs } 1001.1Schs /* Pass remaining arguments on the stack below the %arg0-3 gap. */ 1011.1Schs for (; i < argc; i++) { 1021.1Schs /* LINTED uintptr_t is safe */ 1031.1Schs sp[-9 - i] = va_arg(ap, uintptr_t); 1041.1Schs } 1051.1Schs va_end(ap); 1061.1Schs} 107