Skip to content

Commit 6e7f40c

Browse files
committed
qemu/target/avr: add initial Unicorn integration.
Signed-off-by: Glenn Baker <[email protected]>
1 parent 6a32c04 commit 6e7f40c

File tree

8 files changed

+523
-72
lines changed

8 files changed

+523
-72
lines changed

qemu/include/tcg/tcg.h

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -712,7 +712,7 @@ struct TCGContext {
712712
void *tb_ret_addr;
713713

714714
/* target/riscv/translate.c */
715-
TCGv cpu_gpr[32], cpu_pc; // also target/mips/translate.c
715+
TCGv cpu_gpr[32], cpu_pc; // also target/mips/translate.c, target/avr/translate.c
716716
TCGv_i64 cpu_fpr[32]; /* assume F and D extensions */
717717
TCGv load_res;
718718
TCGv load_val;
@@ -807,6 +807,23 @@ struct TCGContext {
807807

808808
char s390x_cpu_reg_names[16][4]; // renamed from original cpu_reg_names[][] to avoid name clash with m68k
809809
TCGv_i64 regs[16];
810+
811+
// target/avr/translate.c
812+
TCGv cpu_Cf;
813+
TCGv cpu_Zf;
814+
TCGv cpu_Nf;
815+
TCGv cpu_Vf;
816+
TCGv cpu_Sf;
817+
TCGv cpu_Hf;
818+
TCGv cpu_Tf;
819+
TCGv cpu_If;
820+
TCGv cpu_rampD;
821+
TCGv cpu_rampX;
822+
TCGv cpu_rampY;
823+
TCGv cpu_rampZ;
824+
TCGv cpu_eind;
825+
TCGv cpu_sp;
826+
TCGv cpu_skip;
810827
};
811828

812829
static inline size_t temp_idx(TCGContext *tcg_ctx, TCGTemp *ts)

qemu/target/avr/cpu-qom.h

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,19 @@
2222
#define QEMU_AVR_QOM_H
2323

2424
#include "hw/core/cpu.h"
25-
#include "qom/object.h"
25+
26+
typedef void Object;
27+
typedef void ObjectClass;
28+
29+
typedef void DeviceState;
30+
typedef void (*DeviceRealize)(DeviceState *ds);
31+
typedef void (*DeviceReset)(DeviceState *ds);
2632

2733
#define TYPE_AVR_CPU "avr-cpu"
2834

29-
OBJECT_DECLARE_TYPE(AVRCPU, AVRCPUClass,
30-
AVR_CPU)
35+
#define AVR_CPU(obj) ((AVRCPU *)obj)
36+
#define AVR_CPU_CLASS(klass) ((AVRCPUClass *)klass)
37+
#define AVR_CPU_GET_CLASS(obj) (&((AVRCPU *)obj)->cc)
3138

3239
/**
3340
* AVRCPUClass:
@@ -37,13 +44,13 @@ OBJECT_DECLARE_TYPE(AVRCPU, AVRCPUClass,
3744
*
3845
* A AVR CPU model.
3946
*/
40-
struct AVRCPUClass {
47+
typedef struct AVRCPUClass {
4148
/*< private >*/
4249
CPUClass parent_class;
4350
/*< public >*/
4451
DeviceRealize parent_realize;
4552
DeviceReset parent_reset;
46-
};
53+
} AVRCPUClass;
4754

4855

4956
#endif /* !defined (QEMU_AVR_CPU_QOM_H) */

qemu/target/avr/cpu.c

Lines changed: 95 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,10 @@
1919
*/
2020

2121
#include "qemu/osdep.h"
22-
#include "qapi/error.h"
23-
#include "qemu/qemu-print.h"
2422
#include "exec/exec-all.h"
2523
#include "cpu.h"
2624
#include "disas/dis-asm.h"
25+
#include "unicorn_helper.h"
2726

2827
static void avr_cpu_set_pc(CPUState *cs, vaddr value)
2928
{
@@ -56,7 +55,8 @@ static void avr_cpu_reset(DeviceState *ds)
5655
AVRCPUClass *mcc = AVR_CPU_GET_CLASS(cpu);
5756
CPUAVRState *env = &cpu->env;
5857

59-
mcc->parent_reset(ds);
58+
if (mcc->parent_reset)
59+
mcc->parent_reset(ds);
6060

6161
env->pc_w = 0;
6262
env->sregI = 1;
@@ -80,29 +80,28 @@ static void avr_cpu_reset(DeviceState *ds)
8080
memset(env->r, 0, sizeof(env->r));
8181
}
8282

83+
#if 0
8384
static void avr_cpu_disas_set_info(CPUState *cpu, disassemble_info *info)
8485
{
8586
info->mach = bfd_arch_avr;
8687
info->print_insn = avr_print_insn;
8788
}
89+
#endif
8890

89-
static void avr_cpu_realizefn(DeviceState *dev, Error **errp)
91+
static void avr_cpu_realizefn(DeviceState *dev)
9092
{
9193
CPUState *cs = CPU(dev);
9294
AVRCPUClass *mcc = AVR_CPU_GET_CLASS(dev);
93-
Error *local_err = NULL;
9495

95-
cpu_exec_realizefn(cs, &local_err);
96-
if (local_err != NULL) {
97-
error_propagate(errp, local_err);
98-
return;
99-
}
96+
cpu_exec_realizefn(cs);
10097
qemu_init_vcpu(cs);
10198
cpu_reset(cs);
10299

103-
mcc->parent_realize(dev, errp);
100+
if (mcc->parent_realize)
101+
mcc->parent_realize(dev);
104102
}
105103

104+
#if 0
106105
static void avr_cpu_set_int(void *opaque, int irq, int level)
107106
{
108107
AVRCPU *cpu = opaque;
@@ -120,18 +119,24 @@ static void avr_cpu_set_int(void *opaque, int irq, int level)
120119
}
121120
}
122121
}
122+
#endif
123123

