From patchwork Wed Jun 8 11:33:31 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 99416 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [140.186.70.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id E6DD1B6FB8 for ; Wed, 8 Jun 2011 21:59:58 +1000 (EST) Received: from localhost ([::1]:50219 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QUHQP-0008E8-SR for incoming@patchwork.ozlabs.org; Wed, 08 Jun 2011 07:59:54 -0400 Received: from eggs.gnu.org ([140.186.70.92]:59190) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QUHN6-0008D5-8C for qemu-devel@nongnu.org; Wed, 08 Jun 2011 07:56:30 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QUHN4-0002Xr-Nt for qemu-devel@nongnu.org; Wed, 08 Jun 2011 07:56:28 -0400 Received: from mnementh.archaic.org.uk ([81.2.115.146]:41603) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QUHN3-0002XU-SM for qemu-devel@nongnu.org; Wed, 08 Jun 2011 07:56:26 -0400 Received: from pm215 by mnementh.archaic.org.uk with local (Exim 4.72) (envelope-from ) id 1QUH0v-00074m-Ey; Wed, 08 Jun 2011 12:33:33 +0100 From: Peter Maydell To: qemu-devel@nongnu.org Date: Wed, 8 Jun 2011 12:33:31 +0100 Message-Id: <1307532813-27175-2-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 1.7.2.5 In-Reply-To: <1307532813-27175-1-git-send-email-peter.maydell@linaro.org> References: <1307532813-27175-1-git-send-email-peter.maydell@linaro.org> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-Received-From: 81.2.115.146 Cc: Markus Armbruster , Anthony Liguori , =?UTF-8?q?Juha=20Riihim=C3=A4ki?= , Paul Brook , patches@linaro.org Subject: [Qemu-devel] [PATCH RFC 1/3] sysbus: Add support for resizing and unmapping MMIOs X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Juha Riihimäki Add new functions sysbus_mmio_unmap() and sysbus_mmio_resize() which allow a sysbus device user to trim the size of the device's mmio region and also to unmap it. The rationale here is twofold: * Some generic qdev devices might have an mmio region that doesn't match the specific implementation. For example usb-ohci creates an 0x1000 byte mmio for its registers, but the instantiation of the OHCI controller on OMAP3 has only an 0x400 byte space in the memory map. Using resize lets us not worry about how overlapping mapped regions are resolved. * The OMAP GPMC (general purpose memory controller) has a set of registers which allow the guest to control whether and at what size various of its subdevices are mapped. At the moment QEMU's omap_gpmc model isn't qdevified, but when it and its children are this will be necessary. Signed-off-by: Juha Riihimäki Reviewed-by: Peter Maydell --- hw/sysbus.c | 37 +++++++++++++++++++++++++++++++++++++ hw/sysbus.h | 2 ++ 2 files changed, 39 insertions(+), 0 deletions(-) diff --git a/hw/sysbus.c b/hw/sysbus.c index 2e22be7..01ebe47 100644 --- a/hw/sysbus.c +++ b/hw/sysbus.c @@ -39,6 +39,23 @@ void sysbus_connect_irq(SysBusDevice *dev, int n, qemu_irq irq) } } +void sysbus_mmio_unmap(SysBusDevice *dev, int n) +{ + assert(n >= 0 && n < dev->num_mmio); + + if (dev->mmio[n].addr == (target_phys_addr_t)-1) { + /* region already unmapped */ + return; + } + if (dev->mmio[n].cb) { + dev->mmio[n].cb(dev, (target_phys_addr_t)-1); + } else { + cpu_register_physical_memory(dev->mmio[n].addr, dev->mmio[n].size, + IO_MEM_UNASSIGNED); + } + dev->mmio[n].addr = (target_phys_addr_t)-1; +} + void sysbus_mmio_map(SysBusDevice *dev, int n, target_phys_addr_t addr) { assert(n >= 0 && n < dev->num_mmio); @@ -61,6 +78,26 @@ void sysbus_mmio_map(SysBusDevice *dev, int n, target_phys_addr_t addr) } } +void sysbus_mmio_resize(SysBusDevice *dev, int n, target_phys_addr_t newsize) +{ + target_phys_addr_t addr; + assert(n >= 0 && n < dev->num_mmio); + + if (newsize != dev->mmio[n].size) { + addr = dev->mmio[n].addr; + if (addr != (target_phys_addr_t)-1) { + /* The expected use case is that resizes will only happen + * on unmapped regions, but we handle the already-mapped + * case by temporarily unmapping and remapping. + */ + sysbus_mmio_unmap(dev, n); + } + dev->mmio[n].size = newsize; + if (addr != (target_phys_addr_t)-1) { + sysbus_mmio_map(dev, n, addr); + } + } +} /* Request an IRQ source. The actual IRQ object may be populated later. */ void sysbus_init_irq(SysBusDevice *dev, qemu_irq *p) diff --git a/hw/sysbus.h b/hw/sysbus.h index 4e8cb16..70e2488 100644 --- a/hw/sysbus.h +++ b/hw/sysbus.h @@ -53,6 +53,8 @@ void sysbus_init_ioports(SysBusDevice *dev, pio_addr_t ioport, pio_addr_t size); void sysbus_connect_irq(SysBusDevice *dev, int n, qemu_irq irq); void sysbus_mmio_map(SysBusDevice *dev, int n, target_phys_addr_t addr); +void sysbus_mmio_unmap(SysBusDevice *dev, int n); +void sysbus_mmio_resize(SysBusDevice *dev, int n, target_phys_addr_t newsize); /* Legacy helper function for creating devices. */ DeviceState *sysbus_create_varargs(const char *name,