Re: [PATCH v3 03/10] hw/riscv: add RPMI FDT helpers
Daniel Henrique Barboza <[email protected]>
| Newsgroups | org.nongnu.qemu-riscv,org.nongnu.qemu-devel |
|---|---|
| Message-ID | <[email protected]> |
On 7/14/2026 4:56 AM, Subrahmanya Lingappa wrote: > Add helper routines for describing RPMI shared-memory mailbox transports > and service child nodes in the RISC-V virt device tree. > > The helpers keep RPMI node construction in one place so the virt machine > can add service groups without open-coding compatible strings, channel > IDs, interrupts, and shared-memory references at each call site. > > Signed-off-by: Subrahmanya Lingappa <[email protected]> > --- Reviewed-by: Daniel Henrique Barboza <[email protected]> > hw/riscv/meson.build | 1 + > hw/riscv/rpmi-fdt.c | 103 ++++++++++++++++++++++++++++++++++++ > include/hw/riscv/rpmi-fdt.h | 30 +++++++++++ > 3 files changed, 134 insertions(+) > create mode 100644 hw/riscv/rpmi-fdt.c > create mode 100644 include/hw/riscv/rpmi-fdt.h > > diff --git a/hw/riscv/meson.build b/hw/riscv/meson.build > index b70a054579..529ec273fd 100644 > --- a/hw/riscv/meson.build > +++ b/hw/riscv/meson.build > @@ -3,6 +3,7 @@ riscv_ss.add(files('boot.c')) > riscv_ss.add(files('fdt-common.c')) > riscv_ss.add(when: 'CONFIG_RISCV_NUMA', if_true: files('numa.c')) > riscv_ss.add(files('riscv_hart.c')) > +riscv_ss.add(files('rpmi-fdt.c')) > riscv_ss.add(when: 'CONFIG_OPENTITAN', if_true: files('opentitan.c')) > riscv_ss.add(when: 'CONFIG_RISCV_VIRT', if_true: files('virt.c')) > riscv_ss.add(when: 'CONFIG_SHAKTI_C', if_true: files('shakti_c.c')) > diff --git a/hw/riscv/rpmi-fdt.c b/hw/riscv/rpmi-fdt.c > new file mode 100644 > index 0000000000..b2b3daea1c > --- /dev/null > +++ b/hw/riscv/rpmi-fdt.c > @@ -0,0 +1,103 @@ > +/* > + * SPDX-License-Identifier: GPL-2.0-or-later > + * > + * RISC-V RPMI device-tree helpers > + * > + * Copyright (c) 2026 Qualcomm Technologies, Inc. > + * Author: > + * Subrahmanya Lingappa <[email protected]> > + */ > + > +#include "qemu/osdep.h" > +#include "qemu/bswap.h" > +#include "hw/riscv/rpmi-fdt.h" > +#include "hw/misc/riscv_rpmi.h" > +#include "system/device_tree.h" > + > +void riscv_rpmi_fdt_add_mbox(void *fdt, > + const RiscvRpmiFdtMboxConfig *cfg, > + uint32_t *phandle, > + uint32_t *mbox_handle) > +{ > + g_autofree char *name = NULL; > + hwaddr a2p_req_base, p2a_ack_base, p2a_req_base, a2p_ack_base; > + static const char * const regnames_all[RPMI_ALL_NUM_REGS] = { > + "a2p-req", "p2a-ack", "p2a-req", "a2p-ack", "a2p-doorbell" > + }; > + static const char * const regnames_a2p[RPMI_A2P_NUM_REGS] = { > + "a2p-req", "p2a-ack", "a2p-doorbell" > + }; > + > + a2p_req_base = cfg->shmem_base; > + p2a_ack_base = a2p_req_base + cfg->a2p_req_size; > + p2a_req_base = p2a_ack_base + cfg->a2p_req_size; > + a2p_ack_base = p2a_req_base + cfg->p2a_req_size; > + > + *mbox_handle = (*phandle)++; > + name = g_strdup_printf("/soc/mailbox@%" HWADDR_PRIx, cfg->shmem_base); > + qemu_fdt_add_subnode(fdt, name); > + qemu_fdt_setprop_string(fdt, name, "compatible", "riscv,rpmi-shmem-mbox"); > + qemu_fdt_setprop_cell(fdt, name, "riscv,slot-size", RPMI_QUEUE_SLOT_SIZE); > + qemu_fdt_setprop_cell(fdt, name, "#mbox-cells", 1); > + > + if (cfg->p2a_req_size) { > + qemu_fdt_setprop_string_array(fdt, name, "reg-names", > + (char **)®names_all, > + ARRAY_SIZE(regnames_all)); > + qemu_fdt_setprop_cells(fdt, name, "reg", > + (uint32_t)(a2p_req_base >> 32), (uint32_t)a2p_req_base, > + 0x0, cfg->a2p_req_size, > + (uint32_t)(p2a_ack_base >> 32), (uint32_t)p2a_ack_base, > + 0x0, cfg->a2p_req_size, > + (uint32_t)(p2a_req_base >> 32), (uint32_t)p2a_req_base, > + 0x0, cfg->p2a_req_size, > + (uint32_t)(a2p_ack_base >> 32), (uint32_t)a2p_ack_base, > + 0x0, cfg->p2a_req_size, > + (uint32_t)(cfg->doorbell_base >> 32), (uint32_t)cfg->doorbell_base, > + 0x0, cfg->doorbell_size); > + } else { > + qemu_fdt_setprop_string_array(fdt, name, "reg-names", > + (char **)®names_a2p, > + ARRAY_SIZE(regnames_a2p)); > + qemu_fdt_setprop_cells(fdt, name, "reg", > + (uint32_t)(a2p_req_base >> 32), (uint32_t)a2p_req_base, > + 0x0, cfg->a2p_req_size, > + (uint32_t)(p2a_ack_base >> 32), (uint32_t)p2a_ack_base, > + 0x0, cfg->a2p_req_size, > + (uint32_t)(cfg->doorbell_base >> 32), (uint32_t)cfg->doorbell_base, > + 0x0, cfg->doorbell_size); > + } > + > + qemu_fdt_setprop_cells(fdt, name, "phandle", *mbox_handle); > +} > + > +void riscv_rpmi_fdt_add_service(void *fdt, hwaddr shmem_base, > + const char *node_name, > + const char *compatible, > + uint32_t mbox_handle, > + uint32_t service_group, > + bool has_mpxy_channel, > + uint32_t mpxy_channel) > +{ > + g_autofree char *name = g_strdup_printf("/soc/mailbox@%" HWADDR_PRIx "/%s", > + shmem_base, node_name); > + > + qemu_fdt_add_subnode(fdt, name); > + qemu_fdt_setprop_string(fdt, name, "compatible", compatible); > + qemu_fdt_setprop_cells(fdt, name, "mboxes", mbox_handle, service_group); > + if (has_mpxy_channel) { > + qemu_fdt_setprop_cell(fdt, name, "riscv,sbi-mpxy-channel-id", > + mpxy_channel); > + } > +} > + > +void riscv_rpmi_fdt_add_service_node(void *fdt, hwaddr shmem_base, > + const RiscvRpmiServiceConfig *service, > + uint32_t mbox_handle) > +{ > + riscv_rpmi_fdt_add_service(fdt, shmem_base, service->node_name, > + service->compatible, mbox_handle, > + service->service_group, > + service->has_mpxy_channel, > + service->mpxy_channel); > +} > diff --git a/include/hw/riscv/rpmi-fdt.h b/include/hw/riscv/rpmi-fdt.h > new file mode 100644 > index 0000000000..f053ae5d57 > --- /dev/null > +++ b/include/hw/riscv/rpmi-fdt.h > @@ -0,0 +1,30 @@ > +/* > + * SPDX-License-Identifier: GPL-2.0-or-later > + * > + * RISC-V RPMI device-tree helpers > + * > + * Copyright (c) 2026 Qualcomm Technologies, Inc. > + * Author: > + * Subrahmanya Lingappa <[email protected]> > + */ > + > +#ifndef HW_RISCV_RPMI_FDT_H > +#define HW_RISCV_RPMI_FDT_H > + > +#include "exec/hwaddr.h" > +#include "hw/misc/riscv_rpmi.h" > + > +typedef struct RiscvRpmiFdtMboxConfig { > + hwaddr shmem_base; > + hwaddr doorbell_base; > + uint32_t a2p_req_size; > + uint32_t p2a_req_size; > + uint32_t doorbell_size; > +} RiscvRpmiFdtMboxConfig; > + > +void riscv_rpmi_fdt_add_mbox(void *fdt, > + const RiscvRpmiFdtMboxConfig *cfg, > + uint32_t *phandle, > + uint32_t *mbox_handle); > + > +#endif