From 2d6e60cd56cbae0c73fb2b115efab2a3b9e32d1f Mon Sep 17 00:00:00 2001 From: Mikhail Karpenko Date: Thu, 25 Feb 2016 20:01:26 -0700 Subject: [PATCH] WIP: dump memory region --- src/drivers/ata/ahci_elphel.c | 23 +++++---- src/drivers/ata/libahci_debug.c | 91 ++++++++++++++++++++++----------- src/drivers/ata/libahci_debug.h | 34 ++++++++++-- 3 files changed, 104 insertions(+), 44 deletions(-) diff --git a/src/drivers/ata/ahci_elphel.c b/src/drivers/ata/ahci_elphel.c index 8f7b636..7a1f93f 100644 --- a/src/drivers/ata/ahci_elphel.c +++ b/src/drivers/ata/ahci_elphel.c @@ -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 = 0x80000000 + dpriv->fb_offs; - /*printk(KERN_DEBUG "cmd_slot: 0x%p", pp->cmd_slot); - printk(KERN_DEBUG "cmd_slot_dma: 0x%08u", pp->cmd_slot_dma); - printk(KERN_DEBUG "rx_fis: 0x%p", pp->rx_fis); - printk(KERN_DEBUG "rx_fis_dma: 0x%08u", pp->rx_fis_dma); - printk(KERN_DEBUG "base_addr: 0x%08u", dpriv->base_addr);*/ + /*dev_info(dev, "cmd_slot: 0x%p", pp->cmd_slot); + dev_info(dev, "cmd_slot_dma: 0x%08u", pp->cmd_slot_dma); + dev_info(dev, "rx_fis: 0x%p", pp->rx_fis); + dev_info(dev, "rx_fis_dma: 0x%08u", pp->rx_fis_dma); + dev_info(dev, "base_addr: 0x%08u", dpriv->base_addr);*/ /* * 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; + libahci_debug_state_dump(ap); + libahci_debug_state_dump(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); void *vaddr = phys_to_virt(paddr); - dev_err(dev, "current mmio virt addr: %p\n", hpriv->mmio); - dev_err(dev, "current mmio virt addr as uint: %u\n", hpriv->mmio); - dev_err(dev, "mmio phys addr: %u\n", paddr); - dev_err(dev, "mmio phys addr as tr: %p\n", paddr); - dev_err(dev, "back converted mmio virt addr: %p\n", vaddr); + dev_err(dev, "current mmio virt addr: 0x%p\n", hpriv->mmio); + dev_err(dev, "current mmio virt addr as uint: 0x%08x\n", hpriv->mmio); + dev_err(dev, "mmio phys addr: 0x%08x\n", paddr); + dev_err(dev, "mmio phys addr as tr: 0x%p\n", paddr); + 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, "mmio phys addr: %u\n", paddr); //printk(KERN_DEBUG, "back converted mmio virt addr: %p\n", vaddr); diff --git a/src/drivers/ata/libahci_debug.c b/src/drivers/ata/libahci_debug.c index ab6db2b..20be5b1 100644 --- a/src/drivers/ata/libahci_debug.c +++ b/src/drivers/ata/libahci_debug.c @@ -10,13 +10,16 @@ #include #include #include +#include +#include #include "libahci_debug.h" static struct dentry *debug_root = NULL; static struct libahci_debug_list debug_list = {.debug = 0}; static struct ahci_cmd cmd; static bool load_flag = false; -volatile unsigned int *mem_buff; + +static struct mem_buffer mem_buff; /* * 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 host_regs hr = {0}; - phys_addr_t buff_addr; libahci_debug_read_host_regs(host, &hr); 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, "BOHC:\t\t0x%08X\n", hr.BOHC); - buff_addr = virt_to_phys(mem_buff); - seq_printf(f, "\nbuffer location:\t\t0x%08X\n", buff_addr); + seq_printf(f, "\nbuffer location:\t\t0x%08X\n", mem_buff.paddr); return 0; } @@ -461,8 +462,9 @@ void libahci_debug_event(const struct ata_port *port, char *msg, size_t msg_sz) } if (pos != NULL) { + //i = libahci_debug_state_dump(port); 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++) { 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); +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; - phys_addr_t v2p; - u32 *p2v; 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"); - return; + return 0; } - v2p = virt_to_phys(mem_buff); - dev_info(dev, "write to buffer: 0x%08x", v2p); - mem_buff[0] = 0xdeadbeef; - for (i = 1; i < 100; i++) { - mem_buff[i] = 0xa5a5a5a5; + dev_info(dev, "dump page num: %u", page_cntr); + ptr = page_cntr * DUMP_LEN; + if (ptr + DUMP_LEN > SEGMENT_SIZE) + ptr = 0; + 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(); - outer_flush_all(); - for (i = 0; i < 100; i++) { - 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 < CLB_SZ; i++) { + tmp = ioread32(ppriv->cmd_slot); + mem_buff.vaddr[ptr++] = tmp; + } + 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) { - dma_addr_t dma_handle; - - dev_info(dev, "trying to allocate dump buffer"); - mem_buff = dmam_alloc_coherent(dev, PAGE_SIZE, &dma_handle, GFP_KERNEL); - if (!mem_buff) + mem_buff.vaddr = dmam_alloc_coherent(dev, SEGMENT_SIZE, &mem_buff.paddr, GFP_KERNEL); + if (!mem_buff.vaddr) dev_err(dev, "unable to allocate memory"); 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 = { @@ -808,7 +842,6 @@ int libahci_debug_init(struct ata_host *host) } libahci_debug_buff_init(host->dev); - libahci_debug_state_dump(host->dev); return 0; fail_handler: diff --git a/src/drivers/ata/libahci_debug.h b/src/drivers/ata/libahci_debug.h index e50704f..23e8500 100644 --- a/src/drivers/ata/libahci_debug.h +++ b/src/drivers/ata/libahci_debug.h @@ -19,12 +19,22 @@ #define CMD_DMA_BUFSZ 512 #define PORT_RESERVED_2 40 #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 +/* 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 { unsigned int debug; unsigned int port_n; @@ -53,6 +63,20 @@ struct ahci_cmd { 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 struct port_regs { // 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_exec_cmd(struct ata_port *ap); 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_ */ -- 2.18.1