Skip to content

Commit

Permalink
Add nolibc riscv64 support
Browse files Browse the repository at this point in the history
Add `lgcc` to avoid undefined reference to `__clzdi2'

Signed-off-by: Michal Biesek <[email protected]>
  • Loading branch information
michalbiesek committed Aug 23, 2023
1 parent 660cefa commit d305ed5
Show file tree
Hide file tree
Showing 7 changed files with 160 additions and 6 deletions.
4 changes: 2 additions & 2 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -389,11 +389,11 @@ liburing_nolibc="no"
if test "$use_libc" != "yes"; then

#
# Currently, CONFIG_NOLIBC only supports x86-64, x86 (32-bit) and aarch64.
# Currently, CONFIG_NOLIBC only supports x86-64, x86 (32-bit), aarch64 and riscv64.
#
cat > $TMPC << EOF
int main(void){
#if defined(__x86_64__) || defined(__i386__) || defined(__aarch64__)
#if defined(__x86_64__) || defined(__i386__) || defined(__aarch64__) || (defined(__riscv) && __riscv_xlen == 64)
return 0;
#else
#error libc is needed
Expand Down
2 changes: 1 addition & 1 deletion src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ ifeq ($(CONFIG_NOLIBC),y)
liburing_srcs += nolibc.c
override CFLAGS += -nostdlib -nodefaultlibs -ffreestanding -fno-builtin -fno-stack-protector
override CPPFLAGS += -nostdlib -nodefaultlibs -ffreestanding -fno-builtin -fno-stack-protector
override LINK_FLAGS += -nostdlib -nodefaultlibs
override LINK_FLAGS += -nostdlib -nodefaultlibs -lgcc
endif

override CPPFLAGS += -MT "$@" -MMD -MP -MF "$@.d"
Expand Down
48 changes: 48 additions & 0 deletions src/arch/riscv64/lib.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/* SPDX-License-Identifier: MIT */

#ifndef LIBURING_ARCH_RISCV64_LIB_H
#define LIBURING_ARCH_RISCV64_LIB_H

#include <elf.h>
#include <sys/auxv.h>
#include "../../syscall.h"

static inline long __get_page_size(void)
{
Elf64_Off buf[2];
long ret = 4096;
int fd;

fd = __sys_open("/proc/self/auxv", O_RDONLY, 0);
if (fd < 0)
return ret;

while (1) {
ssize_t x;

x = __sys_read(fd, buf, sizeof(buf));
if (x < (long) sizeof(buf))
break;

if (buf[0] == AT_PAGESZ) {
ret = buf[1];
break;
}
}

__sys_close(fd);
return ret;
}

static inline long get_page_size(void)
{
static long cache_val;

if (cache_val)
return cache_val;

cache_val = __get_page_size();
return cache_val;
}

#endif /* #ifndef LIBURING_ARCH_RISCV64_LIB_H */
100 changes: 100 additions & 0 deletions src/arch/riscv64/syscall.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/* SPDX-License-Identifier: MIT */

#ifndef LIBURING_ARCH_RISCV64_SYSCALL_H
#define LIBURING_ARCH_RISCV64_SYSCALL_H

#if defined(__riscv) && __riscv_xlen == 64

#define __do_syscallM(...) ({ \
__asm__ volatile ( \
"ecall" \
: "=r"(a0) \
: __VA_ARGS__ \
: "memory", "a1"); \
(long) a0; \
})

#define __do_syscallN(...) ({ \
__asm__ volatile ( \
"ecall" \
: "=r"(a0) \
: __VA_ARGS__ \
: "memory"); \
(long) a0; \
})

#define __do_syscall0(__n) ({ \
register long a7 __asm__("a7") = __n; \
register long a0 __asm__("a0"); \
\
__do_syscallM("r" (a7)); \
})

#define __do_syscall1(__n, __a) ({ \
register long a7 __asm__("a7") = __n; \
register __typeof__(__a) a0 __asm__("a0") = __a; \
\
__do_syscallM("r" (a7), "0" (a0)); \
})

#define __do_syscall2(__n, __a, __b) ({ \
register long a7 __asm__("a7") = __n; \
register __typeof__(__a) a0 __asm__("a0") = __a; \
register __typeof__(__b) a1 __asm__("a1") = __b; \
\
__do_syscallN("r" (a7), "0" (a0), "r" (a1)); \
})

#define __do_syscall3(__n, __a, __b, __c) ({ \
register long a7 __asm__("a7") = __n; \
register __typeof__(__a) a0 __asm__("a0") = __a; \
register __typeof__(__b) a1 __asm__("a1") = __b; \
register __typeof__(__c) a2 __asm__("a2") = __c; \
\
__do_syscallN("r" (a7), "0" (a0), "r" (a1), "r" (a2)); \
})

#define __do_syscall4(__n, __a, __b, __c, __d) ({ \
register long a7 __asm__("a7") = __n; \
register __typeof__(__a) a0 __asm__("a0") = __a; \
register __typeof__(__b) a1 __asm__("a1") = __b; \
register __typeof__(__c) a2 __asm__("a2") = __c; \
register __typeof__(__d) a3 __asm__("a3") = __d; \
\
__do_syscallN("r" (a7), "0" (a0), "r" (a1), "r" (a2), "r" (a3));\
})

#define __do_syscall5(__n, __a, __b, __c, __d, __e) ({ \
register long a7 __asm__("a7") = __n; \
register __typeof__(__a) a0 __asm__("a0") = __a; \
register __typeof__(__b) a1 __asm__("a1") = __b; \
register __typeof__(__c) a2 __asm__("a2") = __c; \
register __typeof__(__d) a3 __asm__("a3") = __d; \
register __typeof__(__e) a4 __asm__("a4") = __e; \
\
__do_syscallN("r" (a7), "0" (a0), "r" (a1), "r" (a2), "r" (a3), \
"r"(a4)); \
})

#define __do_syscall6(__n, __a, __b, __c, __d, __e, __f) ({ \
register long a7 __asm__("a7") = __n; \
register __typeof__(__a) a0 __asm__("a0") = __a; \
register __typeof__(__b) a1 __asm__("a1") = __b; \
register __typeof__(__c) a2 __asm__("a2") = __c; \
register __typeof__(__d) a3 __asm__("a3") = __d; \
register __typeof__(__e) a4 __asm__("a4") = __e; \
register __typeof__(__f) a5 __asm__("a5") = __f; \
\
__do_syscallN("r" (a7), "0" (a0), "r" (a1), "r" (a2), "r" (a3), \
"r" (a4), "r"(a5)); \
})

#include "../syscall-defs.h"

#else /* #if defined(__riscv) && __riscv_xlen == 64 */

#include "../generic/syscall.h"

#endif /* #if defined(__riscv) && __riscv_xlen == 64 */

#endif /* #ifndef LIBURING_ARCH_RISCV64_SYSCALL_H */
2 changes: 2 additions & 0 deletions src/lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#include "arch/x86/lib.h"
#elif defined(__aarch64__)
#include "arch/aarch64/lib.h"
#elif defined(__riscv) && __riscv_xlen == 64
#include "arch/riscv64/lib.h"
#else
/*
* We don't have nolibc support for this arch. Must use libc!
Expand Down
2 changes: 2 additions & 0 deletions src/syscall.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ static inline bool IS_ERR(const void *ptr)
#include "arch/x86/syscall.h"
#elif defined(__aarch64__)
#include "arch/aarch64/syscall.h"
#elif defined(__riscv) && __riscv_xlen == 64
#include "arch/riscv64/syscall.h"
#else
/*
* We don't have native syscall wrappers
Expand Down
8 changes: 5 additions & 3 deletions test/nolibc.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@
* 1) x86
* 2) x86-64
* 3) aarch64
* 4) riscv64
*
*/
#include "helpers.h"

#if !defined(__x86_64__) && !defined(__i386__) && !defined(__aarch64__)
#if !defined(__x86_64__) && !defined(__i386__) && !defined(__aarch64__) && (!defined(__riscv) && __riscv_xlen != 64)


/*
* This arch doesn't support nolibc.
Expand All @@ -20,7 +22,7 @@ int main(void)
return T_EXIT_SKIP;
}

#else /* #if !defined(__x86_64__) && !defined(__i386__) && !defined(__aarch64__) */
#else /* #if !defined(__x86_64__) && !defined(__i386__) && !defined(__aarch64__) && (!defined(__riscv) && __riscv_xlen != 64) */

#ifndef CONFIG_NOLIBC
#define CONFIG_NOLIBC
Expand Down Expand Up @@ -57,4 +59,4 @@ int main(int argc, char *argv[])
return T_EXIT_PASS;
}

#endif /* #if !defined(__x86_64__) && !defined(__i386__) && !defined(__aarch64__) */
#endif /* #if !defined(__x86_64__) && !defined(__i386__) && !defined(__aarch64__) && (!defined(__riscv) && __riscv_xlen != 64) */

0 comments on commit d305ed5

Please sign in to comment.