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