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 i386_set_task_switched(void); */
107 FUNCTION(i386_set_task_switched):
113 /* void i386_clear_task_switched(void); */
114 FUNCTION(i386_clear_task_switched):
120 /* void arch_cpu_global_TLB_invalidate(); */
121 FUNCTION(arch_cpu_global_TLB_invalidate):
126 /* void i386_fsave(void *fpu_state); */
127 FUNCTION(i386_fsave):
132 /* void i386_fxsave(void *fpu_state); */
133 FUNCTION(i386_fxsave):
138 /* void i386_frstor(void *fpu_state); */
139 FUNCTION(i386_frstor):
144 /* void i386_fxrstor(void *fpu_state); */
145 FUNCTION(i386_fxrstor):
150 /* void i386_fsave_swap(void *old_fpu_state, void *new_fpu_state); */
151 FUNCTION(i386_fsave_swap):
158 /* void i386_fxsave_swap(void *old_fpu_state, void *new_fpu_state); */
159 FUNCTION(i386_fxsave_swap):
166 /* void i386_cpuid(unsigned int selector, unsigned int *data); */
167 FUNCTION(i386_cpuid):
181 /* void i386_context_switch(struct arch_thread *old, struct arch_thread *new); */
182 FUNCTION(i386_context_switch):
183 pusha /* pushes 8 words onto the stack */
185 movl 36(%esp),%eax /* save current_stack */
188 pushl %ss /* push the old ss */
189 popl %edx /* pop it back off the stack */
190 movl %edx,4(%eax) /* save it into the arch_thread structure */
192 movl 40(%esp),%eax /* get new current_stack */
198 /* void i386_swap_pgdir(addr_t new_pgdir); */
199 FUNCTION(i386_swap_pgdir):
204 /* thread exit stub */
206 i386_uspace_exit_stub:
213 i386_uspace_exit_stub_end:
216 /* void i386_enter_uspace(addr_t entry, void *args, addr_t ustack_top); */
217 FUNCTION(i386_enter_uspace):
218 movl 4(%esp),%eax // get entry point
219 movl 8(%esp),%edx // get arguments
220 movl 12(%esp),%ebx // get user stack
227 // copy exit stub to stack
228 movl $i386_uspace_exit_stub_end, %esi
234 cmp $i386_uspace_exit_stub, %esi
238 // push the args onto the user stack
239 movl %edx,-4(%ebx) // args
240 movl %ebx,-8(%ebx) // fake return address to copied exit stub
243 pushl $0x23 // user data segment
244 pushl %ebx // user stack
245 pushl $(1 << 9) | 2 // user flags
246 pushl $0x1b // user code segment
247 pushl %eax // user IP
250 /* void i386_switch_stack_and_call(addr_t stack, void (*func)(void *), void *arg); */
251 FUNCTION(i386_switch_stack_and_call):
252 movl 4(%esp),%eax // new stack
253 movl 8(%esp),%ecx // func
254 movl 12(%esp),%edx // args
256 movl %eax,%esp // switch the stack
257 pushl %edx // push the argument
258 call *%ecx // call the target function
273 FUNCTION(dbg_save_registers):
284 movl %eax, 16(%esi) // caller's %esp
288 movl %eax, 24(%esi) // caller's %esi
292 movl %eax, 32(%esi) // caller's %ebp