]>
Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* kernel/perfmon_fsl_booke.c |
2 | * Freescale Book-E Performance Monitor code | |
3 | * | |
4 | * Author: Andy Fleming | |
5 | * Copyright (c) 2004 Freescale Semiconductor, Inc | |
6 | * | |
7 | * This program is free software; you can redistribute it and/or | |
8 | * modify it under the terms of the GNU General Public License | |
9 | * as published by the Free Software Foundation; either version | |
10 | * 2 of the License, or (at your option) any later version. | |
11 | */ | |
12 | ||
13 | #include <linux/errno.h> | |
14 | #include <linux/sched.h> | |
15 | #include <linux/kernel.h> | |
16 | #include <linux/mm.h> | |
17 | #include <linux/stddef.h> | |
18 | #include <linux/unistd.h> | |
19 | #include <linux/ptrace.h> | |
20 | #include <linux/slab.h> | |
21 | #include <linux/user.h> | |
22 | #include <linux/a.out.h> | |
23 | #include <linux/interrupt.h> | |
1da177e4 LT |
24 | #include <linux/init.h> |
25 | #include <linux/module.h> | |
26 | #include <linux/prctl.h> | |
27 | ||
28 | #include <asm/pgtable.h> | |
29 | #include <asm/uaccess.h> | |
30 | #include <asm/system.h> | |
31 | #include <asm/io.h> | |
32 | #include <asm/reg.h> | |
33 | #include <asm/xmon.h> | |
f7f6f4fe | 34 | #include <asm/pmc.h> |
1da177e4 LT |
35 | |
36 | static inline u32 get_pmlca(int ctr); | |
37 | static inline void set_pmlca(int ctr, u32 pmlca); | |
38 | ||
39 | static inline u32 get_pmlca(int ctr) | |
40 | { | |
41 | u32 pmlca; | |
42 | ||
43 | switch (ctr) { | |
44 | case 0: | |
45 | pmlca = mfpmr(PMRN_PMLCA0); | |
46 | break; | |
47 | case 1: | |
48 | pmlca = mfpmr(PMRN_PMLCA1); | |
49 | break; | |
50 | case 2: | |
51 | pmlca = mfpmr(PMRN_PMLCA2); | |
52 | break; | |
53 | case 3: | |
54 | pmlca = mfpmr(PMRN_PMLCA3); | |
55 | break; | |
56 | default: | |
57 | panic("Bad ctr number\n"); | |
58 | } | |
59 | ||
60 | return pmlca; | |
61 | } | |
62 | ||
63 | static inline void set_pmlca(int ctr, u32 pmlca) | |
64 | { | |
65 | switch (ctr) { | |
66 | case 0: | |
67 | mtpmr(PMRN_PMLCA0, pmlca); | |
68 | break; | |
69 | case 1: | |
70 | mtpmr(PMRN_PMLCA1, pmlca); | |
71 | break; | |
72 | case 2: | |
73 | mtpmr(PMRN_PMLCA2, pmlca); | |
74 | break; | |
75 | case 3: | |
76 | mtpmr(PMRN_PMLCA3, pmlca); | |
77 | break; | |
78 | default: | |
79 | panic("Bad ctr number\n"); | |
80 | } | |
81 | } | |
82 | ||
83 | void init_pmc_stop(int ctr) | |
84 | { | |
85 | u32 pmlca = (PMLCA_FC | PMLCA_FCS | PMLCA_FCU | | |
86 | PMLCA_FCM1 | PMLCA_FCM0); | |
87 | u32 pmlcb = 0; | |
88 | ||
89 | switch (ctr) { | |
90 | case 0: | |
91 | mtpmr(PMRN_PMLCA0, pmlca); | |
92 | mtpmr(PMRN_PMLCB0, pmlcb); | |
93 | break; | |
94 | case 1: | |
95 | mtpmr(PMRN_PMLCA1, pmlca); | |
96 | mtpmr(PMRN_PMLCB1, pmlcb); | |
97 | break; | |
98 | case 2: | |
99 | mtpmr(PMRN_PMLCA2, pmlca); | |
100 | mtpmr(PMRN_PMLCB2, pmlcb); | |
101 | break; | |
102 | case 3: | |
103 | mtpmr(PMRN_PMLCA3, pmlca); | |
104 | mtpmr(PMRN_PMLCB3, pmlcb); | |
105 | break; | |
106 | default: | |
107 | panic("Bad ctr number!\n"); | |
108 | } | |
109 | } | |
110 | ||
111 | void set_pmc_event(int ctr, int event) | |
112 | { | |
113 | u32 pmlca; | |
114 | ||
115 | pmlca = get_pmlca(ctr); | |
116 | ||
117 | pmlca = (pmlca & ~PMLCA_EVENT_MASK) | | |
118 | ((event << PMLCA_EVENT_SHIFT) & | |
119 | PMLCA_EVENT_MASK); | |
120 | ||
121 | set_pmlca(ctr, pmlca); | |
122 | } | |
123 | ||
124 | void set_pmc_user_kernel(int ctr, int user, int kernel) | |
125 | { | |
126 | u32 pmlca; | |
127 | ||
128 | pmlca = get_pmlca(ctr); | |
129 | ||
130 | if(user) | |
131 | pmlca &= ~PMLCA_FCU; | |
132 | else | |
133 | pmlca |= PMLCA_FCU; | |
134 | ||
135 | if(kernel) | |
136 | pmlca &= ~PMLCA_FCS; | |
137 | else | |
138 | pmlca |= PMLCA_FCS; | |
139 | ||
140 | set_pmlca(ctr, pmlca); | |
141 | } | |
142 | ||
143 | void set_pmc_marked(int ctr, int mark0, int mark1) | |
144 | { | |
145 | u32 pmlca = get_pmlca(ctr); | |
146 | ||
147 | if(mark0) | |
148 | pmlca &= ~PMLCA_FCM0; | |
149 | else | |
150 | pmlca |= PMLCA_FCM0; | |
151 | ||
152 | if(mark1) | |
153 | pmlca &= ~PMLCA_FCM1; | |
154 | else | |
155 | pmlca |= PMLCA_FCM1; | |
156 | ||
157 | set_pmlca(ctr, pmlca); | |
158 | } | |
159 | ||
160 | void pmc_start_ctr(int ctr, int enable) | |
161 | { | |
162 | u32 pmlca = get_pmlca(ctr); | |
163 | ||
164 | pmlca &= ~PMLCA_FC; | |
165 | ||
166 | if (enable) | |
167 | pmlca |= PMLCA_CE; | |
168 | else | |
169 | pmlca &= ~PMLCA_CE; | |
170 | ||
171 | set_pmlca(ctr, pmlca); | |
172 | } | |
173 | ||
174 | void pmc_start_ctrs(int enable) | |
175 | { | |
176 | u32 pmgc0 = mfpmr(PMRN_PMGC0); | |
177 | ||
178 | pmgc0 &= ~PMGC0_FAC; | |
179 | pmgc0 |= PMGC0_FCECE; | |
180 | ||
181 | if (enable) | |
182 | pmgc0 |= PMGC0_PMIE; | |
183 | else | |
184 | pmgc0 &= ~PMGC0_PMIE; | |
185 | ||
186 | mtpmr(PMRN_PMGC0, pmgc0); | |
187 | } | |
188 | ||
189 | void pmc_stop_ctrs(void) | |
190 | { | |
191 | u32 pmgc0 = mfpmr(PMRN_PMGC0); | |
192 | ||
193 | pmgc0 |= PMGC0_FAC; | |
194 | ||
195 | pmgc0 &= ~(PMGC0_PMIE | PMGC0_FCECE); | |
196 | ||
197 | mtpmr(PMRN_PMGC0, pmgc0); | |
198 | } | |
199 | ||
200 | void dump_pmcs(void) | |
201 | { | |
202 | printk("pmgc0: %x\n", mfpmr(PMRN_PMGC0)); | |
203 | printk("pmc\t\tpmlca\t\tpmlcb\n"); | |
204 | printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC0), | |
205 | mfpmr(PMRN_PMLCA0), mfpmr(PMRN_PMLCB0)); | |
206 | printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC1), | |
207 | mfpmr(PMRN_PMLCA1), mfpmr(PMRN_PMLCB1)); | |
208 | printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC2), | |
209 | mfpmr(PMRN_PMLCA2), mfpmr(PMRN_PMLCB2)); | |
210 | printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC3), | |
211 | mfpmr(PMRN_PMLCA3), mfpmr(PMRN_PMLCB3)); | |
212 | } | |
213 | ||
214 | EXPORT_SYMBOL(init_pmc_stop); | |
215 | EXPORT_SYMBOL(set_pmc_event); | |
216 | EXPORT_SYMBOL(set_pmc_user_kernel); | |
217 | EXPORT_SYMBOL(set_pmc_marked); | |
218 | EXPORT_SYMBOL(pmc_start_ctr); | |
219 | EXPORT_SYMBOL(pmc_start_ctrs); | |
220 | EXPORT_SYMBOL(pmc_stop_ctrs); | |
221 | EXPORT_SYMBOL(dump_pmcs); |