[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v14 2/9] target-avr: adding AVR CPU features/flavors
From: |
Michael Rolnik |
Subject: |
[Qemu-devel] [PATCH v14 2/9] target-avr: adding AVR CPU features/flavors |
Date: |
Fri, 29 Jul 2016 18:32:18 +0300 |
Signed-off-by: Michael Rolnik <address@hidden>
---
target-avr/cpu.c | 319 +++++++++++++++++++++++++++++++++++++++++++++++++--
target-avr/cpu.h | 52 ++++++++-
target-avr/machine.c | 28 ++---
3 files changed, 373 insertions(+), 26 deletions(-)
diff --git a/target-avr/cpu.c b/target-avr/cpu.c
index c5ee2e9..fa15727 100644
--- a/target-avr/cpu.c
+++ b/target-avr/cpu.c
@@ -203,9 +203,300 @@ static void avr_cpu_class_init(ObjectClass *oc, void
*data)
dc->cannot_destroy_with_object_finalize_yet = true;
}
-static void avr_any_initfn(Object *obj)
+static void avr_avr1_initfn(Object *obj)
{
- /* Set cpu feature flags */
+ 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 {
@@ -214,7 +505,21 @@ typedef struct AVRCPUInfo {
} AVRCPUInfo;
static const AVRCPUInfo avr_cpus[] = {
- { .name = "any", .initfn = avr_any_initfn },
+ {.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)
@@ -226,13 +531,7 @@ static gint avr_cpu_list_compare(gconstpointer a,
gconstpointer b)
name_a = object_class_get_name(class_a);
name_b = object_class_get_name(class_b);
- if (strcmp(name_a, "any-" TYPE_AVR_CPU) == 0) {
- return 1;
- } else if (strcmp(name_b, "any-" TYPE_AVR_CPU) == 0) {
- return -1;
- } else {
- return strcmp(name_a, name_b);
- }
+ return strcmp(name_a, name_b);
}
static void avr_cpu_list_entry(gpointer data, gpointer user_data)
diff --git a/target-avr/cpu.h b/target-avr/cpu.h
index 0cff5f7..9ef8c41 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 {
@@ -111,12 +147,24 @@ struct CPUAVRState {
uint64_t intsrc; /* interrupt sources */
+ uint32_t features;
+
/* Those resources are used only in QEMU core */
CPU_COMMON
};
-#define cpu_list avr_cpu_list
-#define cpu_signal_handler cpu_avr_signal_handler
+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
#include "exec/cpu-all.h"
#include "cpu-qom.h"
diff --git a/target-avr/machine.c b/target-avr/machine.c
index 9f20aed..2b005cc 100644
--- a/target-avr/machine.c
+++ b/target-avr/machine.c
@@ -44,8 +44,8 @@ static void put_sreg(QEMUFile *f, void *opaque, size_t size)
static const VMStateInfo vms_sreg = {
.name = "sreg",
- .get = get_sreg,
- .put = put_sreg,
+ .get = get_sreg,
+ .put = put_sreg,
};
static int get_segment(QEMUFile *f, void *opaque, size_t size)
@@ -68,33 +68,33 @@ static void put_segment(QEMUFile *f, void *opaque, size_t
size)
static const VMStateInfo vms_rampD = {
.name = "rampD",
- .get = get_segment,
- .put = put_segment,
+ .get = get_segment,
+ .put = put_segment,
};
static const VMStateInfo vms_rampX = {
.name = "rampX",
- .get = get_segment,
- .put = put_segment,
+ .get = get_segment,
+ .put = put_segment,
};
static const VMStateInfo vms_rampY = {
.name = "rampY",
- .get = get_segment,
- .put = put_segment,
+ .get = get_segment,
+ .put = put_segment,
};
static const VMStateInfo vms_rampZ = {
.name = "rampZ",
- .get = get_segment,
- .put = put_segment,
+ .get = get_segment,
+ .put = put_segment,
};
static const VMStateInfo vms_eind = {
.name = "eind",
- .get = get_segment,
- .put = put_segment,
+ .get = get_segment,
+ .put = put_segment,
};
const VMStateDescription vms_avr_cpu = {
- .name = "cpu",
- .version_id = 0,
+ .name = "cpu",
+ .version_id = 0,
.minimum_version_id = 0,
.fields = (VMStateField[]) {
VMSTATE_UINT32(env.pc_w, AVRCPU),
--
2.4.9 (Apple Git-60)
- [Qemu-devel] [PATCH v14 0/9] 8bit AVR cores, Michael Rolnik, 2016/07/29
- [Qemu-devel] [PATCH v14 2/9] target-avr: adding AVR CPU features/flavors,
Michael Rolnik <=
- [Qemu-devel] [PATCH v14 3/9] target-avr: adding a sample AVR board, Michael Rolnik, 2016/07/29
- [Qemu-devel] [PATCH v14 1/9] target-avr: AVR cores support is added., Michael Rolnik, 2016/07/29
- [Qemu-devel] [PATCH v14 5/9] target-avr: adding AVR interrupt handling, Michael Rolnik, 2016/07/29
- [Qemu-devel] [PATCH v14 4/9] target-avr: adding instructions encodings, Michael Rolnik, 2016/07/29
- [Qemu-devel] [PATCH v14 6/9] target-avr: adding helpers for IN, OUT, SLEEP, WBR & unsupported instructions, Michael Rolnik, 2016/07/29
- [Qemu-devel] [PATCH v14 8/9] target-avr: instruction decoder generator, Michael Rolnik, 2016/07/29
- [Qemu-devel] [PATCH v14 7/9] target-avr: adding instruction translation, Michael Rolnik, 2016/07/29
- [Qemu-devel] [PATCH v14 9/9] target-avr: adding instruction decoder, Michael Rolnik, 2016/07/29