X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Frtos%2Frtos.c;h=815025704df1168d6880027c185a628f5ea3f01b;hb=ebac7c963a76ba20b4e66b0525d12127295cdccb;hp=129770e80137666044246dfae4faaa5eaeb10b95;hpb=b69119668ed8d9633280f8b596fe9af60f51644b;p=fw%2Fopenocd diff --git a/src/rtos/rtos.c b/src/rtos/rtos.c index 129770e80..815025704 100644 --- a/src/rtos/rtos.c +++ b/src/rtos/rtos.c @@ -29,7 +29,6 @@ #include "server/gdb_server.h" -static long long current_threadid = -1; static void hex_to_str( char* dst, char * hex_src ); static int str_to_hex( char* hex_dst, char* src ); @@ -38,20 +37,30 @@ static int str_to_hex( char* hex_dst, char* src ); /* RTOSs */ extern struct rtos_type FreeRTOS_rtos; extern struct rtos_type ThreadX_rtos; +extern struct rtos_type eCos_rtos; static struct rtos_type *rtos_types[] = { &ThreadX_rtos, &FreeRTOS_rtos, + &eCos_rtos, NULL }; +int rtos_thread_packet(struct connection *connection, char *packet, int packet_size); + +int rtos_smp_init(struct target *target) +{ + if (target->rtos->type->smp_init) + return target->rtos->type->smp_init(target); + return ERROR_TARGET_INIT_FAILED; +} + int rtos_create(Jim_GetOptInfo *goi, struct target * target) { int x; char *cp; - if (! goi->isconfigure) { if (goi->argc != 0) { if (goi->argc != 0) { @@ -111,9 +120,12 @@ int rtos_create(Jim_GetOptInfo *goi, struct target * target) /* Create it */ target->rtos = calloc(1,sizeof(struct rtos)); target->rtos->type = rtos_types[x]; + target->rtos->current_threadid = -1; target->rtos->current_thread = 0; target->rtos->symbols = NULL; target->rtos->target = target; + /* put default thread handler in linux usecase it is overloaded*/ + target->rtos->gdb_thread_packet = rtos_thread_packet; if ( 0 != strcmp( cp, "auto") ) { @@ -123,96 +135,22 @@ int rtos_create(Jim_GetOptInfo *goi, struct target * target) return JIM_OK; } - - - -int gdb_thread_packet(struct connection *connection, struct target *target, char *packet, int packet_size) +int gdb_thread_packet(struct connection *connection, char *packet, int packet_size) { - if (strstr(packet, "qP")) - { - #define TAG_THREADID 1 /* Echo the thread identifier */ - #define TAG_EXISTS 2 /* Is this process defined enough to - fetch registers and its stack */ - #define TAG_DISPLAY 4 /* A short thing maybe to put on a window */ - #define TAG_THREADNAME 8 /* string, maps 1-to-1 with a thread is */ - #define TAG_MOREDISPLAY 16 /* Whatever the kernel wants to say about */ - - // TODO: need to scanf the mode variable (or it with the tags), and the threadid - - unsigned long mode; - threadid_t threadid = 0; - struct thread_detail* detail; - sscanf(packet, "qP%8lx%16" SCNx64, &mode, &threadid); - - - int found = -1; - - if ((target->rtos != NULL) && (target->rtos->thread_details - != NULL)) { - int thread_num; - for (thread_num = 0; thread_num - < target->rtos->thread_count; thread_num++) { - if (target->rtos->thread_details[thread_num].threadid - == threadid) { - if (target->rtos->thread_details[thread_num].exists) { - found = thread_num; - } - } - } - } - if (found == -1) { - gdb_put_packet(connection, "E01", 3); // thread not found - return ERROR_OK; - } - - detail = &target->rtos->thread_details[found]; - - if ( detail->display_str != NULL ) - { - mode &= TAG_DISPLAY; - } - if ( detail->thread_name_str != NULL ) - { - mode &= TAG_THREADNAME; - } - if ( detail->extra_info_str != NULL ) - { - mode &= TAG_MOREDISPLAY; - } - - - mode &= TAG_THREADID | TAG_EXISTS; + struct target *target = get_target_from_connection(connection); + if (target->rtos == NULL) + return rtos_thread_packet(connection, packet, packet_size); /* thread not found*/ + return target->rtos->gdb_thread_packet(connection, packet, packet_size); +} - char thread_str[1000]; - sprintf(thread_str, "%08lx", mode); - sprintf(thread_str, "%016" PRIx64, threadid); - if (mode & TAG_THREADID) { - sprintf(thread_str, "%08" PRIx32 "10%016" PRIx64, TAG_THREADID, threadid); - } - if (mode & TAG_EXISTS) { - sprintf(thread_str, "%08" PRIx32 "08%08" PRIx32, TAG_EXISTS, (detail->exists==true)?1:0); - } - if (mode & TAG_DISPLAY) { - sprintf(thread_str, "%08" PRIx32 "%02x%s", TAG_DISPLAY, (unsigned char)strlen(detail->display_str), detail->display_str ); - } - if (mode & TAG_MOREDISPLAY) { - sprintf(thread_str, "%08" PRIx32 "%02x%s", TAG_MOREDISPLAY, (unsigned char)strlen(detail->extra_info_str), detail->extra_info_str ); - } - if (mode & TAG_THREADNAME) { - sprintf(thread_str, "%08" PRIx32 "%02x%s", TAG_THREADNAME, (unsigned char)strlen(detail->thread_name_str), detail->thread_name_str ); - } - - //gdb_put_packet(connection, tmpstr, sizeof(tmpstr)-1); - gdb_put_packet(connection, thread_str, strlen(thread_str)); +int rtos_thread_packet(struct connection *connection, char *packet, int packet_size) +{ + struct target *target = get_target_from_connection(connection); - // gdb_put_packet(connection, "", 0); - // gdb_put_packet(connection, "OK", 2); // all threads alive - return ERROR_OK; - } - else if (strstr(packet, "qThreadExtraInfo,")) + if (strstr(packet, "qThreadExtraInfo,")) { if ((target->rtos != NULL) && (target->rtos->thread_details != NULL) && (target->rtos->thread_count != 0)) { @@ -278,6 +216,9 @@ int gdb_thread_packet(struct connection *connection, struct target *target, char tmp_str_ptr += sprintf( tmp_str_ptr, " : %s", detail->extra_info_str ); } + assert(strlen(tmp_str) == + (size_t) (tmp_str_ptr - tmp_str)); + char * hex_str = (char*) malloc( strlen(tmp_str)*2 +1 ); str_to_hex( hex_str, tmp_str ); @@ -306,21 +247,20 @@ int gdb_thread_packet(struct connection *connection, struct target *target, char } else { - long long value = 0; + int64_t value = 0; char * hex_name_str = malloc( strlen(packet)); char * name_str; int symbol_num; char* found = strstr( packet, "qSymbol::" ); - int numconv; if (0 == found ) { - numconv =sscanf(packet, "qSymbol:%" SCNx64 ":%s", &value, hex_name_str); + sscanf(packet, "qSymbol:%" SCNx64 ":%s", &value, hex_name_str); } else { // No value returned by GDB - symbol was not found - numconv =sscanf(packet, "qSymbol::%s", hex_name_str); + sscanf(packet, "qSymbol::%s", hex_name_str); } name_str = (char*) malloc( 1+ strlen(hex_name_str) / 2 ); @@ -451,7 +391,17 @@ int gdb_thread_packet(struct connection *connection, struct target *target, char } else if (strstr(packet, "qC")) { - gdb_put_packet(connection, "QC0", 3); + if( target->rtos!=NULL ) + { + char buffer[15]; + int size; + size = snprintf(buffer, 15, "QC%08X", (int)target->rtos->current_thread); + gdb_put_packet(connection, buffer, size); + } + else + { + gdb_put_packet(connection, "QC0", 3); + } return ERROR_OK; } else if ( packet[0] == 'T' ) // Is thread alive? @@ -477,25 +427,28 @@ int gdb_thread_packet(struct connection *connection, struct target *target, char } else { gdb_put_packet(connection, "E01", 3); // thread not found } + return ERROR_OK; } else if ( packet[0] == 'H') // Set current thread ( 'c' for step and continue, 'g' for all other operations ) { - if (packet[1] == 'g') - { - sscanf(packet, "Hg%16" SCNx64, ¤t_threadid); - } + if ((packet[1] == 'g') && (target->rtos != NULL)) + sscanf(packet, "Hg%16" SCNx64, &target->rtos->current_threadid); gdb_put_packet(connection, "OK", 2); + return ERROR_OK; } return GDB_THREAD_PACKET_NOT_CONSUMED; } -int rtos_get_gdb_reg_list(struct connection *connection, struct target *target, struct reg **reg_list[], int *reg_list_size) +int rtos_get_gdb_reg_list(struct connection *connection) { - if ( ( target->rtos != NULL ) && - ( current_threadid != 1 ) && - ( current_threadid != 0 ) && - ( current_threadid != target->rtos->current_thread ) ) + 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; target->rtos->type->get_thread_reg_list( target->rtos, current_threadid, &hex_reg_list ); @@ -512,11 +465,11 @@ int rtos_get_gdb_reg_list(struct connection *connection, struct target *target, -int rtos_generic_stack_read( struct target * target, const struct rtos_register_stacking* stacking, long long stack_ptr, char ** hex_reg_list ) +int rtos_generic_stack_read( struct target * target, const struct rtos_register_stacking* stacking, int64_t stack_ptr, char ** hex_reg_list ) { int list_size = 0; char * tmp_str_ptr; - long long new_stack_ptr; + int64_t new_stack_ptr; int i; int retval; @@ -533,7 +486,7 @@ int rtos_generic_stack_read( struct target * target, const struct rtos_register_ { address -= stacking->stack_registers_size; } - retval = target_read_buffer( target, stack_ptr, stacking->stack_registers_size, stack_data); + retval = target_read_buffer( target, address, stacking->stack_registers_size, stack_data); if ( retval != ERROR_OK ) { LOG_OUTPUT("Error reading stack frame from FreeRTOS thread\r\n"); @@ -553,7 +506,13 @@ int rtos_generic_stack_read( struct target * target, const struct rtos_register_ } *hex_reg_list = (char*)malloc( list_size*2 +1 ); tmp_str_ptr = *hex_reg_list; - new_stack_ptr = stack_ptr + stacking->stack_growth_direction * stacking->stack_registers_size; + new_stack_ptr = stack_ptr - stacking->stack_growth_direction * stacking->stack_registers_size; + if (stacking->stack_alignment != 0) { + /* Align new stack pointer to x byte boundary */ + new_stack_ptr = + (new_stack_ptr & (~((int64_t) stacking->stack_alignment - 1))) + + ((stacking->stack_growth_direction == -1) ? stacking->stack_alignment : 0); + } for( i = 0; i < stacking->num_output_registers; i++ ) { int j;