| .. | .. |
|---|
| 34 | 34 | #include <asm/oplib.h> |
|---|
| 35 | 35 | #include <linux/uaccess.h> |
|---|
| 36 | 36 | #include <asm/page.h> |
|---|
| 37 | | -#include <asm/pgalloc.h> |
|---|
| 38 | | -#include <asm/pgtable.h> |
|---|
| 39 | 37 | #include <asm/delay.h> |
|---|
| 40 | 38 | #include <asm/processor.h> |
|---|
| 41 | 39 | #include <asm/psr.h> |
|---|
| .. | .. |
|---|
| 76 | 74 | { |
|---|
| 77 | 75 | if (sparc_idle) |
|---|
| 78 | 76 | (*sparc_idle)(); |
|---|
| 79 | | - local_irq_enable(); |
|---|
| 77 | + raw_local_irq_enable(); |
|---|
| 80 | 78 | } |
|---|
| 81 | 79 | |
|---|
| 82 | 80 | /* XXX cli/sti -> local_irq_xxx here, check this works once SMP is fixed. */ |
|---|
| .. | .. |
|---|
| 110 | 108 | void machine_power_off(void) |
|---|
| 111 | 109 | { |
|---|
| 112 | 110 | if (auxio_power_register && |
|---|
| 113 | | - (strcmp(of_console_device->type, "serial") || scons_pwroff)) { |
|---|
| 111 | + (!of_node_is_type(of_console_device, "serial") || scons_pwroff)) { |
|---|
| 114 | 112 | u8 power_register = sbus_readb(auxio_power_register); |
|---|
| 115 | 113 | power_register |= AUXIO_POWER_OFF; |
|---|
| 116 | 114 | sbus_writeb(power_register, auxio_power_register); |
|---|
| .. | .. |
|---|
| 145 | 143 | } |
|---|
| 146 | 144 | |
|---|
| 147 | 145 | /* |
|---|
| 148 | | - * The show_stack is an external API which we do not use ourselves. |
|---|
| 146 | + * The show_stack() is external API which we do not use ourselves. |
|---|
| 149 | 147 | * The oops is printed in die_if_kernel. |
|---|
| 150 | 148 | */ |
|---|
| 151 | | -void show_stack(struct task_struct *tsk, unsigned long *_ksp) |
|---|
| 149 | +void show_stack(struct task_struct *tsk, unsigned long *_ksp, const char *loglvl) |
|---|
| 152 | 150 | { |
|---|
| 153 | 151 | unsigned long pc, fp; |
|---|
| 154 | 152 | unsigned long task_base; |
|---|
| .. | .. |
|---|
| 170 | 168 | break; |
|---|
| 171 | 169 | rw = (struct reg_window32 *) fp; |
|---|
| 172 | 170 | pc = rw->ins[7]; |
|---|
| 173 | | - printk("[%08lx : ", pc); |
|---|
| 174 | | - printk("%pS ] ", (void *) pc); |
|---|
| 171 | + printk("%s[%08lx : ", loglvl, pc); |
|---|
| 172 | + printk("%s%pS ] ", loglvl, (void *) pc); |
|---|
| 175 | 173 | fp = rw->ins[6]; |
|---|
| 176 | 174 | } while (++count < 16); |
|---|
| 177 | | - printk("\n"); |
|---|
| 175 | + printk("%s\n", loglvl); |
|---|
| 178 | 176 | } |
|---|
| 179 | 177 | |
|---|
| 180 | 178 | /* |
|---|
| .. | .. |
|---|
| 258 | 256 | return sp; |
|---|
| 259 | 257 | } |
|---|
| 260 | 258 | |
|---|
| 261 | | -asmlinkage int sparc_do_fork(unsigned long clone_flags, |
|---|
| 262 | | - unsigned long stack_start, |
|---|
| 263 | | - struct pt_regs *regs, |
|---|
| 264 | | - unsigned long stack_size) |
|---|
| 265 | | -{ |
|---|
| 266 | | - unsigned long parent_tid_ptr, child_tid_ptr; |
|---|
| 267 | | - unsigned long orig_i1 = regs->u_regs[UREG_I1]; |
|---|
| 268 | | - long ret; |
|---|
| 269 | | - |
|---|
| 270 | | - parent_tid_ptr = regs->u_regs[UREG_I2]; |
|---|
| 271 | | - child_tid_ptr = regs->u_regs[UREG_I4]; |
|---|
| 272 | | - |
|---|
| 273 | | - ret = do_fork(clone_flags, stack_start, stack_size, |
|---|
| 274 | | - (int __user *) parent_tid_ptr, |
|---|
| 275 | | - (int __user *) child_tid_ptr); |
|---|
| 276 | | - |
|---|
| 277 | | - /* If we get an error and potentially restart the system |
|---|
| 278 | | - * call, we're screwed because copy_thread() clobbered |
|---|
| 279 | | - * the parent's %o1. So detect that case and restore it |
|---|
| 280 | | - * here. |
|---|
| 281 | | - */ |
|---|
| 282 | | - if ((unsigned long)ret >= -ERESTART_RESTARTBLOCK) |
|---|
| 283 | | - regs->u_regs[UREG_I1] = orig_i1; |
|---|
| 284 | | - |
|---|
| 285 | | - return ret; |
|---|
| 286 | | -} |
|---|
| 287 | | - |
|---|
| 288 | 259 | /* Copy a Sparc thread. The fork() return value conventions |
|---|
| 289 | 260 | * under SunOS are nothing short of bletcherous: |
|---|
| 290 | 261 | * Parent --> %o0 == childs pid, %o1 == 0 |
|---|
| .. | .. |
|---|
| 301 | 272 | extern void ret_from_fork(void); |
|---|
| 302 | 273 | extern void ret_from_kernel_thread(void); |
|---|
| 303 | 274 | |
|---|
| 304 | | -int copy_thread(unsigned long clone_flags, unsigned long sp, |
|---|
| 305 | | - unsigned long arg, struct task_struct *p) |
|---|
| 275 | +int copy_thread(unsigned long clone_flags, unsigned long sp, unsigned long arg, |
|---|
| 276 | + struct task_struct *p, unsigned long tls) |
|---|
| 306 | 277 | { |
|---|
| 307 | 278 | struct thread_info *ti = task_thread_info(p); |
|---|
| 308 | 279 | struct pt_regs *childregs, *regs = current_pt_regs(); |
|---|
| .. | .. |
|---|
| 338 | 309 | ti->ksp = (unsigned long) new_stack; |
|---|
| 339 | 310 | p->thread.kregs = childregs; |
|---|
| 340 | 311 | |
|---|
| 341 | | - if (unlikely(p->flags & PF_KTHREAD)) { |
|---|
| 312 | + if (unlikely(p->flags & (PF_KTHREAD | PF_IO_WORKER))) { |
|---|
| 342 | 313 | extern int nwindows; |
|---|
| 343 | 314 | unsigned long psr; |
|---|
| 344 | 315 | memset(new_stack, 0, STACKFRAME_SZ + TRACEREG_SZ); |
|---|
| .. | .. |
|---|
| 404 | 375 | regs->u_regs[UREG_I1] = 0; |
|---|
| 405 | 376 | |
|---|
| 406 | 377 | if (clone_flags & CLONE_SETTLS) |
|---|
| 407 | | - childregs->u_regs[UREG_G7] = regs->u_regs[UREG_I3]; |
|---|
| 378 | + childregs->u_regs[UREG_G7] = tls; |
|---|
| 408 | 379 | |
|---|
| 409 | 380 | return 0; |
|---|
| 410 | | -} |
|---|
| 411 | | - |
|---|
| 412 | | -/* |
|---|
| 413 | | - * fill in the fpu structure for a core dump. |
|---|
| 414 | | - */ |
|---|
| 415 | | -int dump_fpu (struct pt_regs * regs, elf_fpregset_t * fpregs) |
|---|
| 416 | | -{ |
|---|
| 417 | | - if (used_math()) { |
|---|
| 418 | | - memset(fpregs, 0, sizeof(*fpregs)); |
|---|
| 419 | | - fpregs->pr_q_entrysize = 8; |
|---|
| 420 | | - return 1; |
|---|
| 421 | | - } |
|---|
| 422 | | -#ifdef CONFIG_SMP |
|---|
| 423 | | - if (test_thread_flag(TIF_USEDFPU)) { |
|---|
| 424 | | - put_psr(get_psr() | PSR_EF); |
|---|
| 425 | | - fpsave(¤t->thread.float_regs[0], ¤t->thread.fsr, |
|---|
| 426 | | - ¤t->thread.fpqueue[0], ¤t->thread.fpqdepth); |
|---|
| 427 | | - if (regs != NULL) { |
|---|
| 428 | | - regs->psr &= ~(PSR_EF); |
|---|
| 429 | | - clear_thread_flag(TIF_USEDFPU); |
|---|
| 430 | | - } |
|---|
| 431 | | - } |
|---|
| 432 | | -#else |
|---|
| 433 | | - if (current == last_task_used_math) { |
|---|
| 434 | | - put_psr(get_psr() | PSR_EF); |
|---|
| 435 | | - fpsave(¤t->thread.float_regs[0], ¤t->thread.fsr, |
|---|
| 436 | | - ¤t->thread.fpqueue[0], ¤t->thread.fpqdepth); |
|---|
| 437 | | - if (regs != NULL) { |
|---|
| 438 | | - regs->psr &= ~(PSR_EF); |
|---|
| 439 | | - last_task_used_math = NULL; |
|---|
| 440 | | - } |
|---|
| 441 | | - } |
|---|
| 442 | | -#endif |
|---|
| 443 | | - memcpy(&fpregs->pr_fr.pr_regs[0], |
|---|
| 444 | | - ¤t->thread.float_regs[0], |
|---|
| 445 | | - (sizeof(unsigned long) * 32)); |
|---|
| 446 | | - fpregs->pr_fsr = current->thread.fsr; |
|---|
| 447 | | - fpregs->pr_qcnt = current->thread.fpqdepth; |
|---|
| 448 | | - fpregs->pr_q_entrysize = 8; |
|---|
| 449 | | - fpregs->pr_en = 1; |
|---|
| 450 | | - if(fpregs->pr_qcnt != 0) { |
|---|
| 451 | | - memcpy(&fpregs->pr_q[0], |
|---|
| 452 | | - ¤t->thread.fpqueue[0], |
|---|
| 453 | | - sizeof(struct fpq) * fpregs->pr_qcnt); |
|---|
| 454 | | - } |
|---|
| 455 | | - /* Zero out the rest. */ |
|---|
| 456 | | - memset(&fpregs->pr_q[fpregs->pr_qcnt], 0, |
|---|
| 457 | | - sizeof(struct fpq) * (32 - fpregs->pr_qcnt)); |
|---|
| 458 | | - return 1; |
|---|
| 459 | 381 | } |
|---|
| 460 | 382 | |
|---|
| 461 | 383 | unsigned long get_wchan(struct task_struct *task) |
|---|