Carlo Marcelo Arenas Belon a écrit : > On Mon, Jan 15, 2007 at 03:21:36AM -0600, Carlo Marcelo Arenas Belon wrote: >> FreeBSD 6.2 guest I noticed the following errors at boot time : >> >> ad0: 2048MB <QEMU HARDDISK 0.8.3> at ata0-master WDMA2 >> ad0: FAILURE - READ_DMA timed out LBA=4194301 >> acd0: CDROM <QEMU CD-ROM/0.8.3> at ata1-master WDMA2 >> acd0: TIMEOUT - READ BIG retrying (1 retry left) >> > > The problem is that FreeBSD is sending a WIN_READDMA (0xC8) command to the > emulated PIIX3 controller before it sets the DMA address that will be used and > therefore the code in ide_dma_start is not setting bm->cur_addr to the right > value (it is left set to 0) and then it is failing the validation in > dma_buf_rw where the distance between bm->cur_addr and bm->addr is expected to > be smaller than 1 page (4K) and resulting in an EOT error and a timeout which > FreeBSD handles by resetting the IDE controller. > > Apparently all other guests I'd tried (Linux, Solaris, OpenBSD and Windows) > set the address first (bmdma_addr_write) and then send the request for a DMA > command and are therefore not affected by this, but even if FreeBSD behavior > is peculiar, it should be OK if implemented against real hardware as per the > spec in : > > http://www.intel.com/design/intarch/datashts/290550.htm > > The following patch moves the initialization of bm->cur_addr to match FreeBSD > behavior while being also compatible with all other guests but keeping in > sync closely the values of the memory addresses which will be used for the DMA > in a way that better emulates real hardware. > > Tested with guests running FreeBSD 6.2 amd64, OpenBSD 4.0 amd64, Ubuntu Linux > 6.06 amd64, OpenSolaris b55b amd64, Windows 2000 Professional i386 and Gentoo > Linux 2006.1 i386. > > Carlo > > > ------------------------------------------------------------------------ > > Index: hw/ide.c > =================================================================== > RCS file: /sources/qemu/qemu/hw/ide.c,v > retrieving revision 1.51 > diff -u -r1.51 ide.c > --- hw/ide.c 20 Jan 2007 01:12:17 -0000 1.51 > +++ hw/ide.c 22 Jan 2007 09:50:20 -0000 > @@ -2230,10 +2230,11 @@ > return; > bm->ide_if = s; > bm->dma_cb = dma_cb; > - bm->cur_addr = bm->addr; > bm->cur_prd_last = 0; > bm->cur_prd_addr = 0; > bm->cur_prd_len = 0; > + if (bm->cur_addr != bm->addr) > + bm->cur_addr = bm->addr;
Why using a condition here? This will probably be slower than doing bm->cur_addr = bm->addr and the result is the same. > if (bm->status & BM_STATUS_DMAING) { > bm->dma_cb(bm, 0); > } > @@ -2363,6 +2364,7 @@ > printf("%s: 0x%08x\n", __func__, val); > #endif > bm->addr = val & ~3; > + bm->cur_addr = bm->addr; > } > > static void bmdma_map(PCIDevice *pci_dev, int region_num, > > > ------------------------------------------------------------------------ > > _______________________________________________ > Qemu-devel mailing list > Qemu-devel@nongnu.org > http://lists.nongnu.org/mailman/listinfo/qemu-devel -- .''`. Aurelien Jarno | GPG: 1024D/F1BCDB73 : :' : Debian developer | Electrical Engineer `. `' [EMAIL PROTECTED] | [EMAIL PROTECTED] `- people.debian.org/~aurel32 | www.aurel32.net _______________________________________________ Qemu-devel mailing list Qemu-devel@nongnu.org http://lists.nongnu.org/mailman/listinfo/qemu-devel