/* Other 32-bit cpus will need to modify this file. */
#if defined (__i386__) || defined(__arm__) || \
- (defined(__powerpc__) && !defined(__powerpc64__))
+ (defined(__powerpc__) && !defined(__powerpc64__)) || \
+ (defined(__mips__) && !defined(__mips64))
static long long _div64 (long long u, long long v);
static long long _mod64 (long long u, long long v);
#endif
#if defined (__i386__) || defined (__arm__) || \
- (defined(__powerpc__) && !defined(__powerpc64__))
+ (defined(__powerpc__) && !defined(__powerpc64__)) || \
+ (defined(__mips__) && !defined(__mips64))
/* 64-bit division functions extracted from libgcc */
typedef long long DWtype;
typedef long Wtype;
typedef unsigned int USItype;
typedef unsigned int UQItype __attribute__ ((mode (QI)));
+typedef unsigned int UDItype __attribute__ ((mode (DI)));
#ifdef _BIG_ENDIAN
struct DWstruct {Wtype high, low;};
: "r" ((USItype) (a)), \
"r" ((USItype) (b)) __CLOBBER_CC );}
+#elif (defined(__mips) && __mips >= 3) && W_TYPE_SIZE == 64
+#if (__GNUC__ >= 5) || (__GNUC__ >= 4 && __GNUC_MINOR__ >= 4)
+#define umul_ppmm(w1, w0, u, v) \
+do { \
+ typedef unsigned int __ll_UTItype __attribute__((mode(TI))); \
+ __ll_UTItype __ll = (__ll_UTItype)(u) * (v); \
+ w1 = __ll >> 64; \
+ w0 = __ll; \
+} while (0)
+#elif __GNUC__ > 2 || __GNUC_MINOR__ >= 7
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("dmultu %2,%3" \
+ : "=l" ((UDItype)(w0)), \
+ "=h" ((UDItype)(w1)) \
+ : "d" ((UDItype)(u)), \
+ "d" ((UDItype)(v)))
+#else
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("dmultu %2,%3\n" \
+ "mflo %0\n" \
+ "mfhi %1" \
+ : "=d" ((UDItype)(w0)), \
+ "=d" ((UDItype)(w1)) \
+ : "d" ((UDItype)(u)), \
+ "d" ((UDItype)(v)))
+#endif
+/* This comes from lib/mpi/longlong.h */
+#elif defined(__mips__) && W_TYPE_SIZE == 32
+#if (__GNUC__ >= 5) || (__GNUC__ >= 4 && __GNUC_MINOR__ >= 4)
+#define umul_ppmm(w1, w0, u, v) \
+do { \
+ UDItype __ll = (UDItype)(u) * (v); \
+ w1 = __ll >> 32; \
+ w0 = __ll; \
+} while (0)
+#elif __GNUC__ > 2 || __GNUC_MINOR__ >= 7
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("multu %2,%3" \
+ : "=l" ((USItype)(w0)), \
+ "=h" ((USItype)(w1)) \
+ : "d" ((USItype)(u)), \
+ "d" ((USItype)(v)))
+#else
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("multu %2,%3\n" \
+ "mflo %0\n" \
+ "mfhi %1" \
+ : "=d" ((USItype)(w0)), \
+ "=d" ((USItype)(w1)) \
+ : "d" ((USItype)(u)), \
+ "d" ((USItype)(v)))
+#endif
+
+#if !defined (sub_ddmmss)
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ do { \
+ UWtype __x; \
+ __x = (al) - (bl); \
+ (sh) = (ah) - (bh) - (__x > (al)); \
+ (sl) = __x; \
+ } while (0)
+#endif
+
+#elif (defined(__mips) && __mips >= 3) && W_TYPE_SIZE == 64
+#if (__GNUC__ >= 5) || (__GNUC__ >= 4 && __GNUC_MINOR__ >= 4)
+#define umul_ppmm(w1, w0, u, v) \
+do { \
+ typedef unsigned int __ll_UTItype __attribute__((mode(TI))); \
+ __ll_UTItype __ll = (__ll_UTItype)(u) * (v); \
+ w1 = __ll >> 64; \
+ w0 = __ll; \
+} while (0)
+#elif __GNUC__ > 2 || __GNUC_MINOR__ >= 7
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("dmultu %2,%3" \
+ : "=l" ((UDItype)(w0)), \
+ "=h" ((UDItype)(w1)) \
+ : "d" ((UDItype)(u)), \
+ "d" ((UDItype)(v)))
+#else
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("dmultu %2,%3\n" \
+ "mflo %0\n" \
+ "mfhi %1" \
+ : "=d" ((UDItype)(w0)), \
+ "=d" ((UDItype)(w1)) \
+ : "d" ((UDItype)(u)), \
+ "d" ((UDItype)(v)))
+#endif
#endif
#define __udiv_qrnnd_c(q, r, n1, n0, d) \
_stp_printf("\n");
}
+#elif defined (__mips__)
+/*
+ * MIPS_CPU_ISA_I was removed from the kernel (3.11) by
+ * Commit: 1990e5429c21 ("MIPS: Get rid of MIPS I flag and test macros.")
+ */
+#ifndef MIPS_CPU_ISA_I
+#define IS_CPU_ISA_MIPS_I(x) (!((x) & (MIPS_CPU_ISA_32BIT | MIPS_CPU_ISA_64BIT)))
+#else
+#define IS_CPU_ISA_MIPS_I(x) ((x) == MIPS_CPU_ISA_I)
+#endif
+/*
+ * Only o32 application has 32bit registers. N32 and N64 both
+ * should use 64bit registers regardless of pointer size
+ */
+static int _stp_probing_app_with_32bit_regs(struct pt_regs *regs)
+{
+ if (!regs)
+ return 0;
+ return (user_mode(regs) &&
+ test_tsk_thread_flag(current, TIF_32BIT_REGS));
+}
+
+void _stp_print_regs(struct pt_regs * regs)
+{
+#ifdef MIPS_PRINT_REGS_SHOW_SYMBOLS
+ /* it is too much stack to do symbol translation by default */
+ char symbol_name[KSYM_SYMBOL_LEN];
+#endif /* MIPS_PRINT_REGS_SHOW_SYMBOLS */
+ const int field = 2 * sizeof(unsigned long);
+ unsigned int cause = regs->cp0_cause;
+ int i;
+
+#ifdef CONFIG_SMP
+ _stp_printf("Cpu %d\n", smp_processor_id());
+#endif
+
+ /*
+ * Saved main processor registers
+ */
+ for (i = 0; i < 32;) {
+ if ((i % 4) == 0)
+ _stp_printf("$%2d :", i);
+ if (i == 0)
+ _stp_printf(" %0*lx", field, 0UL);
+ else if (i == 26 || i == 27)
+ _stp_printf(" %*s", field, "");
+ else
+ _stp_printf(" %0*lx", field, regs->regs[i]);
+
+ i++;
+ if ((i % 4) == 0)
+ _stp_printf("\n");
+ }
+
+ /* Hi and Lo don't exist for R6 */
+ if (current_cpu_data.isa_level != MIPS_CPU_ISA_M32R6
+ && current_cpu_data.isa_level != MIPS_CPU_ISA_M64R6) {
+ _stp_printf("Hi : %0*lx\n", field, regs->hi);
+ _stp_printf("Lo : %0*lx\n", field, regs->lo);
+ }
+
+ /*
+ * Saved cp0 registers
+ */
+ _stp_printf("epc : %0*lx ", field, regs->cp0_epc);
+#ifdef MIPS_PRINT_REGS_SHOW_SYMBOLSx
+ sprint_symbol(symbol_name, regs->cp0_epc);
+ _stp_printf("%s ", symbol_name);
+#endif /* MIPS_PRINT_REGS_SHOW_SYMBOLS */
+
+ _stp_printf("ra : %0*lx ", field, regs->regs[31]);
+#ifdef MIPS_PRINT_REGS_SHOW_SYMBOLS
+ sprint_symbol(symbol_name, regs->regs[31]);
+ _stp_printf("%s", symbol_name);
+#endif /* MIPS_PRINT_REGS_SHOW_SYMBOLS */
+ _stp_printf("\n");
+
+ _stp_printf("Status: %08x ", (uint32_t) regs->cp0_status);
+
+ if (IS_CPU_ISA_MIPS_I(current_cpu_data.isa_level)) {
+ if (regs->cp0_status & ST0_KUO)
+ _stp_printf("KUo ");
+ if (regs->cp0_status & ST0_IEO)
+ _stp_printf("IEo ");
+ if (regs->cp0_status & ST0_KUP)
+ _stp_printf("KUp ");
+ if (regs->cp0_status & ST0_IEP)
+ _stp_printf("IEp ");
+ if (regs->cp0_status & ST0_KUC)
+ _stp_printf("KUc ");
+ if (regs->cp0_status & ST0_IEC)
+ _stp_printf("IEc ");
+ } else {
+ if (regs->cp0_status & ST0_KX)
+ _stp_printf("KX ");
+ if (regs->cp0_status & ST0_SX)
+ _stp_printf("SX ");
+ if (regs->cp0_status & ST0_UX)
+ _stp_printf("UX ");
+ switch (regs->cp0_status & ST0_KSU) {
+ case KSU_USER:
+ _stp_printf("USER ");
+ break;
+ case KSU_SUPERVISOR:
+ _stp_printf("SUPERVISOR ");
+ break;
+ case KSU_KERNEL:
+ _stp_printf("KERNEL ");
+ break;
+ default:
+ _stp_printf("BAD_MODE ");
+ break;
+ }
+ if (regs->cp0_status & ST0_ERL)
+ _stp_printf("ERL ");
+ if (regs->cp0_status & ST0_EXL)
+ _stp_printf("EXL ");
+ if (regs->cp0_status & ST0_IE)
+ _stp_printf("IE ");
+ }
+
+ _stp_printf("\n");
+
+ _stp_printf("Cause : %08x\n", cause);
+
+ cause = (((cause) & CAUSEF_EXCCODE) >> CAUSEB_EXCCODE);
+ if (1 <= cause && cause <= 5)
+ _stp_printf("BadVA : %0*lx\n", field, regs->cp0_badvaddr);
+
+ _stp_printf("PrId : %08x\n", read_c0_prid());
+}
#endif
#define pt_regs_store_register(pt_regs,regno,value) \
(pt_regs->gpr[regno] = (value))
+#elif defined __mips__
+
+#undef pt_regs_fetch_register
+#undef pt_regs_store_register
+#define pt_regs_fetch_register(pt_regs,regno) \
+ ((intptr_t) pt_regs->regs[regno])
+#define pt_regs_store_register(pt_regs,regno,value) \
+ (pt_regs->regs[regno] = (value))
+
#elif defined (__aarch64__)
#define pt_dwarf_register_0(pt_regs) pt_regs->regs[0]
#define REG_SP(regs) regs->ARM_sp
#define REG_LINK(regs) regs->ARM_lr
+#elif defined (__mips__)
+#define REG_IP(regs_arg) ((regs_arg)->cp0_epc)
+#define REG_SP(regs_arg) ((regs_arg)->regs[29])
+
#elif defined (__s390__) || defined (__s390x__)
#ifndef __s390x__
#define MREMAP_SYSCALL_NO(tsk) 1156
#endif
+#if defined(__mips__)
+/* n64 values: scall64-64.S */
+#define MMAP_SYSCALL_NO_MIPS_N64 5009
+#define MMAP2_SYSCALL_NO_MIPS_N64 ((unsigned long)-1) /* does not exits */
+#define MPROTECT_SYSCALL_NO_MIPS_N64 5010
+#define MUNMAP_SYSCALL_NO_MIPS_N64 5011
+#define MREMAP_SYSCALL_NO_MIPS_N64 5024
+
+/* n32 values: scall64-n32.S */
+#define MMAP_SYSCALL_NO_MIPS_N32 6009
+#define MMAP2_SYSCALL_NO_MIPS_N32 ((unsigned long)-1) /* does not exits */
+#define MPROTECT_SYSCALL_NO_MIPS_N32 6010
+#define MUNMAP_SYSCALL_NO_MIPS_N32 6011
+#define MREMAP_SYSCALL_NO_MIPS_N32 6024
+
+/* o32 values: scall32-o32.S */
+#define MMAP_SYSCALL_NO_MIPS_O32 4090
+#define MMAP2_SYSCALL_NO_MIPS_O32 4210
+#define MPROTECT_SYSCALL_NO_MIPS_O32 4125
+#define MUNMAP_SYSCALL_NO_MIPS_O32 4091
+#define MREMAP_SYSCALL_NO_MIPS_O32 4167
+
+#define MMAP_SYSCALL_NO(tsk) ((test_tsk_thread_flag((tsk), TIF_32BIT_ADDR)) ? \
+ ((test_tsk_thread_flag((tsk), TIF_32BIT_REGS)) ? \
+ (MMAP_SYSCALL_NO_MIPS_O32) : \
+ (MMAP_SYSCALL_NO_MIPS_N32)) : \
+ (MMAP_SYSCALL_NO_MIPS_N64))
+#define MMAP2_SYSCALL_NO(tsk) ((test_tsk_thread_flag((tsk), TIF_32BIT_ADDR)) ? \
+ ((test_tsk_thread_flag((tsk), TIF_32BIT_REGS)) ? \
+ (MMAP2_SYSCALL_NO_MIPS_O32) : \
+ (MMAP2_SYSCALL_NO_MIPS_N32)) : \
+ (MMAP2_SYSCALL_NO_MIPS_N64))
+#define MPROTECT_SYSCALL_NO(tsk) ((test_tsk_thread_flag((tsk), TIF_32BIT_ADDR)) ? \
+ ((test_tsk_thread_flag((tsk), TIF_32BIT_REGS)) ? \
+ (MPROTECT_SYSCALL_NO_MIPS_O32) : \
+ (MPROTECT_SYSCALL_NO_MIPS_N32)) : \
+ (MPROTECT_SYSCALL_NO_MIPS_N64))
+#define MUNMAP_SYSCALL_NO(tsk) ((test_tsk_thread_flag((tsk), TIF_32BIT_ADDR)) ? \
+ ((test_tsk_thread_flag((tsk), TIF_32BIT_REGS)) ? \
+ (MUNMAP_SYSCALL_NO_MIPS_O32) : \
+ (MUNMAP_SYSCALL_NO_MIPS_N32)) : \
+ (MUNMAP_SYSCALL_NO_MIPS_N64))
+#define MREMAP_SYSCALL_NO(tsk) ((test_tsk_thread_flag((tsk), TIF_32BIT_ADDR)) ? \
+ ((test_tsk_thread_flag((tsk), TIF_32BIT_REGS)) ? \
+ (MREMAP_SYSCALL_NO_MIPS_O32) : \
+ (MREMAP_SYSCALL_NO_MIPS_N32)) : \
+ (MREMAP_SYSCALL_NO_MIPS_N64))
+#endif
+
#if defined(__s390__) || defined(__s390x__)
#define MMAP_SYSCALL_NO(tsk) 90
#define MMAP2_SYSCALL_NO(tsk) 192
{
return regs->ARM_r7;
}
+
+#elif defined(__mips__)
+/* Define our own function as syscall_get_nr always returns 0 unless
+ * ftrace syscall tracing has been enabled */
+static inline long
+_stp_syscall_get_nr(struct task_struct *task, struct pt_regs *regs)
+{
+ return regs->regs[2];
+}
+
#else
#define _stp_syscall_get_nr syscall_get_nr
#endif
}
#endif
+#if defined(__mips__)
+static inline long
+_stp_syscall_get_nr(struct task_struct *task, struct pt_regs *regs)
+{
+ return regs->regs[2];
+}
+#endif
+
#if defined(__ia64__)
static inline long
_stp_syscall_get_nr(struct task_struct *task, struct pt_regs *regs)