* [RFC/WIP 0/3] WIP CTU CAN FD IP core mapping to the platform bus
@ 2024-12-09 23:32 Pavel Pisa
2024-12-09 23:32 ` [RFC 1/3] hw/net/can: " Pavel Pisa
` (3 more replies)
0 siblings, 4 replies; 6+ messages in thread
From: Pavel Pisa @ 2024-12-09 23:32 UTC (permalink / raw)
To: qemu-devel, Peter Maydell, Gustavo Romero
Cc: Paolo Bonzini, Jason Wang, Francisco Iglesias, Alex Bennée,
Pavel Pisa
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
^ permalink raw reply [flat|nested] 6+ messages in thread
* [RFC 1/3] hw/net/can: WIP CTU CAN FD IP core mapping to the platform bus
2024-12-09 23:32 [RFC/WIP 0/3] WIP CTU CAN FD IP core mapping to the platform bus Pavel Pisa
@ 2024-12-09 23:32 ` 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
` (2 subsequent siblings)
3 siblings, 0 replies; 6+ messages in thread
From: Pavel Pisa @ 2024-12-09 23:32 UTC (permalink / raw)
To: qemu-devel, Peter Maydell, Gustavo Romero
Cc: Paolo Bonzini, Jason Wang, Francisco Iglesias, Alex Bennée,
Pavel Pisa
From: Pavel Pisa <pisa@cmp.felk.cvut.cz>
It is initial attempt (IRQ not working yet) to provide
alternative to PCIe mapping. In this case, the platform
bus is used to match FPGA design for Xilinx Zynq MZ_APO
education kit with four CTU CAN FD cores on branch
mz_apo-2x-xcan-4x-ctu of repo
https://gitlab.fel.cvut.cz/canbus/zynq/zynq-can-sja1000-top
The system is started by command
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,irq=29,canbus=canbus0-bus \
-device ctucan_mm,iobase=0x43c70000,irq=30,canbus=canbus0-bus \
-device ctucan_mm,iobase=0x43bf0000,irq=31,canbus=canbus0-bus \
-device ctucan_mm,iobase=0x43bb0000,irq=32,canbus=canbus0-bus \
Signed-off-by: Pavel Pisa <pisa@cmp.felk.cvut.cz>
---
hw/arm/xilinx_zynq.c | 1 +
hw/net/can/ctucan_mm.c | 279 +++++++++++++++++++++++++++++++++++++++++
hw/net/can/meson.build | 1 +
3 files changed, 281 insertions(+)
create mode 100644 hw/net/can/ctucan_mm.c
diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
index fde4d946b7..cd6444a6fe 100644
--- a/hw/arm/xilinx_zynq.c
+++ b/hw/arm/xilinx_zynq.c
@@ -473,6 +473,7 @@ static void zynq_machine_class_init(ObjectClass *oc, void *data)
"Supported boot modes:"
" jtag qspi sd nor");
object_property_set_default_str(prop, "qspi");
+ machine_class_allow_dynamic_sysbus_dev(mc, "ctucan_mm");
}
static const TypeInfo zynq_machine_type = {
diff --git a/hw/net/can/ctucan_mm.c b/hw/net/can/ctucan_mm.c
new file mode 100644
index 0000000000..43e6823b73
--- /dev/null
+++ b/hw/net/can/ctucan_mm.c
@@ -0,0 +1,279 @@
+/*
+ * CTU CAN FD memory mapped device emulation
+ * http://canbus.pages.fel.cvut.cz/
+ *
+ * Copyright (c) 2024 Pavel Pisa (pisa@cmp.felk.cvut.cz)
+ *
+ * Based on Kvaser PCI CAN device (SJA1000 based) emulation implemented by
+ * Jin Yang and Pavel Pisa
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/event_notifier.h"
+#include "qemu/module.h"
+#include "qemu/thread.h"
+#include "qemu/sockets.h"
+#include "qapi/error.h"
+#include "chardev/char.h"
+#include "hw/irq.h"
+#include "hw/sysbus.h"
+#include "hw/qdev-properties.h"
+#include "migration/vmstate.h"
+#include "net/can_emu.h"
+
+#include "ctucan_core.h"
+
+#define TYPE_CTUCAN_MM_DEV "ctucan_mm"
+
+typedef struct CtuCanMmState CtuCanMmState;
+DECLARE_INSTANCE_CHECKER(CtuCanMmState, CTUCAN_MM_DEV,
+ TYPE_CTUCAN_MM_DEV)
+
+#define CTUCAN_MM_CORE_COUNT 1
+#define CTUCAN_MM_CORE_RANGE 0x1000
+
+#define CTUCAN_MM_BYTES_PER_CORE 0x1000
+
+struct CtuCanMmState {
+ /*< private >*/
+ SysBusDevice parent_obj;
+ /*< public >*/
+
+ struct {
+ uint64_t iobase;
+ uint32_t irq;
+ } cfg;
+
+ MemoryRegion ctucan_io_region;
+
+ CtuCanCoreState ctucan_state[CTUCAN_MM_CORE_COUNT];
+ qemu_irq irq;
+
+ char *model;
+ CanBusState *canbus[CTUCAN_MM_CORE_COUNT];
+};
+
+static void ctucan_mm_reset(DeviceState *dev)
+{
+ CtuCanMmState *d = CTUCAN_MM_DEV(dev);
+ int i;
+
+ for (i = 0 ; i < CTUCAN_MM_CORE_COUNT; i++) {
+ ctucan_hardware_reset(&d->ctucan_state[i]);
+ }
+}
+
+static uint64_t ctucan_mm_cores_io_read(void *opaque, hwaddr addr,
+ unsigned size)
+{
+ CtuCanMmState *d = opaque;
+ CtuCanCoreState *s;
+ hwaddr core_num = addr / CTUCAN_MM_BYTES_PER_CORE;
+
+ if (core_num >= CTUCAN_MM_CORE_COUNT) {
+ return 0;
+ }
+
+ s = &d->ctucan_state[core_num];
+
+ return ctucan_mem_read(s, addr % CTUCAN_MM_BYTES_PER_CORE, size);
+}
+
+static void ctucan_mm_cores_io_write(void *opaque, hwaddr addr, uint64_t data,
+ unsigned size)
+{
+ CtuCanMmState *d = opaque;
+ CtuCanCoreState *s;
+ hwaddr core_num = addr / CTUCAN_MM_BYTES_PER_CORE;
+
+ if (core_num >= CTUCAN_MM_CORE_COUNT) {
+ return;
+ }
+
+ s = &d->ctucan_state[core_num];
+
+ return ctucan_mem_write(s, addr % CTUCAN_MM_BYTES_PER_CORE, data, size);
+}
+
+static const MemoryRegionOps ctucan_mm_cores_io_ops = {
+ .read = ctucan_mm_cores_io_read,
+ .write = ctucan_mm_cores_io_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+ .impl.min_access_size = 1,
+ .impl.max_access_size = 4,
+ .valid.min_access_size = 1,
+ .valid.max_access_size = 4,
+};
+
+static void ctucan_mm_realize(DeviceState *dev, Error **errp)
+{
+ CtuCanMmState *d = CTUCAN_MM_DEV(dev);
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+ int i;
+
+ for (i = 0 ; i < CTUCAN_MM_CORE_COUNT; i++) {
+ ctucan_init(&d->ctucan_state[i], d->irq);
+ }
+
+ for (i = 0 ; i < CTUCAN_MM_CORE_COUNT; i++) {
+ if (ctucan_connect_to_bus(&d->ctucan_state[i], d->canbus[i]) < 0) {
+ error_setg(errp, "ctucan_connect_to_bus failed");
+ return;
+ }
+ }
+
+ /* 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.irq != 0) {
+ //const char *id = "/machine/unattached/device[3]/gic";
+ const char *id = "/machine/unattached/device[3]";
+ 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.irq));
+ }
+}
+
+/*
+static void ctucan_mm_exit(Object *obj)
+{
+ CtuCanMmState *d = CTUCAN_MM_DEV(obj);
+ int i;
+
+ for (i = 0 ; i < CTUCAN_MM_CORE_COUNT; i++) {
+ ctucan_disconnect(&d->ctucan_state[i]);
+ }
+
+ qemu_free_irq(d->irq);
+}
+*/
+
+static void ctucan_mm_reset_init(Object *obj, ResetType type)
+{
+ CtuCanMmState *d = CTUCAN_MM_DEV(obj);
+ unsigned int i;
+
+ for (i = 0 ; i < CTUCAN_MM_CORE_COUNT; i++) {
+ ctucan_init(&d->ctucan_state[i], d->irq);
+ }
+}
+
+static void ctucan_mm_reset_hold(Object *obj, ResetType type)
+{
+ CtuCanMmState *d = CTUCAN_MM_DEV(obj);
+ unsigned int i;
+
+ for (i = 0 ; i < CTUCAN_MM_CORE_COUNT; i++) {
+ ctucan_init(&d->ctucan_state[i], d->irq);
+ }
+}
+
+static const VMStateDescription vmstate_ctucan_mm = {
+ .name = "ctucan_mm",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (const VMStateField[]) {
+ VMSTATE_STRUCT(ctucan_state[0], CtuCanMmState, 0, vmstate_ctucan,
+ CtuCanCoreState),
+#if CTUCAN_MM_CORE_COUNT >= 2
+ VMSTATE_STRUCT(ctucan_state[1], CtuCanMmState, 0, vmstate_ctucan,
+ CtuCanCoreState),
+#endif
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static void ctucan_mm_instance_init(Object *obj)
+{
+ CtuCanMmState *d = CTUCAN_MM_DEV(obj);
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+
+#if CTUCAN_MM_CORE_COUNT <= 1
+ object_property_add_link(obj, "canbus", TYPE_CAN_BUS,
+ (Object **)&d->canbus[0],
+ qdev_prop_allow_set_link_before_realize, 0);
+#else /* CTUCAN_MM_CORE_COUNT >= 2 */
+ object_property_add_link(obj, "canbus0", TYPE_CAN_BUS,
+ (Object **)&d->canbus[0],
+ qdev_prop_allow_set_link_before_realize, 0);
+ object_property_add_link(obj, "canbus1", TYPE_CAN_BUS,
+ (Object **)&d->canbus[1],
+ qdev_prop_allow_set_link_before_realize, 0);
+#endif
+ memory_region_init_io(&d->ctucan_io_region, OBJECT(d),
+ &ctucan_mm_cores_io_ops, d,
+ "ctucan_mm", CTUCAN_MM_CORE_RANGE);
+
+ sysbus_init_mmio(sbd, &d->ctucan_io_region);
+ sysbus_init_irq(sbd, &d->irq);
+}
+
+static Property ctucan_mm_properties[] = {
+ //DEFINE_PROP_UNSIGNED_NODEFAULT("base", CtuCanMmState, cfg.base,
+ // qdev_prop_uint64, uint64_t),
+ DEFINE_PROP_UINT64("iobase", CtuCanMmState, cfg.iobase, 0),
+ DEFINE_PROP_UINT32("irq", CtuCanMmState, cfg.irq, 0),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static void ctucan_mm_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
+
+ rc->phases.enter = ctucan_mm_reset_init;
+ rc->phases.hold = ctucan_mm_reset_hold;
+ dc->realize = ctucan_mm_realize;
+ /* ->exit = ctucan_mm_exit; */
+ dc->desc = "CTU CAN MM";
+ dc->vmsd = &vmstate_ctucan_mm;
+ set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+ dc->user_creatable = true;
+ /* dc->reset = ctucan_mm_reset; */
+ device_class_set_legacy_reset(dc, ctucan_mm_reset);
+
+ device_class_set_props(dc, ctucan_mm_properties);
+}
+
+static const TypeInfo ctucan_mm_info = {
+ .name = TYPE_CTUCAN_MM_DEV,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(CtuCanMmState),
+ .class_init = ctucan_mm_class_init,
+ .instance_init = ctucan_mm_instance_init,
+};
+
+static void ctucan_mm_register_types(void)
+{
+ type_register_static(&ctucan_mm_info);
+}
+
+type_init(ctucan_mm_register_types)
diff --git a/hw/net/can/meson.build b/hw/net/can/meson.build
index 7382344628..de25fdbd1c 100644
--- a/hw/net/can/meson.build
+++ b/hw/net/can/meson.build
@@ -3,6 +3,7 @@ system_ss.add(when: 'CONFIG_CAN_PCI', if_true: files('can_kvaser_pci.c'))
system_ss.add(when: 'CONFIG_CAN_PCI', if_true: files('can_pcm3680_pci.c'))
system_ss.add(when: 'CONFIG_CAN_PCI', if_true: files('can_mioe3680_pci.c'))
system_ss.add(when: 'CONFIG_CAN_CTUCANFD', if_true: files('ctucan_core.c'))
+system_ss.add(when: 'CONFIG_CAN_CTUCANFD', if_true: files('ctucan_mm.c'))
system_ss.add(when: 'CONFIG_CAN_CTUCANFD_PCI', if_true: files('ctucan_pci.c'))
system_ss.add(when: 'CONFIG_XLNX_ZYNQMP', if_true: files('xlnx-zynqmp-can.c'))
system_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files('xlnx-versal-canfd.c'))
--
2.39.5
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [RFC 2/3] hw/net/can: WIP CTU CAN FD mapping of IRQ for platform device solved.
2024-12-09 23:32 [RFC/WIP 0/3] WIP CTU CAN FD IP core mapping to the platform bus Pavel Pisa
2024-12-09 23:32 ` [RFC 1/3] hw/net/can: " Pavel Pisa
@ 2024-12-09 23:32 ` 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
3 siblings, 0 replies; 6+ messages in thread
From: Pavel Pisa @ 2024-12-09 23:32 UTC (permalink / raw)
To: qemu-devel, Peter Maydell, Gustavo Romero
Cc: Paolo Bonzini, Jason Wang, Francisco Iglesias, Alex Bennée,
Pavel Pisa
From: Pavel Pisa <pisa@cmp.felk.cvut.cz>
Signed-off-by: Pavel Pisa <pisa@cmp.felk.cvut.cz>
---
hw/net/can/ctucan_mm.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/hw/net/can/ctucan_mm.c b/hw/net/can/ctucan_mm.c
index 43e6823b73..6d6b8aecb8 100644
--- a/hw/net/can/ctucan_mm.c
+++ b/hw/net/can/ctucan_mm.c
@@ -160,6 +160,9 @@ static void ctucan_mm_realize(DeviceState *dev, Error **errp)
}
sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(gicdev, d->cfg.irq));
}
+ for (i = 0 ; i < CTUCAN_MM_CORE_COUNT; i++) {
+ ctucan_init(&d->ctucan_state[i], d->irq);
+ }
}
/*
--
2.39.5
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [RFC 3/3] hw/net/can: WIP CTU CAN FD add parameter to specify IRQ controller on command line
2024-12-09 23:32 [RFC/WIP 0/3] WIP CTU CAN FD IP core mapping to the platform bus Pavel Pisa
2024-12-09 23:32 ` [RFC 1/3] hw/net/can: " 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 ` Pavel Pisa
2024-12-10 10:08 ` [RFC/WIP 0/3] WIP CTU CAN FD IP core mapping to the platform bus Peter Maydell
3 siblings, 0 replies; 6+ messages in thread
From: Pavel Pisa @ 2024-12-09 23:32 UTC (permalink / raw)
To: qemu-devel, Peter Maydell, Gustavo Romero
Cc: Paolo Bonzini, Jason Wang, Francisco Iglesias, Alex Bennée,
Pavel Pisa
From: Pavel Pisa <pisa@cmp.felk.cvut.cz>
Signed-off-by: Pavel Pisa <pisa@cmp.felk.cvut.cz>
---
hw/net/can/ctucan_mm.c | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/hw/net/can/ctucan_mm.c b/hw/net/can/ctucan_mm.c
index 6d6b8aecb8..e599df18be 100644
--- a/hw/net/can/ctucan_mm.c
+++ b/hw/net/can/ctucan_mm.c
@@ -59,7 +59,8 @@ struct CtuCanMmState {
struct {
uint64_t iobase;
- uint32_t irq;
+ uint32_t irqnum;
+ char *irqctrl;
} cfg;
MemoryRegion ctucan_io_region;
@@ -144,9 +145,16 @@ static void ctucan_mm_realize(DeviceState *dev, Error **errp)
if (d->cfg.iobase != 0) {
sysbus_mmio_map(sbd, 0, d->cfg.iobase);
}
- if (d->cfg.irq != 0) {
+ if (d->cfg.irqnum != 0) {
//const char *id = "/machine/unattached/device[3]/gic";
- const char *id = "/machine/unattached/device[3]";
+ //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) {
@@ -158,7 +166,7 @@ static void ctucan_mm_realize(DeviceState *dev, Error **errp)
error_setg(errp, "%s is not a hotpluggable device", id);
return;
}
- sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(gicdev, d->cfg.irq));
+ 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);
@@ -243,7 +251,8 @@ static Property ctucan_mm_properties[] = {
//DEFINE_PROP_UNSIGNED_NODEFAULT("base", CtuCanMmState, cfg.base,
// qdev_prop_uint64, uint64_t),
DEFINE_PROP_UINT64("iobase", CtuCanMmState, cfg.iobase, 0),
- DEFINE_PROP_UINT32("irq", CtuCanMmState, cfg.irq, 0),
+ DEFINE_PROP_UINT32("irqnum", CtuCanMmState, cfg.irqnum, 0),
+ DEFINE_PROP_STRING("irqctrl", CtuCanMmState, cfg.irqctrl),
DEFINE_PROP_END_OF_LIST(),
};
--
2.39.5
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [RFC/WIP 0/3] WIP CTU CAN FD IP core mapping to the platform bus
2024-12-09 23:32 [RFC/WIP 0/3] WIP CTU CAN FD IP core mapping to the platform bus Pavel Pisa
` (2 preceding siblings ...)
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 ` Peter Maydell
2024-12-10 16:32 ` Pavel Pisa
3 siblings, 1 reply; 6+ messages in thread
From: Peter Maydell @ 2024-12-10 10:08 UTC (permalink / raw)
To: Pavel Pisa
Cc: qemu-devel, Gustavo Romero, Paolo Bonzini, Jason Wang,
Francisco Iglesias, Alex Bennée, Pavel Pisa
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
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [RFC/WIP 0/3] WIP CTU CAN FD IP core mapping to the platform bus
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
0 siblings, 0 replies; 6+ messages in thread
From: Pavel Pisa @ 2024-12-10 16:32 UTC (permalink / raw)
To: qemu-devel, Peter Maydell
Cc: Gustavo Romero, Paolo Bonzini, Jason Wang, Francisco Iglesias,
Alex Bennée
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
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2024-12-10 16:32 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-12-09 23:32 [RFC/WIP 0/3] WIP CTU CAN FD IP core mapping to the platform bus Pavel Pisa
2024-12-09 23:32 ` [RFC 1/3] hw/net/can: " 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
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).