• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/arch/mips/oprofile/
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_rm9000_ops __weak;
20extern struct op_mips_model op_model_loongson2_ops __weak;
21
22static struct op_mips_model *model;
23
24static struct op_counter_config ctr[20];
25
26static 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
37static 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
61static int op_mips_start(void)
62{
63	on_each_cpu(model->cpu_start, NULL, 1);
64
65	return 0;
66}
67
68static void op_mips_stop(void)
69{
70	/* Disable performance monitoring for all counters.  */
71	on_each_cpu(model->cpu_stop, NULL, 1);
72}
73
74int __init oprofile_arch_init(struct oprofile_operations *ops)
75{
76	struct op_mips_model *lmodel = NULL;
77	int res;
78
79	switch (current_cpu_type()) {
80	case CPU_5KC:
81	case CPU_14K:
82	case CPU_14KE:
83	case CPU_20KC:
84	case CPU_24K:
85	case CPU_25KF:
86	case CPU_34K:
87	case CPU_1004K:
88	case CPU_1074K:
89	case CPU_74K:
90	case CPU_SB1:
91	case CPU_SB1A:
92	case CPU_R10000:
93	case CPU_R12000:
94	case CPU_R14000:
95		lmodel = &op_model_mipsxx_ops;
96		break;
97
98	case CPU_RM9000:
99		lmodel = &op_model_rm9000_ops;
100		break;
101	case CPU_LOONGSON2:
102		lmodel = &op_model_loongson2_ops;
103		break;
104	};
105
106	if (!lmodel)
107		return -ENODEV;
108
109	res = lmodel->init();
110	if (res)
111		return res;
112
113	model = lmodel;
114
115	ops->create_files	= op_mips_create_files;
116	ops->setup		= op_mips_setup;
117	//ops->shutdown         = op_mips_shutdown;
118	ops->start		= op_mips_start;
119	ops->stop		= op_mips_stop;
120	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
128void oprofile_arch_exit(void)
129{
130	if (model)
131		model->exit();
132}
133