Hi Claudio, Sorry, I should have missed this one.
On Wed, Jan 14, 2015 at 2:12 PM, Claudio Fontana <claudio.font...@huawei.com> wrote: > On 14.01.2015 11:16, Alvise Rigo wrote: >> Add a generic PCI host controller for virtual platforms, based on the >> previous work by Rob Herring: >> http://lists.gnu.org/archive/html/qemu-devel/2014-06/msg03482.html >> >> The controller relies on a configuration memory region and provides two >> PCI memory regions for I/O (one port and one memory mapped). The device >> needs the following qdev properties to configure the memory regions: >> - cfg_win_size: size of the configuration memory >> - pio_win_size: size of the port I/O space >> - mmio_win_size: size of the MMIO space >> - mmio_win_addr: offset of MMIO space in the system memory >> >> Signed-off-by: Alvise Rigo <a.r...@virtualopensystems.com> >> --- >> hw/pci-host/Makefile.objs | 2 +- >> hw/pci-host/generic-pci.c | 140 >> ++++++++++++++++++++++++++++++++++++++ >> include/hw/pci-host/generic-pci.h | 45 ++++++++++++ >> 3 files changed, 186 insertions(+), 1 deletion(-) >> create mode 100644 hw/pci-host/generic-pci.c >> create mode 100644 include/hw/pci-host/generic-pci.h >> >> diff --git a/hw/pci-host/Makefile.objs b/hw/pci-host/Makefile.objs >> index bb65f9c..8ef9fac 100644 >> --- a/hw/pci-host/Makefile.objs >> +++ b/hw/pci-host/Makefile.objs >> @@ -1,4 +1,4 @@ >> -common-obj-y += pam.o >> +common-obj-y += pam.o generic-pci.o >> >> # PPC devices >> common-obj-$(CONFIG_PREP_PCI) += prep.o >> diff --git a/hw/pci-host/generic-pci.c b/hw/pci-host/generic-pci.c >> new file mode 100644 >> index 0000000..54c9647 >> --- /dev/null >> +++ b/hw/pci-host/generic-pci.c >> @@ -0,0 +1,140 @@ >> +/* >> + * Generic PCI host controller >> + * >> + * Copyright (c) 2014 Linaro, Ltd. >> + * Author: Rob Herring <rob.herr...@linaro.org> >> + * >> + * Based on ARM Versatile PCI controller (hw/pci-host/versatile.c): >> + * Copyright (c) 2006-2009 CodeSourcery. >> + * Written by Paul Brook >> + * >> + * This code is licensed under the LGPL. >> + */ >> + >> +#include "hw/sysbus.h" >> +#include "hw/pci-host/generic-pci.h" >> +#include "exec/address-spaces.h" >> +#include "sysemu/device_tree.h" >> + >> +static const VMStateDescription pci_generic_host_vmstate = { >> + .name = "generic-host-pci", >> + .version_id = 1, >> + .minimum_version_id = 1, >> +}; >> + >> +static void pci_cam_config_write(void *opaque, hwaddr addr, >> + uint64_t val, unsigned size) >> +{ >> + PCIGenState *s = opaque; >> + pci_data_write(&s->pci_bus, addr, val, size); >> +} >> + >> +static uint64_t pci_cam_config_read(void *opaque, hwaddr addr, unsigned >> size) >> +{ >> + PCIGenState *s = opaque; >> + uint32_t val; >> + val = pci_data_read(&s->pci_bus, addr, size); >> + return val; >> +} >> + >> +static const MemoryRegionOps pci_generic_config_ops = { >> + .read = pci_cam_config_read, >> + .write = pci_cam_config_write, >> + .endianness = DEVICE_LITTLE_ENDIAN, >> +}; >> + >> +static void pci_generic_set_irq(void *opaque, int irq_num, int level) >> +{ >> + qemu_irq *pic = opaque; >> + qemu_set_irq(pic[irq_num], level); >> +} >> + >> +static void pci_generic_host_realize(DeviceState *dev, Error **errp) >> +{ >> + PCIHostState *h = PCI_HOST_BRIDGE(dev); >> + PCIGenState *s = PCI_GEN(dev); >> + GenericPCIHostState *gps = &s->pci_gen; >> + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); >> + int i; >> + >> + memory_region_init(&s->pci_io_window, OBJECT(s), "pci_io", >> s->pio_win_size); >> + memory_region_init(&s->pci_mem_space, OBJECT(s), "pci_mem", 1ULL << 32); >> + >> + pci_bus_new_inplace(&s->pci_bus, sizeof(s->pci_bus), dev, "pci", >> + &s->pci_mem_space, &s->pci_io_window, >> + PCI_DEVFN(0, 0), TYPE_PCI_BUS); >> + h->bus = &s->pci_bus; >> + >> + object_initialize(gps, sizeof(*gps), TYPE_GENERIC_PCI_HOST); >> + qdev_set_parent_bus(DEVICE(gps), BUS(&s->pci_bus)); >> + >> + for (i = 0; i < s->irqs; i++) { >> + sysbus_init_irq(sbd, &s->irq[i]); >> + } >> + >> + pci_bus_irqs(&s->pci_bus, pci_generic_set_irq, pci_swizzle_map_irq_fn, >> + s->irq, s->irqs); >> + memory_region_init_io(&s->mem_config, OBJECT(s), >> &pci_generic_config_ops, s, >> + "pci-config", s->cfg_win_size); >> + memory_region_init_alias(&s->pci_mem_window, OBJECT(s), "pci-mem-win", >> + &s->pci_mem_space, s->mmio_win_addr, s->mmio_win_size); >> + >> + sysbus_init_mmio(sbd, &s->mem_config); >> + sysbus_init_mmio(sbd, &s->pci_io_window); >> + sysbus_init_mmio(sbd, &s->pci_mem_window); >> +} >> + >> +static void pci_generic_host_class_init(ObjectClass *klass, void *data) >> +{ >> + PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); >> + DeviceClass *dc = DEVICE_CLASS(klass); >> + >> + k->vendor_id = PCI_VENDOR_ID_REDHAT; >> + k->device_id = PCI_DEVICE_ID_REDHAT_BRIDGE; >> + k->class_id = PCI_CLASS_PROCESSOR_CO; >> + /* >> + * PCI-facing part of the host bridge, not usable without the >> + * host-facing part, which can't be device_add'ed, yet. >> + */ >> + dc->cannot_instantiate_with_device_add_yet = true; >> +} >> + >> +static const TypeInfo pci_generic_host_info = { >> + .name = TYPE_GENERIC_PCI_HOST, >> + .parent = TYPE_PCI_DEVICE, >> + .instance_size = sizeof(GenericPCIHostState), >> + .class_init = pci_generic_host_class_init, >> +}; >> + >> +static Property pci_generic_props[] = { >> + DEFINE_PROP_UINT32("cfg_win_size", PCIGenState, cfg_win_size, 1ULL << >> 20), >> + DEFINE_PROP_UINT32("pio_win_size", PCIGenState, pio_win_size, 64 * >> 1024), >> + DEFINE_PROP_UINT64("mmio_win_size", PCIGenState, mmio_win_size, 1ULL << >> 32), >> + DEFINE_PROP_UINT64("mmio_win_addr", PCIGenState, mmio_win_addr, 0), >> + DEFINE_PROP_UINT32("irqs", PCIGenState, irqs, 4), >> + DEFINE_PROP_END_OF_LIST(), >> +}; >> + >> +static void pci_generic_class_init(ObjectClass *klass, void *data) >> +{ >> + DeviceClass *dc = DEVICE_CLASS(klass); >> + >> + dc->realize = pci_generic_host_realize; >> + dc->vmsd = &pci_generic_host_vmstate; >> + dc->props = pci_generic_props; > > why do some of these assigments have the & and some not? pci_generic_host_vmstate is a VMStateDescription structure defined and initialized at the top of the source file while vmsd is a pointer to such a structure. Regards, alvise > >> +} >> + >> +static const TypeInfo pci_generic_info = { >> + .name = TYPE_GENERIC_PCI, >> + .parent = TYPE_PCI_HOST_BRIDGE, >> + .instance_size = sizeof(PCIGenState), >> + .class_init = pci_generic_class_init, >> +}; >> + >> +static void generic_pci_host_register_types(void) >> +{ >> + type_register_static(&pci_generic_info); >> + type_register_static(&pci_generic_host_info); >> +} >> + >> +type_init(generic_pci_host_register_types) >> \ No newline at end of file >> diff --git a/include/hw/pci-host/generic-pci.h >> b/include/hw/pci-host/generic-pci.h >> new file mode 100644 >> index 0000000..830542e >> --- /dev/null >> +++ b/include/hw/pci-host/generic-pci.h >> @@ -0,0 +1,45 @@ >> +#ifndef QEMU_GENERIC_PCI_H >> +#define QEMU_GENERIC_PCI_H >> + >> +#include "hw/pci/pci.h" >> +#include "hw/pci/pci_bus.h" >> +#include "hw/pci/pci_host.h" >> + >> +#define MAX_PCI_DEVICES (PCI_SLOT_MAX * PCI_FUNC_MAX) >> + >> +typedef struct { >> + /*< private >*/ >> + PCIDevice parent_obj; >> +} GenericPCIHostState; >> + >> +typedef struct PCIGenState { >> + /*< private >*/ >> + PCIHostState parent_obj; >> + >> + qemu_irq irq[MAX_PCI_DEVICES]; >> + MemoryRegion mem_config; >> + /* Container representing the PCI address MMIO space */ >> + MemoryRegion pci_mem_space; >> + /* Alias region into PCI address spaces which we expose as sysbus >> region */ >> + MemoryRegion pci_mem_window; >> + /* PCI I/O region */ >> + MemoryRegion pci_io_window; >> + PCIBus pci_bus; >> + GenericPCIHostState pci_gen; >> + >> + uint32_t cfg_win_size; >> + uint32_t pio_win_size; >> + uint64_t mmio_win_addr; // offset of pci_mem_window inside pci_mem_space >> + uint64_t mmio_win_size; >> + uint32_t irqs; >> +} PCIGenState; >> + >> +#define TYPE_GENERIC_PCI "generic_pci" >> +#define PCI_GEN(obj) \ >> + OBJECT_CHECK(PCIGenState, (obj), TYPE_GENERIC_PCI) >> + >> +#define TYPE_GENERIC_PCI_HOST "generic_pci_host" >> +#define PCI_GEN_HOST(obj) \ >> + OBJECT_CHECK(GenericPCIHostState, (obj), TYPE_GENERIC_PCI_HOST) >> + >> +#endif >> \ No newline at end of file >> > > > -- > Claudio Fontana > Server Virtualization Architect > Huawei Technologies Duesseldorf GmbH > Riesstraße 25 - 80992 München > > office: +49 89 158834 4135 > mobile: +49 15253060158