#include <jtag/jtag.h>
#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"
{
"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)))
"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;
* 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;
}
* 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;
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;
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");
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;
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;
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;
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;
}
{
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) ||
}
/* 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;