summaryrefslogtreecommitdiff
path: root/ioport.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2015-04-30 12:04:11 +0100
committerPeter Maydell <peter.maydell@linaro.org>2015-04-30 12:04:11 +0100
commit06feaacfb4cfef10cc0c93d97df7bfc8a71dbc7e (patch)
tree2aa3c097c678d2d5dde83d6df450aec28b994452 /ioport.c
parenta1fe58f6ad2282399da256b8579b49b43527e486 (diff)
parentd064d9f381b00538e41f14104b88a1ae85d78865 (diff)
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
- miscellaneous cleanups for TCG (Emilio) and NBD (Bogdan) - next part in the thread-safe address_space_* saga: atomic access to the bounce buffer and the map_clients list, from Fam - optional support for linking with tcmalloc, also from Fam - reapplying Peter Crosthwaite's "Respect as_translate_internal length clamp" after fixing the SPARC fallout. - build system fix from Wei Liu - small acpi-build and ioport cleanup by myself # gpg: Signature made Wed Apr 29 09:34:00 2015 BST using RSA key ID 78C7AE83 # gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" # gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" # gpg: WARNING: This key is not certified with sufficiently trusted signatures! # gpg: It is not certain that the signature belongs to the owner. # Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1 # Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83 * remotes/bonzini/tags/for-upstream: (22 commits) nbd/trivial: fix type cast for ioctl translate-all: use bitmap helpers for PageDesc's bitmap target-i386: disable LINT0 after reset Makefile.target: prepend $libs_softmmu to $LIBS milkymist: do not modify libs-softmmu configure: Add support for tcmalloc exec: Respect as_translate_internal length clamp ioport: reserve the whole range of an I/O port in the AddressSpace ioport: loosen assertions on emulation of 16-bit ports ioport: remove wrong comment ide: there is only one data port gus: clean up MemoryRegionPortio sb16: remove useless mixer_write_indexw sun4m: fix slavio sysctrl and led register sizes acpi-build: remove dependency from ram_addr.h memory: add memory_region_ram_resize dma-helpers: Fix race condition of continue_after_map_failure and dma_aio_cancel exec: Notify cpu_register_map_client caller if the bounce buffer is available exec: Protect map_client_list with mutex linux-user, bsd-user: Remove two calls to cpu_exec_init_all ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
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;
}
}