aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/vppinfra/longjmp.S50
-rw-r--r--src/vppinfra/longjmp.h3
-rw-r--r--src/vppinfra/time.h9
-rw-r--r--src/vppinfra/types.h4
4 files changed, 65 insertions, 1 deletions
diff --git a/src/vppinfra/longjmp.S b/src/vppinfra/longjmp.S
index a3435ccb969..c5090877fd7 100644
--- a/src/vppinfra/longjmp.S
+++ b/src/vppinfra/longjmp.S
@@ -816,6 +816,56 @@ cdecl(clib_calljmp):
mov sp, x3
ret
.size cdecl(clib_calljmp), .-cdecl(clib_calljmp)
+#elif defined(__riscv)
+#define foreach_0_to_11 _(0) _(1) _(2) _(3) _(4) _(5) _(6) _(7) _(8) _(9) _(10) _(11)
+ .global cdecl(clib_setjmp)
+ .align 1
+ .type cdecl(clib_setjmp), @function
+cdecl(clib_setjmp):
+ sd ra, 0*8(a0)
+ sd sp, 1*8(a0)
+#define _(x) sd s##x, (x + 2)*8(a0);
+ foreach_0_to_11
+#undef _
+#define _(x) fsd fs##x, (x + 14)*8(a0);
+ foreach_0_to_11
+#undef _
+ mv a0,a1
+ ret
+ .size cdecl(clib_setjmp), .-cdecl(clib_setjmp)
+
+ .global cdecl(clib_longjmp)
+ .align 1
+ .type cdecl(clib_longjmp), @function
+cdecl(clib_longjmp):
+ ld ra, 0*8(a0)
+ ld sp, 1*8(a0)
+#define _(x) ld s##x, (x + 2)*8(a0);
+ foreach_0_to_11
+#undef _
+#define _(x) fld fs##x, (x + 14)*8(a0);
+ foreach_0_to_11
+#undef _
+ mv a0,a1
+ ret
+ .size cdecl(clib_longjmp), .-cdecl(clib_longjmp)
+
+ .global cdecl(clib_calljmp)
+ .align 1
+ .type cdecl(clib_calljmp), @function
+cdecl(clib_calljmp):
+ andi a2,a2, -16 /* Make sure stack is 16-byte aligned. */
+ addi a2, a2, -16 /* allocate space on the new stack */
+ sd ra, 8(a2) /* store return address */
+ sd sp, 0(a2) /* store existing stack pointer */
+ mv sp, a2 /* change stack */
+ mv a2, a0 /* functon pointer to a2 */
+ mv a0, a1 /* 2nd argument becomes 1st one */
+ jalr a2 /* function call */
+ ld ra, 8(sp) /* restore old return address */
+ ld sp, 0(sp) /* restore old stack pointer */
+ ret
+ .size cdecl(clib_calljmp), .-cdecl(clib_calljmp)
#else
#error "unknown machine"
#endif
diff --git a/src/vppinfra/longjmp.h b/src/vppinfra/longjmp.h
index 67c650a6174..62daaad59bd 100644
--- a/src/vppinfra/longjmp.h
+++ b/src/vppinfra/longjmp.h
@@ -95,6 +95,9 @@
#define CLIB_ARCH_LONGJMP_REGS (22)
#elif defined(_mips) && __mips == 64
#define CLIB_ARCH_LONGJMP_REGS (12)
+#elif defined(__riscv)
+/* ra, sp, s0-s11, fs0-fs11 */
+#define CLIB_ARCH_LONGJMP_REGS (26)
#else
#error "unknown machine"
#endif
diff --git a/src/vppinfra/time.h b/src/vppinfra/time.h
index 4d8997f0a9e..761dbed3fe8 100644
--- a/src/vppinfra/time.h
+++ b/src/vppinfra/time.h
@@ -192,6 +192,15 @@ clib_cpu_time_now (void)
return result;
}
+#elif defined(__riscv)
+
+always_inline u64
+clib_cpu_time_now (void)
+{
+ u64 result;
+ asm volatile("rdcycle %0\n" : "=r"(result));
+ return result;
+}
#else
#error "don't know how to read CPU time stamp"
diff --git a/src/vppinfra/types.h b/src/vppinfra/types.h
index b52d6034ae9..598061bb3e8 100644
--- a/src/vppinfra/types.h
+++ b/src/vppinfra/types.h
@@ -73,7 +73,9 @@ typedef unsigned int u32;
typedef unsigned long long u64;
#endif /* CLIB_AVOID_CLASH_WITH_LINUX_TYPES */
-#elif defined(alpha) || (defined(_mips) && __mips == 64) || defined(__x86_64__) || defined (__powerpc64__) || defined (__aarch64__)
+#elif defined(alpha) || (defined(_mips) && __mips == 64) || \
+ defined(__x86_64__) || defined(__powerpc64__) || defined(__aarch64__) || \
+ (defined(__riscv) && __riscv_xlen == 64)
typedef signed int i32;
typedef signed long i64;