X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Ftarget%2Farmv7m.c;h=3d73b295441c44890baeb5ea65e282c0b9a75d7c;hb=2f3ab89a78d217f20233fab0f514b241908c9ce8;hp=7b7893f6415bd5d498537a017ee865df1ceebbe6;hpb=a867e36f78be231bfdf5161ff7172bcf69aa6280;p=openocd.git diff --git a/src/target/armv7m.c b/src/target/armv7m.c index 7b7893f641..3d73b29544 100644 --- a/src/target/armv7m.c +++ b/src/target/armv7m.c @@ -11,6 +11,9 @@ * Copyright (C) 2007,2008 Øyvind Harboe * * oyvind.harboe@zylin.com * * * + * Copyright (C) 2018 by Liviu Ionescu * + * * + * * * 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 * @@ -37,6 +40,7 @@ #include "armv7m.h" #include "algorithm.h" #include "register.h" +#include "semihosting_common.h" #if 0 #define _DEBUG_INSTRUCTION_EXECUTION_ @@ -201,8 +205,8 @@ static int armv7m_set_core_reg(struct reg *reg, uint8_t *buf) return ERROR_TARGET_NOT_HALTED; buf_cpy(buf, reg->value, reg->size); - reg->dirty = 1; - reg->valid = 1; + reg->dirty = true; + reg->valid = true; return ERROR_OK; } @@ -240,8 +244,8 @@ static int armv7m_read_core_reg(struct target *target, struct reg *r, 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; + armv7m->arm.core_cache->reg_list[num].valid = true; + armv7m->arm.core_cache->reg_list[num].dirty = false; return retval; } @@ -279,8 +283,8 @@ static int armv7m_write_core_reg(struct target *target, struct reg *r, goto out_error; } - armv7m->arm.core_cache->reg_list[num].valid = 1; - armv7m->arm.core_cache->reg_list[num].dirty = 0; + armv7m->arm.core_cache->reg_list[num].valid = true; + armv7m->arm.core_cache->reg_list[num].dirty = false; return ERROR_OK; @@ -375,7 +379,8 @@ int armv7m_start_algorithm(struct target *target, } for (int i = 0; i < num_mem_params; i++) { - /* TODO: Write only out params */ + if (mem_params[i].direction == PARAM_IN) + continue; retval = target_write_buffer(target, mem_params[i].address, mem_params[i].size, mem_params[i].value); @@ -384,6 +389,9 @@ int armv7m_start_algorithm(struct target *target, } for (int i = 0; i < num_reg_params; i++) { + if (reg_params[i].direction == PARAM_IN) + continue; + struct reg *reg = register_get_by_name(armv7m->arm.core_cache, reg_params[i].reg_name, 0); /* uint32_t regvalue; */ @@ -403,6 +411,23 @@ int armv7m_start_algorithm(struct target *target, armv7m_set_core_reg(reg, reg_params[i].value); } + { + /* + * Ensure xPSR.T is set to avoid trying to run things in arm + * (non-thumb) mode, which armv7m does not support. + * + * We do this by setting the entirety of xPSR, which should + * remove all the unknowns about xPSR state. + * + * Because xPSR.T is populated on reset from the vector table, + * it might be 0 if the vector table has "bad" data in it. + */ + struct reg *reg = &armv7m->arm.core_cache->reg_list[ARMV7M_xPSR]; + buf_set_u32(reg->value, 0, 32, 0x01000000); + reg->valid = true; + reg->dirty = true; + } + if (armv7m_algorithm_info->core_mode != ARM_MODE_ANY && armv7m_algorithm_info->core_mode != core_mode) { @@ -415,8 +440,8 @@ int armv7m_start_algorithm(struct target *target, 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; + armv7m->arm.core_cache->reg_list[ARMV7M_CONTROL].dirty = true; + armv7m->arm.core_cache->reg_list[ARMV7M_CONTROL].valid = true; } /* save previous core mode */ @@ -510,8 +535,8 @@ int armv7m_wait_algorithm(struct target *target, armv7m_algorithm_info->context[i]); buf_set_u32(armv7m->arm.core_cache->reg_list[i].value, 0, 32, armv7m_algorithm_info->context[i]); - armv7m->arm.core_cache->reg_list[i].valid = 1; - armv7m->arm.core_cache->reg_list[i].dirty = 1; + armv7m->arm.core_cache->reg_list[i].valid = true; + armv7m->arm.core_cache->reg_list[i].dirty = true; } } @@ -520,8 +545,8 @@ int armv7m_wait_algorithm(struct target *target, 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_cache->reg_list[ARMV7M_CONTROL].dirty = true; + armv7m->arm.core_cache->reg_list[ARMV7M_CONTROL].valid = true; } armv7m->arm.core_mode = armv7m_algorithm_info->core_mode; @@ -537,7 +562,7 @@ int armv7m_arch_state(struct target *target) uint32_t ctrl, sp; /* avoid filling log waiting for fileio reply */ - if (arm->semihosting_hit_fileio) + if (target->semihosting && target->semihosting->hit_fileio) return ERROR_OK; ctrl = buf_get_u32(arm->core_cache->reg_list[ARMV7M_CONTROL].value, 0, 32); @@ -552,8 +577,8 @@ int armv7m_arch_state(struct target *target) buf_get_u32(arm->pc->value, 0, 32), (ctrl & 0x02) ? 'p' : 'm', sp, - arm->is_semihosting ? ", semihosting" : "", - arm->is_semihosting_fileio ? " fileio" : ""); + (target->semihosting && target->semihosting->is_active) ? ", semihosting" : "", + (target->semihosting && target->semihosting->is_fileio) ? " fileio" : ""); return ERROR_OK; } @@ -594,8 +619,8 @@ struct reg_cache *armv7m_build_reg_cache(struct target *target) if (storage_size < 4) storage_size = 4; reg_list[i].value = calloc(1, storage_size); - reg_list[i].dirty = 0; - reg_list[i].valid = 0; + reg_list[i].dirty = false; + reg_list[i].valid = false; reg_list[i].type = &armv7m_reg_type; reg_list[i].arch_info = &arch_info[i];