#include <sys/param.h>
#include <sys/systm.h>
#include <sys/proc.h>
#include <sys/ptrace.h>
#include <sys/user.h>
#include <machine/fpu.h>
#include <machine/pcb.h>
#include <machine/psl.h>
#include <machine/reg.h>
int
process_read_regs(struct proc *p, struct reg *regs)
{
struct cpu_info *ci = curcpu();
struct trapframe *tf = trapframe(p);
struct pcb *pcb = &p->p_addr->u_pcb;
bcopy(tf->fixreg, regs->gpr, sizeof(regs->gpr));
if (!(pcb->pcb_flags & PCB_FPU)) {
bzero(regs->fpr, sizeof(regs->fpr));
} else {
if (p == ci->ci_fpuproc)
save_fpu();
bcopy(pcb->pcb_fpu.fpr, regs->fpr, sizeof(regs->fpr));
}
regs->pc = tf->srr0;
regs->ps = tf->srr1;
regs->cnd = tf->cr;
regs->lr = tf->lr;
regs->cnt = tf->ctr;
regs->xer = tf->xer;
regs->mq = 0;
return (0);
}
int
process_read_fpregs(struct proc *p, struct fpreg *regs)
{
struct cpu_info *ci = curcpu();
struct pcb *pcb = &p->p_addr->u_pcb;
if (!(pcb->pcb_flags & PCB_FPU)) {
bzero(regs->fpr, sizeof(regs->fpr));
regs->fpscr = 0;
} else {
if (p == ci->ci_fpuproc)
save_fpu();
bcopy(pcb->pcb_fpu.fpr, regs->fpr, sizeof(regs->fpr));
regs->fpscr = *(u_int64_t *)&pcb->pcb_fpu.fpcsr;
}
return (0);
}
#ifdef PTRACE
int
process_set_pc(struct proc *p, caddr_t addr)
{
struct trapframe *tf = trapframe(p);
tf->srr0 = (u_int32_t)addr;
return 0;
}
int
process_sstep(struct proc *p, int sstep)
{
struct trapframe *tf = trapframe(p);
if (sstep)
tf->srr1 |= PSL_SE;
else
tf->srr1 &= ~PSL_SE;
return 0;
}
int
process_write_regs(struct proc *p, struct reg *regs)
{
struct cpu_info *ci = curcpu();
struct trapframe *tf = trapframe(p);
struct pcb *pcb = &p->p_addr->u_pcb;
if ((regs->ps ^ tf->srr1) & PSL_USERSTATIC)
return EINVAL;
bcopy(regs->gpr, tf->fixreg, sizeof(regs->gpr));
if (p == ci->ci_fpuproc) {
save_fpu();
ci->ci_fpuproc = NULL;
}
bcopy(regs->fpr, pcb->pcb_fpu.fpr, sizeof(regs->fpr));
if (!(pcb->pcb_flags & PCB_FPU)) {
pcb->pcb_fpu.fpcsr = 0;
pcb->pcb_flags |= PCB_FPU;
}
tf->srr0 = regs->pc;
tf->srr1 = regs->ps;
tf->cr = regs->cnd;
tf->lr = regs->lr;
tf->ctr = regs->cnt;
tf->xer = regs->xer;
return (0);
}
int
process_write_fpregs(struct proc *p, struct fpreg *regs)
{
struct cpu_info *ci = curcpu();
struct pcb *pcb = &p->p_addr->u_pcb;
u_int64_t fpscr = regs->fpscr;
if (p == ci->ci_fpuproc) {
save_fpu();
ci->ci_fpuproc = NULL;
}
bcopy(regs->fpr, pcb->pcb_fpu.fpr, sizeof(regs->fpr));
pcb->pcb_fpu.fpcsr = *(double *)&fpscr;
pcb->pcb_flags |= PCB_FPU;
return (0);
}
#endif