[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 1/6] Make config space accessor host bus trapable
From: |
Alexander Graf |
Subject: |
[Qemu-devel] [PATCH 1/6] Make config space accessor host bus trapable |
Date: |
Sun, 3 Jan 2010 02:50:45 +0100 |
Different host buses may have different layouts for config space accessors.
The Mac U3 for example uses the following define to access Type 0 (directly
attached) devices:
#define MACRISC_CFA0(devfn, off) \
((1 << (unsigned int)PCI_SLOT(dev_fn)) \
| (((unsigned int)PCI_FUNC(dev_fn)) << 8) \
| (((unsigned int)(off)) & 0xFCUL))
Obviously, this is different from the encoding we interpret in qemu. In
order to let host controllers take some influence there, we can just
introduce a converter function that takes whatever accessor we have and
makes a qemu understandable one out of it.
This patch is the groundwork for Uninorth PCI config space fixes.
Signed-off-by: Alexander Graf <address@hidden>
CC: Michael S. Tsirkin <address@hidden>
---
hw/apb_pci.c | 1 +
hw/grackle_pci.c | 1 +
hw/gt64xxx.c | 1 +
hw/pci_host.c | 11 +++++++++++
hw/pci_host.h | 5 +++++
hw/pci_host_template.h | 30 ++++++++++++++++++------------
hw/piix_pci.c | 1 +
hw/ppc4xx_pci.c | 1 +
hw/ppce500_pci.c | 1 +
hw/unin_pci.c | 1 +
10 files changed, 41 insertions(+), 12 deletions(-)
diff --git a/hw/apb_pci.c b/hw/apb_pci.c
index f05308b..fedb84c 100644
--- a/hw/apb_pci.c
+++ b/hw/apb_pci.c
@@ -222,6 +222,7 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base,
/* mem_data */
sysbus_mmio_map(s, 3, mem_base);
d = FROM_SYSBUS(APBState, s);
+ pci_host_init(&d->host_state);
d->host_state.bus = pci_register_bus(&d->busdev.qdev, "pci",
pci_apb_set_irq, pci_pbm_map_irq, pic,
0, 32);
diff --git a/hw/grackle_pci.c b/hw/grackle_pci.c
index ee4fed5..7feba63 100644
--- a/hw/grackle_pci.c
+++ b/hw/grackle_pci.c
@@ -88,6 +88,7 @@ PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic)
qdev_init_nofail(dev);
s = sysbus_from_qdev(dev);
d = FROM_SYSBUS(GrackleState, s);
+ pci_host_init(&d->host_state);
d->host_state.bus = pci_register_bus(&d->busdev.qdev, "pci",
pci_grackle_set_irq,
pci_grackle_map_irq,
diff --git a/hw/gt64xxx.c b/hw/gt64xxx.c
index fb7f5bd..8cf93ca 100644
--- a/hw/gt64xxx.c
+++ b/hw/gt64xxx.c
@@ -1120,6 +1120,7 @@ PCIBus *pci_gt64120_init(qemu_irq *pic)
s = qemu_mallocz(sizeof(GT64120State));
s->pci = qemu_mallocz(sizeof(GT64120PCIState));
+ pci_host_init(s->pci);
s->pci->bus = pci_register_bus(NULL, "pci",
pci_gt64120_set_irq, pci_gt64120_map_irq,
pic, 144, 4);
diff --git a/hw/pci_host.c b/hw/pci_host.c
index eeb8dee..2d12887 100644
--- a/hw/pci_host.c
+++ b/hw/pci_host.c
@@ -228,3 +228,14 @@ void pci_host_data_register_ioport(pio_addr_t ioport,
PCIHostState *s)
register_ioport_read(ioport, 4, 2, pci_host_data_readw_ioport, s);
register_ioport_read(ioport, 4, 4, pci_host_data_readl_ioport, s);
}
+
+/* This implements the default x86 way of interpreting the config register */
+static uint32_t pci_host_get_config_reg(PCIHostState *s, uint32_t addr)
+{
+ return s->config_reg | (addr & 3);
+}
+
+void pci_host_init(PCIHostState *s)
+{
+ s->get_config_reg = pci_host_get_config_reg;
+}
diff --git a/hw/pci_host.h b/hw/pci_host.h
index a006687..90a4c63 100644
--- a/hw/pci_host.h
+++ b/hw/pci_host.h
@@ -30,14 +30,19 @@
#include "sysbus.h"
+/* for config space access */
+typedef uint32_t (*pci_config_reg_fn)(PCIHostState *s, uint32_t addr);
+
struct PCIHostState {
SysBusDevice busdev;
+ pci_config_reg_fn get_config_reg;
uint32_t config_reg;
PCIBus *bus;
};
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);
/* 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..55aa85e 100644
--- a/hw/pci_host_template.h
+++ b/hw/pci_host_template.h
@@ -29,48 +29,52 @@ static void glue(pci_host_data_writeb, PCI_HOST_SUFFIX)(
void* opaque, PCI_ADDR_T addr, uint32_t val)
{
PCIHostState *s = opaque;
+ uint32_t config_reg = s->get_config_reg(s, (uint32_t)addr);
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);
+ if (config_reg & (1u << 31))
+ pci_data_write(s->bus, config_reg, val, 1);
}
static void glue(pci_host_data_writew, PCI_HOST_SUFFIX)(
void* opaque, PCI_ADDR_T addr, uint32_t val)
{
PCIHostState *s = opaque;
+ uint32_t config_reg = s->get_config_reg(s, (uint32_t)addr);
#ifdef TARGET_WORDS_BIGENDIAN
val = bswap16(val);
#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);
+ if (config_reg & (1u << 31))
+ pci_data_write(s->bus, config_reg, val, 2);
}
static void glue(pci_host_data_writel, PCI_HOST_SUFFIX)(
void* opaque, PCI_ADDR_T addr, uint32_t val)
{
PCIHostState *s = opaque;
+ uint32_t config_reg = s->get_config_reg(s, (uint32_t)addr);
#ifdef TARGET_WORDS_BIGENDIAN
val = bswap32(val);
#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);
+ if (config_reg & (1u << 31))
+ pci_data_write(s->bus, config_reg, val, 4);
}
static uint32_t glue(pci_host_data_readb, PCI_HOST_SUFFIX)(
void* opaque, PCI_ADDR_T addr)
{
PCIHostState *s = opaque;
+ uint32_t config_reg = s->get_config_reg(s, (uint32_t)addr);
uint32_t val;
- if (!(s->config_reg & (1 << 31)))
+ if (!(config_reg & (1 << 31)))
return 0xff;
- val = pci_data_read(s->bus, s->config_reg | (addr & 3), 1);
+ val = pci_data_read(s->bus, config_reg, 1);
PCI_DPRINTF("readb addr " TARGET_FMT_plx " val %x\n",
(target_phys_addr_t)addr, val);
return val;
@@ -80,10 +84,11 @@ static uint32_t glue(pci_host_data_readw, PCI_HOST_SUFFIX)(
void* opaque, PCI_ADDR_T addr)
{
PCIHostState *s = opaque;
+ uint32_t config_reg = s->get_config_reg(s, (uint32_t)addr);
uint32_t val;
- if (!(s->config_reg & (1 << 31)))
+ if (!(config_reg & (1 << 31)))
return 0xffff;
- val = pci_data_read(s->bus, s->config_reg | (addr & 3), 2);
+ val = pci_data_read(s->bus, config_reg, 2);
PCI_DPRINTF("readw addr " TARGET_FMT_plx " val %x\n",
(target_phys_addr_t)addr, val);
#ifdef TARGET_WORDS_BIGENDIAN
@@ -96,10 +101,11 @@ static uint32_t glue(pci_host_data_readl, PCI_HOST_SUFFIX)(
void* opaque, PCI_ADDR_T addr)
{
PCIHostState *s = opaque;
+ uint32_t config_reg = s->get_config_reg(s, (uint32_t)addr);
uint32_t val;
- if (!(s->config_reg & (1 << 31)))
+ if (!(config_reg))
return 0xffffffff;
- val = pci_data_read(s->bus, s->config_reg | (addr & 3), 4);
+ val = pci_data_read(s->bus, config_reg, 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/piix_pci.c b/hw/piix_pci.c
index 1b67475..97500e0 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -211,6 +211,7 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int
*piix3_devfn, qemu_irq *
dev = qdev_create(NULL, "i440FX-pcihost");
s = FROM_SYSBUS(I440FXState, sysbus_from_qdev(dev));
+ pci_host_init(s);
b = pci_bus_new(&s->busdev.qdev, NULL, 0);
s->bus = b;
qdev_init_nofail(dev);
diff --git a/hw/ppc4xx_pci.c b/hw/ppc4xx_pci.c
index 2d00b61..dd8e290 100644
--- a/hw/ppc4xx_pci.c
+++ b/hw/ppc4xx_pci.c
@@ -357,6 +357,7 @@ PCIBus *ppc4xx_pci_init(CPUState *env, qemu_irq pci_irqs[4],
controller = qemu_mallocz(sizeof(PPC4xxPCIState));
+ pci_host_init(&controller->pci_state);
controller->pci_state.bus = pci_register_bus(NULL, "pci",
ppc4xx_pci_set_irq,
ppc4xx_pci_map_irq,
diff --git a/hw/ppce500_pci.c b/hw/ppce500_pci.c
index a72fb86..5914183 100644
--- a/hw/ppce500_pci.c
+++ b/hw/ppce500_pci.c
@@ -278,6 +278,7 @@ PCIBus *ppce500_pci_init(qemu_irq pci_irqs[4],
target_phys_addr_t registers)
controller = qemu_mallocz(sizeof(PPCE500PCIState));
+ pci_host_init(&controller->pci_state);
controller->pci_state.bus = pci_register_bus(NULL, "pci",
mpc85xx_pci_set_irq,
mpc85xx_pci_map_irq,
diff --git a/hw/unin_pci.c b/hw/unin_pci.c
index 3ae4e7a..fdb9401 100644
--- a/hw/unin_pci.c
+++ b/hw/unin_pci.c
@@ -84,6 +84,7 @@ static int pci_unin_main_init_device(SysBusDevice *dev)
/* Uninorth main bus */
s = FROM_SYSBUS(UNINState, dev);
+ pci_host_init(&s->host_state);
pci_mem_config = pci_host_conf_register_mmio(&s->host_state);
pci_mem_data = pci_host_data_register_mmio(&s->host_state);
sysbus_init_mmio(dev, 0x1000, pci_mem_config);
--
1.6.0.2
- [Qemu-devel] Re: [PATCH 2/6] Add config space conversion function for uni_north, (continued)
- [Qemu-devel] Re: [PATCH 2/6] Add config space conversion function for uni_north, Michael S. Tsirkin, 2010/01/03
- [Qemu-devel] Re: [PATCH 2/6] Add config space conversion function for uni_north, Alexander Graf, 2010/01/03
- [Qemu-devel] Re: [PATCH 2/6] Add config space conversion function for uni_north, Michael S. Tsirkin, 2010/01/03
- [Qemu-devel] Re: [PATCH 2/6] Add config space conversion function for uni_north, Alexander Graf, 2010/01/03
- [Qemu-devel] Re: [PATCH 2/6] Add config space conversion function for uni_north, Michael S. Tsirkin, 2010/01/03
- [Qemu-devel] Re: [PATCH 2/6] Add config space conversion function for uni_north, Alexander Graf, 2010/01/03
- [Qemu-devel] Re: [PATCH 2/6] Add config space conversion function for uni_north, Michael S. Tsirkin, 2010/01/03
- [Qemu-devel] Re: [PATCH 2/6] Add config space conversion function for uni_north, Michael S. Tsirkin, 2010/01/03
[Qemu-devel] [PATCH 4/6] Include dump of lspci -nn on real G5, Alexander Graf, 2010/01/02
[Qemu-devel] [PATCH 6/6] Enable secondary cmd64x, Alexander Graf, 2010/01/02
[Qemu-devel] [PATCH 1/6] Make config space accessor host bus trapable,
Alexander Graf <=
- [Qemu-devel] Re: [PATCH 1/6] Make config space accessor host bus trapable, Michael S. Tsirkin, 2010/01/03
- [Qemu-devel] Re: [PATCH 1/6] Make config space accessor host bus trapable, Alexander Graf, 2010/01/03
- [Qemu-devel] Re: [PATCH 1/6] Make config space accessor host bus trapable, Michael S. Tsirkin, 2010/01/03
- [Qemu-devel] Re: [PATCH 1/6] Make config space accessor host bus trapable, Alexander Graf, 2010/01/03
- [Qemu-devel] Re: [PATCH 1/6] Make config space accessor host bus trapable, Michael S. Tsirkin, 2010/01/03
- [Qemu-devel] Re: [PATCH 1/6] Make config space accessor host bus trapable, Alexander Graf, 2010/01/03
- [Qemu-devel] Re: [PATCH 1/6] Make config space accessor host bus trapable, Michael S. Tsirkin, 2010/01/03
- [Qemu-devel] Re: [PATCH 1/6] Make config space accessor host bus trapable, Blue Swirl, 2010/01/03
- [Qemu-devel] Re: [PATCH 1/6] Make config space accessor host bus trapable, Blue Swirl, 2010/01/10
- [Qemu-devel] Re: [PATCH 1/6] Make config space accessor host bus trapable, Blue Swirl, 2010/01/11