2 * TriCore emulation for qemu: main translation routines.
4 * Copyright (c) 2012-2014 Bastian Koppelmann C-Lab/University Paderborn
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
20 #include "qemu/osdep.h"
21 #include "qapi/error.h"
23 #include "exec/exec-all.h"
24 #include "qemu/error-report.h"
25 #include "tcg/debug-assert.h"
27 static inline void set_feature(CPUTriCoreState
*env
, int feature
)
29 env
->features
|= 1ULL << feature
;
32 static const gchar
*tricore_gdb_arch_name(CPUState
*cs
)
37 static void tricore_cpu_set_pc(CPUState
*cs
, vaddr value
)
39 cpu_env(cs
)->PC
= value
& ~(target_ulong
)1;
42 static vaddr
tricore_cpu_get_pc(CPUState
*cs
)
44 return cpu_env(cs
)->PC
;
47 static void tricore_cpu_synchronize_from_tb(CPUState
*cs
,
48 const TranslationBlock
*tb
)
50 tcg_debug_assert(!(cs
->tcg_cflags
& CF_PCREL
));
51 cpu_env(cs
)->PC
= tb
->pc
;
54 static void tricore_restore_state_to_opc(CPUState
*cs
,
55 const TranslationBlock
*tb
,
58 cpu_env(cs
)->PC
= data
[0];
61 static void tricore_cpu_reset_hold(Object
*obj
)
63 CPUState
*cs
= CPU(obj
);
64 TriCoreCPUClass
*tcc
= TRICORE_CPU_GET_CLASS(obj
);
66 if (tcc
->parent_phases
.hold
) {
67 tcc
->parent_phases
.hold(obj
);
70 cpu_state_reset(cpu_env(cs
));
73 static bool tricore_cpu_has_work(CPUState
*cs
)
78 static int tricore_cpu_mmu_index(CPUState
*cs
, bool ifetch
)
83 static void tricore_cpu_realizefn(DeviceState
*dev
, Error
**errp
)
85 CPUState
*cs
= CPU(dev
);
86 TriCoreCPU
*cpu
= TRICORE_CPU(dev
);
87 TriCoreCPUClass
*tcc
= TRICORE_CPU_GET_CLASS(dev
);
88 CPUTriCoreState
*env
= &cpu
->env
;
89 Error
*local_err
= NULL
;
91 cpu_exec_realizefn(cs
, &local_err
);
92 if (local_err
!= NULL
) {
93 error_propagate(errp
, local_err
);
97 /* Some features automatically imply others */
98 if (tricore_has_feature(env
, TRICORE_FEATURE_162
)) {
99 set_feature(env
, TRICORE_FEATURE_161
);
102 if (tricore_has_feature(env
, TRICORE_FEATURE_161
)) {
103 set_feature(env
, TRICORE_FEATURE_16
);
106 if (tricore_has_feature(env
, TRICORE_FEATURE_16
)) {
107 set_feature(env
, TRICORE_FEATURE_131
);
109 if (tricore_has_feature(env
, TRICORE_FEATURE_131
)) {
110 set_feature(env
, TRICORE_FEATURE_13
);
115 tcc
->parent_realize(dev
, errp
);
118 static ObjectClass
*tricore_cpu_class_by_name(const char *cpu_model
)
123 typename
= g_strdup_printf(TRICORE_CPU_TYPE_NAME("%s"), cpu_model
);
124 oc
= object_class_by_name(typename
);
130 static void tc1796_initfn(Object
*obj
)
132 TriCoreCPU
*cpu
= TRICORE_CPU(obj
);
134 set_feature(&cpu
->env
, TRICORE_FEATURE_13
);
137 static void tc1797_initfn(Object
*obj
)
139 TriCoreCPU
*cpu
= TRICORE_CPU(obj
);
141 set_feature(&cpu
->env
, TRICORE_FEATURE_131
);
144 static void tc27x_initfn(Object
*obj
)
146 TriCoreCPU
*cpu
= TRICORE_CPU(obj
);
148 set_feature(&cpu
->env
, TRICORE_FEATURE_161
);
151 static void tc37x_initfn(Object
*obj
)
153 TriCoreCPU
*cpu
= TRICORE_CPU(obj
);
155 set_feature(&cpu
->env
, TRICORE_FEATURE_162
);
159 #include "hw/core/sysemu-cpu-ops.h"
161 static const struct SysemuCPUOps tricore_sysemu_ops
= {
162 .get_phys_page_debug
= tricore_cpu_get_phys_page_debug
,
165 #include "hw/core/tcg-cpu-ops.h"
167 static const TCGCPUOps tricore_tcg_ops
= {
168 .initialize
= tricore_tcg_init
,
169 .synchronize_from_tb
= tricore_cpu_synchronize_from_tb
,
170 .restore_state_to_opc
= tricore_restore_state_to_opc
,
171 .tlb_fill
= tricore_cpu_tlb_fill
,
174 static void tricore_cpu_class_init(ObjectClass
*c
, void *data
)
176 TriCoreCPUClass
*mcc
= TRICORE_CPU_CLASS(c
);
177 CPUClass
*cc
= CPU_CLASS(c
);
178 DeviceClass
*dc
= DEVICE_CLASS(c
);
179 ResettableClass
*rc
= RESETTABLE_CLASS(c
);
181 device_class_set_parent_realize(dc
, tricore_cpu_realizefn
,
182 &mcc
->parent_realize
);
184 resettable_class_set_parent_phases(rc
, NULL
, tricore_cpu_reset_hold
, NULL
,
185 &mcc
->parent_phases
);
186 cc
->class_by_name
= tricore_cpu_class_by_name
;
187 cc
->has_work
= tricore_cpu_has_work
;
188 cc
->mmu_index
= tricore_cpu_mmu_index
;
190 cc
->gdb_read_register
= tricore_cpu_gdb_read_register
;
191 cc
->gdb_write_register
= tricore_cpu_gdb_write_register
;
192 cc
->gdb_num_core_regs
= 44;
193 cc
->gdb_arch_name
= tricore_gdb_arch_name
;
195 cc
->dump_state
= tricore_cpu_dump_state
;
196 cc
->set_pc
= tricore_cpu_set_pc
;
197 cc
->get_pc
= tricore_cpu_get_pc
;
198 cc
->sysemu_ops
= &tricore_sysemu_ops
;
199 cc
->tcg_ops
= &tricore_tcg_ops
;
202 #define DEFINE_TRICORE_CPU_TYPE(cpu_model, initfn) \
204 .parent = TYPE_TRICORE_CPU, \
205 .instance_init = initfn, \
206 .name = TRICORE_CPU_TYPE_NAME(cpu_model), \
209 static const TypeInfo tricore_cpu_type_infos
[] = {
211 .name
= TYPE_TRICORE_CPU
,
213 .instance_size
= sizeof(TriCoreCPU
),
214 .instance_align
= __alignof(TriCoreCPU
),
216 .class_size
= sizeof(TriCoreCPUClass
),
217 .class_init
= tricore_cpu_class_init
,
219 DEFINE_TRICORE_CPU_TYPE("tc1796", tc1796_initfn
),
220 DEFINE_TRICORE_CPU_TYPE("tc1797", tc1797_initfn
),
221 DEFINE_TRICORE_CPU_TYPE("tc27x", tc27x_initfn
),
222 DEFINE_TRICORE_CPU_TYPE("tc37x", tc37x_initfn
),
225 DEFINE_TYPES(tricore_cpu_type_infos
)