qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] bug report + fix: e1000.c in 0.10.5 does not properly e


From: Bill Paul
Subject: Re: [Qemu-devel] bug report + fix: e1000.c in 0.10.5 does not properly emulate real hardware
Date: Mon, 8 Jun 2009 20:39:26 -0700
User-agent: KMail/1.5.3

Of all the gin joints in all the towns in all the world, Anthony Liguori had 
to walk into mine and say:
> Hi Bill,
>
> Bill Paul wrote:
> > Hi, I hope this is the right forum for this. Apologies if it's not.
> >
> > I downloaded QEMU 0.10.5 and tested it against VxWorks 6.7 using the
> > e1000 emulated network interface, and ran into a couple of problems. The
> > VxWorks Intel PRO/1000 driver has been tested against a real Intel
> > 82540EM adapter, and it works fine, however it does not work with the
> > emulated 82540 in QEMU, because it doesn't quite duplicate the behavior
> > of real hardware.
> >
> > There are two issues:
> >
> > 1) The ICS register is not emulated correctly. It's not easy to discern
> > from the Intel documentation, but the ICS register can be used in place
> > of the ICR register in order to read the currently pending interrupt
> > sources without automatically clearing them. The VxWorks driver needs to
> > check interrupt events twice: once in its ISR, and again in task context.
> > The auto-clear behavior of ICR makes it undesirable to use in the
> > interrupt service routine, since it will clear the interrupt events,
> > preventing the task level code from seeing them too (unless you preserve
> > the values in software, which is tricky to do correcly). Consequently,
> > VxWorks reads the ICS register in its interrupt service routine instead.
> > This doesn't work in QEMU because:
> >
> > - There is no entry in the readops table for reading the ICS register, so
> > reading it always returns 0.
> > - The ICS register contents are not updated to reflect pending events in
> > the set_interrupt_cause() routine.
> >
> > 2) The EERD register is not emulated correctly, which breaks VxWorks'
> > EEPROM access code. The commonly available Intel drivers for Linux and
> > *BSD don't use this register, and neither does the e1000 PXE ROM that
> > comes with QEMU, so it probably hasn't been tested extensively. In real
> > hardware, the register should only be updated when both an EEPROM offset
> > and the START bit are written -- setting the START bit is what triggers
> > an actual EEPROM read transaction. When the transaction is complete, the
> > START bit is cleared, and the DONE bit is set. In QEMU, writing just the
> > EEPROM offset is enough to cause the read transaction to occur: the
> > simulated EEPROM contents appear and the DONE bit is set whether the
> > START bit was set or not.
> >
> > I was able to fix both of these issues in my local copy of e1000.c, and
> > now the VxWorks PRO/1000 driver works correctly. I put the original code,
> > patched version, and a context diff at the following URL:
> >
> > http://www.freebsd.org/~wpaul/qemu
>
> Thanks for the thorough explanation!  Can you send the patch to the
> mailing list as a diff -u and include a Signed-off-by?

I can generate a unified diff, but I'm not sure I understand what is meant by 
"Signed-off-by." Can you elaborate? (Sorry, I'm not familiar with the QEMU 
development process. I just wanted to send a bug report. :)

> Is this only an issue with VxWorks or is it also reproducible in
> FreeBSD?

FreeBSD's PRO/1000 driver is written by Intel, just like the Linux driver. 
Unfortunately, neither driver uses the ICS or EERD registers, so the problems 
aren't visible on either OS, which is probably why nobody noticed them 
before. It's fairly easy to modify the FreeBSD driver to expose the problem 
with the ICS register (like I said, it always returns 0), but testing the 
problem with the EERD register is slightly harder.

>  If the former, is there anything like an evaluation copy of
> VxWorks that I could use as a test harness?

Strictly speaking, no. There's no such thing as a demo or eval version of 
VxWorks. However, I've built some binaries which should make it easy to 
validate the patches I've sent. I put the following files at 
http://www.freebsd.org/~wpaul/qemu :

