1/* 2 * Copyright (c) 2007 Matthew Dillon <dillon@backplane.com> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Neither the name of the author nor the names of its contributors 11 * may be used to endorse or promote products derived from this software 12 * without specific prior written permission. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26/* 27 * swapcontext_quick() and setcontext_quick(). There is *NO* 28 * getcontext_quick() routine on purpose. 29 * 30 * Quick routines are not required to save or resetore scratch registers, 31 * FP regs (which are scratch), or flags. 32 */ 33#include <machine/asm.h> 34#include <cpu/specialreg.h> 35#include <asmcontext.h> 36 37 /* 38 * void setcontext_quick(ucontext_t *ucp) 39 * 40 * Load the register context, effectively switching to the 41 * new context. 42 */ 43 .weak setcontext_quick 44 .set setcontext_quick,_setcontext_quick 45ENTRY(_setcontext_quick) 46 addq $UC_MCONTEXT,%rdi 47 48 /* MC_ONSTACK(%rdi) */ 49 /* MC_RDI(%rdi) - see below */ 50 movq MC_RSI(%rdi),%rsi 51 movq MC_RDX(%rdi),%rdx 52 movq MC_R8(%rdi),%r8 53 movq MC_R9(%rdi),%r9 54 /* MC_RAX(%rdi) - see below */ 55 movq MC_RBX(%rdi),%rbx 56 movq MC_RCX(%rdi),%rcx 57 movq MC_RBP(%rdi),%rbp 58 movq MC_R10(%rdi),%r10 59 movq MC_R11(%rdi),%r11 60 movq MC_R12(%rdi),%r12 61 movq MC_R13(%rdi),%r13 62 movq MC_R14(%rdi),%r14 63 movq MC_R15(%rdi),%r15 64 /* MC_TRAPNO(%rdi) */ 65 /* MC_ADDR(%rdi) */ 66 /* MC_FLAGS(%rdi) */ 67 /* MC_ERR(%rdi) */ 68 /* MC_RIP(%rdi) - see below */ 69 /* MC_CS(%rdi) */ 70 /* MC_RFLAGS(%rdi) */ 71 /* MC_RSP(%rdi) - see below */ 72 /* MC_SS(%rdi) */ 73 74 /* 75 * Load the new stack pointer 76 */ 77 movq MC_RSP(%rdi),%rsp 78 79 /* 80 * Use %rax to hold the return pc. function returns void. Do 81 * not mess with the target stack (particularly not the red-zone!). 82 */ 83 movq MC_RIP(%rdi),%rax 84 85 /* 86 * Finally rdi 87 */ 88 movq MC_RDI(%rdi),%rdi 89 jmp *%rax 90END(_setcontext_quick) 91 92 93 /* 94 * void swapcontext_quick(ucontex_t *oucp, ucontext_t *nucp) 95 * 96 * Save the current state in oucp and switch to nucp. 97 */ 98 .weak swapcontext_quick 99 .set swapcontext_quick,_swapcontext_quick 100ENTRY(_swapcontext_quick) 101 /* 102 * Save 103 */ 104 addq $UC_MCONTEXT,%rdi 105 popq %rax /* return pc */ 106 107 movq %rsi,MC_RSI(%rdi) 108 movq %rbx,MC_RBX(%rdi) 109 movq %rdx,MC_RDX(%rdi) 110 movq %rbp,MC_RBP(%rdi) 111 movq %r10,MC_R10(%rdi) 112 movq %r11,MC_R11(%rdi) 113 movq %r12,MC_R12(%rdi) 114 movq %r13,MC_R13(%rdi) 115 movq %r14,MC_R14(%rdi) 116 movq %r15,MC_R15(%rdi) 117 movq %rsp,MC_RSP(%rdi) 118 movq %rax,MC_RIP(%rdi) 119 120 /* 121 * Restore (copy of setcontext above) 122 */ 123 movq %rsi,%rdi 124 addq $UC_MCONTEXT,%rdi 125 126 /* MC_ONSTACK(%rdi) */ 127 /* MC_RDI(%rdi) - see below */ 128 movq MC_RSI(%rdi),%rsi 129 movq MC_RDX(%rdi),%rdx 130 /* MC_RAX(%rdi) - see below */ 131 movq MC_RBX(%rdi),%rbx 132 movq MC_RCX(%rdi),%rcx 133 movq MC_RBP(%rdi),%rbp 134 movq MC_R10(%rdi),%r10 135 movq MC_R11(%rdi),%r11 136 movq MC_R12(%rdi),%r12 137 movq MC_R13(%rdi),%r13 138 movq MC_R14(%rdi),%r14 139 movq MC_R15(%rdi),%r15 140 /* MC_TRAPNO(%rdi) */ 141 /* MC_ADDR(%rdi) */ 142 /* MC_FLAGS(%rdi) */ 143 /* MC_ERR(%rdi) */ 144 /* MC_RIP(%rdi) - see below */ 145 /* MC_CS(%rdi) */ 146 /* MC_RFLAGS(%rdi) */ 147 /* MC_RSP(%rdi) - see below */ 148 /* MC_SS(%rdi) */ 149 150 /* 151 * Load the new stack pointer 152 */ 153 movq MC_RSP(%rdi),%rsp 154 155 /* 156 * Use %rax to hold the return pc. function returns void. Do 157 * not mess with the target stack (particularly not the red-zone!). 158 */ 159 movq MC_RIP(%rdi),%rax 160 161 /* 162 * Finally rdi 163 */ 164 movq MC_RDI(%rdi),%rdi 165 jmp *%rax 166 167END(_swapcontext_quick) 168 169 .section .note.GNU-stack,"",%progbits 170