diff options
Diffstat (limited to 'src/target')
-rw-r--r-- | src/target/mips32.c | 46 | ||||
-rw-r--r-- | src/target/mips32.h | 17 | ||||
-rw-r--r-- | src/target/mips32_pracc.c | 4 | ||||
-rw-r--r-- | src/target/mips_ejtag.c | 19 | ||||
-rw-r--r-- | src/target/mips_ejtag.h | 14 | ||||
-rw-r--r-- | src/target/mips_m4k.c | 68 | ||||
-rw-r--r-- | src/target/mips_m4k.h | 7 |
7 files changed, 107 insertions, 68 deletions
diff --git a/src/target/mips32.c b/src/target/mips32.c index 0f6f9b09..5bb4104e 100644 --- a/src/target/mips32.c +++ b/src/target/mips32.c @@ -38,6 +38,11 @@ char* mips32_core_reg_list[] = "status", "lo", "hi", "badvaddr", "cause", "pc" }; +const char *mips_isa_strings[] = +{ + "MIPS32", "MIPS16e" +}; + struct mips32_core_reg mips32_core_reg_list_arch_info[MIPS32NUMCOREREGS] = { {0, NULL, NULL}, @@ -103,7 +108,7 @@ int mips32_get_core_reg(struct reg *reg) int retval; struct mips32_core_reg *mips32_reg = reg->arch_info; struct target *target = mips32_reg->target; - struct mips32_common *mips32_target = target->arch_info; + struct mips32_common *mips32_target = target_to_mips32(target); if (target->state != TARGET_HALTED) { @@ -139,7 +144,7 @@ int mips32_read_core_reg(struct target *target, int num) struct mips32_core_reg *mips_core_reg; /* get pointers to arch-specific information */ - struct mips32_common *mips32 = target->arch_info; + struct mips32_common *mips32 = target_to_mips32(target); if ((num < 0) || (num >= MIPS32NUMCOREREGS)) return ERROR_INVALID_ARGUMENTS; @@ -159,7 +164,7 @@ int mips32_write_core_reg(struct target *target, int num) struct mips32_core_reg *mips_core_reg; /* get pointers to arch-specific information */ - struct mips32_common *mips32 = target->arch_info; + struct mips32_common *mips32 = target_to_mips32(target); if ((num < 0) || (num >= MIPS32NUMCOREREGS)) return ERROR_INVALID_ARGUMENTS; @@ -177,7 +182,7 @@ int mips32_write_core_reg(struct target *target, int num) int mips32_get_gdb_reg_list(struct target *target, struct reg **reg_list[], int *reg_list_size) { /* get pointers to arch-specific information */ - struct mips32_common *mips32 = target->arch_info; + struct mips32_common *mips32 = target_to_mips32(target); int i; /* include floating point registers */ @@ -203,7 +208,7 @@ int mips32_save_context(struct target *target) int i; /* get pointers to arch-specific information */ - struct mips32_common *mips32 = target->arch_info; + struct mips32_common *mips32 = target_to_mips32(target); struct mips_ejtag *ejtag_info = &mips32->ejtag_info; /* read core registers */ @@ -225,7 +230,7 @@ int mips32_restore_context(struct target *target) int i; /* get pointers to arch-specific information */ - struct mips32_common *mips32 = target->arch_info; + struct mips32_common *mips32 = target_to_mips32(target); struct mips_ejtag *ejtag_info = &mips32->ejtag_info; for (i = 0; i < MIPS32NUMCOREREGS; i++) @@ -244,15 +249,10 @@ int mips32_restore_context(struct target *target) int mips32_arch_state(struct target *target) { - struct mips32_common *mips32 = target->arch_info; - - if (mips32->common_magic != MIPS32_COMMON_MAGIC) - { - LOG_ERROR("BUG: called for a non-MIPS32 target"); - return ERROR_FAIL; - } + struct mips32_common *mips32 = target_to_mips32(target); - LOG_USER("target halted due to %s, pc: 0x%8.8" PRIx32 "", + 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)); @@ -267,7 +267,7 @@ static const struct reg_arch_type mips32_reg_type = { struct reg_cache *mips32_build_reg_cache(struct target *target) { /* get pointers to arch-specific information */ - struct mips32_common *mips32 = target->arch_info; + struct mips32_common *mips32 = target_to_mips32(target); int num_regs = MIPS32NUMCOREREGS; struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache); @@ -327,7 +327,7 @@ int mips32_run_algorithm(struct target *target, int num_mem_params, struct mem_p int mips32_examine(struct target *target) { - struct mips32_common *mips32 = target->arch_info; + struct mips32_common *mips32 = target_to_mips32(target); if (!target_was_examined(target)) { @@ -347,7 +347,7 @@ int mips32_examine(struct target *target) int mips32_configure_break_unit(struct target *target) { /* get pointers to arch-specific information */ - struct mips32_common *mips32 = target->arch_info; + struct mips32_common *mips32 = target_to_mips32(target); int retval; uint32_t dcr, bpinfo; int i; @@ -359,7 +359,7 @@ int mips32_configure_break_unit(struct target *target) if ((retval = target_read_u32(target, EJTAG_DCR, &dcr)) != ERROR_OK) return retval; - if (dcr & (1 << 16)) + if (dcr & EJTAG_DCR_IB) { /* get number of inst breakpoints */ if ((retval = target_read_u32(target, EJTAG_IBS, &bpinfo)) != ERROR_OK) @@ -378,7 +378,7 @@ int mips32_configure_break_unit(struct target *target) return retval; } - if (dcr & (1 << 17)) + if (dcr & EJTAG_DCR_DB) { /* get number of data breakpoints */ if ((retval = target_read_u32(target, EJTAG_DBS, &bpinfo)) != ERROR_OK) @@ -416,19 +416,19 @@ int mips32_enable_interrupts(struct target *target, int enable) if (enable) { - if (!(dcr & (1 << 4))) + if (!(dcr & EJTAG_DCR_INTE)) { /* enable interrupts */ - dcr |= (1 << 4); + dcr |= EJTAG_DCR_INTE; update = 1; } } else { - if (dcr & (1 << 4)) + if (dcr & EJTAG_DCR_INTE) { /* disable interrupts */ - dcr &= ~(1 << 4); + dcr &= ~EJTAG_DCR_INTE; update = 1; } } diff --git a/src/target/mips32.h b/src/target/mips32.h index 4fe61bcd..b731c686 100644 --- a/src/target/mips32.h +++ b/src/target/mips32.h @@ -26,7 +26,6 @@ #include "target.h" #include "mips32_pracc.h" - #define MIPS32_COMMON_MAGIC 0xB320B320 /* offsets into mips32 core register cache */ @@ -36,10 +35,17 @@ enum MIPS32NUMCOREREGS }; +enum mips32_isa_mode +{ + MIPS32_ISA_MIPS32 = 0, + MIPS32_ISA_MIPS16E = 1, +}; + +extern const char *mips_isa_strings[]; + struct mips32_comparator { int used; - //int type; uint32_t bp_value; uint32_t reg_address; }; @@ -51,6 +57,7 @@ struct mips32_common struct reg_cache *core_cache; struct mips_ejtag ejtag_info; uint32_t core_regs[MIPS32NUMCOREREGS]; + enum mips32_isa_mode isa_mode; int bp_scanned; int num_inst_bpoints; @@ -65,6 +72,12 @@ struct mips32_common int (*write_core_reg)(struct target *target, int num); }; +static inline struct mips32_common * +target_to_mips32(struct target *target) +{ + return target->arch_info; +} + struct mips32_core_reg { uint32_t num; diff --git a/src/target/mips32_pracc.c b/src/target/mips32_pracc.c index 52d31bdf..11d5a43a 100644 --- a/src/target/mips32_pracc.c +++ b/src/target/mips32_pracc.c @@ -810,7 +810,7 @@ int mips32_pracc_write_regs(struct mips_ejtag *ejtag_info, uint32_t *regs) MIPS32_LW(2,36*4,1), /* lw $2,36*4($1) */ MIPS32_MTC0(2,13,0), /* move $2 to cause*/ MIPS32_LW(2,37*4,1), /* lw $2,37*4($1) */ - MIPS32_MTC0(2,24,0), /* move $2 to pc */ + MIPS32_MTC0(2,24,0), /* move $2 to depc (pc) */ MIPS32_LW(2,2*4,1), /* lw $2,2*4($1) */ MIPS32_LW(1,0,15), /* lw $1,($15) */ @@ -884,7 +884,7 @@ int mips32_pracc_read_regs(struct mips_ejtag *ejtag_info, uint32_t *regs) MIPS32_SW(2,35*4,1), /* sw $2,35*4($1) */ MIPS32_MFC0(2,13,0), /* move cause to $2 */ MIPS32_SW(2,36*4,1), /* sw $2,36*4($1) */ - MIPS32_MFC0(2,24,0), /* move pc to $2 */ + MIPS32_MFC0(2,24,0), /* move depc (pc) to $2 */ MIPS32_SW(2,37*4,1), /* sw $2,37*4($1) */ MIPS32_LW(2,0,15), /* lw $2,($15) */ diff --git a/src/target/mips_ejtag.c b/src/target/mips_ejtag.c index 58bd392b..336adb50 100644 --- a/src/target/mips_ejtag.c +++ b/src/target/mips_ejtag.c @@ -264,16 +264,15 @@ int mips_ejtag_init(struct mips_ejtag *ejtag_info) break; } LOG_DEBUG("EJTAG: features:%s%s%s%s%s%s%s", - ejtag_info->impcode & (1 << 28) ? " R3k": " R4k", - ejtag_info->impcode & (1 << 24) ? " DINT": "", - ejtag_info->impcode & (1 << 22) ? " ASID_8": "", - ejtag_info->impcode & (1 << 21) ? " ASID_6": "", - ejtag_info->impcode & (1 << 16) ? " MIPS16": "", - ejtag_info->impcode & (1 << 14) ? " noDMA": " DMA", - ejtag_info->impcode & (1 << 0) ? " MIPS64": " MIPS32" -); - - if ((ejtag_info->impcode & (1 << 14)) == 0) + ejtag_info->impcode & EJTAG_IMP_R3K ? " R3k" : " R4k", + ejtag_info->impcode & EJTAG_IMP_DINT ? " DINT" : "", + ejtag_info->impcode & (1 << 22) ? " ASID_8" : "", + ejtag_info->impcode & (1 << 21) ? " ASID_6" : "", + ejtag_info->impcode & EJTAG_IMP_MIPS16 ? " MIPS16" : "", + ejtag_info->impcode & EJTAG_IMP_NODMA ? " noDMA" : " DMA", + ejtag_info->impcode & EJTAG_DCR_MIPS64 ? " MIPS64" : " MIPS32"); + + if ((ejtag_info->impcode & EJTAG_IMP_NODMA) == 0) LOG_DEBUG("EJTAG: DMA Access Mode Support Enabled"); /* set initial state for ejtag control reg */ diff --git a/src/target/mips_ejtag.h b/src/target/mips_ejtag.h index e9da39ec..2f62f2be 100644 --- a/src/target/mips_ejtag.h +++ b/src/target/mips_ejtag.h @@ -40,7 +40,7 @@ #define EJTAG_INST_TCBDATA 0x12 #define EJTAG_INST_BYPASS 0xFF -/* debug control register bits ECR */ +/* ejtag control register bits ECR */ #define EJTAG_CTRL_TOF (1 << 1) #define EJTAG_CTRL_TIF (1 << 2) #define EJTAG_CTRL_BRKST (1 << 3) @@ -87,11 +87,20 @@ #define EJTAG_DEBUG_DBD (1 << 31) /* implementaion register bits */ +#define EJTAG_IMP_R3K (1 << 28) +#define EJTAG_IMP_DINT (1 << 24) #define EJTAG_IMP_NODMA (1 << 14) #define EJTAG_IMP_MIPS16 (1 << 16) +#define EJTAG_DCR_MIPS64 (1 << 0) -/* breakpoint support */ +/* Debug Control Register DCR */ #define EJTAG_DCR 0xFF300000 +#define EJTAG_DCR_ENM (1 << 29) +#define EJTAG_DCR_DB (1 << 17) +#define EJTAG_DCR_IB (1 << 16) +#define EJTAG_DCR_INTE (1 << 4) + +/* breakpoint support */ #define EJTAG_IBS 0xFF301000 #define EJTAG_IBA1 0xFF301100 #define EJTAG_DBS 0xFF302000 @@ -107,7 +116,6 @@ struct mips_ejtag struct jtag_tap *tap; uint32_t impcode; uint32_t idcode; - /*int use_dma;*/ uint32_t ejtag_ctrl; }; diff --git a/src/target/mips_m4k.c b/src/target/mips_m4k.c index f229690b..1a65c50b 100644 --- a/src/target/mips_m4k.c +++ b/src/target/mips_m4k.c @@ -107,12 +107,12 @@ int mips_m4k_examine_debug_reason(struct target *target) } /* get info about data breakpoint support */ - if ((retval = target_read_u32(target, 0xFF302000, &break_status)) != ERROR_OK) + if ((retval = target_read_u32(target, EJTAG_DBS, &break_status)) != ERROR_OK) return retval; if (break_status & 0x1f) { /* we have halted on a breakpoint */ - if ((retval = target_write_u32(target, 0xFF302000, 0)) != ERROR_OK) + if ((retval = target_write_u32(target, EJTAG_DBS, 0)) != ERROR_OK) return retval; target->debug_reason = DBG_REASON_WATCHPOINT; } @@ -123,14 +123,14 @@ int mips_m4k_examine_debug_reason(struct target *target) int mips_m4k_debug_entry(struct target *target) { - struct mips32_common *mips32 = target->arch_info; + struct mips32_common *mips32 = target_to_mips32(target); struct mips_ejtag *ejtag_info = &mips32->ejtag_info; uint32_t debug_reg; /* read debug register */ mips_ejtag_read_debug(ejtag_info, &debug_reg); - /* make sure break uit configured */ + /* make sure break unit configured */ mips32_configure_break_unit(target); /* attempt to find halt reason */ @@ -145,9 +145,21 @@ int mips_m4k_debug_entry(struct target *target) mips32_save_context(target); + /* default to mips32 isa, it will be changed below if required */ + mips32->isa_mode = MIPS32_ISA_MIPS32; + + if (ejtag_info->impcode & EJTAG_IMP_MIPS16) + { + if (buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32) & 0x01) + { + /* core is running mips16e isa */ + mips32->isa_mode = MIPS32_ISA_MIPS16E; + } + } + LOG_DEBUG("entered debug state at PC 0x%" PRIx32 ", target->state: %s", - *(uint32_t*)(mips32->core_cache->reg_list[MIPS32_PC].value), - target_state_name(target)); + buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32), + target_state_name(target)); return ERROR_OK; } @@ -155,7 +167,7 @@ int mips_m4k_debug_entry(struct target *target) int mips_m4k_poll(struct target *target) { int retval; - struct mips32_common *mips32 = target->arch_info; + struct mips32_common *mips32 = target_to_mips32(target); struct mips_ejtag *ejtag_info = &mips32->ejtag_info; uint32_t ejtag_ctrl = ejtag_info->ejtag_ctrl; @@ -215,7 +227,7 @@ int mips_m4k_poll(struct target *target) int mips_m4k_halt(struct target *target) { - struct mips32_common *mips32 = target->arch_info; + struct mips32_common *mips32 = target_to_mips32(target); struct mips_ejtag *ejtag_info = &mips32->ejtag_info; LOG_DEBUG("target->state: %s", @@ -260,7 +272,7 @@ int mips_m4k_halt(struct target *target) int mips_m4k_assert_reset(struct target *target) { - struct mips32_common *mips32 = target->arch_info; + struct mips32_common *mips32 = target_to_mips32(target); struct mips_ejtag *ejtag_info = &mips32->ejtag_info; LOG_DEBUG("target->state: %s", @@ -339,7 +351,7 @@ int mips_m4k_soft_reset_halt(struct target *target) int mips_m4k_single_step_core(struct target *target) { - struct mips32_common *mips32 = target->arch_info; + struct mips32_common *mips32 = target_to_mips32(target); struct mips_ejtag *ejtag_info = &mips32->ejtag_info; /* configure single step mode */ @@ -358,7 +370,7 @@ int mips_m4k_single_step_core(struct target *target) int mips_m4k_resume(struct target *target, int current, uint32_t address, int handle_breakpoints, int debug_execution) { - struct mips32_common *mips32 = target->arch_info; + struct mips32_common *mips32 = target_to_mips32(target); struct mips_ejtag *ejtag_info = &mips32->ejtag_info; struct breakpoint *breakpoint = NULL; uint32_t resume_pc; @@ -430,7 +442,7 @@ int mips_m4k_resume(struct target *target, int current, uint32_t address, int ha int mips_m4k_step(struct target *target, int current, uint32_t address, int handle_breakpoints) { /* get pointers to arch-specific information */ - struct mips32_common *mips32 = target->arch_info; + struct mips32_common *mips32 = target_to_mips32(target); struct mips_ejtag *ejtag_info = &mips32->ejtag_info; struct breakpoint *breakpoint = NULL; @@ -494,7 +506,7 @@ void mips_m4k_enable_breakpoints(struct target *target) int mips_m4k_set_breakpoint(struct target *target, struct breakpoint *breakpoint) { - struct mips32_common *mips32 = target->arch_info; + struct mips32_common *mips32 = target_to_mips32(target); struct mips32_comparator * comparator_list = mips32->inst_break_list; int retval; @@ -585,8 +597,8 @@ int mips_m4k_set_breakpoint(struct target *target, struct breakpoint *breakpoint int mips_m4k_unset_breakpoint(struct target *target, struct breakpoint *breakpoint) { /* get pointers to arch-specific information */ - struct mips32_common *mips32 = target->arch_info; - struct mips32_comparator * comparator_list = mips32->inst_break_list; + struct mips32_common *mips32 = target_to_mips32(target); + struct mips32_comparator *comparator_list = mips32->inst_break_list; int retval; if (!breakpoint->set) @@ -659,7 +671,7 @@ int mips_m4k_unset_breakpoint(struct target *target, struct breakpoint *breakpoi int mips_m4k_add_breakpoint(struct target *target, struct breakpoint *breakpoint) { - struct mips32_common *mips32 = target->arch_info; + struct mips32_common *mips32 = target_to_mips32(target); if (breakpoint->type == BKPT_HARD) { @@ -680,7 +692,7 @@ int mips_m4k_add_breakpoint(struct target *target, struct breakpoint *breakpoint int mips_m4k_remove_breakpoint(struct target *target, struct breakpoint *breakpoint) { /* get pointers to arch-specific information */ - struct mips32_common *mips32 = target->arch_info; + struct mips32_common *mips32 = target_to_mips32(target); if (target->state != TARGET_HALTED) { @@ -701,8 +713,8 @@ int mips_m4k_remove_breakpoint(struct target *target, struct breakpoint *breakpo int mips_m4k_set_watchpoint(struct target *target, struct watchpoint *watchpoint) { - struct mips32_common *mips32 = target->arch_info; - struct mips32_comparator * comparator_list = mips32->data_break_list; + struct mips32_common *mips32 = target_to_mips32(target); + struct mips32_comparator *comparator_list = mips32->data_break_list; int wp_num = 0; /* * watchpoint enabled, ignore all byte lanes in value register @@ -769,8 +781,8 @@ int mips_m4k_set_watchpoint(struct target *target, struct watchpoint *watchpoint int mips_m4k_unset_watchpoint(struct target *target, struct watchpoint *watchpoint) { /* get pointers to arch-specific information */ - struct mips32_common *mips32 = target->arch_info; - struct mips32_comparator * comparator_list = mips32->data_break_list; + struct mips32_common *mips32 = target_to_mips32(target); + struct mips32_comparator *comparator_list = mips32->data_break_list; if (!watchpoint->set) { @@ -794,7 +806,7 @@ int mips_m4k_unset_watchpoint(struct target *target, struct watchpoint *watchpoi int mips_m4k_add_watchpoint(struct target *target, struct watchpoint *watchpoint) { - struct mips32_common *mips32 = target->arch_info; + struct mips32_common *mips32 = target_to_mips32(target); if (mips32->num_data_bpoints_avail < 1) { @@ -811,7 +823,7 @@ int mips_m4k_add_watchpoint(struct target *target, struct watchpoint *watchpoint int mips_m4k_remove_watchpoint(struct target *target, struct watchpoint *watchpoint) { /* get pointers to arch-specific information */ - struct mips32_common *mips32 = target->arch_info; + struct mips32_common *mips32 = target_to_mips32(target); if (target->state != TARGET_HALTED) { @@ -844,7 +856,7 @@ void mips_m4k_enable_watchpoints(struct target *target) int mips_m4k_read_memory(struct target *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer) { - struct mips32_common *mips32 = target->arch_info; + struct mips32_common *mips32 = target_to_mips32(target); struct mips_ejtag *ejtag_info = &mips32->ejtag_info; LOG_DEBUG("address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "", address, size, count); @@ -876,7 +888,7 @@ int mips_m4k_read_memory(struct target *target, uint32_t address, uint32_t size, int mips_m4k_write_memory(struct target *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer) { - struct mips32_common *mips32 = target->arch_info; + struct mips32_common *mips32 = target_to_mips32(target); struct mips_ejtag *ejtag_info = &mips32->ejtag_info; LOG_DEBUG("address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "", address, size, count); @@ -923,7 +935,7 @@ int mips_m4k_init_arch_info(struct target *target, struct mips_m4k_common *mips_ int mips_m4k_target_create(struct target *target, Jim_Interp *interp) { - struct mips_m4k_common *mips_m4k = calloc(1,sizeof(struct mips_m4k_common)); + struct mips_m4k_common *mips_m4k = calloc(1, sizeof(struct mips_m4k_common)); mips_m4k_init_arch_info(target, mips_m4k, target->tap); @@ -933,7 +945,7 @@ int mips_m4k_target_create(struct target *target, Jim_Interp *interp) int mips_m4k_examine(struct target *target) { int retval; - struct mips32_common *mips32 = target->arch_info; + struct mips32_common *mips32 = target_to_mips32(target); struct mips_ejtag *ejtag_info = &mips32->ejtag_info; uint32_t idcode = 0; @@ -963,7 +975,7 @@ int mips_m4k_examine(struct target *target) int mips_m4k_bulk_write_memory(struct target *target, uint32_t address, uint32_t count, uint8_t *buffer) { - struct mips32_common *mips32 = target->arch_info; + struct mips32_common *mips32 = target_to_mips32(target); struct mips_ejtag *ejtag_info = &mips32->ejtag_info; struct working_area *source; int retval; diff --git a/src/target/mips_m4k.h b/src/target/mips_m4k.h index c5f9be2b..4fe14a0d 100644 --- a/src/target/mips_m4k.h +++ b/src/target/mips_m4k.h @@ -35,6 +35,13 @@ struct mips_m4k_common struct mips32_common mips32_common; }; +static inline struct mips_m4k_common * +target_to_m4k(struct target *target) +{ + return container_of(target->arch_info, + struct mips_m4k_common, mips32_common); +} + int mips_m4k_bulk_write_memory(struct target *target, uint32_t address, uint32_t count, uint8_t *buffer); |