Ranbir,

On Tue, Aug 18, 2026 at 11:36 AM Ranbir Singh <[email protected]> wrote:
>
>
>
>
> ________________________________________
> From: [email protected] 
> <[email protected]> on behalf of 
> Subrahmanya Lingappa <[email protected]>
> Sent: 17 August 2026 16:24
> To: [email protected]
> Cc: [email protected]; Subrahmanya Lingappa; Daniel Henrique Barboza; 
> Palmer Dabbelt; Alistair Francis; Weiwei Li; Liu Zhiwei; Chao Liu
> Subject: [PATCH v9 05/10] riscv: add RPMI system reset service
>
> Add a QEMU implementation of the RPMI System Reset service group.
>
> The service advertises shutdown and cold reboot reset types, validates
> guest requests, and dispatches accepted requests through the machine
> reset and shutdown callbacks. This lets firmware use RPMI reset commands
> while keeping the board-specific reset policy in the RISC-V virt machine.
>
> Signed-off-by: Subrahmanya Lingappa <[email protected]>
> Reviewed-by: Daniel Henrique Barboza <[email protected]>
> ---
>  hw/misc/meson.build           |   1 +
>  hw/misc/riscv_rpmi.c          |  70 +++++++++++-
>  hw/misc/riscv_rpmi_internal.h |  12 +-
>  hw/misc/riscv_rpmi_sysreset.c | 206 ++++++++++++++++++++++++++++++++++
>  hw/riscv/virt.c               |  51 ++++++++-
>  include/hw/misc/riscv_rpmi.h  |  15 +--
>  include/hw/riscv/rpmi-fdt.h   |  11 ++
>  7 files changed, 349 insertions(+), 17 deletions(-)
>  create mode 100644 hw/misc/riscv_rpmi_sysreset.c
>
> diff --git a/hw/misc/meson.build b/hw/misc/meson.build
> index fb761f94b3..f8a317b8f6 100644
> --- a/hw/misc/meson.build
> +++ b/hw/misc/meson.build
> @@ -173,4 +173,5 @@ system_ss.add(when: 'CONFIG_LASI', if_true: 
> files('lasi.c'))
>  system_ss.add(when: 'CONFIG_AXIADO_CLK', if_true: files('axiado_clk.c'))
>  system_ss.add(when: 'CONFIG_RISCV_RPMI', if_true: [files(
>    'riscv_rpmi.c',
> +  'riscv_rpmi_sysreset.c',
>  ), librpmi], if_false: files('riscv_rpmi-stub.c'))
> diff --git a/hw/misc/riscv_rpmi.c b/hw/misc/riscv_rpmi.c
> index 8598a3f133..97517766e9 100644
> --- a/hw/misc/riscv_rpmi.c
> +++ b/hw/misc/riscv_rpmi.c
> @@ -171,10 +171,37 @@ static bool 
> riscv_rpmi_transport_indices_valid(RiscvRpmiState *s)
>                                            s->a2p_req_size);
>  }
>
> +typedef struct RiscvRpmiServiceOps {
> +    uint32_t service_group;
> +    bool (*add)(RiscvRpmiState *s, Error **errp);
> +    void (*remove)(RiscvRpmiState *s);
> +} RiscvRpmiServiceOps;
> +
> +static const RiscvRpmiServiceOps riscv_rpmi_service_ops[] = {
> +    {
> +        .service_group = RISCV_RPMI_SRVGRP_SYSTEM_RESET,
> +        .add = riscv_rpmi_sysreset_add,
> +        .remove = riscv_rpmi_sysreset_remove,
> +    },
> +};
> +
> +static const RiscvRpmiServiceOps *riscv_rpmi_service_ops_by_group(
> +    uint32_t service_group)
> +{
> +    for (uint32_t i = 0; i < ARRAY_SIZE(riscv_rpmi_service_ops); i++) {
> +        if (riscv_rpmi_service_ops[i].service_group == service_group) {
> +            return &riscv_rpmi_service_ops[i];
> +        }
> +    }
> +
> +    return NULL;
> +}
> +
>  static void riscv_rpmi_configure_base(RiscvRpmiState *s,
>                                        const RiscvRpmiConfig *cfg)
>  {
>      s->platform_info = g_strdup(cfg->platform_info);
> +    s->machine_ops = cfg->machine_ops;
>      s->services = cfg->services;
>      s->service_count = cfg->service_count;
>
> @@ -211,7 +238,9 @@ static void riscv_rpmi_reset_hold(Object *obj, ResetType 
> type)
>
>  static void riscv_rpmi_cleanup(RiscvRpmiState *s)
>  {
> -
> +    for (uint32_t i = ARRAY_SIZE(riscv_rpmi_service_ops); i > 0; i--) {
> +        riscv_rpmi_service_ops[i - 1].remove(s);
> +    }
>
>      if (s->context) {
>          rpmi_context_destroy(s->context);
> @@ -234,12 +263,12 @@ static void riscv_rpmi_cleanup(RiscvRpmiState *s)
>      }
>  }
>
> -bool riscv_rpmi_service_enabled(RiscvRpmiState *s, RiscvRpmiServiceKind kind)
> +bool riscv_rpmi_service_enabled(RiscvRpmiState *s, uint32_t service_group)
>  {
>      uint32_t i;
>
>      for (i = 0; i < s->service_count; i++) {
> -        if (s->services[i].kind == kind) {
> +        if (s->services[i].service_group == service_group) {
>              return true;
>          }
>      }
> @@ -247,6 +276,30 @@ bool riscv_rpmi_service_enabled(RiscvRpmiState *s, 
> RiscvRpmiServiceKind kind)
>      return false;
>  }
>
> +bool riscv_rpmi_context_add_group(RiscvRpmiState *s,
> +                                  struct rpmi_service_group *group,
> +                                  const char *name,
> +                                  Error **errp)
> +{
> +    enum rpmi_error rc;
> +
> +    rc = rpmi_context_add_group(s->context, group);
> +    if (rc != RPMI_SUCCESS) {
> +        error_setg(errp, "failed to add RPMI %s service group: %d", name, 
> rc);
> +        return false;
> +    }
> +
> +    return true;
> +}
> +
> +void riscv_rpmi_context_remove_group(RiscvRpmiState *s,
> +                                     struct rpmi_service_group *group)
> +{
> +    if (s->context && group) {
> +        rpmi_context_remove_group(s->context, group);
> +    }
> +}
> +
>  static bool riscv_rpmi_validate_config(RiscvRpmiState *s, Error **errp)
>  {
>      uint64_t queue_bytes;
> @@ -318,11 +371,16 @@ static bool riscv_rpmi_add_service_group(RiscvRpmiState 
> *s,
>                                           const RiscvRpmiServiceConfig 
> *service,
>                                           Error **errp)
>  {
> -    switch (service->kind) {
> -    default:
> -        error_setg(errp, "unsupported RPMI service kind %d", service->kind);
> +    const RiscvRpmiServiceOps *ops;
> +
> +    ops = riscv_rpmi_service_ops_by_group(service->service_group);
> +    if (!ops) {
> +        error_setg(errp, "unsupported RPMI service group %u",
> +                   service->service_group);
>          return false;
>      }
> +
> +    return ops->add(s, errp);
>  }
>
>  static bool riscv_rpmi_init_services(RiscvRpmiState *s, Error **errp)
> diff --git a/hw/misc/riscv_rpmi_internal.h b/hw/misc/riscv_rpmi_internal.h
> index c263033634..ca9838d256 100644
> --- a/hw/misc/riscv_rpmi_internal.h
> +++ b/hw/misc/riscv_rpmi_internal.h
> @@ -18,7 +18,15 @@
>  #define RPMI_PLAT_INFO "QEMU RISC-V RPMI"
>
>  extern const struct rpmi_shmem_platform_ops rpmi_shmem_qemu_ops;
> -bool riscv_rpmi_service_enabled(RiscvRpmiState *s,
> -                                RiscvRpmiServiceKind kind);
> +bool riscv_rpmi_service_enabled(RiscvRpmiState *s, uint32_t service_group);
> +bool riscv_rpmi_context_add_group(RiscvRpmiState *s,
> +                                  struct rpmi_service_group *group,
> +                                  const char *name,
> +                                  Error **errp);
> +void riscv_rpmi_context_remove_group(RiscvRpmiState *s,
> +                                     struct rpmi_service_group *group);
> +
> +bool riscv_rpmi_sysreset_add(RiscvRpmiState *s, Error **errp);
> +void riscv_rpmi_sysreset_remove(RiscvRpmiState *s);
>
>  #endif
> diff --git a/hw/misc/riscv_rpmi_sysreset.c b/hw/misc/riscv_rpmi_sysreset.c
> new file mode 100644
> index 0000000000..775eb5483f
> --- /dev/null
> +++ b/hw/misc/riscv_rpmi_sysreset.c
> @@ -0,0 +1,206 @@
> +/*
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + *
> + * RISC-V RPMI System Reset service.
> + *
> + * Copyright (c) 2026 Qualcomm Technologies, Inc.
> + * Author:
> + *  Subrahmanya Lingappa <[email protected]>
> + */
> +
> +#include "qemu/osdep.h"
> +#include "riscv_rpmi_internal.h"
> +#include "qemu/log.h"
> +#include "librpmi_env.h"
> +
> +typedef struct RiscvRpmiSysresetType {
> +    uint32_t type;
> +    void (*action)(RiscvRpmiState *s);
> +} RiscvRpmiSysresetType;
> +
> +typedef struct RiscvRpmiSysresetGroup {
> +    struct rpmi_service_group group;
> +    struct rpmi_service services[RPMI_SYSRST_SRV_ID_MAX];
> +    RiscvRpmiState *rpmi;
> +} RiscvRpmiSysresetGroup;
> +
> +static void riscv_rpmi_sysreset_reboot(RiscvRpmiState *s)
> +{
> +    const RiscvRpmiMachineOps *ops = s->machine_ops;
> +
> +    if (ops && ops->system_reset) {
> +        ops->system_reset();
> +    }
> +}
> +
> +static void riscv_rpmi_sysreset_shutdown(RiscvRpmiState *s)
> +{
> +    const RiscvRpmiMachineOps *ops = s->machine_ops;
> +
> +    if (ops && ops->system_shutdown) {
> +        ops->system_shutdown();
> +    }
> +}
> +
> +static const RiscvRpmiSysresetType riscv_rpmi_sysreset_types[] = {
> +    {
> +        .type = RPMI_SYSRST_TYPE_SHUTDOWN,
> +        .action = riscv_rpmi_sysreset_shutdown,
> +    }, {
> +        .type = RPMI_SYSRST_TYPE_COLD_REBOOT,
> +        .action = riscv_rpmi_sysreset_reboot,
> +    },
> +};
> +
> +static const RiscvRpmiSysresetType *riscv_rpmi_sysreset_type_by_id(
> +    uint32_t reset_type)
> +{
> +    for (uint32_t index = 0; index < ARRAY_SIZE(riscv_rpmi_sysreset_types);
> +         index++) {
> +        if (riscv_rpmi_sysreset_types[index].type == reset_type) {
> +            return &riscv_rpmi_sysreset_types[index];
> +        }
> +    }
> +
> +    return NULL;
> +}
> +
> +static void riscv_rpmi_do_system_reset(RiscvRpmiState *s,
> +                                       rpmi_uint32_t reset_type)
> +{
> +    const RiscvRpmiSysresetType *type;
> +
> +    type = riscv_rpmi_sysreset_type_by_id(reset_type);
> +    if (type) {
> +        type->action(s);
> +        return;
> +    }
> +
> +    qemu_log_mask(LOG_GUEST_ERROR, "%s: unsupported reset type %u\n",
> +                  __func__, reset_type);
> +}
> +
> +static enum rpmi_error riscv_rpmi_sysreset_get_attributes(
> +    struct rpmi_service_group *group, struct rpmi_service *service,
> +    struct rpmi_transport *trans, rpmi_uint16_t request_data_len,
> +    const rpmi_uint8_t *request_data, rpmi_uint16_t *response_data_len,
> +    rpmi_uint8_t *response_data)
> +{
> +    uint32_t reset_type = ldl_le_p(request_data);
> +    uint32_t *resp = (uint32_t *)response_data;
> +
> +    *response_data_len = 2 * sizeof(*resp);
> +    stl_le_p(&resp[0], RPMI_SUCCESS);
> +    stl_le_p(&resp[1], riscv_rpmi_sysreset_type_by_id(reset_type) ?
> +             RPMI_SYSRST_ATTRS_FLAGS_RESETTYPE : 0);
> +
> +    return RPMI_SUCCESS;
> +}
> +
> +static enum rpmi_error riscv_rpmi_sysreset_do_reset(
> +    struct rpmi_service_group *group, struct rpmi_service *service,
> +    struct rpmi_transport *trans, rpmi_uint16_t request_data_len,
> +    const rpmi_uint8_t *request_data, rpmi_uint16_t *response_data_len,
> +    rpmi_uint8_t *response_data)
> +{
> +    RiscvRpmiSysresetGroup *sysreset = group->priv;
> +    uint32_t reset_type = ldl_le_p(request_data);
> +    uint32_t *resp = (uint32_t *)response_data;
> +
> +    *response_data_len = sizeof(*resp);
> +
> +    if (!riscv_rpmi_sysreset_type_by_id(reset_type)) {
> +        stl_le_p(resp, (uint32_t)RPMI_ERR_INVALID_PARAM);
> +        return RPMI_SUCCESS;
> +    }
> +
> +    stl_le_p(resp, RPMI_SUCCESS);
> +    riscv_rpmi_do_system_reset(sysreset->rpmi, reset_type);
> +    return RPMI_SUCCESS;
> +}
> +
> +static const struct rpmi_service riscv_rpmi_sysreset_services[] = {
> +    [RPMI_SYSRST_SRV_ENABLE_NOTIFICATION] = {
> +        .service_id = RPMI_SYSRST_SRV_ENABLE_NOTIFICATION,
> +        .min_a2p_request_datalen = 8,
> +    },
> +    [RPMI_SYSRST_SRV_GET_ATTRIBUTES] = {
> +        .service_id = RPMI_SYSRST_SRV_GET_ATTRIBUTES,
> +        .min_a2p_request_datalen = 4,
> +        .process_a2p_request = riscv_rpmi_sysreset_get_attributes,
> +    },
> +    [RPMI_SYSRST_SRV_SYSTEM_RESET] = {
> +        .service_id = RPMI_SYSRST_SRV_SYSTEM_RESET,
> +        .min_a2p_request_datalen = 4,
> +        .process_a2p_request = riscv_rpmi_sysreset_do_reset,
> +    },
> +};
> +
> +static struct rpmi_service_group *riscv_rpmi_sysreset_create(RiscvRpmiState 
> *s)
> +{
> +    RiscvRpmiSysresetGroup *sysreset;
> +    struct rpmi_service_group *group;
> +
> +    sysreset = g_new0(RiscvRpmiSysresetGroup, 1);
> +    sysreset->rpmi = s;
> +    memcpy(sysreset->services, riscv_rpmi_sysreset_services,
> +           sizeof(riscv_rpmi_sysreset_services));
> +
> +    group = &sysreset->group;
> +    group->name = "sysreset";
> +    group->servicegroup_id = RPMI_SRVGRP_SYSTEM_RESET;
> +    group->max_service_id = RPMI_SYSRST_SRV_ID_MAX;
> +    group->servicegroup_version =
> +        RPMI_BASE_VERSION(RPMI_SPEC_VERSION_MAJOR, RPMI_SPEC_VERSION_MINOR);
> +    group->privilege_level_bitmap = RPMI_PRIVILEGE_M_MODE_MASK;
> +    group->services = sysreset->services;
> +    group->lock = rpmi_env_alloc_lock();
> +    group->priv = sysreset;
> +
> +    return group;
> +}
> +
> +static void riscv_rpmi_sysreset_destroy(struct rpmi_service_group *group)
> +{
> +    if (!group) {
> +        return;
> +    }
> +
> +    rpmi_env_free_lock(group->lock);
> +    g_free(group->priv);
> +}
> +
> +bool riscv_rpmi_sysreset_add(RiscvRpmiState *s, Error **errp)
> +{
> +    struct rpmi_service_group *group;
> +
> +    if (s->sysreset_group) {
> +        error_setg(errp, "duplicate RPMI sysreset service descriptor");
> +        return false;
> +    }
> +
> +    group = riscv_rpmi_sysreset_create(s);
> +    if (!group) {
> +        error_setg(errp, "failed to create RPMI sysreset service group");
> +        return false;
> +    }
> +
> +    if (!riscv_rpmi_context_add_group(s, group, "sysreset", errp)) {
> +        riscv_rpmi_sysreset_destroy(group);
> +        return false;
> +    }
> +
> +    s->sysreset_group = group;
> +    return true;
> +}
> +
> +void riscv_rpmi_sysreset_remove(RiscvRpmiState *s)
> +{
> +    if (!s->sysreset_group) {
> +        return;
> +    }
> +
> +    riscv_rpmi_context_remove_group(s, s->sysreset_group);
> +    riscv_rpmi_sysreset_destroy(s->sysreset_group);
> +    s->sysreset_group = NULL;
> +}
> diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> index fa0e0db0c3..1a69fd7cfe 100644
> --- a/hw/riscv/virt.c
> +++ b/hw/riscv/virt.c
> @@ -767,7 +767,8 @@ static void create_fdt_pcie(RISCVVirtState *s,
>      create_pcie_irq_map(s, ms->fdt, name, irq_pcie_phandle);
>  }
>
> -static void create_fdt_reset(RISCVVirtState *s, uint32_t *phandle)
> +static void create_fdt_reset(RISCVVirtState *s, uint32_t *phandle,
> +                             bool use_syscon_reset)
>  {
>      char *name;
>      uint32_t test_phandle;
> @@ -791,6 +792,14 @@ static void create_fdt_reset(RISCVVirtState *s, uint32_t 
> *phandle)
>      test_phandle = qemu_fdt_get_phandle(ms->fdt, name);
>      g_free(name);
>
> +    /*
> +     * When RPMI is enabled, advertise reset and shutdown through RPMI so
> +     * firmware routes these operations through the RPMI system reset 
> service.
> +     */
> +    if (!use_syscon_reset) {
> +        return;
> +    }
> +
>      name = g_strdup_printf("/reboot");
>      qemu_fdt_add_subnode(ms->fdt, name);
>      qemu_fdt_setprop_string(ms->fdt, name, "compatible", "syscon-reboot");
> @@ -980,6 +989,34 @@ static void create_fdt_iommu(RISCVVirtState *s, uint16_t 
> bdf)
>  }
>
>
> +static const RiscvRpmiServiceConfig virt_rpmi_services[] = {
> +    {
> +        .node_name = "sysreset",
> +        .compatible = "riscv,rpmi-system-reset",
> +        .service_group = RISCV_RPMI_SRVGRP_SYSTEM_RESET,
> +    },
> +};
> +
> +static uint32_t virt_rpmi_service_count(RISCVVirtState *s)
> +{
> +    return ARRAY_SIZE(virt_rpmi_services);
> +}
> +
> +static void virt_rpmi_system_reset(void)
> +{
> +    qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
> +}
> +
> +static void virt_rpmi_system_shutdown(void)
> +{
> +    qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
> +}
> +
> +static const RiscvRpmiMachineOps virt_rpmi_machine_ops = {
> +    .system_reset = virt_rpmi_system_reset,
> +    .system_shutdown = virt_rpmi_system_shutdown,
> +};
> +
>  static RiscvRpmiConfig virt_rpmi_config(RISCVVirtState *s,
>                                          const uint32_t *hart_ids,
>                                          uint32_t hart_count)
> @@ -991,8 +1028,11 @@ static RiscvRpmiConfig virt_rpmi_config(RISCVVirtState 
> *s,
>          .a2p_req_size = VIRT_RPMI_A2P_REQ_SIZE,
>          .p2a_req_size = VIRT_RPMI_P2A_REQ_SIZE,
>          .platform_info = "QEMU RISC-V virt RPMI",
> +        .machine_ops = &virt_rpmi_machine_ops,
>          .hart_ids = hart_ids,
>          .hart_count = hart_count,
> +        .services = virt_rpmi_services,
> +        .service_count = virt_rpmi_service_count(s),
>      };
>  }
>
> @@ -1001,6 +1041,7 @@ static void create_fdt_rpmi(RISCVVirtState *s, uint32_t 
> *phandle,
>  {
>      RiscvRpmiConfig rpmi_cfg = virt_rpmi_config(s, NULL, 0);
>      uint32_t rpmi_mbox_handle;
> +    uint32_t i;
>      RiscvRpmiFdtMboxConfig cfg = {
>          .shmem_base = rpmi_cfg.shmem_base,
>          .doorbell_base = rpmi_cfg.doorbell_base,
> @@ -1011,6 +1052,12 @@ static void create_fdt_rpmi(RISCVVirtState *s, 
> uint32_t *phandle,
>
>      riscv_rpmi_fdt_add_mbox(MACHINE(s)->fdt, &cfg, phandle,
>                              &rpmi_mbox_handle);
> +
> +    for (i = 0; i < rpmi_cfg.service_count; i++) {
> +        riscv_rpmi_fdt_add_service_node(MACHINE(s)->fdt, rpmi_cfg.shmem_base,
> +                                        &rpmi_cfg.services[i],
> +                                        rpmi_mbox_handle);
> +    }
>  }
>
>  static void finalize_fdt(RISCVVirtState *s)
> @@ -1036,7 +1083,7 @@ static void finalize_fdt(RISCVVirtState *s)
>          create_fdt_rpmi(s, &phandle, msi_pcie_phandle);
>      }
>
> -    create_fdt_reset(s, &phandle);
> +    create_fdt_reset(s, &phandle, !s->have_rpmi);
>
>      create_fdt_uart(s, irq_mmio_phandle);
>
> diff --git a/include/hw/misc/riscv_rpmi.h b/include/hw/misc/riscv_rpmi.h
> index f5fd1ee8c7..a9ccc950e9 100644
> --- a/include/hw/misc/riscv_rpmi.h
> +++ b/include/hw/misc/riscv_rpmi.h
> @@ -27,6 +27,7 @@
>  #define VIRT_RPMI_A2P_REQ_SIZE (16 * RPMI_QUEUE_SLOT_SIZE)
>  #define VIRT_RPMI_P2A_REQ_SIZE 0
>
> +#define RISCV_RPMI_SRVGRP_SYSTEM_RESET   3
>
> Can't we replace the use of these macros with the enum rpmi_servicegroup_id 
> for service_group field in struct RiscvRpmiServiceOps so that there is no 
> need to keep adding such #define's for various service groups which 
> essentially have the same values as that in enum rpmi_servicegroup_id for 
> that group?

yes  local defines duplicate enum rpmi_servicegroup_id, and  the next
version will use librpmi’s enum/values directly.

Thanks
Subbu

>
>  #define TYPE_RISCV_RPMI "riscv-rpmi"
>  OBJECT_DECLARE_SIMPLE_TYPE(RiscvRpmiState, RISCV_RPMI)
> @@ -36,12 +37,11 @@ struct rpmi_service_group;
>  struct rpmi_shmem;
>  struct rpmi_transport;
>
> -typedef enum RiscvRpmiServiceKind {
> -    RISCV_RPMI_SERVICE_INVALID = 0,
> -} RiscvRpmiServiceKind;
> -
> +typedef struct RiscvRpmiMachineOps {
> +    void (*system_reset)(void);
> +    void (*system_shutdown)(void);
> +} RiscvRpmiMachineOps;
>  typedef struct RiscvRpmiServiceConfig {
> -    RiscvRpmiServiceKind kind;
>      const char *node_name;
>      const char *compatible;
>      uint32_t service_group;
> @@ -56,7 +56,7 @@ typedef struct RiscvRpmiConfig {
>      uint32_t a2p_req_size;
>      uint32_t p2a_req_size;
>      const char *platform_info;
> -
> +    const RiscvRpmiMachineOps *machine_ops;
>      const uint32_t *hart_ids;
>      uint32_t hart_count;
>      const RiscvRpmiServiceConfig *services;
> @@ -73,7 +73,8 @@ struct RiscvRpmiState {
>      uint32_t a2p_req_size;
>      uint32_t p2a_req_size;
>      char *platform_info;
> -
> +    const RiscvRpmiMachineOps *machine_ops;
> +    struct rpmi_service_group *sysreset_group;
>      uint32_t *hart_ids;
>      uint32_t hart_count;
>      const RiscvRpmiServiceConfig *services;
> diff --git a/include/hw/riscv/rpmi-fdt.h b/include/hw/riscv/rpmi-fdt.h
> index b157bda1d1..60c5df75d0 100644
> --- a/include/hw/riscv/rpmi-fdt.h
> +++ b/include/hw/riscv/rpmi-fdt.h
> @@ -26,5 +26,16 @@ void riscv_rpmi_fdt_add_mbox(void *fdt,
>                               const RiscvRpmiFdtMboxConfig *cfg,
>                               uint32_t *phandle,
>                               uint32_t *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);
> +
> +void riscv_rpmi_fdt_add_service_node(void *fdt, hwaddr shmem_base,
> +                                     const RiscvRpmiServiceConfig *service,
> +                                     uint32_t mbox_handle);
>
>  #endif
> --
> 2.43.0
>
>

Reply via email to