Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/mips/oprofile/common.c
10817 views
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
18
extern struct op_mips_model op_model_mipsxx_ops __weak;
19
extern struct op_mips_model op_model_rm9000_ops __weak;
20
extern struct op_mips_model op_model_loongson2_ops __weak;
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
74
int __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_20KC:
82
case CPU_24K:
83
case CPU_25KF:
84
case CPU_34K:
85
case CPU_1004K:
86
case CPU_74K:
87
case CPU_SB1:
88
case CPU_SB1A:
89
case CPU_R10000:
90
case CPU_R12000:
91
case CPU_R14000:
92
lmodel = &op_model_mipsxx_ops;
93
break;
94
95
case CPU_RM9000:
96
lmodel = &op_model_rm9000_ops;
97
break;
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
119
printk(KERN_INFO "oprofile: using %s performance monitoring.\n",
120
lmodel->cpu_type);
121
122
return 0;
123
}
124
125
void oprofile_arch_exit(void)
126
{
127
if (model)
128
model->exit();
129
}
130
131