diff options
| author | Palmer Dabbelt <palmer@dabbelt.com> | 2017-04-06 15:24:17 -0700 |
|---|---|---|
| committer | Palmer Dabbelt <palmer@dabbelt.com> | 2017-04-06 15:24:17 -0700 |
| commit | fab7311f18c49be82e8e1681c8966e576525d3ed (patch) | |
| tree | 4b825dc642cb6eb9a060e54bf8d69288fbee4904 /src/rtos | |
| parent | ffe0ced9ebd54ab1e297ebdf0f6b995b3e077989 (diff) | |
| download | riscv-openocd-__archive__.zip riscv-openocd-__archive__.tar.gz riscv-openocd-__archive__.tar.bz2 | |
archive branch__archive__
Diffstat (limited to 'src/rtos')
| -rw-r--r-- | src/rtos/ChibiOS.c | 547 | ||||
| -rw-r--r-- | src/rtos/FreeRTOS.c | 555 | ||||
| -rw-r--r-- | src/rtos/Makefile.am | 32 | ||||
| -rw-r--r-- | src/rtos/ThreadX.c | 617 | ||||
| -rw-r--r-- | src/rtos/eCos.c | 392 | ||||
| -rw-r--r-- | src/rtos/embKernel.c | 342 | ||||
| -rw-r--r-- | src/rtos/linux.c | 1594 | ||||
| -rw-r--r-- | src/rtos/linux_header.h | 37 | ||||
| -rw-r--r-- | src/rtos/mqx.c | 561 | ||||
| -rw-r--r-- | src/rtos/riscv_debug.c | 280 | ||||
| -rw-r--r-- | src/rtos/riscv_debug.h | 9 | ||||
| -rw-r--r-- | src/rtos/rtos.c | 549 | ||||
| -rw-r--r-- | src/rtos/rtos.h | 111 | ||||
| -rw-r--r-- | src/rtos/rtos_chibios_stackings.c | 83 | ||||
| -rw-r--r-- | src/rtos/rtos_chibios_stackings.h | 31 | ||||
| -rw-r--r-- | src/rtos/rtos_ecos_stackings.c | 51 | ||||
| -rw-r--r-- | src/rtos/rtos_ecos_stackings.h | 28 | ||||
| -rw-r--r-- | src/rtos/rtos_embkernel_stackings.c | 55 | ||||
| -rw-r--r-- | src/rtos/rtos_embkernel_stackings.h | 30 | ||||
| -rw-r--r-- | src/rtos/rtos_mqx_stackings.c | 80 | ||||
| -rw-r--r-- | src/rtos/rtos_mqx_stackings.h | 30 | ||||
| -rw-r--r-- | src/rtos/rtos_standard_stackings.c | 270 | ||||
| -rw-r--r-- | src/rtos/rtos_standard_stackings.h | 40 |
23 files changed, 0 insertions, 6324 deletions
diff --git a/src/rtos/ChibiOS.c b/src/rtos/ChibiOS.c deleted file mode 100644 index 00e9df7..0000000 --- a/src/rtos/ChibiOS.c +++ /dev/null @@ -1,547 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2012 by Matthias Blaicher * - * Matthias Blaicher - matthias@blaicher.com * - * * - * Copyright (C) 2011 by Broadcom Corporation * - * Evan Hunter - ehunter@broadcom.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * 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, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <helper/time_support.h> -#include <jtag/jtag.h> -#include "target/target.h" -#include "target/target_type.h" -#include "target/armv7m.h" -#include "target/cortex_m.h" -#include "rtos.h" -#include "helper/log.h" -#include "helper/types.h" -#include "rtos_chibios_stackings.h" - -/** - * @brief ChibiOS/RT memory signature record. - * - * @details Definition copied from os/kernel/include/chregistry.h of ChibiOS/RT. - */ -struct ChibiOS_chdebug { - char ch_identifier[4]; /**< @brief Always set to "main". */ - uint8_t ch_zero; /**< @brief Must be zero. */ - uint8_t ch_size; /**< @brief Size of this structure. */ - uint16_t ch_version; /**< @brief Encoded ChibiOS/RT version. */ - uint8_t ch_ptrsize; /**< @brief Size of a pointer. */ - uint8_t ch_timesize; /**< @brief Size of a @p systime_t. */ - uint8_t ch_threadsize; /**< @brief Size of a @p Thread struct. */ - uint8_t cf_off_prio; /**< @brief Offset of @p p_prio field. */ - uint8_t cf_off_ctx; /**< @brief Offset of @p p_ctx field. */ - uint8_t cf_off_newer; /**< @brief Offset of @p p_newer field. */ - uint8_t cf_off_older; /**< @brief Offset of @p p_older field. */ - uint8_t cf_off_name; /**< @brief Offset of @p p_name field. */ - uint8_t cf_off_stklimit; /**< @brief Offset of @p p_stklimit - field. */ - uint8_t cf_off_state; /**< @brief Offset of @p p_state field. */ - uint8_t cf_off_flags; /**< @brief Offset of @p p_flags field. */ - uint8_t cf_off_refs; /**< @brief Offset of @p p_refs field. */ - uint8_t cf_off_preempt; /**< @brief Offset of @p p_preempt - field. */ - uint8_t cf_off_time; /**< @brief Offset of @p p_time field. */ -}; - -#define GET_CH_KERNEL_MAJOR(codedVersion) ((codedVersion >> 11) & 0x1f) -#define GET_CH_KERNEL_MINOR(codedVersion) ((codedVersion >> 6) & 0x1f) -#define GET_CH_KERNEL_PATCH(codedVersion) ((codedVersion >> 0) & 0x3f) - -/** - * @brief ChibiOS thread states. - */ -static const char * const ChibiOS_thread_states[] = { - "READY", "CURRENT", "SUSPENDED", "WTSEM", "WTMTX", "WTCOND", "SLEEPING", - "WTEXIT", "WTOREVT", "WTANDEVT", "SNDMSGQ", "SNDMSG", "WTMSG", "WTQUEUE", - "FINAL" -}; - -#define CHIBIOS_NUM_STATES (sizeof(ChibiOS_thread_states)/sizeof(char *)) - -/* Maximum ChibiOS thread name. There is no real limit set by ChibiOS but 64 - * chars ought to be enough. - */ -#define CHIBIOS_THREAD_NAME_STR_SIZE (64) - -struct ChibiOS_params { - const char *target_name; - - struct ChibiOS_chdebug *signature; - const struct rtos_register_stacking *stacking_info; -}; - -static struct ChibiOS_params ChibiOS_params_list[] = { - { - "cortex_m", /* target_name */ - 0, - NULL, /* stacking_info */ - }, - { - "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 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_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[]); - -struct rtos_type ChibiOS_rtos = { - .name = "ChibiOS", - - .detect_rtos = ChibiOS_detect_rtos, - .create = ChibiOS_create, - .update_threads = ChibiOS_update_threads, - .get_thread_reg_list = ChibiOS_get_thread_reg_list, - .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 = 1, - ChibiOS_VAL_ch_debug = 2 -}; - -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; - struct ChibiOS_params *param; - struct ChibiOS_chdebug *signature; - - param = (struct ChibiOS_params *) rtos->rtos_specific_params; - - /* Free existing memory description.*/ - if (param->signature) { - free(param->signature); - param->signature = 0; - } - - signature = malloc(sizeof(*signature)); - if (!signature) { - LOG_ERROR("Could not allocate space for ChibiOS/RT memory signature"); - return -1; - } - - retval = target_read_buffer(rtos->target, - rtos->symbols[ChibiOS_VAL_ch_debug].address, - sizeof(*signature), - (uint8_t *) signature); - if (retval != ERROR_OK) { - LOG_ERROR("Could not read ChibiOS/RT memory signature from target"); - goto errfree; - } - - if (strncmp(signature->ch_identifier, "main", 4) != 0) { - LOG_ERROR("Memory signature identifier does not contain magic bytes."); - goto errfree; - } - - if (signature->ch_size < sizeof(*signature)) { - LOG_ERROR("ChibiOS/RT memory signature claims to be smaller " - "than expected"); - goto errfree; - } - - if (signature->ch_size > sizeof(*signature)) { - LOG_WARNING("ChibiOS/RT memory signature claims to be bigger than" - " expected. Assuming compatibility..."); - } - - /* Convert endianness of version field */ - const uint8_t *versionTarget = (const uint8_t *) - &signature->ch_version; - signature->ch_version = rtos->target->endianness == TARGET_LITTLE_ENDIAN ? - le_to_h_u32(versionTarget) : be_to_h_u32(versionTarget); - - const uint16_t ch_version = signature->ch_version; - LOG_INFO("Successfully loaded memory map of ChibiOS/RT target " - "running version %i.%i.%i", GET_CH_KERNEL_MAJOR(ch_version), - GET_CH_KERNEL_MINOR(ch_version), GET_CH_KERNEL_PATCH(ch_version)); - - /* Currently, we have the inherent assumption that all address pointers - * are 32 bit wide. */ - if (signature->ch_ptrsize != sizeof(uint32_t)) { - LOG_ERROR("ChibiOS/RT target memory signature claims an address" - "width unequal to 32 bits!"); - free(signature); - return -1; - } - - param->signature = signature; - return 0; - -errfree: - /* Error reading the ChibiOS memory structure */ - free(signature); - param->signature = 0; - return -1; -} - - -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 - * only stack the FPU registers if it is enabled during ChibiOS build. - * - * Terminating which stacking is used is target depending. - * - * Assumptions: - * - Once ChibiOS is actually initialized, the stacking is fixed. - * - During startup code, the FPU might not be initialized and the - * detection might fail. - * - Since no threads are running during startup, the problem is solved - * by delaying stacking detection until there are more threads - * available than the current execution. In which case - * ChibiOS_get_thread_reg_list is called. - */ - int retval; - - if (!rtos->rtos_specific_params) - return -1; - - struct ChibiOS_params *param; - param = (struct ChibiOS_params *) rtos->rtos_specific_params; - - /* 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) { - /* Found ARM v7m target which includes a FPU */ - uint32_t cpacr; - - retval = target_read_u32(rtos->target, FPU_CPACR, &cpacr); - if (retval != ERROR_OK) { - LOG_ERROR("Could not read CPACR register to check FPU state"); - return -1; - } - - /* Check if CP10 and CP11 are set to full access. - * In ChibiOS this is done in ResetHandler() in crt0.c */ - if (cpacr & 0x00F00000) { - LOG_DEBUG("Enabled FPU detected."); - param->stacking_info = &rtos_chibios_arm_v7m_stacking_w_fpu; - return 0; - } - } - - /* Found ARM v7m target with no or disabled FPU */ - param->stacking_info = &rtos_chibios_arm_v7m_stacking; - return 0; - } - - return -1; -} - -static int ChibiOS_update_threads(struct rtos *rtos) -{ - int retval; - const struct ChibiOS_params *param; - int tasks_found = 0; - int rtos_valid = -1; - - if (!rtos->rtos_specific_params) - return -1; - - if (!rtos->symbols) { - LOG_ERROR("No symbols for ChibiOS"); - return -3; - } - - param = (const struct ChibiOS_params *) rtos->rtos_specific_params; - /* Update the memory signature saved in the target memory */ - if (!param->signature) { - retval = ChibiOS_update_memory_signature(rtos); - if (retval != ERROR_OK) { - LOG_ERROR("Reading the memory signature of ChibiOS/RT failed"); - return retval; - } - } - - /* wipe out previous thread details if any */ - 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 ? - 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; - uint32_t older; - - current = rlist; - previous = rlist; - while (1) { - retval = target_read_u32(rtos->target, - current + signature->cf_off_newer, ¤t); - if (retval != ERROR_OK) { - LOG_ERROR("Could not read next ChibiOS thread"); - return retval; - } - /* Could be NULL if the kernel is not initialized yet or if the - * registry is corrupted. */ - if (current == 0) { - LOG_ERROR("ChibiOS registry integrity check failed, NULL pointer"); - - rtos_valid = 0; - break; - } - /* Fetch previous thread in the list as a integrity check. */ - retval = target_read_u32(rtos->target, - current + signature->cf_off_older, &older); - if ((retval != ERROR_OK) || (older == 0) || (older != previous)) { - LOG_ERROR("ChibiOS registry integrity check failed, " - "double linked list violation"); - rtos_valid = 0; - break; - } - /* Check for full iteration of the linked list. */ - if (current == rlist) - break; - tasks_found++; - previous = current; - } - if (!rtos_valid) { - /* No RTOS, there is always at least the current execution, though */ - LOG_INFO("Only showing current execution because of a broken " - "ChibiOS thread registry."); - - const char tmp_thread_name[] = "Current Execution"; - const char tmp_thread_extra_info[] = "No RTOS thread"; - - rtos->thread_details = malloc( - sizeof(struct thread_detail)); - rtos->thread_details->threadid = 1; - rtos->thread_details->exists = true; - - 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 = malloc( - sizeof(tmp_thread_name)); - strcpy(rtos->thread_details->thread_name_str, tmp_thread_name); - - rtos->current_thread = 1; - rtos->thread_count = 1; - return ERROR_OK; - } - - /* create space for new thread details */ - rtos->thread_details = malloc( - sizeof(struct thread_detail) * tasks_found); - if (!rtos->thread_details) { - LOG_ERROR("Could not allocate space for thread details"); - return -1; - } - - rtos->thread_count = tasks_found; - /* Loop through linked list. */ - struct thread_detail *curr_thrd_details = rtos->thread_details; - while (curr_thrd_details < rtos->thread_details + tasks_found) { - uint32_t name_ptr = 0; - char tmp_str[CHIBIOS_THREAD_NAME_STR_SIZE]; - - retval = target_read_u32(rtos->target, - current + signature->cf_off_newer, ¤t); - if (retval != ERROR_OK) { - LOG_ERROR("Could not read next ChibiOS thread"); - return -6; - } - - /* Check for full iteration of the linked list. */ - if (current == rlist) - break; - - /* Save the thread pointer */ - curr_thrd_details->threadid = current; - - /* read the name pointer */ - retval = target_read_u32(rtos->target, - current + signature->cf_off_name, &name_ptr); - if (retval != ERROR_OK) { - LOG_ERROR("Could not read ChibiOS thread name pointer from target"); - return retval; - } - - /* Read the thread name */ - retval = target_read_buffer(rtos->target, name_ptr, - CHIBIOS_THREAD_NAME_STR_SIZE, - (uint8_t *)&tmp_str); - if (retval != ERROR_OK) { - LOG_ERROR("Error reading thread name from ChibiOS target"); - return retval; - } - tmp_str[CHIBIOS_THREAD_NAME_STR_SIZE - 1] = '\x00'; - - if (tmp_str[0] == '\x00') - strcpy(tmp_str, "No Name"); - - curr_thrd_details->thread_name_str = malloc( - strlen(tmp_str) + 1); - strcpy(curr_thrd_details->thread_name_str, tmp_str); - - /* State info */ - uint8_t threadState; - const char *state_desc; - - retval = target_read_u8(rtos->target, - current + signature->cf_off_state, &threadState); - if (retval != ERROR_OK) { - LOG_ERROR("Error reading thread state from ChibiOS target"); - return retval; - } - - - if (threadState < CHIBIOS_NUM_STATES) - state_desc = ChibiOS_thread_states[threadState]; - else - state_desc = "Unknown state"; - - curr_thrd_details->extra_info_str = malloc(strlen( - state_desc)+1); - strcpy(curr_thrd_details->extra_info_str, state_desc); - - curr_thrd_details->exists = true; - - curr_thrd_details++; - } - - uint32_t current_thrd; - /* NOTE: By design, cf_off_name equals readylist_current_offset */ - retval = target_read_u32(rtos->target, - rlist + signature->cf_off_name, - ¤t_thrd); - if (retval != ERROR_OK) { - LOG_ERROR("Could not read current Thread from ChibiOS target"); - return retval; - } - rtos->current_thread = current_thrd; - - return 0; -} - -static int ChibiOS_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, char **hex_reg_list) -{ - 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; - - param = (const struct ChibiOS_params *) rtos->rtos_specific_params; - - if (!param->signature) - return -1; - - /* Update stacking if it can only be determined from runtime information */ - if ((param->stacking_info == 0) && - (ChibiOS_update_stacking(rtos) != ERROR_OK)) { - LOG_ERROR("Failed to determine exact stacking for the target type %s", rtos->target->type->name); - return -1; - } - - /* Read the stack pointer */ - retval = target_read_u32(rtos->target, - thread_id + param->signature->cf_off_ctx, &stack_ptr); - if (retval != ERROR_OK) { - LOG_ERROR("Error reading stack frame from ChibiOS thread"); - return retval; - } - - return rtos_generic_stack_read(rtos->target, param->stacking_info, stack_ptr, hex_reg_list); -} - -static int ChibiOS_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[]) -{ - *symbol_list = malloc(sizeof(ChibiOS_symbol_list)); - - 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) -{ - if ((target->rtos->symbols != NULL) && - ((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 may be running ChibiOS " - "without ch_debug."); - return 0; - } - - /* looks like ChibiOS with memory map enabled.*/ - return 1; - } - - return 0; -} - -static int ChibiOS_create(struct target *target) -{ - int i = 0; - while ((i < CHIBIOS_NUM_PARAMS) && - (0 != strcmp(ChibiOS_params_list[i].target_name, target->type->name))) { - i++; - } - if (i >= CHIBIOS_NUM_PARAMS) { - LOG_WARNING("Could not find target \"%s\" in ChibiOS compatibility " - "list", target->type->name); - return -1; - } - - target->rtos->rtos_specific_params = (void *) &ChibiOS_params_list[i]; - return 0; -} diff --git a/src/rtos/FreeRTOS.c b/src/rtos/FreeRTOS.c deleted file mode 100644 index 52cebad..0000000 --- a/src/rtos/FreeRTOS.c +++ /dev/null @@ -1,555 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Broadcom Corporation * - * Evan Hunter - ehunter@broadcom.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * 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, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <helper/time_support.h> -#include <jtag/jtag.h> -#include "target/target.h" -#include "target/target_type.h" -#include "rtos.h" -#include "helper/log.h" -#include "helper/types.h" -#include "rtos_standard_stackings.h" -#include "target/armv7m.h" -#include "target/cortex_m.h" - - - -#define FREERTOS_MAX_PRIORITIES 63 - -#define FreeRTOS_STRUCT(int_type, ptr_type, list_prev_offset) - -struct FreeRTOS_params { - const char *target_name; - const unsigned char thread_count_width; - const unsigned char pointer_width; - const unsigned char list_next_offset; - const unsigned char list_width; - const unsigned char list_elem_next_offset; - const unsigned char list_elem_content_offset; - const unsigned char thread_stack_offset; - const unsigned char thread_name_offset; - const struct rtos_register_stacking *stacking_info_cm3; - const struct rtos_register_stacking *stacking_info_cm4f; - const struct rtos_register_stacking *stacking_info_cm4f_fpu; -}; - -static const struct FreeRTOS_params FreeRTOS_params_list[] = { - { - "cortex_m", /* target_name */ - 4, /* thread_count_width; */ - 4, /* pointer_width; */ - 16, /* list_next_offset; */ - 20, /* list_width; */ - 8, /* list_elem_next_offset; */ - 12, /* list_elem_content_offset */ - 0, /* thread_stack_offset; */ - 52, /* thread_name_offset; */ - &rtos_standard_Cortex_M3_stacking, /* stacking_info */ - &rtos_standard_Cortex_M4F_stacking, - &rtos_standard_Cortex_M4F_FPU_stacking, - }, - { - "hla_target", /* target_name */ - 4, /* thread_count_width; */ - 4, /* pointer_width; */ - 16, /* list_next_offset; */ - 20, /* list_width; */ - 8, /* list_elem_next_offset; */ - 12, /* list_elem_content_offset */ - 0, /* thread_stack_offset; */ - 52, /* thread_name_offset; */ - &rtos_standard_Cortex_M3_stacking, /* stacking_info */ - &rtos_standard_Cortex_M4F_stacking, - &rtos_standard_Cortex_M4F_FPU_stacking, - }, - { - "nds32_v3", /* target_name */ - 4, /* thread_count_width; */ - 4, /* pointer_width; */ - 16, /* list_next_offset; */ - 20, /* list_width; */ - 8, /* list_elem_next_offset; */ - 12, /* list_elem_content_offset */ - 0, /* thread_stack_offset; */ - 52, /* thread_name_offset; */ - &rtos_standard_NDS32_N1068_stacking, /* stacking_info */ - &rtos_standard_Cortex_M4F_stacking, - &rtos_standard_Cortex_M4F_FPU_stacking, - }, -}; - -#define FREERTOS_NUM_PARAMS ((int)(sizeof(FreeRTOS_params_list)/sizeof(struct FreeRTOS_params))) - -static int FreeRTOS_detect_rtos(struct target *target); -static int FreeRTOS_create(struct target *target); -static int FreeRTOS_update_threads(struct rtos *rtos); -static int FreeRTOS_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, char **hex_reg_list); -static int FreeRTOS_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[]); - -struct rtos_type FreeRTOS_rtos = { - .name = "FreeRTOS", - - .detect_rtos = FreeRTOS_detect_rtos, - .create = FreeRTOS_create, - .update_threads = FreeRTOS_update_threads, - .get_thread_reg_list = FreeRTOS_get_thread_reg_list, - .get_symbol_list_to_lookup = FreeRTOS_get_symbol_list_to_lookup, -}; - -enum FreeRTOS_symbol_values { - FreeRTOS_VAL_pxCurrentTCB = 0, - FreeRTOS_VAL_pxReadyTasksLists = 1, - FreeRTOS_VAL_xDelayedTaskList1 = 2, - FreeRTOS_VAL_xDelayedTaskList2 = 3, - FreeRTOS_VAL_pxDelayedTaskList = 4, - FreeRTOS_VAL_pxOverflowDelayedTaskList = 5, - FreeRTOS_VAL_xPendingReadyList = 6, - FreeRTOS_VAL_xTasksWaitingTermination = 7, - FreeRTOS_VAL_xSuspendedTaskList = 8, - FreeRTOS_VAL_uxCurrentNumberOfTasks = 9, - FreeRTOS_VAL_uxTopUsedPriority = 10, -}; - -struct symbols { - const char *name; - bool optional; -}; - -static const struct symbols FreeRTOS_symbol_list[] = { - { "pxCurrentTCB", false }, - { "pxReadyTasksLists", false }, - { "xDelayedTaskList1", false }, - { "xDelayedTaskList2", false }, - { "pxDelayedTaskList", false }, - { "pxOverflowDelayedTaskList", false }, - { "xPendingReadyList", false }, - { "xTasksWaitingTermination", true }, /* Only if INCLUDE_vTaskDelete */ - { "xSuspendedTaskList", true }, /* Only if INCLUDE_vTaskSuspend */ - { "uxCurrentNumberOfTasks", false }, - { "uxTopUsedPriority", true }, /* Unavailable since v7.5.3 */ - { NULL, false } -}; - -/* TODO: */ -/* this is not safe for little endian yet */ -/* may be problems reading if sizes are not 32 bit long integers. */ -/* test mallocs for failure */ - -static int FreeRTOS_update_threads(struct rtos *rtos) -{ - int i = 0; - int retval; - int tasks_found = 0; - const struct FreeRTOS_params *param; - - if (rtos->rtos_specific_params == NULL) - return -1; - - param = (const struct FreeRTOS_params *) rtos->rtos_specific_params; - - if (rtos->symbols == NULL) { - LOG_ERROR("No symbols for FreeRTOS"); - return -3; - } - - if (rtos->symbols[FreeRTOS_VAL_uxCurrentNumberOfTasks].address == 0) { - LOG_ERROR("Don't have the number of threads in FreeRTOS"); - return -2; - } - - int thread_list_size = 0; - retval = target_read_buffer(rtos->target, - rtos->symbols[FreeRTOS_VAL_uxCurrentNumberOfTasks].address, - param->thread_count_width, - (uint8_t *)&thread_list_size); - LOG_DEBUG("FreeRTOS: Read uxCurrentNumberOfTasks at 0x%" PRIx64 ", value %d\r\n", - rtos->symbols[FreeRTOS_VAL_uxCurrentNumberOfTasks].address, - thread_list_size); - - if (retval != ERROR_OK) { - LOG_ERROR("Could not read FreeRTOS thread count from target"); - return retval; - } - - /* wipe out previous thread details if any */ - rtos_free_threadlist(rtos); - - /* read the current thread */ - retval = target_read_buffer(rtos->target, - rtos->symbols[FreeRTOS_VAL_pxCurrentTCB].address, - param->pointer_width, - (uint8_t *)&rtos->current_thread); - if (retval != ERROR_OK) { - LOG_ERROR("Error reading current thread in FreeRTOS thread list"); - return retval; - } - LOG_DEBUG("FreeRTOS: Read pxCurrentTCB at 0x%" PRIx64 ", value 0x%" PRIx64 "\r\n", - rtos->symbols[FreeRTOS_VAL_pxCurrentTCB].address, - rtos->current_thread); - - if ((thread_list_size == 0) || (rtos->current_thread == 0)) { - /* Either : No RTOS threads - there is always at least the current execution though */ - /* OR : No current thread - all threads suspended - show the current execution - * of idling */ - char tmp_str[] = "Current Execution"; - thread_list_size++; - tasks_found++; - rtos->thread_details = malloc( - sizeof(struct thread_detail) * thread_list_size); - if (!rtos->thread_details) { - LOG_ERROR("Error allocating memory for %d threads", thread_list_size); - return ERROR_FAIL; - } - rtos->thread_details->threadid = 1; - rtos->thread_details->exists = true; - rtos->thread_details->extra_info_str = NULL; - rtos->thread_details->thread_name_str = malloc(sizeof(tmp_str)); - strcpy(rtos->thread_details->thread_name_str, tmp_str); - - if (thread_list_size == 1) { - rtos->thread_count = 1; - return ERROR_OK; - } - } else { - /* create space for new thread details */ - rtos->thread_details = malloc( - sizeof(struct thread_detail) * thread_list_size); - if (!rtos->thread_details) { - LOG_ERROR("Error allocating memory for %d threads", thread_list_size); - return ERROR_FAIL; - } - } - - /* Find out how many lists are needed to be read from pxReadyTasksLists, */ - if (rtos->symbols[FreeRTOS_VAL_uxTopUsedPriority].address == 0) { - LOG_ERROR("FreeRTOS: uxTopUsedPriority is not defined, consult the OpenOCD manual for a work-around"); - return ERROR_FAIL; - } - int64_t max_used_priority = 0; - retval = target_read_buffer(rtos->target, - rtos->symbols[FreeRTOS_VAL_uxTopUsedPriority].address, - param->pointer_width, - (uint8_t *)&max_used_priority); - if (retval != ERROR_OK) - return retval; - LOG_DEBUG("FreeRTOS: Read uxTopUsedPriority at 0x%" PRIx64 ", value %" PRId64 "\r\n", - rtos->symbols[FreeRTOS_VAL_uxTopUsedPriority].address, - max_used_priority); - if (max_used_priority > FREERTOS_MAX_PRIORITIES) { - LOG_ERROR("FreeRTOS maximum used priority is unreasonably big, not proceeding: %" PRId64 "", - max_used_priority); - return ERROR_FAIL; - } - - symbol_address_t *list_of_lists = - malloc(sizeof(symbol_address_t) * - (max_used_priority+1 + 5)); - if (!list_of_lists) { - LOG_ERROR("Error allocating memory for %" PRId64 " priorities", max_used_priority); - return ERROR_FAIL; - } - - int num_lists; - for (num_lists = 0; num_lists <= max_used_priority; num_lists++) - list_of_lists[num_lists] = rtos->symbols[FreeRTOS_VAL_pxReadyTasksLists].address + - num_lists * param->list_width; - - list_of_lists[num_lists++] = rtos->symbols[FreeRTOS_VAL_xDelayedTaskList1].address; - list_of_lists[num_lists++] = rtos->symbols[FreeRTOS_VAL_xDelayedTaskList2].address; - list_of_lists[num_lists++] = rtos->symbols[FreeRTOS_VAL_xPendingReadyList].address; - list_of_lists[num_lists++] = rtos->symbols[FreeRTOS_VAL_xSuspendedTaskList].address; - list_of_lists[num_lists++] = rtos->symbols[FreeRTOS_VAL_xTasksWaitingTermination].address; - - for (i = 0; i < num_lists; i++) { - if (list_of_lists[i] == 0) - continue; - - /* Read the number of threads in this list */ - int64_t list_thread_count = 0; - retval = target_read_buffer(rtos->target, - list_of_lists[i], - param->thread_count_width, - (uint8_t *)&list_thread_count); - if (retval != ERROR_OK) { - LOG_ERROR("Error reading number of threads in FreeRTOS thread list"); - free(list_of_lists); - return retval; - } - LOG_DEBUG("FreeRTOS: Read thread count for list %d at 0x%" PRIx64 ", value %" PRId64 "\r\n", - i, list_of_lists[i], list_thread_count); - - if (list_thread_count == 0) - continue; - - /* Read the location of first list item */ - uint64_t prev_list_elem_ptr = -1; - uint64_t list_elem_ptr = 0; - retval = target_read_buffer(rtos->target, - list_of_lists[i] + param->list_next_offset, - param->pointer_width, - (uint8_t *)&list_elem_ptr); - if (retval != ERROR_OK) { - LOG_ERROR("Error reading first thread item location in FreeRTOS thread list"); - free(list_of_lists); - return retval; - } - LOG_DEBUG("FreeRTOS: Read first item for list %d at 0x%" PRIx64 ", value 0x%" PRIx64 "\r\n", - i, list_of_lists[i] + param->list_next_offset, list_elem_ptr); - - while ((list_thread_count > 0) && (list_elem_ptr != 0) && - (list_elem_ptr != prev_list_elem_ptr) && - (tasks_found < thread_list_size)) { - /* Get the location of the thread structure. */ - rtos->thread_details[tasks_found].threadid = 0; - retval = target_read_buffer(rtos->target, - list_elem_ptr + param->list_elem_content_offset, - param->pointer_width, - (uint8_t *)&(rtos->thread_details[tasks_found].threadid)); - if (retval != ERROR_OK) { - LOG_ERROR("Error reading thread list item object in FreeRTOS thread list"); - free(list_of_lists); - return retval; - } - LOG_DEBUG("FreeRTOS: Read Thread ID at 0x%" PRIx64 ", value 0x%" PRIx64 "\r\n", - list_elem_ptr + param->list_elem_content_offset, - rtos->thread_details[tasks_found].threadid); - - /* get thread name */ - - #define FREERTOS_THREAD_NAME_STR_SIZE (200) - char tmp_str[FREERTOS_THREAD_NAME_STR_SIZE]; - - /* Read the thread name */ - retval = target_read_buffer(rtos->target, - rtos->thread_details[tasks_found].threadid + param->thread_name_offset, - FREERTOS_THREAD_NAME_STR_SIZE, - (uint8_t *)&tmp_str); - if (retval != ERROR_OK) { - LOG_ERROR("Error reading first thread item location in FreeRTOS thread list"); - free(list_of_lists); - return retval; - } - tmp_str[FREERTOS_THREAD_NAME_STR_SIZE-1] = '\x00'; - LOG_DEBUG("FreeRTOS: Read Thread Name at 0x%" PRIx64 ", value \"%s\"\r\n", - rtos->thread_details[tasks_found].threadid + param->thread_name_offset, - tmp_str); - - if (tmp_str[0] == '\x00') - strcpy(tmp_str, "No Name"); - - rtos->thread_details[tasks_found].thread_name_str = - malloc(strlen(tmp_str)+1); - strcpy(rtos->thread_details[tasks_found].thread_name_str, tmp_str); - rtos->thread_details[tasks_found].exists = true; - - if (rtos->thread_details[tasks_found].threadid == rtos->current_thread) { - char running_str[] = "Running"; - rtos->thread_details[tasks_found].extra_info_str = malloc( - sizeof(running_str)); - strcpy(rtos->thread_details[tasks_found].extra_info_str, - running_str); - } else - rtos->thread_details[tasks_found].extra_info_str = NULL; - - tasks_found++; - list_thread_count--; - - prev_list_elem_ptr = list_elem_ptr; - list_elem_ptr = 0; - retval = target_read_buffer(rtos->target, - prev_list_elem_ptr + param->list_elem_next_offset, - param->pointer_width, - (uint8_t *)&list_elem_ptr); - if (retval != ERROR_OK) { - LOG_ERROR("Error reading next thread item location in FreeRTOS thread list"); - free(list_of_lists); - return retval; - } - LOG_DEBUG("FreeRTOS: Read next thread location at 0x%" PRIx64 ", value 0x%" PRIx64 "\r\n", - prev_list_elem_ptr + param->list_elem_next_offset, - list_elem_ptr); - } - } - - free(list_of_lists); - rtos->thread_count = tasks_found; - return 0; -} - -static int FreeRTOS_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, char **hex_reg_list) -{ - int retval; - const struct FreeRTOS_params *param; - int64_t stack_ptr = 0; - - *hex_reg_list = NULL; - if (rtos == NULL) - return -1; - - if (thread_id == 0) - return -2; - - if (rtos->rtos_specific_params == NULL) - return -1; - - param = (const struct FreeRTOS_params *) rtos->rtos_specific_params; - - /* Read the stack pointer */ - retval = target_read_buffer(rtos->target, - thread_id + param->thread_stack_offset, - param->pointer_width, - (uint8_t *)&stack_ptr); - if (retval != ERROR_OK) { - LOG_ERROR("Error reading stack frame from FreeRTOS thread"); - return retval; - } - LOG_DEBUG("FreeRTOS: Read stack pointer at 0x%" PRIx64 ", value 0x%" PRIx64 "\r\n", - thread_id + param->thread_stack_offset, - stack_ptr); - - /* Check for armv7m with *enabled* FPU, i.e. a Cortex-M4F */ - int cm4_fpu_enabled = 0; - struct armv7m_common *armv7m_target = target_to_armv7m(rtos->target); - if (is_armv7m(armv7m_target)) { - if (armv7m_target->fp_feature == FPv4_SP) { - /* Found ARM v7m target which includes a FPU */ - uint32_t cpacr; - - retval = target_read_u32(rtos->target, FPU_CPACR, &cpacr); - if (retval != ERROR_OK) { - LOG_ERROR("Could not read CPACR register to check FPU state"); - return -1; - } - - /* Check if CP10 and CP11 are set to full access. */ - if (cpacr & 0x00F00000) { - /* Found target with enabled FPU */ - cm4_fpu_enabled = 1; - } - } - } - - if (cm4_fpu_enabled == 1) { - /* Read the LR to decide between stacking with or without FPU */ - uint32_t LR_svc = 0; - retval = target_read_buffer(rtos->target, - stack_ptr + 0x20, - param->pointer_width, - (uint8_t *)&LR_svc); - if (retval != ERROR_OK) { - LOG_OUTPUT("Error reading stack frame from FreeRTOS thread\r\n"); - return retval; - } - if ((LR_svc & 0x10) == 0) - return rtos_generic_stack_read(rtos->target, param->stacking_info_cm4f_fpu, stack_ptr, hex_reg_list); - else - return rtos_generic_stack_read(rtos->target, param->stacking_info_cm4f, stack_ptr, hex_reg_list); - } else - return rtos_generic_stack_read(rtos->target, param->stacking_info_cm3, stack_ptr, hex_reg_list); -} - -static int FreeRTOS_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[]) -{ - unsigned int i; - *symbol_list = calloc( - ARRAY_SIZE(FreeRTOS_symbol_list), sizeof(symbol_table_elem_t)); - - for (i = 0; i < ARRAY_SIZE(FreeRTOS_symbol_list); i++) { - (*symbol_list)[i].symbol_name = FreeRTOS_symbol_list[i].name; - (*symbol_list)[i].optional = FreeRTOS_symbol_list[i].optional; - } - - return 0; -} - -#if 0 - -static int FreeRTOS_set_current_thread(struct rtos *rtos, threadid_t thread_id) -{ - return 0; -} - -static int FreeRTOS_get_thread_ascii_info(struct rtos *rtos, threadid_t thread_id, char **info) -{ - int retval; - const struct FreeRTOS_params *param; - - if (rtos == NULL) - return -1; - - if (thread_id == 0) - return -2; - - if (rtos->rtos_specific_params == NULL) - return -3; - - param = (const struct FreeRTOS_params *) rtos->rtos_specific_params; - -#define FREERTOS_THREAD_NAME_STR_SIZE (200) - char tmp_str[FREERTOS_THREAD_NAME_STR_SIZE]; - - /* Read the thread name */ - retval = target_read_buffer(rtos->target, - thread_id + param->thread_name_offset, - FREERTOS_THREAD_NAME_STR_SIZE, - (uint8_t *)&tmp_str); - if (retval != ERROR_OK) { - LOG_ERROR("Error reading first thread item location in FreeRTOS thread list"); - return retval; - } - tmp_str[FREERTOS_THREAD_NAME_STR_SIZE-1] = '\x00'; - - if (tmp_str[0] == '\x00') - strcpy(tmp_str, "No Name"); - - *info = malloc(strlen(tmp_str)+1); - strcpy(*info, tmp_str); - return 0; -} - -#endif - -static int FreeRTOS_detect_rtos(struct target *target) -{ - if ((target->rtos->symbols != NULL) && - (target->rtos->symbols[FreeRTOS_VAL_pxReadyTasksLists].address != 0)) { - /* looks like FreeRTOS */ - return 1; - } - return 0; -} - -static int FreeRTOS_create(struct target *target) -{ - int i = 0; - while ((i < FREERTOS_NUM_PARAMS) && - (0 != strcmp(FreeRTOS_params_list[i].target_name, target->type->name))) { - i++; - } - if (i >= FREERTOS_NUM_PARAMS) { - LOG_ERROR("Could not find target in FreeRTOS compatibility list"); - return -1; - } - - target->rtos->rtos_specific_params = (void *) &FreeRTOS_params_list[i]; - return 0; -} diff --git a/src/rtos/Makefile.am b/src/rtos/Makefile.am deleted file mode 100644 index a7dab00..0000000 --- a/src/rtos/Makefile.am +++ /dev/null @@ -1,32 +0,0 @@ -# *************************************************************************** -# * Copyright (C) 2011 by Broadcom Corporation * -# * Evan Hunter - ehunter@broadcom.com * -# * * -# * This program is free software; you can redistribute it and/or modify * -# * it under the terms of the GNU General Public License as published by * -# * the Free Software Foundation; either version 2 of the License, or * -# * (at your option) any later version. * -# * * -# * This program is distributed in the hope that it will be useful, * -# * but WITHOUT ANY WARRANTY; without even the implied warranty of * -# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -# * 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, see <http://www.gnu.org/licenses/>. * -# *************************************************************************** - -include $(top_srcdir)/common.mk - -METASOURCES = AUTO -noinst_LTLIBRARIES = librtos.la -noinst_HEADERS = rtos.h rtos_standard_stackings.h rtos_ecos_stackings.h linux_header.h rtos_chibios_stackings.h rtos_embkernel_stackings.h rtos_mqx_stackings.h riscv_debug.h -librtos_la_SOURCES = rtos.c rtos_standard_stackings.c rtos_ecos_stackings.c rtos_chibios_stackings.c rtos_embkernel_stackings.c rtos_mqx_stackings.c FreeRTOS.c ThreadX.c eCos.c linux.c ChibiOS.c embKernel.c mqx.c riscv_debug.c - -librtos_la_CFLAGS = -if IS_MINGW -# FD_* macros are sloppy with their signs on MinGW32 platform -librtos_la_CFLAGS += -Wno-sign-compare -endif - -MAINTAINERCLEANFILES = $(srcdir)/Makefile.in diff --git a/src/rtos/ThreadX.c b/src/rtos/ThreadX.c deleted file mode 100644 index 8267b9f..0000000 --- a/src/rtos/ThreadX.c +++ /dev/null @@ -1,617 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Broadcom Corporation * - * Evan Hunter - ehunter@broadcom.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * 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, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <helper/time_support.h> -#include <jtag/jtag.h> -#include "target/target.h" -#include "target/target_type.h" -#include "rtos.h" -#include "helper/log.h" -#include "helper/types.h" -#include "rtos_standard_stackings.h" - -static const struct rtos_register_stacking *get_stacking_info(const struct rtos *rtos, int64_t stack_ptr); -static const struct rtos_register_stacking *get_stacking_info_arm926ejs(const struct rtos *rtos, int64_t stack_ptr); - -static int is_thread_id_valid(const struct rtos *rtos, int64_t thread_id); -static int is_thread_id_valid_arm926ejs(const struct rtos *rtos, int64_t thread_id); - -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; - const char *desc; -}; - -static const struct ThreadX_thread_state ThreadX_thread_states[] = { - { 0, "Ready" }, - { 1, "Completed" }, - { 2, "Terminated" }, - { 3, "Suspended" }, - { 4, "Sleeping" }, - { 5, "Waiting - Queue" }, - { 6, "Waiting - Semaphore" }, - { 7, "Waiting - Event flag" }, - { 8, "Waiting - Memory" }, - { 9, "Waiting - Memory" }, - { 10, "Waiting - I/O" }, - { 11, "Waiting - Filesystem" }, - { 12, "Waiting - Network" }, - { 13, "Waiting - Mutex" }, -}; - -#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 */ - NULL, /* 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 */ - NULL, /* stack_alignment */ - rtos_threadx_arm926ejs_stack_offsets_interrupt /* register_offsets */ -}, -}; - -struct ThreadX_params { - const char *target_name; - unsigned char pointer_width; - unsigned char thread_stack_offset; - unsigned char thread_name_offset; - 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* (*fn_get_stacking_info)(const struct rtos *rtos, int64_t stack_ptr); - int (*fn_is_thread_id_valid)(const struct rtos *rtos, int64_t thread_id); -}; - -static const struct ThreadX_params ThreadX_params_list[] = { - { - "cortex_m", /* target_name */ - 4, /* pointer_width; */ - 8, /* thread_stack_offset; */ - 40, /* thread_name_offset; */ - 48, /* thread_state_offset; */ - 136, /* thread_next_offset */ - &rtos_standard_Cortex_M3_stacking, /* stacking_info */ - 1, /* stacking_info_nb */ - NULL, /* fn_get_stacking_info */ - NULL, /* fn_is_thread_id_valid */ - }, - { - "cortex_r4", /* target_name */ - 4, /* pointer_width; */ - 8, /* thread_stack_offset; */ - 40, /* thread_name_offset; */ - 48, /* thread_state_offset; */ - 136, /* thread_next_offset */ - &rtos_standard_Cortex_R4_stacking, /* stacking_info */ - 1, /* stacking_info_nb */ - NULL, /* fn_get_stacking_info */ - NULL, /* fn_is_thread_id_valid */ - }, - { - "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, /* fn_get_stacking_info */ - is_thread_id_valid_arm926ejs, /* fn_is_thread_id_valid */ - }, -}; - -#define THREADX_NUM_PARAMS ((int)(sizeof(ThreadX_params_list)/sizeof(struct ThreadX_params))) - -enum ThreadX_symbol_values { - ThreadX_VAL_tx_thread_current_ptr = 0, - ThreadX_VAL_tx_thread_created_ptr = 1, - ThreadX_VAL_tx_thread_created_count = 2, -}; - -static const char * const ThreadX_symbol_list[] = { - "_tx_thread_current_ptr", - "_tx_thread_created_ptr", - "_tx_thread_created_count", - NULL -}; - -const struct rtos_type ThreadX_rtos = { - .name = "ThreadX", - - .detect_rtos = ThreadX_detect_rtos, - .create = ThreadX_create, - .update_threads = ThreadX_update_threads, - .get_thread_reg_list = ThreadX_get_thread_reg_list, - .get_symbol_list_to_lookup = ThreadX_get_symbol_list_to_lookup, -}; - -static const struct rtos_register_stacking *get_stacking_info(const struct rtos *rtos, int64_t stack_ptr) -{ - const struct ThreadX_params *param = (const struct ThreadX_params *) rtos->rtos_specific_params; - - if (param->fn_get_stacking_info != NULL) - return param->fn_get_stacking_info(rtos, stack_ptr); - - return param->stacking_info + 0; -} - -static int is_thread_id_valid(const struct rtos *rtos, int64_t thread_id) -{ - const struct ThreadX_params *param; - - if (rtos->rtos_specific_params == NULL) - return 0; /* invalid */ - - param = (const struct ThreadX_params *) rtos->rtos_specific_params; - - if (param->fn_is_thread_id_valid != NULL) - return param->fn_is_thread_id_valid(rtos, thread_id); - - return (thread_id != 0); -} - -static const struct rtos_register_stacking *get_stacking_info_arm926ejs(const 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%" PRIx64, stack_ptr); - return NULL; - } - - if (flag == 0) { - LOG_DEBUG(" solicited stack"); - return param->stacking_info + 0; - } else { - LOG_DEBUG(" interrupt stack: %u", flag); - return param->stacking_info + 1; - } -} - -static int is_thread_id_valid_arm926ejs(const struct rtos *rtos, int64_t thread_id) -{ - return (thread_id != 0 && thread_id != 1); -} - -static int ThreadX_update_threads(struct rtos *rtos) -{ - int retval; - int tasks_found = 0; - int thread_list_size = 0; - const struct ThreadX_params *param; - - if (rtos == NULL) - return -1; - - if (rtos->rtos_specific_params == NULL) - return -3; - - param = (const struct ThreadX_params *) rtos->rtos_specific_params; - - if (rtos->symbols == NULL) { - LOG_ERROR("No symbols for ThreadX"); - return -4; - } - - if (rtos->symbols[ThreadX_VAL_tx_thread_created_count].address == 0) { - LOG_ERROR("Don't have the number of threads in ThreadX"); - return -2; - } - - /* read the number of threads */ - retval = target_read_buffer(rtos->target, - rtos->symbols[ThreadX_VAL_tx_thread_created_count].address, - 4, - (uint8_t *)&thread_list_size); - - if (retval != ERROR_OK) { - LOG_ERROR("Could not read ThreadX thread count from target"); - return retval; - } - - /* wipe out previous thread details if any */ - rtos_free_threadlist(rtos); - - /* read the current thread id */ - retval = target_read_buffer(rtos->target, - rtos->symbols[ThreadX_VAL_tx_thread_current_ptr].address, - 4, - (uint8_t *)&rtos->current_thread); - - if (retval != ERROR_OK) { - LOG_ERROR("Could not read ThreadX current thread from target"); - return retval; - } - - if ((thread_list_size == 0) || (rtos->current_thread == 0)) { - /* Either : No RTOS threads - there is always at least the current execution though */ - /* OR : No current thread - all threads suspended - show the current execution - * of idling */ - char tmp_str[] = "Current Execution"; - thread_list_size++; - tasks_found++; - rtos->thread_details = malloc( - sizeof(struct thread_detail) * thread_list_size); - rtos->thread_details->threadid = 1; - rtos->thread_details->exists = true; - rtos->thread_details->extra_info_str = NULL; - rtos->thread_details->thread_name_str = malloc(sizeof(tmp_str)); - strcpy(rtos->thread_details->thread_name_str, tmp_str); - - if (thread_list_size == 0) { - rtos->thread_count = 1; - return ERROR_OK; - } - } else { - /* create space for new thread details */ - rtos->thread_details = malloc( - sizeof(struct thread_detail) * thread_list_size); - } - - /* Read the pointer to the first thread */ - int64_t thread_ptr = 0; - retval = target_read_buffer(rtos->target, - rtos->symbols[ThreadX_VAL_tx_thread_created_ptr].address, - param->pointer_width, - (uint8_t *)&thread_ptr); - if (retval != ERROR_OK) { - LOG_ERROR("Could not read ThreadX thread location from target"); - return retval; - } - - /* loop over all threads */ - int64_t prev_thread_ptr = 0; - while ((thread_ptr != prev_thread_ptr) && (tasks_found < thread_list_size)) { - - #define THREADX_THREAD_NAME_STR_SIZE (200) - char tmp_str[THREADX_THREAD_NAME_STR_SIZE]; - unsigned int i = 0; - int64_t name_ptr = 0; - - /* Save the thread pointer */ - rtos->thread_details[tasks_found].threadid = thread_ptr; - - /* read the name pointer */ - retval = target_read_buffer(rtos->target, - thread_ptr + param->thread_name_offset, - param->pointer_width, - (uint8_t *)&name_ptr); - if (retval != ERROR_OK) { - LOG_ERROR("Could not read ThreadX thread name pointer from target"); - return retval; - } - - /* Read the thread name */ - retval = - target_read_buffer(rtos->target, - name_ptr, - THREADX_THREAD_NAME_STR_SIZE, - (uint8_t *)&tmp_str); - if (retval != ERROR_OK) { - LOG_ERROR("Error reading thread name from ThreadX target"); - return retval; - } - tmp_str[THREADX_THREAD_NAME_STR_SIZE-1] = '\x00'; - - if (tmp_str[0] == '\x00') - strcpy(tmp_str, "No Name"); - - rtos->thread_details[tasks_found].thread_name_str = - malloc(strlen(tmp_str)+1); - strcpy(rtos->thread_details[tasks_found].thread_name_str, tmp_str); - - /* Read the thread status */ - int64_t thread_status = 0; - retval = target_read_buffer(rtos->target, - thread_ptr + param->thread_state_offset, - 4, - (uint8_t *)&thread_status); - if (retval != ERROR_OK) { - LOG_ERROR("Error reading thread state from ThreadX target"); - return retval; - } - - for (i = 0; (i < THREADX_NUM_STATES) && - (ThreadX_thread_states[i].value != thread_status); i++) { - /* empty */ - } - - const char *state_desc; - if (i < THREADX_NUM_STATES) - state_desc = ThreadX_thread_states[i].desc; - else - state_desc = "Unknown state"; - - rtos->thread_details[tasks_found].extra_info_str = malloc(strlen( - state_desc)+1); - strcpy(rtos->thread_details[tasks_found].extra_info_str, state_desc); - - rtos->thread_details[tasks_found].exists = true; - - tasks_found++; - prev_thread_ptr = thread_ptr; - - /* Get the location of the next thread structure. */ - thread_ptr = 0; - retval = target_read_buffer(rtos->target, - prev_thread_ptr + param->thread_next_offset, - param->pointer_width, - (uint8_t *) &thread_ptr); - if (retval != ERROR_OK) { - LOG_ERROR("Error reading next thread pointer in ThreadX thread list"); - return retval; - } - } - - rtos->thread_count = tasks_found; - - return 0; -} - -static int ThreadX_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, char **hex_reg_list) -{ - int retval; - const struct ThreadX_params *param; - - *hex_reg_list = NULL; - - if (rtos == NULL) - return -1; - - if (!is_thread_id_valid(rtos, thread_id)) - return -2; - - if (rtos->rtos_specific_params == NULL) - return -3; - - param = (const struct ThreadX_params *) rtos->rtos_specific_params; - - /* Read the stack pointer */ - int64_t stack_ptr = 0; - retval = target_read_buffer(rtos->target, - thread_id + param->thread_stack_offset, - param->pointer_width, - (uint8_t *)&stack_ptr); - if (retval != ERROR_OK) { - LOG_ERROR("Error reading stack frame from ThreadX thread"); - return retval; - } - - LOG_INFO("thread: 0x%" PRIx64 ", stack_ptr=0x%" PRIx64, (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%" PRIx64, (uint64_t)thread_id); - return -6; - } - - 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[]) -{ - unsigned int i; - *symbol_list = calloc( - ARRAY_SIZE(ThreadX_symbol_list), sizeof(symbol_table_elem_t)); - - for (i = 0; i < ARRAY_SIZE(ThreadX_symbol_list); i++) - (*symbol_list)[i].symbol_name = ThreadX_symbol_list[i]; - - return 0; -} - -static int ThreadX_detect_rtos(struct target *target) -{ - if ((target->rtos->symbols != NULL) && - (target->rtos->symbols[ThreadX_VAL_tx_thread_created_ptr].address != 0)) { - /* looks like ThreadX */ - return 1; - } - return 0; -} - -#if 0 - -static int ThreadX_set_current_thread(struct rtos *rtos, threadid_t thread_id) -{ - return 0; -} - -static int ThreadX_get_thread_detail(struct rtos *rtos, - threadid_t thread_id, - struct thread_detail *detail) -{ - unsigned int i = 0; - int retval; - -#define THREADX_THREAD_NAME_STR_SIZE (200) - char tmp_str[THREADX_THREAD_NAME_STR_SIZE]; - - const struct ThreadX_params *param; - - if (rtos == NULL) - return -1; - - if (thread_id == 0) - return -2; - - if (rtos->rtos_specific_params == NULL) - return -3; - - param = (const struct ThreadX_params *) rtos->rtos_specific_params; - - if (rtos->symbols == NULL) { - LOG_ERROR("No symbols for ThreadX"); - return -3; - } - - detail->threadid = thread_id; - - int64_t name_ptr = 0; - /* read the name pointer */ - retval = target_read_buffer(rtos->target, - thread_id + param->thread_name_offset, - param->pointer_width, - (uint8_t *)&name_ptr); - if (retval != ERROR_OK) { - LOG_ERROR("Could not read ThreadX thread name pointer from target"); - return retval; - } - - /* Read the thread name */ - retval = target_read_buffer(rtos->target, - name_ptr, - THREADX_THREAD_NAME_STR_SIZE, - (uint8_t *)&tmp_str); - if (retval != ERROR_OK) { - LOG_ERROR("Error reading thread name from ThreadX target"); - return retval; - } - tmp_str[THREADX_THREAD_NAME_STR_SIZE-1] = '\x00'; - - if (tmp_str[0] == '\x00') - strcpy(tmp_str, "No Name"); - - detail->thread_name_str = malloc(strlen(tmp_str)+1); - - /* Read the thread status */ - int64_t thread_status = 0; - retval = - target_read_buffer(rtos->target, - thread_id + param->thread_state_offset, - 4, - (uint8_t *)&thread_status); - if (retval != ERROR_OK) { - LOG_ERROR("Error reading thread state from ThreadX target"); - return retval; - } - - for (i = 0; (i < THREADX_NUM_STATES) && - (ThreadX_thread_states[i].value != thread_status); i++) { - /* empty */ - } - - char *state_desc; - if (i < THREADX_NUM_STATES) - state_desc = ThreadX_thread_states[i].desc; - else - state_desc = "Unknown state"; - - detail->extra_info_str = malloc(strlen(state_desc)+1); - - detail->exists = true; - - return 0; -} - -#endif - -static int ThreadX_create(struct target *target) -{ - int i = 0; - while ((i < THREADX_NUM_PARAMS) && - (0 != strcmp(ThreadX_params_list[i].target_name, target->type->name))) { - i++; - } - if (i >= THREADX_NUM_PARAMS) { - LOG_ERROR("Could not find target in ThreadX compatibility list"); - return -1; - } - - target->rtos->rtos_specific_params = (void *) &ThreadX_params_list[i]; - target->rtos->current_thread = 0; - target->rtos->thread_details = NULL; - return 0; -} diff --git a/src/rtos/eCos.c b/src/rtos/eCos.c deleted file mode 100644 index e38e11f..0000000 --- a/src/rtos/eCos.c +++ /dev/null @@ -1,392 +0,0 @@ -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * 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, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <helper/time_support.h> -#include <jtag/jtag.h> -#include "target/target.h" -#include "target/target_type.h" -#include "rtos.h" -#include "helper/log.h" -#include "helper/types.h" -#include "rtos_ecos_stackings.h" - -static int eCos_detect_rtos(struct target *target); -static int eCos_create(struct target *target); -static int eCos_update_threads(struct rtos *rtos); -static int eCos_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, char **hex_reg_list); -static int eCos_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[]); - -struct eCos_thread_state { - int value; - const char *desc; -}; - -static const struct eCos_thread_state eCos_thread_states[] = { - { 0, "Ready" }, - { 1, "Sleeping" }, - { 2, "Countsleep" }, - { 4, "Suspended" }, - { 8, "Creating" }, - { 16, "Exited" } -}; - -#define ECOS_NUM_STATES (sizeof(eCos_thread_states)/sizeof(struct eCos_thread_state)) - -struct eCos_params { - const char *target_name; - unsigned char pointer_width; - unsigned char thread_stack_offset; - unsigned char thread_name_offset; - unsigned char thread_state_offset; - unsigned char thread_next_offset; - unsigned char thread_uniqueid_offset; - const struct rtos_register_stacking *stacking_info; -}; - -static const struct eCos_params eCos_params_list[] = { - { - "cortex_m", /* target_name */ - 4, /* pointer_width; */ - 0x0c, /* thread_stack_offset; */ - 0x9c, /* thread_name_offset; */ - 0x3c, /* thread_state_offset; */ - 0xa0, /* thread_next_offset */ - 0x4c, /* thread_uniqueid_offset */ - &rtos_eCos_Cortex_M3_stacking /* stacking_info */ - } -}; - -#define ECOS_NUM_PARAMS ((int)(sizeof(eCos_params_list)/sizeof(struct eCos_params))) - -enum eCos_symbol_values { - eCos_VAL_thread_list = 0, - eCos_VAL_current_thread_ptr = 1 -}; - -static const char * const eCos_symbol_list[] = { - "Cyg_Thread::thread_list", - "Cyg_Scheduler_Base::current_thread", - NULL -}; - -const struct rtos_type eCos_rtos = { - .name = "eCos", - - .detect_rtos = eCos_detect_rtos, - .create = eCos_create, - .update_threads = eCos_update_threads, - .get_thread_reg_list = eCos_get_thread_reg_list, - .get_symbol_list_to_lookup = eCos_get_symbol_list_to_lookup, - -}; - -static int eCos_update_threads(struct rtos *rtos) -{ - int retval; - int tasks_found = 0; - int thread_list_size = 0; - const struct eCos_params *param; - - if (rtos == NULL) - return -1; - - if (rtos->rtos_specific_params == NULL) - return -3; - - param = (const struct eCos_params *) rtos->rtos_specific_params; - - if (rtos->symbols == NULL) { - LOG_ERROR("No symbols for eCos"); - return -4; - } - - if (rtos->symbols[eCos_VAL_thread_list].address == 0) { - LOG_ERROR("Don't have the thread list head"); - return -2; - } - - /* wipe out previous thread details if any */ - rtos_free_threadlist(rtos); - - /* determine the number of current threads */ - uint32_t thread_list_head = rtos->symbols[eCos_VAL_thread_list].address; - uint32_t thread_index; - target_read_buffer(rtos->target, - thread_list_head, - param->pointer_width, - (uint8_t *) &thread_index); - uint32_t first_thread = thread_index; - do { - thread_list_size++; - retval = target_read_buffer(rtos->target, - thread_index + param->thread_next_offset, - param->pointer_width, - (uint8_t *) &thread_index); - if (retval != ERROR_OK) - return retval; - } while (thread_index != first_thread); - - /* read the current thread id */ - uint32_t current_thread_addr; - retval = target_read_buffer(rtos->target, - rtos->symbols[eCos_VAL_current_thread_ptr].address, - 4, - (uint8_t *)¤t_thread_addr); - if (retval != ERROR_OK) - return retval; - rtos->current_thread = 0; - retval = target_read_buffer(rtos->target, - current_thread_addr + param->thread_uniqueid_offset, - 2, - (uint8_t *)&rtos->current_thread); - if (retval != ERROR_OK) { - LOG_ERROR("Could not read eCos current thread from target"); - return retval; - } - - if ((thread_list_size == 0) || (rtos->current_thread == 0)) { - /* Either : No RTOS threads - there is always at least the current execution though */ - /* OR : No current thread - all threads suspended - show the current execution - * of idling */ - char tmp_str[] = "Current Execution"; - thread_list_size++; - tasks_found++; - rtos->thread_details = malloc( - sizeof(struct thread_detail) * thread_list_size); - rtos->thread_details->threadid = 1; - rtos->thread_details->exists = true; - rtos->thread_details->extra_info_str = NULL; - rtos->thread_details->thread_name_str = malloc(sizeof(tmp_str)); - strcpy(rtos->thread_details->thread_name_str, tmp_str); - - if (thread_list_size == 0) { - rtos->thread_count = 1; - return ERROR_OK; - } - } else { - /* create space for new thread details */ - rtos->thread_details = malloc( - sizeof(struct thread_detail) * thread_list_size); - } - - /* loop over all threads */ - thread_index = first_thread; - do { - - #define ECOS_THREAD_NAME_STR_SIZE (200) - char tmp_str[ECOS_THREAD_NAME_STR_SIZE]; - unsigned int i = 0; - uint32_t name_ptr = 0; - uint32_t prev_thread_ptr; - - /* Save the thread pointer */ - uint16_t thread_id; - retval = target_read_buffer(rtos->target, - thread_index + param->thread_uniqueid_offset, - 2, - (uint8_t *)&thread_id); - if (retval != ERROR_OK) { - LOG_ERROR("Could not read eCos thread id from target"); - return retval; - } - rtos->thread_details[tasks_found].threadid = thread_id; - - /* read the name pointer */ - retval = target_read_buffer(rtos->target, - thread_index + param->thread_name_offset, - param->pointer_width, - (uint8_t *)&name_ptr); - if (retval != ERROR_OK) { - LOG_ERROR("Could not read eCos thread name pointer from target"); - return retval; - } - - /* Read the thread name */ - retval = - target_read_buffer(rtos->target, - name_ptr, - ECOS_THREAD_NAME_STR_SIZE, - (uint8_t *)&tmp_str); - if (retval != ERROR_OK) { - LOG_ERROR("Error reading thread name from eCos target"); - return retval; - } - tmp_str[ECOS_THREAD_NAME_STR_SIZE-1] = '\x00'; - - if (tmp_str[0] == '\x00') - strcpy(tmp_str, "No Name"); - - rtos->thread_details[tasks_found].thread_name_str = - malloc(strlen(tmp_str)+1); - strcpy(rtos->thread_details[tasks_found].thread_name_str, tmp_str); - - /* Read the thread status */ - int64_t thread_status = 0; - retval = target_read_buffer(rtos->target, - thread_index + param->thread_state_offset, - 4, - (uint8_t *)&thread_status); - if (retval != ERROR_OK) { - LOG_ERROR("Error reading thread state from eCos target"); - return retval; - } - - for (i = 0; (i < ECOS_NUM_STATES) && (eCos_thread_states[i].value != thread_status); i++) { - /* - * empty - */ - } - - const char *state_desc; - if (i < ECOS_NUM_STATES) - state_desc = eCos_thread_states[i].desc; - else - state_desc = "Unknown state"; - - rtos->thread_details[tasks_found].extra_info_str = malloc(strlen( - state_desc)+1); - strcpy(rtos->thread_details[tasks_found].extra_info_str, state_desc); - - rtos->thread_details[tasks_found].exists = true; - - tasks_found++; - prev_thread_ptr = thread_index; - - /* Get the location of the next thread structure. */ - thread_index = rtos->symbols[eCos_VAL_thread_list].address; - retval = target_read_buffer(rtos->target, - prev_thread_ptr + param->thread_next_offset, - param->pointer_width, - (uint8_t *) &thread_index); - if (retval != ERROR_OK) { - LOG_ERROR("Error reading next thread pointer in eCos thread list"); - return retval; - } - } while (thread_index != first_thread); - - rtos->thread_count = tasks_found; - return 0; -} - -static int eCos_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, char **hex_reg_list) -{ - int retval; - const struct eCos_params *param; - - *hex_reg_list = NULL; - - if (rtos == NULL) - return -1; - - if (thread_id == 0) - return -2; - - if (rtos->rtos_specific_params == NULL) - return -3; - - param = (const struct eCos_params *) rtos->rtos_specific_params; - - /* Find the thread with that thread id */ - uint16_t id = 0; - uint32_t thread_list_head = rtos->symbols[eCos_VAL_thread_list].address; - uint32_t thread_index; - target_read_buffer(rtos->target, thread_list_head, param->pointer_width, - (uint8_t *)&thread_index); - bool done = false; - while (!done) { - retval = target_read_buffer(rtos->target, - thread_index + param->thread_uniqueid_offset, - 2, - (uint8_t *)&id); - if (retval != ERROR_OK) { - LOG_ERROR("Error reading unique id from eCos thread"); - return retval; - } - - if (id == thread_id) { - done = true; - break; - } - target_read_buffer(rtos->target, - thread_index + param->thread_next_offset, - param->pointer_width, - (uint8_t *) &thread_index); - } - - if (done) { - /* Read the stack pointer */ - int64_t stack_ptr = 0; - retval = target_read_buffer(rtos->target, - thread_index + param->thread_stack_offset, - param->pointer_width, - (uint8_t *)&stack_ptr); - if (retval != ERROR_OK) { - LOG_ERROR("Error reading stack frame from eCos thread"); - return retval; - } - - return rtos_generic_stack_read(rtos->target, - param->stacking_info, - stack_ptr, - hex_reg_list); - } - - return -1; -} - -static int eCos_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[]) -{ - unsigned int i; - *symbol_list = calloc( - ARRAY_SIZE(eCos_symbol_list), sizeof(symbol_table_elem_t)); - - for (i = 0; i < ARRAY_SIZE(eCos_symbol_list); i++) - (*symbol_list)[i].symbol_name = eCos_symbol_list[i]; - - return 0; -} - -static int eCos_detect_rtos(struct target *target) -{ - if ((target->rtos->symbols != NULL) && - (target->rtos->symbols[eCos_VAL_thread_list].address != 0)) { - /* looks like eCos */ - return 1; - } - return 0; -} - -static int eCos_create(struct target *target) -{ - int i = 0; - while ((i < ECOS_NUM_PARAMS) && - (0 != strcmp(eCos_params_list[i].target_name, target->type->name))) { - i++; - } - if (i >= ECOS_NUM_PARAMS) { - LOG_ERROR("Could not find target in eCos compatibility list"); - return -1; - } - - target->rtos->rtos_specific_params = (void *) &eCos_params_list[i]; - target->rtos->current_thread = 0; - target->rtos->thread_details = NULL; - return 0; -} diff --git a/src/rtos/embKernel.c b/src/rtos/embKernel.c deleted file mode 100644 index ceb313f..0000000 --- a/src/rtos/embKernel.c +++ /dev/null @@ -1,342 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Broadcom Corporation * - * Evan Hunter - ehunter@broadcom.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * 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, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <helper/time_support.h> -#include <jtag/jtag.h> -#include "target/target.h" -#include "target/target_type.h" -#include "rtos.h" -#include "helper/log.h" -#include "helper/types.h" -#include "rtos_embkernel_stackings.h" - -#define EMBKERNEL_MAX_THREAD_NAME_STR_SIZE (64) - -static int embKernel_detect_rtos(struct target *target); -static int embKernel_create(struct target *target); -static int embKernel_update_threads(struct rtos *rtos); -static int embKernel_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, char **hex_reg_list); -static int embKernel_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[]); - -struct rtos_type embKernel_rtos = { - .name = "embKernel", - .detect_rtos = embKernel_detect_rtos, - .create = embKernel_create, - .update_threads = embKernel_update_threads, - .get_thread_reg_list = - embKernel_get_thread_reg_list, - .get_symbol_list_to_lookup = embKernel_get_symbol_list_to_lookup, -}; - -enum { - SYMBOL_ID_sCurrentTask = 0, - SYMBOL_ID_sListReady = 1, - SYMBOL_ID_sListSleep = 2, - SYMBOL_ID_sListSuspended = 3, - SYMBOL_ID_sMaxPriorities = 4, - SYMBOL_ID_sCurrentTaskCount = 5, -}; - -static const char * const embKernel_symbol_list[] = { - "Rtos::sCurrentTask", - "Rtos::sListReady", - "Rtos::sListSleep", - "Rtos::sListSuspended", - "Rtos::sMaxPriorities", - "Rtos::sCurrentTaskCount", - NULL }; - -struct embKernel_params { - const char *target_name; - const unsigned char pointer_width; - const unsigned char thread_count_width; - const unsigned char rtos_list_size; - const unsigned char thread_stack_offset; - const unsigned char thread_name_offset; - const unsigned char thread_priority_offset; - const unsigned char thread_priority_width; - const unsigned char iterable_next_offset; - const unsigned char iterable_task_owner_offset; - const struct rtos_register_stacking *stacking_info; -}; - -static const struct embKernel_params embKernel_params_list[] = { - { - "cortex_m", /* target_name */ - 4, /* pointer_width */ - 4, /* thread_count_width */ - 8, /*rtos_list_size */ - 0, /*thread_stack_offset */ - 4, /*thread_name_offset */ - 8, /*thread_priority_offset */ - 4, /*thread_priority_width */ - 4, /*iterable_next_offset */ - 12, /*iterable_task_owner_offset */ - &rtos_embkernel_Cortex_M_stacking, /* stacking_info*/ - }, - { "hla_target", /* target_name */ - 4, /* pointer_width */ - 4, /* thread_count_width */ - 8, /*rtos_list_size */ - 0, /*thread_stack_offset */ - 4, /*thread_name_offset */ - 8, /*thread_priority_offset */ - 4, /*thread_priority_width */ - 4, /*iterable_next_offset */ - 12, /*iterable_task_owner_offset */ - &rtos_embkernel_Cortex_M_stacking, /* stacking_info */ - } -}; - -static int embKernel_detect_rtos(struct target *target) -{ - if (target->rtos->symbols != NULL) { - if (target->rtos->symbols[SYMBOL_ID_sCurrentTask].address != 0) - return 1; - } - return 0; -} - -static int embKernel_create(struct target *target) -{ - size_t i = 0; - while ((i < ARRAY_SIZE(embKernel_params_list)) && - (0 != strcmp(embKernel_params_list[i].target_name, target->type->name))) - i++; - - if (i >= ARRAY_SIZE(embKernel_params_list)) { - LOG_WARNING("Could not find target \"%s\" in embKernel compatibility " - "list", target->type->name); - return -1; - } - - target->rtos->rtos_specific_params = (void *) &embKernel_params_list[i]; - return 0; -} - -static int embKernel_get_tasks_details(struct rtos *rtos, int64_t iterable, const struct embKernel_params *param, - struct thread_detail *details, const char* state_str) -{ - int64_t task = 0; - int retval = target_read_buffer(rtos->target, iterable + param->iterable_task_owner_offset, param->pointer_width, - (uint8_t *) &task); - if (retval != ERROR_OK) - return retval; - details->threadid = (threadid_t) task; - details->exists = true; - - int64_t name_ptr = 0; - retval = target_read_buffer(rtos->target, task + param->thread_name_offset, param->pointer_width, - (uint8_t *) &name_ptr); - if (retval != ERROR_OK) - return retval; - - details->thread_name_str = malloc(EMBKERNEL_MAX_THREAD_NAME_STR_SIZE); - if (name_ptr) { - retval = target_read_buffer(rtos->target, name_ptr, EMBKERNEL_MAX_THREAD_NAME_STR_SIZE, - (uint8_t *) details->thread_name_str); - if (retval != ERROR_OK) - return retval; - details->thread_name_str[EMBKERNEL_MAX_THREAD_NAME_STR_SIZE - 1] = 0; - } else { - snprintf(details->thread_name_str, EMBKERNEL_MAX_THREAD_NAME_STR_SIZE, "NoName:[0x%08X]", (unsigned int) task); - } - - int64_t priority = 0; - retval = target_read_buffer(rtos->target, task + param->thread_priority_offset, param->thread_priority_width, - (uint8_t *) &priority); - if (retval != ERROR_OK) - return retval; - details->extra_info_str = malloc(EMBKERNEL_MAX_THREAD_NAME_STR_SIZE); - if (task == rtos->current_thread) { - snprintf(details->extra_info_str, EMBKERNEL_MAX_THREAD_NAME_STR_SIZE, "Pri=%u, Running", - (unsigned int) priority); - } else { - snprintf(details->extra_info_str, EMBKERNEL_MAX_THREAD_NAME_STR_SIZE, "Pri=%u, %s", (unsigned int) priority, - state_str); - } - - LOG_OUTPUT("Getting task details: iterable=0x%08X, task=0x%08X, name=%s\n", (unsigned int)iterable, - (unsigned int)task, details->thread_name_str); - return 0; -} - -static int embKernel_update_threads(struct rtos *rtos) -{ - /* int i = 0; */ - int retval; - const struct embKernel_params *param; - - if (rtos == NULL) - return -1; - - if (rtos->rtos_specific_params == NULL) - return -3; - - if (rtos->symbols == NULL) { - LOG_ERROR("No symbols for embKernel"); - return -4; - } - - if (rtos->symbols[SYMBOL_ID_sCurrentTask].address == 0) { - LOG_ERROR("Don't have the thread list head"); - return -2; - } - - /* wipe out previous thread details if any */ - rtos_free_threadlist(rtos); - - param = (const struct embKernel_params *) rtos->rtos_specific_params; - - retval = target_read_buffer(rtos->target, rtos->symbols[SYMBOL_ID_sCurrentTask].address, param->pointer_width, - (uint8_t *) &rtos->current_thread); - if (retval != ERROR_OK) { - LOG_ERROR("Error reading current thread in embKernel thread list"); - return retval; - } - - int64_t max_used_priority = 0; - retval = target_read_buffer(rtos->target, rtos->symbols[SYMBOL_ID_sMaxPriorities].address, param->pointer_width, - (uint8_t *) &max_used_priority); - if (retval != ERROR_OK) - return retval; - - int thread_list_size = 0; - retval = target_read_buffer(rtos->target, rtos->symbols[SYMBOL_ID_sCurrentTaskCount].address, - param->thread_count_width, (uint8_t *) &thread_list_size); - - if (retval != ERROR_OK) { - LOG_ERROR("Could not read embKernel thread count from target"); - return retval; - } - - /* create space for new thread details */ - rtos->thread_details = malloc(sizeof(struct thread_detail) * thread_list_size); - if (!rtos->thread_details) { - LOG_ERROR("Error allocating memory for %d threads", thread_list_size); - return ERROR_FAIL; - } - - int threadIdx = 0; - /* Look for ready tasks */ - for (int pri = 0; pri < max_used_priority; pri++) { - /* Get first item in queue */ - int64_t iterable = 0; - retval = target_read_buffer(rtos->target, - rtos->symbols[SYMBOL_ID_sListReady].address + (pri * param->rtos_list_size), param->pointer_width, - (uint8_t *) &iterable); - if (retval != ERROR_OK) - return retval; - for (; iterable && threadIdx < thread_list_size; threadIdx++) { - /* Get info from this iterable item */ - retval = embKernel_get_tasks_details(rtos, iterable, param, &rtos->thread_details[threadIdx], "Ready"); - if (retval != ERROR_OK) - return retval; - /* Get next iterable item */ - retval = target_read_buffer(rtos->target, iterable + param->iterable_next_offset, param->pointer_width, - (uint8_t *) &iterable); - if (retval != ERROR_OK) - return retval; - } - } - /* Look for sleeping tasks */ - int64_t iterable = 0; - retval = target_read_buffer(rtos->target, rtos->symbols[SYMBOL_ID_sListSleep].address, param->pointer_width, - (uint8_t *) &iterable); - if (retval != ERROR_OK) - return retval; - for (; iterable && threadIdx < thread_list_size; threadIdx++) { - /*Get info from this iterable item */ - retval = embKernel_get_tasks_details(rtos, iterable, param, &rtos->thread_details[threadIdx], "Sleeping"); - if (retval != ERROR_OK) - return retval; - /*Get next iterable item */ - retval = target_read_buffer(rtos->target, iterable + param->iterable_next_offset, param->pointer_width, - (uint8_t *) &iterable); - if (retval != ERROR_OK) - return retval; - } - - /* Look for suspended tasks */ - iterable = 0; - retval = target_read_buffer(rtos->target, rtos->symbols[SYMBOL_ID_sListSuspended].address, param->pointer_width, - (uint8_t *) &iterable); - if (retval != ERROR_OK) - return retval; - for (; iterable && threadIdx < thread_list_size; threadIdx++) { - /* Get info from this iterable item */ - retval = embKernel_get_tasks_details(rtos, iterable, param, &rtos->thread_details[threadIdx], "Suspended"); - if (retval != ERROR_OK) - return retval; - /*Get next iterable item */ - retval = target_read_buffer(rtos->target, iterable + param->iterable_next_offset, param->pointer_width, - (uint8_t *) &iterable); - if (retval != ERROR_OK) - return retval; - } - - rtos->thread_count = 0; - rtos->thread_count = threadIdx; - LOG_OUTPUT("Found %u tasks\n", (unsigned int)threadIdx); - return 0; -} - -static int embKernel_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, char **hex_reg_list) -{ - int retval; - const struct embKernel_params *param; - int64_t stack_ptr = 0; - - *hex_reg_list = NULL; - if (rtos == NULL) - return -1; - - if (thread_id == 0) - return -2; - - if (rtos->rtos_specific_params == NULL) - return -1; - - param = (const struct embKernel_params *) rtos->rtos_specific_params; - - /* Read the stack pointer */ - retval = target_read_buffer(rtos->target, thread_id + param->thread_stack_offset, param->pointer_width, - (uint8_t *) &stack_ptr); - if (retval != ERROR_OK) { - LOG_ERROR("Error reading stack frame from embKernel thread"); - return retval; - } - - return rtos_generic_stack_read(rtos->target, param->stacking_info, stack_ptr, hex_reg_list); -} - -static int embKernel_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[]) -{ - unsigned int i; - *symbol_list = calloc(ARRAY_SIZE(embKernel_symbol_list), sizeof(symbol_table_elem_t)); - - for (i = 0; i < ARRAY_SIZE(embKernel_symbol_list); i++) - (*symbol_list)[i].symbol_name = embKernel_symbol_list[i]; - - return 0; -} - diff --git a/src/rtos/linux.c b/src/rtos/linux.c deleted file mode 100644 index 8c150af..0000000 --- a/src/rtos/linux.c +++ /dev/null @@ -1,1594 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by STEricsson * - * Heythem Bouhaja heythem.bouhaja@stericsson.com : creation * - * Michel JAOUEN michel.jaouen@stericsson.com : adaptation to rtos * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * 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, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <helper/time_support.h> -#include <jtag/jtag.h> -#include "target/target.h" -#include "target/target_type.h" -#include "helper/log.h" -#include "helper/types.h" -#include "rtos.h" -#include "rtos_standard_stackings.h" -#include <target/register.h> -#include "server/gdb_server.h" - -#define LINUX_USER_KERNEL_BORDER 0xc0000000 -#include "linux_header.h" -#define PHYS -#define MAX_THREADS 200 -/* specific task */ -struct linux_os { - const char *name; - uint32_t init_task_addr; - int thread_count; - int threadid_count; - int preupdtate_threadid_count; - int nr_cpus; - int threads_lookup; - int threads_needs_update; - struct current_thread *current_threads; - struct threads *thread_list; - /* virt2phys parameter */ - uint32_t phys_mask; - uint32_t phys_base; -}; - -struct current_thread { - int64_t threadid; - int32_t core_id; -#ifdef PID_CHECK - uint32_t pid; -#endif - uint32_t TS; - struct current_thread *next; -}; - -struct threads { - char name[17]; - uint32_t base_addr; /* address to read magic */ - uint32_t state; /* magic value : filled only at creation */ - uint32_t pid; /* linux pid : id for identifying a thread */ - uint32_t oncpu; /* content cpu number in current thread */ - uint32_t asid; /* filled only at creation */ - int64_t threadid; - int status; /* dead = 1 alive = 2 current = 3 alive and current */ - /* value that should not change during the live of a thread ? */ - uint32_t thread_info_addr; /* contain latest thread_info_addr computed */ - /* retrieve from thread_info */ - struct cpu_context *context; - struct threads *next; -}; - -struct cpu_context { - uint32_t R4; - uint32_t R5; - uint32_t R6; - uint32_t R7; - uint32_t R8; - uint32_t R9; - uint32_t IP; - uint32_t FP; - uint32_t SP; - uint32_t PC; - uint32_t preempt_count; -}; -struct cpu_context *cpu_context_read(struct target *target, uint32_t base_addr, - uint32_t *info_addr); -static int insert_into_threadlist(struct target *target, struct threads *t); - -static int linux_os_create(struct target *target); - -static int linux_os_dummy_update(struct rtos *rtos) -{ - /* update is done only when thread request come - * too many thread to do it on each stop */ - return 0; -} - -static int linux_compute_virt2phys(struct target *target, uint32_t address) -{ - struct linux_os *linux_os = (struct linux_os *) - target->rtos->rtos_specific_params; - uint32_t pa = 0; - int retval = target->type->virt2phys(target, address, &pa); - if (retval != ERROR_OK) { - LOG_ERROR("Cannot compute linux virt2phys translation"); - /* fixes default address */ - linux_os->phys_base = 0; - return ERROR_FAIL; - } - - linux_os->init_task_addr = address; - address = address & linux_os->phys_mask; - linux_os->phys_base = pa - address; - return ERROR_OK; -} - -static int linux_read_memory(struct target *target, - uint32_t address, uint32_t size, uint32_t count, - uint8_t *buffer) -{ -#ifdef PHYS - struct linux_os *linux_os = (struct linux_os *) - target->rtos->rtos_specific_params; - uint32_t pa = (address & linux_os->phys_mask) + linux_os->phys_base; -#endif - if (address < 0xc000000) { - LOG_ERROR("linux awareness : address in user space"); - return ERROR_FAIL; - } -#ifdef PHYS - target_read_phys_memory(target, pa, size, count, buffer); -#endif - target_read_memory(target, address, size, count, buffer); - return ERROR_OK; -} - -static char *reg_converter(char *buffer, void *reg, int size) -{ - int i; - - for (i = 0; i < size; i++) - buffer += sprintf(buffer, "%02x", ((uint8_t *) reg)[i]); - - return buffer; -} - -int fill_buffer(struct target *target, uint32_t addr, uint8_t *buffer) -{ - - if ((addr & 0xfffffffc) != addr) - LOG_INFO("unaligned address %" PRIx32 "!!", addr); - - int retval = linux_read_memory(target, addr, 4, 1, buffer); - return retval; - -} - -uint32_t get_buffer(struct target *target, const uint8_t *buffer) -{ - uint32_t value = 0; - const uint8_t *value_ptr = buffer; - value = target_buffer_get_u32(target, value_ptr); - return value; -} - -static int linux_os_thread_reg_list(struct rtos *rtos, - int64_t thread_id, char **hex_reg_list) -{ - struct target *target = rtos->target; - struct linux_os *linux_os = (struct linux_os *) - target->rtos->rtos_specific_params; - int i = 0; - struct current_thread *tmp = linux_os->current_threads; - struct current_thread *next; - char *hex_string; - int found = 0; - int retval; - /* check if a current thread is requested */ - next = tmp; - - do { - if (next->threadid == thread_id) - found = 1; - else - next = next->next; - } while ((found == 0) && (next != tmp) && (next != NULL)); - - if (found == 1) { - /* search target to perfom the access */ - struct reg **reg_list; - int reg_list_size, reg_packet_size = 0; - struct target_list *head; - head = target->head; - found = 0; - do { - if (head->target->coreid == next->core_id) { - - target = head->target; - found = 1; - } else - head = head->next; - - } while ((head != (struct target_list *)NULL) && (found == 0)); - - if (found == 0) { - LOG_ERROR - ( - "current thread %" PRIx64 ": no target to perform access of core id %" PRIx32, - thread_id, - next->core_id); - return ERROR_FAIL; - } - - /*LOG_INFO("thread %lx current on core %x",thread_id, - * target->coreid);*/ - retval = - target_get_gdb_reg_list(target, ®_list, ®_list_size, - REG_CLASS_GENERAL); - - if (retval != ERROR_OK) - return retval; - - for (i = 0; i < reg_list_size; i++) - reg_packet_size += reg_list[i]->size; - - assert(reg_packet_size > 0); - - *hex_reg_list = malloc(DIV_ROUND_UP(reg_packet_size, 8) * 2); - - hex_string = *hex_reg_list; - - for (i = 0; i < reg_list_size; i++) { - if (!reg_list[i]->valid) - reg_list[i]->type->get(reg_list[i]); - - hex_string = reg_converter(hex_string, - reg_list[i]->value, - (reg_list[i]->size) / 8); - } - - free(reg_list); - - } else { - struct threads *temp = linux_os->thread_list; - *hex_reg_list = calloc(1, 500 * sizeof(char)); - hex_string = *hex_reg_list; - - for (i = 0; i < 16; i++) - hex_string += sprintf(hex_string, "%02x", 0); - - while ((temp != NULL) && - (temp->threadid != target->rtos->current_threadid)) - temp = temp->next; - - if (temp != NULL) { - if (temp->context == NULL) - temp->context = cpu_context_read(target, - temp-> - base_addr, - &temp-> - thread_info_addr); - - hex_string = - reg_converter(hex_string, &temp->context->R4, 4); - hex_string = - reg_converter(hex_string, &temp->context->R5, 4); - hex_string = - reg_converter(hex_string, &temp->context->R6, 4); - hex_string = - reg_converter(hex_string, &temp->context->R7, 4); - hex_string = - reg_converter(hex_string, &temp->context->R8, 4); - hex_string = - reg_converter(hex_string, &temp->context->R9, 4); - - for (i = 0; i < 4; i++) /*R10 = 0x0 */ - hex_string += sprintf(hex_string, "%02x", 0); - - hex_string = - reg_converter(hex_string, &temp->context->FP, 4); - hex_string = - reg_converter(hex_string, &temp->context->IP, 4); - hex_string = - reg_converter(hex_string, &temp->context->SP, 4); - - for (i = 0; i < 4; i++) - hex_string += sprintf(hex_string, "%02x", 0); - - hex_string = - reg_converter(hex_string, &temp->context->PC, 4); - - for (i = 0; i < 100; i++) /*100 */ - hex_string += sprintf(hex_string, "%02x", 0); - - uint32_t cpsr = 0x00000000; - reg_converter(hex_string, &cpsr, 4); - } - } - return ERROR_OK; -} - -static int linux_os_detect(struct target *target) -{ - LOG_INFO("should no be called"); - return 0; -} - -static int linux_os_smp_init(struct target *target); -static int linux_os_clean(struct target *target); -#define INIT_TASK 0 -static const char * const linux_symbol_list[] = { - "init_task", - NULL -}; - -static int linux_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[]) -{ - unsigned int i; - *symbol_list = (symbol_table_elem_t *) - calloc(ARRAY_SIZE(linux_symbol_list), sizeof(symbol_table_elem_t)); - - for (i = 0; i < ARRAY_SIZE(linux_symbol_list); i++) - (*symbol_list)[i].symbol_name = linux_symbol_list[i]; - - return 0; -} - -static char *linux_ps_command(struct target *target); - -const struct rtos_type Linux_os = { - .name = "linux", - .detect_rtos = linux_os_detect, - .create = linux_os_create, - .smp_init = linux_os_smp_init, - .update_threads = linux_os_dummy_update, - .get_thread_reg_list = linux_os_thread_reg_list, - .get_symbol_list_to_lookup = linux_get_symbol_list_to_lookup, - .clean = linux_os_clean, - .ps_command = linux_ps_command, -}; - -static int linux_thread_packet(struct connection *connection, char const *packet, - int packet_size); -static void linux_identify_current_threads(struct target *target); - -#ifdef PID_CHECK -int fill_task_pid(struct target *target, struct threads *t) -{ - uint32_t pid_addr = t->base_addr + PID; - uint8_t buffer[4]; - int retval = fill_buffer(target, pid_addr, buffer); - - if (retval == ERROR_OK) { - uint32_t val = get_buffer(target, buffer); - t->pid = val; - } else - LOG_ERROR("fill_task_pid: unable to read memory"); - - return retval; -} -#endif - -int fill_task(struct target *target, struct threads *t) -{ - int retval; - uint32_t pid_addr = t->base_addr + PID; - uint32_t mem_addr = t->base_addr + MEM; - uint32_t on_cpu = t->base_addr + ONCPU; - uint8_t *buffer = calloc(1, 4); - retval = fill_buffer(target, t->base_addr, buffer); - - if (retval == ERROR_OK) { - uint32_t val = get_buffer(target, buffer); - t->state = val; - } else - LOG_ERROR("fill_task: unable to read memory"); - - retval = fill_buffer(target, pid_addr, buffer); - - if (retval == ERROR_OK) { - uint32_t val = get_buffer(target, buffer); - t->pid = val; - } else - LOG_ERROR("fill task: unable to read memory"); - - retval = fill_buffer(target, on_cpu, buffer); - - if (retval == ERROR_OK) { - uint32_t val = get_buffer(target, buffer); - t->oncpu = val; - } else - LOG_ERROR("fill task: unable to read memory"); - - retval = fill_buffer(target, mem_addr, buffer); - - if (retval == ERROR_OK) { - uint32_t val = get_buffer(target, buffer); - - if (val != 0) { - uint32_t asid_addr = val + MM_CTX; - retval = fill_buffer(target, asid_addr, buffer); - - if (retval == ERROR_OK) { - val = get_buffer(target, buffer); - t->asid = val; - } else - LOG_ERROR - ("fill task: unable to read memory -- ASID"); - } else - t->asid = 0; - } else - LOG_ERROR("fill task: unable to read memory"); - - free(buffer); - - return retval; -} - -int get_name(struct target *target, struct threads *t) -{ - int retval; - uint32_t full_name[4]; - uint32_t comm = t->base_addr + COMM; - int i; - - for (i = 0; i < 17; i++) - t->name[i] = 0; - - retval = linux_read_memory(target, comm, 4, 4, (uint8_t *) full_name); - - if (retval != ERROR_OK) { - LOG_ERROR("get_name: unable to read memory\n"); - return ERROR_FAIL; - } - - uint32_t raw_name = target_buffer_get_u32(target, - (const uint8_t *) - &full_name[0]); - t->name[3] = raw_name >> 24; - t->name[2] = raw_name >> 16; - t->name[1] = raw_name >> 8; - t->name[0] = raw_name; - raw_name = - target_buffer_get_u32(target, (const uint8_t *)&full_name[1]); - t->name[7] = raw_name >> 24; - t->name[6] = raw_name >> 16; - t->name[5] = raw_name >> 8; - t->name[4] = raw_name; - raw_name = - target_buffer_get_u32(target, (const uint8_t *)&full_name[2]); - t->name[11] = raw_name >> 24; - t->name[10] = raw_name >> 16; - t->name[9] = raw_name >> 8; - t->name[8] = raw_name; - raw_name = - target_buffer_get_u32(target, (const uint8_t *)&full_name[3]); - t->name[15] = raw_name >> 24; - t->name[14] = raw_name >> 16; - t->name[13] = raw_name >> 8; - t->name[12] = raw_name; - return ERROR_OK; - -} - -int get_current(struct target *target, int create) -{ - struct target_list *head; - head = target->head; - uint8_t *buf; - uint32_t val; - uint32_t ti_addr; - uint8_t *buffer = calloc(1, 4); - struct linux_os *linux_os = (struct linux_os *) - target->rtos->rtos_specific_params; - struct current_thread *ctt = linux_os->current_threads; - - /* invalid current threads content */ - while (ctt != NULL) { - ctt->threadid = -1; - ctt->TS = 0xdeadbeef; - ctt = ctt->next; - } - - while (head != (struct target_list *)NULL) { - struct reg **reg_list; - int reg_list_size; - int retval; - - if (target_get_gdb_reg_list(head->target, ®_list, - ®_list_size, REG_CLASS_GENERAL) != ERROR_OK) { - free(buffer); - return ERROR_TARGET_FAILURE; - } - - if (!reg_list[13]->valid) - reg_list[13]->type->get(reg_list[13]); - - buf = reg_list[13]->value; - val = get_buffer(target, buf); - ti_addr = (val & 0xffffe000); - uint32_t TS_addr = ti_addr + 0xc; - retval = fill_buffer(target, TS_addr, buffer); - - if (retval == ERROR_OK) { - uint32_t TS = get_buffer(target, buffer); - uint32_t cpu, on_cpu = TS + ONCPU; - retval = fill_buffer(target, on_cpu, buffer); - - if (retval == ERROR_OK) { - /*uint32_t cpu = get_buffer(target, buffer);*/ - struct current_thread *ct = - linux_os->current_threads; - cpu = head->target->coreid; - - while ((ct != NULL) && (ct->core_id != (int32_t) cpu)) - ct = ct->next; - - if ((ct != NULL) && (ct->TS == 0xdeadbeef)) - ct->TS = TS; - else - LOG_ERROR - ("error in linux current thread update"); - - if (create && ct) { - struct threads *t; - t = calloc(1, sizeof(struct threads)); - t->base_addr = ct->TS; - fill_task(target, t); - get_name(target, t); - t->oncpu = cpu; - insert_into_threadlist(target, t); - t->status = 3; - t->thread_info_addr = 0xdeadbeef; - ct->threadid = t->threadid; - linux_os->thread_count++; -#ifdef PID_CHECK - ct->pid = t->pid; -#endif - /*LOG_INFO("Creation of current thread %s",t->name);*/ - } - } - } - - free(reg_list); - head = head->next; - } - - free(buffer); - - return ERROR_OK; -} - -struct cpu_context *cpu_context_read(struct target *target, uint32_t base_addr, - uint32_t *thread_info_addr_old) -{ - struct cpu_context *context = calloc(1, sizeof(struct cpu_context)); - uint32_t preempt_count_addr = 0; - uint32_t registers[10]; - uint8_t *buffer = calloc(1, 4); - uint32_t stack = base_addr + QAT; - uint32_t thread_info_addr = 0; - uint32_t thread_info_addr_update = 0; - int retval = ERROR_FAIL; - context->R4 = 0xdeadbeef; - context->R5 = 0xdeadbeef; - context->R6 = 0xdeadbeef; - context->R7 = 0xdeadbeef; - context->R8 = 0xdeadbeef; - context->R9 = 0xdeadbeef; - context->IP = 0xdeadbeef; - context->FP = 0xdeadbeef; - context->SP = 0xdeadbeef; - context->PC = 0xdeadbeef; -retry: - - if (*thread_info_addr_old == 0xdeadbeef) { - retval = fill_buffer(target, stack, buffer); - - if (retval == ERROR_OK) - thread_info_addr = get_buffer(target, buffer); - else - LOG_ERROR("cpu_context: unable to read memory"); - - thread_info_addr_update = thread_info_addr; - } else - thread_info_addr = *thread_info_addr_old; - - preempt_count_addr = thread_info_addr + PREEMPT; - retval = fill_buffer(target, preempt_count_addr, buffer); - - if (retval == ERROR_OK) - context->preempt_count = get_buffer(target, buffer); - else { - if (*thread_info_addr_old != 0xdeadbeef) { - LOG_ERROR - ("cpu_context: cannot read at thread_info_addr"); - - if (*thread_info_addr_old < LINUX_USER_KERNEL_BORDER) - LOG_INFO - ("cpu_context : thread_info_addr in userspace!!!"); - - *thread_info_addr_old = 0xdeadbeef; - goto retry; - } - - LOG_ERROR("cpu_context: unable to read memory"); - } - - thread_info_addr += CPU_CONT; - - retval = linux_read_memory(target, thread_info_addr, 4, 10, - (uint8_t *) registers); - - if (retval != ERROR_OK) { - free(buffer); - LOG_ERROR("cpu_context: unable to read memory\n"); - return context; - } - - context->R4 = - target_buffer_get_u32(target, (const uint8_t *)®isters[0]); - context->R5 = - target_buffer_get_u32(target, (const uint8_t *)®isters[1]); - context->R6 = - target_buffer_get_u32(target, (const uint8_t *)®isters[2]); - context->R7 = - target_buffer_get_u32(target, (const uint8_t *)®isters[3]); - context->R8 = - target_buffer_get_u32(target, (const uint8_t *)®isters[4]); - context->R9 = - target_buffer_get_u32(target, (const uint8_t *)®isters[5]); - context->IP = - target_buffer_get_u32(target, (const uint8_t *)®isters[6]); - context->FP = - target_buffer_get_u32(target, (const uint8_t *)®isters[7]); - context->SP = - target_buffer_get_u32(target, (const uint8_t *)®isters[8]); - context->PC = - target_buffer_get_u32(target, (const uint8_t *)®isters[9]); - - if (*thread_info_addr_old == 0xdeadbeef) - *thread_info_addr_old = thread_info_addr_update; - - free(buffer); - - return context; -} - -uint32_t next_task(struct target *target, struct threads *t) -{ - uint8_t *buffer = calloc(1, 4); - uint32_t next_addr = t->base_addr + NEXT; - int retval = fill_buffer(target, next_addr, buffer); - - if (retval == ERROR_OK) { - uint32_t val = get_buffer(target, buffer); - val = val - NEXT; - free(buffer); - return val; - } else - LOG_ERROR("next task: unable to read memory"); - - free(buffer); - - return 0; -} - -struct current_thread *add_current_thread(struct current_thread *currents, - struct current_thread *ct) -{ - ct->next = NULL; - - if (currents == NULL) { - currents = ct; - return currents; - } else { - struct current_thread *temp = currents; - - while (temp->next != NULL) - temp = temp->next; - - temp->next = ct; - return currents; - } -} - -struct threads *liste_del_task(struct threads *task_list, struct threads **t, - struct threads *prev) -{ - LOG_INFO("del task %" PRId64, (*t)->threadid); - prev->next = (*t)->next; - - if (prev == task_list) - task_list = prev; - - /* free content of threads */ - if ((*t)->context) - free((*t)->context); - - free(*t); - *t = prev; - return task_list; -} - -struct threads *liste_add_task(struct threads *task_list, struct threads *t, - struct threads **last) -{ - t->next = NULL; - - if (*last == NULL) - if (task_list == NULL) { - task_list = t; - return task_list; - } else { - struct threads *temp = task_list; - - while (temp->next != NULL) - temp = temp->next; - - temp->next = t; - *last = t; - return task_list; - } else { - (*last)->next = t; - *last = t; - return task_list; - } -} - -#ifdef PID_CHECK -static int current_pid(struct linux_os *linux_os, uint32_t pid) -#else -static int current_base_addr(struct linux_os *linux_os, uint32_t base_addr) -#endif -{ - struct current_thread *ct = linux_os->current_threads; -#ifdef PID_CHECK - - while ((ct != NULL) && (ct->pid != pid)) -#else - while ((ct != NULL) && (ct->TS != base_addr)) -#endif - ct = ct->next; -#ifdef PID_CHECK - if ((ct != NULL) && (ct->pid == pid)) -#else - if ((ct != NULL) && (ct->TS == base_addr)) -#endif - return 1; - - return 0; -} - -int linux_get_tasks(struct target *target, int context) -{ - int loop = 0; - int retval = 0; - struct linux_os *linux_os = (struct linux_os *) - target->rtos->rtos_specific_params; - linux_os->thread_list = NULL; - linux_os->thread_count = 0; - - if (linux_os->init_task_addr == 0xdeadbeef) { - LOG_INFO("no init symbol\n"); - return ERROR_FAIL; - } - - int64_t start = timeval_ms(); - - struct threads *t = calloc(1, sizeof(struct threads)); - struct threads *last = NULL; - t->base_addr = linux_os->init_task_addr; - /* retrieve the thread id , currently running in the different smp core */ - get_current(target, 1); - - while (((t->base_addr != linux_os->init_task_addr) && - (t->base_addr != 0)) || (loop == 0)) { - loop++; - fill_task(target, t); - retval = get_name(target, t); - - if (loop > MAX_THREADS) { - free(t); - LOG_INFO("more than %d threads !!", MAX_THREADS); - return ERROR_FAIL; - } - - if (retval != ERROR_OK) { - free(t); - return ERROR_FAIL; - } - - /* check that this thread is not one the current threads already - * created */ -#ifdef PID_CHECK - - if (!current_pid(linux_os, t->pid)) { -#else - if (!current_base_addr(linux_os, t->base_addr)) { -#endif - t->threadid = linux_os->threadid_count; - t->status = 1; - linux_os->threadid_count++; - - linux_os->thread_list = - liste_add_task(linux_os->thread_list, t, &last); - /* no interest to fill the context if it is a current thread. */ - linux_os->thread_count++; - t->thread_info_addr = 0xdeadbeef; - - if (context) - t->context = - cpu_context_read(target, t->base_addr, - &t->thread_info_addr); - } else { - /*LOG_INFO("thread %s is a current thread already created",t->name); */ - free(t); - } - - uint32_t base_addr = next_task(target, t); - t = calloc(1, sizeof(struct threads)); - t->base_addr = base_addr; - } - - linux_os->threads_lookup = 1; - linux_os->threads_needs_update = 0; - linux_os->preupdtate_threadid_count = linux_os->threadid_count - 1; - /* check that all current threads have been identified */ - - LOG_INFO("complete time %" PRId64 ", thread mean %" PRId64 "\n", - (timeval_ms() - start), - (timeval_ms() - start) / linux_os->threadid_count); - - LOG_INFO("threadid count %d", linux_os->threadid_count); - free(t); - - return ERROR_OK; -} - -static int clean_threadlist(struct target *target) -{ - struct linux_os *linux_os = (struct linux_os *) - target->rtos->rtos_specific_params; - struct threads *old, *temp = linux_os->thread_list; - - while (temp != NULL) { - old = temp; - - if (temp->context) - free(temp->context); - - temp = temp->next; - free(old); - } - - return ERROR_OK; -} - -static int linux_os_clean(struct target *target) -{ - struct linux_os *os_linux = (struct linux_os *) - target->rtos->rtos_specific_params; - clean_threadlist(target); - os_linux->init_task_addr = 0xdeadbeef; - os_linux->name = "linux"; - os_linux->thread_list = NULL; - os_linux->thread_count = 0; - os_linux->nr_cpus = 0; - os_linux->threads_lookup = 0; - os_linux->threads_needs_update = 0; - os_linux->threadid_count = 1; - return ERROR_OK; -} - -static int insert_into_threadlist(struct target *target, struct threads *t) -{ - struct linux_os *linux_os = (struct linux_os *) - target->rtos->rtos_specific_params; - struct threads *temp = linux_os->thread_list; - t->threadid = linux_os->threadid_count; - linux_os->threadid_count++; - t->status = 1; - t->next = NULL; - - if (temp == NULL) - linux_os->thread_list = t; - else { - while (temp->next != NULL) - temp = temp->next; - - t->next = NULL; - temp->next = t; - } - - return ERROR_OK; -} - -static void linux_identify_current_threads(struct target *target) -{ - struct linux_os *linux_os = (struct linux_os *) - target->rtos->rtos_specific_params; - struct threads *thread_list = linux_os->thread_list; - struct current_thread *ct = linux_os->current_threads; - struct threads *t = NULL; - - while ((ct != NULL)) { - if (ct->threadid == -1) { - - /* un-identified thread */ - int found = 0; - t = calloc(1, sizeof(struct threads)); - t->base_addr = ct->TS; -#ifdef PID_CHECK - - if (fill_task_pid(target, t) != ERROR_OK) { -error_handling: - free(t); - LOG_ERROR - ("linux identify_current_threads: unable to read pid"); - return; - } -#endif - - /* search in the list of threads if pid - already present */ - while ((thread_list != NULL) && (found == 0)) { -#ifdef PID_CHECK - if (thread_list->pid == t->pid) { -#else - if (thread_list->base_addr == t->base_addr) { -#endif - free(t); - t = thread_list; - found = 1; - } - thread_list = thread_list->next; - } - - if (!found) { - /* it is a new thread */ - if (fill_task(target, t) != ERROR_OK) - goto error_handling; - - get_name(target, t); - insert_into_threadlist(target, t); - t->thread_info_addr = 0xdeadbeef; - } - - t->status = 3; - ct->threadid = t->threadid; -#ifdef PID_CHECK - ct->pid = t->pid; -#endif - linux_os->thread_count++; -#if 0 - if (found == 0) - LOG_INFO("current thread core %x identified %s", - ct->core_id, t->name); - else - LOG_INFO("current thread core %x, reused %s", - ct->core_id, t->name); -#endif - } -#if 0 - else { - struct threads tmp; - tmp.base_addr = ct->TS; - get_name(target, &tmp); - LOG_INFO("current thread core %x , already identified %s !!!", - ct->core_id, tmp.name); - } -#endif - ct = ct->next; - } - - return; -#ifndef PID_CHECK -error_handling: - free(t); - LOG_ERROR("unable to read pid"); - return; - -#endif -} - -static int linux_task_update(struct target *target, int context) -{ - struct linux_os *linux_os = (struct linux_os *) - target->rtos->rtos_specific_params; - struct threads *thread_list = linux_os->thread_list; - int retval; - int loop = 0; - linux_os->thread_count = 0; - - /*thread_list = thread_list->next; skip init_task*/ - while (thread_list != NULL) { - thread_list->status = 0; /*setting all tasks to dead state*/ - - if (thread_list->context) { - free(thread_list->context); - thread_list->context = NULL; - } - - thread_list = thread_list->next; - } - - int found = 0; - - if (linux_os->init_task_addr == 0xdeadbeef) { - LOG_INFO("no init symbol\n"); - return ERROR_FAIL; - } - int64_t start = timeval_ms(); - struct threads *t = calloc(1, sizeof(struct threads)); - uint32_t previous = 0xdeadbeef; - t->base_addr = linux_os->init_task_addr; - retval = get_current(target, 0); - /*check that all current threads have been identified */ - linux_identify_current_threads(target); - - while (((t->base_addr != linux_os->init_task_addr) && - (t->base_addr != previous)) || (loop == 0)) { - /* for avoiding any permanent loop for any reason possibly due to - * target */ - loop++; - previous = t->base_addr; - /* read only pid */ -#ifdef PID_CHECK - retval = fill_task_pid(target, t); -#endif - - if (retval != ERROR_OK) { - free(t); - return ERROR_FAIL; - } - - thread_list = linux_os->thread_list; - - while (thread_list != NULL) { -#ifdef PID_CHECK - if (t->pid == thread_list->pid) { -#else - if (t->base_addr == thread_list->base_addr) { -#endif - if (!thread_list->status) { -#ifdef PID_CHECK - if (t->base_addr != thread_list->base_addr) - LOG_INFO("thread base_addr has changed !!"); -#endif - /* this is not a current thread */ - thread_list->base_addr = t->base_addr; - thread_list->status = 1; - - /* we don 't update this field any more */ - - /*thread_list->state = t->state; - thread_list->oncpu = t->oncpu; - thread_list->asid = t->asid; - */ - if (context) - thread_list->context = - cpu_context_read(target, - thread_list-> - base_addr, - &thread_list-> - thread_info_addr); - } else { - /* it is a current thread no need to read context */ - } - - linux_os->thread_count++; - found = 1; - break; - } else { - found = 0; - thread_list = thread_list->next; - } - } - - if (found == 0) { - uint32_t base_addr; - fill_task(target, t); - get_name(target, t); - retval = insert_into_threadlist(target, t); - t->thread_info_addr = 0xdeadbeef; - - if (context) - t->context = - cpu_context_read(target, t->base_addr, - &t->thread_info_addr); - - base_addr = next_task(target, t); - t = calloc(1, sizeof(struct threads)); - t->base_addr = base_addr; - linux_os->thread_count++; - } else - t->base_addr = next_task(target, t); - } - - LOG_INFO("update thread done %" PRId64 ", mean%" PRId64 "\n", - (timeval_ms() - start), (timeval_ms() - start) / loop); - free(t); - linux_os->threads_needs_update = 0; - return ERROR_OK; -} - -int linux_gdb_thread_packet(struct target *target, - struct connection *connection, char const *packet, - int packet_size) -{ - int retval; - struct linux_os *linux_os = - (struct linux_os *)target->rtos->rtos_specific_params; - - if (linux_os->init_task_addr == 0xdeadbeef) { - /* it has not been initialized */ - LOG_INFO("received thread request without init task address"); - gdb_put_packet(connection, "l", 1); - return ERROR_OK; - } - - retval = linux_get_tasks(target, 1); - - if (retval != ERROR_OK) - return ERROR_TARGET_FAILURE; - - char *out_str = calloc(1, 350 * sizeof(int64_t)); - char *tmp_str = out_str; - tmp_str += sprintf(tmp_str, "m"); - struct threads *temp = linux_os->thread_list; - - while (temp != NULL) { - tmp_str += sprintf(tmp_str, "%016" PRIx64, temp->threadid); - temp = temp->next; - if (temp) - tmp_str += sprintf(tmp_str, ","); - } - - gdb_put_packet(connection, out_str, strlen(out_str)); - free(out_str); - return ERROR_OK; -} - -int linux_gdb_thread_update(struct target *target, - struct connection *connection, char const *packet, - int packet_size) -{ - int found = 0; - struct linux_os *linux_os = (struct linux_os *) - target->rtos->rtos_specific_params; - struct threads *temp = linux_os->thread_list; - - while (temp != NULL) { - if (temp->threadid == linux_os->preupdtate_threadid_count + 1) { - /*LOG_INFO("FOUND");*/ - found = 1; - break; - } else - temp = temp->next; - } - - if (found == 1) { - /*LOG_INFO("INTO GDB THREAD UPDATE FOUNDING START TASK");*/ - char *out_strr = calloc(1, 350 * sizeof(int64_t)); - char *tmp_strr = out_strr; - tmp_strr += sprintf(tmp_strr, "m"); - /*LOG_INFO("CHAR MALLOC & M DONE");*/ - tmp_strr += sprintf(tmp_strr, "%016" PRIx64, temp->threadid); - - temp = temp->next; - - while (temp != NULL) { - /*LOG_INFO("INTO GDB THREAD UPDATE WHILE");*/ - tmp_strr += sprintf(tmp_strr, ","); - tmp_strr += - sprintf(tmp_strr, "%016" PRIx64, temp->threadid); - temp = temp->next; - } - - /*tmp_str[0] = 0;*/ - gdb_put_packet(connection, out_strr, strlen(out_strr)); - linux_os->preupdtate_threadid_count = - linux_os->threadid_count - 1; - free(out_strr); - } else - gdb_put_packet(connection, "l", 1); - - return ERROR_OK; -} - -int linux_thread_extra_info(struct target *target, - struct connection *connection, char const *packet, - int packet_size) -{ - int64_t threadid = 0; - struct linux_os *linux_os = (struct linux_os *) - target->rtos->rtos_specific_params; - sscanf(packet, "qThreadExtraInfo,%" SCNx64, &threadid); - /*LOG_INFO("lookup extra info for thread %" SCNx64, threadid);*/ - struct threads *temp = linux_os->thread_list; - - while (temp != NULL) { - if (temp->threadid == threadid) { - char *pid = " PID: "; - char *pid_current = "*PID: "; - char *name = "NAME: "; - int str_size = strlen(pid) + strlen(name); - char *tmp_str = calloc(1, str_size + 50); - char *tmp_str_ptr = tmp_str; - - /* discriminate current task */ - if (temp->status == 3) - tmp_str_ptr += sprintf(tmp_str_ptr, "%s", - pid_current); - else - tmp_str_ptr += sprintf(tmp_str_ptr, "%s", pid); - - tmp_str_ptr += - sprintf(tmp_str_ptr, "%d", (int)temp->pid); - tmp_str_ptr += sprintf(tmp_str_ptr, "%s", " | "); - sprintf(tmp_str_ptr, "%s", name); - sprintf(tmp_str_ptr, "%s", temp->name); - char *hex_str = calloc(1, strlen(tmp_str) * 2 + 1); - int pkt_len = hexify(hex_str, tmp_str, 0, strlen(tmp_str) * 2 + 1); - gdb_put_packet(connection, hex_str, pkt_len); - free(hex_str); - free(tmp_str); - return ERROR_OK; - } - - temp = temp->next; - } - - LOG_INFO("thread not found"); - return ERROR_OK; -} - -int linux_gdb_T_packet(struct connection *connection, - struct target *target, char const *packet, int packet_size) -{ - int64_t threadid; - struct linux_os *linux_os = (struct linux_os *) - target->rtos->rtos_specific_params; - int retval = ERROR_OK; - sscanf(packet, "T%" SCNx64, &threadid); - - if (linux_os->threads_needs_update == 0) { - struct threads *temp = linux_os->thread_list; - struct threads *prev = linux_os->thread_list; - - while (temp != NULL) { - if (temp->threadid == threadid) { - if (temp->status != 0) { - gdb_put_packet(connection, "OK", 2); - return ERROR_OK; - } else { - /* delete item in the list */ - linux_os->thread_list = - liste_del_task(linux_os-> - thread_list, &temp, - prev); - linux_os->thread_count--; - gdb_put_packet(connection, "E01", 3); - return ERROR_OK; - } - } - - /* for deletion */ - prev = temp; - temp = temp->next; - } - - LOG_INFO("gdb requested status on non existing thread"); - gdb_put_packet(connection, "E01", 3); - return ERROR_OK; - - } else { - retval = linux_task_update(target, 1); - struct threads *temp = linux_os->thread_list; - - while (temp != NULL) { - if (temp->threadid == threadid) { - if (temp->status == 1) { - gdb_put_packet(connection, "OK", 2); - return ERROR_OK; - } else { - gdb_put_packet(connection, "E01", 3); - return ERROR_OK; - } - } - - temp = temp->next; - } - } - - return retval; -} - -int linux_gdb_h_packet(struct connection *connection, - struct target *target, char const *packet, int packet_size) -{ - struct linux_os *linux_os = (struct linux_os *) - target->rtos->rtos_specific_params; - struct current_thread *ct = linux_os->current_threads; - - /* select to display the current thread of the selected target */ - while ((ct != NULL) && (ct->core_id != target->coreid)) - ct = ct->next; - - int64_t current_gdb_thread_rq; - - if (linux_os->threads_lookup == 1) { - if ((ct != NULL) && (ct->threadid == -1)) { - ct = linux_os->current_threads; - - while ((ct != NULL) && (ct->threadid == -1)) - ct = ct->next; - } - - if (ct == NULL) { - /* no current thread can be identified - * any way with smp */ - LOG_INFO("no current thread identified"); - /* attempt to display the name of the 2 threads identified with - * get_current */ - struct threads t; - ct = linux_os->current_threads; - - while ((ct != NULL) && (ct->threadid == -1)) { - t.base_addr = ct->TS; - get_name(target, &t); - LOG_INFO("name of unidentified thread %s", - t.name); - ct = ct->next; - } - - gdb_put_packet(connection, "OK", 2); - return ERROR_OK; - } - - if (packet[1] == 'g') { - sscanf(packet, "Hg%16" SCNx64, ¤t_gdb_thread_rq); - - if (current_gdb_thread_rq == 0) { - target->rtos->current_threadid = ct->threadid; - gdb_put_packet(connection, "OK", 2); - } else { - target->rtos->current_threadid = - current_gdb_thread_rq; - gdb_put_packet(connection, "OK", 2); - } - } else if (packet[1] == 'c') { - sscanf(packet, "Hc%16" SCNx64, ¤t_gdb_thread_rq); - - if ((current_gdb_thread_rq == 0) || - (current_gdb_thread_rq == ct->threadid)) { - target->rtos->current_threadid = ct->threadid; - gdb_put_packet(connection, "OK", 2); - } else - gdb_put_packet(connection, "E01", 3); - } - } else - gdb_put_packet(connection, "OK", 2); - - return ERROR_OK; -} - -static int linux_thread_packet(struct connection *connection, char const *packet, - int packet_size) -{ - int retval = ERROR_OK; - struct current_thread *ct; - struct target *target = get_target_from_connection(connection); - struct linux_os *linux_os = (struct linux_os *) - target->rtos->rtos_specific_params; - - switch (packet[0]) { - case 'T': /* Is thread alive?*/ - - linux_gdb_T_packet(connection, target, packet, packet_size); - break; - case 'H': /* Set current thread */ - /* ( 'c' for step and continue, 'g' for all other operations )*/ - /*LOG_INFO(" H packet received '%s'", packet);*/ - linux_gdb_h_packet(connection, target, packet, packet_size); - break; - case 'q': - - if (strncmp(packet, "qSymbol", 7) == 0) { - if (rtos_qsymbol(connection, packet, packet_size) == 1) { - linux_compute_virt2phys(target, - target->rtos-> - symbols[INIT_TASK]. - address); - } - - break; - } else if (strncmp(packet, "qfThreadInfo", 12) == 0) { - if (linux_os->thread_list == NULL) { - retval = linux_gdb_thread_packet(target, - connection, - packet, - packet_size); - break; - } else { - retval = linux_gdb_thread_update(target, - connection, - packet, - packet_size); - break; - } - } else if (strncmp(packet, "qsThreadInfo", 12) == 0) { - gdb_put_packet(connection, "l", 1); - break; - } else if (strncmp(packet, "qThreadExtraInfo,", 17) == 0) { - linux_thread_extra_info(target, connection, packet, - packet_size); - break; - } else { - retval = GDB_THREAD_PACKET_NOT_CONSUMED; - break; - } - - case 'Q': - /* previously response was : thread not found - * gdb_put_packet(connection, "E01", 3); */ - retval = GDB_THREAD_PACKET_NOT_CONSUMED; - break; - case 'c': - case 's': { - if (linux_os->threads_lookup == 1) { - ct = linux_os->current_threads; - - while ((ct != NULL) && (ct->core_id) != target->coreid) - ct = ct->next; - - if ((ct != NULL) && (ct->threadid == -1)) { - ct = linux_os->current_threads; - - while ((ct != NULL) && (ct->threadid == -1)) - ct = ct->next; - } - - if ((ct != NULL) && (ct->threadid != - target->rtos-> - current_threadid) - && (target->rtos->current_threadid != -1)) - LOG_WARNING("WARNING! current GDB thread do not match" \ - "current thread running." \ - "Switch thread in GDB to threadid %d", - (int)ct->threadid); - - LOG_INFO("threads_needs_update = 1"); - linux_os->threads_needs_update = 1; - } - } - - /* if a packet handler returned an error, exit input loop */ - if (retval != ERROR_OK) - return retval; - } - - return retval; -} - -static int linux_os_smp_init(struct target *target) -{ - struct target_list *head; - /* keep only target->rtos */ - struct rtos *rtos = target->rtos; - struct linux_os *os_linux = - (struct linux_os *)rtos->rtos_specific_params; - struct current_thread *ct; - head = target->head; - - while (head != (struct target_list *)NULL) { - if (head->target->rtos != rtos) { - struct linux_os *smp_os_linux = - (struct linux_os *)head->target->rtos-> - rtos_specific_params; - /* remap smp target on rtos */ - free(head->target->rtos); - head->target->rtos = rtos; - /* reuse allocated ct */ - ct = smp_os_linux->current_threads; - ct->threadid = -1; - ct->TS = 0xdeadbeef; - ct->core_id = head->target->coreid; - os_linux->current_threads = - add_current_thread(os_linux->current_threads, ct); - os_linux->nr_cpus++; - free(smp_os_linux); - } - - head = head->next; - } - - return ERROR_OK; -} - -static int linux_os_create(struct target *target) -{ - struct linux_os *os_linux = calloc(1, sizeof(struct linux_os)); - struct current_thread *ct = calloc(1, sizeof(struct current_thread)); - LOG_INFO("linux os creation\n"); - os_linux->init_task_addr = 0xdeadbeef; - os_linux->name = "linux"; - os_linux->thread_list = NULL; - os_linux->thread_count = 0; - target->rtos->current_threadid = -1; - os_linux->nr_cpus = 1; - os_linux->threads_lookup = 0; - os_linux->threads_needs_update = 0; - os_linux->threadid_count = 1; - os_linux->current_threads = NULL; - target->rtos->rtos_specific_params = os_linux; - ct->core_id = target->coreid; - ct->threadid = -1; - ct->TS = 0xdeadbeef; - os_linux->current_threads = - add_current_thread(os_linux->current_threads, ct); - /* overload rtos thread default handler */ - target->rtos->gdb_thread_packet = linux_thread_packet; - /* initialize a default virt 2 phys translation */ - os_linux->phys_mask = ~0xc0000000; - os_linux->phys_base = 0x0; - return JIM_OK; -} - -static char *linux_ps_command(struct target *target) -{ - struct linux_os *linux_os = (struct linux_os *) - target->rtos->rtos_specific_params; - int retval = ERROR_OK; - char *display; - - if (linux_os->threads_lookup == 0) - retval = linux_get_tasks(target, 1); - else { - if (linux_os->threads_needs_update != 0) - retval = linux_task_update(target, 0); - } - - if (retval == ERROR_OK) { - struct threads *temp = linux_os->thread_list; - char *tmp; - LOG_INFO("allocation for %d threads line", - linux_os->thread_count); - display = calloc((linux_os->thread_count + 2) * 80, 1); - - if (!display) - goto error; - - tmp = display; - tmp += sprintf(tmp, "PID\t\tCPU\t\tASID\t\tNAME\n"); - tmp += sprintf(tmp, "---\t\t---\t\t----\t\t----\n"); - - while (temp != NULL) { - if (temp->status) { - if (temp->context) - tmp += - sprintf(tmp, - "%" PRId32 "\t\t%" PRId32 "\t\t%" PRIx32 "\t\t%s\n", - temp->pid, temp->oncpu, - temp->asid, temp->name); - else - tmp += - sprintf(tmp, - "%" PRId32 "\t\t%" PRId32 "\t\t%" PRIx32 "\t\t%s\n", - temp->pid, temp->oncpu, - temp->asid, temp->name); - } - - temp = temp->next; - } - - return display; - } - -error: - display = calloc(40, 1); - sprintf(display, "linux_ps_command failed\n"); - return display; -} diff --git a/src/rtos/linux_header.h b/src/rtos/linux_header.h deleted file mode 100644 index a2b408e..0000000 --- a/src/rtos/linux_header.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef OPENOCD_RTOS_LINUX_HEADER_H -#define OPENOCD_RTOS_LINUX_HEADER_H - -/* gdb script to update the header file - according to kernel version and build option - before executing function awareness - kernel symbol must be loaded : symbol vmlinux - -define awareness - set logging off - set logging file linux_header.h - set logging on - - printf "#define QAT %p\n",&((struct task_struct *)(0))->stack - set $a=&((struct list_head *)(0))->next - set $a=(int)$a+(int)&((struct task_struct *)(0))->tasks - printf "#define NEXT %p\n",$a - printf "#define COMM %p\n",&((struct task_struct *)(0))->comm - printf "#define MEM %p\n",&((struct task_struct *)(0))->mm - printf "#define ONCPU %p\n",&((struct task_struct *)(0))->on_cpu - printf "#define PID %p\n",&((struct task_struct *)(0))->pid - printf "#define CPU_CONT %p\n",&((struct thread_info *)(0))->cpu_context - printf "#define PREEMPT %p\n",&((struct thread_info *)(0))->preempt_count - printf "#define MM_CTX %p\n",&((struct mm_struct *)(0))->context - end -*/ -#define QAT 0x4 -#define NEXT 0x1b0 -#define COMM 0x2d4 -#define MEM 0x1cc -#define ONCPU 0x18 -#define PID 0x1f4 -#define CPU_CONT 0x1c -#define PREEMPT 0x4 -#define MM_CTX 0x160 - -#endif /* OPENOCD_RTOS_LINUX_HEADER_H */ diff --git a/src/rtos/mqx.c b/src/rtos/mqx.c deleted file mode 100644 index b8095a0..0000000 --- a/src/rtos/mqx.c +++ /dev/null @@ -1,561 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2014 by Marian Cingel * - * cingel.marian@gmail.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * 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, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <stdint.h> -#include <helper/time_support.h> -#include <jtag/jtag.h> -#include "target/target.h" -#include "target/target_type.h" -#include "rtos.h" -#include "helper/log.h" -#include "helper/types.h" -#include "rtos_mqx_stackings.h" - -/* constants */ -#define MQX_THREAD_NAME_LENGTH (255) -#define MQX_KERNEL_OFFSET_TDLIST (0x0108) -#define MQX_KERNEL_OFFSET_SYSTEM_TASK (0x0050) -#define MQX_KERNEL_OFFSET_ACTIVE_TASK (0x001C) -#define MQX_KERNEL_OFFSET_CAPABILITY (0x0000) -#define MQX_QUEUE_OFFSET_SIZE (0x0008) -#define MQX_TASK_OFFSET_STATE (0x0008) -#define MQX_TASK_OFFSET_ID (0x000c) -#define MQX_TASK_OFFSET_TEMPLATE (0x0068) -#define MQX_TASK_OFFSET_STACK (0x0014) -#define MQX_TASK_OFFSET_TDLIST (0x006C) -#define MQX_TASK_OFFSET_NEXT (0x0000) -#define MQX_TASK_TEMPLATE_OFFSET_NAME (0x0010) -#define MQX_TASK_OFFSET_ERROR_CODE (0x005C) -#define MQX_TASK_STATE_MASK (0xFFF) - -/* types */ -enum mqx_symbols { - mqx_VAL_mqx_kernel_data, - mqx_VAL_MQX_init_struct, -}; - -enum mqx_arch { - mqx_arch_cortexm, -}; - -struct mqx_params { - const char *target_name; - const enum mqx_arch target_arch; - const struct rtos_register_stacking *stacking_info; -}; - -struct mqx_state { - uint32_t state; - char *name; -}; - -/* local data */ -static const struct mqx_state mqx_states[] = { - { 0x0002, "READY" }, - { 0x0003, "BLOCKED" }, - { 0x0005, "RCV_SPECIFIC_BLOCKED" }, - { 0x0007, "RCV_ANY_BLOCKED" }, - { 0x0009, "DYING" }, - { 0x000B, "UNHANDLED_INT_BLOCKED" }, - { 0x000D, "SEND_BLOCKED" }, - { 0x000F, "BREAKPOINT_BLOCKED" }, - { 0x0211, "IO_BLOCKED" }, - { 0x0021, "SEM_BLOCKED" }, - { 0x0223, "MUTEX_BLOCKED" }, - { 0x0025, "EVENT_BLOCKED" }, - { 0x0229, "TASK_QUEUE_BLOCKED" }, - { 0x042B, "LWSEM_BLOCKED" }, - { 0x042D, "LWEVENT_BLOCKED" }, -}; - -static const char * const mqx_symbol_list[] = { - "_mqx_kernel_data", - "MQX_init_struct", - NULL -}; - -static const struct mqx_params mqx_params_list[] = { - { "cortex_m", mqx_arch_cortexm, &rtos_mqx_arm_v7m_stacking }, -}; - -/* - * Perform simple address check to avoid bus fault. - */ -static int mqx_valid_address_check( - struct rtos *rtos, - uint32_t address -) -{ - enum mqx_arch arch_type = ((struct mqx_params *)rtos->rtos_specific_params)->target_arch; - const char * targetname = ((struct mqx_params *)rtos->rtos_specific_params)->target_name; - - /* Cortex-M address range */ - if (arch_type == mqx_arch_cortexm) { - if ( - /* code and sram area */ - (address && address <= 0x3FFFFFFFu) || - /* external ram area*/ - (address >= 0x6000000u && address <= 0x9FFFFFFFu) - ) { - return ERROR_OK; - } - return ERROR_FAIL; - } - LOG_ERROR("MQX RTOS - unknown architecture %s", targetname); - return ERROR_FAIL; -} - -/* - * Wrapper of 'target_read_buffer' fn. - * Include address check. - */ -static int mqx_target_read_buffer( - struct target *target, - uint32_t address, - uint32_t size, - uint8_t *buffer -) -{ - int status = mqx_valid_address_check(target->rtos, address); - if (status != ERROR_OK) { - LOG_WARNING("MQX RTOS - target address 0x%" PRIx32 " is not allowed to read", address); - return status; - } - status = target_read_buffer(target, address, size, buffer); - if (status != ERROR_OK) { - LOG_ERROR("MQX RTOS - reading target address 0x%" PRIx32" failed", address); - return status; - } - return ERROR_OK; -} - -/* - * Get symbol address if present - */ -static int mqx_get_symbol( - struct rtos *rtos, - enum mqx_symbols symbol, - void *result -) -{ - /* TODO: additional check ?? */ - (*(int *)result) = (uint32_t)rtos->symbols[symbol].address; - return ERROR_OK; -} - -/* - * Get value of struct member by passing - * member offset, width and name (debug purpose) - */ -static int mqx_get_member( - struct rtos *rtos, - const uint32_t base_address, - int32_t member_offset, - int32_t member_width, - const char *member_name, - void *result -) -{ - int status = ERROR_FAIL; - status = mqx_target_read_buffer( - rtos->target, base_address + member_offset, member_width, result - ); - if (status != ERROR_OK) - LOG_WARNING("MQX RTOS - cannot read \"%s\" at address 0x%" PRIx32, - member_name, (uint32_t)(base_address + member_offset)); - return status; -} - -/* - * Check whether scheduler started - */ -static int mqx_is_scheduler_running( - struct rtos *rtos -) -{ - uint32_t kernel_data_symbol = 0; - uint32_t kernel_data_addr = 0; - uint32_t system_td_addr = 0; - uint32_t active_td_addr = 0; - uint32_t capability_value = 0; - - /* get '_mqx_kernel_data' symbol */ - if (ERROR_OK != mqx_get_symbol( - rtos, mqx_VAL_mqx_kernel_data, &kernel_data_symbol - )) { - return ERROR_FAIL; - } - /* get '_mqx_kernel_data' */ - if (ERROR_OK != mqx_get_member( - rtos, kernel_data_symbol, 0, 4, - "_mqx_kernel_data", &kernel_data_addr - )) { - return ERROR_FAIL; - } - /* return if '_mqx_kernel_data' is NULL or default 0xFFFFFFFF */ - if (0 == kernel_data_addr || (uint32_t)(-1) == kernel_data_addr) - return ERROR_FAIL; - /* get kernel_data->ADDRESSING_CAPABILITY */ - if (ERROR_OK != mqx_get_member( - rtos, kernel_data_addr, MQX_KERNEL_OFFSET_CAPABILITY, 4, - "kernel_data->ADDRESSING_CAPABILITY", (void *)&capability_value - )) { - return ERROR_FAIL; - } - /* check first member, the '_mqx_kernel_data->ADDRESSING_CAPABILITY'. - it supose to be set to value 8 */ - if (capability_value != 8) { - LOG_WARNING("MQX RTOS - value of '_mqx_kernel_data->ADDRESSING_CAPABILITY' contains invalid value"); - return ERROR_FAIL; - } - /* get active ptr */ - if (ERROR_OK != mqx_get_member( - rtos, kernel_data_addr, MQX_KERNEL_OFFSET_ACTIVE_TASK, 4, - "kernel_data->ACTIVE_PTR", (void *)&active_td_addr - )) { - return ERROR_FAIL; - } - /* active task is system task, scheduler has not not run yet */ - system_td_addr = kernel_data_addr + MQX_KERNEL_OFFSET_SYSTEM_TASK; - if (active_td_addr == system_td_addr) { - LOG_WARNING("MQX RTOS - scheduler does not run"); - return ERROR_FAIL; - } - return ERROR_OK; -} - -/* - * API function, return 1 if MQX is present - */ -static int mqx_detect_rtos( - struct target *target -) -{ - if ( - (target->rtos->symbols != NULL) && - (target->rtos->symbols[mqx_VAL_mqx_kernel_data].address != 0) - ) { - return 1; - } - return 0; -} - -/* - * API function, pass MQX extra info to context data - */ -static int mqx_create( - struct target *target -) -{ - /* check target name against supported architectures */ - int mqx_params_list_num = (sizeof(mqx_params_list)/sizeof(struct mqx_params)); - for (int i = 0; i < mqx_params_list_num; i++) { - if (0 == strcmp(mqx_params_list[i].target_name, target->type->name)) { - target->rtos->rtos_specific_params = (void *)&mqx_params_list[i]; - /* LOG_DEBUG("MQX RTOS - valid architecture: %s", target->type->name); */ - return 0; - } - } - LOG_ERROR("MQX RTOS - could not find target \"%s\" in MQX compatibility list", target->type->name); - return -1; -} - -/* - * API function, update list of threads - */ -static int mqx_update_threads( - struct rtos *rtos -) -{ - uint32_t task_queue_addr = 0; - uint32_t kernel_data_addr = 0; - uint16_t task_queue_size = 0; - uint32_t active_td_addr = 0; - - if (!rtos->rtos_specific_params) - return -3; - - if (!rtos->symbols) - return -4; - - /* clear old data */ - rtos_free_threadlist(rtos); - /* check scheduler */ - if (ERROR_OK != mqx_is_scheduler_running(rtos)) - return ERROR_FAIL; - /* get kernel_data symbol */ - if (ERROR_OK != mqx_get_symbol( - rtos, mqx_VAL_mqx_kernel_data, &kernel_data_addr - )) { - return ERROR_FAIL; - } - /* read kernel_data */ - if (ERROR_OK != mqx_get_member( - rtos, kernel_data_addr, 0, 4, "_mqx_kernel_data", &kernel_data_addr - )) { - return ERROR_FAIL; - } - /* get task queue address */ - task_queue_addr = kernel_data_addr + MQX_KERNEL_OFFSET_TDLIST; - /* get task queue size */ - if (ERROR_OK != mqx_get_member( - rtos, task_queue_addr, MQX_QUEUE_OFFSET_SIZE, 2, - "kernel_data->TD_LIST.SIZE", &task_queue_size - )) { - return ERROR_FAIL; - } - /* get active ptr */ - if (ERROR_OK != mqx_get_member( - rtos, kernel_data_addr, MQX_KERNEL_OFFSET_ACTIVE_TASK, 4, - "kernel_data->ACTIVE_PTR", (void *)&active_td_addr - )) { - return ERROR_FAIL; - } - - /* setup threads info */ - rtos->thread_count = task_queue_size; - rtos->current_thread = 0; - rtos->thread_details = calloc(rtos->thread_count, sizeof(struct thread_detail)); - if (NULL == rtos->thread_details) - return ERROR_FAIL; - - /* loop over each task and setup thread details, - the current_taskpool_addr is set to queue head - NOTE: debugging functions task create/destroy - might cause to show invalid data. - */ - for ( - uint32_t i = 0, taskpool_addr = task_queue_addr; - i < (uint32_t)rtos->thread_count; - i++ - ) { - uint8_t task_name[MQX_THREAD_NAME_LENGTH + 1]; - uint32_t task_addr = 0, task_template = 0, task_state = 0; - uint32_t task_name_addr = 0, task_id = 0, task_errno = 0; - uint32_t state_index = 0, state_max = 0; - uint32_t extra_info_length = 0; - char *state_name = "unknown state"; - - /* set current taskpool address */ - if (ERROR_OK != mqx_get_member( - rtos, taskpool_addr, MQX_TASK_OFFSET_NEXT, 4, - "td_struct_ptr->NEXT", &taskpool_addr - )) { - return ERROR_FAIL; - } - /* get task address from taskpool */ - task_addr = taskpool_addr - MQX_TASK_OFFSET_TDLIST; - /* get address of 'td_struct_ptr->TEMPLATE_LIST_PTR' */ - if (ERROR_OK != mqx_get_member( - rtos, task_addr, MQX_TASK_OFFSET_TEMPLATE, 4, - "td_struct_ptr->TEMPLATE_LIST_PTR", &task_template - )) { - return ERROR_FAIL; - } - /* get address of 'td_struct_ptr->TEMPLATE_LIST_PTR->NAME' */ - if (ERROR_OK != mqx_get_member( - rtos, task_template, MQX_TASK_TEMPLATE_OFFSET_NAME, 4, - "td_struct_ptr->TEMPLATE_LIST_PTR->NAME", &task_name_addr - )) { - return ERROR_FAIL; - } - /* get value of 'td_struct->TEMPLATE_LIST_PTR->NAME' */ - if (ERROR_OK != mqx_get_member( - rtos, task_name_addr, 0, MQX_THREAD_NAME_LENGTH, - "*td_struct_ptr->TEMPLATE_LIST_PTR->NAME", task_name - )) { - return ERROR_FAIL; - } - /* always terminate last character by force, - otherwise openocd might fail if task_name - has corrupted data */ - task_name[MQX_THREAD_NAME_LENGTH] = '\0'; - /* get value of 'td_struct_ptr->TASK_ID' */ - if (ERROR_OK != mqx_get_member( - rtos, task_addr, MQX_TASK_OFFSET_ID, 4, - "td_struct_ptr->TASK_ID", &task_id - )) { - return ERROR_FAIL; - } - /* get task errno */ - if (ERROR_OK != mqx_get_member( - rtos, task_addr, MQX_TASK_OFFSET_ERROR_CODE, 4, - "td_struct_ptr->TASK_ERROR_CODE", &task_errno - )) { - return ERROR_FAIL; - } - /* get value of 'td_struct_ptr->STATE' */ - if (ERROR_OK != mqx_get_member( - rtos, task_addr, MQX_TASK_OFFSET_STATE, 4, - "td_struct_ptr->STATE", &task_state - )) { - return ERROR_FAIL; - } - task_state &= MQX_TASK_STATE_MASK; - /* and search for defined state */ - state_max = (sizeof(mqx_states)/sizeof(struct mqx_state)); - for (state_index = 0; (state_index < state_max); state_index++) { - if (mqx_states[state_index].state == task_state) { - state_name = mqx_states[state_index].name; - break; - } - } - - /* setup thread details struct */ - rtos->thread_details[i].threadid = task_id; - rtos->thread_details[i].exists = true; - /* set thread name */ - rtos->thread_details[i].thread_name_str = malloc(strlen((void *)task_name) + 1); - if (NULL == rtos->thread_details[i].thread_name_str) - return ERROR_FAIL; - strcpy(rtos->thread_details[i].thread_name_str, (void *)task_name); - /* set thread extra info - * - task state - * - task address - * - task errno - * calculate length as: - * state length + address length + errno length + formatter length - */ - extra_info_length += strlen((void *)state_name) + 8 + 8 + 8; - rtos->thread_details[i].extra_info_str = malloc(extra_info_length + 1); - if (NULL == rtos->thread_details[i].extra_info_str) - return ERROR_FAIL; - snprintf( - rtos->thread_details[i].extra_info_str, extra_info_length, "%s : 0x%"PRIx32 " : %" PRIu32, - state_name, task_addr, task_errno - ); - /* set active thread */ - if (active_td_addr == task_addr) - rtos->current_thread = task_id; - } - return ERROR_OK; -} - -/* - * API function, get info of selected thread - */ -static int mqx_get_thread_reg_list( - struct rtos *rtos, - int64_t thread_id, - char **hex_reg_list -) -{ - int64_t stack_ptr = 0; - uint32_t my_task_addr = 0; - uint32_t task_queue_addr = 0; - uint32_t task_queue_size = 0; - uint32_t kernel_data_addr = 0; - - *hex_reg_list = NULL; - if (thread_id == 0) { - LOG_ERROR("MQX RTOS - invalid threadid: 0x%X", (int)thread_id); - return ERROR_FAIL; - } - if (ERROR_OK != mqx_is_scheduler_running(rtos)) - return ERROR_FAIL; - /* get kernel_data symbol */ - if (ERROR_OK != mqx_get_symbol( - rtos, mqx_VAL_mqx_kernel_data, &kernel_data_addr - )) { - return ERROR_FAIL; - } - /* read kernel_data */ - if (ERROR_OK != mqx_get_member( - rtos, kernel_data_addr, 0, 4, "_mqx_kernel_data", &kernel_data_addr - )) { - return ERROR_FAIL; - } - /* get task queue address */ - task_queue_addr = kernel_data_addr + MQX_KERNEL_OFFSET_TDLIST; - /* get task queue size */ - if (ERROR_OK != mqx_get_member( - rtos, task_queue_addr, MQX_QUEUE_OFFSET_SIZE, 2, - "kernel_data->TD_LIST.SIZE", &task_queue_size - )) { - return ERROR_FAIL; - } - /* search for taskid */ - for ( - uint32_t i = 0, taskpool_addr = task_queue_addr; - i < (uint32_t)rtos->thread_count; - i++ - ) { - uint32_t tmp_address = 0, task_addr = 0; - uint32_t task_id = 0; - /* set current taskpool address */ - tmp_address = taskpool_addr; - if (ERROR_OK != mqx_get_member( - rtos, tmp_address, MQX_TASK_OFFSET_NEXT, 4, - "td_struct_ptr->NEXT", &taskpool_addr - )) { - return ERROR_FAIL; - } - /* get task address from taskpool */ - task_addr = taskpool_addr - MQX_TASK_OFFSET_TDLIST; - /* get value of td_struct->TASK_ID */ - if (ERROR_OK != mqx_get_member( - rtos, task_addr, MQX_TASK_OFFSET_ID, 4, - "td_struct_ptr->TASK_ID", &task_id - )) { - return ERROR_FAIL; - } - /* found taskid, break */ - if (task_id == thread_id) { - my_task_addr = task_addr; - break; - } - } - if (!my_task_addr) { - LOG_ERROR("MQX_RTOS - threadid %" PRId64 " does not match any task", thread_id); - return ERROR_FAIL; - } - /* get task stack head address */ - if (ERROR_OK != mqx_get_member( - rtos, my_task_addr, MQX_TASK_OFFSET_STACK, 4, "task->STACK_PTR", &stack_ptr - )) { - return ERROR_FAIL; - } - return rtos_generic_stack_read( - rtos->target, ((struct mqx_params *)rtos->rtos_specific_params)->stacking_info, stack_ptr, hex_reg_list - ); -} - -/* API function, export list of required symbols */ -static int mqx_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[]) -{ - *symbol_list = calloc(ARRAY_SIZE(mqx_symbol_list), sizeof(symbol_table_elem_t)); - if (NULL == *symbol_list) - return ERROR_FAIL; - /* export required symbols */ - for (int i = 0; i < (int)(ARRAY_SIZE(mqx_symbol_list)); i++) - (*symbol_list)[i].symbol_name = mqx_symbol_list[i]; - return ERROR_OK; -} - -struct rtos_type mqx_rtos = { - .name = "mqx", - .detect_rtos = mqx_detect_rtos, - .create = mqx_create, - .update_threads = mqx_update_threads, - .get_thread_reg_list = mqx_get_thread_reg_list, - .get_symbol_list_to_lookup = mqx_get_symbol_list_to_lookup, -}; diff --git a/src/rtos/riscv_debug.c b/src/rtos/riscv_debug.c deleted file mode 100644 index 181d471..0000000 --- a/src/rtos/riscv_debug.c +++ /dev/null @@ -1,280 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "riscv_debug.h" -#include "target/target.h" -#include "target/riscv/riscv.h" -#include "rtos.h" -#include "server/gdb_server.h" - -static int riscv_update_threads(struct rtos *rtos); -static int riscv_gdb_thread_packet(struct connection *connection, const char *packet, int packet_size); - -static int riscv_detect_rtos(struct target *target) -{ - LOG_ERROR("riscv_detect_rtos() unimplemented"); - return -1; -} - -static int riscv_create_rtos(struct target *target) -{ - LOG_DEBUG("RISC-V Debug 'RTOS' created: this doesn't meat you're running an RTOS, just that you have multi-hart support on RISC-V"); - - struct riscv_rtos *r = calloc(1, sizeof(*r)); - target->rtos->rtos_specific_params = r; -#if 0 - r->target_hartid = 0; - r->target_any_hart = true; - r->target_every_hart = true; -#endif - - target->rtos->current_threadid = 1; - target->rtos->current_thread = 1; - riscv_update_threads(target->rtos); - - target->rtos->gdb_thread_packet = riscv_gdb_thread_packet; - - return JIM_OK; -} - -static int riscv_update_threads(struct rtos *rtos) -{ - LOG_DEBUG("Updating the RISC-V Hart List"); - - /* Figures out how many harts there are on the system. */ - int hart_count = riscv_count_harts(rtos->target); - if (rtos->thread_count != hart_count) { - rtos_free_threadlist(rtos); - rtos->thread_count = hart_count; - rtos->thread_details = calloc(rtos->thread_count, sizeof(*rtos->thread_details)); - for (int i = 0; i < rtos->thread_count; ++i) { - LOG_DEBUG(" Setting up Hart %d", i); - rtos->thread_details[i].threadid = i + 1; - rtos->thread_details[i].exists = true; - if (asprintf(&rtos->thread_details[i].thread_name_str, "Hart %d", i) < 0) - LOG_ERROR("riscv_update_threads() failed asprintf"); - if (asprintf(&rtos->thread_details[i].extra_info_str, "RV64") < 0) - LOG_ERROR("riscv_update_threads() failed asprintf"); - } - } - return JIM_OK; -} - -static int riscv_gdb_thread_packet(struct connection *connection, const char *packet, int packet_size) -{ - struct target *target = get_target_from_connection(connection); - struct rtos *rtos = target->rtos; - struct riscv_rtos *r = (struct riscv_rtos *)(target->rtos->rtos_specific_params); - - char *packet_stttrr = malloc(packet_size + 1); - memset(packet_stttrr, '\0', packet_size + 1); - memcpy(packet_stttrr, packet, packet_size); - LOG_DEBUG("riscv_gdb_thread_packet(%s)", packet_stttrr); - - switch (packet[0]) { - case 'q': - if (strncmp(packet, "qfThreadInfo", 12) == 0) { - riscv_update_threads(target->rtos); - r->qs_thread_info_offset = 1; - - char m[16]; - snprintf(m, 16, "m%08x", (int)rtos->thread_details[0].threadid); - gdb_put_packet(connection, m, strlen(m)); - return ERROR_OK; - } - - if (strncmp(packet, "qsThreadInfo", 12) == 0) { - if (r->qs_thread_info_offset >= rtos->thread_count) { - gdb_put_packet(connection, "l", 1); - return ERROR_OK; - } - - int tid = r->qs_thread_info_offset++; - char m[16]; - snprintf(m, 16, "m%08x", (int)rtos->thread_details[tid].threadid); - gdb_put_packet(connection, m, strlen(m)); - return ERROR_OK; - } - - if (strncmp(packet, "qAttached", 9) == 0) { - gdb_put_packet(connection, "1", 1); - return ERROR_OK; - } - - if (strncmp(packet, "qThreadExtraInfo", 16) == 0) { - char tid_str[32]; - memcpy(tid_str, packet + 17, packet_size - 17); - tid_str[packet_size - 17] = '\0'; - char *end; - int tid = strtol(tid_str, &end, 16); - if (*end != '\0') { - LOG_ERROR("Got qThreadExtraInfo with non-numeric TID: '%s'", tid_str); - gdb_put_packet(connection, NULL, 0); - return ERROR_FAIL; - } - - char m[16]; - snprintf(m, 16, "hart %d", tid); - char h[33]; - h[0] = '\0'; - for (size_t i = 0; i < strlen(m); ++i) { - char byte[3]; - snprintf(byte, 3, "%02x", m[i]); - strncat(h, byte, 32); - } - gdb_put_packet(connection, h, strlen(h)); - return ERROR_OK; - } - - return GDB_THREAD_PACKET_NOT_CONSUMED; - - case 'Q': - return GDB_THREAD_PACKET_NOT_CONSUMED; - - case 'H': - /* ‘H op thread-id’ - * - * Set thread for subsequent operations (‘m’, ‘M’, ‘g’, ‘G’, - * et.al.). Depending on the operation to be performed, op - * should be ‘c’ for step and continue operations (note that - * this is deprecated, supporting the ‘vCont’ command is a - * better option), and ‘g’ for other operations. The thread - * designator thread-id has the format and interpretation - * described in thread-id syntax. - * - * Reply: - * ‘OK’ for success - * ‘E NN’ for an error - */ - { - char tid_str[32]; - memcpy(tid_str, packet + 2, packet_size - 2); - tid_str[packet_size - 2] = '\0'; - char *entptr; - int tid = strtol(tid_str, &entptr, 16); - if (*entptr != '\0') { - LOG_ERROR("Got H packet, but without integer: %s", tid_str); - return GDB_THREAD_PACKET_NOT_CONSUMED; - } - - riscv_enable_rtos(target); - switch (tid) { - case 0: - case -1: - riscv_set_all_rtos_harts(target); - break; - default: - riscv_set_rtos_hartid(target, tid - 1); - break; - } - - switch (packet[1]) { - case 'g': - case 'c': - gdb_put_packet(connection, "OK", 2); - return ERROR_OK; - default: - LOG_ERROR("Unknown H packet subtype %2x\n", packet[1]); - gdb_put_packet(connection, NULL, 0); - return ERROR_FAIL; - } - } - - case 'T': - { - char tid_str[32]; - memcpy(tid_str, packet + 1, packet_size - 1); - tid_str[packet_size - 1] = '\0'; - char *end; - int tid = strtol(tid_str, &end, 16); - if (*end != '\0') { - LOG_ERROR("T packet with non-numeric tid %s", tid_str); - gdb_put_packet(connection, NULL, 0); - return ERROR_FAIL; - } - - riscv_enable_rtos(target); - riscv_update_threads(target->rtos); - if (tid <= target->rtos->thread_count) { - gdb_put_packet(connection, "OK", 2); - return ERROR_OK; - } else { - gdb_put_packet(connection, "E00", 3); - return ERROR_OK; - } - } - - - case 'c': - case 's': - target->state = TARGET_HALTED; - return JIM_OK; - - case 'R': - { - char *packet_str = malloc(packet_size + 1); - memset(packet_str, '\0', packet_size + 1); - memcpy(packet_str, packet, packet_size); - LOG_WARNING("riscv_gdb_thread_packet(%s): unimplemented", packet_str); - gdb_put_packet(connection, NULL, 0); - return JIM_OK; - } - default: - LOG_ERROR("Unknown packet of type 0x%2.2x", packet[0]); - gdb_put_packet(connection, NULL, 0); - return JIM_OK; - } -} - -static int riscv_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, char **hex_reg_list) -{ - LOG_DEBUG("Updating RISC-V regiser list for hart %d", (int)(thread_id - 1)); - -#if 0 - LOG_ERROR(" Not actually updating"); - *hex_reg_list = 0; - return JIM_OK; -#endif - - size_t n_regs = 32; - size_t xlen = 64; - size_t reg_chars = xlen / 8 * 2; - - ssize_t hex_reg_list_length = n_regs * reg_chars + 2; - *hex_reg_list = malloc(hex_reg_list_length); - *hex_reg_list[0] = '\0'; - for (size_t i = 0; i < n_regs; ++i) { - if (riscv_has_register(rtos->target, thread_id, i)) { - uint64_t reg_value = riscv_get_register(rtos->target, thread_id - 1, i); - for (size_t byte = 0; byte < xlen / 8; ++byte) { - uint8_t reg_byte = reg_value >> (byte * 8); - char hex[3]; - snprintf(hex, 3, "%02x", reg_byte); - strncat(*hex_reg_list, hex, hex_reg_list_length); - } - } else { - for (size_t byte = 0; byte < xlen / 8; ++byte) - strncat(*hex_reg_list, "xx", hex_reg_list_length); - } - } - return JIM_OK; -} - -static int riscv_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[]) -{ - *symbol_list = calloc(1, sizeof(symbol_table_elem_t)); - (*symbol_list)[0].symbol_name = NULL; - (*symbol_list)[0].optional = false; - return JIM_OK; -} - -const struct rtos_type riscv_rtos = -{ - .name = "riscv", - .detect_rtos = riscv_detect_rtos, - .create = riscv_create_rtos, - .update_threads = riscv_update_threads, - .get_thread_reg_list = riscv_get_thread_reg_list, - .get_symbol_list_to_lookup = riscv_get_symbol_list_to_lookup, -}; diff --git a/src/rtos/riscv_debug.h b/src/rtos/riscv_debug.h deleted file mode 100644 index bcc7411..0000000 --- a/src/rtos/riscv_debug.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef RTOS__RISCV_H -#define RTOS__RISCV_H - -struct riscv_rtos { - /* The index into the thread list used to handle */ - int qs_thread_info_offset; -}; - -#endif diff --git a/src/rtos/rtos.c b/src/rtos/rtos.c deleted file mode 100644 index 76443b6..0000000 --- a/src/rtos/rtos.c +++ /dev/null @@ -1,549 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Broadcom Corporation * - * Evan Hunter - ehunter@broadcom.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * 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, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "rtos.h" -#include "target/target.h" -#include "helper/log.h" -#include "helper/binarybuffer.h" -#include "server/gdb_server.h" - -/* RTOSs */ -extern struct rtos_type FreeRTOS_rtos; -extern struct rtos_type ThreadX_rtos; -extern struct rtos_type eCos_rtos; -extern struct rtos_type Linux_os; -extern struct rtos_type ChibiOS_rtos; -extern struct rtos_type embKernel_rtos; -extern struct rtos_type mqx_rtos; -extern struct rtos_type riscv_rtos; - -static struct rtos_type *rtos_types[] = { - &ThreadX_rtos, - &FreeRTOS_rtos, - &eCos_rtos, - &Linux_os, - &ChibiOS_rtos, - &embKernel_rtos, - &mqx_rtos, - &riscv_rtos, - NULL -}; - -int rtos_thread_packet(struct connection *connection, const 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; -} - -static int os_alloc(struct target *target, struct rtos_type *ostype) -{ - struct rtos *os = target->rtos = calloc(1, sizeof(struct rtos)); - - if (!os) - return JIM_ERR; - - os->type = ostype; - os->current_threadid = -1; - os->current_thread = 0; - os->symbols = NULL; - os->target = target; - - /* RTOS drivers can override the packet handler in _create(). */ - os->gdb_thread_packet = rtos_thread_packet; - - return JIM_OK; -} - -static void os_free(struct target *target) -{ - if (!target->rtos) - return; - - if (target->rtos->symbols) - free(target->rtos->symbols); - - free(target->rtos); - target->rtos = NULL; -} - -static int os_alloc_create(struct target *target, struct rtos_type *ostype) -{ - int ret = os_alloc(target, ostype); - - if (JIM_OK == ret) { - ret = target->rtos->type->create(target); - if (ret != JIM_OK) - os_free(target); - } - - return ret; -} - -int rtos_create(Jim_GetOptInfo *goi, struct target *target) -{ - int x; - const char *cp; - struct Jim_Obj *res; - - if (!goi->isconfigure && goi->argc != 0) { - Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "NO PARAMS"); - return JIM_ERR; - } - - os_free(target); - - Jim_GetOpt_String(goi, &cp, NULL); - - if (0 == strcmp(cp, "auto")) { - /* Auto detect tries to look up all symbols for each RTOS, - * and runs the RTOS driver's _detect() function when GDB - * finds all symbols for any RTOS. See rtos_qsymbol(). */ - target->rtos_auto_detect = true; - - /* rtos_qsymbol() will iterate over all RTOSes. Allocate - * target->rtos here, and set it to the first RTOS type. */ - return os_alloc(target, rtos_types[0]); - } - - for (x = 0; rtos_types[x]; x++) - if (0 == strcmp(cp, rtos_types[x]->name)) - return os_alloc_create(target, rtos_types[x]); - - Jim_SetResultFormatted(goi->interp, "Unknown RTOS type %s, try one of: ", cp); - res = Jim_GetResult(goi->interp); - for (x = 0; rtos_types[x]; x++) - Jim_AppendStrings(goi->interp, res, rtos_types[x]->name, ", ", NULL); - Jim_AppendStrings(goi->interp, res, " or auto", NULL); - - return JIM_ERR; -} - -int gdb_thread_packet(struct connection *connection, char const *packet, int packet_size) -{ - 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); -} - -static symbol_table_elem_t *next_symbol(struct rtos *os, char *cur_symbol, uint64_t cur_addr) -{ - symbol_table_elem_t *s; - - if (!os->symbols) - os->type->get_symbol_list_to_lookup(&os->symbols); - - if (!cur_symbol[0]) - return &os->symbols[0]; - - for (s = os->symbols; s->symbol_name; s++) - if (!strcmp(s->symbol_name, cur_symbol)) { - s->address = cur_addr; - s++; - return s; - } - - return NULL; -} - -/* searches for 'symbol' in the lookup table for 'os' and returns TRUE, - * if 'symbol' is not declared optional */ -static bool is_symbol_mandatory(const struct rtos *os, const char *symbol) -{ - for (symbol_table_elem_t *s = os->symbols; s->symbol_name; ++s) { - if (!strcmp(s->symbol_name, symbol)) - return !s->optional; - } - return false; -} - -/* rtos_qsymbol() processes and replies to all qSymbol packets from GDB. - * - * GDB sends a qSymbol:: packet (empty address, empty name) to notify - * that it can now answer qSymbol::hexcodedname queries, to look up symbols. - * - * If the qSymbol packet has no address that means GDB did not find the - * symbol, in which case auto-detect will move on to try the next RTOS. - * - * rtos_qsymbol() then calls the next_symbol() helper function, which - * iterates over symbol names for the current RTOS until it finds the - * symbol in the received GDB packet, and then returns the next entry - * in the list of symbols. - * - * If GDB replied about the last symbol for the RTOS and the RTOS was - * specified explicitly, then no further symbol lookup is done. When - * auto-detecting, the RTOS driver _detect() function must return success. - * - * rtos_qsymbol() returns 1 if an RTOS has been detected, or 0 otherwise. - */ -int rtos_qsymbol(struct connection *connection, char const *packet, int packet_size) -{ - int rtos_detected = 0; - uint64_t addr = 0; - size_t reply_len; - char reply[GDB_BUFFER_SIZE], cur_sym[GDB_BUFFER_SIZE / 2] = ""; - symbol_table_elem_t *next_sym = NULL; - struct target *target = get_target_from_connection(connection); - struct rtos *os = target->rtos; - - reply_len = sprintf(reply, "OK"); - - if (!os) - goto done; - - /* Decode any symbol name in the packet*/ - int len = unhexify(cur_sym, strchr(packet + 8, ':') + 1, strlen(strchr(packet + 8, ':') + 1)); - cur_sym[len] = 0; - - if ((strcmp(packet, "qSymbol::") != 0) && /* GDB is not offering symbol lookup for the first time */ - (!sscanf(packet, "qSymbol:%" SCNx64 ":", &addr)) && /* GDB did not find an address for a symbol */ - is_symbol_mandatory(os, cur_sym)) { /* the symbol is mandatory for this RTOS */ - - /* GDB could not find an address for the previous symbol */ - if (!target->rtos_auto_detect) { - LOG_WARNING("RTOS %s not detected. (GDB could not find symbol \'%s\')", os->type->name, cur_sym); - goto done; - } else { - /* Autodetecting RTOS - try next RTOS */ - if (!rtos_try_next(target)) { - LOG_WARNING("No RTOS could be auto-detected!"); - goto done; - } - - /* Next RTOS selected - invalidate current symbol */ - cur_sym[0] = '\x00'; - } - } - next_sym = next_symbol(os, cur_sym, addr); - - if (!next_sym->symbol_name) { - /* No more symbols need looking up */ - - if (!target->rtos_auto_detect) { - rtos_detected = 1; - goto done; - } - - if (os->type->detect_rtos(target)) { - LOG_INFO("Auto-detected RTOS: %s", os->type->name); - rtos_detected = 1; - goto done; - } else { - LOG_WARNING("No RTOS could be auto-detected!"); - goto done; - } - } - - if (8 + (strlen(next_sym->symbol_name) * 2) + 1 > sizeof(reply)) { - LOG_ERROR("ERROR: RTOS symbol '%s' name is too long for GDB!", next_sym->symbol_name); - goto done; - } - - reply_len = snprintf(reply, sizeof(reply), "qSymbol:"); - reply_len += hexify(reply + reply_len, next_sym->symbol_name, 0, sizeof(reply) - reply_len); - -done: - gdb_put_packet(connection, reply, reply_len); - return rtos_detected; -} - -int rtos_thread_packet(struct connection *connection, char const *packet, int packet_size) -{ - struct target *target = get_target_from_connection(connection); - - if (strncmp(packet, "qThreadExtraInfo,", 17) == 0) { - if ((target->rtos != NULL) && (target->rtos->thread_details != NULL) && - (target->rtos->thread_count != 0)) { - threadid_t threadid = 0; - int found = -1; - sscanf(packet, "qThreadExtraInfo,%" SCNx64, &threadid); - - 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; - } - - struct thread_detail *detail = &target->rtos->thread_details[found]; - - int str_size = 0; - if (detail->thread_name_str != NULL) - str_size += strlen(detail->thread_name_str); - if (detail->extra_info_str != NULL) - str_size += strlen(detail->extra_info_str); - - char *tmp_str = calloc(str_size + 4, sizeof(char)); - char *tmp_str_ptr = tmp_str; - - if (detail->thread_name_str != NULL) - tmp_str_ptr += sprintf(tmp_str_ptr, "%s", detail->thread_name_str); - if (detail->extra_info_str != NULL) { - if (tmp_str_ptr != tmp_str) - tmp_str_ptr += sprintf(tmp_str_ptr, " : "); - 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 = malloc(strlen(tmp_str) * 2 + 1); - int pkt_len = hexify(hex_str, tmp_str, 0, strlen(tmp_str) * 2 + 1); - - gdb_put_packet(connection, hex_str, pkt_len); - free(hex_str); - free(tmp_str); - return ERROR_OK; - - } - gdb_put_packet(connection, "", 0); - return ERROR_OK; - } else if (strncmp(packet, "qSymbol", 7) == 0) { - if (rtos_qsymbol(connection, packet, packet_size) == 1) { - target->rtos_auto_detect = false; - target->rtos->type->create(target); - target->rtos->type->update_threads(target->rtos); - } - return ERROR_OK; - } else if (strncmp(packet, "qfThreadInfo", 12) == 0) { - int i; - if (target->rtos != NULL) { - if (target->rtos->thread_count == 0) { - gdb_put_packet(connection, "l", 1); - } else { - /*thread id are 16 char +1 for ',' */ - char *out_str = malloc(17 * target->rtos->thread_count + 1); - char *tmp_str = out_str; - for (i = 0; i < target->rtos->thread_count; i++) { - tmp_str += sprintf(tmp_str, "%c%016" PRIx64, i == 0 ? 'm' : ',', - target->rtos->thread_details[i].threadid); - } - gdb_put_packet(connection, out_str, strlen(out_str)); - free(out_str); - } - } else - gdb_put_packet(connection, "l", 1); - - return ERROR_OK; - } else if (strncmp(packet, "qsThreadInfo", 12) == 0) { - gdb_put_packet(connection, "l", 1); - return ERROR_OK; - } else if (strncmp(packet, "qAttached", 9) == 0) { - gdb_put_packet(connection, "1", 1); - return ERROR_OK; - } else if (strncmp(packet, "qOffsets", 8) == 0) { - char offsets[] = "Text=0;Data=0;Bss=0"; - gdb_put_packet(connection, offsets, sizeof(offsets)-1); - return ERROR_OK; - } else if (strncmp(packet, "qCRC:", 5) == 0) { - /* make sure we check this before "qC" packet below - * otherwise it gets incorrectly handled */ - return GDB_THREAD_PACKET_NOT_CONSUMED; - } else if (strncmp(packet, "qC", 2) == 0) { - if (target->rtos != NULL) { - char buffer[19]; - int size; - size = snprintf(buffer, 19, "QC%016" PRIx64, 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? */ - threadid_t threadid; - int found = -1; - sscanf(packet, "T%" SCNx64, &threadid); - 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, "OK", 2); /* thread alive */ - 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') && (target->rtos != NULL)) { - sscanf(packet, "Hg%16" SCNx64, &target->rtos->current_threadid); - LOG_DEBUG("RTOS: GDB requested to set current thread to 0x%" PRIx64 "\r\n", - 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 = 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; - - LOG_INFO("RTOS: getting register list for thread 0x%" PRIx64 - ", target->rtos->current_thread=0x%" PRIx64 "\r\n", - current_threadid, - target->rtos->current_thread); - - target->rtos->type->get_thread_reg_list(target->rtos, - current_threadid, - &hex_reg_list); - - if (hex_reg_list != NULL) { - gdb_put_packet(connection, hex_reg_list, strlen(hex_reg_list)); - free(hex_reg_list); - return ERROR_OK; - } - } - return ERROR_FAIL; -} - -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; - int64_t new_stack_ptr; - int i; - int retval; - - if (stack_ptr == 0) { - LOG_ERROR("Error: null stack pointer in thread"); - return -5; - } - /* Read the stack */ - uint8_t *stack_data = malloc(stacking->stack_registers_size); - uint32_t address = stack_ptr; - - if (stacking->stack_growth_direction == 1) - address -= stacking->stack_registers_size; - retval = target_read_buffer(target, address, stacking->stack_registers_size, stack_data); - if (retval != ERROR_OK) { - free(stack_data); - LOG_ERROR("Error reading stack frame from thread"); - return retval; - } - LOG_DEBUG("RTOS: Read stack frame at 0x%" PRIx32, address); - -#if 0 - LOG_OUTPUT("Stack Data :"); - for (i = 0; i < stacking->stack_registers_size; i++) - LOG_OUTPUT("%02X", stack_data[i]); - LOG_OUTPUT("\r\n"); -#endif - for (i = 0; i < stacking->num_output_registers; i++) - list_size += stacking->register_offsets[i].width_bits/8; - *hex_reg_list = malloc(list_size*2 + 1); - tmp_str_ptr = *hex_reg_list; - if (stacking->calculate_process_stack != NULL) { - new_stack_ptr = stacking->calculate_process_stack(target, - stack_data, stacking, stack_ptr); - } else { - new_stack_ptr = stack_ptr - stacking->stack_growth_direction * - stacking->stack_registers_size; - } - for (i = 0; i < stacking->num_output_registers; i++) { - int j; - for (j = 0; j < stacking->register_offsets[i].width_bits/8; j++) { - if (stacking->register_offsets[i].offset == -1) - tmp_str_ptr += sprintf(tmp_str_ptr, "%02x", 0); - else if (stacking->register_offsets[i].offset == -2) - tmp_str_ptr += sprintf(tmp_str_ptr, "%02x", - ((uint8_t *)&new_stack_ptr)[j]); - else - tmp_str_ptr += sprintf(tmp_str_ptr, "%02x", - stack_data[stacking->register_offsets[i].offset + j]); - } - } - free(stack_data); -/* LOG_OUTPUT("Output register string: %s\r\n", *hex_reg_list); */ - return ERROR_OK; -} - -int rtos_try_next(struct target *target) -{ - struct rtos *os = target->rtos; - struct rtos_type **type = rtos_types; - - if (!os) - return 0; - - while (*type && os->type != *type) - type++; - - if (!*type || !*(++type)) - return 0; - - os->type = *type; - if (os->symbols) { - free(os->symbols); - os->symbols = NULL; - } - - return 1; -} - -int rtos_update_threads(struct target *target) -{ - if ((target->rtos != NULL) && (target->rtos->type != NULL)) - target->rtos->type->update_threads(target->rtos); - return ERROR_OK; -} - -void rtos_free_threadlist(struct rtos *rtos) -{ - if (rtos->thread_details) { - int j; - - for (j = 0; j < rtos->thread_count; j++) { - struct thread_detail *current_thread = &rtos->thread_details[j]; - free(current_thread->thread_name_str); - free(current_thread->extra_info_str); - } - free(rtos->thread_details); - rtos->thread_details = NULL; - rtos->thread_count = 0; - } -} diff --git a/src/rtos/rtos.h b/src/rtos/rtos.h deleted file mode 100644 index 70c1193..0000000 --- a/src/rtos/rtos.h +++ /dev/null @@ -1,111 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Broadcom Corporation * - * Evan Hunter - ehunter@broadcom.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * 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, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ - -#ifndef OPENOCD_RTOS_RTOS_H -#define OPENOCD_RTOS_RTOS_H - -#include "server/server.h" -#include <jim-nvp.h> - -typedef int64_t threadid_t; -typedef int64_t symbol_address_t; - -struct reg; - -/** - * Table should be terminated by an element with NULL in symbol_name - */ -typedef struct symbol_table_elem_struct { - const char *symbol_name; - symbol_address_t address; - bool optional; -} symbol_table_elem_t; - -struct thread_detail { - threadid_t threadid; - bool exists; - char *thread_name_str; - char *extra_info_str; -}; - -struct rtos { - const struct rtos_type *type; - - symbol_table_elem_t *symbols; - struct target *target; - /* add a context variable instead of global variable */ - int64_t current_threadid; - threadid_t current_thread; - struct thread_detail *thread_details; - int thread_count; - int (*gdb_thread_packet)(struct connection *connection, char const *packet, int packet_size); - void *rtos_specific_params; -}; - -struct rtos_type { - const char *name; - int (*detect_rtos)(struct target *target); - int (*create)(struct target *target); - int (*smp_init)(struct target *target); - int (*update_threads)(struct rtos *rtos); - int (*get_thread_reg_list)(struct rtos *rtos, int64_t thread_id, char **hex_reg_list); - int (*get_symbol_list_to_lookup)(symbol_table_elem_t *symbol_list[]); - int (*clean)(struct target *target); - char * (*ps_command)(struct target *target); -}; - -struct stack_register_offset { - signed short offset; /* offset in bytes from stack head, or -1 to indicate - * register is not stacked, or -2 to indicate this is the - * stack pointer register */ - unsigned short width_bits; -}; - -struct rtos_register_stacking { - unsigned char stack_registers_size; - signed char stack_growth_direction; - unsigned char num_output_registers; - /* Some targets require evaluating the stack to determine the - * actual stack pointer for a process. If this field is NULL, - * just use stacking->stack_registers_size * stack_growth_direction - * to calculate adjustment. - */ - int64_t (*calculate_process_stack)(struct target *target, - const uint8_t *stack_data, - const struct rtos_register_stacking *stacking, - int64_t stack_ptr); - const struct stack_register_offset *register_offsets; -}; - -#define GDB_THREAD_PACKET_NOT_CONSUMED (-40) - -int rtos_create(Jim_GetOptInfo *goi, struct target *target); -int rtos_generic_stack_read(struct target *target, - const struct rtos_register_stacking *stacking, - int64_t stack_ptr, - char **hex_reg_list); -int rtos_try_next(struct target *target); -int gdb_thread_packet(struct connection *connection, char const *packet, int packet_size); -int rtos_get_gdb_reg_list(struct connection *connection); -int rtos_update_threads(struct target *target); -void rtos_free_threadlist(struct rtos *rtos); -int rtos_smp_init(struct target *target); -/* function for handling symbol access */ -int rtos_qsymbol(struct connection *connection, char const *packet, int packet_size); - -#endif /* OPENOCD_RTOS_RTOS_H */ diff --git a/src/rtos/rtos_chibios_stackings.c b/src/rtos/rtos_chibios_stackings.c deleted file mode 100644 index 3651c49..0000000 --- a/src/rtos/rtos_chibios_stackings.c +++ /dev/null @@ -1,83 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2012 by Matthias Blaicher * - * Matthias Blaicher - matthias@blaicher.com * - * * - * Copyright (C) 2011 by Broadcom Corporation * - * Evan Hunter - ehunter@broadcom.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * 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, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "rtos.h" -#include "target/armv7m.h" - -static const struct stack_register_offset rtos_chibios_arm_v7m_stack_offsets[ARMV7M_NUM_CORE_REGS] = { - { -1, 32 }, /* r0 */ - { -1, 32 }, /* r1 */ - { -1, 32 }, /* r2 */ - { -1, 32 }, /* r3 */ - { 0x00, 32 }, /* r4 */ - { 0x04, 32 }, /* r5 */ - { 0x08, 32 }, /* r6 */ - { 0x0c, 32 }, /* r7 */ - { 0x10, 32 }, /* r8 */ - { 0x14, 32 }, /* r9 */ - { 0x18, 32 }, /* r10 */ - { 0x1c, 32 }, /* r11 */ - { -1, 32 }, /* r12 */ - { -2, 32 }, /* sp */ - { -1, 32 }, /* lr */ - { 0x20, 32 }, /* pc */ - { -1, 32 }, /* xPSR */ -}; - -const struct rtos_register_stacking rtos_chibios_arm_v7m_stacking = { - 0x24, /* stack_registers_size */ - -1, /* stack_growth_direction */ - ARMV7M_NUM_CORE_REGS, /* num_output_registers */ - NULL, /* stack_alignment */ - rtos_chibios_arm_v7m_stack_offsets /* register_offsets */ -}; - -static const struct stack_register_offset rtos_chibios_arm_v7m_stack_offsets_w_fpu[ARMV7M_NUM_CORE_REGS] = { - { -1, 32 }, /* r0 */ - { -1, 32 }, /* r1 */ - { -1, 32 }, /* r2 */ - { -1, 32 }, /* r3 */ - { 0x40, 32 }, /* r4 */ - { 0x44, 32 }, /* r5 */ - { 0x48, 32 }, /* r6 */ - { 0x4c, 32 }, /* r7 */ - { 0x50, 32 }, /* r8 */ - { 0x54, 32 }, /* r9 */ - { 0x58, 32 }, /* r10 */ - { 0x5c, 32 }, /* r11 */ - { -1, 32 }, /* r12 */ - { -2, 32 }, /* sp */ - { -1, 32 }, /* lr */ - { 0x60, 32 }, /* pc */ - { -1, 32 }, /* xPSR */ -}; - -const struct rtos_register_stacking rtos_chibios_arm_v7m_stacking_w_fpu = { - 0x64, /* stack_registers_size */ - -1, /* stack_growth_direction */ - ARMV7M_NUM_CORE_REGS, /* num_output_registers */ - NULL, /* stack_alignment */ - rtos_chibios_arm_v7m_stack_offsets_w_fpu /* register_offsets */ -}; diff --git a/src/rtos/rtos_chibios_stackings.h b/src/rtos/rtos_chibios_stackings.h deleted file mode 100644 index 130aaa1..0000000 --- a/src/rtos/rtos_chibios_stackings.h +++ /dev/null @@ -1,31 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Broadcom Corporation * - * Evan Hunter - ehunter@broadcom.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * 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, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ - -#ifndef OPENOCD_RTOS_RTOS_CHIBIOS_STACKINGS_H -#define OPENOCD_RTOS_RTOS_CHIBIOS_STACKINGS_H - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "rtos.h" - -extern const struct rtos_register_stacking rtos_chibios_arm_v7m_stacking; -extern const struct rtos_register_stacking rtos_chibios_arm_v7m_stacking_w_fpu; - -#endif /* OPENOCD_RTOS_RTOS_CHIBIOS_STACKINGS_H */ diff --git a/src/rtos/rtos_ecos_stackings.c b/src/rtos/rtos_ecos_stackings.c deleted file mode 100644 index 43d97a6..0000000 --- a/src/rtos/rtos_ecos_stackings.c +++ /dev/null @@ -1,51 +0,0 @@ -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * 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, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "rtos.h" -#include "rtos_standard_stackings.h" -#include "target/armv7m.h" - -static const struct stack_register_offset rtos_eCos_Cortex_M3_stack_offsets[ARMV7M_NUM_CORE_REGS] = { - { 0x0c, 32 }, /* r0 */ - { 0x10, 32 }, /* r1 */ - { 0x14, 32 }, /* r2 */ - { 0x18, 32 }, /* r3 */ - { 0x1c, 32 }, /* r4 */ - { 0x20, 32 }, /* r5 */ - { 0x24, 32 }, /* r6 */ - { 0x28, 32 }, /* r7 */ - { 0x2c, 32 }, /* r8 */ - { 0x30, 32 }, /* r9 */ - { 0x34, 32 }, /* r10 */ - { 0x38, 32 }, /* r11 */ - { 0x3c, 32 }, /* r12 */ - { -2, 32 }, /* sp */ - { -1, 32 }, /* lr */ - { 0x40, 32 }, /* pc */ - { -1, 32 }, /* xPSR */ -}; - -const struct rtos_register_stacking rtos_eCos_Cortex_M3_stacking = { - 0x44, /* stack_registers_size */ - -1, /* stack_growth_direction */ - ARMV7M_NUM_CORE_REGS, /* num_output_registers */ - rtos_generic_stack_align8, /* stack_alignment */ - rtos_eCos_Cortex_M3_stack_offsets /* register_offsets */ -}; diff --git a/src/rtos/rtos_ecos_stackings.h b/src/rtos/rtos_ecos_stackings.h deleted file mode 100644 index 951f7de..0000000 --- a/src/rtos/rtos_ecos_stackings.h +++ /dev/null @@ -1,28 +0,0 @@ -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * 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, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ - -#ifndef OPENOCD_RTOS_RTOS_ECOS_STACKINGS_H -#define OPENOCD_RTOS_RTOS_ECOS_STACKINGS_H - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "rtos.h" - -extern const struct rtos_register_stacking rtos_eCos_Cortex_M3_stacking; - -#endif /* OPENOCD_RTOS_RTOS_ECOS_STACKINGS_H */ diff --git a/src/rtos/rtos_embkernel_stackings.c b/src/rtos/rtos_embkernel_stackings.c deleted file mode 100644 index 2a30629..0000000 --- a/src/rtos/rtos_embkernel_stackings.c +++ /dev/null @@ -1,55 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Broadcom Corporation * - * Evan Hunter - ehunter@broadcom.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * 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, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "rtos.h" -#include "target/armv7m.h" -#include "rtos_standard_stackings.h" - -static const struct stack_register_offset rtos_embkernel_Cortex_M_stack_offsets[ARMV7M_NUM_CORE_REGS] = { - { 0x24, 32 }, /* r0 */ - { 0x28, 32 }, /* r1 */ - { 0x2c, 32 }, /* r2 */ - { 0x30, 32 }, /* r3 */ - { 0x00, 32 }, /* r4 */ - { 0x04, 32 }, /* r5 */ - { 0x08, 32 }, /* r6 */ - { 0x0c, 32 }, /* r7 */ - { 0x10, 32 }, /* r8 */ - { 0x14, 32 }, /* r9 */ - { 0x18, 32 }, /* r10 */ - { 0x1c, 32 }, /* r11 */ - { 0x34, 32 }, /* r12 */ - { -2, 32 }, /* sp */ - { 0x38, 32 }, /* lr */ - { 0x3c, 32 }, /* pc */ - { 0x40, 32 }, /* xPSR */ -}; - -const struct rtos_register_stacking rtos_embkernel_Cortex_M_stacking = { - 0x40, /* stack_registers_size */ - -1, /* stack_growth_direction */ - ARMV7M_NUM_CORE_REGS, /* num_output_registers */ - rtos_generic_stack_align8, /* stack_alignment */ - rtos_embkernel_Cortex_M_stack_offsets /* register_offsets */ -}; - - diff --git a/src/rtos/rtos_embkernel_stackings.h b/src/rtos/rtos_embkernel_stackings.h deleted file mode 100644 index 89a0c2f..0000000 --- a/src/rtos/rtos_embkernel_stackings.h +++ /dev/null @@ -1,30 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Broadcom Corporation * - * Evan Hunter - ehunter@broadcom.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * 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, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ - -#ifndef OPENOCD_RTOS_RTOS_EMBKERNEL_STACKINGS_H -#define OPENOCD_RTOS_RTOS_EMBKERNEL_STACKINGS_H - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "rtos.h" - -extern const struct rtos_register_stacking rtos_embkernel_Cortex_M_stacking; - -#endif /* OPENOCD_RTOS_RTOS_EMBKERNEL_STACKINGS_H */ diff --git a/src/rtos/rtos_mqx_stackings.c b/src/rtos/rtos_mqx_stackings.c deleted file mode 100644 index 5db2f8e..0000000 --- a/src/rtos/rtos_mqx_stackings.c +++ /dev/null @@ -1,80 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2014 by Marian Cingel * - * cingel.marian@gmail.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * 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, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "rtos.h" -#include "target/armv7m.h" - - -/* - * standard exception stack - * ( stack base, higher memory address ) - * - xpsr - 0x48 - * - pc - 0x44 - * - lr - 0x40 - * - r12 - 0x3C - * - r3 - 0x38 - * - r2 - 0x34 - * - r1 - 0x30 - * - r0 - 0x2C - * extended stack in svc_pending handler - * - lr - 0x28 - * - r11 - 0x24 - * - r10 - 0x20 - * - r9 - 0x1C - * - r8 - 0x18 - * - r7 - 0x14 - * - r6 - 0x10 - * - r5 - 0x0C - * - r4 - 0x08 - * - BASEPRI - 0x04 - * - SHPR3 - 0x00 ( contains pend_svc exception priority ) - * ( stack head, lower address, stored in 'task->STACK_PTR' ) - */ - -static const struct stack_register_offset rtos_mqx_arm_v7m_stack_offsets[ARMV7M_NUM_CORE_REGS] = { - { 0x2C, 32 }, /* r0 */ - { 0x30, 32 }, /* r1 */ - { 0x34, 32 }, /* r2 */ - { 0x38, 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 */ - { 0x3C, 32 }, /* r12 */ - { -2 , 32 }, /* sp */ - { 0x28, 32 }, /* lr */ - { 0x44, 32 }, /* pc */ - { 0x48, 32 }, /* xPSR */ -}; - -const struct rtos_register_stacking rtos_mqx_arm_v7m_stacking = { - 0x4C, /* stack_registers_size, calculate offset base address */ - -1, /* stack_growth_direction */ - ARMV7M_NUM_CORE_REGS, /* num_output_registers */ - NULL, /* stack_alignment */ - rtos_mqx_arm_v7m_stack_offsets /* register_offsets */ -}; - diff --git a/src/rtos/rtos_mqx_stackings.h b/src/rtos/rtos_mqx_stackings.h deleted file mode 100644 index 6ebd287..0000000 --- a/src/rtos/rtos_mqx_stackings.h +++ /dev/null @@ -1,30 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2014 by Marian Cingel * - * cingel.marian@gmail.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * 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, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ - -#ifndef OPENOCD_RTOS_RTOS_MQX_STACKINGS_H -#define OPENOCD_RTOS_RTOS_MQX_STACKINGS_H - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "rtos.h" - -extern const struct rtos_register_stacking rtos_mqx_arm_v7m_stacking; - -#endif /* OPENOCD_RTOS_RTOS_MQX_STACKINGS_H */ diff --git a/src/rtos/rtos_standard_stackings.c b/src/rtos/rtos_standard_stackings.c deleted file mode 100644 index 0176c01..0000000 --- a/src/rtos/rtos_standard_stackings.c +++ /dev/null @@ -1,270 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Broadcom Corporation * - * Evan Hunter - ehunter@broadcom.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * 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, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "rtos.h" -#include "target/armv7m.h" - -static const struct stack_register_offset rtos_standard_Cortex_M3_stack_offsets[ARMV7M_NUM_CORE_REGS] = { - { 0x20, 32 }, /* r0 */ - { 0x24, 32 }, /* r1 */ - { 0x28, 32 }, /* r2 */ - { 0x2c, 32 }, /* r3 */ - { 0x00, 32 }, /* r4 */ - { 0x04, 32 }, /* r5 */ - { 0x08, 32 }, /* r6 */ - { 0x0c, 32 }, /* r7 */ - { 0x10, 32 }, /* r8 */ - { 0x14, 32 }, /* r9 */ - { 0x18, 32 }, /* r10 */ - { 0x1c, 32 }, /* r11 */ - { 0x30, 32 }, /* r12 */ - { -2, 32 }, /* sp */ - { 0x34, 32 }, /* lr */ - { 0x38, 32 }, /* pc */ - { 0x3c, 32 }, /* xPSR */ -}; - -static const struct stack_register_offset rtos_standard_Cortex_M4F_stack_offsets[] = { - { 0x24, 32 }, /* r0 */ - { 0x28, 32 }, /* r1 */ - { 0x2c, 32 }, /* r2 */ - { 0x30, 32 }, /* r3 */ - { 0x00, 32 }, /* r4 */ - { 0x04, 32 }, /* r5 */ - { 0x08, 32 }, /* r6 */ - { 0x0c, 32 }, /* r7 */ - { 0x10, 32 }, /* r8 */ - { 0x14, 32 }, /* r9 */ - { 0x18, 32 }, /* r10 */ - { 0x1c, 32 }, /* r11 */ - { 0x34, 32 }, /* r12 */ - { -2, 32 }, /* sp */ - { 0x38, 32 }, /* lr */ - { 0x3c, 32 }, /* pc */ - { 0x40, 32 }, /* xPSR */ -}; - -static const struct stack_register_offset rtos_standard_Cortex_M4F_FPU_stack_offsets[] = { - { 0x64, 32 }, /* r0 */ - { 0x68, 32 }, /* r1 */ - { 0x6c, 32 }, /* r2 */ - { 0x70, 32 }, /* r3 */ - { 0x00, 32 }, /* r4 */ - { 0x04, 32 }, /* r5 */ - { 0x08, 32 }, /* r6 */ - { 0x0c, 32 }, /* r7 */ - { 0x10, 32 }, /* r8 */ - { 0x14, 32 }, /* r9 */ - { 0x18, 32 }, /* r10 */ - { 0x1c, 32 }, /* r11 */ - { 0x74, 32 }, /* r12 */ - { -2, 32 }, /* sp */ - { 0x78, 32 }, /* lr */ - { 0x7c, 32 }, /* pc */ - { 0x80, 32 }, /* xPSR */ -}; - - -static const struct stack_register_offset rtos_standard_Cortex_R4_stack_offsets[] = { - { 0x08, 32 }, /* r0 (a1) */ - { 0x0c, 32 }, /* r1 (a2) */ - { 0x10, 32 }, /* r2 (a3) */ - { 0x14, 32 }, /* r3 (a4) */ - { 0x18, 32 }, /* r4 (v1) */ - { 0x1c, 32 }, /* r5 (v2) */ - { 0x20, 32 }, /* r6 (v3) */ - { 0x24, 32 }, /* r7 (v4) */ - { 0x28, 32 }, /* r8 (a1) */ - { 0x2c, 32 }, /* r9 (sb) */ - { 0x30, 32 }, /* r10 (sl) */ - { 0x34, 32 }, /* r11 (fp) */ - { 0x38, 32 }, /* r12 (ip) */ - { -2, 32 }, /* sp */ - { 0x3c, 32 }, /* lr */ - { 0x40, 32 }, /* pc */ - { -1, 96 }, /* FPA1 */ - { -1, 96 }, /* FPA2 */ - { -1, 96 }, /* FPA3 */ - { -1, 96 }, /* FPA4 */ - { -1, 96 }, /* FPA5 */ - { -1, 96 }, /* FPA6 */ - { -1, 96 }, /* FPA7 */ - { -1, 96 }, /* FPA8 */ - { -1, 32 }, /* FPS */ - { 0x04, 32 }, /* CSPR */ -}; - -static const struct stack_register_offset rtos_standard_NDS32_N1068_stack_offsets[] = { - { 0x88, 32 }, /* R0 */ - { 0x8C, 32 }, /* R1 */ - { 0x14, 32 }, /* R2 */ - { 0x18, 32 }, /* R3 */ - { 0x1C, 32 }, /* R4 */ - { 0x20, 32 }, /* R5 */ - { 0x24, 32 }, /* R6 */ - { 0x28, 32 }, /* R7 */ - { 0x2C, 32 }, /* R8 */ - { 0x30, 32 }, /* R9 */ - { 0x34, 32 }, /* R10 */ - { 0x38, 32 }, /* R11 */ - { 0x3C, 32 }, /* R12 */ - { 0x40, 32 }, /* R13 */ - { 0x44, 32 }, /* R14 */ - { 0x48, 32 }, /* R15 */ - { 0x4C, 32 }, /* R16 */ - { 0x50, 32 }, /* R17 */ - { 0x54, 32 }, /* R18 */ - { 0x58, 32 }, /* R19 */ - { 0x5C, 32 }, /* R20 */ - { 0x60, 32 }, /* R21 */ - { 0x64, 32 }, /* R22 */ - { 0x68, 32 }, /* R23 */ - { 0x6C, 32 }, /* R24 */ - { 0x70, 32 }, /* R25 */ - { 0x74, 32 }, /* R26 */ - { 0x78, 32 }, /* R27 */ - { 0x7C, 32 }, /* R28 */ - { 0x80, 32 }, /* R29 */ - { 0x84, 32 }, /* R30 (LP) */ - { 0x00, 32 }, /* R31 (SP) */ - { 0x04, 32 }, /* PSW */ - { 0x08, 32 }, /* IPC */ - { 0x0C, 32 }, /* IPSW */ - { 0x10, 32 }, /* IFC_LP */ -}; - -static int64_t rtos_generic_stack_align(struct target *target, - const uint8_t *stack_data, const struct rtos_register_stacking *stacking, - int64_t stack_ptr, int align) -{ - int64_t new_stack_ptr; - int64_t aligned_stack_ptr; - new_stack_ptr = stack_ptr - stacking->stack_growth_direction * - stacking->stack_registers_size; - aligned_stack_ptr = new_stack_ptr & ~((int64_t)align - 1); - if (aligned_stack_ptr != new_stack_ptr && - stacking->stack_growth_direction == -1) { - /* If we have a downward growing stack, the simple alignment code - * above results in a wrong result (since it rounds down to nearest - * alignment). We want to round up so add an extra align. - */ - aligned_stack_ptr += (int64_t)align; - } - return aligned_stack_ptr; -} - -int64_t rtos_generic_stack_align8(struct target *target, - const uint8_t *stack_data, const struct rtos_register_stacking *stacking, - int64_t stack_ptr) -{ - return rtos_generic_stack_align(target, stack_data, - stacking, stack_ptr, 8); -} - -/* The Cortex-M3 will indicate that an alignment adjustment - * has been done on the stack by setting bit 9 of the stacked xPSR - * register. In this case, we can just add an extra 4 bytes to get - * to the program stack. Note that some places in the ARM documentation - * make this a little unclear but the padding takes place before the - * normal exception stacking - so xPSR is always available at a fixed - * location. - * - * Relevant documentation: - * Cortex-M series processors -> Cortex-M3 -> Revision: xxx -> - * Cortex-M3 Devices Generic User Guide -> The Cortex-M3 Processor -> - * Exception Model -> Exception entry and return -> Exception entry - * Cortex-M series processors -> Cortex-M3 -> Revision: xxx -> - * Cortex-M3 Devices Generic User Guide -> Cortex-M3 Peripherals -> - * System control block -> Configuration and Control Register (STKALIGN) - * - * This is just a helper function for use in the calculate_process_stack - * function for a given architecture/rtos. - */ -int64_t rtos_Cortex_M_stack_align(struct target *target, - const uint8_t *stack_data, const struct rtos_register_stacking *stacking, - int64_t stack_ptr, size_t xpsr_offset) -{ - const uint32_t ALIGN_NEEDED = (1 << 9); - uint32_t xpsr; - int64_t new_stack_ptr; - - new_stack_ptr = stack_ptr - stacking->stack_growth_direction * - stacking->stack_registers_size; - xpsr = (target->endianness == TARGET_LITTLE_ENDIAN) ? - le_to_h_u32(&stack_data[xpsr_offset]) : - be_to_h_u32(&stack_data[xpsr_offset]); - if ((xpsr & ALIGN_NEEDED) != 0) { - LOG_DEBUG("XPSR(0x%08" PRIx32 ") indicated stack alignment was necessary\r\n", - xpsr); - new_stack_ptr -= (stacking->stack_growth_direction * 4); - } - return new_stack_ptr; -} - -static int64_t rtos_standard_Cortex_M3_stack_align(struct target *target, - const uint8_t *stack_data, const struct rtos_register_stacking *stacking, - int64_t stack_ptr) -{ - const int XPSR_OFFSET = 0x3c; - return rtos_Cortex_M_stack_align(target, stack_data, stacking, - stack_ptr, XPSR_OFFSET); -} - -const struct rtos_register_stacking rtos_standard_Cortex_M3_stacking = { - 0x40, /* stack_registers_size */ - -1, /* stack_growth_direction */ - ARMV7M_NUM_CORE_REGS, /* num_output_registers */ - rtos_standard_Cortex_M3_stack_align, /* stack_alignment */ - rtos_standard_Cortex_M3_stack_offsets /* register_offsets */ -}; - -const struct rtos_register_stacking rtos_standard_Cortex_M4F_stacking = { - 0x44, /* stack_registers_size 4 more for LR*/ - -1, /* stack_growth_direction */ - ARMV7M_NUM_CORE_REGS, /* num_output_registers */ - rtos_standard_Cortex_M3_stack_align, /* stack_alignment */ - rtos_standard_Cortex_M4F_stack_offsets /* register_offsets */ -}; - -const struct rtos_register_stacking rtos_standard_Cortex_M4F_FPU_stacking = { - 0xcc, /* stack_registers_size 4 more for LR + 48 more for FPU S0-S15 register*/ - -1, /* stack_growth_direction */ - ARMV7M_NUM_CORE_REGS, /* num_output_registers */ - rtos_standard_Cortex_M3_stack_align, /* stack_alignment */ - rtos_standard_Cortex_M4F_FPU_stack_offsets /* register_offsets */ -}; - -const struct rtos_register_stacking rtos_standard_Cortex_R4_stacking = { - 0x48, /* stack_registers_size */ - -1, /* stack_growth_direction */ - 26, /* num_output_registers */ - rtos_generic_stack_align8, /* stack_alignment */ - rtos_standard_Cortex_R4_stack_offsets /* register_offsets */ -}; - -const struct rtos_register_stacking rtos_standard_NDS32_N1068_stacking = { - 0x90, /* stack_registers_size */ - -1, /* stack_growth_direction */ - 32, /* num_output_registers */ - rtos_generic_stack_align8, /* stack_alignment */ - rtos_standard_NDS32_N1068_stack_offsets /* register_offsets */ -}; diff --git a/src/rtos/rtos_standard_stackings.h b/src/rtos/rtos_standard_stackings.h deleted file mode 100644 index 6971efd..0000000 --- a/src/rtos/rtos_standard_stackings.h +++ /dev/null @@ -1,40 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Broadcom Corporation * - * Evan Hunter - ehunter@broadcom.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * 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, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ - -#ifndef OPENOCD_RTOS_RTOS_STANDARD_STACKINGS_H -#define OPENOCD_RTOS_RTOS_STANDARD_STACKINGS_H - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "rtos.h" - -extern const struct rtos_register_stacking rtos_standard_Cortex_M3_stacking; -extern const struct rtos_register_stacking rtos_standard_Cortex_M4F_stacking; -extern const struct rtos_register_stacking rtos_standard_Cortex_M4F_FPU_stacking; -extern const struct rtos_register_stacking rtos_standard_Cortex_R4_stacking; -extern const struct rtos_register_stacking rtos_standard_NDS32_N1068_stacking; -int64_t rtos_generic_stack_align8(struct target *target, - const uint8_t *stack_data, const struct rtos_register_stacking *stacking, - int64_t stack_ptr); -int64_t rtos_Cortex_M_stack_align(struct target *target, - const uint8_t *stack_data, const struct rtos_register_stacking *stacking, - int64_t stack_ptr, size_t xpsr_offset); - -#endif /* OPENOCD_RTOS_RTOS_STANDARD_STACKINGS_H */ |
