qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] Add MIPS ELF loader
@ 2006-03-28  6:57 Dirk Behme
  2006-03-28 13:01 ` Thiemo Seufer
  2006-04-23 17:16 ` Fabrice Bellard
  0 siblings, 2 replies; 16+ messages in thread
From: Dirk Behme @ 2006-03-28  6:57 UTC (permalink / raw)
  To: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 466 bytes --]

Hi,

ELF loader feature for MIPS in patch

http://lists.gnu.org/archive/html/qemu-devel/2006-03/msg00033.html

was rejected because it breaks loading of raw kernel images:

http://lists.gnu.org/archive/html/qemu-devel/2006-03/msg00082.html

What about the patch in attachment? It first tries to load
image as an ELF file. If this fails it falls back to raw
image load. Additionally, it takes feature of patch above to
go on even if no BIOS is found.

Regards

Dirk


[-- Attachment #2: mips_elf_load.txt --]
[-- Type: text/plain, Size: 7148 bytes --]

--- ./hw/mips_r4k.c_orig	2006-03-28 07:48:21.000000000 +0200
+++ ./hw/mips_r4k.c	2006-03-28 08:52:18.000000000 +0200
@@ -5,6 +5,30 @@
 #define KERNEL_LOAD_ADDR 0x80010000
 #define INITRD_LOAD_ADDR 0x80800000
 
+#include "disas.h"
+
+#define ELF_CLASS   ELFCLASS32
+#ifdef TARGET_WORDS_BIGENDIAN
+# define ELF_DATA    ELFDATA2MSB
+#else
+# define ELF_DATA    ELFDATA2LSB
+#endif
+#define ELF_ARCH    EM_MIPS
+
+#include "elf.h"
+
+#ifndef BSWAP_NEEDED
+#define bswap_ehdr32(e) do { } while (0)
+#define bswap_phdr32(e) do { } while (0)
+#define bswap_shdr32(e) do { } while (0)
+#define bswap_sym32(e) do { } while (0)
+#endif
+
+#define SZ             32
+#define elf_word        uint32_t
+#define bswapSZs       bswap32s
+#include "elf_ops.h"
+
 extern FILE *logfile;
 
 static PITState *pit;
@@ -101,6 +125,83 @@ void cpu_mips_clock_init (CPUState *env)
     cpu_mips_update_count(env, 1, 0);
 }
 
