From 3d824320ba604f04522b890fbb6f84cf390cff50 Mon Sep 17 00:00:00 2001 From: Denis Drakhnia Date: Tue, 9 Jan 2024 21:16:49 +0200 Subject: [PATCH] e2k: add more cpu models and set idr.mdl --- linux-user/e2k/cpu_loop.c | 17 +++++--- linux-user/e2k/target_elf.h | 10 +++++ target/e2k/cpu.c | 87 ++++++++++++++++++++++--------------- target/e2k/cpu.h | 3 +- 4 files changed, 77 insertions(+), 40 deletions(-) diff --git a/linux-user/e2k/cpu_loop.c b/linux-user/e2k/cpu_loop.c index af490cfb3d..7ade963f77 100644 --- a/linux-user/e2k/cpu_loop.c +++ b/linux-user/e2k/cpu_loop.c @@ -204,13 +204,20 @@ const char *cpu_get_model(uint32_t eflags) /* TODO: can't check for EM_E2K_OLD flags because e_machine isn't saved anywhere... */ switch(machine) { - case E2K_MACH_EV2: name = "e2c+"; break; - case E2K_MACH_EV3: name = "e2s"; break; + case E2K_MACH_EV1: name = "elbrus-v1"; break; + case E2K_MACH_EV2: name = "elbrus-v2"; break; + case E2K_MACH_EV3: name = "elbrus-v3"; break; case E2K_MACH_1CPLUS: case E2K_MACH_8C: - case E2K_MACH_EV4: name = "e8c"; break; - case E2K_MACH_EV5: name = "e8c2"; break; - case E2K_MACH_EV6: name = "e16c"; break; + case E2K_MACH_EV4: name = "elbrus-v4"; break; + case E2K_MACH_EV5: name = "elbrus-v5"; break; + case E2K_MACH_12C: + case E2K_MACH_16C: + case E2K_MACH_2C3: + case E2K_MACH_EV6: name = "elbrus-v6"; break; + case E2K_MACH_48C: + case E2K_MACH_8V7: + case E2K_MACH_EV7: name = "elbrus-v7"; break; } return name; diff --git a/linux-user/e2k/target_elf.h b/linux-user/e2k/target_elf.h index 8004f69f19..a94c215a51 100644 --- a/linux-user/e2k/target_elf.h +++ b/linux-user/e2k/target_elf.h @@ -17,11 +17,21 @@ #define E2K_MACH_EV4 4 #define E2K_MACH_EV5 5 #define E2K_MACH_EV6 6 +#define E2K_MACH_EV7 7 /* elbrus-v4 based processors */ #define E2K_MACH_8C 19 #define E2K_MACH_1CPLUS 20 +/* elbrus-v6 based processors */ +#define E2K_MACH_12C 21 +#define E2K_MACH_16C 22 +#define E2K_MACH_2C3 23 + +/* elbrus-v7 based processors */ +#define E2K_MACH_48C 24 +#define E2K_MACH_8V7 25 + const char *cpu_get_model(uint32_t eflags); #endif /* E2K_TARGET_ELF_H */ diff --git a/target/e2k/cpu.c b/target/e2k/cpu.c index 0e2d4d9e22..b6bc847810 100644 --- a/target/e2k/cpu.c +++ b/target/e2k/cpu.c @@ -61,9 +61,6 @@ static void e2k_cpu_reset(DeviceState *dev) e2k_update_fp_status(env); e2k_update_fx_status(env); - // FIXME: testing - env->idr = 0x3a207; /* mimic 8c */ - // FIXME: correct values env->psp.base = 0x810000; env->psp.size = 0x100000; @@ -100,37 +97,58 @@ static void e2k_cpu_disas_set_info(CPUState *cs, disassemble_info *info) /* https://www.altlinux.org/Модели_процессоров_Эльбрус */ #define DEFAULT_CPU_MODEL "e8c" + +#define MDL_E3M 0 /* Elbrus */ +#define MDL_ES 1 /* Elbrus-S */ +#define MDL_E3S 2 /* Elbrus-3S */ +#define MDL_E2S 3 /* Elbrus-4C */ +#define MDL_ES2 4 /* Elbrus-2C+ */ +#define MDL_RESERVED 5 /* unknown "reserved" processor */ +#define MDL_ES2_NO_DSP 6 /* Elbrus-2CM */ +#define MDL_E8C 7 /* Elbrus-8C */ +#define MDL_E1CP 8 /* Elbrus-1C+ */ +#define MDL_E8C2 9 /* Elbrus-8C2 */ +#define MDL_E12C 10 /* Elbrus-12C */ +#define MDL_E16C 11 /* Elbrus-16C */ +#define MDL_E2C3 12 /* Elbrus-2C3 */ +#define MDL_E48C 13 /* Elbrus-48C FIXME: assumption */ +#define MDL_E8V7 14 /* Elbrus-8v7 FIXME: assumption */ + +#define CPU_MODEL(ISET, NAME, GDB_ARCH, IDR, CANON) \ + { \ + .name = NAME, \ + .canonical_name = CANON, \ + .gdb_arch = GDB_ARCH, \ + .isa_version = ISET, \ + .idr = IDR, \ + } + static const struct e2k_def_t e2k_defs[] = { - { - .name = "e2cplus", /* however it may work better */ - .canonical_name = "MCST Elbrus 2C+ (Monocube)", - .gdb_arch = "elbrus-v2", - .isa_version = 2, - }, - { - .name = "e2s", - .canonical_name = "MCST Elbrus 4C", - .gdb_arch = "elbrus-v3", - .isa_version = 3, - }, - { - .name = "e8c", /* default choice for system */ - .canonical_name = "MCST Elbrus 8C", - .gdb_arch = "elbrus-8c", - .isa_version = 4, - }, - { - .name = "e8c2", - .canonical_name = "MCST Elbrus 8CB", - .gdb_arch = "elbrus-v5", - .isa_version = 5, - }, - { - .name = "e16c", - .canonical_name = "MCST Elbrus 16C", - .gdb_arch = "elbrus-v6", - .isa_version = 6, - }, + CPU_MODEL(1, "elbrus-v1", "elbrus-v1", MDL_E3M, "MCST Elbrus"), + CPU_MODEL(2, "elbrus-v2", "elbrus-v2", MDL_ES, "MCST Elbrus-S"), + CPU_MODEL(3, "elbrus-v3", "elbrus-v3", MDL_E2S, "MCST Elbrus-4C"), + CPU_MODEL(4, "elbrus-v4", "elbrus-v4", MDL_E8C, "MCST Elbrus-8C"), + CPU_MODEL(5, "elbrus-v5", "elbrus-v5", MDL_E8C2, "MCST Elbrus-8C2"), + CPU_MODEL(6, "elbrus-v6", "elbrus-v6", MDL_E16C, "MCST Elbrus-16C"), + CPU_MODEL(7, "elbrus-v7", "elbrus-v7", MDL_E48C, "MCST Elbrus-48C"), + CPU_MODEL(1, "generic", "elbrus-v1", MDL_E3M, "MCST Elbrus"), + CPU_MODEL(1, "elbrus", "elbrus-v1", MDL_E3M, "MCST Elbrus"), + CPU_MODEL(1, "e3m", "elbrus-v1", MDL_E3M, "MCST Elbrus-3M1"), + CPU_MODEL(2, "elbrus-s", "elbrus-v2", MDL_ES, "MCST Elbrus-S"), + CPU_MODEL(2, "e3s", "elbrus-v2", MDL_E3S, "MCST Elbrus-3S"), + CPU_MODEL(2, "es2", "elbrus-v2", MDL_ES2, "MCST Elbrus-2C+ (Monocube)"), + CPU_MODEL(2, "e2cplus", "elbrus-v2", MDL_ES2, "MCST Elbrus-2C+ (Monocube)"), + CPU_MODEL(2, "e2cm", "elbrus-v2", MDL_ES2_NO_DSP, "MCST Elbrus-2CM"), + CPU_MODEL(3, "e2s", "elbrus-v3", MDL_E2S, "MCST Elbrus-4C"), + CPU_MODEL(3, "e4c", "elbrus-v3", MDL_E2S, "MCST Elbrus-4C"), + CPU_MODEL(4, "e8c", "elbrus-8c", MDL_E8C, "MCST Elbrus-8C"), + CPU_MODEL(4, "e1cplus", "elbrus-1c+", MDL_E1CP, "MCST Elbrus-1C+"), + CPU_MODEL(5, "e8c2", "elbrus-v5", MDL_E8C2, "MCST Elbrus-8C2"), + CPU_MODEL(6, "e16c", "elbrus-16c", MDL_E16C, "MCST Elbrus-16C"), + CPU_MODEL(6, "e12c", "elbrus-12c", MDL_E12C, "MCST Elbrus-12C"), + CPU_MODEL(6, "e2c3", "elbrus-2c3", MDL_E2C3, "MCST Elbrus-2C3"), + CPU_MODEL(7, "e48c", "elbrus-v7", MDL_E48C, "MCST Elbrus-48C"), + CPU_MODEL(7, "e8v7", "elbrus-v7", MDL_E8V7, "MCST Elbrus-8v7"), }; static void e2k_cpu_set_pc(CPUState *cs, vaddr value) @@ -207,6 +225,7 @@ static void e2k_cpu_realizefn(DeviceState *dev, Error **errp) E2KCPU *cpu = E2K_CPU(dev); CPUE2KState *env = &cpu->env; + env->idr = env->def.idr; env->version = env->def.isa_version; cpu_exec_realizefn(cs, &local_err); @@ -336,7 +355,7 @@ void e2k_cpu_list(void) size_t len = 0; for (i = 0; i < ARRAY_SIZE(e2k_defs); i++) { - qemu_printf("%6s (%-30s) ISA version: v%d\n", + qemu_printf("%12s (%-30s) ISA version: v%d\n", e2k_defs[i].name, e2k_defs[i].canonical_name, e2k_defs[i].isa_version diff --git a/target/e2k/cpu.h b/target/e2k/cpu.h index 7e74dd9b8c..c3c16382ba 100644 --- a/target/e2k/cpu.h +++ b/target/e2k/cpu.h @@ -400,6 +400,7 @@ struct e2k_def_t { const char *canonical_name; const char *gdb_arch; uint32_t isa_version; + uint64_t idr; }; typedef struct { @@ -837,7 +838,6 @@ typedef struct CPUArchState { uint32_t cuir; /* System Register */ uint64_t osr0; - uint64_t idr; uint64_t core_mode; /* Packed Floating Point Flag Register (PFPFR) */ @@ -893,6 +893,7 @@ typedef struct CPUArchState { /* Fields up to this point are cleared by a CPU reset */ struct {} end_reset_fields; + uint64_t idr; /* ISA version */ uint32_t version; /* Force alop to preserve the destination register before writing to it.