This is an automated email from Gerrit.

"Walter Ji <walter...@oss.cipunited.com>" just uploaded a new patch set to 
Gerrit, which you can find at https://review.openocd.org/c/openocd/+/7864

-- gerrit

commit d2bcb479789bf4f68ce58282cc8a50cf3f096785
Author: Walter Ji <walter...@oss.cipunited.com>
Date:   Fri Aug 25 17:27:37 2023 +0800

    target/mips32: update cpu definitions
    
    Add cpu_type for detecting different target config.
    Add CPx register definitions for target configuration.
    Add instructions for more flexibility on controlling target.
    Add FPU/DSP instr for accessing  their registers.
    
    Change-Id: I59c1f4cc4020db8a78e8d79f7421b87382fa1709
    Signed-off-by: Walter Ji <walter...@oss.cipunited.com>

diff --git a/src/target/mips32.c b/src/target/mips32.c
index 4e6d25118e..5f3933f09c 100644
--- a/src/target/mips32.c
+++ b/src/target/mips32.c
@@ -27,7 +27,7 @@ static const char *mips_isa_strings[] = {
        "MIPS32", "MIPS16", "", "MICRO MIPS32",
 };
 
-#define MIPS32_GDB_DUMMY_FP_REG 1
+#define MIPS32_GDB_FP_REG 1
 
 /*
  * GDB registers
@@ -73,87 +73,178 @@ static const struct {
        { 29, "r29", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
        { 30, "r30", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
        { 31, "r31", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
-       { 32, "status", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cp0", 0 },
-       { 33, "lo", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
-       { 34, "hi", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
-       { 35, "badvaddr", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cp0", 0 },
-       { 36, "cause", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cp0", 0 },
-       { 37, "pc", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
-
-       { 38,  "f0", REG_TYPE_IEEE_SINGLE, NULL,
-               "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
-       { 39,  "f1", REG_TYPE_IEEE_SINGLE, NULL,
-               "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
-       { 40,  "f2", REG_TYPE_IEEE_SINGLE, NULL,
-               "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
-       { 41,  "f3", REG_TYPE_IEEE_SINGLE, NULL,
-               "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
-       { 42,  "f4", REG_TYPE_IEEE_SINGLE, NULL,
-               "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
-       { 43,  "f5", REG_TYPE_IEEE_SINGLE, NULL,
-               "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
-       { 44,  "f6", REG_TYPE_IEEE_SINGLE, NULL,
-               "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
-       { 45,  "f7", REG_TYPE_IEEE_SINGLE, NULL,
-               "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
-       { 46,  "f8", REG_TYPE_IEEE_SINGLE, NULL,
-               "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
-       { 47,  "f9", REG_TYPE_IEEE_SINGLE, NULL,
-               "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
-       { 48, "f10", REG_TYPE_IEEE_SINGLE, NULL,
-               "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
-       { 49, "f11", REG_TYPE_IEEE_SINGLE, NULL,
-               "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
-       { 50, "f12", REG_TYPE_IEEE_SINGLE, NULL,
-               "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
-       { 51, "f13", REG_TYPE_IEEE_SINGLE, NULL,
-               "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
-       { 52, "f14", REG_TYPE_IEEE_SINGLE, NULL,
-               "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
-       { 53, "f15", REG_TYPE_IEEE_SINGLE, NULL,
-               "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
-       { 54, "f16", REG_TYPE_IEEE_SINGLE, NULL,
-               "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
-       { 55, "f17", REG_TYPE_IEEE_SINGLE, NULL,
-               "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
-       { 56, "f18", REG_TYPE_IEEE_SINGLE, NULL,
-               "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
-       { 57, "f19", REG_TYPE_IEEE_SINGLE, NULL,
-               "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
-       { 58, "f20", REG_TYPE_IEEE_SINGLE, NULL,
-               "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
-       { 59, "f21", REG_TYPE_IEEE_SINGLE, NULL,
-               "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
-       { 60, "f22", REG_TYPE_IEEE_SINGLE, NULL,
-               "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
-       { 61, "f23", REG_TYPE_IEEE_SINGLE, NULL,
-               "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
-       { 62, "f24", REG_TYPE_IEEE_SINGLE, NULL,
-               "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
-       { 63, "f25", REG_TYPE_IEEE_SINGLE, NULL,
-               "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
-       { 64, "f26", REG_TYPE_IEEE_SINGLE, NULL,
-               "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
-       { 65, "f27", REG_TYPE_IEEE_SINGLE, NULL,
-               "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
-       { 66, "f28", REG_TYPE_IEEE_SINGLE, NULL,
-               "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
-       { 67, "f29", REG_TYPE_IEEE_SINGLE, NULL,
-               "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
-       { 68, "f30", REG_TYPE_IEEE_SINGLE, NULL,
-               "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
-       { 69, "f31", REG_TYPE_IEEE_SINGLE, NULL,
-               "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
-       { 70, "fcsr", REG_TYPE_INT, "float",
-               "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
-       { 71, "fir", REG_TYPE_INT, "float",
-               "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
+       { 32,  "lo", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
+       { 33,  "hi", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
+
+       { MIPS32_REGLIST_FP_INDEX + 0,  "f0", REG_TYPE_IEEE_DOUBLE, NULL,
+               "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG },
+       { MIPS32_REGLIST_FP_INDEX + 1,  "f1", REG_TYPE_IEEE_DOUBLE, NULL,
+               "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG },
+       { MIPS32_REGLIST_FP_INDEX + 2,  "f2", REG_TYPE_IEEE_DOUBLE, NULL,
+               "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG },
+       { MIPS32_REGLIST_FP_INDEX + 3,  "f3", REG_TYPE_IEEE_DOUBLE, NULL,
+               "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG },
+       { MIPS32_REGLIST_FP_INDEX + 4,  "f4", REG_TYPE_IEEE_DOUBLE, NULL,
+               "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG },
+       { MIPS32_REGLIST_FP_INDEX + 5,  "f5", REG_TYPE_IEEE_DOUBLE, NULL,
+               "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG },
+       { MIPS32_REGLIST_FP_INDEX + 6,  "f6", REG_TYPE_IEEE_DOUBLE, NULL,
+               "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG },
+       { MIPS32_REGLIST_FP_INDEX + 7,  "f7", REG_TYPE_IEEE_DOUBLE, NULL,
+               "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG },
+       { MIPS32_REGLIST_FP_INDEX + 8,  "f8", REG_TYPE_IEEE_DOUBLE, NULL,
+               "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG },
+       { MIPS32_REGLIST_FP_INDEX + 9,  "f9", REG_TYPE_IEEE_DOUBLE, NULL,
+               "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG },
+       { MIPS32_REGLIST_FP_INDEX + 10, "f10", REG_TYPE_IEEE_DOUBLE, NULL,
+               "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG },
+       { MIPS32_REGLIST_FP_INDEX + 11, "f11", REG_TYPE_IEEE_DOUBLE, NULL,
+               "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG },
+       { MIPS32_REGLIST_FP_INDEX + 12, "f12", REG_TYPE_IEEE_DOUBLE, NULL,
+               "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG },
+       { MIPS32_REGLIST_FP_INDEX + 13, "f13", REG_TYPE_IEEE_DOUBLE, NULL,
+               "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG },
+       { MIPS32_REGLIST_FP_INDEX + 14, "f14", REG_TYPE_IEEE_DOUBLE, NULL,
+               "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG },
+       { MIPS32_REGLIST_FP_INDEX + 15, "f15", REG_TYPE_IEEE_DOUBLE, NULL,
+               "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG },
+       { MIPS32_REGLIST_FP_INDEX + 16, "f16", REG_TYPE_IEEE_DOUBLE, NULL,
+               "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG },
+       { MIPS32_REGLIST_FP_INDEX + 17, "f17", REG_TYPE_IEEE_DOUBLE, NULL,
+               "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG },
+       { MIPS32_REGLIST_FP_INDEX + 18, "f18", REG_TYPE_IEEE_DOUBLE, NULL,
+               "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG },
+       { MIPS32_REGLIST_FP_INDEX + 19, "f19", REG_TYPE_IEEE_DOUBLE, NULL,
+               "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG },
+       { MIPS32_REGLIST_FP_INDEX + 20, "f20", REG_TYPE_IEEE_DOUBLE, NULL,
+               "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG },
+       { MIPS32_REGLIST_FP_INDEX + 21, "f21", REG_TYPE_IEEE_DOUBLE, NULL,
+               "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG },
+       { MIPS32_REGLIST_FP_INDEX + 22, "f22", REG_TYPE_IEEE_DOUBLE, NULL,
+               "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG },
+       { MIPS32_REGLIST_FP_INDEX + 23, "f23", REG_TYPE_IEEE_DOUBLE, NULL,
+               "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG },
+       { MIPS32_REGLIST_FP_INDEX + 24, "f24", REG_TYPE_IEEE_DOUBLE, NULL,
+               "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG },
+       { MIPS32_REGLIST_FP_INDEX + 25, "f25", REG_TYPE_IEEE_DOUBLE, NULL,
+               "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG },
+       { MIPS32_REGLIST_FP_INDEX + 26, "f26", REG_TYPE_IEEE_DOUBLE, NULL,
+               "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG },
+       { MIPS32_REGLIST_FP_INDEX + 27, "f27", REG_TYPE_IEEE_DOUBLE, NULL,
+               "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG },
+       { MIPS32_REGLIST_FP_INDEX + 28, "f28", REG_TYPE_IEEE_DOUBLE, NULL,
+               "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG },
+       { MIPS32_REGLIST_FP_INDEX + 29, "f29", REG_TYPE_IEEE_DOUBLE, NULL,
+               "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG },
+       { MIPS32_REGLIST_FP_INDEX + 30, "f30", REG_TYPE_IEEE_DOUBLE, NULL,
+               "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG },
+       { MIPS32_REGLIST_FP_INDEX + 31, "f31", REG_TYPE_IEEE_DOUBLE, NULL,
+               "org.gnu.gdb.mips.fpu", MIPS32_GDB_FP_REG },
+       { MIPS32_REGLIST_FPC_INDEX + 0, "fcsr", REG_TYPE_INT, "float",
+               "org.gnu.gdb.mips.fpu", 0 },
+       { MIPS32_REGLIST_FPC_INDEX + 1, "fir", REG_TYPE_INT, "float",
+               "org.gnu.gdb.mips.fpu", 0 },
+
+       { MIPS32_REGLIST_C0_INDEX + 0, "status", REG_TYPE_INT, NULL, 
"org.gnu.gdb.mips.cp0", 0 },
+       { MIPS32_REGLIST_C0_INDEX + 1, "badvaddr", REG_TYPE_INT, NULL, 
"org.gnu.gdb.mips.cp0", 0 },
+       { MIPS32_REGLIST_C0_INDEX + 2, "cause", REG_TYPE_INT, NULL, 
"org.gnu.gdb.mips.cp0", 0 },
+       { MIPS32_REGLIST_C0_INDEX + 3, "pc", REG_TYPE_INT, NULL, 
"org.gnu.gdb.mips.cpu", 0 },
+       { MIPS32_REGLIST_C0_INDEX + 4, "guestCtl1", REG_TYPE_INT, NULL, 
"org.gnu.gdb.mips.cp0", 0 },
 };
 
 
 #define MIPS32_NUM_REGS ARRAY_SIZE(mips32_regs)
 
-static uint8_t mips32_gdb_dummy_fp_value[] = {0, 0, 0, 0};
+/* WAYS MAPPING */
+static const int wayTable[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 
15, 16};    /* field->ways mapping */
+static const int setTableISDS[] = {64, 128, 256, 512, 1024, 2048, 4096, 32,    
          /* field->sets mapping */
+                                  16*1024, 32*1024, 64*1024, 128*1024, 
256*1024, 512*1024, 1024*1024, 2048*1024};
+
+/* BPL */
+static const int bplTable[] = {0, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048,
+                                                               4*1024, 8*1024, 
16*1024, 32*1024, 64*1024}; /* field->bytes per line */
+
+static uint32_t  ftlb_ways[16] = {2, 3, 4, 5,  6, 7, 8, 0,                     
0, 0, 0, 0,             0, 0, 0, 0};
+static uint32_t  ftlb_sets[16] = {1, 2, 4, 8,  16, 32, 64, 128,        256, 0, 
0, 0,   0, 0, 0, 0};
+
+
+#define zero   0
+
+#define AT     1
+
+#define v0     2
+#define v1     3
+
+#define a0     4
+#define a1     5
+#define a2     6
+#define        a3      7
+#define t0     8
+#define t1     9
+#define t2     10
+#define t3     11
+#define t4     12
+#define t5     13
+#define t6     14
+#define t7     15
+#define ta0    12      /* alias for $t4 */
+#define ta1    13      /* alias for $t5 */
+#define ta2    14      /* alias for $t6 */
+#define ta3    15      /* alias for $t7 */
+
+#define s0     16
+#define s1     17
+#define s2     18
+#define s3     19
+#define s4     20
+#define s5     21
+#define s6     22
+#define s7     23
+#define s8     30              /* == fp */
+
+#define t8     24
+#define t9     25
+#define k0     26
+#define k1     27
+
+#define gp     28
+
+#define sp     29
+#define fp     30
+#define ra     31
+
+#define ALL            0
+#define INST           1
+#define DATA           2
+#define ALLNOWB                3
+#define DATANOWB       4
+#define L2             5
+
+/* Order fixed */
+static const struct {
+       const char *name;
+} mips32_dsp_regs[MIPS32NUMDSPREGS] = {
+       { "hi0"},
+       { "hi1"},
+       { "hi2"},
+       { "hi3"},
+       { "lo0"},
+       { "lo1"},
+       { "lo2"},
+       { "lo3"},
+       { "control"},
+};
+
+static const struct {
+       unsigned int option;
+       const char *arg;
+} invalidate_cmd[5] = {
+       { ALL, "all", },
+       { INST, "inst", },
+       { DATA, "data", },
+       { ALLNOWB, "allnowb", },
+       { DATANOWB, "datanowb", },
+};
 
 static int mips32_get_core_reg(struct reg *reg)
 {
@@ -174,12 +265,21 @@ static int mips32_set_core_reg(struct reg *reg, uint8_t 
*buf)
 {
        struct mips32_core_reg *mips32_reg = reg->arch_info;
        struct target *target = mips32_reg->target;
-       uint32_t value = buf_get_u32(buf, 0, 32);
+       uint64_t value;
+
+       if (reg->size == 64)
+               value = buf_get_u64(buf, 0, 64);
+       else
+               value = buf_get_u32(buf, 0, 32);
 
        if (target->state != TARGET_HALTED)
                return ERROR_TARGET_NOT_HALTED;
 
-       buf_set_u32(reg->value, 0, 32, value);
+       if (reg->size == 64)
+               buf_set_u64(reg->value, 0, 64, value);
+       else
+               buf_set_u32(reg->value, 0, 32, value);
+
        reg->dirty = true;
        reg->valid = true;
 
@@ -188,7 +288,8 @@ static int mips32_set_core_reg(struct reg *reg, uint8_t 
*buf)
 
 static int mips32_read_core_reg(struct target *target, unsigned int num)
 {
-       uint32_t reg_value;
+       unsigned int cnum;
+       uint64_t reg_value = 0;
 
        /* get pointers to arch-specific information */
        struct mips32_common *mips32 = target_to_mips32(target);
@@ -196,17 +297,42 @@ static int mips32_read_core_reg(struct target *target, 
unsigned int num)
        if (num >= MIPS32_NUM_REGS)
                return ERROR_COMMAND_SYNTAX_ERROR;
 
-       reg_value = mips32->core_regs[num];
-       buf_set_u32(mips32->core_cache->reg_list[num].value, 0, 32, reg_value);
+       if (num >= MIPS32_REGLIST_C0_INDEX) {
+               /* CP0 */
+               cnum = num - MIPS32_REGLIST_C0_INDEX;
+               reg_value = mips32->core_regs.cp0[cnum];
+               buf_set_u32(mips32->core_cache->reg_list[num].value, 0, 32, 
reg_value);
+               if (cnum == 0)
+                       mips32_detect_fpr_mode_change(mips32, reg_value);
+       } else if (num >= MIPS32_REGLIST_FPC_INDEX) {
+               /* FPCR */
+               cnum = num - MIPS32_REGLIST_FPC_INDEX;
+               reg_value = mips32->core_regs.fpcr[cnum];
+               buf_set_u32(mips32->core_cache->reg_list[num].value, 0, 32, 
reg_value);
+       } else if (num >= MIPS32_REGLIST_FP_INDEX) {
+               /* FPR */
+               cnum = num - MIPS32_REGLIST_FP_INDEX;
+               reg_value = mips32->core_regs.fpr[cnum];
+               buf_set_u64(mips32->core_cache->reg_list[num].value, 0, 64, 
reg_value);
+       } else {
+               /* GPR */
+               cnum = num - 0;
+               reg_value = mips32->core_regs.gpr[cnum];
+               buf_set_u32(mips32->core_cache->reg_list[num].value, 0, 32, 
reg_value);
+       }
+
        mips32->core_cache->reg_list[num].valid = true;
        mips32->core_cache->reg_list[num].dirty = false;
 
+       LOG_DEBUG("read core reg %i value 0x%" PRIx64 "", num, reg_value);
+
        return ERROR_OK;
 }
 
 static int mips32_write_core_reg(struct target *target, unsigned int num)
 {
-       uint32_t reg_value;
+       unsigned int cnum;
+       uint64_t reg_value;
 
        /* get pointers to arch-specific information */
        struct mips32_common *mips32 = target_to_mips32(target);
@@ -214,9 +340,31 @@ static int mips32_write_core_reg(struct target *target, 
unsigned int num)
        if (num >= MIPS32_NUM_REGS)
                return ERROR_COMMAND_SYNTAX_ERROR;
 
-       reg_value = buf_get_u32(mips32->core_cache->reg_list[num].value, 0, 32);
-       mips32->core_regs[num] = reg_value;
-       LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", num, reg_value);
+       if (num >= MIPS32_REGLIST_C0_INDEX) {
+               /* CP0 */
+               cnum = num - MIPS32_REGLIST_C0_INDEX;
+               reg_value = 
buf_get_u32(mips32->core_cache->reg_list[num].value, 0, 32);
+               mips32->core_regs.cp0[cnum] = (uint32_t)reg_value;
+               if (cnum == 0)
+                       mips32_detect_fpr_mode_change(mips32, reg_value);
+       } else if (num >= MIPS32_REGLIST_FPC_INDEX) {
+               /* FPCR */
+               cnum = num - MIPS32_REGLIST_FPC_INDEX;
+               reg_value = 
buf_get_u32(mips32->core_cache->reg_list[num].value, 0, 32);
+               mips32->core_regs.fpcr[cnum] = (uint32_t)reg_value;
+       } else if (num >= MIPS32_REGLIST_FP_INDEX) {
+               /* FPR */
+               cnum = num - MIPS32_REGLIST_FP_INDEX;
+               reg_value = 
buf_get_u64(mips32->core_cache->reg_list[num].value, 0, 64);
+               mips32->core_regs.fpr[cnum] = reg_value;
+       } else {
+               /* GPR */
+               cnum = num - 0;
+               reg_value = 
buf_get_u32(mips32->core_cache->reg_list[num].value, 0, 32);
+               mips32->core_regs.gpr[cnum] = (uint32_t)reg_value;
+       }
+
+       LOG_DEBUG("write core reg %i value 0x%" PRIx64 "", num, reg_value);
        mips32->core_cache->reg_list[num].valid = true;
        mips32->core_cache->reg_list[num].dirty = false;
 
@@ -285,7 +433,7 @@ int mips32_arch_state(struct target *target)
        LOG_USER("target halted in %s mode due to %s, pc: 0x%8.8" PRIx32 "",
                mips_isa_strings[mips32->isa_mode],
                debug_reason_name(target),
-               buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 
32));
+               
buf_get_u32(mips32->core_cache->reg_list[MIPS32_REGLIST_C0_PC_INDEX].value, 0, 
32));
 
        return ERROR_OK;
 }
