From patchwork Wed Jun 8 11:33:32 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 1776 Return-Path: Delivered-To: unknown Received: from imap.gmail.com (74.125.159.109) by localhost6.localdomain6 with IMAP4-SSL; 08 Jun 2011 14:55:46 -0000 Delivered-To: patches@linaro.org Received: by 10.52.181.10 with SMTP id ds10cs168044vdc; Wed, 8 Jun 2011 04:33:44 -0700 (PDT) Received: by 10.14.52.207 with SMTP id e55mr2953168eec.3.1307532822499; Wed, 08 Jun 2011 04:33:42 -0700 (PDT) Received: from mnementh.archaic.org.uk (mnementh.archaic.org.uk [81.2.115.146]) by mx.google.com with ESMTPS id a48si833629eeg.63.2011.06.08.04.33.41 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 08 Jun 2011 04:33:42 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 81.2.115.146 as permitted sender) client-ip=81.2.115.146; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 81.2.115.146 as permitted sender) smtp.mail=pm215@archaic.org.uk Received: from pm215 by mnementh.archaic.org.uk with local (Exim 4.72) (envelope-from ) id 1QUH0v-00074o-Fa; Wed, 08 Jun 2011 12:33:33 +0100 From: Peter Maydell To: qemu-devel@nongnu.org Cc: patches@linaro.org, Paul Brook , Anthony Liguori , Markus Armbruster , =?UTF-8?q?Juha=20Riihim=C3=A4ki?= Subject: [PATCH RFC 2/3] sysbus: Allow sysbus MMIO passthrough Date: Wed, 8 Jun 2011 12:33:32 +0100 Message-Id: <1307532813-27175-3-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> Add new function sysbus_pass_mmio() to allow a sysbus device to delegate MMIO to another sysbus device. This allows a limited form of composition for sysbus devices. Signed-off-by: Peter Maydell --- hw/sysbus.c | 26 ++++++++++++++++++++++++++ hw/sysbus.h | 3 +++ 2 files changed, 29 insertions(+), 0 deletions(-) diff --git a/hw/sysbus.c b/hw/sysbus.c index 01ebe47..793b0c1 100644 --- a/hw/sysbus.c +++ b/hw/sysbus.c @@ -43,6 +43,10 @@ void sysbus_mmio_unmap(SysBusDevice *dev, int n) { assert(n >= 0 && n < dev->num_mmio); + if (dev->mmio[n].delegate) { + sysbus_mmio_unmap(dev->mmio[n].delegate, dev->mmio[n].delegate_mmio); + return; + } if (dev->mmio[n].addr == (target_phys_addr_t)-1) { /* region already unmapped */ return; @@ -60,6 +64,11 @@ void sysbus_mmio_map(SysBusDevice *dev, int n, target_phys_addr_t addr) { assert(n >= 0 && n < dev->num_mmio); + if (dev->mmio[n].delegate) { + sysbus_mmio_map(dev->mmio[n].delegate, dev->mmio[n].delegate_mmio, + addr); + return; + } if (dev->mmio[n].addr == addr) { /* ??? region already mapped here. */ return; @@ -83,6 +92,11 @@ 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 (dev->mmio[n].delegate) { + sysbus_mmio_resize(dev->mmio[n].delegate, dev->mmio[n].delegate_mmio, + newsize); + return; + } if (newsize != dev->mmio[n].size) { addr = dev->mmio[n].addr; if (addr != (target_phys_addr_t)-1) { @@ -127,6 +141,7 @@ void sysbus_init_mmio(SysBusDevice *dev, target_phys_addr_t size, assert(dev->num_mmio < QDEV_MAX_MMIO); n = dev->num_mmio++; + dev->mmio[n].delegate = 0; dev->mmio[n].addr = -1; dev->mmio[n].size = size; dev->mmio[n].iofunc = iofunc; @@ -139,11 +154,22 @@ void sysbus_init_mmio_cb(SysBusDevice *dev, target_phys_addr_t size, assert(dev->num_mmio < QDEV_MAX_MMIO); n = dev->num_mmio++; + dev->mmio[n].delegate = 0; dev->mmio[n].addr = -1; dev->mmio[n].size = size; dev->mmio[n].cb = cb; } +void sysbus_pass_mmio(SysBusDevice *dev, SysBusDevice *target, int target_mmio) +{ + int n; + + assert(dev->num_mmio < QDEV_MAX_MMIO); + n = dev->num_mmio++; + dev->mmio[n].delegate = target; + dev->mmio[n].delegate_mmio = target_mmio; +} + void sysbus_init_ioports(SysBusDevice *dev, pio_addr_t ioport, pio_addr_t size) { pio_addr_t i; diff --git a/hw/sysbus.h b/hw/sysbus.h index 70e2488..789e4c5 100644 --- a/hw/sysbus.h +++ b/hw/sysbus.h @@ -19,6 +19,8 @@ struct SysBusDevice { qemu_irq *irqp[QDEV_MAX_IRQ]; int num_mmio; struct { + SysBusDevice *delegate; + int delegate_mmio; target_phys_addr_t addr; target_phys_addr_t size; mmio_mapfunc cb; @@ -46,6 +48,7 @@ void sysbus_init_mmio(SysBusDevice *dev, target_phys_addr_t size, ram_addr_t iofunc); void sysbus_init_mmio_cb(SysBusDevice *dev, target_phys_addr_t size, mmio_mapfunc cb); +void sysbus_pass_mmio(SysBusDevice *dev, SysBusDevice *target, int target_mmio); void sysbus_init_irq(SysBusDevice *dev, qemu_irq *p); void sysbus_pass_irq(SysBusDevice *dev, SysBusDevice *target); void sysbus_init_ioports(SysBusDevice *dev, pio_addr_t ioport, pio_addr_t size);