e2k: implement detecting ISA version by ELF flags, throw an error for protected mode and x86 recompiled binaries for now
This commit is contained in:
parent
8c3fd2ef2d
commit
3a3878c337
|
@ -21,6 +21,7 @@
|
|||
#include "qemu-common.h"
|
||||
#include "qemu.h"
|
||||
#include "cpu_loop-common.h"
|
||||
#include "target_elf.h"
|
||||
|
||||
void helper_return(CPUE2KState *env);
|
||||
|
||||
|
@ -118,15 +119,50 @@ void cpu_loop(CPUE2KState *env)
|
|||
|
||||
void target_cpu_copy_regs(CPUE2KState *env, struct target_pt_regs *regs)
|
||||
{
|
||||
CPUState *cpu = env_cpu(env);
|
||||
TaskState *ts = cpu->opaque;
|
||||
struct image_info *info = ts->info;
|
||||
uint32_t eflags = info->elf_flags;
|
||||
|
||||
env->ip = regs->ip;
|
||||
env->pcsp = regs->pcsp;
|
||||
env->psp = regs->psp;
|
||||
env->usd.lo = regs->usd_lo;
|
||||
env->usd.hi = regs->usd_hi;
|
||||
env->sbr = regs->sbr;
|
||||
env->elf_flags = info->elf_flags;
|
||||
|
||||
if (eflags & E2K_ELF_PM) {
|
||||
fprintf(stderr, "Protected mode is unsupported\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (eflags & E2K_ELF_X86APP) {
|
||||
fprintf(stderr, "x86 recompiler is unsupported\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
e2k_break_save_state(env);
|
||||
|
||||
env->pcs_base = env->pcsp.base;
|
||||
env->ps_base = env->psp.base;
|
||||
}
|
||||
|
||||
const char *cpu_get_model(uint32_t eflags)
|
||||
{
|
||||
const char *name = "any";
|
||||
uint32_t machine = E2K_ELF_MACH(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_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;
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,27 @@
|
|||
#ifndef E2K_TARGET_ELF_H
|
||||
#define E2K_TARGET_ELF_H
|
||||
static inline const char *cpu_get_model(uint32_t eflags)
|
||||
{
|
||||
return "any";
|
||||
}
|
||||
|
||||
#define E2K_ELF_IPD_MASK ((1U << 1)|(1U << 0))
|
||||
#define E2K_ELF_X86APP (1U << 2)
|
||||
#define E2K_ELF_4MB_PAGES (1U << 3)
|
||||
#define E2K_ELF_INCOMPAT (1U << 4)
|
||||
#define E2K_ELF_PM (1U << 5)
|
||||
|
||||
#define E2K_ELF_OLD_MACH(x) (((x) >> 28) & 7)
|
||||
#define E2K_ELF_MACH(x) (((x) >> 24) & 255)
|
||||
|
||||
#define E2K_MACH_BASE 0
|
||||
#define E2K_MACH_EV1 1
|
||||
#define E2K_MACH_EV2 2
|
||||
#define E2K_MACH_EV3 3
|
||||
#define E2K_MACH_EV4 4
|
||||
#define E2K_MACH_EV5 5
|
||||
#define E2K_MACH_EV6 6
|
||||
|
||||
/* elbrus-v4 based processors */
|
||||
#define E2K_MACH_8C 19
|
||||
#define E2K_MACH_1CPLUS 20
|
||||
|
||||
const char *cpu_get_model(uint32_t eflags);
|
||||
|
||||
#endif /* E2K_TARGET_ELF_H */
|
||||
|
|
|
@ -96,37 +96,35 @@ void cpu_e2k_set_id(CPUE2KState *env, unsigned int cpu)
|
|||
#define DEFAULT_CPU_MODEL "e8c"
|
||||
static const struct e2k_def_t e2k_defs[] = {
|
||||
{
|
||||
.name = "e8c", // default choice
|
||||
.canonical_name = "MCST Elbrus 8C",
|
||||
.gdb_arch = "elbrus-8c",
|
||||
.isa_version = 4,
|
||||
},
|
||||
{
|
||||
.name = "e2c+", // however it may work better
|
||||
.name = "e2c+", /* however it may work better */
|
||||
.canonical_name = "MCST Elbrus 2C+ (Monocube)",
|
||||
.gdb_arch = "elbrus-v2",
|
||||
.isa_version = 2,
|
||||
},
|
||||
{
|
||||
.name = "e8c2",
|
||||
.canonical_name = "MCST Elbrus 8CB",
|
||||
.gdb_arch = "elbrus-v5",
|
||||
.isa_version = 5,
|
||||
},
|
||||
#if 0 /* for reference, never tested */
|
||||
{
|
||||
.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,
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
static inline void cpu_dump_state_br(CPUE2KState *env, FILE *f, int flags)
|
||||
|
@ -217,7 +215,7 @@ static ObjectClass *e2k_cpu_class_by_name(const char *cpu_model)
|
|||
if (!strcasecmp(cpu_model, "any")) {
|
||||
cpu_model = DEFAULT_CPU_MODEL;
|
||||
}
|
||||
#endif // CONFIG_USER_ONLY
|
||||
#endif
|
||||
|
||||
typename = e2k_cpu_type_name(cpu_model);
|
||||
oc = object_class_by_name(typename);
|
||||
|
|
|
@ -665,6 +665,8 @@ typedef struct {
|
|||
uint32_t version;
|
||||
|
||||
struct e2k_def_t def;
|
||||
|
||||
uint32_t elf_flags;
|
||||
} CPUE2KState;
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue