Hello,

Here is a patch to implement embedding width and count options
in the md and mm commands. The patch is against KDB v1.8. 

As Keith put it elsewhere, some hardware requires that accesses
be a specific width, this can be achieved by setting BYTESPERWORD
but it is awkward.  We want md1 to read one byte, md2, md4, md8 
commands.  All can have a count field, e.g. md1c8 reads 8 bytes 
one at a time.  mm1, mm2, mm4, mm8 to set memory no count field.

The implementation tries to make minimal modifications to the
existing code. In addition to the relatively simple changes to 
kdb_md and kdb_mm, I had to modify kdb_parse so that it can 
parse "md1c20" to be the "md" command. For a normal cmd
shortcut, the typed in command length is less than the length of
the actual command, whereas in this case, it is the opposite, 
that needed another loop over all commands in kdb_parse.  

Comments?

Regards,
Vamsi Krishna S.
Linux Technology Center,
IBM Software Labs, Bangalore.


--- 246-kdb-pure/kdb/kdbmain.c  Tue Aug 28 19:00:26 2001
+++ 246-kdb/kdb/kdbmain.c       Wed Aug 29 10:08:37 2001
@@ -620,6 +620,23 @@
                        }
                }
        }
+       
+       /* 
+        * If we don't find a command by this name, see if the first 
+        * few characters of this match any of the known commands.
+        * e.g., md1c20 should match md.
+        */
+       if (i == KDB_MAX_COMMANDS) {
+               for(tp=kdb_commands, i=0; i < KDB_MAX_COMMANDS; i++,tp++) {
+                       if (tp->cmd_name) {
+                               if (strncmp(argv[0], 
+                                           tp->cmd_name,
+                                           strlen(tp->cmd_name))==0) {
+                                       break;
+                               }
+                       }
+               }
+       }
 
        if (i < KDB_MAX_COMMANDS) {
                int result, no_watchdog;
@@ -1460,9 +1477,13 @@
 /*
  * kdb_md
  *
- *     This function implements the 'md', 'mdr' and 'mds' commands.
+ *     This function implements the 'md', 'md1', 'md2', 'md4', 'md8'
+ *     'mdr' and 'mds' commands.
  *
  *     md|mds  [<addr arg> [<line count> [<radix>]]]
+ *     mdWcN   [<addr arg> [<line count> [<radix>]]] 
+ *             where W = is the width (1, 2, 4 or 8) and N is the count.
+ *             for eg., md1c20 reads 20 bytes, 1 at a time.
  *     mdr  <addr arg>,<byte count>
  *
  * Inputs:
@@ -1484,7 +1505,6 @@
 {
        char fmtchar;
        char fmtstr[64];
-       int radix, count, width;
        kdb_machreg_t addr;
        unsigned long word;
        long    offset = 0;
@@ -1493,50 +1513,62 @@
        int     nextarg;
        int     nosect = 0;
        static kdb_machreg_t lastaddr;
-       static unsigned long lastcount;
+       static unsigned long last_line_count;
        static unsigned long lastradix;
-       char    lastbuf[50];
        int     symbolic = 0;
+       int line_count = 8;
+       int radix = 16;
+       int width = sizeof(kdb_machreg_t);
 
-       /*
-        * Defaults in case the relevent environment variables are unset
-        */
-       radix = 16;
-       count = 8;
-       width = sizeof(kdb_machreg_t);
+       kdbgetintenv("BYTESPERWORD", &width);
+       kdbgetintenv("MDCOUNT", &line_count);
+       kdbgetintenv("RADIX", &radix);
+       kdbgetintenv("NOSECT", &nosect);
 
-       if (strcmp(argv[0], "mdr") == 0 && argc != 2)
-               return KDB_ARGCOUNT;
+       if (strcmp(argv[0], "mdr") == 0) {
+               if (argc != 2) 
+                       return KDB_ARGCOUNT;
+       } else if (argv[0][2]) {
+               width = (int)(argv[0][2] - '0');
+               if (argv[0][3] == 'c') {
+                       int count;
+                       count = simple_strtoul(&argv[0][4], 0, 0);
+                       line_count = ((count * width) + 15) / 16;
+               }
+       }
 
        if (argc == 0) {
                if (lastaddr == 0)
                        return KDB_ARGCOUNT;
-               sprintf(lastbuf, kdb_machreg_fmt, lastaddr);
-               argv[1] = lastbuf;
-               argc = 1;
-               count = lastcount;
+               addr = lastaddr;
+               line_count = last_line_count;
                radix = lastradix;
        } else {
                kdb_machreg_t val;
 
-               if (argc >= 2) {
+               nextarg = 1;
+               diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
+               if (diag)
+                       return diag;
+               if (argc > nextarg+2)
+                       return KDB_ARGCOUNT;
 
-                       diag = kdbgetularg(argv[2], &val);
+               if (argc >= nextarg) {
+                       diag = kdbgetularg(argv[nextarg], &val);
                        if (!diag)
-                               count = (int) val;
-               } else {
-                       diag = kdbgetintenv("MDCOUNT", &count);
+                               line_count = (int) val;
                }
-
-               if (argc >= 3) {
-                       diag = kdbgetularg(argv[3], &val);
+               if (argc >= nextarg+1) {
+                       diag = kdbgetularg(argv[nextarg+1], &val);
                        if (!diag)
                                radix = (int) val;
-               } else {
-                       diag = kdbgetintenv("RADIX",&radix);
                }
        }
 
+       if (strcmp(argv[0], "mdr") == 0) {
+               return(kdb_mdr(addr, line_count));
+       }
+
        switch (radix) {
        case 10:
                fmtchar = 'd';
@@ -1551,9 +1583,6 @@
                return KDB_BADRADIX;
        }
 
-       kdbgetintenv("BYTESPERWORD", &width);
-       kdbgetintenv("NOSECT", &nosect);
-
        if (strcmp(argv[0], "mds") == 0) {
                symbolic = 1;
                width = sizeof(kdb_machreg_t);
@@ -1577,26 +1606,17 @@
        }
 
 
-       nextarg = 1;
-       diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
-       if (diag)
-               return diag;
-
-       if (strcmp(argv[0], "mdr") == 0) {
-               return(kdb_mdr(addr, count));
-       }
-
        /* Round address down modulo BYTESPERWORD */
 
        addr &= ~(width-1);
 
        /*
-        * Remember count and radix for next 'md'
+        * Remember line_count and radix for next 'md'
         */
-       lastcount = count;
+       last_line_count = line_count;
        lastradix = radix;
 
-       while (count--) {
+       while (line_count--) {
                int     num = (symbolic?1 :(16 / width));
                char    cbuf[32];
                char    *c = cbuf;
@@ -1664,7 +1684,6 @@
                }
                kdb_printf(" %s\n", cbuf);
        }
-
        lastaddr = addr;
 
        return 0;
@@ -1701,8 +1720,9 @@
        unsigned long contents;
        unsigned long word;
        int nextarg;
+       int width;
 
-       if (argc != 2) {
+       if (argc < 2) {
                return KDB_ARGCOUNT;
        }
 
@@ -1721,16 +1741,18 @@
        if (nextarg != argc + 1)
                return KDB_ARGCOUNT;
 
+       width = argv[0][2] ? (argv[0][2] - '0') : (sizeof(kdb_machreg_t));
+
        /*
         * To prevent modification of invalid addresses, check first.
         */
-       word = kdba_getword(addr, sizeof(word));
+       word = kdba_getword(addr, width);
        if (KDB_STATE(SUPPRESS)) {
                KDB_STATE_CLEAR(SUPPRESS);
                return 0;
        }
 
-       diag = kdba_putword(addr, sizeof(contents), contents);
+       diag = kdba_putword(addr, width, contents);
 
        kdb_printf(kdb_machreg_fmt " = " kdb_machreg_fmt "\n", addr, contents);
 

Reply via email to