1 /* 2 * s390x 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 21 #include "qemu/osdep.h" 22 #include "cpu.h" 23 #include "internal.h" 24 #include "exec/exec-all.h" 25 #include "exec/gdbstub.h" 26 #include "qemu/bitops.h" 27 #include "sysemu/hw_accel.h" 28 #include "sysemu/tcg.h" 29 30 int s390_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) 31 { 32 S390CPU *cpu = S390_CPU(cs); 33 CPUS390XState *env = &cpu->env; 34 35 switch (n) { 36 case S390_PSWM_REGNUM: 37 return gdb_get_regl(mem_buf, s390_cpu_get_psw_mask(env)); 38 case S390_PSWA_REGNUM: 39 return gdb_get_regl(mem_buf, env->psw.addr); 40 case S390_R0_REGNUM ... S390_R15_REGNUM: 41 return gdb_get_regl(mem_buf, env->regs[n - S390_R0_REGNUM]); 42 } 43 return 0; 44 } 45 46 int s390_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) 47 { 48 S390CPU *cpu = S390_CPU(cs); 49 CPUS390XState *env = &cpu->env; 50 target_ulong tmpl = ldtul_p(mem_buf); 51 52 switch (n) { 53 case S390_PSWM_REGNUM: 54 s390_cpu_set_psw(env, tmpl, env->psw.addr); 55 break; 56 case S390_PSWA_REGNUM: 57 env->psw.addr = tmpl; 58 break; 59 case S390_R0_REGNUM ... S390_R15_REGNUM: 60 env->regs[n - S390_R0_REGNUM] = tmpl; 61 break; 62 default: 63 return 0; 64 } 65 return 8; 66 } 67 68 /* the values represent the positions in s390-acr.xml */ 69 #define S390_A0_REGNUM 0 70 #define S390_A15_REGNUM 15 71 /* total number of registers in s390-acr.xml */ 72 #define S390_NUM_AC_REGS 16 73 74 static int cpu_read_ac_reg(CPUS390XState *env, GByteArray *buf, int n) 75 { 76 switch (n) { 77 case S390_A0_REGNUM ... S390_A15_REGNUM: 78 return gdb_get_reg32(buf, env->aregs[n]); 79 default: 80 return 0; 81 } 82 } 83 84 static int cpu_write_ac_reg(CPUS390XState *env, uint8_t *mem_buf, int n) 85 { 86 switch (n) { 87 case S390_A0_REGNUM ... S390_A15_REGNUM: 88 env->aregs[n] = ldl_p(mem_buf); 89 cpu_synchronize_post_init(env_cpu(env)); 90 return 4; 91 default: 92 return 0; 93 } 94 } 95 96 /* the values represent the positions in s390-fpr.xml */ 97 #define S390_FPC_REGNUM 0 98 #define S390_F0_REGNUM 1 99 #define S390_F15_REGNUM 16 100 /* total number of registers in s390-fpr.xml */ 101 #define S390_NUM_FP_REGS 17 102 103 static int cpu_read_fp_reg(CPUS390XState *env, GByteArray *buf, int n) 104 { 105 switch (n) { 106 case S390_FPC_REGNUM: 107 return gdb_get_reg32(buf, env->fpc); 108 case S390_F0_REGNUM ... S390_F15_REGNUM: 109 return gdb_get_reg64(buf, *get_freg(env, n - S390_F0_REGNUM)); 110 default: 111 return 0; 112 } 113 } 114 115 static int cpu_write_fp_reg(CPUS390XState *env, uint8_t *mem_buf, int n) 116 { 117 switch (n) { 118 case S390_FPC_REGNUM: 119 env->fpc = ldl_p(mem_buf); 120 return 4; 121 case S390_F0_REGNUM ... S390_F15_REGNUM: 122 *get_freg(env, n - S390_F0_REGNUM) = ldtul_p(mem_buf); 123 return 8; 124 default: 125 return 0; 126 } 127 } 128 129 /* the values represent the positions in s390-vx.xml */ 130 #define S390_V0L_REGNUM 0 131 #define S390_V15L_REGNUM 15 132 #define S390_V16_REGNUM 16 133 #define S390_V31_REGNUM 31 134 /* total number of registers in s390-vx.xml */ 135 #define S390_NUM_VREGS 32 136 137 static int cpu_read_vreg(CPUS390XState *env, GByteArray *buf, int n) 138 { 139 int ret; 140 141 switch (n) { 142 case S390_V0L_REGNUM ... S390_V15L_REGNUM: 143 ret = gdb_get_reg64(buf, env->vregs[n][1]); 144 break; 145 case S390_V16_REGNUM ... S390_V31_REGNUM: 146 ret = gdb_get_reg64(buf, env->vregs[n][0]); 147 ret += gdb_get_reg64(buf, env->vregs[n][1]); 148 break; 149 default: 150 ret = 0; 151 } 152 153 return ret; 154 } 155 156 static int cpu_write_vreg(CPUS390XState *env, uint8_t *mem_buf, int n) 157 { 158 switch (n) { 159 case S390_V0L_REGNUM ... S390_V15L_REGNUM: 160 env->vregs[n][1] = ldtul_p(mem_buf + 8); 161 return 8; 162 case S390_V16_REGNUM ... S390_V31_REGNUM: 163 env->vregs[n][0] = ldtul_p(mem_buf); 164 env->vregs[n][1] = ldtul_p(mem_buf + 8); 165 return 16; 166 default: 167 return 0; 168 } 169 } 170 171 /* the values represent the positions in s390-cr.xml */ 172 #define S390_C0_REGNUM 0 173 #define S390_C15_REGNUM 15 174 /* total number of registers in s390-cr.xml */ 175 #define S390_NUM_C_REGS 16 176 177 #ifndef CONFIG_USER_ONLY 178 static int cpu_read_c_reg(CPUS390XState *env, GByteArray *buf, int n) 179 { 180 switch (n) { 181 case S390_C0_REGNUM ... S390_C15_REGNUM: 182 return gdb_get_regl(buf, env->cregs[n]); 183 default: 184 return 0; 185 } 186 } 187 188 static int cpu_write_c_reg(CPUS390XState *env, uint8_t *mem_buf, int n) 189 { 190 switch (n) { 191 case S390_C0_REGNUM ... S390_C15_REGNUM: 192 env->cregs[n] = ldtul_p(mem_buf); 193 if (tcg_enabled()) { 194 tlb_flush(env_cpu(env)); 195 } 196 cpu_synchronize_post_init(env_cpu(env)); 197 return 8; 198 default: 199 return 0; 200 } 201 } 202 203 /* the values represent the positions in s390-virt.xml */ 204 #define S390_VIRT_CKC_REGNUM 0 205 #define S390_VIRT_CPUTM_REGNUM 1 206 #define S390_VIRT_BEA_REGNUM 2 207 #define S390_VIRT_PREFIX_REGNUM 3 208 #define S390_VIRT_PP_REGNUM 4 209 #define S390_VIRT_PFT_REGNUM 5 210 #define S390_VIRT_PFS_REGNUM 6 211 #define S390_VIRT_PFC_REGNUM 7 212 /* total number of registers in s390-virt.xml */ 213 #define S390_NUM_VIRT_REGS 8 214 215 static int cpu_read_virt_reg(CPUS390XState *env, GByteArray *mem_buf, int n) 216 { 217 switch (n) { 218 case S390_VIRT_CKC_REGNUM: 219 return gdb_get_regl(mem_buf, env->ckc); 220 case S390_VIRT_CPUTM_REGNUM: 221 return gdb_get_regl(mem_buf, env->cputm); 222 case S390_VIRT_BEA_REGNUM: 223 return gdb_get_regl(mem_buf, env->gbea); 224 case S390_VIRT_PREFIX_REGNUM: 225 return gdb_get_regl(mem_buf, env->psa); 226 case S390_VIRT_PP_REGNUM: 227 return gdb_get_regl(mem_buf, env->pp); 228 case S390_VIRT_PFT_REGNUM: 229 return gdb_get_regl(mem_buf, env->pfault_token); 230 case S390_VIRT_PFS_REGNUM: 231 return gdb_get_regl(mem_buf, env->pfault_select); 232 case S390_VIRT_PFC_REGNUM: 233 return gdb_get_regl(mem_buf, env->pfault_compare); 234 default: 235 return 0; 236 } 237 } 238 239 static int cpu_write_virt_reg(CPUS390XState *env, uint8_t *mem_buf, int n) 240 { 241 switch (n) { 242 case S390_VIRT_CKC_REGNUM: 243 env->ckc = ldtul_p(mem_buf); 244 cpu_synchronize_post_init(env_cpu(env)); 245 return 8; 246 case S390_VIRT_CPUTM_REGNUM: 247 env->cputm = ldtul_p(mem_buf); 248 cpu_synchronize_post_init(env_cpu(env)); 249 return 8; 250 case S390_VIRT_BEA_REGNUM: 251 env->gbea = ldtul_p(mem_buf); 252 cpu_synchronize_post_init(env_cpu(env)); 253 return 8; 254 case S390_VIRT_PREFIX_REGNUM: 255 env->psa = ldtul_p(mem_buf); 256 cpu_synchronize_post_init(env_cpu(env)); 257 return 8; 258 case S390_VIRT_PP_REGNUM: 259 env->pp = ldtul_p(mem_buf); 260 cpu_synchronize_post_init(env_cpu(env)); 261 return 8; 262 case S390_VIRT_PFT_REGNUM: 263 env->pfault_token = ldtul_p(mem_buf); 264 cpu_synchronize_post_init(env_cpu(env)); 265 return 8; 266 case S390_VIRT_PFS_REGNUM: 267 env->pfault_select = ldtul_p(mem_buf); 268 cpu_synchronize_post_init(env_cpu(env)); 269 return 8; 270 case S390_VIRT_PFC_REGNUM: 271 env->pfault_compare = ldtul_p(mem_buf); 272 cpu_synchronize_post_init(env_cpu(env)); 273 return 8; 274 default: 275 return 0; 276 } 277 } 278 #endif 279 280 /* the values represent the positions in s390-gs.xml */ 281 #define S390_GS_RESERVED_REGNUM 0 282 #define S390_GS_GSD_REGNUM 1 283 #define S390_GS_GSSM_REGNUM 2 284 #define S390_GS_GSEPLA_REGNUM 3 285 /* total number of registers in s390-gs.xml */ 286 #define S390_NUM_GS_REGS 4 287 288 static int cpu_read_gs_reg(CPUS390XState *env, GByteArray *buf, int n) 289 { 290 return gdb_get_regl(buf, env->gscb[n]); 291 } 292 293 static int cpu_write_gs_reg(CPUS390XState *env, uint8_t *mem_buf, int n) 294 { 295 env->gscb[n] = ldtul_p(mem_buf); 296 cpu_synchronize_post_init(env_cpu(env)); 297 return 8; 298 } 299 300 void s390_cpu_gdb_init(CPUState *cs) 301 { 302 gdb_register_coprocessor(cs, cpu_read_ac_reg, 303 cpu_write_ac_reg, 304 S390_NUM_AC_REGS, "s390-acr.xml", 0); 305 306 gdb_register_coprocessor(cs, cpu_read_fp_reg, 307 cpu_write_fp_reg, 308 S390_NUM_FP_REGS, "s390-fpr.xml", 0); 309 310 gdb_register_coprocessor(cs, cpu_read_vreg, 311 cpu_write_vreg, 312 S390_NUM_VREGS, "s390-vx.xml", 0); 313 314 gdb_register_coprocessor(cs, cpu_read_gs_reg, 315 cpu_write_gs_reg, 316 S390_NUM_GS_REGS, "s390-gs.xml", 0); 317 318 #ifndef CONFIG_USER_ONLY 319 gdb_register_coprocessor(cs, cpu_read_c_reg, 320 cpu_write_c_reg, 321 S390_NUM_C_REGS, "s390-cr.xml", 0); 322 323 if (kvm_enabled()) { 324 gdb_register_coprocessor(cs, cpu_read_virt_reg, 325 cpu_write_virt_reg, 326 S390_NUM_VIRT_REGS, "s390-virt.xml", 0); 327 } 328 #endif 329 } 330