aboutsummaryrefslogtreecommitdiff
path: root/linux-user
diff options
context:
space:
mode:
authorths <ths@c046a42c-6fe2-441c-8c8c-71466251a162>2007-10-08 13:36:46 +0000
committerths <ths@c046a42c-6fe2-441c-8c8c-71466251a162>2007-10-08 13:36:46 +0000
commit48733d195b10a61a18c0aafcdd0ae711bdfe03a6 (patch)
tree0ec94b143eb719c00a3157fc5be1ec9f7e73e724 /linux-user
parente69b406510a7267b79d4ba7e8a1c8d4b28af2fb1 (diff)
downloadqemu-48733d195b10a61a18c0aafcdd0ae711bdfe03a6.zip
qemu-48733d195b10a61a18c0aafcdd0ae711bdfe03a6.tar.gz
qemu-48733d195b10a61a18c0aafcdd0ae711bdfe03a6.tar.bz2
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
Diffstat (limited to 'linux-user')
-rw-r--r--linux-user/elfload.c20
-rw-r--r--linux-user/main.c75
-rw-r--r--linux-user/syscall.c8
-rw-r--r--linux-user/syscall_defs.h6
4 files changed, 104 insertions, 5 deletions
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 79c1c4d..1db6bab 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 fd130ef..b4bc93d 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 af5b9d9..021ac97 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 90bea9b..ccccebb 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;