aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin
diff options
context:
space:
mode:
Diffstat (limited to 'arch/blackfin')
-rw-r--r--arch/blackfin/Kconfig2
-rw-r--r--arch/blackfin/configs/CM-BF527_defconfig2
-rw-r--r--arch/blackfin/configs/CM-BF548_defconfig2
-rw-r--r--arch/blackfin/configs/CM-BF561_defconfig2
-rw-r--r--arch/blackfin/include/asm/Kbuild1
-rw-r--r--arch/blackfin/include/asm/processor.h2
-rw-r--r--arch/blackfin/include/asm/unistd.h2
-rw-r--r--arch/blackfin/kernel/entry.S55
-rw-r--r--arch/blackfin/kernel/process.c98
-rw-r--r--arch/blackfin/kernel/signal.c4
-rw-r--r--arch/blackfin/mach-common/entry.S57
11 files changed, 40 insertions, 187 deletions
diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig
index b6f3ad5441c5..ab9ff4075f4d 100644
--- a/arch/blackfin/Kconfig
+++ b/arch/blackfin/Kconfig
@@ -45,6 +45,8 @@ config BLACKFIN
45 select ARCH_USES_GETTIMEOFFSET if !GENERIC_CLOCKEVENTS 45 select ARCH_USES_GETTIMEOFFSET if !GENERIC_CLOCKEVENTS
46 select HAVE_MOD_ARCH_SPECIFIC 46 select HAVE_MOD_ARCH_SPECIFIC
47 select MODULES_USE_ELF_RELA 47 select MODULES_USE_ELF_RELA
48 select GENERIC_KERNEL_THREAD
49 select GENERIC_KERNEL_EXECVE
48 50
49config GENERIC_CSUM 51config GENERIC_CSUM
50 def_bool y 52 def_bool y
diff --git a/arch/blackfin/configs/CM-BF527_defconfig b/arch/blackfin/configs/CM-BF527_defconfig
index c280a50e7943..f59c80ee78e3 100644
--- a/arch/blackfin/configs/CM-BF527_defconfig
+++ b/arch/blackfin/configs/CM-BF527_defconfig
@@ -106,7 +106,7 @@ CONFIG_MUSB_PIO_ONLY=y
106CONFIG_USB_STORAGE=m 106CONFIG_USB_STORAGE=m
107CONFIG_USB_GADGET=m 107CONFIG_USB_GADGET=m
108CONFIG_USB_ETH=m 108CONFIG_USB_ETH=m
109CONFIG_USB_FILE_STORAGE=m 109CONFIG_USB_MASS_STORAGE=m
110CONFIG_USB_G_SERIAL=m 110CONFIG_USB_G_SERIAL=m
111CONFIG_USB_G_PRINTER=m 111CONFIG_USB_G_PRINTER=m
112CONFIG_RTC_CLASS=y 112CONFIG_RTC_CLASS=y
diff --git a/arch/blackfin/configs/CM-BF548_defconfig b/arch/blackfin/configs/CM-BF548_defconfig
index 349922be01f3..e961483f1879 100644
--- a/arch/blackfin/configs/CM-BF548_defconfig
+++ b/arch/blackfin/configs/CM-BF548_defconfig
@@ -107,7 +107,7 @@ CONFIG_USB_ZERO=m
107CONFIG_USB_ETH=m 107CONFIG_USB_ETH=m
108# CONFIG_USB_ETH_RNDIS is not set 108# CONFIG_USB_ETH_RNDIS is not set
109CONFIG_USB_GADGETFS=m 109CONFIG_USB_GADGETFS=m
110CONFIG_USB_FILE_STORAGE=m 110CONFIG_USB_MASS_STORAGE=m
111CONFIG_USB_G_SERIAL=m 111CONFIG_USB_G_SERIAL=m
112CONFIG_USB_G_PRINTER=m 112CONFIG_USB_G_PRINTER=m
113CONFIG_MMC=m 113CONFIG_MMC=m
diff --git a/arch/blackfin/configs/CM-BF561_defconfig b/arch/blackfin/configs/CM-BF561_defconfig
index 0456deaa2d6f..24936b91a6ee 100644
--- a/arch/blackfin/configs/CM-BF561_defconfig
+++ b/arch/blackfin/configs/CM-BF561_defconfig
@@ -83,7 +83,7 @@ CONFIG_GPIOLIB=y
83CONFIG_GPIO_SYSFS=y 83CONFIG_GPIO_SYSFS=y
84CONFIG_USB_GADGET=m 84CONFIG_USB_GADGET=m
85CONFIG_USB_ETH=m 85CONFIG_USB_ETH=m
86CONFIG_USB_FILE_STORAGE=m 86CONFIG_USB_MASS_STORAGE=m
87CONFIG_USB_G_SERIAL=m 87CONFIG_USB_G_SERIAL=m
88CONFIG_USB_G_PRINTER=m 88CONFIG_USB_G_PRINTER=m
89CONFIG_MMC=y 89CONFIG_MMC=y
diff --git a/arch/blackfin/include/asm/Kbuild b/arch/blackfin/include/asm/Kbuild
index 5a0625aad6a0..27d70759474c 100644
--- a/arch/blackfin/include/asm/Kbuild
+++ b/arch/blackfin/include/asm/Kbuild
@@ -38,6 +38,7 @@ generic-y += statfs.h
38generic-y += termbits.h 38generic-y += termbits.h
39generic-y += termios.h 39generic-y += termios.h
40generic-y += topology.h 40generic-y += topology.h
41generic-y += trace_clock.h
41generic-y += types.h 42generic-y += types.h
42generic-y += ucontext.h 43generic-y += ucontext.h
43generic-y += unaligned.h 44generic-y += unaligned.h
diff --git a/arch/blackfin/include/asm/processor.h b/arch/blackfin/include/asm/processor.h
index 4ef7cfe43ceb..d0e72e9475a6 100644
--- a/arch/blackfin/include/asm/processor.h
+++ b/arch/blackfin/include/asm/processor.h
@@ -75,8 +75,6 @@ static inline void release_thread(struct task_struct *dead_task)
75{ 75{
76} 76}
77 77
78extern int kernel_thread(int (*fn) (void *), void *arg, unsigned long flags);
79
80/* 78/*
81 * Free current thread data structures etc.. 79 * Free current thread data structures etc..
82 */ 80 */
diff --git a/arch/blackfin/include/asm/unistd.h b/arch/blackfin/include/asm/unistd.h
index 5b2a0748d7d3..460514a1a4e1 100644
--- a/arch/blackfin/include/asm/unistd.h
+++ b/arch/blackfin/include/asm/unistd.h
@@ -446,6 +446,8 @@
446#define __ARCH_WANT_SYS_NICE 446#define __ARCH_WANT_SYS_NICE
447#define __ARCH_WANT_SYS_RT_SIGACTION 447#define __ARCH_WANT_SYS_RT_SIGACTION
448#define __ARCH_WANT_SYS_RT_SIGSUSPEND 448#define __ARCH_WANT_SYS_RT_SIGSUSPEND
449#define __ARCH_WANT_SYS_EXECVE
450#define __ARCH_WANT_SYS_VFORK
449 451
450/* 452/*
451 * "Conditional" syscalls 453 * "Conditional" syscalls
diff --git a/arch/blackfin/kernel/entry.S b/arch/blackfin/kernel/entry.S
index f33792cc1a0d..4071265fc4fe 100644
--- a/arch/blackfin/kernel/entry.S
+++ b/arch/blackfin/kernel/entry.S
@@ -46,53 +46,14 @@ ENTRY(_ret_from_fork)
46 SP += -12; 46 SP += -12;
47 pseudo_long_call _schedule_tail, p5; 47 pseudo_long_call _schedule_tail, p5;
48 SP += 12; 48 SP += 12;
49 r0 = [sp + PT_IPEND]; 49 p1 = [sp++];
50 cc = bittst(r0,1); 50 r0 = [sp++];
51 if cc jump .Lin_kernel; 51 cc = p1 == 0;
52 if cc jump .Lfork;
53 sp += -12;
54 call (p1);
55 sp += 12;
56.Lfork:
52 RESTORE_CONTEXT 57 RESTORE_CONTEXT
53 rti; 58 rti;
54.Lin_kernel:
55 bitclr(r0,1);
56 [sp + PT_IPEND] = r0;
57 /* do a 'fake' RTI by jumping to [RETI]
58 * to avoid clearing supervisor mode in child
59 */
60 r0 = [sp + PT_PC];
61 [sp + PT_P0] = r0;
62
63 RESTORE_ALL_SYS
64 jump (p0);
65ENDPROC(_ret_from_fork) 59ENDPROC(_ret_from_fork)
66
67ENTRY(_sys_vfork)
68 r0 = sp;
69 r0 += 24;
70 [--sp] = rets;
71 SP += -12;
72 pseudo_long_call _bfin_vfork, p2;
73 SP += 12;
74 rets = [sp++];
75 rts;
76ENDPROC(_sys_vfork)
77
78ENTRY(_sys_clone)
79 r0 = sp;
80 r0 += 24;
81 [--sp] = rets;
82 SP += -12;
83 pseudo_long_call _bfin_clone, p2;
84 SP += 12;
85 rets = [sp++];
86 rts;
87ENDPROC(_sys_clone)
88
89ENTRY(_sys_rt_sigreturn)
90 r0 = sp;
91 r0 += 24;
92 [--sp] = rets;
93 SP += -12;
94 pseudo_long_call _do_rt_sigreturn, p2;
95 SP += 12;
96 rets = [sp++];
97 rts;
98ENDPROC(_sys_rt_sigreturn)
diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c
index bb1cc721fcf7..3e16ad9b0a99 100644
--- a/arch/blackfin/kernel/process.c
+++ b/arch/blackfin/kernel/process.c
@@ -102,40 +102,6 @@ void cpu_idle(void)
102} 102}
103 103
104/* 104/*
105 * This gets run with P1 containing the
106 * function to call, and R1 containing
107 * the "args". Note P0 is clobbered on the way here.
108 */
109void kernel_thread_helper(void);
110__asm__(".section .text\n"
111 ".align 4\n"
112 "_kernel_thread_helper:\n\t"
113 "\tsp += -12;\n\t"
114 "\tr0 = r1;\n\t" "\tcall (p1);\n\t" "\tcall _do_exit;\n" ".previous");
115
116/*
117 * Create a kernel thread.
118 */
119pid_t kernel_thread(int (*fn) (void *), void *arg, unsigned long flags)
120{
121 struct pt_regs regs;
122
123 memset(&regs, 0, sizeof(regs));
124
125 regs.r1 = (unsigned long)arg;
126 regs.p1 = (unsigned long)fn;
127 regs.pc = (unsigned long)kernel_thread_helper;
128 regs.orig_p0 = -1;
129 /* Set bit 2 to tell ret_from_fork we should be returning to kernel
130 mode. */
131 regs.ipend = 0x8002;
132 __asm__ __volatile__("%0 = syscfg;":"=da"(regs.syscfg):);
133 return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL,
134 NULL);
135}
136EXPORT_SYMBOL(kernel_thread);
137
138/*
139 * Do necessary setup to start up a newly executed thread. 105 * Do necessary setup to start up a newly executed thread.
140 * 106 *
141 * pass the data segment into user programs if it exists, 107 * pass the data segment into user programs if it exists,
@@ -161,70 +127,48 @@ void flush_thread(void)
161{ 127{
162} 128}
163 129
164asmlinkage int bfin_vfork(struct pt_regs *regs) 130asmlinkage int bfin_clone(unsigned long clone_flags, unsigned long newsp)
165{
166 return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), regs, 0, NULL,
167 NULL);
168}
169
170asmlinkage int bfin_clone(struct pt_regs *regs)
171{ 131{
172 unsigned long clone_flags;
173 unsigned long newsp;
174
175#ifdef __ARCH_SYNC_CORE_DCACHE 132#ifdef __ARCH_SYNC_CORE_DCACHE
176 if (current->nr_cpus_allowed == num_possible_cpus()) 133 if (current->nr_cpus_allowed == num_possible_cpus())
177 set_cpus_allowed_ptr(current, cpumask_of(smp_processor_id())); 134 set_cpus_allowed_ptr(current, cpumask_of(smp_processor_id()));
178#endif 135#endif
179 136 if (newsp)
180 /* syscall2 puts clone_flags in r0 and usp in r1 */
181 clone_flags = regs->r0;
182 newsp = regs->r1;
183 if (!newsp)
184 newsp = rdusp();
185 else
186 newsp -= 12; 137 newsp -= 12;
187 return do_fork(clone_flags, newsp, regs, 0, NULL, NULL); 138 return do_fork(clone_flags, newsp, 0, NULL, NULL);
188} 139}
189 140
190int 141int
191copy_thread(unsigned long clone_flags, 142copy_thread(unsigned long clone_flags,
192 unsigned long usp, unsigned long topstk, 143 unsigned long usp, unsigned long topstk,
193 struct task_struct *p, struct pt_regs *regs) 144 struct task_struct *p)
194{ 145{
195 struct pt_regs *childregs; 146 struct pt_regs *childregs;
147 unsigned long *v;
196 148
197 childregs = (struct pt_regs *) (task_stack_page(p) + THREAD_SIZE) - 1; 149 childregs = (struct pt_regs *) (task_stack_page(p) + THREAD_SIZE) - 1;
198 *childregs = *regs; 150 v = ((unsigned long *)childregs) - 2;
199 childregs->r0 = 0; 151 if (unlikely(p->flags & PF_KTHREAD)) {
152 memset(childregs, 0, sizeof(struct pt_regs));
153 v[0] = usp;
154 v[1] = topstk;
155 childregs->orig_p0 = -1;
156 childregs->ipend = 0x8000;
157 __asm__ __volatile__("%0 = syscfg;":"=da"(childregs->syscfg):);
158 p->thread.usp = 0;
159 } else {
160 *childregs = *current_pt_regs();
161 childregs->r0 = 0;
162 p->thread.usp = usp ? : rdusp();
163 v[0] = v[1] = 0;
164 }
200 165
201 p->thread.usp = usp; 166 p->thread.ksp = (unsigned long)v;
202 p->thread.ksp = (unsigned long)childregs;
203 p->thread.pc = (unsigned long)ret_from_fork; 167 p->thread.pc = (unsigned long)ret_from_fork;
204 168
205 return 0; 169 return 0;
206} 170}
207 171
208/*
209 * sys_execve() executes a new program.
210 */
211asmlinkage int sys_execve(const char __user *name,
212 const char __user *const __user *argv,
213 const char __user *const __user *envp)
214{
215 int error;
216 struct filename *filename;
217 struct pt_regs *regs = (struct pt_regs *)((&name) + 6);
218
219 filename = getname(name);
220 error = PTR_ERR(filename);
221 if (IS_ERR(filename))
222 return error;
223 error = do_execve(filename->name, argv, envp, regs);
224 putname(filename);
225 return error;
226}
227
228unsigned long get_wchan(struct task_struct *p) 172unsigned long get_wchan(struct task_struct *p)
229{ 173{
230 unsigned long fp, pc; 174 unsigned long fp, pc;
diff --git a/arch/blackfin/kernel/signal.c b/arch/blackfin/kernel/signal.c
index 6ed20a1a4af9..84b4be05840c 100644
--- a/arch/blackfin/kernel/signal.c
+++ b/arch/blackfin/kernel/signal.c
@@ -82,9 +82,9 @@ rt_restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, int *p
82 return err; 82 return err;
83} 83}
84 84
85asmlinkage int do_rt_sigreturn(unsigned long __unused) 85asmlinkage int sys_rt_sigreturn(void)
86{ 86{
87 struct pt_regs *regs = (struct pt_regs *)__unused; 87 struct pt_regs *regs = current_pt_regs();
88 unsigned long usp = rdusp(); 88 unsigned long usp = rdusp();
89 struct rt_sigframe *frame = (struct rt_sigframe *)(usp); 89 struct rt_sigframe *frame = (struct rt_sigframe *)(usp);
90 sigset_t set; 90 sigset_t set;
diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S
index 1c3d2c5bb0bb..86b5a095c5a1 100644
--- a/arch/blackfin/mach-common/entry.S
+++ b/arch/blackfin/mach-common/entry.S
@@ -530,61 +530,6 @@ ENTRY(_trap) /* Exception: 4th entry into system event table(supervisor mode)*/
530 jump .Lsyscall_really_exit; 530 jump .Lsyscall_really_exit;
531ENDPROC(_trap) 531ENDPROC(_trap)
532 532
533ENTRY(_kernel_execve)
534 link SIZEOF_PTREGS;
535 p0 = sp;
536 r3 = SIZEOF_PTREGS / 4;
537 r4 = 0(x);
538.Lclear_regs:
539 [p0++] = r4;
540 r3 += -1;
541 cc = r3 == 0;
542 if !cc jump .Lclear_regs (bp);
543
544 p0 = sp;
545 sp += -16;
546 [sp + 12] = p0;
547 pseudo_long_call _do_execve, p5;
548 SP += 16;
549 cc = r0 == 0;
550 if ! cc jump .Lexecve_failed;
551 /* Success. Copy our temporary pt_regs to the top of the kernel
552 * stack and do a normal exception return.
553 */
554 r1 = sp;
555 r0 = (-KERNEL_STACK_SIZE) (x);
556 r1 = r1 & r0;
557 p2 = r1;
558 p3 = [p2];
559 r0 = KERNEL_STACK_SIZE - 4 (z);
560 p1 = r0;
561 p1 = p1 + p2;
562
563 p0 = fp;
564 r4 = [p0--];
565 r3 = SIZEOF_PTREGS / 4;
566.Lcopy_regs:
567 r4 = [p0--];
568 [p1--] = r4;
569 r3 += -1;
570 cc = r3 == 0;
571 if ! cc jump .Lcopy_regs (bp);
572
573 r0 = (KERNEL_STACK_SIZE - SIZEOF_PTREGS) (z);
574 p1 = r0;
575 p1 = p1 + p2;
576 sp = p1;
577 r0 = syscfg;
578 [SP + PT_SYSCFG] = r0;
579 [p3 + (TASK_THREAD + THREAD_KSP)] = sp;
580
581 RESTORE_CONTEXT;
582 rti;
583.Lexecve_failed:
584 unlink;
585 rts;
586ENDPROC(_kernel_execve)
587
588ENTRY(_system_call) 533ENTRY(_system_call)
589 /* Store IPEND */ 534 /* Store IPEND */
590 p2.l = lo(IPEND); 535 p2.l = lo(IPEND);
@@ -1486,7 +1431,7 @@ ENTRY(_sys_call_table)
1486 .long _sys_ni_syscall /* old sys_ipc */ 1431 .long _sys_ni_syscall /* old sys_ipc */
1487 .long _sys_fsync 1432 .long _sys_fsync
1488 .long _sys_ni_syscall /* old sys_sigreturn */ 1433 .long _sys_ni_syscall /* old sys_sigreturn */
1489 .long _sys_clone /* 120 */ 1434 .long _bfin_clone /* 120 */
1490 .long _sys_setdomainname 1435 .long _sys_setdomainname
1491 .long _sys_newuname 1436 .long _sys_newuname
1492 .long _sys_ni_syscall /* old sys_modify_ldt */ 1437 .long _sys_ni_syscall /* old sys_modify_ldt */