/* * Write contents of register REGNO in task TASK. */ int put_reg(struct task_struct *task, unsigned int regno, unsigned long data) { if (regno <= PT_EDA) ((unsigned long *)user_regs(task->thread_info))[regno] = data; else if (regno == PT_USP) task->thread.usp = data; else if (regno == PT_PPC) { /* Write pseudo-PC to ERP only if changed. */ if (data != get_pseudo_pc(task)) ((unsigned long *)user_regs(task->thread_info))[PT_ERP] = data; } else if (regno <= PT_MAX) return put_debugreg(task->pid, regno, data); else return -1; return 0; }
/* * Write contents of register REGNO in task TASK. */ static inline int put_reg(struct task_struct *task, unsigned int regno, unsigned long data) { if (regno == PT_USP) task->thread.usp = data; else if (regno < PT_MAX) ((unsigned long *)user_regs(task))[regno] = data; else return -1; return 0; }
/* * Get contents of register REGNO in task TASK. */ static inline long get_reg(struct task_struct *task, unsigned int regno) { /* USP is a special case, it's not in the pt_regs struct but * in the tasks thread struct */ if (regno == PT_USP) return task->thread.usp; else if (regno < PT_MAX) return ((unsigned long *)user_regs(task))[regno]; else return 0; }
int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, unsigned long unused, struct task_struct *p, struct pt_regs *regs) { struct pt_regs * childregs; struct switch_stack *swstack; /* put the pt_regs structure at the end of the new kernel stack page and fix it up * remember that the task_struct doubles as the kernel stack for the task */ childregs = user_regs(p->thread_info); *childregs = *regs; /* struct copy of pt_regs */ p->set_child_tid = p->clear_child_tid = NULL; childregs->r10 = 0; /* child returns 0 after a fork/clone */ /* put the switch stack right below the pt_regs */ swstack = ((struct switch_stack *)childregs) - 1; swstack->r9 = 0; /* parameter to ret_from_sys_call, 0 == dont restart the syscall */ /* we want to return into ret_from_sys_call after the _resume */ swstack->return_ip = (unsigned long) ret_from_fork; /* Will call ret_from_sys_call */ /* fix the user-mode stackpointer */ p->thread.usp = usp; /* and the kernel-mode one */ p->thread.ksp = (unsigned long) swstack; #ifdef DEBUG printk("copy_thread: new regs at 0x%p, as shown below:\n", childregs); show_registers(childregs); #endif return 0; }
/* * Get contents of register REGNO in task TASK. */ long get_reg(struct task_struct *task, unsigned int regno) { /* USP is a special case, it's not in the pt_regs struct but * in the tasks thread struct */ unsigned long ret; if (regno <= PT_EDA) ret = ((unsigned long *)user_regs(task->thread_info))[regno]; else if (regno == PT_USP) ret = task->thread.usp; else if (regno == PT_PPC) ret = get_pseudo_pc(task); else if (regno <= PT_MAX) ret = get_debugreg(task->pid, regno); else ret = 0; return ret; }
unsigned long thread_saved_pc(struct task_struct *t) { return (unsigned long)user_regs(t->stack)->pc; }
/* * Return saved PC of a blocked thread. */ unsigned long thread_saved_pc(struct task_struct *t) { return (unsigned long)user_regs(t->thread_info)->irp; }