mirror of
https://github.com/riscv-software-src/opensbi.git
synced 2025-10-09 10:02:19 +01:00

A platform can have multiple IPI devices (such as ACLINT MSWI, AIA IMSIC, etc). Currently, OpenSBI rely on platform calling the sbi_ipi_set_device() function in correct order and prefer the first avaiable IPI device which is fragile. Instead of the above, introduce IPI device rating and prefer the highest rated IPI device. This further allows extending the sbi_ipi_raw_clear() to clear all available IPI devices. Signed-off-by: Anup Patel <apatel@ventanamicro.com> Tested-by: Nick Hu <nick.hu@sifive.com> Link: https://lore.kernel.org/r/20250904052410.546818-2-apatel@ventanamicro.com Signed-off-by: Anup Patel <anup@brainfault.org>
104 lines
2.4 KiB
C
104 lines
2.4 KiB
C
/*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*
|
|
* Copyright (c) 2019 Western Digital Corporation or its affiliates.
|
|
*
|
|
* Authors:
|
|
* Anup Patel <anup.patel@wdc.com>
|
|
*/
|
|
|
|
#ifndef __SBI_IPI_H__
|
|
#define __SBI_IPI_H__
|
|
|
|
#include <sbi/sbi_types.h>
|
|
|
|
/* clang-format off */
|
|
|
|
#define SBI_IPI_EVENT_MAX (8 * __SIZEOF_LONG__)
|
|
|
|
/* clang-format on */
|
|
|
|
/** IPI hardware device */
|
|
struct sbi_ipi_device {
|
|
/** Name of the IPI device */
|
|
char name[32];
|
|
|
|
/** Ratings of the IPI device (higher is better) */
|
|
unsigned long rating;
|
|
|
|
/** Send IPI to a target HART index */
|
|
void (*ipi_send)(u32 hart_index);
|
|
|
|
/** Clear IPI for the current hart */
|
|
void (*ipi_clear)(void);
|
|
};
|
|
|
|
enum sbi_ipi_update_type {
|
|
SBI_IPI_UPDATE_SUCCESS,
|
|
SBI_IPI_UPDATE_BREAK,
|
|
SBI_IPI_UPDATE_RETRY,
|
|
};
|
|
|
|
struct sbi_scratch;
|
|
|
|
/** IPI event operations or callbacks */
|
|
struct sbi_ipi_event_ops {
|
|
/** Name of the IPI event operations */
|
|
char name[32];
|
|
|
|
/**
|
|
* Update callback to save/enqueue data for remote HART
|
|
* Note: This is an optional callback and it is called just before
|
|
* triggering IPI to remote HART.
|
|
* @return < 0, error or failure
|
|
* @return SBI_IPI_UPDATE_SUCCESS, success
|
|
* @return SBI_IPI_UPDATE_BREAK, break IPI, done on local hart
|
|
* @return SBI_IPI_UPDATE_RETRY, need retry
|
|
*/
|
|
int (* update)(struct sbi_scratch *scratch,
|
|
struct sbi_scratch *remote_scratch,
|
|
u32 remote_hartindex, void *data);
|
|
|
|
/**
|
|
* Sync callback to wait for remote HART
|
|
* Note: This is an optional callback and it is called just after
|
|
* triggering IPI to remote HART.
|
|
*/
|
|
void (* sync)(struct sbi_scratch *scratch);
|
|
|
|
/**
|
|
* Process callback to handle IPI event
|
|
* Note: This is a mandatory callback and it is called on the
|
|
* remote HART after IPI is triggered.
|
|
*/
|
|
void (* process)(struct sbi_scratch *scratch);
|
|
};
|
|
|
|
int sbi_ipi_send_many(ulong hmask, ulong hbase, u32 event, void *data);
|
|
|
|
int sbi_ipi_event_create(const struct sbi_ipi_event_ops *ops);
|
|
|
|
void sbi_ipi_event_destroy(u32 event);
|
|
|
|
int sbi_ipi_send_smode(ulong hmask, ulong hbase);
|
|
|
|
void sbi_ipi_clear_smode(void);
|
|
|
|
int sbi_ipi_send_halt(ulong hmask, ulong hbase);
|
|
|
|
void sbi_ipi_process(void);
|
|
|
|
int sbi_ipi_raw_send(u32 hartindex);
|
|
|
|
void sbi_ipi_raw_clear(bool all_devices);
|
|
|
|
const struct sbi_ipi_device *sbi_ipi_get_device(void);
|
|
|
|
void sbi_ipi_add_device(const struct sbi_ipi_device *dev);
|
|
|
|
int sbi_ipi_init(struct sbi_scratch *scratch, bool cold_boot);
|
|
|
|
void sbi_ipi_exit(struct sbi_scratch *scratch);
|
|
|
|
#endif
|