[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH RFC v19 02/13] target-avr: adding AVR CPU features/f
From: |
Michael Rolnik |
Subject: |
[Qemu-devel] [PATCH RFC v19 02/13] target-avr: adding AVR CPU features/flavors |
Date: |
Thu, 8 Jun 2017 21:49:37 +0300 |
Signed-off-by: Michael Rolnik <address@hidden>
Message-Id: <address@hidden>
Signed-off-by: Richard Henderson <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 af307d3418..2922709a9c 100644
--- a/target/avr/cpu.c
+++ b/target/avr/cpu.c
@@ -197,12 +197,323 @@ static void avr_cpu_class_init(ObjectClass *oc, void
*data)
cc->gdb_num_core_regs = 35;
}
+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 fb05216ff5..54dc58c0df 100644
--- a/target/avr/cpu.h
+++ b/target/avr/cpu.h
@@ -78,6 +78,42 @@
#define AVR_CPU_REGS_LAST (AVR_CPU_REGS_BASE + AVR_CPU_REGS - 1)
#define AVR_CPU_IO_REGS_LAST (AVR_CPU_IO_REGS_BASE + AVR_CPU_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 {
@@ -104,10 +140,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.11.0 (Apple Git-81)
- [Qemu-devel] [PATCH RFC v19 00/13] QEMU AVR 8 bit cores, Michael Rolnik, 2017/06/08
- [Qemu-devel] [PATCH RFC v19 02/13] target-avr: adding AVR CPU features/flavors,
Michael Rolnik <=
- [Qemu-devel] [PATCH RFC v19 03/13] target-avr: adding a sample AVR board, Michael Rolnik, 2017/06/08
- [Qemu-devel] [PATCH RFC v19 04/13] target-avr: adding instructions encodings, Michael Rolnik, 2017/06/08
- [Qemu-devel] [PATCH RFC v19 05/13] target-avr: adding AVR interrupt handling, Michael Rolnik, 2017/06/08
- [Qemu-devel] [PATCH RFC v19 06/13] target-avr: adding helpers for IN, OUT, SLEEP, WBR & unsupported instructions, Michael Rolnik, 2017/06/08
- [Qemu-devel] [PATCH RFC v19 09/13] target-avr: adding instruction decoder, Michael Rolnik, 2017/06/08