+static int load_mips_kernel_elf(const char *filename, elf_word *entry)
+{
+    struct elf32_hdr ehdr;
+    int retval, fd, i;
+    Elf32_Half machine;
+
+    fd = open(filename, O_RDONLY | O_BINARY);
+    if (fd < 0)
+       goto error;
+
+    retval = read(fd, &ehdr, sizeof(ehdr));
+    if (retval < 0)
+       goto error;
+
+    if (ehdr.e_ident[0] != 0x7f || ehdr.e_ident[1] != 'E'
+       || ehdr.e_ident[2] != 'L' || ehdr.e_ident[3] != 'F')
+       goto error;
+    machine = tswap16(ehdr.e_machine);
+    if (machine == EM_MIPS) {
+       struct elf32_phdr phdr;
+
+       bswap_ehdr32(&ehdr);
+
+       *entry = ehdr.e_entry;
+       retval = lseek(fd, ehdr.e_phoff, SEEK_SET);
+       if (retval < 0)
+           goto error;
+
+       for (i = 0; i < ehdr.e_phnum; i++) {
+           retval = read(fd, &phdr, sizeof(phdr));
+           if (retval < 0)
+               goto error;
+           bswap_phdr32(&phdr);
+           if (phdr.p_type == PT_LOAD) {
+               uint8_t *addr;
+               size_t sz = phdr.p_filesz;
+
+               if (phdr.p_vaddr < 0x80000000
+                   || phdr.p_memsz > 0x20000000
+                   || (phdr.p_vaddr < 0xa0000000 && (phdr.p_vaddr + 
+phdr.p_memsz) >= 0xa0000000)
+                   || (phdr.p_vaddr < 0xc0000000 && (phdr.p_vaddr + 
+phdr.p_memsz) >= 0xc0000000))
+                   goto error;
+               addr = (uint8_t *)(phys_ram_base + (phdr.p_vaddr & 0x1fffffff));
+               retval = lseek(fd, phdr.p_offset, SEEK_SET);
+               if (retval < 0)
+                   goto error;
+               while (sz) {
+                   retval = read(fd, addr, sz);
+                   switch (retval) {
+                   case -1:
+                       goto error;
+                   case 0: /* EOF */
+                       if (sz)
+                           goto error;
+                       break;
+                   default:
+                       if (sz < retval)
+                           goto error;
+                       sz -= retval;
+                       retval = 0;
+                       break;
+                   }
+               }
+           }
+       }
+       load_symbols32(&ehdr, fd);
+    }
+
+    close(fd);
+    return retval;
+error:
+    close(fd);
+    return -1;
+}
+
 static void io_writeb (void *opaque, target_phys_addr_t addr, uint32_t value)
 {
 #if 0
@@ -191,12 +292,12 @@ void mips_r4k_init (int ram_size, int vg
     char buf[1024];
     target_ulong kernel_base, kernel_size, initrd_base, initrd_size;
     unsigned long bios_offset;
+    elf_word entry = 0;
     int io_memory;
     int linux_boot;
     int ret;
     CPUState *env;
 
-    printf("%s: start\n", __func__);
     linux_boot = (kernel_filename != NULL);
 
     env = cpu_init();
@@ -204,47 +305,59 @@ void mips_r4k_init (int ram_size, int vg
 
     /* allocate RAM */
     cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
+
+    /* Try to load a BIOS image. If this fails, we continue regardless */
     bios_offset = ram_size + vga_ram_size;
     snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);
-    printf("%s: load BIOS '%s' size %d\n", __func__, buf, BIOS_SIZE);
     ret = load_image(buf, phys_ram_base + bios_offset);
-    if (ret != BIOS_SIZE) {
-        fprintf(stderr, "qemu: could not load MIPS bios '%s'\n", buf);
-        exit(1);
+    if (ret == BIOS_SIZE) {
+       cpu_register_physical_memory((uint32_t)(0x1fc00000),
+                                    BIOS_SIZE, bios_offset | IO_MEM_ROM);
+       env->PC = 0xBFC00000;
+       printf("qemu: successfully loaded BIOS '%s' size %d\n", buf, BIOS_SIZE);
+       if (!kernel_filename)
+           return;
+    } else {
+       /* not fatal */
+        fprintf(stderr, "%s: Warning, could not load MIPS bios '%s', go on anyway\n",
+                __func__, buf);
     }
-    cpu_register_physical_memory((uint32_t)(0x1fc00000),
-                                 BIOS_SIZE, bios_offset | IO_MEM_ROM);
-#if 0
-    memcpy(phys_ram_base + 0x10000, phys_ram_base + bios_offset, BIOS_SIZE);
-    env->PC = 0x80010004;
-#else
-    env->PC = 0xBFC00004;
-#endif
     if (linux_boot) {
-        kernel_base = KERNEL_LOAD_ADDR;
-        /* now we can load the kernel */
-        kernel_size = load_image(kernel_filename,
-                                phys_ram_base + (kernel_base - 0x80000000));
-        if (kernel_size == (target_ulong) -1) {
-            fprintf(stderr, "qemu: could not load kernel '%s'\n", 
-                    kernel_filename);
-            exit(1);
-        }
+        /* load kernel. First try to load ELF file, if this fails
+           fall back to standard raw binary image */
+        if (!load_mips_kernel_elf(kernel_filename, &entry)) {
+	     env->PC = entry;
+	} else {
+	     /* ELF file load failed, seems to be a raw binary image */
+             kernel_base = KERNEL_LOAD_ADDR;
+	     /* now we can load the kernel */
+	     kernel_size = load_image(kernel_filename,
+				      phys_ram_base + (kernel_base - 0x80000000));
+	     if (kernel_size == (target_ulong) -1) {
+	          fprintf(stderr, "%s: could not load kernel '%s'\n", 
+                          __func__, kernel_filename);
+	          exit(1);
+	     }
+	     env->PC = KERNEL_LOAD_ADDR;
+	}
+        printf("qemu: successfully loaded '%s' to start address 0x%08x\n", 
+	        kernel_filename, env->PC);
+
         /* load initrd */
         if (initrd_filename) {
             initrd_base = INITRD_LOAD_ADDR;
             initrd_size = load_image(initrd_filename,
                                      phys_ram_base + initrd_base);
             if (initrd_size == (target_ulong) -1) {
-                fprintf(stderr, "qemu: could not load initial ram disk '%s'\n", 
-                        initrd_filename);
+                fprintf(stderr, "%s: could not load initial ram disk '%s'\n", 
+                        __func__, initrd_filename);
                 exit(1);
             }
         } else {
             initrd_base = 0;
             initrd_size = 0;
         }
-        env->PC = KERNEL_LOAD_ADDR;
+  
 	/* Store command line.  */
         strcpy (phys_ram_base + (16 << 20) - 256, kernel_cmdline);
         /* FIXME: little endian support */


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Qemu-devel] [PATCH] Add MIPS ELF loader
  2006-03-28  6:57 [Qemu-devel] [PATCH] Add MIPS ELF loader Dirk Behme
@ 2006-03-28 13:01 ` Thiemo Seufer
  2006-03-30 13:40   ` Dirk Behme
  2006-04-23 17:16 ` Fabrice Bellard
  1 sibling, 1 reply; 16+ messages in thread
From: Thiemo Seufer @ 2006-03-28 13:01 UTC (permalink / raw)
  To: qemu-devel

On Tue, Mar 28, 2006 at 08:57:15AM +0200, Dirk Behme wrote:
> Hi,
> 
> ELF loader feature for MIPS in patch
> 
> http://lists.gnu.org/archive/html/qemu-devel/2006-03/msg00033.html
> 
> was rejected because it breaks loading of raw kernel images:
> 
> http://lists.gnu.org/archive/html/qemu-devel/2006-03/msg00082.html
> 
> What about the patch in attachment? It first tries to load
> image as an ELF file. If this fails it falls back to raw
> image load. Additionally, it takes feature of patch above to
> go on even if no BIOS is found.

A slightly more polished version with less noisy messages is appended.
It also adjusts the ramdisk load address to physical addressing,
similiar to the binary kernel load.


Thiemo


Index: qemu-work/hw/mips_r4k.c
===================================================================
--- qemu-work.orig/hw/mips_r4k.c	2006-03-28 12:27:55.000000000 +0100
+++ qemu-work/hw/mips_r4k.c	2006-03-28 13:49:10.000000000 +0100
@@ -1,6 +1,8 @@
 #define KERNEL_LOAD_ADDR 0x80010000
 #define INITRD_LOAD_ADDR 0x80800000
 
+#define PHYSADDR(addr) ((addr) & 0x1fffffff)
+
 extern FILE *logfile;
 
 static PITState *pit;
@@ -101,6 +105,108 @@
     cpu_mips_update_count(env, 1, 0);
 }
 
+#include "disas.h"
+
+#define ELF_CLASS   ELFCLASS32
+#ifdef TARGET_WORDS_BIGENDIAN
+# define ELF_DATA    ELFDATA2MSB
+#else
+# define ELF_DATA    ELFDATA2LSB
+#endif
+#define ELF_ARCH    EM_MIPS
+
+#include "elf.h"
+
+#ifndef BSWAP_NEEDED
+#define bswap_ehdr32(e) do { } while (0)
+#define bswap_phdr32(e) do { } while (0)
+#define bswap_shdr32(e) do { } while (0)
+#define bswap_sym32(e) do { } while (0)
+#endif
+
+#define SZ		32
+#define elf_word        uint32_t
+#define bswapSZs	bswap32s
+#include "elf_ops.h"
+
+static int load_mips_kernel_elf(const char *filename, elf_word *entry)
+{
+    struct elf32_hdr ehdr;
+    int retval, fd, i;
+    Elf32_Half machine;
+
+    fd = open(filename, O_RDONLY | O_BINARY);
+    if (fd < 0)
+	goto error;
+
+    retval = read(fd, &ehdr, sizeof(ehdr));
+    if (retval < 0)
+	goto error;
+
+    if (ehdr.e_ident[0] != 0x7f || ehdr.e_ident[1] != 'E'
+	|| ehdr.e_ident[2] != 'L' || ehdr.e_ident[3] != 'F')
+	goto error;
+    machine = tswap16(ehdr.e_machine);
+    if (machine == EM_MIPS) {
+	struct elf32_phdr phdr;
+
+	bswap_ehdr32(&ehdr);
+
+	*entry = ehdr.e_entry;
+	retval = lseek(fd, ehdr.e_phoff, SEEK_SET);
+	if (retval < 0)
+	    goto error;
+
+	for (i = 0; i < ehdr.e_phnum; i++) {
+	    retval = read(fd, &phdr, sizeof(phdr));
+	    if (retval < 0)
+		goto error;
+	    bswap_phdr32(&phdr);
+	    if (phdr.p_type == PT_LOAD) {
+		uint8_t *addr;
+		size_t sz = phdr.p_filesz;
+
+		if (phdr.p_vaddr < 0x80000000
+		    || phdr.p_memsz > 0x20000000
+		    || (phdr.p_vaddr < 0xa0000000
+			&& (phdr.p_vaddr + phdr.p_memsz) >= 0xa0000000)
+		    || (phdr.p_vaddr < 0xc0000000
+			&& (phdr.p_vaddr + phdr.p_memsz) >= 0xc0000000))
+		    goto error;
+		addr = (uint8_t *)(phys_ram_base + PHYSADDR(phdr.p_vaddr));
+		retval = lseek(fd, phdr.p_offset, SEEK_SET);
+		if (retval < 0)
+		    goto error;
+		while (sz) {
+		    retval = read(fd, addr, sz);
+		    switch (retval) {
+		    case -1:
+			goto error;
+		    case 0: /* EOF */
+			if (sz)
+			    goto error;
+			break;
+		    default:
+			if (sz < retval)
+			    goto error;
+			sz -= retval;
+			retval = 0;
+			break;
+		    }
+		}
+	    }
+	}
+	load_symbols32(&ehdr, fd);
+    }
+
+    close(fd);
+    return retval;
+ error:
+    close(fd);
+    return -1;
+}
+
+
 static void io_writeb (void *opaque, target_phys_addr_t addr, uint32_t value)
 {
 #if 0
@@ -183,72 +319,70 @@
                     const char *initrd_filename)
 {
     char buf[1024];
-    target_ulong kernel_base, kernel_size, initrd_base, initrd_size;
+    elf_word entry = 0;
     unsigned long bios_offset;
     int io_memory;
-    int linux_boot;
     int ret;
     CPUState *env;
-
-    printf("%s: start\n", __func__);
-    linux_boot = (kernel_filename != NULL);
+    int i;
 
     env = cpu_init();
     register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
 
     /* allocate RAM */
     cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
+
+    /* Try to load a BIOS image. If this fails, we continue regardless,
+       but initialize the hardware ourselves. When a kernel gets
+       preloaded we also initialize the hardware, since the BIOS wasn't
+       run. */
     bios_offset = ram_size + vga_ram_size;
     snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);
     printf("%s: load BIOS '%s' size %d\n", __func__, buf, BIOS_SIZE);
     ret = load_image(buf, phys_ram_base + bios_offset);
-    if (ret != BIOS_SIZE) {
-        fprintf(stderr, "qemu: could not load MIPS bios '%s'\n", buf);
-        exit(1);
+    if (ret == BIOS_SIZE) {
+	cpu_register_physical_memory((uint32_t)(0x1fc00000),
+				     BIOS_SIZE, bios_offset | IO_MEM_ROM);
+	env->PC = 0xBFC00000;
+	if (!kernel_filename)
+	    return;
+    } else {
+	/* not fatal */
+        fprintf(stderr, "qemu: Warning, could not load MIPS bios '%s'\n",
+		buf);
     }
-    cpu_register_physical_memory((uint32_t)(0x1fc00000),
-                                 BIOS_SIZE, bios_offset | IO_MEM_ROM);
-#if 0
-    memcpy(phys_ram_base + 0x10000, phys_ram_base + bios_offset, BIOS_SIZE);
-    env->PC = 0x80010004;
-#else
-    env->PC = 0xBFC00004;
-#endif
-    if (linux_boot) {
-        kernel_base = KERNEL_LOAD_ADDR;
-        /* now we can load the kernel */
-        kernel_size = load_image(kernel_filename,
-                                phys_ram_base + (kernel_base - 0x80000000));
-        if (kernel_size == (target_ulong) -1) {
-            fprintf(stderr, "qemu: could not load kernel '%s'\n", 
-                    kernel_filename);
-            exit(1);
-        }
+
+    if (kernel_filename) {
+	if (!load_mips_kernel_elf(kernel_filename, &entry))
+	    env->PC = entry;
+	else {
+	    /* try to load as binary image */
+            if (load_image(kernel_filename,
+			   phys_ram_base + PHYSADDR(KERNEL_LOAD_ADDR))
+		== (target_ulong) -1) {
+		fprintf(stderr, "qemu: could not load kernel '%s'\n",
+			kernel_filename);
+                exit(1);
+            }
+	    env->PC = KERNEL_LOAD_ADDR;
+	}
+
         /* load initrd */
         if (initrd_filename) {
-            initrd_base = INITRD_LOAD_ADDR;
-            initrd_size = load_image(initrd_filename,
-                                     phys_ram_base + initrd_base);
-            if (initrd_size == (target_ulong) -1) {
+            if (load_image(initrd_filename,
+			   phys_ram_base + PHYSADDR(INITRD_LOAD_ADDR))
+		== (target_ulong) -1) {
                 fprintf(stderr, "qemu: could not load initial ram disk '%s'\n", 
                         initrd_filename);
                 exit(1);
             }
-        } else {
-            initrd_base = 0;
-            initrd_size = 0;
         }
-        env->PC = KERNEL_LOAD_ADDR;
+
 	/* Store command line.  */
         strcpy (phys_ram_base + (16 << 20) - 256, kernel_cmdline);
         /* FIXME: little endian support */
         *(int *)(phys_ram_base + (16 << 20) - 260) = tswap32 (0x12345678);
         *(int *)(phys_ram_base + (16 << 20) - 264) = tswap32 (ram_size);
-    } else {
-        kernel_base = 0;
-        kernel_size = 0;
-        initrd_base = 0;
-        initrd_size = 0;
     }
 
     /* Init internal devices */

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Qemu-devel] [PATCH] Add MIPS ELF loader
  2006-03-28 13:01 ` Thiemo Seufer
@ 2006-03-30 13:40   ` Dirk Behme
  2006-03-30 13:53     ` Thiemo Seufer
  0 siblings, 1 reply; 16+ messages in thread
From: Dirk Behme @ 2006-03-30 13:40 UTC (permalink / raw)
  To: qemu-devel

Thiemo Seufer wrote:
> On Tue, Mar 28, 2006 at 08:57:15AM +0200, Dirk Behme wrote:
>>What about the patch in attachment? It first tries to load
>>image as an ELF file. If this fails it falls back to raw
>>image load. Additionally, it takes feature of patch above to
>>go on even if no BIOS is found.
> 
> 
> A slightly more polished version with less noisy messages is appended.
> It also adjusts the ramdisk load address to physical addressing,
> similiar to the binary kernel load.

One question I just found:

If we go on if no BIOS is found/executed and we load some 
stuff to e.g. 0x80010000, where is the default address 
translation made? As I understand MIPS, code in kseg0 
(0x80000000) and kseg1 (0xA0000000) should be executable 
without MMU/TLB setup because it is mapped by default to 
physical 0x0. But looks to me that I get a

cpu_mips_handle_mmu_fault pc 80010000 ad 80010000 rw 2 
is_user 0 smmu 1

for it.

Dirk

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Qemu-devel] [PATCH] Add MIPS ELF loader
  2006-03-30 13:40   ` Dirk Behme
@ 2006-03-30 13:53     ` Thiemo Seufer
  2006-03-30 14:29       ` Alexander Voropay
  0 siblings, 1 reply; 16+ messages in thread
From: Thiemo Seufer @ 2006-03-30 13:53 UTC (permalink / raw)
  To: qemu-devel

On Thu, Mar 30, 2006 at 03:40:25PM +0200, Dirk Behme wrote:
> Thiemo Seufer wrote:
> >On Tue, Mar 28, 2006 at 08:57:15AM +0200, Dirk Behme wrote:
> >>What about the patch in attachment? It first tries to load
> >>image as an ELF file. If this fails it falls back to raw
> >>image load. Additionally, it takes feature of patch above to
> >>go on even if no BIOS is found.
> >
> >
> >A slightly more polished version with less noisy messages is appended.
> >It also adjusts the ramdisk load address to physical addressing,
> >similiar to the binary kernel load.
> 
> One question I just found:
> 
> If we go on if no BIOS is found/executed and we load some 
> stuff to e.g. 0x80010000, where is the default address 
> translation made? As I understand MIPS, code in kseg0 
> (0x80000000) and kseg1 (0xA0000000) should be executable 
> without MMU/TLB setup because it is mapped by default to 
> physical 0x0. But looks to me that I get a
> 
> cpu_mips_handle_mmu_fault pc 80010000 ad 80010000 rw 2 
> is_user 0 smmu 1

That comes not from the MIPS TLB mapping (which is for KSEG0/1 a fixed
translation involving the high bits) but the underlying qemu softmmu
support.

The whole thing works but eats significant performance, there should
be room for improvements.


Thiemo

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Qemu-devel] [PATCH] Add MIPS ELF loader
  2006-03-30 13:53     ` Thiemo Seufer
@ 2006-03-30 14:29       ` Alexander Voropay
  2006-03-30 17:34         ` Dirk Behme
       [not found]         ` <442C0F57.3010200@gmail.com>
  0 siblings, 2 replies; 16+ messages in thread
From: Alexander Voropay @ 2006-03-30 14:29 UTC (permalink / raw)
  To: qemu-devel

"Thiemo Seufer" <ths@networkno.de> wrote:

>> cpu_mips_handle_mmu_fault pc 80010000 ad 80010000 rw 2 
>> is_user 0 smmu 1
> 
> That comes not from the MIPS TLB mapping (which is for KSEG0/1 a fixed
> translation involving the high bits) but the underlying qemu softmmu
> support.

 I'm trying to implement a mips_bios, unfortunately, quemu seems can't
run a code at the 0xbfc00000 region.

 See a http://pastebin.com/628591

 The conventional 'move k0,zero' instruction (line 35) causes an general
exceprion to 0xbfc00380, see line 70

--
-=AV=-

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Qemu-devel] [PATCH] Add MIPS ELF loader
  2006-03-30 14:29       ` Alexander Voropay
@ 2006-03-30 17:34         ` Dirk Behme
       [not found]         ` <442C0F57.3010200@gmail.com>
  1 sibling, 0 replies; 16+ messages in thread
From: Dirk Behme @ 2006-03-30 17:34 UTC (permalink / raw)
  To: Alexander Voropay, qemu-devel

Alexander Voropay wrote:
> I'm trying to implement a mips_bios, unfortunately, quemu seems can't
> run a code at the 0xbfc00000 region.
> 
> See a http://pastebin.com/628591
> 
> The conventional 'move k0,zero' instruction (line 35) causes an general
> exceprion to 0xbfc00380, see line 70

Try to change the following lines in hw/mips_r4k.c:

//#define KERNEL_LOAD_ADDR 0x80010000
#define KERNEL_LOAD_ADDR 0xBFC00000

//cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
cpu_register_physical_memory(0x1fc00000, ram_size, IO_MEM_RAM);

//kernel_size = load_image(kernel_filename,
//	 		      phys_ram_base + (kernel_base - 0x80000000));
kernel_size = load_image(kernel_filename, phys_ram_base);

Works for me:

(gdb) p/x $pc
$1 = 0xbfc00000
(gdb) x/2i $pc
0xbfc00000 <_start>:    b       0xbfc00400 <reset>
0xbfc00004 <_start+4>:  nop
(gdb) x/2i 0x1fc00000
0x1fc00000:     b       0x1fc00400
0x1fc00004:     nop
(gdb)

Best regards

Dirk

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Qemu-devel] [PATCH] Add MIPS ELF loader
       [not found]         ` <442C0F57.3010200@gmail.com>
@ 2006-04-02 12:54           ` Alexander Voropay
  0 siblings, 0 replies; 16+ messages in thread
From: Alexander Voropay @ 2006-04-02 12:54 UTC (permalink / raw)
  To: Dirk Behme, qemu-devel

"Dirk Behme" <dirk.behme@googlemail.com> wrote:
>> See a http://pastebin.com/628591
> Sorry, does this link really work? I get a nearly empty page  for this.

Ah, pastebin keeps data only a day.

> I'm working on something similiar, if you want to call an 
> embedded bootloader like uboot a BIOS ;)  Anyway, I need to 
> execute mips assembly starting from 0xbfc00000 as well.

 I'm trying to port a mmon:
