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