diff options
| author | Kimplul <kimi.h.kuparinen@gmail.com> | 2024-06-01 16:42:55 +0300 |
|---|---|---|
| committer | Kimplul <kimi.h.kuparinen@gmail.com> | 2024-06-01 16:42:55 +0300 |
| commit | 7a1c7ed1b1c30ba4c668194a955fb414e471bade (patch) | |
| tree | 2f49f04e455f004af640918abfcd6f91ce6a1323 | |
| parent | e8f80bae97a835b6b256228d4bbeaf48ae16dcbb (diff) | |
| download | kmi-7a1c7ed1b1c30ba4c668194a955fb414e471bade.tar.gz kmi-7a1c7ed1b1c30ba4c668194a955fb414e471bade.zip | |
add sleep syscall
+ Sets the current core to sleep
| -rw-r--r-- | arch/riscv64/kernel/power.c | 6 | ||||
| -rw-r--r-- | arch/riscv64/kernel/sbi.h | 6 | ||||
| -rw-r--r-- | include/kmi/power.h | 8 | ||||
| -rw-r--r-- | include/kmi/syscalls.h | 3 | ||||
| -rw-r--r-- | include/kmi/uapi.h | 5 | ||||
| -rw-r--r-- | src/uapi/conf.c | 10 | ||||
| -rw-r--r-- | src/uapi/dispatch.c | 1 |
7 files changed, 38 insertions, 1 deletions
diff --git a/arch/riscv64/kernel/power.c b/arch/riscv64/kernel/power.c index 49fc9c5..21e4957 100644 --- a/arch/riscv64/kernel/power.c +++ b/arch/riscv64/kernel/power.c @@ -49,3 +49,9 @@ stat_t poweroff(enum poweroff_type type) return ERR_INVAL; } + +stat_t sleep() +{ + sbi_hart_stop(); + return ERR_MISC; +} diff --git a/arch/riscv64/kernel/sbi.h b/arch/riscv64/kernel/sbi.h index fe75c85..d536f58 100644 --- a/arch/riscv64/kernel/sbi.h +++ b/arch/riscv64/kernel/sbi.h @@ -149,6 +149,12 @@ static inline struct sbiret sbi_hart_start(unsigned long hartid, 0, 0, 0); } +#define FID_HSM_STOP 1 +static inline struct sbiret sbi_hart_stop() +{ + return sbi_ecall(EID_HSM, FID_HSM_STOP, 0, 0, 0, 0, 0, 0); +} + /** Hart status function ID. */ #define FID_HSM_STATUS 2 diff --git a/include/kmi/power.h b/include/kmi/power.h index d11b9d1..db00999 100644 --- a/include/kmi/power.h +++ b/include/kmi/power.h @@ -35,4 +35,12 @@ enum poweroff_type { */ stat_t poweroff(enum poweroff_type type); +/** + * Set the current core to sleep. + * + * @return Nothing on success (we should be sleeping), + * \ref ERR_MISC if sleep was not successful + */ +stat_t sleep(); + #endif diff --git a/include/kmi/syscalls.h b/include/kmi/syscalls.h index 1de4fb2..e503709 100644 --- a/include/kmi/syscalls.h +++ b/include/kmi/syscalls.h @@ -142,6 +142,9 @@ enum { /** Shutdown, reboot, etc. */ SYS_POWEROFF, + /** Set this core to sleep. */ + SYS_SLEEP, + /** Request to handle IRQ. */ SYS_IRQ_REQ, diff --git a/include/kmi/uapi.h b/include/kmi/uapi.h index 40cfae4..d1d3a38 100644 --- a/include/kmi/uapi.h +++ b/include/kmi/uapi.h @@ -764,6 +764,11 @@ SYSCALL_DECLARE3(clear_cap, tid, off, cap); SYSCALL_DECLARE1(poweroff, type); /** + * Sets the current core to sleep. Might take parameters in the future if there + * arises a need for different levels of sleep, but for now zero params. */ +SYSCALL_DECLARE0(sleep); + +/** * Request to handle IRQ. * * @param t Current tcb. diff --git a/src/uapi/conf.c b/src/uapi/conf.c index 894b98a..497aef0 100644 --- a/src/uapi/conf.c +++ b/src/uapi/conf.c @@ -108,8 +108,16 @@ SYSCALL_DEFINE1(poweroff)(struct tcb *t, sys_arg_t type) case SHUTDOWN: case COLD_REBOOT: case WARM_REBOOT: - return_args2(t, OK, poweroff(type)); + return_args1(t, poweroff(type)); }; return_args1(t, ERR_INVAL); } + +SYSCALL_DEFINE0(sleep)(struct tcb *t) +{ + if (!(has_cap(t->caps, CAP_POWER))) + return_args1(t, ERR_PERM); + + return_args1(t, sleep()); +} diff --git a/src/uapi/dispatch.c b/src/uapi/dispatch.c index 5b523cc..f160091 100644 --- a/src/uapi/dispatch.c +++ b/src/uapi/dispatch.c @@ -76,6 +76,7 @@ void handle_syscall(sys_arg_t syscall, sys_arg_t a, sys_arg_t b, case SYS_GET_CAP: sys_get_cap(t, a, b, c, d, e); break; case SYS_CLEAR_CAP: sys_clear_cap(t, a, b, c, d, e); break; case SYS_POWEROFF: sys_poweroff(t, a, b, c, d, e); break; + case SYS_SLEEP: sys_sleep(t, a, b, c, d, e); break; case SYS_IRQ_REQ: sys_irq_req(t, a, b, c, d, e); break; default: error("Syscall %zu outside allowed range [0 - %i]\n", syscall, |
