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

WIP: dump memory region

parent 1625be9d
...@@ -79,11 +79,11 @@ static int elphel_port_start(struct ata_port *ap) ...@@ -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) ...@@ -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) ...@@ -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);
......
...@@ -10,13 +10,16 @@ ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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 (!ap)
return 0;
if (!mem_buff) { 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) ...@@ -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:
......
...@@ -19,12 +19,22 @@ ...@@ -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 { ...@@ -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); ...@@ -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_ */
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