Browse Source

Implementation of riscv_hwprobe syscall from Linux (#325)

See: https://www.kernel.org/doc/html/latest/arch/riscv/hwprobe.html
pull/328/head
Wojciech Muła 2 years ago
committed by Andrew Waterman
parent
commit
ab24ff2666
  1. 2
      machine/minit.c
  2. 1
      machine/mtrap.h
  3. 51
      pk/syscall.c
  4. 1
      pk/syscall.h

2
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

1
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;

51
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[] = {

1
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

Loading…
Cancel
Save