@@ -322,25 +470,19 @@ struct reg_cache *mips32_build_reg_cache(struct target 
*target)
                arch_info[i].mips32_common = mips32;
 
                reg_list[i].name = mips32_regs[i].name;
-               reg_list[i].size = 32;
-
-               if (mips32_regs[i].flag == MIPS32_GDB_DUMMY_FP_REG) {
-                       reg_list[i].value = mips32_gdb_dummy_fp_value;
-                       reg_list[i].valid = true;
-                       reg_list[i].arch_info = NULL;
-                       register_init_dummy(&reg_list[i]);
-               } else {
-                       reg_list[i].value = calloc(1, 4);
-                       reg_list[i].valid = false;
-                       reg_list[i].type = &mips32_reg_type;
-                       reg_list[i].arch_info = &arch_info[i];
-
-                       reg_list[i].reg_data_type = calloc(1, sizeof(struct 
reg_data_type));
-                       if (reg_list[i].reg_data_type)
-                               reg_list[i].reg_data_type->type = 
mips32_regs[i].type;
-                       else
-                               LOG_ERROR("unable to allocate reg type list");
-               }
+               reg_list[i].size = mips32_regs[i].flag ? 64 : 32;
+
+               reg_list[i].value = mips32_regs[i].flag ? calloc(1, 8) : 
calloc(1, 4);
+               reg_list[i].valid = false;
+               reg_list[i].type = &mips32_reg_type;
+               reg_list[i].arch_info = &arch_info[i];
+
+               reg_list[i].reg_data_type = calloc(1, sizeof(struct 
reg_data_type));
+               if (reg_list[i].reg_data_type)
+                       reg_list[i].reg_data_type->type = mips32_regs[i].type;
+               else
+                       LOG_ERROR("unable to allocate reg type list");
+
 
                reg_list[i].dirty = false;
 
@@ -407,7 +549,7 @@ static int mips32_run_and_wait(struct target *target, 
target_addr_t entry_point,
                return ERROR_TARGET_TIMEOUT;
        }
 
-       pc = buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32);
+       pc = 
buf_get_u32(mips32->core_cache->reg_list[MIPS32_REGLIST_C0_PC_INDEX].value, 0, 
32);
        if (exit_point && (pc != exit_point)) {
                LOG_DEBUG("failed algorithm halted at 0x%" PRIx32 " ", pc);
                return ERROR_TARGET_TIMEOUT;
@@ -751,15 +893,242 @@ int mips32_cpu_probe(struct target *target)
        return ERROR_OK;
 }
 
