Commit 2d6e60cd authored by Mikhail Karpenko's avatar Mikhail Karpenko
Browse files

WIP: dump memory region

parent 1625be9d
Loading
Loading
Loading
Loading
+13 −10
Original line number Original line Diff line number Diff line
@@ -79,11 +79,11 @@ static int elphel_port_start(struct ata_port *ap)
	//pp->rx_fis_dma = virt_to_phys(pp->rx_fis);
	//pp->rx_fis_dma = virt_to_phys(pp->rx_fis);
	pp->rx_fis_dma = 0x80000000 + dpriv->fb_offs;
	pp->rx_fis_dma = 0x80000000 + dpriv->fb_offs;


	/*printk(KERN_DEBUG "cmd_slot: 0x%p", pp->cmd_slot);
	/*dev_info(dev, "cmd_slot: 0x%p", pp->cmd_slot);
	printk(KERN_DEBUG "cmd_slot_dma: 0x%08u", pp->cmd_slot_dma);
	dev_info(dev, "cmd_slot_dma: 0x%08u", pp->cmd_slot_dma);
	printk(KERN_DEBUG "rx_fis: 0x%p", pp->rx_fis);
	dev_info(dev, "rx_fis: 0x%p", pp->rx_fis);
	printk(KERN_DEBUG "rx_fis_dma: 0x%08u", pp->rx_fis_dma);
	dev_info(dev, "rx_fis_dma: 0x%08u", pp->rx_fis_dma);
	printk(KERN_DEBUG "base_addr: 0x%08u", dpriv->base_addr);*/
	dev_info(dev, "base_addr: 0x%08u", dpriv->base_addr);*/


	/*
	/*
	 * Save off initial list of interrupts to be enabled.
	 * Save off initial list of interrupts to be enabled.
@@ -93,6 +93,9 @@ static int elphel_port_start(struct ata_port *ap)


	ap->private_data = pp;
	ap->private_data = pp;


	libahci_debug_state_dump(ap);
	libahci_debug_state_dump(ap);

	return ahci_port_resume(ap);
	return ahci_port_resume(ap);
}
}


@@ -170,11 +173,11 @@ static int elphel_drv_probe(struct platform_device *pdev)


	phys_addr_t paddr = virt_to_phys(hpriv->mmio);
	phys_addr_t paddr = virt_to_phys(hpriv->mmio);
	void *vaddr = phys_to_virt(paddr);
	void *vaddr = phys_to_virt(paddr);
	dev_err(dev, "current mmio virt addr: %p\n", hpriv->mmio);
	dev_err(dev, "current mmio virt addr: 0x%p\n", hpriv->mmio);
	dev_err(dev, "current mmio virt addr as uint: %u\n", hpriv->mmio);
	dev_err(dev, "current mmio virt addr as uint: 0x%08x\n", hpriv->mmio);
	dev_err(dev, "mmio phys addr: %u\n", paddr);
	dev_err(dev, "mmio phys addr: 0x%08x\n", paddr);
	dev_err(dev, "mmio phys addr as tr: %p\n", paddr);
	dev_err(dev, "mmio phys addr as tr: 0x%p\n", paddr);
	dev_err(dev, "back converted mmio virt addr: %p\n", vaddr);
	dev_err(dev, "back converted mmio virt addr: 0x%p\n", vaddr);
	//printk(KERN_DEBUG, "current mmio virt addr: %p\n", hpriv->mmio);
	//printk(KERN_DEBUG, "current mmio virt addr: %p\n", hpriv->mmio);
	//printk(KERN_DEBUG, "mmio phys addr: %u\n", paddr);
	//printk(KERN_DEBUG, "mmio phys addr: %u\n", paddr);
	//printk(KERN_DEBUG, "back converted mmio virt addr: %p\n", vaddr);
	//printk(KERN_DEBUG, "back converted mmio virt addr: %p\n", vaddr);
+62 −29
Original line number Original line Diff line number Diff line
@@ -10,13 +10,16 @@
#include <linux/debugfs.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <linux/seq_file.h>
#include <linux/poll.h>
#include <linux/poll.h>
#include <asm/outercache.h>
#include <asm/cacheflush.h>
#include "libahci_debug.h"
#include "libahci_debug.h"


static struct dentry	*debug_root = NULL;
static struct dentry	*debug_root = NULL;
static struct libahci_debug_list debug_list = {.debug = 0};
static struct libahci_debug_list debug_list = {.debug = 0};
static struct ahci_cmd	cmd;
static struct ahci_cmd	cmd;
static bool load_flag = false;
static bool load_flag = false;
volatile unsigned int *mem_buff;

static struct mem_buffer mem_buff;


/*
/*
 * Print PxIS (0x10) analysis
 * Print PxIS (0x10) analysis
@@ -248,7 +251,6 @@ static int libahci_debug_host_show(struct seq_file *f, void *p)
{
{
	struct ata_host		*host = f->private;
	struct ata_host		*host = f->private;
	struct host_regs	hr = {0};
	struct host_regs	hr = {0};
	phys_addr_t			buff_addr;


	libahci_debug_read_host_regs(host, &hr);
	libahci_debug_read_host_regs(host, &hr);
	seq_printf(f, "CAP:\t\t0x%08X\n", hr.CAP);
	seq_printf(f, "CAP:\t\t0x%08X\n", hr.CAP);
@@ -263,8 +265,7 @@ static int libahci_debug_host_show(struct seq_file *f, void *p)
	seq_printf(f, "EM_CTL:\t\t0x%08X\n", hr.EM_CTL);
	seq_printf(f, "EM_CTL:\t\t0x%08X\n", hr.EM_CTL);
	seq_printf(f, "BOHC:\t\t0x%08X\n", hr.BOHC);
	seq_printf(f, "BOHC:\t\t0x%08X\n", hr.BOHC);


	buff_addr = virt_to_phys(mem_buff);
	seq_printf(f, "\nbuffer location:\t\t0x%08X\n", mem_buff.paddr);
	seq_printf(f, "\nbuffer location:\t\t0x%08X\n", buff_addr);


	return 0;
	return 0;
}
}
@@ -461,8 +462,9 @@ void libahci_debug_event(const struct ata_port *port, char *msg, size_t msg_sz)
			}
			}


			if (pos != NULL) {
			if (pos != NULL) {
				//i = libahci_debug_state_dump(port);
				spin_lock_irqsave(&pos->debug_list_lock, flags);
				spin_lock_irqsave(&pos->debug_list_lock, flags);
				len = snprintf(format_msg, LIBAHCI_DEBUG_BUFSZ, "%s %s\n", EVT_MARKER, msg);
				len = snprintf(format_msg, LIBAHCI_DEBUG_BUFSZ, "%s [%08u] %s\n", EVT_MARKER, i, msg);
				for (i = 0; i < len; i++) {
				for (i = 0; i < len; i++) {
					pos->libahci_debug_buf[(pos->tail+ i) % LIBAHCI_DEBUG_BUFSZ] = format_msg[i];
					pos->libahci_debug_buf[(pos->tail+ i) % LIBAHCI_DEBUG_BUFSZ] = format_msg[i];
				}
				}
@@ -675,45 +677,77 @@ void libahci_debug_wait_flag(void)
}
}
EXPORT_SYMBOL_GPL(libahci_debug_wait_flag);
EXPORT_SYMBOL_GPL(libahci_debug_wait_flag);


static void libahci_debug_buff_line(void *mem, u32 cntr)
{
	int i;
	u32 *mem_ptr = mem;

	mem_ptr[0] = cntr;
	for (i = 1; i < MARKER_LEN; i++) {
		mem_ptr[i] = 0xa5a5a5a5;
	}
}

/*
/*
 * Copy controller registers to buffer memory
 * Copy controller registers to buffer memory and return the record number
 */
 */
