1 /* $Id: process.c,v 1.28 2004/05/05 16:54:23 lethal Exp $ 2 * 3 * linux/arch/sh/kernel/process.c 4 * 5 * Copyright (C) 1995 Linus Torvalds 6 * 7 * SuperH version: Copyright (C) 1999, 2000 Niibe Yutaka & Kaz Kojima 8 */ 9 10 /* 11 * This file handles the architecture-dependent parts of process handling.. 12 */ 13 14 #include <linux/module.h> 15 #include <linux/unistd.h> 16 #include <linux/mm.h> 17 #include <linux/elfcore.h> 18 #include <linux/a.out.h> 19 #include <linux/slab.h> 20 #include <linux/pm.h> 21 #include <linux/ptrace.h> 22 #include <linux/platform.h> 23 #include <linux/kallsyms.h> 24 #include <linux/kexec.h> 25 26 #include <asm/io.h> 27 #include <asm/uaccess.h> 28 #include <asm/mmu_context.h> 29 #include <asm/elf.h> 30 31 static int hlt_counter=0; 32 33 int ubc_usercnt = 0; 34 35 #define HARD_IDLE_TIMEOUT (HZ / 3) 36 37 void (*pm_idle)(void); 38 39 void (*pm_power_off)(void); 40 EXPORT_SYMBOL(pm_power_off); 41 42 void disable_hlt(void) 43 { 44 hlt_counter++; 45 } 46 47 EXPORT_SYMBOL(disable_hlt); 48 49 void enable_hlt(void) 50 { 51 hlt_counter--; 52 } 53 54 EXPORT_SYMBOL(enable_hlt); 55 56 void default_idle(void) 57 { 58 if (!hlt_counter) 59 cpu_sleep(); 60 else 61 cpu_relax(); 62 } 63 64 void cpu_idle(void) 65 { 66 /* endless idle loop with no priority at all */ 67 while (1) { 68 void (*idle)(void) = pm_idle; 69 70 if (!idle) 71 idle = default_idle; 72 73 while (!need_resched()) 74 idle(); 75 76 preempt_enable_no_resched(); 77 schedule(); 78 preempt_disable(); 79 } 80 } 81 82 void machine_restart(char * __unused) 83 { 84 85 #ifdef CONFIG_KEXEC 86 struct kimage *image; 87 image = xchg(&kexec_image, 0); 88 if (image) { 89 machine_shutdown(); 90 machine_kexec(image); 91 } 92 #endif 93 94 /* SR.BL=1 and invoke address error to let CPU reset (manual reset) */ 95 asm volatile("ldc %0, sr\n\t" 96 "mov.l @%1, %0" : : "r" (0x10000000), "r" (0x80000001)); 97 } 98 99 void machine_halt(void) 100 { 101 local_irq_disable(); 102 103 while (1) 104 cpu_sleep(); 105 } 106 107 void machine_power_off(void) 108 { 109 if (pm_power_off) 110 pm_power_off(); 111 } 112 113 void show_regs(struct pt_regs * regs) 114 { 115 printk("\n"); 116 printk("Pid : %d, Comm: %20s\n", current->pid, current->comm); 117 print_symbol("PC is at %s\n", regs->pc); 118 printk("PC : %08lx SP : %08lx SR : %08lx ", 119 regs->pc, regs->regs[15], regs->sr); 120 #ifdef CONFIG_MMU 121 printk("TEA : %08x ", ctrl_inl(MMU_TEA)); 122 #else 123 printk(" "); 124 #endif 125 printk("%s\n", print_tainted()); 126 127 printk("R0 : %08lx R1 : %08lx R2 : %08lx R3 : %08lx\n", 128 regs->regs[0],regs->regs[1], 129 regs->regs[2],regs->regs[3]); 130 printk("R4 : %08lx R5 : %08lx R6 : %08lx R7 : %08lx\n", 131 regs->regs[4],regs->regs[5], 132 regs->regs[6],regs->regs[7]); 133 printk("R8 : %08lx R9 : %08lx R10 : %08lx R11 : %08lx\n", 134 regs->regs[8],regs->regs[9], 135 regs->regs[10],regs->regs[11]); 136 printk("R12 : %08lx R13 : %08lx R14 : %08lx\n", 137 regs->regs[12],regs->regs[13], 138 regs->regs[14]); 139 printk("MACH: %08lx MACL: %08lx GBR : %08lx PR : %08lx\n", 140 regs->mach, regs->macl, regs->gbr, regs->pr); 141 142 /* 143 * If we're in kernel mode, dump the stack too.. 144 */ 145 if (!user_mode(regs)) { 146 extern void show_task(unsigned long *sp); 147 unsigned long sp = regs->regs[15]; 148 149 show_task((unsigned long *)sp); 150 } 151 } 152 153 /* 154 * Create a kernel thread 155 */ 156 157 /* 158 * This is the mechanism for creating a new kernel thread. 159 * 160 */ 161 extern void kernel_thread_helper(void); 162 __asm__(".align 5\n" 163 "kernel_thread_helper:\n\t" 164 "jsr @r5\n\t" 165 " nop\n\t" 166 "mov.l 1f, r1\n\t" 167 "jsr @r1\n\t" 168 " mov r0, r4\n\t" 169 ".align 2\n\t" 170 "1:.long do_exit"); 171 172 int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) 173 { /* Don't use this in BL=1(cli). Or else, CPU resets! */ 174 struct pt_regs regs; 175 176 memset(®s, 0, sizeof(regs)); 177 regs.regs[4] = (unsigned long) arg; 178 regs.regs[5] = (unsigned long) fn; 179 180 regs.pc = (unsigned long) kernel_thread_helper; 181 regs.sr = (1 << 30); 182 183 /* Ok, create the new process.. */ 184 return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); 185 } 186 187 /* 188 * Free current thread data structures etc.. 189 */ 190 void exit_thread(void) 191 { 192 if (current->thread.ubc_pc) { 193 current->thread.ubc_pc = 0; 194 ubc_usercnt -= 1; 195 } 196 } 197 198 void flush_thread(void) 199 { 200 #if defined(CONFIG_SH_FPU) 201 struct task_struct *tsk = current; 202 /* Forget lazy FPU state */ 203 clear_fpu(tsk, task_pt_regs(tsk)); 204 clear_used_math(); 205 #endif 206 } 207 208 void release_thread(struct task_struct *dead_task) 209 { 210 /* do nothing */ 211 } 212 213 /* Fill in the fpu structure for a core dump.. */ 214 int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu) 215 { 216 int fpvalid = 0; 217 218 #if defined(CONFIG_SH_FPU) 219 struct task_struct *tsk = current; 220 221 fpvalid = !!tsk_used_math(tsk); 222 if (fpvalid) { 223 unlazy_fpu(tsk, regs); 224 memcpy(fpu, &tsk->thread.fpu.hard, sizeof(*fpu)); 225 } 226 #endif 227 228 return fpvalid; 229 } 230 231 /* 232 * Capture the user space registers if the task is not running (in user space) 233 */ 234 int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs) 235 { 236 struct pt_regs ptregs; 237 238 ptregs = *task_pt_regs(tsk); 239 elf_core_copy_regs(regs, &ptregs); 240 241 return 1; 242 } 243 244 int 245 dump_task_fpu (struct task_struct *tsk, elf_fpregset_t *fpu) 246 { 247 int fpvalid = 0; 248 249 #if defined(CONFIG_SH_FPU) 250 fpvalid = !!tsk_used_math(tsk); 251 if (fpvalid) { 252 unlazy_fpu(tsk, task_pt_regs(tsk)); 253 memcpy(fpu, &tsk->thread.fpu.hard, sizeof(*fpu)); 254 } 255 #endif 256 257 return fpvalid; 258 } 259 260 asmlinkage void ret_from_fork(void); 261 262 int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, 263 unsigned long unused, 264 struct task_struct *p, struct pt_regs *regs) 265 { 266 struct pt_regs *childregs; 267 #if defined(CONFIG_SH_FPU) 268 struct task_struct *tsk = current; 269 270 unlazy_fpu(tsk, regs); 271 p->thread.fpu = tsk->thread.fpu; 272 copy_to_stopped_child_used_math(p); 273 #endif 274 275 childregs = task_pt_regs(p); 276 *childregs = *regs; 277 278 if (user_mode(regs)) { 279 childregs->regs[15] = usp; 280 } else { 281 childregs->regs[15] = (unsigned long)task_stack_page(p) + THREAD_SIZE; 282 } 283 if (clone_flags & CLONE_SETTLS) { 284 childregs->gbr = childregs->regs[0]; 285 } 286 childregs->regs[0] = 0; /* Set return value for child */ 287 288 p->thread.sp = (unsigned long) childregs; 289 p->thread.pc = (unsigned long) ret_from_fork; 290 291 p->thread.ubc_pc = 0; 292 293 return 0; 294 } 295 296 /* Tracing by user break controller. */ 297 static void 298 ubc_set_tracing(int asid, unsigned long pc) 299 { 300 ctrl_outl(pc, UBC_BARA); 301 302 /* We don't have any ASID settings for the SH-2! */ 303 if (cpu_data->type != CPU_SH7604) 304 ctrl_outb(asid, UBC_BASRA); 305 306 ctrl_outl(0, UBC_BAMRA); 307 308 if (cpu_data->type == CPU_SH7729) { 309 ctrl_outw(BBR_INST | BBR_READ | BBR_CPU, UBC_BBRA); 310 ctrl_outl(BRCR_PCBA | BRCR_PCTE, UBC_BRCR); 311 } else { 312 ctrl_outw(BBR_INST | BBR_READ, UBC_BBRA); 313 ctrl_outw(BRCR_PCBA, UBC_BRCR); 314 } 315 } 316 317 /* 318 * switch_to(x,y) should switch tasks from x to y. 319 * 320 */ 321 struct task_struct *__switch_to(struct task_struct *prev, struct task_struct *next) 322 { 323 #if defined(CONFIG_SH_FPU) 324 unlazy_fpu(prev, task_pt_regs(prev)); 325 #endif 326 327 #ifdef CONFIG_PREEMPT 328 { 329 unsigned long flags; 330 struct pt_regs *regs; 331 332 local_irq_save(flags); 333 regs = task_pt_regs(prev); 334 if (user_mode(regs) && regs->regs[15] >= 0xc0000000) { 335 int offset = (int)regs->regs[15]; 336 337 /* Reset stack pointer: clear critical region mark */ 338 regs->regs[15] = regs->regs[1]; 339 if (regs->pc < regs->regs[0]) 340 /* Go to rewind point */ 341 regs->pc = regs->regs[0] + offset; 342 } 343 local_irq_restore(flags); 344 } 345 #endif 346 347 /* 348 * Restore the kernel mode register 349 * k7 (r7_bank1) 350 */ 351 asm volatile("ldc %0, r7_bank" 352 : /* no output */ 353 : "r" (task_thread_info(next))); 354 355 #ifdef CONFIG_MMU 356 /* If no tasks are using the UBC, we're done */ 357 if (ubc_usercnt == 0) 358 /* If no tasks are using the UBC, we're done */; 359 else if (next->thread.ubc_pc && next->mm) { 360 ubc_set_tracing(next->mm->context & MMU_CONTEXT_ASID_MASK, 361 next->thread.ubc_pc); 362 } else { 363 ctrl_outw(0, UBC_BBRA); 364 ctrl_outw(0, UBC_BBRB); 365 } 366 #endif 367 368 return prev; 369 } 370 371 asmlinkage int sys_fork(unsigned long r4, unsigned long r5, 372 unsigned long r6, unsigned long r7, 373 struct pt_regs regs) 374 { 375 #ifdef CONFIG_MMU 376 return do_fork(SIGCHLD, regs.regs[15], ®s, 0, NULL, NULL); 377 #else 378 /* fork almost works, enough to trick you into looking elsewhere :-( */ 379 return -EINVAL; 380 #endif 381 } 382 383 asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp, 384 unsigned long parent_tidptr, 385 unsigned long child_tidptr, 386 struct pt_regs regs) 387 { 388 if (!newsp) 389 newsp = regs.regs[15]; 390 return do_fork(clone_flags, newsp, ®s, 0, 391 (int __user *)parent_tidptr, (int __user *)child_tidptr); 392 } 393 394 /* 395 * This is trivial, and on the face of it looks like it 396 * could equally well be done in user mode. 397 * 398 * Not so, for quite unobvious reasons - register pressure. 399 * In user mode vfork() cannot have a stack frame, and if 400 * done by calling the "clone()" system call directly, you 401 * do not have enough call-clobbered registers to hold all 402 * the information you need. 403 */ 404 asmlinkage int sys_vfork(unsigned long r4, unsigned long r5, 405 unsigned long r6, unsigned long r7, 406 struct pt_regs regs) 407 { 408 return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.regs[15], ®s, 409 0, NULL, NULL); 410 } 411 412 /* 413 * sys_execve() executes a new program. 414 */ 415 asmlinkage int sys_execve(char *ufilename, char **uargv, 416 char **uenvp, unsigned long r7, 417 struct pt_regs regs) 418 { 419 int error; 420 char *filename; 421 422 filename = getname((char __user *)ufilename); 423 error = PTR_ERR(filename); 424 if (IS_ERR(filename)) 425 goto out; 426 427 error = do_execve(filename, 428 (char __user * __user *)uargv, 429 (char __user * __user *)uenvp, 430 ®s); 431 if (error == 0) { 432 task_lock(current); 433 current->ptrace &= ~PT_DTRACE; 434 task_unlock(current); 435 } 436 putname(filename); 437 out: 438 return error; 439 } 440 441 unsigned long get_wchan(struct task_struct *p) 442 { 443 unsigned long schedule_frame; 444 unsigned long pc; 445 446 if (!p || p == current || p->state == TASK_RUNNING) 447 return 0; 448 449 /* 450 * The same comment as on the Alpha applies here, too ... 451 */ 452 pc = thread_saved_pc(p); 453 if (in_sched_functions(pc)) { 454 schedule_frame = ((unsigned long *)(long)p->thread.sp)[1]; 455 return (unsigned long)((unsigned long *)schedule_frame)[1]; 456 } 457 return pc; 458 } 459 460 asmlinkage void break_point_trap(unsigned long r4, unsigned long r5, 461 unsigned long r6, unsigned long r7, 462 struct pt_regs regs) 463 { 464 /* Clear tracing. */ 465 ctrl_outw(0, UBC_BBRA); 466 ctrl_outw(0, UBC_BBRB); 467 current->thread.ubc_pc = 0; 468 ubc_usercnt -= 1; 469 470 force_sig(SIGTRAP, current); 471 } 472 473 asmlinkage void break_point_trap_software(unsigned long r4, unsigned long r5, 474 unsigned long r6, unsigned long r7, 475 struct pt_regs regs) 476 { 477 regs.pc -= 2; 478 force_sig(SIGTRAP, current); 479 } 480