import PULS_20160108
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / arch / arm / kernel / etm.c
CommitLineData
c5d6c770
AS
1/*
2 * linux/arch/arm/kernel/etm.c
3 *
4 * Driver for ARM's Embedded Trace Macrocell and Embedded Trace Buffer.
5 *
6 * Copyright (C) 2009 Nokia Corporation.
7 * Alexander Shishkin
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/types.h>
17#include <linux/io.h>
6fa3eb70 18#include <linux/slab.h>
c5d6c770
AS
19#include <linux/sysrq.h>
20#include <linux/device.h>
21#include <linux/clk.h>
22#include <linux/amba/bus.h>
23#include <linux/fs.h>
24#include <linux/uaccess.h>
25#include <linux/miscdevice.h>
26#include <linux/vmalloc.h>
27#include <linux/mutex.h>
73017a54 28#include <linux/module.h>
c5d6c770
AS
29#include <asm/hardware/coresight.h>
30#include <asm/sections.h>
31
32MODULE_LICENSE("GPL");
33MODULE_AUTHOR("Alexander Shishkin");
34
8234eaef
AS
35/*
36 * ETM tracer state
37 */
38struct tracectx {
39 unsigned int etb_bufsz;
40 void __iomem *etb_regs;
6fa3eb70
S
41 void __iomem **etm_regs;
42 int etm_regs_count;
8234eaef
AS
43 unsigned long flags;
44 int ncmppairs;
45 int etm_portsz;
6fa3eb70
S
46 int etm_contextid_size;
47 u32 etb_fc;
48 unsigned long range_start;
49 unsigned long range_end;
50 unsigned long data_range_start;
51 unsigned long data_range_end;
52 bool dump_initial_etb;
8234eaef
AS
53 struct device *dev;
54 struct clk *emu_clk;
55 struct mutex mutex;
56};
57
6fa3eb70
S
58static struct tracectx tracer = {
59 .range_start = (unsigned long)_stext,
60 .range_end = (unsigned long)_etext,
61};
c5d6c770
AS
62
63static inline bool trace_isrunning(struct tracectx *t)
64{
65 return !!(t->flags & TRACER_RUNNING);
66}
67
6fa3eb70 68static int etm_setup_address_range(struct tracectx *t, int id, int n,
c5d6c770
AS
69 unsigned long start, unsigned long end, int exclude, int data)
70{
6fa3eb70 71 u32 flags = ETMAAT_ARM | ETMAAT_IGNCONTEXTID | ETMAAT_IGNSECURITY |
c5d6c770
AS
72 ETMAAT_NOVALCMP;
73
74 if (n < 1 || n > t->ncmppairs)
75 return -EINVAL;
76
77 /* comparators and ranges are numbered starting with 1 as opposed
78 * to bits in a word */
79 n--;
80
81 if (data)
82 flags |= ETMAAT_DLOADSTORE;
83 else
84 flags |= ETMAAT_IEXEC;
85
86 /* first comparator for the range */
6fa3eb70
S
87 etm_writel(t, id, flags, ETMR_COMP_ACC_TYPE(n * 2));
88 etm_writel(t, id, start, ETMR_COMP_VAL(n * 2));
c5d6c770
AS
89
90 /* second comparator is right next to it */
6fa3eb70
S
91 etm_writel(t, id, flags, ETMR_COMP_ACC_TYPE(n * 2 + 1));
92 etm_writel(t, id, end, ETMR_COMP_VAL(n * 2 + 1));
93
94 if (data) {
95 flags = exclude ? ETMVDC3_EXCLONLY : 0;
96 if (exclude)
97 n += 8;
98 etm_writel(t, id, flags | BIT(n), ETMR_VIEWDATACTRL3);
99 } else {
100 flags = exclude ? ETMTE_INCLEXCL : 0;
101 etm_writel(t, id, flags | (1 << n), ETMR_TRACEENCTRL);
102 }
c5d6c770
AS
103
104 return 0;
105}
106
6fa3eb70 107static int trace_start_etm(struct tracectx *t, int id)
c5d6c770
AS
108{
109 u32 v;
110 unsigned long timeout = TRACER_TIMEOUT;
111
c5d6c770 112 v = ETMCTRL_OPTS | ETMCTRL_PROGRAM | ETMCTRL_PORTSIZE(t->etm_portsz);
6fa3eb70 113 v |= ETMCTRL_CONTEXTIDSIZE(t->etm_contextid_size);
c5d6c770
AS
114
115 if (t->flags & TRACER_CYCLE_ACC)
116 v |= ETMCTRL_CYCLEACCURATE;
117
6fa3eb70
S
118 if (t->flags & TRACER_BRANCHOUTPUT)
119 v |= ETMCTRL_BRANCH_OUTPUT;
120
121 if (t->flags & TRACER_TRACE_DATA)
122 v |= ETMCTRL_DATA_DO_ADDR;
123
124 if (t->flags & TRACER_TIMESTAMP)
125 v |= ETMCTRL_TIMESTAMP_EN;
126
127 if (t->flags & TRACER_RETURN_STACK)
128 v |= ETMCTRL_RETURN_STACK_EN;
c5d6c770 129
6fa3eb70 130 etm_unlock(t, id);
c5d6c770 131
6fa3eb70
S
132 etm_writel(t, id, v, ETMR_CTRL);
133
134 while (!(etm_readl(t, id, ETMR_CTRL) & ETMCTRL_PROGRAM) && --timeout)
c5d6c770
AS
135 ;
136 if (!timeout) {
137 dev_dbg(t->dev, "Waiting for progbit to assert timed out\n");
6fa3eb70 138 etm_lock(t, id);
c5d6c770
AS
139 return -EFAULT;
140 }
141
6fa3eb70
S
142 if (t->range_start || t->range_end)
143 etm_setup_address_range(t, id, 1,
144 t->range_start, t->range_end, 0, 0);
145 else
146 etm_writel(t, id, ETMTE_INCLEXCL, ETMR_TRACEENCTRL);
147
148 etm_writel(t, id, 0, ETMR_TRACEENCTRL2);
149 etm_writel(t, id, 0, ETMR_TRACESSCTRL);
150 etm_writel(t, id, 0x6f, ETMR_TRACEENEVT);
151
152 etm_writel(t, id, 0, ETMR_VIEWDATACTRL1);
153 etm_writel(t, id, 0, ETMR_VIEWDATACTRL2);
154
155 if (t->data_range_start || t->data_range_end)
156 etm_setup_address_range(t, id, 2, t->data_range_start,
157 t->data_range_end, 0, 1);
158 else
159 etm_writel(t, id, ETMVDC3_EXCLONLY, ETMR_VIEWDATACTRL3);
160
161 etm_writel(t, id, 0x6f, ETMR_VIEWDATAEVT);
c5d6c770
AS
162
163 v &= ~ETMCTRL_PROGRAM;
164 v |= ETMCTRL_PORTSEL;
165
6fa3eb70 166 etm_writel(t, id, v, ETMR_CTRL);
c5d6c770
AS
167
168 timeout = TRACER_TIMEOUT;
6fa3eb70 169 while (etm_readl(t, id, ETMR_CTRL) & ETMCTRL_PROGRAM && --timeout)
c5d6c770
AS
170 ;
171 if (!timeout) {
172 dev_dbg(t->dev, "Waiting for progbit to deassert timed out\n");
6fa3eb70 173 etm_lock(t, id);
c5d6c770
AS
174 return -EFAULT;
175 }
176
6fa3eb70
S
177 etm_lock(t, id);
178 return 0;
179}
180
181static int trace_start(struct tracectx *t)
182{
183 int ret;
184 int id;
185 u32 etb_fc = t->etb_fc;
186
187 etb_unlock(t);
188
189 t->dump_initial_etb = false;
190 etb_writel(t, 0, ETBR_WRITEADDR);
191 etb_writel(t, etb_fc, ETBR_FORMATTERCTRL);
192 etb_writel(t, 1, ETBR_CTRL);
193
194 etb_lock(t);
195
196 /* configure etm(s) */
197 for (id = 0; id < t->etm_regs_count; id++) {
198 ret = trace_start_etm(t, id);
199 if (ret)
200 return ret;
201 }
c5d6c770
AS
202
203 t->flags |= TRACER_RUNNING;
204
205 return 0;
206}
207
6fa3eb70 208static int trace_stop_etm(struct tracectx *t, int id)
c5d6c770
AS
209{
210 unsigned long timeout = TRACER_TIMEOUT;
211
6fa3eb70 212 etm_unlock(t, id);
c5d6c770 213
6fa3eb70
S
214 etm_writel(t, id, 0x440, ETMR_CTRL);
215 while (!(etm_readl(t, id, ETMR_CTRL) & ETMCTRL_PROGRAM) && --timeout)
c5d6c770
AS
216 ;
217 if (!timeout) {
6fa3eb70
S
218 dev_err(t->dev,
219 "etm%d: Waiting for progbit to assert timed out\n",
220 id);
221 etm_lock(t, id);
c5d6c770
AS
222 return -EFAULT;
223 }
224
6fa3eb70
S
225 etm_lock(t, id);
226 return 0;
227}
228
229static int trace_power_down_etm(struct tracectx *t, int id)
230{
231 unsigned long timeout = TRACER_TIMEOUT;
232 etm_unlock(t, id);
233 while (!(etm_readl(t, id, ETMR_STATUS) & ETMST_PROGBIT) && --timeout)
234 ;
235 if (!timeout) {
236 dev_err(t->dev, "etm%d: Waiting for status progbit to assert timed out\n",
237 id);
238 etm_lock(t, id);
239 return -EFAULT;
240 }
241
242 etm_writel(t, id, 0x441, ETMR_CTRL);
243
244 etm_lock(t, id);
245 return 0;
246}
247
248static int trace_stop(struct tracectx *t)
249{
250 int id;
251 unsigned long timeout = TRACER_TIMEOUT;
252 u32 etb_fc = t->etb_fc;
253
254 for (id = 0; id < t->etm_regs_count; id++)
255 trace_stop_etm(t, id);
256
257 for (id = 0; id < t->etm_regs_count; id++)
258 trace_power_down_etm(t, id);
c5d6c770
AS
259
260 etb_unlock(t);
6fa3eb70
S
261 if (etb_fc) {
262 etb_fc |= ETBFF_STOPFL;
263 etb_writel(t, t->etb_fc, ETBR_FORMATTERCTRL);
264 }
265 etb_writel(t, etb_fc | ETBFF_MANUAL_FLUSH, ETBR_FORMATTERCTRL);
c5d6c770
AS
266
267 timeout = TRACER_TIMEOUT;
268 while (etb_readl(t, ETBR_FORMATTERCTRL) &
269 ETBFF_MANUAL_FLUSH && --timeout)
270 ;
271 if (!timeout) {
272 dev_dbg(t->dev, "Waiting for formatter flush to commence "
273 "timed out\n");
274 etb_lock(t);
275 return -EFAULT;
276 }
277
278 etb_writel(t, 0, ETBR_CTRL);
279
280 etb_lock(t);
281
282 t->flags &= ~TRACER_RUNNING;
283
284 return 0;
285}
286
287static int etb_getdatalen(struct tracectx *t)
288{
289 u32 v;
6fa3eb70 290 int wp;
c5d6c770
AS
291
292 v = etb_readl(t, ETBR_STATUS);
293
294 if (v & 1)
295 return t->etb_bufsz;
296
c5d6c770 297 wp = etb_readl(t, ETBR_WRITEADDR);
6fa3eb70 298 return wp;
c5d6c770
AS
299}
300
301/* sysrq+v will always stop the running trace and leave it at that */
302static void etm_dump(void)
303{
304 struct tracectx *t = &tracer;
305 u32 first = 0;
306 int length;
307
308 if (!t->etb_regs) {
309 printk(KERN_INFO "No tracing hardware found\n");
310 return;
311 }
312
313 if (trace_isrunning(t))
314 trace_stop(t);
315
316 etb_unlock(t);
317
318 length = etb_getdatalen(t);
319
320 if (length == t->etb_bufsz)
321 first = etb_readl(t, ETBR_WRITEADDR);
322
323 etb_writel(t, first, ETBR_READADDR);
324
325 printk(KERN_INFO "Trace buffer contents length: %d\n", length);
326 printk(KERN_INFO "--- ETB buffer begin ---\n");
327 for (; length; length--)
328 printk("%08x", cpu_to_be32(etb_readl(t, ETBR_READMEM)));
329 printk(KERN_INFO "\n--- ETB buffer end ---\n");
330
c5d6c770
AS
331 etb_lock(t);
332}
333
1495cc9d 334static void sysrq_etm_dump(int key)
c5d6c770 335{
6fa3eb70
S
336 if (!mutex_trylock(&tracer.mutex)) {
337 printk(KERN_INFO "Tracing hardware busy\n");
338 return;
339 }
c5d6c770
AS
340 dev_dbg(tracer.dev, "Dumping ETB buffer\n");
341 etm_dump();
6fa3eb70 342 mutex_unlock(&tracer.mutex);
c5d6c770
AS
343}
344
345static struct sysrq_key_op sysrq_etm_op = {
346 .handler = sysrq_etm_dump,
9387a393 347 .help_msg = "etm-buffer-dump(v)",
c5d6c770
AS
348 .action_msg = "etm",
349};
350
351static int etb_open(struct inode *inode, struct file *file)
352{
353 if (!tracer.etb_regs)
354 return -ENODEV;
355
356 file->private_data = &tracer;
357
358 return nonseekable_open(inode, file);
359}
360
361static ssize_t etb_read(struct file *file, char __user *data,
362 size_t len, loff_t *ppos)
363{
364 int total, i;
365 long length;
366 struct tracectx *t = file->private_data;
367 u32 first = 0;
368 u32 *buf;
6fa3eb70
S
369 int wpos;
370 int skip;
371 long wlength;
372 loff_t pos = *ppos;
c5d6c770
AS
373
374 mutex_lock(&t->mutex);
375
376 if (trace_isrunning(t)) {
377 length = 0;
378 goto out;
379 }
380
381 etb_unlock(t);
382
383 total = etb_getdatalen(t);
6fa3eb70
S
384 if (total == 0 && t->dump_initial_etb)
385 total = t->etb_bufsz;
c5d6c770
AS
386 if (total == t->etb_bufsz)
387 first = etb_readl(t, ETBR_WRITEADDR);
388
6fa3eb70
S
389 if (pos > total * 4) {
390 skip = 0;
391 wpos = total;
392 } else {
393 skip = (int)pos % 4;
394 wpos = (int)pos / 4;
395 }
396 total -= wpos;
397 first = (first + wpos) % t->etb_bufsz;
398
c5d6c770
AS
399 etb_writel(t, first, ETBR_READADDR);
400
6fa3eb70
S
401 wlength = min(total, DIV_ROUND_UP(skip + (int)len, 4));
402 length = min(total * 4 - skip, (int)len);
403 buf = vmalloc(wlength * 4);
c5d6c770 404
6fa3eb70
S
405 dev_dbg(t->dev, "ETB read %ld bytes to %lld from %ld words at %d\n",
406 length, pos, wlength, first);
407 dev_dbg(t->dev, "ETB buffer length: %d\n", total + wpos);
c5d6c770 408 dev_dbg(t->dev, "ETB status reg: %x\n", etb_readl(t, ETBR_STATUS));
6fa3eb70 409 for (i = 0; i < wlength; i++)
c5d6c770
AS
410 buf[i] = etb_readl(t, ETBR_READMEM);
411
c5d6c770
AS
412 etb_lock(t);
413
6fa3eb70 414 length -= copy_to_user(data, (u8 *)buf + skip, length);
c5d6c770 415 vfree(buf);
6fa3eb70 416 *ppos = pos + length;
c5d6c770
AS
417
418out:
419 mutex_unlock(&t->mutex);
420
421 return length;
422}
423
424static int etb_release(struct inode *inode, struct file *file)
425{
426 /* there's nothing to do here, actually */
427 return 0;
428}
429
430static const struct file_operations etb_fops = {
431 .owner = THIS_MODULE,
432 .read = etb_read,
433 .open = etb_open,
434 .release = etb_release,
6038f373 435 .llseek = no_llseek,
c5d6c770
AS
436};
437
438static struct miscdevice etb_miscdev = {
439 .name = "tracebuf",
440 .minor = 0,
441 .fops = &etb_fops,
442};
443
351a102d 444static int etb_probe(struct amba_device *dev, const struct amba_id *id)
c5d6c770
AS
445{
446 struct tracectx *t = &tracer;
447 int ret = 0;
448
449 ret = amba_request_regions(dev, NULL);
450 if (ret)
451 goto out;
452
6fa3eb70 453 mutex_lock(&t->mutex);
c5d6c770
AS
454 t->etb_regs = ioremap_nocache(dev->res.start, resource_size(&dev->res));
455 if (!t->etb_regs) {
456 ret = -ENOMEM;
457 goto out_release;
458 }
459
6fa3eb70
S
460 t->dev = &dev->dev;
461 t->dump_initial_etb = true;
c5d6c770
AS
462 amba_set_drvdata(dev, t);
463
c5d6c770
AS
464 etb_unlock(t);
465 t->etb_bufsz = etb_readl(t, ETBR_DEPTH);
466 dev_dbg(&dev->dev, "Size: %x\n", t->etb_bufsz);
467
468 /* make sure trace capture is disabled */
469 etb_writel(t, 0, ETBR_CTRL);
470 etb_writel(t, 0x1000, ETBR_FORMATTERCTRL);
471 etb_lock(t);
6fa3eb70
S
472 mutex_unlock(&t->mutex);
473
474 etb_miscdev.parent = &dev->dev;
475
476 ret = misc_register(&etb_miscdev);
477 if (ret)
478 goto out_unmap;
479
480 /* Get optional clock. Currently used to select clock source on omap3 */
481 t->emu_clk = clk_get(&dev->dev, "emu_src_ck");
482 if (IS_ERR(t->emu_clk))
483 dev_dbg(&dev->dev, "Failed to obtain emu_src_ck.\n");
484 else
485 clk_enable(t->emu_clk);
c5d6c770
AS
486
487 dev_dbg(&dev->dev, "ETB AMBA driver initialized.\n");
488
489out:
490 return ret;
491
492out_unmap:
6fa3eb70 493 mutex_lock(&t->mutex);
c5d6c770
AS
494 amba_set_drvdata(dev, NULL);
495 iounmap(t->etb_regs);
6fa3eb70 496 t->etb_regs = NULL;
c5d6c770
AS
497
498out_release:
6fa3eb70 499 mutex_unlock(&t->mutex);
c5d6c770
AS
500 amba_release_regions(dev);
501
502 return ret;
503}
504
505static int etb_remove(struct amba_device *dev)
506{
507 struct tracectx *t = amba_get_drvdata(dev);
508
509 amba_set_drvdata(dev, NULL);
510
511 iounmap(t->etb_regs);
512 t->etb_regs = NULL;
513
6fa3eb70
S
514 if (!IS_ERR(t->emu_clk)) {
515 clk_disable(t->emu_clk);
516 clk_put(t->emu_clk);
517 }
c5d6c770
AS
518
519 amba_release_regions(dev);
520
521 return 0;
522}
523
524static struct amba_id etb_ids[] = {
525 {
526 .id = 0x0003b907,
527 .mask = 0x0007ffff,
528 },
529 { 0, 0 },
530};
531
532static struct amba_driver etb_driver = {
533 .drv = {
534 .name = "etb",
535 .owner = THIS_MODULE,
536 },
537 .probe = etb_probe,
538 .remove = etb_remove,
539 .id_table = etb_ids,
540};
541
542/* use a sysfs file "trace_running" to start/stop tracing */
543static ssize_t trace_running_show(struct kobject *kobj,
544 struct kobj_attribute *attr,
545 char *buf)
546{
547 return sprintf(buf, "%x\n", trace_isrunning(&tracer));
548}
549
550static ssize_t trace_running_store(struct kobject *kobj,
551 struct kobj_attribute *attr,
552 const char *buf, size_t n)
553{
554 unsigned int value;
555 int ret;
556
557 if (sscanf(buf, "%u", &value) != 1)
558 return -EINVAL;
559
560 mutex_lock(&tracer.mutex);
6fa3eb70
S
561 if (!tracer.etb_regs)
562 ret = -ENODEV;
563 else
564 ret = value ? trace_start(&tracer) : trace_stop(&tracer);
c5d6c770
AS
565 mutex_unlock(&tracer.mutex);
566
567 return ret ? : n;
568}
569
570static struct kobj_attribute trace_running_attr =
571 __ATTR(trace_running, 0644, trace_running_show, trace_running_store);
572
573static ssize_t trace_info_show(struct kobject *kobj,
574 struct kobj_attribute *attr,
575 char *buf)
576{
577 u32 etb_wa, etb_ra, etb_st, etb_fc, etm_ctrl, etm_st;
578 int datalen;
6fa3eb70
S
579 int id;
580 int ret;
c5d6c770 581
6fa3eb70
S
582 mutex_lock(&tracer.mutex);
583 if (tracer.etb_regs) {
584 etb_unlock(&tracer);
585 datalen = etb_getdatalen(&tracer);
586 etb_wa = etb_readl(&tracer, ETBR_WRITEADDR);
587 etb_ra = etb_readl(&tracer, ETBR_READADDR);
588 etb_st = etb_readl(&tracer, ETBR_STATUS);
589 etb_fc = etb_readl(&tracer, ETBR_FORMATTERCTRL);
590 etb_lock(&tracer);
591 } else {
592 etb_wa = etb_ra = etb_st = etb_fc = ~0;
593 datalen = -1;
594 }
c5d6c770 595
6fa3eb70 596 ret = sprintf(buf, "Trace buffer len: %d\nComparator pairs: %d\n"
c5d6c770
AS
597 "ETBR_WRITEADDR:\t%08x\n"
598 "ETBR_READADDR:\t%08x\n"
599 "ETBR_STATUS:\t%08x\n"
6fa3eb70 600 "ETBR_FORMATTERCTRL:\t%08x\n",
c5d6c770
AS
601 datalen,
602 tracer.ncmppairs,
603 etb_wa,
604 etb_ra,
605 etb_st,
6fa3eb70
S
606 etb_fc
607 );
608
609 for (id = 0; id < tracer.etm_regs_count; id++) {
610 etm_unlock(&tracer, id);
611 etm_ctrl = etm_readl(&tracer, id, ETMR_CTRL);
612 etm_st = etm_readl(&tracer, id, ETMR_STATUS);
613 etm_lock(&tracer, id);
614 ret += sprintf(buf + ret, "ETMR_CTRL:\t%08x\n"
615 "ETMR_STATUS:\t%08x\n",
c5d6c770
AS
616 etm_ctrl,
617 etm_st
618 );
6fa3eb70
S
619 }
620 mutex_unlock(&tracer.mutex);
621
622 return ret;
c5d6c770
AS
623}
624
625static struct kobj_attribute trace_info_attr =
626 __ATTR(trace_info, 0444, trace_info_show, NULL);
627
628static ssize_t trace_mode_show(struct kobject *kobj,
629 struct kobj_attribute *attr,
630 char *buf)
631{
632 return sprintf(buf, "%d %d\n",
633 !!(tracer.flags & TRACER_CYCLE_ACC),
634 tracer.etm_portsz);
635}
636
637static ssize_t trace_mode_store(struct kobject *kobj,
638 struct kobj_attribute *attr,
639 const char *buf, size_t n)
640{
641 unsigned int cycacc, portsz;
642
643 if (sscanf(buf, "%u %u", &cycacc, &portsz) != 2)
644 return -EINVAL;
645
646 mutex_lock(&tracer.mutex);
647 if (cycacc)
648 tracer.flags |= TRACER_CYCLE_ACC;
649 else
650 tracer.flags &= ~TRACER_CYCLE_ACC;
651
652 tracer.etm_portsz = portsz & 0x0f;
653 mutex_unlock(&tracer.mutex);
654
655 return n;
656}
657
658static struct kobj_attribute trace_mode_attr =
659 __ATTR(trace_mode, 0644, trace_mode_show, trace_mode_store);
660
6fa3eb70
S
661static ssize_t trace_contextid_size_show(struct kobject *kobj,
662 struct kobj_attribute *attr,
663 char *buf)
664{
665 /* 0: No context id tracing, 1: One byte, 2: Two bytes, 3: Four bytes */
666 return sprintf(buf, "%d\n", (1 << tracer.etm_contextid_size) >> 1);
667}
668
669static ssize_t trace_contextid_size_store(struct kobject *kobj,
670 struct kobj_attribute *attr,
671 const char *buf, size_t n)
672{
673 unsigned int contextid_size;
674
675 if (sscanf(buf, "%u", &contextid_size) != 1)
676 return -EINVAL;
677
678 if (contextid_size == 3 || contextid_size > 4)
679 return -EINVAL;
680
681 mutex_lock(&tracer.mutex);
682 tracer.etm_contextid_size = fls(contextid_size);
683 mutex_unlock(&tracer.mutex);
684
685 return n;
686}
687
688static struct kobj_attribute trace_contextid_size_attr =
689 __ATTR(trace_contextid_size, 0644,
690 trace_contextid_size_show, trace_contextid_size_store);
691
692static ssize_t trace_branch_output_show(struct kobject *kobj,
693 struct kobj_attribute *attr,
694 char *buf)
695{
696 return sprintf(buf, "%d\n", !!(tracer.flags & TRACER_BRANCHOUTPUT));
697}
698
699static ssize_t trace_branch_output_store(struct kobject *kobj,
700 struct kobj_attribute *attr,
701 const char *buf, size_t n)
702{
703 unsigned int branch_output;
704
705 if (sscanf(buf, "%u", &branch_output) != 1)
706 return -EINVAL;
707
708 mutex_lock(&tracer.mutex);
709 if (branch_output) {
710 tracer.flags |= TRACER_BRANCHOUTPUT;
711 /* Branch broadcasting is incompatible with the return stack */
712 tracer.flags &= ~TRACER_RETURN_STACK;
713 } else {
714 tracer.flags &= ~TRACER_BRANCHOUTPUT;
715 }
716 mutex_unlock(&tracer.mutex);
717
718 return n;
719}
720
721static struct kobj_attribute trace_branch_output_attr =
722 __ATTR(trace_branch_output, 0644,
723 trace_branch_output_show, trace_branch_output_store);
724
725static ssize_t trace_return_stack_show(struct kobject *kobj,
726 struct kobj_attribute *attr,
727 char *buf)
728{
729 return sprintf(buf, "%d\n", !!(tracer.flags & TRACER_RETURN_STACK));
730}
731
732static ssize_t trace_return_stack_store(struct kobject *kobj,
733 struct kobj_attribute *attr,
734 const char *buf, size_t n)
735{
736 unsigned int return_stack;
737
738 if (sscanf(buf, "%u", &return_stack) != 1)
739 return -EINVAL;
740
741 mutex_lock(&tracer.mutex);
742 if (return_stack) {
743 tracer.flags |= TRACER_RETURN_STACK;
744 /* Return stack is incompatible with branch broadcasting */
745 tracer.flags &= ~TRACER_BRANCHOUTPUT;
746 } else {
747 tracer.flags &= ~TRACER_RETURN_STACK;
748 }
749 mutex_unlock(&tracer.mutex);
750
751 return n;
752}
753
754static struct kobj_attribute trace_return_stack_attr =
755 __ATTR(trace_return_stack, 0644,
756 trace_return_stack_show, trace_return_stack_store);
757
758static ssize_t trace_timestamp_show(struct kobject *kobj,
759 struct kobj_attribute *attr,
760 char *buf)
761{
762 return sprintf(buf, "%d\n", !!(tracer.flags & TRACER_TIMESTAMP));
763}
764
765static ssize_t trace_timestamp_store(struct kobject *kobj,
766 struct kobj_attribute *attr,
767 const char *buf, size_t n)
768{
769 unsigned int timestamp;
770
771 if (sscanf(buf, "%u", &timestamp) != 1)
772 return -EINVAL;
773
774 mutex_lock(&tracer.mutex);
775 if (timestamp)
776 tracer.flags |= TRACER_TIMESTAMP;
777 else
778 tracer.flags &= ~TRACER_TIMESTAMP;
779 mutex_unlock(&tracer.mutex);
780
781 return n;
782}
783
784static struct kobj_attribute trace_timestamp_attr =
785 __ATTR(trace_timestamp, 0644,
786 trace_timestamp_show, trace_timestamp_store);
787
788static ssize_t trace_range_show(struct kobject *kobj,
789 struct kobj_attribute *attr,
790 char *buf)
791{
792 return sprintf(buf, "%08lx %08lx\n",
793 tracer.range_start, tracer.range_end);
794}
795
796static ssize_t trace_range_store(struct kobject *kobj,
797 struct kobj_attribute *attr,
798 const char *buf, size_t n)
799{
800 unsigned long range_start, range_end;
801
802 if (sscanf(buf, "%lx %lx", &range_start, &range_end) != 2)
803 return -EINVAL;
804
805 mutex_lock(&tracer.mutex);
806 tracer.range_start = range_start;
807 tracer.range_end = range_end;
808 mutex_unlock(&tracer.mutex);
809
810 return n;
811}
812
813
814static struct kobj_attribute trace_range_attr =
815 __ATTR(trace_range, 0644, trace_range_show, trace_range_store);
816
817static ssize_t trace_data_range_show(struct kobject *kobj,
818 struct kobj_attribute *attr,
819 char *buf)
820{
821 unsigned long range_start;
822 u64 range_end;
823 mutex_lock(&tracer.mutex);
824 range_start = tracer.data_range_start;
825 range_end = tracer.data_range_end;
826 if (!range_end && (tracer.flags & TRACER_TRACE_DATA))
827 range_end = 0x100000000ULL;
828 mutex_unlock(&tracer.mutex);
829 return sprintf(buf, "%08lx %08llx\n", range_start, range_end);
830}
831
832static ssize_t trace_data_range_store(struct kobject *kobj,
833 struct kobj_attribute *attr,
834 const char *buf, size_t n)
835{
836 unsigned long range_start;
837 u64 range_end;
838
839 if (sscanf(buf, "%lx %llx", &range_start, &range_end) != 2)
840 return -EINVAL;
841
842 mutex_lock(&tracer.mutex);
843 tracer.data_range_start = range_start;
844 tracer.data_range_end = (unsigned long)range_end;
845 if (range_end)
846 tracer.flags |= TRACER_TRACE_DATA;
847 else
848 tracer.flags &= ~TRACER_TRACE_DATA;
849 mutex_unlock(&tracer.mutex);
850
851 return n;
852}
853
854
855static struct kobj_attribute trace_data_range_attr =
856 __ATTR(trace_data_range, 0644,
857 trace_data_range_show, trace_data_range_store);
858
351a102d 859static int etm_probe(struct amba_device *dev, const struct amba_id *id)
c5d6c770
AS
860{
861 struct tracectx *t = &tracer;
862 int ret = 0;
6fa3eb70
S
863 void __iomem **new_regs;
864 int new_count;
865 u32 etmccr;
866 u32 etmidr;
867 u32 etmccer = 0;
868 u8 etm_version = 0;
869
870 mutex_lock(&t->mutex);
871 new_count = t->etm_regs_count + 1;
872 new_regs = krealloc(t->etm_regs,
873 sizeof(t->etm_regs[0]) * new_count, GFP_KERNEL);
c5d6c770 874
6fa3eb70
S
875 if (!new_regs) {
876 dev_dbg(&dev->dev, "Failed to allocate ETM register array\n");
877 ret = -ENOMEM;
c5d6c770
AS
878 goto out;
879 }
6fa3eb70 880 t->etm_regs = new_regs;
c5d6c770
AS
881
882 ret = amba_request_regions(dev, NULL);
883 if (ret)
884 goto out;
885
6fa3eb70
S
886 t->etm_regs[t->etm_regs_count] =
887 ioremap_nocache(dev->res.start, resource_size(&dev->res));
888 if (!t->etm_regs[t->etm_regs_count]) {
c5d6c770
AS
889 ret = -ENOMEM;
890 goto out_release;
891 }
892
6fa3eb70 893 amba_set_drvdata(dev, t->etm_regs[t->etm_regs_count]);
c5d6c770 894
6fa3eb70 895 t->flags = TRACER_CYCLE_ACC | TRACER_TRACE_DATA | TRACER_BRANCHOUTPUT;
c5d6c770 896 t->etm_portsz = 1;
6fa3eb70 897 t->etm_contextid_size = 3;
c5d6c770 898
6fa3eb70
S
899 etm_unlock(t, t->etm_regs_count);
900 (void)etm_readl(t, t->etm_regs_count, ETMMR_PDSR);
988257cf 901 /* dummy first read */
6fa3eb70
S
902 (void)etm_readl(&tracer, t->etm_regs_count, ETMMR_OSSRR);
903
904 etmccr = etm_readl(t, t->etm_regs_count, ETMR_CONFCODE);
905 t->ncmppairs = etmccr & 0xf;
906 if (etmccr & ETMCCR_ETMIDR_PRESENT) {
907 etmidr = etm_readl(t, t->etm_regs_count, ETMR_ID);
908 etm_version = ETMIDR_VERSION(etmidr);
909 if (etm_version >= ETMIDR_VERSION_3_1)
910 etmccer = etm_readl(t, t->etm_regs_count, ETMR_CCE);
911 }
912 etm_writel(t, t->etm_regs_count, 0x441, ETMR_CTRL);
913 etm_writel(t, t->etm_regs_count, new_count, ETMR_TRACEIDR);
914 etm_lock(t, t->etm_regs_count);
c5d6c770
AS
915
916 ret = sysfs_create_file(&dev->dev.kobj,
917 &trace_running_attr.attr);
918 if (ret)
919 goto out_unmap;
920
921 /* failing to create any of these two is not fatal */
922 ret = sysfs_create_file(&dev->dev.kobj, &trace_info_attr.attr);
923 if (ret)
924 dev_dbg(&dev->dev, "Failed to create trace_info in sysfs\n");
925
926 ret = sysfs_create_file(&dev->dev.kobj, &trace_mode_attr.attr);
927 if (ret)
928 dev_dbg(&dev->dev, "Failed to create trace_mode in sysfs\n");
929
6fa3eb70
S
930 ret = sysfs_create_file(&dev->dev.kobj,
931 &trace_contextid_size_attr.attr);
932 if (ret)
933 dev_dbg(&dev->dev,
934 "Failed to create trace_contextid_size in sysfs\n");
935
936 ret = sysfs_create_file(&dev->dev.kobj,
937 &trace_branch_output_attr.attr);
938 if (ret)
939 dev_dbg(&dev->dev,
940 "Failed to create trace_branch_output in sysfs\n");
941
942 if (etmccer & ETMCCER_RETURN_STACK_IMPLEMENTED) {
943 ret = sysfs_create_file(&dev->dev.kobj,
944 &trace_return_stack_attr.attr);
945 if (ret)
946 dev_dbg(&dev->dev,
947 "Failed to create trace_return_stack in sysfs\n");
948 }
949
950 if (etmccer & ETMCCER_TIMESTAMPING_IMPLEMENTED) {
951 ret = sysfs_create_file(&dev->dev.kobj,
952 &trace_timestamp_attr.attr);
953 if (ret)
954 dev_dbg(&dev->dev,
955 "Failed to create trace_timestamp in sysfs\n");
956 }
957
958 ret = sysfs_create_file(&dev->dev.kobj, &trace_range_attr.attr);
959 if (ret)
960 dev_dbg(&dev->dev, "Failed to create trace_range in sysfs\n");
961
962 if (etm_version < ETMIDR_VERSION_PFT_1_0) {
963 ret = sysfs_create_file(&dev->dev.kobj,
964 &trace_data_range_attr.attr);
965 if (ret)
966 dev_dbg(&dev->dev,
967 "Failed to create trace_data_range in sysfs\n");
968 } else {
969 tracer.flags &= ~TRACER_TRACE_DATA;
970 }
971
972 dev_dbg(&dev->dev, "ETM AMBA driver initialized.\n");
973
974 /* Enable formatter if there are multiple trace sources */
975 if (new_count > 1)
976 t->etb_fc = ETBFF_ENFCONT | ETBFF_ENFTC;
977
978 t->etm_regs_count = new_count;
c5d6c770
AS
979
980out:
6fa3eb70 981 mutex_unlock(&t->mutex);
c5d6c770
AS
982 return ret;
983
984out_unmap:
985 amba_set_drvdata(dev, NULL);
6fa3eb70 986 iounmap(t->etm_regs[t->etm_regs_count]);
c5d6c770
AS
987
988out_release:
989 amba_release_regions(dev);
990
6fa3eb70 991 mutex_unlock(&t->mutex);
c5d6c770
AS
992 return ret;
993}
994
995static int etm_remove(struct amba_device *dev)
996{
6fa3eb70
S
997 int i;
998 struct tracectx *t = &tracer;
999 void __iomem *etm_regs = amba_get_drvdata(dev);
1000
1001 sysfs_remove_file(&dev->dev.kobj, &trace_running_attr.attr);
1002 sysfs_remove_file(&dev->dev.kobj, &trace_info_attr.attr);
1003 sysfs_remove_file(&dev->dev.kobj, &trace_mode_attr.attr);
1004 sysfs_remove_file(&dev->dev.kobj, &trace_range_attr.attr);
1005 sysfs_remove_file(&dev->dev.kobj, &trace_data_range_attr.attr);
c5d6c770
AS
1006
1007 amba_set_drvdata(dev, NULL);
1008
6fa3eb70
S
1009 mutex_lock(&t->mutex);
1010 for (i = 0; i < t->etm_regs_count; i++)
1011 if (t->etm_regs[i] == etm_regs)
1012 break;
1013 for (; i < t->etm_regs_count - 1; i++)
1014 t->etm_regs[i] = t->etm_regs[i + 1];
1015 t->etm_regs_count--;
1016 if (!t->etm_regs_count) {
1017 kfree(t->etm_regs);
1018 t->etm_regs = NULL;
1019 }
1020 mutex_unlock(&t->mutex);
c5d6c770 1021
6fa3eb70 1022 iounmap(etm_regs);
c5d6c770
AS
1023 amba_release_regions(dev);
1024
c5d6c770
AS
1025 return 0;
1026}
1027
1028static struct amba_id etm_ids[] = {
1029 {
1030 .id = 0x0003b921,
1031 .mask = 0x0007ffff,
1032 },
6fa3eb70
S
1033 {
1034 .id = 0x0003b950,
1035 .mask = 0x0007ffff,
1036 },
c5d6c770
AS
1037 { 0, 0 },
1038};
1039
1040static struct amba_driver etm_driver = {
1041 .drv = {
1042 .name = "etm",
1043 .owner = THIS_MODULE,
1044 },
1045 .probe = etm_probe,
1046 .remove = etm_remove,
1047 .id_table = etm_ids,
1048};
1049
1050static int __init etm_init(void)
1051{
1052 int retval;
1053
6fa3eb70
S
1054 mutex_init(&tracer.mutex);
1055
c5d6c770
AS
1056 retval = amba_driver_register(&etb_driver);
1057 if (retval) {
1058 printk(KERN_ERR "Failed to register etb\n");
1059 return retval;
1060 }
1061
1062 retval = amba_driver_register(&etm_driver);
1063 if (retval) {
1064 amba_driver_unregister(&etb_driver);
1065 printk(KERN_ERR "Failed to probe etm\n");
1066 return retval;
1067 }
1068
1069 /* not being able to install this handler is not fatal */
1070 (void)register_sysrq_key('v', &sysrq_etm_op);
1071
1072 return 0;
1073}
1074
1075device_initcall(etm_init);
1076