void libahci_debug_state_dump(struct device *dev)
unsigned int libahci_debug_state_dump(struct ata_port *ap)
{
{
	static u32 page_cntr;
	static u32 page_cntr;
	phys_addr_t v2p;
	u32 *p2v;
	int i;
	int i;
	u32 tmp;
	u32 ptr;
	struct device *dev = ap->dev;
	struct ahci_host_priv *hpriv = ap->host->private_data;
	void __iomem *host_mmio = hpriv->mmio;
	struct ahci_port_priv *ppriv = ap->private_data;
	void __iomem *port_mmio = ahci_port_base(ap);


	if (!mem_buff) {
	if (!ap)
		return 0;

	if (!mem_buff.vaddr) {
		dev_err(dev, "dump buffer has not been allocated");
		dev_err(dev, "dump buffer has not been allocated");
		return;
		return 0;
	}
	}


	v2p = virt_to_phys(mem_buff);
	dev_info(dev, "dump page num: %u", page_cntr);
	dev_info(dev, "write to buffer: 0x%08x", v2p);
	ptr = page_cntr * DUMP_LEN;
	mem_buff[0] = 0xdeadbeef;
	if (ptr + DUMP_LEN > SEGMENT_SIZE)
	for (i = 1; i < 100; i++) {
		ptr = 0;
		mem_buff[i] = 0xa5a5a5a5;
	dev_info(dev, "current ptr: %u", ptr);
	for (i = 0; i < GHC_SZ; i++) {
		tmp = ioread32(host_mmio + 4 * i);
		mem_buff.vaddr[ptr++] = tmp;
	}
	for (i = 0; i < PORT_REG_SZ; i++) {
		tmp = ioread32(port_mmio + 4 * i);
		mem_buff.vaddr[ptr++] = tmp;
	}
	}
	/*__cpu_flush_kern_all();
	for (i = 0; i < CLB_SZ; i++) {
	outer_flush_all();
		tmp = ioread32(ppriv->cmd_slot);
	for (i = 0; i < 100; i++) {
		mem_buff.vaddr[ptr++] = tmp;
		v2p = virt_to_phys(mem_buff + 4*i);
		dev_info(dev, "read phys addr: 0x%x, data: 0x%08x", v2p, *(mem_buff + 4*i));
	}*/
	}
	}
	for (i = 0; i < FIS_SZ; i++) {
		tmp = ioread32(ppriv->rx_fis);
		mem_buff.vaddr[ptr++] = tmp;
	}
	libahci_debug_buff_line(&mem_buff.vaddr[ptr + ALIGN_OFFSET], page_cntr);
	//__cpuc_flush_kern_all();
	//outer_flush_all();
	page_cntr++;

	return page_cntr;
}
EXPORT_SYMBOL_GPL(libahci_debug_state_dump);


