diff options
Diffstat (limited to 'arch/powerpc')
-rw-r--r-- | arch/powerpc/kernel/Makefile | 1 | ||||
-rw-r--r-- | arch/powerpc/kernel/perfmon_fsl_booke.c | 222 |
2 files changed, 223 insertions, 0 deletions
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index b86d380f01b4..0cc0995b81b0 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile | |||
@@ -38,6 +38,7 @@ obj-$(CONFIG_6xx) += idle_6xx.o l2cr_6xx.o cpu_setup_6xx.o | |||
38 | obj-$(CONFIG_TAU) += tau_6xx.o | 38 | obj-$(CONFIG_TAU) += tau_6xx.o |
39 | obj32-$(CONFIG_SOFTWARE_SUSPEND) += swsusp_32.o | 39 | obj32-$(CONFIG_SOFTWARE_SUSPEND) += swsusp_32.o |
40 | obj32-$(CONFIG_MODULES) += module_32.o | 40 | obj32-$(CONFIG_MODULES) += module_32.o |
41 | obj-$(CONFIG_E500) += perfmon_fsl_booke.o | ||
41 | 42 | ||
42 | ifeq ($(CONFIG_PPC_MERGE),y) | 43 | ifeq ($(CONFIG_PPC_MERGE),y) |
43 | 44 | ||
diff --git a/arch/powerpc/kernel/perfmon_fsl_booke.c b/arch/powerpc/kernel/perfmon_fsl_booke.c new file mode 100644 index 000000000000..32455dfcc36b --- /dev/null +++ b/arch/powerpc/kernel/perfmon_fsl_booke.c | |||
@@ -0,0 +1,222 @@ | |||
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> | ||
24 | #include <linux/config.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/module.h> | ||
27 | #include <linux/prctl.h> | ||
28 | |||
29 | #include <asm/pgtable.h> | ||
30 | #include <asm/uaccess.h> | ||
31 | #include <asm/system.h> | ||
32 | #include <asm/io.h> | ||
33 | #include <asm/reg.h> | ||
34 | #include <asm/xmon.h> | ||
35 | #include <asm/pmc.h> | ||
36 | |||
37 | static inline u32 get_pmlca(int ctr); | ||
38 | static inline void set_pmlca(int ctr, u32 pmlca); | ||
39 | |||
40 | static inline u32 get_pmlca(int ctr) | ||
41 | { | ||
42 | u32 pmlca; | ||
43 | |||
44 | switch (ctr) { | ||
45 | case 0: | ||
46 | pmlca = mfpmr(PMRN_PMLCA0); | ||
47 | break; | ||
48 | case 1: | ||
49 | pmlca = mfpmr(PMRN_PMLCA1); | ||
50 | break; | ||
51 | case 2: | ||
52 | pmlca = mfpmr(PMRN_PMLCA2); | ||
53 | break; | ||
54 | case 3: | ||
55 | pmlca = mfpmr(PMRN_PMLCA3); | ||
56 | break; | ||
57 | default: | ||
58 | panic("Bad ctr number\n"); | ||
59 | } | ||
60 | |||
61 | return pmlca; | ||
62 | } | ||
63 | |||
64 | static inline void set_pmlca(int ctr, u32 pmlca) | ||
65 | { | ||
66 | switch (ctr) { | ||
67 | case 0: | ||
68 | mtpmr(PMRN_PMLCA0, pmlca); | ||
69 | break; | ||
70 | case 1: | ||
71 | mtpmr(PMRN_PMLCA1, pmlca); | ||
72 | break; | ||
73 | case 2: | ||
74 | mtpmr(PMRN_PMLCA2, pmlca); | ||
75 | break; | ||
76 | case 3: | ||
77 | mtpmr(PMRN_PMLCA3, pmlca); | ||
78 | break; | ||
79 | default: | ||
80 | panic("Bad ctr number\n"); | ||
81 | } | ||
82 | } | ||
83 | |||
84 | void init_pmc_stop(int ctr) | ||
85 | { | ||
86 | u32 pmlca = (PMLCA_FC | PMLCA_FCS | PMLCA_FCU | | ||
87 | PMLCA_FCM1 | PMLCA_FCM0); | ||
88 | u32 pmlcb = 0; | ||
89 | |||
90 | switch (ctr) { | ||
91 | case 0: | ||
92 | mtpmr(PMRN_PMLCA0, pmlca); | ||
93 | mtpmr(PMRN_PMLCB0, pmlcb); | ||
94 | break; | ||
95 | case 1: | ||
96 | mtpmr(PMRN_PMLCA1, pmlca); | ||
97 | mtpmr(PMRN_PMLCB1, pmlcb); | ||
98 | break; | ||
99 | case 2: | ||
100 | mtpmr(PMRN_PMLCA2, pmlca); | ||
101 | mtpmr(PMRN_PMLCB2, pmlcb); | ||
102 | break; | ||
103 | case 3: | ||
104 | mtpmr(PMRN_PMLCA3, pmlca); | ||
105 | mtpmr(PMRN_PMLCB3, pmlcb); | ||
106 | break; | ||
107 | default: | ||
108 | panic("Bad ctr number!\n"); | ||
109 | } | ||
110 | } | ||
111 | |||
112 | void set_pmc_event(int ctr, int event) | ||
113 | { | ||
114 | u32 pmlca; | ||
115 | |||
116 | pmlca = get_pmlca(ctr); | ||
117 | |||
118 | pmlca = (pmlca & ~PMLCA_EVENT_MASK) | | ||
119 | ((event << PMLCA_EVENT_SHIFT) & | ||
120 | PMLCA_EVENT_MASK); | ||
121 | |||
122 | set_pmlca(ctr, pmlca); | ||
123 | } | ||
124 | |||
125 | void set_pmc_user_kernel(int ctr, int user, int kernel) | ||
126 | { | ||
127 | u32 pmlca; | ||
128 | |||
129 | pmlca = get_pmlca(ctr); | ||
130 | |||
131 | if(user) | ||
132 | pmlca &= ~PMLCA_FCU; | ||
133 | else | ||
134 | pmlca |= PMLCA_FCU; | ||
135 | |||
136 | if(kernel) | ||
137 | pmlca &= ~PMLCA_FCS; | ||
138 | else | ||
139 | pmlca |= PMLCA_FCS; | ||
140 | |||
141 | set_pmlca(ctr, pmlca); | ||
142 | } | ||
143 | |||
144 | void set_pmc_marked(int ctr, int mark0, int mark1) | ||
145 | { | ||
146 | u32 pmlca = get_pmlca(ctr); | ||
147 | |||
148 | if(mark0) | ||
149 | pmlca &= ~PMLCA_FCM0; | ||
150 | else | ||
151 | pmlca |= PMLCA_FCM0; | ||
152 | |||
153 | if(mark1) | ||
154 | pmlca &= ~PMLCA_FCM1; | ||
155 | else | ||
156 | pmlca |= PMLCA_FCM1; | ||
157 | |||
158 | set_pmlca(ctr, pmlca); | ||
159 | } | ||
160 | |||
161 | void pmc_start_ctr(int ctr, int enable) | ||
162 | { | ||
163 | u32 pmlca = get_pmlca(ctr); | ||
164 | |||
165 | pmlca &= ~PMLCA_FC; | ||
166 | |||
167 | if (enable) | ||
168 | pmlca |= PMLCA_CE; | ||
169 | else | ||
170 | pmlca &= ~PMLCA_CE; | ||
171 | |||
172 | set_pmlca(ctr, pmlca); | ||
173 | } | ||
174 | |||
175 | void pmc_start_ctrs(int enable) | ||
176 | { | ||
177 | u32 pmgc0 = mfpmr(PMRN_PMGC0); | ||
178 | |||
179 | pmgc0 &= ~PMGC0_FAC; | ||
180 | pmgc0 |= PMGC0_FCECE; | ||
181 | |||
182 | if (enable) | ||
183 | pmgc0 |= PMGC0_PMIE; | ||
184 | else | ||
185 | pmgc0 &= ~PMGC0_PMIE; | ||
186 | |||
187 | mtpmr(PMRN_PMGC0, pmgc0); | ||
188 | } | ||
189 | |||
190 | void pmc_stop_ctrs(void) | ||
191 | { | ||
192 | u32 pmgc0 = mfpmr(PMRN_PMGC0); | ||
193 | |||
194 | pmgc0 |= PMGC0_FAC; | ||
195 | |||
196 | pmgc0 &= ~(PMGC0_PMIE | PMGC0_FCECE); | ||
197 | |||
198 | mtpmr(PMRN_PMGC0, pmgc0); | ||
199 | } | ||
200 | |||
201 | void dump_pmcs(void) | ||
202 | { | ||
203 | printk("pmgc0: %x\n", mfpmr(PMRN_PMGC0)); | ||
204 | printk("pmc\t\tpmlca\t\tpmlcb\n"); | ||
205 | printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC0), | ||
206 | mfpmr(PMRN_PMLCA0), mfpmr(PMRN_PMLCB0)); | ||
207 | printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC1), | ||
208 | mfpmr(PMRN_PMLCA1), mfpmr(PMRN_PMLCB1)); | ||
209 | printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC2), | ||
210 | mfpmr(PMRN_PMLCA2), mfpmr(PMRN_PMLCB2)); | ||
211 | printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC3), | ||
212 | mfpmr(PMRN_PMLCA3), mfpmr(PMRN_PMLCB3)); | ||
213 | } | ||
214 | |||
215 | EXPORT_SYMBOL(init_pmc_stop); | ||
216 | EXPORT_SYMBOL(set_pmc_event); | ||
217 | EXPORT_SYMBOL(set_pmc_user_kernel); | ||
218 | EXPORT_SYMBOL(set_pmc_marked); | ||
219 | EXPORT_SYMBOL(pmc_start_ctr); | ||
220 | EXPORT_SYMBOL(pmc_start_ctrs); | ||
221 | EXPORT_SYMBOL(pmc_stop_ctrs); | ||
222 | EXPORT_SYMBOL(dump_pmcs); | ||