linux/e2k: emulate /proc/cpuinfo

This commit is contained in:
Denis Drakhnia 2024-04-01 13:39:29 +03:00
parent 4c6f8ab7ce
commit 6e4ae247a7
9 changed files with 82 additions and 48 deletions

View File

@ -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 */

View File

@ -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);

View File

@ -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
);
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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);

View File

@ -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;

View File

@ -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:

View File

@ -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;
}