static void libahci_debug_buff_init(struct device *dev)
static void libahci_debug_buff_init(struct device *dev)
{
{
	dma_addr_t dma_handle;
	mem_buff.vaddr = dmam_alloc_coherent(dev, SEGMENT_SIZE, &mem_buff.paddr, GFP_KERNEL);

	if (!mem_buff.vaddr)
	dev_info(dev, "trying to allocate dump buffer");
	mem_buff = dmam_alloc_coherent(dev, PAGE_SIZE, &dma_handle, GFP_KERNEL);
	if (!mem_buff)
		dev_err(dev, "unable to allocate memory");
		dev_err(dev, "unable to allocate memory");
	else
	else
		dev_info(dev, "buffer allocated at 0x%08x", dma_handle);
		dev_info(dev, "dump buffer allocated");
}
}


static const struct file_operations libahci_debug_host_ops = {
static const struct file_operations libahci_debug_host_ops = {
@@ -808,7 +842,6 @@ int libahci_debug_init(struct ata_host *host)
	}
	}


	libahci_debug_buff_init(host->dev);
	libahci_debug_buff_init(host->dev);
	libahci_debug_state_dump(host->dev);
	return 0;
	return 0;


fail_handler:
fail_handler:
+29 −5
Original line number Original line Diff line number Diff line
@@ -19,12 +19,22 @@
#define CMD_DMA_BUFSZ	512
#define CMD_DMA_BUFSZ	512
#define PORT_RESERVED_2		40
#define PORT_RESERVED_2		40
#define PORT_VENDOR_BYTES	16
#define PORT_VENDOR_BYTES	16
#define BUFFER_ADDRESS		0x38130000
/* Buffer is 100 Mb*/
#define BUFFER_PAGES		25600
#define SEGMENT_SIZE		0x10000
#define LIBAHCI_DEBUG_BUFSZ	16384
#define LIBAHCI_DEBUG_BUFSZ	16384


/* Total size of dump buffer in bytes*/
#define SEGMENT_SIZE		0x10000
/* The sizes below are in DWORDs*/
#define GHC_SZ			0x0B
#define PORT_REG_SZ		0x20
#define CLB_SZ			0x08
#define FIS_SZ			0x40
#define DUMP_LEN		0x240

/* The length of delimiter line in memory */
#define MARKER_LEN		0x10
/* Offset to the end of nearest 16 DWORD string */
#define ALIGN_OFFSET	0x0d

struct libahci_debug_list {
struct libahci_debug_list {
	unsigned int		debug;
	unsigned int		debug;
	unsigned int		port_n;
	unsigned int		port_n;
@@ -53,6 +63,20 @@ struct ahci_cmd {
	int					cmd_sent;
	int					cmd_sent;
};
};


struct mem_buffer {
	volatile u32 *vaddr;
	dma_addr_t paddr;
	ssize_t size;
};

struct dump_record {
	u32 reg_ghc[GHC_SZ];
	u32 reg_port[PORT_REG_SZ];
	u32 reg_clb[CLB_SZ];
	u32 reg_fis[FIS_SZ];
	u32 cntr;
};

// AHCI Port registers
// AHCI Port registers
struct port_regs {
struct port_regs {
	// Port command list base address
	// Port command list base address
@@ -104,6 +128,6 @@ void libahci_debug_dump_sg(const struct ata_queued_cmd *qc, const char *prefix);
void libahci_debug_irq_notify(const struct ata_port *ap);
void libahci_debug_irq_notify(const struct ata_port *ap);
void libahci_debug_exec_cmd(struct ata_port *ap);
void libahci_debug_exec_cmd(struct ata_port *ap);
void libahci_debug_wait_flag(void);
void libahci_debug_wait_flag(void);
void libahci_debug_state_dump(struct device *dev);
unsigned int libahci_debug_state_dump(struct ata_port *ap);


#endif /* _LIBAHCI_DEBUG_H_ */
#endif /* _LIBAHCI_DEBUG_H_ */