1 /* $NetBSD: process_machdep.c,v 1.19 2026/08/21 14:01:16 tls Exp $ */ 2 3 /* $OpenBSD: process_machdep.c,v 1.3 1999/06/18 05:19:52 mickey Exp $ */ 4 5 /* 6 * Copyright (c) 1999-2004 Michael Shalayeff 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 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, 22 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 27 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 28 * THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include <sys/cdefs.h> 32 __KERNEL_RCSID(0, "$NetBSD: process_machdep.c,v 1.19 2026/08/21 14:01:16 tls Exp $"); 33 34 #include <sys/param.h> 35 #include <sys/systm.h> 36 #include <sys/proc.h> 37 #include <sys/ptrace.h> 38 39 #include <uvm/uvm_extern.h> 40 41 #include <machine/cpufunc.h> 42 #include <machine/pmap.h> 43 #include <machine/frame.h> 44 #include <machine/pcb.h> 45 46 #include <hppa/hppa/machdep.h> 47 48 int 49 process_read_regs(struct lwp *l, struct reg *regs) 50 { 51 struct trapframe *tf = l->l_md.md_regs; 52 53 regs->r_regs[ 0] = tf->tf_ipsw; 54 regs->r_regs[ 1] = tf->tf_r1; 55 regs->r_regs[ 2] = tf->tf_rp; 56 regs->r_regs[ 3] = tf->tf_r3; 57 regs->r_regs[ 4] = tf->tf_r4; 58 regs->r_regs[ 5] = tf->tf_r5; 59 regs->r_regs[ 6] = tf->tf_r6; 60 regs->r_regs[ 7] = tf->tf_r7; 61 regs->r_regs[ 8] = tf->tf_r8; 62 regs->r_regs[ 9] = tf->tf_r9; 63 regs->r_regs[10] = tf->tf_r10; 64 regs->r_regs[11] = tf->tf_r11; 65 regs->r_regs[12] = tf->tf_r12; 66 regs->r_regs[13] = tf->tf_r13; 67 regs->r_regs[14] = tf->tf_r14; 68 regs->r_regs[15] = tf->tf_r15; 69 regs->r_regs[16] = tf->tf_r16; 70 regs->r_regs[17] = tf->tf_r17; 71 regs->r_regs[18] = tf->tf_r18; 72 regs->r_regs[19] = tf->tf_t4; 73 regs->r_regs[20] = tf->tf_t3; 74 regs->r_regs[21] = tf->tf_t2; 75 regs->r_regs[22] = tf->tf_t1; 76 regs->r_regs[23] = tf->tf_arg3; 77 regs->r_regs[24] = tf->tf_arg2; 78 regs->r_regs[25] = tf->tf_arg1; 79 regs->r_regs[26] = tf->tf_arg0; 80 regs->r_regs[27] = tf->tf_dp; 81 regs->r_regs[28] = tf->tf_ret0; 82 regs->r_regs[29] = tf->tf_ret1; 83 regs->r_regs[30] = tf->tf_sp; 84 regs->r_regs[31] = tf->tf_r31; 85 86 regs->r_sar = tf->tf_sar; 87 88 regs->r_pcsqh = tf->tf_iisq_head; 89 regs->r_pcsqt = tf->tf_iisq_tail; 90 regs->r_pcoqh = tf->tf_iioq_head; 91 regs->r_pcoqt = tf->tf_iioq_tail; 92 93 regs->r_sr0 = tf->tf_sr0; 94 regs->r_sr1 = tf->tf_sr1; 95 regs->r_sr2 = tf->tf_sr2; 96 regs->r_sr3 = tf->tf_sr3; 97 regs->r_sr4 = tf->tf_sr4; 98 regs->r_sr5 = tf->tf_sr5; 99 regs->r_sr6 = tf->tf_sr6; 100 regs->r_sr7 = tf->tf_sr7; 101 102 regs->r_cr27 = tf->tf_cr27; 103 #if 0 104 regs->r_cr26 = tf->tf_cr26; 105 #endif 106 107 return 0; 108 } 109 110 int 111 process_read_fpregs(struct lwp *l, struct fpreg *fpregs, size_t *sz) 112 { 113 struct pcb *pcb = lwp_getpcb(l); 114 115 hppa_fpu_flush(l); 116 memcpy(fpregs, pcb->pcb_fpregs, sizeof(*fpregs)); 117 return 0; 118 } 119 120 int 121 process_write_regs(struct lwp *l, const struct reg *regs) 122 { 123 struct trapframe *tf = l->l_md.md_regs; 124 125 tf->tf_ipsw = regs->r_regs[ 0]; 126 tf->tf_r1 = regs->r_regs[ 1]; 127 tf->tf_rp = regs->r_regs[ 2]; 128 tf->tf_r3 = regs->r_regs[ 3]; 129 tf->tf_r4 = regs->r_regs[ 4]; 130 tf->tf_r5 = regs->r_regs[ 5]; 131 tf->tf_r6 = regs->r_regs[ 6]; 132 tf->tf_r7 = regs->r_regs[ 7]; 133 tf->tf_r8 = regs->r_regs[ 8]; 134 tf->tf_r9 = regs->r_regs[ 9]; 135 tf->tf_r10 = regs->r_regs[10]; 136 tf->tf_r11 = regs->r_regs[11]; 137 tf->tf_r12 = regs->r_regs[12]; 138 tf->tf_r13 = regs->r_regs[13]; 139 tf->tf_r14 = regs->r_regs[14]; 140 tf->tf_r15 = regs->r_regs[15]; 141 tf->tf_r16 = regs->r_regs[16]; 142 tf->tf_r17 = regs->r_regs[17]; 143 tf->tf_r18 = regs->r_regs[18]; 144 tf->tf_t4 = regs->r_regs[19]; 145 tf->tf_t3 = regs->r_regs[20]; 146 tf->tf_t2 = regs->r_regs[21]; 147 tf->tf_t1 = regs->r_regs[22]; 148 tf->tf_arg3 = regs->r_regs[23]; 149 tf->tf_arg2 = regs->r_regs[24]; 150 tf->tf_arg1 = regs->r_regs[25]; 151 tf->tf_arg0 = regs->r_regs[26]; 152 tf->tf_dp = regs->r_regs[27]; 153 tf->tf_ret0 = regs->r_regs[28]; 154 tf->tf_ret1 = regs->r_regs[29]; 155 tf->tf_sp = regs->r_regs[30]; 156 tf->tf_r31 = regs->r_regs[31]; 157 158 tf->tf_sar = regs->r_sar; 159 160 tf->tf_iisq_head = regs->r_pcsqh; 161 tf->tf_iisq_tail = regs->r_pcsqt; 162 tf->tf_iioq_head = regs->r_pcoqh | HPPA_PC_PRIV_USER; 163 tf->tf_iioq_tail = regs->r_pcoqt | HPPA_PC_PRIV_USER; 164 165 tf->tf_sr0 = regs->r_sr0; 166 tf->tf_sr1 = regs->r_sr1; 167 tf->tf_sr2 = regs->r_sr2; 168 tf->tf_sr3 = regs->r_sr3; 169 tf->tf_sr4 = regs->r_sr4; 170 171 tf->tf_cr27 = regs->r_cr27; 172 #if 0 173 tf->tf_cr26 = regs->r_cr26; 174 #endif 175 176 return 0; 177 } 178 179 int 180 process_write_fpregs(struct lwp *l, const struct fpreg *fpregs, size_t sz) 181 { 182 struct pcb *pcb = lwp_getpcb(l); 183 184 kpreempt_disable(); 185 hppa_fpu_flush(l); 186 memcpy(pcb->pcb_fpregs, fpregs, sizeof(*fpregs)); 187 hppa_fpu_commit(l); 188 kpreempt_enable(); 189 return 0; 190 } 191 192 int 193 process_set_pc(struct lwp *l, void *addr) 194 { 195 196 l->l_md.md_regs->tf_iioq_head = (register_t)addr | HPPA_PC_PRIV_USER; 197 l->l_md.md_regs->tf_iioq_tail = l->l_md.md_regs->tf_iioq_head + 4; 198 return 0; 199 } 200