diff options
| author | Kimplul <kimi.h.kuparinen@gmail.com> | 2022-11-09 16:27:23 +0200 |
|---|---|---|
| committer | Kimplul <kimi.h.kuparinen@gmail.com> | 2022-11-09 17:27:11 +0200 |
| commit | a3e45d5dcaf1bf3a9e684b5fcc301413ec994a9b (patch) | |
| tree | ae319c8f389e7ca39bbdd4b114655f8604563305 /arch | |
| parent | 2b5533aefef026fe7bada314ebdb2651b809979a (diff) | |
| download | kmi-a3e45d5dcaf1bf3a9e684b5fcc301413ec994a9b.tar.gz kmi-a3e45d5dcaf1bf3a9e684b5fcc301413ec994a9b.zip | |
add basic IPI structure
Diffstat (limited to 'arch')
| -rw-r--r-- | arch/riscv64/kernel/cpu.c | 34 | ||||
| -rw-r--r-- | arch/riscv64/kernel/entry.S | 14 | ||||
| -rw-r--r-- | arch/riscv64/kernel/proc.c | 23 | ||||
| -rw-r--r-- | arch/riscv64/kernel/sbi.h | 20 |
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 */ |
