Hi,

I found that currently OpenOCD supports ThreadX only for Cortext M3 and R4
cores. But I work with Cypress FX3 chip that has ARM926EJS core and ThreadX.

I found that I need to search next information:
1. TX_THREAD offset information
2. Stacking information

TX_THREAD offset information is a simple. It same to the Cortex M3/R4 one.

Stacking information more difficult for me.

I use disassembler to restore some ThreadX procs to understand how to
registers saves to stack. I found that for ARM926 uses two types of
stacking:
1. Solicited and
2. Interrupt

First type of context saves only R4-R11, R14 and CPSR registers. Interrupt
context saves full set of registers: R0-R12,R14 and CPSR.

First DWORD (32bit) in stack indicates type of context:
0x00000000 - Solicited context
0x00000001 - Interrupt context

Solicited context uses when rescheduling occured via API calls, like
_tx_thread_sleep(), _tx_thread_relinquish() and any other that calls
_tx_thread_system_return() at the end (this function saves Solicited
context). This type of scheduling like to simple function call so PC (r14)
does not saves. This type of context requires 11 DWORDS to save (1 for type
and 10 for registers).

Interrupt context uses when rescheduling occured from ISR. This type of
context requires 17 DWORDS to save (1 for type and 16 for registers).

Context restores at the _tx_thread_schedule(). It determine type of context
and load appropriate registers set from stack.


I modify ThreadX.c to add ARM926EJS support (patch is attached). Now I can
see threads, it names and states. But I see wrong stack trace, like:
(arm-gdb)info threads
[New Thread 1074062196]
[New Thread 1074057804]
[New Thread 1074056680]
[New Thread 1074056948]
[New Thread 1074056224]
[New Thread 1074058112]
[New Thread 1074057256]
[New Thread 1074059220]
  Id   Target Id         Frame
  9    Thread 1074059220 (04_UIB_THREAD :  : Sleeping) 0x00000000 in ?? ()
  8    Thread 1074057256 (05_LPP_THREAD :  : Waiting - Event flag)
0x00000000 in ?? ()
  7    Thread 1074058112 (03_PIB_THREAD :  : Waiting - Event flag)
0x00000000 in ?? ()
  6    Thread 1074056224 (Debug Thread :  : Waiting - Queue) 0x00000000 in
?? ()
  5    Thread 1074056948 (06_SIB_THREAD :  : Sleeping) 0x00000000 in ?? ()
  4    Thread 1074056680 (02_SYSTEM_THREAD :  : Waiting - Event flag)
0x00000000 in ?? ()
  3    Thread 1074057804 (01_DMA_THREAD :  : Waiting - Queue) 0x00000000 in
?? ()
  2    Thread 1074062196 (System Timer Thread :  : Suspended) 0x00000000 in
?? ()
* 1    Thread 1074051620 (MAIN :  : Ready) 0x4001429c in gpio_init () at
epilib/gpio.c:84
(arm-gdb)thread 5
[Switching to thread 5 (Thread 1074056948)]
#0  0x00000000 in ?? ()
(arm-gdb)bt
#0  0x00000000 in ?? ()
#1  0x40003a30 in _tx_thread_system_suspend (thread_ptr=0x4004d7d4
<glUibThread>) at tx_thread_system_suspend.c:803
#2  0x60000052 in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
(arm-gdb)info registers
r0             0x0    0
r1             0x0    0
r2             0x0    0
r3             0x0    0
r4             0x4004d7d4    1074059220
r5             0x60000053    1610612819
r6             0x600000d3    1610612947
r7             0x4    4
r8             0x0    0
r9             0x0    0
r10            0x0    0
r11            0x0    0
r12            0x0    0
sp             0x40059380    0x40059380
lr             0x40003a30    0x40003a30 <_tx_thread_system_suspend+1472>
pc             0x0    0x0
cpsr           0x60000053    1610612819

Only one thread at time shows more-less correct stack trace.

I don't understand where I am wrong. So any help and suggestions is
welcomed!

PS Patch based on OpenOCD-0.8.0

-- 
WBR, Alexander Drozdov
http://htrd.su
--- openocd-0.8.0/src/rtos/ThreadX.c    2014-03-30 14:54:34.000000000 +1100
+++ openocd-0.8.0.new/src/rtos/ThreadX.c        2015-01-29 14:49:32.825672075 
+1000
@@ -31,12 +31,17 @@
 #include "helper/types.h"
 #include "rtos_standard_stackings.h"
 
