X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Ftarget%2Fmips_m4k.c;h=5f5aa72ee3ee39e4b9d0b79865c2e63764edfd0c;hp=a83217ff957498c016aad30b13315d250c86f929;hb=ff5deeeeaa4f394931e3c5ccfb4cfd33beda0743;hpb=66ee303456910f684244a20a0ac2e958d40b78cb diff --git a/src/target/mips_m4k.c b/src/target/mips_m4k.c index a83217ff95..5f5aa72ee3 100644 --- a/src/target/mips_m4k.c +++ b/src/target/mips_m4k.c @@ -4,6 +4,8 @@ * * * Copyright (C) 2008 by David T.L. Wong * * * + * Copyright (C) 2009 by David N. Claffey * + * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * @@ -30,7 +32,6 @@ #include "target_type.h" #include "register.h" - /* cli handling */ /* forward declarations */ @@ -106,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; } @@ -122,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 */ @@ -144,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; } @@ -154,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; @@ -214,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", @@ -259,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", @@ -338,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 */ @@ -357,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; @@ -429,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; @@ -493,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; @@ -584,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) @@ -658,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) { @@ -679,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) { @@ -700,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 @@ -768,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) { @@ -793,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) { @@ -810,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) { @@ -843,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); @@ -875,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); @@ -922,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); @@ -932,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; @@ -962,7 +975,55 @@ 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) { - return mips_m4k_write_memory(target, address, 4, count, buffer); + struct mips32_common *mips32 = target_to_mips32(target); + struct mips_ejtag *ejtag_info = &mips32->ejtag_info; + struct working_area *source; + int retval; + int write = 1; + + LOG_DEBUG("address: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "", address, count); + + if (target->state != TARGET_HALTED) + { + LOG_WARNING("target not halted"); + return ERROR_TARGET_NOT_HALTED; + } + + /* check alignment */ + if (address & 0x3u) + return ERROR_TARGET_UNALIGNED_ACCESS; + + /* Get memory for block write handler */ + retval = target_alloc_working_area(target, MIPS32_FASTDATA_HANDLER_SIZE, &source); + if (retval != ERROR_OK) + { + LOG_WARNING("No working area available, falling back to non-bulk write"); + return mips_m4k_write_memory(target, address, 4, count, buffer); + } + + /* TAP data register is loaded LSB first (little endian) */ + if (target->endianness == TARGET_BIG_ENDIAN) + { + uint32_t i, t32; + for(i = 0; i < (count * 4); i += 4) + { + t32 = be_to_h_u32((uint8_t *) &buffer[i]); + h_u32_to_le(&buffer[i], t32); + } + } + + retval = mips32_pracc_fastdata_xfer(ejtag_info, source, write, address, count, (uint32_t*) buffer); + if (retval != ERROR_OK) + { + /* FASTDATA access failed, try normal memory write */ + LOG_DEBUG("Fastdata access Failed, falling back to non-bulk write"); + retval = mips_m4k_write_memory(target, address, 4, count, buffer); + } + + if (source) + target_free_working_area(target, source); + + return retval; } int mips_m4k_checksum_memory(struct target *target, uint32_t address, uint32_t size, uint32_t *checksum)