1*cdecda8dSBrooks Davis/*- 2*cdecda8dSBrooks Davis * Copyright (c) 2000 Peter Wemm <peter@FreeBSD.org> 3*cdecda8dSBrooks Davis * Copyright (c) 2003 Alan L. Cox <alc@cs.rice.edu> 4*cdecda8dSBrooks Davis * All rights reserved. 5*cdecda8dSBrooks Davis * 6*cdecda8dSBrooks Davis * Redistribution and use in source and binary forms, with or without 7*cdecda8dSBrooks Davis * modification, are permitted provided that the following conditions 8*cdecda8dSBrooks Davis * are met: 9*cdecda8dSBrooks Davis * 1. Redistributions of source code must retain the above copyright 10*cdecda8dSBrooks Davis * notice, this list of conditions and the following disclaimer. 11*cdecda8dSBrooks Davis * 2. Redistributions in binary form must reproduce the above copyright 12*cdecda8dSBrooks Davis * notice, this list of conditions and the following disclaimer in the 13*cdecda8dSBrooks Davis * documentation and/or other materials provided with the distribution. 14*cdecda8dSBrooks Davis * 15*cdecda8dSBrooks Davis * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16*cdecda8dSBrooks Davis * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17*cdecda8dSBrooks Davis * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18*cdecda8dSBrooks Davis * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19*cdecda8dSBrooks Davis * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20*cdecda8dSBrooks Davis * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21*cdecda8dSBrooks Davis * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22*cdecda8dSBrooks Davis * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23*cdecda8dSBrooks Davis * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24*cdecda8dSBrooks Davis * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25*cdecda8dSBrooks Davis * SUCH DAMAGE. 26*cdecda8dSBrooks Davis */ 27*cdecda8dSBrooks Davis 28*cdecda8dSBrooks Davis#include <machine/asm.h> 29*cdecda8dSBrooks Davis/* 30*cdecda8dSBrooks Davis * With thanks to John Dyson for the original version of this. 31*cdecda8dSBrooks Davis */ 32*cdecda8dSBrooks Davis 33*cdecda8dSBrooks Davis#include <SYS.h> 34*cdecda8dSBrooks Davis 35*cdecda8dSBrooks Davis/* 36*cdecda8dSBrooks Davis * %edi %rsi %rdx %rcx 37*cdecda8dSBrooks Davis * rfork_thread(flags, stack_addr, start_fnc, start_arg); 38*cdecda8dSBrooks Davis * 39*cdecda8dSBrooks Davis * flags: Flags to rfork system call. See rfork(2). 40*cdecda8dSBrooks Davis * stack_addr: Top of stack for thread. 41*cdecda8dSBrooks Davis * start_fnc: Address of thread function to call in child. 42*cdecda8dSBrooks Davis * start_arg: Argument to pass to the thread function in child. 43*cdecda8dSBrooks Davis */ 44*cdecda8dSBrooks Davis 45*cdecda8dSBrooks DavisENTRY(rfork_thread) 46*cdecda8dSBrooks Davis pushq %rbx 47*cdecda8dSBrooks Davis pushq %r12 48*cdecda8dSBrooks Davis movq %rdx, %rbx 49*cdecda8dSBrooks Davis movq %rcx, %r12 50*cdecda8dSBrooks Davis 51*cdecda8dSBrooks Davis /* 52*cdecda8dSBrooks Davis * Prepare and execute the thread creation syscall 53*cdecda8dSBrooks Davis */ 54*cdecda8dSBrooks Davis _SYSCALL(rfork) 55*cdecda8dSBrooks Davis jb 2f 56*cdecda8dSBrooks Davis 57*cdecda8dSBrooks Davis /* 58*cdecda8dSBrooks Davis * Check to see if we are in the parent or child 59*cdecda8dSBrooks Davis */ 60*cdecda8dSBrooks Davis cmpl $0, %edx 61*cdecda8dSBrooks Davis jnz 1f 62*cdecda8dSBrooks Davis popq %r12 63*cdecda8dSBrooks Davis popq %rbx 64*cdecda8dSBrooks Davis ret 65*cdecda8dSBrooks Davis 66*cdecda8dSBrooks Davis /* 67*cdecda8dSBrooks Davis * If we are in the child (new thread), then 68*cdecda8dSBrooks Davis * set-up the call to the internal subroutine. If it 69*cdecda8dSBrooks Davis * returns, then call __exit. 70*cdecda8dSBrooks Davis */ 71*cdecda8dSBrooks Davis1: 72*cdecda8dSBrooks Davis movq %rsi, %rsp 73*cdecda8dSBrooks Davis movq %r12, %rdi 74*cdecda8dSBrooks Davis call *%rbx 75*cdecda8dSBrooks Davis movl %eax, %edi 76*cdecda8dSBrooks Davis 77*cdecda8dSBrooks Davis /* 78*cdecda8dSBrooks Davis * Exit system call 79*cdecda8dSBrooks Davis */ 80*cdecda8dSBrooks Davis _SYSCALL(exit) 81*cdecda8dSBrooks Davis 82*cdecda8dSBrooks Davis /* 83*cdecda8dSBrooks Davis * Branch here if the thread creation fails: 84*cdecda8dSBrooks Davis */ 85*cdecda8dSBrooks Davis2: 86*cdecda8dSBrooks Davis popq %r12 87*cdecda8dSBrooks Davis popq %rbx 88*cdecda8dSBrooks Davis jmp HIDENAME(cerror) 89*cdecda8dSBrooks DavisEND(rfork_thread) 90*cdecda8dSBrooks Davis 91*cdecda8dSBrooks Davis .section .note.GNU-stack,"",%progbits 92