+static const struct rtos_register_stacking* get_stacking_info(struct rtos 
*rtos, int64_t stack_ptr);
+static const struct rtos_register_stacking* get_stacking_info_arm926ejs(struct 
rtos *rtos, int64_t stack_ptr);
+
 static int ThreadX_detect_rtos(struct target *target);
 static int ThreadX_create(struct target *target);
 static int ThreadX_update_threads(struct rtos *rtos);
 static int ThreadX_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, 
char **hex_reg_list);
 static int ThreadX_get_symbol_list_to_lookup(symbol_table_elem_t 
*symbol_list[]);
 
+
+
 struct ThreadX_thread_state {
        int value;
        char *desc;
@@ -61,6 +66,66 @@
 
 #define THREADX_NUM_STATES (sizeof(ThreadX_thread_states)/sizeof(struct 
ThreadX_thread_state))
 
+#define ARM926EJS_REGISTERS_SIZE_SOLICITED (11 * 4)
+static const struct stack_register_offset 
rtos_threadx_arm926ejs_stack_offsets_solicited[] = {
+       { -1,   32 },           /* r0        */
+       { -1,   32 },           /* r1        */
+       { -1,   32 },           /* r2        */
+       { -1,   32 },           /* r3        */
+       { 0x08, 32 },           /* r4        */
+       { 0x0C, 32 },           /* r5        */
+       { 0x10, 32 },           /* r6        */
+       { 0x14, 32 },           /* r7        */
+       { 0x18, 32 },           /* r8        */
+       { 0x1C, 32 },           /* r9        */
+       { 0x20, 32 },           /* r10       */
+       { 0x24, 32 },           /* r11       */
+       { -1,   32 },           /* r12       */
+       { -2,   32 },           /* sp (r13)  */
+       { 0x28, 32 },           /* lr (r14)  */
+       { -1,   32 },           /* pc (r15)  */
+//     { -1,   32 },           /* lr (r14)  */
+//     { 0x28, 32 },           /* pc (r15)  */
+       { 0x04, 32 },           /* xPSR      */
+};
+#define ARM926EJS_REGISTERS_SIZE_INTERRUPT (17 * 4)
+static const struct stack_register_offset 
rtos_threadx_arm926ejs_stack_offsets_interrupt[] = {
+       { 0x08, 32 },           /* r0        */
+       { 0x0C, 32 },           /* r1        */
+       { 0x10, 32 },           /* r2        */
+       { 0x14, 32 },           /* r3        */
+       { 0x18, 32 },           /* r4        */
+       { 0x1C, 32 },           /* r5        */
+       { 0x20, 32 },           /* r6        */
+       { 0x24, 32 },           /* r7        */
+       { 0x28, 32 },           /* r8        */
+       { 0x2C, 32 },           /* r9        */
+       { 0x30, 32 },           /* r10       */
+       { 0x34, 32 },           /* r11       */
+       { 0x38, 32 },           /* r12       */
+       { -2,   32 },           /* sp (r13)  */
+       { 0x3C, 32 },           /* lr (r14)  */
+       { 0x40, 32 },           /* pc (r15)  */
+       { 0x04, 32 },           /* xPSR      */
+};
+
+const struct rtos_register_stacking rtos_threadx_arm926ejs_stacking[] = {
+    {
+       ARM926EJS_REGISTERS_SIZE_SOLICITED, /* stack_registers_size */
+       -1,                                               /* 
stack_growth_direction */
+       17,                           /* num_output_registers */
+       8,                                                /* stack_alignment */
+       rtos_threadx_arm926ejs_stack_offsets_solicited  /* register_offsets */  
  
+       },
+    {
+       ARM926EJS_REGISTERS_SIZE_INTERRUPT, /* stack_registers_size */
+       -1,                                               /* 
stack_growth_direction */
+       17,                           /* num_output_registers */
+       8,                                                /* stack_alignment */
+       rtos_threadx_arm926ejs_stack_offsets_interrupt  /* register_offsets */  
  
+       },
+};
+
 struct ThreadX_params {
        char *target_name;
        unsigned char pointer_width;
@@ -69,6 +134,8 @@
        unsigned char thread_state_offset;
        unsigned char thread_next_offset;
        const struct rtos_register_stacking *stacking_info;
+       size_t                               stacking_info_nb;
+       const struct rtos_register_stacking* (*stacking_info_proc)(struct rtos 
*rtos, int64_t stack_ptr);
 };
 
 const struct ThreadX_params ThreadX_params_list[] = {
@@ -80,6 +147,8 @@
        48,                                                     /* 
thread_state_offset; */
        136,                                            /* thread_next_offset */
        &rtos_standard_Cortex_M3_stacking,      /* stacking_info */
+       1,                                  /* stacking_info_nb */
+       NULL,                               /* stacking_info_proc */
        },
        {
        "cortex_r4",                            /* target_name */
@@ -89,6 +158,19 @@
        48,                                                     /* 
thread_state_offset; */
        136,                                            /* thread_next_offset */
        &rtos_standard_Cortex_R4_stacking,      /* stacking_info */
+       1,                                  /* stacking_info_nb */
+       NULL,                               /* stacking_info_proc */
+       },
+       {
+       "arm926ejs",                            /* target_name */
+       4,                                                      /* 
pointer_width; */
+       8,                                                      /* 
thread_stack_offset; */
+       40,                                                     /* 
thread_name_offset; */
+       48,                                                     /* 
thread_state_offset; */
+       136,                                            /* thread_next_offset */
+       rtos_threadx_arm926ejs_stacking,        /* stacking_info */
+       2,                                  /* stacking_info_nb */
+       get_stacking_info_arm926ejs,        /* stacking_info_proc */  
        },
 };
 
