Commit eada2a9e authored by Federico Vaga's avatar Federico Vaga

sw:drv: add debug interface

Signed-off-by: Federico Vaga's avatarFederico Vaga <federico.vaga@cern.ch>
parent 2c425e43
......@@ -244,3 +244,12 @@ You can find the HMQ *sysfs* attributes at::
.. [1] https://www.kernel.org/doc/Documentation/driver-model/platform.txt
Debugging Interface
-------------------
The driver exports on debugfs a file in YAML format which contains status
information: variable values, register values. This file is named as
the Mock Turtle instance that represents "trtl-%04x".::
cat /sys/kernel/debug/trtl-0001
......@@ -25,6 +25,7 @@ mockturtle-y := mockturtle-core.o
mockturtle-y += mockturtle-cpu.o
mockturtle-y += mockturtle-hmq.o
mockturtle-y += mockturtle-tty.o
mockturtle-y += mockturtle-dbg.o
all modules:
$(MAKE) -C $(LINUX) M=$(shell /bin/pwd) modules
......
......@@ -14,7 +14,6 @@
#include <linux/vmalloc.h>
#include <linux/interrupt.h>
#include <linux/byteorder/generic.h>
#include <linux/debugfs.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/spinlock.h>
......@@ -637,13 +636,6 @@ int trtl_probe(struct platform_device *pdev)
goto out_cfg;
}
trtl->dbg_dir = debugfs_create_dir(dev_name(&trtl->dev), NULL);
if (IS_ERR_OR_NULL(trtl->dbg_dir)) {
dev_err(&pdev->dev, "Cannot create debugfs\n");
err = PTR_ERR(trtl->dbg_dir);
goto out_dbg;
}
/* Reset all CPUs */
trtl_cpu_reset_set(trtl, (1 << trtl->cfgrom.n_cpu) - 1);
......@@ -691,13 +683,13 @@ int trtl_probe(struct platform_device *pdev)
dev_info(&trtl->dev, "%s: Application ID: 0x%08x\n",
__func__, trtl->cfgrom.app_id);
trtl_debugfs_init(trtl);
return 0;
out_cpu:
while (--i)
trtl_remove_cpu(trtl, i);
debugfs_remove_recursive(trtl->dbg_dir);
out_dbg:
out_rom:
sysfs_remove_bin_file(&trtl->dev.kobj, &trtl_config_rom_sysfs);
out_cfg:
......@@ -717,6 +709,8 @@ int trtl_remove(struct platform_device *pdev)
struct trtl_dev *trtl = platform_get_drvdata(pdev);
int i;
trtl_debugfs_exit(trtl);
trtl_tty_remove(trtl);
for (i = 0; i < trtl->cfgrom.n_cpu; ++i)
......@@ -727,7 +721,6 @@ int trtl_remove(struct platform_device *pdev)
free_irq(platform_get_irq(pdev, TRTL_IRQ_HMQ_OUT), trtl);
free_irq(platform_get_irq(pdev, TRTL_IRQ_NOT), trtl);
debugfs_remove_recursive(trtl->dbg_dir);
sysfs_remove_bin_file(&trtl->dev.kobj, &trtl_config_rom_sysfs);
/* FIXME cannot explain why, but without sleep the _kernel_ crash */
......
/*
* Copyright (C) 2014-2016 CERN (www.cern.ch)
* Author: Federico Vaga <federico.vaga@cern.ch>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <linux/debugfs.h>
#include <linux/device.h>
#include <linux/seq_file.h>
#include <hw/mockturtle_cpu_csr.h>
#include "mockturtle-drv.h"
static int trtl_dbg_info_seq_read(struct seq_file *s, void *data)
{
struct trtl_dev *trtl = s->private;
struct trtl_cpu *cpu;
struct trtl_hmq *hmq;
int i, k;
seq_printf(s, "%s\n", dev_name(&trtl->dev));
seq_printf(s, "cpu-core:\n");
seq_printf(s, " HMQ input status LO: 0x%x:\n",
trtl_ioread(trtl, trtl->base_csr + MT_CPU_CSR_REG_HMQI_STATUS_LO));
seq_printf(s, " HMQ input status HI: 0x%x:\n",
trtl_ioread(trtl, trtl->base_csr + MT_CPU_CSR_REG_HMQI_STATUS_HI));
seq_printf(s, " HMQ output status LO: 0x%x:\n",
trtl_ioread(trtl, trtl->base_csr + MT_CPU_CSR_REG_HMQO_STATUS_LO));
seq_printf(s, " HMQ output status HI: 0x%x:\n",
trtl_ioread(trtl, trtl->base_csr + MT_CPU_CSR_REG_HMQO_STATUS_HI));
seq_printf(s, " cpu-core:\n");
for (i = 0; i < trtl->cfgrom.n_cpu; ++i) {
cpu = &trtl->cpu[i];
seq_printf(s, " - index: %d\n", cpu->index);
seq_printf(s, " name: %s\n", dev_name(&cpu->dev));
seq_printf(s, " hmq:\n");
for (k = 0; k < trtl->cfgrom.n_hmq[i]; ++k) {
hmq = &cpu->hmq[k];
seq_printf(s, " - index: %d\n", hmq->index);
seq_printf(s, " name: %s\n", dev_name(&hmq->dev));
seq_printf(s, " buf-in-r: %d (look user)\n", hmq->buf_in.idx_r);
seq_printf(s, " buf-in-w: %d\n", hmq->buf_in.idx_w);
seq_printf(s, " buf-out-r: %d\n", hmq->buf_out.idx_r);
seq_printf(s, " buf-out-w: %d\n", hmq->buf_out.idx_w);
}
}
return 0;
}
static int trtl_dbg_info_open(struct inode *inode, struct file *file)
{
return single_open(file, trtl_dbg_info_seq_read, inode->i_private);
}
static const struct file_operations trtl_dbg_info_ops = {
.owner = THIS_MODULE,
.open = trtl_dbg_info_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
/**
* It creates the debug info file
* @trtl: the mock turtle device instance
*/
void trtl_debugfs_init(struct trtl_dev *trtl)
{
char name[20];
trtl->dbg_dir = debugfs_create_dir(dev_name(&trtl->dev), NULL);
if (IS_ERR_OR_NULL(trtl->dbg_dir)) {
dev_err(&trtl->dev, "Cannot create debugfs\n");
return;
}
trtl->dbg_info = debugfs_create_file("info", 0444,
trtl->dbg_dir, trtl,
&trtl_dbg_info_ops);
if (IS_ERR_OR_NULL(trtl->dbg_info)) {
dev_err(&trtl->dev,
"Cannot create debugfs file: %ld\n",
PTR_ERR(trtl->dbg_info));
trtl->dbg_info = NULL;
}
}
/**
* It removes the debug info file
* @trtl: the mock turtle device instance
*/
void trtl_debugfs_exit(struct trtl_dev *trtl)
{
if (trtl->dbg_dir)
debugfs_remove_recursive(trtl->dbg_dir);
}
......@@ -182,7 +182,6 @@ struct trtl_cpu {
int index; /**< instance number */
struct device dev; /**< device representing a single CPU */
struct dentry *dbg_msg; /**< debug messages interface */
struct circ_buf cbuf; /**< debug circular buffer */
struct spinlock lock;
struct trtl_hmq hmq[TRTL_MAX_MQ_CHAN]; /**< list of HMQ slots used by
......@@ -214,8 +213,6 @@ struct trtl_dev {
enum trtl_smem_modifier mod; /**< smem operation modifier */
struct dentry *dbg_dir; /**< root debug directory */
uint32_t message_sequence; /**< message sequence number */
struct spinlock lock_cpu_sel;
struct spinlock lock_hmq_sel;
......@@ -223,6 +220,9 @@ struct trtl_dev {
const struct trtl_config_rom cfgrom; /**< synthesis configuration ROM */
struct tty_driver *tty_driver;
struct dentry *dbg_dir; /**< root debug directory */
struct dentry *dbg_info; /**< information */
};
static inline u32 trtl_ioread(struct trtl_dev *trtl, void *addr)
......@@ -242,7 +242,6 @@ extern int trtl_minor_get(struct device *dev, enum trtl_dev_type type);
extern void trtl_minor_put(struct device *dev);
/* CPU data */
extern const struct file_operations trtl_cpu_dbg_fops;
extern const struct file_operations trtl_cpu_fops;
extern const struct attribute_group *trtl_cpu_groups[];
extern void trtl_cpu_reset_set(struct trtl_dev *trtl, uint8_t mask);
......@@ -258,7 +257,9 @@ extern void trtl_hmq_purge(struct trtl_hmq *hmq);
/* TTY */
extern int trtl_tty_probe(struct trtl_dev *trtl);
extern void trtl_tty_remove(struct trtl_dev *trtl);
/* DBG */
extern void trtl_debugfs_init(struct trtl_dev *trtl);
extern void trtl_debugfs_exit(struct trtl_dev *trtl);
extern struct class trtl_cdev_class;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment