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