qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] MIPS64 problem with ethernet


From: Aurelien Jarno
Subject: Re: [Qemu-devel] MIPS64 problem with ethernet
Date: Mon, 28 May 2007 01:07:37 +0200
User-agent: Mutt/1.5.13 (2006-08-11)

On Sun, May 27, 2007 at 06:30:52AM -0500, Jason Wessel wrote:
> Aurelien Jarno wrote:
> >As discussed on IRC, the problem is only present on 32-bit hosts. It is
> >due to the do_ddivu which is falsely implemented using lldiv and then by
> >casting the result. The patch below uses / and % as on the 64-bit host
> >code. It is maybe slower than lldiv, but at least it gives the correct
> >result. This probably involves some libgcc code, so it is better to keep
> >it in op_helper.c for 32-bit hosts.
> >
> >  
> 
> With your change the ethernet does come up but it seems there is a 
> further problem, perhaps with ddivu.  My host is a 32bit host, and this 
> does seem to work on a 64bit host or the real hardware.  Doing something 
> like an ls /proc does not work in the emulated target.   The reason is 
> that the compatibility syscalls are 32bit and there is some sign 
> extension problem somewhere.
> 
> I put the following code in kernel/main/init.c as an illustration of the 
> problem.
>    {
>        unsigned long v1 = 0xffffffff80731111;
>        unsigned int v2 = v1 + 1;
>        printk("v1 %lx v2 %08x\n", v1, v2);
>    }
> 
> On the real hw it prints correctly as:
> v1 ffffffff80731111 v2 80731112
> 
> On the emulated 64 bit + 64bit kernel on a 32 bit host it prints as:
> v1 ffffffff80731111 v2 ffffffff80731112
> 
> This might be due to the ddivu in printk, but it could be elsewhere...
> 

The problem is actually not specific to 32-bit hosts. It is a bug in the
lwu instruction, which should not sign extend the loaded byte.

Please find below a patch to fix that.

Index: target-mips/op_mem.c
===================================================================
RCS file: /sources/qemu/qemu/target-mips/op_mem.c,v
retrieving revision 1.10
diff -u -d -p -r1.10 op_mem.c
--- target-mips/op_mem.c        20 May 2007 01:36:28 -0000      1.10
+++ target-mips/op_mem.c        27 May 2007 22:59:13 -0000
@@ -63,7 +63,7 @@ void glue(op_lw, MEMSUFFIX) (void)
 
 void glue(op_lwu, MEMSUFFIX) (void)
 {
-    T0 = glue(ldl, MEMSUFFIX)(T0);
+    T0 = (uint32_t) glue(ldl, MEMSUFFIX)(T0);
     RETURN();
 }
 
-- 
  .''`.  Aurelien Jarno             | GPG: 1024D/F1BCDB73
 : :' :  Debian developer           | Electrical Engineer
 `. `'   address@hidden         | address@hidden
   `-    people.debian.org/~aurel32 | www.aurel32.net




reply via email to

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