442 lines
13 KiB
Diff
Executable File
442 lines
13 KiB
Diff
Executable File
diff --git a/src/rtos/FreeRTOS.c b/src/rtos/FreeRTOS.c
|
|
--- a/src/rtos/FreeRTOS.c
|
|
+++ b/src/rtos/FreeRTOS.c
|
|
@@ -53,6 +53,22 @@ struct FreeRTOS_params {
|
|
};
|
|
|
|
static const struct FreeRTOS_params FreeRTOS_params_list[] = {
|
|
+#if 1
|
|
+ {
|
|
+ "riscv", /* target_name */
|
|
+ 4, /* thread_count_width; */
|
|
+ 4, /* pointer_width; */
|
|
+ 16, /* list_next_offset; */
|
|
+ 20, /* list_width; */
|
|
+ 8, /* list_elem_next_offset; */
|
|
+ 12, /* list_elem_content_offset */
|
|
+ 0, /* thread_stack_offset; */
|
|
+ 52, /* thread_name_offset; */
|
|
+ &rtos_standard_RiscV32I_stacking, /* stacking_info */
|
|
+ NULL,
|
|
+ NULL,
|
|
+ },
|
|
+#endif
|
|
{
|
|
"cortex_m", /* target_name */
|
|
4, /* thread_count_width; */
|
|
@@ -553,3 +569,118 @@ static int FreeRTOS_create(struct target *target)
|
|
target->rtos->rtos_specific_params = (void *) &FreeRTOS_params_list[i];
|
|
return 0;
|
|
}
|
|
+
|
|
+int FreeRTOS_get_thread_reg(struct rtos *rtos, int64_t thread_id, char **hex_reg_list, int index)
|
|
+{
|
|
+ int retval, i;
|
|
+ const struct FreeRTOS_params *param= (const struct FreeRTOS_params *) rtos->rtos_specific_params;
|
|
+ int64_t stack_ptr = 0;
|
|
+ struct rtos_register_stacking *stack;
|
|
+ *hex_reg_list = NULL;
|
|
+ if (rtos == NULL)
|
|
+ return -1;
|
|
+
|
|
+ if (thread_id == 0)
|
|
+ return -2;
|
|
+
|
|
+ if (rtos->rtos_specific_params == NULL)
|
|
+ return -1;
|
|
+
|
|
+
|
|
+ /* Read the stack pointer */
|
|
+ retval = target_read_buffer(rtos->target,
|
|
+ thread_id + param->thread_stack_offset,
|
|
+ param->pointer_width,
|
|
+ (uint8_t *)&stack_ptr);
|
|
+ if (retval != ERROR_OK) {
|
|
+ LOG_ERROR("Error reading stack frame from FreeRTOS thread");
|
|
+ return retval;
|
|
+ }
|
|
+ LOG_DEBUG("FreeRTOS: Read stack pointer at 0x%" PRIx64 ", value 0x%" PRIx64 "\r\n",
|
|
+ thread_id + param->thread_stack_offset,
|
|
+ stack_ptr);
|
|
+
|
|
+ /* Check for armv7m with *enabled* FPU, i.e. a Cortex-M4F */
|
|
+ int cm4_fpu_enabled = 0;
|
|
+ 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. */
|
|
+ if (cpacr & 0x00F00000) {
|
|
+ /* Found target with enabled FPU */
|
|
+ cm4_fpu_enabled = 1;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (cm4_fpu_enabled == 1) {
|
|
+ /* Read the LR to decide between stacking with or without FPU */
|
|
+ uint32_t LR_svc = 0;
|
|
+ retval = target_read_buffer(rtos->target,
|
|
+ stack_ptr + 0x20,
|
|
+ param->pointer_width,
|
|
+ (uint8_t *)&LR_svc);
|
|
+ if (retval != ERROR_OK) {
|
|
+ LOG_OUTPUT("Error reading stack frame from FreeRTOS thread\r\n");
|
|
+ return retval;
|
|
+ }
|
|
+ if ((LR_svc & 0x10) == 0)
|
|
+ {
|
|
+ stack = (struct rtos_register_stacking*)param->stacking_info_cm4f_fpu;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ stack = (struct rtos_register_stacking*)param->stacking_info_cm4f;
|
|
+ }
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ stack = (struct rtos_register_stacking*)param->stacking_info_cm3;
|
|
+ }
|
|
+
|
|
+ /* Read the stack */
|
|
+ uint8_t *stack_data = malloc(stack->stack_registers_size);
|
|
+ uint32_t address = stack_ptr;
|
|
+
|
|
+ if (stack->stack_growth_direction == 1)
|
|
+ address -= stack->stack_registers_size;
|
|
+ retval = target_read_buffer(rtos->target, address, stack->stack_registers_size, stack_data);
|
|
+ if (retval != ERROR_OK) {
|
|
+ free(stack_data);
|
|
+ LOG_ERROR("Error reading stack frame from thread");
|
|
+ return retval;
|
|
+ }
|
|
+
|
|
+ /* Remap */
|
|
+ if(index >= stack->num_output_registers)
|
|
+ {
|
|
+ if(index == 0x20)
|
|
+ {
|
|
+ index = 0x1;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if(NULL==(*hex_reg_list = malloc(stack->register_offsets[index].width_bits/4 + 1)))
|
|
+ return ERROR_FAIL;
|
|
+
|
|
+ memset(*hex_reg_list, 0x0, stack->register_offsets[index].width_bits/4 + 1);
|
|
+ char *tmp_str_ptr = *hex_reg_list;
|
|
+
|
|
+ for (i= 0; i < stack->register_offsets[index].width_bits/8; i++)
|
|
+ {
|
|
+ tmp_str_ptr += sprintf(tmp_str_ptr, "%02x",
|
|
+ stack_data[stack->register_offsets[index].offset + i]);
|
|
+ }
|
|
+
|
|
+ free(stack_data);
|
|
+ return ERROR_OK;
|
|
+}
|
|
\ No newline at end of file
|
|
diff --git a/src/rtos/ThreadX.c b/src/rtos/ThreadX.c
|
|
--- a/src/rtos/ThreadX.c
|
|
+++ b/src/rtos/ThreadX.c
|
|
@@ -141,6 +141,20 @@ struct ThreadX_params {
|
|
};
|
|
|
|
static const struct ThreadX_params ThreadX_params_list[] = {
|
|
+#if 0
|
|
+ {
|
|
+ "riscv", /* target_name */
|
|
+ 4, /* pointer_width; */
|
|
+ 8, /* thread_stack_offset; */
|
|
+ 40, /* thread_name_offset; */
|
|
+ 48, /* thread_state_offset; */
|
|
+ 136, /* thread_next_offset */
|
|
+ &rtos_standard_RiscV32I_stacking, /* stacking_info */
|
|
+ 1, /* stacking_info_nb */
|
|
+ NULL, /* fn_get_stacking_info */
|
|
+ NULL, /* fn_is_thread_id_valid */
|
|
+ },
|
|
+#endif
|
|
{
|
|
"cortex_m", /* target_name */
|
|
4, /* pointer_width; */
|
|
new mode 100755
|
|
diff --git a/src/rtos/rtos.c b/src/rtos/rtos.c
|
|
--- a/src/rtos/rtos.c
|
|
+++ b/src/rtos/rtos.c
|
|
@@ -436,6 +436,8 @@ int rtos_get_gdb_reg_list(struct connection *connection)
|
|
return ERROR_FAIL;
|
|
}
|
|
|
|
+
|
|
+
|
|
int rtos_generic_stack_read(struct target *target,
|
|
const struct rtos_register_stacking *stacking,
|
|
int64_t stack_ptr,
|
|
@@ -500,6 +502,35 @@ int rtos_generic_stack_read(struct target *target,
|
|
return ERROR_OK;
|
|
}
|
|
|
|
+int rtos_get_gdb_reg(struct connection *connection, int index)
|
|
+{
|
|
+ struct target *target = get_target_from_connection(connection);
|
|
+ int64_t current_threadid = target->rtos->current_threadid;
|
|
+ if ((target->rtos != NULL) && (current_threadid != -1) &&
|
|
+ (current_threadid != 0) &&
|
|
+ ((current_threadid != target->rtos->current_thread) ||
|
|
+ (target->smp))) { /* in smp several current thread are possible */
|
|
+ char *hex_reg_list = NULL;
|
|
+
|
|
+
|
|
+ if(0 == strcmp(target->rtos->type->name, FreeRTOS_rtos.name) )
|
|
+ {
|
|
+ int FreeRTOS_get_thread_reg(struct rtos *rtos, int64_t thread_id, char **hex_reg_list, int index);
|
|
+ if(ERROR_OK!=FreeRTOS_get_thread_reg(target->rtos, current_threadid, &hex_reg_list, index))
|
|
+ {
|
|
+ return ERROR_FAIL;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (hex_reg_list != NULL) {
|
|
+ gdb_put_packet(connection, hex_reg_list, strlen(hex_reg_list));
|
|
+ free(hex_reg_list);
|
|
+ return ERROR_OK;
|
|
+ }
|
|
+ }
|
|
+ return ERROR_FAIL;
|
|
+}
|
|
+
|
|
int rtos_try_next(struct target *target)
|
|
{
|
|
struct rtos *os = target->rtos;
|
|
diff --git a/src/rtos/rtos.h b/src/rtos/rtos.h
|
|
--- a/src/rtos/rtos.h
|
|
+++ b/src/rtos/rtos.h
|
|
@@ -107,5 +107,5 @@ void rtos_free_threadlist(struct rtos *rtos);
|
|
int rtos_smp_init(struct target *target);
|
|
/* function for handling symbol access */
|
|
int rtos_qsymbol(struct connection *connection, char const *packet, int packet_size);
|
|
-
|
|
+int rtos_get_gdb_reg(struct connection *connection, int index);
|
|
#endif /* OPENOCD_RTOS_RTOS_H */
|
|
diff --git a/src/rtos/rtos_standard_stackings.c b/src/rtos/rtos_standard_stackings.c
|
|
--- a/src/rtos/rtos_standard_stackings.c
|
|
+++ b/src/rtos/rtos_standard_stackings.c
|
|
@@ -23,6 +23,43 @@
|
|
#include "rtos.h"
|
|
#include "target/armv7m.h"
|
|
|
|
+#include "log.h"
|
|
+
|
|
+static const struct stack_register_offset rtos_standard_RiscV32I_stack_offsets[] = {
|
|
+ { -1 , 32 }, /* X0 */
|
|
+ { 0x00, 32 }, /* x1 ra */
|
|
+ { 0x04, 32 }, /* x2 sp */
|
|
+ { 0x08, 32 }, /* x3 gp */
|
|
+ { 0x0c, 32 }, /* x4 tp */
|
|
+ { 0x10, 32 }, /* x5 t0 */
|
|
+ { 0x14, 32 }, /* x6 t1 */
|
|
+ { 0x18, 32 }, /* x7 t2 */
|
|
+ { 0x1c, 32 }, /* x8 s0/fp */
|
|
+ { 0x20, 32 }, /* x9 s1 */
|
|
+ { 0x24, 32 }, /* x10 a0 */
|
|
+ { 0x28, 32 }, /* x11 a1 */
|
|
+ { 0x2c, 32 }, /* x12 a2 */
|
|
+ { 0x30, 32 }, /* x13 a3 */
|
|
+ { 0x34, 32 }, /* x14 a4 */
|
|
+ { 0x38, 32 }, /* x15 a5 */
|
|
+ { 0x3c, 32 }, /* x16 a6 */
|
|
+ { 0x40, 32 }, /* x17 a7 */
|
|
+ { 0x44, 32 }, /* x18 s2 */
|
|
+ { 0x48, 32 }, /* x19 s3 */
|
|
+ { 0x4c, 32 }, /* x20 s4 */
|
|
+ { 0x50, 32 }, /* x21 s5 */
|
|
+ { 0x54, 32 }, /* x22 s6 */
|
|
+ { 0x58, 32 }, /* x23 s7 */
|
|
+ { 0x5c, 32 }, /* x24 s8 */
|
|
+ { 0x60, 32 }, /* x25 s9 */
|
|
+ { 0x64, 32 }, /* x26 s10 */
|
|
+ { 0x68, 32 }, /* x27 s11 */
|
|
+ { 0x6c, 32 }, /* x28 t3 */
|
|
+ { 0x70, 32 }, /* x29 t4 */
|
|
+ { 0x74, 32 }, /* x30 t5 */
|
|
+ { 0x78, 32 }, /* x31 t6 */
|
|
+ { 0x80, 32 } /* PC */
|
|
+};
|
|
static const struct stack_register_offset rtos_standard_Cortex_M3_stack_offsets[ARMV7M_NUM_CORE_REGS] = {
|
|
{ 0x20, 32 }, /* r0 */
|
|
{ 0x24, 32 }, /* r1 */
|
|
@@ -225,10 +262,54 @@ static int64_t rtos_standard_Cortex_M3_stack_align(struct target *target,
|
|
int64_t stack_ptr)
|
|
{
|
|
const int XPSR_OFFSET = 0x3c;
|
|
+#if 0
|
|
+ int i, *ptr=(int*)stack_data;
|
|
+ for(i=0; i<17; i++)
|
|
+ {
|
|
+ LOG_INFO("X%02d = 0x%08x.", i, *ptr++);
|
|
+ }
|
|
+#endif
|
|
return rtos_Cortex_M_stack_align(target, stack_data, stacking,
|
|
stack_ptr, XPSR_OFFSET);
|
|
}
|
|
|
|
+int64_t rtos_standard_RiscV32I_stack_align(struct target *target,
|
|
+ const uint8_t *stack_data, const struct rtos_register_stacking *stacking,
|
|
+ int64_t stack_ptr)
|
|
+{
|
|
+ int64_t new_stack_ptr;
|
|
+ int64_t aligned_stack_ptr;
|
|
+#if 0
|
|
+ int i, *ptr=(int*)stack_data;
|
|
+ for(i=1; i<32; i++)
|
|
+ {
|
|
+ LOG_INFO("X%02d = 0x%08x.", i, *ptr++);
|
|
+ }
|
|
+#endif
|
|
+ new_stack_ptr = stack_ptr - stacking->stack_growth_direction *
|
|
+ stacking->stack_registers_size;
|
|
+
|
|
+ aligned_stack_ptr = new_stack_ptr & ~((int64_t)4 - 1);
|
|
+ if (aligned_stack_ptr != new_stack_ptr &&
|
|
+ stacking->stack_growth_direction == -1) {
|
|
+ /* If we have a downward growing stack, the simple alignment code
|
|
+ * above results in a wrong result (since it rounds down to nearest
|
|
+ * alignment). We want to round up so add an extra align.
|
|
+ */
|
|
+ aligned_stack_ptr += (int64_t)4;
|
|
+ }
|
|
+ //LOG_INFO("raw 0x%lx,before 0x%lx, now 0x%lx.", stack_ptr, new_stack_ptr, aligned_stack_ptr);
|
|
+ return aligned_stack_ptr;
|
|
+}
|
|
+
|
|
+const struct rtos_register_stacking rtos_standard_RiscV32I_stacking = {
|
|
+ 0x84, /* stack_registers_size */
|
|
+ -1, /* stack_growth_direction */
|
|
+ 32, /* num_output_registers */
|
|
+ rtos_standard_RiscV32I_stack_align, /* stack_alignment */
|
|
+ rtos_standard_RiscV32I_stack_offsets /* register_offsets */
|
|
+};
|
|
+
|
|
const struct rtos_register_stacking rtos_standard_Cortex_M3_stacking = {
|
|
0x40, /* stack_registers_size */
|
|
-1, /* stack_growth_direction */
|
|
diff --git a/src/rtos/rtos_standard_stackings.h b/src/rtos/rtos_standard_stackings.h
|
|
--- a/src/rtos/rtos_standard_stackings.h
|
|
+++ b/src/rtos/rtos_standard_stackings.h
|
|
@@ -24,7 +24,7 @@
|
|
#endif
|
|
|
|
#include "rtos.h"
|
|
-
|
|
+extern const struct rtos_register_stacking rtos_standard_RiscV32I_stacking;
|
|
extern const struct rtos_register_stacking rtos_standard_Cortex_M3_stacking;
|
|
extern const struct rtos_register_stacking rtos_standard_Cortex_M4F_stacking;
|
|
extern const struct rtos_register_stacking rtos_standard_Cortex_M4F_FPU_stacking;
|
|
diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c
|
|
--- a/src/server/gdb_server.c
|
|
+++ b/src/server/gdb_server.c
|
|
@@ -255,7 +255,7 @@ static int gdb_get_char_inner(struct connection *connection, int *next_char)
|
|
|
|
#ifdef _DEBUG_GDB_IO_
|
|
debug_buffer = strndup(gdb_con->buffer, gdb_con->buf_cnt);
|
|
- LOG_DEBUG("received '%s'", debug_buffer);
|
|
+ LOG_INFO("received '%s'", debug_buffer);
|
|
free(debug_buffer);
|
|
#endif
|
|
|
|
@@ -267,7 +267,7 @@ static int gdb_get_char_inner(struct connection *connection, int *next_char)
|
|
else
|
|
connection->input_pending = 0;
|
|
#ifdef _DEBUG_GDB_IO_
|
|
- LOG_DEBUG("returned char '%c' (0x%2.2x)", *next_char, *next_char);
|
|
+ LOG_INFO("returned char '%c' (0x%2.2x)", *next_char, *next_char);
|
|
#endif
|
|
|
|
return retval;
|
|
@@ -293,7 +293,7 @@ static inline int gdb_get_char_fast(struct connection *connection,
|
|
connection->input_pending = 0;
|
|
|
|
#ifdef _DEBUG_GDB_IO_
|
|
- LOG_DEBUG("returned char '%c' (0x%2.2x)", *next_char, *next_char);
|
|
+ LOG_INFO("returned char '%c' (0x%2.2x)", *next_char, *next_char);
|
|
#endif
|
|
|
|
return ERROR_OK;
|
|
@@ -377,7 +377,7 @@ static int gdb_put_packet_inner(struct connection *connection,
|
|
if (reply == '$') {
|
|
/* fix a problem with some IAR tools */
|
|
gdb_putback_char(connection, reply);
|
|
- LOG_DEBUG("Unexpected start of new packet");
|
|
+ LOG_INFO("Unexpected start of new packet");
|
|
break;
|
|
}
|
|
|
|
@@ -388,7 +388,7 @@ static int gdb_put_packet_inner(struct connection *connection,
|
|
while (1) {
|
|
#ifdef _DEBUG_GDB_IO_
|
|
debug_buffer = strndup(buffer, len);
|
|
- LOG_DEBUG("sending packet '$%s#%2.2x'", debug_buffer, my_checksum);
|
|
+ LOG_INFO("sending packet '$%s#%2.2x'", debug_buffer, my_checksum);
|
|
free(debug_buffer);
|
|
#endif
|
|
|
|
@@ -608,7 +608,7 @@ static int gdb_get_packet_inner(struct connection *connection,
|
|
return retval;
|
|
|
|
#ifdef _DEBUG_GDB_IO_
|
|
- LOG_DEBUG("character: '%c'", character);
|
|
+ LOG_INFO("character: '%c'", character);
|
|
#endif
|
|
|
|
switch (character) {
|
|
@@ -1140,7 +1140,7 @@ static int gdb_get_registers_packet(struct connection *connection,
|
|
int i;
|
|
|
|
#ifdef _DEBUG_GDB_IO_
|
|
- LOG_DEBUG("-");
|
|
+ LOG_INFO("-");
|
|
#endif
|
|
|
|
if ((target->rtos != NULL) && (ERROR_OK == rtos_get_gdb_reg_list(connection)))
|
|
@@ -1180,7 +1180,7 @@ static int gdb_get_registers_packet(struct connection *connection,
|
|
{
|
|
char *reg_packet_p_debug;
|
|
reg_packet_p_debug = strndup(reg_packet, reg_packet_size);
|
|
- LOG_DEBUG("reg_packet: %s", reg_packet_p_debug);
|
|
+ LOG_INFO("reg_packet: %s", reg_packet_p_debug);
|
|
free(reg_packet_p_debug);
|
|
}
|
|
#endif
|
|
@@ -1204,7 +1204,7 @@ static int gdb_set_registers_packet(struct connection *connection,
|
|
char const *packet_p;
|
|
|
|
#ifdef _DEBUG_GDB_IO_
|
|
- LOG_DEBUG("-");
|
|
+ LOG_INFO("-");
|
|
#endif
|
|
|
|
/* skip command character */
|
|
@@ -1265,9 +1265,11 @@ static int gdb_get_register_packet(struct connection *connection,
|
|
int retval;
|
|
|
|
#ifdef _DEBUG_GDB_IO_
|
|
- LOG_DEBUG("-");
|
|
+ LOG_INFO("-");
|
|
#endif
|
|
-
|
|
+ if ((target->rtos != NULL) && (ERROR_OK == rtos_get_gdb_reg(connection, reg_num)))
|
|
+ return ERROR_OK;
|
|
+
|
|
retval = target_get_gdb_reg_list(target, ®_list, ®_list_size,
|
|
REG_CLASS_ALL);
|
|
if (retval != ERROR_OK)
|