Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/powerpc/powerpc Add a "machine dcr" command, for th...



details:   https://anonhg.NetBSD.org/src/rev/fd7dae3debc7
branches:  trunk
changeset: 540590:fd7dae3debc7
user:      scw <scw%NetBSD.org@localhost>
date:      Thu Dec 19 13:29:53 2002 +0000

description:
Add a "machine dcr" command, for the IBM4XX case, which permits
reading/writing of the cpu's DCR registers.

diffstat:

 sys/arch/powerpc/powerpc/db_interface.c |  79 ++++++++++++++++++++++++++++++++-
 1 files changed, 77 insertions(+), 2 deletions(-)

diffs (115 lines):

diff -r 886b931d839a -r fd7dae3debc7 sys/arch/powerpc/powerpc/db_interface.c
--- a/sys/arch/powerpc/powerpc/db_interface.c   Thu Dec 19 12:48:42 2002 +0000
+++ b/sys/arch/powerpc/powerpc/db_interface.c   Thu Dec 19 13:29:53 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: db_interface.c,v 1.21 2002/11/25 05:10:39 thorpej Exp $ */
+/*     $NetBSD: db_interface.c,v 1.22 2002/12/19 13:29:53 scw Exp $ */
 /*     $OpenBSD: db_interface.c,v 1.2 1996/12/28 06:21:50 rahnds Exp $ */
 
 #define USERACC
@@ -26,6 +26,7 @@
 #include <ddb/db_command.h>
 #include <ddb/db_extern.h>
 #include <ddb/db_access.h>
+#include <ddb/db_lex.h>
 #include <ddb/db_output.h>
 #include <ddb/ddbvar.h>
 #endif
@@ -48,6 +49,9 @@
 static void db_ppc4xx_reset(db_expr_t, int, db_expr_t, char *);
 static void db_ppc4xx_tf(db_expr_t, int, db_expr_t, char *);
 static void db_ppc4xx_dumptlb(db_expr_t, int, db_expr_t, char *);
+static void db_ppc4xx_dcr(db_expr_t, int, db_expr_t, char *);
+static db_expr_t db_ppc4xx_mfdcr(db_expr_t);
+static void db_ppc4xx_mtdcr(db_expr_t, db_expr_t);
 #ifdef USERACC
 static void db_ppc4xx_useracc(db_expr_t, int, db_expr_t, char *);
 #endif
@@ -160,8 +164,9 @@
        { "ctx",        db_ppc4xx_ctx,          0,      0 },
        { "pv",         db_ppc4xx_pv,           0,      0 },
        { "reset",      db_ppc4xx_reset,        0,      0 },
-       { "tf",         db_ppc4xx_tf,   0,      0 },
+       { "tf",         db_ppc4xx_tf,           0,      0 },
        { "tlb",        db_ppc4xx_dumptlb,      0,      0 },
+       { "dcr",        db_ppc4xx_dcr,          CS_MORE|CS_SET_DOT,     0 },
 #ifdef USERACC
        { "user",       db_ppc4xx_useracc,      0,      0 },
 #endif
@@ -328,6 +333,76 @@
        }
 }
 
+static void
+db_ppc4xx_dcr(db_expr_t address, int have_addr, db_expr_t count, char *modif)
+{
+       db_expr_t new_value;
+       db_expr_t addr;
+
+       addr = address;
+
+       while (db_expression(&new_value)) {
+               db_printf("dcr 0x%lx\t\t%s = ", addr,
+                   db_num_to_str(db_ppc4xx_mfdcr(addr)));
+               db_ppc4xx_mtdcr(addr, new_value);
+               db_printf("%s\n", db_num_to_str(db_ppc4xx_mfdcr(addr)));
+               addr += 1;
+       }
+
+       if (addr == address) {
+               db_next = (db_addr_t)addr + 1;
+               db_prev = (db_addr_t)addr;
+               db_printf("dcr 0x%lx\t\t%s\n", addr,
+                   db_num_to_str(db_ppc4xx_mfdcr(addr)));
+       } else {
+               db_next = (db_addr_t)addr;
+               db_prev = (db_addr_t)addr - 1;
+       }
+
+       db_skip_to_eol();
+}
+
+/*
+ * XXX Grossness Alert! XXX
+ *
+ * Please look away now if you don't like self-modifying code
+ */
+static u_int32_t db_ppc4xx_dcrfunc[4];
+
+static db_expr_t
+db_ppc4xx_mfdcr(db_expr_t reg)
+{
+       db_expr_t (*func)(void);
+
+       reg = (((reg & 0x1f) << 5) | ((reg >> 5) & 0x1f)) << 11;
+       db_ppc4xx_dcrfunc[0] = 0x7c0004ac;              /* sync */
+       db_ppc4xx_dcrfunc[1] = 0x4c00012c;              /* isync */
+       db_ppc4xx_dcrfunc[2] = 0x7c600286 | reg;        /* mfdcr reg, r3 */
+       db_ppc4xx_dcrfunc[3] = 0x4e800020;              /* blr */
+
+       __syncicache((void *)db_ppc4xx_dcrfunc, sizeof(db_ppc4xx_dcrfunc));
+       func = (db_expr_t (*)(void))(void *)db_ppc4xx_dcrfunc;
+
+       return ((*func)());
+}
+
+static void
+db_ppc4xx_mtdcr(db_expr_t reg, db_expr_t val)
+{
+       db_expr_t (*func)(db_expr_t);
+
+       reg = (((reg & 0x1f) << 5) | ((reg >> 5) & 0x1f)) << 11;
+       db_ppc4xx_dcrfunc[0] = 0x7c0004ac;              /* sync */
+       db_ppc4xx_dcrfunc[1] = 0x4c00012c;              /* isync */
+       db_ppc4xx_dcrfunc[2] = 0x7c600386 | reg;        /* mtdcr r3, reg */
+       db_ppc4xx_dcrfunc[3] = 0x4e800020;              /* blr */
+
+       __syncicache((void *)db_ppc4xx_dcrfunc, sizeof(db_ppc4xx_dcrfunc));
+       func = (db_expr_t (*)(db_expr_t))(void *)db_ppc4xx_dcrfunc;
+
+       (*func)(val);
+}
+
 #ifdef USERACC
 static void
 db_ppc4xx_useracc(db_expr_t addr, int have_addr, db_expr_t count, char *modif)



Home | Main Index | Thread Index | Old Index