http://www.brouhaha.com/~eric/software/mmon/
It's fairly simply MIPS monitor which requires only ~200 bytes
and a working 16c550 UART.

> I think it should be possible to switch to 0xbfc00000 by 
> adjusting the addresses in
> hw/mips_r4k.c

 Things are more complicated. There should be two mode for the MIPS
emulator : to run MIPS BIOS/Monitor after a "full hardwere reset" and
to run a Linux kernel with "pre-initialized hardware".
MIPS Monitor should run in the BEV mode (Boot Exception Vector)
to use vectors like 0xbfc00380 while Linux should use 0x80000380.
This state is controlled under the SR[BEV] CP0 register.
GXEmul has a special -Q swith to run MIPS emulation in the BEV mode.

 There is another bug : for unknown reason, Qemu start BIOS execution
from the 0xbfc00004, not from the first address, see a hw/mips_r4k.c:221
I've just changet it to the 0xbfc00000

 In the current Qemu-CVS it is possible fo pass a control to the BIOS region
0xbfc00000. Just omit a "-kernel" option and use a dummy MIPS ELF
file as a parameter. This file may contain just a series of zeros (NOPs).
Qemu will start execution of the binary 'mips_bios.bin' at the 0xbfc00000
(except 0xbfc00004 bug).

>Try to change the following lines in hw/mips_r4k.c:
>cpu_register_physical_memory(0x1fc00000, ram_size, IO_MEM_RAM);

 This already done in the CVS hw/mips_r4k.c:215

 Look at the my mmon-qemu port:
