From ccc04a70823d23bda0a7ae14651444363cf624ad Mon Sep 17 00:00:00 2001 From: Sebastian Sumpf Date: Tue, 16 May 2023 19:30:56 +0200 Subject: [PATCH] qemu-usb: support read/write of unused IO ranges The XHCI model reserves 0x4000 of IO memory but uses only 0x530. Implement read (0) and write (nop) for these regions as real hardware does. fixes #4902 --- repos/libports/src/lib/qemu-usb/qemu_emul.cc | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/repos/libports/src/lib/qemu-usb/qemu_emul.cc b/repos/libports/src/lib/qemu-usb/qemu_emul.cc index 23d17ec64e..d2583b203e 100644 --- a/repos/libports/src/lib/qemu-usb/qemu_emul.cc +++ b/repos/libports/src/lib/qemu-usb/qemu_emul.cc @@ -633,18 +633,28 @@ struct Controller : public Qemu::Controller MemoryRegionOps const *ops; } mmio_regions [max_numports() + 4 /* number of HC MMIO regions */]; + uint64_t _mmio_size; typedef Genode::Hex Hex; + /* + * The device model does not implement the whole _mmio_size, add read/write + * for the gaps. + */ + static uint64_t _read_unsued(void *, hwaddr, unsigned) { return 0ul; } + static void _write_unsused(void *, hwaddr, uint64_t, unsigned) { } + MemoryRegionOps _ops { _read_unsued, _write_unsused }; + Mmio _unused_region { 0, 0, 0, &_ops }; + Controller() { Genode::memset(mmio_regions, 0, sizeof(mmio_regions)); } - void mmio_add_region(uint64_t size) { _mmio_size = size; } + void mmio_add_region(uint64_t size) { _mmio_size = size; } - void mmio_add_region_io(Genode::addr_t id, uint64_t size, MemoryRegionOps const *ops) + void mmio_add_region_io(Genode::addr_t id, uint64_t size, MemoryRegionOps const *ops) { for (Mmio &mmio : mmio_regions) { if (mmio.id != 0) continue; @@ -664,12 +674,10 @@ struct Controller : public Qemu::Controller return mmio; } - Genode::error("could not find MMIO region for offset: ", - Genode::Hex(offset)); - throw -1; + return _unused_region; } - void mmio_add_sub_region(Genode::addr_t id, Genode::off_t offset) + void mmio_add_sub_region(Genode::addr_t id, Genode::off_t offset) { for (Mmio &mmio : mmio_regions) { if (mmio.id != id) continue;