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