1 /* 2 * ARM 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 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 "cpu.h" 22 #include "exec/gdbstub.h" 23 24 typedef struct RegisterSysregXmlParam { 25 CPUState *cs; 26 GString *s; 27 int n; 28 } RegisterSysregXmlParam; 29 30 /* Old gdb always expect FPA registers. Newer (xml-aware) gdb only expect 31 whatever the target description contains. Due to a historical mishap 32 the FPA registers appear in between core integer regs and the CPSR. 33 We hack round this by giving the FPA regs zero size when talking to a 34 newer gdb. */ 35 36 int arm_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) 37 { 38 ARMCPU *cpu = ARM_CPU(cs); 39 CPUARMState *env = &cpu->env; 40 41 if (n < 16) { 42 /* Core integer register. */ 43 return gdb_get_reg32(mem_buf, env->regs[n]); 44 } 45 if (n < 24) { 46 /* FPA registers. */ 47 if (gdb_has_xml) { 48 return 0; 49 } 50 memset(mem_buf, 0, 12); 51 return 12; 52 } 53 switch (n) { 54 case 24: 55 /* FPA status register. */ 56 if (gdb_has_xml) { 57 return 0; 58 } 59 return gdb_get_reg32(mem_buf, 0); 60 case 25: 61 /* CPSR */ 62 return gdb_get_reg32(mem_buf, cpsr_read(env)); 63 } 64 /* Unknown register. */ 65 return 0; 66 } 67 68 int arm_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) 69 { 70 ARMCPU *cpu = ARM_CPU(cs); 71 CPUARMState *env = &cpu->env; 72 uint32_t tmp; 73 74 tmp = ldl_p(mem_buf); 75 76 /* Mask out low bit of PC to workaround gdb bugs. This will probably 77 cause problems if we ever implement the Jazelle DBX extensions. */ 78 if (n == 15) { 79 tmp &= ~1; 80 } 81 82 if (n < 16) { 83 /* Core integer register. */ 84 env->regs[n] = tmp; 85 return 4; 86 } 87 if (n < 24) { /* 16-23 */ 88 /* FPA registers (ignored). */ 89 if (gdb_has_xml) { 90 return 0; 91 } 92 return 12; 93 } 94 switch (n) { 95 case 24: 96 /* FPA status register (ignored). */ 97 if (gdb_has_xml) { 98 return 0; 99 } 100 return 4; 101 case 25: 102 /* CPSR */ 103 cpsr_write(env, tmp, 0xffffffff, CPSRWriteByGDBStub); 104 return 4; 105 } 106 /* Unknown register. */ 107 return 0; 108 } 109 110 static void arm_gen_one_xml_sysreg_tag(GString *s, DynamicGDBXMLInfo *dyn_xml, 111 ARMCPRegInfo *ri, uint32_t ri_key, 112 int bitsize, int regnum) 113 { 114 g_string_append_printf(s, "<reg name=\"%s\"", ri->name); 115 g_string_append_printf(s, " bitsize=\"%d\"", bitsize); 116 g_string_append_printf(s, " regnum=\"%d\"", regnum); 117 g_string_append_printf(s, " group=\"cp_regs\"/>"); 118 dyn_xml->data.cpregs.keys[dyn_xml->num] = ri_key; 119 dyn_xml->num++; 120 } 121 122 static void arm_register_sysreg_for_xml(gpointer key, gpointer value, 123 gpointer p) 124 { 125 uint32_t ri_key = *(uint32_t *)key; 126 ARMCPRegInfo *ri = value; 127 RegisterSysregXmlParam *param = (RegisterSysregXmlParam *)p; 128 GString *s = param->s; 129 ARMCPU *cpu = ARM_CPU(param->cs); 130 CPUARMState *env = &cpu->env; 131 DynamicGDBXMLInfo *dyn_xml = &cpu->dyn_sysreg_xml; 132 133 if (!(ri->type & (ARM_CP_NO_RAW | ARM_CP_NO_GDB))) { 134 if (arm_feature(env, ARM_FEATURE_AARCH64)) { 135 if (ri->state == ARM_CP_STATE_AA64) { 136 arm_gen_one_xml_sysreg_tag(s , dyn_xml, ri, ri_key, 64, 137 param->n++); 138 } 139 } else { 140 if (ri->state == ARM_CP_STATE_AA32) { 141 if (!arm_feature(env, ARM_FEATURE_EL3) && 142 (ri->secure & ARM_CP_SECSTATE_S)) { 143 return; 144 } 145 if (ri->type & ARM_CP_64BIT) { 146 arm_gen_one_xml_sysreg_tag(s , dyn_xml, ri, ri_key, 64, 147 param->n++); 148 } else { 149 arm_gen_one_xml_sysreg_tag(s , dyn_xml, ri, ri_key, 32, 150 param->n++); 151 } 152 } 153 } 154 } 155 } 156 157 int arm_gen_dynamic_sysreg_xml(CPUState *cs, int base_reg) 158 { 159 ARMCPU *cpu = ARM_CPU(cs); 160 GString *s = g_string_new(NULL); 161 RegisterSysregXmlParam param = {cs, s, base_reg}; 162 163 cpu->dyn_sysreg_xml.num = 0; 164 cpu->dyn_sysreg_xml.data.cpregs.keys = g_new(uint32_t, g_hash_table_size(cpu->cp_regs)); 165 g_string_printf(s, "<?xml version=\"1.0\"?>"); 166 g_string_append_printf(s, "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">"); 167 g_string_append_printf(s, "<feature name=\"org.qemu.gdb.arm.sys.regs\">"); 168 g_hash_table_foreach(cpu->cp_regs, arm_register_sysreg_for_xml, ¶m); 169 g_string_append_printf(s, "</feature>"); 170 cpu->dyn_sysreg_xml.desc = g_string_free(s, false); 171 return cpu->dyn_sysreg_xml.num; 172 } 173 174 struct TypeSize { 175 const char *gdb_type; 176 int size; 177 const char sz, suffix; 178 }; 179 180 static const struct TypeSize vec_lanes[] = { 181 /* quads */ 182 { "uint128", 128, 'q', 'u' }, 183 { "int128", 128, 'q', 's' }, 184 /* 64 bit */ 185 { "uint64", 64, 'd', 'u' }, 186 { "int64", 64, 'd', 's' }, 187 { "ieee_double", 64, 'd', 'f' }, 188 /* 32 bit */ 189 { "uint32", 32, 's', 'u' }, 190 { "int32", 32, 's', 's' }, 191 { "ieee_single", 32, 's', 'f' }, 192 /* 16 bit */ 193 { "uint16", 16, 'h', 'u' }, 194 { "int16", 16, 'h', 's' }, 195 /* 196 * TODO: currently there is no reliable way of telling 197 * if the remote gdb actually understands ieee_half so 198 * we don't expose it in the target description for now. 199 * { "ieee_half", 16, 'h', 'f' }, 200 */ 201 /* bytes */ 202 { "uint8", 8, 'b', 'u' }, 203 { "int8", 8, 'b', 's' }, 204 }; 205 206 207 int arm_gen_dynamic_svereg_xml(CPUState *cs, int base_reg) 208 { 209 ARMCPU *cpu = ARM_CPU(cs); 210 GString *s = g_string_new(NULL); 211 DynamicGDBXMLInfo *info = &cpu->dyn_svereg_xml; 212 g_autoptr(GString) ts = g_string_new(""); 213 int i, bits, reg_width = (cpu->sve_max_vq * 128); 214 info->num = 0; 215 g_string_printf(s, "<?xml version=\"1.0\"?>"); 216 g_string_append_printf(s, "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">"); 217 g_string_append_printf(s, "<feature name=\"org.qemu.gdb.aarch64.sve\">"); 218 219 /* First define types and totals in a whole VL */ 220 for (i = 0; i < ARRAY_SIZE(vec_lanes); i++) { 221 int count = reg_width / vec_lanes[i].size; 222 g_string_printf(ts, "vq%d%c%c", count, 223 vec_lanes[i].sz, vec_lanes[i].suffix); 224 g_string_append_printf(s, 225 "<vector id=\"%s\" type=\"%s\" count=\"%d\"/>", 226 ts->str, vec_lanes[i].gdb_type, count); 227 } 228 /* 229 * Now define a union for each size group containing unsigned and 230 * signed and potentially float versions of each size from 128 to 231 * 8 bits. 232 */ 233 for (bits = 128; bits >= 8; bits /= 2) { 234 int count = reg_width / bits; 235 g_string_append_printf(s, "<union id=\"vq%dn\">", count); 236 for (i = 0; i < ARRAY_SIZE(vec_lanes); i++) { 237 if (vec_lanes[i].size == bits) { 238 g_string_append_printf(s, "<field name=\"%c\" type=\"vq%d%c%c\"/>", 239 vec_lanes[i].suffix, 240 count, 241 vec_lanes[i].sz, vec_lanes[i].suffix); 242 } 243 } 244 g_string_append(s, "</union>"); 245 } 246 /* And now the final union of unions */ 247 g_string_append(s, "<union id=\"vq\">"); 248 for (bits = 128; bits >= 8; bits /= 2) { 249 int count = reg_width / bits; 250 for (i = 0; i < ARRAY_SIZE(vec_lanes); i++) { 251 if (vec_lanes[i].size == bits) { 252 g_string_append_printf(s, "<field name=\"%c\" type=\"vq%dn\"/>", 253 vec_lanes[i].sz, count); 254 break; 255 } 256 } 257 } 258 g_string_append(s, "</union>"); 259 260 /* Then define each register in parts for each vq */ 261 for (i = 0; i < 32; i++) { 262 g_string_append_printf(s, 263 "<reg name=\"z%d\" bitsize=\"%d\"" 264 " regnum=\"%d\" group=\"vector\"" 265 " type=\"vq\"/>", 266 i, reg_width, base_reg++); 267 info->num++; 268 } 269 /* fpscr & status registers */ 270 g_string_append_printf(s, "<reg name=\"fpsr\" bitsize=\"32\"" 271 " regnum=\"%d\" group=\"float\"" 272 " type=\"int\"/>", base_reg++); 273 g_string_append_printf(s, "<reg name=\"fpcr\" bitsize=\"32\"" 274 " regnum=\"%d\" group=\"float\"" 275 " type=\"int\"/>", base_reg++); 276 info->num += 2; 277 /* 278 * Predicate registers aren't so big they are worth splitting up 279 * but we do need to define a type to hold the array of quad 280 * references. 281 */ 282 g_string_append_printf(s, 283 "<vector id=\"vqp\" type=\"uint16\" count=\"%d\"/>", 284 cpu->sve_max_vq); 285 for (i = 0; i < 16; i++) { 286 g_string_append_printf(s, 287 "<reg name=\"p%d\" bitsize=\"%d\"" 288 " regnum=\"%d\" group=\"vector\"" 289 " type=\"vqp\"/>", 290 i, cpu->sve_max_vq * 16, base_reg++); 291 info->num++; 292 } 293 g_string_append_printf(s, 294 "<reg name=\"ffr\" bitsize=\"%d\"" 295 " regnum=\"%d\" group=\"vector\"" 296 " type=\"vqp\"/>", 297 cpu->sve_max_vq * 16, base_reg++); 298 g_string_append_printf(s, 299 "<reg name=\"vg\" bitsize=\"64\"" 300 " regnum=\"%d\" group=\"vector\"" 301 " type=\"uint32\"/>", 302 base_reg++); 303 info->num += 2; 304 g_string_append_printf(s, "</feature>"); 305 cpu->dyn_svereg_xml.desc = g_string_free(s, false); 306 307 return cpu->dyn_svereg_xml.num; 308 } 309 310 311 const char *arm_gdb_get_dynamic_xml(CPUState *cs, const char *xmlname) 312 { 313 ARMCPU *cpu = ARM_CPU(cs); 314 315 if (strcmp(xmlname, "system-registers.xml") == 0) { 316 return cpu->dyn_sysreg_xml.desc; 317 } else if (strcmp(xmlname, "sve-registers.xml") == 0) { 318 return cpu->dyn_svereg_xml.desc; 319 } 320 return NULL; 321 } 322