[PATCH] embed width and count in md/mm commands

Vamsi Krishna S . r1vamsi at in.ibm.com
Tue Aug 28 21:52:35 PDT 2001


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);
 



More information about the kdb mailing list