qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Pavel Pisa <pisa@fel.cvut.cz>
To: qemu-devel@nongnu.org, Peter Maydell <peter.maydell@linaro.org>,
	Gustavo Romero <gustavo.romero@linaro.org>
Cc: "Paolo Bonzini" <pbonzini@redhat.com>,
	"Jason Wang" <jasowang@redhat.com>,
	"Francisco Iglesias" <francisco.iglesias@amd.com>,
	"Alex Bennée" <alex.bennee@linaro.org>,
	"Pavel Pisa" <pisa@cmp.felk.cvut.cz>
Subject: [RFC/WIP 0/3] WIP CTU CAN FD IP core mapping to the platform bus
Date: Tue, 10 Dec 2024 00:32:50 +0100	[thread overview]
Message-ID: <cover.1733783500.git.pisa@cmp.felk.cvut.cz> (raw)

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



             reply	other threads:[~2024-12-09 23:34 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-12-09 23:32 Pavel Pisa [this message]
2024-12-09 23:32 ` [RFC 1/3] hw/net/can: WIP CTU CAN FD IP core mapping to the platform bus Pavel Pisa
2024-12-09 23:32 ` [RFC 2/3] hw/net/can: WIP CTU CAN FD mapping of IRQ for platform device solved Pavel Pisa
2024-12-09 23:32 ` [RFC 3/3] hw/net/can: WIP CTU CAN FD add parameter to specify IRQ controller on command line Pavel Pisa
2024-12-10 10:08 ` [RFC/WIP 0/3] WIP CTU CAN FD IP core mapping to the platform bus Peter Maydell
2024-12-10 16:32   ` Pavel Pisa

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=cover.1733783500.git.pisa@cmp.felk.cvut.cz \
    --to=pisa@fel.cvut.cz \
    --cc=alex.bennee@linaro.org \
    --cc=francisco.iglesias@amd.com \
    --cc=gustavo.romero@linaro.org \
    --cc=jasowang@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=pisa@cmp.felk.cvut.cz \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).