[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] RE: [PATCH 5/9] powerpc/kvm: Add freescale pci controller's
From: |
Liu Yu |
Subject: |
[Qemu-devel] RE: [PATCH 5/9] powerpc/kvm: Add freescale pci controller's support |
Date: |
Fri, 16 Jan 2009 15:37:42 +0800 |
> -----Original Message-----
> From: address@hidden
> [mailto:address@hidden On Behalf Of Hollis Blanchard
> Sent: Friday, January 16, 2009 4:02 AM
> To: Liu Yu-B13201
> Cc: address@hidden; address@hidden
> Subject: Re: [PATCH 5/9] powerpc/kvm: Add freescale pci
> controller's support
>
> On Thu, 2009-01-15 at 20:34 +0800, Liu Yu wrote:
> > Signed-off-by: Liu Yu <address@hidden>
> > ---
> > Makefile.target | 2 +
> > hw/ppce500_pci.c | 369
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++
> > 2 files changed, 371 insertions(+), 0 deletions(-)
> > create mode 100644 hw/ppce500_pci.c
> >
> > diff --git a/Makefile.target b/Makefile.target
> > index 58fe88f..2079fcb 100644
> > --- a/Makefile.target
> > +++ b/Makefile.target
> > @@ -649,6 +649,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..9077591
> > --- /dev/null
> > +++ b/hw/ppce500_pci.c
> > @@ -0,0 +1,369 @@
> > +/*
> > + * 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;
>
> Out of curiosity, is "gasket_time" supposed to be an actual timer, or
> just a scratch register? It looks like you've just implemented it as a
> scratch register.
Just a scratch register I think.
I tried today that if I removed it, virtio-pci cannot be found.
>
> > + 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,
>
> Missing & here.
Fixed. Thanks.
>
> > + &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__);
> > + }
> > +
> > + pci_debug("%s: devfn %x irq %d -> %d devno:%x\n", __func__,
> > + pci_dev->devfn, irq_num, ret, devno);
> > +
> > + return ret;
> > +}
> > +
> > +static void mpc85xx_pci_set_irq(qemu_irq *pic, int
> irq_num, int level)
> > +{
> > + pci_debug("%s: PCI irq %d, level:%d\n", __func__,
> irq_num, level);
> > +
> > + qemu_set_irq(pic[irq_num], level);
> > +}
> > +
> > +static void ppce500_pci_save(QEMUFile *f, void *opaque)
> > +{
> > + PPCE500PCIState *controller = opaque;
> > + int i;
> > +
> > + pci_device_save(controller->pci_dev, f);
> > +
> > + for (i = 0; i < PPCE500_PCI_NR_POBS; i++) {
> > + qemu_put_be32s(f, &controller->pob[i].potar);
> > + qemu_put_be32s(f, &controller->pob[i].potear);
> > + qemu_put_be32s(f, &controller->pob[i].powbar);
> > + qemu_put_be32s(f, &controller->pob[i].powar);
> > + }
> > +
> > + for (i = 0; i < PPCE500_PCI_NR_PIBS; i++) {
> > + qemu_put_be32s(f, &controller->pib[i].pitar);
> > + qemu_put_be32s(f, &controller->pib[i].piwbar);
> > + qemu_put_be32s(f, &controller->pib[i].piwbear);
> > + qemu_put_be32s(f, &controller->pib[i].piwar);
> > + }
> > + qemu_put_be32s(f, &controller->gasket_time);
> > +}
> > +
> > +static int ppce500_pci_load(QEMUFile *f, void *opaque, int
> version_id)
> > +{
> > + PPCE500PCIState *controller = opaque;
> > + int i;
> > +
> > + if (version_id != 1)
> > + return -EINVAL;
> > +
> > + pci_device_load(controller->pci_dev, f);
> > +
> > + for (i = 0; i < PPCE500_PCI_NR_POBS; i++) {
> > + qemu_get_be32s(f, &controller->pob[i].potar);
> > + qemu_get_be32s(f, &controller->pob[i].potear);
> > + qemu_get_be32s(f, &controller->pob[i].powbar);
> > + qemu_get_be32s(f, &controller->pob[i].powar);
> > + }
> > +
> > + for (i = 0; i < PPCE500_PCI_NR_PIBS; i++) {
> > + qemu_get_be32s(f, &controller->pib[i].pitar);
> > + qemu_get_be32s(f, &controller->pib[i].piwbar);
> > + qemu_get_be32s(f, &controller->pib[i].piwbear);
> > + qemu_get_be32s(f, &controller->pib[i].piwar);
> > + }
> > + qemu_get_be32s(f, &controller->gasket_time);
> > +
> > + return 0;
> > +}
>
> Should have a newline here.
Fixed. Thanks.
- [Qemu-devel] RE: [PATCH 9/9] powerpc/kvm: Add MPC85xx board support, (continued)
- [Qemu-devel] Re: [PATCH 7/9] powerpc/kvm: Add E500 core emulation, Hollis Blanchard, 2009/01/15
- [Qemu-devel] RE: [PATCH 7/9] powerpc/kvm: Add E500 core emulation, Liu Yu, 2009/01/16
- [Qemu-devel] RE: [PATCH 7/9] powerpc/kvm: Add E500 core emulation, Hollis Blanchard, 2009/01/16
- [Qemu-devel] RE: [PATCH 7/9] powerpc/kvm: Add E500 core emulation, Liu Yu, 2009/01/19
- [Qemu-devel] RE: [PATCH 7/9] powerpc/kvm: Add E500 core emulation, Liu Yu, 2009/01/19
- [Qemu-devel] Re: [PATCH 5/9] powerpc/kvm: Add freescale pci controller's support, Hollis Blanchard, 2009/01/15
- [Qemu-devel] RE: [PATCH 5/9] powerpc/kvm: Add freescale pci controller's support,
Liu Yu <=
- Re: [Qemu-devel] [PATCH 3/9] powerpc/kvm: Enable mpic for E500 platform, Anthony Liguori, 2009/01/15
- RE: [Qemu-devel] [PATCH 3/9] powerpc/kvm: Enable mpic for E500 platform, Liu Yu, 2009/01/16
- RE: [Qemu-devel] [PATCH 3/9] powerpc/kvm: Enable mpic for E500 platform, Hollis Blanchard, 2009/01/16
- Re: [Qemu-devel] [PATCH 3/9] powerpc/kvm: Enable mpic for E500 platform, Aurelien Jarno, 2009/01/16
[Qemu-devel] Re: [PATCH 0/9] powerpc/kvm: Add MPC85xx platform support, Hollis Blanchard, 2009/01/15
Re: [Qemu-devel] [PATCH 0/9] powerpc/kvm: Add MPC85xx platform support, Anthony Liguori, 2009/01/15