diff options
author | Atish Patra <atish.patra@wdc.com> | 2019-11-24 23:33:47 -0800 |
---|---|---|
committer | Anup Patel <anup@brainfault.org> | 2019-12-23 09:12:13 +0530 |
commit | 9777aeef41a613b3c27056a695d4d6007760b3a8 (patch) | |
tree | a50c68b24fa6caf5932f0b96aafaf2509cc6be62 /lib/sbi/sbi_ipi.c | |
parent | 109266397a6d8a37f4450c5ff80ea3737a6acd3e (diff) |
lib: Add IPI extension in SBI
This patch adds new IPI extension which replaces ipi related
v0.1 extensions. This also adds a new API for ipi sending as trap
handling is not necessary in v0.2 SBI IPI related extensions.
It also modifies the IPI sending code which now accepts hart mask as a value
instead of S-mode virtual address. Thus, the caller should set it to exact hart
mask value everytime.
Signed-off-by: Atish Patra <atish.patra@wdc.com>
Reviewed-by: Anup Patel <anup.patel@wdc.com>
Diffstat (limited to 'lib/sbi/sbi_ipi.c')
-rw-r--r-- | lib/sbi/sbi_ipi.c | 34 |
1 files changed, 24 insertions, 10 deletions
diff --git a/lib/sbi/sbi_ipi.c b/lib/sbi/sbi_ipi.c index 8dc78a5..c235927 100644 --- a/lib/sbi/sbi_ipi.c +++ b/lib/sbi/sbi_ipi.c @@ -11,13 +11,13 @@ #include <sbi/riscv_asm.h> #include <sbi/riscv_atomic.h> #include <sbi/riscv_barrier.h> +#include <sbi/sbi_bitops.h> #include <sbi/sbi_error.h> #include <sbi/sbi_hart.h> #include <sbi/sbi_ipi.h> #include <sbi/sbi_platform.h> #include <sbi/sbi_tlb.h> #include <sbi/sbi_trap.h> -#include <sbi/sbi_unpriv.h> static unsigned long ipi_data_off; @@ -53,20 +53,34 @@ static int sbi_ipi_send(struct sbi_scratch *scratch, u32 hartid, u32 event, return 0; } -int sbi_ipi_send_many(struct sbi_scratch *scratch, - struct sbi_trap_info *uptrap, - ulong *pmask, u32 event, void *data) +/** + * As this this function only handlers scalar values of hart mask, it must be + * set to all online harts if the intention is to send IPIs to all the harts. + * If hmask is zero, no IPIs will be sent. + */ +int sbi_ipi_send_many(struct sbi_scratch *scratch, ulong hmask, ulong hbase, + u32 event, void *data) { ulong i, m; ulong mask = sbi_hart_available_mask(); + ulong tempmask; u32 hartid = sbi_current_hartid(); + unsigned long last_bit = __fls(mask); + + if (hbase > last_bit) + /* hart base is not available */ + return SBI_EINVAL; + /** + * FIXME: This check is valid only ULONG size. This is oka for now as + * avaialble hart mask can support upto ULONG size only. + */ + tempmask = hmask << hbase; + tempmask = ~mask & tempmask; + if (tempmask) + /* at least one of the hart in hmask is not available */ + return SBI_EINVAL; - if (pmask) { - mask &= sbi_load_ulong(pmask, scratch, uptrap); - if (uptrap->cause) - return SBI_ETRAP; - } - + mask &= (hmask << hbase); /* Send IPIs to every other hart on the set */ for (i = 0, m = mask; m; i++, m >>= 1) if ((m & 1UL) && (i != hartid)) |