+
+static uint32_t mips32_determine_cputype_from_prid(uint32_t prid, uint32_t 
config, uint32_t config1)
+{
+       uint32_t cpu_type;
+
+       /* Determine CPU type from PRID. */
+       if (((prid >> 16) & 0xff) == 16)
+               /* Altera */
+               return (uint32_t)MIPS32_CPU_MP32;
+
+       if (((prid >> 16) & 0xff) == 2)
+               /* Broadcom */
+               return (uint32_t)MIPS32_CPU_BCM;
+
+       if (((prid >> 16) & 0xff) == 3) {
+               /* AMD Alchemy processors */
+               switch ((prid >> 24) & 0xff) {
+                       case 0x00:
+                               cpu_type = MIPS32_CPU_AU1000;
+                               break;
+
+                       case 0x01:
+                               cpu_type = MIPS32_CPU_AU1500;
+                               break;
+
+                       case 0x02:
+                               cpu_type = MIPS32_CPU_AU1100;
+                               break;
+
+                       case 0x03:
+                               cpu_type = MIPS32_CPU_AU1550;
+                               break;
+
+                       case 0x04:
+                               cpu_type = MIPS32_CPU_AU1200;
+                               break;
+
+                       default:
+                               cpu_type = MIPS32_CPU_UNKNOWN;
+                               break;
+               } /* end of switch */
+
+               return cpu_type;
+       }
+
+       switch ((prid >> 8) & 0xff) {   /* MIPS Technologies cores */
+               case 0x80:
+                       cpu_type = MIPS32_CPU_4Kc;
+                       break;
+
+               case 0x81:
+                       if (config1 & 1)
+                               cpu_type = MIPS32_CPU_5Kf;         /* fpu 
present */
+                       else
+                               cpu_type = MIPS32_CPU_5Kc;
+                       break;
+
+               case 0x82:
+                       cpu_type = MIPS32_CPU_20Kc;
+                       break;
+
+               case 0x83:
+                       if ((config >> 20) & 1)
+                               cpu_type = MIPS32_CPU_4Kp;
+                       else
+                               cpu_type = MIPS32_CPU_4Km;
+                       break;
+
+               case 0x84:
+               case 0x90:
+                       cpu_type = MIPS32_CPU_4KEc;
+                       break;
+
+               case 0x85:
+               case 0x91:
+                       if ((config >> 20) & 1)
+                               cpu_type = MIPS32_CPU_4KEp;
+                       else
+                               cpu_type = MIPS32_CPU_4KEm;
+                       break;
+
+               case 0x86:
+                       cpu_type = MIPS32_CPU_4KSc;
+                       break;
+
+               case 0x87:
+                       cpu_type = MIPS32_CPU_M4K;
+                       break;
+
+               case 0x88:
+                       cpu_type = MIPS32_CPU_25Kf;
+                       break;
+
+               case 0x89:
+                       if (config1 & 1)
+                               cpu_type = MIPS32_CPU_5KEf;     /* fpu present 
*/
+                       else
+                               cpu_type = MIPS32_CPU_5KEc;
+                       break;
+
+               case 0x92:
+                       cpu_type = MIPS32_CPU_4KSd;
+                       break;
+
+               case 0x93:
+                       if (config1 & 1)
+                               cpu_type = MIPS32_CPU_24Kf;     /* fpu present 
*/
+                       else
+                               cpu_type = MIPS32_CPU_24Kc;
+                       break;
+
+               case 0x95:
+                       if (config1 & 1)
+                               cpu_type = MIPS32_CPU_34Kf;     /* fpu present 
*/
+                       else {
+                               /* TODO: */
+                               /* In MT with a single-threaded FPU, Config1.FP 
may be 0   */
+                               /* even though an FPU exists.  Scan all TC 
contexts and if */
+                               /* any have Config1.FP, then set processor to 
100Kf.       */
+                               cpu_type = MIPS32_CPU_34Kc;
+                       }
+                       break;
+
+               case 0x96:
+                       if (config1 & 1)
+                               cpu_type = MIPS32_CPU_24KEf;    /* fpu present 
*/
+                       else
+                               cpu_type = MIPS32_CPU_24KEc;
+                       break;
+
+               case 0x97:
+                       if (config1 & 1)
+                               cpu_type = MIPS32_CPU_74Kf;     /* fpu present 
*/
+                       else
+                               cpu_type = MIPS32_CPU_74Kc;
+                       break;
+
+               case 0x99:
+                       if (config1 & 1)
+                               cpu_type = MIPS32_CPU_1004Kf;   /* fpu present 
*/
+                       else {
+                               /* TODO: */
+                               /* In MT with a single-threaded FPU, Config1.FP 
may be 0   */
+                               /* even though an FPU exists.  Scan all TC 
contexts and if */
+                               /* any have Config1.FP, then set processor to 
100Kf.       */
+                               cpu_type = MIPS32_CPU_1004Kc;
+                       }
+                       break;
+
+               case 0x9A:
+                       if (config1 & 1)
+                               cpu_type = MIPS32_CPU_1074Kf;   /* fpu present 
*/
+                       else {
+                               /* TODO: */
+                               /* In MT with a single-threaded FPU, Config1.FP 
may be 0   */
+                               /* even though an FPU exists.  Scan all TC 
contexts and if */
+                               /* any have Config1.FP, then set processor to 
100Kf.       */
+                               cpu_type = MIPS32_CPU_1074Kc;
+                       }
+                       break;
+
+               case 0x9B:
+                       cpu_type = MIPS32_CPU_M14K;
+                       break;
+
+               case 0x9C:
+                       if (config1& 1)
+                               cpu_type = MIPS32_CPU_M14Kf;    /* fpu present 
*/
+                       else
+                               cpu_type = MIPS32_CPU_M14Kc;
+                       break;
+
+               case 0x9D:
+                       if (config1 & 1)
+                               cpu_type = MIPS32_CPU_M14KEf;
+                       else
+                               cpu_type = MIPS32_CPU_M14KE;
+                       break;
+
+               case 0x9E:
+                       if (config1 & 1)
+                               cpu_type = MIPS32_CPU_M14KEcf;
+                       else
+                               cpu_type = MIPS32_CPU_M14KEc;
+                       break;
+
+               case 0xA0:
+                       cpu_type = MIPS32_CPU_INTERAPTIV;
+                       break;
+
+               case 0xA1:
+                       cpu_type = MIPS32_CPU_INTERAPTIV_CM;
+                       break;
+
+               case 0xA2:
+                       cpu_type = MIPS32_CPU_PROAPTIV;
+                       break;
+
+               case 0xA3:
+                       cpu_type = MIPS32_CPU_PROAPTIV_CM;
+                       break;
+
+               case 0xA6:
+                       cpu_type = MIPS32_CPU_M5100;
+                       break;
+
+               case 0xA7:
+                       cpu_type = MIPS32_CPU_M5150;
+                       break;
+
+               case 0xA8:
+                       cpu_type = MIPS32_CPU_P5600;
+                       break;
+
+               case 0xA9:
+                       cpu_type = MIPS32_CPU_I5500;
+                       break;
+
+               default:
+                       cpu_type = MIPS32_CPU_UNKNOWN;
+                       break;
+       }
+
+       return (cpu_type);
+}
+
 /* read config to config3 cp0 registers and log isa implementation */
 int mips32_read_config_regs(struct target *target)
 {
        struct mips32_common *mips32 = target_to_mips32(target);
        struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
+       int retval;
 
        if (ejtag_info->config_regs == 0)
                for (int i = 0; i != 4; i++) {
-                       int retval = mips32_cp0_read(ejtag_info, 
&ejtag_info->config[i], 16, i);
+                       retval = mips32_cp0_read(ejtag_info, 
&ejtag_info->config[i], 16, i);
                        if (retval != ERROR_OK) {
                                LOG_ERROR("isa info not available, failed to 
read cp0 config register: %" PRId32, i);
                                ejtag_info->config_regs = 0;
@@ -772,29 +1141,83 @@ int mips32_read_config_regs(struct target *target)
        else
                return ERROR_OK;        /* already successfully read */
 
-       LOG_DEBUG("read  %"PRIu32" config registers", ejtag_info->config_regs);
+       LOG_DEBUG("read %"PRIu32" config registers", ejtag_info->config_regs);
 
        if (ejtag_info->impcode & EJTAG_IMP_MIPS16) {
                mips32->isa_imp = MIPS32_MIPS16;
-               LOG_USER("MIPS32 with MIPS16 support implemented");
-
+               LOG_USER("ISA implemented: %s", "MIPS32, MIPS16");
        } else if (ejtag_info->config_regs >= 4) {      /* config3 implemented 
*/
                unsigned isa_imp = (ejtag_info->config[3] & 
MIPS32_CONFIG3_ISA_MASK) >> MIPS32_CONFIG3_ISA_SHIFT;
                if (isa_imp == 1) {
                        mips32->isa_imp = MMIPS32_ONLY;
-                       LOG_USER("MICRO MIPS32 only implemented");
+                       LOG_USER("ISA implemented: %s", "microMIPS32");
 
                } else if (isa_imp != 0) {
                        mips32->isa_imp = MIPS32_MMIPS32;
-                       LOG_USER("MIPS32 and MICRO MIPS32 implemented");
+                       LOG_USER("ISA implemented: %s", "MIPS32, microMIPS32");
                }
+       } else if (mips32->isa_imp == MIPS32_ONLY)      /* initial default 
value */
+               LOG_USER("ISA implemented: %s", "MIPS32");
+
+
+       /* Retrieve DSP info */
+       mips32->dsp_imp = ((ejtag_info->config[3] & MIPS32_CONFIG3_DSPP_MASK) 
>> MIPS32_CONFIG3_DSPP_SHIFT);
+
+       if (mips32->dsp_imp) {
+               mips32->dsp_imp = ((ejtag_info->config[3] & 
MIPS32_CONFIG3_DSPREV_MASK) >> MIPS32_CONFIG3_DSPREV_SHIFT) + 1;
+               char buf[16];
+               sprintf(buf, "yes, rev %d", mips32->dsp_imp);
+               LOG_USER("DSP implemented: %s", buf);
+       } else {
+               LOG_USER("DSP implemented: %s", "no");
        }
 
-       if (mips32->isa_imp == MIPS32_ONLY)     /* initial default value */
-               LOG_USER("MIPS32 only implemented");
+
+       /* Determine if FDC and CDMM are implemented for this core */
+       uint32_t dcr;
+
+       retval = target_read_u32(target, EJTAG_DCR, &dcr);
+       if (retval != ERROR_OK) {
+               LOG_ERROR("failed to read EJTAG_DCR register");
+               return retval;
+       }
+
+       uint32_t prid;
+       retval = mips32_cp0_read(ejtag_info, &prid, 15, 0);
+       if (retval != ERROR_OK) {
+               LOG_ERROR("failed to read PRID");
+               return retval;
+       }
+
+       LOG_USER("PRID: 0x%08x", prid);
+
+       uint32_t cpu_type = mips32_determine_cputype_from_prid(prid, 
ejtag_info->config[0], ejtag_info->config[1]);
+
+       /* Determine which CP0 registers are available in the current processor 
core */
+       switch (cpu_type) {
+       case MIPS32_CPU_M14KE:
+       case MIPS32_CPU_M14KEf:
+               mips32->cp0_mask = MIPS_CP0_mAPTIV_uC;
+               break;
+       case MIPS32_CPU_M14KEc:
+       case MIPS32_CPU_M14KEcf:
+       case MIPS32_CPU_M5150:
+               mips32->cp0_mask = MIPS_CP0_mAPTIV_uP;
+               break;
+       case MIPS32_CPU_INTERAPTIV:
+       case MIPS32_CPU_INTERAPTIV_CM:
+               mips32->cp0_mask = MIPS_CP0_iAPTIV;
+               break;
+       default:
+               mips32->cp0_mask = MIPS_CP0_MK4;
+               break;
+       }
+
+       LOG_USER("CPU type: 0x%08x, CP0 mask: 0x%08x", cpu_type, 
mips32->cp0_mask);
 
        return ERROR_OK;
 }
+
 int mips32_checksum_memory(struct target *target, target_addr_t address,
                uint32_t count, uint32_t *checksum)
 {
@@ -1022,6 +1445,711 @@ COMMAND_HANDLER(mips32_handle_cp0_command)
        return ERROR_OK;
 }
 
+COMMAND_HANDLER(mips32_handle_cpuinfo_command)
+{
+       int retval;
+       struct target *target = get_current_target(CMD_CTX);
+       struct mips32_common *mips32 = target_to_mips32(target);
+       struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
+
+       struct mips32_cpu_features info = {};
+
+       char text[40] = {0};
+       uint32_t ways, sets, bpl;
+
+       uint32_t prid; /* cp0 PRID - 15, 0 */
+       uint32_t config; /*     cp0 config - 16, 0 */
+       uint32_t config1; /*    cp0 config - 16, 1 */
+       uint32_t config2; /*    cp0 config - 16, 2 */
+       uint32_t config3; /*    cp0 config - 16, 3 */
+       uint32_t config4; /*    cp0 config - 16, 4 */
+       uint32_t config5; /*    cp0 config - 16, 5 */
+       uint32_t config7; /*    cp0 config - 16, 7 */
+
+       if (target->state != TARGET_HALTED) {
+               command_print(CMD, "target must be stopped for \"%s\" command", 
CMD_NAME);
+               return ERROR_OK;
+       }
+
+       /* No arg.s for now */
+       if (CMD_ARGC >= 1)
+               return ERROR_COMMAND_SYNTAX_ERROR;
+
+       /* Read PRID and config registers */
+       retval = mips32_cp0_read(ejtag_info, &prid, 15, 0);
+       if (retval  != ERROR_OK)
+               return retval;
+
+       /* Read Config, Config(1,2,3,5 and 7) registers */
+       retval = mips32_cp0_read(ejtag_info, &config, 16, 0);
+       if (retval != ERROR_OK)
+               return retval;
+
+       retval = mips32_cp0_read(ejtag_info, &config1, 16, 1);
+       if (retval != ERROR_OK)
+               return retval;
+
+       retval = mips32_cp0_read(ejtag_info, &config2, 16, 2);
+       if (retval != ERROR_OK)
+               return retval;
+
+       retval = mips32_cp0_read(ejtag_info, &config3, 16, 3);
+       if (retval != ERROR_OK)
+               return retval;
+
+       retval = mips32_cp0_read(ejtag_info, &config4, 16, 4);
+       if (retval != ERROR_OK)
+               return retval;
+
+       retval = mips32_cp0_read(ejtag_info, &config5, 16, 5);
+       if (retval != ERROR_OK)
+               return retval;
+
+       retval = mips32_cp0_read(ejtag_info, &config7, 16, 7);
+       if (retval != ERROR_OK)
+               return retval;
+
+       /* Read and store dspase and mtase (and other) architecture extension 
presence bits */
+       info.dspase = (config3 & 0x00000400) ? 1 : 0;           /* dsp ase */
+       info.smase      = (config3 & 0x00000002) ? 1 : 0;               /* 
smartmips ase */
+       info.mtase  = (config3 & 0x00000004) ? 1 : 0;           /* 
multithreading */
+       info.m16ase = (config1 & 0x00000004) ? 1 : 0;           /* mips16(e) 
ase */
+       info.micromipsase = ((config3 >> 14) & 0x3) != 0;
+       info.mmu_type = (config >> 7) & 7;                                      
/* MMU Type Info */
+       info.vzase = (config3 & (1<<23)) ? 1 : 0;                       /* VZ */
+       LOG_USER("VZ Module: %d", info.vzase);
+
+       /* Check if Virtualization supported */
+       /* TODO List */
+       if (info.vzase) {
+               /* Core supports Virtualization - now get Guest Info */
+               uint32_t width;
+               uint32_t guestCtl0;
+
+               retval = mips32_cp0_read(ejtag_info, &guestCtl0, 12, 6);
+               if (retval  != ERROR_OK)
+                       return retval;
+
+               info.guest_ctl1_present = (guestCtl0 >> 22) & 0x1;
+
+               retval = mips32_determine_guestid_width(ejtag_info, &width);
+               if (retval != ERROR_OK)
+                       return retval;
+
+               info.vz_guest_id_width = width;
+
+               LOG_USER("guest ID width: %d", info.vz_guest_id_width);
+       }
+
+       /* MIPS SIMD Architecture (MSA) */
+       info.msa = (config3 & 0x10000000) ? 1 : 0;
+       info.cdmm = (config3 & 0x00000008) ? 1 : 0;
+       info.mvh = (config5 & (1<<5)) ? 1 : 0;          /* mvh */
+
+       /* MMU Supported */
+       info.tlb_entries = 0;
+
+       /* MMU types */
+       if (((info.mmu_type == 1) || (info.mmu_type == 4)) || ((info.mmu_type 
== 3) && info.vzase)) {
+               info.tlb_entries = (((config1 >> 25) & 0x3f)+1);
+               info.mmu_type = (config >> 7) & 7;
+               if (info.mmu_type == 1)
+                       /* VTLB only   !!!Does not account for Config4.ExtVTLB 
*/
+                       info.tlb_entries = (uint32_t)(((config1 >> 25) & 
0x3f)+1);
+               else    /* root RPU */
+                       if ((info.mmu_type == 3) && info.vzase)
+                               info.tlb_entries = (uint32_t)(((config1 >> 25) 
& 0x3f)+1);
+                       else {
+                               /*  VTLB and FTLB */
+                               if (info.mmu_type == 4) {
+                                       ways = ftlb_ways[(config4 >> 4) & 0xf];
+                                       sets = ftlb_sets[config4 & 0xf];
+                                       info.tlb_entries = 
(uint32_t)((((config1 >> 25) & 0x3f)+1) + (ways*sets));
+                               } else
+                                       info.tlb_entries = 0;
+               }
+       }
+
+       /* If release 2 of Arch. then get exception base info */
+       if (((config >> 10) & 7) != 0) {        /* release 2 */
+               uint32_t  ebase;
+               retval = mips32_cp0_read(ejtag_info, &ebase, 15, 1);
+               if (retval != ERROR_OK)
+                       return retval;
+
+               info.cpuid = (uint32_t)(ebase & 0x1ff);
+       } else {
+               info.cpuid = 0;
+       }
+
+       info.cpu_type = mips32_determine_cputype_from_prid(prid, config, 
config1);
+
+       /* Determine Core info */
+       switch (info.cpu_type) {
+               case MIPS32_CPU_4Kc:
+                       info.cpu_core = MIPS32_CPU_4Kc;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "4Kc");
+               break;
+
+               case MIPS32_CPU_4Km:
+                       info.cpu_core = MIPS32_CPU_4Km;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "4Km");
+               break;
+
+               case MIPS32_CPU_4Kp:
+                       info.cpu_core = MIPS32_CPU_4Kp;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "4Kp");
+               break;
+
+               case MIPS32_CPU_4KEc:
+                       info.cpu_core = MIPS32_CPU_4KEc;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "4KEc");
+               break;
+
+               case MIPS32_CPU_4KEm:
+                       info.cpu_core = MIPS32_CPU_4KEm;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "4KEm");
+               break;
+               case MIPS32_CPU_4KEp:
+                       info.cpu_core = MIPS32_CPU_4KEp;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "4KEp");
+               break;
+
+               case MIPS32_CPU_4KSc:
+                       info.cpu_core = MIPS32_CPU_4KSc;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "4KSc");
+               break;
+
+               case MIPS32_CPU_4KSd:
+                       info.cpu_core = MIPS32_CPU_4KSd;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "4KSd");
+               break;
+
+               case MIPS32_CPU_M4K:
+                       info.cpu_core = MIPS32_CPU_M4K;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "4K");
+               break;
+
+               case MIPS32_CPU_24Kc:
+                       info.cpu_core = MIPS32_CPU_24Kc;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "24Kc");
+               break;
+
+               case MIPS32_CPU_24Kf:
+                       info.cpu_core = MIPS32_CPU_24Kf;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "24Kf");
+               break;
+
+               case MIPS32_CPU_24KEc:
+                       info.cpu_core = MIPS32_CPU_24KEc;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "24KEc");
+               break;
+
+               case MIPS32_CPU_24KEf:
+                       info.cpu_core = MIPS32_CPU_24KEf;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "24KEf");
+               break;
+
+               case MIPS32_CPU_34Kc:
+                       info.cpu_core = MIPS32_CPU_34Kc;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "34Kc");
+               break;
+
+               case MIPS32_CPU_34Kf:
+                       info.cpu_core = MIPS32_CPU_34Kf;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "3Kf ");
+               break;
+
+               case MIPS32_CPU_5Kc:
+                       info.cpu_core = MIPS32_CPU_5Kc;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS64;
+                       strcpy(text, "5Kc");
+               break;
+
+               case MIPS32_CPU_5Kf:
+                       info.cpu_core = MIPS32_CPU_5Kf;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS64;
+                       strcpy(text, "5Kf");
+               break;
+
+               case MIPS32_CPU_5KEc:
+                       info.cpu_core = MIPS32_CPU_5KEc;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS64;
+                       strcpy(text, "5KEc");
+               break;
+
+               case MIPS32_CPU_5KEf:
+                       info.cpu_core = MIPS32_CPU_5KEf;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS64;
+                       strcpy(text, "5KEf");
+               break;
+
+               case MIPS32_CPU_20Kc:
+                       info.cpu_core = MIPS32_CPU_20Kc;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS64;
+                       strcpy(text, "20Kc");
+               break;
+
+               case MIPS32_CPU_25Kf:
+                       info.cpu_core = MIPS32_CPU_25Kf;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS64;
+                       strcpy(text, "25Kf");
+               break;
+
+               case MIPS32_CPU_AU1000:
+                       info.cpu_core = MIPS32_CPU_AU1000;
+                       info.vendor = MIPS32_CPU_VENDOR_ALCHEMY;
+                       info.isa = MIPS32;
+                       strcpy(text, "AU1000");
+               break;
+               case MIPS32_CPU_AU1100:
+                       info.cpu_core = MIPS32_CPU_AU1100;
+                       info.vendor = MIPS32_CPU_VENDOR_ALCHEMY;
+                       info.isa = MIPS32;
+                       strcpy(text, "AU1100");
+               break;
+
+               case MIPS32_CPU_AU1200:
+                       info.cpu_core = MIPS32_CPU_AU1200;
+                       info.vendor = MIPS32_CPU_VENDOR_ALCHEMY;
+                       info.isa = MIPS32;
+                       strcpy(text, "AU1200");
+               break;
+
+               case MIPS32_CPU_AU1500:
+                       info.cpu_core = MIPS32_CPU_AU1500;
+                       info.vendor = MIPS32_CPU_VENDOR_ALCHEMY;
+                       info.isa = MIPS32;
+                       strcpy(text, "AU1500");
+               break;
+
+               case MIPS32_CPU_AU1550:
+                       info.cpu_core = MIPS32_CPU_AU1550;
+                       info.vendor = MIPS32_CPU_VENDOR_ALCHEMY;
+                       info.isa = MIPS32;
+                       strcpy(text, "AU1550");
+               break;
+
+               case MIPS32_CPU_74Kc:
+                       info.cpu_core = MIPS32_CPU_74Kc;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "74Kc");
+               break;
+
+               case MIPS32_CPU_74Kf:
+                       info.cpu_core = MIPS32_CPU_74Kf;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "74Kf");
+               break;
+
+               case MIPS32_CPU_84Kc:
+                       info.cpu_core = MIPS32_CPU_84Kc;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "84Kc");
+               break;
+
+               case MIPS32_CPU_84Kf:
+                       info.cpu_core = MIPS32_CPU_84Kf;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "84Kf");
+               break;
+
+               case MIPS32_CPU_M14K:
+                       info.cpu_core = MIPS32_CPU_M14K;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       strcpy(text, "M14K");
+                       break;
+
+               case MIPS32_CPU_M14Kc:
+                       info.cpu_core = MIPS32_CPU_M14Kc;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       strcpy(text, "M14Kc");
+                       break;
+
+               case MIPS32_CPU_M14Kf:
+                       info.cpu_core = MIPS32_CPU_M14Kf;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       strcpy(text, "M14Kf");
+                       break;
+
+               case MIPS32_CPU_M14KE:
+                       info.cpu_core = MIPS32_CPU_M14KE;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       strcpy(text, "microAptiv_UC");
+                       break;
+
+               case MIPS32_CPU_M14KEf:
+                       info.cpu_core = MIPS32_CPU_M14KEf;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       strcpy(text, "microAptiv_UCF");
+                       break;
+
+               case MIPS32_CPU_M14KEc:
+                       info.cpu_core = MIPS32_CPU_M14KEc;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       strcpy(text, "microAptiv_UP");
+                       break;
+
+               case MIPS32_CPU_M14KEcf:
+                       info.cpu_core = MIPS32_CPU_M14KEcf;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       strcpy(text, "microAptiv_UPF");
+                       break;
+
+               case MIPS32_CPU_M5100:
+                       info.cpu_core = MIPS32_CPU_M5100;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       strcpy(text, "M5100");
+                       break;
+
+               case MIPS32_CPU_M5150:
+                       info.cpu_core = MIPS32_CPU_M5150;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       strcpy(text, "M5150");
+                       break;
+
+               case MIPS32_CPU_BCM:
+                       info.cpu_core = MIPS32_CPU_BCM;
+                       info.vendor = MIPS32_CPU_VENDOR_BROADCOM;
+                       info.isa = MIPS32;
+                       strcpy(text, "BCM");
+               break;
+
+               case MIPS32_CPU_MP32:
+                       info.cpu_core = MIPS32_CPU_MP32;
+                       info.vendor = MIPS32_CPU_VENDOR_ALTERA;
+                       info.isa = MIPS32;
+                       strcpy(text, "MP32");
+               break;
+
+               case MIPS32_CPU_1004Kc:
+                       info.cpu_core = MIPS32_CPU_1004Kc;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "1004Kc");
+               break;
+
+               case MIPS32_CPU_1004Kf:
+                       info.cpu_core = MIPS32_CPU_1004Kf;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "1004Kf");
+               break;
+
+               case MIPS32_CPU_1074Kc:
+                       info.cpu_core = MIPS32_CPU_1074Kc;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "1074Kc");
+               break;
+
+               case MIPS32_CPU_1074Kf:
+                       info.cpu_core = MIPS32_CPU_1074Kf;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "1074Kf");
+               break;
+
+               case MIPS32_CPU_PROAPTIV:
+                       info.cpu_core = MIPS32_CPU_PROAPTIV;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "PROAPTIV");
+               break;
+
+               case MIPS32_CPU_PROAPTIV_CM:
+                       info.cpu_core = MIPS32_CPU_PROAPTIV_CM;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "PROAPTIV_CM");
+               break;
+
+               case MIPS32_CPU_INTERAPTIV:
+                       info.cpu_core = MIPS32_CPU_INTERAPTIV;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "INTERAPTIV");
+               break;
+
+               case MIPS32_CPU_INTERAPTIV_CM:
+                       info.cpu_core = MIPS32_CPU_INTERAPTIV_CM;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "INTERAPTIV_CM");
+               break;
+
+               case MIPS32_CPU_P5600:
+                       info.cpu_core = MIPS32_CPU_P5600;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "P5600");
+               break;
+
+               case MIPS32_CPU_I5500:
+                       info.cpu_core = MIPS32_CPU_I5500;
+                       info.vendor = MIPS32_CPU_VENDOR_MTI;
+                       info.isa = MIPS32;
+                       strcpy(text, "I5500");
+               break;
+       }
+
+       /* Determine Instr Cache Size */
+       ways = wayTable[(config1 >> MIPS32_CFG1_IASHIFT) & 7];
+       sets = setTableISDS[(config1 >> MIPS32_CFG1_ISSHIFT) & 7];
+       bpl  = bplTable[(config1 >> MIPS32_CFG1_ILSHIFT) & 7];
+       info.inst_cache_size = ways*sets*bpl;
+
+       /* Determine data cache size */
+       ways = wayTable[(config1 >>  MIPS32_CFG1_DASHIFT) & 7];
+       sets = setTableISDS[(config1 >> MIPS32_CFG1_DSSHIFT) & 7];
+       bpl  = bplTable[(config1 >> MIPS32_CFG1_DLSHIFT) & 7];
+       info.data_cache_size = ways*sets*bpl;
+
+       /* Display Core Type info */
+       LOG_USER("cpu_core: MIPS_%s", &text[0]);
+
+       LOG_USER("cpu_type: %d", info.cpu_type);
+
+       /* Display Core Vendor ID */
+       switch (info.vendor) {
+               case MIPS32_CPU_VENDOR_MTI:
+                       strcpy(text, "MIPS");
+               break;
+
+               case MIPS32_CPU_VENDOR_ALCHEMY:
+                       strcpy(text, "Alchemy");
+               break;
+
+               case MIPS32_CPU_VENDOR_BROADCOM:
+                       strcpy(text, "Broadcom");
+               break;
+
+               case MIPS32_CPU_VENDOR_ALTERA:
+                       strcpy(text, "Altera");
+               break;
+
+               default:
+                       sprintf(text, "Unknown CPU vendor code %u.", ((prid & 
0x00ffff00) >> 16));
+               break;
+       }
+
+       /* Display Core Vendor */
+       LOG_USER(" vendor: %s", &text[0]);
+       LOG_USER("  cpuid: %d", info.cpuid);
+       switch ((((config3 & 0x0000C000) >>  14))) {
+               case 0:
+                       strcpy(text, "MIPS32");
+               break;
+               case 1:
+                       strcpy(text, "microMIPS");
+               break;
+               case 2:
+                       strcpy(text, "MIPS32 (at reset) and microMIPS");
+               break;
+
+               case 3:
+                       strcpy(text, "microMIPS (at reset) and MIPS32");
+               break;
+       }
+
+       /* Display Instruction Set Info */
+       LOG_USER("instr Set: %s", &text[0]);
+       LOG_USER("prid: %x", prid);
+       uint32_t rev = prid & 0x000000ff;
+       LOG_USER("rtl: %x.%x.%x", (rev & 0xE0), (rev & 0x1C), (rev & 0x3));
+
+       LOG_USER("Instr Cache: %d", info.inst_cache_size);
+       LOG_USER(" Data Cache: %d", info.data_cache_size);
+
+       LOG_USER("Max Number of Instr Breakpoints: %d", 
mips32->num_inst_bpoints);
+       LOG_USER("Max Number of  Data Breakpoints: %d", 
mips32->num_data_bpoints);
+
+       if (info.mtase) {
+               LOG_USER("mta: true");
+
+               /* Get VPE and Thread info */
+               uint32_t tcbind;
+               uint32_t mvpconf0;
+
+               /* Read tcbind register */
+               retval = mips32_cp0_read(ejtag_info, &tcbind, 2, 2);
+               if (retval != ERROR_OK)
+                       return retval;
+
+               LOG_USER("curvpe: %d", (tcbind & 0xf));
+               LOG_USER(" curtc: %d", ((tcbind >> 21) & 0xff));
+
+               /* Read mvpconf0 register */
+               retval = mips32_cp0_read(ejtag_info, &mvpconf0, 0, 2);
+               if (retval != ERROR_OK)
+                       return retval;
+
+               LOG_USER(" numtc: %d", (mvpconf0 & 0xf)+1);
+               LOG_USER("numvpe: %d", ((mvpconf0 >> 10) & 0xf)+1);
+       } else {
+               LOG_USER("mta: false");
+       }
+
+       switch (info.mmu_type) {
+               case MIPS32_MMU_TLB:
+                       strcpy(text, "TLB");
+               break;
+               case MIPS32_MMU_BAT:
+                       strcpy(text, "BAT");
+               break;
+               case MIPS32_MMU_FIXED:
+                       strcpy(text, "FIXED");
+               break;
+               case MIPS32_MMU_DUAL_VTLB_FTLB:
+                       strcpy(text, "DUAL VAR/FIXED");
+               break;
+               default:
+                       strcpy(text, "Unknown");
+       }
+
+       LOG_USER("MMU Type: %s", &text[0]);
+       LOG_USER("TLB Entries: %d", info.tlb_entries);
+
+       /* does the core support a DSP */
+       if (info.dspase)
+               strcpy(text, "true");
+       else
+               strcpy(text, "false");
+
+       LOG_USER("DSP Module: %s", &text[0]);
+
+       /* MIPS SIMD Architecture (MSA) */
+       if (info.msa)
+               strcpy(text, "true");
+       else
+               strcpy(text, "false");
+
+       LOG_USER("msa: %s", &text[0]);
+
+       /* Move To/From High COP0 (MTHC0/MFHC0) instructions are implemented. */
+       if (info.mvh)
+               strcpy(text, "true");
+       else
+               strcpy(text, "false");
+
+       LOG_USER("mvh: %s", &text[0]);
+
+       /* Common Device Memory Map implemented? */
+       if (info.cdmm)
+               strcpy(text, "true");
+       else
+               strcpy(text, "false");
+
+
+       LOG_USER("cdmm: %s", &text[0]);
+
+       return ERROR_OK;
+}
+
+
+extern void ejtag_main_print_imp(struct mips_ejtag *ejtag_info);
+extern int mips_ejtag_get_impcode(struct mips_ejtag *ejtag_info);
+
+COMMAND_HANDLER(mips32_handle_ejtag_reg_command)
+{
+       struct target *target = get_current_target(CMD_CTX);
+       struct mips32_common *mips32 = target_to_mips32(target);
+       struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
+
+       uint32_t idcode;
+       uint32_t impcode;
+       uint32_t ejtag_ctrl;
+       uint32_t dcr;
+       int retval;
+
+       retval = mips_ejtag_get_idcode(ejtag_info);
+       idcode = ejtag_info->idcode;
+       retval = mips_ejtag_get_impcode(ejtag_info);
+       impcode = ejtag_info->impcode;
+       mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
+       ejtag_ctrl = ejtag_info->ejtag_ctrl;
+       retval = mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
+
+       if (retval != ERROR_OK)
+               LOG_INFO("Encounter an Error");
+
+       LOG_USER("       idcode: 0x%8.8x", idcode);
+       LOG_USER("      impcode: 0x%8.8x", impcode);
+       LOG_USER("ejtag control: 0x%8.8x", ejtag_ctrl);
+
+       ejtag_main_print_imp(ejtag_info);
+
+       /* Display current DCR */
+       retval = target_read_u32(target, EJTAG_DCR, &dcr);
+       LOG_USER("          DCR: 0x%8.8x", dcr);
+
+       if (((dcr > 22) & 0x1) == 1)
+               LOG_USER("DAS supported");
+
+       if (((dcr > 18) & 0x1) == 1)
+               LOG_USER("FDC supported");
+
+       if (((dcr > 17) & 0x1) == 1)
+               LOG_USER("DataBrk supported");
+
+       if (((dcr > 16) & 0x1) == 1)
+               LOG_USER("InstBrk supported");
+
+       if (((dcr > 15) & 0x1) == 1)
+               LOG_USER("Inverted Data value supported");
+
+       if (((dcr > 14) & 0x1) == 1)
+               LOG_USER("Data value stored supported");
+
+       if (((dcr > 10) & 0x1) == 1)
+               LOG_USER("Complex Breakpoints supported");
+
+       if (((dcr > 9) & 0x1) == 1)
+               LOG_USER("PC Sampling supported");
+
+       return ERROR_OK;
+}
+
 COMMAND_HANDLER(mips32_handle_scan_delay_command)
 {
        struct target *target = get_current_target(CMD_CTX);
@@ -1031,7 +2159,7 @@ COMMAND_HANDLER(mips32_handle_scan_delay_command)
        if (CMD_ARGC == 1)
                COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], ejtag_info->scan_delay);
        else if (CMD_ARGC > 1)
