1/*- 2 * $FreeBSD: head/tools/KSE/ksetest/kse_asm.S 99073 2002-06-29 17:39:07Z julian $
| 1/* 2 * Copyright (c) 2002 Jonathan Mini <mini@freebsd.org>. 3 * Copyright (c) 2001 Daniel Eischen <deischen@freebsd.org>. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Neither the name of the author nor the names of its contributors 12 * may be used to endorse or promote products derived from this software 13 * without specific prior written permission. 14 * 15 * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 * $FreeBSD: head/tools/KSE/ksetest/kse_asm.S 103581 2002-09-19 02:15:27Z mini $
|
3 */ 4
| 28 */ 29
|
5#include <machine/asmacros.h>
| 30#include 31__FBSDID("$FreeBSD: head/tools/KSE/ksetest/kse_asm.S 103581 2002-09-19 02:15:27Z mini $");
|
6
| 32
|
7/*****************************************************************************/ 8/* Scheduling */ 9/*****************************************************************************/
| 33/* 34 * Where do we define these? 35 */ 36#define MC_SIZE 640 /* sizeof mcontext_t */ 37#define UC_MC_OFFSET 16 /* offset to mcontext from ucontext */ 38#define UC_MC_LEN_OFFSET 96 /* offset to mc_len from mcontext */ 39#define MC_LEN_OFFSET 80 /* offset to mc_len from mcontext */ 40#define MC_FP_REGS_OFFSET 96 /* offset to FP regs from mcontext */ 41#define MC_FP_CW_OFFSET 96 /* offset to FP control word */ 42#define MC_OWNEDFP_OFFSET 88 /* offset to mc_ownedfp from mcontext */ 43#define KM_STACK_SP_OFFSET 32 /* offset to km_stack.ss_sp */ 44#define KM_STACK_SIZE_OFFSET 36 /* offset to km_stack.ss_sp */ 45#define KM_FUNC_OFFSET 28 /* offset to km_func */ 46 47/* 48 * int uts_to_thread(thread_mailbox *tdp, thread_mailbox **curthreadp); 49 * 50 * Does not return on success, returns -1 otherwise. 51 */ 52ENTRY(uts_to_thread) 53 movl 4(%esp), %edx /* get address of thread_mailbox */ 54 /* .. ucontext_t is at offset 0 */ 55 cmpl $0, %edx /* check for null pointer */ 56 jne 1f 57 movl $-1, %eax 58 jmp 5f 591: cmpl $MC_SIZE, UC_MC_LEN_OFFSET(%edx) /* is context valid? */ 60 je 2f 61 movl $-1, %eax /* bzzzt, invalid context */ 62 jmp 5f 632: movl 8(%esp), %eax /* get address of curthreadp */ 64 movl %edx, (%eax) /* we're now the current thread */ 65 /* 66 * From here on, we don't touch the old stack. 67 */ 68 addl $UC_MC_OFFSET, %edx /* add offset to mcontext */ 69 movl 4(%edx), %gs 70 movl 8(%edx), %fs 71 movl 12(%edx), %es 72 movl 16(%edx), %ds 73 movl 76(%edx), %ss 74 movl 20(%edx), %edi 75 movl 24(%edx), %esi 76 movl 28(%edx), %ebp 77 movl 72(%edx), %esp /* switch to context defined stack */ 78 subl $4, %esp /* leave space for the return address */ 79 movl 60(%edx), %eax /* put return address at top of stack */ 80 movl %eax, (%esp) 81 cmpl $0, MC_OWNEDFP_OFFSET(%edx) /* are FP regs valid? */ 82 jz 3f 83 frstor MC_FP_REGS_OFFSET(%edx) /* restore FP regs */ 84 jmp 4f 853: fninit 86 fldcw MC_FP_CW_OFFSET(%edx) 874: movl 48(%edx), %eax /* restore ax, bx, cx */ 88 movl 36(%edx), %ebx 89 movl 44(%edx), %ecx 90 pushl 68(%edx) /* flags on stack */ 91 pushl 40(%edx) /* %edx on stack */ 92 popl %edx /* %edx off stack */ 93 popf /* flags off stack */ 945: ret /* %eip off stack */
|
10
| 95
|
11 .data 12 13 .text 14 15#define TF_GS -0x04 /* don't laugh! */ 16#define TF_FS 0x00 17#define TF_ES 0x04 18#define TF_DS 0x08 19#define TF_EDI 0x0c 20#define TF_ESI 0x10 21#define TF_EBP 0x14 22#define TF_ISP 0x18 23#define TF_EBX 0x1c 24#define TF_EDX 0x20 25#define TF_ECX 0x24 26#define TF_EAX 0x28 27#define TF_TRAPNO 0x2c 28#define TF_ERR 0x30 29#define TF_EIP 0x34 30#define TF_CS 0x38 31#define TF_EFLAGS 0x3c 32#define TF_ESP 0x40 33#define TF_SS 0x44 34
| |
35/*
| 96/*
|
36 * savethread
| 97 * int thread_to_uts(thread_mailbox *tm, kse_mailbox *km); 98 * 99 * Does not return on success, returns -1 otherwise.
|
37 */
| 100 */
|
38GEN_ENTRY(savethread)
| 101ENTRY(thread_to_uts) 102 movl 4(%esp), %eax /* get address of context */ 103 cmpl $0, %eax /* check for null pointer */ 104 jne 1f 105 movl $-1, %eax 106 jmp 2f 1071: pushl %edx /* save value of edx */ 108 movl %eax, %edx /* get address of context */ 109 addl $UC_MC_OFFSET, %edx /* add offset to mcontext */ 110 movl %gs, 4(%edx) 111 movl %fs, 8(%edx) 112 movl %es, 12(%edx) 113 movl %ds, 16(%edx) 114 movl %edi, 20(%edx) 115 movl %esi, 24(%edx) 116 movl %ebp, 28(%edx) 117 movl %ebx, 36(%edx) 118 movl $0, 48(%edx) /* store successful return in eax */ 119 popl %eax /* get saved value of edx */ 120 movl %eax, 40(%edx) /* save edx */ 121 movl %ecx, 44(%edx) 122 movl (%esp), %eax /* get return address */ 123 movl %eax, 60(%edx) /* save return address */ 124 movl %ss, 76(%edx) 125 /* 126 * Don't save floating point registers here. 127 * 128 * This is an explicit call to get the current context, so 129 * the caller is done with the floating point registers. 130 * Contexts formed by involuntary switches, such as signal delivery, 131 * have floating point registers saved by the kernel. 132 */ 133 fnstcw MC_FP_CW_OFFSET(%edx) 134 movl $0, MC_OWNEDFP_OFFSET(%edx) /* no FP */ 135 lahf /* get eflags */ 136 movl %eax, 68(%edx) /* store eflags */ 137 movl %esp, %eax /* setcontext pushes the return */ 138 addl $4, %eax /* address onto the top of the */ 139 movl %eax, 72(%edx) /* stack; account for this */ 140 movl $MC_SIZE, MC_LEN_OFFSET(%edx) /* context is now valid */ 141 movl 8(%esp), %edx /* get address of mailbox */ 142 movl KM_STACK_SP_OFFSET(%edx), %eax /* get bottom of stack */ 143 addl KM_STACK_SIZE_OFFSET(%edx), %eax /* add length */ 144 movl %eax, %esp /* switch to the uts's stack */ 145 pushl %edx /* push the address of the mailbox */ 146 pushl KM_FUNC_OFFSET(%edx) /* .. the uts can return to itself */ 147 pushl KM_FUNC_OFFSET(%edx) /* push the address of the uts func */ 1482: ret
|
39
| 149
|
40 /* Switch to new thread. First, save context as needed. */ 41 pushl %edx 42 movl 8(%esp), %edx /* get context area */ 43 44 movl %eax,TF_EAX(%edx) 45 movl %ebx,TF_EBX(%edx) 46 movl %ecx,TF_ECX(%edx) 47 popl %eax /* get dx off the stack again */ 48 movl %eax,TF_EDX(%edx) 49 movl (%esp),%eax /* get the return address */ 50 movl %eax,TF_EIP(%edx) 51 movl %esp,TF_ESP(%edx) 52 movl %esp,TF_ISP(%edx) /* XXX */ 53 movl %ebp,TF_EBP(%edx) 54 movl %esi,TF_ESI(%edx) 55 movl %edi,TF_EDI(%edx) 56 movl %cs,TF_CS(%edx) 57 movl %ds,TF_DS(%edx) 58 movl %es,TF_ES(%edx) 59 movl %fs,TF_FS(%edx) 60 movl %gs,TF_GS(%edx) 61 ret 62 63 64GEN_ENTRY(loadthread) 65 mov 4(%esp), %edx /* get context area */ 66 67/* movl TF_ISP(%edx), %esp */ /* select which is correct */ 68 movl TF_ESP(%edx), %esp /* get the new stack online */ 69 movl TF_EBP(%edx), %ebp 70 movl TF_EIP(%edx),%eax 71 push %eax /* return adddress */ 72#if 0 73 movl TF_CS(%edx), %cs 74 movl TF_DS(%edx), %ds 75 movl TF_ES(%edx), %es 76 movl TF_FS(%edx), %fs 77 movl TF_GS(%edx), %gs 78#endif 79 movl TF_ESI(%edx), %esi 80 movl TF_EDI(%edx), %edi 81 82 movl TF_EDX(%edx), %eax 83 pushl %eax 84 movl TF_ECX(%edx), %ecx 85 movl TF_EBX(%edx), %ebx 86 movl TF_EAX(%edx), %eax 87 popl %edx 88 ret
| |
| |