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
  16#include "op_impl.h"
  17
  18extern struct op_mips_model op_model_mipsxx_ops __weak;
  19extern struct op_mips_model op_model_loongson2_ops __weak;
  20
  21static struct op_mips_model *model;
  22
  23static struct op_counter_config ctr[20];
  24
  25static int op_mips_setup(void)
  26{
  27        /* Pre-compute the values to stuff in the hardware registers.  */
  28        model->reg_setup(ctr);
  29
  30        /* Configure the registers on all cpus.  */
  31        on_each_cpu(model->cpu_setup, NULL, 1);
  32
  33        return 0;
  34}
  35
  36static int op_mips_create_files(struct super_block *sb, struct dentry *root)
  37{
  38        int i;
  39
  40        for (i = 0; i < model->num_counters; ++i) {
  41                struct dentry *dir;
  42                char buf[4];
  43
  44                snprintf(buf, sizeof buf, "%d", i);
  45                dir = oprofilefs_mkdir(sb, root, buf);
  46
  47                oprofilefs_create_ulong(sb, dir, "enabled", &ctr[i].enabled);
  48                oprofilefs_create_ulong(sb, dir, "event", &ctr[i].event);
  49                oprofilefs_create_ulong(sb, dir, "count", &ctr[i].count);
  50                oprofilefs_create_ulong(sb, dir, "kernel", &ctr[i].kernel);
  51                oprofilefs_create_ulong(sb, dir, "user", &ctr[i].user);
  52                oprofilefs_create_ulong(sb, dir, "exl", &ctr[i].exl);
  53                /* Dummy.  */
  54                oprofilefs_create_ulong(sb, dir, "unit_mask", &ctr[i].unit_mask);
  55        }
  56
  57        return 0;
  58}
  59
  60static int op_mips_start(void)
  61{
  62        on_each_cpu(model->cpu_start, NULL, 1);
  63
  64        return 0;
  65}
  66
  67static void op_mips_stop(void)
  68{
  69        /* Disable performance monitoring for all counters.  */
  70        on_each_cpu(model->cpu_stop, NULL, 1);
  71}
  72
  73int __init oprofile_arch_init(struct oprofile_operations *ops)
  74{
  75        struct op_mips_model *lmodel = NULL;
  76        int res;
  77
  78        switch (current_cpu_type()) {
  79        case CPU_5KC:
  80        case CPU_M14KC:
  81        case CPU_M14KEC:
  82        case CPU_20KC:
  83        case CPU_24K:
  84        case CPU_25KF:
  85        case CPU_34K:
  86        case CPU_1004K:
  87        case CPU_74K:
  88        case CPU_LOONGSON1:
  89        case CPU_SB1:
  90        case CPU_SB1A:
  91        case CPU_R10000:
  92        case CPU_R12000:
  93        case CPU_R14000:
  94        case CPU_XLR:
  95                lmodel = &op_model_mipsxx_ops;
  96                break;
  97
  98        case CPU_LOONGSON2:
  99                lmodel = &op_model_loongson2_ops;
 100                break;
 101        };
 102
 103        if (!lmodel)
 104                return -ENODEV;
 105
 106        res = lmodel->init();
 107        if (res)
 108                return res;
 109
 110        model = lmodel;
 111
 112        ops->create_files       = op_mips_create_files;
 113        ops->setup              = op_mips_setup;
 114        //ops->shutdown         = op_mips_shutdown;
 115        ops->start              = op_mips_start;
 116        ops->stop               = op_mips_stop;
 117        ops->cpu_type           = lmodel->cpu_type;
 118        ops->backtrace          = op_mips_backtrace;
 119
 120        printk(KERN_INFO "oprofile: using %s performance monitoring.\n",
 121               lmodel->cpu_type);
 122
 123        return 0;
 124}
 125
 126void oprofile_arch_exit(void)
 127{
 128        if (model)
 129                model->exit();
 130}
 131