From 28d4271d1a9103099e6711fc58f9a479c8722e60 Mon Sep 17 00:00:00 2001 From: Carl Smith Date: Thu, 26 Jul 2018 15:45:28 +1200 Subject: 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 --- src/vppinfra/longjmp.S | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/vppinfra/longjmp.h | 2 ++ src/vppinfra/time.h | 10 +++++++ src/vppinfra/types.h | 12 ++++---- 4 files changed, 92 insertions(+), 6 deletions(-) (limited to 'src') 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; -- cgit 1.2.3-korg