Message ID | 20230726132512.149618-15-sergey.kambalin@auriga.com |
---|---|
State | New |
Headers | show |
Series | Raspberry Pi 4B machine | expand |
On Wed, 26 Jul 2023 at 14:51, Sergey Kambalin <serg.oker@gmail.com> wrote: > > Signed-off-by: Sergey Kambalin <sergey.kambalin@auriga.com> > --- > hw/arm/bcm2838_pcie.c | 65 +++++++++++++++++++++++++++++++++++ PCI controllers live in hw/pci-host/ . I'm not too familiar with the PCI subsystem, so I've cc'd Marcel and Michael as the PCI maintainers. The PCI-relevant patches in this series are 14 and 15: https://patchew.org/QEMU/20230726132512.149618-1-sergey.kambalin@auriga.com/20230726132512.149618-15-sergey.kambalin@auriga.com/ https://patchew.org/QEMU/20230726132512.149618-1-sergey.kambalin@auriga.com/20230726132512.149618-16-sergey.kambalin@auriga.com/ and maybe 16: https://patchew.org/QEMU/20230726132512.149618-1-sergey.kambalin@auriga.com/20230726132512.149618-17-sergey.kambalin@auriga.com/ > hw/arm/meson.build | 5 ++- > hw/arm/trace-events | 4 +++ > include/hw/arm/bcm2838_pcie.h | 44 ++++++++++++++++++++++++ > 4 files changed, 117 insertions(+), 1 deletion(-) > create mode 100644 hw/arm/bcm2838_pcie.c > create mode 100644 include/hw/arm/bcm2838_pcie.h > > diff --git a/hw/arm/bcm2838_pcie.c b/hw/arm/bcm2838_pcie.c > new file mode 100644 > index 0000000000..522e19f3cf > --- /dev/null > +++ b/hw/arm/bcm2838_pcie.c > @@ -0,0 +1,65 @@ > +/* > + * BCM2838 PCIe Root Complex emulation > + * > + * Copyright (C) 2022 Ovchinnikov Vitalii <vitalii.ovchinnikov@auriga.com> > + * > + * SPDX-License-Identifier: GPL-2.0-or-later > + */ > + > +#include "qemu/osdep.h" > +#include "qemu/log.h" > +#include "qapi/error.h" > +#include "hw/irq.h" > +#include "hw/pci-host/gpex.h" > +#include "hw/qdev-properties.h" > +#include "migration/vmstate.h" > +#include "qemu/module.h" > +#include "hw/arm/bcm2838_pcie.h" > +#include "trace.h" > + > +/* > + * RC root part (D0:F0) > + */ > + > +static void bcm2838_pcie_root_init(Object *obj) > +{ > + PCIBridge *br = PCI_BRIDGE(obj); > + BCM2838PcieRootState *s = BCM2838_PCIE_ROOT(obj); > + > + br->bus_name = "pcie.1"; > + memset(s->regs, 0xFF, sizeof(s->regs)); Generally registers should be set in some reset method, not in an instance_init method. (Your base class here uses 3-phase-reset, so you will need to do so too.) > +} > + > +static void bcm2838_pcie_root_class_init(ObjectClass *class, void *data) > +{ > + DeviceClass *dc = DEVICE_CLASS(class); > + PCIDeviceClass *k = PCI_DEVICE_CLASS(class); > + PCIERootPortClass *rpc = PCIE_ROOT_PORT_CLASS(class); > + > + dc->desc = "BCM2711 PCIe Bridge"; > + /* > + * PCI-facing part of the host bridge, not usable without the host-facing > + * part, which can't be device_add'ed. > + */ > + dc->user_creatable = false; > + k->vendor_id = BCM2838_PCIE_VENDOR_ID; > + k->device_id = BCM2838_PCIE_DEVICE_ID; > + k->revision = BCM2838_PCIE_REVISION; > + rpc->exp_offset = BCM2838_PCIE_EXP_CAP_OFFSET; > + rpc->aer_offset = BCM2838_PCIE_AER_CAP_OFFSET; > +} > + > +static const TypeInfo bcm2838_pcie_root_info = { > + .name = TYPE_BCM2838_PCIE_ROOT, > + .parent = TYPE_PCIE_ROOT_PORT, > + .instance_size = sizeof(BCM2838PcieRootState), > + .instance_init = bcm2838_pcie_root_init, > + .class_init = bcm2838_pcie_root_class_init, > +}; > + > +static void bcm2838_pcie_register(void) > +{ > + type_register_static(&bcm2838_pcie_root_info); > +} > + > +type_init(bcm2838_pcie_register) > diff --git a/hw/arm/meson.build b/hw/arm/meson.build > index 768b2608c1..72680fa534 100644 > --- a/hw/arm/meson.build > +++ b/hw/arm/meson.build > @@ -39,7 +39,10 @@ arm_ss.add(when: 'CONFIG_ALLWINNER_A10', if_true: files('allwinner-a10.c', 'cubi > arm_ss.add(when: 'CONFIG_ALLWINNER_H3', if_true: files('allwinner-h3.c', 'orangepi.c')) > arm_ss.add(when: 'CONFIG_ALLWINNER_R40', if_true: files('allwinner-r40.c', 'bananapi_m2u.c')) > arm_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2836.c', 'raspi.c')) > -arm_ss.add(when: ['CONFIG_RASPI', 'TARGET_AARCH64'], if_true: files('bcm2838.c', 'raspi4b.c')) > +arm_ss.add(when: ['CONFIG_RASPI', 'TARGET_AARCH64'], if_true: files( > + 'bcm2838.c', > + 'bcm2838_pcie.c', > + 'raspi4b.c')) > arm_ss.add(when: 'CONFIG_STM32F100_SOC', if_true: files('stm32f100_soc.c')) > arm_ss.add(when: 'CONFIG_STM32F205_SOC', if_true: files('stm32f205_soc.c')) > arm_ss.add(when: 'CONFIG_STM32F405_SOC', if_true: files('stm32f405_soc.c')) > diff --git a/hw/arm/trace-events b/hw/arm/trace-events > index 4f0167e638..6cfab31539 100644 > --- a/hw/arm/trace-events > +++ b/hw/arm/trace-events > @@ -55,5 +55,9 @@ smmuv3_notify_flag_add(const char *iommu) "ADD SMMUNotifier node for iommu mr=%s > smmuv3_notify_flag_del(const char *iommu) "DEL SMMUNotifier node for iommu mr=%s" > smmuv3_inv_notifiers_iova(const char *name, uint16_t asid, uint16_t vmid, uint64_t iova, uint8_t tg, uint64_t num_pages) "iommu mr=%s asid=%d vmid=%d iova=0x%"PRIx64" tg=%d num_pages=0x%"PRIx64 > > +# bcm2838_pcie.c > +bcm2838_pcie_host_read(unsigned int size, uint64_t offset, uint64_t value) "%u bytes @ 0x%04"PRIx64": 0x%016"PRIx64 > +bcm2838_pcie_host_write(unsigned int size, uint64_t offset, uint64_t value) "%u bytes @ 0x%04"PRIx64": 0x%016"PRIx64 > + > # bcm2838.c > bcm2838_gic_set_irq(int irq, int level) "gic irq:%d lvl:%d" > diff --git a/include/hw/arm/bcm2838_pcie.h b/include/hw/arm/bcm2838_pcie.h > new file mode 100644 > index 0000000000..b3d39b808d > --- /dev/null > +++ b/include/hw/arm/bcm2838_pcie.h > @@ -0,0 +1,44 @@ > +/* > + * BCM2838 PCIe Root Complex emulation > + * > + * Copyright (C) 2022 Ovchinnikov Vitalii <vitalii.ovchinnikov@auriga.com> > + * > + * SPDX-License-Identifier: GPL-2.0-or-later > + */ > + > +#ifndef BCM2838_PCIE_H > +#define BCM2838_PCIE_H > + > +#include "exec/hwaddr.h" > +#include "hw/sysbus.h" > +#include "hw/pci/pci.h" > +#include "hw/pci/pcie_host.h" > +#include "hw/pci/pcie_port.h" > +#include "qom/object.h" > + > +#define TYPE_BCM2838_PCIE_ROOT "bcm2838-pcie-root" > +OBJECT_DECLARE_SIMPLE_TYPE(BCM2838PcieRootState, BCM2838_PCIE_ROOT) > + > +#define BCM2838_PCIE_VENDOR_ID 0x14E4 > +#define BCM2838_PCIE_DEVICE_ID 0x2711 > +#define BCM2838_PCIE_REVISION 20 > + > +#define BCM2838_PCIE_REGS_SIZE 0x9310 > +#define BCM2838_PCIE_NUM_IRQS 4 > + > +#define BCM2838_PCIE_EXP_CAP_OFFSET 0xAC > +#define BCM2838_PCIE_AER_CAP_OFFSET 0x100 > + > +#define BCM2838_PCIE_EXT_CFG_DATA 0x8000 > +#define BCM2838_PCIE_EXT_CFG_INDEX 0x9000 > + > +struct BCM2838PcieRootState { > + /*< private >*/ > + PCIESlot parent_obj; > + > + /*< public >*/ > + uint8_t regs[BCM2838_PCIE_REGS_SIZE - PCIE_CONFIG_SPACE_SIZE]; > +}; > + > + > +#endif /* BCM2838_PCIE_H */ > -- > 2.34.1 thanks -- PMM
diff --git a/hw/arm/bcm2838_pcie.c b/hw/arm/bcm2838_pcie.c new file mode 100644 index 0000000000..522e19f3cf --- /dev/null +++ b/hw/arm/bcm2838_pcie.c @@ -0,0 +1,65 @@ +/* + * BCM2838 PCIe Root Complex emulation + * + * Copyright (C) 2022 Ovchinnikov Vitalii <vitalii.ovchinnikov@auriga.com> + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "qemu/log.h" +#include "qapi/error.h" +#include "hw/irq.h" +#include "hw/pci-host/gpex.h" +#include "hw/qdev-properties.h" +#include "migration/vmstate.h" +#include "qemu/module.h" +#include "hw/arm/bcm2838_pcie.h" +#include "trace.h" + +/* + * RC root part (D0:F0) + */ + +static void bcm2838_pcie_root_init(Object *obj) +{ + PCIBridge *br = PCI_BRIDGE(obj); + BCM2838PcieRootState *s = BCM2838_PCIE_ROOT(obj); + + br->bus_name = "pcie.1"; + memset(s->regs, 0xFF, sizeof(s->regs)); +} + +static void bcm2838_pcie_root_class_init(ObjectClass *class, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(class); + PCIDeviceClass *k = PCI_DEVICE_CLASS(class); + PCIERootPortClass *rpc = PCIE_ROOT_PORT_CLASS(class); + + dc->desc = "BCM2711 PCIe Bridge"; + /* + * PCI-facing part of the host bridge, not usable without the host-facing + * part, which can't be device_add'ed. + */ + dc->user_creatable = false; + k->vendor_id = BCM2838_PCIE_VENDOR_ID; + k->device_id = BCM2838_PCIE_DEVICE_ID; + k->revision = BCM2838_PCIE_REVISION; + rpc->exp_offset = BCM2838_PCIE_EXP_CAP_OFFSET; + rpc->aer_offset = BCM2838_PCIE_AER_CAP_OFFSET; +} + +static const TypeInfo bcm2838_pcie_root_info = { + .name = TYPE_BCM2838_PCIE_ROOT, + .parent = TYPE_PCIE_ROOT_PORT, + .instance_size = sizeof(BCM2838PcieRootState), + .instance_init = bcm2838_pcie_root_init, + .class_init = bcm2838_pcie_root_class_init, +}; + +static void bcm2838_pcie_register(void) +{ + type_register_static(&bcm2838_pcie_root_info); +} + +type_init(bcm2838_pcie_register) diff --git a/hw/arm/meson.build b/hw/arm/meson.build index 768b2608c1..72680fa534 100644 --- a/hw/arm/meson.build +++ b/hw/arm/meson.build @@ -39,7 +39,10 @@ arm_ss.add(when: 'CONFIG_ALLWINNER_A10', if_true: files('allwinner-a10.c', 'cubi arm_ss.add(when: 'CONFIG_ALLWINNER_H3', if_true: files('allwinner-h3.c', 'orangepi.c')) arm_ss.add(when: 'CONFIG_ALLWINNER_R40', if_true: files('allwinner-r40.c', 'bananapi_m2u.c')) arm_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2836.c', 'raspi.c')) -arm_ss.add(when: ['CONFIG_RASPI', 'TARGET_AARCH64'], if_true: files('bcm2838.c', 'raspi4b.c')) +arm_ss.add(when: ['CONFIG_RASPI', 'TARGET_AARCH64'], if_true: files( + 'bcm2838.c', + 'bcm2838_pcie.c', + 'raspi4b.c')) arm_ss.add(when: 'CONFIG_STM32F100_SOC', if_true: files('stm32f100_soc.c')) arm_ss.add(when: 'CONFIG_STM32F205_SOC', if_true: files('stm32f205_soc.c')) arm_ss.add(when: 'CONFIG_STM32F405_SOC', if_true: files('stm32f405_soc.c')) diff --git a/hw/arm/trace-events b/hw/arm/trace-events index 4f0167e638..6cfab31539 100644 --- a/hw/arm/trace-events +++ b/hw/arm/trace-events @@ -55,5 +55,9 @@ smmuv3_notify_flag_add(const char *iommu) "ADD SMMUNotifier node for iommu mr=%s smmuv3_notify_flag_del(const char *iommu) "DEL SMMUNotifier node for iommu mr=%s" smmuv3_inv_notifiers_iova(const char *name, uint16_t asid, uint16_t vmid, uint64_t iova, uint8_t tg, uint64_t num_pages) "iommu mr=%s asid=%d vmid=%d iova=0x%"PRIx64" tg=%d num_pages=0x%"PRIx64 +# bcm2838_pcie.c +bcm2838_pcie_host_read(unsigned int size, uint64_t offset, uint64_t value) "%u bytes @ 0x%04"PRIx64": 0x%016"PRIx64 +bcm2838_pcie_host_write(unsigned int size, uint64_t offset, uint64_t value) "%u bytes @ 0x%04"PRIx64": 0x%016"PRIx64 + # bcm2838.c bcm2838_gic_set_irq(int irq, int level) "gic irq:%d lvl:%d" diff --git a/include/hw/arm/bcm2838_pcie.h b/include/hw/arm/bcm2838_pcie.h new file mode 100644 index 0000000000..b3d39b808d --- /dev/null +++ b/include/hw/arm/bcm2838_pcie.h @@ -0,0 +1,44 @@ +/* + * BCM2838 PCIe Root Complex emulation + * + * Copyright (C) 2022 Ovchinnikov Vitalii <vitalii.ovchinnikov@auriga.com> + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef BCM2838_PCIE_H +#define BCM2838_PCIE_H + +#include "exec/hwaddr.h" +#include "hw/sysbus.h" +#include "hw/pci/pci.h" +#include "hw/pci/pcie_host.h" +#include "hw/pci/pcie_port.h" +#include "qom/object.h" + +#define TYPE_BCM2838_PCIE_ROOT "bcm2838-pcie-root" +OBJECT_DECLARE_SIMPLE_TYPE(BCM2838PcieRootState, BCM2838_PCIE_ROOT) + +#define BCM2838_PCIE_VENDOR_ID 0x14E4 +#define BCM2838_PCIE_DEVICE_ID 0x2711 +#define BCM2838_PCIE_REVISION 20 + +#define BCM2838_PCIE_REGS_SIZE 0x9310 +#define BCM2838_PCIE_NUM_IRQS 4 + +#define BCM2838_PCIE_EXP_CAP_OFFSET 0xAC +#define BCM2838_PCIE_AER_CAP_OFFSET 0x100 + +#define BCM2838_PCIE_EXT_CFG_DATA 0x8000 +#define BCM2838_PCIE_EXT_CFG_INDEX 0x9000 + +struct BCM2838PcieRootState { + /*< private >*/ + PCIESlot parent_obj; + + /*< public >*/ + uint8_t regs[BCM2838_PCIE_REGS_SIZE - PCIE_CONFIG_SPACE_SIZE]; +}; + + +#endif /* BCM2838_PCIE_H */
Signed-off-by: Sergey Kambalin <sergey.kambalin@auriga.com> --- hw/arm/bcm2838_pcie.c | 65 +++++++++++++++++++++++++++++++++++ hw/arm/meson.build | 5 ++- hw/arm/trace-events | 4 +++ include/hw/arm/bcm2838_pcie.h | 44 ++++++++++++++++++++++++ 4 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 hw/arm/bcm2838_pcie.c create mode 100644 include/hw/arm/bcm2838_pcie.h