]> git.proxmox.com Git - qemu.git/blobdiff - linux-user/main.c
SH usermode fault handling.
[qemu.git] / linux-user / main.c
index 1f4720516d27dead22832f4c24a55d22747daba7..74642cc36160a1a44a68b41b3d0c8875229f0a6a 100644 (file)
@@ -34,6 +34,7 @@
 #endif
 
 static const char *interp_prefix = CONFIG_QEMU_PREFIX;
+const char *qemu_uname_release = CONFIG_UNAME_RELEASE;
 
 #if defined(__i386__) && !defined(CONFIG_STATIC)
 /* Force usage of an ELF interpreter even if it is an ELF shared
@@ -1326,7 +1327,6 @@ void cpu_loop(CPUMIPSState *env)
                                      arg5, 
                                      arg6);
                 }
-                fail:
                 env->PC += 4;
                 if ((unsigned int)ret >= (unsigned int)(-1133)) {
                     env->gpr[7] = 1; /* error flag */
@@ -1341,39 +1341,10 @@ void cpu_loop(CPUMIPSState *env)
             break;
         case EXCP_CpU:
         case EXCP_RI:
-            {
-                uint32_t insn, op;
-
-                insn = tget32(env->PC);
-                op = insn >> 26;
-                //                printf("insn=%08x op=%02x\n", insn, op);
-                /* XXX: totally dummy FP ops just to be able to launch
-                   a few executables */
-                switch(op) {
-                case 0x31: /* LWC1 */
-                    env->PC += 4;
-                    break;
-                case 0x39: /* SWC1 */
-                    env->PC += 4;
-                    break;
-                case 0x11:
-                    switch((insn >> 21) & 0x1f) {
-                    case 0x02: /* CFC1 */
-                        env->PC += 4;
-                        break;
-                    default:
-                        goto sigill;
-                    }
-                    break;
-                default:
-                sigill:
-                    info.si_signo = TARGET_SIGILL;
-                    info.si_errno = 0;
-                    info.si_code = 0;
-                    queue_signal(info.si_signo, &info);
-                    break;
-                }
-            }
+            info.si_signo = TARGET_SIGILL;
+            info.si_errno = 0;
+            info.si_code = 0;
+            queue_signal(info.si_signo, &info);
             break;
         default:
             //        error:
@@ -1387,6 +1358,52 @@ void cpu_loop(CPUMIPSState *env)
 }
 #endif
 
+#ifdef TARGET_SH4
+void cpu_loop (CPUState *env)
+{
+    int trapnr, ret;
+    target_siginfo_t info;
+    
+    while (1) {
+        trapnr = cpu_sh4_exec (env);
+        
+        switch (trapnr) {
+        case 0x160:
+            ret = do_syscall(env, 
+                             env->gregs[0x13], 
+                             env->gregs[0x14], 
+                             env->gregs[0x15], 
+                             env->gregs[0x16], 
+                             env->gregs[0x17], 
+                             env->gregs[0x10], 
+                             0);
+            env->gregs[0x10] = 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
+
 void usage(void)
 {
     printf("qemu-" TARGET_ARCH " version " QEMU_VERSION ", Copyright (c) 2003-2005 Fabrice Bellard\n"
@@ -1482,6 +1499,8 @@ int main(int argc, char **argv)
             }
         } else if (!strcmp(r, "g")) {
             gdbstub_port = atoi(argv[optind++]);
+       } else if (!strcmp(r, "r")) {
+           qemu_uname_release = argv[optind++];
         } else 
 #ifdef USE_CODE_COPY
         if (!strcmp(r, "no-code-copy")) {
@@ -1510,7 +1529,7 @@ int main(int argc, char **argv)
     env = cpu_init();
     global_env = env;
     
-    if (elf_exec(filename, argv+optind, environ, regs, info) != 0) {
+    if (loader_exec(filename, argv+optind, environ, regs, info) != 0) {
        printf("Error loading %s\n", filename);
        _exit(1);
     }
@@ -1521,6 +1540,7 @@ int main(int argc, char **argv)
         fprintf(logfile, "start_brk   0x%08lx\n" , info->start_brk);
         fprintf(logfile, "end_code    0x%08lx\n" , info->end_code);
         fprintf(logfile, "start_code  0x%08lx\n" , info->start_code);
+        fprintf(logfile, "start_data  0x%08lx\n" , info->start_data);
         fprintf(logfile, "end_data    0x%08lx\n" , info->end_data);
         fprintf(logfile, "start_stack 0x%08lx\n" , info->start_stack);
         fprintf(logfile, "brk         0x%08lx\n" , info->brk);
@@ -1535,6 +1555,7 @@ int main(int argc, char **argv)
     memset(ts, 0, sizeof(TaskState));
     env->opaque = ts;
     ts->used = 1;
+    ts->info = info;
     env->user_mode_only = 1;
     
 #if defined(TARGET_I386)
@@ -1664,6 +1685,18 @@ int main(int argc, char **argv)
             env->gpr[i] = regs->regs[i];
         }
         env->PC = regs->cp0_epc;
+#ifdef MIPS_USES_FPU
+        env->CP0_Status |= (1 << CP0St_CU1);
+#endif
+    }
+#elif defined(TARGET_SH4)
+    {
+        int i;
+
+        for(i = 0; i < 16; i++) {
+            env->gregs[i] = regs->regs[i];
+        }
+        env->pc = regs->pc;
     }
 #else
 #error unsupported target CPU