aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/kernel/Makefile1
-rw-r--r--arch/powerpc/kernel/perfmon_fsl_booke.c221
-rw-r--r--arch/powerpc/kernel/pmc.c2
-rw-r--r--arch/powerpc/oprofile/Makefile2
-rw-r--r--arch/powerpc/oprofile/common.c10
-rw-r--r--arch/powerpc/oprofile/op_model_7450.c2
-rw-r--r--arch/powerpc/oprofile/op_model_fsl_booke.c170
-rw-r--r--arch/powerpc/oprofile/op_model_power4.c2
-rw-r--r--arch/powerpc/oprofile/op_model_rs64.c2
9 files changed, 149 insertions, 263 deletions
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 8b133afbdc20..7af23c43fd4b 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -38,7 +38,6 @@ obj-$(CONFIG_6xx) += idle_6xx.o l2cr_6xx.o cpu_setup_6xx.o
38obj-$(CONFIG_TAU) += tau_6xx.o 38obj-$(CONFIG_TAU) += tau_6xx.o
39obj32-$(CONFIG_SOFTWARE_SUSPEND) += swsusp_32.o 39obj32-$(CONFIG_SOFTWARE_SUSPEND) += swsusp_32.o
40obj32-$(CONFIG_MODULES) += module_32.o 40obj32-$(CONFIG_MODULES) += module_32.o
41obj-$(CONFIG_E500) += perfmon_fsl_booke.o
42 41
43ifeq ($(CONFIG_PPC_MERGE),y) 42ifeq ($(CONFIG_PPC_MERGE),y)
44 43
diff --git a/arch/powerpc/kernel/perfmon_fsl_booke.c b/arch/powerpc/kernel/perfmon_fsl_booke.c
deleted file mode 100644
index e0dcf2b41fbe..000000000000
--- a/arch/powerpc/kernel/perfmon_fsl_booke.c
+++ /dev/null
@@ -1,221 +0,0 @@
1/* arch/powerpc/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/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>
34#include <asm/pmc.h>
35
36static inline u32 get_pmlca(int ctr);
37static inline void set_pmlca(int ctr, u32 pmlca);
38
39static 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
63static 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
83void 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
111void 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
124void 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
143void 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
160void 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
174void 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
189void 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
200void 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
214EXPORT_SYMBOL(init_pmc_stop);
215EXPORT_SYMBOL(set_pmc_event);
216EXPORT_SYMBOL(set_pmc_user_kernel);
217EXPORT_SYMBOL(set_pmc_marked);
218EXPORT_SYMBOL(pmc_start_ctr);
219EXPORT_SYMBOL(pmc_start_ctrs);
220EXPORT_SYMBOL(pmc_stop_ctrs);
221EXPORT_SYMBOL(dump_pmcs);
diff --git a/arch/powerpc/kernel/pmc.c b/arch/powerpc/kernel/pmc.c
index a0a2efadeabf..3d8f6f44641e 100644
--- a/arch/powerpc/kernel/pmc.c
+++ b/arch/powerpc/kernel/pmc.c
@@ -71,7 +71,7 @@ int reserve_pmc_hardware(perf_irq_t new_perf_irq)
71 } 71 }
72 72
73 pmc_owner_caller = __builtin_return_address(0); 73 pmc_owner_caller = __builtin_return_address(0);
74 perf_irq = new_perf_irq ? : dummy_perf; 74 perf_irq = new_perf_irq ? new_perf_irq : dummy_perf;
75 75
76 out: 76 out:
77 spin_unlock(&pmc_owner_lock); 77 spin_unlock(&pmc_owner_lock);
diff --git a/arch/powerpc/oprofile/Makefile b/arch/powerpc/oprofile/Makefile
index 3145d610b5b0..0b5df9c96ae0 100644
--- a/arch/powerpc/oprofile/Makefile
+++ b/arch/powerpc/oprofile/Makefile
@@ -13,4 +13,4 @@ DRIVER_OBJS := $(addprefix ../../../drivers/oprofile/, \
13oprofile-y := $(DRIVER_OBJS) common.o backtrace.o 13oprofile-y := $(DRIVER_OBJS) common.o backtrace.o
14oprofile-$(CONFIG_PPC64) += op_model_rs64.o op_model_power4.o 14oprofile-$(CONFIG_PPC64) += op_model_rs64.o op_model_power4.o
15oprofile-$(CONFIG_FSL_BOOKE) += op_model_fsl_booke.o 15oprofile-$(CONFIG_FSL_BOOKE) += op_model_fsl_booke.o
16oprofile-$(CONFIG_PPC32) += op_model_7450.o 16oprofile-$(CONFIG_6xx) += op_model_7450.o
diff --git a/arch/powerpc/oprofile/common.c b/arch/powerpc/oprofile/common.c
index fd0bbbe7a4de..63bbef3b63f1 100644
--- a/arch/powerpc/oprofile/common.c
+++ b/arch/powerpc/oprofile/common.c
@@ -34,6 +34,11 @@ static void op_handle_interrupt(struct pt_regs *regs)
34 model->handle_interrupt(regs, ctr); 34 model->handle_interrupt(regs, ctr);
35} 35}
36 36
37static void op_powerpc_cpu_setup(void *dummy)
38{
39 model->cpu_setup(ctr);
40}
41
37static int op_powerpc_setup(void) 42static int op_powerpc_setup(void)
38{ 43{
39 int err; 44 int err;
@@ -47,7 +52,7 @@ static int op_powerpc_setup(void)
47 model->reg_setup(ctr, &sys, model->num_counters); 52 model->reg_setup(ctr, &sys, model->num_counters);
48 53
49 /* Configure the registers on all cpus. */ 54 /* Configure the registers on all cpus. */
50 on_each_cpu(model->cpu_setup, NULL, 0, 1); 55 on_each_cpu(op_powerpc_cpu_setup, NULL, 0, 1);
51 56
52 return 0; 57 return 0;
53} 58}
@@ -142,7 +147,8 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
142 case PPC_OPROFILE_POWER4: 147 case PPC_OPROFILE_POWER4:
143 model = &op_model_power4; 148 model = &op_model_power4;
144 break; 149 break;
145#else 150#endif
151#ifdef CONFIG_6xx
146 case PPC_OPROFILE_G4: 152 case PPC_OPROFILE_G4:
147 model = &op_model_7450; 153 model = &op_model_7450;
148 break; 154 break;
diff --git a/arch/powerpc/oprofile/op_model_7450.c b/arch/powerpc/oprofile/op_model_7450.c
index d8ee3aea83f8..f481c0ed5e67 100644
--- a/arch/powerpc/oprofile/op_model_7450.c
+++ b/arch/powerpc/oprofile/op_model_7450.c
@@ -81,7 +81,7 @@ static void pmc_stop_ctrs(void)
81 81
82/* Configures the counters on this CPU based on the global 82/* Configures the counters on this CPU based on the global
83 * settings */ 83 * settings */
84static void fsl7450_cpu_setup(void *unused) 84static void fsl7450_cpu_setup(struct op_counter_config *ctr)
85{ 85{
86 /* freeze all counters */ 86 /* freeze all counters */
87 pmc_stop_ctrs(); 87 pmc_stop_ctrs();
diff --git a/arch/powerpc/oprofile/op_model_fsl_booke.c b/arch/powerpc/oprofile/op_model_fsl_booke.c
index e29dede31423..0b3c31f5209e 100644
--- a/arch/powerpc/oprofile/op_model_fsl_booke.c
+++ b/arch/powerpc/oprofile/op_model_fsl_booke.c
@@ -32,42 +32,152 @@ static unsigned long reset_value[OP_MAX_COUNTER];
32static int num_counters; 32static int num_counters;
33static int oprofile_running; 33static int oprofile_running;
34 34
35static inline unsigned int ctr_read(unsigned int i) 35static void init_pmc_stop(int ctr)
36{ 36{
37 switch(i) { 37 u32 pmlca = (PMLCA_FC | PMLCA_FCS | PMLCA_FCU |
38 case 0: 38 PMLCA_FCM1 | PMLCA_FCM0);
39 return mfpmr(PMRN_PMC0); 39 u32 pmlcb = 0;
40 case 1:
41 return mfpmr(PMRN_PMC1);
42 case 2:
43 return mfpmr(PMRN_PMC2);
44 case 3:
45 return mfpmr(PMRN_PMC3);
46 default:
47 return 0;
48 }
49}
50 40
51static inline void ctr_write(unsigned int i, unsigned int val) 41 switch (ctr) {
52{
53 switch(i) {
54 case 0: 42 case 0:
55 mtpmr(PMRN_PMC0, val); 43 mtpmr(PMRN_PMLCA0, pmlca);
44 mtpmr(PMRN_PMLCB0, pmlcb);
56 break; 45 break;
57 case 1: 46 case 1:
58 mtpmr(PMRN_PMC1, val); 47 mtpmr(PMRN_PMLCA1, pmlca);
48 mtpmr(PMRN_PMLCB1, pmlcb);
59 break; 49 break;
60 case 2: 50 case 2:
61 mtpmr(PMRN_PMC2, val); 51 mtpmr(PMRN_PMLCA2, pmlca);
52 mtpmr(PMRN_PMLCB2, pmlcb);
62 break; 53 break;
63 case 3: 54 case 3:
64 mtpmr(PMRN_PMC3, val); 55 mtpmr(PMRN_PMLCA3, pmlca);
56 mtpmr(PMRN_PMLCB3, pmlcb);
65 break; 57 break;
66 default: 58 default:
67 break; 59 panic("Bad ctr number!\n");
68 } 60 }
69} 61}
70 62
63static void set_pmc_event(int ctr, int event)
64{
65 u32 pmlca;
66
67 pmlca = get_pmlca(ctr);
68
69 pmlca = (pmlca & ~PMLCA_EVENT_MASK) |
70 ((event << PMLCA_EVENT_SHIFT) &
71 PMLCA_EVENT_MASK);
72
73 set_pmlca(ctr, pmlca);
74}
75
76static void set_pmc_user_kernel(int ctr, int user, int kernel)
77{
78 u32 pmlca;
79
80 pmlca = get_pmlca(ctr);
81
82 if(user)
83 pmlca &= ~PMLCA_FCU;
84 else
85 pmlca |= PMLCA_FCU;
86
87 if(kernel)
88 pmlca &= ~PMLCA_FCS;
89 else
90 pmlca |= PMLCA_FCS;
91
92 set_pmlca(ctr, pmlca);
93}
94
95static void set_pmc_marked(int ctr, int mark0, int mark1)
96{
97 u32 pmlca = get_pmlca(ctr);
98
99 if(mark0)
100 pmlca &= ~PMLCA_FCM0;
101 else
102 pmlca |= PMLCA_FCM0;
103
104 if(mark1)
105 pmlca &= ~PMLCA_FCM1;
106 else
107 pmlca |= PMLCA_FCM1;
108
109 set_pmlca(ctr, pmlca);
110}
111
112static void pmc_start_ctr(int ctr, int enable)
113{
114 u32 pmlca = get_pmlca(ctr);
115
116 pmlca &= ~PMLCA_FC;
117
118 if (enable)
119 pmlca |= PMLCA_CE;
120 else
121 pmlca &= ~PMLCA_CE;
122
123 set_pmlca(ctr, pmlca);
124}
125
126static void pmc_start_ctrs(int enable)
127{
128 u32 pmgc0 = mfpmr(PMRN_PMGC0);
129
130 pmgc0 &= ~PMGC0_FAC;
131 pmgc0 |= PMGC0_FCECE;
132
133 if (enable)
134 pmgc0 |= PMGC0_PMIE;
135 else
136 pmgc0 &= ~PMGC0_PMIE;
137
138 mtpmr(PMRN_PMGC0, pmgc0);
139}
140
141static void pmc_stop_ctrs(void)
142{
143 u32 pmgc0 = mfpmr(PMRN_PMGC0);
144
145 pmgc0 |= PMGC0_FAC;
146
147 pmgc0 &= ~(PMGC0_PMIE | PMGC0_FCECE);
148
149 mtpmr(PMRN_PMGC0, pmgc0);
150}
151
152static void dump_pmcs(void)
153{
154 printk("pmgc0: %x\n", mfpmr(PMRN_PMGC0));
155 printk("pmc\t\tpmlca\t\tpmlcb\n");
156 printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC0),
157 mfpmr(PMRN_PMLCA0), mfpmr(PMRN_PMLCB0));
158 printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC1),
159 mfpmr(PMRN_PMLCA1), mfpmr(PMRN_PMLCB1));
160 printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC2),
161 mfpmr(PMRN_PMLCA2), mfpmr(PMRN_PMLCB2));
162 printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC3),
163 mfpmr(PMRN_PMLCA3), mfpmr(PMRN_PMLCB3));
164}
165
166static void fsl_booke_cpu_setup(struct op_counter_config *ctr)
167{
168 int i;
169
170 /* freeze all counters */
171 pmc_stop_ctrs();
172
173 for (i = 0;i < num_counters;i++) {
174 init_pmc_stop(i);
175
176 set_pmc_event(i, ctr[i].event);
177
178 set_pmc_user_kernel(i, ctr[i].user, ctr[i].kernel);
179 }
180}
71 181
72static void fsl_booke_reg_setup(struct op_counter_config *ctr, 182static void fsl_booke_reg_setup(struct op_counter_config *ctr,
73 struct op_system_config *sys, 183 struct op_system_config *sys,
@@ -77,23 +187,14 @@ static void fsl_booke_reg_setup(struct op_counter_config *ctr,
77 187
78 num_counters = num_ctrs; 188 num_counters = num_ctrs;
79 189
80 /* freeze all counters */
81 pmc_stop_ctrs();
82
83 /* Our counters count up, and "count" refers to 190 /* Our counters count up, and "count" refers to
84 * how much before the next interrupt, and we interrupt 191 * how much before the next interrupt, and we interrupt
85 * on overflow. So we calculate the starting value 192 * on overflow. So we calculate the starting value
86 * which will give us "count" until overflow. 193 * which will give us "count" until overflow.
87 * Then we set the events on the enabled counters */ 194 * Then we set the events on the enabled counters */
88 for (i = 0; i < num_counters; ++i) { 195 for (i = 0; i < num_counters; ++i)
89 reset_value[i] = 0x80000000UL - ctr[i].count; 196 reset_value[i] = 0x80000000UL - ctr[i].count;
90 197
91 init_pmc_stop(i);
92
93 set_pmc_event(i, ctr[i].event);
94
95 set_pmc_user_kernel(i, ctr[i].user, ctr[i].kernel);
96 }
97} 198}
98 199
99static void fsl_booke_start(struct op_counter_config *ctr) 200static void fsl_booke_start(struct op_counter_config *ctr)
@@ -105,8 +206,8 @@ static void fsl_booke_start(struct op_counter_config *ctr)
105 for (i = 0; i < num_counters; ++i) { 206 for (i = 0; i < num_counters; ++i) {
106 if (ctr[i].enabled) { 207 if (ctr[i].enabled) {
107 ctr_write(i, reset_value[i]); 208 ctr_write(i, reset_value[i]);
108 /* Set Each enabled counterd to only 209 /* Set each enabled counter to only
109 * count when the Mark bit is not set */ 210 * count when the Mark bit is *not* set */
110 set_pmc_marked(i, 1, 0); 211 set_pmc_marked(i, 1, 0);
111 pmc_start_ctr(i, 1); 212 pmc_start_ctr(i, 1);
112 } else { 213 } else {
@@ -177,6 +278,7 @@ static void fsl_booke_handle_interrupt(struct pt_regs *regs,
177 278
178struct op_powerpc_model op_model_fsl_booke = { 279struct op_powerpc_model op_model_fsl_booke = {
179 .reg_setup = fsl_booke_reg_setup, 280 .reg_setup = fsl_booke_reg_setup,
281 .cpu_setup = fsl_booke_cpu_setup,
180 .start = fsl_booke_start, 282 .start = fsl_booke_start,
181 .stop = fsl_booke_stop, 283 .stop = fsl_booke_stop,
182 .handle_interrupt = fsl_booke_handle_interrupt, 284 .handle_interrupt = fsl_booke_handle_interrupt,
diff --git a/arch/powerpc/oprofile/op_model_power4.c b/arch/powerpc/oprofile/op_model_power4.c
index 6a927effcc77..356709d515b9 100644
--- a/arch/powerpc/oprofile/op_model_power4.c
+++ b/arch/powerpc/oprofile/op_model_power4.c
@@ -82,7 +82,7 @@ static inline int mmcra_must_set_sample(void)
82 return 0; 82 return 0;
83} 83}
84 84
85static void power4_cpu_setup(void *unused) 85static void power4_cpu_setup(struct op_counter_config *ctr)
86{ 86{
87 unsigned int mmcr0 = mmcr0_val; 87 unsigned int mmcr0 = mmcr0_val;
88 unsigned long mmcra = mmcra_val; 88 unsigned long mmcra = mmcra_val;
diff --git a/arch/powerpc/oprofile/op_model_rs64.c b/arch/powerpc/oprofile/op_model_rs64.c
index 042f8f4867ad..19c5ee089bc9 100644
--- a/arch/powerpc/oprofile/op_model_rs64.c
+++ b/arch/powerpc/oprofile/op_model_rs64.c
@@ -102,7 +102,7 @@ static void rs64_reg_setup(struct op_counter_config *ctr,
102 /* XXX setup user and kernel profiling */ 102 /* XXX setup user and kernel profiling */
103} 103}
104 104
105static void rs64_cpu_setup(void *unused) 105static void rs64_cpu_setup(struct op_counter_config *ctr)
106{ 106{
107 unsigned int mmcr0; 107 unsigned int mmcr0;
108 108