124-
static void avr_cpu_initfn(Object *obj)
124+
static void avr_cpu_initfn(Object *obj, struct uc_struct *uc)
125125
{
126126
AVRCPU *cpu = AVR_CPU(obj);
127+
CPUAVRState *const env = &cpu->env;
127128

129+
env->uc = uc;
128130
cpu_set_cpustate_pointers(cpu);
129131

132+
#if 0
130133
/* Set the number of interrupts supported by the CPU. */
131134
qdev_init_gpio_in(DEVICE(cpu), avr_cpu_set_int,
132135
sizeof(cpu->env.intsrc) * 8);
136+
#endif
133137
}
134138

139+
#if 0
135140
static ObjectClass *avr_cpu_class_by_name(const char *cpu_model)
136141
{
137142
ObjectClass *oc;
@@ -143,7 +148,9 @@ static ObjectClass *avr_cpu_class_by_name(const char *cpu_model)
143148
}
144149
return oc;
145150
}
151+
#endif
146152

153+
#if 0
147154
static void avr_cpu_dump_state(CPUState *cs, FILE *f, int flags)
148155
{
149156
AVRCPU *cpu = AVR_CPU(cs);
@@ -182,36 +189,45 @@ static void avr_cpu_dump_state(CPUState *cs, FILE *f, int flags)
182189
}
183190
qemu_fprintf(f, "\n");
184191
}
192+
#endif
185193

186194
static void avr_cpu_class_init(ObjectClass *oc, void *data)
187195
{
188-
DeviceClass *dc = DEVICE_CLASS(oc);
189196
CPUClass *cc = CPU_CLASS(oc);
190197
AVRCPUClass *mcc = AVR_CPU_CLASS(oc);
191198

192-
mcc->parent_realize = dc->realize;
193-
dc->realize = avr_cpu_realizefn;
194-
195-
device_class_set_parent_reset(dc, avr_cpu_reset, &mcc->parent_reset);
199+
mcc->parent_realize = NULL;
200+
mcc->parent_reset = NULL;
196201

202+
#if 0
197203
cc->class_by_name = avr_cpu_class_by_name;
204+
#endif
198205

206+
cc->reset = avr_cpu_reset;
199207
cc->has_work = avr_cpu_has_work;
200208
cc->do_interrupt = avr_cpu_do_interrupt;
201209
cc->cpu_exec_interrupt = avr_cpu_exec_interrupt;
210+
#if 0
202211
cc->dump_state = avr_cpu_dump_state;
212+
#endif
203213
cc->set_pc = avr_cpu_set_pc;
214+
#if 0
204215
cc->memory_rw_debug = avr_cpu_memory_rw_debug;
216+
#endif
205217
cc->get_phys_page_debug = avr_cpu_get_phys_page_debug;
206218
cc->tlb_fill = avr_cpu_tlb_fill;
219+
#if 0
207220
cc->vmsd = &vms_avr_cpu;
208221
cc->disas_set_info = avr_cpu_disas_set_info;
222+
#endif
209223
cc->tcg_initialize = avr_cpu_tcg_init;
210224
cc->synchronize_from_tb = avr_cpu_synchronize_from_tb;
225+
#if 0
211226
cc->gdb_read_register = avr_cpu_gdb_read_register;
212227
cc->gdb_write_register = avr_cpu_gdb_write_register;
213228
cc->gdb_num_core_regs = 35;
214229
cc->gdb_core_xml_file = "avr-cpu.xml";
230+
#endif
215231
}
216232

