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