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