aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCarl Smith <carl.smith@alliedtelesis.co.nz>2018-07-26 15:45:28 +1200
committerDave Barach <openvpp@barachs.net>2018-07-27 12:04:37 +0000
commit28d4271d1a9103099e6711fc58f9a479c8722e60 (patch)
tree40839c9981cbcf4e14585c118955d28993c407f9
parentfc5dda3d0a96fd9722cdac055dfa4865823d5ebd (diff)
mips64: Add timer and longjump support
Also correct types.h for mips64 which could never be hit as _mips was part of the previous ifdef. Change-Id: Id0435c8fc960c5d25c43129b9d9f1606e39ba8e3 Signed-off-by: Carl Smith <carl.smith@alliedtelesis.co.nz>
-rw-r--r--src/vppinfra/longjmp.S74
-rw-r--r--src/vppinfra/longjmp.h2
-rw-r--r--src/vppinfra/time.h10
-rw-r--r--src/vppinfra/types.h12
4 files changed, 92 insertions, 6 deletions
diff --git a/src/vppinfra/longjmp.S b/src/vppinfra/longjmp.S
index d4dd4c7d916..6468dba45bf 100644
--- a/src/vppinfra/longjmp.S
+++ b/src/vppinfra/longjmp.S
@@ -580,6 +580,80 @@ clib_longjmp:
clib_calljmp:
1: B .S1 1b
+#elif defined(_mips) && __mips == 64
+
+ .global clib_setjmp
+ .align 8
+ .type clib_setjmp, %function
+clib_setjmp:
+ sd $ra, 0($a0)
+ sd $sp, 8($a0)
+ sd $gp, 16($a0)
+ sd $16, 24($a0)
+ sd $17, 32($a0)
+ sd $18, 40($a0)
+ sd $19, 48($a0)
+ sd $20, 56($a0)
+ sd $21, 64($a0)
+ sd $22, 72($a0)
+ sd $23, 80($a0)
+ sd $30, 88($a0)
+ move $v0, $a1
+ jr $ra
+ nop
+
+ .global clib_longjmp
+ .align 8
+ .type clib_longjmp, @function
+clib_longjmp:
+ move $v0, $a1
+ bne $v0, $0, 1f
+ nop
+ daddu $v0, $v0, 1
+1:
+ ld $ra, 0($a0)
+ ld $sp, 8($a0)
+ ld $gp, 16($a0)
+ ld $16, 24($a0)
+ ld $17, 32($a0)
+ ld $18, 40($a0)
+ ld $19, 48($a0)
+ ld $20, 56($a0)
+ ld $21, 64($a0)
+ ld $22, 72($a0)
+ ld $23, 80($a0)
+ ld $30, 88($a0)
+ jr $ra
+ nop
+
+ .global clib_calljmp
+ .align 8
+ .type clib_calljmp, %function
+clib_calljmp:
+ /* Force 16 byte alignment of the new stack */
+ li $t1, -16
+ and $t0, $a2, $t1
+ /* Save old ra/gp/sp on new stack */
+ daddiu $t0, $t0, (-24)
+ sd $ra, 0($t0)
+ sd $gp, 8($t0)
+ sd $sp, 16($t0)
+ /* Switch stacks */
+ move $sp, $t0
+ /* Away we go */
+ move $t9, $a0
+ move $a0, $a1
+ jalr $t9
+ nop
+ /* Switch back to old ra/gp/sp */
+ move $t0, $sp
+ ld $ra, 0($t0)
+ ld $gp, 8($t0)
+ ld $sp, 16($t0)
+ /* Return to caller */
+ jr $ra
+ nop
+
#elif defined (__aarch64__)
/*
Copyright (c) 2011, 2012 ARM Ltd
diff --git a/src/vppinfra/longjmp.h b/src/vppinfra/longjmp.h
index 8d83203e41d..67c650a6174 100644
--- a/src/vppinfra/longjmp.h
+++ b/src/vppinfra/longjmp.h
@@ -93,6 +93,8 @@
#elif defined(__aarch64__)
#define CLIB_ARCH_LONGJMP_REGS (22)
+#elif defined(_mips) && __mips == 64
+#define CLIB_ARCH_LONGJMP_REGS (12)
#else
#error "unknown machine"
#endif
diff --git a/src/vppinfra/time.h b/src/vppinfra/time.h
index 39bc188ebe5..ced9677d1e2 100644
--- a/src/vppinfra/time.h
+++ b/src/vppinfra/time.h
@@ -174,6 +174,16 @@ clib_cpu_time_now (void)
return ((u64) h << 32) | l;
}
+#elif defined(_mips) && __mips == 64
+
+always_inline u64
+clib_cpu_time_now (void)
+{
+ u64 result;
+ asm volatile ("rdhwr %0,$31\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 5fd378314f3..c5e7f09ef23 100644
--- a/src/vppinfra/types.h
+++ b/src/vppinfra/types.h
@@ -64,7 +64,7 @@ typedef unsigned int u128 __attribute__ ((mode (TI)));
#endif
#endif
-#if (defined(i386) || defined(_mips) || defined(powerpc) || defined (__SPU__) || defined(__sparc__) || defined(__arm__) || defined (__xtensa__) || defined(__TMS320C6X__))
+#if (defined(i386) || (defined(_mips) && __mips != 64) || defined(powerpc) || defined (__SPU__) || defined(__sparc__) || defined(__arm__) || defined (__xtensa__) || defined(__TMS320C6X__))
typedef signed int i32;
typedef signed long long i64;
@@ -73,16 +73,16 @@ typedef unsigned int u32;
typedef unsigned long long u64;
#endif /* CLIB_AVOID_CLASH_WITH_LINUX_TYPES */
-#elif defined(_mips) && __mips == 64
-#define log2_uword_bits 6
-#define clib_address_bits _MIPS_SZPTR
-
-#elif defined(alpha) || defined(__x86_64__) || defined (__powerpc64__) || defined (__aarch64__)
+#elif defined(alpha) || (defined(_mips) && __mips == 64) || defined(__x86_64__) || defined (__powerpc64__) || defined (__aarch64__)
typedef signed int i32;
typedef signed long i64;
#define log2_uword_bits 6
+#if defined(_mips)
+#define clib_address_bits _MIPS_SZPTR
+#else
#define clib_address_bits 64
+#endif
#ifndef CLIB_AVOID_CLASH_WITH_LINUX_TYPES
typedef unsigned int u32;