-                       return ERROR_COMMAND_SYNTAX_ERROR;
+               return ERROR_COMMAND_SYNTAX_ERROR;
 
        command_print(CMD, "scan delay: %d nsec", ejtag_info->scan_delay);
        if (ejtag_info->scan_delay >= MIPS32_SCAN_DELAY_LEGACY_MODE) {
@@ -1053,13 +2181,27 @@ static const struct command_registration 
mips32_exec_command_handlers[] = {
                .usage = "regnum select [value]",
                .help = "display/modify cp0 register",
        },
-               {
+       {
+               .name = "cpuinfo",
+               .handler = mips32_handle_cpuinfo_command,
+               .mode = COMMAND_EXEC,
+               .help = "cpuinfo displays information for the current CPU 
core.",
+               .usage = "",
+       },
+       {
                .name = "scan_delay",
                .handler = mips32_handle_scan_delay_command,
                .mode = COMMAND_ANY,
                .help = "display/set scan delay in nano seconds",
                .usage = "[value]",
        },
+       {
+               .name = "ejtag_reg",
+               .handler = mips32_handle_ejtag_reg_command,
+               .mode = COMMAND_ANY,
+               .help = "read ejtag registers",
+               .usage = "",
+       },
        COMMAND_REGISTRATION_DONE
 };
 
diff --git a/src/target/mips32.h b/src/target/mips32.h
index 3d03e98c58..e46d165c55 100644
--- a/src/target/mips32.h
+++ b/src/target/mips32.h
@@ -46,26 +46,190 @@
 #define MIPS32_CONFIG0_AR_SHIFT 10
 #define MIPS32_CONFIG0_AR_MASK (0x7 << MIPS32_CONFIG0_AR_SHIFT)
 
+#define MIPS32_CONFIG1_FP_SHIFT        0
+#define MIPS32_CONFIG1_FP_MASK (1 << MIPS32_CONFIG1_FP_SHIFT)
+
 #define MIPS32_CONFIG1_DL_SHIFT 10
 #define MIPS32_CONFIG1_DL_MASK (0x7 << MIPS32_CONFIG1_DL_SHIFT)
 
+#define MIPS32_CONFIG3_DSPP_SHIFT      10
+#define MIPS32_CONFIG3_DSPP_MASK       (1 << MIPS32_CONFIG3_DSPP_SHIFT)
+
+#define MIPS32_CONFIG3_DSPREV_SHIFT    11
+#define MIPS32_CONFIG3_DSPREV_MASK     (1 << MIPS32_CONFIG3_DSPREV_SHIFT)
+
 #define MIPS32_CONFIG3_ISA_SHIFT       14
 #define MIPS32_CONFIG3_ISA_MASK                (3 << MIPS32_CONFIG3_ISA_SHIFT)
 
 #define MIPS32_ARCH_REL1 0x0
 #define MIPS32_ARCH_REL2 0x1
 
-#define MIPS32_SCAN_DELAY_LEGACY_MODE 2000000
+#define MIPS32_SCAN_DELAY_LEGACY_MODE  2000000
+
+#define MIPS32_NUM_DSPREGS             9
+
+
+/* Bit Mask indicating CP0 register supported by this core */
+#define        MIPS_CP0_MK4            0x0001
+#define        MIPS_CP0_mAPTIV_uC      0x0002
+#define        MIPS_CP0_mAPTIV_uP      0x0004
+#define MIPS_CP0_iAPTIV                0x0008
+
+/* CP0 Status register fields */
+#define MIPS32_CP0_STATUS_FR_SHIFT     26
+#define MIPS32_CP0_STATUS_CU1_SHIFT    29
+
+/* CP1 FIR register fields */
+#define MIPS32_CP1_FIR_F64_SHIFT       22
+
+static const struct {
+       unsigned int reg;
+       unsigned int sel;
+       const char *name;
+       const unsigned int core;
+} mips32_cp0_regs[] = {
+       {0, 0, "index", MIPS_CP0_iAPTIV | MIPS_CP0_mAPTIV_uP},
+       {0, 1, "mvpcontrol", MIPS_CP0_iAPTIV},
+       {0, 2, "mvpconf0", MIPS_CP0_iAPTIV},
+       {0, 3, "mvpconf1", MIPS_CP0_iAPTIV},
+       {1, 0, "random", MIPS_CP0_iAPTIV | MIPS_CP0_mAPTIV_uP},
+       {1, 1, "vpecontrol", MIPS_CP0_iAPTIV},
+       {1, 2, "vpeconf0", MIPS_CP0_iAPTIV},
+       {1, 3, "vpeconf1", MIPS_CP0_iAPTIV},
+       {1, 4, "yqmask", MIPS_CP0_iAPTIV},
+       {1, 5, "vpeschedule", MIPS_CP0_iAPTIV},
+       {1, 6, "vpeschefback", MIPS_CP0_iAPTIV},
+       {1, 7, "vpeopt", MIPS_CP0_iAPTIV},
+       {2, 0, "entrylo0", MIPS_CP0_iAPTIV | MIPS_CP0_mAPTIV_uP},
+       {2, 1, "tcstatus", MIPS_CP0_iAPTIV},
+       {2, 2, "tcbind", MIPS_CP0_iAPTIV},
+       {2, 3, "tcrestart", MIPS_CP0_iAPTIV},
+       {2, 4, "tchalt", MIPS_CP0_iAPTIV},
+       {2, 5, "tccontext", MIPS_CP0_iAPTIV},
+       {2, 6, "tcschedule", MIPS_CP0_iAPTIV},
+       {2, 7, "tcschefback", MIPS_CP0_iAPTIV},
+       {3, 0, "entrylo1", MIPS_CP0_iAPTIV | MIPS_CP0_mAPTIV_uP},
+       {3, 7, "tcopt", MIPS_CP0_iAPTIV},
+       {4, 0, "context", MIPS_CP0_iAPTIV | MIPS_CP0_mAPTIV_uP},
+       {4, 2, "userlocal", MIPS_CP0_iAPTIV | MIPS_CP0_mAPTIV_uC | 
MIPS_CP0_mAPTIV_uP | MIPS_CP0_MK4},
+       {5, 0, "pagemask", MIPS_CP0_iAPTIV | MIPS_CP0_mAPTIV_uP},
+       {5, 1, "pagegrain", MIPS_CP0_mAPTIV_uP},
+       {5, 2, "segctl0", MIPS_CP0_iAPTIV},
+       {5, 3, "segctl1", MIPS_CP0_iAPTIV},
+       {5, 4, "segctl2", MIPS_CP0_iAPTIV},
+       {6, 0, "wired", MIPS_CP0_iAPTIV | MIPS_CP0_mAPTIV_uP},
+       {6, 1, "srsconf0", MIPS_CP0_iAPTIV},
+       {6, 2, "srsconf1", MIPS_CP0_iAPTIV},
+       {6, 3, "srsconf2", MIPS_CP0_iAPTIV},
+       {6, 4, "srsconf3", MIPS_CP0_iAPTIV},
+       {6, 5, "srsconf4", MIPS_CP0_iAPTIV},
+       {7, 0, "hwrena", MIPS_CP0_iAPTIV | MIPS_CP0_mAPTIV_uC | 
MIPS_CP0_mAPTIV_uP | MIPS_CP0_MK4},
+       {8, 0, "badvaddr", MIPS_CP0_iAPTIV | MIPS_CP0_mAPTIV_uC | 
MIPS_CP0_mAPTIV_uP | MIPS_CP0_MK4},
+       {8, 1, "badinstr", MIPS_CP0_mAPTIV_uC | MIPS_CP0_mAPTIV_uP},
+       {8, 2, "badinstrp", MIPS_CP0_mAPTIV_uC | MIPS_CP0_mAPTIV_uP},
+       {9, 0, "count", MIPS_CP0_iAPTIV | MIPS_CP0_mAPTIV_uC | 
MIPS_CP0_mAPTIV_uP | MIPS_CP0_MK4},
+       {10, 0, "entryhi", MIPS_CP0_iAPTIV | MIPS_CP0_mAPTIV_uP},
+       {10, 4, "guestctl1", MIPS_CP0_iAPTIV | MIPS_CP0_mAPTIV_uP | 
MIPS_CP0_mAPTIV_uC | MIPS_CP0_MK4},
+       {10, 5, "guestctl2", MIPS_CP0_iAPTIV | MIPS_CP0_mAPTIV_uP | 
MIPS_CP0_mAPTIV_uC | MIPS_CP0_MK4},
+       {10, 6, "guestctl3", MIPS_CP0_iAPTIV | MIPS_CP0_mAPTIV_uP | 
MIPS_CP0_mAPTIV_uC | MIPS_CP0_MK4},
+       {11, 0, "compare", MIPS_CP0_iAPTIV | MIPS_CP0_mAPTIV_uC | 
MIPS_CP0_mAPTIV_uP | MIPS_CP0_MK4},
+       {11, 4, "guestctl0ext", MIPS_CP0_iAPTIV | MIPS_CP0_mAPTIV_uP | 
MIPS_CP0_mAPTIV_uC | MIPS_CP0_MK4},
+       {12, 0, "status", MIPS_CP0_iAPTIV | MIPS_CP0_mAPTIV_uC | 
MIPS_CP0_mAPTIV_uP | MIPS_CP0_MK4},
+       {12, 1, "intctl", MIPS_CP0_iAPTIV | MIPS_CP0_mAPTIV_uC | 
MIPS_CP0_mAPTIV_uP | MIPS_CP0_MK4},
+       {12, 2, "srsctl", MIPS_CP0_iAPTIV | MIPS_CP0_mAPTIV_uC | 
MIPS_CP0_mAPTIV_uP | MIPS_CP0_MK4},
+       {12, 3, "srsmap", MIPS_CP0_iAPTIV},
+       {12, 3, "srsmap1", MIPS_CP0_iAPTIV | MIPS_CP0_mAPTIV_uC | 
MIPS_CP0_mAPTIV_uP},
+       {12, 4, "view_ipl", MIPS_CP0_mAPTIV_uC | MIPS_CP0_mAPTIV_uP | 
MIPS_CP0_MK4},
+       {12, 5, "srsmap2", MIPS_CP0_iAPTIV | MIPS_CP0_mAPTIV_uC | 
MIPS_CP0_mAPTIV_uP},
+       {12, 6, "guestctl0", MIPS_CP0_iAPTIV | MIPS_CP0_mAPTIV_uP | 
MIPS_CP0_mAPTIV_uC | MIPS_CP0_MK4},
+       {12, 7, "gtoffset", MIPS_CP0_iAPTIV | MIPS_CP0_mAPTIV_uP | 
MIPS_CP0_mAPTIV_uC | MIPS_CP0_MK4},
+       {13, 0, "cause", MIPS_CP0_iAPTIV | MIPS_CP0_mAPTIV_uC | 
MIPS_CP0_mAPTIV_uP | MIPS_CP0_MK4},
+       {13, 5, "nestedexc", MIPS_CP0_mAPTIV_uC | MIPS_CP0_mAPTIV_uP| 
MIPS_CP0_MK4},
+       {14, 0, "epc", MIPS_CP0_iAPTIV | MIPS_CP0_mAPTIV_uC | 
MIPS_CP0_mAPTIV_uP | MIPS_CP0_MK4},
+       {14, 2, "nestedepc", MIPS_CP0_iAPTIV | MIPS_CP0_mAPTIV_uC | 
MIPS_CP0_mAPTIV_uP | MIPS_CP0_MK4},
+       {15, 0, "prid", MIPS_CP0_iAPTIV | MIPS_CP0_mAPTIV_uC | 
MIPS_CP0_mAPTIV_uP | MIPS_CP0_MK4},
+       {15, 1, "ebase", MIPS_CP0_iAPTIV | MIPS_CP0_mAPTIV_uC | 
MIPS_CP0_mAPTIV_uP | MIPS_CP0_MK4},
+       {15, 2, "cdmmbase", MIPS_CP0_iAPTIV | MIPS_CP0_mAPTIV_uC | 
MIPS_CP0_mAPTIV_uP | MIPS_CP0_MK4},
+       {15, 3, "cmgcrbase", MIPS_CP0_iAPTIV},
+       {16, 0, "config", MIPS_CP0_iAPTIV | MIPS_CP0_mAPTIV_uC | 
MIPS_CP0_mAPTIV_uP | MIPS_CP0_MK4},
+       {16, 1, "config1", MIPS_CP0_iAPTIV | MIPS_CP0_mAPTIV_uC | 
MIPS_CP0_mAPTIV_uP | MIPS_CP0_MK4},
+       {16, 2, "config2", MIPS_CP0_iAPTIV | MIPS_CP0_mAPTIV_uC | 
MIPS_CP0_mAPTIV_uP | MIPS_CP0_MK4},
+       {16, 3, "config3", MIPS_CP0_iAPTIV | MIPS_CP0_mAPTIV_uC | 
MIPS_CP0_mAPTIV_uP | MIPS_CP0_MK4},
+       {16, 4, "config4", MIPS_CP0_iAPTIV | MIPS_CP0_mAPTIV_uC | 
MIPS_CP0_mAPTIV_uP | MIPS_CP0_MK4},
+       {16, 5, "config5", MIPS_CP0_iAPTIV | MIPS_CP0_mAPTIV_uC | 
MIPS_CP0_mAPTIV_uP | MIPS_CP0_MK4},
+       {16, 7, "config7", MIPS_CP0_iAPTIV | MIPS_CP0_mAPTIV_uC | 
MIPS_CP0_mAPTIV_uP | MIPS_CP0_MK4},
+       {17, 0, "lladdr", MIPS_CP0_iAPTIV | MIPS_CP0_mAPTIV_uP | MIPS_CP0_MK4},
+       {18, 0, "watchlo0", MIPS_CP0_iAPTIV},
+       {18, 1, "watchlo1", MIPS_CP0_iAPTIV},
+       {18, 2, "watchlo2", MIPS_CP0_iAPTIV},
+       {18, 3, "watchlo3", MIPS_CP0_iAPTIV},
+       {19, 0, "watchhi0", MIPS_CP0_iAPTIV},
+       {19, 1, "watchhi1", MIPS_CP0_iAPTIV},
+       {19, 2, "watchhi2", MIPS_CP0_iAPTIV},
+       {19, 3, "watchhi3", MIPS_CP0_iAPTIV},
+       {23, 0, "debug", MIPS_CP0_iAPTIV | MIPS_CP0_mAPTIV_uC | 
MIPS_CP0_mAPTIV_uP | MIPS_CP0_MK4},
+       {23, 1, "tracecontrol", MIPS_CP0_iAPTIV | MIPS_CP0_mAPTIV_uC | 
MIPS_CP0_mAPTIV_uP | MIPS_CP0_MK4},
+       {23, 2, "tracecontrol2", MIPS_CP0_iAPTIV | MIPS_CP0_mAPTIV_uC | 
MIPS_CP0_mAPTIV_uP | MIPS_CP0_MK4},
+       {23, 3, "usertracedata1", MIPS_CP0_iAPTIV | MIPS_CP0_mAPTIV_uC | 
MIPS_CP0_mAPTIV_uP | MIPS_CP0_MK4},
+       {23, 4, "tracebpc", MIPS_CP0_mAPTIV_uC | MIPS_CP0_mAPTIV_uP | 
MIPS_CP0_MK4},
+       {23, 4, "traceibpc", MIPS_CP0_iAPTIV},
+       {23, 5, "tracedbpc", MIPS_CP0_iAPTIV},
+       {24, 0, "depc", MIPS_CP0_iAPTIV | MIPS_CP0_mAPTIV_uC | 
MIPS_CP0_mAPTIV_uP | MIPS_CP0_MK4},
+       {24, 2, "tracecontrol3", MIPS_CP0_iAPTIV},
+       {24, 3, "usertracedata2", MIPS_CP0_iAPTIV | MIPS_CP0_mAPTIV_uC | 
MIPS_CP0_mAPTIV_uP | MIPS_CP0_MK4},
+       {25, 0, "perfctl0", MIPS_CP0_iAPTIV | MIPS_CP0_mAPTIV_uC | 
MIPS_CP0_mAPTIV_uP | MIPS_CP0_MK4},
+       {25, 1, "perfcnt0", MIPS_CP0_iAPTIV | MIPS_CP0_mAPTIV_uC | 
MIPS_CP0_mAPTIV_uP | MIPS_CP0_MK4},
+       {25, 2, "perfctl1", MIPS_CP0_iAPTIV | MIPS_CP0_mAPTIV_uC | 
MIPS_CP0_mAPTIV_uP | MIPS_CP0_MK4},
+       {25, 3, "perfcnt1", MIPS_CP0_iAPTIV | MIPS_CP0_mAPTIV_uC | 
MIPS_CP0_mAPTIV_uP | MIPS_CP0_MK4},
+       {26, 0, "errctl", MIPS_CP0_iAPTIV | MIPS_CP0_mAPTIV_uC | 
MIPS_CP0_mAPTIV_uP | MIPS_CP0_MK4},
+       {27, 0, "cacheerr", MIPS_CP0_iAPTIV},
+       {28, 0, "itaglo", MIPS_CP0_iAPTIV},
+       {28, 0, "taglo", MIPS_CP0_iAPTIV},
+       {28, 1, "idatalo", MIPS_CP0_iAPTIV},
+       {28, 1, "datalo", MIPS_CP0_iAPTIV},
+       {28, 2, "dtaglo", MIPS_CP0_iAPTIV},
+       {28, 3, "ddatalo", MIPS_CP0_iAPTIV},
+       {28, 4, "l23taglo", MIPS_CP0_iAPTIV},
+       {28, 5, "l23datalo", MIPS_CP0_iAPTIV},
+       {29, 1, "idatahi", MIPS_CP0_iAPTIV},
+       {29, 2, "dtaghi", MIPS_CP0_iAPTIV},
+       {29, 5, "l23datahi", MIPS_CP0_iAPTIV},
+       {30, 0, "errorepc", MIPS_CP0_iAPTIV | MIPS_CP0_mAPTIV_uC | 
MIPS_CP0_mAPTIV_uP | MIPS_CP0_MK4},
+       {31, 0, "desave", MIPS_CP0_iAPTIV | MIPS_CP0_mAPTIV_uC | 
MIPS_CP0_mAPTIV_uP | MIPS_CP0_MK4},
+       {31, 2, "kscratch1", MIPS_CP0_mAPTIV_uC | MIPS_CP0_mAPTIV_uP},
+       {31, 3, "kscratch2", MIPS_CP0_mAPTIV_uC | MIPS_CP0_mAPTIV_uP},
+};
+
+#define MIPS32NUMCP0REGS ((int)ARRAY_SIZE(mips32_cp0_regs))
 
 /* Insert extra NOPs after the DRET instruction on exit from debug. */
 #define        EJTAG_QUIRK_PAD_DRET            BIT(0)
 
 /* offsets into mips32 core register cache */
-enum {
-       MIPS32_PC = 37,
-       MIPS32_FIR = 71,
-       MIPS32NUMCOREREGS
-};
+
+#define MIPS32_REG_GP_COUNT                    34
+#define MIPS32_REG_FP_COUNT                    32
+#define MIPS32_REG_FPC_COUNT                   2
+#define MIPS32_REG_C0_COUNT                    5
+
+#define MIPS32_REGLIST_GP_INDEX                        0
+#define MIPS32_REGLIST_FP_INDEX                        
(MIPS32_REGLIST_GP_INDEX + MIPS32_REG_GP_COUNT)
+#define MIPS32_REGLIST_FPC_INDEX               (MIPS32_REGLIST_FP_INDEX + 
MIPS32_REG_FP_COUNT)
+#define MIPS32_REGLIST_C0_INDEX                        
(MIPS32_REGLIST_FPC_INDEX + MIPS32_REG_FPC_COUNT)
+
+#define MIPS32_REGLIST_C0_STATUS_INDEX         (MIPS32_REGLIST_C0_INDEX + 0)
+#define MIPS32_REGLIST_C0_BADVADDR_INDEX       (MIPS32_REGLIST_C0_INDEX + 1)
+#define MIPS32_REGLIST_C0_CAUSE_INDEX          (MIPS32_REGLIST_C0_INDEX + 2)
+#define MIPS32_REGLIST_C0_PC_INDEX             (MIPS32_REGLIST_C0_INDEX + 3)
+#define MIPS32_REGLIST_C0_GUESTCTL1_INDEX      (MIPS32_REGLIST_C0_INDEX + 4)
+
+#define MIPS32_REG_C0_STATUS_INDEX             0
+#define MIPS32_REG_C0_BADVADDR_INDEX           1
+#define MIPS32_REG_C0_CAUSE_INDEX              2
+#define MIPS32_REG_C0_PC_INDEX                 3
+#define MIPS32_REG_C0_GUESTCTL1_INDEX          4
+
+#define MIPS32NUMDSPREGS 9
 
 enum mips32_isa_mode {
        MIPS32_ISA_MIPS32 = 0,
@@ -80,21 +244,139 @@ enum mips32_isa_imp {
        MIPS32_MMIPS32 = 3,
 };
 
+#define MIPS32_CORE_4K         0x0000
+#define MIPS32_CORE_4KE                0x0100
+#define MIPS32_CORE_4KS                0x0200
+#define MIPS32_CORE_5K         0x0400
+#define MIPS32_CORE_20K                0x0800
+#define MIPS32_CORE_M4K                0x1000
+#define MIPS32_CORE_24K                0x2000
+#define MIPS32_CORE_34K                0x4000
+#define MIPS32_CORE_AU1                0x8000
+#define MIPS32_CORE_24KE       0x10000
+#define MIPS32_CORE_74K                0x20000
+#define MIPS32_CORE_84K                0x40000
+#define MIPS32_CORE_BCM                0x80000
+#define MIPS32_CORE_1004K      0x100000
+#define MIPS32_CORE_1074K      0x200000
+#define MIPS32_CORE_M14K       0x400000
+#define MIPS32_CORE_ALTERA     0x800000
+#define MIPS32_CORE_PROAPTIV   0x1000000
+#define MIPS32_CORE_INTERAPTIV 0x2000000
+#define MIPS32_CORE_5KE                0x4000000
+#define MIPS32_CORE_P5600      0x8000000
+#define MIPS32_CORE_I5500      0x10000000
+
+#define MIPS32_CORE_MASK       0xFFFFFF00
+#define MIPS32_VARIANT_MASK    0x00FF
+
+enum mips32_cpu_type {
+       MIPS32_CPU_UNKNOWN = 0,
+       MIPS32_CPU_4Kc = 0x0001 | MIPS32_CORE_4K,
+       MIPS32_CPU_4Km = 0x0002 | MIPS32_CORE_4K,
+       MIPS32_CPU_4Kp = 0x0004 | MIPS32_CORE_4K,
+       MIPS32_CPU_4KEc = 0x0001 | MIPS32_CORE_4KE,
+       MIPS32_CPU_4KEm = 0x0002 | MIPS32_CORE_4KE,
+       MIPS32_CPU_4KEp = 0x0004 | MIPS32_CORE_4KE,
+       MIPS32_CPU_4KSc = 0x0001 | MIPS32_CORE_4KS,
+       MIPS32_CPU_4KSd = 0x0002 | MIPS32_CORE_4KS,
+       MIPS32_CPU_M4K = 0x0008 | MIPS32_CORE_M4K,
+       MIPS32_CPU_24Kc = 0x0001 | MIPS32_CORE_24K,
+       MIPS32_CPU_24Kf = 0x0010 | MIPS32_CORE_24K,
+       MIPS32_CPU_24KEc = 0x0001 | MIPS32_CORE_24KE,
+       MIPS32_CPU_24KEf = 0x0010 | MIPS32_CORE_24KE,
+       MIPS32_CPU_34Kc = 0x0001 | MIPS32_CORE_34K,
+       MIPS32_CPU_34Kf = 0x0010 | MIPS32_CORE_34K,
+       MIPS32_CPU_5Kc = 0x0001 | MIPS32_CORE_5K,
+       MIPS32_CPU_5Kf = 0x0010 | MIPS32_CORE_5K,
+       MIPS32_CPU_5KEc = 0x0001 | MIPS32_CORE_5KE,
+       MIPS32_CPU_5KEf = 0x0010 | MIPS32_CORE_5KE,
+       MIPS32_CPU_20Kc = 0x0001 | MIPS32_CORE_20K,
+       MIPS32_CPU_25Kf = 0x0010 | MIPS32_CORE_20K,
+       MIPS32_CPU_AU1000 = 0x0001 | MIPS32_CORE_AU1,
+       MIPS32_CPU_AU1100 = 0x0002 | MIPS32_CORE_AU1,
+       MIPS32_CPU_AU1200 = 0x0003 | MIPS32_CORE_AU1,
+       MIPS32_CPU_AU1500 = 0x0004 | MIPS32_CORE_AU1,
+       MIPS32_CPU_AU1550 = 0x0005 | MIPS32_CORE_AU1,
+       MIPS32_CPU_74Kc = 0x0001 | MIPS32_CORE_74K,
+       MIPS32_CPU_74Kf = 0x0010 | MIPS32_CORE_74K,
+       MIPS32_CPU_84Kc = 0x0001 | MIPS32_CORE_84K,
+       MIPS32_CPU_84Kf = 0x0010 | MIPS32_CORE_84K,
+       MIPS32_CPU_BCM = 0x0000 | MIPS32_CORE_BCM,
+       MIPS32_CPU_MP32 = 0x0000 | MIPS32_CORE_ALTERA,
+       MIPS32_CPU_1004Kc = 0x0001 | MIPS32_CORE_1004K,
+       MIPS32_CPU_1004Kf = 0x0010 | MIPS32_CORE_1004K,
+       MIPS32_CPU_1074Kc = 0x0001 | MIPS32_CORE_1074K,
+       MIPS32_CPU_1074Kf = 0x0010 | MIPS32_CORE_1074K,
+       MIPS32_CPU_M14Kc = 0x0001 | MIPS32_CORE_M14K,
+       MIPS32_CPU_M14K = 0x0002 | MIPS32_CORE_M14K,
+       MIPS32_CPU_M14Kf = 0x0010 | MIPS32_CORE_M14K,
+       /* now called microAptiv UC */
+       MIPS32_CPU_M14KE = 0x0020 | MIPS32_CORE_M14K,
+       /* now called microAptiv UCF */
+       MIPS32_CPU_M14KEf = 0x0030 | MIPS32_CORE_M14K,
+       /* now called microAptiv UP */
+       MIPS32_CPU_M14KEc = 0x0040 | MIPS32_CORE_M14K,
+       /* now called microAptiv UPF */
+       MIPS32_CPU_M14KEcf = 0x0050 | MIPS32_CORE_M14K,
+       MIPS32_CPU_M5100 = 0x0090 | MIPS32_CORE_M14K,
+       MIPS32_CPU_M5150 = 0x00B0 | MIPS32_CORE_M14K,
+       MIPS32_CPU_PROAPTIV = 0x0001 | MIPS32_CORE_PROAPTIV,
+       MIPS32_CPU_PROAPTIV_CM = 0x0002 | MIPS32_CORE_PROAPTIV,
+       MIPS32_CPU_INTERAPTIV = 0x0001 | MIPS32_CORE_INTERAPTIV,
+       MIPS32_CPU_INTERAPTIV_CM = 0x0002 | MIPS32_CORE_INTERAPTIV,
+       MIPS32_CPU_P5600 = MIPS32_CORE_P5600,
+       MIPS32_CPU_I5500 = MIPS32_CORE_I5500,
+};
+
+enum mips32_fp_imp {
+       MIPS32_FP_IMP_NONE = 0,
+       MIPS32_FP_IMP_32 = 1,
+       MIPS32_FP_IMP_64 = 2,
+       MIPS32_FP_IMP_UNKNOWN = 3,
+};
+
+enum mips32_dsp_imp {
+       MIPS32_DSP_IMP_NONE = 0,
+       MIPS32_DSP_IMP_REV1 = 1,
+       MIPS32_DSP_IMP_REV2 = 2,
+};
+
 struct mips32_comparator {
        int used;
        uint32_t bp_value;
        uint32_t reg_address;
 };
 
+struct mips32_core_regs {
+       uint32_t gpr[MIPS32_REG_GP_COUNT];
+       uint64_t fpr[MIPS32_REG_FP_COUNT];
+       uint32_t fpcr[MIPS32_REG_FPC_COUNT];
+       uint32_t cp0[MIPS32_REG_C0_COUNT];
+};
+
 struct mips32_common {
        unsigned int common_magic;
 
        void *arch_info;
        struct reg_cache *core_cache;
        struct mips_ejtag ejtag_info;
-       uint32_t core_regs[MIPS32NUMCOREREGS];
+
+       struct mips32_core_regs core_regs;
+
        enum mips32_isa_mode isa_mode;
        enum mips32_isa_imp isa_imp;
+       enum mips32_fp_imp fp_imp;
+       enum mips32_dsp_imp dsp_imp;
+
+       int fdc;
+       int semihosting;
+       uint32_t cp0_mask;
+
+       /* FPU enabled (cp0.status.cu1) */
+       bool fpu_enabled;
+       /* FPU mode (cp0.status.fr) */
+       bool fpu_in_64bit;
 
        /* processor identification register */
        uint32_t prid;
@@ -111,6 +393,7 @@ struct mips32_common {
        int num_data_bpoints_avail;
        struct mips32_comparator *inst_break_list;
        struct mips32_comparator *data_break_list;
+       uint32_t dbs_value;
 
        /* register cache to processor synchronization */
        int (*read_core_reg)(struct target *target, unsigned int num);
@@ -140,14 +423,18 @@ struct mips32_algorithm {
 #define MIPS32_OP_BEQ  0x04u
 #define MIPS32_OP_BGTZ 0x07u
 #define MIPS32_OP_BNE  0x05u
+#define MIPS32_OP_ADD 0x20u
 #define MIPS32_OP_ADDI 0x08u
 #define MIPS32_OP_AND  0x24u
 #define MIPS32_OP_CACHE        0x2Fu
 #define MIPS32_OP_COP0 0x10u
+#define MIPS32_OP_COP1 0x11u
 #define MIPS32_OP_J    0x02u
 #define MIPS32_OP_JR   0x08u
 #define MIPS32_OP_LUI  0x0Fu
 #define MIPS32_OP_LW   0x23u
+#define MIPS32_OP_LWC1 0x31u
+#define MIPS32_OP_LDC1 0x35u
 #define MIPS32_OP_LB   0x20u
 #define MIPS32_OP_LBU  0x24u
 #define MIPS32_OP_LHU  0x25u
@@ -155,6 +442,7 @@ struct mips32_algorithm {
 #define MIPS32_OP_MTHI 0x11u
 #define MIPS32_OP_MFLO 0x12u
 #define MIPS32_OP_MTLO 0x13u
+#define MIPS32_OP_MUL  0x02u
 #define MIPS32_OP_RDHWR        0x3Bu
 #define MIPS32_OP_SB   0x28u
 #define MIPS32_OP_SH   0x29u
@@ -164,10 +452,15 @@ struct mips32_algorithm {
 #define MIPS32_OP_XOR  0x26u
 #define MIPS32_OP_SLTU 0x2Bu
 #define MIPS32_OP_SRL  0x03u
+#define MIPS32_OP_SRA  0x03u
 #define MIPS32_OP_SYNCI        0x1Fu
 #define MIPS32_OP_SLL  0x00u
+#define MIPS32_OP_SLLV 0x04u
 #define MIPS32_OP_SLTI 0x0Au
+#define MIPS32_OP_TLB  0x10u
 #define MIPS32_OP_MOVN 0x0Bu
+#define MIPS32_OP_SWC1 0x39u
+#define MIPS32_OP_SDC1 0x3Du
 
 #define MIPS32_OP_REGIMM       0x01u
 #define MIPS32_OP_SDBBP        0x3Fu
@@ -175,16 +468,22 @@ struct mips32_algorithm {
 #define MIPS32_OP_SPECIAL2     0x07u
 #define MIPS32_OP_SPECIAL3     0x1Fu
 
-#define MIPS32_COP0_MF 0x00u
-#define MIPS32_COP0_MT 0x04u
+#define MIPS32_COP_MF  0x00u
+#define MIPS32_COP_CF  0x02u
+#define MIPS32_COP_MFH 0x03u
+#define MIPS32_COP_MT  0x04u
+#define MIPS32_COP_MTH 0x07u
 
 #define MIPS32_R_INST(opcode, rs, rt, rd, shamt, funct) \
        (((opcode) << 26) | ((rs) << 21) | ((rt) << 16) | ((rd) << 11) | 
((shamt) << 6) | (funct))
 #define MIPS32_I_INST(opcode, rs, rt, immd) \
        (((opcode) << 26) | ((rs) << 21) | ((rt) << 16) | (immd))
 #define MIPS32_J_INST(opcode, addr)    (((opcode) << 26) | (addr))
+#define MIPS32_TLB_INST(opcode, co, rs, rt) \
+       (((opcode) << 26) | ((co) << 25) | ((rs) << 6) | (rt))
 
 #define MIPS32_ISA_NOP                         0
+#define MIPS32_ISA_ADD(dst, src, tar)          
MIPS32_R_INST(MIPS32_OP_SPECIAL, src, tar, dst, 0, MIPS32_OP_ADD)
 #define MIPS32_ISA_ADDI(tar, src, val)         MIPS32_I_INST(MIPS32_OP_ADDI, 
src, tar, val)
 #define MIPS32_ISA_ADDIU(tar, src, val)                
MIPS32_I_INST(MIPS32_OP_ADDIU, src, tar, val)
 #define MIPS32_ISA_ADDU(dst, src, tar)         
MIPS32_R_INST(MIPS32_OP_SPECIAL, src, tar, dst, 0, MIPS32_OP_ADDU)
@@ -196,30 +495,44 @@ struct mips32_algorithm {
 #define MIPS32_ISA_BGTZ(reg, off)              MIPS32_I_INST(MIPS32_OP_BGTZ, 
reg, 0, off)
 #define MIPS32_ISA_BNE(src, tar, off)          MIPS32_I_INST(MIPS32_OP_BNE, 
src, tar, off)
 #define MIPS32_ISA_CACHE(op, off, base)                
MIPS32_I_INST(MIPS32_OP_CACHE, base, op, off)
+#define MIPS32_ISA_CFC1(gpr, cpr)              MIPS32_R_INST(MIPS32_OP_COP1, 
MIPS32_COP_CF, gpr, cpr, 0, 0)
 #define MIPS32_ISA_J(tar)                      MIPS32_J_INST(MIPS32_OP_J, 
(0x0FFFFFFFu & (tar)) >> 2)
 #define MIPS32_ISA_JR(reg)                     MIPS32_R_INST(0, reg, 0, 0, 0, 
MIPS32_OP_JR)
+#define MIPS32_ISA_JRHB(reg)           MIPS32_R_INST(0, reg, 0, 0, 0x10, 
MIPS32_OP_JR)
 
 #define MIPS32_ISA_LB(reg, off, base)          MIPS32_I_INST(MIPS32_OP_LB, 
base, reg, off)
 #define MIPS32_ISA_LBU(reg, off, base)         MIPS32_I_INST(MIPS32_OP_LBU, 
base, reg, off)
 #define MIPS32_ISA_LHU(reg, off, base)         MIPS32_I_INST(MIPS32_OP_LHU, 
base, reg, off)
 #define MIPS32_ISA_LUI(reg, val)               MIPS32_I_INST(MIPS32_OP_LUI, 0, 
reg, val)
 #define MIPS32_ISA_LW(reg, off, base)          MIPS32_I_INST(MIPS32_OP_LW, 
base, reg, off)
-
-#define MIPS32_ISA_MFC0(gpr, cpr, sel)         MIPS32_R_INST(MIPS32_OP_COP0, 
MIPS32_COP0_MF, gpr, cpr, 0, sel)
-#define MIPS32_ISA_MTC0(gpr, cpr, sel)         MIPS32_R_INST(MIPS32_OP_COP0, 
MIPS32_COP0_MT, gpr, cpr, 0, sel)
+#define MIPS32_ISA_LWC1(reg, off, base)                
MIPS32_I_INST(MIPS32_OP_LWC1, base, reg, off)
+#define MIPS32_ISA_LDC1(reg, off, base)                
MIPS32_I_INST(MIPS32_OP_LDC1, base, reg, off)
+
+#define MIPS32_ISA_MFC0(gpr, cpr, sel)         MIPS32_R_INST(MIPS32_OP_COP0, 
MIPS32_COP_MF, gpr, cpr, 0, sel)
+#define MIPS32_ISA_MFC1(gpr, cpr)              MIPS32_R_INST(MIPS32_OP_COP1, 
MIPS32_COP_MF, gpr, cpr, 0, 0)
+#define MIPS32_ISA_MFHC1(gpr, cpr)             MIPS32_R_INST(MIPS32_OP_COP1, 
MIPS32_COP_MFH, gpr, cpr, 0, 0)
+#define MIPS32_ISA_MTC0(gpr, cpr, sel)         MIPS32_R_INST(MIPS32_OP_COP0, 
MIPS32_COP_MT, gpr, cpr, 0, sel)
+#define MIPS32_ISA_MTC1(gpr, cpr)              MIPS32_R_INST(MIPS32_OP_COP1, 
MIPS32_COP_MT, gpr, cpr, 0, 0)
+#define MIPS32_ISA_MTHC1(gpr, cpr)             MIPS32_R_INST(MIPS32_OP_COP1, 
MIPS32_COP_MTH, gpr, cpr, 0, 0)
 #define MIPS32_ISA_MFLO(reg)                   MIPS32_R_INST(0, 0, 0, reg, 0, 
MIPS32_OP_MFLO)
 #define MIPS32_ISA_MFHI(reg)                   MIPS32_R_INST(0, 0, 0, reg, 0, 
MIPS32_OP_MFHI)
 #define MIPS32_ISA_MTLO(reg)                   MIPS32_R_INST(0, reg, 0, 0, 0, 
MIPS32_OP_MTLO)
 #define MIPS32_ISA_MTHI(reg)                   MIPS32_R_INST(0, reg, 0, 0, 0, 
MIPS32_OP_MTHI)
 
+#define MIPS32_ISA_MUL(dst, src, t)            MIPS32_R_INST(28, src, t, dst, 
0, MIPS32_OP_MUL)
+
 #define MIPS32_ISA_MOVN(dst, src, tar)         
MIPS32_R_INST(MIPS32_OP_SPECIAL, src, tar, dst, 0, MIPS32_OP_MOVN)
+#define MIPS32_ISA_OR(dst, src, val)           MIPS32_R_INST(0, src, val, dst, 
0, 37)
 #define MIPS32_ISA_ORI(tar, src, val)          MIPS32_I_INST(MIPS32_OP_ORI, 
src, tar, val)
 #define MIPS32_ISA_RDHWR(tar, dst)             
MIPS32_R_INST(MIPS32_OP_SPECIAL3, 0, tar, dst, 0, MIPS32_OP_RDHWR)
 #define MIPS32_ISA_SB(reg, off, base)          MIPS32_I_INST(MIPS32_OP_SB, 
base, reg, off)
 #define MIPS32_ISA_SH(reg, off, base)          MIPS32_I_INST(MIPS32_OP_SH, 
base, reg, off)
 #define MIPS32_ISA_SW(reg, off, base)          MIPS32_I_INST(MIPS32_OP_SW, 
base, reg, off)
+#define MIPS32_ISA_SWC1(reg, off, base)                
MIPS32_I_INST(MIPS32_OP_SWC1, base, reg, off)
+#define MIPS32_ISA_SDC1(reg, off, base)                
MIPS32_I_INST(MIPS32_OP_SDC1, base, reg, off)
 
 #define MIPS32_ISA_SLL(dst, src, sa)           
MIPS32_R_INST(MIPS32_OP_SPECIAL, 0, src, dst, sa, MIPS32_OP_SLL)
+#define MIPS32_ISA_SLLV(dst, src, sa)          
MIPS32_R_INST(MIPS32_OP_SPECIAL, 0, src, dst, sa, MIPS32_OP_SLLV)
 #define MIPS32_ISA_SLTI(tar, src, val)         MIPS32_I_INST(MIPS32_OP_SLTI, 
src, tar, val)
 #define MIPS32_ISA_SLTU(dst, src, tar)         
MIPS32_R_INST(MIPS32_OP_SPECIAL, src, tar, dst, 0, MIPS32_OP_SLTU)
 #define MIPS32_ISA_SRL(reg, src, off)          MIPS32_R_INST(0, 0, src, reg, 
off, MIPS32_OP_SRL)
@@ -231,6 +544,9 @@ struct mips32_algorithm {
 
 #define MIPS32_ISA_SYNCI_STEP          0x1     /* reg num od address step size 
to be used with synci instruction */
 
+
+#define MIPS32_ISA_TLBR()                                      
MIPS32_TLB_INST(MIPS32_OP_TLB, 1, 0, 1)
+
 /**
  * Cache operations definitions
  * Operation field is 5 bits long :
@@ -247,10 +563,12 @@ struct mips32_algorithm {
 #define MIPS16_ISA_SDBBP                       0xE801u
 
 /*MICRO MIPS INSTRUCTIONS, see doc MD00582 */
-#define POOL32A                                        0X00u
-#define POOL32AXF                              0x3Cu
-#define POOL32B                                        0x08u
-#define POOL32I                                        0x10u
+#define MMIPS32_POOL32A                                        0X00u
+#define MMIPS32_POOL32F                                        0X15u
+#define MMIPS32_POOL32FXF                              0x3Bu
+#define MMIPS32_POOL32AXF                              0x3Cu
+#define MMIPS32_POOL32B                                        0x08u
+#define MMIPS32_POOL32I                                        0x10u
 #define MMIPS32_OP_ADDI                        0x04u
 #define MMIPS32_OP_ADDIU               0x0Cu
 #define MMIPS32_OP_ADDU                        0x150u
@@ -260,15 +578,23 @@ struct mips32_algorithm {
 #define MMIPS32_OP_BGTZ                        0x06u
 #define MMIPS32_OP_BNE                 0x2Du
 #define MMIPS32_OP_CACHE               0x06u
+#define MMIPS32_OP_CFC1                        0x40u
 #define MMIPS32_OP_J                   0x35u
 #define MMIPS32_OP_JALR                        0x03Cu
+#define MMIPS32_OP_JALRHB              0x07Cu
 #define MMIPS32_OP_LB                  0x07u
 #define MMIPS32_OP_LBU                 0x05u
 #define MMIPS32_OP_LHU                 0x0Du
 #define MMIPS32_OP_LUI                 0x0Du
 #define MMIPS32_OP_LW                  0x3Fu
+#define MMIPS32_OP_LWC1                        0x27u
+#define MMIPS32_OP_LDC1                        0x2Fu
 #define MMIPS32_OP_MFC0                        0x03u
+#define MMIPS32_OP_MFC1                        0x80u
+#define MMIPS32_OP_MFHC1               0xC0u
 #define MMIPS32_OP_MTC0                        0x0Bu
+#define MMIPS32_OP_MTC1                        0xA0u
+#define MMIPS32_OP_MTHC1               0xE0u
 #define MMIPS32_OP_MFLO                        0x075u
 #define MMIPS32_OP_MFHI                        0x035u
 #define MMIPS32_OP_MTLO                        0x0F5u
@@ -279,6 +605,8 @@ struct mips32_algorithm {
 #define MMIPS32_OP_SB                  0x06u
 #define MMIPS32_OP_SH                  0x0Eu
 #define MMIPS32_OP_SW                  0x3Eu
+#define MMIPS32_OP_SWC1                        0x26u
+#define MMIPS32_OP_SDC1                        0x2Eu
 #define MMIPS32_OP_SLTU                        0x390u
 #define MMIPS32_OP_SLL                 0x000u
 #define MMIPS32_OP_SLTI                        0x24u
@@ -289,55 +617,66 @@ struct mips32_algorithm {
 
 #define MMIPS32_ADDI(tar, src, val)            MIPS32_I_INST(MMIPS32_OP_ADDI, 
tar, src, val)
 #define MMIPS32_ADDIU(tar, src, val)           MIPS32_I_INST(MMIPS32_OP_ADDIU, 
tar, src, val)
-#define MMIPS32_ADDU(dst, src, tar)            MIPS32_R_INST(POOL32A, tar, 
src, dst, 0, MMIPS32_OP_ADDU)
-#define MMIPS32_AND(dst, src, tar)             MIPS32_R_INST(POOL32A, tar, 
src, dst, 0, MMIPS32_OP_AND)
+#define MMIPS32_ADDU(dst, src, tar)            MIPS32_R_INST(MMIPS32_POOL32A, 
tar, src, dst, 0, MMIPS32_OP_ADDU)
+#define MMIPS32_AND(dst, src, tar)             MIPS32_R_INST(MMIPS32_POOL32A, 
tar, src, dst, 0, MMIPS32_OP_AND)
 #define MMIPS32_ANDI(tar, src, val)            MIPS32_I_INST(MMIPS32_OP_ANDI, 
tar, src, val)
 
 #define MMIPS32_B(off)                         MMIPS32_BEQ(0, 0, off)
 #define MMIPS32_BEQ(src, tar, off)             MIPS32_I_INST(MMIPS32_OP_BEQ, 
tar, src, off)
-#define MMIPS32_BGTZ(reg, off)                 MIPS32_I_INST(POOL32I, 
MMIPS32_OP_BGTZ, reg, off)
+#define MMIPS32_BGTZ(reg, off)                 MIPS32_I_INST(MMIPS32_POOL32I, 
MMIPS32_OP_BGTZ, reg, off)
 #define MMIPS32_BNE(src, tar, off)             MIPS32_I_INST(MMIPS32_OP_BNE, 
tar, src, off)
-#define MMIPS32_CACHE(op, off, base)           MIPS32_R_INST(POOL32B, op, 
base, MMIPS32_OP_CACHE << 1, 0, off)
+#define MMIPS32_CACHE(op, off, base)           MIPS32_R_INST(MMIPS32_POOL32B, 
op, base, MMIPS32_OP_CACHE << 1, 0, off)
+#define MMIPS32_CFC1(gpr, cpr)                 MIPS32_R_INST(MMIPS32_POOL32F, 
gpr, cpr, 0, MMIPS32_OP_CFC1, MMIPS32_POOL32FXF)
 
 #define MMIPS32_J(tar)                         MIPS32_J_INST(MMIPS32_OP_J, 
((0x07FFFFFFu & ((tar) >> 1))))
-#define MMIPS32_JR(reg)                                MIPS32_R_INST(POOL32A, 
0, reg, 0, MMIPS32_OP_JALR, POOL32AXF)
+#define MMIPS32_JR(reg)                                
MIPS32_R_INST(MMIPS32_POOL32A, 0, reg, 0, MMIPS32_OP_JALR, MMIPS32_POOL32AXF)
+#define MMIPS32_JRHB(reg)                      MIPS32_R_INST(MMIPS32_POOL32A, 
0, reg, 0, MMIPS32_OP_JALRHB, MMIPS32_POOL32AXF)
 #define MMIPS32_LB(reg, off, base)             MIPS32_I_INST(MMIPS32_OP_LB, 
reg, base, off)
 #define MMIPS32_LBU(reg, off, base)            MIPS32_I_INST(MMIPS32_OP_LBU, 
reg, base, off)
 #define MMIPS32_LHU(reg, off, base)            MIPS32_I_INST(MMIPS32_OP_LHU, 
reg, base, off)
-#define MMIPS32_LUI(reg, val)                  MIPS32_I_INST(POOL32I, 
MMIPS32_OP_LUI, reg, val)
+#define MMIPS32_LUI(reg, val)                  MIPS32_I_INST(MMIPS32_POOL32I, 
MMIPS32_OP_LUI, reg, val)
 #define MMIPS32_LW(reg, off, base)             MIPS32_I_INST(MMIPS32_OP_LW, 
reg, base, off)
-
-#define MMIPS32_MFC0(gpr, cpr, sel)            MIPS32_R_INST(POOL32A, gpr, 
cpr, sel, MMIPS32_OP_MFC0, POOL32AXF)
-#define MMIPS32_MFLO(reg)                      MIPS32_R_INST(POOL32A, 0, reg, 
0, MMIPS32_OP_MFLO, POOL32AXF)
-#define MMIPS32_MFHI(reg)                      MIPS32_R_INST(POOL32A, 0, reg, 
0, MMIPS32_OP_MFHI, POOL32AXF)
-#define MMIPS32_MTC0(gpr, cpr, sel)            MIPS32_R_INST(POOL32A, gpr, 
cpr, sel, MMIPS32_OP_MTC0, POOL32AXF)
-#define MMIPS32_MTLO(reg)                      MIPS32_R_INST(POOL32A, 0, reg, 
0, MMIPS32_OP_MTLO, POOL32AXF)
-#define MMIPS32_MTHI(reg)                      MIPS32_R_INST(POOL32A, 0, reg, 
0, MMIPS32_OP_MTHI, POOL32AXF)
-
-#define MMIPS32_MOVN(dst, src, tar)            MIPS32_R_INST(POOL32A, tar, 
src, dst, 0, MMIPS32_OP_MOVN)
+#define MMIPS32_LWC1(reg, off, base)           MIPS32_I_INST(MMIPS32_OP_LWC1, 
reg, base, off)
+#define MMIPS32_LDC1(reg, off, base)           MIPS32_I_INST(MMIPS32_OP_LDC1, 
reg, base, off)
+
+#define MMIPS32_MFC0(gpr, cpr, sel)            MIPS32_R_INST(MMIPS32_POOL32A, 
gpr, cpr, sel, MMIPS32_OP_MFC0, MMIPS32_POOL32AXF)
+#define MMIPS32_MFC1(gpr, cpr)                 MIPS32_R_INST(MMIPS32_POOL32F, 
gpr, cpr, 0, MMIPS32_OP_MFC1, MMIPS32_POOL32FXF)
+#define MMIPS32_MFHC1(gpr, cpr)                        
MIPS32_R_INST(MMIPS32_POOL32F, gpr, cpr, 0, MMIPS32_OP_MFHC1, MMIPS32_POOL32FXF)
+#define MMIPS32_MFLO(reg)                      MIPS32_R_INST(MMIPS32_POOL32A, 
0, reg, 0, MMIPS32_OP_MFLO, MMIPS32_POOL32AXF)
+#define MMIPS32_MFHI(reg)                      MIPS32_R_INST(MMIPS32_POOL32A, 
0, reg, 0, MMIPS32_OP_MFHI, MMIPS32_POOL32AXF)
+#define MMIPS32_MTC0(gpr, cpr, sel)            MIPS32_R_INST(MMIPS32_POOL32A, 
gpr, cpr, sel, MMIPS32_OP_MTC0, MMIPS32_POOL32AXF)
+#define MMIPS32_MTC1(gpr, cpr)                 MIPS32_R_INST(MMIPS32_POOL32F, 
gpr, cpr, 0, MMIPS32_OP_MTC1, MMIPS32_POOL32FXF)
+#define MMIPS32_MTHC1(gpr, cpr)                        
MIPS32_R_INST(MMIPS32_POOL32F, gpr, cpr, 0, MMIPS32_OP_MTHC1, MMIPS32_POOL32FXF)
+#define MMIPS32_MTLO(reg)                      MIPS32_R_INST(MMIPS32_POOL32A, 
0, reg, 0, MMIPS32_OP_MTLO, MMIPS32_POOL32AXF)
+#define MMIPS32_MTHI(reg)                      MIPS32_R_INST(MMIPS32_POOL32A, 
0, reg, 0, MMIPS32_OP_MTHI, MMIPS32_POOL32AXF)
+
+#define MMIPS32_MOVN(dst, src, tar)            MIPS32_R_INST(MMIPS32_POOL32A, 
tar, src, dst, 0, MMIPS32_OP_MOVN)
 #define MMIPS32_NOP                            0
 #define MMIPS32_ORI(tar, src, val)             MIPS32_I_INST(MMIPS32_OP_ORI, 
tar, src, val)
-#define MMIPS32_RDHWR(tar, dst)                        MIPS32_R_INST(POOL32A, 
dst, tar, 0, MMIPS32_OP_RDHWR, POOL32AXF)
+#define MMIPS32_RDHWR(tar, dst)                        
MIPS32_R_INST(MMIPS32_POOL32A, dst, tar, 0, MMIPS32_OP_RDHWR, MMIPS32_POOL32AXF)
 #define MMIPS32_SB(reg, off, base)             MIPS32_I_INST(MMIPS32_OP_SB, 
reg, base, off)
 #define MMIPS32_SH(reg, off, base)             MIPS32_I_INST(MMIPS32_OP_SH, 
reg, base, off)
 #define MMIPS32_SW(reg, off, base)             MIPS32_I_INST(MMIPS32_OP_SW, 
reg, base, off)
-
-#define MMIPS32_SRL(reg, src, off)             MIPS32_R_INST(POOL32A, reg, 
src, off, 0, MMIPS32_OP_SRL)
-#define MMIPS32_SLTU(dst, src, tar)            MIPS32_R_INST(POOL32A, tar, 
src, dst, 0, MMIPS32_OP_SLTU)
-#define MMIPS32_SYNCI(off, base)               MIPS32_I_INST(POOL32I, 
MMIPS32_OP_SYNCI, base, off)
-#define MMIPS32_SLL(dst, src, sa)              MIPS32_R_INST(POOL32A, dst, 
src, sa, 0, MMIPS32_OP_SLL)
+#define MMIPS32_SWC1(reg, off, base)           MIPS32_I_INST(MMIPS32_OP_SWC1, 
reg, base, off)
+#define MMIPS32_SDC1(reg, off, base)           MIPS32_I_INST(MMIPS32_OP_SDC1, 
reg, base, off)
+
+#define MMIPS32_SRL(reg, src, off)             MIPS32_R_INST(MMIPS32_POOL32A, 
reg, src, off, 0, MMIPS32_OP_SRL)
+#define MMIPS32_SLTU(dst, src, tar)            MIPS32_R_INST(MMIPS32_POOL32A, 
tar, src, dst, 0, MMIPS32_OP_SLTU)
+#define MMIPS32_SYNCI(off, base)               MIPS32_I_INST(MMIPS32_POOL32I, 
MMIPS32_OP_SYNCI, base, off)
+#define MMIPS32_SLL(dst, src, sa)              MIPS32_R_INST(MMIPS32_POOL32A, 
dst, src, sa, 0, MMIPS32_OP_SLL)
+#define MMIPS32_SLLV(dst, src, sa)             MIPS32_R_INST(MMIPS32_POOL32A, 
dst, src, sa, 0, MMIPS32_OP_SLLV)
 #define MMIPS32_SLTI(tar, src, val)            MIPS32_I_INST(MMIPS32_OP_SLTI, 
tar, src, val)
-#define MMIPS32_SYNC                           0x00001A7Cu /* 
MIPS32_R_INST(POOL32A, 0, 0, 0, 0x1ADu, POOL32AXF) */
+#define MMIPS32_SYNC                           0x00001A7Cu /* 
MIPS32_R_INST(MMIPS32_POOL32A, 0, 0, 0, 0x1ADu, MMIPS32_POOL32AXF) */
 
-#define MMIPS32_XOR(reg, val1, val2)           MIPS32_R_INST(POOL32A, val1, 
val2, reg, 0, MMIPS32_OP_XOR)
+#define MMIPS32_XOR(reg, val1, val2)           MIPS32_R_INST(MMIPS32_POOL32A, 
val1, val2, reg, 0, MMIPS32_OP_XOR)
 #define MMIPS32_XORI(tar, src, val)            MIPS32_I_INST(MMIPS32_OP_XORI, 
tar, src, val)
 
 #define MMIPS32_SYNCI_STEP     0x1u    /* reg num od address step size to be 
used with synci instruction */
 
 
 /* ejtag specific instructions */
-#define MMIPS32_DRET                   0x0000E37Cu     /* 
MIPS32_R_INST(POOL32A, 0, 0, 0, 0x38D, POOL32AXF) */
-#define MMIPS32_SDBBP                  0x0000DB7Cu     /* 
MIPS32_R_INST(POOL32A, 0, 0, 0, 0x1BD, POOL32AXF) */
+#define MMIPS32_DRET                   0x0000E37Cu     /* 
MIPS32_R_INST(MMIPS32_POOL32A, 0, 0, 0, 0x38D, MMIPS32_POOL32AXF) */
+#define MMIPS32_SDBBP                  0x0000DB7Cu     /* 
MIPS32_R_INST(MMIPS32_POOL32A, 0, 0, 0, 0x1BD, MMIPS32_POOL32AXF) */
 #define MMIPS16_SDBBP                  0x46C0u         /* POOL16C instr */
 
 /* instruction code with isa selection */
@@ -353,30 +692,43 @@ struct mips32_algorithm {
 #define MIPS32_BGTZ(isa, reg, off)             (isa ? MMIPS32_BGTZ(reg, off) : 
MIPS32_ISA_BGTZ(reg, off))
 #define MIPS32_BNE(isa, src, tar, off)         (isa ? MMIPS32_BNE(src, tar, 
off) : MIPS32_ISA_BNE(src, tar, off))
 #define MIPS32_CACHE(isa, op, off, base)       (isa ? MMIPS32_CACHE(op, off, 
base) : MIPS32_ISA_CACHE(op, off, base))
+#define MIPS32_CFC1(isa, gpr, cpr)             (isa ? MMIPS32_CFC1(gpr, cpr) : 
MIPS32_ISA_CFC1(gpr, cpr))
 
 #define MIPS32_J(isa, tar)                     (isa ? MMIPS32_J(tar) : 
MIPS32_ISA_J(tar))
 #define MIPS32_JR(isa, reg)                    (isa ? MMIPS32_JR(reg) : 
MIPS32_ISA_JR(reg))
+#define MIPS32_JRHB(isa, reg)          (isa ? MMIPS32_JRHB(reg) : 
MIPS32_ISA_JRHB(reg))
 #define MIPS32_LB(isa, reg, off, base)         (isa ? MMIPS32_LB(reg, off, 
base) : MIPS32_ISA_LB(reg, off, base))
 #define MIPS32_LBU(isa, reg, off, base)                (isa ? MMIPS32_LBU(reg, 
off, base) : MIPS32_ISA_LBU(reg, off, base))
 #define MIPS32_LHU(isa, reg, off, base)                (isa ? MMIPS32_LHU(reg, 
off, base) : MIPS32_ISA_LHU(reg, off, base))
 #define MIPS32_LW(isa, reg, off, base)         (isa ? MMIPS32_LW(reg, off, 
base) : MIPS32_ISA_LW(reg, off, base))
+#define MIPS32_LWC1(isa, reg, off, base)       (isa ? MMIPS32_LWC1(reg, off, 
base) : MIPS32_ISA_LWC1(reg, off, base))
 #define MIPS32_LUI(isa, reg, val)              (isa ? MMIPS32_LUI(reg, val) : 
MIPS32_ISA_LUI(reg, val))
 
 #define MIPS32_MFC0(isa, gpr, cpr, sel)                (isa ? 
MMIPS32_MFC0(gpr, cpr, sel) : MIPS32_ISA_MFC0(gpr, cpr, sel))
 #define MIPS32_MTC0(isa, gpr, cpr, sel)                (isa ? 
MMIPS32_MTC0(gpr, cpr, sel) : MIPS32_ISA_MTC0(gpr, cpr, sel))
+#define MIPS32_MFC1(isa, gpr, cpr)             (isa ? MMIPS32_MFC1(gpr, cpr) : 
MIPS32_ISA_MFC1(gpr, cpr))
+#define MIPS32_MFHC1(isa, gpr, cpr)            (isa ? MMIPS32_MFHC1(gpr, cpr) 
: MIPS32_ISA_MFHC1(gpr, cpr))
+#define MIPS32_MTC1(isa, gpr, cpr)             (isa ? MMIPS32_MTC1(gpr, cpr) : 
MIPS32_ISA_MTC1(gpr, cpr))
+#define MIPS32_MTHC1(isa, gpr, cpr)            (isa ? MMIPS32_MTHC1(gpr, cpr) 
: MIPS32_ISA_MTHC1(gpr, cpr))
 #define MIPS32_MFLO(isa, reg)                  (isa ? MMIPS32_MFLO(reg) : 
MIPS32_ISA_MFLO(reg))
 #define MIPS32_MFHI(isa, reg)                  (isa ? MMIPS32_MFHI(reg) : 
MIPS32_ISA_MFHI(reg))
 #define MIPS32_MTLO(isa, reg)                  (isa ? MMIPS32_MTLO(reg) : 
MIPS32_ISA_MTLO(reg))
 #define MIPS32_MTHI(isa, reg)                  (isa ? MMIPS32_MTHI(reg) : 
MIPS32_ISA_MTHI(reg))
 
+#define MIPS32_MUL(isa, dst, src, t)           (MIPS32_ISA_MUL(dst, src, t))
+
 #define MIPS32_MOVN(isa, dst, src, tar)                (isa ? 
MMIPS32_MOVN(dst, src, tar) : MIPS32_ISA_MOVN(dst, src, tar))
 #define MIPS32_ORI(isa, tar, src, val)         (isa ? MMIPS32_ORI(tar, src, 
val) : MIPS32_ISA_ORI(tar, src, val))
 #define MIPS32_RDHWR(isa, tar, dst)            (isa ? MMIPS32_RDHWR(tar, dst) 
: MIPS32_ISA_RDHWR(tar, dst))
 #define MIPS32_SB(isa, reg, off, base)         (isa ? MMIPS32_SB(reg, off, 
base) : MIPS32_ISA_SB(reg, off, base))
 #define MIPS32_SH(isa, reg, off, base)         (isa ? MMIPS32_SH(reg, off, 
base) : MIPS32_ISA_SH(reg, off, base))
 #define MIPS32_SW(isa, reg, off, base)         (isa ? MMIPS32_SW(reg, off, 
base) : MIPS32_ISA_SW(reg, off, base))
+#define MIPS32_SWC1(isa, reg, off, base)       (isa ? MMIPS32_SWC1(reg, off, 
base) : MIPS32_ISA_SWC1(reg, off, base))
+#define MIPS32_SDC1(isa, reg, off, base)       (isa ? MMIPS32_SDC1(reg, off, 
base) : MIPS32_ISA_SDC1(reg, off, base))
 
 #define MIPS32_SLL(isa, dst, src, sa)          (isa ? MMIPS32_SLL(dst, src, 
sa) : MIPS32_ISA_SLL(dst, src, sa))
+#define MIPS32_EHB(isa)                                (isa ? MMIPS32_SLL(0, 
0, 3) : MIPS32_ISA_SLL(0, 0, 3))
+#define MIPS32_SLLV(isa, dst, src, sa)         (MIPS32_ISA_SLLV(dst, src, sa))
 #define MIPS32_SLTI(isa, tar, src, val)                (isa ? 
MMIPS32_SLTI(tar, src, val) : MIPS32_ISA_SLTI(tar, src, val))
 #define MIPS32_SLTU(isa, dst, src, tar)                (isa ? 
MMIPS32_SLTU(dst, src, tar) : MIPS32_ISA_SLTU(dst, src, tar))
 #define MIPS32_SRL(isa, reg, src, off)         (isa ? MMIPS32_SRL(reg, src, 
off) : MIPS32_ISA_SRL(reg, src, off))
@@ -391,9 +743,266 @@ struct mips32_algorithm {
 /* ejtag specific instructions */
 #define MIPS32_DRET(isa)                       (isa ? MMIPS32_DRET : 
MIPS32_ISA_DRET)
 #define MIPS32_SDBBP(isa)                      (isa ? MMIPS32_SDBBP : 
MIPS32_ISA_SDBBP)
-
 #define MIPS16_SDBBP(isa)                      (isa ? MMIPS16_SDBBP : 
MIPS16_ISA_SDBBP)
 
+/* ejtag specific instructions */
+#define MICRO_MIPS32_SDBBP                     0x000046C0
+#define MICRO_MIPS_SDBBP                       0x46C0
+#define MIPS32_DSP_ENABLE                      0x1000000
+
+#define MIPS32_S_INST(rs, rac, opcode)                 \
+       (((rs) << 21) | ((rac) << 11) | (opcode))
+
+#define MIPS32_DSP_R_INST(rt, immd, opcode, extrw) \
+       ((0x1F << 26) | ((immd) << 16) | ((rt) << 11) | ((opcode) << 6) | 
(extrw))
+#define MIPS32_DSP_W_INST(rs, immd, opcode, extrw) \
+       ((0x1F << 26) | ((rs) << 21) | ((immd) << 11) | ((opcode) << 6) | 
(extrw))
+
+#define MIPS32_DSP_MFHI(reg, ac)               MIPS32_R_INST(0, ac, 0, reg, 0, 
MIPS32_OP_MFHI)
+#define MIPS32_DSP_MFLO(reg, ac)       MIPS32_R_INST(0, ac, 0, reg, 0, 
MIPS32_OP_MFLO)
+#define MIPS32_DSP_MTLO(reg, ac)       MIPS32_S_INST(reg, ac, MIPS32_OP_MTLO)
+#define MIPS32_DSP_MTHI(reg, ac)       MIPS32_S_INST(reg, ac, MIPS32_OP_MTHI)
+#define MIPS32_DSP_RDDSP(rt, mask)     MIPS32_DSP_R_INST(rt, mask, 0x12, 0x38)
+#define MIPS32_DSP_WRDSP(rs, mask)     MIPS32_DSP_W_INST(rs, mask, 0x13, 0x38)
+
+
+/*
+ * MIPS32 Config1 Register (CP0 Register 16, Select 1)
+ */
+#define MIPS32_CFG1_M                  0x80000000              /* Config2 
implemented */
+#define MIPS32_CFG1_MMUSMASK           0x7e000000              /* mmu size - 1 
*/
+#define MIPS32_CFG1_MMUSSHIFT          25
+#define MIPS32_CFG1_ISMASK             0x01c00000              /* icache lines 
64<<n */
+#define MIPS32_CFG1_ISSHIFT            22
+#define MIPS32_CFG1_ILMASK             0x00380000              /* icache line 
size 2<<n */
+#define MIPS32_CFG1_ILSHIFT            19
+#define MIPS32_CFG1_IAMASK             0x00070000              /* icache ways 
- 1 */
+#define MIPS32_CFG1_IASHIFT            16
+#define MIPS32_CFG1_DSMASK             0x0000e000              /* dcache lines 
64<<n */
+#define MIPS32_CFG1_DSSHIFT            13
+#define MIPS32_CFG1_DLMASK             0x00001c00              /* dcache line 
size 2<<n */
+#define MIPS32_CFG1_DLSHIFT            10
+#define MIPS32_CFG1_DAMASK             0x00000380              /* dcache ways 
- 1 */
+#define MIPS32_CFG1_DASHIFT            7
+#define MIPS32_CFG1_C2                 0x00000040              /* Coprocessor 
2 present */
+#define MIPS32_CFG1_MD                 0x00000020              /* MDMX 
implemented */
+#define MIPS32_CFG1_PC                 0x00000010              /* performance 
counters implemented */
+#define MIPS32_CFG1_WR                 0x00000008              /* watch 
registers implemented */
+#define MIPS32_CFG1_CA                 0x00000004              /* compression 
(mips16) implemented */
+#define MIPS32_CFG1_EP                 0x00000002              /* ejtag 
implemented */
+#define MIPS32_CFG1_FP                 0x00000001              /* fpu 
implemented */
+
+
+/*
+ * Cache operations
+ */
+#define Index_Invalidate_I             0x00    /* 0    0 */
+#define Index_Writeback_Inv_D          0x01    /* 0    1 */
+#define Index_Writeback_Inv_T          0x02    /* 0    2 */
+#define Index_Writeback_Inv_S          0x03    /* 0    3 */
+#define Index_Load_Tag_I               0x04    /* 1    0 */
+#define Index_Load_Tag_D               0x05    /* 1    1 */
+#define Index_Load_Tag_T               0x06    /* 1    2 */
+#define Index_Load_Tag_S               0x07    /* 1    3 */
+#define Index_Store_Tag_I              0x08    /* 2    0 */
+#define Index_Store_Tag_D              0x09    /* 2    1 */
+#define Index_Store_Tag_T              0x0A    /* 2    2 */
+#define Index_Store_Tag_S              0x0B    /* 2    3 */
+#define Hit_Invalidate_I               0x10    /* 4    0 */
+#define Hit_Invalidate_D               0x11    /* 4    1 */
+#define Hit_Invalidate_T               0x12    /* 4    2 */
+#define Hit_Invalidate_S               0x13    /* 4    3 */
+#define Fill_I                         0x14    /* 5    0 */
+#define Hit_Writeback_Inv_D            0x15    /* 5    1 */
+#define Hit_Writeback_Inv_T            0x16    /* 5    2 */
+#define Hit_Writeback_Inv_S            0x17    /* 5    3 */
+#define Hit_Writeback_D                        0x19    /* 6    1 */
+#define Hit_Writeback_T                        0x1A    /* 6    1 */
+#define Hit_Writeback_S                        0x1B    /* 6    3 */
+#define Fetch_Lock_I                   0x1C    /* 7    0 */
+#define Fetch_Lock_D                   0x1D    /* 7    1 */
+
+/*
+ * MIPS32 Cache Coherency Attribute
+ *
+ * 0:
+ * - Cacheable, noncoherent, write-through, no write allocate (microAptiv)
+ * - Reserved (interAptiv)
+ *
+ * 1:
+ * - Cacheable, noncoherent, write-through, write allocate (microAptiv)
+ * - Reserved (interAptiv)
+ *
+ * 2:
+ * - Uncached (microAptiv, interAptiv)
+ *
+ * 3:
+ * - Cacheable, noncoherent, write-back, write allocate (microAptiv, 
interAptiv)
+ *
+ * 4:
+ * - Cacheable, coherent, write-back, write-allocate, read misses request 
Exclusive (interAptiv)
+ * - Cacheable, noncoherent, write-back, write allocate (interAptiv)
+ *
+ * 5:
+ * - Cacheable, noncoherent, write-back, write allocate (microAptiv)
+ * - Cacheable, coherent, write-back, write-allocate, read misses request 
Shared (interAptiv)
+ *
+ * 6:
+ * - Cacheable, noncoherent, write-back, write allocate (microAptiv)
+ * - Reserved (interAptiv)
+ *
+ * 7:
+ * - Uncached (microAptiv, interAptiv)
+ */
+#define MIPS32_CCA_WT_NOWA             0
+#define MIPS32_CCA_WT_WA               1
+#define MIPS32_CCA_UC                  2
+#define MIPS32_CCA_WB                  3
+#define MIPS32_CCA_IAPTIV_CWBE         4
+#define MIPS32_CCA_IAPTIV_CWB          5
+#define MIPS32_CCA_IAPTIV_RES          6
+#define MIPS32_CCA_IAPTIV_UCA          7
+
+/*
+ * MIPS32 Coprocessor 0 register numbers
+ */
+#define MIPS32_C0_INDEX                        0
+#define MIPS32_C0_INX                  0
+#define MIPS32_C0_RANDOM               1
+#define MIPS32_C0_RAND                 1
+#define MIPS32_C0_ENTRYLO0             2
+#define MIPS32_C0_TLBLO0               2
+#define MIPS32_C0_ENTRYLO1             3
+#define MIPS32_C0_TLBLO1               3
+#define MIPS32_C0_CONTEXT              4
+#define MIPS32_C0_CTXT                 4
+#define MIPS32_C0_PAGEMASK             5
+#define MIPS32_C0_PAGEGRAIN            (5, 1)
+#define MIPS32_C0_WIRED                        6
+#define MIPS32_C0_HWRENA               7
+#define MIPS32_C0_BADVADDR             8
+#define MIPS32_C0_VADDR                        8
+#define MIPS32_C0_COUNT                        9
+#define MIPS32_C0_ENTRYHI              10
+#define MIPS32_C0_TLBHI                        10
+#define MIPS32_C0_GUESTCTL1            10
+#define MIPS32_C0_COMPARE              11
+#define MIPS32_C0_STATUS               12
+#define MIPS32_C0_SR                   12
+#define MIPS32_C0_INTCTL               (12, 1)
+#define MIPS32_C0_SRSCTL               (12, 2)
+#define MIPS32_C0_SRSMAP               (12, 3)
+#define MIPS32_C0_CAUSE                        13
+#define MIPS32_C0_CR                   13
+#define MIPS32_C0_EPC                  14
+#define MIPS32_C0_PRID                 15
+#define MIPS32_C0_EBASE                        (15, 1)
+#define MIPS32_C0_CONFIG               16
+#define MIPS32_C0_CONFIG0              (16, 0)
+#define MIPS32_C0_CONFIG1              (16, 1)
+#define MIPS32_C0_CONFIG2              (16, 2)
+#define MIPS32_C0_CONFIG3              (16, 3)
+#define MIPS32_C0_LLADDR               17
+#define MIPS32_C0_WATCHLO              18
+#define MIPS32_C0_WATCHHI              19
+#define MIPS32_C0_DEBUG                        23
+#define MIPS32_C0_DEPC                 24
+#define MIPS32_C0_PERFCNT              25
+#define MIPS32_C0_ERRCTL               26
+#define MIPS32_C0_CACHEERR             27
+#define MIPS32_C0_TAGLO                        28
+#define MIPS32_C0_ITAGLO               28
+#define MIPS32_C0_DTAGLO               (28, 2)
+#define MIPS32_C0_TAGLO2               (28, 4)
+#define MIPS32_C0_DATALO               (28, 1)
+#define MIPS32_C0_IDATALO              (28, 1)
+#define MIPS32_C0_DDATALO              (28, 3)
+#define MIPS32_C0_DATALO2              (28, 5)
+#define MIPS32_C0_TAGHI                        29
+#define MIPS32_C0_ITAGHI               29
+#define MIPS32_C0_DATAHI               (29, 1)
+#define MIPS32_C0_ERRPC                        30
+#define MIPS32_C0_DESAVE               31
+
+/*
+ * MIPS32 MMU types
+ */
+#define MIPS32_MMU_TLB                 1
+#define MIPS32_MMU_BAT                 2
+#define MIPS32_MMU_FIXED               3
+#define MIPS32_MMU_DUAL_VTLB_FTLB      4
+
+enum mips32_cpu_vendor {
+       MIPS32_CPU_VENDOR_MTI,
+       MIPS32_CPU_VENDOR_ALCHEMY,
+       MIPS32_CPU_VENDOR_BROADCOM,
+       MIPS32_CPU_VENDOR_ALTERA,
+};
+
+enum mips32_isa_supported {
+       MIPS16,
+       MIPS32,
+       MIPS64,
+       MICROMIPS_ONLY,
+       MIPS32_AT_RESET_AND_MICROMIPS,
+       MICROMIPS_AT_RESET_AND_MIPS32,
+};
+
+struct mips32_cpu_features {
+       /* Type of CPU  (4Kc, 24Kf, etc.) */
+       uint32_t cpu_core;
+
+       /* Internal representation of cpu type */
+       uint32_t cpu_type;
+
+       /* Processor vendor */
+       enum mips32_cpu_vendor vendor;
+
+       /* Supported ISA and boot config */
+       enum mips32_isa_supported isa;
+
+       /* PRID */
+       uint32_t prid;
+
+       /* Processor implemented the MultiThreading ASE */
+       bool mtase;
+
+       /* Processor implemented the DSP ASE */
+       bool dspase;
+
+       /* Processor implemented the SmartMIPS ASE */
+       bool smase;
+
+       /* Processor implemented the MIPS16[e] ASE */
+       bool m16ase;
+
+       /* Processor implemented the microMIPS ASE */
+       bool micromipsase;
+
+       /* Processor implemented the Virtualization ASE */
+       uint32_t vzase;
+
+       uint32_t vz_guest_id_width;
+
+       /* ebase.cpuid number */
+       uint32_t cpuid;
+
+       uint32_t inst_cache_size;
+       uint32_t data_cache_size;
+       uint32_t mmu_type;
+       uint32_t tlb_entries;
+       uint32_t num_shadow_regs;
+
+       /* Processor implemented the MSA module */
+       bool msa;
+
+       /* Processor implemented mfhc0 and mthc0 instructions */
+       bool mvh;
+
+       bool guest_ctl1_present;
+       bool cdmm;
+};
+
 extern const struct command_registration mips32_command_handlers[];
 
 int mips32_arch_state(struct target *target);
diff --git a/src/target/mips_ejtag.c b/src/target/mips_ejtag.c
index 5c92bf9ee3..389461cae6 100644
--- a/src/target/mips_ejtag.c
+++ b/src/target/mips_ejtag.c
@@ -47,7 +47,7 @@ int mips_ejtag_get_idcode(struct mips_ejtag *ejtag_info)
        return mips_ejtag_drscan_32(ejtag_info, &ejtag_info->idcode);
 }
 
-static int mips_ejtag_get_impcode(struct mips_ejtag *ejtag_info)
+int mips_ejtag_get_impcode(struct mips_ejtag *ejtag_info)
 {
        mips_ejtag_set_instr(ejtag_info, EJTAG_INST_IMPCODE);
 
@@ -332,7 +332,7 @@ static void ejtag_v26_print_imp(struct mips_ejtag 
*ejtag_info)
                EJTAG_IMP_HAS(EJTAG_V26_IMP_DINT) ? " DINT" : "");
 }
 
-static void ejtag_main_print_imp(struct mips_ejtag *ejtag_info)
+void ejtag_main_print_imp(struct mips_ejtag *ejtag_info)
 {
        LOG_DEBUG("EJTAG main: features:%s%s%s%s%s",
                EJTAG_IMP_HAS(EJTAG_IMP_ASID8) ? " ASID_8" : "",

-- 


Reply via email to