Loading arch/unicore32/Kconfig +2 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ config UNICORE32 select ARCH_WANT_FRAME_POINTERS select GENERIC_IOMAP select MODULES_USE_ELF_REL select GENERIC_KERNEL_THREAD select GENERIC_KERNEL_EXECVE help UniCore-32 is 32-bit Instruction Set Architecture, including a series of low-power-consumption RISC chip Loading arch/unicore32/include/asm/processor.h +0 −5 Original line number Diff line number Diff line Loading @@ -72,11 +72,6 @@ unsigned long get_wchan(struct task_struct *p); #define cpu_relax() barrier() /* * Create a new kernel thread */ extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags); #define task_pt_regs(p) \ ((struct pt_regs *)(THREAD_START_SP + task_stack_page(p)) - 1) Loading arch/unicore32/kernel/entry.S +7 −8 Original line number Diff line number Diff line Loading @@ -573,17 +573,16 @@ ENDPROC(ret_to_user) */ ENTRY(ret_from_fork) b.l schedule_tail get_thread_info tsk ldw r1, [tsk+], #TI_FLAGS @ check for syscall tracing mov why, #1 cand.a r1, #_TIF_SYSCALL_TRACE @ are we tracing syscalls? beq ret_slow_syscall mov r1, sp mov r0, #1 @ trace exit [IP = 1] b.l syscall_trace b ret_slow_syscall ENDPROC(ret_from_fork) ENTRY(ret_from_kernel_thread) b.l schedule_tail mov r0, r5 adr lr, ret_slow_syscall mov pc, r4 ENDPROC(ret_from_kernel_thread) /*============================================================================= * SWI handler *----------------------------------------------------------------------------- Loading arch/unicore32/kernel/process.c +14 −44 Original line number Diff line number Diff line Loading @@ -258,6 +258,7 @@ void release_thread(struct task_struct *dead_task) } asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); asmlinkage void ret_from_kernel_thread(void) __asm__("ret_from_kernel_thread"); int copy_thread(unsigned long clone_flags, unsigned long stack_start, Loading @@ -266,17 +267,22 @@ copy_thread(unsigned long clone_flags, unsigned long stack_start, struct thread_info *thread = task_thread_info(p); struct pt_regs *childregs = task_pt_regs(p); *childregs = *regs; childregs->UCreg_00 = 0; childregs->UCreg_sp = stack_start; memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save)); thread->cpu_context.sp = (unsigned long)childregs; if (unlikely(!regs)) { thread->cpu_context.pc = (unsigned long)ret_from_kernel_thread; thread->cpu_context.r4 = stack_start; thread->cpu_context.r5 = stk_sz; memset(childregs, 0, sizeof(struct pt_regs)); } else { thread->cpu_context.pc = (unsigned long)ret_from_fork; *childregs = *regs; childregs->UCreg_00 = 0; childregs->UCreg_sp = stack_start; if (clone_flags & CLONE_SETTLS) childregs->UCreg_16 = regs->UCreg_03; } return 0; } Loading Loading @@ -305,42 +311,6 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fp) } EXPORT_SYMBOL(dump_fpu); /* * Shuffle the argument into the correct register before calling the * thread function. r1 is the thread argument, r2 is the pointer to * the thread function, and r3 points to the exit function. */ asm(".pushsection .text\n" " .align\n" " .type kernel_thread_helper, #function\n" "kernel_thread_helper:\n" " mov.a asr, r7\n" " mov r0, r4\n" " mov lr, r6\n" " mov pc, r5\n" " .size kernel_thread_helper, . - kernel_thread_helper\n" " .popsection"); /* * Create a kernel thread. */ pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) { struct pt_regs regs; memset(®s, 0, sizeof(regs)); regs.UCreg_04 = (unsigned long)arg; regs.UCreg_05 = (unsigned long)fn; regs.UCreg_06 = (unsigned long)do_exit; regs.UCreg_07 = PRIV_MODE; regs.UCreg_pc = (unsigned long)kernel_thread_helper; regs.UCreg_asr = regs.UCreg_07 | PSR_I_BIT; return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); } EXPORT_SYMBOL(kernel_thread); unsigned long get_wchan(struct task_struct *p) { struct stackframe frame; Loading arch/unicore32/kernel/sys.c +0 −42 Original line number Diff line number Diff line Loading @@ -63,48 +63,6 @@ asmlinkage long __sys_execve(const char __user *filename, return error; } int kernel_execve(const char *filename, const char *const argv[], const char *const envp[]) { struct pt_regs regs; int ret; memset(®s, 0, sizeof(struct pt_regs)); ret = do_execve(filename, (const char __user *const __user *)argv, (const char __user *const __user *)envp, ®s); if (ret < 0) goto out; /* * Save argc to the register structure for userspace. */ regs.UCreg_00 = ret; /* * We were successful. We won't be returning to our caller, but * instead to user space by manipulating the kernel stack. */ asm("add r0, %0, %1\n\t" "mov r1, %2\n\t" "mov r2, %3\n\t" "mov r22, #0\n\t" /* not a syscall */ "mov r23, %0\n\t" /* thread structure */ "b.l memmove\n\t" /* copy regs to top of stack */ "mov sp, r0\n\t" /* reposition stack pointer */ "b ret_to_user" : : "r" (current_thread_info()), "Ir" (THREAD_START_SP - sizeof(regs)), "r" (®s), "Ir" (sizeof(regs)) : "r0", "r1", "r2", "r3", "ip", "lr", "memory"); out: return ret; } /* Note: used by the compat code even in 64-bit Linux. */ SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len, unsigned long, prot, unsigned long, flags, Loading Loading
arch/unicore32/Kconfig +2 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ config UNICORE32 select ARCH_WANT_FRAME_POINTERS select GENERIC_IOMAP select MODULES_USE_ELF_REL select GENERIC_KERNEL_THREAD select GENERIC_KERNEL_EXECVE help UniCore-32 is 32-bit Instruction Set Architecture, including a series of low-power-consumption RISC chip Loading
arch/unicore32/include/asm/processor.h +0 −5 Original line number Diff line number Diff line Loading @@ -72,11 +72,6 @@ unsigned long get_wchan(struct task_struct *p); #define cpu_relax() barrier() /* * Create a new kernel thread */ extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags); #define task_pt_regs(p) \ ((struct pt_regs *)(THREAD_START_SP + task_stack_page(p)) - 1) Loading
arch/unicore32/kernel/entry.S +7 −8 Original line number Diff line number Diff line Loading @@ -573,17 +573,16 @@ ENDPROC(ret_to_user) */ ENTRY(ret_from_fork) b.l schedule_tail get_thread_info tsk ldw r1, [tsk+], #TI_FLAGS @ check for syscall tracing mov why, #1 cand.a r1, #_TIF_SYSCALL_TRACE @ are we tracing syscalls? beq ret_slow_syscall mov r1, sp mov r0, #1 @ trace exit [IP = 1] b.l syscall_trace b ret_slow_syscall ENDPROC(ret_from_fork) ENTRY(ret_from_kernel_thread) b.l schedule_tail mov r0, r5 adr lr, ret_slow_syscall mov pc, r4 ENDPROC(ret_from_kernel_thread) /*============================================================================= * SWI handler *----------------------------------------------------------------------------- Loading
arch/unicore32/kernel/process.c +14 −44 Original line number Diff line number Diff line Loading @@ -258,6 +258,7 @@ void release_thread(struct task_struct *dead_task) } asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); asmlinkage void ret_from_kernel_thread(void) __asm__("ret_from_kernel_thread"); int copy_thread(unsigned long clone_flags, unsigned long stack_start, Loading @@ -266,17 +267,22 @@ copy_thread(unsigned long clone_flags, unsigned long stack_start, struct thread_info *thread = task_thread_info(p); struct pt_regs *childregs = task_pt_regs(p); *childregs = *regs; childregs->UCreg_00 = 0; childregs->UCreg_sp = stack_start; memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save)); thread->cpu_context.sp = (unsigned long)childregs; if (unlikely(!regs)) { thread->cpu_context.pc = (unsigned long)ret_from_kernel_thread; thread->cpu_context.r4 = stack_start; thread->cpu_context.r5 = stk_sz; memset(childregs, 0, sizeof(struct pt_regs)); } else { thread->cpu_context.pc = (unsigned long)ret_from_fork; *childregs = *regs; childregs->UCreg_00 = 0; childregs->UCreg_sp = stack_start; if (clone_flags & CLONE_SETTLS) childregs->UCreg_16 = regs->UCreg_03; } return 0; } Loading Loading @@ -305,42 +311,6 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fp) } EXPORT_SYMBOL(dump_fpu); /* * Shuffle the argument into the correct register before calling the * thread function. r1 is the thread argument, r2 is the pointer to * the thread function, and r3 points to the exit function. */ asm(".pushsection .text\n" " .align\n" " .type kernel_thread_helper, #function\n" "kernel_thread_helper:\n" " mov.a asr, r7\n" " mov r0, r4\n" " mov lr, r6\n" " mov pc, r5\n" " .size kernel_thread_helper, . - kernel_thread_helper\n" " .popsection"); /* * Create a kernel thread. */ pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) { struct pt_regs regs; memset(®s, 0, sizeof(regs)); regs.UCreg_04 = (unsigned long)arg; regs.UCreg_05 = (unsigned long)fn; regs.UCreg_06 = (unsigned long)do_exit; regs.UCreg_07 = PRIV_MODE; regs.UCreg_pc = (unsigned long)kernel_thread_helper; regs.UCreg_asr = regs.UCreg_07 | PSR_I_BIT; return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); } EXPORT_SYMBOL(kernel_thread); unsigned long get_wchan(struct task_struct *p) { struct stackframe frame; Loading
arch/unicore32/kernel/sys.c +0 −42 Original line number Diff line number Diff line Loading @@ -63,48 +63,6 @@ asmlinkage long __sys_execve(const char __user *filename, return error; } int kernel_execve(const char *filename, const char *const argv[], const char *const envp[]) { struct pt_regs regs; int ret; memset(®s, 0, sizeof(struct pt_regs)); ret = do_execve(filename, (const char __user *const __user *)argv, (const char __user *const __user *)envp, ®s); if (ret < 0) goto out; /* * Save argc to the register structure for userspace. */ regs.UCreg_00 = ret; /* * We were successful. We won't be returning to our caller, but * instead to user space by manipulating the kernel stack. */ asm("add r0, %0, %1\n\t" "mov r1, %2\n\t" "mov r2, %3\n\t" "mov r22, #0\n\t" /* not a syscall */ "mov r23, %0\n\t" /* thread structure */ "b.l memmove\n\t" /* copy regs to top of stack */ "mov sp, r0\n\t" /* reposition stack pointer */ "b ret_to_user" : : "r" (current_thread_info()), "Ir" (THREAD_START_SP - sizeof(regs)), "r" (®s), "Ir" (sizeof(regs)) : "r0", "r1", "r2", "r3", "ip", "lr", "memory"); out: return ret; } /* Note: used by the compat code even in 64-bit Linux. */ SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len, unsigned long, prot, unsigned long, flags, Loading