[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v16 02/10] target-avr: adding AVR CPU features/flavo
From: |
Michael Rolnik |
Subject: |
[Qemu-devel] [PATCH v16 02/10] target-avr: adding AVR CPU features/flavors |
Date: |
Thu, 18 Aug 2016 01:38:36 +0300 |
Signed-off-by: Michael Rolnik <address@hidden>
---
target-avr/cpu.c | 311 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
target-avr/cpu.h | 48 +++++++++
2 files changed, 359 insertions(+)
diff --git a/target-avr/cpu.c b/target-avr/cpu.c
index e99f804..d817266 100644
--- a/target-avr/cpu.c
+++ b/target-avr/cpu.c
@@ -200,12 +200,323 @@ static void avr_cpu_class_init(ObjectClass *oc, void
*data)
dc->cannot_destroy_with_object_finalize_yet = true;
}
+static void avr_avr1_initfn(Object *obj)
+{
+ AVRCPU *cpu = AVR_CPU(obj);
+ CPUAVRState *env = &cpu->env;
+
+ avr_set_feature(env, AVR_FEATURE_LPM);
+ avr_set_feature(env, AVR_FEATURE_2_BYTE_SP);
+ avr_set_feature(env, AVR_FEATURE_2_BYTE_PC);
+}
+
+static void avr_avr2_initfn(Object *obj)
+{
+ AVRCPU *cpu = AVR_CPU(obj);
+ CPUAVRState *env = &cpu->env;
+
+ avr_set_feature(env, AVR_FEATURE_LPM);
+ avr_set_feature(env, AVR_FEATURE_IJMP_ICALL);
+ avr_set_feature(env, AVR_FEATURE_ADIW_SBIW);
+ avr_set_feature(env, AVR_FEATURE_SRAM);
+ avr_set_feature(env, AVR_FEATURE_BREAK);
+
+ avr_set_feature(env, AVR_FEATURE_2_BYTE_PC);
+ avr_set_feature(env, AVR_FEATURE_2_BYTE_SP);
+}
+
+static void avr_avr25_initfn(Object *obj)
+{
+ AVRCPU *cpu = AVR_CPU(obj);
+ CPUAVRState *env = &cpu->env;
+
+ avr_set_feature(env, AVR_FEATURE_LPM);
+ avr_set_feature(env, AVR_FEATURE_IJMP_ICALL);
+ avr_set_feature(env, AVR_FEATURE_ADIW_SBIW);
+ avr_set_feature(env, AVR_FEATURE_SRAM);
+ avr_set_feature(env, AVR_FEATURE_BREAK);
+
+ avr_set_feature(env, AVR_FEATURE_2_BYTE_PC);
+ avr_set_feature(env, AVR_FEATURE_2_BYTE_SP);
+ avr_set_feature(env, AVR_FEATURE_LPMX);
+ avr_set_feature(env, AVR_FEATURE_MOVW);
+}
+
+static void avr_avr3_initfn(Object *obj)
+{
+ AVRCPU *cpu = AVR_CPU(obj);
+ CPUAVRState *env = &cpu->env;
+
+ avr_set_feature(env, AVR_FEATURE_LPM);
+ avr_set_feature(env, AVR_FEATURE_IJMP_ICALL);
+ avr_set_feature(env, AVR_FEATURE_ADIW_SBIW);
+ avr_set_feature(env, AVR_FEATURE_SRAM);
+ avr_set_feature(env, AVR_FEATURE_BREAK);
+
+ avr_set_feature(env, AVR_FEATURE_2_BYTE_PC);
+ avr_set_feature(env, AVR_FEATURE_2_BYTE_SP);
+ avr_set_feature(env, AVR_FEATURE_JMP_CALL);
+}
+
+static void avr_avr31_initfn(Object *obj)
+{
+ AVRCPU *cpu = AVR_CPU(obj);
+ CPUAVRState *env = &cpu->env;
+
+ avr_set_feature(env, AVR_FEATURE_LPM);
+ avr_set_feature(env, AVR_FEATURE_IJMP_ICALL);
+ avr_set_feature(env, AVR_FEATURE_ADIW_SBIW);
+ avr_set_feature(env, AVR_FEATURE_SRAM);
+ avr_set_feature(env, AVR_FEATURE_BREAK);
+
+ avr_set_feature(env, AVR_FEATURE_2_BYTE_PC);
+ avr_set_feature(env, AVR_FEATURE_2_BYTE_SP);
+ avr_set_feature(env, AVR_FEATURE_RAMPZ);
+ avr_set_feature(env, AVR_FEATURE_ELPM);
+ avr_set_feature(env, AVR_FEATURE_JMP_CALL);
+}
+
+static void avr_avr35_initfn(Object *obj)
+{
+ AVRCPU *cpu = AVR_CPU(obj);
+ CPUAVRState *env = &cpu->env;
+
+ avr_set_feature(env, AVR_FEATURE_LPM);
+ avr_set_feature(env, AVR_FEATURE_IJMP_ICALL);
+ avr_set_feature(env, AVR_FEATURE_ADIW_SBIW);
+ avr_set_feature(env, AVR_FEATURE_SRAM);
+ avr_set_feature(env, AVR_FEATURE_BREAK);
+
+ avr_set_feature(env, AVR_FEATURE_2_BYTE_PC);
+ avr_set_feature(env, AVR_FEATURE_2_BYTE_SP);
+ avr_set_feature(env, AVR_FEATURE_JMP_CALL);
+ avr_set_feature(env, AVR_FEATURE_LPMX);
+ avr_set_feature(env, AVR_FEATURE_MOVW);
+}
+
+static void avr_avr4_initfn(Object *obj)
+{
+ AVRCPU *cpu = AVR_CPU(obj);
+ CPUAVRState *env = &cpu->env;
+
+ avr_set_feature(env, AVR_FEATURE_LPM);
+ avr_set_feature(env, AVR_FEATURE_IJMP_ICALL);
+ avr_set_feature(env, AVR_FEATURE_ADIW_SBIW);
+ avr_set_feature(env, AVR_FEATURE_SRAM);
+ avr_set_feature(env, AVR_FEATURE_BREAK);
+
+ avr_set_feature(env, AVR_FEATURE_2_BYTE_PC);
+ avr_set_feature(env, AVR_FEATURE_2_BYTE_SP);
+ avr_set_feature(env, AVR_FEATURE_LPMX);
+ avr_set_feature(env, AVR_FEATURE_MOVW);
+ avr_set_feature(env, AVR_FEATURE_MUL);
+}
+
+static void avr_avr5_initfn(Object *obj)
+{
+ AVRCPU *cpu = AVR_CPU(obj);
+ CPUAVRState *env = &cpu->env;
+
+ avr_set_feature(env, AVR_FEATURE_LPM);
+ avr_set_feature(env, AVR_FEATURE_IJMP_ICALL);
+ avr_set_feature(env, AVR_FEATURE_ADIW_SBIW);
+ avr_set_feature(env, AVR_FEATURE_SRAM);
+ avr_set_feature(env, AVR_FEATURE_BREAK);
+
+ avr_set_feature(env, AVR_FEATURE_2_BYTE_PC);
+ avr_set_feature(env, AVR_FEATURE_2_BYTE_SP);
+ avr_set_feature(env, AVR_FEATURE_JMP_CALL);
+ avr_set_feature(env, AVR_FEATURE_LPMX);
+ avr_set_feature(env, AVR_FEATURE_MOVW);
+ avr_set_feature(env, AVR_FEATURE_MUL);
+}
+
+static void avr_avr51_initfn(Object *obj)
+{
+ AVRCPU *cpu = AVR_CPU(obj);
+ CPUAVRState *env = &cpu->env;
+
+ avr_set_feature(env, AVR_FEATURE_LPM);
+ avr_set_feature(env, AVR_FEATURE_IJMP_ICALL);
+ avr_set_feature(env, AVR_FEATURE_ADIW_SBIW);
+ avr_set_feature(env, AVR_FEATURE_SRAM);
+ avr_set_feature(env, AVR_FEATURE_BREAK);
+
+ avr_set_feature(env, AVR_FEATURE_2_BYTE_PC);
+ avr_set_feature(env, AVR_FEATURE_2_BYTE_SP);
+ avr_set_feature(env, AVR_FEATURE_RAMPZ);
+ avr_set_feature(env, AVR_FEATURE_ELPMX);
+ avr_set_feature(env, AVR_FEATURE_ELPM);
+ avr_set_feature(env, AVR_FEATURE_JMP_CALL);
+ avr_set_feature(env, AVR_FEATURE_LPMX);
+ avr_set_feature(env, AVR_FEATURE_MOVW);
+ avr_set_feature(env, AVR_FEATURE_MUL);
+}
+
+static void avr_avr6_initfn(Object *obj)
+{
+ AVRCPU *cpu = AVR_CPU(obj);
+ CPUAVRState *env = &cpu->env;
+
+ avr_set_feature(env, AVR_FEATURE_LPM);
+ avr_set_feature(env, AVR_FEATURE_IJMP_ICALL);
+ avr_set_feature(env, AVR_FEATURE_ADIW_SBIW);
+ avr_set_feature(env, AVR_FEATURE_SRAM);
+ avr_set_feature(env, AVR_FEATURE_BREAK);
+
+ avr_set_feature(env, AVR_FEATURE_3_BYTE_PC);
+ avr_set_feature(env, AVR_FEATURE_2_BYTE_SP);
+ avr_set_feature(env, AVR_FEATURE_RAMPZ);
+ avr_set_feature(env, AVR_FEATURE_EIJMP_EICALL);
+ avr_set_feature(env, AVR_FEATURE_ELPMX);
+ avr_set_feature(env, AVR_FEATURE_ELPM);
+ avr_set_feature(env, AVR_FEATURE_JMP_CALL);
+ avr_set_feature(env, AVR_FEATURE_LPMX);
+ avr_set_feature(env, AVR_FEATURE_MOVW);
+ avr_set_feature(env, AVR_FEATURE_MUL);
+}
+
+static void avr_xmega2_initfn(Object *obj)
+{
+ AVRCPU *cpu = AVR_CPU(obj);
+ CPUAVRState *env = &cpu->env;
+
+ avr_set_feature(env, AVR_FEATURE_LPM);
+ avr_set_feature(env, AVR_FEATURE_IJMP_ICALL);
+ avr_set_feature(env, AVR_FEATURE_ADIW_SBIW);
+ avr_set_feature(env, AVR_FEATURE_SRAM);
+ avr_set_feature(env, AVR_FEATURE_BREAK);
+
+ avr_set_feature(env, AVR_FEATURE_2_BYTE_PC);
+ avr_set_feature(env, AVR_FEATURE_2_BYTE_SP);
+ avr_set_feature(env, AVR_FEATURE_JMP_CALL);
+ avr_set_feature(env, AVR_FEATURE_LPMX);
+ avr_set_feature(env, AVR_FEATURE_MOVW);
+ avr_set_feature(env, AVR_FEATURE_MUL);
+ avr_set_feature(env, AVR_FEATURE_RMW);
+}
+
+static void avr_xmega4_initfn(Object *obj)
+{
+ AVRCPU *cpu = AVR_CPU(obj);
+ CPUAVRState *env = &cpu->env;
+
+ avr_set_feature(env, AVR_FEATURE_LPM);
+ avr_set_feature(env, AVR_FEATURE_IJMP_ICALL);
+ avr_set_feature(env, AVR_FEATURE_ADIW_SBIW);
+ avr_set_feature(env, AVR_FEATURE_SRAM);
+ avr_set_feature(env, AVR_FEATURE_BREAK);
+
+ avr_set_feature(env, AVR_FEATURE_2_BYTE_PC);
+ avr_set_feature(env, AVR_FEATURE_2_BYTE_SP);
+ avr_set_feature(env, AVR_FEATURE_RAMPZ);
+ avr_set_feature(env, AVR_FEATURE_ELPMX);
+ avr_set_feature(env, AVR_FEATURE_ELPM);
+ avr_set_feature(env, AVR_FEATURE_JMP_CALL);
+ avr_set_feature(env, AVR_FEATURE_LPMX);
+ avr_set_feature(env, AVR_FEATURE_MOVW);
+ avr_set_feature(env, AVR_FEATURE_MUL);
+ avr_set_feature(env, AVR_FEATURE_RMW);
+}
+
+static void avr_xmega5_initfn(Object *obj)
+{
+ AVRCPU *cpu = AVR_CPU(obj);
+ CPUAVRState *env = &cpu->env;
+
+ avr_set_feature(env, AVR_FEATURE_LPM);
+ avr_set_feature(env, AVR_FEATURE_IJMP_ICALL);
+ avr_set_feature(env, AVR_FEATURE_ADIW_SBIW);
+ avr_set_feature(env, AVR_FEATURE_SRAM);
+ avr_set_feature(env, AVR_FEATURE_BREAK);
+
+ avr_set_feature(env, AVR_FEATURE_2_BYTE_PC);
+ avr_set_feature(env, AVR_FEATURE_2_BYTE_SP);
+ avr_set_feature(env, AVR_FEATURE_RAMPD);
+ avr_set_feature(env, AVR_FEATURE_RAMPX);
+ avr_set_feature(env, AVR_FEATURE_RAMPY);
+ avr_set_feature(env, AVR_FEATURE_RAMPZ);
+ avr_set_feature(env, AVR_FEATURE_ELPMX);
+ avr_set_feature(env, AVR_FEATURE_ELPM);
+ avr_set_feature(env, AVR_FEATURE_JMP_CALL);
+ avr_set_feature(env, AVR_FEATURE_LPMX);
+ avr_set_feature(env, AVR_FEATURE_MOVW);
+ avr_set_feature(env, AVR_FEATURE_MUL);
+ avr_set_feature(env, AVR_FEATURE_RMW);
+}
+
+static void avr_xmega6_initfn(Object *obj)
+{
+ AVRCPU *cpu = AVR_CPU(obj);
+ CPUAVRState *env = &cpu->env;
+
+ avr_set_feature(env, AVR_FEATURE_LPM);
+ avr_set_feature(env, AVR_FEATURE_IJMP_ICALL);
+ avr_set_feature(env, AVR_FEATURE_ADIW_SBIW);
+ avr_set_feature(env, AVR_FEATURE_SRAM);
+ avr_set_feature(env, AVR_FEATURE_BREAK);
+
+ avr_set_feature(env, AVR_FEATURE_3_BYTE_PC);
+ avr_set_feature(env, AVR_FEATURE_2_BYTE_SP);
+ avr_set_feature(env, AVR_FEATURE_RAMPZ);
+ avr_set_feature(env, AVR_FEATURE_EIJMP_EICALL);
+ avr_set_feature(env, AVR_FEATURE_ELPMX);
+ avr_set_feature(env, AVR_FEATURE_ELPM);
+ avr_set_feature(env, AVR_FEATURE_JMP_CALL);
+ avr_set_feature(env, AVR_FEATURE_LPMX);
+ avr_set_feature(env, AVR_FEATURE_MOVW);
+ avr_set_feature(env, AVR_FEATURE_MUL);
+ avr_set_feature(env, AVR_FEATURE_RMW);
+}
+
+static void avr_xmega7_initfn(Object *obj)
+{
+ AVRCPU *cpu = AVR_CPU(obj);
+ CPUAVRState *env = &cpu->env;
+
+ avr_set_feature(env, AVR_FEATURE_LPM);
+ avr_set_feature(env, AVR_FEATURE_IJMP_ICALL);
+ avr_set_feature(env, AVR_FEATURE_ADIW_SBIW);
+ avr_set_feature(env, AVR_FEATURE_SRAM);
+ avr_set_feature(env, AVR_FEATURE_BREAK);
+
+ avr_set_feature(env, AVR_FEATURE_3_BYTE_PC);
+ avr_set_feature(env, AVR_FEATURE_2_BYTE_SP);
+ avr_set_feature(env, AVR_FEATURE_RAMPD);
+ avr_set_feature(env, AVR_FEATURE_RAMPX);
+ avr_set_feature(env, AVR_FEATURE_RAMPY);
+ avr_set_feature(env, AVR_FEATURE_RAMPZ);
+ avr_set_feature(env, AVR_FEATURE_EIJMP_EICALL);
+ avr_set_feature(env, AVR_FEATURE_ELPMX);
+ avr_set_feature(env, AVR_FEATURE_ELPM);
+ avr_set_feature(env, AVR_FEATURE_JMP_CALL);
+ avr_set_feature(env, AVR_FEATURE_LPMX);
+ avr_set_feature(env, AVR_FEATURE_MOVW);
+ avr_set_feature(env, AVR_FEATURE_MUL);
+ avr_set_feature(env, AVR_FEATURE_RMW);
+}
+
typedef struct AVRCPUInfo {
const char *name;
void (*initfn)(Object *obj);
} AVRCPUInfo;
static const AVRCPUInfo avr_cpus[] = {
+ {.name = "avr1", .initfn = avr_avr1_initfn},
+ {.name = "avr2", .initfn = avr_avr2_initfn},
+ {.name = "avr25", .initfn = avr_avr25_initfn},
+ {.name = "avr3", .initfn = avr_avr3_initfn},
+ {.name = "avr31", .initfn = avr_avr31_initfn},
+ {.name = "avr35", .initfn = avr_avr35_initfn},
+ {.name = "avr4", .initfn = avr_avr4_initfn},
+ {.name = "avr5", .initfn = avr_avr5_initfn},
+ {.name = "avr51", .initfn = avr_avr51_initfn},
+ {.name = "avr6", .initfn = avr_avr6_initfn},
+ {.name = "xmega2", .initfn = avr_xmega2_initfn},
+ {.name = "xmega4", .initfn = avr_xmega4_initfn},
+ {.name = "xmega5", .initfn = avr_xmega5_initfn},
+ {.name = "xmega6", .initfn = avr_xmega6_initfn},
+ {.name = "xmega7", .initfn = avr_xmega7_initfn},
};
static gint avr_cpu_list_compare(gconstpointer a, gconstpointer b)
diff --git a/target-avr/cpu.h b/target-avr/cpu.h
index 64a2cf9..fecf208 100644
--- a/target-avr/cpu.h
+++ b/target-avr/cpu.h
@@ -83,6 +83,42 @@
#define AVR_CPU_IO_REGS_LAST (AVR_CPU_IO_REGS_BASE + AVR_CPU_IO_REGS - 1)
#define AVR_EXT_IO_REGS_LAST (AVR_EXT_IO_REGS_BASE + AVR_EXT_IO_REGS - 1)
+enum avr_features {
+ AVR_FEATURE_SRAM,
+
+ AVR_FEATURE_1_BYTE_PC,
+ AVR_FEATURE_2_BYTE_PC,
+ AVR_FEATURE_3_BYTE_PC,
+
+ AVR_FEATURE_1_BYTE_SP,
+ AVR_FEATURE_2_BYTE_SP,
+
+ AVR_FEATURE_BREAK,
+ AVR_FEATURE_DES,
+ AVR_FEATURE_RMW, /* Read Modify Write - XCH LAC LAS LAT */
+
+ AVR_FEATURE_EIJMP_EICALL,
+ AVR_FEATURE_IJMP_ICALL,
+ AVR_FEATURE_JMP_CALL,
+
+ AVR_FEATURE_ADIW_SBIW,
+
+ AVR_FEATURE_SPM,
+ AVR_FEATURE_SPMX,
+
+ AVR_FEATURE_ELPMX,
+ AVR_FEATURE_ELPM,
+ AVR_FEATURE_LPMX,
+ AVR_FEATURE_LPM,
+
+ AVR_FEATURE_MOVW,
+ AVR_FEATURE_MUL,
+ AVR_FEATURE_RAMPD,
+ AVR_FEATURE_RAMPX,
+ AVR_FEATURE_RAMPY,
+ AVR_FEATURE_RAMPZ,
+};
+
typedef struct CPUAVRState CPUAVRState;
struct CPUAVRState {
@@ -109,10 +145,22 @@ struct CPUAVRState {
uint64_t intsrc; /* interrupt sources */
+ uint32_t features;
+
/* Those resources are used only in QEMU core */
CPU_COMMON
};
+static inline int avr_feature(CPUAVRState *env, int feature)
+{
+ return (env->features & (1U << feature)) != 0;
+}
+
+static inline void avr_set_feature(CPUAVRState *env, int feature)
+{
+ env->features |= (1U << feature);
+}
+
#define cpu_list avr_cpu_list
#define cpu_signal_handler cpu_avr_signal_handler
--
2.4.9 (Apple Git-60)
- [Qemu-devel] [PATCH v16 00/10] 8bit AVR cores, Michael Rolnik, 2016/08/17
- [Qemu-devel] [PATCH v16 01/10] target-avr: AVR cores support is added., Michael Rolnik, 2016/08/17
- [Qemu-devel] [PATCH v16 02/10] target-avr: adding AVR CPU features/flavors,
Michael Rolnik <=
- [Qemu-devel] [PATCH v16 03/10] target-avr: adding a sample AVR board, Michael Rolnik, 2016/08/17
- [Qemu-devel] [PATCH v16 04/10] target-avr: adding instructions encodings, Michael Rolnik, 2016/08/17
- [Qemu-devel] [PATCH v16 05/10] target-avr: adding AVR interrupt handling, Michael Rolnik, 2016/08/17
- [Qemu-devel] [PATCH v16 06/10] target-avr: adding helpers for IN, OUT, SLEEP, WBR & unsupported instructions, Michael Rolnik, 2016/08/17
- [Qemu-devel] [PATCH v16 07/10] target-avr: adding instruction translation, Michael Rolnik, 2016/08/17
- [Qemu-devel] [PATCH v16 08/10] target-avr: instruction decoder generator, Michael Rolnik, 2016/08/17
- [Qemu-devel] [PATCH v16 09/10] target-avr: adding instruction decoder, Michael Rolnik, 2016/08/17