|
@@ -312,7 +312,7 @@ int kdbgetularg(const char *arg, unsigned long *value)
|
|
|
|
|
|
if (endp == arg) {
|
|
if (endp == arg) {
|
|
/*
|
|
/*
|
|
- * Try base 16, for us folks too lazy to type the
|
|
|
|
|
|
+ * Also try base 16, for us folks too lazy to type the
|
|
* leading 0x...
|
|
* leading 0x...
|
|
*/
|
|
*/
|
|
val = simple_strtoul(arg, &endp, 16);
|
|
val = simple_strtoul(arg, &endp, 16);
|
|
@@ -325,6 +325,25 @@ int kdbgetularg(const char *arg, unsigned long *value)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+int kdbgetu64arg(const char *arg, u64 *value)
|
|
|
|
+{
|
|
|
|
+ char *endp;
|
|
|
|
+ u64 val;
|
|
|
|
+
|
|
|
|
+ val = simple_strtoull(arg, &endp, 0);
|
|
|
|
+
|
|
|
|
+ if (endp == arg) {
|
|
|
|
+
|
|
|
|
+ val = simple_strtoull(arg, &endp, 16);
|
|
|
|
+ if (endp == arg)
|
|
|
|
+ return KDB_BADINT;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ *value = val;
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* kdb_set - This function implements the 'set' command. Alter an
|
|
* kdb_set - This function implements the 'set' command. Alter an
|
|
* existing environment variable or create a new one.
|
|
* existing environment variable or create a new one.
|
|
@@ -1770,11 +1789,65 @@ static int kdb_go(int argc, const char **argv)
|
|
*/
|
|
*/
|
|
static int kdb_rd(int argc, const char **argv)
|
|
static int kdb_rd(int argc, const char **argv)
|
|
{
|
|
{
|
|
- int diag = kdb_check_regs();
|
|
|
|
- if (diag)
|
|
|
|
- return diag;
|
|
|
|
|
|
+ int len = kdb_check_regs();
|
|
|
|
+#if DBG_MAX_REG_NUM > 0
|
|
|
|
+ int i;
|
|
|
|
+ char *rname;
|
|
|
|
+ int rsize;
|
|
|
|
+ u64 reg64;
|
|
|
|
+ u32 reg32;
|
|
|
|
+ u16 reg16;
|
|
|
|
+ u8 reg8;
|
|
|
|
+
|
|
|
|
+ if (len)
|
|
|
|
+ return len;
|
|
|
|
+
|
|
|
|
+ for (i = 0; i < DBG_MAX_REG_NUM; i++) {
|
|
|
|
+ rsize = dbg_reg_def[i].size * 2;
|
|
|
|
+ if (rsize > 16)
|
|
|
|
+ rsize = 2;
|
|
|
|
+ if (len + strlen(dbg_reg_def[i].name) + 4 + rsize > 80) {
|
|
|
|
+ len = 0;
|
|
|
|
+ kdb_printf("\n");
|
|
|
|
+ }
|
|
|
|
+ if (len)
|
|
|
|
+ len += kdb_printf(" ");
|
|
|
|
+ switch(dbg_reg_def[i].size * 8) {
|
|
|
|
+ case 8:
|
|
|
|
+ rname = dbg_get_reg(i, ®8, kdb_current_regs);
|
|
|
|
+ if (!rname)
|
|
|
|
+ break;
|
|
|
|
+ len += kdb_printf("%s: %02x", rname, reg8);
|
|
|
|
+ break;
|
|
|
|
+ case 16:
|
|
|
|
+ rname = dbg_get_reg(i, ®16, kdb_current_regs);
|
|
|
|
+ if (!rname)
|
|
|
|
+ break;
|
|
|
|
+ len += kdb_printf("%s: %04x", rname, reg16);
|
|
|
|
+ break;
|
|
|
|
+ case 32:
|
|
|
|
+ rname = dbg_get_reg(i, ®32, kdb_current_regs);
|
|
|
|
+ if (!rname)
|
|
|
|
+ break;
|
|
|
|
+ len += kdb_printf("%s: %08x", rname, reg32);
|
|
|
|
+ break;
|
|
|
|
+ case 64:
|
|
|
|
+ rname = dbg_get_reg(i, ®64, kdb_current_regs);
|
|
|
|
+ if (!rname)
|
|
|
|
+ break;
|
|
|
|
+ len += kdb_printf("%s: %016llx", rname, reg64);
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ len += kdb_printf("%s: ??", dbg_reg_def[i].name);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ kdb_printf("\n");
|
|
|
|
+#else
|
|
|
|
+ if (len)
|
|
|
|
+ return len;
|
|
|
|
|
|
kdb_dumpregs(kdb_current_regs);
|
|
kdb_dumpregs(kdb_current_regs);
|
|
|
|
+#endif
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1782,32 +1855,67 @@ static int kdb_rd(int argc, const char **argv)
|
|
* kdb_rm - This function implements the 'rm' (register modify) command.
|
|
* kdb_rm - This function implements the 'rm' (register modify) command.
|
|
* rm register-name new-contents
|
|
* rm register-name new-contents
|
|
* Remarks:
|
|
* Remarks:
|
|
- * Currently doesn't allow modification of control or
|
|
|
|
- * debug registers.
|
|
|
|
|
|
+ * Allows register modification with the same restrictions as gdb
|
|
*/
|
|
*/
|
|
static int kdb_rm(int argc, const char **argv)
|
|
static int kdb_rm(int argc, const char **argv)
|
|
{
|
|
{
|
|
|
|
+#if DBG_MAX_REG_NUM > 0
|
|
int diag;
|
|
int diag;
|
|
- int ind = 0;
|
|
|
|
- unsigned long contents;
|
|
|
|
|
|
+ const char *rname;
|
|
|
|
+ int i;
|
|
|
|
+ u64 reg64;
|
|
|
|
+ u32 reg32;
|
|
|
|
+ u16 reg16;
|
|
|
|
+ u8 reg8;
|
|
|
|
|
|
if (argc != 2)
|
|
if (argc != 2)
|
|
return KDB_ARGCOUNT;
|
|
return KDB_ARGCOUNT;
|
|
/*
|
|
/*
|
|
* Allow presence or absence of leading '%' symbol.
|
|
* Allow presence or absence of leading '%' symbol.
|
|
*/
|
|
*/
|
|
- if (argv[1][0] == '%')
|
|
|
|
- ind = 1;
|
|
|
|
|
|
+ rname = argv[1];
|
|
|
|
+ if (*rname == '%')
|
|
|
|
+ rname++;
|
|
|
|
|
|
- diag = kdbgetularg(argv[2], &contents);
|
|
|
|
|
|
+ diag = kdbgetu64arg(argv[2], ®64);
|
|
if (diag)
|
|
if (diag)
|
|
return diag;
|
|
return diag;
|
|
|
|
|
|
diag = kdb_check_regs();
|
|
diag = kdb_check_regs();
|
|
if (diag)
|
|
if (diag)
|
|
return diag;
|
|
return diag;
|
|
|
|
+
|
|
|
|
+ diag = KDB_BADREG;
|
|
|
|
+ for (i = 0; i < DBG_MAX_REG_NUM; i++) {
|
|
|
|
+ if (strcmp(rname, dbg_reg_def[i].name) == 0) {
|
|
|
|
+ diag = 0;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (!diag) {
|
|
|
|
+ switch(dbg_reg_def[i].size * 8) {
|
|
|
|
+ case 8:
|
|
|
|
+ reg8 = reg64;
|
|
|
|
+ dbg_set_reg(i, ®8, kdb_current_regs);
|
|
|
|
+ break;
|
|
|
|
+ case 16:
|
|
|
|
+ reg16 = reg64;
|
|
|
|
+ dbg_set_reg(i, ®16, kdb_current_regs);
|
|
|
|
+ break;
|
|
|
|
+ case 32:
|
|
|
|
+ reg32 = reg64;
|
|
|
|
+ dbg_set_reg(i, ®32, kdb_current_regs);
|
|
|
|
+ break;
|
|
|
|
+ case 64:
|
|
|
|
+ dbg_set_reg(i, ®64, kdb_current_regs);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return diag;
|
|
|
|
+#else
|
|
kdb_printf("ERROR: Register set currently not implemented\n");
|
|
kdb_printf("ERROR: Register set currently not implemented\n");
|
|
- return 0;
|
|
|
|
|
|
+ return 0;
|
|
|
|
+#endif
|
|
}
|
|
}
|
|
|
|
|
|
#if defined(CONFIG_MAGIC_SYSRQ)
|
|
#if defined(CONFIG_MAGIC_SYSRQ)
|