Add commands that are like the other "md" commands but that allow you
to read memory that's in the IO space.

Signed-off-by: Douglas Anderson <diand...@chromium.org>
---

 kernel/debug/kdb/kdb_main.c    | 38 +++++++++++++++++++++++----
 kernel/debug/kdb/kdb_private.h |  1 +
 kernel/debug/kdb/kdb_support.c | 48 ++++++++++++++++++++++++++++++++++
 3 files changed, 82 insertions(+), 5 deletions(-)

diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c
index be72657741a5..a90d1e1482c2 100644
--- a/kernel/debug/kdb/kdb_main.c
+++ b/kernel/debug/kdb/kdb_main.c
@@ -1526,7 +1526,7 @@ static int kdb_mdr(int argc, const char **argv)
  */
 static void kdb_md_line(const char *fmtstr, unsigned long addr,
                        bool symbolic, bool nosect, int bytesperword,
-                       int num, int repeat, bool phys)
+                       int num, int repeat, bool phys, bool do_iomap)
 {
        /* print just one line of data */
        kdb_symtab_t symtab;
@@ -1543,7 +1543,10 @@ static void kdb_md_line(const char *fmtstr, unsigned 
long addr,
                kdb_printf(kdb_machreg_fmt0 " ", addr);
 
        for (i = 0; i < num && repeat--; i++) {
-               if (phys) {
+               if (do_iomap) {
+                       if (kdb_getioword(&word, addr, bytesperword))
+                               break;
+               } else if (phys) {
                        if (kdb_getphysword(&word, addr, bytesperword))
                                break;
                } else if (kdb_getword(&word, addr, bytesperword))
@@ -1646,6 +1649,7 @@ static int kdb_md(int argc, const char **argv)
        bool symbolic = false;
        bool valid = false;
        bool phys = false;
+       bool do_iomap = false;
 
        kdbgetintenv("MDCOUNT", &mdcount);
        kdbgetintenv("RADIX", &radix);
@@ -1655,6 +1659,8 @@ static int kdb_md(int argc, const char **argv)
                valid = true;
        else if (kdb_md_parse_arg0("mdp", argv[0], &repeat, &bytesperword))
                phys = valid = true;
+       else if (kdb_md_parse_arg0("mdi", argv[0], &repeat, &bytesperword))
+               do_iomap = valid = true;
        else if (strcmp(argv[0], "mds") == 0)
                valid = true;
 
@@ -1765,7 +1771,11 @@ static int kdb_md(int argc, const char **argv)
                if (KDB_FLAG(CMD_INTERRUPT))
                        return 0;
                for (a = addr, z = 0; z < repeat; a += bytesperword, ++z) {
-                       if (phys) {
+                       if (do_iomap) {
+                               if (kdb_getioword(&word, a, bytesperword)
+                                               || word)
+                                       break;
+                       } else if (phys) {
                                if (kdb_getphysword(&word, a, bytesperword)
                                                || word)
                                        break;
@@ -1774,7 +1784,7 @@ static int kdb_md(int argc, const char **argv)
                }
                n = min(num, repeat);
                kdb_md_line(fmtstr, addr, symbolic, nosect, bytesperword,
-                           num, repeat, phys);
+                           num, repeat, phys, do_iomap);
                addr += bytesperword * n;
                repeat -= n;
                z = (z + num - 1) / num;
@@ -2604,7 +2614,7 @@ static int kdb_per_cpu(int argc, const char **argv)
                kdb_printf("%5d ", cpu);
                kdb_md_line(fmtstr, addr,
                        bytesperword == KDB_WORD_SIZE,
-                       1, bytesperword, 1, 1, 0);
+                       true, bytesperword, 1, 1, false, false);
        }
 #undef KDB_PCU
        return 0;
@@ -2717,6 +2727,24 @@ static kdbtab_t maintab[] = {
                .help = "Display RAM given a PA using word size (W); show N 
words",
                .flags = KDB_ENABLE_MEM_READ | KDB_REPEAT_NO_ARGS,
        },
+       {       .name = "mdi",
+               .func = kdb_md,
+               .usage = "<paddr> <bytes>",
+               .help = "Display IO Memory",
+               .flags = KDB_ENABLE_MEM_READ | KDB_REPEAT_NO_ARGS,
+       },
+       {       .name = "mdiW",
+               .func = kdb_md,
+               .usage = "<paddr> <bytes>",
+               .help = "Display IO Memory using word size (W)",
+               .flags = KDB_ENABLE_MEM_READ | KDB_REPEAT_NO_ARGS,
+       },
+       {       .name = "mdiWcN",
+               .func = kdb_md,
+               .usage = "<paddr> <bytes>",
+               .help = "Display IO Memory using word size (W); show N words",
+               .flags = KDB_ENABLE_MEM_READ | KDB_REPEAT_NO_ARGS,
+       },
        {       .name = "mdr",
                .func = kdb_mdr,
                .usage = "<vaddr> <bytes>",
diff --git a/kernel/debug/kdb/kdb_private.h b/kernel/debug/kdb/kdb_private.h
index 1f685d9f16f9..caece6240140 100644
--- a/kernel/debug/kdb/kdb_private.h
+++ b/kernel/debug/kdb/kdb_private.h
@@ -97,6 +97,7 @@ extern int kdb_putarea_size(unsigned long, void *, size_t);
 #define kdb_getarea(x, addr) kdb_getarea_size(&(x), addr, sizeof((x)))
 #define kdb_putarea(addr, x) kdb_putarea_size(addr, &(x), sizeof((x)))
 
+extern int kdb_getioword(unsigned long *word, unsigned long addr, size_t size);
 extern int kdb_getphysword(unsigned long *word,
                        unsigned long addr, size_t size);
 extern int kdb_getword(unsigned long *, unsigned long, size_t);
diff --git a/kernel/debug/kdb/kdb_support.c b/kernel/debug/kdb/kdb_support.c
index 0a39497140bf..5a4e3a0e96a5 100644
--- a/kernel/debug/kdb/kdb_support.c
+++ b/kernel/debug/kdb/kdb_support.c
@@ -19,6 +19,7 @@
 #include <linux/ptrace.h>
 #include <linux/highmem.h>
 #include <linux/hardirq.h>
+#include <linux/io.h>
 #include <linux/delay.h>
 #include <linux/uaccess.h>
 #include <linux/kdb.h>
@@ -331,6 +332,53 @@ static int kdb_getphys(void *res, unsigned long addr, 
size_t size)
        return 0;
 }
 
+/*
+ * kdb_getioword
+ * Inputs:
+ *     word    Pointer to the word to receive the result.
+ *     addr    Address of the area to copy.
+ *     size    Size of the area.
+ * Returns:
+ *     0 for success, < 0 for error.
+ */
+int kdb_getioword(unsigned long *word, unsigned long addr, size_t size)
+{
+       void __iomem *mapped = ioremap(addr, size);
+       int diag = 0;
+
+       *word = 0;      /* Default value if addr or size is invalid */
+
+       if (!mapped)
+               return KDB_BADADDR;
+
+       switch (size) {
+       case 1:
+               *word = readb(mapped);
+               break;
+       case 2:
+               *word = readw(mapped);
+               break;
+       case 4:
+               *word = readl(mapped);
+               break;
+       case 8:
+#ifdef CONFIG_64BIT
+               if (size <= sizeof(*word)) {
+                       *word = readq(mapped);
+                       break;
+               }
+#endif
+               fallthrough;
+       default:
+               kdb_func_printf("bad width %zu\n", size);
+               diag = KDB_BADWIDTH;
+       }
+
+       iounmap(mapped);
+
+       return diag;
+}
+
 /*
  * kdb_getphysword
  * Inputs:
-- 
2.45.2.627.g7a2c4fd464-goog



_______________________________________________
Kgdb-bugreport mailing list
Kgdb-bugreport@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/kgdb-bugreport

Reply via email to