fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / arch / mips / oprofile / op_model_mipsxx.c
index a175d67..455d76a 100644 (file)
@@ -3,12 +3,13 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2004, 2005 by Ralf Baechle
+ * Copyright (C) 2004, 05, 06 by Ralf Baechle
  * Copyright (C) 2005 by MIPS Technologies, Inc.
  */
 #include <linux/oprofile.h>
 #include <linux/interrupt.h>
 #include <linux/smp.h>
+#include <asm/irq_regs.h>
 
 #include "op_impl.h"
 
@@ -17,7 +18,7 @@
 #define M_PERFCTL_SUPERVISOR           (1UL      <<  2)
 #define M_PERFCTL_USER                 (1UL      <<  3)
 #define M_PERFCTL_INTERRUPT_ENABLE     (1UL      <<  4)
-#define M_PERFCTL_EVENT(event)         ((event)  << 5)
+#define M_PERFCTL_EVENT(event)         (((event) & 0x3f)  << 5)
 #define M_PERFCTL_VPEID(vpe)           ((vpe)    << 16)
 #define M_PERFCTL_MT_EN(filter)                ((filter) << 20)
 #define    M_TC_EN_ALL                 M_PERFCTL_MT_EN(0)
 #define M_COUNTER_OVERFLOW             (1UL      << 31)
 
 #ifdef CONFIG_MIPS_MT_SMP
-#define WHAT   (M_TC_EN_VPE | M_PERFCTL_VPEID(smp_processor_id()))
+#define WHAT           (M_TC_EN_VPE | M_PERFCTL_VPEID(smp_processor_id()))
+#define vpe_id()       smp_processor_id()
 #else
-#define WHAT   0
+#define WHAT           0
+#define vpe_id()       smp_processor_id()
 #endif
 
 #define __define_perf_accessors(r, n, np)                              \
                                                                        \
 static inline unsigned int r_c0_ ## r ## n(void)                       \
 {                                                                      \
-       unsigned int cpu = smp_processor_id();                          \
+       unsigned int cpu = vpe_id();                                    \
                                                                        \
        switch (cpu) {                                                  \
        case 0:                                                         \
@@ -54,7 +57,7 @@ static inline unsigned int r_c0_ ## r ## n(void)                      \
                                                                        \
 static inline void w_c0_ ## r ## n(unsigned int value)                 \
 {                                                                      \
-       unsigned int cpu = smp_processor_id();                          \
+       unsigned int cpu = vpe_id();                                    \
                                                                        \
        switch (cpu) {                                                  \
        case 0:                                                         \
@@ -170,7 +173,7 @@ static void mipsxx_cpu_stop(void *args)
        }
 }
 
-static int mipsxx_perfcount_handler(struct pt_regs *regs)
+static int mipsxx_perfcount_handler(void)
 {
        unsigned int counters = op_model_mipsxx_ops.num_counters;
        unsigned int control;
@@ -184,7 +187,7 @@ static int mipsxx_perfcount_handler(struct pt_regs *regs)
                counter = r_c0_perfcntr ## n();                         \
                if ((control & M_PERFCTL_INTERRUPT_ENABLE) &&           \
                    (counter & M_COUNTER_OVERFLOW)) {                   \
-                       oprofile_add_sample(regs, n);                   \
+                       oprofile_add_sample(get_irq_regs(), n);         \
                        w_c0_perfcntr ## n(reg.counter[n]);             \
                        handled = 1;                                    \
                }
@@ -215,13 +218,23 @@ static inline int __n_counters(void)
 
 static inline int n_counters(void)
 {
-       int counters = __n_counters();
+       int counters;
 
-#ifndef CONFIG_SMP
-       if (current_cpu_data.cputype == CPU_34K)
-               return counters >> 1;
-#endif
+       switch (current_cpu_data.cputype) {
+       case CPU_R10000:
+               counters = 2;
+
+       case CPU_R12000:
+       case CPU_R14000:
+               counters = 4;
+
+       default:
+               counters = __n_counters();
+       }
 
+#ifdef CONFIG_MIPS_MT_SMP
+       counters >> 1;
+#endif
        return counters;
 }
 
@@ -281,6 +294,18 @@ static int __init mipsxx_init(void)
                op_model_mipsxx_ops.cpu_type = "mips/5K";
                break;
 
+       case CPU_R10000:
+               if ((current_cpu_data.processor_id & 0xff) == 0x20)
+                       op_model_mipsxx_ops.cpu_type = "mips/r10000-v2.x";
+               else
+                       op_model_mipsxx_ops.cpu_type = "mips/r10000";
+               break;
+
+       case CPU_R12000:
+       case CPU_R14000:
+               op_model_mipsxx_ops.cpu_type = "mips/r12000";
+               break;
+
        case CPU_SB1:
        case CPU_SB1A:
                op_model_mipsxx_ops.cpu_type = "mips/sb1";