From 30476b2282c69c9ec1e44e33a4c0b5d5f4bc884e Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 30 Mar 2015 12:50:36 +0200 Subject: ioport: remove wrong comment ioport.c has not been using an alias since commit b40acf9 (ioport: Switch dispatching to memory core layer, 2013-06-24). Remove the obsolete comment. Signed-off-by: Paolo Bonzini --- ioport.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'ioport.c') diff --git a/ioport.c b/ioport.c index 783a3ae675..eb954e3460 100644 --- a/ioport.c +++ b/ioport.c @@ -239,10 +239,6 @@ static void portio_list_add_1(PortioList *piolist, mrpio->ports[i].base = start + off_low; } - /* - * Use an alias so that the callback is called with an absolute address, - * rather than an offset relative to to start + off_low. - */ memory_region_init_io(&mrpio->mr, piolist->owner, &portio_ops, mrpio, piolist->name, off_high - off_low); if (piolist->flush_coalesced_mmio) { -- cgit v1.2.3 From 147ed379838176d4780688157891c06f49403b19 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 30 Mar 2015 12:49:40 +0200 Subject: ioport: loosen assertions on emulation of 16-bit ports Right now, ioport.c assumes that the entire range specified with MemoryRegionPortio includes a region with size == 1. This however is not true for the VBE DISPI ports, which are 16-bit only. The next patch will make these regions' length equal to two, which can cause the assertions to trigger. Replace them with simple conditionals. Also, ioport.c will emulate a 16-bit ioport with two distinct reads or writes, even if one of the two accesses is out of the bounds given by the MemoryRegionPortio array. Do not do this anymore, instead discard writes to the incorrect register and read it as all-ones. This ensures that the mrp->read and mrp->write callbacks get an in-range ioport number. Signed-off-by: Paolo Bonzini --- ioport.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'ioport.c') diff --git a/ioport.c b/ioport.c index eb954e3460..090c2628ed 100644 --- a/ioport.c +++ b/ioport.c @@ -187,9 +187,14 @@ static uint64_t portio_read(void *opaque, hwaddr addr, unsigned size) data = mrp->read(mrpio->portio_opaque, mrp->base + addr); } else if (size == 2) { mrp = find_portio(mrpio, addr, 1, false); - assert(mrp); - data = mrp->read(mrpio->portio_opaque, mrp->base + addr) | - (mrp->read(mrpio->portio_opaque, mrp->base + addr + 1) << 8); + if (mrp) { + data = mrp->read(mrpio->portio_opaque, mrp->base + addr); + if (addr + 1 < mrp->offset + mrp->len) { + data |= mrp->read(mrpio->portio_opaque, mrp->base + addr + 1) << 8; + } else { + data |= 0xff00; + } + } } return data; } @@ -204,9 +209,12 @@ static void portio_write(void *opaque, hwaddr addr, uint64_t data, mrp->write(mrpio->portio_opaque, mrp->base + addr, data); } else if (size == 2) { mrp = find_portio(mrpio, addr, 1, true); - assert(mrp); - mrp->write(mrpio->portio_opaque, mrp->base + addr, data & 0xff); - mrp->write(mrpio->portio_opaque, mrp->base + addr + 1, data >> 8); + if (mrp) { + mrp->write(mrpio->portio_opaque, mrp->base + addr, data & 0xff); + if (addr + 1 < mrp->offset + mrp->len) { + mrp->write(mrpio->portio_opaque, mrp->base + addr + 1, data >> 8); + } + } } } -- cgit v1.2.3 From 4080a13c11398d684668d286da27b6f8ee668e44 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 30 Mar 2015 12:35:00 +0200 Subject: ioport: reserve the whole range of an I/O port in the AddressSpace When an I/O port is more than 1 byte long, ioport.c is currently creating "short" regions, for example 0x1ce-0x1ce for the 16-bit Bochs index port. When I/O ports are memory mapped, and thus accessed via a subpage_ops memory region, subpage_accepts gets confused because it finds a hole at 0x1cf and rejects the access. In order to fix this, modify registration of the region to cover the whole size of the I/O port. Attempts to access an invalid port will be blocked by find_portio returning NULL. This only affects the VBE DISPI regions. For all other cases, the MemoryRegionPortio entries for 2- or 4-byte accesses overlap an entry for 1-byte accesses, thus the size of the memory region is not affected. Reported-by: Zoltan Balaton Signed-off-by: Paolo Bonzini --- ioport.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'ioport.c') diff --git a/ioport.c b/ioport.c index 090c2628ed..304d5d6f59 100644 --- a/ioport.c +++ b/ioport.c @@ -269,7 +269,7 @@ void portio_list_add(PortioList *piolist, /* Handle the first entry specially. */ off_last = off_low = pio_start->offset; - off_high = off_low + pio_start->len; + off_high = off_low + pio_start->len + pio_start->size - 1; count = 1; for (pio = pio_start + 1; pio->size != 0; pio++, count++) { @@ -284,10 +284,10 @@ void portio_list_add(PortioList *piolist, /* ... and start collecting anew. */ pio_start = pio; off_low = off_last; - off_high = off_low + pio->len; + off_high = off_low + pio->len + pio_start->size - 1; count = 0; } else if (off_last + pio->len > off_high) { - off_high = off_last + pio->len; + off_high = off_last + pio->len + pio_start->size - 1; } } -- cgit v1.2.3