qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] enabling bus-master IDE driver


From: Juergen Keil
Subject: Re: [Qemu-devel] enabling bus-master IDE driver
Date: Fri, 26 Nov 2004 11:48:19 +0100 (CET)


> On Tue, Nov 23, 2004 at 04:03:39PM +0000, Norikatsu Shigemura wrote:
> > On Tue, 16 Nov 2004 20:41:35 +0100
> > Juergen Lock <address@hidden> wrote:
> > > > > It now says "Current Transfer Mode: Multi-Word DMA Mode 2".
> > > > > I'm not real sure how I test to see if disk access is faster,
> > > > > or by how much, but this appears to be progress for XP.
> > > > Windows 2000 isn't that verbose - it simply prints "DMA mode".
> > > > Interesting that XP has enabled "Multi-Word DMA Mode 2".
> > > >...
> > > FreeBSD guests (at least 5.3-BETA1) say they use WDMA2, which i guess
> > > is the same:
> > 
> >     Your patch works quite good.  I confirmed that it works on
> >     Windows XP SP2 and FreeBSD 5.3-RELEASE as guest OSs, and
> >     host's cpu loadavg reduced(MAX: 97% -> 30% on boot, etc..).
> > 
> > # http://people.FreeBSD.org/~nork/qemu/qemu05.png  but Japanese
> > 
> >     May I commit your patch as ports/emulators/qemu/files/patch-hw::ide.c?
> > 
> Mmmh actually I was waiting for words from people in the know about
> this, like is WDMA2 really the best we're gonna get?  Since linux guests'
> DMA was reported to be faster without the patch...

FreeBSD identifies QEMU's pci-ide controller as an "Intel PIIX3" chipset,
and has built-in knowledge that the PIIX3 does not support UDMA modes.
WDMA2 is the fastest dma transfer rate that is supported by the PIIX3
(according to freebsd source, I didn't verify this but I guess it's correct).
So that's why freebsd is using WDMA2.

See function ata_intel_ident() in sys/dev/ata/ata-chipcet.c:

http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/dev/ata/ata-chipset.c?rev=1.92&con
tent-type=text/x-cvsweb-markup



I don't think that you'll notice a difference in speed or performance inside
qemu between multiword dma and ultra dma modes.  qemu does not emulate the
ide hardware at such a low level that the dma transfer modes on the bus
matters.  The important thing is that the ide dma commands are used, so that
the hw/ide.c will move data to/from pc memory.  If a pio mode is used
the guest os' interrupt handler moves the data word-by-word to or from the
ide controller hardware, using emulated x86 instructions, and that is quite
expensive.

         -------------
         
Btw. FreeBSD 5.2.1 does not enable DMA on the QEMU-HDD, it uses PIO4 mode.

Trying to enable DMA with "atacontrol mode 0 WDMA2 BIOSPIO" crashes
the FreeBSD kernel (-> a FreeBSD kernel problem).

Problem: PCI busmastering is not enabled in the PCI command register.
It seems the BIOS is supposed to enable busmastering, but bochs bios
apparently doesn't enable pci-ide busmastering.  ata-pci.c function
ata_pci_attach() does not set ctrl->r_io1 which would be needed in
ata_pci_allocated() to allocate and enable DMA (ctrl->dmainit() is not
called).

As a workaround, always enable busmastering on qemu's pci-ide device.

Default to WDMA2 mode (the real Intel PIIX3 hardware which we
emulate does not support UDMA modes).

(The following patch needs to be applied on top of the previous version
of the pci-ide busmastering dma patch)

diff -ru /home/jk/src/qemu-cvs/hw/ide.c ./hw/ide.c
--- /home/jk/src/qemu-cvs/hw/ide.c      2004-11-18 22:23:13.000000000 +0100
+++ ./hw/ide.c  2004-11-21 11:26:56.143862000 +0100
@@ -430,7 +430,7 @@
         put_le16(p + 59, 0x100 | s->mult_sectors);
     put_le16(p + 60, s->nb_sectors);
     put_le16(p + 61, s->nb_sectors >> 16);
-    put_le16(p + 63, 0x07 /*| 0x4 << 8*/); /* Multiword DMA supported/selected 
*/
+    put_le16(p + 63, 0x07 | 0x4 << 8); /* Multiword DMA supported/selected */
     put_le16(p + 64, 0x03); /* PIO modes 3,4 supported */
     put_le16(p + 80, (1 << 1) | (1 << 2));
     put_le16(p + 82, (1 << 14));
@@ -439,7 +439,7 @@
     put_le16(p + 85, (1 << 14));
     put_le16(p + 86, 0);
     put_le16(p + 87, (1 << 14));
-    put_le16(p + 88, 0x3f | 0x20 << 8); /* UltraDMA modes supported/selected */
+    put_le16(p + 88, 0x3f /*| 0x20 << 8*/); /* UltraDMA modes 
supported/selected */
     put_le16(p + 93, 1 | (1 << 1) | (1 << 3) | (1 << 13) | (1 << 14));
 }
 
@@ -462,7 +462,7 @@
     put_le16(p + 48, 1); /* dword I/O (XXX: should not be set on CDROM) */
     put_le16(p + 49, 1 << 8 | 1 << 9); /* DMA and LBA supported */
     put_le16(p + 53, 7); /* words 64-70, 54-58, 88 valid */
-    put_le16(p + 63, 0x07 /*| 0x4 << 8*/); /* Multiword DMA supported/selected 
*/
+    put_le16(p + 63, 0x07 | 0x4 << 8); /* Multiword DMA supported/selected */
     put_le16(p + 64, 0x03); /* PIO modes 3,4 supported */
     put_le16(p + 65, 0xb4); /* minimum DMA multiword tx cycle time */
     put_le16(p + 66, 0xb4); /* recommended DMA multiword tx cycle time */
@@ -473,7 +473,7 @@
     put_le16(p + 72, 30); /* in ns */
 
     put_le16(p + 80, 0x1e); /* support up to ATA/ATAPI-4 */
-    put_le16(p + 88, 0x3f | 0x20 << 8); /* UltraDMA modes supported/selected */
+    put_le16(p + 88, 0x3f /*| 0x20 << 8*/); /* UltraDMA modes 
supported/selected */
 }
 
 static void ide_set_signature(IDEState *s)
@@ -2192,6 +2192,12 @@
     ide_init2(&d->ide_if[2], 16, hd_table[2], hd_table[3]);
 }
 
+
+// PCI 0x04: command(word), 0x06(word): status
+#define PCI_COMMAND_IOACCESS                0x0001
+#define PCI_COMMAND_MEMACCESS               0x0002
+#define PCI_COMMAND_BUSMASTER               0x0004
+
 /* hd_table must contain 4 block drivers */
 /* NOTE: for the PIIX3, the IRQs and IOports are hardcoded */
 void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table)
@@ -2209,6 +2215,8 @@
     pci_conf[0x01] = 0x80;
     pci_conf[0x02] = 0x10;
     pci_conf[0x03] = 0x70;
+    pci_conf[0x04] = PCI_COMMAND_IOACCESS | PCI_COMMAND_MEMACCESS \
+       | PCI_COMMAND_BUSMASTER;
     pci_conf[0x09] = 0x8a; // programming interface = PCI_IDE bus master is sup
ported
     pci_conf[0x0a] = 0x01; // class_sub = PCI_IDE
     pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage





reply via email to

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