18 #include <linux/errno.h>
19 #include <linux/sched.h>
20 #include <linux/kernel.h>
23 #include <linux/stddef.h>
25 #include <linux/ptrace.h>
26 #include <linux/elf.h>
30 #include <linux/module.h>
33 #include <linux/slab.h>
36 #include <asm/pgtable.h>
37 #include <asm/uaccess.h>
39 #include <asm/processor.h>
44 #include <asm/asm-offsets.h>
56 #if XTENSA_HAVE_COPROCESSORS
58 void coprocessor_release_all(
struct thread_info *ti)
60 unsigned long cpenable;
69 cpenable = ti->cpenable;
72 if (coprocessor_owner[i] == ti) {
73 coprocessor_owner[
i] = 0;
74 cpenable &= ~(1 <<
i);
78 ti->cpenable = cpenable;
79 coprocessor_clear_cpenable();
86 unsigned long cpenable;
91 cpenable = ti->cpenable;
94 if ((cpenable & 1) != 0 && coprocessor_owner[i] == ti)
95 coprocessor_flush(ti, i);
116 while (!need_resched())
128 #if XTENSA_HAVE_COPROCESSORS
139 #if XTENSA_HAVE_COPROCESSORS
141 coprocessor_flush_all(ti);
142 coprocessor_release_all(ti);
152 #if XTENSA_HAVE_COPROCESSORS
201 int copy_thread(
unsigned long clone_flags,
unsigned long usp_thread_fn,
202 unsigned long thread_fn_arg,
207 #if (XTENSA_HAVE_COPROCESSORS || XTENSA_HAVE_IO_PORTS)
212 *((
int*)childregs - 3) = (
unsigned long)childregs;
213 *((
int*)childregs - 4) = 0;
219 unsigned long usp = usp_thread_fn ?
220 usp_thread_fn : regs->
areg[1];
231 childregs->
areg[2] = 0;
249 if (regs->
areg[1] == usp && len != 0) {
250 int callinc = (regs->
areg[0] >> 30) & 3;
253 (
unsigned __user*)(usp - 12));
255 childregs->
wmask = 1;
265 childregs->
areg[2] = childregs->
areg[6];
273 *((
int *)childregs - 1) = thread_fn_arg;
274 *((
int *)childregs - 2) = usp_thread_fn;
281 #if (XTENSA_HAVE_COPROCESSORS || XTENSA_HAVE_IO_PORTS)
296 unsigned long sp,
pc;
307 if (sp < stack_page +
sizeof(
struct task_struct) ||
317 sp = *(
unsigned long *)sp - 3;
318 }
while (count++ < 16);
333 unsigned long wb,
ws, wm;
343 memset(elfregs, 0,
sizeof(*elfregs));
349 elfregs->
pc = regs->
pc;
357 live = (wm & 2) ? 4 : (wm & 4) ? 8 : (wm & 8) ? 12 : 16;
360 memcpy(elfregs->
a + last, regs->
areg + last, (wm >> 4) * 16);
370 void __user *parent_tid,
void *child_tls,
371 void __user *child_tid,
long a5,
374 return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid);