qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: "Michael S. Tsirkin" <mst@redhat.com>
To: Alexander Graf <agraf@suse.de>
Cc: Blue Swirl <blauwirbel@gmail.com>,
	QEMU Developers <qemu-devel@nongnu.org>,
	Aurelien Jarno <aurelien@aurel32.net>
Subject: [Qemu-devel] Re: [PATCH 1/6] Make config space accessor host bus trapable
Date: Sun, 3 Jan 2010 17:45:39 +0200	[thread overview]
Message-ID: <20100103154539.GB8137@redhat.com> (raw)
In-Reply-To: <1262483450-15206-2-git-send-email-agraf@suse.de>

On Sun, Jan 03, 2010 at 02:50:45AM +0100, Alexander Graf wrote:
> 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 <agraf@suse.de>
> CC: Michael S. Tsirkin <mst@redhat.com>

Thanks!

It always bothered me that the code in pci_host uses x86 encoding and
other architectures are converted to x86.  As long as we are adding
redirection, maybe we should get rid of this, and make get_config_reg
return register and devfn separately, so we don't need to encode/decode
back and forth?

OTOH if we are after a quick fix, won't it be simpler to have
unin_pci simply use its own routines instead of pci_host_conf_register_mmio
etc?

> ---
>  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;
> +}

So config_reg is always set but only used for PC now?
This is not very pretty ...

> 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
> 
> 

  reply	other threads:[~2010-01-03 15:48 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   ` Michael S. Tsirkin [this message]
2010-01-03 16:09     ` [Qemu-devel] " 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
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=20100103154539.GB8137@redhat.com \
    --to=mst@redhat.com \
    --cc=agraf@suse.de \
    --cc=aurelien@aurel32.net \
    --cc=blauwirbel@gmail.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).