linux/arch/mips/oprofile/common.c
<<
>>
Prefs
   1/*
   2 * This file is subject to the terms and conditions of the GNU General Public
   3 * License.  See the file "COPYING" in the main directory of this archive
   4 * for more details.
   5 *
   6 * Copyright (C) 2004, 2005 Ralf Baechle
   7 * Copyright (C) 2005 MIPS Technologies, Inc.
   8 */
   9#include <linux/compiler.h>
  10#include <linux/errno.h>
  11#include <linux/init.h>
  12#include <linux/oprofile.h>
  13#include <linux/smp.h>
  14#include <asm/cpu-info.h>
  15#include <asm/cpu-type.h>
  16
  17#include "op_impl.h"
  18
  19extern struct op_mips_model op_model_mipsxx_ops __weak;
  20extern struct op_mips_model op_model_loongson2_ops __weak;
  21extern struct op_mips_model op_model_loongson3_ops __weak;
  22
  23static struct op_mips_model *model;
  24
  25static struct op_counter_config ctr[20];
  26
  27static int op_mips_setup(void)
  28{
  29        /* Pre-compute the values to stuff in the hardware registers.  */
  30        model->reg_setup(ctr);
  31
  32        /* Configure the registers on all cpus.  */
  33        on_each_cpu(model->cpu_setup, NULL, 1);
  34
  35        return 0;
  36}
  37
  38static int op_mips_create_files(struct dentry *root)
  39{
  40        int i;
  41
  42        for (i = 0; i < model->num_counters; ++i) {
  43                struct dentry *dir;
  44                char buf[4];
  45
  46                snprintf(buf, sizeof buf, "%d", i);
  47                dir = oprofilefs_mkdir(root, buf);
  48
  49                oprofilefs_create_ulong(dir, "enabled", &ctr[i].enabled);
  50                oprofilefs_create_ulong(dir, "event", &ctr[i].event);
  51                oprofilefs_create_ulong(dir, "count", &ctr[i].count);
  52                oprofilefs_create_ulong(dir, "kernel", &ctr[i].kernel);
  53                oprofilefs_create_ulong(dir, "user", &ctr[i].user);
  54                oprofilefs_create_ulong(dir, "exl", &ctr[i].exl);
  55                /* Dummy.  */
  56                oprofilefs_create_ulong(dir, "unit_mask", &ctr[i].unit_mask);
  57        }
  58
  59        return 0;
  60}
  61
  62static int op_mips_start(void)
  63{
  64        on_each_cpu(model->cpu_start, NULL, 1);
  65
  66        return 0;
  67}
  68
  69static void op_mips_stop(void)
  70{
  71        /* Disable performance monitoring for all counters.  */
  72        on_each_cpu(model->cpu_stop, NULL, 1);
  73}
  74
  75int __init oprofile_arch_init(struct oprofile_operations *ops)
  76{
  77        struct op_mips_model *lmodel = NULL;
  78        int res;
  79
  80        switch (boot_cpu_type()) {
  81        case CPU_5KC:
  82        case CPU_M14KC:
  83        case CPU_M14KEC:
  84        case CPU_20KC:
  85        case CPU_24K:
  86        case CPU_25KF:
  87        case CPU_34K:
  88        case CPU_1004K:
  89        case CPU_74K:
  90        case CPU_1074K:
  91        case CPU_INTERAPTIV:
  92        case CPU_PROAPTIV:
  93        case CPU_P5600:
  94        case CPU_I6400:
  95        case CPU_M5150:
  96        case CPU_LOONGSON1:
  97        case CPU_SB1:
  98        case CPU_SB1A:
  99        case CPU_R10000:
 100        case CPU_R12000:
 101        case CPU_R14000:
 102        case CPU_R16000:
 103        case CPU_XLR:
 104                lmodel = &op_model_mipsxx_ops;
 105                break;
 106
 107        case CPU_LOONGSON2:
 108                lmodel = &op_model_loongson2_ops;
 109                break;
 110        case CPU_LOONGSON3:
 111                lmodel = &op_model_loongson3_ops;
 112                break;
 113        };
 114
 115        /*
 116         * Always set the backtrace. This allows unsupported CPU types to still
 117         * use timer-based oprofile.
 118         */
 119        ops->backtrace = op_mips_backtrace;
 120
 121        if (!lmodel)
 122                return -ENODEV;
 123
 124        res = lmodel->init();
 125        if (res)
 126                return res;
 127
 128        model = lmodel;
 129
 130        ops->create_files       = op_mips_create_files;
 131        ops->setup              = op_mips_setup;
 132        //ops->shutdown         = op_mips_shutdown;
 133        ops->start              = op_mips_start;
 134        ops->stop               = op_mips_stop;
 135        ops->cpu_type           = lmodel->cpu_type;
 136
 137        printk(KERN_INFO "oprofile: using %s performance monitoring.\n",
 138               lmodel->cpu_type);
 139
 140        return 0;
 141}
 142
 143void oprofile_arch_exit(void)
 144{
 145        if (model)
 146                model->exit();
 147}
 148