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