e2k: v9.0.0 fixes
This commit is contained in:
parent
8d28806a5d
commit
a84db39085
@ -72,7 +72,7 @@ void cpu_loop(CPUE2KState *env)
|
|||||||
process_queued_cpu_work(cs);
|
process_queued_cpu_work(cs);
|
||||||
|
|
||||||
switch (trapnr) {
|
switch (trapnr) {
|
||||||
case EXCP_SYSCALL: {
|
case E2K_EXCP_SYSCALL: {
|
||||||
abi_ullong args[E2K_SYSCALL_MAX_ARGS] = { 0 };
|
abi_ullong args[E2K_SYSCALL_MAX_ARGS] = { 0 };
|
||||||
int i, psize = MIN(E2K_SYSCALL_MAX_ARGS, env->wd.size);
|
int i, psize = MIN(E2K_SYSCALL_MAX_ARGS, env->wd.size);
|
||||||
abi_ulong ret;
|
abi_ulong ret;
|
||||||
@ -97,25 +97,25 @@ void cpu_loop(CPUE2KState *env)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EXCP_ILLEGAL_OPCODE:
|
case E2K_EXCP_ILLEGAL_OPCODE:
|
||||||
case EXCP_PRIV_ACTION:
|
case E2K_EXCP_PRIV_ACTION:
|
||||||
gen_signal(env, TARGET_SIGILL, TARGET_ILL_ILLOPC, env->ip);
|
gen_signal(env, TARGET_SIGILL, TARGET_ILL_ILLOPC, env->ip);
|
||||||
break;
|
break;
|
||||||
case EXCP_ILLEGAL_OPERAND:
|
case E2K_EXCP_ILLEGAL_OPERAND:
|
||||||
gen_signal(env, TARGET_SIGILL, TARGET_ILL_ILLOPN, env->ip);
|
gen_signal(env, TARGET_SIGILL, TARGET_ILL_ILLOPN, env->ip);
|
||||||
break;
|
break;
|
||||||
case EXCP_CHAIN_STACK_BOUNDS:
|
case E2K_EXCP_CHAIN_STACK_BOUNDS:
|
||||||
stack_expand(env, &env->pcsp);
|
stack_expand(env, &env->pcsp);
|
||||||
break;
|
break;
|
||||||
case EXCP_PROC_STACK_BOUNDS:
|
case E2K_EXCP_PROC_STACK_BOUNDS:
|
||||||
stack_expand(env, &env->psp);
|
stack_expand(env, &env->psp);
|
||||||
break;
|
break;
|
||||||
case EXCP_WINDOW_BOUNDS:
|
case E2K_EXCP_WINDOW_BOUNDS:
|
||||||
case EXCP_ARRAY_BOUNDS:
|
case E2K_EXCP_ARRAY_BOUNDS:
|
||||||
case EXCP_DATA_PAGE:
|
case E2K_EXCP_DATA_PAGE:
|
||||||
gen_signal(env, TARGET_SIGSEGV, TARGET_SEGV_MAPERR, env->ip);
|
gen_signal(env, TARGET_SIGSEGV, TARGET_SEGV_MAPERR, env->ip);
|
||||||
break;
|
break;
|
||||||
case EXCP_DIV:
|
case E2K_EXCP_DIV:
|
||||||
gen_signal(env, TARGET_SIGFPE, 0, env->ip);
|
gen_signal(env, TARGET_SIGFPE, 0, env->ip);
|
||||||
break;
|
break;
|
||||||
/* QEMU common interrupts */
|
/* QEMU common interrupts */
|
||||||
|
@ -250,7 +250,7 @@ static void target_setup_frame(int sig, struct target_sigaction *ka,
|
|||||||
env->wd.size = 8;
|
env->wd.size = 8;
|
||||||
|
|
||||||
if (info && (ka->sa_flags & TARGET_SA_SIGINFO)) {
|
if (info && (ka->sa_flags & TARGET_SA_SIGINFO)) {
|
||||||
tswap_siginfo(&frame->info, info);
|
frame->info = *info;
|
||||||
env->regs[1].lo = frame_addr + offsetof(struct target_sigframe, info);
|
env->regs[1].lo = frame_addr + offsetof(struct target_sigframe, info);
|
||||||
env->tags[1] = E2K_TAG_NUMBER64;
|
env->tags[1] = E2K_TAG_NUMBER64;
|
||||||
env->regs[2].lo = frame_addr + offsetof(struct target_sigframe, uc);
|
env->regs[2].lo = frame_addr + offsetof(struct target_sigframe, uc);
|
||||||
|
33
linux-user/e2k/target_mman.h
Normal file
33
linux-user/e2k/target_mman.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#ifndef LINUX_USER_E2K_TARGET_MMAN_H
|
||||||
|
#define LINUX_USER_E2K_TARGET_MMAN_H
|
||||||
|
|
||||||
|
#ifdef TARGET_E2K64
|
||||||
|
# define TARGET_TASK_SIZE 0xd00000000000UL
|
||||||
|
#else
|
||||||
|
# define TARGET_TASK_SIZE 0xf0000000UL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define TASK_UNMAPPED_BASE TARGET_PAGE_ALIGN(TARGET_TASK_SIZE / 3)
|
||||||
|
#define ELF_ET_DYN_BASE (2 * TARGET_TASK_SIZE / 3)
|
||||||
|
|
||||||
|
#define TARGET_MAP_ANONYMOUS 0x000010 /* don't use a file */
|
||||||
|
#define TARGET_MAP_FIXED 0x000100 /* Interpret addr exactly */
|
||||||
|
#define TARGET_MAP_DENYWRITE 0x000800 /* ETXTBSY */
|
||||||
|
#define TARGET_MAP_GROWSDOWN 0x001000 /* stack-like segment */
|
||||||
|
#define TARGET_MAP_GROWSUP 0x002000 /* register stack-like segment */
|
||||||
|
#define TARGET_MAP_EXECUTABLE 0x004000 /* mark it as an executable */
|
||||||
|
#define TARGET_MAP_LOCKED 0x008000 /* pages are locked */
|
||||||
|
#define TARGET_MAP_NORESERVE 0x010000 /* don't check for reservations */
|
||||||
|
#define TARGET_MAP_POPULATE 0x020000 /* populate (prefault) pagetables */
|
||||||
|
#define TARGET_MAP_NONBLOCK 0x040000 /* do not block on IO */
|
||||||
|
#define TARGET_MAP_FIRST32 0x080000 /* in protected mode map in */
|
||||||
|
/* first 2 ** 32 area */
|
||||||
|
#define TARGET_MAP_WRITECOMBINED 0x100000 /* Write combine */
|
||||||
|
#define TARGET_MAP_HUGETLB 0x200000 /* create a huge page mapping */
|
||||||
|
#define TARGET_MAP_FIXED_NOREPLACE 0x400000 /* MAP_FIXED which doesn't unmap */
|
||||||
|
/* underlying mapping */
|
||||||
|
#define TARGET_MAP_STACK TARGET_MAP_GROWSDOWN
|
||||||
|
|
||||||
|
#include "../generic/target_mman.h"
|
||||||
|
|
||||||
|
#endif /* LINUX_USER_E2K_TARGET_MMAN_H */
|
0
linux-user/e2k/target_proc.h
Normal file
0
linux-user/e2k/target_proc.h
Normal file
@ -65,14 +65,6 @@ struct target_pt_regs {
|
|||||||
uint16_t gext[32];
|
uint16_t gext[32];
|
||||||
};
|
};
|
||||||
|
|
||||||
// FIXME: Is it right place for these constants?
|
|
||||||
#if TARGET_LONG_BITS == 64
|
|
||||||
#define TARGET_PAGE_OFFSET 0x0000d00000000000UL
|
|
||||||
#define TARGET_TASK_SIZE TARGET_PAGE_OFFSET
|
|
||||||
#else
|
|
||||||
#define TARGET_TASK_SIZE 0xe0000000UL
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* modes for sys_access_hw_stacks */
|
/* modes for sys_access_hw_stacks */
|
||||||
enum {
|
enum {
|
||||||
READ_CHAIN_STACK,
|
READ_CHAIN_STACK,
|
||||||
|
@ -9,12 +9,12 @@
|
|||||||
|
|
||||||
#ifdef TARGET_E2K32
|
#ifdef TARGET_E2K32
|
||||||
# define TARGET_LONG_BITS 32
|
# define TARGET_LONG_BITS 32
|
||||||
|
# define TARGET_VIRT_ADDR_SPACE_BITS 32
|
||||||
#else
|
#else
|
||||||
# define TARGET_LONG_BITS 64
|
# define TARGET_LONG_BITS 64
|
||||||
|
# define TARGET_VIRT_ADDR_SPACE_BITS 48
|
||||||
#endif
|
#endif
|
||||||
#define TARGET_PAGE_BITS 12 /* 4k */
|
#define TARGET_PAGE_BITS 12 /* 4k */
|
||||||
#define TARGET_PHYS_ADDR_SPACE_BITS 40
|
#define TARGET_PHYS_ADDR_SPACE_BITS 40
|
||||||
#define TARGET_VIRT_ADDR_SPACE_BITS 48
|
|
||||||
#define NB_MMU_MODES 4
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -81,15 +81,15 @@ static bool e2k_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
void e2k_cpu_do_interrupt(CPUState *cs)
|
void e2k_cpu_do_interrupt(CPUState *cs)
|
||||||
{
|
{
|
||||||
qemu_log_mask(LOG_UNIMP, "e2k_cpu_do_interrupt: not implemented\n");
|
qemu_log_mask(LOG_UNIMP, "e2k_cpu_do_interrupt: not implemented\n");
|
||||||
cs->exception_index = -1;
|
cs->exception_index = -1;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void cpu_e2k_disas_set_info(CPUState *cs, disassemble_info *info)
|
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;
|
||||||
@ -102,7 +102,7 @@ static void cpu_e2k_disas_set_info(CPUState *cs, disassemble_info *info)
|
|||||||
#define DEFAULT_CPU_MODEL "e8c"
|
#define DEFAULT_CPU_MODEL "e8c"
|
||||||
static const struct e2k_def_t e2k_defs[] = {
|
static const struct e2k_def_t e2k_defs[] = {
|
||||||
{
|
{
|
||||||
.name = "e2c+", /* however it may work better */
|
.name = "e2cplus", /* however it may work better */
|
||||||
.canonical_name = "MCST Elbrus 2C+ (Monocube)",
|
.canonical_name = "MCST Elbrus 2C+ (Monocube)",
|
||||||
.gdb_arch = "elbrus-v2",
|
.gdb_arch = "elbrus-v2",
|
||||||
.isa_version = 2,
|
.isa_version = 2,
|
||||||
@ -147,6 +147,15 @@ static void e2k_cpu_synchronize_from_tb(CPUState *cs, const TranslationBlock *tb
|
|||||||
cpu->env.ip = tb->pc;
|
cpu->env.ip = tb->pc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void e2k_restore_state_to_opc(CPUState *cs, const TranslationBlock *tb,
|
||||||
|
const uint64_t *data)
|
||||||
|
{
|
||||||
|
E2KCPU *cpu = E2K_CPU(cs);
|
||||||
|
CPUE2KState *env = &cpu->env;
|
||||||
|
|
||||||
|
env->ip = data[0];
|
||||||
|
}
|
||||||
|
|
||||||
static bool e2k_cpu_has_work(CPUState *cs)
|
static bool e2k_cpu_has_work(CPUState *cs)
|
||||||
{
|
{
|
||||||
// TODO: e2k_cpu_has_work
|
// TODO: e2k_cpu_has_work
|
||||||
@ -154,6 +163,20 @@ static bool e2k_cpu_has_work(CPUState *cs)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int e2k_env_mmu_index(CPUE2KState *env, bool ifetch)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_USER_ONLY
|
||||||
|
return MMU_USER_IDX;
|
||||||
|
#else
|
||||||
|
# error softmmu is not supported on E2K
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int e2k_cpu_mmu_index(CPUState *cs, bool ifetch)
|
||||||
|
{
|
||||||
|
return e2k_env_mmu_index(cpu_env(cs), ifetch);
|
||||||
|
}
|
||||||
|
|
||||||
static char *e2k_cpu_type_name(const char *cpu_model)
|
static char *e2k_cpu_type_name(const char *cpu_model)
|
||||||
{
|
{
|
||||||
return g_strdup(cpu_model);
|
return g_strdup(cpu_model);
|
||||||
@ -205,14 +228,12 @@ static void e2k_cpu_initfn(Object* obj)
|
|||||||
E2KCPUClass *ecc = E2K_CPU_GET_CLASS(obj);
|
E2KCPUClass *ecc = E2K_CPU_GET_CLASS(obj);
|
||||||
CPUE2KState *env = &cpu->env;
|
CPUE2KState *env = &cpu->env;
|
||||||
|
|
||||||
cpu_set_cpustate_pointers(cpu);
|
|
||||||
|
|
||||||
if (ecc->cpu_def) {
|
if (ecc->cpu_def) {
|
||||||
env->def = *ecc->cpu_def;
|
env->def = *ecc->cpu_def;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static gchar* e2k_cpu_gdb_arch_name(CPUState *cs)
|
static const gchar* e2k_cpu_gdb_arch_name(CPUState *cs)
|
||||||
{
|
{
|
||||||
E2KCPU *cpu = E2K_CPU(cs);
|
E2KCPU *cpu = E2K_CPU(cs);
|
||||||
CPUE2KState *env = &cpu->env;
|
CPUE2KState *env = &cpu->env;
|
||||||
@ -223,8 +244,10 @@ static gchar* e2k_cpu_gdb_arch_name(CPUState *cs)
|
|||||||
static struct TCGCPUOps e2k_tcg_ops = {
|
static struct TCGCPUOps e2k_tcg_ops = {
|
||||||
.initialize = e2k_tcg_initialize,
|
.initialize = e2k_tcg_initialize,
|
||||||
.synchronize_from_tb = e2k_cpu_synchronize_from_tb,
|
.synchronize_from_tb = e2k_cpu_synchronize_from_tb,
|
||||||
.do_interrupt = e2k_cpu_do_interrupt,
|
.restore_state_to_opc = e2k_restore_state_to_opc,
|
||||||
|
|
||||||
#ifdef CONFIG_SOFTMMU
|
#ifdef CONFIG_SOFTMMU
|
||||||
|
.do_interrupt = e2k_cpu_do_interrupt,
|
||||||
.cpu_exec_interrupt = e2k_cpu_exec_interrupt,
|
.cpu_exec_interrupt = e2k_cpu_exec_interrupt,
|
||||||
.tlb_fill = e2k_cpu_tlb_fill,
|
.tlb_fill = e2k_cpu_tlb_fill,
|
||||||
#endif
|
#endif
|
||||||
@ -250,8 +273,9 @@ static void e2k_cpu_class_init(ObjectClass *oc, void *data)
|
|||||||
cc->has_work = e2k_cpu_has_work;
|
cc->has_work = e2k_cpu_has_work;
|
||||||
cc->dump_state = e2k_cpu_dump_state;
|
cc->dump_state = e2k_cpu_dump_state;
|
||||||
cc->set_pc = e2k_cpu_set_pc;
|
cc->set_pc = e2k_cpu_set_pc;
|
||||||
|
cc->mmu_index = e2k_cpu_mmu_index;
|
||||||
cc->class_by_name = e2k_cpu_class_by_name;
|
cc->class_by_name = e2k_cpu_class_by_name;
|
||||||
cc->disas_set_info = cpu_e2k_disas_set_info;
|
cc->disas_set_info = e2k_cpu_disas_set_info;
|
||||||
|
|
||||||
cc->gdb_core_xml_file = "e2k-v1.xml";
|
cc->gdb_core_xml_file = "e2k-v1.xml";
|
||||||
cc->gdb_arch_name = e2k_cpu_gdb_arch_name;
|
cc->gdb_arch_name = e2k_cpu_gdb_arch_name;
|
||||||
|
106
target/e2k/cpu.h
106
target/e2k/cpu.h
@ -268,56 +268,56 @@ typedef enum {
|
|||||||
#define IDR_WBL_TO_BYTES(wbl) ((wbl) ? (1 << ((wbs) + 4)) : 1)
|
#define IDR_WBL_TO_BYTES(wbl) ((wbl) ? (1 << ((wbs) + 4)) : 1)
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
EXCP_ILLEGAL_OPCODE = 0,
|
E2K_EXCP_ILLEGAL_OPCODE = 0,
|
||||||
EXCP_PRIV_ACTION = 1,
|
E2K_EXCP_PRIV_ACTION = 1,
|
||||||
EXCP_FP_DISABLED = 2,
|
E2K_EXCP_FP_DISABLED = 2,
|
||||||
EXCP_FP_STACK_U = 3,
|
E2K_EXCP_FP_STACK_U = 3,
|
||||||
EXCP_D_INTERRUPT = 4,
|
E2K_EXCP_D_INTERRUPT = 4,
|
||||||
EXCP_DIAG_CT_COND = 5,
|
E2K_EXCP_DIAG_CT_COND = 5,
|
||||||
EXCP_DIAG_INSTR_ADDR = 6,
|
E2K_EXCP_DIAG_INSTR_ADDR = 6,
|
||||||
EXCP_ILLEGAL_INSTR_ADDR = 7,
|
E2K_EXCP_ILLEGAL_INSTR_ADDR = 7,
|
||||||
EXCP_INSTR_DEBUG = 8,
|
E2K_EXCP_INSTR_DEBUG = 8,
|
||||||
EXCP_WINDOW_BOUNDS = 9,
|
E2K_EXCP_WINDOW_BOUNDS = 9,
|
||||||
EXCP_USER_STACK_BOUNDS = 10,
|
E2K_EXCP_USER_STACK_BOUNDS = 10,
|
||||||
EXCP_PROC_STACK_BOUNDS = 11,
|
E2K_EXCP_PROC_STACK_BOUNDS = 11,
|
||||||
EXCP_CHAIN_STACK_BOUNDS = 12,
|
E2K_EXCP_CHAIN_STACK_BOUNDS = 12,
|
||||||
EXCP_FP_STACK_O = 13,
|
E2K_EXCP_FP_STACK_O = 13,
|
||||||
EXCP_DIAG_COND = 14,
|
E2K_EXCP_DIAG_COND = 14,
|
||||||
EXCP_DIAG_OPERAND = 15,
|
E2K_EXCP_DIAG_OPERAND = 15,
|
||||||
EXCP_ILLEGAL_OPERAND = 16,
|
E2K_EXCP_ILLEGAL_OPERAND = 16,
|
||||||
EXCP_ARRAY_BOUNDS = 17,
|
E2K_EXCP_ARRAY_BOUNDS = 17,
|
||||||
EXCP_ACCESS_RIGHTS = 18,
|
E2K_EXCP_ACCESS_RIGHTS = 18,
|
||||||
EXCP_ADDR_NOT_ALIGNED = 19,
|
E2K_EXCP_ADDR_NOT_ALIGNED = 19,
|
||||||
EXCP_INSTR_PAGE_MISS = 20,
|
E2K_EXCP_INSTR_PAGE_MISS = 20,
|
||||||
EXCP_INSTR_PAGE_PROT = 21,
|
E2K_EXCP_INSTR_PAGE_PROT = 21,
|
||||||
EXCP_AINSTR_PAGE_MISS = 22,
|
E2K_EXCP_AINSTR_PAGE_MISS = 22,
|
||||||
EXCP_AINSTR_PAGE_PROT = 23,
|
E2K_EXCP_AINSTR_PAGE_PROT = 23,
|
||||||
EXCP_LAST_WISH = 24,
|
E2K_EXCP_LAST_WISH = 24,
|
||||||
EXCP_BASE_NOT_ALIGNED = 25,
|
E2K_EXCP_BASE_NOT_ALIGNED = 25,
|
||||||
|
|
||||||
EXCP_DATA_DEBUG = 28,
|
E2K_EXCP_DATA_DEBUG = 28,
|
||||||
EXCP_DATA_PAGE = 29,
|
E2K_EXCP_DATA_PAGE = 29,
|
||||||
|
|
||||||
EXCP_RECOVERY_POINT = 31,
|
E2K_EXCP_RECOVERY_POINT = 31,
|
||||||
EXCP_INTERRUPT = 32,
|
E2K_EXCP_INTERRUPT = 32,
|
||||||
EXCP_NM_INTERRUPT = 33,
|
E2K_EXCP_NM_INTERRUPT = 33,
|
||||||
EXCP_DIV = 34,
|
E2K_EXCP_DIV = 34,
|
||||||
EXCP_FP = 35,
|
E2K_EXCP_FP = 35,
|
||||||
EXCP_MEM_LOCK = 36,
|
E2K_EXCP_MEM_LOCK = 36,
|
||||||
EXCP_MEM_LOCK_AS = 37,
|
E2K_EXCP_MEM_LOCK_AS = 37,
|
||||||
EXCP_MEM_ERROR_OUT_CPU = 38,
|
E2K_EXCP_MEM_ERROR_OUT_CPU = 38,
|
||||||
EXCP_MEM_ERROR_MAU = 39,
|
E2K_EXCP_MEM_ERROR_MAU = 39,
|
||||||
EXCP_MEM_ERROR_L2 = 40,
|
E2K_EXCP_MEM_ERROR_L2 = 40,
|
||||||
EXCP_MEM_ERROR_L1_35 = 41,
|
E2K_EXCP_MEM_ERROR_L1_35 = 41,
|
||||||
EXCP_MEM_ERROR_L1_02 = 42,
|
E2K_EXCP_MEM_ERROR_L1_02 = 42,
|
||||||
EXCP_MEM_ERROR_ICACHE = 43,
|
E2K_EXCP_MEM_ERROR_ICACHE = 43,
|
||||||
|
|
||||||
EXCP_MAX = 43,
|
E2K_EXCP_MAX = 43,
|
||||||
|
|
||||||
#ifdef CONFIG_USER_ONLY
|
#ifdef CONFIG_USER_ONLY
|
||||||
EXCP_SYSCALL = 100,
|
E2K_EXCP_SYSCALL = 100,
|
||||||
#endif
|
#endif
|
||||||
} Exception;
|
} E2KException;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
SR_PSR = 0x00,
|
SR_PSR = 0x00,
|
||||||
@ -919,29 +919,20 @@ typedef struct CPUArchState {
|
|||||||
struct ArchCPU {
|
struct ArchCPU {
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
CPUState parent_obj;
|
CPUState parent_obj;
|
||||||
/*< public >*/
|
|
||||||
|
|
||||||
CPUNegativeOffsetState neg;
|
/*< public >*/
|
||||||
CPUE2KState env;
|
CPUE2KState env;
|
||||||
|
CPUNegativeOffsetState neg;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline void cpu_get_tb_cpu_state(CPUE2KState *env, target_ulong *pc,
|
static inline void cpu_get_tb_cpu_state(CPUE2KState *env, vaddr *pc,
|
||||||
target_ulong *cs_base, uint32_t *pflags)
|
uint64_t *cs_base, uint32_t *pflags)
|
||||||
{
|
{
|
||||||
*pc = env->ip;
|
*pc = env->ip;
|
||||||
*cs_base = 0;
|
*cs_base = 0;
|
||||||
*pflags = MMU_USER_IDX;
|
*pflags = MMU_USER_IDX;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int cpu_mmu_index(CPUE2KState *env, bool ifetch)
|
|
||||||
{
|
|
||||||
#ifdef CONFIG_USER_ONLY
|
|
||||||
return MMU_USER_IDX;
|
|
||||||
#else
|
|
||||||
#error softmmu is not supported on E2K
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void e2k_cpu_dump_state(CPUState *cs, FILE *f, int flags);
|
void e2k_cpu_dump_state(CPUState *cs, FILE *f, int flags);
|
||||||
void e2k_cpu_do_interrupt(CPUState *cs);
|
void e2k_cpu_do_interrupt(CPUState *cs);
|
||||||
void e2k_cpu_list(void);
|
void e2k_cpu_list(void);
|
||||||
@ -952,6 +943,7 @@ void e2k_cpu_register_gdb_regs_for_features(CPUState *cs);
|
|||||||
bool e2k_cpu_tlb_fill(CPUState *cpu, vaddr address, int size,
|
bool e2k_cpu_tlb_fill(CPUState *cpu, vaddr address, int size,
|
||||||
MMUAccessType access_type, int mmu_idx,
|
MMUAccessType access_type, int mmu_idx,
|
||||||
bool probe, uintptr_t retaddr);
|
bool probe, uintptr_t retaddr);
|
||||||
|
int e2k_env_mmu_index(CPUE2KState *env, bool ifetch);
|
||||||
void e2k_update_fp_status(CPUE2KState *env);
|
void e2k_update_fp_status(CPUE2KState *env);
|
||||||
void e2k_update_fx_status(CPUE2KState *env);
|
void e2k_update_fx_status(CPUE2KState *env);
|
||||||
/*
|
/*
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
#include "helper-tcg.h"
|
#include "helper-tcg.h"
|
||||||
#include "exec/gdbstub.h"
|
#include "exec/gdbstub.h"
|
||||||
|
#include "gdbstub/helpers.h"
|
||||||
|
|
||||||
/* TODO: reverse engineer e2k-linux-gdb register ids */
|
/* TODO: reverse engineer e2k-linux-gdb register ids */
|
||||||
|
|
||||||
@ -300,8 +301,10 @@ int e2k_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gdb_get_v2(CPUE2KState *env, GByteArray *buf, int n)
|
static int gdb_get_v2(CPUState *cs, GByteArray *buf, int n)
|
||||||
{
|
{
|
||||||
|
CPUE2KState *env = cpu_env(cs);
|
||||||
|
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
/* idr */
|
/* idr */
|
||||||
return gdb_get_reg64(buf, env->idr);
|
return gdb_get_reg64(buf, env->idr);
|
||||||
@ -310,14 +313,16 @@ static int gdb_get_v2(CPUE2KState *env, GByteArray *buf, int n)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gdb_set_v2(CPUE2KState *env, uint8_t *mem_buf, int n)
|
static int gdb_set_v2(CPUState *cs, uint8_t *mem_buf, int n)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%s: unknown register %d\n", __FUNCTION__, n);
|
fprintf(stderr, "%s: unknown register %d\n", __FUNCTION__, n);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gdb_get_v3(CPUE2KState *env, GByteArray *buf, int n)
|
static int gdb_get_v3(CPUState *cs, GByteArray *buf, int n)
|
||||||
{
|
{
|
||||||
|
CPUE2KState *env = cpu_env(cs);
|
||||||
|
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
/* core_mode */
|
/* core_mode */
|
||||||
return gdb_get_reg64(buf, env->core_mode);
|
return gdb_get_reg64(buf, env->core_mode);
|
||||||
@ -326,14 +331,16 @@ static int gdb_get_v3(CPUE2KState *env, GByteArray *buf, int n)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gdb_set_v3(CPUE2KState *env, uint8_t *mem_buf, int n)
|
static int gdb_set_v3(CPUState *cs, uint8_t *mem_buf, int n)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%s: unknown register %d\n", __FUNCTION__, n);
|
fprintf(stderr, "%s: unknown register %d\n", __FUNCTION__, n);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gdb_get_v5(CPUE2KState *env, GByteArray *buf, int n)
|
static int gdb_get_v5(CPUState *cs, GByteArray *buf, int n)
|
||||||
{
|
{
|
||||||
|
CPUE2KState *env = cpu_env(cs);
|
||||||
|
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
/* lsr1 */
|
/* lsr1 */
|
||||||
return gdb_get_reg64(buf, env->lsr_lcnt);
|
return gdb_get_reg64(buf, env->lsr_lcnt);
|
||||||
@ -351,7 +358,7 @@ static int gdb_get_v5(CPUE2KState *env, GByteArray *buf, int n)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gdb_set_v5(CPUE2KState *env, uint8_t *mem_buf, int n)
|
static int gdb_set_v5(CPUState *cs, uint8_t *mem_buf, int n)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%s: unknown register %d\n", __FUNCTION__, n);
|
fprintf(stderr, "%s: unknown register %d\n", __FUNCTION__, n);
|
||||||
return 0;
|
return 0;
|
||||||
@ -364,16 +371,16 @@ void e2k_cpu_register_gdb_regs_for_features(CPUState *cs)
|
|||||||
|
|
||||||
if (env->version >= 2) {
|
if (env->version >= 2) {
|
||||||
gdb_register_coprocessor(cs, gdb_get_v2, gdb_set_v2,
|
gdb_register_coprocessor(cs, gdb_get_v2, gdb_set_v2,
|
||||||
1, "e2k-v2.xml", 574);
|
gdb_find_static_feature("e2k-v2.xml"), 574);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (env->version >= 3) {
|
if (env->version >= 3) {
|
||||||
gdb_register_coprocessor(cs, gdb_get_v3, gdb_set_v3,
|
gdb_register_coprocessor(cs, gdb_get_v3, gdb_set_v3,
|
||||||
1, "e2k-v3.xml", 575);
|
gdb_find_static_feature("e2k-v3.xml"), 575);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (env->version >= 5) {
|
if (env->version >= 5) {
|
||||||
gdb_register_coprocessor(cs, gdb_get_v5, gdb_set_v5,
|
gdb_register_coprocessor(cs, gdb_get_v5, gdb_set_v5,
|
||||||
66, "e2k-v5.xml", 576);
|
gdb_find_static_feature("e2k-v5.xml"), 576);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ static inline void ps_push(CPUE2KState *env, uint64_t value, uint8_t tag)
|
|||||||
{
|
{
|
||||||
#ifndef CONFIG_USER_ONLY
|
#ifndef CONFIG_USER_ONLY
|
||||||
if ((env->psp.index + 8) > env->psp.size) {
|
if ((env->psp.index + 8) > env->psp.size) {
|
||||||
raise_exception(env, EXCP_PROC_STACK_BOUNDS);
|
raise_exception(env, E2K_EXCP_PROC_STACK_BOUNDS);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -30,7 +30,7 @@ static inline void ps_push(CPUE2KState *env, uint64_t value, uint8_t tag)
|
|||||||
static inline uint64_t ps_pop(CPUE2KState *env, uint8_t *ret_tag)
|
static inline uint64_t ps_pop(CPUE2KState *env, uint8_t *ret_tag)
|
||||||
{
|
{
|
||||||
if (env->psp.index < 8) {
|
if (env->psp.index < 8) {
|
||||||
raise_exception(env, EXCP_PROC_STACK_BOUNDS);
|
raise_exception(env, E2K_EXCP_PROC_STACK_BOUNDS);
|
||||||
}
|
}
|
||||||
env->psp.index -= 8;
|
env->psp.index -= 8;
|
||||||
if (ret_tag != NULL) {
|
if (ret_tag != NULL) {
|
||||||
@ -135,7 +135,7 @@ static void pcs_push(CPUE2KState *env, E2KCrs *crs)
|
|||||||
{
|
{
|
||||||
#ifndef CONFIG_USER_ONLY
|
#ifndef CONFIG_USER_ONLY
|
||||||
if ((env->pcsp.index + sizeof(E2KCrs) * 2) > env->pcsp.size) {
|
if ((env->pcsp.index + sizeof(E2KCrs) * 2) > env->pcsp.size) {
|
||||||
raise_exception(env, EXCP_CHAIN_STACK_BOUNDS);
|
raise_exception(env, E2K_EXCP_CHAIN_STACK_BOUNDS);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -148,7 +148,7 @@ static void pcs_pop(CPUE2KState *env, E2KCrs *crs)
|
|||||||
crs_read(env, env->pcsp.base + env->pcsp.index, crs);
|
crs_read(env, env->pcsp.base + env->pcsp.index, crs);
|
||||||
|
|
||||||
if (env->pcsp.index < sizeof(E2KCrs)) {
|
if (env->pcsp.index < sizeof(E2KCrs)) {
|
||||||
raise_exception(env, EXCP_CHAIN_STACK_BOUNDS);
|
raise_exception(env, E2K_EXCP_CHAIN_STACK_BOUNDS);
|
||||||
} else {
|
} else {
|
||||||
env->pcsp.index -= sizeof(E2KCrs);
|
env->pcsp.index -= sizeof(E2KCrs);
|
||||||
}
|
}
|
||||||
@ -219,7 +219,7 @@ void HELPER(call)(CPUE2KState *env, uint64_t ctpr_raw, int call_wbs,
|
|||||||
env->ip = ctpr.base;
|
env->ip = ctpr.base;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
raise_exception(env, EXCP_ILLEGAL_OPCODE);
|
raise_exception(env, E2K_EXCP_ILLEGAL_OPCODE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -228,11 +228,11 @@ void HELPER(call)(CPUE2KState *env, uint64_t ctpr_raw, int call_wbs,
|
|||||||
void HELPER(expand_stacks)(CPUE2KState *env)
|
void HELPER(expand_stacks)(CPUE2KState *env)
|
||||||
{
|
{
|
||||||
if ((env->psp.size - env->psp.index) <= (E2K_REG_LEN * E2K_NR_COUNT * 4)) {
|
if ((env->psp.size - env->psp.index) <= (E2K_REG_LEN * E2K_NR_COUNT * 4)) {
|
||||||
raise_exception_ra(env, EXCP_PROC_STACK_BOUNDS, GETPC());
|
raise_exception_ra(env, E2K_EXCP_PROC_STACK_BOUNDS, GETPC());
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((env->pcsp.size - env->pcsp.index) <= (sizeof(E2KCrs) * 2)) {
|
if ((env->pcsp.size - env->pcsp.index) <= (sizeof(E2KCrs) * 2)) {
|
||||||
raise_exception_ra(env, EXCP_CHAIN_STACK_BOUNDS, GETPC());
|
raise_exception_ra(env, E2K_EXCP_CHAIN_STACK_BOUNDS, GETPC());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_USER_ONLY */
|
#endif /* CONFIG_USER_ONLY */
|
||||||
@ -266,7 +266,7 @@ void HELPER(return)(CPUE2KState *env)
|
|||||||
env->wd.psize = 2;
|
env->wd.psize = 2;
|
||||||
env->regs[0].lo = 119; /* TARGET_NR_sigreturn */
|
env->regs[0].lo = 119; /* TARGET_NR_sigreturn */
|
||||||
env->tags[0] = E2K_TAG_NUMBER64;
|
env->tags[0] = E2K_TAG_NUMBER64;
|
||||||
cs->exception_index = EXCP_SYSCALL;
|
cs->exception_index = E2K_EXCP_SYSCALL;
|
||||||
cpu_loop_exit(cs);
|
cpu_loop_exit(cs);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -290,10 +290,10 @@ void G_NORETURN raise_exception_ra(CPUE2KState *env, int exception_index,
|
|||||||
CPUState *cs = env_cpu(env);
|
CPUState *cs = env_cpu(env);
|
||||||
switch (exception_index) {
|
switch (exception_index) {
|
||||||
#ifdef CONFIG_USER_ONLY
|
#ifdef CONFIG_USER_ONLY
|
||||||
case EXCP_SYSCALL:
|
case E2K_EXCP_SYSCALL:
|
||||||
#endif
|
#endif
|
||||||
case EXCP_PROC_STACK_BOUNDS:
|
case E2K_EXCP_PROC_STACK_BOUNDS:
|
||||||
case EXCP_CHAIN_STACK_BOUNDS:
|
case E2K_EXCP_CHAIN_STACK_BOUNDS:
|
||||||
/* ignore */
|
/* ignore */
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -317,7 +317,7 @@ void HELPER(setwd)(CPUE2KState *env, int wsz, int nfx, int dbl)
|
|||||||
diff = size - env->wd.size;
|
diff = size - env->wd.size;
|
||||||
|
|
||||||
if (size < env->wd.psize) {
|
if (size < env->wd.psize) {
|
||||||
raise_exception(env, EXCP_ILLEGAL_OPCODE);
|
raise_exception(env, E2K_EXCP_ILLEGAL_OPCODE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (diff > 0) {
|
if (diff > 0) {
|
||||||
@ -342,7 +342,7 @@ bool e2k_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
|
|||||||
CPUE2KState *env = &cpu->env;
|
CPUE2KState *env = &cpu->env;
|
||||||
|
|
||||||
e2k_proc_call(env, env->wd.size, env->ip, true);
|
e2k_proc_call(env, env->wd.size, env->ip, true);
|
||||||
cs->exception_index = EXCP_DATA_PAGE;
|
cs->exception_index = E2K_EXCP_DATA_PAGE;
|
||||||
cpu_loop_exit_restore(cs, retaddr);
|
cpu_loop_exit_restore(cs, retaddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ void HELPER(aau_load_program)(CPUE2KState *env)
|
|||||||
E2KCtpr ctpr = env->ctprs[1];
|
E2KCtpr ctpr = env->ctprs[1];
|
||||||
|
|
||||||
if (ctpr.tag != CTPR_TAG_DISP || ctpr.opc != CTPR_OPC_LDISP) {
|
if (ctpr.tag != CTPR_TAG_DISP || ctpr.opc != CTPR_OPC_LDISP) {
|
||||||
helper_raise_exception(env, EXCP_ILLEGAL_OPCODE);
|
helper_raise_exception(env, E2K_EXCP_ILLEGAL_OPCODE);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < 32; i++) {
|
for (i = 0; i < 32; i++) {
|
||||||
@ -62,7 +62,7 @@ target_ulong HELPER(mova_ptr)(CPUE2KState *env, int chan, int area, int ind,
|
|||||||
void *ignore;
|
void *ignore;
|
||||||
int flags;
|
int flags;
|
||||||
|
|
||||||
flags = probe_access_flags(env, page, MMU_DATA_LOAD, mmu_idx,
|
flags = probe_access_flags(env, page, 0, MMU_DATA_LOAD, mmu_idx,
|
||||||
true, &ignore, 0);
|
true, &ignore, 0);
|
||||||
as->last_page = page;
|
as->last_page = page;
|
||||||
as->last_page_valid = !(flags & TLB_INVALID_MASK);
|
as->last_page_valid = !(flags & TLB_INVALID_MASK);
|
||||||
|
@ -145,11 +145,11 @@ void HELPER(state_reg_set)(CPUE2KState *env, uint64_t value, int index)
|
|||||||
case SR_ILCR1:
|
case SR_ILCR1:
|
||||||
break;
|
break;
|
||||||
case SR_CUIR:
|
case SR_CUIR:
|
||||||
raise_exception(env, EXCP_ILLEGAL_OPCODE); /* FIXME */
|
raise_exception(env, E2K_EXCP_ILLEGAL_OPCODE); /* FIXME */
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if ((env->psr & PSR_PM) == 0) {
|
if ((env->psr & PSR_PM) == 0) {
|
||||||
raise_exception(env, EXCP_PRIV_ACTION);
|
raise_exception(env, E2K_EXCP_PRIV_ACTION);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -12,13 +12,13 @@ static int e2k_probe_access(CPUE2KState *env, target_ulong addr, int size,
|
|||||||
int flags;
|
int flags;
|
||||||
void *ignore;
|
void *ignore;
|
||||||
|
|
||||||
flags = probe_access_flags(env, addr, access_type, mmu_idx,
|
flags = probe_access_flags(env, addr, 0, access_type, mmu_idx,
|
||||||
true, &ignore, 0);
|
true, &ignore, 0);
|
||||||
|
|
||||||
if (flags & TLB_INVALID_MASK) {
|
if (flags & TLB_INVALID_MASK) {
|
||||||
return 0;
|
return 0;
|
||||||
} else if ((addr & TARGET_PAGE_MASK) != (addr_end & TARGET_PAGE_MASK)) {
|
} else if ((addr & TARGET_PAGE_MASK) != (addr_end & TARGET_PAGE_MASK)) {
|
||||||
flags = probe_access_flags(env, addr_end, access_type, mmu_idx, true,
|
flags = probe_access_flags(env, addr_end, 0, access_type, mmu_idx, true,
|
||||||
&ignore, 0);
|
&ignore, 0);
|
||||||
return !(flags & TLB_INVALID_MASK);
|
return !(flags & TLB_INVALID_MASK);
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user