Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
common.c
Go to the documentation of this file.
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 
21 
22 static struct op_mips_model *model;
23 
24 static struct op_counter_config ctr[20];
25 
26 static int op_mips_setup(void)
27 {
28  /* Pre-compute the values to stuff in the hardware registers. */
29  model->reg_setup(ctr);
30 
31  /* Configure the registers on all cpus. */
32  on_each_cpu(model->cpu_setup, NULL, 1);
33 
34  return 0;
35 }
36 
37 static int op_mips_create_files(struct super_block *sb, struct dentry *root)
38 {
39  int i;
40 
41  for (i = 0; i < model->num_counters; ++i) {
42  struct dentry *dir;
43  char buf[4];
44 
45  snprintf(buf, sizeof buf, "%d", i);
46  dir = oprofilefs_mkdir(sb, root, buf);
47 
48  oprofilefs_create_ulong(sb, dir, "enabled", &ctr[i].enabled);
49  oprofilefs_create_ulong(sb, dir, "event", &ctr[i].event);
50  oprofilefs_create_ulong(sb, dir, "count", &ctr[i].count);
51  oprofilefs_create_ulong(sb, dir, "kernel", &ctr[i].kernel);
52  oprofilefs_create_ulong(sb, dir, "user", &ctr[i].user);
53  oprofilefs_create_ulong(sb, dir, "exl", &ctr[i].exl);
54  /* Dummy. */
55  oprofilefs_create_ulong(sb, dir, "unit_mask", &ctr[i].unit_mask);
56  }
57 
58  return 0;
59 }
60 
61 static int op_mips_start(void)
62 {
63  on_each_cpu(model->cpu_start, NULL, 1);
64 
65  return 0;
66 }
67 
68 static void op_mips_stop(void)
69 {
70  /* Disable performance monitoring for all counters. */
71  on_each_cpu(model->cpu_stop, NULL, 1);
72 }
73 
75 {
76  struct op_mips_model *lmodel = NULL;
77  int res;
78 
79  switch (current_cpu_type()) {
80  case CPU_5KC:
81  case CPU_M14KC:
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  lmodel = &op_model_mipsxx_ops;
95  break;
96 
97  case CPU_RM9000:
98  lmodel = &op_model_rm9000_ops;
99  break;
100  case CPU_LOONGSON2:
101  lmodel = &op_model_loongson2_ops;
102  break;
103  };
104 
105  if (!lmodel)
106  return -ENODEV;
107 
108  res = lmodel->init();
109  if (res)
110  return res;
111 
112  model = lmodel;
113 
114  ops->create_files = op_mips_create_files;
115  ops->setup = op_mips_setup;
116  //ops->shutdown = op_mips_shutdown;
117  ops->start = op_mips_start;
118  ops->stop = op_mips_stop;
119  ops->cpu_type = lmodel->cpu_type;
121 
122  printk(KERN_INFO "oprofile: using %s performance monitoring.\n",
123  lmodel->cpu_type);
124 
125  return 0;
126 }
127 
129 {
130  if (model)
131  model->exit();
132 }