http://www.nwpi.ru/~alec/mips/mmon-quemu-0.5.tgz
It uses a dummy 'reset' ELF file to run a mips_bios.bin .

 You could find my qemu.log there:
http://www.nwpi.ru/~alec/mips/qemu_log.txt
It goes into infinity exception loop. The command string was
$ qemu-system-mips -d out_asm,in_asm,op,int,exec,cpu -m 16 -nographic reset
The mips_bios.bin is a my port of 'mmon'.


P.S. JFYI: A good explanation of the MIPS reset:
http://www.amd.com/files/connectivitysolutions/aufamily/au1000/Au1000Reset_rev1.2.pdf

--
-=AV=-

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Qemu-devel] [PATCH] Add MIPS ELF loader
       [not found] <154e01c66453$111e4f20$e90d11ac@spb.in.rosprint.ru>
@ 2006-04-20 10:16 ` Marius Groeger
  2006-04-20 10:28   ` Thiemo Seufer
  0 siblings, 1 reply; 16+ messages in thread
From: Marius Groeger @ 2006-04-20 10:16 UTC (permalink / raw)
  To: Alexander Voropay; +Cc: qemu-devel

Hi Alex,

> I've written to the qemu-devel list, no answers.

I copied the list.

> You could find my qemu.log there:
> http://www.nwpi.ru/~alec/mips/qemu_log.txt
> It goes into infinity exception loop. The command string was

