From patchwork Mon Jan 4 10:45:16 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Isaku Yamahata X-Patchwork-Id: 42058 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id EFA31B6F0F for ; Mon, 4 Jan 2010 21:46:23 +1100 (EST) Received: from localhost ([127.0.0.1]:48552 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NRkS0-0003Ou-3z for incoming@patchwork.ozlabs.org; Mon, 04 Jan 2010 05:46:16 -0500 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1NRkR7-0003Nt-9l for qemu-devel@nongnu.org; Mon, 04 Jan 2010 05:45:21 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1NRkR2-0003Kc-Ov for qemu-devel@nongnu.org; Mon, 04 Jan 2010 05:45:20 -0500 Received: from [199.232.76.173] (port=44966 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NRkR2-0003KR-G7 for qemu-devel@nongnu.org; Mon, 04 Jan 2010 05:45:16 -0500 Received: from mail.valinux.co.jp ([210.128.90.3]:50703) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1NRkR1-0003K0-LQ for qemu-devel@nongnu.org; Mon, 04 Jan 2010 05:45:16 -0500 Received: from ps.local.valinux.co.jp (vagw.valinux.co.jp [210.128.90.14]) by mail.valinux.co.jp (Postfix) with SMTP id 6FC091827A; Mon, 4 Jan 2010 19:45:08 +0900 (JST) Received: (nullmailer pid 19316 invoked by uid 1000); Mon, 04 Jan 2010 10:45:16 -0000 Date: Mon, 4 Jan 2010 19:45:16 +0900 From: Isaku Yamahata To: Alexander Graf Subject: Re: [Qemu-devel] Re: [PATCH 1/6] Make config space accessor host bus trapable Message-ID: <20100104104516.GD4672@valinux.co.jp> References: <20100103154539.GB8137@redhat.com> <75078DD9-314F-4FA8-896B-36C5B771C6A7@suse.de> <20100103172937.GB8508@redhat.com> <20100103174430.GA8522@redhat.com> <41679128-EE37-47DA-82F6-830A4C364183@suse.de> <20100103180609.GB8522@redhat.com> <472F306A-0699-401C-8E6A-8E79B86E4C95@suse.de> <1262551822.2173.267.camel@pasglop> <19BFDDD5-85E0-42EC-9D71-391CECC023F5@suse.de> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <19BFDDD5-85E0-42EC-9D71-391CECC023F5@suse.de> User-Agent: Mutt/1.5.19 (2009-01-05) X-Virus-Scanned: clamav-milter 0.95.2 at va-mail.local.valinux.co.jp X-Virus-Status: Clean X-detected-operating-system: by monty-python.gnu.org: GNU/Linux 2.6 (newer, 3) Cc: Blue Swirl , QEMU Developers , Aurelien Jarno , "Michael S. Tsirkin" X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org On Mon, Jan 04, 2010 at 04:26:46AM +0100, Alexander Graf wrote: > > On 03.01.2010, at 21:50, Benjamin Herrenschmidt wrote: > > > On Sun, 2010-01-03 at 21:27 +0100, Alexander Graf wrote: > > > >> I think if unin_pci is the only user, it'd be better to do it hacky > >> inside unin_pci.c. But if there's a chance there's another user, it'd > >> be better to make it generic. > >> > >> Since this is the first time I ever stumbled across type 0 and type 1 > >> PCI config space addresses, I simply don't know if there are any. Blue > >> Swirls comment indicated that there are. Ben also sounded as if it's > >> rather common to not use the x86 format. On the other hand, it looks > >> like nobody in qemu needed it so far - and we're implementing ARM, > >> MIPS and all other sorts of platforms. > >> > >> So if anyone with knowledge in PCI could shed some light here, please > >> do so. > > > > My feeling is that what you're better off doing is to have the qemu core > > take an abstract struct to identify a device config space location, that > > consists of separate fields for: > > > > - The PCI domain (which is what host bridge it hangs off since bus > > numbers are not unique between domains) > > > > - The bus number > > Hm, I think it'd make more sense to just store a PCIBus pointer in there. We could then fetch the bus and domain id from there. > > I'll write something up :-). > > > Alex > Does the following patch help? I did only compile test though. From 9c62b4846f95ebe84e182f76295016e1fe980699 Mon Sep 17 00:00:00 2001 From: Isaku Yamahata Date: Mon, 4 Jan 2010 19:39:36 +0900 Subject: [PATCH] pci: pcihost clean up. remove some codes by introduce callback to calculate pci device and offset in configuration space. Signed-off-by: Isaku Yamahata --- hw/gt64xxx.c | 9 +--- hw/pci_host.c | 115 ++++++++++++++++++++++++++++-------------------- hw/pci_host.h | 17 ++++++- hw/pci_host_template.h | 21 +++------ hw/prep_pci.c | 68 +++-------------------------- hw/sh_pci.c | 92 +++++++++++++++++--------------------- hw/versatile_pci.c | 74 +++++-------------------------- 7 files changed, 150 insertions(+), 246 deletions(-) diff --git a/hw/gt64xxx.c b/hw/gt64xxx.c index fb7f5bd..b399f0c 100644 --- a/hw/gt64xxx.c +++ b/hw/gt64xxx.c @@ -530,8 +530,7 @@ static void gt64120_writel (void *opaque, target_phys_addr_t addr, case GT_PCI0_CFGDATA: if (!(s->regs[GT_PCI0_CMD] & 1) && (s->pci->config_reg & 0x00fff800)) val = bswap32(val); - if (s->pci->config_reg & (1u << 31)) - pci_data_write(s->pci->bus, s->pci->config_reg, val, 4); + pci_data_write(s->pci, 0, val, 4); break; /* Interrupts */ @@ -768,10 +767,7 @@ static uint32_t gt64120_readl (void *opaque, val = s->pci->config_reg; break; case GT_PCI0_CFGDATA: - if (!(s->pci->config_reg & (1 << 31))) - val = 0xffffffff; - else - val = pci_data_read(s->pci->bus, s->pci->config_reg, 4); + val = pci_data_read(s->pci, 0, 4); if (!(s->regs[GT_PCI0_CMD] & 1) && (s->pci->config_reg & 0x00fff800)) val = bswap32(val); break; @@ -1119,6 +1115,7 @@ PCIBus *pci_gt64120_init(qemu_irq *pic) s = qemu_mallocz(sizeof(GT64120State)); s->pci = qemu_mallocz(sizeof(GT64120PCIState)); + pci_host_init(s->pci, NULL, NULL); s->pci->bus = pci_register_bus(NULL, "pci", pci_gt64120_set_irq, pci_gt64120_map_irq, diff --git a/hw/pci_host.c b/hw/pci_host.c index eeb8dee..6677175 100644 --- a/hw/pci_host.c +++ b/hw/pci_host.c @@ -40,6 +40,49 @@ do { printf("pci_host_data: " fmt , ## __VA_ARGS__); } while (0) */ /* the helper functio to get a PCIDeice* for a given pci address */ +PCIDevice *pci_host_find_dev(PCIBus *bus, uint32_t addr) +{ + uint8_t bus_num = addr >> 16; + uint8_t devfn = addr >> 8; + + return pci_find_device(bus, bus_num, PCI_SLOT(devfn), PCI_FUNC(devfn)); +} + +uint32_t pci_host_config_offset(uint32_t addr) +{ + return addr & (PCI_CONFIG_SPACE_SIZE - 1); +} + +static uint32_t pci_host_pci_addr(PCIHostState *s, uint32_t addr) +{ + return s->config_reg | (addr & 3); +} +static PCIDevice *pci_host_find_dev_active(PCIBus *bus, uint32_t pci_addr) +{ + if (!(pci_addr & (1u << 31))) + return NULL; + + return pci_host_find_dev(bus, pci_addr); +} + +static PCIDevice *pci_host_dev_find_fn_noswap(PCIHostState *s, uint32_t addr) +{ + return pci_host_find_dev_active(s->bus, pci_host_pci_addr(s, addr)); +} + +static PCIDevice *pci_host_dev_find_fn(PCIHostState *s, uint32_t addr) +{ +#ifdef TARGET_WORDS_BIGENDIAN + addr = bswap32(addr); +#endif + return pci_host_find_dev_active(s->bus, pci_host_pci_addr(s, addr)); +} + +static uint32_t pci_host_config_offset_fn(PCIHostState *s, uint32_t addr) +{ + return pci_host_config_offset(pci_host_pci_addr(s, addr)); +} + static inline PCIDevice *pci_dev_find_by_addr(PCIBus *bus, uint32_t addr) { uint8_t bus_num = addr >> 16; @@ -48,10 +91,10 @@ static inline PCIDevice *pci_dev_find_by_addr(PCIBus *bus, uint32_t addr) return pci_find_device(bus, bus_num, PCI_SLOT(devfn), PCI_FUNC(devfn)); } -void pci_data_write(PCIBus *s, uint32_t addr, uint32_t val, int len) +void pci_data_write(PCIHostState *s, uint32_t addr, uint32_t val, int len) { - PCIDevice *pci_dev = pci_dev_find_by_addr(s, addr); - uint32_t config_addr = addr & (PCI_CONFIG_SPACE_SIZE - 1); + PCIDevice *pci_dev = s->dev_find(s, addr); + uint32_t config_addr = s->config_offset(s, addr); if (!pci_dev) return; @@ -61,10 +104,10 @@ void pci_data_write(PCIBus *s, uint32_t addr, uint32_t val, int len) pci_dev->config_write(pci_dev, config_addr, val, len); } -uint32_t pci_data_read(PCIBus *s, uint32_t addr, int len) +uint32_t pci_data_read(PCIHostState *s, uint32_t addr, int len) { - PCIDevice *pci_dev = pci_dev_find_by_addr(s, addr); - uint32_t config_addr = addr & (PCI_CONFIG_SPACE_SIZE - 1); + PCIDevice *pci_dev = s->dev_find(s, addr); + uint32_t config_addr = s->config_offset(s, addr); uint32_t val; assert(len == 1 || len == 2 || len == 4); @@ -79,14 +122,24 @@ uint32_t pci_data_read(PCIBus *s, uint32_t addr, int len) return val; } +void pci_host_init(PCIHostState *s, + pci_dev_find_fn dev_find, + pci_config_offset_fn config_offset) +{ + if (!dev_find) + dev_find = pci_host_dev_find_fn; + if (!config_offset) + config_offset = pci_host_config_offset_fn; + + s->dev_find = dev_find; + s->config_offset = config_offset; +} + static void pci_host_config_writel(void *opaque, target_phys_addr_t addr, uint32_t val) { PCIHostState *s = opaque; -#ifdef TARGET_WORDS_BIGENDIAN - val = bswap32(val); -#endif PCI_DPRINTF("%s addr " TARGET_FMT_plx " val %"PRIx32"\n", __func__, addr, val); s->config_reg = val; @@ -97,9 +150,6 @@ static uint32_t pci_host_config_readl(void *opaque, target_phys_addr_t addr) PCIHostState *s = opaque; uint32_t val = s->config_reg; -#ifdef TARGET_WORDS_BIGENDIAN - val = bswap32(val); -#endif PCI_DPRINTF("%s addr " TARGET_FMT_plx " val %"PRIx32"\n", __func__, addr, val); return val; @@ -119,48 +169,16 @@ static CPUReadMemoryFunc * const pci_host_config_read[] = { int pci_host_conf_register_mmio(PCIHostState *s) { + pci_host_init(s, NULL, NULL); return cpu_register_io_memory(pci_host_config_read, pci_host_config_write, s); } -static void pci_host_config_writel_noswap(void *opaque, - target_phys_addr_t addr, - uint32_t val) -{ - PCIHostState *s = opaque; - - PCI_DPRINTF("%s addr " TARGET_FMT_plx " val %"PRIx32"\n", - __func__, addr, val); - s->config_reg = val; -} - -static uint32_t pci_host_config_readl_noswap(void *opaque, - target_phys_addr_t addr) -{ - PCIHostState *s = opaque; - uint32_t val = s->config_reg; - - PCI_DPRINTF("%s addr " TARGET_FMT_plx " val %"PRIx32"\n", - __func__, addr, val); - return val; -} - -static CPUWriteMemoryFunc * const pci_host_config_write_noswap[] = { - &pci_host_config_writel_noswap, - &pci_host_config_writel_noswap, - &pci_host_config_writel_noswap, -}; - -static CPUReadMemoryFunc * const pci_host_config_read_noswap[] = { - &pci_host_config_readl_noswap, - &pci_host_config_readl_noswap, - &pci_host_config_readl_noswap, -}; - int pci_host_conf_register_mmio_noswap(PCIHostState *s) { - return cpu_register_io_memory(pci_host_config_read_noswap, - pci_host_config_write_noswap, s); + pci_host_init(s, pci_host_dev_find_fn_noswap, NULL); + return cpu_register_io_memory(pci_host_config_read, + pci_host_config_write, s); } static void pci_host_config_writel_ioport(void *opaque, @@ -183,6 +201,7 @@ static uint32_t pci_host_config_readl_ioport(void *opaque, uint32_t addr) void pci_host_conf_register_ioport(pio_addr_t ioport, PCIHostState *s) { + pci_host_init(s, NULL, NULL); register_ioport_write(ioport, 4, 4, pci_host_config_writel_ioport, s); register_ioport_read(ioport, 4, 4, pci_host_config_readl_ioport, s); } diff --git a/hw/pci_host.h b/hw/pci_host.h index a006687..47c339a 100644 --- a/hw/pci_host.h +++ b/hw/pci_host.h @@ -30,14 +30,27 @@ #include "sysbus.h" +typedef PCIDevice *(*pci_dev_find_fn)(PCIHostState *s, uint32_t addr); +typedef uint32_t (*pci_config_offset_fn)(PCIHostState *s, uint32_t addr); + struct PCIHostState { SysBusDevice busdev; uint32_t config_reg; PCIBus *bus; + + pci_dev_find_fn dev_find; + pci_config_offset_fn config_offset; }; -void pci_data_write(PCIBus *s, uint32_t addr, uint32_t val, int len); -uint32_t pci_data_read(PCIBus *s, uint32_t addr, int len); +void pci_host_init(PCIHostState *s, + pci_dev_find_fn dev_find, + pci_config_offset_fn config_offset); + +PCIDevice *pci_host_find_dev(PCIBus *bus, uint32_t addr); +uint32_t pci_host_config_offset(uint32_t addr); + +void pci_data_write(PCIHostState *s, uint32_t addr, uint32_t val, int len); +uint32_t pci_data_read(PCIHostState *s, uint32_t addr, int len); /* for mmio */ int pci_host_conf_register_mmio(PCIHostState *s); diff --git a/hw/pci_host_template.h b/hw/pci_host_template.h index 11e6c88..24a03e0 100644 --- a/hw/pci_host_template.h +++ b/hw/pci_host_template.h @@ -32,8 +32,7 @@ static void glue(pci_host_data_writeb, PCI_HOST_SUFFIX)( PCI_DPRINTF("writeb addr " TARGET_FMT_plx " val %x\n", (target_phys_addr_t)addr, val); - if (s->config_reg & (1u << 31)) - pci_data_write(s->bus, s->config_reg | (addr & 3), val, 1); + pci_data_write(s, addr, val, 1); } static void glue(pci_host_data_writew, PCI_HOST_SUFFIX)( @@ -45,8 +44,7 @@ static void glue(pci_host_data_writew, PCI_HOST_SUFFIX)( #endif PCI_DPRINTF("writew addr " TARGET_FMT_plx " val %x\n", (target_phys_addr_t)addr, val); - if (s->config_reg & (1u << 31)) - pci_data_write(s->bus, s->config_reg | (addr & 3), val, 2); + pci_data_write(s, addr, val, 2); } static void glue(pci_host_data_writel, PCI_HOST_SUFFIX)( @@ -58,8 +56,7 @@ static void glue(pci_host_data_writel, PCI_HOST_SUFFIX)( #endif PCI_DPRINTF("writel addr " TARGET_FMT_plx " val %x\n", (target_phys_addr_t)addr, val); - if (s->config_reg & (1u << 31)) - pci_data_write(s->bus, s->config_reg, val, 4); + pci_data_write(s, addr, val, 4); } static uint32_t glue(pci_host_data_readb, PCI_HOST_SUFFIX)( @@ -68,9 +65,7 @@ static uint32_t glue(pci_host_data_readb, PCI_HOST_SUFFIX)( PCIHostState *s = opaque; uint32_t val; - if (!(s->config_reg & (1 << 31))) - return 0xff; - val = pci_data_read(s->bus, s->config_reg | (addr & 3), 1); + val = pci_data_read(s, addr, 1); PCI_DPRINTF("readb addr " TARGET_FMT_plx " val %x\n", (target_phys_addr_t)addr, val); return val; @@ -81,9 +76,7 @@ static uint32_t glue(pci_host_data_readw, PCI_HOST_SUFFIX)( { PCIHostState *s = opaque; uint32_t val; - if (!(s->config_reg & (1 << 31))) - return 0xffff; - val = pci_data_read(s->bus, s->config_reg | (addr & 3), 2); + val = pci_data_read(s, addr, 2); PCI_DPRINTF("readw addr " TARGET_FMT_plx " val %x\n", (target_phys_addr_t)addr, val); #ifdef TARGET_WORDS_BIGENDIAN @@ -97,9 +90,7 @@ static uint32_t glue(pci_host_data_readl, PCI_HOST_SUFFIX)( { PCIHostState *s = opaque; uint32_t val; - if (!(s->config_reg & (1 << 31))) - return 0xffffffff; - val = pci_data_read(s->bus, s->config_reg | (addr & 3), 4); + val = pci_data_read(s, addr, 4); PCI_DPRINTF("readl addr " TARGET_FMT_plx " val %x\n", (target_phys_addr_t)addr, val); #ifdef TARGET_WORDS_BIGENDIAN diff --git a/hw/prep_pci.c b/hw/prep_pci.c index 19f028c..8640b2e 100644 --- a/hw/prep_pci.c +++ b/hw/prep_pci.c @@ -40,72 +40,16 @@ static inline uint32_t PPC_PCIIO_config(target_phys_addr_t addr) return (addr & 0x7ff) | (i << 11); } -static void PPC_PCIIO_writeb (void *opaque, target_phys_addr_t addr, uint32_t val) +static PCIDevice *PPC_dev_find_fn(PCIHostState *s, uint32_t addr) { - PREPPCIState *s = opaque; - pci_data_write(s->bus, PPC_PCIIO_config(addr), val, 1); + return pci_host_find_dev(s->bus, PPC_PCIIO_config(addr)); } -static void PPC_PCIIO_writew (void *opaque, target_phys_addr_t addr, uint32_t val) +static uint32_t PPC_config_offset_fn(PCIHostState *s, uint32_t addr) { - PREPPCIState *s = opaque; -#ifdef TARGET_WORDS_BIGENDIAN - val = bswap16(val); -#endif - pci_data_write(s->bus, PPC_PCIIO_config(addr), val, 2); + return pci_host_config_offset(PPC_PCIIO_config(addr)); } -static void PPC_PCIIO_writel (void *opaque, target_phys_addr_t addr, uint32_t val) -{ - PREPPCIState *s = opaque; -#ifdef TARGET_WORDS_BIGENDIAN - val = bswap32(val); -#endif - pci_data_write(s->bus, PPC_PCIIO_config(addr), val, 4); -} - -static uint32_t PPC_PCIIO_readb (void *opaque, target_phys_addr_t addr) -{ - PREPPCIState *s = opaque; - uint32_t val; - val = pci_data_read(s->bus, PPC_PCIIO_config(addr), 1); - return val; -} - -static uint32_t PPC_PCIIO_readw (void *opaque, target_phys_addr_t addr) -{ - PREPPCIState *s = opaque; - uint32_t val; - val = pci_data_read(s->bus, PPC_PCIIO_config(addr), 2); -#ifdef TARGET_WORDS_BIGENDIAN - val = bswap16(val); -#endif - return val; -} - -static uint32_t PPC_PCIIO_readl (void *opaque, target_phys_addr_t addr) -{ - PREPPCIState *s = opaque; - uint32_t val; - val = pci_data_read(s->bus, PPC_PCIIO_config(addr), 4); -#ifdef TARGET_WORDS_BIGENDIAN - val = bswap32(val); -#endif - return val; -} - -static CPUWriteMemoryFunc * const PPC_PCIIO_write[] = { - &PPC_PCIIO_writeb, - &PPC_PCIIO_writew, - &PPC_PCIIO_writel, -}; - -static CPUReadMemoryFunc * const PPC_PCIIO_read[] = { - &PPC_PCIIO_readb, - &PPC_PCIIO_readw, - &PPC_PCIIO_readl, -}; - static int prep_map_irq(PCIDevice *pci_dev, int irq_num) { return (irq_num + (pci_dev->devfn >> 3)) & 1; @@ -132,8 +76,8 @@ PCIBus *pci_prep_init(qemu_irq *pic) pci_host_data_register_ioport(0xcfc, s); - PPC_io_memory = cpu_register_io_memory(PPC_PCIIO_read, - PPC_PCIIO_write, s); + pci_host_init(s, PPC_dev_find_fn, PPC_config_offset_fn); + PPC_io_memory = pci_host_data_register_mmio(s); cpu_register_physical_memory(0x80800000, 0x00400000, PPC_io_memory); /* PCI host bridge */ diff --git a/hw/sh_pci.c b/hw/sh_pci.c index abe4c75..209b92e 100644 --- a/hw/sh_pci.c +++ b/hw/sh_pci.c @@ -29,13 +29,37 @@ #include "bswap.h" typedef struct { - PCIBus *bus; + PCIHostState pci_state; PCIDevice *dev; - uint32_t par; uint32_t mbr; uint32_t iobr; + uint32_t par; } SHPCIC; +static void sh_pci_data_write(SHPCIC *p, uint32_t val) +{ + uint32_t addr = p->par; + PCIDevice *dev = pci_host_find_dev(p->pci_state.bus, addr); + uint32_t config_offset = pci_host_config_offset(addr); + + if (!dev) { + return; + } + dev->config_write(dev, config_offset, val, 4); +} + +static uint32_t sh_pci_data_read(SHPCIC *p) +{ + uint32_t addr = p->par; + PCIDevice *dev = pci_host_find_dev(p->pci_state.bus, addr); + uint32_t config_offset = pci_host_config_offset(addr); + + if (!dev) { + return ~(uint32_t)0; + } + return dev->config_read(dev, config_offset, 4); +} + static void sh_pci_reg_write (void *p, target_phys_addr_t addr, uint32_t val) { SHPCIC *pcic = p; @@ -53,7 +77,7 @@ static void sh_pci_reg_write (void *p, target_phys_addr_t addr, uint32_t val) pcic->iobr = val; break; case 0x220: - pci_data_write(pcic->bus, pcic->par, val, 4); + sh_pci_data_write(pcic, val); break; } } @@ -67,51 +91,21 @@ static uint32_t sh_pci_reg_read (void *p, target_phys_addr_t addr) case 0x1c0: return pcic->par; case 0x220: - return pci_data_read(pcic->bus, pcic->par, 4); + return sh_pci_data_read(pcic); } return 0; } -static void sh_pci_data_write (SHPCIC *pcic, target_phys_addr_t addr, - uint32_t val, int size) -{ - pci_data_write(pcic->bus, addr + pcic->mbr, val, size); -} - -static uint32_t sh_pci_mem_read (SHPCIC *pcic, target_phys_addr_t addr, - int size) -{ - return pci_data_read(pcic->bus, addr + pcic->mbr, size); -} - -static void sh_pci_writeb (void *p, target_phys_addr_t addr, uint32_t val) -{ - sh_pci_data_write(p, addr, val, 1); -} - -static void sh_pci_writew (void *p, target_phys_addr_t addr, uint32_t val) -{ - sh_pci_data_write(p, addr, val, 2); -} - -static void sh_pci_writel (void *p, target_phys_addr_t addr, uint32_t val) +static PCIDevice *sh_pci_dev_find_fn(PCIHostState *s, uint32_t addr) { - sh_pci_data_write(p, addr, val, 4); + SHPCIC *pcic = DO_UPCAST(SHPCIC, pci_state, s); + return pci_host_find_dev(pcic->pci_state.bus, addr + pcic->mbr); } -static uint32_t sh_pci_readb (void *p, target_phys_addr_t addr) +static uint32_t sh_pci_config_offset_fn(PCIHostState *s, uint32_t addr) { - return sh_pci_mem_read(p, addr, 1); -} - -static uint32_t sh_pci_readw (void *p, target_phys_addr_t addr) -{ - return sh_pci_mem_read(p, addr, 2); -} - -static uint32_t sh_pci_readl (void *p, target_phys_addr_t addr) -{ - return sh_pci_mem_read(p, addr, 4); + SHPCIC *pcic = DO_UPCAST(SHPCIC, pci_state, s); + return pci_host_config_offset(addr + pcic->mbr); } static int sh_pci_addr2port(SHPCIC *pcic, target_phys_addr_t addr) @@ -159,11 +153,6 @@ static MemOp sh_pci_reg = { { NULL, NULL, sh_pci_reg_write }, }; -static MemOp sh_pci_mem = { - { sh_pci_readb, sh_pci_readw, sh_pci_readl }, - { sh_pci_writeb, sh_pci_writew, sh_pci_writel }, -}; - static MemOp sh_pci_iop = { { sh_pci_inb, sh_pci_inw, sh_pci_inl }, { sh_pci_outb, sh_pci_outw, sh_pci_outl }, @@ -176,14 +165,15 @@ PCIBus *sh_pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq, int mem, reg, iop; p = qemu_mallocz(sizeof(SHPCIC)); - p->bus = pci_register_bus(NULL, "pci", - set_irq, map_irq, opaque, devfn_min, nirq); + p->pci_state.bus = pci_register_bus(NULL, "pci", set_irq, map_irq, + opaque, devfn_min, nirq); - p->dev = pci_register_device(p->bus, "SH PCIC", sizeof(PCIDevice), - -1, NULL, NULL); + p->dev = pci_register_device(p->pci_state.bus, "SH PCIC", + sizeof(PCIDevice), -1, NULL, NULL); reg = cpu_register_io_memory(sh_pci_reg.r, sh_pci_reg.w, p); iop = cpu_register_io_memory(sh_pci_iop.r, sh_pci_iop.w, p); - mem = cpu_register_io_memory(sh_pci_mem.r, sh_pci_mem.w, p); + pci_host_init(&p->pci_state, sh_pci_dev_find_fn, sh_pci_config_offset_fn); + mem = pci_host_data_register_mmio(&p->pci_state); cpu_register_physical_memory(0x1e200000, 0x224, reg); cpu_register_physical_memory(0x1e240000, 0x40000, iop); cpu_register_physical_memory(0x1d000000, 0x1000000, mem); @@ -198,5 +188,5 @@ PCIBus *sh_pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq, p->dev->config[0x06] = 0x90; p->dev->config[0x07] = 0x02; - return p->bus; + return p->pci_state.bus; } diff --git a/hw/versatile_pci.c b/hw/versatile_pci.c index 153c651..31bc1cd 100644 --- a/hw/versatile_pci.c +++ b/hw/versatile_pci.c @@ -12,7 +12,7 @@ #include "pci_host.h" typedef struct { - SysBusDevice busdev; + PCIHostState pci_state; qemu_irq irq[4]; int realview; int mem_config; @@ -23,69 +23,16 @@ static inline uint32_t vpb_pci_config_addr(target_phys_addr_t addr) return addr & 0xffffff; } -static void pci_vpb_config_writeb (void *opaque, target_phys_addr_t addr, - uint32_t val) +static PCIDevice *pci_vpb_dev_find_fn(PCIHostState *s, uint32_t addr) { - pci_data_write(opaque, vpb_pci_config_addr (addr), val, 1); + return pci_host_find_dev(s->bus, vpb_pci_config_addr(addr)); } -static void pci_vpb_config_writew (void *opaque, target_phys_addr_t addr, - uint32_t val) +static uint32_t pci_vpb_config_offset_fn(PCIHostState *s, uint32_t addr) { -#ifdef TARGET_WORDS_BIGENDIAN - val = bswap16(val); -#endif - pci_data_write(opaque, vpb_pci_config_addr (addr), val, 2); + return pci_host_config_offset(vpb_pci_config_addr(addr)); } -static void pci_vpb_config_writel (void *opaque, target_phys_addr_t addr, - uint32_t val) -{ -#ifdef TARGET_WORDS_BIGENDIAN - val = bswap32(val); -#endif - pci_data_write(opaque, vpb_pci_config_addr (addr), val, 4); -} - -static uint32_t pci_vpb_config_readb (void *opaque, target_phys_addr_t addr) -{ - uint32_t val; - val = pci_data_read(opaque, vpb_pci_config_addr (addr), 1); - return val; -} - -static uint32_t pci_vpb_config_readw (void *opaque, target_phys_addr_t addr) -{ - uint32_t val; - val = pci_data_read(opaque, vpb_pci_config_addr (addr), 2); -#ifdef TARGET_WORDS_BIGENDIAN - val = bswap16(val); -#endif - return val; -} - -static uint32_t pci_vpb_config_readl (void *opaque, target_phys_addr_t addr) -{ - uint32_t val; - val = pci_data_read(opaque, vpb_pci_config_addr (addr), 4); -#ifdef TARGET_WORDS_BIGENDIAN - val = bswap32(val); -#endif - return val; -} - -static CPUWriteMemoryFunc * const pci_vpb_config_write[] = { - &pci_vpb_config_writeb, - &pci_vpb_config_writew, - &pci_vpb_config_writel, -}; - -static CPUReadMemoryFunc * const pci_vpb_config_read[] = { - &pci_vpb_config_readb, - &pci_vpb_config_readw, - &pci_vpb_config_readl, -}; - static int pci_vpb_map_irq(PCIDevice *d, int irq_num) { return irq_num; @@ -114,7 +61,8 @@ static void pci_vpb_map(SysBusDevice *dev, target_phys_addr_t base) static int pci_vpb_init(SysBusDevice *dev) { - PCIVPBState *s = FROM_SYSBUS(PCIVPBState, dev); + PCIHostState *pci_state = FROM_SYSBUS(PCIHostState, dev); + PCIVPBState *s = DO_UPCAST(PCIVPBState, pci_state, pci_state); PCIBus *bus; int i; @@ -127,8 +75,9 @@ static int pci_vpb_init(SysBusDevice *dev) /* ??? Register memory space. */ - s->mem_config = cpu_register_io_memory(pci_vpb_config_read, - pci_vpb_config_write, bus); + pci_host_init(&s->pci_state, + pci_vpb_dev_find_fn, pci_vpb_config_offset_fn); + s->mem_config = pci_host_data_register_mmio(&s->pci_state); sysbus_init_mmio_cb(dev, 0x04000000, pci_vpb_map); pci_create_simple(bus, -1, "versatile_pci_host"); @@ -137,7 +86,8 @@ static int pci_vpb_init(SysBusDevice *dev) static int pci_realview_init(SysBusDevice *dev) { - PCIVPBState *s = FROM_SYSBUS(PCIVPBState, dev); + PCIHostState *pci_state = FROM_SYSBUS(PCIHostState, dev); + PCIVPBState *s = DO_UPCAST(PCIVPBState, pci_state, pci_state); s->realview = 1; return pci_vpb_init(dev); }