Пример #1
0
Файл: etm.c Проект: 08opt/linux
static int trace_start(struct tracectx *t)
{
	u32 v;
	unsigned long timeout = TRACER_TIMEOUT;

	etb_unlock(t);

	etb_writel(t, 0, ETBR_FORMATTERCTRL);
	etb_writel(t, 1, ETBR_CTRL);

	etb_lock(t);

	/* configure etm */
	v = ETMCTRL_OPTS | ETMCTRL_PROGRAM | ETMCTRL_PORTSIZE(t->etm_portsz);

	if (t->flags & TRACER_CYCLE_ACC)
		v |= ETMCTRL_CYCLEACCURATE;

	etm_unlock(t);

	etm_writel(t, v, ETMR_CTRL);

	while (!(etm_readl(t, ETMR_CTRL) & ETMCTRL_PROGRAM) && --timeout)
		;
	if (!timeout) {
		dev_dbg(t->dev, "Waiting for progbit to assert timed out\n");
		etm_lock(t);
		return -EFAULT;
	}

	etm_setup_address_range(t, 1, (unsigned long)_stext,
			(unsigned long)_etext, 0, 0);
	etm_writel(t, 0, ETMR_TRACEENCTRL2);
	etm_writel(t, 0, ETMR_TRACESSCTRL);
	etm_writel(t, 0x6f, ETMR_TRACEENEVT);

	v &= ~ETMCTRL_PROGRAM;
	v |= ETMCTRL_PORTSEL;

	etm_writel(t, v, ETMR_CTRL);

	timeout = TRACER_TIMEOUT;
	while (etm_readl(t, ETMR_CTRL) & ETMCTRL_PROGRAM && --timeout)
		;
	if (!timeout) {
		dev_dbg(t->dev, "Waiting for progbit to deassert timed out\n");
		etm_lock(t);
		return -EFAULT;
	}

	etm_lock(t);

	t->flags |= TRACER_RUNNING;

	return 0;
}
Пример #2
0
Файл: etm.c Проект: 08opt/linux
static int trace_stop(struct tracectx *t)
{
	unsigned long timeout = TRACER_TIMEOUT;

	etm_unlock(t);

	etm_writel(t, 0x440, ETMR_CTRL);
	while (!(etm_readl(t, ETMR_CTRL) & ETMCTRL_PROGRAM) && --timeout)
		;
	if (!timeout) {
		dev_dbg(t->dev, "Waiting for progbit to assert timed out\n");
		etm_lock(t);
		return -EFAULT;
	}

	etm_lock(t);

	etb_unlock(t);
	etb_writel(t, ETBFF_MANUAL_FLUSH, ETBR_FORMATTERCTRL);

	timeout = TRACER_TIMEOUT;
	while (etb_readl(t, ETBR_FORMATTERCTRL) &
			ETBFF_MANUAL_FLUSH && --timeout)
		;
	if (!timeout) {
		dev_dbg(t->dev, "Waiting for formatter flush to commence "
				"timed out\n");
		etb_lock(t);
		return -EFAULT;
	}

	etb_writel(t, 0, ETBR_CTRL);

	etb_lock(t);

	t->flags &= ~TRACER_RUNNING;

	return 0;
}
static void coresight_etm_restore(void)
{
	struct etm_info *p_etm_info;
	void __iomem *p_etm_base = ETM_BASE(raw_smp_processor_id());

	/* unlock software lock */
	etm_unlock();

	/* Fix me, normally, lock OS lock can disable trace unit and external access,
	 * but found OS lock can't lock/unlock issue when doing MBTF test, so replace
	 * with TRC_PRGCTLR to disabel trace unit
	 */
#if USE_OSLOCK
	etm_os_lock();
#else
	writel_relaxed(0x0, p_etm_base + TRC_PRGCTLR);
#endif

	/* restore registers */
	p_etm_info = this_cpu_ptr(&cpu_etm_info);
	writel_relaxed(p_etm_info->trc_config, p_etm_base + TRC_CONFIGR);
	writel_relaxed(p_etm_info->trc_eventctl0, p_etm_base + TRC_EVENTCTL0R);
	writel_relaxed(p_etm_info->trc_eventctl1, p_etm_base + TRC_EVENTCTL1R);
	writel_relaxed(p_etm_info->trc_stallctl, p_etm_base + TRC_STALLCTLR);
	writel_relaxed(p_etm_info->trc_tsctlr, p_etm_base + TRC_TSCTLR);
	writel_relaxed(p_etm_info->trc_syncpr, p_etm_base + TRC_SYNCPR);
	writel_relaxed(p_etm_info->trc_bbctl, p_etm_base + TRC_BBCTLR);
	writel_relaxed(p_etm_info->trc_traceid, p_etm_base + TRC_TRACEIDR);
	writel_relaxed(p_etm_info->trc_victlr, p_etm_base + TRC_VICTLR);
	writel_relaxed(p_etm_info->trc_viiectl, p_etm_base + TRC_VIIECTLR);
	writel_relaxed(p_etm_info->trc_vissctl, p_etm_base + TRC_VISSCTLR);
#if USE_OSLOCK
	writel_relaxed(p_etm_info->trc_prgctl, p_etm_base + TRC_PRGCTLR);
#else
	writel_relaxed(0x1, p_etm_base + TRC_PRGCTLR);
#endif

	/* unlock os lock */
	etm_os_unlock();

	/* lock software lock */
	etm_lock();
}
Пример #4
0
Файл: etm.c Проект: 08opt/linux
static ssize_t trace_info_show(struct kobject *kobj,
				  struct kobj_attribute *attr,
				  char *buf)
{
	u32 etb_wa, etb_ra, etb_st, etb_fc, etm_ctrl, etm_st;
	int datalen;

	etb_unlock(&tracer);
	datalen = etb_getdatalen(&tracer);
	etb_wa = etb_readl(&tracer, ETBR_WRITEADDR);
	etb_ra = etb_readl(&tracer, ETBR_READADDR);
	etb_st = etb_readl(&tracer, ETBR_STATUS);
	etb_fc = etb_readl(&tracer, ETBR_FORMATTERCTRL);
	etb_lock(&tracer);

	etm_unlock(&tracer);
	etm_ctrl = etm_readl(&tracer, ETMR_CTRL);
	etm_st = etm_readl(&tracer, ETMR_STATUS);
	etm_lock(&tracer);

	return sprintf(buf, "Trace buffer len: %d\nComparator pairs: %d\n"
			"ETBR_WRITEADDR:\t%08x\n"
			"ETBR_READADDR:\t%08x\n"
			"ETBR_STATUS:\t%08x\n"
			"ETBR_FORMATTERCTRL:\t%08x\n"
			"ETMR_CTRL:\t%08x\n"
			"ETMR_STATUS:\t%08x\n",
			datalen,
			tracer.ncmppairs,
			etb_wa,
			etb_ra,
			etb_st,
			etb_fc,
			etm_ctrl,
			etm_st
			);
}
static void coresight_etm_save(void)
{
	struct etm_info *p_etm_info;
	u32 timeout, val;
	void __iomem *p_etm_base = ETM_BASE(raw_smp_processor_id());

	mb();
	isb();

	/* unlock software lock */
	etm_unlock();

	/* Fix me, normally, lock OS lock can disable trace unit and external access,
	 * but found OS lock can't lock/unlock issue when doing MBTF test, so replace
	 * with TRC_PRGCTLR to disabel trace unit
	 */
#if USE_OSLOCK
	etm_os_lock();
#else
	writel_relaxed(0x0, p_etm_base + TRC_PRGCTLR);
#endif

	/* Check the programmers' model is stable */
	timeout = 100;
	do {
		val = readl(p_etm_base + TRC_STATR);
		if (val & (0x1 << 1))
			break;
		udelay(1);
	} while (--timeout);
	if (!timeout)
		pr_info("cpu%d's programmer model is unstable.\n",
			raw_smp_processor_id());

	/* save register */
	p_etm_info = this_cpu_ptr(&cpu_etm_info);
	p_etm_info->trc_config = readl_relaxed(p_etm_base + TRC_CONFIGR);
	p_etm_info->trc_eventctl0 = readl_relaxed(p_etm_base + TRC_EVENTCTL0R);
	p_etm_info->trc_eventctl1 = readl_relaxed(p_etm_base + TRC_EVENTCTL1R);
	p_etm_info->trc_stallctl = readl_relaxed(p_etm_base + TRC_STALLCTLR);
	p_etm_info->trc_tsctlr = readl_relaxed(p_etm_base + TRC_TSCTLR);
	p_etm_info->trc_syncpr = readl_relaxed(p_etm_base + TRC_SYNCPR);
	p_etm_info->trc_bbctl = readl_relaxed(p_etm_base + TRC_BBCTLR);
	p_etm_info->trc_traceid = readl_relaxed(p_etm_base + TRC_TRACEIDR);
	p_etm_info->trc_victlr = readl_relaxed(p_etm_base + TRC_VICTLR);
	p_etm_info->trc_viiectl = readl_relaxed(p_etm_base + TRC_VIIECTLR);
	p_etm_info->trc_vissctl = readl_relaxed(p_etm_base + TRC_VISSCTLR);
#if USE_OSLOCK
	p_etm_info->trc_prgctl = readl_relaxed(p_etm_base + TRC_PRGCTLR);
#endif

	/* ensure trace unit is idle to be powered down */
	timeout = 100;
	do {
		val = readl(p_etm_base + TRC_STATR);
		if (val & (0x1 << 0))
			break;
		udelay(1);
	} while (--timeout);
	if (!timeout)
		pr_info("cpu%d's programmer model is not idle.\n",
			raw_smp_processor_id());

	/* lock software lock */
	etm_lock();
}
Пример #6
0
Файл: etm.c Проект: 08opt/linux
static int __devinit etm_probe(struct amba_device *dev, const struct amba_id *id)
{
	struct tracectx *t = &tracer;
	int ret = 0;

	if (t->etm_regs) {
		dev_dbg(&dev->dev, "ETM already initialized\n");
		ret = -EBUSY;
		goto out;
	}

	ret = amba_request_regions(dev, NULL);
	if (ret)
		goto out;

	t->etm_regs = ioremap_nocache(dev->res.start, resource_size(&dev->res));
	if (!t->etm_regs) {
		ret = -ENOMEM;
		goto out_release;
	}

	amba_set_drvdata(dev, t);

	mutex_init(&t->mutex);
	t->dev = &dev->dev;
	t->flags = TRACER_CYCLE_ACC;
	t->etm_portsz = 1;

	etm_unlock(t);
	(void)etm_readl(t, ETMMR_PDSR);
	/* dummy first read */
	(void)etm_readl(&tracer, ETMMR_OSSRR);

	t->ncmppairs = etm_readl(t, ETMR_CONFCODE) & 0xf;
	etm_writel(t, 0x440, ETMR_CTRL);
	etm_lock(t);

	ret = sysfs_create_file(&dev->dev.kobj,
			&trace_running_attr.attr);
	if (ret)
		goto out_unmap;

	/* failing to create any of these two is not fatal */
	ret = sysfs_create_file(&dev->dev.kobj, &trace_info_attr.attr);
	if (ret)
		dev_dbg(&dev->dev, "Failed to create trace_info in sysfs\n");

	ret = sysfs_create_file(&dev->dev.kobj, &trace_mode_attr.attr);
	if (ret)
		dev_dbg(&dev->dev, "Failed to create trace_mode in sysfs\n");

	dev_dbg(t->dev, "ETM AMBA driver initialized.\n");

out:
	return ret;

out_unmap:
	amba_set_drvdata(dev, NULL);
	iounmap(t->etm_regs);

out_release:
	amba_release_regions(dev);

	return ret;
}