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.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 "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 return gdb_get_zeroes(mem_buf, 12); 51 } 52 switch (n) { 53 case 24: 54 /* FPA status register. */ 55 if (gdb_has_xml) { 56 return 0; 57 } 58 return gdb_get_reg32(mem_buf, 0); 59 case 25: 60 /* CPSR, or XPSR for M-profile */ 61 if (arm_feature(env, ARM_FEATURE_M)) { 62 return gdb_get_reg32(mem_buf, xpsr_read(env)); 63 } else { 64 return gdb_get_reg32(mem_buf, cpsr_read(env)); 65 } 66 } 67 /* Unknown register. */ 68 return 0; 69 } 70 71 int arm_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) 72 { 73 ARMCPU *cpu = ARM_CPU(cs); 74 CPUARMState *env = &cpu->env; 75 uint32_t tmp; 76 77 tmp = ldl_p(mem_buf); 78 79 /* Mask out low bit of PC to workaround gdb bugs. This will probably 80 cause problems if we ever implement the Jazelle DBX extensions. */ 81 if (n == 15) { 82 tmp &= ~1; 83 } 84 85 if (n < 16) { 86 /* Core integer register. */ 87 if (n == 13 && arm_feature(env, ARM_FEATURE_M)) { 88 /* M profile SP low bits are always 0 */ 89 tmp &= ~3; 90 } 91 env->regs[n] = tmp; 92 return 4; 93 } 94 if (n < 24) { /* 16-23 */ 95 /* FPA registers (ignored). */ 96 if (gdb_has_xml) { 97 return 0; 98 } 99 return 12; 100 } 101 switch (n) { 102 case 24: 103 /* FPA status register (ignored). */ 104 if (gdb_has_xml) { 105 return 0; 106 } 107 return 4; 108 case 25: 109 /* CPSR, or XPSR for M-profile */ 110 if (arm_feature(env, ARM_FEATURE_M)) { 111 /* 112 * Don't allow writing to XPSR.Exception as it can cause 113 * a transition into or out of handler mode (it's not 114 * writeable via the MSR insn so this is a reasonable 115 * restriction). Other fields are safe to update. 116 */ 117 xpsr_write(env, tmp, ~XPSR_EXCP); 118 } else { 119 cpsr_write(env, tmp, 0xffffffff, CPSRWriteByGDBStub); 120 } 121 return 4; 122 } 123 /* Unknown register. */ 124 return 0; 125 } 126 127 static void arm_gen_one_xml_sysreg_tag(GString *s, DynamicGDBXMLInfo *dyn_xml, 128 ARMCPRegInfo *ri, uint32_t ri_key, 129 int bitsize, int regnum) 130 { 131 g_string_append_printf(s, "<reg name=\"%s\"", ri->name); 132 g_string_append_printf(s, " bitsize=\"%d\"", bitsize); 133 g_string_append_printf(s, " regnum=\"%d\"", regnum); 134 g_string_append_printf(s, " group=\"cp_regs\"/>"); 135 dyn_xml->data.cpregs.keys[dyn_xml->num] = ri_key; 136 dyn_xml->num++; 137 } 138 139 static void arm_register_sysreg_for_xml(gpointer key, gpointer value, 140 gpointer p) 141 { 142 uint32_t ri_key = *(uint32_t *)key; 143 ARMCPRegInfo *ri = value; 144 RegisterSysregXmlParam *param = (RegisterSysregXmlParam *)p; 145 GString *s = param->s; 146 ARMCPU *cpu = ARM_CPU(param->cs); 147 CPUARMState *env = &cpu->env; 148 DynamicGDBXMLInfo *dyn_xml = &cpu->dyn_sysreg_xml; 149 150 if (!(ri->type & (ARM_CP_NO_RAW | ARM_CP_NO_GDB))) { 151 if (arm_feature(env, ARM_FEATURE_AARCH64)) { 152 if (ri->state == ARM_CP_STATE_AA64) { 153 arm_gen_one_xml_sysreg_tag(s , dyn_xml, ri, ri_key, 64, 154 param->n++); 155 } 156 } else { 157 if (ri->state == ARM_CP_STATE_AA32) { 158 if (!arm_feature(env, ARM_FEATURE_EL3) && 159 (ri->secure & ARM_CP_SECSTATE_S)) { 160 return; 161 } 162 if (ri->type & ARM_CP_64BIT) { 163 arm_gen_one_xml_sysreg_tag(s , dyn_xml, ri, ri_key, 64, 164 param->n++); 165 } else { 166 arm_gen_one_xml_sysreg_tag(s , dyn_xml, ri, ri_key, 32, 167 param->n++); 168 } 169 } 170 } 171 } 172 } 173 174 int arm_gen_dynamic_sysreg_xml(CPUState *cs, int base_reg) 175 { 176 ARMCPU *cpu = ARM_CPU(cs); 177 GString *s = g_string_new(NULL); 178 RegisterSysregXmlParam param = {cs, s, base_reg}; 179 180 cpu->dyn_sysreg_xml.num = 0; 181 cpu->dyn_sysreg_xml.data.cpregs.keys = g_new(uint32_t, g_hash_table_size(cpu->cp_regs)); 182 g_string_printf(s, "<?xml version=\"1.0\"?>"); 183 g_string_append_printf(s, "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">"); 184 g_string_append_printf(s, "<feature name=\"org.qemu.gdb.arm.sys.regs\">"); 185 g_hash_table_foreach(cpu->cp_regs, arm_register_sysreg_for_xml, ¶m); 186 g_string_append_printf(s, "</feature>"); 187 cpu->dyn_sysreg_xml.desc = g_string_free(s, false); 188 return cpu->dyn_sysreg_xml.num; 189 } 190 191 struct TypeSize { 192 const char *gdb_type; 193 int size; 194 const char sz, suffix; 195 }; 196 197 static const struct TypeSize vec_lanes[] = { 198 /* quads */ 199 { "uint128", 128, 'q', 'u' }, 200 { "int128", 128, 'q', 's' }, 201 /* 64 bit */ 202 { "ieee_double", 64, 'd', 'f' }, 203 { "uint64", 64, 'd', 'u' }, 204 { "int64", 64, 'd', 's' }, 205 /* 32 bit */ 206 { "ieee_single", 32, 's', 'f' }, 207 { "uint32", 32, 's', 'u' }, 208 { "int32", 32, 's', 's' }, 209 /* 16 bit */ 210 { "ieee_half", 16, 'h', 'f' }, 211 { "uint16", 16, 'h', 'u' }, 212 { "int16", 16, 'h', 's' }, 213 /* bytes */ 214 { "uint8", 8, 'b', 'u' }, 215 { "int8", 8, 'b', 's' }, 216 }; 217 218 219 int arm_gen_dynamic_svereg_xml(CPUState *cs, int base_reg) 220 { 221 ARMCPU *cpu = ARM_CPU(cs); 222 GString *s = g_string_new(NULL); 223 DynamicGDBXMLInfo *info = &cpu->dyn_svereg_xml; 224 g_autoptr(GString) ts = g_string_new(""); 225 int i, j, bits, reg_width = (cpu->sve_max_vq * 128); 226 info->num = 0; 227 g_string_printf(s, "<?xml version=\"1.0\"?>"); 228 g_string_append_printf(s, "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">"); 229 g_string_append_printf(s, "<feature name=\"org.gnu.gdb.aarch64.sve\">"); 230 231 /* First define types and totals in a whole VL */ 232 for (i = 0; i < ARRAY_SIZE(vec_lanes); i++) { 233 int count = reg_width / vec_lanes[i].size; 234 g_string_printf(ts, "svev%c%c", vec_lanes[i].sz, vec_lanes[i].suffix); 235 g_string_append_printf(s, 236 "<vector id=\"%s\" type=\"%s\" count=\"%d\"/>", 237 ts->str, vec_lanes[i].gdb_type, count); 238 } 239 /* 240 * Now define a union for each size group containing unsigned and 241 * signed and potentially float versions of each size from 128 to 242 * 8 bits. 243 */ 244 for (bits = 128, i = 0; bits >= 8; bits /= 2, i++) { 245 const char suf[] = { 'q', 'd', 's', 'h', 'b' }; 246 g_string_append_printf(s, "<union id=\"svevn%c\">", suf[i]); 247 for (j = 0; j < ARRAY_SIZE(vec_lanes); j++) { 248 if (vec_lanes[j].size == bits) { 249 g_string_append_printf(s, "<field name=\"%c\" type=\"svev%c%c\"/>", 250 vec_lanes[j].suffix, 251 vec_lanes[j].sz, vec_lanes[j].suffix); 252 } 253 } 254 g_string_append(s, "</union>"); 255 } 256 /* And now the final union of unions */ 257 g_string_append(s, "<union id=\"svev\">"); 258 for (bits = 128, i = 0; bits >= 8; bits /= 2, i++) { 259 const char suf[] = { 'q', 'd', 's', 'h', 'b' }; 260 g_string_append_printf(s, "<field name=\"%c\" type=\"svevn%c\"/>", 261 suf[i], suf[i]); 262 } 263 g_string_append(s, "</union>"); 264 265 /* Finally the sve prefix type */ 266 g_string_append_printf(s, 267 "<vector id=\"svep\" type=\"uint8\" count=\"%d\"/>", 268 reg_width / 8); 269 270 /* Then define each register in parts for each vq */ 271 for (i = 0; i < 32; i++) { 272 g_string_append_printf(s, 273 "<reg name=\"z%d\" bitsize=\"%d\"" 274 " regnum=\"%d\" type=\"svev\"/>", 275 i, reg_width, base_reg++); 276 info->num++; 277 } 278 /* fpscr & status registers */ 279 g_string_append_printf(s, "<reg name=\"fpsr\" bitsize=\"32\"" 280 " regnum=\"%d\" group=\"float\"" 281 " type=\"int\"/>", base_reg++); 282 g_string_append_printf(s, "<reg name=\"fpcr\" bitsize=\"32\"" 283 " regnum=\"%d\" group=\"float\"" 284 " type=\"int\"/>", base_reg++); 285 info->num += 2; 286 287 for (i = 0; i < 16; i++) { 288 g_string_append_printf(s, 289 "<reg name=\"p%d\" bitsize=\"%d\"" 290 " regnum=\"%d\" type=\"svep\"/>", 291 i, cpu->sve_max_vq * 16, base_reg++); 292 info->num++; 293 } 294 g_string_append_printf(s, 295 "<reg name=\"ffr\" bitsize=\"%d\"" 296 " regnum=\"%d\" group=\"vector\"" 297 " type=\"svep\"/>", 298 cpu->sve_max_vq * 16, base_reg++); 299 g_string_append_printf(s, 300 "<reg name=\"vg\" bitsize=\"64\"" 301 " regnum=\"%d\" type=\"int\"/>", 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