1 /* 2 * SPARC gdb server stub 3 * 4 * Copyright (c) 2003-2005 Fabrice Bellard 5 * Copyright (c) 2013 SUSE LINUX Products GmbH 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 19 */ 20 #include "qemu/osdep.h" 21 #include "cpu.h" 22 #include "gdbstub/helpers.h" 23 24 #ifdef TARGET_ABI32 25 #define gdb_get_rega(buf, val) gdb_get_reg32(buf, val) 26 #else 27 #define gdb_get_rega(buf, val) gdb_get_regl(buf, val) 28 #endif 29 30 int sparc_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) 31 { 32 CPUSPARCState *env = cpu_env(cs); 33 34 if (n < 8) { 35 /* g0..g7 */ 36 return gdb_get_rega(mem_buf, env->gregs[n]); 37 } 38 if (n < 32) { 39 /* register window */ 40 return gdb_get_rega(mem_buf, env->regwptr[n - 8]); 41 } 42 #if defined(TARGET_ABI32) || !defined(TARGET_SPARC64) 43 if (n < 64) { 44 /* fprs */ 45 if (n & 1) { 46 return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.lower); 47 } else { 48 return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.upper); 49 } 50 } 51 /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */ 52 switch (n) { 53 case 64: 54 return gdb_get_rega(mem_buf, env->y); 55 case 65: 56 return gdb_get_rega(mem_buf, cpu_get_psr(env)); 57 case 66: 58 return gdb_get_rega(mem_buf, env->wim); 59 case 67: 60 return gdb_get_rega(mem_buf, env->tbr); 61 case 68: 62 return gdb_get_rega(mem_buf, env->pc); 63 case 69: 64 return gdb_get_rega(mem_buf, env->npc); 65 case 70: 66 return gdb_get_rega(mem_buf, cpu_get_fsr(env)); 67 case 71: 68 return gdb_get_rega(mem_buf, 0); /* csr */ 69 default: 70 return gdb_get_rega(mem_buf, 0); 71 } 72 #else 73 if (n < 64) { 74 /* f0-f31 */ 75 if (n & 1) { 76 return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.lower); 77 } else { 78 return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.upper); 79 } 80 } 81 if (n < 80) { 82 /* f32-f62 (16 double width registers, even register numbers only) 83 * n == 64: f32 : env->fpr[16] 84 * n == 65: f34 : env->fpr[17] 85 * etc... 86 * n == 79: f62 : env->fpr[31] 87 */ 88 return gdb_get_reg64(mem_buf, env->fpr[(n - 64) + 16].ll); 89 } 90 switch (n) { 91 case 80: 92 return gdb_get_regl(mem_buf, env->pc); 93 case 81: 94 return gdb_get_regl(mem_buf, env->npc); 95 case 82: 96 return gdb_get_regl(mem_buf, (cpu_get_ccr(env) << 32) | 97 ((env->asi & 0xff) << 24) | 98 ((env->pstate & 0xfff) << 8) | 99 cpu_get_cwp64(env)); 100 case 83: 101 return gdb_get_regl(mem_buf, cpu_get_fsr(env)); 102 case 84: 103 return gdb_get_regl(mem_buf, env->fprs); 104 case 85: 105 return gdb_get_regl(mem_buf, env->y); 106 } 107 #endif 108 return 0; 109 } 110 111 int sparc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) 112 { 113 SPARCCPU *cpu = SPARC_CPU(cs); 114 CPUSPARCState *env = &cpu->env; 115 #if defined(TARGET_ABI32) 116 uint32_t tmp; 117 118 tmp = ldl_p(mem_buf); 119 #else 120 target_ulong tmp; 121 122 tmp = ldtul_p(mem_buf); 123 #endif 124 125 if (n < 8) { 126 /* g0..g7 */ 127 env->gregs[n] = tmp; 128 } else if (n < 32) { 129 /* register window */ 130 env->regwptr[n - 8] = tmp; 131 } 132 #if defined(TARGET_ABI32) || !defined(TARGET_SPARC64) 133 else if (n < 64) { 134 /* fprs */ 135 /* f0-f31 */ 136 if (n & 1) { 137 env->fpr[(n - 32) / 2].l.lower = tmp; 138 } else { 139 env->fpr[(n - 32) / 2].l.upper = tmp; 140 } 141 } else { 142 /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */ 143 switch (n) { 144 case 64: 145 env->y = tmp; 146 break; 147 case 65: 148 cpu_put_psr(env, tmp); 149 break; 150 case 66: 151 env->wim = tmp; 152 break; 153 case 67: 154 env->tbr = tmp; 155 break; 156 case 68: 157 env->pc = tmp; 158 break; 159 case 69: 160 env->npc = tmp; 161 break; 162 case 70: 163 cpu_put_fsr(env, tmp); 164 break; 165 default: 166 return 0; 167 } 168 } 169 return 4; 170 #else 171 else if (n < 64) { 172 /* f0-f31 */ 173 tmp = ldl_p(mem_buf); 174 if (n & 1) { 175 env->fpr[(n - 32) / 2].l.lower = tmp; 176 } else { 177 env->fpr[(n - 32) / 2].l.upper = tmp; 178 } 179 return 4; 180 } else if (n < 80) { 181 /* f32-f62 (16 double width registers, even register numbers only) 182 * n == 64: f32 : env->fpr[16] 183 * n == 65: f34 : env->fpr[17] 184 * etc... 185 * n == 79: f62 : env->fpr[31] 186 */ 187 env->fpr[(n - 64) + 16].ll = tmp; 188 } else { 189 switch (n) { 190 case 80: 191 env->pc = tmp; 192 break; 193 case 81: 194 env->npc = tmp; 195 break; 196 case 82: 197 cpu_put_ccr(env, tmp >> 32); 198 env->asi = (tmp >> 24) & 0xff; 199 env->pstate = (tmp >> 8) & 0xfff; 200 cpu_put_cwp64(env, tmp & 0xff); 201 break; 202 case 83: 203 cpu_put_fsr(env, tmp); 204 break; 205 case 84: 206 env->fprs = tmp; 207 break; 208 case 85: 209 env->y = tmp; 210 break; 211 default: 212 return 0; 213 } 214 } 215 return 8; 216 #endif 217 } 218