--- ../qemu-CVS/qemu/hw/mips_malta.c	2007-02-02 23:57:24.000000000 +0300
+++ hw/mips_malta.c	2007-02-11 19:48:25.000000000 +0300
@@ -383,29 +383,21 @@
      a3 - RAM size in bytes
 */
 
-static void write_bootloader (CPUState *env, unsigned long bios_offset, int64_t kernel_addr)
+static void emulate_bootloader (CPUState *env, int64_t kernel_addr)
 {
     uint32_t *p;
 
-    /* Small bootloader */
-    p = (uint32_t *) (phys_ram_base + bios_offset);
-    stl_raw(p++, 0x0bf00010);                                      /* j 0x1fc00040 */
-    stl_raw(p++, 0x00000000);                                      /* nop */
-
-    /* Second part of the bootloader */
-    p = (uint32_t *) (phys_ram_base + bios_offset + 0x040);
-    stl_raw(p++, 0x3c040000);                                      /* lui a0, 0 */
-    stl_raw(p++, 0x34840002);                                      /* ori a0, a0, 2 */
-    stl_raw(p++, 0x3c050000 | ((ENVP_ADDR >> 16) & 0xffff));       /* lui a1, high(ENVP_ADDR) */
-    stl_raw(p++, 0x34a50000 | (ENVP_ADDR & 0xffff));               /* ori a1, a0, low(ENVP_ADDR) */
-    stl_raw(p++, 0x3c060000 | (((ENVP_ADDR + 8) >> 16) & 0xffff)); /* lui a2, high(ENVP_ADDR + 8) */
-    stl_raw(p++, 0x34c60000 | ((ENVP_ADDR + 8) & 0xffff));         /* ori a2, a2, low(ENVP_ADDR + 8) */
-    stl_raw(p++, 0x3c070000 | (env->ram_size >> 16));              /* lui a3, high(env->ram_size) */
-    stl_raw(p++, 0x34e70000 | (env->ram_size & 0xffff));           /* ori a3, a3, low(env->ram_size) */
-    stl_raw(p++, 0x3c1f0000 | ((kernel_addr >> 16) & 0xffff));     /* lui ra, high(kernel_addr) */;
-    stl_raw(p++, 0x37ff0000 | (kernel_addr & 0xffff));             /* ori ra, ra, low(kernel_addr) */
-    stl_raw(p++, 0x03e00008);                                      /* jr ra */
-    stl_raw(p++, 0x00000000);                                      /* nop */
+    env->gpr[4] = 2;			/* a0 */
+    env->gpr[5] = ENVP_ADDR;		/* a1 */
+    env->gpr[6] = (ENVP_ADDR + 8);	/* a2 */
+    env->gpr[7] = env->ram_size;	/* a3 */
+    env->PC = kernel_addr;
+
+    /* Stack frame (at 64-bit boudary) */
+    env->gpr[29] = (int32_t)(0x80004000-8);	/* SP */
+    p = (uint32_t *)(phys_ram_base +0x4000-8);
+    stl_raw(p++, 0);
+    stl_raw(p++, 0);
 }
 
 static void prom_set(int index, const char *string, ...)
@@ -481,13 +473,13 @@
 static void main_cpu_reset(void *opaque)
 {
     CPUState *env = opaque;
+    int64_t kernel_addr;
     cpu_reset(env);
 
-    /* The bootload does not need to be rewritten as it is located in a
-       read only location. The kernel location and the arguments table
-       location does not change. */
-    if (env->kernel_filename)
-        load_kernel (env);
+    if (env->kernel_filename) {
+        kernel_addr = load_kernel (env);
+        emulate_bootloader(env, kernel_addr);
+    }
 }
 
 void mips_malta_init (int ram_size, int vga_ram_size, int boot_device,
@@ -528,7 +520,7 @@
         env->kernel_cmdline = kernel_cmdline;
         env->initrd_filename = initrd_filename;
         kernel_addr = load_kernel(env);
-        write_bootloader(env, bios_offset, kernel_addr);
+        emulate_bootloader(env, kernel_addr);
     } else {
         snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);
         ret = load_image(buf, phys_ram_base + bios_offset);
