aboutsummaryrefslogtreecommitdiff
path: root/arch/riscv64/kernel/cpu.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/riscv64/kernel/cpu.c')
-rw-r--r--arch/riscv64/kernel/cpu.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/arch/riscv64/kernel/cpu.c b/arch/riscv64/kernel/cpu.c
index d6d07ec..60140e6 100644
--- a/arch/riscv64/kernel/cpu.c
+++ b/arch/riscv64/kernel/cpu.c
@@ -11,6 +11,8 @@
#include <arch/cpu.h>
+#include "sbi.h"
+
/** Keeps track of initialized cpus. */
static atomic_long cpus = 0;
@@ -40,3 +42,35 @@ struct tcb *cur_tcb()
register struct tcb *t __asm__ ("tp");
return t;
}
+
+/**
+ * Helper for cpu_send_ipi() to convert linear \p cpu_id to SBI \c
+ * hart_mask_base.
+ *
+ * @param cpu_id CPU id to convert.
+ * @return Corresponding \c hart_mask_base.
+ */
+static long __cpu_offset(id_t cpu_id)
+{
+ return cpu_id / (sizeof(long) * 8);
+}
+
+/**
+ * Helper for cpu_send_ipi() to convert linear \p cpu_id to SBI \c
+ * hart_mask.
+ *
+ * @param cpu_id CPU id to convert.
+ * @param offset Offset from __cpu_offset().
+ * @return Corresponding \c hart_mask.
+ */
+static long __cpu_mask(id_t cpu_id, long offset)
+{
+ return cpu_id - offset * sizeof(long) * 8;
+}
+
+void cpu_send_ipi(id_t cpu_id)
+{
+ long offset = __cpu_offset(cpu_id);
+ long mask = __cpu_mask(cpu_id, offset);
+ sbi_send_ipi(mask, offset);
+}