11b773b6eSMarkus Pfeiffer/* 21b773b6eSMarkus Pfeiffer * Copyright (c) 2006 The DragonFly Project. All rights reserved. 31b773b6eSMarkus Pfeiffer * 41b773b6eSMarkus Pfeiffer * This code is derived from software contributed to The DragonFly Project 51b773b6eSMarkus Pfeiffer * by Matthew Dillon <dillon@backplane.com> 61b773b6eSMarkus Pfeiffer * 71b773b6eSMarkus Pfeiffer * Redistribution and use in source and binary forms, with or without 81b773b6eSMarkus Pfeiffer * modification, are permitted provided that the following conditions 91b773b6eSMarkus Pfeiffer * are met: 101b773b6eSMarkus Pfeiffer * 111b773b6eSMarkus Pfeiffer * 1. Redistributions of source code must retain the above copyright 121b773b6eSMarkus Pfeiffer * notice, this list of conditions and the following disclaimer. 131b773b6eSMarkus Pfeiffer * 2. Redistributions in binary form must reproduce the above copyright 141b773b6eSMarkus Pfeiffer * notice, this list of conditions and the following disclaimer in 151b773b6eSMarkus Pfeiffer * the documentation and/or other materials provided with the 161b773b6eSMarkus Pfeiffer * distribution. 171b773b6eSMarkus Pfeiffer * 3. Neither the name of The DragonFly Project nor the names of its 181b773b6eSMarkus Pfeiffer * contributors may be used to endorse or promote products derived 191b773b6eSMarkus Pfeiffer * from this software without specific, prior written permission. 201b773b6eSMarkus Pfeiffer * 211b773b6eSMarkus Pfeiffer * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 221b773b6eSMarkus Pfeiffer * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 231b773b6eSMarkus Pfeiffer * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 241b773b6eSMarkus Pfeiffer * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 251b773b6eSMarkus Pfeiffer * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 261b773b6eSMarkus Pfeiffer * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 271b773b6eSMarkus Pfeiffer * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 281b773b6eSMarkus Pfeiffer * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 291b773b6eSMarkus Pfeiffer * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 301b773b6eSMarkus Pfeiffer * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 311b773b6eSMarkus Pfeiffer * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 321b773b6eSMarkus Pfeiffer * SUCH DAMAGE. 331b773b6eSMarkus Pfeiffer * 341b773b6eSMarkus Pfeiffer */ 351b773b6eSMarkus Pfeiffer 361b773b6eSMarkus Pfeiffer#include <machine/asm.h> 3763261abbSMatthew Dillon#include <cpu/specialreg.h> 381b773b6eSMarkus Pfeiffer#include <asmcontext.h> 391b773b6eSMarkus Pfeiffer 401b773b6eSMarkus Pfeiffer /* 411b773b6eSMarkus Pfeiffer * This function is special-cased because the context it saves 421b773b6eSMarkus Pfeiffer * includes a stale stack context (because it returns before the 431b773b6eSMarkus Pfeiffer * caller presumably makes the call to setcontext()). 441b773b6eSMarkus Pfeiffer */ 451b773b6eSMarkus Pfeiffer .weak getcontext 461b773b6eSMarkus Pfeiffer .set getcontext,_getcontext 471b773b6eSMarkus PfeifferENTRY(_getcontext) 481b773b6eSMarkus Pfeiffer /* 491b773b6eSMarkus Pfeiffer * Retrieve the current signal mask and save it in &ucp->uc_sigmask. 501b773b6eSMarkus Pfeiffer */ 511b773b6eSMarkus Pfeiffer pushq %rdi /* save ucontext_t pointer passed */ 521b773b6eSMarkus Pfeiffer movq %rdi,%rdx 531b773b6eSMarkus Pfeiffer addq $UC_SIGMASK,%rdx /* pointer to signal mask */ 541b773b6eSMarkus Pfeiffer movq $0,%rsi 551b773b6eSMarkus Pfeiffer movq $SIG_BLOCK,%rdi 561b773b6eSMarkus Pfeiffer call PIC_PLT(CNAME(_sigprocmask)) 571b773b6eSMarkus Pfeiffer /* 581b773b6eSMarkus Pfeiffer * Save what we need because our stack context is going stale. 591b773b6eSMarkus Pfeiffer */ 601b773b6eSMarkus Pfeiffer popq %rdi 6163261abbSMatthew Dillon movq $0,UC_LINK(%rdi) /* make sure UC_LINK is clear */ 6263261abbSMatthew Dillon movq %rdi,%r9 /* save ucontext in %r9 */ 6363261abbSMatthew Dillon movq (%rsp),%r8 /* save return PC in %r8 */ 641b773b6eSMarkus Pfeiffer addq $UC_MCONTEXT,%rdi 6563261abbSMatthew Dillon 6663261abbSMatthew Dillon movq $0,MC_ONSTACK(%rdi) /* MC_ONSTACK(%rdi) */ 6763261abbSMatthew Dillon movq %rdi,MC_RDI(%rdi) 6863261abbSMatthew Dillon movq %rsi,MC_RSI(%rdi) 6963261abbSMatthew Dillon movq %rdx,MC_RDX(%rdi) 7063261abbSMatthew Dillon movq %r8,MC_R8(%rdi) 7163261abbSMatthew Dillon movq %r9,MC_R9(%rdi) 7263261abbSMatthew Dillon /* movq %rax,MC_RAX(%rdi) - not needed, replaced below */ 7363261abbSMatthew Dillon movq %rbx,MC_RBX(%rdi) 7463261abbSMatthew Dillon /* movq %rcx,MC_RCX(%rdi) - not needed, scratch */ 7563261abbSMatthew Dillon movq %rbp,MC_RBP(%rdi) 7663261abbSMatthew Dillon movq %r10,MC_R10(%rdi) 7763261abbSMatthew Dillon movq %r11,MC_R11(%rdi) 7863261abbSMatthew Dillon movq %r12,MC_R12(%rdi) 7963261abbSMatthew Dillon movq %r13,MC_R13(%rdi) 8063261abbSMatthew Dillon movq %r14,MC_R14(%rdi) 8163261abbSMatthew Dillon movq %r15,MC_R15(%rdi) 8263261abbSMatthew Dillon /* MC_TRAPNO(%rdi) */ 8363261abbSMatthew Dillon /* MC_ADDR(%rdi) */ 8463261abbSMatthew Dillon /* MC_FLAGS(%rdi) */ 8563261abbSMatthew Dillon /* MC_ERR(%rdi) */ 8663261abbSMatthew Dillon /* MC_RIP(%rdi) - see below */ 8763261abbSMatthew Dillon /* MC_CS(%rdi) */ 8863261abbSMatthew Dillon movq $KUCSEL,MC_CS(%rdi) 8963261abbSMatthew Dillon 9063261abbSMatthew Dillon pushfq 9163261abbSMatthew Dillon popq MC_RFLAGS(%rdi) 9263261abbSMatthew Dillon /* MC_RSP(%rdi) - see below */ 9363261abbSMatthew Dillon movq $KUDSEL,MC_SS(%rdi) 9463261abbSMatthew Dillon 951b773b6eSMarkus Pfeiffer /* 9663261abbSMatthew Dillon * FP registers are scratch, do not save or restore, but make 9763261abbSMatthew Dillon * sure the context can be restored by a signal handler (where 9863261abbSMatthew Dillon * they might not be) by properly initializing the FP control 9963261abbSMatthew Dillon * fields. 1001b773b6eSMarkus Pfeiffer */ 10163261abbSMatthew Dillon movl $_MC_FPOWNED_NONE,MC_OWNEDFP(%rdi) 10263261abbSMatthew Dillon movl $_MC_FPFMT_NODEV,MC_FPFORMAT(%rdi) 103*bc27e030SMatthew Dillon#if 0 10463261abbSMatthew Dillon movl $_MC_FPFMT_YMM,MC_FPFORMAT(%rdi) 10563261abbSMatthew Dillon movq %rdi,%rsi 10663261abbSMatthew Dillon movq $CPU_XFEATURE_X87 | CPU_XFEATURE_SSE | CPU_XFEATURE_YMM,%rax 1071b773b6eSMarkus Pfeiffer movq $0,%rdx 10863261abbSMatthew Dillon xsave MC_FPREGS(%rsi) 10963261abbSMatthew Dillon movq %rsi,%rdi 110*bc27e030SMatthew Dillon#endif 11163261abbSMatthew Dillon 11263261abbSMatthew Dillon /* 11363261abbSMatthew Dillon * Saved stack pointer as if we had returned from this 11463261abbSMatthew Dillon * procedure. 11563261abbSMatthew Dillon */ 11663261abbSMatthew Dillon movq %rsp,MC_RSP(%rdi) 11763261abbSMatthew Dillon addq $8,MC_RSP(%rdi) 11863261abbSMatthew Dillon 11963261abbSMatthew Dillon /* 12063261abbSMatthew Dillon * Save rflags 12163261abbSMatthew Dillon * XXX 12263261abbSMatthew Dillon */ 12363261abbSMatthew Dillon 12463261abbSMatthew Dillon /* 12563261abbSMatthew Dillon * Saved instruction pointer as if we had returned from 12663261abbSMatthew Dillon * this procedure. 12763261abbSMatthew Dillon */ 12863261abbSMatthew Dillon movq (%rsp),%rdx 12963261abbSMatthew Dillon movq %rdx,MC_RIP(%rdi) 13063261abbSMatthew Dillon 13163261abbSMatthew Dillon /* 13263261abbSMatthew Dillon * On restore as if procedure returned the value 1 13363261abbSMatthew Dillon */ 13463261abbSMatthew Dillon movq $1,MC_RAX(%rdi) 13563261abbSMatthew Dillon 13663261abbSMatthew Dillon /* 13763261abbSMatthew Dillon * Set MC_LEN 13863261abbSMatthew Dillon */ 13963261abbSMatthew Dillon movl $SIZEOF_MCONTEXT_T,MC_LEN(%rdi) 14063261abbSMatthew Dillon 14163261abbSMatthew Dillon /* 14263261abbSMatthew Dillon * Return 0 14363261abbSMatthew Dillon */ 14463261abbSMatthew Dillon subq %rax,%rax 1451b773b6eSMarkus Pfeiffer ret 14663261abbSMatthew Dillon 14763261abbSMatthew Dillon#if 0 1481b773b6eSMarkus Pfeiffer1: 1491b773b6eSMarkus Pfeiffer pushq %rsi 1501b773b6eSMarkus Pfeiffer#ifdef PIC 1511b773b6eSMarkus Pfeiffer movq PIC_GOT(HIDENAME(cerror)),%rdx 1521b773b6eSMarkus Pfeiffer jmp *%rdx 1531b773b6eSMarkus Pfeiffer#else 1541b773b6eSMarkus Pfeiffer jmp HIDENAME(cerror) 1551b773b6eSMarkus Pfeiffer#endif 15663261abbSMatthew Dillon#endif 1571b773b6eSMarkus PfeifferEND(_getcontext) 1588b927cb7SJohn Marino 1598b927cb7SJohn Marino .section .note.GNU-stack,"",%progbits 160