I'm not quite sure why but you're getting a RI exception on the 
address 0xbfc00008 wich is the "move k0, zero" in the delay slot. I 
don't see a problem in the code, but have you tried this sequence?

   move k0, zero
   j	   0xbfc00400
   nop

Marius

-- 
Marius Groeger <mgroeger@sysgo.com>
SYSGO AG                      Embedded and Real-Time Software
Voice: +49 6136 9948 0                  FAX: +49 6136 9948 10
www.sysgo.com | www.elinos.com | www.osek.de | www.pikeos.com

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Qemu-devel] [PATCH] Add MIPS ELF loader
  2006-04-20 10:16 ` [Qemu-devel] [PATCH] Add MIPS ELF loader Marius Groeger
@ 2006-04-20 10:28   ` Thiemo Seufer
  2006-04-20 11:02     ` Alexander Voropay
  0 siblings, 1 reply; 16+ messages in thread
From: Thiemo Seufer @ 2006-04-20 10:28 UTC (permalink / raw)
  To: qemu-devel

Marius Groeger wrote:
> Hi Alex,
> 
> >I've written to the qemu-devel list, no answers.
> 
> I copied the list.
> 
> >You could find my qemu.log there:
> >http://www.nwpi.ru/~alec/mips/qemu_log.txt
> >It goes into infinity exception loop. The command string was
> 
> I'm not quite sure why but you're getting a RI exception on the 
> address 0xbfc00008 wich is the "move k0, zero" in the delay slot. I 
> don't see a problem in the code, but have you tried this sequence?
> 
>   move k0, zero
>   j	   0xbfc00400
>   nop

Is the move implemented as addiu or as daddiu? The latter would RI.


Thiemo

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Qemu-devel] [PATCH] Add MIPS ELF loader
  2006-04-20 10:28   ` Thiemo Seufer
@ 2006-04-20 11:02     ` Alexander Voropay
  2006-04-20 12:19       ` Alexander Voropay
  0 siblings, 1 reply; 16+ messages in thread
From: Alexander Voropay @ 2006-04-20 11:02 UTC (permalink / raw)
  To: qemu-devel, Thiemo Seufer

"Thiemo Seufer" <ths@networkno.de> wrote:

>> >You could find my qemu.log there:
>> >http://www.nwpi.ru/~alec/mips/qemu_log.txt
>> >It goes into infinity exception loop. 
>> 
>> I'm not quite sure why but you're getting a RI exception on the 
>> address 0xbfc00008 wich is the "move k0, zero" in the delay slot. I 
>> don't see a problem in the code, but have you tried this sequence?
>> 
>>   move k0, zero
>>   j    0xbfc00400
>>   nop
> 
> Is the move implemented as addiu or as daddiu? The latter would RI.

 Oh! It was daddu (gcc -mips3) opcode.

 Thank you!

 Can someone add a path to make a log more readable (exception cause decode).

 The disassembler should be improved too, to mark a 64-bit opcodes as invalid
for MIPS32...

--
-=AV=-

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Qemu-devel] [PATCH] Add MIPS ELF loader
  2006-04-20 11:02     ` Alexander Voropay
@ 2006-04-20 12:19       ` Alexander Voropay
  2006-04-21 12:35         ` [Qemu-devel] CP0 after reset bug (Was: Add MIPS ELF loader) Alexander Voropay
  0 siblings, 1 reply; 16+ messages in thread
From: Alexander Voropay @ 2006-04-20 12:19 UTC (permalink / raw)
  To: qemu-devel

>>>   move k0, zero
>>>   j    0xbfc00400
>>>   nop
>> 
>> Is the move implemented as addiu or as daddiu? The latter would RI.
> 
> Oh! It was daddu (gcc -mips3) opcode.

 Another issue:

mtc0  zero, C0_CAUSE

===============
IN:
0xbfc00424:  mtc0       zero,$13

OP:
0x0000: save_pc 0xbfc00424
0x0001: raise_exception 0x11
0x0002: reset_T0
0x0003: exit_tb
0x0004: end

---------------- 3 00000000
OUT: [size=24]
0x08a96a90:  movl   $0xbfc00424,0x80(%ebp)
0x08a96a9a:  push   $0x11
0x08a96a9f:  call   0x8080fe8
0x08a96aa4:  pop    %eax
0x08a96aa5:  xor    %ebx,%ebx
0x08a96aa7:  ret

do_raise_exception_err: 17 0
do_interrupt enter: PC bfc00424 EPC 00000000 cause -1 excp 17
do_interrupt: PC bfc00380 EPC bfc00424 cause 11 excp 17
    S 00400000 C 0000042c A 00000000 D 00000000
------------------------------------------------
pc=0xbfc00380 HI=0x00000000 LO=0x00000000 ds 0004 00000000 0
GPR00: r0 00000000 at 00400000 v0 00400000 v1 00000000
GPR04: a0 00000000 a1 00000000 a2 00000000 a3 00000000
GPR08: t0 00018000 t1 00000000 t2 00000000 t3 00000000
GPR12: t4 00000000 t5 00000000 t6 00000000 t7 00000000
GPR16: s0 00000000 s1 00000000 s2 00000000 s3 00000000
GPR20: s4 00000000 s5 00000000 s6 00000000 s7 00000000
GPR24: t8 00000000 t9 00000000 k0 00000000 k1 00000000
GPR28: gp 00000000 sp 00000000 s8 00000000 ra 00000000
CP0 Status  0x00400002 Cause   0x0000042c EPC    0xbfc00424
    Config0 0x80008090 Config1 0x1e190c8a LLAddr 0x00000000
IN:
0xbfc00380:  j  0xbfc019c0

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Qemu-devel] CP0 after reset bug (Was: Add MIPS ELF loader)
  2006-04-20 12:19       ` Alexander Voropay
