qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH 2/6] kvm/powerpc: Add freescale pcicontroller's


From: Aurelien Jarno
Subject: Re: [Qemu-devel] [PATCH 2/6] kvm/powerpc: Add freescale pcicontroller's support
Date: Mon, 9 Feb 2009 11:28:32 +0100
User-agent: Mutt/1.5.18 (2008-05-17)

On Mon, Feb 09, 2009 at 04:33:25PM +0800, Liu Yu-B13201 wrote:
> > -----Original Message-----
> > From: Aurelien Jarno [mailto:address@hidden 
> > Sent: Sunday, January 25, 2009 12:03 AM
> > To: Liu Yu-B13201
> > Cc: address@hidden; address@hidden; address@hidden
> > Subject: Re: [Qemu-devel] [PATCH 2/6] kvm/powerpc: Add 
> > freescale pcicontroller's support
> > 
> > On Thu, Jan 22, 2009 at 06:14:12PM +0800, Liu Yu wrote:
> > > This patch add the emulation of freescale's pci controller 
> > for MPC85xx platform.
> > > 
> > > Signed-off-by: Liu Yu <address@hidden>
> > 
> > I have one general comment for this patch, QEMU (mostly) uses 
> > spaces for
> > indentation, while this patch uses spaces + tab. Would it be 
> > possible to
> > convert it to spaces only, using 4 spaces?
> 
> Fixed.
> 
> > 
> > I also have one minor comment inside. Otherwise the patch looks ok.
> > 
> > >  Makefile.target  |    2 +
> > >  hw/ppce500_pci.c |  370 
> > ++++++++++++++++++++++++++++++++++++++++++++++++++++++
> > >  2 files changed, 372 insertions(+), 0 deletions(-)
> > >  create mode 100644 hw/ppce500_pci.c
> > > 
> > > diff --git a/Makefile.target b/Makefile.target
> > > index a091ce9..5cae257 100644
> > > --- a/Makefile.target
> > > +++ b/Makefile.target
> > > @@ -598,6 +598,8 @@ OBJS+= unin_pci.o ppc_chrp.o
> > >  # PowerPC 4xx boards
> > >  OBJS+= pflash_cfi02.o ppc4xx_devs.o ppc4xx_pci.o 
> > ppc405_uc.o ppc405_boards.o
> > >  OBJS+= ppc440.o ppc440_bamboo.o
> > > +# PowerPC E500 boards
> > > +OBJS+= ppce500_pci.o
> > >  ifdef FDT_LIBS
> > >  OBJS+= device_tree.o
> > >  LIBS+= $(FDT_LIBS)
> > > diff --git a/hw/ppce500_pci.c b/hw/ppce500_pci.c
> > > new file mode 100644
> > > index 0000000..6325555
> > > --- /dev/null
> > > +++ b/hw/ppce500_pci.c
> > > @@ -0,0 +1,370 @@
> > > +/*
> > > + * QEMU PowerPC E500 embedded processors pci controller emulation
> > > + *
> > > + * Copyright (C) 2009 Freescale Semiconductor, Inc. All 
> > rights reserved.
> > > + *
> > > + * Author: Yu Liu,     <address@hidden>
> > > + *
> > > + * This file is derived from hw/ppc4xx_pci.c,
> > > + * the copyright for that material belongs to the original owners.
> > > + *
> > > + * This is free software; you can redistribute it and/or modify
> > > + * it under the terms of  the GNU General  Public License 
> > as published by
> > > + * the Free Software Foundation;  either version 2 of the  
> > License, or
> > > + * (at your option) any later version.
> > > + */
> > > +
> > > +#include "hw.h"
> > > +#include "ppc.h"
> > > +#include "ppce500.h"
> > > +typedef target_phys_addr_t pci_addr_t;
> > > +#include "pci.h"
> > > +#include "pci_host.h"
> > > +#include "bswap.h"
> > > +#include "qemu-log.h"
> > > +
> > > +#ifdef DEBUG_PCI
> > > +#define pci_debug(fmt, arg...) fprintf(stderr, fmt, ##arg)
> > > +#else
> > > +#define pci_debug(fmt, arg...)
> > > +#endif
> > > +
> > > +#define PCIE500_CFGADDR       0x0
> > > +#define PCIE500_CFGDATA       0x4
> > > +#define PCIE500_REG_BASE      0xC00
> > > +#define PCIE500_REG_SIZE      (0x1000 - PCIE500_REG_BASE)
> > > +
> > > +#define PPCE500_PCI_CONFIG_ADDR          0x0
> > > +#define PPCE500_PCI_CONFIG_DATA          0x4
> > > +#define PPCE500_PCI_INTACK               0x8
> > > +
> > > +#define PPCE500_PCI_OW1                  (0xC20 - 
> > PCIE500_REG_BASE)
> > > +#define PPCE500_PCI_OW2                  (0xC40 - 
> > PCIE500_REG_BASE)
> > > +#define PPCE500_PCI_OW3                  (0xC60 - 
> > PCIE500_REG_BASE)
> > > +#define PPCE500_PCI_OW4                  (0xC80 - 
> > PCIE500_REG_BASE)
> > > +#define PPCE500_PCI_IW3                  (0xDA0 - 
> > PCIE500_REG_BASE)
> > > +#define PPCE500_PCI_IW2                  (0xDC0 - 
> > PCIE500_REG_BASE)
> > > +#define PPCE500_PCI_IW1                  (0xDE0 - 
> > PCIE500_REG_BASE)
> > > +
> > > +#define PPCE500_PCI_GASKET_TIMR          (0xE20 - 
> > PCIE500_REG_BASE)
> > > +
> > > +#define PCI_POTAR                0x0
> > > +#define PCI_POTEAR               0x4
> > > +#define PCI_POWBAR               0x8
> > > +#define PCI_POWAR                0x10
> > > +
> > > +#define PCI_PITAR                0x0
> > > +#define PCI_PIWBAR               0x8
> > > +#define PCI_PIWBEAR              0xC
> > > +#define PCI_PIWAR                0x10
> > > +
> > > +#define PPCE500_PCI_NR_POBS 5
> > > +#define PPCE500_PCI_NR_PIBS 3
> > > +
> > > +struct  pci_outbound {
> > > +    uint32_t potar;
> > > +    uint32_t potear;
> > > +    uint32_t powbar;
> > > +    uint32_t powar;
> > > +};
> > > +
> > > +struct pci_inbound {
> > > +    uint32_t pitar;
> > > +    uint32_t piwbar;
> > > +    uint32_t piwbear;
> > > +    uint32_t piwar;
> > > +};
> > > +
> > > +struct PPCE500PCIState {
> > > +    struct pci_outbound pob[PPCE500_PCI_NR_POBS];
> > > +    struct pci_inbound pib[PPCE500_PCI_NR_PIBS];
> > > +    uint32_t gasket_time;
> > > +    PCIHostState pci_state;
> > > +    PCIDevice *pci_dev;
> > > +};
> > > +
> > > +typedef struct PPCE500PCIState PPCE500PCIState;
> > > +
> > > +static uint32_t pcie500_cfgaddr_readl(void *opaque, 
> > target_phys_addr_t addr)
> > > +{
> > > +    PPCE500PCIState *pci = opaque;
> > > +
> > > +    pci_debug("%s: (addr:%Lx) -> value:%x\n", __func__, addr,
> > > +             pci->pci_state.config_reg);
> > > +    return pci->pci_state.config_reg;
> > > +}
> > > +
> > > +static CPUReadMemoryFunc *pcie500_cfgaddr_read[] = {
> > > +    &pcie500_cfgaddr_readl,
> > > +    &pcie500_cfgaddr_readl,
> > > +    &pcie500_cfgaddr_readl,
> > > +};
> > > +
> > > +static void pcie500_cfgaddr_writel(void *opaque, 
> > target_phys_addr_t addr,
> > > +                                  uint32_t value)
> > > +{
> > > +    PPCE500PCIState *controller = opaque;
> > > +
> > > +    pci_debug("%s: value:%x -> (addr%Lx)\n", __func__, 
> > value, addr);
> > > +    controller->pci_state.config_reg = value & ~0x3;
> > > +}
> > > +
> > > +static CPUWriteMemoryFunc *pcie500_cfgaddr_write[] = {
> > > +    &pcie500_cfgaddr_writel,
> > > +    &pcie500_cfgaddr_writel,
> > > +    &pcie500_cfgaddr_writel,
> > > +};
> > > +
> > > +static CPUReadMemoryFunc *pcie500_cfgdata_read[] = {
> > > +    &pci_host_data_readb,
> > > +    &pci_host_data_readw,
> > > +    &pci_host_data_readl,
> > > +};
> > > +
> > > +static CPUWriteMemoryFunc *pcie500_cfgdata_write[] = {
> > > +    &pci_host_data_writeb,
> > > +    &pci_host_data_writew,
> > > +    &pci_host_data_writel,
> > > +};
> > > +
> > > +static uint32_t pci_reg_read4(void *opaque, 
> > target_phys_addr_t addr)
> > > +{
> > > +    PPCE500PCIState *pci = opaque;
> > > +    unsigned long win;
> > > +    uint32_t value = 0;
> > > +
> > > +    win = addr & 0xfe0;
> > > +
> > > +    switch (win) {
> > > +    case PPCE500_PCI_OW1:
> > > +    case PPCE500_PCI_OW2:
> > > +    case PPCE500_PCI_OW3:
> > > +    case PPCE500_PCI_OW4:
> > > + switch (addr & 0xC) {
> > > + case PCI_POTAR: value = pci->pob[(addr >> 5) & 
> > 0x7].potar; break;
> > > + case PCI_POTEAR: value = pci->pob[(addr >> 5) & 
> > 0x7].potear; break;
> > > + case PCI_POWBAR: value = pci->pob[(addr >> 5) & 
> > 0x7].powbar; break;
> > > + case PCI_POWAR: value = pci->pob[(addr >> 5) & 
> > 0x7].powar; break;
> > > + default: break;
> > > + }
> > > + break;
> > > +
> > > +    case PPCE500_PCI_IW3:
> > > +    case PPCE500_PCI_IW2:
> > > +    case PPCE500_PCI_IW1:
> > > + switch (addr & 0xC) {
> > > + case PCI_PITAR: value = pci->pib[(addr >> 5) & 
> > 0x3].pitar; break;
> > > + case PCI_PIWBAR: value = pci->pib[(addr >> 5) & 
> > 0x3].piwbar; break;
> > > + case PCI_PIWBEAR: value = pci->pib[(addr >> 5) & 
> > 0x3].piwbear; break;
> > > + case PCI_PIWAR: value = pci->pib[(addr >> 5) & 
> > 0x3].piwar; break;
> > > + default: break;
> > > + };
> > > + break;
> > > +
> > > +    case PPCE500_PCI_GASKET_TIMR:
> > > + value = pci->gasket_time;
> > > + break;
> > > +
> > > +    default:
> > > + break;
> > > +    }
> > > +
> > > +    pci_debug("%s: win:%lx(addr:%Lx) -> 
> > value:%x\n",__func__,win,addr,value);
> > > +    return value;
> > > +}
> > > +
> > > +static CPUReadMemoryFunc *e500_pci_reg_read[] = {
> > > +    &pci_reg_read4,
> > > +    &pci_reg_read4,
> > > +    &pci_reg_read4,
> > > +};
> > > +
> > > +static void pci_reg_write4(void *opaque, target_phys_addr_t addr,
> > > +                               uint32_t value)
> > > +{
> > > +    PPCE500PCIState *pci = opaque;
> > > +    unsigned long win;
> > > +
> > > +    win = addr & 0xfe0;
> > > +
> > > +    pci_debug("%s: value:%x -> 
> > win:%lx(addr:%Lx)\n",__func__,value,win,addr);
> > > +
> > > +    switch (win) {
> > > +    case PPCE500_PCI_OW1:
> > > +    case PPCE500_PCI_OW2:
> > > +    case PPCE500_PCI_OW3:
> > > +    case PPCE500_PCI_OW4:
> > > + switch (addr & 0xC) {
> > > + case PCI_POTAR: pci->pob[(addr >> 5) & 0x7].potar = 
> > value; break;
> > > + case PCI_POTEAR: pci->pob[(addr >> 5) & 0x7].potear = 
> > value; break;
> > > + case PCI_POWBAR: pci->pob[(addr >> 5) & 0x7].powbar = 
> > value; break;
> > > + case PCI_POWAR: pci->pob[(addr >> 5) & 0x7].powar = 
> > value; break;
> > > + default: break;
> > > + };
> > > + break;
> > > +
> > > +    case PPCE500_PCI_IW3:
> > > +    case PPCE500_PCI_IW2:
> > > +    case PPCE500_PCI_IW1:
> > > + switch (addr & 0xC) {
> > > + case PCI_PITAR: pci->pib[(addr >> 5) & 0x3].pitar = 
> > value; break;
> > > + case PCI_PIWBAR: pci->pib[(addr >> 5) & 0x3].piwbar = 
> > value; break;
> > > + case PCI_PIWBEAR: pci->pib[(addr >> 5) & 0x3].piwbear = 
> > value; break;
> > > + case PCI_PIWAR: pci->pib[(addr >> 5) & 0x3].piwar = 
> > value; break;
> > > + default: break;
> > > + };
> > > + break;
> > > +
> > > +    case PPCE500_PCI_GASKET_TIMR:
> > > + pci->gasket_time = value;
> > > + break;
> > > +
> > > +    default:
> > > + break;
> > > +    };
> > > +}
> > > +
> > > +static CPUWriteMemoryFunc *e500_pci_reg_write[] = {
> > > +    &pci_reg_write4,
> > > +    &pci_reg_write4,
> > > +    &pci_reg_write4,
> > > +};
> > > +
> > > +static int mpc85xx_pci_map_irq(PCIDevice *pci_dev, int irq_num)
> > > +{
> > > +    int devno = pci_dev->devfn >> 3, ret = 0;
> > > +
> > > +    switch (devno) {
> > > + /* Two PCI slot */
> > > + case 0x11:
> > > + case 0x12:
> > > +     ret = (irq_num + devno - 0x10) % 4;
> > > +     break;
> > > + default:
> > > +     printf("Error:%s:unknow dev number\n", __func__);
> > > +    }
> > 
> > While I understand that the physical board only supports two PCI
> > devices, I wonder if we shouldn't actually support more in QEMU. Think
> > for example to virtio which can quickly takes two slots.
> 
> Certainly it could support more.
> Here only support two is because MPC8544.dts says so, kernel will access pci 
> device according to dts file.
> 
> The dts file in this patchset is copied from MPC8544's dts file, so we must 
> keep it consistent here.
> 
> If we need more pci devices, I'd prefer to do it in a isolated patch, as we 
> need modify both here and dts file.
> 

I see, then it's fine with me.

-- 
Aurelien Jarno                          GPG: 1024D/F1BCDB73
address@hidden                 http://www.aurel32.net




reply via email to

[Prev in Thread] Current Thread [Next in Thread]