-rwxr-xr-x  1 wpaul  devel   335360 Jun  9 02:47 bootrom.bin
-rw-r--r--  1 wpaul  devel   341939 Jun  9 02:53 bootrom.pxe
-rw-r--r--  1 wpaul  devel    36246 Jun  8 23:38 e1000.c
-rw-r--r--  1 wpaul  devel     1354 Jun  9 03:01 e1000.c.diff_u
-rw-r--r--  1 wpaul  devel    36077 Jun  8 23:38 e1000.c.orig
-rw-r--r--  1 wpaul  devel     1977 Jun  8 23:38 e1000.c.patch
-rwxr-xr-x  1 wpaul  devel  1721417 Jun  9 02:47 vxWorks
-rw-r--r--  1 wpaul  devel  1474560 Jun  9 02:47 vxworks.img

bootrom.bin and bootrom.pxe are floppy and PXE based VxWorks bootroms for the 
x86 arch. The bootrom.bin image is meant to go on a floppy with a special 
boot block. The bootrom.pxe image is largely the same code, but designed to 
be downloaded and booted via PXE. It works with QEMU, but you need to set up 
a DHCP and TFTP server in order to use it.

vxWorks is a standalone VxWorks 6.7 image for x86, which you can download and 
boot via ethernet with the boot floppy image as described below.

vxworks.img is a floppy disk image with bootrom.bin and the loader boot block 
already on it. I was able to run it using:

# qemu -net nic,macaddr=0:0:e8:1:2:3,model=e1000 -net tap -fda vxworks.img

Once the bootrom loads, you'll see a blue screen and a "Press any key to stop 
auto-boot" prompt with a 7 second countdown. Press a key, and you should be 
at the "[VxWorks Boot]:" prompt.

The bootrom normally wants to boot from floppy, so you need to change the boot 
configuration to tell it to boot from network. If you press "?" and then 
ENTER at the boot prompt, you should see a list of available boot devices, 
and "gei0" should be listed. To change the boot parameters, type "c" and then 
ENTER.

For "boot device," specify "gei0".
For "processor number," just hit ENTER.
For "host name," just hit ENTER.
For "File name," you can specify the path to the vxWorks image on your FTP 
server.
For "inet on ethernet," specify the IP address and netmask for the simulated 
target in the form of <IP>:<netmask>, e.g.: "10.0.0.1:ffffff00"
For "inet on backplane," just hit ENTER.
For "host inet", specify the IP address of the FTP server from which you want 
to download the vxWorks image.
For "gateway imet," specify the IP address of the default gateway for the 
simulated network.
For "user" and "ftp password," provide a valid username and password 
combination that can be used to log into the FTP server where the vxWorks 
image resides. (If the password is left blank, it will try to load the image 
via rsh instead, which is clunky, but sometimes useful.)
For all the rest of the fields, just hit ENTER (they're not useful here, but 
feel free to play with them).

Once you get back to the "[VxWorks Boot]:" prompt, the ethernet should be 
live, and you should be able to ping the bootrom via the simulated network. 
To boot the vxWorks image, type "@" and then ENTER at the prompt, and it 
should say "Loading...." The image should transfer via FTP, and you should be 
presented with a small VxWorks banner and the target shell prompt ("->").

The supplied VxWorks image has ping and the telnet server built in. I till 
inherit the IP address and other information from the bootrom. You can type 
"version" at the shell prompt to see. You should be able to telnet to the 
VxWorks image via the simulated network. You can also do things like:

-> ifconfig "-a"
-> ifconfig "-h"
-> i (list tasks)
-> help (small amount of shell command help)
-> ping "<ip address>", <number of ping packets> (ping "10.0.1.2", 3)
-> muxShow (show network interfaces)
-> vxBusShow (show drivers and devices)

With the broken e1000 code, the bootrom will crash QEMU almost as soon as it 
starts. This is because the problem with the ICS register causes the PRO/1000 
driver to fail to detect that any interrupts are asserted, so it never acks 
and clears them. This causes the VxWorks driver's interrupt service routine 
to re-trigger endlessly. The problem with the EERD register causes it to 
botch the first 2 bytes of the ethernet address when reading it from NVRAM 
during startup. With the patch applied, it all works fine.

I hope all this makes sense. VxWorks is designed to be fairly bare bones, 
since it's usually up to the customer to design their application code on top 
of it.

-Bill

> Regards,
>
> Anthony Liguori
>
> > -Bill

-- 
=============================================================================
-Bill Paul            (510) 749-2329 | Senior Engineer, Master of Unix-Fu
                 address@hidden | Wind River Systems
=============================================================================
   "I put a dollar in a change machine. Nothing changed." - George Carlin
=============================================================================

Attachment: e1000.c.diff_u
Description: Text Data


reply via email to

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