@ 2006-04-21 12:35         ` Alexander Voropay
  2006-04-21 12:51           ` Thiemo Seufer
  0 siblings, 1 reply; 16+ messages in thread
From: Alexander Voropay @ 2006-04-21 12:35 UTC (permalink / raw)
  To: qemu-devel

"Alexander Voropay" <a.voropay@equant.ru> wrote:

> Another issue:
> 
> IN:
> 0xbfc00424:  mtc0       zero,$13
> 0x0001: raise_exception 0x11

 The problem is a code *before* this :
==========
        mfc0    v0,C0_SR
        and     v0,SR_SR                # preserve Soft Reset
        or      v0,SR_BEV               # set Boot Exceptions

        mtc0    v0,C0_SR                # 32 bit, kernel mode, bootstrap
        mtc0    zero,C0_CAUSE     # <-- TRAP there !!!
==========

 This code is a cut'n'paste from the "See MIPS Run" p.338

 Unfortunately, this code clears CU0  bits in the CP0(SR).
It makes CP0 unusable for program and causes an exception 11 :
Coprocessor Unusable on the next CP0 access.

 The Qemu has a bug there. The "See MIPS Run" p.51 states:

CU0 - Coprocessor 0 usable; Set 1 to be able to use some nominally
priveleged instructions in the user mode. You don't want to do this.
The CPU control instructions encoded as coprocessor 0 type are
always usable in kernel mode, regardless of the setting of this bit.

 Qemu does simply check:
./target-mips/translate.c:1181
===================
    if (!(ctx->CP0_Status & (1 << CP0St_CU0)) &&
        !(ctx->hflags & MIPS_HFLAG_UM) &&
        !(ctx->hflags & MIPS_HFLAG_ERL) &&
        !(ctx->hflags & MIPS_HFLAG_EXL)) {
        if (loglevel & CPU_LOG_TB_IN_ASM) {
            fprintf(logfile, "CP0 is not usable\n");
        }
        generate_exception_err (ctx, EXCP_CpU, 0);
        return;
===================

 This check is not enought to emulate a Coprocessor Unusable
situation on Reset (when CPU is in the kernel mode).

--
-=AV=-

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Qemu-devel] CP0 after reset bug (Was: Add MIPS ELF loader)
  2006-04-21 12:35         ` [Qemu-devel] CP0 after reset bug (Was: Add MIPS ELF loader) Alexander Voropay
@ 2006-04-21 12:51           ` Thiemo Seufer
  2006-04-21 14:29             ` Alexander Voropay
  0 siblings, 1 reply; 16+ messages in thread
From: Thiemo Seufer @ 2006-04-21 12:51 UTC (permalink / raw)
  To: Alexander Voropay, qemu-devel

Alexander Voropay wrote:
[snip]
> Unfortunately, this code clears CU0  bits in the CP0(SR).
> It makes CP0 unusable for program and causes an exception 11 :
> Coprocessor Unusable on the next CP0 access.
> 
> The Qemu has a bug there. The "See MIPS Run" p.51 states:
> 
> CU0 - Coprocessor 0 usable; Set 1 to be able to use some nominally
> priveleged instructions in the user mode. You don't want to do this.
> The CPU control instructions encoded as coprocessor 0 type are
> always usable in kernel mode, regardless of the setting of this bit.
> 
> Qemu does simply check:
> ./target-mips/translate.c:1181
> ===================
>    if (!(ctx->CP0_Status & (1 << CP0St_CU0)) &&
>        !(ctx->hflags & MIPS_HFLAG_UM) &&
>        !(ctx->hflags & MIPS_HFLAG_ERL) &&
>        !(ctx->hflags & MIPS_HFLAG_EXL)) {
>        if (loglevel & CPU_LOG_TB_IN_ASM) {
>            fprintf(logfile, "CP0 is not usable\n");
>        }
>        generate_exception_err (ctx, EXCP_CpU, 0);
>        return;
> ===================
> 
> This check is not enought to emulate a Coprocessor Unusable
> situation on Reset (when CPU is in the kernel mode).

A patch which doesn't negate the HFLAGS_UM check fixes this and was
posted here a while ago.


Thiemo

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Qemu-devel] CP0 after reset bug (Was: Add MIPS ELF loader)
  2006-04-21 12:51           ` Thiemo Seufer
@ 2006-04-21 14:29             ` Alexander Voropay
  0 siblings, 0 replies; 16+ messages in thread
From: Alexander Voropay @ 2006-04-21 14:29 UTC (permalink / raw)
  To: Thiemo Seufer, qemu-devel

"Thiemo Seufer" <ths@networkno.de> wrote:

>> The Qemu has a bug there. The "See MIPS Run" p.51 states:
> A patch which doesn't negate the HFLAGS_UM check fixes this and was
> posted here a while ago.

 Thx, found.
http://lists.gnu.org/archive/html/qemu-devel/2006-03/msg00148.html

 Is it possible to push it into the CVS ?

--
-=AV=-

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Qemu-devel] [PATCH] Add MIPS ELF loader
  2006-03-28  6:57 [Qemu-devel] [PATCH] Add MIPS ELF loader Dirk Behme
  2006-03-28 13:01 ` Thiemo Seufer
@ 2006-04-23 17:16 ` Fabrice Bellard
  2006-04-25 23:57   ` Thiemo Seufer
  1 sibling, 1 reply; 16+ messages in thread
From: Fabrice Bellard @ 2006-04-23 17:16 UTC (permalink / raw)
  To: qemu-devel

I just added an ELF loader (inspirated from the SPARC one) which should 
work for all architectures. It supports symbol loading and use the CPU 
physical memory mappings to compute correct RAM addresses.

Fabrice.

Dirk Behme wrote:
> Hi,
> 
> ELF loader feature for MIPS in patch
> 
> http://lists.gnu.org/archive/html/qemu-devel/2006-03/msg00033.html
> 
> was rejected because it breaks loading of raw kernel images:
> 
> http://lists.gnu.org/archive/html/qemu-devel/2006-03/msg00082.html
> 
> What about the patch in attachment? It first tries to load
> image as an ELF file. If this fails it falls back to raw
> image load. Additionally, it takes feature of patch above to
> go on even if no BIOS is found.
> 
> Regards
> 
> Dirk

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Qemu-devel] [PATCH] Add MIPS ELF loader
  2006-04-23 17:16 ` Fabrice Bellard
@ 2006-04-25 23:57   ` Thiemo Seufer
  0 siblings, 0 replies; 16+ messages in thread
