From: Marcelo Tosatti <mtosatti@redhat.com>
To: Julien Grall <julien.grall@citrix.com>
Cc: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH] fix dma.c MemoryRegion convertion
Date: Fri, 14 Dec 2012 21:39:57 -0200 [thread overview]
Message-ID: <20121214233957.GA19778@amt.cnet> (raw)
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—DMA Command Register (IO)
I/O Address: Channels 0–3—08h; Channels 4–7—0D0h
Also the size of the region is wrong.
Fixes WinXP-32 installation.
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
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, uint64_t data,
}
}
-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 = opaque;
@@ -200,7 +202,7 @@ static void write_cont(void *opaque, hwaddr nport, uint64_t data,
iport = (nport >> d->dshift) & 0x0f;
switch (iport) {
- case 0x01: /* command */
+ case 0x08: /* command */
if ((data != 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, uint64_t data,
d->command = data;
break;
- case 0x02:
+ case 0x09:
ichan = data & 3;
if (data & 4) {
d->status |= 1 << (ichan + 4);
@@ -220,7 +222,7 @@ static void write_cont(void *opaque, hwaddr nport, uint64_t data,
DMA_run();
break;
- case 0x03: /* single mask */
+ case 0x0a: /* single mask */
if (data & 4)
d->mask |= 1 << (data & 3);
else
@@ -228,7 +230,7 @@ static void write_cont(void *opaque, hwaddr nport, uint64_t data,
DMA_run();
break;
- case 0x04: /* mode */
+ case 0x0b: /* mode */
{
ichan = data & 3;
#ifdef DEBUG_DMA
@@ -247,23 +249,23 @@ static void write_cont(void *opaque, hwaddr nport, uint64_t data,
break;
}
- case 0x05: /* clear flip flop */
+ case 0x0c: /* clear flip flop */
d->flip_flop = 0;
break;
- case 0x06: /* reset */
+ case 0x0d: /* reset */
d->flip_flop = 0;
d->mask = ~0;
d->status = 0;
d->command = 0;
break;
- case 0x07: /* clear mask for all channels */
+ case 0x0e: /* clear mask for all channels */
d->mask = 0;
DMA_run();
break;
- case 0x08: /* write mask for all channels */
+ case 0x0f: /* write mask for all channels */
d->mask = data;
DMA_run();
break;
@@ -281,11 +283,22 @@ static void write_cont(void *opaque, hwaddr nport, uint64_t data,
#endif
}
+static void write_cont(void *opaque, hwaddr nport, uint64_t data,
+ unsigned size)
+{
+ struct dma_cont *d = opaque;
+ int add = 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 = opaque;
int iport, val;
+ nport += d->iobase + (8 << d->dshift);
+
iport = (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 = opaque;
- write_cont(d, (0x06 << d->dshift), 0, 1);
+ __write_cont(d, (0xd << d->dshift), 0, 1);
}
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, int dshift,
d->cpu_request_exit = cpu_request_exit;
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);
@@ -535,12 +548,13 @@ static void dma_init2(struct dma_cont *d, int base, int dshift,
}
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);
qemu_register_reset(dma_reset, d);
dma_reset(d);
+ d->iobase = base;
for (i = 0; i < ARRAY_SIZE (d->regs); ++i) {
d->regs[i].transfer_handler = dma_phony_handler;
}
next reply other threads:[~2012-12-14 23:53 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-12-14 23:39 Marcelo Tosatti [this message]
2012-12-15 9:02 ` [Qemu-devel] [PATCH] fix dma.c MemoryRegion convertion Blue Swirl
2012-12-15 13:45 ` Julien Grall
2012-12-15 17:08 ` Andreas Färber
2012-12-17 0:01 ` Marcelo Tosatti
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20121214233957.GA19778@amt.cnet \
--to=mtosatti@redhat.com \
--cc=julien.grall@citrix.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.