xref: /openbmc/qemu/target/hexagon/cpu.c (revision 47f3361a)
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 
hexagon_v66_cpu_init(Object * obj)2948ac9e88SBrian Cain static void hexagon_v66_cpu_init(Object *obj) { }
hexagon_v67_cpu_init(Object * obj)30fc2622f6STaylor Simpson static void hexagon_v67_cpu_init(Object *obj) { }
hexagon_v68_cpu_init(Object * obj)31fc2622f6STaylor Simpson static void hexagon_v68_cpu_init(Object *obj) { }
hexagon_v69_cpu_init(Object * obj)32fc2622f6STaylor Simpson static void hexagon_v69_cpu_init(Object *obj) { }
hexagon_v71_cpu_init(Object * obj)33fc2622f6STaylor Simpson static void hexagon_v71_cpu_init(Object *obj) { }
hexagon_v73_cpu_init(Object * obj)34fc2622f6STaylor Simpson static void hexagon_v73_cpu_init(Object *obj) { }
3545183ccdSTaylor Simpson 
hexagon_cpu_class_by_name(const char * cpu_model)3645183ccdSTaylor Simpson static ObjectClass *hexagon_cpu_class_by_name(const char *cpu_model)
3745183ccdSTaylor Simpson {
3845183ccdSTaylor Simpson     ObjectClass *oc;
3945183ccdSTaylor Simpson     char *typename;
4045183ccdSTaylor Simpson     char **cpuname;
4145183ccdSTaylor Simpson 
4245183ccdSTaylor Simpson     cpuname = g_strsplit(cpu_model, ",", 1);
4345183ccdSTaylor Simpson     typename = g_strdup_printf(HEXAGON_CPU_TYPE_NAME("%s"), cpuname[0]);
4445183ccdSTaylor Simpson     oc = object_class_by_name(typename);
4545183ccdSTaylor Simpson     g_strfreev(cpuname);
4645183ccdSTaylor Simpson     g_free(typename);
47d5be19f5SPhilippe Mathieu-Daudé 
4845183ccdSTaylor Simpson     return oc;
4945183ccdSTaylor Simpson }
5045183ccdSTaylor Simpson 
51*47f3361aSBrian Cain static Property hexagon_cpu_properties[] = {
52*47f3361aSBrian Cain     DEFINE_PROP_BOOL("lldb-compat", HexagonCPU, lldb_compat, false),
53*47f3361aSBrian Cain     DEFINE_PROP_UNSIGNED("lldb-stack-adjust", HexagonCPU, lldb_stack_adjust, 0,
54*47f3361aSBrian Cain                          qdev_prop_uint32, target_ulong),
55*47f3361aSBrian Cain     DEFINE_PROP_BOOL("short-circuit", HexagonCPU, short_circuit, true),
56*47f3361aSBrian Cain     DEFINE_PROP_END_OF_LIST()
57*47f3361aSBrian Cain };
5845183ccdSTaylor Simpson 
5945183ccdSTaylor Simpson const char * const hexagon_regnames[TOTAL_PER_THREAD_REGS] = {
6045183ccdSTaylor Simpson    "r0", "r1",  "r2",  "r3",  "r4",   "r5",  "r6",  "r7",
6145183ccdSTaylor Simpson    "r8", "r9",  "r10", "r11", "r12",  "r13", "r14", "r15",
6245183ccdSTaylor Simpson   "r16", "r17", "r18", "r19", "r20",  "r21", "r22", "r23",
6345183ccdSTaylor Simpson   "r24", "r25", "r26", "r27", "r28",  "r29", "r30", "r31",
6445183ccdSTaylor Simpson   "sa0", "lc0", "sa1", "lc1", "p3_0", "c5",  "m0",  "m1",
6545183ccdSTaylor Simpson   "usr", "pc",  "ugp", "gp",  "cs0",  "cs1", "c14", "c15",
6640438b67STaylor Simpson   "c16", "c17", "c18", "c19", "pkt_cnt",  "insn_cnt", "hvx_cnt", "c23",
6745183ccdSTaylor Simpson   "c24", "c25", "c26", "c27", "c28",  "c29", "c30", "c31",
6845183ccdSTaylor Simpson };
6945183ccdSTaylor Simpson 
7045183ccdSTaylor Simpson /*
7145183ccdSTaylor Simpson  * One of the main debugging techniques is to use "-d cpu" and compare against
7245183ccdSTaylor Simpson  * LLDB output when single stepping.  However, the target and qemu put the
7345183ccdSTaylor Simpson  * stacks at different locations.  This is used to compensate so the diff is
7445183ccdSTaylor Simpson  * cleaner.
7545183ccdSTaylor Simpson  */
adjust_stack_ptrs(CPUHexagonState * env,target_ulong addr)762d27cebbSTaylor Simpson static target_ulong adjust_stack_ptrs(CPUHexagonState *env, target_ulong addr)
7745183ccdSTaylor Simpson {
787d9ab202STaylor Simpson     HexagonCPU *cpu = env_archcpu(env);
7945183ccdSTaylor Simpson     target_ulong stack_adjust = cpu->lldb_stack_adjust;
8045183ccdSTaylor Simpson     target_ulong stack_start = env->stack_start;
8145183ccdSTaylor Simpson     target_ulong stack_size = 0x10000;
8245183ccdSTaylor Simpson 
8345183ccdSTaylor Simpson     if (stack_adjust == 0) {
8445183ccdSTaylor Simpson         return addr;
8545183ccdSTaylor Simpson     }
8645183ccdSTaylor Simpson 
8745183ccdSTaylor Simpson     if (stack_start + 0x1000 >= addr && addr >= (stack_start - stack_size)) {
8845183ccdSTaylor Simpson         return addr - stack_adjust;
8945183ccdSTaylor Simpson     }
9045183ccdSTaylor Simpson     return addr;
9145183ccdSTaylor Simpson }
9245183ccdSTaylor Simpson 
9372895676SMukilan Thiyagarajan /* HEX_REG_P3_0_ALIASED (aka C4) is an alias for the predicate registers */
read_p3_0(CPUHexagonState * env)942d27cebbSTaylor Simpson static target_ulong read_p3_0(CPUHexagonState *env)
9545183ccdSTaylor Simpson {
9645183ccdSTaylor Simpson     int32_t control_reg = 0;
9745183ccdSTaylor Simpson     int i;
9845183ccdSTaylor Simpson     for (i = NUM_PREGS - 1; i >= 0; i--) {
9945183ccdSTaylor Simpson         control_reg <<= 8;
10045183ccdSTaylor Simpson         control_reg |= env->pred[i] & 0xff;
10145183ccdSTaylor Simpson     }
10245183ccdSTaylor Simpson     return control_reg;
10345183ccdSTaylor Simpson }
10445183ccdSTaylor Simpson 
print_reg(FILE * f,CPUHexagonState * env,int regnum)10545183ccdSTaylor Simpson static void print_reg(FILE *f, CPUHexagonState *env, int regnum)
10645183ccdSTaylor Simpson {
10745183ccdSTaylor Simpson     target_ulong value;
10845183ccdSTaylor Simpson 
10972895676SMukilan Thiyagarajan     if (regnum == HEX_REG_P3_0_ALIASED) {
11045183ccdSTaylor Simpson         value = read_p3_0(env);
11145183ccdSTaylor Simpson     } else {
11245183ccdSTaylor Simpson         value = regnum < 32 ? adjust_stack_ptrs(env, env->gpr[regnum])
11345183ccdSTaylor Simpson                             : env->gpr[regnum];
11445183ccdSTaylor Simpson     }
11545183ccdSTaylor Simpson 
11645183ccdSTaylor Simpson     qemu_fprintf(f, "  %s = 0x" TARGET_FMT_lx "\n",
11745183ccdSTaylor Simpson                  hexagon_regnames[regnum], value);
11845183ccdSTaylor Simpson }
11945183ccdSTaylor Simpson 
print_vreg(FILE * f,CPUHexagonState * env,int regnum,bool skip_if_zero)120a1559537STaylor Simpson static void print_vreg(FILE *f, CPUHexagonState *env, int regnum,
121a1559537STaylor Simpson                        bool skip_if_zero)
122a1559537STaylor Simpson {
123a1559537STaylor Simpson     if (skip_if_zero) {
124a1559537STaylor Simpson         bool nonzero_found = false;
125a1559537STaylor Simpson         for (int i = 0; i < MAX_VEC_SIZE_BYTES; i++) {
126a1559537STaylor Simpson             if (env->VRegs[regnum].ub[i] != 0) {
127a1559537STaylor Simpson                 nonzero_found = true;
128a1559537STaylor Simpson                 break;
129a1559537STaylor Simpson             }
130a1559537STaylor Simpson         }
131a1559537STaylor Simpson         if (!nonzero_found) {
132a1559537STaylor Simpson             return;
133a1559537STaylor Simpson         }
134a1559537STaylor Simpson     }
135a1559537STaylor Simpson 
136a1559537STaylor Simpson     qemu_fprintf(f, "  v%d = ( ", regnum);
137a1559537STaylor Simpson     qemu_fprintf(f, "0x%02x", env->VRegs[regnum].ub[MAX_VEC_SIZE_BYTES - 1]);
138a1559537STaylor Simpson     for (int i = MAX_VEC_SIZE_BYTES - 2; i >= 0; i--) {
139a1559537STaylor Simpson         qemu_fprintf(f, ", 0x%02x", env->VRegs[regnum].ub[i]);
140a1559537STaylor Simpson     }
141a1559537STaylor Simpson     qemu_fprintf(f, " )\n");
142a1559537STaylor Simpson }
143a1559537STaylor Simpson 
hexagon_debug_vreg(CPUHexagonState * env,int regnum)144a1559537STaylor Simpson void hexagon_debug_vreg(CPUHexagonState *env, int regnum)
145a1559537STaylor Simpson {
146a1559537STaylor Simpson     print_vreg(stdout, env, regnum, false);
147a1559537STaylor Simpson }
148a1559537STaylor Simpson 
print_qreg(FILE * f,CPUHexagonState * env,int regnum,bool skip_if_zero)149a1559537STaylor Simpson static void print_qreg(FILE *f, CPUHexagonState *env, int regnum,
150a1559537STaylor Simpson                        bool skip_if_zero)
151a1559537STaylor Simpson {
152a1559537STaylor Simpson     if (skip_if_zero) {
153a1559537STaylor Simpson         bool nonzero_found = false;
154a1559537STaylor Simpson         for (int i = 0; i < MAX_VEC_SIZE_BYTES / 8; i++) {
155a1559537STaylor Simpson             if (env->QRegs[regnum].ub[i] != 0) {
156a1559537STaylor Simpson                 nonzero_found = true;
157a1559537STaylor Simpson                 break;
158a1559537STaylor Simpson             }
159a1559537STaylor Simpson         }
160a1559537STaylor Simpson         if (!nonzero_found) {
161a1559537STaylor Simpson             return;
162a1559537STaylor Simpson         }
163a1559537STaylor Simpson     }
164a1559537STaylor Simpson 
165a1559537STaylor Simpson     qemu_fprintf(f, "  q%d = ( ", regnum);
166a1559537STaylor Simpson     qemu_fprintf(f, "0x%02x",
167a1559537STaylor Simpson                  env->QRegs[regnum].ub[MAX_VEC_SIZE_BYTES / 8 - 1]);
168a1559537STaylor Simpson     for (int i = MAX_VEC_SIZE_BYTES / 8 - 2; i >= 0; i--) {
169a1559537STaylor Simpson         qemu_fprintf(f, ", 0x%02x", env->QRegs[regnum].ub[i]);
170a1559537STaylor Simpson     }
171a1559537STaylor Simpson     qemu_fprintf(f, " )\n");
172a1559537STaylor Simpson }
173a1559537STaylor Simpson 
hexagon_debug_qreg(CPUHexagonState * env,int regnum)174a1559537STaylor Simpson void hexagon_debug_qreg(CPUHexagonState *env, int regnum)
175a1559537STaylor Simpson {
176a1559537STaylor Simpson     print_qreg(stdout, env, regnum, false);
177a1559537STaylor Simpson }
178a1559537STaylor Simpson 
hexagon_dump(CPUHexagonState * env,FILE * f,int flags)179a1559537STaylor Simpson static void hexagon_dump(CPUHexagonState *env, FILE *f, int flags)
18045183ccdSTaylor Simpson {
1817d9ab202STaylor Simpson     HexagonCPU *cpu = env_archcpu(env);
18245183ccdSTaylor Simpson 
18345183ccdSTaylor Simpson     if (cpu->lldb_compat) {
18445183ccdSTaylor Simpson         /*
18545183ccdSTaylor Simpson          * When comparing with LLDB, it doesn't step through single-cycle
18645183ccdSTaylor Simpson          * hardware loops the same way.  So, we just skip them here
18745183ccdSTaylor Simpson          */
18845183ccdSTaylor Simpson         if (env->gpr[HEX_REG_PC] == env->last_pc_dumped) {
18945183ccdSTaylor Simpson             return;
19045183ccdSTaylor Simpson         }
19145183ccdSTaylor Simpson         env->last_pc_dumped = env->gpr[HEX_REG_PC];
19245183ccdSTaylor Simpson     }
19345183ccdSTaylor Simpson 
19445183ccdSTaylor Simpson     qemu_fprintf(f, "General Purpose Registers = {\n");
19545183ccdSTaylor Simpson     for (int i = 0; i < 32; i++) {
19645183ccdSTaylor Simpson         print_reg(f, env, i);
19745183ccdSTaylor Simpson     }
19845183ccdSTaylor Simpson     print_reg(f, env, HEX_REG_SA0);
19945183ccdSTaylor Simpson     print_reg(f, env, HEX_REG_LC0);
20045183ccdSTaylor Simpson     print_reg(f, env, HEX_REG_SA1);
20145183ccdSTaylor Simpson     print_reg(f, env, HEX_REG_LC1);
20245183ccdSTaylor Simpson     print_reg(f, env, HEX_REG_M0);
20345183ccdSTaylor Simpson     print_reg(f, env, HEX_REG_M1);
20445183ccdSTaylor Simpson     print_reg(f, env, HEX_REG_USR);
20572895676SMukilan Thiyagarajan     print_reg(f, env, HEX_REG_P3_0_ALIASED);
20645183ccdSTaylor Simpson     print_reg(f, env, HEX_REG_GP);
20745183ccdSTaylor Simpson     print_reg(f, env, HEX_REG_UGP);
20845183ccdSTaylor Simpson     print_reg(f, env, HEX_REG_PC);
20945183ccdSTaylor Simpson #ifdef CONFIG_USER_ONLY
21045183ccdSTaylor Simpson     /*
21145183ccdSTaylor Simpson      * Not modelled in user mode, print junk to minimize the diff's
21245183ccdSTaylor Simpson      * with LLDB output
21345183ccdSTaylor Simpson      */
21445183ccdSTaylor Simpson     qemu_fprintf(f, "  cause = 0x000000db\n");
21545183ccdSTaylor Simpson     qemu_fprintf(f, "  badva = 0x00000000\n");
21645183ccdSTaylor Simpson     qemu_fprintf(f, "  cs0 = 0x00000000\n");
21745183ccdSTaylor Simpson     qemu_fprintf(f, "  cs1 = 0x00000000\n");
21845183ccdSTaylor Simpson #else
21945183ccdSTaylor Simpson     print_reg(f, env, HEX_REG_CAUSE);
22045183ccdSTaylor Simpson     print_reg(f, env, HEX_REG_BADVA);
22145183ccdSTaylor Simpson     print_reg(f, env, HEX_REG_CS0);
22245183ccdSTaylor Simpson     print_reg(f, env, HEX_REG_CS1);
22345183ccdSTaylor Simpson #endif
22445183ccdSTaylor Simpson     qemu_fprintf(f, "}\n");
225a1559537STaylor Simpson 
226a1559537STaylor Simpson     if (flags & CPU_DUMP_FPU) {
227a1559537STaylor Simpson         qemu_fprintf(f, "Vector Registers = {\n");
228a1559537STaylor Simpson         for (int i = 0; i < NUM_VREGS; i++) {
229a1559537STaylor Simpson             print_vreg(f, env, i, true);
230a1559537STaylor Simpson         }
231a1559537STaylor Simpson         for (int i = 0; i < NUM_QREGS; i++) {
232a1559537STaylor Simpson             print_qreg(f, env, i, true);
233a1559537STaylor Simpson         }
234a1559537STaylor Simpson         qemu_fprintf(f, "}\n");
235a1559537STaylor Simpson     }
23645183ccdSTaylor Simpson }
23745183ccdSTaylor Simpson 
hexagon_dump_state(CPUState * cs,FILE * f,int flags)23845183ccdSTaylor Simpson static void hexagon_dump_state(CPUState *cs, FILE *f, int flags)
23945183ccdSTaylor Simpson {
2407ab74281SPhilippe Mathieu-Daudé     hexagon_dump(cpu_env(cs), f, flags);
24145183ccdSTaylor Simpson }
24245183ccdSTaylor Simpson 
hexagon_debug(CPUHexagonState * env)24345183ccdSTaylor Simpson void hexagon_debug(CPUHexagonState *env)
24445183ccdSTaylor Simpson {
245a1559537STaylor Simpson     hexagon_dump(env, stdout, CPU_DUMP_FPU);
24645183ccdSTaylor Simpson }
24745183ccdSTaylor Simpson 
hexagon_cpu_set_pc(CPUState * cs,vaddr value)24845183ccdSTaylor Simpson static void hexagon_cpu_set_pc(CPUState *cs, vaddr value)
24945183ccdSTaylor Simpson {
2507ab74281SPhilippe Mathieu-Daudé     cpu_env(cs)->gpr[HEX_REG_PC] = value;
25145183ccdSTaylor Simpson }
25245183ccdSTaylor Simpson 
hexagon_cpu_get_pc(CPUState * cs)253e4fdf9dfSRichard Henderson static vaddr hexagon_cpu_get_pc(CPUState *cs)
254e4fdf9dfSRichard Henderson {
2557ab74281SPhilippe Mathieu-Daudé     return cpu_env(cs)->gpr[HEX_REG_PC];
256e4fdf9dfSRichard Henderson }
257e4fdf9dfSRichard Henderson 
hexagon_cpu_synchronize_from_tb(CPUState * cs,const TranslationBlock * tb)25845183ccdSTaylor Simpson static void hexagon_cpu_synchronize_from_tb(CPUState *cs,
25945183ccdSTaylor Simpson                                             const TranslationBlock *tb)
26045183ccdSTaylor Simpson {
261b254c342SPhilippe Mathieu-Daudé     tcg_debug_assert(!tcg_cflags_has(cs, CF_PCREL));
2627ab74281SPhilippe Mathieu-Daudé     cpu_env(cs)->gpr[HEX_REG_PC] = tb->pc;
26345183ccdSTaylor Simpson }
26445183ccdSTaylor Simpson 
hexagon_cpu_has_work(CPUState * cs)26545183ccdSTaylor Simpson static bool hexagon_cpu_has_work(CPUState *cs)
26645183ccdSTaylor Simpson {
26745183ccdSTaylor Simpson     return true;
26845183ccdSTaylor Simpson }
26945183ccdSTaylor Simpson 
hexagon_restore_state_to_opc(CPUState * cs,const TranslationBlock * tb,const uint64_t * data)27090157814SRichard Henderson static void hexagon_restore_state_to_opc(CPUState *cs,
27190157814SRichard Henderson                                          const TranslationBlock *tb,
27290157814SRichard Henderson                                          const uint64_t *data)
27345183ccdSTaylor Simpson {
2747ab74281SPhilippe Mathieu-Daudé     cpu_env(cs)->gpr[HEX_REG_PC] = data[0];
27545183ccdSTaylor Simpson }
27645183ccdSTaylor Simpson 
hexagon_cpu_reset_hold(Object * obj,ResetType type)277ad80e367SPeter Maydell static void hexagon_cpu_reset_hold(Object *obj, ResetType type)
27845183ccdSTaylor Simpson {
279ab85156dSPeter Maydell     CPUState *cs = CPU(obj);
280348802b5SPhilippe Mathieu-Daudé     HexagonCPUClass *mcc = HEXAGON_CPU_GET_CLASS(obj);
2817ab74281SPhilippe Mathieu-Daudé     CPUHexagonState *env = cpu_env(cs);
28245183ccdSTaylor Simpson 
283ab85156dSPeter Maydell     if (mcc->parent_phases.hold) {
284ad80e367SPeter Maydell         mcc->parent_phases.hold(obj, type);
285ab85156dSPeter Maydell     }
286c0336c87STaylor Simpson 
287c0336c87STaylor Simpson     set_default_nan_mode(1, &env->fp_status);
288c0336c87STaylor Simpson     set_float_detect_tininess(float_tininess_before_rounding, &env->fp_status);
28945183ccdSTaylor Simpson }
29045183ccdSTaylor Simpson 
hexagon_cpu_disas_set_info(CPUState * s,disassemble_info * info)29145183ccdSTaylor Simpson static void hexagon_cpu_disas_set_info(CPUState *s, disassemble_info *info)
29245183ccdSTaylor Simpson {
29345183ccdSTaylor Simpson     info->print_insn = print_insn_hexagon;
29445183ccdSTaylor Simpson }
29545183ccdSTaylor Simpson 
hexagon_cpu_realize(DeviceState * dev,Error ** errp)29645183ccdSTaylor Simpson static void hexagon_cpu_realize(DeviceState *dev, Error **errp)
29745183ccdSTaylor Simpson {
29845183ccdSTaylor Simpson     CPUState *cs = CPU(dev);
29945183ccdSTaylor Simpson     HexagonCPUClass *mcc = HEXAGON_CPU_GET_CLASS(dev);
30045183ccdSTaylor Simpson     Error *local_err = NULL;
30145183ccdSTaylor Simpson 
30245183ccdSTaylor Simpson     cpu_exec_realizefn(cs, &local_err);
30345183ccdSTaylor Simpson     if (local_err != NULL) {
30445183ccdSTaylor Simpson         error_propagate(errp, local_err);
30545183ccdSTaylor Simpson         return;
30645183ccdSTaylor Simpson     }
30745183ccdSTaylor Simpson 
308b647652eSTaylor Simpson     gdb_register_coprocessor(cs, hexagon_hvx_gdb_read_register,
309b647652eSTaylor Simpson                              hexagon_hvx_gdb_write_register,
310ac1e8671SAkihiko Odaki                              gdb_find_static_feature("hexagon-hvx.xml"), 0);
311b647652eSTaylor Simpson 
31245183ccdSTaylor Simpson     qemu_init_vcpu(cs);
31345183ccdSTaylor Simpson     cpu_reset(cs);
31445183ccdSTaylor Simpson 
31545183ccdSTaylor Simpson     mcc->parent_realize(dev, errp);
31645183ccdSTaylor Simpson }
31745183ccdSTaylor Simpson 
hexagon_cpu_init(Object * obj)31845183ccdSTaylor Simpson static void hexagon_cpu_init(Object *obj)
31945183ccdSTaylor Simpson {
32045183ccdSTaylor Simpson }
32145183ccdSTaylor Simpson 
32245183ccdSTaylor Simpson #include "hw/core/tcg-cpu-ops.h"
32345183ccdSTaylor Simpson 
3241764ad70SRichard Henderson static const TCGCPUOps hexagon_tcg_ops = {
32545183ccdSTaylor Simpson     .initialize = hexagon_translate_init,
32645183ccdSTaylor Simpson     .synchronize_from_tb = hexagon_cpu_synchronize_from_tb,
32790157814SRichard Henderson     .restore_state_to_opc = hexagon_restore_state_to_opc,
32845183ccdSTaylor Simpson };
32945183ccdSTaylor Simpson 
hexagon_cpu_class_init(ObjectClass * c,void * data)33045183ccdSTaylor Simpson static void hexagon_cpu_class_init(ObjectClass *c, void *data)
33145183ccdSTaylor Simpson {
33245183ccdSTaylor Simpson     HexagonCPUClass *mcc = HEXAGON_CPU_CLASS(c);
33345183ccdSTaylor Simpson     CPUClass *cc = CPU_CLASS(c);
33445183ccdSTaylor Simpson     DeviceClass *dc = DEVICE_CLASS(c);
335ab85156dSPeter Maydell     ResettableClass *rc = RESETTABLE_CLASS(c);
33645183ccdSTaylor Simpson 
33745183ccdSTaylor Simpson     device_class_set_parent_realize(dc, hexagon_cpu_realize,
33845183ccdSTaylor Simpson                                     &mcc->parent_realize);
33945183ccdSTaylor Simpson 
340*47f3361aSBrian Cain     device_class_set_props(dc, hexagon_cpu_properties);
341ab85156dSPeter Maydell     resettable_class_set_parent_phases(rc, NULL, hexagon_cpu_reset_hold, NULL,
342ab85156dSPeter Maydell                                        &mcc->parent_phases);
34345183ccdSTaylor Simpson 
34445183ccdSTaylor Simpson     cc->class_by_name = hexagon_cpu_class_by_name;
34545183ccdSTaylor Simpson     cc->has_work = hexagon_cpu_has_work;
34645183ccdSTaylor Simpson     cc->dump_state = hexagon_dump_state;
34745183ccdSTaylor Simpson     cc->set_pc = hexagon_cpu_set_pc;
348e4fdf9dfSRichard Henderson     cc->get_pc = hexagon_cpu_get_pc;
34945183ccdSTaylor Simpson     cc->gdb_read_register = hexagon_gdb_read_register;
35045183ccdSTaylor Simpson     cc->gdb_write_register = hexagon_gdb_write_register;
35145183ccdSTaylor Simpson     cc->gdb_stop_before_watchpoint = true;
352ab930e80SMatheus Tavares Bernardino     cc->gdb_core_xml_file = "hexagon-core.xml";
35345183ccdSTaylor Simpson     cc->disas_set_info = hexagon_cpu_disas_set_info;
35445183ccdSTaylor Simpson     cc->tcg_ops = &hexagon_tcg_ops;
35545183ccdSTaylor Simpson }
35645183ccdSTaylor Simpson 
35745183ccdSTaylor Simpson #define DEFINE_CPU(type_name, initfn)      \
35845183ccdSTaylor Simpson     {                                      \
35945183ccdSTaylor Simpson         .name = type_name,                 \
36045183ccdSTaylor Simpson         .parent = TYPE_HEXAGON_CPU,        \
36145183ccdSTaylor Simpson         .instance_init = initfn            \
36245183ccdSTaylor Simpson     }
36345183ccdSTaylor Simpson 
36445183ccdSTaylor Simpson static const TypeInfo hexagon_cpu_type_infos[] = {
36545183ccdSTaylor Simpson     {
36645183ccdSTaylor Simpson         .name = TYPE_HEXAGON_CPU,
36745183ccdSTaylor Simpson         .parent = TYPE_CPU,
36845183ccdSTaylor Simpson         .instance_size = sizeof(HexagonCPU),
369f669c992SRichard Henderson         .instance_align = __alignof(HexagonCPU),
37045183ccdSTaylor Simpson         .instance_init = hexagon_cpu_init,
37145183ccdSTaylor Simpson         .abstract = true,
37245183ccdSTaylor Simpson         .class_size = sizeof(HexagonCPUClass),
37345183ccdSTaylor Simpson         .class_init = hexagon_cpu_class_init,
37445183ccdSTaylor Simpson     },
37548ac9e88SBrian Cain     DEFINE_CPU(TYPE_HEXAGON_CPU_V66,              hexagon_v66_cpu_init),
37645183ccdSTaylor Simpson     DEFINE_CPU(TYPE_HEXAGON_CPU_V67,              hexagon_v67_cpu_init),
377fc2622f6STaylor Simpson     DEFINE_CPU(TYPE_HEXAGON_CPU_V68,              hexagon_v68_cpu_init),
378fc2622f6STaylor Simpson     DEFINE_CPU(TYPE_HEXAGON_CPU_V69,              hexagon_v69_cpu_init),
379fc2622f6STaylor Simpson     DEFINE_CPU(TYPE_HEXAGON_CPU_V71,              hexagon_v71_cpu_init),
380fc2622f6STaylor Simpson     DEFINE_CPU(TYPE_HEXAGON_CPU_V73,              hexagon_v73_cpu_init),
38145183ccdSTaylor Simpson };
38245183ccdSTaylor Simpson 
38345183ccdSTaylor Simpson DEFINE_TYPES(hexagon_cpu_type_infos)
384