From: Thiemo Seufer @ 2006-04-25 23:57 UTC (permalink / raw)
  To: qemu-devel

Fabrice Bellard wrote:
> I just added an ELF loader (inspirated from the SPARC one) which should 
> work for all architectures. It supports symbol loading and use the CPU 
> physical memory mappings to compute correct RAM addresses.

I extended it so that it provides the ELF entry point address, fixed
a memory leak for the failure case, put the large buffer read in a
read loop, and let the mips-4kc use it with fallback to raw binaries.

Also, the mips support handles a missing BIOS nor in a more graceful
way.

I was busier that I hoped the last days, collecting the MIPS specific
patches may take a few days longer.


Thiemo


Index: qemu-work/hw/mips_r4k.c
===================================================================
--- qemu-work.orig/hw/mips_r4k.c	2006-04-25 23:22:22.000000000 +0100
+++ qemu-work/hw/mips_r4k.c	2006-04-25 23:22:25.000000000 +0100
@@ -5,6 +5,8 @@
 #define KERNEL_LOAD_ADDR 0x80010000
 #define INITRD_LOAD_ADDR 0x80800000
 
+#define VIRT_TO_PHYS_ADDEND (-0x80000000LL)
+
 extern FILE *logfile;
 
 static PITState *pit;
@@ -101,6 +103,7 @@
     cpu_mips_update_count(env, 1, 0);
 }
 
+
 static void io_writeb (void *opaque, target_phys_addr_t addr, uint32_t value)
 {
 #if 0
@@ -189,72 +192,71 @@
                     const char *initrd_filename)
 {
     char buf[1024];
-    target_ulong kernel_base, kernel_size, initrd_base, initrd_size;
+    int64_t entry = 0;
     unsigned long bios_offset;
     int io_memory;
-    int linux_boot;
     int ret;
     CPUState *env;
-
-    printf("%s: start\n", __func__);
-    linux_boot = (kernel_filename != NULL);
+    long kernel_size;
 
     env = cpu_init();
     register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
 
     /* allocate RAM */
     cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
+
+    /* Try to load a BIOS image. If this fails, we continue regardless,
+       but initialize the hardware ourselves. When a kernel gets
+       preloaded we also initialize the hardware, since the BIOS wasn't
+       run. */
     bios_offset = ram_size + vga_ram_size;
     snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);
     printf("%s: load BIOS '%s' size %d\n", __func__, buf, BIOS_SIZE);
     ret = load_image(buf, phys_ram_base + bios_offset);
-    if (ret != BIOS_SIZE) {
-        fprintf(stderr, "qemu: could not load MIPS bios '%s'\n", buf);
-        exit(1);
+    if (ret == BIOS_SIZE) {
+	cpu_register_physical_memory((uint32_t)(0x1fc00000),
+				     BIOS_SIZE, bios_offset | IO_MEM_ROM);
+	env->PC = 0xBFC00000;
+	if (!kernel_filename)
+	    return;
+    } else {
+	/* not fatal */
+        fprintf(stderr, "qemu: Warning, could not load MIPS bios '%s'\n",
+		buf);
     }
-    cpu_register_physical_memory((uint32_t)(0x1fc00000),
-                                 BIOS_SIZE, bios_offset | IO_MEM_ROM);
-#if 0
-    memcpy(phys_ram_base + 0x10000, phys_ram_base + bios_offset, BIOS_SIZE);
-    env->PC = 0x80010004;
-#else
-    env->PC = 0xBFC00004;
-#endif
-    if (linux_boot) {
-        kernel_base = KERNEL_LOAD_ADDR;
-        /* now we can load the kernel */
-        kernel_size = load_image(kernel_filename,
-                                phys_ram_base + (kernel_base - 0x80000000));
-        if (kernel_size == (target_ulong) -1) {
-            fprintf(stderr, "qemu: could not load kernel '%s'\n", 
-                    kernel_filename);
-            exit(1);
-        }
+
+    kernel_size = 0;
+    if (kernel_filename) {
+	kernel_size = load_elf(kernel_filename, VIRT_TO_PHYS_ADDEND, &entry);
+	if (kernel_size >= 0)
+	    env->PC = entry;
+	else {
+	    kernel_size = load_image(kernel_filename,
+                                     phys_ram_base + KERNEL_LOAD_ADDR + VIRT_TO_PHYS_ADDEND);
+            if (kernel_size < 0) {
+                fprintf(stderr, "qemu: could not load kernel '%s'\n",
+                        kernel_filename);
+                exit(1);
+            }
+            env->PC = KERNEL_LOAD_ADDR;
+	}
+
         /* load initrd */
         if (initrd_filename) {
-            initrd_base = INITRD_LOAD_ADDR;
-            initrd_size = load_image(initrd_filename,
-                                     phys_ram_base + initrd_base);
-            if (initrd_size == (target_ulong) -1) {
+            if (load_image(initrd_filename,
+			   phys_ram_base + INITRD_LOAD_ADDR + VIRT_TO_PHYS_ADDEND)
+		== (target_ulong) -1) {
                 fprintf(stderr, "qemu: could not load initial ram disk '%s'\n", 
                         initrd_filename);
                 exit(1);
             }
-        } else {
-            initrd_base = 0;
-            initrd_size = 0;
         }
-        env->PC = KERNEL_LOAD_ADDR;
+
 	/* Store command line.  */
         strcpy (phys_ram_base + (16 << 20) - 256, kernel_cmdline);
         /* FIXME: little endian support */
         *(int *)(phys_ram_base + (16 << 20) - 260) = tswap32 (0x12345678);
         *(int *)(phys_ram_base + (16 << 20) - 264) = tswap32 (ram_size);
-    } else {
-        kernel_base = 0;
-        kernel_size = 0;
-        initrd_base = 0;
-        initrd_size = 0;
     }
 
     /* Init internal devices */
Index: qemu-work/elf_ops.h
===================================================================
--- qemu-work.orig/elf_ops.h	2006-04-25 23:22:22.000000000 +0100
+++ qemu-work/elf_ops.h	2006-04-25 23:23:10.000000000 +0100
@@ -138,7 +138,8 @@
     return -1;
 }
 
-int glue(load_elf, SZ)(int fd, int64_t virt_to_phys_addend, int must_swab)
+int glue(load_elf, SZ)(int fd, int64_t virt_to_phys_addend,
+                       int must_swab, int64_t *entry)
 {
     struct elfhdr ehdr;
     struct elf_phdr *phdr = NULL, *ph;
@@ -152,6 +153,9 @@
         glue(bswap_ehdr, SZ)(&ehdr);
     }
 
+    if (entry)
+   	*entry = (int64_t)ehdr.e_entry;
+
     glue(load_symbols, SZ)(&ehdr, fd, must_swab);
 
     size = ehdr.e_phnum * sizeof(phdr[0]);
@@ -176,9 +180,29 @@
             /* XXX: avoid allocating */
             data = qemu_mallocz(mem_size);
             if (ph->p_filesz > 0) {
-                lseek(fd, ph->p_offset, SEEK_SET);
-                if (read(fd, data, ph->p_filesz) != ph->p_filesz)
-                    goto fail;
+                size_t sz = ph->p_filesz;
+                int retval;
+
+                retval = lseek(fd, ph->p_offset, SEEK_SET);
+		if (retval < 0)
+		    goto fail2;
+                while (sz) {
+		    retval = read(fd, data, sz);
+		    switch (retval) {
+		    case -1:
+                        goto fail2;
+		    case 0: /* EOF */
+			if (sz)
+			    goto fail;
+			break;
+		    default:
+			if (sz < retval)
+			    goto fail2;
+			sz -= retval;
+			retval = 0;
+			break;
+		    }
+		}
             }
             addr = ph->p_vaddr + virt_to_phys_addend;
 
@@ -190,6 +214,8 @@
         }
     }
     return total_size;
