From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:47468) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Tjf42-0007GG-Dc for qemu-devel@nongnu.org; Fri, 14 Dec 2012 18:53:11 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Tjf40-0008I4-NK for qemu-devel@nongnu.org; Fri, 14 Dec 2012 18:53:10 -0500 Received: from mx1.redhat.com ([209.132.183.28]:42726) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Tjf40-0008I0-Eo for qemu-devel@nongnu.org; Fri, 14 Dec 2012 18:53:08 -0500 Date: Fri, 14 Dec 2012 21:39:57 -0200 From: Marcelo Tosatti Message-ID: <20121214233957.GA19778@amt.cnet> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Subject: [Qemu-devel] [PATCH] fix dma.c MemoryRegion convertion List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Julien Grall Cc: qemu-devel@nongnu.org The high byte of the ioport address is necessary to compute the register address, see "82371AB PCI ISA IDE Xcelerator (PIIX4)" document, eg: 4.2.1.1. DCOM=E2=80=94DMA Command Register (IO) I/O Address: Channels 0=E2=80=933=E2=80=9408h; Channels 4=E2=80=937=E2=80= =940D0h Also the size of the region is wrong. Fixes WinXP-32 installation. Signed-off-by: Marcelo Tosatti diff --git a/hw/dma.c b/hw/dma.c index c2d7b21..e7de522 100644 --- a/hw/dma.c +++ b/hw/dma.c @@ -56,6 +56,7 @@ static struct dma_cont { uint8_t mask; uint8_t flip_flop; int dshift; + int iobase; struct dma_regs regs[4]; qemu_irq *cpu_request_exit; MemoryRegion channel_io; @@ -192,7 +193,8 @@ static void write_chan(void *opaque, hwaddr nport, ui= nt64_t data, } } =20 -static void write_cont(void *opaque, hwaddr nport, uint64_t data, + +static void __write_cont(void *opaque, hwaddr nport, uint64_t data, unsigned size) { struct dma_cont *d =3D opaque; @@ -200,7 +202,7 @@ static void write_cont(void *opaque, hwaddr nport, ui= nt64_t data, =20 iport =3D (nport >> d->dshift) & 0x0f; switch (iport) { - case 0x01: /* command */ + case 0x08: /* command */ if ((data !=3D 0) && (data & CMD_NOT_SUPPORTED)) { dolog("command %"PRIx64" not supported\n", data); return; @@ -208,7 +210,7 @@ static void write_cont(void *opaque, hwaddr nport, ui= nt64_t data, d->command =3D data; break; =20 - case 0x02: + case 0x09: ichan =3D data & 3; if (data & 4) { d->status |=3D 1 << (ichan + 4); @@ -220,7 +222,7 @@ static void write_cont(void *opaque, hwaddr nport, ui= nt64_t data, DMA_run(); break; =20 - case 0x03: /* single mask */ + case 0x0a: /* single mask */ if (data & 4) d->mask |=3D 1 << (data & 3); else @@ -228,7 +230,7 @@ static void write_cont(void *opaque, hwaddr nport, ui= nt64_t data, DMA_run(); break; =20 - case 0x04: /* mode */ + case 0x0b: /* mode */ { ichan =3D data & 3; #ifdef DEBUG_DMA @@ -247,23 +249,23 @@ static void write_cont(void *opaque, hwaddr nport, = uint64_t data, break; } =20 - case 0x05: /* clear flip flop */ + case 0x0c: /* clear flip flop */ d->flip_flop =3D 0; break; =20 - case 0x06: /* reset */ + case 0x0d: /* reset */ d->flip_flop =3D 0; d->mask =3D ~0; d->status =3D 0; d->command =3D 0; break; =20 - case 0x07: /* clear mask for all channels */ + case 0x0e: /* clear mask for all channels */ d->mask =3D 0; DMA_run(); break; =20 - case 0x08: /* write mask for all channels */ + case 0x0f: /* write mask for all channels */ d->mask =3D data; DMA_run(); break; @@ -281,11 +283,22 @@ static void write_cont(void *opaque, hwaddr nport, = uint64_t data, #endif } =20 +static void write_cont(void *opaque, hwaddr nport, uint64_t data, + unsigned size) +{ + struct dma_cont *d =3D opaque; + int add =3D d->iobase + (8 << d->dshift); + + __write_cont(opaque, nport+add, data, size); +} + static uint64_t read_cont(void *opaque, hwaddr nport, unsigned size) { struct dma_cont *d =3D opaque; int iport, val; =20 + nport +=3D d->iobase + (8 << d->dshift); + iport =3D (nport >> d->dshift) & 0x0f; switch (iport) { case 0x08: /* status */ @@ -467,7 +480,7 @@ void DMA_schedule(int nchan) static void dma_reset(void *opaque) { struct dma_cont *d =3D opaque; - write_cont(d, (0x06 << d->dshift), 0, 1); + __write_cont(d, (0xd << d->dshift), 0, 1); } =20 static int dma_phony_handler (void *opaque, int nchan, int dma_pos, int = dma_len) @@ -523,7 +536,7 @@ static void dma_init2(struct dma_cont *d, int base, i= nt dshift, d->cpu_request_exit =3D cpu_request_exit; =20 memory_region_init_io(&d->channel_io, &channel_io_ops, d, - "dma-chan", 8 << d->dshift); + "dma-chan", 8); memory_region_add_subregion(isa_address_space_io(NULL), base, &d->channel_io); =20 @@ -535,12 +548,13 @@ static void dma_init2(struct dma_cont *d, int base,= int dshift, } =20 memory_region_init_io(&d->cont_io, &cont_io_ops, d, "dma-cont", - 8 << d->dshift); + 8); memory_region_add_subregion(isa_address_space_io(NULL), base + (8 << d->dshift), &d->cont_io); =20 qemu_register_reset(dma_reset, d); dma_reset(d); + d->iobase =3D base; for (i =3D 0; i < ARRAY_SIZE (d->regs); ++i) { d->regs[i].transfer_handler =3D dma_phony_handler; }