2 ** Copyright 2001, Travis Geiselbrecht. All rights reserved.
3 ** Copyright 2002, Michael Noisternig. All rights reserved.
4 ** Distributed under the terms of the NewOS License.
7 #define FUNCTION(x) .global x; .type x,@function; x
11 /* int atomic_add(int *val, int incr) */
19 /* int atomic_and(int *val, int incr) */
35 /* int atomic_or(int *val, int incr) */
51 /* int atomic_set(int *val, int set_to) */
58 /* int test_and_set(int *val, int set_to, int test_val) */
59 FUNCTION(test_and_set):
69 /* uint64 i386_rdtsc() */
75 /* saves the conversion factor needed for system_time */
80 FUNCTION(setup_system_time):
85 /* bigtime_t i386_cycles_to_time(uint64 cycles); */
86 FUNCTION(i386_cycles_to_time):
93 movl %edx, %ecx /* save high half */
94 mull %ebx /* truncate %eax, but keep %edx */
96 movl %edx, %ecx /* save high half of low */
98 /* now compute [%edx, %eax] + [%ecx], propagating carry */
99 subl %ebx, %ebx /* need zero to propagate carry */
106 /* void arch_cpu_global_TLB_invalidate(); */
107 FUNCTION(arch_cpu_global_TLB_invalidate):
112 /* void i386_fsave(void *fpu_state); */
113 FUNCTION(i386_fsave):
118 /* void i386_fxsave(void *fpu_state); */
119 FUNCTION(i386_fxsave):
124 /* void i386_frstor(void *fpu_state); */
125 FUNCTION(i386_frstor):
130 /* void i386_fxrstor(void *fpu_state); */
131 FUNCTION(i386_fxrstor):
136 /* void i386_fsave_swap(void *old_fpu_state, void *new_fpu_state); */
137 FUNCTION(i386_fsave_swap):
144 /* void i386_fxsave_swap(void *old_fpu_state, void *new_fpu_state); */
145 FUNCTION(i386_fxsave_swap):
152 /* void i386_context_switch(struct arch_thread *old, struct arch_thread *new); */
153 FUNCTION(i386_context_switch):
154 pusha /* pushes 8 words onto the stack */
156 movl 36(%esp),%eax /* save current_stack */
159 pushl %ss /* push the old ss */
160 popl %edx /* pop it back off the stack */
161 movl %edx,4(%eax) /* save it into the arch_thread structure */
163 movl 40(%esp),%eax /* get new current_stack */
169 /* void i386_swap_pgdir(addr_t new_pgdir); */
170 FUNCTION(i386_swap_pgdir):
175 /* thread exit stub */
177 i386_uspace_exit_stub:
184 i386_uspace_exit_stub_end:
187 /* void i386_enter_uspace(addr_t entry, void *args, addr_t ustack_top); */
188 FUNCTION(i386_enter_uspace):
189 movl 4(%esp),%eax // get entry point
190 movl 8(%esp),%edx // get arguments
191 movl 12(%esp),%ebx // get user stack
198 // copy exit stub to stack
199 movl $i386_uspace_exit_stub_end, %esi
205 cmp $i386_uspace_exit_stub, %esi
209 // push the args onto the user stack
210 movl %edx,-4(%ebx) // args
211 movl %ebx,-8(%ebx) // fake return address to copied exit stub
214 pushl $0x23 // user data segment
215 pushl %ebx // user stack
216 pushl $(1 << 9) | 2 // user flags
217 pushl $0x1b // user code segment
218 pushl %eax // user IP
221 /* void i386_switch_stack_and_call(addr_t stack, void (*func)(void *), void *arg); */
222 FUNCTION(i386_switch_stack_and_call):
223 movl 4(%esp),%eax // new stack
224 movl 8(%esp),%ecx // func
225 movl 12(%esp),%edx // args
227 movl %eax,%esp // switch the stack
228 pushl %edx // push the argument
229 call *%ecx // call the target function
244 FUNCTION(dbg_save_registers):
255 movl %eax, 16(%esi) // caller's %esp
259 movl %eax, 24(%esi) // caller's %esi
263 movl %eax, 32(%esi) // caller's %ebp