* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
* *
- * ARMv7-M Architecture, Application Level Reference Manual *
+ * ARMv7-M Architecture, Application Level Reference Manual *
* ARM DDI 0405C (September 2008) *
* *
***************************************************************************/
{
int i;
struct armv7m_common *armv7m = target_to_armv7m(target);
+ struct reg_cache *cache = armv7m->arm.core_cache;
LOG_DEBUG(" ");
armv7m->pre_restore_context(target);
for (i = ARMV7M_NUM_REGS - 1; i >= 0; i--) {
- if (armv7m->arm.core_cache->reg_list[i].dirty)
- armv7m->write_core_reg(target, i);
+ if (cache->reg_list[i].dirty) {
+ uint32_t value = buf_get_u32(cache->reg_list[i].value, 0, 32);
+ armv7m->arm.write_core_reg(target, &cache->reg_list[i], i, ARM_MODE_ANY, value);
+ }
}
return ERROR_OK;
int retval;
struct arm_reg *armv7m_reg = reg->arch_info;
struct target *target = armv7m_reg->target;
- struct armv7m_common *armv7m = target_to_armv7m(target);
+ struct arm *arm = target_to_arm(target);
if (target->state != TARGET_HALTED)
return ERROR_TARGET_NOT_HALTED;
- retval = armv7m->read_core_reg(target, armv7m_reg->num);
+ retval = arm->read_core_reg(target, reg, armv7m_reg->num, arm->core_mode);
return retval;
}
return ERROR_OK;
}
-static int armv7m_read_core_reg(struct target *target, unsigned num)
+static int armv7m_read_core_reg(struct target *target, struct reg *r,
+ int num, enum arm_mode mode)
{
uint32_t reg_value;
int retval;
struct arm_reg *armv7m_core_reg;
struct armv7m_common *armv7m = target_to_armv7m(target);
- if (num >= ARMV7M_NUM_REGS)
- return ERROR_COMMAND_SYNTAX_ERROR;
+ assert(num < (int)armv7m->arm.core_cache->num_regs);
armv7m_core_reg = armv7m->arm.core_cache->reg_list[num].arch_info;
retval = armv7m->load_core_reg_u32(target,
- armv7m_core_reg->num,
- ®_value);
+ armv7m_core_reg->num, ®_value);
+
buf_set_u32(armv7m->arm.core_cache->reg_list[num].value, 0, 32, reg_value);
armv7m->arm.core_cache->reg_list[num].valid = 1;
armv7m->arm.core_cache->reg_list[num].dirty = 0;
return retval;
}
-static int armv7m_write_core_reg(struct target *target, unsigned num)
+static int armv7m_write_core_reg(struct target *target, struct reg *r,
+ int num, enum arm_mode mode, uint32_t value)
{
int retval;
uint32_t reg_value;
struct arm_reg *armv7m_core_reg;
struct armv7m_common *armv7m = target_to_armv7m(target);
- if (num >= ARMV7M_NUM_REGS)
- return ERROR_COMMAND_SYNTAX_ERROR;
+ assert(num < (int)armv7m->arm.core_cache->num_regs);
reg_value = buf_get_u32(armv7m->arm.core_cache->reg_list[num].value, 0, 32);
armv7m_core_reg = armv7m->arm.core_cache->reg_list[num].arch_info;
armv7m->arm.core_cache->reg_list[num].dirty = armv7m->arm.core_cache->reg_list[num].valid;
return ERROR_JTAG_DEVICE_ERROR;
}
+
LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", num, reg_value);
armv7m->arm.core_cache->reg_list[num].valid = 1;
armv7m->arm.core_cache->reg_list[num].dirty = 0;
* if it does not support this arch */
*((char *)armv7m->arm.pc->value) |= 1;
#else
- (*reg_list)[25] = &armv7m->core_cache->reg_list[ARMV7M_xPSR];
+ (*reg_list)[25] = &armv7m->arm.core_cache->reg_list[ARMV7M_xPSR];
#endif
return ERROR_OK;
/* refresh core register cache
* Not needed if core register cache is always consistent with target process state */
for (unsigned i = 0; i < ARMV7M_NUM_REGS; i++) {
- if (!armv7m->arm.core_cache->reg_list[i].valid)
- armv7m->read_core_reg(target, i);
+
armv7m_algorithm_info->context[i] = buf_get_u32(
armv7m->arm.core_cache->reg_list[i].value,
0,
armv7m_set_core_reg(reg, reg_params[i].value);
}
- if (armv7m_algorithm_info->core_mode != ARM_MODE_ANY) {
+ if (armv7m_algorithm_info->core_mode != ARM_MODE_ANY &&
+ armv7m_algorithm_info->core_mode != core_mode) {
+
+ /* we cannot set ARM_MODE_HANDLER, so use ARM_MODE_THREAD instead */
+ if (armv7m_algorithm_info->core_mode == ARM_MODE_HANDLER) {
+ armv7m_algorithm_info->core_mode = ARM_MODE_THREAD;
+ LOG_INFO("ARM_MODE_HANDLER not currently supported, using ARM_MODE_THREAD instead");
+ }
+
LOG_DEBUG("setting core_mode: 0x%2.2x", armv7m_algorithm_info->core_mode);
buf_set_u32(armv7m->arm.core_cache->reg_list[ARMV7M_CONTROL].value,
0, 1, armv7m_algorithm_info->core_mode);
armv7m->arm.core_cache->reg_list[ARMV7M_CONTROL].dirty = 1;
armv7m->arm.core_cache->reg_list[ARMV7M_CONTROL].valid = 1;
}
+
+ /* save previous core mode */
armv7m_algorithm_info->core_mode = core_mode;
retval = target_resume(target, 0, entry_point, 1, 1);
}
}
+ /* restore previous core mode */
+ if (armv7m_algorithm_info->core_mode != armv7m->arm.core_mode) {
+ LOG_DEBUG("restoring core_mode: 0x%2.2x", armv7m_algorithm_info->core_mode);
+ buf_set_u32(armv7m->arm.core_cache->reg_list[ARMV7M_CONTROL].value,
+ 0, 1, armv7m_algorithm_info->core_mode);
+ armv7m->arm.core_cache->reg_list[ARMV7M_CONTROL].dirty = 1;
+ armv7m->arm.core_cache->reg_list[ARMV7M_CONTROL].valid = 1;
+ }
+
armv7m->arm.core_mode = armv7m_algorithm_info->core_mode;
return retval;
arm->arch_info = armv7m;
arm->setup_semihosting = armv7m_setup_semihosting;
- /* FIXME remove v7m-specific r/w core_reg functions;
- * use the generic ARM core support..
- */
- armv7m->read_core_reg = armv7m_read_core_reg;
- armv7m->write_core_reg = armv7m_write_core_reg;
+ arm->read_core_reg = armv7m_read_core_reg;
+ arm->write_core_reg = armv7m_write_core_reg;
return arm_init_arch_info(target, arm);
}
goto cleanup;
armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
- armv7m_info.core_mode = ARM_MODE_ANY;
+ armv7m_info.core_mode = ARM_MODE_THREAD;
init_reg_param(®_params[0], "r0", 32, PARAM_IN_OUT);
init_reg_param(®_params[1], "r1", 32, PARAM_OUT);
return retval;
armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
- armv7m_info.core_mode = ARM_MODE_ANY;
+ armv7m_info.core_mode = ARM_MODE_THREAD;
init_reg_param(®_params[0], "r0", 32, PARAM_OUT);
buf_set_u32(reg_params[0].value, 0, 32, address);