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 (double width, even numbers only) */ 83 return gdb_get_reg64(mem_buf, env->fpr[(n - 32) / 2].ll); 84 } 85 switch (n) { 86 case 80: 87 return gdb_get_regl(mem_buf, env->pc); 88 case 81: 89 return gdb_get_regl(mem_buf, env->npc); 90 case 82: 91 return gdb_get_regl(mem_buf, (cpu_get_ccr(env) << 32) | 92 ((env->asi & 0xff) << 24) | 93 ((env->pstate & 0xfff) << 8) | 94 cpu_get_cwp64(env)); 95 case 83: 96 return gdb_get_regl(mem_buf, cpu_get_fsr(env)); 97 case 84: 98 return gdb_get_regl(mem_buf, env->fprs); 99 case 85: 100 return gdb_get_regl(mem_buf, env->y); 101 } 102 #endif 103 return 0; 104 } 105 106 int sparc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) 107 { 108 SPARCCPU *cpu = SPARC_CPU(cs); 109 CPUSPARCState *env = &cpu->env; 110 #if defined(TARGET_ABI32) 111 uint32_t tmp; 112 113 tmp = ldl_p(mem_buf); 114 #else 115 target_ulong tmp; 116 117 tmp = ldtul_p(mem_buf); 118 #endif 119 120 if (n < 8) { 121 /* g0..g7 */ 122 env->gregs[n] = tmp; 123 } else if (n < 32) { 124 /* register window */ 125 env->regwptr[n - 8] = tmp; 126 } 127 #if defined(TARGET_ABI32) || !defined(TARGET_SPARC64) 128 else if (n < 64) { 129 /* fprs */ 130 /* f0-f31 */ 131 if (n & 1) { 132 env->fpr[(n - 32) / 2].l.lower = tmp; 133 } else { 134 env->fpr[(n - 32) / 2].l.upper = tmp; 135 } 136 } else { 137 /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */ 138 switch (n) { 139 case 64: 140 env->y = tmp; 141 break; 142 case 65: 143 cpu_put_psr(env, tmp); 144 break; 145 case 66: 146 env->wim = tmp; 147 break; 148 case 67: 149 env->tbr = tmp; 150 break; 151 case 68: 152 env->pc = tmp; 153 break; 154 case 69: 155 env->npc = tmp; 156 break; 157 case 70: 158 cpu_put_fsr(env, tmp); 159 break; 160 default: 161 return 0; 162 } 163 } 164 return 4; 165 #else 166 else if (n < 64) { 167 /* f0-f31 */ 168 tmp = ldl_p(mem_buf); 169 if (n & 1) { 170 env->fpr[(n - 32) / 2].l.lower = tmp; 171 } else { 172 env->fpr[(n - 32) / 2].l.upper = tmp; 173 } 174 return 4; 175 } else if (n < 80) { 176 /* f32-f62 (double width, even numbers only) */ 177 env->fpr[(n - 32) / 2].ll = tmp; 178 } else { 179 switch (n) { 180 case 80: 181 env->pc = tmp; 182 break; 183 case 81: 184 env->npc = tmp; 185 break; 186 case 82: 187 cpu_put_ccr(env, tmp >> 32); 188 env->asi = (tmp >> 24) & 0xff; 189 env->pstate = (tmp >> 8) & 0xfff; 190 cpu_put_cwp64(env, tmp & 0xff); 191 break; 192 case 83: 193 cpu_put_fsr(env, tmp); 194 break; 195 case 84: 196 env->fprs = tmp; 197 break; 198 case 85: 199 env->y = tmp; 200 break; 201 default: 202 return 0; 203 } 204 } 205 return 8; 206 #endif 207 } 208