hw/arm/xilinx_zynq.c | 1 + hw/net/can/ctucan_mm.c | 291 +++++++++++++++++++++++++++++++++++++++++ hw/net/can/meson.build | 1 + 3 files changed, 293 insertions(+) create mode 100644 hw/net/can/ctucan_mm.c
From: Pavel Pisa <pisa@cmp.felk.cvut.cz> Hello Peter, Gustavo and others, our CTU CAN FD IP core is used on many FPGA platforms and has been even tapeout on some other university and even prototypes of the massive production chips (support for that organized by our former student in his company). But actual QEMU emulation targets only PCI/PCIe mapping in hw/net/can/ctucan_pci.c of the core in hw/net/can/ctucan_core.c I would like to add support to map the core at fixed position for SoCs and command line controlled location for FPGA targets. I have working proof of concept on the branch net-can-ctucanfd-platform/ https://github.com/ppisa/qemu/commits/net-can-ctucanfd-platform/ But I am sure that IRQ delivery should be cleaned and even for PCI/PCIe the logical OR function should be added into delivery of interrupts from individual cores to the IRQ on platform or PCI/PCIe level The code at this moment: hw/net/can/ctucan_core.h typedef struct CtuCanCoreState { ... qemu_irq irq; CanBusClientState bus_client; } CtuCanCoreState; hw/net/can/ctucan_core.c: int ctucan_init(CtuCanCoreState *s, qemu_irq irq) { s->irq = irq; qemu_irq_lower(s->irq); ctucan_hardware_reset(s); return 0; } static void ctucan_update_irq(CtuCanCoreState *s) { ... if (s->int_stat.u32 & s->int_ena.u32) { qemu_irq_raise(s->irq); } else { qemu_irq_lower(s->irq); } } Memory mapping of the core hw/net/can/ctucan_mm.c: struct CtuCanMmState { /*< private >*/ SysBusDevice parent_obj; /*< public >*/ struct { uint64_t iobase; uint32_t irqnum; char *irqctrl; } cfg; MemoryRegion ctucan_io_region; CtuCanCoreState ctucan_state[CTUCAN_MM_CORE_COUNT]; qemu_irq irq; char *model; CanBusState *canbus[CTUCAN_MM_CORE_COUNT]; }; and qemu_irq value is propagated into CTU CAN FD cores in hw/net/can/ctucan_mm.c: static void ctucan_mm_realize(DeviceState *dev, Error **errp) { CtuCanMmState *d = CTUCAN_MM_DEV(dev); SysBusDevice *sbd = SYS_BUS_DEVICE(dev); int i; ... /* memory_region_add_subregion(get_system_memory(), 0x43c30000, &d->ctucan_io_region); */ if (d->cfg.iobase != 0) { sysbus_mmio_map(sbd, 0, d->cfg.iobase); } if (d->cfg.irqnum != 0) { //const char *id = "/machine/unattached/device[3]/gic"; //const char *id = "/machine/unattached/device[3]"; char *id = d->cfg.irqctrl; if (!id) { error_setg(errp, "irqctrl object path is mandatory when irqnum is specified"); return; } Object *obj = object_resolve_path_at(container_get(qdev_get_machine(), "/peripheral"), id); DeviceState *gicdev; if (!obj) { error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND, "Device '%s' not found", id); return; } gicdev = (DeviceState *)object_dynamic_cast(obj, TYPE_DEVICE); if (!gicdev) { error_setg(errp, "%s is not a hotpluggable device", id); return; } sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(gicdev, d->cfg.irqnum)); } for (i = 0 ; i < CTUCAN_MM_CORE_COUNT; i++) { ctucan_init(&d->ctucan_state[i], d->irq); } } There is magic how to obtain interrupt controller object of the SoC. I have found that next parameters are working for Xilinx Zynq platform qemu-system-arm -m 1G -M xilinx-zynq-a9 \ -kernel kernel-zynq \ -dtb zynq-microzed-uart1-2x-xcan-4x-ctu-axi.dtb \ -initrd ramdisk.cpio \ -serial null -serial mon:stdio \ -nographic \ -object can-bus,id=canbus0-bus \ -object can-host-socketcan,if=can0,canbus=canbus0-bus,id=canbus0-socketcan \ -device ctucan_mm,iobase=0x43c30000,irqnum=29,irqctrl=/machine/unattached/device[3],canbus=canbus0-bus \ -device ctucan_mm,iobase=0x43c70000,irqnum=30,irqctrl=/machine/unattached/device[3],canbus=canbus0-bus \ -device ctucan_mm,iobase=0x43bf0000,irqnum=31,irqctrl=/machine/unattached/device[3],canbus=canbus0-bus \ -device ctucan_mm,iobase=0x43bb0000,irqnum=32,irqctrl=/machine/unattached/device[3],canbus=canbus0-bus \ But in general, I am not sure if copying of qemu_irq object (s->irq = irq;) is correct according to the conventions and I would like more some solution which allows to process/combine multiple requests in some callback on the level of PCI/PCIe or platform level integration object before passing to the parent bus/interrupt controller level. Pavel Pisa (3): hw/net/can: WIP CTU CAN FD IP core mapping to the platform bus hw/net/can: WIP CTU CAN FD mapping of IRQ for platform device solved. hw/net/can: WIP CTU CAN FD add parameter to specify IRQ controller on command line hw/arm/xilinx_zynq.c | 1 + hw/net/can/ctucan_mm.c | 291 +++++++++++++++++++++++++++++++++++++++++ hw/net/can/meson.build | 1 + 3 files changed, 293 insertions(+) create mode 100644 hw/net/can/ctucan_mm.c -- 2.39.5
On Mon, 9 Dec 2024 at 23:33, Pavel Pisa <pisa@fel.cvut.cz> wrote: > our CTU CAN FD IP core is used on many FPGA platforms > and has been even tapeout on some other university > and even prototypes of the massive production chips > (support for that organized by our former student > in his company). > > But actual QEMU emulation targets only PCI/PCIe mapping in > > hw/net/can/ctucan_pci.c > > of the core in > > hw/net/can/ctucan_core.c > > I would like to add support to map the core at fixed position for > SoCs and command line controlled location for FPGA targets. Command line instantiation of devices at command line controlled addresses and with command line connection of IRQ lines is basically something we do not currently support. There is some prototype/design work going on about generic "create a machine from the command line" handling, which would inevitably involve allowing the user to specify addresses and IRQ lines. But I don't really want to see ad-hoc device-specific additions of small parts of similar functionality. If there's a SoC that QEMU models that has this CAN controller, then it's the SoC model (written in C) that defines where it is mapped in memory and what IRQ lines it is wired up to. thanks -- PMM
Hello Peter, On Tuesday 10 of December 2024 11:08:53 Peter Maydell wrote: > On Mon, 9 Dec 2024 at 23:33, Pavel Pisa <pisa@fel.cvut.cz> wrote: > > our CTU CAN FD IP core is used on many FPGA platforms > > and has been even tapeout on some other university > > and even prototypes of the massive production chips > > (support for that organized by our former student > > in his company). > > > > But actual QEMU emulation targets only PCI/PCIe mapping in > > > > hw/net/can/ctucan_pci.c > > > > of the core in > > > > hw/net/can/ctucan_core.c > > > > I would like to add support to map the core at fixed position for > > SoCs and command line controlled location for FPGA targets. > > Command line instantiation of devices at command line > controlled addresses and with command line connection > of IRQ lines is basically something we do not > currently support. There is some prototype/design work > going on about generic "create a machine from > the command line" handling, which would inevitably > involve allowing the user to specify addresses and IRQ > lines. But I don't really want to see ad-hoc device-specific > additions of small parts of similar functionality. > > If there's a SoC that QEMU models that has this CAN > controller, then it's the SoC model (written in C) > that defines where it is mapped in memory and what > IRQ lines it is wired up to. There should be such SoC in some time even in public. I understand that in such case the mapping should be part of its support. But main area of the CTU CAN FD IP core use are FPGAs for now, Xilinx Zynq and above, Intel/Altera SoC+FPGAs, actual next target to test is Microchip PolarFire on BeagleV-Fire which allows to develop and test driver for Linux, NuttX and RTEMS on the single chip. And it would be great if there is option to run that on CI and have (still simplified - no bitrate miscmatch check etc) model for SW development with QEMU. And CTU CAN FD does not belong to the core Zynq or PolarFire support in such cases. So even this actual solution is usable in such cases. But as I have expected, it is not so welcomed in mainline... which is why I attempt to find what can be done. Do you consider the the proposed trick (target object specified by "irqctrl" parameter on commad line and then resolved by object_resolve_path_at()) as unacceptable for mainline? Another problem is if the qemu_irq can be copied in ctucan_mm_realize. I have tried even another solution where chip core kept pointer to qemu_irq in the bus integration wrapper (PCI/PCIe and platform). But even for mainlined PCI/PCIe CTU CAN FD support I would like to update support to provide real "or" operation between IRQs outputs from individual controllers to PCI/PCIe interrupt link. So in this case, I would be happy to hear if I can reuse qemu_irq and some routing or if I should define own mechanism to activate callback provided by the bus integration wrapper from the core emulation code. But may it be some pin logic already implemented in QEMU can be used there. Best wishes, Pavel PS: does somebody have some experience, information for use of "16c3:abcd" DWC_usb3 / PCIe bridge on i.MX6 Sabre Litte, I have sent plea for help two months ago without any respone and it would help our another CAN controller development project, iMX6 FlexCAN support. -- Pavel Pisa phone: +420 603531357 e-mail: pisa@cmp.felk.cvut.cz Department of Control Engineering FEE CVUT Karlovo namesti 13, 121 35, Prague 2 university: http://control.fel.cvut.cz/ personal: http://cmp.felk.cvut.cz/~pisa social: https://social.kernel.org/ppisa projects: https://www.openhub.net/accounts/ppisa CAN related:http://canbus.pages.fel.cvut.cz/ RISC-V education: https://comparch.edu.cvut.cz/ Open Technologies Research Education and Exchange Services https://gitlab.fel.cvut.cz/otrees/org/-/wikis/home
© 2016 - 2025 Red Hat, Inc.