From: Isaku Yamahata <yamahata@valinux.co.jp>
To: Alexander Graf <agraf@suse.de>
Cc: Blue Swirl <blauwirbel@gmail.com>,
QEMU Developers <qemu-devel@nongnu.org>,
Aurelien Jarno <aurelien@aurel32.net>,
"Michael S. Tsirkin" <mst@redhat.com>
Subject: Re: [Qemu-devel] Re: [PATCH 1/6] Make config space accessor host bus trapable
Date: Mon, 4 Jan 2010 19:45:16 +0900 [thread overview]
Message-ID: <20100104104516.GD4672@valinux.co.jp> (raw)
In-Reply-To: <19BFDDD5-85E0-42EC-9D71-391CECC023F5@suse.de>
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 <yamahata@valinux.co.jp>
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 <yamahata@valinux.co.jp>
---
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);
}
--
1.6.5.4
--
yamahata
next prev parent reply other threads:[~2010-01-04 10:45 UTC|newest]
Thread overview: 48+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-01-03 1:50 [Qemu-devel] [PATCH 0/6] PPC NewWorld fixery Alexander Graf
2010-01-03 1:50 ` [Qemu-devel] [PATCH 1/6] Make config space accessor host bus trapable Alexander Graf
2010-01-03 15:45 ` [Qemu-devel] " Michael S. Tsirkin
2010-01-03 16:09 ` Alexander Graf
2010-01-03 17:29 ` Michael S. Tsirkin
2010-01-03 17:40 ` Alexander Graf
2010-01-03 17:44 ` Michael S. Tsirkin
2010-01-03 17:50 ` Alexander Graf
2010-01-03 18:06 ` Michael S. Tsirkin
2010-01-03 19:18 ` Blue Swirl
2010-01-10 18:41 ` Blue Swirl
2010-01-11 21:29 ` Blue Swirl
2010-01-11 22:33 ` Igor Kovalenko
2010-01-12 19:29 ` Blue Swirl
2010-01-18 19:47 ` Blue Swirl
2010-01-03 20:27 ` Alexander Graf
2010-01-03 20:50 ` Benjamin Herrenschmidt
2010-01-04 3:26 ` Alexander Graf
2010-01-04 10:45 ` Isaku Yamahata [this message]
2010-01-04 10:55 ` Alexander Graf
2010-01-04 11:08 ` Isaku Yamahata
2010-01-04 11:07 ` Michael S. Tsirkin
2010-01-04 11:13 ` Alexander Graf
2010-01-04 20:10 ` Benjamin Herrenschmidt
2010-01-04 21:12 ` Michael S. Tsirkin
2010-01-04 21:25 ` Benjamin Herrenschmidt
2010-01-04 21:30 ` Michael S. Tsirkin
2010-01-04 21:53 ` Benjamin Herrenschmidt
2010-01-04 22:25 ` Michael S. Tsirkin
2010-01-04 22:51 ` Benjamin Herrenschmidt
2010-01-04 22:59 ` Michael S. Tsirkin
2010-01-04 23:08 ` Alexander Graf
2010-01-04 23:12 ` Michael S. Tsirkin
2010-01-04 23:39 ` Benjamin Herrenschmidt
2010-01-04 23:33 ` Benjamin Herrenschmidt
2010-01-03 1:50 ` [Qemu-devel] [PATCH 2/6] Add config space conversion function for uni_north Alexander Graf
2010-01-03 15:32 ` [Qemu-devel] " Michael S. Tsirkin
2010-01-03 15:40 ` Alexander Graf
2010-01-03 15:47 ` Michael S. Tsirkin
2010-01-03 16:13 ` Alexander Graf
2010-01-03 16:20 ` Michael S. Tsirkin
2010-01-03 16:35 ` Alexander Graf
2010-01-03 17:23 ` Michael S. Tsirkin
2010-01-03 15:48 ` Michael S. Tsirkin
2010-01-03 1:50 ` [Qemu-devel] [PATCH 3/6] Use Mac99_U3 type on ppc64 Alexander Graf
2010-01-03 1:50 ` [Qemu-devel] [PATCH 4/6] Include dump of lspci -nn on real G5 Alexander Graf
2010-01-03 1:50 ` [Qemu-devel] [PATCH 5/6] Make interrupts work Alexander Graf
2010-01-03 1:50 ` [Qemu-devel] [PATCH 6/6] Enable secondary cmd64x Alexander Graf
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20100104104516.GD4672@valinux.co.jp \
--to=yamahata@valinux.co.jp \
--cc=agraf@suse.de \
--cc=aurelien@aurel32.net \
--cc=blauwirbel@gmail.com \
--cc=mst@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.