[Top][All Lists]
[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
=============================================================================
e1000.c.diff_u
Description: Text Data