1 /* $OpenBSD: process_machdep.c,v 1.13 2007/09/09 20:49:18 kettenis Exp $ */ 2 /* $NetBSD: process_machdep.c,v 1.1 1996/09/30 16:34:53 ws Exp $ */ 3 4 /* 5 * Copyright (C) 1995, 1996 Wolfgang Solfrank. 6 * Copyright (C) 1995, 1996 TooLs GmbH. 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This product includes software developed by TooLs GmbH. 20 * 4. The name of TooLs GmbH may not be used to endorse or promote products 21 * derived from this software without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR 24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 28 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 29 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 30 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 31 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 32 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 */ 34 #include <sys/param.h> 35 #include <sys/systm.h> 36 #include <sys/proc.h> 37 #include <sys/ptrace.h> 38 #include <sys/user.h> 39 40 #include <machine/fpu.h> 41 #include <machine/pcb.h> 42 #include <machine/psl.h> 43 #include <machine/reg.h> 44 45 int 46 process_read_regs(struct proc *p, struct reg *regs) 47 { 48 struct cpu_info *ci = curcpu(); 49 struct trapframe *tf = trapframe(p); 50 struct pcb *pcb = &p->p_addr->u_pcb; 51 52 bcopy(tf->fixreg, regs->gpr, sizeof(regs->gpr)); 53 54 if (!(pcb->pcb_flags & PCB_FPU)) { 55 bzero(regs->fpr, sizeof(regs->fpr)); 56 } else { 57 /* XXX What if the state is on the other cpu? */ 58 if (p == ci->ci_fpuproc) 59 save_fpu(); 60 bcopy(pcb->pcb_fpu.fpr, regs->fpr, sizeof(regs->fpr)); 61 } 62 63 regs->pc = tf->srr0; 64 regs->ps = tf->srr1; /* is this the correct value for this ? */ 65 regs->cnd = tf->cr; 66 regs->lr = tf->lr; 67 regs->cnt = tf->ctr; 68 regs->xer = tf->xer; 69 regs->mq = 0; /* what should this really be? */ 70 71 return (0); 72 } 73 74 int 75 process_read_fpregs(struct proc *p, struct fpreg *regs) 76 { 77 struct cpu_info *ci = curcpu(); 78 struct pcb *pcb = &p->p_addr->u_pcb; 79 80 if (!(pcb->pcb_flags & PCB_FPU)) { 81 bzero(regs->fpr, sizeof(regs->fpr)); 82 regs->fpscr = 0; 83 } else { 84 /* XXX What if the state is on the other cpu? */ 85 if (p == ci->ci_fpuproc) 86 save_fpu(); 87 bcopy(pcb->pcb_fpu.fpr, regs->fpr, sizeof(regs->fpr)); 88 regs->fpscr = *(u_int64_t *)&pcb->pcb_fpu.fpcsr; 89 } 90 91 return (0); 92 } 93 94 #ifdef PTRACE 95 96 /* 97 * Set the process's program counter. 98 */ 99 int 100 process_set_pc(struct proc *p, caddr_t addr) 101 { 102 struct trapframe *tf = trapframe(p); 103 104 tf->srr0 = (u_int32_t)addr; 105 return 0; 106 } 107 108 int 109 process_sstep(struct proc *p, int sstep) 110 { 111 struct trapframe *tf = trapframe(p); 112 113 if (sstep) 114 tf->srr1 |= PSL_SE; 115 else 116 tf->srr1 &= ~PSL_SE; 117 return 0; 118 } 119 120 int 121 process_write_regs(struct proc *p, struct reg *regs) 122 { 123 struct cpu_info *ci = curcpu(); 124 struct trapframe *tf = trapframe(p); 125 struct pcb *pcb = &p->p_addr->u_pcb; 126 127 if ((regs->ps ^ tf->srr1) & PSL_USERSTATIC) 128 return EINVAL; 129 130 bcopy(regs->gpr, tf->fixreg, sizeof(regs->gpr)); 131 132 /* XXX What if the state is on the other cpu? */ 133 if (p == ci->ci_fpuproc) { /* release the fpu */ 134 save_fpu(); 135 ci->ci_fpuproc = NULL; 136 } 137 138 bcopy(regs->fpr, pcb->pcb_fpu.fpr, sizeof(regs->fpr)); 139 if (!(pcb->pcb_flags & PCB_FPU)) { 140 pcb->pcb_fpu.fpcsr = 0; 141 pcb->pcb_flags |= PCB_FPU; 142 } 143 144 tf->srr0 = regs->pc; 145 tf->srr1 = regs->ps; /* is this the correct value for this ? */ 146 tf->cr = regs->cnd; 147 tf->lr = regs->lr; 148 tf->ctr = regs->cnt; 149 tf->xer = regs->xer; 150 /* regs->mq = 0; what should this really be? */ 151 152 return (0); 153 } 154 155 int 156 process_write_fpregs(struct proc *p, struct fpreg *regs) 157 { 158 struct cpu_info *ci = curcpu(); 159 struct pcb *pcb = &p->p_addr->u_pcb; 160 u_int64_t fpscr = regs->fpscr; 161 162 /* XXX What if the state is on the other cpu? */ 163 if (p == ci->ci_fpuproc) { /* release the fpu */ 164 save_fpu(); 165 ci->ci_fpuproc = NULL; 166 } 167 168 bcopy(regs->fpr, pcb->pcb_fpu.fpr, sizeof(regs->fpr)); 169 pcb->pcb_fpu.fpcsr = *(double *)&fpscr; 170 pcb->pcb_flags |= PCB_FPU; 171 172 return (0); 173 } 174 175 #endif /* PTRACE */ 176