From 6e4ae247a7cea9730b10822244b1b22e61b6ca77 Mon Sep 17 00:00:00 2001 From: Denis Drakhnia Date: Mon, 1 Apr 2024 13:39:29 +0300 Subject: [PATCH] linux/e2k: emulate /proc/cpuinfo --- linux-user/e2k/target_proc.h | 39 ++++++++++++++++++++++ linux-user/syscall.c | 2 +- target/e2k/cpu.c | 64 +++++++++++++++++------------------- target/e2k/cpu.h | 7 ++-- target/e2k/gdbstub.c | 8 ++--- target/e2k/helper.c | 4 +-- target/e2k/helper_aau.c | 2 +- target/e2k/helper_int.c | 2 +- target/e2k/translate.c | 2 +- 9 files changed, 82 insertions(+), 48 deletions(-) diff --git a/linux-user/e2k/target_proc.h b/linux-user/e2k/target_proc.h index e69de29bb2..01b843c2f2 100644 --- a/linux-user/e2k/target_proc.h +++ b/linux-user/e2k/target_proc.h @@ -0,0 +1,39 @@ +/* + * E2K specific proc functions for linux-user + * + * SPDX-License-Identifier: GPL-2.0-only + */ + +#ifndef LINUX_USER_E2K_TARGET_PROC_H +#define LINUX_USER_E2K_TARGET_PROC_H + +static int open_cpuinfo(CPUArchState *cpu_env, int fd) +{ + CPUE2KState *env = &env_archcpu(cpu_env)->env; + int i, num_cpus, model, revision; + + model = extract32(env->def.idr, IDR_MDL_OFF, IDR_MDL_LEN); + revision = extract32(env->def.idr, IDR_REV_OFF, IDR_REV_LEN); + + num_cpus = sysconf(_SC_NPROCESSORS_ONLN); + for (i = 0; i < num_cpus; i++) { + dprintf(fd, "processor\t: %d\n", i); + dprintf(fd, "vendor_id\t: QEMU\n"); + dprintf(fd, "cpu family\t: %d\n", env->def.isa); + dprintf(fd, "model\t\t: %d\n", model); + dprintf(fd, "model name\t: %s\n", env->def.model_name); + dprintf(fd, "revision\t: %d\n\n", revision); + } + +#if 0 + dprintf(fd, "cache0\t\t: level=1 type=Instruction scope=Private size=128K line_size=256 associativity=4\n"); + dprintf(fd, "cache1\t\t: level=1 type=Data scope=Private size=64K line_size=32 associativity=4\n"); + dprintf(fd, "cache2\t\t: level=2 type=Unified scope=Private size=512K line_size=64 associativity=4\n"); + dprintf(fd, "cache3\t\t: level=3 type=Unified scope=Shared size=16384K line_size=64 associativity=16\n"); +#endif + + return 0; +} +#define HAVE_ARCH_PROC_CPUINFO + +#endif /* LINUX_USER_E2K_TARGET_PROC_H */ diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 5131c3a5d2..6284fef6b6 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -7169,7 +7169,7 @@ static abi_long copy_procedure_stack(CPUE2KState *env, abi_ulong dst, /* v5+ has different stack layout and we need to shuffle registers * for backward compatibility. */ - if (env->version >= 5) { + if (env->def.isa >= 5) { int i, j; bool to_ps = dst >= env->psp.base && dst < (env->psp.base + env->psp.size); diff --git a/target/e2k/cpu.c b/target/e2k/cpu.c index 2867865328..2e935cdf44 100644 --- a/target/e2k/cpu.c +++ b/target/e2k/cpu.c @@ -82,7 +82,7 @@ static void e2k_cpu_disas_set_info(CPUState *cs, disassemble_info *info) E2KCPU *cpu = E2K_CPU(cs); CPUE2KState *env = &cpu->env; - info->mach = env->version * 3; + info->mach = env->def.isa * 3; info->print_insn = print_insn_e2k; } @@ -105,41 +105,42 @@ static void e2k_cpu_disas_set_info(CPUState *cs, disassemble_info *info) #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) \ +#define CPU_MODEL(ISET, NAME, GDB_ARCH, IDR, MODEL, CANON) \ { \ .name = NAME, \ .canonical_name = CANON, \ + .model_name = MODEL, \ .gdb_arch = GDB_ARCH, \ - .isa_version = ISET, \ + .isa = ISET, \ .idr = IDR, \ } static const struct e2k_def_t e2k_defs[] = { - 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"), + CPU_MODEL(1, "elbrus-v1", "elbrus-v1", MDL_E3M, "E3M", "MCST Elbrus"), + CPU_MODEL(2, "elbrus-v2", "elbrus-v2", MDL_ES, "ES", "MCST Elbrus-S"), + CPU_MODEL(3, "elbrus-v3", "elbrus-v3", MDL_E2S, "E2S", "MCST Elbrus-4C"), + CPU_MODEL(4, "elbrus-v4", "elbrus-v4", MDL_E8C, "E8C", "MCST Elbrus-8C"), + CPU_MODEL(5, "elbrus-v5", "elbrus-v5", MDL_E8C2, "E8C2", "MCST Elbrus-8C2"), + CPU_MODEL(6, "elbrus-v6", "elbrus-v6", MDL_E16C, "E16C", "MCST Elbrus-16C"), + CPU_MODEL(7, "elbrus-v7", "elbrus-v7", MDL_E48C, "E48C", "MCST Elbrus-48C"), + CPU_MODEL(1, "generic", "elbrus-v1", MDL_E3M, "E3M", "MCST Elbrus"), + CPU_MODEL(1, "elbrus", "elbrus-v1", MDL_E3M, "E3M", "MCST Elbrus"), + CPU_MODEL(1, "e3m", "elbrus-v1", MDL_E3M, "E3M", "MCST Elbrus-3M1"), + CPU_MODEL(2, "elbrus-s", "elbrus-v2", MDL_ES, "ES", "MCST Elbrus-S"), + CPU_MODEL(2, "e3s", "elbrus-v2", MDL_E3S, "E3S", "MCST Elbrus-3S"), + CPU_MODEL(2, "es2", "elbrus-v2", MDL_ES2, "E2C+DSP", "MCST Elbrus-2C+ (Monocube)"), + CPU_MODEL(2, "e2cplus", "elbrus-v2", MDL_ES2, "E2C+DSP", "MCST Elbrus-2C+ (Monocube)"), + CPU_MODEL(2, "e2cm", "elbrus-v2", MDL_ES2_NO_DSP, "E2C", "MCST Elbrus-2CM"), + CPU_MODEL(3, "e2s", "elbrus-v3", MDL_E2S, "E2S", "MCST Elbrus-4C"), + CPU_MODEL(3, "e4c", "elbrus-v3", MDL_E2S, "E2S", "MCST Elbrus-4C"), + CPU_MODEL(4, "e8c", "elbrus-8c", MDL_E8C, "E8C", "MCST Elbrus-8C"), + CPU_MODEL(4, "e1cplus", "elbrus-1c+", MDL_E1CP, "E1CP", "MCST Elbrus-1C+"), + CPU_MODEL(5, "e8c2", "elbrus-v5", MDL_E8C2, "E8C2", "MCST Elbrus-8C2"), + CPU_MODEL(6, "e16c", "elbrus-16c", MDL_E16C, "E16C", "MCST Elbrus-16C"), + CPU_MODEL(6, "e12c", "elbrus-12c", MDL_E12C, "E12C", "MCST Elbrus-12C"), + CPU_MODEL(6, "e2c3", "elbrus-2c3", MDL_E2C3, "E2C3", "MCST Elbrus-2C3"), + CPU_MODEL(7, "e48c", "elbrus-v7", MDL_E48C, "E48C", "MCST Elbrus-48C"), + CPU_MODEL(7, "e8v7", "elbrus-v7", MDL_E8V7, "E8V7", "MCST Elbrus-8v7"), }; static void e2k_cpu_set_pc(CPUState *cs, vaddr value) @@ -213,11 +214,6 @@ static void e2k_cpu_realizefn(DeviceState *dev, Error **errp) CPUState *cs = CPU(dev); E2KCPUClass *ecc = E2K_CPU_GET_CLASS(dev); Error *local_err = NULL; - 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); if (local_err != NULL) { @@ -349,7 +345,7 @@ void e2k_cpu_list(void) qemu_printf("%12s (%-30s) ISA version: v%d\n", e2k_defs[i].name, e2k_defs[i].canonical_name, - e2k_defs[i].isa_version + e2k_defs[i].isa ); } diff --git a/target/e2k/cpu.h b/target/e2k/cpu.h index f76d96673f..93977e0bed 100644 --- a/target/e2k/cpu.h +++ b/target/e2k/cpu.h @@ -422,8 +422,10 @@ typedef enum { struct e2k_def_t { const char *name; const char *canonical_name; + const char *model_name; const char *gdb_arch; - uint32_t isa_version; + /* ISA version */ + uint32_t isa; uint64_t idr; }; @@ -928,9 +930,6 @@ 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. * Default: false */ bool force_save_alc_dst; diff --git a/target/e2k/gdbstub.c b/target/e2k/gdbstub.c index 49a03e7005..b817523b73 100644 --- a/target/e2k/gdbstub.c +++ b/target/e2k/gdbstub.c @@ -293,7 +293,7 @@ static int gdb_get_v2(CPUState *cs, GByteArray *buf, int n) if (n == 0) { /* idr */ - return gdb_get_reg64(buf, env->idr); + return gdb_get_reg64(buf, env->def.idr); } return 0; @@ -355,17 +355,17 @@ void e2k_cpu_register_gdb_regs_for_features(CPUState *cs) E2KCPU *cpu = E2K_CPU(cs); CPUE2KState *env = &cpu->env; - if (env->version >= 2) { + if (env->def.isa >= 2) { gdb_register_coprocessor(cs, gdb_get_v2, gdb_set_v2, gdb_find_static_feature("e2k-v2.xml"), 574); } - if (env->version >= 3) { + if (env->def.isa >= 3) { gdb_register_coprocessor(cs, gdb_get_v3, gdb_set_v3, gdb_find_static_feature("e2k-v3.xml"), 575); } - if (env->version >= 5) { + if (env->def.isa >= 5) { gdb_register_coprocessor(cs, gdb_get_v5, gdb_set_v5, gdb_find_static_feature("e2k-v5.xml"), 576); } diff --git a/target/e2k/helper.c b/target/e2k/helper.c index c48300b9ff..357dac39c5 100644 --- a/target/e2k/helper.c +++ b/target/e2k/helper.c @@ -53,7 +53,7 @@ static void ps_spill(CPUE2KState *env, int n, bool fx) } #endif - if (env->version >= 5) { + if (env->def.isa >= 5) { for (int i = 0; i < n; i++, index += 16) { ps_write(env, env->regs[i].lo, env->tags[i], index); @@ -87,7 +87,7 @@ static void ps_fill(CPUE2KState *env, int n, bool fx) raise_exception(env, E2K_EXCP_PROC_STACK_BOUNDS); } - if (env->version >= 5) { + if (env->def.isa >= 5) { for (int i = n; i-- > 0; index -= 16) { if (fx) { env->regs[i].hi = ps_read(env, NULL, index - 8); diff --git a/target/e2k/helper_aau.c b/target/e2k/helper_aau.c index 4d6e61ff7b..cc5bea9504 100644 --- a/target/e2k/helper_aau.c +++ b/target/e2k/helper_aau.c @@ -66,7 +66,7 @@ target_ulong HELPER(mova_ptr)(CPUE2KState *env, int chan, int area, int ind, helper_raise_exception(env, E2K_EXCP_ILLEGAL_OPCODE); } - if ((env->version <= 4 || (env->version == 5 && size == 16)) && addr & (size - 1)) { + if ((env->def.isa <= 4 || (env->def.isa == 5 && size == 16)) && addr & (size - 1)) { return 0; } else if (page != as->last_page) { void *ignore; diff --git a/target/e2k/helper_int.c b/target/e2k/helper_int.c index 2dbea5e372..2d260a90d1 100644 --- a/target/e2k/helper_int.c +++ b/target/e2k/helper_int.c @@ -178,7 +178,7 @@ uint64_t HELPER(state_reg_get)(CPUE2KState *env, int index) case SR_ILCR: return env_ilcr_get(env); case SR_BR: return env_br_get(env); case SR_BGR: return env->bgr; - case SR_IDR: return env->idr; + case SR_IDR: return env->def.idr; case SR_CLKR: return cpu_get_host_ticks(); // FIXME case SR_RNDPR: case SR_SCLKR: diff --git a/target/e2k/translate.c b/target/e2k/translate.c index 22e52b52ed..ea70705a00 100644 --- a/target/e2k/translate.c +++ b/target/e2k/translate.c @@ -6710,7 +6710,7 @@ static void e2k_tr_init_disas_context(DisasContextBase *db, CPUState *cs) E2KCPU *cpu = E2K_CPU(cs); CPUE2KState *env = &cpu->env; - ctx->version = env->version; + ctx->version = env->def.isa; ctx->enable_tags = env->enable_tags; ctx->force_save_alc_dst = env->force_save_alc_dst; }