2015-01-29 15:32 GMT+10:00 Alexander Drozdov <adrozd...@gmail.com>:
>
> 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:

Hi all again,

I found root cause of problem: ThreadX for ARM926EJS does not need
stack alignment by 8 bytes. Im my final patch, ThreadX threads info,
backtracing, registers info and so on works correctly for ARM926EJS.
Patch is attached.

Cross build for Win32/64 with patched sources and patch (located at
the src directory):
https://mega.co.nz/#!2lFETbIB!ggBj1mhIqUI1qhblsaRGoEoY7YIOHvAmQWLo_M1I-Kw



-- 
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-02-05 21:01:35.524321020 
+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 */
+       0,                                                /* 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 */
+       0,                                                /* 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: 
stack_ptr=0x%llx", stack_ptr);
+               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;
@@ -306,7 +423,7 @@
        if (rtos == NULL)
                return -1;
 
-       if (thread_id == 0)
+       if (thread_id == 0 || thread_id == 1)
                return -2;
 
        if (rtos->rtos_specific_params == NULL)
@@ -324,8 +441,23 @@
                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);
+       
+       if (stacking_info == NULL) {
+           LOG_ERROR("Unknown stacking info for thread id=0x%llx", 
(uint64_t)thread_id);
+           return -6;
+       }
 
-       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