aboutsummaryrefslogtreecommitdiff
path: root/ioport.c
diff options
context:
space:
mode:
Diffstat (limited to 'ioport.c')
-rw-r--r--ioport.c30
1 files changed, 17 insertions, 13 deletions
diff --git a/ioport.c b/ioport.c
index b345bd9abe..e39093edb9 100644
--- a/ioport.c
+++ b/ioport.c
@@ -191,9 +191,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;
}
@@ -208,9 +213,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);
+ }
+ }
}
}
@@ -243,10 +251,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) {
@@ -269,7 +273,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 +288,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;
}
}