Files
kunlun/tools/openocd/multi_task_debug_for_riscv_openocd.patch
2024-09-28 14:37:24 +08:00

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, &reg_list, &reg_list_size,
REG_CLASS_ALL);
if (retval != ERROR_OK)