X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Frtos%2FChibiOS.c;h=7d1f5cf852eb579bc9ff9cad6394e5360470b83a;hb=c4ab127b4069e20e296081bdf1007d4a5979e348;hp=2c2b7953334406bd8473fc0f096af1568c1566db;hpb=14e12c3969fef1a4649de1db0b0fac47e5295708;p=fw%2Fopenocd diff --git a/src/rtos/ChibiOS.c b/src/rtos/ChibiOS.c index 2c2b79533..7d1f5cf85 100644 --- a/src/rtos/ChibiOS.c +++ b/src/rtos/ChibiOS.c @@ -29,8 +29,11 @@ #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" #include "rtos_chibios_stackings.h" @@ -93,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 */ 0, - &rtos_chibios_arm_v7m_stacking, /* stacking_info */ + NULL, /* stacking_info */ } }; #define CHIBIOS_NUM_PARAMS ((int)(sizeof(ChibiOS_params_list)/sizeof(struct ChibiOS_params))) @@ -132,8 +135,6 @@ static char *ChibiOS_symbol_list[] = { NULL }; -#define CHIBIOS_NUM_SYMBOLS (sizeof(ChibiOS_symbol_list)/sizeof(char *)) - static int ChibiOS_update_memory_signature(struct rtos *rtos) { int retval; @@ -190,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; @@ -220,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,26 +314,17 @@ static int ChibiOS_update_threads(struct rtos *rtos) /* ChibiOS does not save the current thread count. We have to first * parse the double linked thread list to check for errors and the number of * threads. */ - uint32_t rlist; + 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; - retval = target_read_buffer(rtos->target, - rtos->symbols[ChibiOS_VAL_rlist].address, - param->signature->ch_ptrsize, - (uint8_t *)&rlist); - if (retval != ERROR_OK) { - LOG_ERROR("Could not read ChibiOS ReadyList from target"); - return retval; - } 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; @@ -302,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"); @@ -360,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; @@ -377,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; @@ -407,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; @@ -430,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, + current + 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; } @@ -447,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) || @@ -467,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; @@ -483,9 +512,9 @@ static int ChibiOS_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[]) { unsigned int i; *symbol_list = (symbol_table_elem_t *) malloc( - sizeof(symbol_table_elem_t) * CHIBIOS_NUM_SYMBOLS); + sizeof(symbol_table_elem_t) * ARRAY_SIZE(ChibiOS_symbol_list)); - for (i = 0; i < CHIBIOS_NUM_SYMBOLS; i++) + for (i = 0; i < ARRAY_SIZE(ChibiOS_symbol_list); i++) (*symbol_list)[i].symbol_name = ChibiOS_symbol_list[i]; return 0;