diff options
author | Wojciech Muła <wojciech_mula@poczta.onet.pl> | 2024-04-24 06:58:59 +0200 |
---|---|---|
committer | Andrew Waterman <andrew@sifive.com> | 2024-05-20 18:37:48 -0700 |
commit | ab24ff26666e14b3b6c4a8c8bb2c209d2587bb3e (patch) | |
tree | 98780651ffcc8ea390e77bce5869983f31be5ab4 | |
parent | 86ed1b3b062bc81c2f42d6676a71cfba52880915 (diff) | |
download | riscv-pk-ab24ff26666e14b3b6c4a8c8bb2c209d2587bb3e.zip riscv-pk-ab24ff26666e14b3b6c4a8c8bb2c209d2587bb3e.tar.gz riscv-pk-ab24ff26666e14b3b6c4a8c8bb2c209d2587bb3e.tar.bz2 |
Implementation of riscv_hwprobe syscall from Linux (#325)
See: https://www.kernel.org/doc/html/latest/arch/riscv/hwprobe.html
-rw-r--r-- | machine/minit.c | 2 | ||||
-rw-r--r-- | machine/mtrap.h | 1 | ||||
-rw-r--r-- | pk/syscall.c | 51 | ||||
-rw-r--r-- | pk/syscall.h | 1 |
4 files changed, 55 insertions, 0 deletions
diff --git a/machine/minit.c b/machine/minit.c index 95ddaa1..55f50cb 100644 --- a/machine/minit.c +++ b/machine/minit.c @@ -17,6 +17,7 @@ uintptr_t mem_size; volatile uint64_t* mtime; volatile uint32_t* plic_priorities; +uint64_t misa_image; size_t plic_ndevs; void* kernel_start; void* kernel_end; @@ -126,6 +127,7 @@ static void memory_init() static void hart_init() { + misa_image = read_csr(misa); mstatus_init(); fp_init(); #ifndef BBL_BOOT_MACHINE diff --git a/machine/mtrap.h b/machine/mtrap.h index 2f2e499..41071f3 100644 --- a/machine/mtrap.h +++ b/machine/mtrap.h @@ -35,6 +35,7 @@ extern uintptr_t mem_size; extern volatile uint64_t* mtime; extern volatile uint32_t* plic_priorities; extern size_t plic_ndevs; +extern uint64_t misa_image; typedef struct { volatile uint32_t* ipi; diff --git a/pk/syscall.c b/pk/syscall.c index 3dd0bf7..dc0d35f 100644 --- a/pk/syscall.c +++ b/pk/syscall.c @@ -8,6 +8,7 @@ #include "mmap.h" #include "boot.h" #include "usermem.h" +#include <stdint.h> #include <string.h> #include <errno.h> @@ -662,6 +663,55 @@ int sys_getdents(int fd, void* dirbuf, int count) return 0; //stub } +// Partial implementation on riscv_hwprobe from Linux +// See: https://www.kernel.org/doc/html/latest/arch/riscv/hwprobe.html + +#define RISCV_HWPROBE_KEY_IMA_EXT_0 4 +#define RISCV_HWPROBE_IMA_FD (1 << 0) +#define RISCV_HWPROBE_IMA_C (1 << 1) +#define RISCV_HWPROBE_IMA_V (1 << 2) +#define RISCV_HWPROBE_EXT_ZBA (1 << 3) +#define RISCV_HWPROBE_EXT_ZBB (1 << 4) +#define RISCV_HWPROBE_EXT_ZBS (1 << 5) +#define RISCV_HWPROBE_EXT_ZICBOZ (1 << 6) + +struct riscv_hwprobe { + int64_t key; + uint64_t value; +}; + +long sys_riscv_hwprobe(struct riscv_hwprobe* probes, size_t count, size_t reserved_cpusetsize, void* reserved_cpuset, unsigned int reserved_flags) +{ + if ((reserved_cpusetsize != 0) || (reserved_cpuset != NULL) || (reserved_flags != 0)) { + return -EBADF; + } + + for (size_t i=0; i < count; i++) { + struct riscv_hwprobe kv; + memcpy_from_user(&kv, &probes[i], sizeof(kv)); + + if (kv.key == RISCV_HWPROBE_KEY_IMA_EXT_0) { + kv.value = 0; + #define supports_extension(letter) (misa_image & (1 << (letter - 'A'))) + + if (supports_extension('C')) + kv.value |= RISCV_HWPROBE_IMA_C; + if (supports_extension('V')) + kv.value |= RISCV_HWPROBE_IMA_V; + + #undef supports_extension + } else { + // "If a key is unknown to the kernel, its key field will be cleared to -1, and its value set to 0" + kv.key = -1; + kv.value = 0; + } + + memcpy_to_user(&probes[i], &kv, sizeof(kv)); + } + + return 0; +} + static int sys_stub_success() { return 0; @@ -719,6 +769,7 @@ long do_syscall(long a0, long a1, long a2, long a3, long a4, long a5, unsigned l [SYS_chdir] = sys_chdir, [SYS_readlinkat] = sys_readlinkat, [SYS_readv] = sys_readv, + [SYS_riscv_hwprobe] = sys_riscv_hwprobe, }; const static void* old_syscall_table[] = { diff --git a/pk/syscall.h b/pk/syscall.h index 6731edd..2d430fa 100644 --- a/pk/syscall.h +++ b/pk/syscall.h @@ -59,6 +59,7 @@ #define SYS_madvise 233 #define SYS_statx 291 #define SYS_readv 65 +#define SYS_riscv_hwprobe 258 #define OLD_SYSCALL_THRESHOLD 1024 #define SYS_open 1024 |