1 /* $NetBSD: process_machdep.c,v 1.6 2001/02/28 18:15:42 bjh21 Exp $ */ 2 3 /* 4 * Copyright (c) 1995 Frank Lancaster. All rights reserved. 5 * Copyright (c) 1995 Tools GmbH. All rights reserved. 6 * Copyright (c) 1995 Charles M. Hannum. All rights reserved. 7 * Copyright (c) 1993 The Regents of the University of California. 8 * Copyright (c) 1993 Jan-Simon Pendry 9 * All rights reserved. 10 * 11 * This code is derived from software contributed to Berkeley by 12 * Jan-Simon Pendry. 13 * 14 * Redistribution and use in source and binary forms, with or without 15 * modification, are permitted provided that the following conditions 16 * are met: 17 * 1. Redistributions of source code must retain the above copyright 18 * notice, this list of conditions and the following disclaimer. 19 * 2. Redistributions in binary form must reproduce the above copyright 20 * notice, this list of conditions and the following disclaimer in the 21 * documentation and/or other materials provided with the distribution. 22 * 3. All advertising materials mentioning features or use of this software 23 * must display the following acknowledgement: 24 * This product includes software developed by the University of 25 * California, Berkeley and its contributors. 26 * 4. Neither the name of the University nor the names of its contributors 27 * may be used to endorse or promote products derived from this software 28 * without specific prior written permission. 29 * 30 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 31 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 32 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 33 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 34 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 35 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 36 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 37 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 38 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 39 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 40 * SUCH DAMAGE. 41 * 42 * From: 43 * Id: procfs_i386.c,v 4.1 1993/12/17 10:47:45 jsp Rel 44 */ 45 46 /* 47 * This file may seem a bit stylized, but that so that it's easier to port. 48 * Functions to be implemented here are: 49 * 50 * process_read_regs(proc, regs) 51 * Get the current user-visible register set from the process 52 * and copy it into the regs structure (<machine/reg.h>). 53 * The process is stopped at the time read_regs is called. 54 * 55 * process_write_regs(proc, regs) 56 * Update the current register set from the passed in regs 57 * structure. Take care to avoid clobbering special CPU 58 * registers or privileged bits in the PSL. 59 * The process is stopped at the time write_regs is called. 60 * 61 * process_sstep(proc, sstep) 62 * Arrange for the process to trap or not trap depending on sstep 63 * after executing a single instruction. 64 * 65 * process_set_pc(proc) 66 * Set the process's program counter. 67 */ 68 69 #include "opt_armfpe.h" 70 #include "opt_progmode.h" 71 72 #include <sys/param.h> 73 74 __KERNEL_RCSID(0, "$NetBSD: process_machdep.c,v 1.6 2001/02/28 18:15:42 bjh21 Exp $"); 75 76 #include <sys/proc.h> 77 #include <sys/ptrace.h> 78 #include <sys/systm.h> 79 #include <sys/user.h> 80 81 #include <machine/frame.h> 82 #include <machine/pcb.h> 83 #include <machine/reg.h> 84 85 #include <arm/armreg.h> 86 87 #ifdef ARMFPE 88 #include <arm32/fpe-arm/armfpe.h> 89 #endif /* ARMFPE */ 90 91 static __inline struct trapframe * 92 process_frame(struct proc *p) 93 { 94 95 return p->p_addr->u_pcb.pcb_tf; 96 } 97 98 int 99 process_read_regs(struct proc *p, struct reg *regs) 100 { 101 struct trapframe *tf = process_frame(p); 102 103 KASSERT(tf != NULL); 104 bcopy((caddr_t)&tf->tf_r0, (caddr_t)regs->r, sizeof(regs->r)); 105 regs->r_sp = tf->tf_usr_sp; 106 regs->r_lr = tf->tf_usr_lr; 107 regs->r_pc = tf->tf_pc; 108 regs->r_cpsr = tf->tf_spsr; 109 110 return(0); 111 } 112 113 int 114 process_read_fpregs(struct proc *p, struct fpreg *regs) 115 { 116 #ifdef ARMFPE 117 arm_fpe_getcontext(p, regs); 118 return(0); 119 #else /* ARMFPE */ 120 /* No hardware FP support */ 121 memset(regs, 0, sizeof(struct fpreg)); 122 return(0); 123 #endif /* ARMFPE */ 124 } 125 126 int 127 process_write_regs(struct proc *p, struct reg *regs) 128 { 129 struct trapframe *tf = process_frame(p); 130 131 KASSERT(tf != NULL); 132 bcopy((caddr_t)regs->r, (caddr_t)&tf->tf_r0, sizeof(regs->r)); 133 tf->tf_usr_sp = regs->r_sp; 134 tf->tf_usr_lr = regs->r_lr; 135 #ifdef PROG32 136 tf->tf_pc = regs->r_pc; 137 tf->tf_spsr &= ~PSR_FLAGS; 138 tf->tf_spsr |= regs->r_cpsr & PSR_FLAGS; 139 #else /* PROG26 */ 140 if ((regs->r_pc & (R15_MODE | R15_IRQ_DISABLE | R15_FIQ_DISABLE)) != 0) 141 return EPERM; 142 143 tf->tf_r15 = regs->r_pc; 144 #endif 145 146 return(0); 147 } 148 149 int 150 process_write_fpregs(struct proc *p, struct fpreg *regs) 151 { 152 #ifdef ARMFPE 153 arm_fpe_setcontext(p, regs); 154 return(0); 155 #else /* ARMFPE */ 156 /* No hardware FP support */ 157 return(0); 158 #endif /* ARMFPE */ 159 } 160 161 int 162 process_set_pc(struct proc *p, caddr_t addr) 163 { 164 struct trapframe *tf = process_frame(p); 165 166 KASSERT(tf != NULL); 167 #ifdef PROG32 168 tf->tf_pc = (int)addr; 169 #else /* PROG26 */ 170 /* Only set the PC, not the PSR */ 171 if (((register_t)addr & R15_PC) != (register_t)addr) 172 return EINVAL; 173 tf->tf_r15 = (tf->tf_r15 & ~R15_PC) | (register_t)addr; 174 #endif 175 176 return (0); 177 } 178