+ fail2:
+    qemu_free(data);
  fail:
     qemu_free(phdr);
     return -1;
Index: qemu-work/hw/sun4m.c
===================================================================
--- qemu-work.orig/hw/sun4m.c	2006-04-25 23:22:22.000000000 +0100
+++ qemu-work/hw/sun4m.c	2006-04-25 23:22:25.000000000 +0100
@@ -269,7 +269,7 @@
                                  prom_offset | IO_MEM_ROM);
 
     snprintf(buf, sizeof(buf), "%s/%s", bios_dir, PROM_FILENAMEE);
-    ret = load_elf(buf, 0);
+    ret = load_elf(buf, 0, NULL);
     if (ret < 0) {
 	snprintf(buf, sizeof(buf), "%s/%s", bios_dir, PROM_FILENAMEB);
 	ret = load_image(buf, phys_ram_base + prom_offset);
@@ -282,7 +282,7 @@
 
     kernel_size = 0;
     if (linux_boot) {
-        kernel_size = load_elf(kernel_filename, -0xf0000000);
+        kernel_size = load_elf(kernel_filename, -0xf0000000, NULL);
         if (kernel_size < 0)
 	    kernel_size = load_aout(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
 	if (kernel_size < 0)
Index: qemu-work/hw/sun4u.c
===================================================================
--- qemu-work.orig/hw/sun4u.c	2006-04-25 23:22:22.000000000 +0100
+++ qemu-work/hw/sun4u.c	2006-04-25 23:22:25.000000000 +0100
@@ -283,7 +283,7 @@
                                  prom_offset | IO_MEM_ROM);
 
     snprintf(buf, sizeof(buf), "%s/%s", bios_dir, PROM_FILENAMEE);
-    ret = load_elf(buf, 0);
+    ret = load_elf(buf, 0, NULL);
     if (ret < 0) {
 	snprintf(buf, sizeof(buf), "%s/%s", bios_dir, PROM_FILENAMEB);
 	ret = load_image(buf, phys_ram_base + prom_offset);
@@ -298,7 +298,7 @@
     initrd_size = 0;
     if (linux_boot) {
         /* XXX: put correct offset */
-        kernel_size = load_elf(kernel_filename, 0);
+        kernel_size = load_elf(kernel_filename, 0, NULL);
         if (kernel_size < 0)
 	    kernel_size = load_aout(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
 	if (kernel_size < 0)
Index: qemu-work/loader.c
===================================================================
--- qemu-work.orig/loader.c	2006-04-25 23:22:22.000000000 +0100
+++ qemu-work/loader.c	2006-04-25 23:22:25.000000000 +0100
@@ -194,7 +194,8 @@
 #include "elf_ops.h"
 
 /* return < 0 if error, otherwise the number of bytes loaded in memory */
-int load_elf(const char *filename, int64_t virt_to_phys_addend)
+int load_elf(const char *filename, int64_t virt_to_phys_addend,
+             int64_t *entry)
 {
     int fd, data_order, must_swab, ret;
     uint8_t e_ident[EI_NIDENT];
@@ -220,9 +221,9 @@
     
     lseek(fd, 0, SEEK_SET);
     if (e_ident[EI_CLASS] == ELFCLASS64) {
-        ret = load_elf64(fd, virt_to_phys_addend, must_swab);
+        ret = load_elf64(fd, virt_to_phys_addend, must_swab, entry);
     } else {
-        ret = load_elf32(fd, virt_to_phys_addend, must_swab);
+        ret = load_elf32(fd, virt_to_phys_addend, must_swab, entry);
     }
 
     close(fd);
Index: qemu-work/vl.h
===================================================================
--- qemu-work.orig/vl.h	2006-04-25 23:22:22.000000000 +0100
+++ qemu-work/vl.h	2006-04-25 23:22:25.000000000 +0100
@@ -872,7 +872,7 @@
 /* loader.c */
 int get_image_size(const char *filename);
 int load_image(const char *filename, uint8_t *addr);
-int load_elf(const char *filename, int64_t virt_to_phys_addend);
+int load_elf(const char *filename, int64_t virt_to_phys_addend, int64_t *entry);
 int load_aout(const char *filename, uint8_t *addr);
 
 /* slavio_timer.c */

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2006-04-25 23:57 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <154e01c66453$111e4f20$e90d11ac@spb.in.rosprint.ru>
2006-04-20 10:16 ` [Qemu-devel] [PATCH] Add MIPS ELF loader Marius Groeger
2006-04-20 10:28   ` Thiemo Seufer
2006-04-20 11:02     ` Alexander Voropay
2006-04-20 12:19       ` Alexander Voropay
2006-04-21 12:35         ` [Qemu-devel] CP0 after reset bug (Was: Add MIPS ELF loader) Alexander Voropay
2006-04-21 12:51           ` Thiemo Seufer
2006-04-21 14:29             ` Alexander Voropay
2006-03-28  6:57 [Qemu-devel] [PATCH] Add MIPS ELF loader Dirk Behme
2006-03-28 13:01 ` Thiemo Seufer
2006-03-30 13:40   ` Dirk Behme
2006-03-30 13:53     ` Thiemo Seufer
2006-03-30 14:29       ` Alexander Voropay
2006-03-30 17:34         ` Dirk Behme
     [not found]         ` <442C0F57.3010200@gmail.com>
2006-04-02 12:54           ` Alexander Voropay
2006-04-23 17:16 ` Fabrice Bellard
2006-04-25 23:57   ` Thiemo Seufer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).