target/openrisc/or1k: Use 'bool' data type
[fw/openocd] / src / rtos / ChibiOS.c
index 7d1f5cf852eb579bc9ff9cad6394e5360470b83a..8839acc9a61f44c3938bcbfb769c00dc93184594 100644 (file)
@@ -16,9 +16,7 @@
  *   GNU General Public License for more details.                          *
  *                                                                         *
  *   You should have received a copy of the GNU General Public License     *
- *   along with this program; if not, write to the                         *
- *   Free Software Foundation, Inc.,                                       *
- *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
  ***************************************************************************/
 
 #ifdef HAVE_CONFIG_H
@@ -36,7 +34,6 @@
 #include "helper/types.h"
 #include "rtos_chibios_stackings.h"
 
-
 /**
  * @brief   ChibiOS/RT memory signature record.
  *
@@ -72,10 +69,9 @@ struct ChibiOS_chdebug {
 /**
  * @brief ChibiOS thread states.
  */
-const char *ChibiOS_thread_states[] = {
-       "READY", "CURRENT", "SUSPENDED", "WTSEM", "WTMTX", "WTCOND", "SLEEPING",
-       "WTEXIT", "WTOREVT", "WTANDEVT", "SNDMSGQ", "SNDMSG", "WTMSG", "WTQUEUE",
-       "FINAL"
+static const char * const ChibiOS_thread_states[] = { "READY", "CURRENT",
+"WTSTART", "SUSPENDED", "QUEUED", "WTSEM", "WTMTX", "WTCOND", "SLEEPING",
+"WTEXIT", "WTOREVT", "WTANDEVT", "SNDMSGQ", "SNDMSG", "WTMSG", "FINAL"
 };
 
 #define CHIBIOS_NUM_STATES (sizeof(ChibiOS_thread_states)/sizeof(char *))
@@ -92,24 +88,25 @@ struct ChibiOS_params {
        const struct rtos_register_stacking *stacking_info;
 };
 
-struct ChibiOS_params ChibiOS_params_list[] = {
+static struct ChibiOS_params ChibiOS_params_list[] = {
        {
-       "cortex_m3",                                                    /* target_name */
+       "cortex_m",                                                     /* target_name */
        0,
        NULL,                                                                   /* stacking_info */
        },
        {
-       "stm32_stlink",                                                 /* target_name */
+       "hla_target",                                                   /* target_name */
        0,
        NULL,                                                                   /* stacking_info */
        }
 };
 #define CHIBIOS_NUM_PARAMS ((int)(sizeof(ChibiOS_params_list)/sizeof(struct ChibiOS_params)))
 
-static int ChibiOS_detect_rtos(struct target *target);
+static bool ChibiOS_detect_rtos(struct target *target);
 static int ChibiOS_create(struct target *target);
 static int ChibiOS_update_threads(struct rtos *rtos);
-static int ChibiOS_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, char **hex_reg_list);
+static int ChibiOS_get_thread_reg_list(struct rtos *rtos, int64_t thread_id,
+               struct rtos_reg **reg_list, int *num_regs);
 static int ChibiOS_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[]);
 
 struct rtos_type ChibiOS_rtos = {
@@ -122,19 +119,28 @@ struct rtos_type ChibiOS_rtos = {
        .get_symbol_list_to_lookup = ChibiOS_get_symbol_list_to_lookup,
 };
 
+
+/* In ChibiOS/RT 3.0 the rlist structure has become part of a system
+ * data structure ch. We declare both symbols as optional and later
+ * use whatever is available.
+ */
+
 enum ChibiOS_symbol_values {
        ChibiOS_VAL_rlist = 0,
-       ChibiOS_VAL_ch_debug = 1,
-       ChibiOS_VAL_chSysInit = 2
+       ChibiOS_VAL_ch = 1,
+       ChibiOS_VAL_ch_debug = 2
 };
 
-static char *ChibiOS_symbol_list[] = {
-       "rlist",                /* Thread ready list*/
-       "ch_debug",             /* Memory Signatur containing offsets of fields in rlist*/
-       "chSysInit",    /* Necessary part of API, used for ChibiOS detection*/
-       NULL
+static symbol_table_elem_t ChibiOS_symbol_list[] = {
+       { "rlist", 0, true},            /* Thread ready list */
+       { "ch", 0, true},                       /* System data structure */
+       { "ch_debug", 0, false},        /* Memory Signature containing offsets of fields in rlist */
+       { NULL, 0, false}
 };
 
+/* Offset of the rlist structure within the system data structure (ch) */
+#define CH_RLIST_OFFSET 0x00
+
 static int ChibiOS_update_memory_signature(struct rtos *rtos)
 {
        int retval;
@@ -216,7 +222,7 @@ static int ChibiOS_update_stacking(struct rtos *rtos)
        /* Sometimes the stacking can not be determined only by looking at the
         * target name but only a runtime.
         *
-        * For example, this is the case for cortex-m4 targets and ChibiOS which
+        * For example, this is the case for Cortex-M4 targets and ChibiOS which
         * only stack the FPU registers if it is enabled during ChibiOS build.
         *
         * Terminating which stacking is used is target depending.
@@ -238,10 +244,10 @@ static int ChibiOS_update_stacking(struct rtos *rtos)
        struct ChibiOS_params *param;
        param = (struct ChibiOS_params *) rtos->rtos_specific_params;
 
-       /* Check for armv7m with *enabled* FPU, i.e. a Cortex M4  */
+       /* Check for armv7m with *enabled* FPU, i.e. a Cortex-M4  */
        struct armv7m_common *armv7m_target = target_to_armv7m(rtos->target);
        if (is_armv7m(armv7m_target)) {
-               if (armv7m_target->fp_feature == FPv4_SP) {
+               if (armv7m_target->fp_feature != FP_NONE) {
                        /* Found ARM v7m target which includes a FPU */
                        uint32_t cpacr;
 
@@ -254,11 +260,9 @@ static int ChibiOS_update_stacking(struct rtos *rtos)
                        /* Check if CP10 and CP11 are set to full access.
                         * In ChibiOS this is done in ResetHandler() in crt0.c */
                        if (cpacr & 0x00F00000) {
-                               /* Found target with enabled FPU */
-                               /* FIXME: Need to figure out how to specify the FPU registers */
-                               LOG_ERROR("ChibiOS ARM v7m targets with enabled FPU "
-                                                 " are NOT supported");
-                               return -1;
+                               LOG_DEBUG("Enabled FPU detected.");
+                               param->stacking_info = &rtos_chibios_arm_v7m_stacking_w_fpu;
+                               return 0;
                        }
                }
 
@@ -296,25 +300,14 @@ static int ChibiOS_update_threads(struct rtos *rtos)
        }
 
        /* wipe out previous thread details if any */
-       int j;
-       if (rtos->thread_details) {
-               for (j = 0; j < rtos->thread_count; j++) {
-                       struct thread_detail *current_thread = &rtos->thread_details[j];
-                       if (current_thread->display_str != NULL)
-                               free(current_thread->display_str);
-                       if (current_thread->thread_name_str != NULL)
-                               free(current_thread->thread_name_str);
-                       if (current_thread->extra_info_str != NULL)
-                               free(current_thread->extra_info_str);
-               }
-               free(rtos->thread_details);
-               rtos->thread_details = NULL;
-               rtos->thread_count = 0;
-       }
+       rtos_free_threadlist(rtos);
+
        /* ChibiOS does not save the current thread count. We have to first
         * parse the double linked thread list to check for errors and the number of
         * threads. */
-       const uint32_t rlist = rtos->symbols[ChibiOS_VAL_rlist].address;
+       const uint32_t rlist = rtos->symbols[ChibiOS_VAL_rlist].address ?
+               rtos->symbols[ChibiOS_VAL_rlist].address :
+               rtos->symbols[ChibiOS_VAL_ch].address + CH_RLIST_OFFSET /* ChibiOS3 */;
        const struct ChibiOS_chdebug *signature = param->signature;
        uint32_t current;
        uint32_t previous;
@@ -360,17 +353,16 @@ static int ChibiOS_update_threads(struct rtos *rtos)
                const char tmp_thread_name[] = "Current Execution";
                const char tmp_thread_extra_info[] = "No RTOS thread";
 
-               rtos->thread_details = (struct thread_detail *) malloc(
+               rtos->thread_details = malloc(
                                sizeof(struct thread_detail));
                rtos->thread_details->threadid = 1;
                rtos->thread_details->exists = true;
-               rtos->thread_details->display_str = NULL;
 
-               rtos->thread_details->extra_info_str = (char *) malloc(
+               rtos->thread_details->extra_info_str = malloc(
                                sizeof(tmp_thread_extra_info));
                strcpy(rtos->thread_details->extra_info_str, tmp_thread_extra_info);
 
-               rtos->thread_details->thread_name_str = (char *) malloc(
+               rtos->thread_details->thread_name_str = malloc(
                                sizeof(tmp_thread_name));
                strcpy(rtos->thread_details->thread_name_str, tmp_thread_name);
 
@@ -380,7 +372,7 @@ static int ChibiOS_update_threads(struct rtos *rtos)
        }
 
        /* create space for new thread details */
-       rtos->thread_details = (struct thread_detail *) malloc(
+       rtos->thread_details = malloc(
                        sizeof(struct thread_detail) * tasks_found);
        if (!rtos->thread_details) {
                LOG_ERROR("Could not allocate space for thread details");
@@ -429,7 +421,7 @@ static int ChibiOS_update_threads(struct rtos *rtos)
                if (tmp_str[0] == '\x00')
                        strcpy(tmp_str, "No Name");
 
-               curr_thrd_details->thread_name_str = (char *)malloc(
+               curr_thrd_details->thread_name_str = malloc(
                                strlen(tmp_str) + 1);
                strcpy(curr_thrd_details->thread_name_str, tmp_str);
 
@@ -448,14 +440,13 @@ static int ChibiOS_update_threads(struct rtos *rtos)
                if (threadState < CHIBIOS_NUM_STATES)
                        state_desc = ChibiOS_thread_states[threadState];
                else
-                       state_desc = "Unknown state";
+                       state_desc = "Unknown";
 
-               curr_thrd_details->extra_info_str = (char *)malloc(strlen(
-                                       state_desc)+1);
-               strcpy(curr_thrd_details->extra_info_str, state_desc);
+               curr_thrd_details->extra_info_str = malloc(strlen(
+                                       state_desc)+8);
+               sprintf(curr_thrd_details->extra_info_str, "State: %s", state_desc);
 
                curr_thrd_details->exists = true;
-               curr_thrd_details->display_str = NULL;
 
                curr_thrd_details++;
        }
@@ -463,7 +454,7 @@ static int ChibiOS_update_threads(struct rtos *rtos)
        uint32_t current_thrd;
        /* NOTE: By design, cf_off_name equals readylist_current_offset */
        retval = target_read_u32(rtos->target,
-                                                        current + signature->cf_off_name,
+                                                        rlist + signature->cf_off_name,
                                                         &current_thrd);
        if (retval != ERROR_OK) {
                LOG_ERROR("Could not read current Thread from ChibiOS target");
@@ -474,13 +465,13 @@ static int ChibiOS_update_threads(struct rtos *rtos)
        return 0;
 }
 
-static int ChibiOS_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, char **hex_reg_list)
+static int ChibiOS_get_thread_reg_list(struct rtos *rtos, int64_t thread_id,
+               struct rtos_reg **reg_list, int *num_regs)
 {
        int retval;
        const struct ChibiOS_params *param;
        uint32_t stack_ptr = 0;
 
-       *hex_reg_list = NULL;
        if ((rtos == NULL) || (thread_id == 0) ||
                        (rtos->rtos_specific_params == NULL))
                return -1;
@@ -505,38 +496,37 @@ static int ChibiOS_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, cha
                return retval;
        }
 
-       return rtos_generic_stack_read(rtos->target, param->stacking_info, stack_ptr, hex_reg_list);
+       return rtos_generic_stack_read(rtos->target, param->stacking_info, stack_ptr, reg_list, num_regs);
 }
 
 static int ChibiOS_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[])
 {
-       unsigned int i;
-       *symbol_list = (symbol_table_elem_t *) malloc(
-                       sizeof(symbol_table_elem_t) * ARRAY_SIZE(ChibiOS_symbol_list));
+       *symbol_list = malloc(sizeof(ChibiOS_symbol_list));
 
-       for (i = 0; i < ARRAY_SIZE(ChibiOS_symbol_list); i++)
-               (*symbol_list)[i].symbol_name = ChibiOS_symbol_list[i];
+       if (*symbol_list == NULL)
+               return ERROR_FAIL;
 
+       memcpy(*symbol_list, ChibiOS_symbol_list, sizeof(ChibiOS_symbol_list));
        return 0;
 }
 
-static int ChibiOS_detect_rtos(struct target *target)
+static bool ChibiOS_detect_rtos(struct target *target)
 {
        if ((target->rtos->symbols != NULL) &&
-                       (target->rtos->symbols[ChibiOS_VAL_rlist].address != 0) &&
-                       (target->rtos->symbols[ChibiOS_VAL_chSysInit].address != 0)) {
+                       ((target->rtos->symbols[ChibiOS_VAL_rlist].address != 0) ||
+                        (target->rtos->symbols[ChibiOS_VAL_ch].address != 0))) {
 
                if (target->rtos->symbols[ChibiOS_VAL_ch_debug].address == 0) {
-                       LOG_INFO("It looks like the target is running ChibiOS without "
-                                       "ch_debug.");
-                       return 0;
+                       LOG_INFO("It looks like the target may be running ChibiOS "
+                                       "without ch_debug.");
+                       return false;
                }
 
                /* looks like ChibiOS with memory map enabled.*/
-               return 1;
+               return true;
        }
 
-       return 0;
+       return false;
 }
 
 static int ChibiOS_create(struct target *target)