qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] e1000 autoneg timing, piix/osx


From: Alexander Graf
Subject: Re: [Qemu-devel] e1000 autoneg timing, piix/osx
Date: Thu, 03 Jul 2014 17:25:04 +0200
User-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:24.0) Gecko/20100101 Thunderbird/24.6.0


On 03.07.14 16:14, Gabriel L. Somlo wrote:
On Thu, Jul 03, 2014 at 04:02:06PM +0200, Alexander Graf wrote:
On 03.07.14 15:58, Gabriel L. Somlo wrote:
On Thu, Jul 03, 2014 at 03:20:50PM +0200, Alexander Graf wrote:
On 03.07.2014, at 15:17, Gabriel L. Somlo <address@hidden> wrote:

On Thu, Jul 03, 2014 at 10:04:55AM +0200, Alexander Graf wrote:
so Ethernet, SATA, and USB, all sharing IRQ 11. Is there an easy way
to force one of those to use a different IRQ ?
Oh, and on Q35, while Ethernet (and one of the USBs) is still on IRQ 11,
SATA ended up on IRQ 10, and things are fine there...

IIRC if you plug the device in a different slot, the irq distribution
should be different :).
Sorry for being thick, but I'm still trying to figure out if there's a
command-line way of making that happen. Re-ordering the "-device"
arguments to qemu obviously doesn't make a difference in how they're
assigned...
The magic word is "devfn" :). It's basically the token PCI uses to find out which slot and function 
id a device is on. You can set "devfn" with the "addr" attribute on -device.
OK. So simply doing "-device e1000-82545em,...,bus=pci.0,addr=5" to
move it up one slot from its default of "4" gets it set up with IRQ 10.
As long as it doesn't share an irq line with the SATA controller, the
network link gets detected just fine, same as on Q35.

So this is not really an autonegotiation or timing bug, it's an
unfortunate side effect of the OS X built-in proprietary e1000 driver
not playing nice when IRQs are shared with SATA in particular. At
least as far as I'm able to tell so far... :)

So I'll send out some autoneg cleanup patches after 2.1 is officially
out, but the "osx link on piix not working" mystery is solved as far
as I can tell :)
Maybe only ICR bits that actually would trigger an interrupt get cleared?
you mean, modify e1000's mac_icr_read() to only clear bits on read if
the mask says they should be "active" at that moment ?

The e1000 spec doesn't seem to say that though, it's "you read it,
it's now 0", regardless of the mask configuration.

http://download.intel.com/design/network/manuals/8254x_GBe_SDM.pdf
on page 293.

Maybe the IRQ line is simply never shared on real Macs :). Who knows.

Does this (untested!) patch make it work for you?


Alex

diff --git a/hw/net/e1000.c b/hw/net/e1000.c
index 0fc29a0..7db0538 100644
--- a/hw/net/e1000.c
+++ b/hw/net/e1000.c
@@ -1090,9 +1090,24 @@ static uint32_t
 mac_icr_read(E1000State *s, int index)
 {
     uint32_t ret = s->mac_reg[ICR];
+    uint32_t new_icr = 0;

     DBGOUT(INTERRUPT, "ICR read: %x\n", ret);
-    set_interrupt_cause(s, 0, 0);
+
+    /*
+     * Mac OS X reads ICR on every interrupt. When the IRQ line is shared,
+     * this may result in a race where LSC is not interpreted yet, but
+     * already gets cleared.
+     *
+     * The easiest fix is to delay LSC events until after they have been
+     * property unmasked, so let's just claim we never saw any here.
+     */
+    if ((ret & E1000_ICS_LSC) && !(s->mac_reg[IMS] & E1000_ICS_LSC)) {
+        ret &= ~E1000_ICS_LSC;
+        new_icr |= E1000_ICS_LSC;
+    }
+
+    set_interrupt_cause(s, 0, new_icr);
     return ret;
 }




reply via email to

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