powerpc/xmon: Dump memory in CPU endian format
authorDouglas Miller <dougmill@linux.vnet.ibm.com>
Tue, 7 Feb 2017 13:40:44 +0000 (07:40 -0600)
committerMichael Ellerman <mpe@ellerman.id.au>
Tue, 21 Feb 2017 05:00:21 +0000 (16:00 +1100)
Extend the dump command to allow display of 2, 4, and 8 byte words in
CPU endian format. Also adds dump command for "1 byte values" for the
sake of symmetry. New commands are:

  d1 dump 1 byte values
  d2 dump 2 byte values
  d4 dump 4 byte values
  d8 dump 8 byte values

Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Signed-off-by: Douglas Miller <dougmill@linux.vnet.ibm.com>
Acked-by: Balbir Singh <bsingharora@gmail.com>
arch/powerpc/xmon/xmon.c

index a44b049b9cf6db4f28e1dbc007711ef331f21f14..57503cdbd76fa8569cd11c5882fed0a2450d99e3 100644 (file)
@@ -212,6 +212,10 @@ Commands:\n\
   "\
   C    checksum\n\
   d    dump bytes\n\
+  d1   dump 1 byte values\n\
+  d2   dump 2 byte values\n\
+  d4   dump 4 byte values\n\
+  d8   dump 8 byte values\n\
   di   dump instructions\n\
   df   dump float values\n\
   dd   dump double values\n\
@@ -2334,9 +2338,42 @@ static void dump_pacas(void)
 }
 #endif
 
+static void dump_by_size(unsigned long addr, long count, int size)
+{
+       unsigned char temp[16];
+       int i, j;
+       u64 val;
+
+       count = ALIGN(count, 16);
+
+       for (i = 0; i < count; i += 16, addr += 16) {
+               printf(REG, addr);
+
+               if (mread(addr, temp, 16) != 16) {
+                       printf("\nFaulted reading %d bytes from 0x"REG"\n", 16, addr);
+                       return;
+               }
+
+               for (j = 0; j < 16; j += size) {
+                       putchar(' ');
+                       switch (size) {
+                       case 1: val = temp[j]; break;
+                       case 2: val = *(u16 *)&temp[j]; break;
+                       case 4: val = *(u32 *)&temp[j]; break;
+                       case 8: val = *(u64 *)&temp[j]; break;
+                       default: val = 0;
+                       }
+
+                       printf("%0*lx", size * 2, val);
+               }
+               printf("\n");
+       }
+}
+
 static void
 dump(void)
 {
+       static char last[] = { "d?\n" };
        int c;
 
        c = inchar();
@@ -2350,8 +2387,9 @@ dump(void)
        }
 #endif
 
-       if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
+       if (c == '\n')
                termch = c;
+
        scanhex((void *)&adrs);
        if (termch != '\n')
                termch = 0;
@@ -2383,9 +2421,23 @@ dump(void)
                        ndump = 64;
                else if (ndump > MAX_DUMP)
                        ndump = MAX_DUMP;
-               prdump(adrs, ndump);
+
+               switch (c) {
+               case '8':
+               case '4':
+               case '2':
+               case '1':
+                       ndump = ALIGN(ndump, 16);
+                       dump_by_size(adrs, ndump, c - '0');
+                       last[1] = c;
+                       last_cmd = last;
+                       break;
+               default:
+                       prdump(adrs, ndump);
+                       last_cmd = "d\n";
+               }
+
                adrs += ndump;
-               last_cmd = "d\n";
        }
 }