On 29/12/15 17:59, Programmingkid wrote: > This patch solves the few problems that needed to be solved in order for a > Mac OS 10.4 guest to use the rtl8139 nic. > > The pci_dma_read() function would only return zero when a MemoryRegion object > was not enabled. Enabling the object makes the pci_dma_read() function work > correctly. > > The Linux rtl8139 driver needs base address register zero set to PIO. This > conflicts with Mac OS 10.4's driver needing base address register zero set to > MMIO. So a macro has been added that allows the user to decide which operating > system this network interface card will be compatible with. Note: Windows XP's > driver works regardless of the macro setting. > > Signed-off-by: John Arbuckle <programmingk...@gmail.com> > > --- > hw/net/rtl8139.c | 15 ++++++++++++++- > include/hw/pci/pci.h | 1 + > 2 files changed, 15 insertions(+), 1 deletions(-) > > diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c > index 90ef72b..e17a471 100644 > --- a/hw/net/rtl8139.c > +++ b/hw/net/rtl8139.c > @@ -64,6 +64,14 @@ > /* debug RTL8139 card */ > //#define DEBUG_RTL8139 1 > > +/* > + * The driver that ships with Mac OS 10.4 has to have its base address > register > + * 0 set to MMIO space. This directly conflicts with the Linux driver that > + * needs the PIO set to base address register 0. Mac OS 10.5 or higher does > not > + * need this macro set. > + */ > +/* #define MAC_OS_10_4_DRIVER_COMPATIBILITY 1 */ > + > #define PCI_PERIOD 30 /* 30 ns period = 33.333333 Mhz frequency */ > > #define SET_MASKED(input, mask, curr) \ > @@ -3444,9 +3452,14 @@ static void pci_rtl8139_realize(PCIDevice *dev, Error > **errp) > "rtl8139", 0x100); > memory_region_init_io(&s->bar_mem, OBJECT(s), &rtl8139_mmio_ops, s, > "rtl8139", 0x100); > + > +#ifdef MAC_OS_10_4_DRIVER_COMPATIBILITY > + pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar_mem); > + pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &s->bar_io); > +#else > pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->bar_io); > pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar_mem); > - > +#endif > qemu_macaddr_default_if_unset(&s->conf.macaddr); > > /* prepare eeprom */ > diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h > index 379b6e1..8e95c75 100644 > --- a/include/hw/pci/pci.h > +++ b/include/hw/pci/pci.h > @@ -699,6 +699,7 @@ static inline int pci_dma_rw(PCIDevice *dev, dma_addr_t > addr, > static inline int pci_dma_read(PCIDevice *dev, dma_addr_t addr, > void *buf, dma_addr_t len) > { > + memory_region_set_enabled(&dev->bus_master_enable_region, true); > return pci_dma_rw(dev, addr, buf, len, DMA_DIRECTION_TO_DEVICE); > }
Can you provide more information about how you tested this patch? The ordering of the BARs is interesting - according to http://www.opensource.apple.com/source/AppleRTL8139Ethernet/AppleRTL8139Ethernet-141/RTL8139.cpp the driver tries to map the BARs like this: // Get the virtual address mapping of CSR registers located at // Base Address Range 0 (0x10). csrMap = pciNub->mapDeviceMemoryWithRegister( kIOPCIConfigBaseAddress1 ); if ( 0 == csrMap ) break; Now according to http://www.opensource.apple.com/source/IOPCIFamily/IOPCIFamily-151.5/IOKit/pci/IOPCIDevice.h kIOPCIConfigBaseAddress1 is actually BAR1 rather than BAR0, although in rtl8139.c both bar_mem and bar_io access the chip registers so I'm not sure why this would fail - can you try and trace the accesses through to determine exactly why the NIC doesn't work with the current BAR ordering? ATB, Mark.