217233
/*
@@ -321,11 +337,28 @@ static void avr_avr6_initfn(Object *obj)
321337
}
322338

323339
typedef struct AVRCPUInfo {
340+
int model;
324341
const char *name;
325342
void (*initfn)(Object *obj);
326343
} AVRCPUInfo;
327344

345+
static const AVRCPUInfo avr_cpu_info[] ={
346+
{UC_CPU_AVR_AVR5, "avr5", avr_avr5_initfn},
347+
{UC_CPU_AVR_AVR51, "avr51", avr_avr51_initfn},
348+
{UC_CPU_AVR_AVR6, "avr6", avr_avr6_initfn},
349+
};
350+
351+
static const AVRCPUInfo *avr_cpu_info_get(int cpu_model)
352+
{
353+
for (int i = 0; i < ARRAY_SIZE(avr_cpu_info); i++) {
354+
const AVRCPUInfo *const cip = &avr_cpu_info[i];
355+
if (cpu_model == cip->model)
356+
return cip;
357+
}
358+
return NULL;
359+
}
328360

361+
#if 0
329362
static void avr_cpu_list_entry(gpointer data, gpointer user_data)
330363
{
331364
const char *typename = object_class_get_name(OBJECT_CLASS(data));
@@ -364,3 +397,48 @@ static const TypeInfo avr_cpu_type_info[] = {
364397
};
365398

366399
DEFINE_TYPES(avr_cpu_type_info)
400+
#endif
401+
402+
AVRCPU *cpu_avr_init(struct uc_struct *uc)
403+
{
404+
AVRCPU *cpu;
405+
CPUState *cs;
406+
CPUClass *cc;
407+
ObjectClass *oc;
408+
409+
cpu = calloc(1, sizeof(*cpu));
410+
if (cpu == NULL) {
411+
return NULL;
412+
}
413+
414+
if (uc->cpu_model == INT_MAX)
415+
uc->cpu_model = UC_CPU_AVR_AVR6;
416+
const AVRCPUInfo *const cip = avr_cpu_info_get(uc->cpu_model);
417+
if (!cip) {
418+
free(cpu);
419+
return NULL;
420+
}
421+
422+
cs = &cpu->parent_obj;
423+
cc = &AVR_CPU_GET_CLASS(cpu)->parent_class;
424+
oc = (ObjectClass *)cc;
425+
cs->cc = cc;
426+
cs->uc = uc;
427+
uc->cpu = cs;
428+
429+
cpu_class_init(uc, cc);
430+
avr_cpu_class_init(oc, NULL);
431+
432+
cpu_common_initfn(uc, cs);
433+
avr_cpu_initfn(cs, uc);
434+
cip->initfn(cs);
435+
436+
avr_cpu_realizefn(cs);
437+
438+
// init address space
439+
cpu_address_space_init(cs, 0, cs->memory);
440+
441+
qemu_init_vcpu(cs);
442+
443+
return cpu;
444+
}

qemu/target/avr/cpu.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
#include "cpu-qom.h"
2525
#include "exec/cpu-defs.h"
26+
#include "disas/dis-asm.h"
2627

2728
#ifdef CONFIG_USER_ONLY
2829
#error "AVR 8-bit does not support user mode"
@@ -137,6 +138,9 @@ struct CPUAVRState {
137138
bool fullacc; /* CPU/MEM if true MEM only otherwise */
138139

139140
uint64_t features;
141+
142+
// Unicorn engine
143+
struct uc_struct *uc;
140144
};
141145

142146
/**
@@ -152,6 +156,8 @@ typedef struct AVRCPU {
152156

153157
CPUNegativeOffsetState neg;
154158
CPUAVRState env;
159+
160+
AVRCPUClass cc;
155161
} AVRCPU;
156162

157163
extern const struct VMStateDescription vms_avr_cpu;
@@ -182,7 +188,7 @@ static inline int avr_cpu_mmu_index(CPUAVRState *env, bool ifetch)
182188
return ifetch ? MMU_CODE_IDX : MMU_DATA_IDX;
183189
}
184190

185-
void avr_cpu_tcg_init(void);
191+
void avr_cpu_tcg_init(struct uc_struct *uc);
186192

187193
void avr_cpu_list(void);
188194
int cpu_avr_exec(CPUState *cpu);

0 commit comments

Comments
 (0)