rtos : compilation error on amd64
[openocd.git] / src / rtos / ThreadX.c
1 /***************************************************************************
2 * Copyright (C) 2011 by Broadcom Corporation *
3 * Evan Hunter - ehunter@broadcom.com *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include <helper/time_support.h>
26 #include <jtag/jtag.h>
27 #include "target/target.h"
28 #include "target/target_type.h"
29 #include "rtos.h"
30 #include "helper/log.h"
31 #include "rtos_standard_stackings.h"
32
33
34 static int ThreadX_detect_rtos( struct target* target );
35 static int ThreadX_create( struct target* target );
36 static int ThreadX_update_threads( struct rtos* rtos);
37 static int ThreadX_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, char ** hex_reg_list );
38 static int ThreadX_get_symbol_list_to_lookup(symbol_table_elem_t * symbol_list[]);
39
40
41
42 struct ThreadX_thread_state
43 {
44 int value;
45 char * desc;
46 };
47
48
49 struct ThreadX_thread_state ThreadX_thread_states[] =
50 {
51 { 0, "Ready" },
52 { 1, "Completed" },
53 { 2, "Terminated" },
54 { 3, "Suspended" },
55 { 4, "Sleeping" },
56 { 5, "Waiting - Queue" },
57 { 6, "Waiting - Semaphore" },
58 { 7, "Waiting - Event flag" },
59 { 8, "Waiting - Memory" },
60 { 9, "Waiting - Memory" },
61 { 10, "Waiting - I/O" },
62 { 11, "Waiting - Filesystem" },
63 { 12, "Waiting - Network" },
64 { 13, "Waiting - Mutex" },
65 };
66
67
68 #define THREADX_NUM_STATES (sizeof(ThreadX_thread_states)/sizeof(struct ThreadX_thread_state))
69
70
71 struct ThreadX_params
72 {
73 char * target_name;
74 unsigned char pointer_width;
75 unsigned char thread_stack_offset;
76 unsigned char thread_name_offset;
77 unsigned char thread_state_offset;
78 unsigned char thread_next_offset;
79 const struct rtos_register_stacking* stacking_info;
80 };
81
82 const struct ThreadX_params ThreadX_params_list[] =
83 {
84 { "cortex_m3", // target_name
85 4, // pointer_width;
86 8, // thread_stack_offset;
87 40, // thread_name_offset;
88 48, // thread_state_offset;
89 136, // thread_next_offset
90 &rtos_standard_Cortex_M3_stacking, // stacking_info
91 }
92
93 };
94
95 #define THREADX_NUM_PARAMS ((int)(sizeof(ThreadX_params_list)/sizeof(struct ThreadX_params)))
96
97 enum ThreadX_symbol_values
98 {
99 ThreadX_VAL_tx_thread_current_ptr = 0,
100 ThreadX_VAL_tx_thread_created_ptr = 1,
101 ThreadX_VAL_tx_thread_created_count = 2,
102 };
103
104 static char* ThreadX_symbol_list[] =
105 {
106 "_tx_thread_current_ptr",
107 "_tx_thread_created_ptr",
108 "_tx_thread_created_count",
109 NULL
110 };
111
112
113
114 #define THREADX_NUM_SYMBOLS (sizeof(ThreadX_symbol_list)/sizeof(char*))
115
116
117 const struct rtos_type ThreadX_rtos =
118 {
119 .name = "ThreadX",
120
121 .detect_rtos = ThreadX_detect_rtos,
122 .create = ThreadX_create,
123 .update_threads = ThreadX_update_threads,
124 .get_thread_reg_list = ThreadX_get_thread_reg_list,
125 .get_symbol_list_to_lookup = ThreadX_get_symbol_list_to_lookup,
126
127 };
128
129 static int ThreadX_update_threads( struct rtos* rtos)
130 {
131 int retval;
132 int tasks_found = 0;
133 int thread_list_size = 0;
134 const struct ThreadX_params* param;
135
136 if ( rtos == NULL )
137 {
138 return -1;
139 }
140
141 if (rtos->rtos_specific_params == NULL )
142 {
143 return -3;
144 }
145
146 param = (const struct ThreadX_params*) rtos->rtos_specific_params;
147
148 if ( rtos->symbols == NULL )
149 {
150 LOG_OUTPUT("No symbols for ThreadX\r\n");
151 return -4;
152 }
153
154 if ( rtos->symbols[ThreadX_VAL_tx_thread_created_count].address == 0 )
155 {
156 LOG_OUTPUT("Don't have the number of threads in ThreadX \r\n");
157 return -2;
158 }
159
160
161
162
163
164 // read the number of threads
165 retval = target_read_buffer( rtos->target, rtos->symbols[ThreadX_VAL_tx_thread_created_count].address, 4, (uint8_t *)&thread_list_size);
166
167 if ( retval != ERROR_OK )
168 {
169 LOG_OUTPUT("Could not read ThreadX thread count from target\r\n");
170 return retval;
171 }
172
173
174 // wipe out previous thread details if any
175 if ( rtos->thread_details != NULL )
176 {
177 int j;
178 for( j = 0; j < rtos->thread_count; j++ )
179 {
180 if ( rtos->thread_details[j].display_str != NULL )
181 {
182 free( rtos->thread_details[j].display_str );
183 rtos->thread_details[j].display_str = NULL;
184 }
185 if ( rtos->thread_details[j].thread_name_str != NULL )
186 {
187 free( rtos->thread_details[j].thread_name_str );
188 rtos->thread_details[j].thread_name_str = NULL;
189 }
190 if ( rtos->thread_details[j].extra_info_str != NULL )
191 {
192 free( rtos->thread_details[j].extra_info_str );
193 rtos->thread_details[j].extra_info_str = NULL;
194 }
195 }
196 free( rtos->thread_details );
197 rtos->thread_details = NULL;
198 }
199
200
201 // read the current thread id
202 retval = target_read_buffer( rtos->target, rtos->symbols[ThreadX_VAL_tx_thread_current_ptr].address, 4, (uint8_t *)&rtos->current_thread);
203
204 if ( retval != ERROR_OK )
205 {
206 LOG_OUTPUT("Could not read ThreadX current thread from target\r\n");
207 return retval;
208 }
209
210 if ( ( thread_list_size == 0 ) || ( rtos->current_thread == 0 ) )
211 {
212 // Either : No RTOS threads - there is always at least the current execution though
213 // OR : No current thread - all threads suspended - show the current execution of idling
214 char tmp_str[] = "Current Execution";
215 thread_list_size++;
216 tasks_found++;
217 rtos->thread_details = (struct thread_detail*) malloc( sizeof( struct thread_detail ) * thread_list_size );
218 rtos->thread_details->threadid = 1;
219 rtos->thread_details->exists = true;
220 rtos->thread_details->display_str = NULL;
221 rtos->thread_details->extra_info_str = NULL;
222 rtos->thread_details->thread_name_str = (char*) malloc( sizeof(tmp_str) );
223 strcpy( rtos->thread_details->thread_name_str, tmp_str );
224
225
226 if ( thread_list_size == 0 )
227 {
228 rtos->thread_count = 1;
229 return ERROR_OK;
230 }
231 }
232 else
233 {
234 // create space for new thread details
235 rtos->thread_details = (struct thread_detail*) malloc( sizeof( struct thread_detail ) * thread_list_size );
236 }
237
238
239
240 // Read the pointer to the first thread
241 int64_t thread_ptr = 0;
242 retval = target_read_buffer( rtos->target, rtos->symbols[ThreadX_VAL_tx_thread_created_ptr].address, param->pointer_width, (uint8_t *)&thread_ptr);
243 if ( retval != ERROR_OK )
244 {
245 LOG_OUTPUT("Could not read ThreadX thread location from target\r\n");
246 return retval;
247 }
248
249
250 // loop over all threads
251 int64_t prev_thread_ptr = 0;
252 while ( ( thread_ptr != prev_thread_ptr ) && ( tasks_found < thread_list_size ) )
253 {
254
255 #define THREADX_THREAD_NAME_STR_SIZE (200)
256 char tmp_str[THREADX_THREAD_NAME_STR_SIZE];
257 unsigned int i = 0;
258 int64_t name_ptr = 0;
259
260 // Save the thread pointer
261 rtos->thread_details[tasks_found].threadid = thread_ptr;
262
263
264 // read the name pointer
265 retval = target_read_buffer( rtos->target, thread_ptr + param->thread_name_offset, param->pointer_width, (uint8_t *)&name_ptr);
266 if ( retval != ERROR_OK )
267 {
268 LOG_OUTPUT("Could not read ThreadX thread name pointer from target\r\n");
269 return retval;
270 }
271
272 // Read the thread name
273 retval = target_read_buffer( rtos->target, name_ptr, THREADX_THREAD_NAME_STR_SIZE, (uint8_t *)&tmp_str);
274 if ( retval != ERROR_OK )
275 {
276 LOG_OUTPUT("Error reading thread name from ThreadX target\r\n");
277 return retval;
278 }
279 tmp_str[THREADX_THREAD_NAME_STR_SIZE-1] = '\x00';
280
281 if ( tmp_str[0] == '\x00' )
282 {
283 strcpy(tmp_str,"No Name");
284 }
285
286
287 rtos->thread_details[tasks_found].thread_name_str = (char*)malloc( strlen(tmp_str)+1 );
288 strcpy( rtos->thread_details[tasks_found].thread_name_str, tmp_str );
289
290
291
292 // Read the thread status
293 int64_t thread_status = 0;
294 retval = target_read_buffer( rtos->target, thread_ptr + param->thread_state_offset, 4, (uint8_t *)&thread_status);
295 if ( retval != ERROR_OK )
296 {
297 LOG_OUTPUT("Error reading thread state from ThreadX target\r\n");
298 return retval;
299 }
300
301 for( i = 0; (i < THREADX_NUM_STATES) && (ThreadX_thread_states[i].value!=thread_status); i++ )
302 {
303 }
304
305
306 char * state_desc;
307 if (i < THREADX_NUM_STATES)
308 {
309 state_desc = ThreadX_thread_states[i].desc;
310 }
311 else
312 {
313 state_desc = "Unknown state";
314 }
315
316 rtos->thread_details[tasks_found].extra_info_str = (char*)malloc( strlen(state_desc)+1 );
317 strcpy( rtos->thread_details[tasks_found].extra_info_str, state_desc );
318
319 rtos->thread_details[tasks_found].exists = true;
320
321 rtos->thread_details[tasks_found].display_str = NULL;
322
323
324
325
326
327 tasks_found++;
328 prev_thread_ptr = thread_ptr;
329
330 // Get the location of the next thread structure.
331 thread_ptr = 0;
332 retval = target_read_buffer( rtos->target, prev_thread_ptr + param->thread_next_offset, param->pointer_width, (uint8_t *) &thread_ptr );
333 if ( retval != ERROR_OK )
334 {
335 LOG_OUTPUT("Error reading next thread pointer in ThreadX thread list\r\n");
336 return retval;
337 }
338
339 }
340
341 rtos->thread_count = tasks_found;
342
343 return 0;
344 }
345
346 static int ThreadX_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, char ** hex_reg_list )
347 {
348
349 int retval;
350 const struct ThreadX_params* param;
351
352 *hex_reg_list = NULL;
353
354 if ( rtos == NULL )
355 {
356 return -1;
357 }
358
359 if ( thread_id == 0 )
360 {
361 return -2;
362 }
363
364 if (rtos->rtos_specific_params == NULL )
365 {
366 return -3;
367 }
368
369 param = (const struct ThreadX_params*) rtos->rtos_specific_params;
370
371 // Read the stack pointer
372 int64_t stack_ptr = 0;
373 retval = target_read_buffer( rtos->target, thread_id + param->thread_stack_offset, param->pointer_width, (uint8_t*)&stack_ptr);
374 if ( retval != ERROR_OK )
375 {
376 LOG_OUTPUT("Error reading stack frame from ThreadX thread\r\n");
377 return retval;
378 }
379
380 return rtos_generic_stack_read( rtos->target, param->stacking_info, stack_ptr, hex_reg_list );
381 }
382
383
384
385 static int ThreadX_get_symbol_list_to_lookup(symbol_table_elem_t * symbol_list[])
386 {
387 unsigned int i;
388 *symbol_list = (symbol_table_elem_t *) malloc( sizeof( symbol_table_elem_t ) * THREADX_NUM_SYMBOLS );
389
390 for( i = 0; i < THREADX_NUM_SYMBOLS; i++ )
391 {
392 (*symbol_list)[i].symbol_name = ThreadX_symbol_list[i];
393 }
394
395 return 0;
396 }
397
398 static int ThreadX_detect_rtos( struct target* target )
399 {
400 if ( ( target->rtos->symbols != NULL ) &&
401 ( target->rtos->symbols[ThreadX_VAL_tx_thread_created_ptr].address != 0 ) )
402 {
403 // looks like ThreadX
404 return 1;
405 }
406 return 0;
407 }
408
409
410
411 #if 0
412
413 static int ThreadX_set_current_thread(struct rtos *rtos, threadid_t thread_id)
414 {
415 return 0;
416 }
417
418
419
420 static int ThreadX_get_thread_detail( struct rtos* rtos, threadid_t thread_id, struct thread_detail* detail )
421 {
422 unsigned int i = 0;
423 int retval;
424
425 #define THREADX_THREAD_NAME_STR_SIZE (200)
426 char tmp_str[THREADX_THREAD_NAME_STR_SIZE];
427
428 const struct ThreadX_params* param;
429
430 if ( rtos == NULL )
431 {
432 return -1;
433 }
434
435 if ( thread_id == 0 )
436 {
437 return -2;
438 }
439
440 if (rtos->rtos_specific_params == NULL )
441 {
442 return -3;
443 }
444
445 param = (const struct ThreadX_params*) rtos->rtos_specific_params;
446
447 if ( rtos->symbols == NULL )
448 {
449 LOG_OUTPUT("No symbols for ThreadX\r\n");
450 return -3;
451 }
452
453 detail->threadid = thread_id;
454
455 int64_t name_ptr = 0;
456 // read the name pointer
457 retval = target_read_buffer( rtos->target, thread_id + param->thread_name_offset, param->pointer_width, (uint8_t *)&name_ptr);
458 if ( retval != ERROR_OK )
459 {
460 LOG_OUTPUT("Could not read ThreadX thread name pointer from target\r\n");
461 return retval;
462 }
463
464 // Read the thread name
465 retval = target_read_buffer( rtos->target, name_ptr, THREADX_THREAD_NAME_STR_SIZE, (uint8_t *)&tmp_str);
466 if ( retval != ERROR_OK )
467 {
468 LOG_OUTPUT("Error reading thread name from ThreadX target\r\n");
469 return retval;
470 }
471 tmp_str[THREADX_THREAD_NAME_STR_SIZE-1] = '\x00';
472
473 if ( tmp_str[0] == '\x00' )
474 {
475 strcpy(tmp_str,"No Name");
476 }
477
478 detail->thread_name_str = (char*)malloc( strlen(tmp_str)+1 );
479
480
481 // Read the thread status
482 int64_t thread_status = 0;
483 retval = target_read_buffer( rtos->target, thread_id + param->thread_state_offset, 4, (uint8_t *)&thread_status);
484 if ( retval != ERROR_OK )
485 {
486 LOG_OUTPUT("Error reading thread state from ThreadX target\r\n");
487 return retval;
488 }
489
490 for( i = 0; (i < THREADX_NUM_STATES) && (ThreadX_thread_states[i].value!=thread_status); i++ )
491 {
492 }
493
494
495 char * state_desc;
496 if (i < THREADX_NUM_STATES)
497 {
498 state_desc = ThreadX_thread_states[i].desc;
499 }
500 else
501 {
502 state_desc = "Unknown state";
503 }
504
505 detail->extra_info_str = (char*)malloc( strlen(state_desc)+1 );
506
507 detail->exists = true;
508
509 detail->display_str = NULL;
510
511
512
513
514 return 0;
515 }
516
517 #endif
518
519 static int ThreadX_create( struct target* target )
520 {
521 int i = 0;
522 while ( ( i < THREADX_NUM_PARAMS ) && ( 0 != strcmp( ThreadX_params_list[i].target_name, target->type->name ) ) )
523 {
524 i++;
525 }
526 if ( i >= THREADX_NUM_PARAMS )
527 {
528 LOG_OUTPUT("Could not find target in ThreadX compatability list\r\n");
529 return -1;
530 }
531
532 target->rtos->rtos_specific_params = (void*) &ThreadX_params_list[i];
533 target->rtos->current_thread = 0;
534 target->rtos->thread_details = NULL;
535 return 0;
536 }

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)