1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22/* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27#pragma ident "%Z%%M% %I% %E% SMI" 28 29 .file "%M%" 30 31#include <SYS.h> 32#include <sys/regset.h> 33#include <../assym.h> 34 35 /* 36 * This is where execution resumes when a thread created with 37 * thr_create() or pthread_create() returns (see setup_context()). 38 * We pass the (void *) return value to _thr_terminate(). 39 */ 40 ENTRY(_lwp_start) 41 movq %rax, %rdi 42 call _thr_terminate 43 RET /* actually, never returns */ 44 SET_SIZE(_lwp_start) 45 46 /* All we need to do now is (carefully) call lwp_exit(). */ 47 ENTRY(_lwp_terminate) 48 SYSTRAP_RVAL1(lwp_exit) 49 RET /* if we return, it is very bad */ 50 SET_SIZE(_lwp_terminate) 51 52 ENTRY(set_curthread) 53 movq %rdi, %fs:0 54 ret 55 SET_SIZE(set_curthread) 56 57 ENTRY(__lwp_park) 58 movq %rsi, %rdx 59 movq %rdi, %rsi 60 movq $0, %rdi 61 SYSTRAP_RVAL1(lwp_park) 62 SYSLWPERR 63 RET 64 SET_SIZE(__lwp_park) 65 66 ENTRY(__lwp_unpark) 67 movq %rdi, %rsi 68 movq $1, %rdi 69 SYSTRAP_RVAL1(lwp_park) 70 SYSLWPERR 71 RET 72 SET_SIZE(__lwp_unpark) 73 74 ENTRY(__lwp_unpark_all) 75 movq %rsi, %rdx 76 movq %rdi, %rsi 77 movq $2, %rdi 78 SYSTRAP_RVAL1(lwp_park) 79 SYSLWPERR 80 RET 81 SET_SIZE(__lwp_unpark_all) 82 83 ENTRY(lwp_yield) 84 SYSTRAP_RVAL1(yield) 85 RETC 86 SET_SIZE(lwp_yield) 87 88/* 89 * __sighndlr(int sig, siginfo_t *si, ucontext_t *uc, void (*hndlr)()) 90 * 91 * This is called from sigacthandler() for the entire purpose of 92 * communicating the ucontext to java's stack tracing functions. 93 */ 94 ENTRY(__sighndlr) 95 .globl __sighndlrend 96 pushq %rbp 97 movq %rsp, %rbp 98 call *%rcx 99 leave 100 ret 101__sighndlrend: 102 SET_SIZE(__sighndlr) 103 104/* 105 * int _sigsetjmp(sigjmp_buf env, int savemask) 106 * 107 * This version is faster than the old non-threaded version because we 108 * don't normally have to call __getcontext() to get the signal mask. 109 * (We have a copy of it in the ulwp_t structure.) 110 */ 111 112#undef sigsetjmp 113 114#if SIZEOF_SIGJMP_BUF < SIZEOF_UCONTEXT_T 115 116#error "sigjmp_buf is too small to contain a ucontext_t" 117 118#else 119 120#if defined(__GNUC_AS__) 121#define REGOFF(reg) ( reg * CLONGSIZE ) 122#else 123#define REGOFF(reg) [ reg \* CLONGSIZE ] 124#endif 125 126 ENTRY2(sigsetjmp,_sigsetjmp) 127 pushq %rbp 128 movq %rsp, %rbp 129 130 /* construct a complete gregset_t for __csigsetjmp */ 131 subq $REGOFF(_NGREG), %rsp 132 movq %r15, REGOFF(REG_R15) (%rsp) 133 movq %r14, REGOFF(REG_R14) (%rsp) 134 movq %r13, REGOFF(REG_R13) (%rsp) 135 movq %r12, REGOFF(REG_R12) (%rsp) 136 movq %r11, REGOFF(REG_R11) (%rsp) 137 movq %r10, REGOFF(REG_R10) (%rsp) 138 movq %r9, REGOFF(REG_R9) (%rsp) 139 movq %r8, REGOFF(REG_R8) (%rsp) 140 movq %rdi, REGOFF(REG_RDI) (%rsp) 141 movq %rsi, REGOFF(REG_RSI) (%rsp) 142 movq %rbx, REGOFF(REG_RBX) (%rsp) 143 movq %rdx, REGOFF(REG_RDX) (%rsp) 144 movq %rcx, REGOFF(REG_RCX) (%rsp) 145 movq $0, REGOFF(REG_RAX) (%rsp) 146 movq $0, REGOFF(REG_TRAPNO) (%rsp) 147 movq $0, REGOFF(REG_ERR) (%rsp) 148 xorq %rax, %rax 149 movw %cs, %ax 150 movq %rax, REGOFF(REG_CS) (%rsp) 151 movq $0, REGOFF(REG_RFL) (%rsp) 152 movw %ss, %ax 153 movq %rax, REGOFF(REG_SS) (%rsp) 154 movw %fs, %ax 155 movq %rax, REGOFF(REG_FS) (%rsp) 156 movw %gs, %ax 157 movq %rax, REGOFF(REG_GS) (%rsp) 158 movw %es, %ax 159 movq %rax, REGOFF(REG_ES) (%rsp) 160 movw %ds, %ax 161 movq %rax, REGOFF(REG_DS) (%rsp) 162 movq %fs:0, %rax 163 movq %rax, REGOFF(REG_FSBASE) (%rsp) 164 movq $0, REGOFF(REG_GSBASE) (%rsp) 165 166 movq (%rbp), %rax /* previous %rbp */ 167 movq %rax, REGOFF(REG_RBP) (%rsp) 168 movq 8(%rbp), %rax /* previous %rip */ 169 movq %rax, REGOFF(REG_RIP) (%rsp) 170 leaq 16(%rbp), %rax /* previous %rsp */ 171 movq %rax, REGOFF(REG_RSP) (%rsp) 172 173 movq %rsp, %rdx /* pointer to gregset_t */ 174 call __csigsetjmp 175 xorq %rax, %rax 176 leave 177 ret 178 SET_SIZE(sigsetjmp) 179 SET_SIZE(_sigsetjmp) 180 181#endif /* SIZEOF_SIGJMP_BUF < SIZEOF_UCONTEXT_T */ 182