From e629076003998b004e9bcf3a0e71633383d93863 Mon Sep 17 00:00:00 2001 From: Chris Johns Date: Wed, 30 Nov 2016 09:19:05 +1100 Subject: libdebugger: Build for ARM's without a CP15. --- cpukit/libdebugger/rtems-debugger-arm.c | 154 +++++++++++++++++++++++--------- 1 file changed, 114 insertions(+), 40 deletions(-) (limited to 'cpukit/libdebugger') diff --git a/cpukit/libdebugger/rtems-debugger-arm.c b/cpukit/libdebugger/rtems-debugger-arm.c index 945dc9c2d9..8126c1471e 100644 --- a/cpukit/libdebugger/rtems-debugger-arm.c +++ b/cpukit/libdebugger/rtems-debugger-arm.c @@ -36,7 +36,6 @@ #include #include -#include #include #include "rtems-debugger-target.h" @@ -46,6 +45,60 @@ #include #endif +/* + * ARM Variant controls. + */ +#if defined(__ARM_ARCH_7A__) || \ + defined(__ARM_ARCH_7R__) + #define ARM_CP15 1 +#endif + +#if (defined(__ARM_ARCH_7M__) || \ + defined(__ARM_ARCH_7EM__)) + #define ARM_THUMB_ONLY 1 +#else + #define ARM_THUMB_ONLY 0 +#endif + +#if defined(ARM_MULTILIB_ARCH_V4) + #define ARM_PSR_HAS_INT_MASK 1 + #define ARM_PSR_HAS_THUMB 1 +#else + #define ARM_PSR_HAS_INT_MASK 0 + #define ARM_PSR_HAS_THUMB 0 +#endif + +#if ARM_CP15 +#include +#endif + +/** + * If thumb build of code switch the asm to thumb as required. + * + * If the variant only supports thumb insturctions disable the support. + */ +#define ARM_SWITCH_REG uint32_t arm_switch_reg +#define ARM_SWITCH_REG_ASM [arm_switch_reg] "=&r" (arm_switch_reg) +#if !ARM_THUMB_ONLY && defined(__thumb__) + #define ASM_ARM_MODE ".align 2\nbx pc\n.arm\n" + #define ASM_THUMB_MODE "add %[arm_switch_reg], pc, #1\nbx %[arm_switch_reg]\n.thumb\n" +#else + #define ASM_ARM_MODE + #define ASM_THUMB_MODE +#endif + +/* + * Hack to work around ARMv7-M not having a the T and I bits in the PSR. + * + * This needs to be fixed when real support for this ARM variant is added. + */ +#if !defined(ARM_PSR_I) + #define ARM_PSR_I 0 +#endif +#if !defined(ARM_PSR_T) + #define ARM_PSR_T 0 +#endif + /* * The ARM has 2 interrupt bits. */ @@ -112,7 +165,7 @@ #ifdef __thumb__ static const uint8_t breakpoint[2] = { 0x55, 0xbe }; #else - static const uint8_t breakpoint[4] = { 0x75, 0xe0a, 0x20, 0xe1 }; + static const uint8_t breakpoint[4] = { 0x75, 0xe0, 0x20, 0xe1 }; #endif /** @@ -120,11 +173,6 @@ */ RTEMS_INTERRUPT_LOCK_DEFINE(static, target_lock, "target_lock") -/** - * The init value for the text section. - */ -static uint32_t text_section_flags; - /** * Is a session active? */ @@ -225,22 +273,24 @@ mode_label(int mode) #define ARM_CP14_WRITE(_val, _CRn, _CRm, _opc2) \ do { \ - ARM_SWITCH_REGISTERS; \ + ARM_SWITCH_REG; \ asm volatile( \ - ARM_SWITCH_TO_ARM \ + ASM_ARM_MODE \ ARM_CP14_INSTR(mcr, val, _CRn, _CRm, _opc2) \ - ARM_SWITCH_BACK \ - : ARM_SWITCH_OUTPUT : [val] "r" (_val)); \ + ASM_THUMB_MODE \ + : ARM_SWITCH_REG_ASM \ + : [val] "r" (_val)); \ } while (0) #define ARM_CP14_READ(_val, _CRn, _CRm, _opc2) \ do { \ - ARM_SWITCH_REGISTERS; \ + ARM_SWITCH_REG; \ asm volatile( \ - ARM_SWITCH_TO_ARM \ + ASM_ARM_MODE \ ARM_CP14_INSTR(mrc, val, _CRn, _CRm, _opc2) \ - ARM_SWITCH_BACK \ - : [val] "=&r" (_val) ARM_SWITCH_ADDITIONAL_OUTPUT); \ + ASM_THUMB_MODE \ + : ARM_SWITCH_REG_ASM, \ + [val] "=&r" (_val)); \ } while (0) static int @@ -556,19 +606,6 @@ target_exception(CPU_Exception_frame* frame) (uint32_t) frame, (intptr_t) frame->register_pc, FRAME_SR); } -/** - * If thumb build of code switch the asm to thumb as required. - */ -#ifdef __thumb__ - #define ASM_ARM_MODE ".align 2\nbx pc\n.arm\n" - #define ASM_THUMB_MODE "add %[arm_switch_reg], pc, #1\nbx %[arm_switch_reg]\n.thumb\n" - #define ARM_SWITCH_REG uint32_t arm_switch_reg -#else - #define ASM_ARM_MODE - #define ASM_THUMB_MODE - #define ARM_SWITCH_REG -#endif - /** * Exception stack frame size. * @@ -607,7 +644,7 @@ target_exception(CPU_Exception_frame* frame) "sub sp, #4\n" \ "str lr, [sp]\n" /* save the link reg */ \ ASM_THUMB_MODE \ - : [arm_switch_reg] "=&r" (arm_switch_reg) \ + : ARM_SWITCH_REG_ASM \ : [frame_size] "i" (EXCEPTION_FRAME_SIZE) \ : "memory") @@ -682,7 +719,7 @@ target_exception(CPU_Exception_frame* frame) EXCEPTION_ENTRY_FPU(frame_fpu_size) \ "msr cpsr, r1\n" /* restore the irq mask */ \ ASM_THUMB_MODE \ - : [arm_switch_reg] "=&r" (arm_switch_reg), \ + : ARM_SWITCH_REG_ASM, \ [o_frame] "=r" (_frame) \ : [psr_t] "i" (ARM_PSR_T), \ [psr_i] "i" (ARM_PSR_I), \ @@ -755,7 +792,7 @@ target_exception(CPU_Exception_frame* frame) "mov lr, r5\n" /* get the PC */ \ "str lr, [sp]\n" /* save the link reg */ \ ASM_THUMB_MODE \ - : [arm_switch_reg] "=&r" (arm_switch_reg) \ + : ARM_SWITCH_REG_ASM \ : [psr_i] "i" (ARM_PSR_I), \ [r0_r12_size] "i" (13 * sizeof(uint32_t)), \ [frame_cpsr] "i" (EXCEPTION_FRAME_SIZE - sizeof(uint32_t)), \ @@ -821,10 +858,14 @@ target_exception_prefetch_abort(void) EXCEPTION_ENTRY_EXC(); arm_debug_break_unload(); EXCEPTION_ENTRY_THREAD(frame); +#if ARM_CP15 if ((arm_cp15_get_instruction_fault_status() & 0x1f) == 0x02) frame->vector = 2; else frame->vector = 3; +#else + frame->vector = 3; +#endif target_exception(frame); EXCEPTION_EXIT_THREAD(frame); arm_debug_break_load(); @@ -846,18 +887,19 @@ target_exception_data_abort(void) EXCEPTION_EXIT_EXC(); } -int -rtems_debugger_target_enable(void) +#if ARM_CP15 +/** + * The init value for the text section. + */ +static uint32_t text_section_flags; + +static void +rtems_debugger_target_set_vectors(void) { - rtems_interrupt_lock_context lock_context; - void* text_begin; - void* text_end; - debug_session_active = true; + void* text_begin; + void* text_end; text_begin = &bsp_section_text_begin[0]; text_end = &bsp_section_text_end[0]; - rtems_interrupt_lock_acquire(&target_lock, &lock_context); - arm_debug_break_unload(); - arm_debug_break_clear(); text_section_flags = arm_cp15_set_translation_table_entries(text_begin, text_end, @@ -870,6 +912,34 @@ rtems_debugger_target_enable(void) target_exception_prefetch_abort); arm_cp15_set_exception_handler(ARM_EXCEPTION_DATA_ABORT, target_exception_data_abort); +} +#else +static void +rtems_debugger_target_set_vectors(void) +{ + /* + * Dummy, please add support for your ARM variant. + */ + void* ui = target_exception_undefined_instruction; + void* sc = target_exception_supervisor_call; + void* pa = target_exception_prefetch_abort; + void* da = target_exception_data_abort; + (void) ui; + (void) sc; + (void) pa; + (void) da; +} +#endif + +int +rtems_debugger_target_enable(void) +{ + rtems_interrupt_lock_context lock_context; + debug_session_active = true; + rtems_interrupt_lock_acquire(&target_lock, &lock_context); + arm_debug_break_unload(); + arm_debug_break_clear(); + rtems_debugger_target_set_vectors(); rtems_interrupt_lock_release(&target_lock, &lock_context); return 0; } @@ -1121,6 +1191,7 @@ rtems_debugger_target_thread_stepping(rtems_debugger_thread* thread) /* * Save the interrupt state before stepping if set. */ +#if ARM_PSR_HAS_INT_MASK if ((FRAME_SR & CPSR_INTS_MASK) != 0) { uint32_t int_state; int_state = @@ -1131,6 +1202,7 @@ rtems_debugger_target_thread_stepping(rtems_debugger_thread* thread) * Mask the interrupt when stepping. */ FRAME_SR |= CPSR_INTS_MASK; +#endif break; } } @@ -1142,6 +1214,7 @@ int rtems_debugger_target_exception_to_signal(CPU_Exception_frame* frame) { int sig = RTEMS_DEBUGGER_SIGNAL_HUP; +#if defined(ARM_EXCEPTION_RESET) switch (frame->vector) { case ARM_EXCEPTION_RESET: case ARM_EXCEPTION_SWI: @@ -1164,6 +1237,7 @@ rtems_debugger_target_exception_to_signal(CPU_Exception_frame* frame) default: break; } +#endif return sig; } -- cgit v1.2.3