145183ccdSTaylor Simpson /* 2fc2622f6STaylor 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" 27b647652eSTaylor Simpson #include "exec/gdbstub.h" 2845183ccdSTaylor Simpson 29fc2622f6STaylor Simpson static void hexagon_v67_cpu_init(Object *obj) { } 30fc2622f6STaylor Simpson static void hexagon_v68_cpu_init(Object *obj) { } 31fc2622f6STaylor Simpson static void hexagon_v69_cpu_init(Object *obj) { } 32fc2622f6STaylor Simpson static void hexagon_v71_cpu_init(Object *obj) { } 33fc2622f6STaylor Simpson static void hexagon_v73_cpu_init(Object *obj) { } 3445183ccdSTaylor Simpson 35f0e0c984SMatheus Tavares Bernardino static void hexagon_cpu_list_entry(gpointer data, gpointer user_data) 36f0e0c984SMatheus Tavares Bernardino { 37f0e0c984SMatheus Tavares Bernardino ObjectClass *oc = data; 38f0e0c984SMatheus Tavares Bernardino char *name = g_strdup(object_class_get_name(oc)); 39f0e0c984SMatheus Tavares Bernardino if (g_str_has_suffix(name, HEXAGON_CPU_TYPE_SUFFIX)) { 40f0e0c984SMatheus Tavares Bernardino name[strlen(name) - strlen(HEXAGON_CPU_TYPE_SUFFIX)] = '\0'; 41f0e0c984SMatheus Tavares Bernardino } 42f0e0c984SMatheus Tavares Bernardino qemu_printf(" %s\n", name); 43f0e0c984SMatheus Tavares Bernardino g_free(name); 44f0e0c984SMatheus Tavares Bernardino } 45f0e0c984SMatheus Tavares Bernardino 46f0e0c984SMatheus Tavares Bernardino void hexagon_cpu_list(void) 47f0e0c984SMatheus Tavares Bernardino { 48f0e0c984SMatheus Tavares Bernardino GSList *list; 49f0e0c984SMatheus Tavares Bernardino list = object_class_get_list_sorted(TYPE_HEXAGON_CPU, false); 50f0e0c984SMatheus Tavares Bernardino qemu_printf("Available CPUs:\n"); 51f0e0c984SMatheus Tavares Bernardino g_slist_foreach(list, hexagon_cpu_list_entry, NULL); 52f0e0c984SMatheus Tavares Bernardino g_slist_free(list); 53f0e0c984SMatheus Tavares Bernardino } 54f0e0c984SMatheus Tavares Bernardino 5545183ccdSTaylor Simpson static ObjectClass *hexagon_cpu_class_by_name(const char *cpu_model) 5645183ccdSTaylor Simpson { 5745183ccdSTaylor Simpson ObjectClass *oc; 5845183ccdSTaylor Simpson char *typename; 5945183ccdSTaylor Simpson char **cpuname; 6045183ccdSTaylor Simpson 6145183ccdSTaylor Simpson cpuname = g_strsplit(cpu_model, ",", 1); 6245183ccdSTaylor Simpson typename = g_strdup_printf(HEXAGON_CPU_TYPE_NAME("%s"), cpuname[0]); 6345183ccdSTaylor Simpson oc = object_class_by_name(typename); 6445183ccdSTaylor Simpson g_strfreev(cpuname); 6545183ccdSTaylor Simpson g_free(typename); 66*d5be19f5SPhilippe Mathieu-Daudé 6745183ccdSTaylor Simpson return oc; 6845183ccdSTaylor Simpson } 6945183ccdSTaylor Simpson 7045183ccdSTaylor Simpson static Property hexagon_lldb_compat_property = 7145183ccdSTaylor Simpson DEFINE_PROP_BOOL("lldb-compat", HexagonCPU, lldb_compat, false); 7245183ccdSTaylor Simpson static Property hexagon_lldb_stack_adjust_property = 7345183ccdSTaylor Simpson DEFINE_PROP_UNSIGNED("lldb-stack-adjust", HexagonCPU, lldb_stack_adjust, 7445183ccdSTaylor Simpson 0, qdev_prop_uint32, target_ulong); 75d54c5615STaylor Simpson static Property hexagon_short_circuit_property = 76d54c5615STaylor Simpson DEFINE_PROP_BOOL("short-circuit", HexagonCPU, short_circuit, true); 7745183ccdSTaylor Simpson 7845183ccdSTaylor Simpson const char * const hexagon_regnames[TOTAL_PER_THREAD_REGS] = { 7945183ccdSTaylor Simpson "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 8045183ccdSTaylor Simpson "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", 8145183ccdSTaylor Simpson "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", 8245183ccdSTaylor Simpson "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", 8345183ccdSTaylor Simpson "sa0", "lc0", "sa1", "lc1", "p3_0", "c5", "m0", "m1", 8445183ccdSTaylor Simpson "usr", "pc", "ugp", "gp", "cs0", "cs1", "c14", "c15", 8540438b67STaylor Simpson "c16", "c17", "c18", "c19", "pkt_cnt", "insn_cnt", "hvx_cnt", "c23", 8645183ccdSTaylor Simpson "c24", "c25", "c26", "c27", "c28", "c29", "c30", "c31", 8745183ccdSTaylor Simpson }; 8845183ccdSTaylor Simpson 8945183ccdSTaylor Simpson /* 9045183ccdSTaylor Simpson * One of the main debugging techniques is to use "-d cpu" and compare against 9145183ccdSTaylor Simpson * LLDB output when single stepping. However, the target and qemu put the 9245183ccdSTaylor Simpson * stacks at different locations. This is used to compensate so the diff is 9345183ccdSTaylor Simpson * cleaner. 9445183ccdSTaylor Simpson */ 952d27cebbSTaylor Simpson static target_ulong adjust_stack_ptrs(CPUHexagonState *env, target_ulong addr) 9645183ccdSTaylor Simpson { 977d9ab202STaylor Simpson HexagonCPU *cpu = env_archcpu(env); 9845183ccdSTaylor Simpson target_ulong stack_adjust = cpu->lldb_stack_adjust; 9945183ccdSTaylor Simpson target_ulong stack_start = env->stack_start; 10045183ccdSTaylor Simpson target_ulong stack_size = 0x10000; 10145183ccdSTaylor Simpson 10245183ccdSTaylor Simpson if (stack_adjust == 0) { 10345183ccdSTaylor Simpson return addr; 10445183ccdSTaylor Simpson } 10545183ccdSTaylor Simpson 10645183ccdSTaylor Simpson if (stack_start + 0x1000 >= addr && addr >= (stack_start - stack_size)) { 10745183ccdSTaylor Simpson return addr - stack_adjust; 10845183ccdSTaylor Simpson } 10945183ccdSTaylor Simpson return addr; 11045183ccdSTaylor Simpson } 11145183ccdSTaylor Simpson 11272895676SMukilan Thiyagarajan /* HEX_REG_P3_0_ALIASED (aka C4) is an alias for the predicate registers */ 1132d27cebbSTaylor Simpson static target_ulong read_p3_0(CPUHexagonState *env) 11445183ccdSTaylor Simpson { 11545183ccdSTaylor Simpson int32_t control_reg = 0; 11645183ccdSTaylor Simpson int i; 11745183ccdSTaylor Simpson for (i = NUM_PREGS - 1; i >= 0; i--) { 11845183ccdSTaylor Simpson control_reg <<= 8; 11945183ccdSTaylor Simpson control_reg |= env->pred[i] & 0xff; 12045183ccdSTaylor Simpson } 12145183ccdSTaylor Simpson return control_reg; 12245183ccdSTaylor Simpson } 12345183ccdSTaylor Simpson 12445183ccdSTaylor Simpson static void print_reg(FILE *f, CPUHexagonState *env, int regnum) 12545183ccdSTaylor Simpson { 12645183ccdSTaylor Simpson target_ulong value; 12745183ccdSTaylor Simpson 12872895676SMukilan Thiyagarajan if (regnum == HEX_REG_P3_0_ALIASED) { 12945183ccdSTaylor Simpson value = read_p3_0(env); 13045183ccdSTaylor Simpson } else { 13145183ccdSTaylor Simpson value = regnum < 32 ? adjust_stack_ptrs(env, env->gpr[regnum]) 13245183ccdSTaylor Simpson : env->gpr[regnum]; 13345183ccdSTaylor Simpson } 13445183ccdSTaylor Simpson 13545183ccdSTaylor Simpson qemu_fprintf(f, " %s = 0x" TARGET_FMT_lx "\n", 13645183ccdSTaylor Simpson hexagon_regnames[regnum], value); 13745183ccdSTaylor Simpson } 13845183ccdSTaylor Simpson 139a1559537STaylor Simpson static void print_vreg(FILE *f, CPUHexagonState *env, int regnum, 140a1559537STaylor Simpson bool skip_if_zero) 141a1559537STaylor Simpson { 142a1559537STaylor Simpson if (skip_if_zero) { 143a1559537STaylor Simpson bool nonzero_found = false; 144a1559537STaylor Simpson for (int i = 0; i < MAX_VEC_SIZE_BYTES; i++) { 145a1559537STaylor Simpson if (env->VRegs[regnum].ub[i] != 0) { 146a1559537STaylor Simpson nonzero_found = true; 147a1559537STaylor Simpson break; 148a1559537STaylor Simpson } 149a1559537STaylor Simpson } 150a1559537STaylor Simpson if (!nonzero_found) { 151a1559537STaylor Simpson return; 152a1559537STaylor Simpson } 153a1559537STaylor Simpson } 154a1559537STaylor Simpson 155a1559537STaylor Simpson qemu_fprintf(f, " v%d = ( ", regnum); 156a1559537STaylor Simpson qemu_fprintf(f, "0x%02x", env->VRegs[regnum].ub[MAX_VEC_SIZE_BYTES - 1]); 157a1559537STaylor Simpson for (int i = MAX_VEC_SIZE_BYTES - 2; i >= 0; i--) { 158a1559537STaylor Simpson qemu_fprintf(f, ", 0x%02x", env->VRegs[regnum].ub[i]); 159a1559537STaylor Simpson } 160a1559537STaylor Simpson qemu_fprintf(f, " )\n"); 161a1559537STaylor Simpson } 162a1559537STaylor Simpson 163a1559537STaylor Simpson void hexagon_debug_vreg(CPUHexagonState *env, int regnum) 164a1559537STaylor Simpson { 165a1559537STaylor Simpson print_vreg(stdout, env, regnum, false); 166a1559537STaylor Simpson } 167a1559537STaylor Simpson 168a1559537STaylor Simpson static void print_qreg(FILE *f, CPUHexagonState *env, int regnum, 169a1559537STaylor Simpson bool skip_if_zero) 170a1559537STaylor Simpson { 171a1559537STaylor Simpson if (skip_if_zero) { 172a1559537STaylor Simpson bool nonzero_found = false; 173a1559537STaylor Simpson for (int i = 0; i < MAX_VEC_SIZE_BYTES / 8; i++) { 174a1559537STaylor Simpson if (env->QRegs[regnum].ub[i] != 0) { 175a1559537STaylor Simpson nonzero_found = true; 176a1559537STaylor Simpson break; 177a1559537STaylor Simpson } 178a1559537STaylor Simpson } 179a1559537STaylor Simpson if (!nonzero_found) { 180a1559537STaylor Simpson return; 181a1559537STaylor Simpson } 182a1559537STaylor Simpson } 183a1559537STaylor Simpson 184a1559537STaylor Simpson qemu_fprintf(f, " q%d = ( ", regnum); 185a1559537STaylor Simpson qemu_fprintf(f, "0x%02x", 186a1559537STaylor Simpson env->QRegs[regnum].ub[MAX_VEC_SIZE_BYTES / 8 - 1]); 187a1559537STaylor Simpson for (int i = MAX_VEC_SIZE_BYTES / 8 - 2; i >= 0; i--) { 188a1559537STaylor Simpson qemu_fprintf(f, ", 0x%02x", env->QRegs[regnum].ub[i]); 189a1559537STaylor Simpson } 190a1559537STaylor Simpson qemu_fprintf(f, " )\n"); 191a1559537STaylor Simpson } 192a1559537STaylor Simpson 193a1559537STaylor Simpson void hexagon_debug_qreg(CPUHexagonState *env, int regnum) 194a1559537STaylor Simpson { 195a1559537STaylor Simpson print_qreg(stdout, env, regnum, false); 196a1559537STaylor Simpson } 197a1559537STaylor Simpson 198a1559537STaylor Simpson static void hexagon_dump(CPUHexagonState *env, FILE *f, int flags) 19945183ccdSTaylor Simpson { 2007d9ab202STaylor Simpson HexagonCPU *cpu = env_archcpu(env); 20145183ccdSTaylor Simpson 20245183ccdSTaylor Simpson if (cpu->lldb_compat) { 20345183ccdSTaylor Simpson /* 20445183ccdSTaylor Simpson * When comparing with LLDB, it doesn't step through single-cycle 20545183ccdSTaylor Simpson * hardware loops the same way. So, we just skip them here 20645183ccdSTaylor Simpson */ 20745183ccdSTaylor Simpson if (env->gpr[HEX_REG_PC] == env->last_pc_dumped) { 20845183ccdSTaylor Simpson return; 20945183ccdSTaylor Simpson } 21045183ccdSTaylor Simpson env->last_pc_dumped = env->gpr[HEX_REG_PC]; 21145183ccdSTaylor Simpson } 21245183ccdSTaylor Simpson 21345183ccdSTaylor Simpson qemu_fprintf(f, "General Purpose Registers = {\n"); 21445183ccdSTaylor Simpson for (int i = 0; i < 32; i++) { 21545183ccdSTaylor Simpson print_reg(f, env, i); 21645183ccdSTaylor Simpson } 21745183ccdSTaylor Simpson print_reg(f, env, HEX_REG_SA0); 21845183ccdSTaylor Simpson print_reg(f, env, HEX_REG_LC0); 21945183ccdSTaylor Simpson print_reg(f, env, HEX_REG_SA1); 22045183ccdSTaylor Simpson print_reg(f, env, HEX_REG_LC1); 22145183ccdSTaylor Simpson print_reg(f, env, HEX_REG_M0); 22245183ccdSTaylor Simpson print_reg(f, env, HEX_REG_M1); 22345183ccdSTaylor Simpson print_reg(f, env, HEX_REG_USR); 22472895676SMukilan Thiyagarajan print_reg(f, env, HEX_REG_P3_0_ALIASED); 22545183ccdSTaylor Simpson print_reg(f, env, HEX_REG_GP); 22645183ccdSTaylor Simpson print_reg(f, env, HEX_REG_UGP); 22745183ccdSTaylor Simpson print_reg(f, env, HEX_REG_PC); 22845183ccdSTaylor Simpson #ifdef CONFIG_USER_ONLY 22945183ccdSTaylor Simpson /* 23045183ccdSTaylor Simpson * Not modelled in user mode, print junk to minimize the diff's 23145183ccdSTaylor Simpson * with LLDB output 23245183ccdSTaylor Simpson */ 23345183ccdSTaylor Simpson qemu_fprintf(f, " cause = 0x000000db\n"); 23445183ccdSTaylor Simpson qemu_fprintf(f, " badva = 0x00000000\n"); 23545183ccdSTaylor Simpson qemu_fprintf(f, " cs0 = 0x00000000\n"); 23645183ccdSTaylor Simpson qemu_fprintf(f, " cs1 = 0x00000000\n"); 23745183ccdSTaylor Simpson #else 23845183ccdSTaylor Simpson print_reg(f, env, HEX_REG_CAUSE); 23945183ccdSTaylor Simpson print_reg(f, env, HEX_REG_BADVA); 24045183ccdSTaylor Simpson print_reg(f, env, HEX_REG_CS0); 24145183ccdSTaylor Simpson print_reg(f, env, HEX_REG_CS1); 24245183ccdSTaylor Simpson #endif 24345183ccdSTaylor Simpson qemu_fprintf(f, "}\n"); 244a1559537STaylor Simpson 245a1559537STaylor Simpson if (flags & CPU_DUMP_FPU) { 246a1559537STaylor Simpson qemu_fprintf(f, "Vector Registers = {\n"); 247a1559537STaylor Simpson for (int i = 0; i < NUM_VREGS; i++) { 248a1559537STaylor Simpson print_vreg(f, env, i, true); 249a1559537STaylor Simpson } 250a1559537STaylor Simpson for (int i = 0; i < NUM_QREGS; i++) { 251a1559537STaylor Simpson print_qreg(f, env, i, true); 252a1559537STaylor Simpson } 253a1559537STaylor Simpson qemu_fprintf(f, "}\n"); 254a1559537STaylor Simpson } 25545183ccdSTaylor Simpson } 25645183ccdSTaylor Simpson 25745183ccdSTaylor Simpson static void hexagon_dump_state(CPUState *cs, FILE *f, int flags) 25845183ccdSTaylor Simpson { 25945183ccdSTaylor Simpson HexagonCPU *cpu = HEXAGON_CPU(cs); 26045183ccdSTaylor Simpson CPUHexagonState *env = &cpu->env; 26145183ccdSTaylor Simpson 262a1559537STaylor Simpson hexagon_dump(env, f, flags); 26345183ccdSTaylor Simpson } 26445183ccdSTaylor Simpson 26545183ccdSTaylor Simpson void hexagon_debug(CPUHexagonState *env) 26645183ccdSTaylor Simpson { 267a1559537STaylor Simpson hexagon_dump(env, stdout, CPU_DUMP_FPU); 26845183ccdSTaylor Simpson } 26945183ccdSTaylor Simpson 27045183ccdSTaylor Simpson static void hexagon_cpu_set_pc(CPUState *cs, vaddr value) 27145183ccdSTaylor Simpson { 27245183ccdSTaylor Simpson HexagonCPU *cpu = HEXAGON_CPU(cs); 27345183ccdSTaylor Simpson CPUHexagonState *env = &cpu->env; 27445183ccdSTaylor Simpson env->gpr[HEX_REG_PC] = value; 27545183ccdSTaylor Simpson } 27645183ccdSTaylor Simpson 277e4fdf9dfSRichard Henderson static vaddr hexagon_cpu_get_pc(CPUState *cs) 278e4fdf9dfSRichard Henderson { 279e4fdf9dfSRichard Henderson HexagonCPU *cpu = HEXAGON_CPU(cs); 280e4fdf9dfSRichard Henderson CPUHexagonState *env = &cpu->env; 281e4fdf9dfSRichard Henderson return env->gpr[HEX_REG_PC]; 282e4fdf9dfSRichard Henderson } 283e4fdf9dfSRichard Henderson 28445183ccdSTaylor Simpson static void hexagon_cpu_synchronize_from_tb(CPUState *cs, 28545183ccdSTaylor Simpson const TranslationBlock *tb) 28645183ccdSTaylor Simpson { 28745183ccdSTaylor Simpson HexagonCPU *cpu = HEXAGON_CPU(cs); 28845183ccdSTaylor Simpson CPUHexagonState *env = &cpu->env; 289ba445655SAnton Johansson tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL)); 290ba445655SAnton Johansson env->gpr[HEX_REG_PC] = tb->pc; 29145183ccdSTaylor Simpson } 29245183ccdSTaylor Simpson 29345183ccdSTaylor Simpson static bool hexagon_cpu_has_work(CPUState *cs) 29445183ccdSTaylor Simpson { 29545183ccdSTaylor Simpson return true; 29645183ccdSTaylor Simpson } 29745183ccdSTaylor Simpson 29890157814SRichard Henderson static void hexagon_restore_state_to_opc(CPUState *cs, 29990157814SRichard Henderson const TranslationBlock *tb, 30090157814SRichard Henderson const uint64_t *data) 30145183ccdSTaylor Simpson { 30290157814SRichard Henderson HexagonCPU *cpu = HEXAGON_CPU(cs); 30390157814SRichard Henderson CPUHexagonState *env = &cpu->env; 30490157814SRichard Henderson 30545183ccdSTaylor Simpson env->gpr[HEX_REG_PC] = data[0]; 30645183ccdSTaylor Simpson } 30745183ccdSTaylor Simpson 308ab85156dSPeter Maydell static void hexagon_cpu_reset_hold(Object *obj) 30945183ccdSTaylor Simpson { 310ab85156dSPeter Maydell CPUState *cs = CPU(obj); 31145183ccdSTaylor Simpson HexagonCPU *cpu = HEXAGON_CPU(cs); 31245183ccdSTaylor Simpson HexagonCPUClass *mcc = HEXAGON_CPU_GET_CLASS(cpu); 313c0336c87STaylor Simpson CPUHexagonState *env = &cpu->env; 31445183ccdSTaylor Simpson 315ab85156dSPeter Maydell if (mcc->parent_phases.hold) { 316ab85156dSPeter Maydell mcc->parent_phases.hold(obj); 317ab85156dSPeter Maydell } 318c0336c87STaylor Simpson 319c0336c87STaylor Simpson set_default_nan_mode(1, &env->fp_status); 320c0336c87STaylor Simpson set_float_detect_tininess(float_tininess_before_rounding, &env->fp_status); 32145183ccdSTaylor Simpson } 32245183ccdSTaylor Simpson 32345183ccdSTaylor Simpson static void hexagon_cpu_disas_set_info(CPUState *s, disassemble_info *info) 32445183ccdSTaylor Simpson { 32545183ccdSTaylor Simpson info->print_insn = print_insn_hexagon; 32645183ccdSTaylor Simpson } 32745183ccdSTaylor Simpson 32845183ccdSTaylor Simpson static void hexagon_cpu_realize(DeviceState *dev, Error **errp) 32945183ccdSTaylor Simpson { 33045183ccdSTaylor Simpson CPUState *cs = CPU(dev); 33145183ccdSTaylor Simpson HexagonCPUClass *mcc = HEXAGON_CPU_GET_CLASS(dev); 33245183ccdSTaylor Simpson Error *local_err = NULL; 33345183ccdSTaylor Simpson 33445183ccdSTaylor Simpson cpu_exec_realizefn(cs, &local_err); 33545183ccdSTaylor Simpson if (local_err != NULL) { 33645183ccdSTaylor Simpson error_propagate(errp, local_err); 33745183ccdSTaylor Simpson return; 33845183ccdSTaylor Simpson } 33945183ccdSTaylor Simpson 340b647652eSTaylor Simpson gdb_register_coprocessor(cs, hexagon_hvx_gdb_read_register, 341b647652eSTaylor Simpson hexagon_hvx_gdb_write_register, 342b647652eSTaylor Simpson NUM_VREGS + NUM_QREGS, 343b647652eSTaylor Simpson "hexagon-hvx.xml", 0); 344b647652eSTaylor Simpson 34545183ccdSTaylor Simpson qemu_init_vcpu(cs); 34645183ccdSTaylor Simpson cpu_reset(cs); 34745183ccdSTaylor Simpson 34845183ccdSTaylor Simpson mcc->parent_realize(dev, errp); 34945183ccdSTaylor Simpson } 35045183ccdSTaylor Simpson 35145183ccdSTaylor Simpson static void hexagon_cpu_init(Object *obj) 35245183ccdSTaylor Simpson { 35345183ccdSTaylor Simpson qdev_property_add_static(DEVICE(obj), &hexagon_lldb_compat_property); 35445183ccdSTaylor Simpson qdev_property_add_static(DEVICE(obj), &hexagon_lldb_stack_adjust_property); 355d54c5615STaylor Simpson qdev_property_add_static(DEVICE(obj), &hexagon_short_circuit_property); 35645183ccdSTaylor Simpson } 35745183ccdSTaylor Simpson 35845183ccdSTaylor Simpson #include "hw/core/tcg-cpu-ops.h" 35945183ccdSTaylor Simpson 36011906557SRichard Henderson static const struct TCGCPUOps hexagon_tcg_ops = { 36145183ccdSTaylor Simpson .initialize = hexagon_translate_init, 36245183ccdSTaylor Simpson .synchronize_from_tb = hexagon_cpu_synchronize_from_tb, 36390157814SRichard Henderson .restore_state_to_opc = hexagon_restore_state_to_opc, 36445183ccdSTaylor Simpson }; 36545183ccdSTaylor Simpson 36645183ccdSTaylor Simpson static void hexagon_cpu_class_init(ObjectClass *c, void *data) 36745183ccdSTaylor Simpson { 36845183ccdSTaylor Simpson HexagonCPUClass *mcc = HEXAGON_CPU_CLASS(c); 36945183ccdSTaylor Simpson CPUClass *cc = CPU_CLASS(c); 37045183ccdSTaylor Simpson DeviceClass *dc = DEVICE_CLASS(c); 371ab85156dSPeter Maydell ResettableClass *rc = RESETTABLE_CLASS(c); 37245183ccdSTaylor Simpson 37345183ccdSTaylor Simpson device_class_set_parent_realize(dc, hexagon_cpu_realize, 37445183ccdSTaylor Simpson &mcc->parent_realize); 37545183ccdSTaylor Simpson 376ab85156dSPeter Maydell resettable_class_set_parent_phases(rc, NULL, hexagon_cpu_reset_hold, NULL, 377ab85156dSPeter Maydell &mcc->parent_phases); 37845183ccdSTaylor Simpson 37945183ccdSTaylor Simpson cc->class_by_name = hexagon_cpu_class_by_name; 38045183ccdSTaylor Simpson cc->has_work = hexagon_cpu_has_work; 38145183ccdSTaylor Simpson cc->dump_state = hexagon_dump_state; 38245183ccdSTaylor Simpson cc->set_pc = hexagon_cpu_set_pc; 383e4fdf9dfSRichard Henderson cc->get_pc = hexagon_cpu_get_pc; 38445183ccdSTaylor Simpson cc->gdb_read_register = hexagon_gdb_read_register; 38545183ccdSTaylor Simpson cc->gdb_write_register = hexagon_gdb_write_register; 386ab930e80SMatheus Tavares Bernardino cc->gdb_num_core_regs = TOTAL_PER_THREAD_REGS; 38745183ccdSTaylor Simpson cc->gdb_stop_before_watchpoint = true; 388ab930e80SMatheus Tavares Bernardino cc->gdb_core_xml_file = "hexagon-core.xml"; 38945183ccdSTaylor Simpson cc->disas_set_info = hexagon_cpu_disas_set_info; 39045183ccdSTaylor Simpson cc->tcg_ops = &hexagon_tcg_ops; 39145183ccdSTaylor Simpson } 39245183ccdSTaylor Simpson 39345183ccdSTaylor Simpson #define DEFINE_CPU(type_name, initfn) \ 39445183ccdSTaylor Simpson { \ 39545183ccdSTaylor Simpson .name = type_name, \ 39645183ccdSTaylor Simpson .parent = TYPE_HEXAGON_CPU, \ 39745183ccdSTaylor Simpson .instance_init = initfn \ 39845183ccdSTaylor Simpson } 39945183ccdSTaylor Simpson 40045183ccdSTaylor Simpson static const TypeInfo hexagon_cpu_type_infos[] = { 40145183ccdSTaylor Simpson { 40245183ccdSTaylor Simpson .name = TYPE_HEXAGON_CPU, 40345183ccdSTaylor Simpson .parent = TYPE_CPU, 40445183ccdSTaylor Simpson .instance_size = sizeof(HexagonCPU), 405f669c992SRichard Henderson .instance_align = __alignof(HexagonCPU), 40645183ccdSTaylor Simpson .instance_init = hexagon_cpu_init, 40745183ccdSTaylor Simpson .abstract = true, 40845183ccdSTaylor Simpson .class_size = sizeof(HexagonCPUClass), 40945183ccdSTaylor Simpson .class_init = hexagon_cpu_class_init, 41045183ccdSTaylor Simpson }, 41145183ccdSTaylor Simpson DEFINE_CPU(TYPE_HEXAGON_CPU_V67, hexagon_v67_cpu_init), 412fc2622f6STaylor Simpson DEFINE_CPU(TYPE_HEXAGON_CPU_V68, hexagon_v68_cpu_init), 413fc2622f6STaylor Simpson DEFINE_CPU(TYPE_HEXAGON_CPU_V69, hexagon_v69_cpu_init), 414fc2622f6STaylor Simpson DEFINE_CPU(TYPE_HEXAGON_CPU_V71, hexagon_v71_cpu_init), 415fc2622f6STaylor Simpson DEFINE_CPU(TYPE_HEXAGON_CPU_V73, hexagon_v73_cpu_init), 41645183ccdSTaylor Simpson }; 41745183ccdSTaylor Simpson 41845183ccdSTaylor Simpson DEFINE_TYPES(hexagon_cpu_type_infos) 419