From 48733d195b10a61a18c0aafcdd0ae711bdfe03a6 Mon Sep 17 00:00:00 2001 From: ths Date: Mon, 8 Oct 2007 13:36:46 +0000 Subject: [PATCH] CRIS Linux userland emulation, part 2. By Edgar E. Iglesias. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3367 c046a42c-6fe2-441c-8c8c-71466251a162 --- linux-user/elfload.c | 20 +++++++++++ linux-user/main.c | 75 +++++++++++++++++++++++++++++++++++++++ linux-user/syscall.c | 8 +++-- linux-user/syscall_defs.h | 6 ++-- 4 files changed, 104 insertions(+), 5 deletions(-) diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 79c1c4da6e..1db6bab5e8 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -334,6 +334,26 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i #endif +#ifdef TARGET_CRIS + +#define ELF_START_MMAP 0x80000000 + +#define elf_check_arch(x) ( (x) == EM_CRIS ) + +#define ELF_CLASS ELFCLASS32 +#define ELF_DATA ELFDATA2LSB +#define ELF_ARCH EM_CRIS + +static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop) +{ + regs->erp = infop->entry; +} + +#define USE_ELF_CORE_DUMP +#define ELF_EXEC_PAGESIZE 8192 + +#endif + #ifdef TARGET_M68K #define ELF_START_MMAP 0x80000000 diff --git a/linux-user/main.c b/linux-user/main.c index fd130ef9cc..b4bc93da5f 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -1601,6 +1601,61 @@ void cpu_loop (CPUState *env) } #endif +#ifdef TARGET_CRIS +void cpu_loop (CPUState *env) +{ + int trapnr, ret; + target_siginfo_t info; + + while (1) { + trapnr = cpu_cris_exec (env); + switch (trapnr) { + case 0xaa: + { + info.si_signo = SIGSEGV; + info.si_errno = 0; + /* XXX: check env->error_code */ + info.si_code = TARGET_SEGV_MAPERR; + info._sifields._sigfault._addr = env->debug1; + queue_signal(info.si_signo, &info); + } + break; + case EXCP_BREAK: + ret = do_syscall(env, + env->regs[9], + env->regs[10], + env->regs[11], + env->regs[12], + env->regs[13], + env->pregs[7], + env->pregs[11]); + env->regs[10] = ret; + env->pc += 2; + break; + case EXCP_DEBUG: + { + int sig; + + sig = gdb_handlesig (env, TARGET_SIGTRAP); + if (sig) + { + info.si_signo = sig; + info.si_errno = 0; + info.si_code = TARGET_TRAP_BRKPT; + queue_signal(info.si_signo, &info); + } + } + break; + default: + printf ("Unhandled trap: 0x%x\n", trapnr); + cpu_dump_state(env, stderr, fprintf, 0); + exit (1); + } + process_pending_signals (env); + } +} +#endif + #ifdef TARGET_M68K void cpu_loop(CPUM68KState *env) @@ -2195,6 +2250,26 @@ int main(int argc, char **argv) env->pc = regs->pc; env->unique = regs->unique; } +#elif defined(TARGET_CRIS) + { + env->regs[0] = regs->r0; + env->regs[1] = regs->r1; + env->regs[2] = regs->r2; + env->regs[3] = regs->r3; + env->regs[4] = regs->r4; + env->regs[5] = regs->r5; + env->regs[6] = regs->r6; + env->regs[7] = regs->r7; + env->regs[8] = regs->r8; + env->regs[9] = regs->r9; + env->regs[10] = regs->r10; + env->regs[11] = regs->r11; + env->regs[12] = regs->r12; + env->regs[13] = regs->r13; + env->regs[14] = info->start_stack; + env->regs[15] = regs->acr; + env->pc = regs->erp; + } #else #error unsupported target CPU #endif diff --git a/linux-user/syscall.c b/linux-user/syscall.c index af5b9d9225..021ac9741a 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -74,7 +74,7 @@ //#define DEBUG #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) \ - || defined(TARGET_M68K) || defined(TARGET_SH4) + || defined(TARGET_M68K) || defined(TARGET_SH4) || defined(TARGET_CRIS) /* 16 bit uid wrappers emulation */ #define USE_UID16 #endif @@ -2286,6 +2286,10 @@ int do_fork(CPUState *env, unsigned int flags, target_ulong newsp) for (i = 7; i < 30; i++) new_env->ir[i] = 0; } +#elif defined(TARGET_CRIS) + if (!newsp) + newsp = env->regs[14]; + new_env->regs[14] = newsp; #else #error unsupported target CPU #endif @@ -3502,7 +3506,7 @@ target_long do_syscall(void *cpu_env, int num, target_long arg1, #endif #ifdef TARGET_NR_mmap case TARGET_NR_mmap: -#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_M68K) +#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_CRIS) { target_ulong *v; target_ulong v1, v2, v3, v4, v5, v6; diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index 90bea9b70b..ccccebb5ca 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -49,7 +49,7 @@ #define TARGET_IOC_TYPEBITS 8 #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SH4) \ - || defined(TARGET_M68K) || defined(TARGET_ALPHA) + || defined(TARGET_M68K) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) #define TARGET_IOC_SIZEBITS 14 #define TARGET_IOC_DIRBITS 2 @@ -289,7 +289,7 @@ struct target_sigaction; int do_sigaction(int sig, const struct target_sigaction *act, struct target_sigaction *oact); -#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_MIPS) || defined (TARGET_SH4) || defined(TARGET_M68K) || defined(TARGET_ALPHA) +#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_MIPS) || defined (TARGET_SH4) || defined(TARGET_M68K) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) #if defined(TARGET_SPARC) #define TARGET_SA_NOCLDSTOP 8u @@ -884,7 +884,7 @@ struct target_winsize { #define TARGET_MAP_NONBLOCK 0x10000 /* do not block on IO */ #endif -#if defined(TARGET_I386) || defined(TARGET_ARM) +#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_CRIS) struct target_stat { unsigned short st_dev; unsigned short __pad1;