@@ -118,6 +200,41 @@
 
 };
 
+static const struct rtos_register_stacking* get_stacking_info(struct rtos 
*rtos, int64_t stack_ptr)
+{
+    const struct ThreadX_params *param = (const struct ThreadX_params *) 
rtos->rtos_specific_params;
+    
+    if (param->stacking_info_proc != NULL) {
+        return param->stacking_info_proc(rtos, stack_ptr);
+    }
+    
+    return (param->stacking_info + 0);
+}
+
+static const struct rtos_register_stacking* get_stacking_info_arm926ejs(struct 
rtos *rtos, int64_t stack_ptr)
+{
+    const struct ThreadX_params *param = (const struct ThreadX_params *) 
rtos->rtos_specific_params;
+    int      retval;
+    uint32_t flag;
+    
+       retval = target_read_buffer(rtos->target,
+                                           stack_ptr,
+                                           sizeof(flag),
+                                           (uint8_t *)&flag);
+       if (retval != ERROR_OK) {
+               LOG_ERROR("Error reading stack data from ThreadX thread");
+               return NULL;
+       }
+       
+       if (flag == 0) {
+           LOG_INFO("  solicited stack");
+           return param->stacking_info + 0;
+       } else {
+           LOG_INFO("  interrupt stack: %u", flag);
+           return param->stacking_info + 1;
+       }
+}
+
 static int ThreadX_update_threads(struct rtos *rtos)
 {
        int retval;
@@ -324,8 +441,18 @@
                LOG_ERROR("Error reading stack frame from ThreadX thread");
                return retval;
        }
+       
+       LOG_INFO("thread: 0x%llx, stack_ptr=0x%llx", (uint64_t)thread_id, 
(uint64_t)stack_ptr);
+       
+       if (stack_ptr == 0) {
+           LOG_ERROR("null stack pointer in thread");
+           return -5;
+       }
+       
+       const struct rtos_register_stacking *stacking_info = 
+           get_stacking_info(rtos, stack_ptr);
 
-       return rtos_generic_stack_read(rtos->target, param->stacking_info, 
stack_ptr, hex_reg_list);
+       return rtos_generic_stack_read(rtos->target, stacking_info, stack_ptr, 
hex_reg_list);
 }
 
 static int ThreadX_get_symbol_list_to_lookup(symbol_table_elem_t 
*symbol_list[])
------------------------------------------------------------------------------
Dive into the World of Parallel Programming. The Go Parallel Website,
sponsored by Intel and developed in partnership with Slashdot Media, is your
hub for all things parallel software development, from weekly thought
leadership blogs to news, videos, case studies, tutorials and more. Take a
look and join the conversation now. http://goparallel.sourceforge.net/
_______________________________________________
OpenOCD-devel mailing list
OpenOCD-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openocd-devel

Reply via email to