145183ccdSTaylor Simpson /* 2*fc2622f6STaylor Simpson * Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights Reserved. 345183ccdSTaylor Simpson * 445183ccdSTaylor Simpson * This program is free software; you can redistribute it and/or modify 545183ccdSTaylor Simpson * it under the terms of the GNU General Public License as published by 645183ccdSTaylor Simpson * the Free Software Foundation; either version 2 of the License, or 745183ccdSTaylor Simpson * (at your option) any later version. 845183ccdSTaylor Simpson * 945183ccdSTaylor Simpson * This program is distributed in the hope that it will be useful, 1045183ccdSTaylor Simpson * but WITHOUT ANY WARRANTY; without even the implied warranty of 1145183ccdSTaylor Simpson * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1245183ccdSTaylor Simpson * GNU General Public License for more details. 1345183ccdSTaylor Simpson * 1445183ccdSTaylor Simpson * You should have received a copy of the GNU General Public License 1545183ccdSTaylor Simpson * along with this program; if not, see <http://www.gnu.org/licenses/>. 1645183ccdSTaylor Simpson */ 1745183ccdSTaylor Simpson 1845183ccdSTaylor Simpson #include "qemu/osdep.h" 1945183ccdSTaylor Simpson #include "qemu/qemu-print.h" 2045183ccdSTaylor Simpson #include "cpu.h" 2145183ccdSTaylor Simpson #include "internal.h" 2245183ccdSTaylor Simpson #include "exec/exec-all.h" 2345183ccdSTaylor Simpson #include "qapi/error.h" 2445183ccdSTaylor Simpson #include "hw/qdev-properties.h" 25c0336c87STaylor Simpson #include "fpu/softfloat-helpers.h" 26ba445655SAnton Johansson #include "tcg/tcg.h" 2745183ccdSTaylor Simpson 28*fc2622f6STaylor Simpson static void hexagon_v67_cpu_init(Object *obj) { } 29*fc2622f6STaylor Simpson static void hexagon_v68_cpu_init(Object *obj) { } 30*fc2622f6STaylor Simpson static void hexagon_v69_cpu_init(Object *obj) { } 31*fc2622f6STaylor Simpson static void hexagon_v71_cpu_init(Object *obj) { } 32*fc2622f6STaylor Simpson static void hexagon_v73_cpu_init(Object *obj) { } 3345183ccdSTaylor Simpson 3445183ccdSTaylor Simpson static ObjectClass *hexagon_cpu_class_by_name(const char *cpu_model) 3545183ccdSTaylor Simpson { 3645183ccdSTaylor Simpson ObjectClass *oc; 3745183ccdSTaylor Simpson char *typename; 3845183ccdSTaylor Simpson char **cpuname; 3945183ccdSTaylor Simpson 4045183ccdSTaylor Simpson cpuname = g_strsplit(cpu_model, ",", 1); 4145183ccdSTaylor Simpson typename = g_strdup_printf(HEXAGON_CPU_TYPE_NAME("%s"), cpuname[0]); 4245183ccdSTaylor Simpson oc = object_class_by_name(typename); 4345183ccdSTaylor Simpson g_strfreev(cpuname); 4445183ccdSTaylor Simpson g_free(typename); 4545183ccdSTaylor Simpson if (!oc || !object_class_dynamic_cast(oc, TYPE_HEXAGON_CPU) || 4645183ccdSTaylor Simpson object_class_is_abstract(oc)) { 4745183ccdSTaylor Simpson return NULL; 4845183ccdSTaylor Simpson } 4945183ccdSTaylor Simpson return oc; 5045183ccdSTaylor Simpson } 5145183ccdSTaylor Simpson 5245183ccdSTaylor Simpson static Property hexagon_lldb_compat_property = 5345183ccdSTaylor Simpson DEFINE_PROP_BOOL("lldb-compat", HexagonCPU, lldb_compat, false); 5445183ccdSTaylor Simpson static Property hexagon_lldb_stack_adjust_property = 5545183ccdSTaylor Simpson DEFINE_PROP_UNSIGNED("lldb-stack-adjust", HexagonCPU, lldb_stack_adjust, 5645183ccdSTaylor Simpson 0, qdev_prop_uint32, target_ulong); 5745183ccdSTaylor Simpson 5845183ccdSTaylor Simpson const char * const hexagon_regnames[TOTAL_PER_THREAD_REGS] = { 5945183ccdSTaylor Simpson "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 6045183ccdSTaylor Simpson "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", 6145183ccdSTaylor Simpson "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", 6245183ccdSTaylor Simpson "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", 6345183ccdSTaylor Simpson "sa0", "lc0", "sa1", "lc1", "p3_0", "c5", "m0", "m1", 6445183ccdSTaylor Simpson "usr", "pc", "ugp", "gp", "cs0", "cs1", "c14", "c15", 6540438b67STaylor Simpson "c16", "c17", "c18", "c19", "pkt_cnt", "insn_cnt", "hvx_cnt", "c23", 6645183ccdSTaylor Simpson "c24", "c25", "c26", "c27", "c28", "c29", "c30", "c31", 6745183ccdSTaylor Simpson }; 6845183ccdSTaylor Simpson 6945183ccdSTaylor Simpson /* 7045183ccdSTaylor Simpson * One of the main debugging techniques is to use "-d cpu" and compare against 7145183ccdSTaylor Simpson * LLDB output when single stepping. However, the target and qemu put the 7245183ccdSTaylor Simpson * stacks at different locations. This is used to compensate so the diff is 7345183ccdSTaylor Simpson * cleaner. 7445183ccdSTaylor Simpson */ 752d27cebbSTaylor Simpson static target_ulong adjust_stack_ptrs(CPUHexagonState *env, target_ulong addr) 7645183ccdSTaylor Simpson { 777d9ab202STaylor Simpson HexagonCPU *cpu = env_archcpu(env); 7845183ccdSTaylor Simpson target_ulong stack_adjust = cpu->lldb_stack_adjust; 7945183ccdSTaylor Simpson target_ulong stack_start = env->stack_start; 8045183ccdSTaylor Simpson target_ulong stack_size = 0x10000; 8145183ccdSTaylor Simpson 8245183ccdSTaylor Simpson if (stack_adjust == 0) { 8345183ccdSTaylor Simpson return addr; 8445183ccdSTaylor Simpson } 8545183ccdSTaylor Simpson 8645183ccdSTaylor Simpson if (stack_start + 0x1000 >= addr && addr >= (stack_start - stack_size)) { 8745183ccdSTaylor Simpson return addr - stack_adjust; 8845183ccdSTaylor Simpson } 8945183ccdSTaylor Simpson return addr; 9045183ccdSTaylor Simpson } 9145183ccdSTaylor Simpson 9272895676SMukilan Thiyagarajan /* HEX_REG_P3_0_ALIASED (aka C4) is an alias for the predicate registers */ 932d27cebbSTaylor Simpson static target_ulong read_p3_0(CPUHexagonState *env) 9445183ccdSTaylor Simpson { 9545183ccdSTaylor Simpson int32_t control_reg = 0; 9645183ccdSTaylor Simpson int i; 9745183ccdSTaylor Simpson for (i = NUM_PREGS - 1; i >= 0; i--) { 9845183ccdSTaylor Simpson control_reg <<= 8; 9945183ccdSTaylor Simpson control_reg |= env->pred[i] & 0xff; 10045183ccdSTaylor Simpson } 10145183ccdSTaylor Simpson return control_reg; 10245183ccdSTaylor Simpson } 10345183ccdSTaylor Simpson 10445183ccdSTaylor Simpson static void print_reg(FILE *f, CPUHexagonState *env, int regnum) 10545183ccdSTaylor Simpson { 10645183ccdSTaylor Simpson target_ulong value; 10745183ccdSTaylor Simpson 10872895676SMukilan Thiyagarajan if (regnum == HEX_REG_P3_0_ALIASED) { 10945183ccdSTaylor Simpson value = read_p3_0(env); 11045183ccdSTaylor Simpson } else { 11145183ccdSTaylor Simpson value = regnum < 32 ? adjust_stack_ptrs(env, env->gpr[regnum]) 11245183ccdSTaylor Simpson : env->gpr[regnum]; 11345183ccdSTaylor Simpson } 11445183ccdSTaylor Simpson 11545183ccdSTaylor Simpson qemu_fprintf(f, " %s = 0x" TARGET_FMT_lx "\n", 11645183ccdSTaylor Simpson hexagon_regnames[regnum], value); 11745183ccdSTaylor Simpson } 11845183ccdSTaylor Simpson 119a1559537STaylor Simpson static void print_vreg(FILE *f, CPUHexagonState *env, int regnum, 120a1559537STaylor Simpson bool skip_if_zero) 121a1559537STaylor Simpson { 122a1559537STaylor Simpson if (skip_if_zero) { 123a1559537STaylor Simpson bool nonzero_found = false; 124a1559537STaylor Simpson for (int i = 0; i < MAX_VEC_SIZE_BYTES; i++) { 125a1559537STaylor Simpson if (env->VRegs[regnum].ub[i] != 0) { 126a1559537STaylor Simpson nonzero_found = true; 127a1559537STaylor Simpson break; 128a1559537STaylor Simpson } 129a1559537STaylor Simpson } 130a1559537STaylor Simpson if (!nonzero_found) { 131a1559537STaylor Simpson return; 132a1559537STaylor Simpson } 133a1559537STaylor Simpson } 134a1559537STaylor Simpson 135a1559537STaylor Simpson qemu_fprintf(f, " v%d = ( ", regnum); 136a1559537STaylor Simpson qemu_fprintf(f, "0x%02x", env->VRegs[regnum].ub[MAX_VEC_SIZE_BYTES - 1]); 137a1559537STaylor Simpson for (int i = MAX_VEC_SIZE_BYTES - 2; i >= 0; i--) { 138a1559537STaylor Simpson qemu_fprintf(f, ", 0x%02x", env->VRegs[regnum].ub[i]); 139a1559537STaylor Simpson } 140a1559537STaylor Simpson qemu_fprintf(f, " )\n"); 141a1559537STaylor Simpson } 142a1559537STaylor Simpson 143a1559537STaylor Simpson void hexagon_debug_vreg(CPUHexagonState *env, int regnum) 144a1559537STaylor Simpson { 145a1559537STaylor Simpson print_vreg(stdout, env, regnum, false); 146a1559537STaylor Simpson } 147a1559537STaylor Simpson 148a1559537STaylor Simpson static void print_qreg(FILE *f, CPUHexagonState *env, int regnum, 149a1559537STaylor Simpson bool skip_if_zero) 150a1559537STaylor Simpson { 151a1559537STaylor Simpson if (skip_if_zero) { 152a1559537STaylor Simpson bool nonzero_found = false; 153a1559537STaylor Simpson for (int i = 0; i < MAX_VEC_SIZE_BYTES / 8; i++) { 154a1559537STaylor Simpson if (env->QRegs[regnum].ub[i] != 0) { 155a1559537STaylor Simpson nonzero_found = true; 156a1559537STaylor Simpson break; 157a1559537STaylor Simpson } 158a1559537STaylor Simpson } 159a1559537STaylor Simpson if (!nonzero_found) { 160a1559537STaylor Simpson return; 161a1559537STaylor Simpson } 162a1559537STaylor Simpson } 163a1559537STaylor Simpson 164a1559537STaylor Simpson qemu_fprintf(f, " q%d = ( ", regnum); 165a1559537STaylor Simpson qemu_fprintf(f, "0x%02x", 166a1559537STaylor Simpson env->QRegs[regnum].ub[MAX_VEC_SIZE_BYTES / 8 - 1]); 167a1559537STaylor Simpson for (int i = MAX_VEC_SIZE_BYTES / 8 - 2; i >= 0; i--) { 168a1559537STaylor Simpson qemu_fprintf(f, ", 0x%02x", env->QRegs[regnum].ub[i]); 169a1559537STaylor Simpson } 170a1559537STaylor Simpson qemu_fprintf(f, " )\n"); 171a1559537STaylor Simpson } 172a1559537STaylor Simpson 173a1559537STaylor Simpson void hexagon_debug_qreg(CPUHexagonState *env, int regnum) 174a1559537STaylor Simpson { 175a1559537STaylor Simpson print_qreg(stdout, env, regnum, false); 176a1559537STaylor Simpson } 177a1559537STaylor Simpson 178a1559537STaylor Simpson static void hexagon_dump(CPUHexagonState *env, FILE *f, int flags) 17945183ccdSTaylor Simpson { 1807d9ab202STaylor Simpson HexagonCPU *cpu = env_archcpu(env); 18145183ccdSTaylor Simpson 18245183ccdSTaylor Simpson if (cpu->lldb_compat) { 18345183ccdSTaylor Simpson /* 18445183ccdSTaylor Simpson * When comparing with LLDB, it doesn't step through single-cycle 18545183ccdSTaylor Simpson * hardware loops the same way. So, we just skip them here 18645183ccdSTaylor Simpson */ 18745183ccdSTaylor Simpson if (env->gpr[HEX_REG_PC] == env->last_pc_dumped) { 18845183ccdSTaylor Simpson return; 18945183ccdSTaylor Simpson } 19045183ccdSTaylor Simpson env->last_pc_dumped = env->gpr[HEX_REG_PC]; 19145183ccdSTaylor Simpson } 19245183ccdSTaylor Simpson 19345183ccdSTaylor Simpson qemu_fprintf(f, "General Purpose Registers = {\n"); 19445183ccdSTaylor Simpson for (int i = 0; i < 32; i++) { 19545183ccdSTaylor Simpson print_reg(f, env, i); 19645183ccdSTaylor Simpson } 19745183ccdSTaylor Simpson print_reg(f, env, HEX_REG_SA0); 19845183ccdSTaylor Simpson print_reg(f, env, HEX_REG_LC0); 19945183ccdSTaylor Simpson print_reg(f, env, HEX_REG_SA1); 20045183ccdSTaylor Simpson print_reg(f, env, HEX_REG_LC1); 20145183ccdSTaylor Simpson print_reg(f, env, HEX_REG_M0); 20245183ccdSTaylor Simpson print_reg(f, env, HEX_REG_M1); 20345183ccdSTaylor Simpson print_reg(f, env, HEX_REG_USR); 20472895676SMukilan Thiyagarajan print_reg(f, env, HEX_REG_P3_0_ALIASED); 20545183ccdSTaylor Simpson print_reg(f, env, HEX_REG_GP); 20645183ccdSTaylor Simpson print_reg(f, env, HEX_REG_UGP); 20745183ccdSTaylor Simpson print_reg(f, env, HEX_REG_PC); 20845183ccdSTaylor Simpson #ifdef CONFIG_USER_ONLY 20945183ccdSTaylor Simpson /* 21045183ccdSTaylor Simpson * Not modelled in user mode, print junk to minimize the diff's 21145183ccdSTaylor Simpson * with LLDB output 21245183ccdSTaylor Simpson */ 21345183ccdSTaylor Simpson qemu_fprintf(f, " cause = 0x000000db\n"); 21445183ccdSTaylor Simpson qemu_fprintf(f, " badva = 0x00000000\n"); 21545183ccdSTaylor Simpson qemu_fprintf(f, " cs0 = 0x00000000\n"); 21645183ccdSTaylor Simpson qemu_fprintf(f, " cs1 = 0x00000000\n"); 21745183ccdSTaylor Simpson #else 21845183ccdSTaylor Simpson print_reg(f, env, HEX_REG_CAUSE); 21945183ccdSTaylor Simpson print_reg(f, env, HEX_REG_BADVA); 22045183ccdSTaylor Simpson print_reg(f, env, HEX_REG_CS0); 22145183ccdSTaylor Simpson print_reg(f, env, HEX_REG_CS1); 22245183ccdSTaylor Simpson #endif 22345183ccdSTaylor Simpson qemu_fprintf(f, "}\n"); 224a1559537STaylor Simpson 225a1559537STaylor Simpson if (flags & CPU_DUMP_FPU) { 226a1559537STaylor Simpson qemu_fprintf(f, "Vector Registers = {\n"); 227a1559537STaylor Simpson for (int i = 0; i < NUM_VREGS; i++) { 228a1559537STaylor Simpson print_vreg(f, env, i, true); 229a1559537STaylor Simpson } 230a1559537STaylor Simpson for (int i = 0; i < NUM_QREGS; i++) { 231a1559537STaylor Simpson print_qreg(f, env, i, true); 232a1559537STaylor Simpson } 233a1559537STaylor Simpson qemu_fprintf(f, "}\n"); 234a1559537STaylor Simpson } 23545183ccdSTaylor Simpson } 23645183ccdSTaylor Simpson 23745183ccdSTaylor Simpson static void hexagon_dump_state(CPUState *cs, FILE *f, int flags) 23845183ccdSTaylor Simpson { 23945183ccdSTaylor Simpson HexagonCPU *cpu = HEXAGON_CPU(cs); 24045183ccdSTaylor Simpson CPUHexagonState *env = &cpu->env; 24145183ccdSTaylor Simpson 242a1559537STaylor Simpson hexagon_dump(env, f, flags); 24345183ccdSTaylor Simpson } 24445183ccdSTaylor Simpson 24545183ccdSTaylor Simpson void hexagon_debug(CPUHexagonState *env) 24645183ccdSTaylor Simpson { 247a1559537STaylor Simpson hexagon_dump(env, stdout, CPU_DUMP_FPU); 24845183ccdSTaylor Simpson } 24945183ccdSTaylor Simpson 25045183ccdSTaylor Simpson static void hexagon_cpu_set_pc(CPUState *cs, vaddr value) 25145183ccdSTaylor Simpson { 25245183ccdSTaylor Simpson HexagonCPU *cpu = HEXAGON_CPU(cs); 25345183ccdSTaylor Simpson CPUHexagonState *env = &cpu->env; 25445183ccdSTaylor Simpson env->gpr[HEX_REG_PC] = value; 25545183ccdSTaylor Simpson } 25645183ccdSTaylor Simpson 257e4fdf9dfSRichard Henderson static vaddr hexagon_cpu_get_pc(CPUState *cs) 258e4fdf9dfSRichard Henderson { 259e4fdf9dfSRichard Henderson HexagonCPU *cpu = HEXAGON_CPU(cs); 260e4fdf9dfSRichard Henderson CPUHexagonState *env = &cpu->env; 261e4fdf9dfSRichard Henderson return env->gpr[HEX_REG_PC]; 262e4fdf9dfSRichard Henderson } 263e4fdf9dfSRichard Henderson 26445183ccdSTaylor Simpson static void hexagon_cpu_synchronize_from_tb(CPUState *cs, 26545183ccdSTaylor Simpson const TranslationBlock *tb) 26645183ccdSTaylor Simpson { 26745183ccdSTaylor Simpson HexagonCPU *cpu = HEXAGON_CPU(cs); 26845183ccdSTaylor Simpson CPUHexagonState *env = &cpu->env; 269ba445655SAnton Johansson tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL)); 270ba445655SAnton Johansson env->gpr[HEX_REG_PC] = tb->pc; 27145183ccdSTaylor Simpson } 27245183ccdSTaylor Simpson 27345183ccdSTaylor Simpson static bool hexagon_cpu_has_work(CPUState *cs) 27445183ccdSTaylor Simpson { 27545183ccdSTaylor Simpson return true; 27645183ccdSTaylor Simpson } 27745183ccdSTaylor Simpson 27890157814SRichard Henderson static void hexagon_restore_state_to_opc(CPUState *cs, 27990157814SRichard Henderson const TranslationBlock *tb, 28090157814SRichard Henderson const uint64_t *data) 28145183ccdSTaylor Simpson { 28290157814SRichard Henderson HexagonCPU *cpu = HEXAGON_CPU(cs); 28390157814SRichard Henderson CPUHexagonState *env = &cpu->env; 28490157814SRichard Henderson 28545183ccdSTaylor Simpson env->gpr[HEX_REG_PC] = data[0]; 28645183ccdSTaylor Simpson } 28745183ccdSTaylor Simpson 288ab85156dSPeter Maydell static void hexagon_cpu_reset_hold(Object *obj) 28945183ccdSTaylor Simpson { 290ab85156dSPeter Maydell CPUState *cs = CPU(obj); 29145183ccdSTaylor Simpson HexagonCPU *cpu = HEXAGON_CPU(cs); 29245183ccdSTaylor Simpson HexagonCPUClass *mcc = HEXAGON_CPU_GET_CLASS(cpu); 293c0336c87STaylor Simpson CPUHexagonState *env = &cpu->env; 29445183ccdSTaylor Simpson 295ab85156dSPeter Maydell if (mcc->parent_phases.hold) { 296ab85156dSPeter Maydell mcc->parent_phases.hold(obj); 297ab85156dSPeter Maydell } 298c0336c87STaylor Simpson 299c0336c87STaylor Simpson set_default_nan_mode(1, &env->fp_status); 300c0336c87STaylor Simpson set_float_detect_tininess(float_tininess_before_rounding, &env->fp_status); 30145183ccdSTaylor Simpson } 30245183ccdSTaylor Simpson 30345183ccdSTaylor Simpson static void hexagon_cpu_disas_set_info(CPUState *s, disassemble_info *info) 30445183ccdSTaylor Simpson { 30545183ccdSTaylor Simpson info->print_insn = print_insn_hexagon; 30645183ccdSTaylor Simpson } 30745183ccdSTaylor Simpson 30845183ccdSTaylor Simpson static void hexagon_cpu_realize(DeviceState *dev, Error **errp) 30945183ccdSTaylor Simpson { 31045183ccdSTaylor Simpson CPUState *cs = CPU(dev); 31145183ccdSTaylor Simpson HexagonCPUClass *mcc = HEXAGON_CPU_GET_CLASS(dev); 31245183ccdSTaylor Simpson Error *local_err = NULL; 31345183ccdSTaylor Simpson 31445183ccdSTaylor Simpson cpu_exec_realizefn(cs, &local_err); 31545183ccdSTaylor Simpson if (local_err != NULL) { 31645183ccdSTaylor Simpson error_propagate(errp, local_err); 31745183ccdSTaylor Simpson return; 31845183ccdSTaylor Simpson } 31945183ccdSTaylor Simpson 32045183ccdSTaylor Simpson qemu_init_vcpu(cs); 32145183ccdSTaylor Simpson cpu_reset(cs); 32245183ccdSTaylor Simpson 32345183ccdSTaylor Simpson mcc->parent_realize(dev, errp); 32445183ccdSTaylor Simpson } 32545183ccdSTaylor Simpson 32645183ccdSTaylor Simpson static void hexagon_cpu_init(Object *obj) 32745183ccdSTaylor Simpson { 32845183ccdSTaylor Simpson HexagonCPU *cpu = HEXAGON_CPU(obj); 32945183ccdSTaylor Simpson 33045183ccdSTaylor Simpson cpu_set_cpustate_pointers(cpu); 33145183ccdSTaylor Simpson qdev_property_add_static(DEVICE(obj), &hexagon_lldb_compat_property); 33245183ccdSTaylor Simpson qdev_property_add_static(DEVICE(obj), &hexagon_lldb_stack_adjust_property); 33345183ccdSTaylor Simpson } 33445183ccdSTaylor Simpson 33545183ccdSTaylor Simpson #include "hw/core/tcg-cpu-ops.h" 33645183ccdSTaylor Simpson 33711906557SRichard Henderson static const struct TCGCPUOps hexagon_tcg_ops = { 33845183ccdSTaylor Simpson .initialize = hexagon_translate_init, 33945183ccdSTaylor Simpson .synchronize_from_tb = hexagon_cpu_synchronize_from_tb, 34090157814SRichard Henderson .restore_state_to_opc = hexagon_restore_state_to_opc, 34145183ccdSTaylor Simpson }; 34245183ccdSTaylor Simpson 34345183ccdSTaylor Simpson static void hexagon_cpu_class_init(ObjectClass *c, void *data) 34445183ccdSTaylor Simpson { 34545183ccdSTaylor Simpson HexagonCPUClass *mcc = HEXAGON_CPU_CLASS(c); 34645183ccdSTaylor Simpson CPUClass *cc = CPU_CLASS(c); 34745183ccdSTaylor Simpson DeviceClass *dc = DEVICE_CLASS(c); 348ab85156dSPeter Maydell ResettableClass *rc = RESETTABLE_CLASS(c); 34945183ccdSTaylor Simpson 35045183ccdSTaylor Simpson device_class_set_parent_realize(dc, hexagon_cpu_realize, 35145183ccdSTaylor Simpson &mcc->parent_realize); 35245183ccdSTaylor Simpson 353ab85156dSPeter Maydell resettable_class_set_parent_phases(rc, NULL, hexagon_cpu_reset_hold, NULL, 354ab85156dSPeter Maydell &mcc->parent_phases); 35545183ccdSTaylor Simpson 35645183ccdSTaylor Simpson cc->class_by_name = hexagon_cpu_class_by_name; 35745183ccdSTaylor Simpson cc->has_work = hexagon_cpu_has_work; 35845183ccdSTaylor Simpson cc->dump_state = hexagon_dump_state; 35945183ccdSTaylor Simpson cc->set_pc = hexagon_cpu_set_pc; 360e4fdf9dfSRichard Henderson cc->get_pc = hexagon_cpu_get_pc; 36145183ccdSTaylor Simpson cc->gdb_read_register = hexagon_gdb_read_register; 36245183ccdSTaylor Simpson cc->gdb_write_register = hexagon_gdb_write_register; 363a1559537STaylor Simpson cc->gdb_num_core_regs = TOTAL_PER_THREAD_REGS + NUM_VREGS + NUM_QREGS; 36445183ccdSTaylor Simpson cc->gdb_stop_before_watchpoint = true; 36545183ccdSTaylor Simpson cc->disas_set_info = hexagon_cpu_disas_set_info; 36645183ccdSTaylor Simpson cc->tcg_ops = &hexagon_tcg_ops; 36745183ccdSTaylor Simpson } 36845183ccdSTaylor Simpson 36945183ccdSTaylor Simpson #define DEFINE_CPU(type_name, initfn) \ 37045183ccdSTaylor Simpson { \ 37145183ccdSTaylor Simpson .name = type_name, \ 37245183ccdSTaylor Simpson .parent = TYPE_HEXAGON_CPU, \ 37345183ccdSTaylor Simpson .instance_init = initfn \ 37445183ccdSTaylor Simpson } 37545183ccdSTaylor Simpson 37645183ccdSTaylor Simpson static const TypeInfo hexagon_cpu_type_infos[] = { 37745183ccdSTaylor Simpson { 37845183ccdSTaylor Simpson .name = TYPE_HEXAGON_CPU, 37945183ccdSTaylor Simpson .parent = TYPE_CPU, 38045183ccdSTaylor Simpson .instance_size = sizeof(HexagonCPU), 38145183ccdSTaylor Simpson .instance_init = hexagon_cpu_init, 38245183ccdSTaylor Simpson .abstract = true, 38345183ccdSTaylor Simpson .class_size = sizeof(HexagonCPUClass), 38445183ccdSTaylor Simpson .class_init = hexagon_cpu_class_init, 38545183ccdSTaylor Simpson }, 38645183ccdSTaylor Simpson DEFINE_CPU(TYPE_HEXAGON_CPU_V67, hexagon_v67_cpu_init), 387*fc2622f6STaylor Simpson DEFINE_CPU(TYPE_HEXAGON_CPU_V68, hexagon_v68_cpu_init), 388*fc2622f6STaylor Simpson DEFINE_CPU(TYPE_HEXAGON_CPU_V69, hexagon_v69_cpu_init), 389*fc2622f6STaylor Simpson DEFINE_CPU(TYPE_HEXAGON_CPU_V71, hexagon_v71_cpu_init), 390*fc2622f6STaylor Simpson DEFINE_CPU(TYPE_HEXAGON_CPU_V73, hexagon_v73_cpu_init), 39145183ccdSTaylor Simpson }; 39245183ccdSTaylor Simpson 39345183ccdSTaylor Simpson DEFINE_TYPES(hexagon_cpu_type_infos) 394