linux/e2k: emulate /proc/cpuinfo
This commit is contained in:
parent
4c6f8ab7ce
commit
6e4ae247a7
|
@ -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 */
|
|
@ -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
|
/* v5+ has different stack layout and we need to shuffle registers
|
||||||
* for backward compatibility. */
|
* for backward compatibility. */
|
||||||
if (env->version >= 5) {
|
if (env->def.isa >= 5) {
|
||||||
int i, j;
|
int i, j;
|
||||||
bool to_ps = dst >= env->psp.base
|
bool to_ps = dst >= env->psp.base
|
||||||
&& dst < (env->psp.base + env->psp.size);
|
&& dst < (env->psp.base + env->psp.size);
|
||||||
|
|
|
@ -82,7 +82,7 @@ static void e2k_cpu_disas_set_info(CPUState *cs, disassemble_info *info)
|
||||||
E2KCPU *cpu = E2K_CPU(cs);
|
E2KCPU *cpu = E2K_CPU(cs);
|
||||||
CPUE2KState *env = &cpu->env;
|
CPUE2KState *env = &cpu->env;
|
||||||
|
|
||||||
info->mach = env->version * 3;
|
info->mach = env->def.isa * 3;
|
||||||
info->print_insn = print_insn_e2k;
|
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_E48C 13 /* Elbrus-48C FIXME: assumption */
|
||||||
#define MDL_E8V7 14 /* Elbrus-8v7 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, \
|
.name = NAME, \
|
||||||
.canonical_name = CANON, \
|
.canonical_name = CANON, \
|
||||||
|
.model_name = MODEL, \
|
||||||
.gdb_arch = GDB_ARCH, \
|
.gdb_arch = GDB_ARCH, \
|
||||||
.isa_version = ISET, \
|
.isa = ISET, \
|
||||||
.idr = IDR, \
|
.idr = IDR, \
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct e2k_def_t e2k_defs[] = {
|
static const struct e2k_def_t e2k_defs[] = {
|
||||||
CPU_MODEL(1, "elbrus-v1", "elbrus-v1", MDL_E3M, "MCST Elbrus"),
|
CPU_MODEL(1, "elbrus-v1", "elbrus-v1", MDL_E3M, "E3M", "MCST Elbrus"),
|
||||||
CPU_MODEL(2, "elbrus-v2", "elbrus-v2", MDL_ES, "MCST Elbrus-S"),
|
CPU_MODEL(2, "elbrus-v2", "elbrus-v2", MDL_ES, "ES", "MCST Elbrus-S"),
|
||||||
CPU_MODEL(3, "elbrus-v3", "elbrus-v3", MDL_E2S, "MCST Elbrus-4C"),
|
CPU_MODEL(3, "elbrus-v3", "elbrus-v3", MDL_E2S, "E2S", "MCST Elbrus-4C"),
|
||||||
CPU_MODEL(4, "elbrus-v4", "elbrus-v4", MDL_E8C, "MCST Elbrus-8C"),
|
CPU_MODEL(4, "elbrus-v4", "elbrus-v4", MDL_E8C, "E8C", "MCST Elbrus-8C"),
|
||||||
CPU_MODEL(5, "elbrus-v5", "elbrus-v5", MDL_E8C2, "MCST Elbrus-8C2"),
|
CPU_MODEL(5, "elbrus-v5", "elbrus-v5", MDL_E8C2, "E8C2", "MCST Elbrus-8C2"),
|
||||||
CPU_MODEL(6, "elbrus-v6", "elbrus-v6", MDL_E16C, "MCST Elbrus-16C"),
|
CPU_MODEL(6, "elbrus-v6", "elbrus-v6", MDL_E16C, "E16C", "MCST Elbrus-16C"),
|
||||||
CPU_MODEL(7, "elbrus-v7", "elbrus-v7", MDL_E48C, "MCST Elbrus-48C"),
|
CPU_MODEL(7, "elbrus-v7", "elbrus-v7", MDL_E48C, "E48C", "MCST Elbrus-48C"),
|
||||||
CPU_MODEL(1, "generic", "elbrus-v1", MDL_E3M, "MCST Elbrus"),
|
CPU_MODEL(1, "generic", "elbrus-v1", MDL_E3M, "E3M", "MCST Elbrus"),
|
||||||
CPU_MODEL(1, "elbrus", "elbrus-v1", MDL_E3M, "MCST Elbrus"),
|
CPU_MODEL(1, "elbrus", "elbrus-v1", MDL_E3M, "E3M", "MCST Elbrus"),
|
||||||
CPU_MODEL(1, "e3m", "elbrus-v1", MDL_E3M, "MCST Elbrus-3M1"),
|
CPU_MODEL(1, "e3m", "elbrus-v1", MDL_E3M, "E3M", "MCST Elbrus-3M1"),
|
||||||
CPU_MODEL(2, "elbrus-s", "elbrus-v2", MDL_ES, "MCST Elbrus-S"),
|
CPU_MODEL(2, "elbrus-s", "elbrus-v2", MDL_ES, "ES", "MCST Elbrus-S"),
|
||||||
CPU_MODEL(2, "e3s", "elbrus-v2", MDL_E3S, "MCST Elbrus-3S"),
|
CPU_MODEL(2, "e3s", "elbrus-v2", MDL_E3S, "E3S", "MCST Elbrus-3S"),
|
||||||
CPU_MODEL(2, "es2", "elbrus-v2", MDL_ES2, "MCST Elbrus-2C+ (Monocube)"),
|
CPU_MODEL(2, "es2", "elbrus-v2", MDL_ES2, "E2C+DSP", "MCST Elbrus-2C+ (Monocube)"),
|
||||||
CPU_MODEL(2, "e2cplus", "elbrus-v2", MDL_ES2, "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, "MCST Elbrus-2CM"),
|
CPU_MODEL(2, "e2cm", "elbrus-v2", MDL_ES2_NO_DSP, "E2C", "MCST Elbrus-2CM"),
|
||||||
CPU_MODEL(3, "e2s", "elbrus-v3", MDL_E2S, "MCST Elbrus-4C"),
|
CPU_MODEL(3, "e2s", "elbrus-v3", MDL_E2S, "E2S", "MCST Elbrus-4C"),
|
||||||
CPU_MODEL(3, "e4c", "elbrus-v3", MDL_E2S, "MCST Elbrus-4C"),
|
CPU_MODEL(3, "e4c", "elbrus-v3", MDL_E2S, "E2S", "MCST Elbrus-4C"),
|
||||||
CPU_MODEL(4, "e8c", "elbrus-8c", MDL_E8C, "MCST Elbrus-8C"),
|
CPU_MODEL(4, "e8c", "elbrus-8c", MDL_E8C, "E8C", "MCST Elbrus-8C"),
|
||||||
CPU_MODEL(4, "e1cplus", "elbrus-1c+", MDL_E1CP, "MCST Elbrus-1C+"),
|
CPU_MODEL(4, "e1cplus", "elbrus-1c+", MDL_E1CP, "E1CP", "MCST Elbrus-1C+"),
|
||||||
CPU_MODEL(5, "e8c2", "elbrus-v5", MDL_E8C2, "MCST Elbrus-8C2"),
|
CPU_MODEL(5, "e8c2", "elbrus-v5", MDL_E8C2, "E8C2", "MCST Elbrus-8C2"),
|
||||||
CPU_MODEL(6, "e16c", "elbrus-16c", MDL_E16C, "MCST Elbrus-16C"),
|
CPU_MODEL(6, "e16c", "elbrus-16c", MDL_E16C, "E16C", "MCST Elbrus-16C"),
|
||||||
CPU_MODEL(6, "e12c", "elbrus-12c", MDL_E12C, "MCST Elbrus-12C"),
|
CPU_MODEL(6, "e12c", "elbrus-12c", MDL_E12C, "E12C", "MCST Elbrus-12C"),
|
||||||
CPU_MODEL(6, "e2c3", "elbrus-2c3", MDL_E2C3, "MCST Elbrus-2C3"),
|
CPU_MODEL(6, "e2c3", "elbrus-2c3", MDL_E2C3, "E2C3", "MCST Elbrus-2C3"),
|
||||||
CPU_MODEL(7, "e48c", "elbrus-v7", MDL_E48C, "MCST Elbrus-48C"),
|
CPU_MODEL(7, "e48c", "elbrus-v7", MDL_E48C, "E48C", "MCST Elbrus-48C"),
|
||||||
CPU_MODEL(7, "e8v7", "elbrus-v7", MDL_E8V7, "MCST Elbrus-8v7"),
|
CPU_MODEL(7, "e8v7", "elbrus-v7", MDL_E8V7, "E8V7", "MCST Elbrus-8v7"),
|
||||||
};
|
};
|
||||||
|
|
||||||
static void e2k_cpu_set_pc(CPUState *cs, vaddr value)
|
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);
|
CPUState *cs = CPU(dev);
|
||||||
E2KCPUClass *ecc = E2K_CPU_GET_CLASS(dev);
|
E2KCPUClass *ecc = E2K_CPU_GET_CLASS(dev);
|
||||||
Error *local_err = NULL;
|
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);
|
cpu_exec_realizefn(cs, &local_err);
|
||||||
if (local_err != NULL) {
|
if (local_err != NULL) {
|
||||||
|
@ -349,7 +345,7 @@ void e2k_cpu_list(void)
|
||||||
qemu_printf("%12s (%-30s) ISA version: v%d\n",
|
qemu_printf("%12s (%-30s) ISA version: v%d\n",
|
||||||
e2k_defs[i].name,
|
e2k_defs[i].name,
|
||||||
e2k_defs[i].canonical_name,
|
e2k_defs[i].canonical_name,
|
||||||
e2k_defs[i].isa_version
|
e2k_defs[i].isa
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -422,8 +422,10 @@ typedef enum {
|
||||||
struct e2k_def_t {
|
struct e2k_def_t {
|
||||||
const char *name;
|
const char *name;
|
||||||
const char *canonical_name;
|
const char *canonical_name;
|
||||||
|
const char *model_name;
|
||||||
const char *gdb_arch;
|
const char *gdb_arch;
|
||||||
uint32_t isa_version;
|
/* ISA version */
|
||||||
|
uint32_t isa;
|
||||||
uint64_t idr;
|
uint64_t idr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -928,9 +930,6 @@ typedef struct CPUArchState {
|
||||||
/* Fields up to this point are cleared by a CPU reset */
|
/* Fields up to this point are cleared by a CPU reset */
|
||||||
struct {} end_reset_fields;
|
struct {} end_reset_fields;
|
||||||
|
|
||||||
uint64_t idr;
|
|
||||||
/* ISA version */
|
|
||||||
uint32_t version;
|
|
||||||
/* Force alop to preserve the destination register before writing to it.
|
/* Force alop to preserve the destination register before writing to it.
|
||||||
* Default: false */
|
* Default: false */
|
||||||
bool force_save_alc_dst;
|
bool force_save_alc_dst;
|
||||||
|
|
|
@ -293,7 +293,7 @@ static int gdb_get_v2(CPUState *cs, GByteArray *buf, int n)
|
||||||
|
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
/* idr */
|
/* idr */
|
||||||
return gdb_get_reg64(buf, env->idr);
|
return gdb_get_reg64(buf, env->def.idr);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -355,17 +355,17 @@ void e2k_cpu_register_gdb_regs_for_features(CPUState *cs)
|
||||||
E2KCPU *cpu = E2K_CPU(cs);
|
E2KCPU *cpu = E2K_CPU(cs);
|
||||||
CPUE2KState *env = &cpu->env;
|
CPUE2KState *env = &cpu->env;
|
||||||
|
|
||||||
if (env->version >= 2) {
|
if (env->def.isa >= 2) {
|
||||||
gdb_register_coprocessor(cs, gdb_get_v2, gdb_set_v2,
|
gdb_register_coprocessor(cs, gdb_get_v2, gdb_set_v2,
|
||||||
gdb_find_static_feature("e2k-v2.xml"), 574);
|
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_register_coprocessor(cs, gdb_get_v3, gdb_set_v3,
|
||||||
gdb_find_static_feature("e2k-v3.xml"), 575);
|
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_register_coprocessor(cs, gdb_get_v5, gdb_set_v5,
|
||||||
gdb_find_static_feature("e2k-v5.xml"), 576);
|
gdb_find_static_feature("e2k-v5.xml"), 576);
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,7 +53,7 @@ static void ps_spill(CPUE2KState *env, int n, bool fx)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (env->version >= 5) {
|
if (env->def.isa >= 5) {
|
||||||
for (int i = 0; i < n; i++, index += 16) {
|
for (int i = 0; i < n; i++, index += 16) {
|
||||||
ps_write(env, env->regs[i].lo, env->tags[i], index);
|
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);
|
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) {
|
for (int i = n; i-- > 0; index -= 16) {
|
||||||
if (fx) {
|
if (fx) {
|
||||||
env->regs[i].hi = ps_read(env, NULL, index - 8);
|
env->regs[i].hi = ps_read(env, NULL, index - 8);
|
||||||
|
|
|
@ -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);
|
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;
|
return 0;
|
||||||
} else if (page != as->last_page) {
|
} else if (page != as->last_page) {
|
||||||
void *ignore;
|
void *ignore;
|
||||||
|
|
|
@ -178,7 +178,7 @@ uint64_t HELPER(state_reg_get)(CPUE2KState *env, int index)
|
||||||
case SR_ILCR: return env_ilcr_get(env);
|
case SR_ILCR: return env_ilcr_get(env);
|
||||||
case SR_BR: return env_br_get(env);
|
case SR_BR: return env_br_get(env);
|
||||||
case SR_BGR: return env->bgr;
|
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_CLKR: return cpu_get_host_ticks(); // FIXME
|
||||||
case SR_RNDPR:
|
case SR_RNDPR:
|
||||||
case SR_SCLKR:
|
case SR_SCLKR:
|
||||||
|
|
|
@ -6710,7 +6710,7 @@ static void e2k_tr_init_disas_context(DisasContextBase *db, CPUState *cs)
|
||||||
E2KCPU *cpu = E2K_CPU(cs);
|
E2KCPU *cpu = E2K_CPU(cs);
|
||||||
CPUE2KState *env = &cpu->env;
|
CPUE2KState *env = &cpu->env;
|
||||||
|
|
||||||
ctx->version = env->version;
|
ctx->version = env->def.isa;
|
||||||
ctx->enable_tags = env->enable_tags;
|
ctx->enable_tags = env->enable_tags;
|
||||||
ctx->force_save_alc_dst = env->force_save_alc_dst;
|
ctx->force_save_alc_dst = env->force_save_alc_dst;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue