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(®_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" : "", --