aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2022-11-09 16:27:23 +0200
committerKimplul <kimi.h.kuparinen@gmail.com>2022-11-09 17:27:11 +0200
commita3e45d5dcaf1bf3a9e684b5fcc301413ec994a9b (patch)
treeae319c8f389e7ca39bbdd4b114655f8604563305 /arch
parent2b5533aefef026fe7bada314ebdb2651b809979a (diff)
downloadkmi-a3e45d5dcaf1bf3a9e684b5fcc301413ec994a9b.tar.gz
kmi-a3e45d5dcaf1bf3a9e684b5fcc301413ec994a9b.zip
add basic IPI structure
Diffstat (limited to 'arch')
-rw-r--r--arch/riscv64/kernel/cpu.c34
-rw-r--r--arch/riscv64/kernel/entry.S14
-rw-r--r--arch/riscv64/kernel/proc.c23
-rw-r--r--arch/riscv64/kernel/sbi.h20
4 files changed, 83 insertions, 8 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);
+}
diff --git a/arch/riscv64/kernel/entry.S b/arch/riscv64/kernel/entry.S
index db662bb..355cd3d 100644
--- a/arch/riscv64/kernel/entry.S
+++ b/arch/riscv64/kernel/entry.S
@@ -77,17 +77,14 @@ _save_context:
handle_exception:
li t0, EXC_SYSCALL
- /* system exceptions fall through, syscalls jump */
+ /* system exceptions fall through, syscalls and ipis jump */
/* temp, at some point we want to handle system exceptions as well */
- beq s4, t0, handle_syscall
+ beq s4, t0, handle_dispatch
j restore_all
-handle_syscall:
- /* add 4 (size of ecall) to EPC to avoid running the same instruction
- * twice */
- csrr s0, CSR_SEPC
- addi s0, s0, 4
+handle_dispatch:
/* store execution continuation point */
+ csrr s0, CSR_SEPC
sr s0, 0(tp)
/* allocate space for sys_ret structure on stack and shift argument
* registers down one to make room for the pointer to this structure */
@@ -99,7 +96,8 @@ handle_syscall:
mv a2, a1
mv a1, a0
mv a0, sp
- jal syscall_dispatch
+ /* jump to C */
+ jal dispatch
/* move structure from stack into registers. */
lr a0, offsetof_s(sp)
lr a1, offsetof_ar0(sp)
diff --git a/arch/riscv64/kernel/proc.c b/arch/riscv64/kernel/proc.c
index ed8bf93..d2b8dfb 100644
--- a/arch/riscv64/kernel/proc.c
+++ b/arch/riscv64/kernel/proc.c
@@ -8,6 +8,7 @@
#include <apos/tcb.h>
#include <apos/elf.h>
+#include <apos/string.h>
#include <arch/proc.h>
@@ -54,3 +55,25 @@ void set_thread(struct tcb *t)
r->sp = (long)t->thread_stack_top;
r->tp = (long)t->thread_storage;
}
+
+void save_regs(struct tcb *t, void *p)
+{
+ struct riscv_regs *r = (struct riscv_regs *)(t++);
+ memcpy(p, r, sizeof(*r));
+}
+
+void load_regs(void *p, struct tcb *t)
+{
+ struct riscv_regs *r = (struct riscv_regs *)(t++);
+ memcpy(r, p, sizeof(*r));
+}
+
+void adjust_ipi(struct tcb *t)
+{
+ UNUSED(t);
+}
+
+void adjust_syscall(struct tcb *t)
+{
+ t->exec += 4;
+}
diff --git a/arch/riscv64/kernel/sbi.h b/arch/riscv64/kernel/sbi.h
index 2add35f..19cc595 100644
--- a/arch/riscv64/kernel/sbi.h
+++ b/arch/riscv64/kernel/sbi.h
@@ -106,4 +106,24 @@ static inline struct sbiret sbi_system_reset(uint32_t reset_type,
0);
}
+/** Supervisor IPI extension ID. */
+#define EID_sPI 0x735049
+
+/** Supervisor IPI function ID. */
+#define FID_IPI 0
+
+/**
+ * Send IPI.
+ *
+ * @param hart_mask Bitmap of harts to send IPI to.
+ * @param hart_mask_base Base of \p hart_mask.
+ * @return SBI call return. \see sbiret.
+ */
+static inline struct sbiret sbi_send_ipi(unsigned long hart_mask,
+ unsigned long hart_mask_base)
+{
+ return sbi_ecall(EID_sPI, FID_IPI, hart_mask, hart_mask_base, 0, 0, 0,
+ 0);
+}
+
#endif /* APOS_RISCV_SBI_H */