X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Frtos%2FChibiOS.c;h=cf590b7fefc27ee162866c2a115a9b2d01113740;hp=be5fe8472d29f0ce339ec9b96efcfa4b4ecc1cf1;hb=9b6de72c2ba149ac6f3e11d6d0dd3030bf7b19f9;hpb=8104b58dbc55c7300b343231cc5bd430063d5721 diff --git a/src/rtos/ChibiOS.c b/src/rtos/ChibiOS.c index be5fe8472d..cf590b7fef 100644 --- a/src/rtos/ChibiOS.c +++ b/src/rtos/ChibiOS.c @@ -29,6 +29,8 @@ #include #include "target/target.h" #include "target/target_type.h" +#include "target/armv7m.h" +#include "target/cortex_m.h" #include "rtos.h" #include "helper/log.h" #include "helper/types.h" @@ -94,12 +96,12 @@ struct ChibiOS_params ChibiOS_params_list[] = { { "cortex_m3", /* target_name */ 0, - &rtos_chibios_arm_v7m_stacking, /* stacking_info */ + NULL, /* stacking_info */ }, { - "stm32_stlink", /* target_name */ + "hla_target", /* target_name */ 0, - &rtos_chibios_arm_v7m_stacking, /* stacking_info */ + NULL, /* stacking_info */ } }; #define CHIBIOS_NUM_PARAMS ((int)(sizeof(ChibiOS_params_list)/sizeof(struct ChibiOS_params))) @@ -189,6 +191,15 @@ static int ChibiOS_update_memory_signature(struct rtos *rtos) "running version %i.%i.%i", GET_CH_KERNEL_MAJOR(ch_version), GET_CH_KERNEL_MINOR(ch_version), GET_CH_KERNEL_PATCH(ch_version)); + /* Currently, we have the inherent assumption that all address pointers + * are 32 bit wide. */ + if (signature->ch_ptrsize != sizeof(uint32_t)) { + LOG_ERROR("ChibiOS/RT target memory signature claims an address" + "width unequal to 32 bits!"); + free(signature); + return -1; + } + param->signature = signature; return 0; @@ -219,8 +230,43 @@ static int ChibiOS_update_stacking(struct rtos *rtos) * available than the current execution. In which case * ChibiOS_get_thread_reg_list is called. */ + int retval; + + if (!rtos->rtos_specific_params) + return -1; + + struct ChibiOS_params *param; + param = (struct ChibiOS_params *) rtos->rtos_specific_params; + + /* Check for armv7m with *enabled* FPU, i.e. a Cortex M4 */ + struct armv7m_common *armv7m_target = target_to_armv7m(rtos->target); + if (is_armv7m(armv7m_target)) { + if (armv7m_target->fp_feature == FPv4_SP) { + /* Found ARM v7m target which includes a FPU */ + uint32_t cpacr; + + retval = target_read_u32(rtos->target, FPU_CPACR, &cpacr); + if (retval != ERROR_OK) { + LOG_ERROR("Could not read CPACR register to check FPU state"); + return -1; + } + + /* Check if CP10 and CP11 are set to full access. + * In ChibiOS this is done in ResetHandler() in crt0.c */ + if (cpacr & 0x00F00000) { + /* Found target with enabled FPU */ + /* FIXME: Need to figure out how to specify the FPU registers */ + LOG_ERROR("ChibiOS ARM v7m targets with enabled FPU " + " are NOT supported"); + return -1; + } + } + + /* Found ARM v7m target with no or disabled FPU */ + param->stacking_info = &rtos_chibios_arm_v7m_stacking; + return 0; + } - /* TODO: Add actual detection, currently it will not work with FPU enabled.*/ return -1; } @@ -269,6 +315,7 @@ static int ChibiOS_update_threads(struct rtos *rtos) * parse the double linked thread list to check for errors and the number of * threads. */ const uint32_t rlist = rtos->symbols[ChibiOS_VAL_rlist].address; + const struct ChibiOS_chdebug *signature = param->signature; uint32_t current; uint32_t previous; uint32_t older; @@ -276,10 +323,8 @@ static int ChibiOS_update_threads(struct rtos *rtos) current = rlist; previous = rlist; while (1) { - retval = target_read_buffer(rtos->target, - current + param->signature->cf_off_newer, - param->signature->ch_ptrsize, - (uint8_t *)¤t); + retval = target_read_u32(rtos->target, + current + signature->cf_off_newer, ¤t); if (retval != ERROR_OK) { LOG_ERROR("Could not read next ChibiOS thread"); return retval; @@ -293,10 +338,8 @@ static int ChibiOS_update_threads(struct rtos *rtos) break; } /* Fetch previous thread in the list as a integrity check. */ - retval = target_read_buffer(rtos->target, - current + param->signature->cf_off_older, - param->signature->ch_ptrsize, - (uint8_t *)&older); + retval = target_read_u32(rtos->target, + current + signature->cf_off_older, &older); if ((retval != ERROR_OK) || (older == 0) || (older != previous)) { LOG_ERROR("ChibiOS registry integrity check failed, " "double linked list violation"); @@ -351,10 +394,8 @@ static int ChibiOS_update_threads(struct rtos *rtos) uint32_t name_ptr = 0; char tmp_str[CHIBIOS_THREAD_NAME_STR_SIZE]; - retval = target_read_buffer(rtos->target, - current + param->signature->cf_off_newer, - param->signature->ch_ptrsize, - (uint8_t *)¤t); + retval = target_read_u32(rtos->target, + current + signature->cf_off_newer, ¤t); if (retval != ERROR_OK) { LOG_ERROR("Could not read next ChibiOS thread"); return -6; @@ -368,10 +409,8 @@ static int ChibiOS_update_threads(struct rtos *rtos) curr_thrd_details->threadid = current; /* read the name pointer */ - retval = target_read_buffer(rtos->target, - current + param->signature->cf_off_name, - param->signature->ch_ptrsize, - (uint8_t *)&name_ptr); + retval = target_read_u32(rtos->target, + current + signature->cf_off_name, &name_ptr); if (retval != ERROR_OK) { LOG_ERROR("Could not read ChibiOS thread name pointer from target"); return retval; @@ -398,9 +437,8 @@ static int ChibiOS_update_threads(struct rtos *rtos) uint8_t threadState; const char *state_desc; - retval = target_read_buffer(rtos->target, - current + param->signature->cf_off_state, - 1, &threadState); + retval = target_read_u8(rtos->target, + current + signature->cf_off_state, &threadState); if (retval != ERROR_OK) { LOG_ERROR("Error reading thread state from ChibiOS target"); return retval; @@ -421,15 +459,17 @@ static int ChibiOS_update_threads(struct rtos *rtos) curr_thrd_details++; } + + uint32_t current_thrd; /* NOTE: By design, cf_off_name equals readylist_current_offset */ - retval = target_read_buffer(rtos->target, - rlist + param->signature->cf_off_name, - param->signature->ch_ptrsize, - (uint8_t *)&rtos->current_thread); + retval = target_read_u32(rtos->target, + rlist + signature->cf_off_name, + ¤t_thrd); if (retval != ERROR_OK) { LOG_ERROR("Could not read current Thread from ChibiOS target"); return retval; } + rtos->current_thread = current_thrd; return 0; } @@ -438,7 +478,7 @@ static int ChibiOS_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, cha { int retval; const struct ChibiOS_params *param; - int64_t stack_ptr = 0; + uint32_t stack_ptr = 0; *hex_reg_list = NULL; if ((rtos == NULL) || (thread_id == 0) || @@ -458,10 +498,8 @@ static int ChibiOS_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, cha } /* Read the stack pointer */ - retval = target_read_buffer(rtos->target, - thread_id + param->signature->cf_off_ctx, - param->signature->ch_ptrsize, - (uint8_t *)&stack_ptr); + retval = target_read_u32(rtos->target, + thread_id + param->signature->cf_off_ctx, &stack_ptr); if (retval != ERROR_OK) { LOG_ERROR("Error reading stack frame from ChibiOS thread"); return retval;