This is an automated email from Gerrit. "Mateus Campaner Hercules <mchercu...@gmail.com>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/7481
-- gerrit commit fd28414332a81e21329996dd46e1bbf04296029a Author: Mateus Campaner Hercules <mchercu...@gmail.com> Date: Wed Feb 15 14:06:43 2023 -0300 FreeRTOS: added support to M3_MPU & M4_MPU ports Added new FreeRTOS stackings and a patch to name parsing. Added a symbol to check if port is using any kind of MPU. TODO: check MPU enabling on non-arm MPU peripherals. Signed-off-by: Mateus Campaner Hercules <mchercu...@gmail.com> Change-Id: Ia6a1bd69fab5f4b4823bc4e03fb8f71044ad4cdf diff --git a/contrib/rtos-helpers/FreeRTOS-openocd.c b/contrib/rtos-helpers/FreeRTOS-openocd.c index 000453d5d4..4b1a2bca74 100644 --- a/contrib/rtos-helpers/FreeRTOS-openocd.c +++ b/contrib/rtos-helpers/FreeRTOS-openocd.c @@ -20,3 +20,9 @@ #endif const int USED uxTopUsedPriority = configMAX_PRIORITIES - 1; + +#ifdef portUSING_MPU_WRAPPERS +const int USED uxMPUPortInUse = sizeof(xMPU_SETTINGS); +#else +const int USED uxMPUPortInUse = 0; +#endif diff --git a/src/rtos/FreeRTOS.c b/src/rtos/FreeRTOS.c index 070275f2c5..ad29c0c0a8 100644 --- a/src/rtos/FreeRTOS.c +++ b/src/rtos/FreeRTOS.c @@ -40,6 +40,8 @@ struct freertos_params { 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; + const struct rtos_register_stacking *stacking_info_cm4f_mpu; + const struct rtos_register_stacking *stacking_info_cm4f_mpu_fpu; }; static const struct freertos_params freertos_params_list[] = { @@ -56,6 +58,8 @@ static const struct freertos_params freertos_params_list[] = { &rtos_standard_cortex_m3_stacking, /* stacking_info */ &rtos_standard_cortex_m4f_stacking, &rtos_standard_cortex_m4f_fpu_stacking, + &rtos_standard_cortex_m4f_mpu_stacking, + &rtos_standard_cortex_m4f_mpu_fpu_stacking, }, { "hla_target", /* target_name */ @@ -70,6 +74,8 @@ static const struct freertos_params freertos_params_list[] = { &rtos_standard_cortex_m3_stacking, /* stacking_info */ &rtos_standard_cortex_m4f_stacking, &rtos_standard_cortex_m4f_fpu_stacking, + &rtos_standard_cortex_m4f_mpu_stacking, + &rtos_standard_cortex_m4f_mpu_fpu_stacking, }, }; @@ -103,6 +109,7 @@ enum freertos_symbol_values { FREERTOS_VAL_UX_CURRENT_NUMBER_OF_TASKS = 9, FREERTOS_VAL_UX_TOP_USED_PRIORITY = 10, FREERTOS_VAL_X_SCHEDULER_RUNNING = 11, + FREERTOS_VAL_UX_MPU_PORT_IN_USE = 12, }; struct symbols { @@ -123,6 +130,7 @@ static const struct symbols freertos_symbol_list[] = { { "uxCurrentNumberOfTasks", false }, { "uxTopUsedPriority", true }, /* Unavailable since v7.5.3 */ { "xSchedulerRunning", false }, + { "uxMPUPortInUse", true }, /* Used to detect if a MPU port is in use. */ { NULL, false } }; @@ -326,6 +334,25 @@ static int freertos_update_threads(struct rtos *rtos) list_elem_ptr + param->list_elem_content_offset, rtos->thread_details[tasks_found].threadid); + /* The FreeRTOS kernel does not provide any query or symbol + * to identify the port in use, as is it's premise: The user + * API is independent from Host. But that leaves us a problem: + * In the CM4_MPU port the TCB layout is modified, because of + * the MPU regions, and that gives us an additional offset to + * the actual thread name. + * Use contrib/rtos-helpers/FreeRTOS-openocd.c to get the + * necessary symbol. */ + + uint32_t mpu_name_offset; + retval = target_read_u32(rtos->target, + rtos->symbols[FREERTOS_VAL_UX_MPU_PORT_IN_USE].address, + &mpu_name_offset); + if (retval != ERROR_OK) + return retval; + + LOG_DEBUG("FreeRTOS: Read uxMPUPortInUse at 0x%" PRIx64 ", value %" PRIu32, + rtos->symbols[FREERTOS_VAL_UX_MPU_PORT_IN_USE].address, + mpu_name_offset); /* get thread name */ #define FREERTOS_THREAD_NAME_STR_SIZE (200) @@ -333,7 +360,7 @@ static int freertos_update_threads(struct rtos *rtos) /* Read the thread name */ retval = target_read_buffer(rtos->target, - rtos->thread_details[tasks_found].threadid + param->thread_name_offset, + rtos->thread_details[tasks_found].threadid + param->thread_name_offset + mpu_name_offset, FREERTOS_THREAD_NAME_STR_SIZE, (uint8_t *)&tmp_str); if (retval != ERROR_OK) { @@ -343,8 +370,8 @@ static int freertos_update_threads(struct rtos *rtos) } tmp_str[FREERTOS_THREAD_NAME_STR_SIZE-1] = '\x00'; LOG_DEBUG("FreeRTOS: Read Thread Name at 0x%" PRIx64 ", value '%s'", - rtos->thread_details[tasks_found].threadid + param->thread_name_offset, - tmp_str); + rtos->thread_details[tasks_found].threadid + param->thread_name_offset + mpu_name_offset, + tmp_str); if (tmp_str[0] == '\x00') strcpy(tmp_str, "No Name"); @@ -442,6 +469,56 @@ static int freertos_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, } } + /* Check for armv7m with *implemented* MPU, i.e. some vendors use a custom implementation */ + int cm4_mpu_enabled = 0; + if (is_armv7m(armv7m_target)) { + /* MPU_TYPE is always implemented on armv7m */ + uint32_t mpu_type; + + retval = target_read_u32(rtos->target, MPU_TYPE, &mpu_type); + if (retval != ERROR_OK) { + LOG_ERROR("Could not read MPU_TYPE register to check if MPU is implemented"); + return -1; + } + + /* Check if DREGION is not zero */ + if (mpu_type & 0x0000FF00) { + uint32_t mpu_ctrl; + + retval = target_read_u32(rtos->target, MPU_CTRL, &mpu_ctrl); + if (retval != ERROR_OK) { + LOG_ERROR("Could not read MPU_CTRL on a mpu present core"); + return -1; + } + + /* Check if ENABLE bit of MPU_CTRL is enabled */ + if (mpu_ctrl & 0x00000001) { + /* Found target with enabled MPU */ + cm4_mpu_enabled = 1; + } + } + } + + if (cm4_mpu_enabled == 1) { + /* Read the LR to decide between stacking with or without FPU */ + uint32_t lr_svc = 0; + retval = target_read_u32(rtos->target, + stack_ptr + 0x20, + &lr_svc); + if (retval != ERROR_OK) { + LOG_OUTPUT("Error reading stack frame from FreeRTOS thread"); + return retval; + } + if ((lr_svc & 0x10) == 0) + return rtos_generic_stack_read(rtos->target, + param->stacking_info_cm4f_mpu_fpu, + stack_ptr, + reg_list, + num_regs); + else + return rtos_generic_stack_read(rtos->target, param->stacking_info_cm4f_mpu, stack_ptr, reg_list, num_regs); + } + if (cm4_fpu_enabled == 1) { /* Read the LR to decide between stacking with or without FPU */ uint32_t lr_svc = 0; diff --git a/src/rtos/rtos_standard_stackings.c b/src/rtos/rtos_standard_stackings.c index 5478080cf7..1d96acd1c5 100644 --- a/src/rtos/rtos_standard_stackings.c +++ b/src/rtos/rtos_standard_stackings.c @@ -11,7 +11,6 @@ #include "rtos.h" #include "target/armv7m.h" -#include "rtos_standard_stackings.h" static const struct stack_register_offset rtos_standard_cortex_m3_stack_offsets[ARMV7M_NUM_CORE_REGS] = { { ARMV7M_R0, 0x20, 32 }, /* r0 */ @@ -73,6 +72,46 @@ static const struct stack_register_offset rtos_standard_cortex_m4f_fpu_stack_off { ARMV7M_XPSR, 0x80, 32 }, /* xPSR */ }; +static const struct stack_register_offset rtos_standard_cortex_m4f_mpu_stack_offsets[] = { + { ARMV7M_R0, 0x28, 32 }, /* r0 */ + { ARMV7M_R1, 0x2c, 32 }, /* r1 */ + { ARMV7M_R2, 0x30, 32 }, /* r2 */ + { ARMV7M_R3, 0x34, 32 }, /* r3 */ + { ARMV7M_R4, 0x04, 32 }, /* r4 */ + { ARMV7M_R5, 0x08, 32 }, /* r5 */ + { ARMV7M_R6, 0x0c, 32 }, /* r6 */ + { ARMV7M_R7, 0x10, 32 }, /* r7 */ + { ARMV7M_R8, 0x14, 32 }, /* r8 */ + { ARMV7M_R9, 0x18, 32 }, /* r9 */ + { ARMV7M_R10, 0x1c, 32 }, /* r10 */ + { ARMV7M_R11, 0x20, 32 }, /* r11 */ + { ARMV7M_R12, 0x38, 32 }, /* r12 */ + { ARMV7M_R13, -2, 32 }, /* sp */ + { ARMV7M_R14, 0x3c, 32 }, /* lr */ + { ARMV7M_PC, 0x40, 32 }, /* pc */ + { ARMV7M_XPSR, 0x44, 32 }, /* xPSR */ +}; + +static const struct stack_register_offset rtos_standard_cortex_m4f_mpu_fpu_stack_offsets[] = { + { ARMV7M_R0, 0x68, 32 }, /* r0 */ + { ARMV7M_R1, 0x6c, 32 }, /* r1 */ + { ARMV7M_R2, 0x70, 32 }, /* r2 */ + { ARMV7M_R3, 0x74, 32 }, /* r3 */ + { ARMV7M_R4, 0x04, 32 }, /* r4 */ + { ARMV7M_R5, 0x08, 32 }, /* r5 */ + { ARMV7M_R6, 0x0c, 32 }, /* r6 */ + { ARMV7M_R7, 0x10, 32 }, /* r7 */ + { ARMV7M_R8, 0x14, 32 }, /* r8 */ + { ARMV7M_R9, 0x18, 32 }, /* r9 */ + { ARMV7M_R10, 0x1c, 32 }, /* r10 */ + { ARMV7M_R11, 0x20, 32 }, /* r11 */ + { ARMV7M_R12, 0x78, 32 }, /* r12 */ + { ARMV7M_R13, -2, 32 }, /* sp */ + { ARMV7M_R14, 0x7c, 32 }, /* lr */ + { ARMV7M_PC, 0x80, 32 }, /* pc */ + { ARMV7M_XPSR, 0x84, 32 }, /* xPSR */ +}; + static const struct stack_register_offset rtos_standard_cortex_r4_stack_offsets[] = { { 0, 0x08, 32 }, /* r0 (a1) */ @@ -103,6 +142,45 @@ static const struct stack_register_offset rtos_standard_cortex_r4_stack_offsets[ { 26, 0x04, 32 }, /* CSPR */ }; +static const struct stack_register_offset rtos_standard_nds32_n1068_stack_offsets[] = { + { 0, 0x88, 32 }, /* R0 */ + { 1, 0x8C, 32 }, /* R1 */ + { 2, 0x14, 32 }, /* R2 */ + { 3, 0x18, 32 }, /* R3 */ + { 4, 0x1C, 32 }, /* R4 */ + { 5, 0x20, 32 }, /* R5 */ + { 6, 0x24, 32 }, /* R6 */ + { 7, 0x28, 32 }, /* R7 */ + { 8, 0x2C, 32 }, /* R8 */ + { 9, 0x30, 32 }, /* R9 */ + { 10, 0x34, 32 }, /* R10 */ + { 11, 0x38, 32 }, /* R11 */ + { 12, 0x3C, 32 }, /* R12 */ + { 13, 0x40, 32 }, /* R13 */ + { 14, 0x44, 32 }, /* R14 */ + { 15, 0x48, 32 }, /* R15 */ + { 16, 0x4C, 32 }, /* R16 */ + { 17, 0x50, 32 }, /* R17 */ + { 18, 0x54, 32 }, /* R18 */ + { 19, 0x58, 32 }, /* R19 */ + { 20, 0x5C, 32 }, /* R20 */ + { 21, 0x60, 32 }, /* R21 */ + { 22, 0x64, 32 }, /* R22 */ + { 23, 0x68, 32 }, /* R23 */ + { 24, 0x6C, 32 }, /* R24 */ + { 25, 0x70, 32 }, /* R25 */ + { 26, 0x74, 32 }, /* R26 */ + { 27, 0x78, 32 }, /* R27 */ + { 28, 0x7C, 32 }, /* R28 */ + { 29, 0x80, 32 }, /* R29 */ + { 30, 0x84, 32 }, /* R30 (LP) */ + { 31, 0x00, 32 }, /* R31 (SP) */ + { 32, 0x04, 32 }, /* PSW */ + { 33, 0x08, 32 }, /* IPC */ + { 34, 0x0C, 32 }, /* IPSW */ + { 35, 0x10, 32 }, /* IFC_LP */ +}; + static target_addr_t rtos_generic_stack_align(struct target *target, const uint8_t *stack_data, const struct rtos_register_stacking *stacking, target_addr_t stack_ptr, int align) @@ -198,6 +276,24 @@ static target_addr_t rtos_standard_cortex_m4f_fpu_stack_align(struct target *tar stack_ptr, XPSR_OFFSET); } +static target_addr_t rtos_standard_cortex_m4f_mpu_stack_align(struct target *target, + const uint8_t *stack_data, const struct rtos_register_stacking *stacking, + target_addr_t stack_ptr) +{ + const int XPSR_OFFSET = 0x44; + return rtos_cortex_m_stack_align(target, stack_data, stacking, + stack_ptr, XPSR_OFFSET); +} + +static target_addr_t rtos_standard_cortex_m4f_mpu_fpu_stack_align(struct target *target, + const uint8_t *stack_data, const struct rtos_register_stacking *stacking, + target_addr_t stack_ptr) +{ + const int XPSR_OFFSET = 0x84; + return rtos_cortex_m_stack_align(target, stack_data, stacking, + stack_ptr, XPSR_OFFSET); +} + const struct rtos_register_stacking rtos_standard_cortex_m3_stacking = { .stack_registers_size = 0x40, @@ -223,6 +319,22 @@ const struct rtos_register_stacking rtos_standard_cortex_m4f_fpu_stacking = { .register_offsets = rtos_standard_cortex_m4f_fpu_stack_offsets }; +const struct rtos_register_stacking rtos_standard_cortex_m4f_mpu_stacking = { + .stack_registers_size = 0x44, + .stack_growth_direction = -1, + .num_output_registers = ARMV7M_NUM_CORE_REGS, + .calculate_process_stack = rtos_standard_cortex_m4f_mpu_stack_align, + .register_offsets = rtos_standard_cortex_m4f_mpu_stack_offsets +}; + +const struct rtos_register_stacking rtos_standard_cortex_m4f_mpu_fpu_stacking = { + .stack_registers_size = 0xcc, + .stack_growth_direction = -1, + .num_output_registers = ARMV7M_NUM_CORE_REGS, + .calculate_process_stack = rtos_standard_cortex_m4f_mpu_fpu_stack_align, + .register_offsets = rtos_standard_cortex_m4f_mpu_fpu_stack_offsets +}; + const struct rtos_register_stacking rtos_standard_cortex_r4_stacking = { .stack_registers_size = 0x48, .stack_growth_direction = -1, @@ -230,3 +342,11 @@ const struct rtos_register_stacking rtos_standard_cortex_r4_stacking = { .calculate_process_stack = rtos_generic_stack_align8, .register_offsets = rtos_standard_cortex_r4_stack_offsets }; + +const struct rtos_register_stacking rtos_standard_nds32_n1068_stacking = { + .stack_registers_size = 0x90, + .stack_growth_direction = -1, + .num_output_registers = 32, + .calculate_process_stack = rtos_generic_stack_align8, + .register_offsets = rtos_standard_nds32_n1068_stack_offsets +}; diff --git a/src/rtos/rtos_standard_stackings.h b/src/rtos/rtos_standard_stackings.h index 99fbe07e48..513644ebe9 100644 --- a/src/rtos/rtos_standard_stackings.h +++ b/src/rtos/rtos_standard_stackings.h @@ -13,6 +13,8 @@ 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_m4f_mpu_stacking; +extern const struct rtos_register_stacking rtos_standard_cortex_m4f_mpu_fpu_stacking; extern const struct rtos_register_stacking rtos_standard_cortex_r4_stacking; target_addr_t rtos_generic_stack_align8(struct target *target, const uint8_t *stack_data, const struct rtos_register_stacking *stacking, diff --git a/src/target/cortex_m.h b/src/target/cortex_m.h index a1c43b56de..59e1c4b375 100644 --- a/src/target/cortex_m.h +++ b/src/target/cortex_m.h @@ -99,6 +99,9 @@ struct cortex_m_part_info { #define FPU_FPCAR 0xE000EF38 #define FPU_FPDSCR 0xE000EF3C +#define MPU_TYPE 0xE000ED90 +#define MPU_CTRL 0xE000ED94 + #define TPIU_SSPSR 0xE0040000 #define TPIU_CSPSR 0xE0040004 #define TPIU_ACPR 0xE0040010 --