Skip to content

Commit 48e96c0

Browse files
authored
Implementation of riscv_hwprobe syscall from Linux (#325)
See: https://www.kernel.org/doc/html/latest/arch/riscv/hwprobe.html
1 parent 6b5c8db commit 48e96c0

File tree

4 files changed

+55
-0
lines changed

4 files changed

+55
-0
lines changed

machine/minit.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
uintptr_t mem_size;
1818
volatile uint64_t* mtime;
1919
volatile uint32_t* plic_priorities;
20+
uint64_t misa_image;
2021
size_t plic_ndevs;
2122
void* kernel_start;
2223
void* kernel_end;
@@ -125,6 +126,7 @@ static void memory_init()
125126

126127
static void hart_init()
127128
{
129+
misa_image = read_csr(misa);
128130
mstatus_init();
129131
fp_init();
130132
#ifndef BBL_BOOT_MACHINE

machine/mtrap.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ extern uintptr_t mem_size;
3535
extern volatile uint64_t* mtime;
3636
extern volatile uint32_t* plic_priorities;
3737
extern size_t plic_ndevs;
38+
extern uint64_t misa_image;
3839

3940
typedef struct {
4041
volatile uint32_t* ipi;

pk/syscall.c

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "mmap.h"
99
#include "boot.h"
1010
#include "usermem.h"
11+
#include <stdint.h>
1112
#include <string.h>
1213
#include <errno.h>
1314

@@ -662,6 +663,55 @@ int sys_getdents(int fd, void* dirbuf, int count)
662663
return 0; //stub
663664
}
664665

666+
// Partial implementation on riscv_hwprobe from Linux
667+
// See: https://www.kernel.org/doc/html/latest/arch/riscv/hwprobe.html
668+
669+
#define RISCV_HWPROBE_KEY_IMA_EXT_0 4
670+
#define RISCV_HWPROBE_IMA_FD (1 << 0)
671+
#define RISCV_HWPROBE_IMA_C (1 << 1)
672+
#define RISCV_HWPROBE_IMA_V (1 << 2)
673+
#define RISCV_HWPROBE_EXT_ZBA (1 << 3)
674+
#define RISCV_HWPROBE_EXT_ZBB (1 << 4)
675+
#define RISCV_HWPROBE_EXT_ZBS (1 << 5)
676+
#define RISCV_HWPROBE_EXT_ZICBOZ (1 << 6)
677+
678+
struct riscv_hwprobe {
679+
int64_t key;
680+
uint64_t value;
681+
};
682+
683+
long sys_riscv_hwprobe(struct riscv_hwprobe* probes, size_t count, size_t reserved_cpusetsize, void* reserved_cpuset, unsigned int reserved_flags)
684+
{
685+
if ((reserved_cpusetsize != 0) || (reserved_cpuset != NULL) || (reserved_flags != 0)) {
686+
return -EBADF;
687+
}
688+
689+
for (size_t i=0; i < count; i++) {
690+
struct riscv_hwprobe kv;
691+
memcpy_from_user(&kv, &probes[i], sizeof(kv));
692+
693+
if (kv.key == RISCV_HWPROBE_KEY_IMA_EXT_0) {
694+
kv.value = 0;
695+
#define supports_extension(letter) (misa_image & (1 << (letter - 'A')))
696+
697+
if (supports_extension('C'))
698+
kv.value |= RISCV_HWPROBE_IMA_C;
699+
if (supports_extension('V'))
700+
kv.value |= RISCV_HWPROBE_IMA_V;
701+
702+
#undef supports_extension
703+
} else {
704+
// "If a key is unknown to the kernel, its key field will be cleared to -1, and its value set to 0"
705+
kv.key = -1;
706+
kv.value = 0;
707+
}
708+
709+
memcpy_to_user(&probes[i], &kv, sizeof(kv));
710+
}
711+
712+
return 0;
713+
}
714+
665715
static int sys_stub_success()
666716
{
667717
return 0;
@@ -719,6 +769,7 @@ long do_syscall(long a0, long a1, long a2, long a3, long a4, long a5, unsigned l
719769
[SYS_chdir] = sys_chdir,
720770
[SYS_readlinkat] = sys_readlinkat,
721771
[SYS_readv] = sys_readv,
772+
[SYS_riscv_hwprobe] = sys_riscv_hwprobe,
722773
};
723774

724775
const static void* old_syscall_table[] = {

pk/syscall.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
#define SYS_madvise 233
6060
#define SYS_statx 291
6161
#define SYS_readv 65
62+
#define SYS_riscv_hwprobe 258
6263

6364
#define OLD_SYSCALL_THRESHOLD 1024
6465
#define SYS_open 1024

0 commit comments

Comments
 (0)