qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH] Support reset command for MIPS systems


From: Stefan Weil
Subject: [Qemu-devel] [PATCH] Support reset command for MIPS systems
Date: Thu, 07 Sep 2006 22:20:29 +0200
User-agent: Thunderbird 1.5.0.5 (X11/20060812)

Hello,

this patch adds support for MIPS system reset. I tried to copy
as much code as possible from the other architectures like
i386 which already supported reset.

If you have a working MIPS boot ROM at the reset address (0xbfc00000),
it is now possible to reboot your system like a real one.

Regards
Stefan


Index: hw/mips_r4k.c
===================================================================
RCS file: /sources/qemu/qemu/hw/mips_r4k.c,v
retrieving revision 1.19
diff -u -b -B -u -r1.19 mips_r4k.c
--- hw/mips_r4k.c       17 Aug 2006 10:45:20 -0000      1.19
+++ hw/mips_r4k.c       7 Sep 2006 19:51:11 -0000
@@ -189,6 +189,12 @@
     &io_readl,
 };
 
+static void main_cpu_reset(void *opaque)
+{
+    CPUState *env = opaque;
+    cpu_reset(env);
+}
+
 void mips_r4k_init (int ram_size, int vga_ram_size, int boot_device,
                     DisplayState *ds, const char **fd_filename, int snapshot,
                     const char *kernel_filename, const char *kernel_cmdline,
@@ -204,6 +210,7 @@
 
     env = cpu_init();
     register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
+    qemu_register_reset(main_cpu_reset, env);
 
     /* allocate RAM */
     cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
Index: target-mips/helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-mips/helper.c,v
retrieving revision 1.15
diff -u -b -B -u -r1.15 helper.c
--- target-mips/helper.c        26 Jun 2006 20:29:47 -0000      1.15
+++ target-mips/helper.c        7 Sep 2006 19:51:12 -0000
@@ -243,6 +243,39 @@
     return ret;
 }
 
+/* NOTE: must be called outside the CPU execute loop */
+void cpu_reset(CPUState *env)
+{
+#ifdef MIPS_USES_R4K_TLB
+    env->CP0_random = MIPS_TLB_NB - 1;
+#endif
+    env->CP0_Wired = 0;
+    env->CP0_Config0 = MIPS_CONFIG0;
+#if defined (MIPS_CONFIG1)
+    env->CP0_Config1 = MIPS_CONFIG1;
+#endif
+#if defined (MIPS_CONFIG2)
+    env->CP0_Config2 = MIPS_CONFIG2;
+#endif
+#if defined (MIPS_CONFIG3)
+    env->CP0_Config3 = MIPS_CONFIG3;
+#endif
+    env->CP0_WatchLo = 0;
+    env->CP0_Status = (1 << CP0St_CU0) | (1 << CP0St_BEV);
+    if (env->hflags & MIPS_HFLAG_BMASK) {
+        /* If the exception was raised from a delay slot,
+         * come back to the jump
+         */
+        env->CP0_ErrorEPC = env->PC - 4;
+        env->hflags &= ~MIPS_HFLAG_BMASK;
+    } else {
+        env->CP0_ErrorEPC = env->PC;
+    }
+    env->hflags |= MIPS_HFLAG_ERL;
+    env->CP0_Status |= (1 << CP0St_ERL);
+    env->PC = 0xBFC00000;
+}
+
 void do_interrupt (CPUState *env)
 {
     target_ulong pc, offset;
@@ -294,26 +327,11 @@
     enter_debug_mode:
         env->hflags |= MIPS_HFLAG_DM;
         /* EJTAG probe trap enable is not implemented... */
-        pc = 0xBFC00480;
+        env->PC = 0xBFC00480;
         break;
     case EXCP_RESET:
-#ifdef MIPS_USES_R4K_TLB
-        env->CP0_random = MIPS_TLB_NB - 1;
-#endif
-        env->CP0_Wired = 0;
-        env->CP0_Config0 = MIPS_CONFIG0;
-#if defined (MIPS_CONFIG1)
-        env->CP0_Config1 = MIPS_CONFIG1;
-#endif
-#if defined (MIPS_CONFIG2)
-        env->CP0_Config2 = MIPS_CONFIG2;
-#endif
-#if defined (MIPS_CONFIG3)
-        env->CP0_Config3 = MIPS_CONFIG3;
-#endif
-        env->CP0_WatchLo = 0;
-        env->CP0_Status = (1 << CP0St_CU0) | (1 << CP0St_BEV);
-        goto set_error_EPC;
+        cpu_reset(env);
+        break;
     case EXCP_SRESET:
         env->CP0_Status = (1 << CP0St_CU0) | (1 << CP0St_BEV) |
             (1 << CP0St_SR);
@@ -334,7 +352,7 @@
         }
         env->hflags |= MIPS_HFLAG_ERL;
        env->CP0_Status |= (1 << CP0St_ERL);
-        pc = 0xBFC00000;
+        env->PC = 0xBFC00000;
         break;
     case EXCP_MCHECK:
         cause = 24;
@@ -411,6 +429,7 @@
             env->CP0_EPC = env->PC;
             env->CP0_Cause &= ~0x80000000;
         }
+        env->PC = pc;
         break;
     default:
         if (logfile) {
@@ -420,7 +439,6 @@
         printf("Invalid MIPS exception %d. Exiting\n", env->exception_index);
         exit(1);
     }
-    env->PC = pc;
     if (logfile && env->exception_index != EXCP_EXT_INTERRUPT) {
         fprintf(logfile, "%s: PC %08x EPC %08x cause %d excp %d\n"
                 "    S %08x C %08x A %08x D %08x\n",

reply via email to

[Prev in Thread] Current Thread [Next in Thread]