aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel/etm.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/kernel/etm.c')
-rw-r--r--arch/arm/kernel/etm.c473
1 files changed, 343 insertions, 130 deletions
diff --git a/arch/arm/kernel/etm.c b/arch/arm/kernel/etm.c
index 1bec8b5f22f..496b8b84e45 100644
--- a/arch/arm/kernel/etm.c
+++ b/arch/arm/kernel/etm.c
@@ -15,6 +15,7 @@
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/types.h> 16#include <linux/types.h>
17#include <linux/io.h> 17#include <linux/io.h>
18#include <linux/slab.h>
18#include <linux/sysrq.h> 19#include <linux/sysrq.h>
19#include <linux/device.h> 20#include <linux/device.h>
20#include <linux/clk.h> 21#include <linux/clk.h>
@@ -36,26 +37,36 @@ MODULE_AUTHOR("Alexander Shishkin");
36struct tracectx { 37struct tracectx {
37 unsigned int etb_bufsz; 38 unsigned int etb_bufsz;
38 void __iomem *etb_regs; 39 void __iomem *etb_regs;
39 void __iomem *etm_regs; 40 void __iomem **etm_regs;
41 int etm_regs_count;
40 unsigned long flags; 42 unsigned long flags;
41 int ncmppairs; 43 int ncmppairs;
42 int etm_portsz; 44 int etm_portsz;
45 u32 etb_fc;
46 unsigned long range_start;
47 unsigned long range_end;
48 unsigned long data_range_start;
49 unsigned long data_range_end;
50 bool dump_initial_etb;
43 struct device *dev; 51 struct device *dev;
44 struct clk *emu_clk; 52 struct clk *emu_clk;
45 struct mutex mutex; 53 struct mutex mutex;
46}; 54};
47 55
48static struct tracectx tracer; 56static struct tracectx tracer = {
57 .range_start = (unsigned long)_stext,
58 .range_end = (unsigned long)_etext,
59};
49 60
50static inline bool trace_isrunning(struct tracectx *t) 61static inline bool trace_isrunning(struct tracectx *t)
51{ 62{
52 return !!(t->flags & TRACER_RUNNING); 63 return !!(t->flags & TRACER_RUNNING);
53} 64}
54 65
55static int etm_setup_address_range(struct tracectx *t, int n, 66static int etm_setup_address_range(struct tracectx *t, int id, int n,
56 unsigned long start, unsigned long end, int exclude, int data) 67 unsigned long start, unsigned long end, int exclude, int data)
57{ 68{
58 u32 flags = ETMAAT_ARM | ETMAAT_IGNCONTEXTID | ETMAAT_NSONLY | \ 69 u32 flags = ETMAAT_ARM | ETMAAT_IGNCONTEXTID | ETMAAT_IGNSECURITY |
59 ETMAAT_NOVALCMP; 70 ETMAAT_NOVALCMP;
60 71
61 if (n < 1 || n > t->ncmppairs) 72 if (n < 1 || n > t->ncmppairs)
@@ -71,95 +82,155 @@ static int etm_setup_address_range(struct tracectx *t, int n,
71 flags |= ETMAAT_IEXEC; 82 flags |= ETMAAT_IEXEC;
72 83
73 /* first comparator for the range */ 84 /* first comparator for the range */
74 etm_writel(t, flags, ETMR_COMP_ACC_TYPE(n * 2)); 85 etm_writel(t, id, flags, ETMR_COMP_ACC_TYPE(n * 2));
75 etm_writel(t, start, ETMR_COMP_VAL(n * 2)); 86 etm_writel(t, id, start, ETMR_COMP_VAL(n * 2));
76 87
77 /* second comparator is right next to it */ 88 /* second comparator is right next to it */
78 etm_writel(t, flags, ETMR_COMP_ACC_TYPE(n * 2 + 1)); 89 etm_writel(t, id, flags, ETMR_COMP_ACC_TYPE(n * 2 + 1));
79 etm_writel(t, end, ETMR_COMP_VAL(n * 2 + 1)); 90 etm_writel(t, id, end, ETMR_COMP_VAL(n * 2 + 1));
80 91
81 flags = exclude ? ETMTE_INCLEXCL : 0; 92 if (data) {
82 etm_writel(t, flags | (1 << n), ETMR_TRACEENCTRL); 93 flags = exclude ? ETMVDC3_EXCLONLY : 0;
94 if (exclude)
95 n += 8;
96 etm_writel(t, id, flags | BIT(n), ETMR_VIEWDATACTRL3);
97 } else {
98 flags = exclude ? ETMTE_INCLEXCL : 0;
99 etm_writel(t, id, flags | (1 << n), ETMR_TRACEENCTRL);
100 }
83 101
84 return 0; 102 return 0;
85} 103}
86 104
87static int trace_start(struct tracectx *t) 105static int trace_start_etm(struct tracectx *t, int id)
88{ 106{
89 u32 v; 107 u32 v;
90 unsigned long timeout = TRACER_TIMEOUT; 108 unsigned long timeout = TRACER_TIMEOUT;
91 109
92 etb_unlock(t);
93
94 etb_writel(t, 0, ETBR_FORMATTERCTRL);
95 etb_writel(t, 1, ETBR_CTRL);
96
97 etb_lock(t);
98
99 /* configure etm */
100 v = ETMCTRL_OPTS | ETMCTRL_PROGRAM | ETMCTRL_PORTSIZE(t->etm_portsz); 110 v = ETMCTRL_OPTS | ETMCTRL_PROGRAM | ETMCTRL_PORTSIZE(t->etm_portsz);
101 111
102 if (t->flags & TRACER_CYCLE_ACC) 112 if (t->flags & TRACER_CYCLE_ACC)
103 v |= ETMCTRL_CYCLEACCURATE; 113 v |= ETMCTRL_CYCLEACCURATE;
104 114
105 etm_unlock(t); 115 if (t->flags & TRACER_TRACE_DATA)
116 v |= ETMCTRL_DATA_DO_ADDR;
117
118 etm_unlock(t, id);
106 119
107 etm_writel(t, v, ETMR_CTRL); 120 etm_writel(t, id, v, ETMR_CTRL);
108 121
109 while (!(etm_readl(t, ETMR_CTRL) & ETMCTRL_PROGRAM) && --timeout) 122 while (!(etm_readl(t, id, ETMR_CTRL) & ETMCTRL_PROGRAM) && --timeout)
110 ; 123 ;
111 if (!timeout) { 124 if (!timeout) {
112 dev_dbg(t->dev, "Waiting for progbit to assert timed out\n"); 125 dev_dbg(t->dev, "Waiting for progbit to assert timed out\n");
113 etm_lock(t); 126 etm_lock(t, id);
114 return -EFAULT; 127 return -EFAULT;
115 } 128 }
116 129
117 etm_setup_address_range(t, 1, (unsigned long)_stext, 130 if (t->range_start || t->range_end)
118 (unsigned long)_etext, 0, 0); 131 etm_setup_address_range(t, id, 1,
119 etm_writel(t, 0, ETMR_TRACEENCTRL2); 132 t->range_start, t->range_end, 0, 0);
120 etm_writel(t, 0, ETMR_TRACESSCTRL); 133 else
121 etm_writel(t, 0x6f, ETMR_TRACEENEVT); 134 etm_writel(t, id, ETMTE_INCLEXCL, ETMR_TRACEENCTRL);
135
136 etm_writel(t, id, 0, ETMR_TRACEENCTRL2);
137 etm_writel(t, id, 0, ETMR_TRACESSCTRL);
138 etm_writel(t, id, 0x6f, ETMR_TRACEENEVT);
139
140 etm_writel(t, id, 0, ETMR_VIEWDATACTRL1);
141 etm_writel(t, id, 0, ETMR_VIEWDATACTRL2);
142
143 if (t->data_range_start || t->data_range_end)
144 etm_setup_address_range(t, id, 2, t->data_range_start,
145 t->data_range_end, 0, 1);
146 else
147 etm_writel(t, id, ETMVDC3_EXCLONLY, ETMR_VIEWDATACTRL3);
148
149 etm_writel(t, id, 0x6f, ETMR_VIEWDATAEVT);
122 150
123 v &= ~ETMCTRL_PROGRAM; 151 v &= ~ETMCTRL_PROGRAM;
124 v |= ETMCTRL_PORTSEL; 152 v |= ETMCTRL_PORTSEL;
125 153
126 etm_writel(t, v, ETMR_CTRL); 154 etm_writel(t, id, v, ETMR_CTRL);
127 155
128 timeout = TRACER_TIMEOUT; 156 timeout = TRACER_TIMEOUT;
129 while (etm_readl(t, ETMR_CTRL) & ETMCTRL_PROGRAM && --timeout) 157 while (etm_readl(t, id, ETMR_CTRL) & ETMCTRL_PROGRAM && --timeout)
130 ; 158 ;
131 if (!timeout) { 159 if (!timeout) {
132 dev_dbg(t->dev, "Waiting for progbit to deassert timed out\n"); 160 dev_dbg(t->dev, "Waiting for progbit to deassert timed out\n");
133 etm_lock(t); 161 etm_lock(t, id);
134 return -EFAULT; 162 return -EFAULT;
135 } 163 }
136 164
137 etm_lock(t); 165 etm_lock(t, id);
166 return 0;
167}
168
169static int trace_start(struct tracectx *t)
170{
171 int ret;
172 int id;
173 u32 etb_fc = t->etb_fc;
174
175 etb_unlock(t);
176
177 t->dump_initial_etb = false;
178 etb_writel(t, 0, ETBR_WRITEADDR);
179 etb_writel(t, etb_fc, ETBR_FORMATTERCTRL);
180 etb_writel(t, 1, ETBR_CTRL);
181
182 etb_lock(t);
183
184 /* configure etm(s) */
185 for (id = 0; id < t->etm_regs_count; id++) {
186 ret = trace_start_etm(t, id);
187 if (ret)
188 return ret;
189 }
138 190
139 t->flags |= TRACER_RUNNING; 191 t->flags |= TRACER_RUNNING;
140 192
141 return 0; 193 return 0;
142} 194}
143 195
144static int trace_stop(struct tracectx *t) 196static int trace_stop_etm(struct tracectx *t, int id)
145{ 197{
146 unsigned long timeout = TRACER_TIMEOUT; 198 unsigned long timeout = TRACER_TIMEOUT;
147 199
148 etm_unlock(t); 200 etm_unlock(t, id);
149 201
150 etm_writel(t, 0x440, ETMR_CTRL); 202 etm_writel(t, id, 0x441, ETMR_CTRL);
151 while (!(etm_readl(t, ETMR_CTRL) & ETMCTRL_PROGRAM) && --timeout) 203 while (!(etm_readl(t, id, ETMR_CTRL) & ETMCTRL_PROGRAM) && --timeout)
152 ; 204 ;
153 if (!timeout) { 205 if (!timeout) {
154 dev_dbg(t->dev, "Waiting for progbit to assert timed out\n"); 206 dev_dbg(t->dev, "Waiting for progbit to assert timed out\n");
155 etm_lock(t); 207 etm_lock(t, id);
156 return -EFAULT; 208 return -EFAULT;
157 } 209 }
158 210
159 etm_lock(t); 211 etm_lock(t, id);
212 return 0;
213}
214
215static int trace_stop(struct tracectx *t)
216{
217 int id;
218 int ret;
219 unsigned long timeout = TRACER_TIMEOUT;
220 u32 etb_fc = t->etb_fc;
221
222 for (id = 0; id < t->etm_regs_count; id++) {
223 ret = trace_stop_etm(t, id);
224 if (ret)
225 return ret;
226 }
160 227
161 etb_unlock(t); 228 etb_unlock(t);
162 etb_writel(t, ETBFF_MANUAL_FLUSH, ETBR_FORMATTERCTRL); 229 if (etb_fc) {
230 etb_fc |= ETBFF_STOPFL;
231 etb_writel(t, t->etb_fc, ETBR_FORMATTERCTRL);
232 }
233 etb_writel(t, etb_fc | ETBFF_MANUAL_FLUSH, ETBR_FORMATTERCTRL);
163 234
164 timeout = TRACER_TIMEOUT; 235 timeout = TRACER_TIMEOUT;
165 while (etb_readl(t, ETBR_FORMATTERCTRL) & 236 while (etb_readl(t, ETBR_FORMATTERCTRL) &
@@ -184,24 +255,15 @@ static int trace_stop(struct tracectx *t)
184static int etb_getdatalen(struct tracectx *t) 255static int etb_getdatalen(struct tracectx *t)
185{ 256{
186 u32 v; 257 u32 v;
187 int rp, wp; 258 int wp;
188 259
189 v = etb_readl(t, ETBR_STATUS); 260 v = etb_readl(t, ETBR_STATUS);
190 261
191 if (v & 1) 262 if (v & 1)
192 return t->etb_bufsz; 263 return t->etb_bufsz;
193 264
194 rp = etb_readl(t, ETBR_READADDR);
195 wp = etb_readl(t, ETBR_WRITEADDR); 265 wp = etb_readl(t, ETBR_WRITEADDR);
196 266 return wp;
197 if (rp > wp) {
198 etb_writel(t, 0, ETBR_READADDR);
199 etb_writel(t, 0, ETBR_WRITEADDR);
200
201 return 0;
202 }
203
204 return wp - rp;
205} 267}
206 268
207/* sysrq+v will always stop the running trace and leave it at that */ 269/* sysrq+v will always stop the running trace and leave it at that */
@@ -234,21 +296,18 @@ static void etm_dump(void)
234 printk("%08x", cpu_to_be32(etb_readl(t, ETBR_READMEM))); 296 printk("%08x", cpu_to_be32(etb_readl(t, ETBR_READMEM)));
235 printk(KERN_INFO "\n--- ETB buffer end ---\n"); 297 printk(KERN_INFO "\n--- ETB buffer end ---\n");
236 298
237 /* deassert the overflow bit */
238 etb_writel(t, 1, ETBR_CTRL);
239 etb_writel(t, 0, ETBR_CTRL);
240
241 etb_writel(t, 0, ETBR_TRIGGERCOUNT);
242 etb_writel(t, 0, ETBR_READADDR);
243 etb_writel(t, 0, ETBR_WRITEADDR);
244
245 etb_lock(t); 299 etb_lock(t);
246} 300}
247 301
248static void sysrq_etm_dump(int key) 302static void sysrq_etm_dump(int key)
249{ 303{
304 if (!mutex_trylock(&tracer.mutex)) {
305 printk(KERN_INFO "Tracing hardware busy\n");
306 return;
307 }
250 dev_dbg(tracer.dev, "Dumping ETB buffer\n"); 308 dev_dbg(tracer.dev, "Dumping ETB buffer\n");
251 etm_dump(); 309 etm_dump();
310 mutex_unlock(&tracer.mutex);
252} 311}
253 312
254static struct sysrq_key_op sysrq_etm_op = { 313static struct sysrq_key_op sysrq_etm_op = {
@@ -275,6 +334,10 @@ static ssize_t etb_read(struct file *file, char __user *data,
275 struct tracectx *t = file->private_data; 334 struct tracectx *t = file->private_data;
276 u32 first = 0; 335 u32 first = 0;
277 u32 *buf; 336 u32 *buf;
337 int wpos;
338 int skip;
339 long wlength;
340 loff_t pos = *ppos;
278 341
279 mutex_lock(&t->mutex); 342 mutex_lock(&t->mutex);
280 343
@@ -286,31 +349,39 @@ static ssize_t etb_read(struct file *file, char __user *data,
286 etb_unlock(t); 349 etb_unlock(t);
287 350
288 total = etb_getdatalen(t); 351 total = etb_getdatalen(t);
352 if (total == 0 && t->dump_initial_etb)
353 total = t->etb_bufsz;
289 if (total == t->etb_bufsz) 354 if (total == t->etb_bufsz)
290 first = etb_readl(t, ETBR_WRITEADDR); 355 first = etb_readl(t, ETBR_WRITEADDR);
291 356
357 if (pos > total * 4) {
358 skip = 0;
359 wpos = total;
360 } else {
361 skip = (int)pos % 4;
362 wpos = (int)pos / 4;
363 }
364 total -= wpos;
365 first = (first + wpos) % t->etb_bufsz;
366
292 etb_writel(t, first, ETBR_READADDR); 367 etb_writel(t, first, ETBR_READADDR);
293 368
294 length = min(total * 4, (int)len); 369 wlength = min(total, DIV_ROUND_UP(skip + (int)len, 4));
295 buf = vmalloc(length); 370 length = min(total * 4 - skip, (int)len);
371 buf = vmalloc(wlength * 4);
296 372
297 dev_dbg(t->dev, "ETB buffer length: %d\n", total); 373 dev_dbg(t->dev, "ETB read %ld bytes to %lld from %ld words at %d\n",
374 length, pos, wlength, first);
375 dev_dbg(t->dev, "ETB buffer length: %d\n", total + wpos);
298 dev_dbg(t->dev, "ETB status reg: %x\n", etb_readl(t, ETBR_STATUS)); 376 dev_dbg(t->dev, "ETB status reg: %x\n", etb_readl(t, ETBR_STATUS));
299 for (i = 0; i < length / 4; i++) 377 for (i = 0; i < wlength; i++)
300 buf[i] = etb_readl(t, ETBR_READMEM); 378 buf[i] = etb_readl(t, ETBR_READMEM);
301 379
302 /* the only way to deassert overflow bit in ETB status is this */
303 etb_writel(t, 1, ETBR_CTRL);
304 etb_writel(t, 0, ETBR_CTRL);
305
306 etb_writel(t, 0, ETBR_WRITEADDR);
307 etb_writel(t, 0, ETBR_READADDR);
308 etb_writel(t, 0, ETBR_TRIGGERCOUNT);
309
310 etb_lock(t); 380 etb_lock(t);
311 381
312 length -= copy_to_user(data, buf, length); 382 length -= copy_to_user(data, (u8 *)buf + skip, length);
313 vfree(buf); 383 vfree(buf);
384 *ppos = pos + length;
314 385
315out: 386out:
316 mutex_unlock(&t->mutex); 387 mutex_unlock(&t->mutex);
@@ -347,28 +418,17 @@ static int __devinit etb_probe(struct amba_device *dev, const struct amba_id *id
347 if (ret) 418 if (ret)
348 goto out; 419 goto out;
349 420
421 mutex_lock(&t->mutex);
350 t->etb_regs = ioremap_nocache(dev->res.start, resource_size(&dev->res)); 422 t->etb_regs = ioremap_nocache(dev->res.start, resource_size(&dev->res));
351 if (!t->etb_regs) { 423 if (!t->etb_regs) {
352 ret = -ENOMEM; 424 ret = -ENOMEM;
353 goto out_release; 425 goto out_release;
354 } 426 }
355 427
428 t->dev = &dev->dev;
429 t->dump_initial_etb = true;
356 amba_set_drvdata(dev, t); 430 amba_set_drvdata(dev, t);
357 431
358 etb_miscdev.parent = &dev->dev;
359
360 ret = misc_register(&etb_miscdev);
361 if (ret)
362 goto out_unmap;
363
364 t->emu_clk = clk_get(&dev->dev, "emu_src_ck");
365 if (IS_ERR(t->emu_clk)) {
366 dev_dbg(&dev->dev, "Failed to obtain emu_src_ck.\n");
367 return -EFAULT;
368 }
369
370 clk_enable(t->emu_clk);
371
372 etb_unlock(t); 432 etb_unlock(t);
373 t->etb_bufsz = etb_readl(t, ETBR_DEPTH); 433 t->etb_bufsz = etb_readl(t, ETBR_DEPTH);
374 dev_dbg(&dev->dev, "Size: %x\n", t->etb_bufsz); 434 dev_dbg(&dev->dev, "Size: %x\n", t->etb_bufsz);
@@ -377,6 +437,20 @@ static int __devinit etb_probe(struct amba_device *dev, const struct amba_id *id
377 etb_writel(t, 0, ETBR_CTRL); 437 etb_writel(t, 0, ETBR_CTRL);
378 etb_writel(t, 0x1000, ETBR_FORMATTERCTRL); 438 etb_writel(t, 0x1000, ETBR_FORMATTERCTRL);
379 etb_lock(t); 439 etb_lock(t);
440 mutex_unlock(&t->mutex);
441
442 etb_miscdev.parent = &dev->dev;
443
444 ret = misc_register(&etb_miscdev);
445 if (ret)
446 goto out_unmap;
447
448 /* Get optional clock. Currently used to select clock source on omap3 */
449 t->emu_clk = clk_get(&dev->dev, "emu_src_ck");
450 if (IS_ERR(t->emu_clk))
451 dev_dbg(&dev->dev, "Failed to obtain emu_src_ck.\n");
452 else
453 clk_enable(t->emu_clk);
380 454
381 dev_dbg(&dev->dev, "ETB AMBA driver initialized.\n"); 455 dev_dbg(&dev->dev, "ETB AMBA driver initialized.\n");
382 456
@@ -384,10 +458,13 @@ out:
384 return ret; 458 return ret;
385 459
386out_unmap: 460out_unmap:
461 mutex_lock(&t->mutex);
387 amba_set_drvdata(dev, NULL); 462 amba_set_drvdata(dev, NULL);
388 iounmap(t->etb_regs); 463 iounmap(t->etb_regs);
464 t->etb_regs = NULL;
389 465
390out_release: 466out_release:
467 mutex_unlock(&t->mutex);
391 amba_release_regions(dev); 468 amba_release_regions(dev);
392 469
393 return ret; 470 return ret;
@@ -402,8 +479,10 @@ static int etb_remove(struct amba_device *dev)
402 iounmap(t->etb_regs); 479 iounmap(t->etb_regs);
403 t->etb_regs = NULL; 480 t->etb_regs = NULL;
404 481
405 clk_disable(t->emu_clk); 482 if (!IS_ERR(t->emu_clk)) {
406 clk_put(t->emu_clk); 483 clk_disable(t->emu_clk);
484 clk_put(t->emu_clk);
485 }
407 486
408 amba_release_regions(dev); 487 amba_release_regions(dev);
409 488
@@ -447,7 +526,10 @@ static ssize_t trace_running_store(struct kobject *kobj,
447 return -EINVAL; 526 return -EINVAL;
448 527
449 mutex_lock(&tracer.mutex); 528 mutex_lock(&tracer.mutex);
450 ret = value ? trace_start(&tracer) : trace_stop(&tracer); 529 if (!tracer.etb_regs)
530 ret = -ENODEV;
531 else
532 ret = value ? trace_start(&tracer) : trace_stop(&tracer);
451 mutex_unlock(&tracer.mutex); 533 mutex_unlock(&tracer.mutex);
452 534
453 return ret ? : n; 535 return ret ? : n;
@@ -462,36 +544,50 @@ static ssize_t trace_info_show(struct kobject *kobj,
462{ 544{
463 u32 etb_wa, etb_ra, etb_st, etb_fc, etm_ctrl, etm_st; 545 u32 etb_wa, etb_ra, etb_st, etb_fc, etm_ctrl, etm_st;
464 int datalen; 546 int datalen;
547 int id;
548 int ret;
465 549
466 etb_unlock(&tracer); 550 mutex_lock(&tracer.mutex);
467 datalen = etb_getdatalen(&tracer); 551 if (tracer.etb_regs) {
468 etb_wa = etb_readl(&tracer, ETBR_WRITEADDR); 552 etb_unlock(&tracer);
469 etb_ra = etb_readl(&tracer, ETBR_READADDR); 553 datalen = etb_getdatalen(&tracer);
470 etb_st = etb_readl(&tracer, ETBR_STATUS); 554 etb_wa = etb_readl(&tracer, ETBR_WRITEADDR);
471 etb_fc = etb_readl(&tracer, ETBR_FORMATTERCTRL); 555 etb_ra = etb_readl(&tracer, ETBR_READADDR);
472 etb_lock(&tracer); 556 etb_st = etb_readl(&tracer, ETBR_STATUS);
473 557 etb_fc = etb_readl(&tracer, ETBR_FORMATTERCTRL);
474 etm_unlock(&tracer); 558 etb_lock(&tracer);
475 etm_ctrl = etm_readl(&tracer, ETMR_CTRL); 559 } else {
476 etm_st = etm_readl(&tracer, ETMR_STATUS); 560 etb_wa = etb_ra = etb_st = etb_fc = ~0;
477 etm_lock(&tracer); 561 datalen = -1;
562 }
478 563
479 return sprintf(buf, "Trace buffer len: %d\nComparator pairs: %d\n" 564 ret = sprintf(buf, "Trace buffer len: %d\nComparator pairs: %d\n"
480 "ETBR_WRITEADDR:\t%08x\n" 565 "ETBR_WRITEADDR:\t%08x\n"
481 "ETBR_READADDR:\t%08x\n" 566 "ETBR_READADDR:\t%08x\n"
482 "ETBR_STATUS:\t%08x\n" 567 "ETBR_STATUS:\t%08x\n"
483 "ETBR_FORMATTERCTRL:\t%08x\n" 568 "ETBR_FORMATTERCTRL:\t%08x\n",
484 "ETMR_CTRL:\t%08x\n"
485 "ETMR_STATUS:\t%08x\n",
486 datalen, 569 datalen,
487 tracer.ncmppairs, 570 tracer.ncmppairs,
488 etb_wa, 571 etb_wa,
489 etb_ra, 572 etb_ra,
490 etb_st, 573 etb_st,
491 etb_fc, 574 etb_fc
575 );
576
577 for (id = 0; id < tracer.etm_regs_count; id++) {
578 etm_unlock(&tracer, id);
579 etm_ctrl = etm_readl(&tracer, id, ETMR_CTRL);
580 etm_st = etm_readl(&tracer, id, ETMR_STATUS);
581 etm_lock(&tracer, id);
582 ret += sprintf(buf + ret, "ETMR_CTRL:\t%08x\n"
583 "ETMR_STATUS:\t%08x\n",
492 etm_ctrl, 584 etm_ctrl,
493 etm_st 585 etm_st
494 ); 586 );
587 }
588 mutex_unlock(&tracer.mutex);
589
590 return ret;
495} 591}
496 592
497static struct kobj_attribute trace_info_attr = 593static struct kobj_attribute trace_info_attr =
@@ -530,42 +626,121 @@ static ssize_t trace_mode_store(struct kobject *kobj,
530static struct kobj_attribute trace_mode_attr = 626static struct kobj_attribute trace_mode_attr =
531 __ATTR(trace_mode, 0644, trace_mode_show, trace_mode_store); 627 __ATTR(trace_mode, 0644, trace_mode_show, trace_mode_store);
532 628
629static ssize_t trace_range_show(struct kobject *kobj,
630 struct kobj_attribute *attr,
631 char *buf)
632{
633 return sprintf(buf, "%08lx %08lx\n",
634 tracer.range_start, tracer.range_end);
635}
636
637static ssize_t trace_range_store(struct kobject *kobj,
638 struct kobj_attribute *attr,
639 const char *buf, size_t n)
640{
641 unsigned long range_start, range_end;
642
643 if (sscanf(buf, "%lx %lx", &range_start, &range_end) != 2)
644 return -EINVAL;
645
646 mutex_lock(&tracer.mutex);
647 tracer.range_start = range_start;
648 tracer.range_end = range_end;
649 mutex_unlock(&tracer.mutex);
650
651 return n;
652}
653
654
655static struct kobj_attribute trace_range_attr =
656 __ATTR(trace_range, 0644, trace_range_show, trace_range_store);
657
658static ssize_t trace_data_range_show(struct kobject *kobj,
659 struct kobj_attribute *attr,
660 char *buf)
661{
662 unsigned long range_start;
663 u64 range_end;
664 mutex_lock(&tracer.mutex);
665 range_start = tracer.data_range_start;
666 range_end = tracer.data_range_end;
667 if (!range_end && (tracer.flags & TRACER_TRACE_DATA))
668 range_end = 0x100000000ULL;
669 mutex_unlock(&tracer.mutex);
670 return sprintf(buf, "%08lx %08llx\n", range_start, range_end);
671}
672
673static ssize_t trace_data_range_store(struct kobject *kobj,
674 struct kobj_attribute *attr,
675 const char *buf, size_t n)
676{
677 unsigned long range_start;
678 u64 range_end;
679
680 if (sscanf(buf, "%lx %llx", &range_start, &range_end) != 2)
681 return -EINVAL;
682
683 mutex_lock(&tracer.mutex);
684 tracer.data_range_start = range_start;
685 tracer.data_range_end = (unsigned long)range_end;
686 if (range_end)
687 tracer.flags |= TRACER_TRACE_DATA;
688 else
689 tracer.flags &= ~TRACER_TRACE_DATA;
690 mutex_unlock(&tracer.mutex);
691
692 return n;
693}
694
695
696static struct kobj_attribute trace_data_range_attr =
697 __ATTR(trace_data_range, 0644,
698 trace_data_range_show, trace_data_range_store);
699
533static int __devinit etm_probe(struct amba_device *dev, const struct amba_id *id) 700static int __devinit etm_probe(struct amba_device *dev, const struct amba_id *id)
534{ 701{
535 struct tracectx *t = &tracer; 702 struct tracectx *t = &tracer;
536 int ret = 0; 703 int ret = 0;
704 void __iomem **new_regs;
705 int new_count;
537 706
538 if (t->etm_regs) { 707 mutex_lock(&t->mutex);
539 dev_dbg(&dev->dev, "ETM already initialized\n"); 708 new_count = t->etm_regs_count + 1;
540 ret = -EBUSY; 709 new_regs = krealloc(t->etm_regs,
710 sizeof(t->etm_regs[0]) * new_count, GFP_KERNEL);
711
712 if (!new_regs) {
713 dev_dbg(&dev->dev, "Failed to allocate ETM register array\n");
714 ret = -ENOMEM;
541 goto out; 715 goto out;
542 } 716 }
717 t->etm_regs = new_regs;
543 718
544 ret = amba_request_regions(dev, NULL); 719 ret = amba_request_regions(dev, NULL);
545 if (ret) 720 if (ret)
546 goto out; 721 goto out;
547 722
548 t->etm_regs = ioremap_nocache(dev->res.start, resource_size(&dev->res)); 723 t->etm_regs[t->etm_regs_count] =
549 if (!t->etm_regs) { 724 ioremap_nocache(dev->res.start, resource_size(&dev->res));
725 if (!t->etm_regs[t->etm_regs_count]) {
550 ret = -ENOMEM; 726 ret = -ENOMEM;
551 goto out_release; 727 goto out_release;
552 } 728 }
553 729
554 amba_set_drvdata(dev, t); 730 amba_set_drvdata(dev, t->etm_regs[t->etm_regs_count]);
555 731
556 mutex_init(&t->mutex); 732 t->flags = TRACER_CYCLE_ACC | TRACER_TRACE_DATA;
557 t->dev = &dev->dev;
558 t->flags = TRACER_CYCLE_ACC;
559 t->etm_portsz = 1; 733 t->etm_portsz = 1;
560 734
561 etm_unlock(t); 735 etm_unlock(t, t->etm_regs_count);
562 (void)etm_readl(t, ETMMR_PDSR); 736 (void)etm_readl(t, t->etm_regs_count, ETMMR_PDSR);
563 /* dummy first read */ 737 /* dummy first read */
564 (void)etm_readl(&tracer, ETMMR_OSSRR); 738 (void)etm_readl(&tracer, t->etm_regs_count, ETMMR_OSSRR);
565 739
566 t->ncmppairs = etm_readl(t, ETMR_CONFCODE) & 0xf; 740 t->ncmppairs = etm_readl(t, t->etm_regs_count, ETMR_CONFCODE) & 0xf;
567 etm_writel(t, 0x440, ETMR_CTRL); 741 etm_writel(t, t->etm_regs_count, 0x441, ETMR_CTRL);
568 etm_lock(t); 742 etm_writel(t, t->etm_regs_count, new_count, ETMR_TRACEIDR);
743 etm_lock(t, t->etm_regs_count);
569 744
570 ret = sysfs_create_file(&dev->dev.kobj, 745 ret = sysfs_create_file(&dev->dev.kobj,
571 &trace_running_attr.attr); 746 &trace_running_attr.attr);
@@ -581,36 +756,68 @@ static int __devinit etm_probe(struct amba_device *dev, const struct amba_id *id
581 if (ret) 756 if (ret)
582 dev_dbg(&dev->dev, "Failed to create trace_mode in sysfs\n"); 757 dev_dbg(&dev->dev, "Failed to create trace_mode in sysfs\n");
583 758
584 dev_dbg(t->dev, "ETM AMBA driver initialized.\n"); 759 ret = sysfs_create_file(&dev->dev.kobj, &trace_range_attr.attr);
760 if (ret)
761 dev_dbg(&dev->dev, "Failed to create trace_range in sysfs\n");
762
763 ret = sysfs_create_file(&dev->dev.kobj, &trace_data_range_attr.attr);
764 if (ret)
765 dev_dbg(&dev->dev,
766 "Failed to create trace_data_range in sysfs\n");
767
768 dev_dbg(&dev->dev, "ETM AMBA driver initialized.\n");
769
770 /* Enable formatter if there are multiple trace sources */
771 if (new_count > 1)
772 t->etb_fc = ETBFF_ENFCONT | ETBFF_ENFTC;
773
774 t->etm_regs_count = new_count;
585 775
586out: 776out:
777 mutex_unlock(&t->mutex);
587 return ret; 778 return ret;
588 779
589out_unmap: 780out_unmap:
590 amba_set_drvdata(dev, NULL); 781 amba_set_drvdata(dev, NULL);
591 iounmap(t->etm_regs); 782 iounmap(t->etm_regs[t->etm_regs_count]);
592 783
593out_release: 784out_release:
594 amba_release_regions(dev); 785 amba_release_regions(dev);
595 786
787 mutex_unlock(&t->mutex);
596 return ret; 788 return ret;
597} 789}
598 790
599static int etm_remove(struct amba_device *dev) 791static int etm_remove(struct amba_device *dev)
600{ 792{
601 struct tracectx *t = amba_get_drvdata(dev); 793 int i;
794 struct tracectx *t = &tracer;
795 void __iomem *etm_regs = amba_get_drvdata(dev);
796
797 sysfs_remove_file(&dev->dev.kobj, &trace_running_attr.attr);
798 sysfs_remove_file(&dev->dev.kobj, &trace_info_attr.attr);
799 sysfs_remove_file(&dev->dev.kobj, &trace_mode_attr.attr);
800 sysfs_remove_file(&dev->dev.kobj, &trace_range_attr.attr);
801 sysfs_remove_file(&dev->dev.kobj, &trace_data_range_attr.attr);
602 802
603 amba_set_drvdata(dev, NULL); 803 amba_set_drvdata(dev, NULL);
604 804
605 iounmap(t->etm_regs); 805 mutex_lock(&t->mutex);
606 t->etm_regs = NULL; 806 for (i = 0; i < t->etm_regs_count; i++)
807 if (t->etm_regs[i] == etm_regs)
808 break;
809 for (; i < t->etm_regs_count - 1; i++)
810 t->etm_regs[i] = t->etm_regs[i + 1];
811 t->etm_regs_count--;
812 if (!t->etm_regs_count) {
813 kfree(t->etm_regs);
814 t->etm_regs = NULL;
815 }
816 mutex_unlock(&t->mutex);
607 817
818 iounmap(etm_regs);
608 amba_release_regions(dev); 819 amba_release_regions(dev);
609 820
610 sysfs_remove_file(&dev->dev.kobj, &trace_running_attr.attr);
611 sysfs_remove_file(&dev->dev.kobj, &trace_info_attr.attr);
612 sysfs_remove_file(&dev->dev.kobj, &trace_mode_attr.attr);
613
614 return 0; 821 return 0;
615} 822}
616 823
@@ -619,6 +826,10 @@ static struct amba_id etm_ids[] = {
619 .id = 0x0003b921, 826 .id = 0x0003b921,
620 .mask = 0x0007ffff, 827 .mask = 0x0007ffff,
621 }, 828 },
829 {
830 .id = 0x0003b950,
831 .mask = 0x0007ffff,
832 },
622 { 0, 0 }, 833 { 0, 0 },
623}; 834};
624 835
@@ -636,6 +847,8 @@ static int __init etm_init(void)
636{ 847{
637 int retval; 848 int retval;
638 849
850 mutex_init(&tracer.mutex);
851
639 retval = amba_driver_register(&etb_driver); 852 retval = amba_driver_register(&etb_driver);
640 if (retval) { 853 if (retval) {
641 printk(KERN_ERR "Failed to register etb\n"); 854 printk(KERN_ERR "Failed to register etb\n");