File indexing completed on 2025-05-11 08:24:15
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027 #define TARGET_DEBUG 0
0028
0029 #define ARM_DUMP_ROM_TABLES 0
0030
0031 #ifdef HAVE_CONFIG_H
0032 #include "config.h"
0033 #endif
0034
0035 #include <errno.h>
0036 #include <inttypes.h>
0037 #include <stdlib.h>
0038
0039 #include <rtems.h>
0040 #include <rtems/score/threadimpl.h>
0041
0042 #include <rtems/debugger/rtems-debugger-bsp.h>
0043
0044 #include "rtems-debugger-target.h"
0045 #include "rtems-debugger-threads.h"
0046
0047 #if TARGET_DEBUG
0048 #include <rtems/bspIo.h>
0049 #endif
0050
0051
0052
0053
0054 #if (__ARM_ARCH >= 7) && \
0055 (__ARM_ARCH_PROFILE == 'A' || __ARM_ARCH_PROFILE == 'R')
0056 #define ARM_CP15 1
0057 #endif
0058
0059 #if (__ARM_ARCH >= 7) && \
0060 (__ARM_ARCH_PROFILE == 'M')
0061 #define ARM_THUMB_ONLY 1
0062 #else
0063 #define ARM_THUMB_ONLY 0
0064 #endif
0065
0066 #if defined(ARM_MULTILIB_ARCH_V4)
0067 #define ARM_PSR_HAS_INT_MASK 1
0068 #define ARM_PSR_HAS_THUMB 1
0069 #else
0070 #define ARM_PSR_HAS_INT_MASK 0
0071 #define ARM_PSR_HAS_THUMB 0
0072 #endif
0073
0074 #if ARM_CP15
0075 #include <libcpu/arm-cp15.h>
0076 #endif
0077
0078
0079
0080
0081
0082
0083 #define NEEDS_THUMB_SWITCH !ARM_THUMB_ONLY && defined(__thumb__)
0084
0085 #if NEEDS_THUMB_SWITCH
0086 #define ARM_SWITCH_REG uint32_t arm_switch_reg
0087 #define ARM_SWITCH_REG_ASM [arm_switch_reg] "=&r" (arm_switch_reg)
0088 #define ARM_SWITCH_REG_ASM_L ARM_SWITCH_REG_ASM,
0089 #define ASM_ARM_ASM ".align 2\n.arm\n"
0090 #define ASM_ARM_MODE ".align 2\nbx pc\n.arm\n"
0091 #define ASM_THUMB_MODE "add %[arm_switch_reg], pc, #1\nbx %[arm_switch_reg]\n.thumb\n"
0092 #define ARM_THUMB_MODE() __asm__ volatile(ASM_THUMB_MODE : ARM_SWITCH_REG_ASM : :);
0093 #define ARM_ARM_MODE() __asm__ volatile(ASM_ARM_MODE : : :);
0094 #else
0095 #define ARM_SWITCH_REG
0096 #define ARM_SWITCH_REG_ASM
0097 #define ARM_SWITCH_REG_ASM_L
0098 #define ASM_ARM_ASM
0099 #define ASM_ARM_MODE
0100 #define ASM_THUMB_MODE
0101 #define ARM_THUMB_MODE()
0102 #define ARM_ARM_MODE()
0103 #endif
0104
0105 #ifdef ARM_MULTILIB_HAS_BARRIER_INSTRUCTIONS
0106 #define ARM_SYNC_INST "isb\n"
0107 #else
0108 #define ARM_SYNC_INST
0109 #endif
0110
0111
0112
0113
0114
0115
0116 #if !defined(ARM_PSR_I)
0117 #define ARM_PSR_I 0
0118 #endif
0119 #if !defined(ARM_PSR_T)
0120 #define ARM_PSR_T 0
0121 #endif
0122
0123
0124
0125
0126 #define CPSR_IRQ_DISABLE 0x80
0127 #define CPSR_FIQ_DISABLE 0x40
0128 #define CPSR_INTS_MASK (CPSR_IRQ_DISABLE | CPSR_FIQ_DISABLE)
0129
0130
0131
0132
0133 #define RTEMS_DEBUGGER_SWBREAK_NUM 64
0134
0135
0136
0137
0138 #define RTEMS_DEBUGGER_NUMREGS 26
0139
0140
0141
0142
0143 #define RTEMS_DEBUGGER_REG_BYTES 4
0144 #define RTEMS_DEBUGGER_FP_REG_BYTES 12
0145
0146
0147
0148
0149 #define REG_R0 0
0150 #define REG_R1 1
0151 #define REG_R2 2
0152 #define REG_R3 3
0153 #define REG_R4 4
0154 #define REG_R5 5
0155 #define REG_R6 6
0156 #define REG_R7 7
0157 #define REG_R8 8
0158 #define REG_R9 9
0159 #define REG_R10 10
0160 #define REG_R11 11
0161 #define REG_R12 12
0162 #define REG_SP 13
0163 #define REG_LR 14
0164 #define REG_PC 15
0165 #define REG_F0 16
0166 #define REG_F1 17
0167 #define REG_F2 18
0168 #define REG_F3 19
0169 #define REG_F4 20
0170 #define REG_F5 21
0171 #define REG_F6 22
0172 #define REG_F7 23
0173 #define REG_FPS 24
0174 #define REG_CPSR 25
0175
0176
0177
0178
0179
0180
0181
0182
0183 static const size_t arm_reg_offsets[RTEMS_DEBUGGER_NUMREGS + 1] =
0184 {
0185 0,
0186 4,
0187 8,
0188 12,
0189 16,
0190 20,
0191 24,
0192 28,
0193 32,
0194 36,
0195 40,
0196 44,
0197 48,
0198 52,
0199 56,
0200 60,
0201 64,
0202 76,
0203 88,
0204 100,
0205 112,
0206 124,
0207 136,
0208 148,
0209 160,
0210 164,
0211 168
0212 };
0213
0214
0215
0216
0217 #define RTEMS_DEBUGGER_NUMREGBYTES arm_reg_offsets[RTEMS_DEBUGGER_NUMREGS]
0218
0219
0220
0221
0222 #if defined(ARM_MULTILIB_ARCH_V4) || defined(ARM_MULTILIB_ARCH_V6M)
0223 #define FRAME_SR(_frame) (_frame)->register_cpsr
0224 #elif defined(ARM_MULTILIB_ARCH_V7M)
0225 #define FRAME_SR(_frame) (_frame)->register_xpsr
0226 #else
0227 #error ARM architecture is not supported.
0228 #endif
0229
0230
0231
0232
0233 #define EXC_FRAME_PRINT(_out, _prefix, _frame) \
0234 do { \
0235 _out(_prefix " R0 = %08" PRIx32 " R1 = %08" PRIx32 \
0236 " R2 = %08" PRIx32 " R3 = %08" PRIx32 "\n", \
0237 _frame->register_r0, _frame->register_r1, \
0238 _frame->register_r2, _frame->register_r3); \
0239 _out(_prefix " R4 = %08" PRIx32 " R5 = %08" PRIx32 \
0240 " R6 = %08" PRIx32 " R7 = %08" PRIx32 "\n", \
0241 _frame->register_r4, _frame->register_r5, \
0242 _frame->register_r6, _frame->register_r7); \
0243 _out(_prefix " R8 = %08" PRIx32 " R9 = %08" PRIx32 \
0244 " R10 = %08" PRIx32 " R11 = %08" PRIx32 "\n", \
0245 _frame->register_r8, _frame->register_r9, \
0246 _frame->register_r10, _frame->register_r11); \
0247 _out(_prefix " R12 = %08" PRIx32 " SP = %08" PRIx32 \
0248 " LR = %08" PRIxPTR " PC = %08" PRIxPTR "\n", \
0249 _frame->register_r12, _frame->register_sp, \
0250 (intptr_t) _frame->register_lr, (intptr_t) _frame->register_pc); \
0251 _out(_prefix " CPSR = %08" PRIx32 " %c%c%c%c%c%c%c%c%c%c%c" \
0252 " GE:%" PRIx32 " IT:%02" PRIx32 " M:%" PRIx32 " %s\n", \
0253 FRAME_SR(_frame), \
0254 (FRAME_SR(_frame) & (1 << 31)) != 0 ? 'N' : '-', \
0255 (FRAME_SR(_frame) & (1 << 30)) != 0 ? 'Z' : '-', \
0256 (FRAME_SR(_frame) & (1 << 29)) != 0 ? 'C' : '-', \
0257 (FRAME_SR(_frame) & (1 << 28)) != 0 ? 'V' : '-', \
0258 (FRAME_SR(_frame) & (1 << 27)) != 0 ? 'Q' : '-', \
0259 (FRAME_SR(_frame) & (1 << 24)) != 0 ? 'J' : '-', \
0260 (FRAME_SR(_frame) & (1 << 9)) != 0 ? 'E' : '-', \
0261 (FRAME_SR(_frame) & (1 << 8)) != 0 ? 'A' : '-', \
0262 (FRAME_SR(_frame) & (1 << 7)) != 0 ? 'I' : '-', \
0263 (FRAME_SR(_frame) & (1 << 6)) != 0 ? 'F' : '-', \
0264 (FRAME_SR(_frame) & (1 << 5)) != 0 ? 'T' : '-', \
0265 (FRAME_SR(_frame) >> 16) & 0xf, \
0266 ((FRAME_SR(_frame) >> (25 - 5)) & (0x3 << 5)) | ((FRAME_SR(_frame) >> 10) & 0x1f), \
0267 FRAME_SR(_frame) & 0x1f, arm_mode_label(FRAME_SR(_frame) & 0x1f)); \
0268 } while (0)
0269
0270
0271
0272
0273 #ifdef __thumb__
0274 static const uint8_t breakpoint[2] = { 0x55, 0xbe };
0275 #else
0276 static const uint8_t breakpoint[4] = { 0x75, 0xe0, 0x20, 0xe1 };
0277 #endif
0278
0279
0280
0281
0282 RTEMS_INTERRUPT_LOCK_DEFINE(static, target_lock, "target_lock")
0283
0284
0285
0286
0287
0288 static const size_t exc_offsets[2][5] =
0289 {
0290
0291 { 0, 4, 0, 4, 8 },
0292
0293 { 0, 2, 0, 4, 8 }
0294 };
0295
0296
0297
0298
0299 static bool debug_session_active;
0300
0301
0302
0303
0304
0305 static int debug_version;
0306 static void* debug_registers;
0307 static int debug_revision;
0308 static int debug_disable_ints;
0309 static int hw_breakpoints;
0310 static int hw_watchpoints;
0311
0312
0313
0314
0315 #define ARM_HW_BREAKPOINT_MAX (16)
0316 #define ARM_HW_WATCHPOINT_MAX (16)
0317
0318
0319
0320
0321 #define ARM_HW_BP_UNLINKED_INSTR_MATCH (0x00)
0322 #define ARM_HW_BP_UNLINKED_INSTR_MISMATCH (0x04)
0323
0324
0325
0326
0327 #define ARM_HW_BP_PRIV_PL0_SUP_SYS (0x00)
0328 #define ARM_HW_BP_PRIV_PL1_ONLY (0x01)
0329 #define ARM_HW_BP_PRIV_PL0_ONLY (0x02)
0330 #define ARM_HW_BP_PRIV_ALL_MODES (0x03)
0331
0332
0333
0334
0335
0336
0337
0338
0339 static uint32_t hw_breaks[ARM_HW_BREAKPOINT_MAX * 2];
0340
0341
0342
0343
0344 #define ARM_HWB_BCR(_bp) (hw_breaks[((_bp) * 2) + 1])
0345 #define ARM_HWB_VCR(_bp) (hw_breaks[(_bp) * 2])
0346 #define ARM_HWB_ENALBED(_bp) ((ARM_HWB_BCR(_bp) & 1) != 0)
0347 #define ARM_HWB_CLEAR(_bp) ARM_HWB_BCR(_bp) = 0; ARM_HWB_VCR(_bp) = 0
0348 #define ARM_HWB_CLEAR_ALL() memset(&hw_breaks[0], 0, sizeof(hw_breaks))
0349
0350
0351
0352
0353 #define ARM_HW_DSCR_MOE_HALT_REQUEST (0x0)
0354 #define ARM_HW_DSCR_MOE_BREAKPOINT_EVENT (0x1)
0355 #define ARM_HW_DSCR_MOE_ASYNC_WATCHPOINT (0x2)
0356 #define ARM_HW_DSCR_MOE_BREAKPOINT_INSTR (0x3)
0357 #define ARM_HW_DSCR_MOE_EXTERNAL (0x4)
0358 #define ARM_HW_DSCR_MOE_VECTOR_CATCH_EVENT (0x5)
0359 #define ARM_HW_DSCR_MOE_OS_UNLOCK_EVENT (0x8)
0360 #define ARM_HW_DSCR_MOE_SYNC_WATCHPOINT (0xa)
0361
0362
0363
0364
0365 #if ARM_CP15
0366 static void __attribute__((naked)) arm_debug_unlock_abort(void);
0367 #endif
0368
0369
0370
0371
0372 #if TARGET_DEBUG
0373 void rtems_debugger_printk_lock(rtems_interrupt_lock_context* lock_context);
0374 void rtems_debugger_printk_unlock(rtems_interrupt_lock_context* lock_context);
0375
0376 static void target_printk(const char* format, ...) RTEMS_PRINTFLIKE(1, 2);
0377 static void
0378 target_printk(const char* format, ...)
0379 {
0380 rtems_interrupt_lock_context lock_context;
0381 va_list ap;
0382 va_start(ap, format);
0383 rtems_debugger_printk_lock(&lock_context);
0384 vprintk(format, ap);
0385 rtems_debugger_printk_unlock(&lock_context);
0386 va_end(ap);
0387 }
0388 #else
0389 #define target_printk(_fmt, ...)
0390 #define mode_labels(_m) NULL
0391 #endif
0392
0393 static const char*
0394 arm_mode_label(int mode)
0395 {
0396 switch (mode) {
0397 case 0x10:
0398 return "USR";
0399 case 0x11:
0400 return "FIQ";
0401 case 0x12:
0402 return "IRQ";
0403 case 0x13:
0404 return "SVC";
0405 case 0x16:
0406 return "MON";
0407 case 0x17:
0408 return "ABT";
0409 case 0x1a:
0410 return "HYP";
0411 case 0x1b:
0412 return "UND";
0413 case 0x1f:
0414 return "SYS";
0415 }
0416 return "---";
0417 }
0418
0419 #if TARGET_DEBUG
0420 static const char*
0421 arm_moe_label(uint32_t moe)
0422 {
0423 switch (moe) {
0424 case ARM_HW_DSCR_MOE_HALT_REQUEST:
0425 return "HLT";
0426 case ARM_HW_DSCR_MOE_BREAKPOINT_EVENT:
0427 return "BPE";
0428 case ARM_HW_DSCR_MOE_ASYNC_WATCHPOINT:
0429 return "AWP";
0430 case ARM_HW_DSCR_MOE_BREAKPOINT_INSTR:
0431 return "BPI";
0432 case ARM_HW_DSCR_MOE_EXTERNAL:
0433 return "EXT";
0434 case ARM_HW_DSCR_MOE_VECTOR_CATCH_EVENT:
0435 return "VCE";
0436 case ARM_HW_DSCR_MOE_OS_UNLOCK_EVENT:
0437 return "OUL";
0438 case ARM_HW_DSCR_MOE_SYNC_WATCHPOINT:
0439 return "SWP";
0440 default:
0441 break;
0442 }
0443 return "RSV";
0444 }
0445 #endif
0446
0447
0448
0449
0450 #define ARM_CP_INSTR(_opc, _cp, _op1, _val, _CRn, _CRm, _op2) \
0451 #_opc " p" #_cp ", " #_op1 ", %[" #_val "], c" #_CRn ", c" #_CRm ", " #_op2 "\n"
0452
0453 #define ARM_CP_WRITE(_cp, _op1, _val, _CRn, _CRm, _op2) \
0454 do { \
0455 ARM_SWITCH_REG; \
0456 asm volatile( \
0457 ASM_ARM_MODE \
0458 ARM_CP_INSTR(mcr, _cp, _op1, val, _CRn, _CRm, _op2) \
0459 ARM_SYNC_INST \
0460 ASM_THUMB_MODE \
0461 : ARM_SWITCH_REG_ASM \
0462 : [val] "r" (_val)); \
0463 } while (0)
0464
0465 #define ARM_CP_READ(_cp, _op1, _val, _CRn, _CRm, _op2) \
0466 do { \
0467 ARM_SWITCH_REG; \
0468 asm volatile( \
0469 ASM_ARM_MODE \
0470 ARM_SYNC_INST \
0471 ARM_CP_INSTR(mrc, _cp, _op1, val, _CRn, _CRm, _op2) \
0472 ASM_THUMB_MODE \
0473 : ARM_SWITCH_REG_ASM_L \
0474 [val] "=&r" (_val)); \
0475 } while (0)
0476
0477
0478
0479
0480
0481
0482
0483
0484
0485
0486
0487
0488
0489
0490
0491 #define ARM_CP14_WRITE(_val, _CRn, _CRm, _op2) \
0492 ARM_CP_WRITE(14, 0, _val, _CRn, _CRm, _op2)
0493
0494 #define ARM_CP14_READ(_val, _CRn, _CRm, _op2) \
0495 ARM_CP_READ(14, 0, _val, _CRn, _CRm, _op2)
0496
0497
0498
0499
0500
0501
0502
0503 #define ARM_CP15_WRITE(_val, _op1, _CRn, _CRm, _op2) \
0504 ARM_CP_WRITE(15, _op1, _val, _CRn, _CRm, _op2)
0505
0506 #define ARM_CP15_READ(_val, _op1, _CRn, _CRm, _op2) \
0507 ARM_CP_READ(15, _op1, _val, _CRn, _CRm, _op2)
0508
0509
0510
0511
0512
0513 #define ARM_MMAP_ADDR(reg) \
0514 (((volatile uint32_t*) debug_registers) + (reg))
0515 #define ARM_MMAP_WRITE(reg, val) *ARM_MMAP_ADDR(reg) = (val)
0516 #define ARM_MMAP_READ(reg) *ARM_MMAP_ADDR(reg)
0517 #define ARM_MMAP_WRITE_SYNC(reg, val) \
0518 ARM_MMAP_WRITE(reg, val); \
0519 _ARM_Data_synchronization_barrier(); \
0520 _ARM_Instruction_synchronization_barrier()
0521
0522
0523
0524
0525 #define ARM_MMAP_DBGDSCR 34
0526 #define ARM_MMAP_DBGBCR 80
0527 #define ARM_MMAP_DBGBVR 64
0528
0529 static bool
0530 arm_debug_authentication(uint32_t dbgauthstatus)
0531 {
0532 bool granted = (dbgauthstatus & (1 << 0)) != 0;
0533 rtems_debugger_printf("rtems-db: arm debug: authentication: %s " \
0534 "(%s %s %s %s %s %s %s %s)\n",
0535 granted ? "granted" : "denied",
0536 (dbgauthstatus & (1 << 0)) == 0 ? "-" : "NSE",
0537 (dbgauthstatus & (1 << 1)) == 0 ? "-" : "NSI",
0538 (dbgauthstatus & (1 << 2)) == 0 ? "-" : "NSNE",
0539 (dbgauthstatus & (1 << 3)) == 0 ? "-" : "NSNI",
0540 (dbgauthstatus & (1 << 4)) == 0 ? "-" : "SE",
0541 (dbgauthstatus & (1 << 5)) == 0 ? "-" : "SI",
0542 (dbgauthstatus & (1 << 6)) == 0 ? "-" : "SNE",
0543 (dbgauthstatus & (1 << 7)) == 0 ? "-" : "SNI");
0544 return granted;
0545 }
0546
0547 static int
0548 arm_debug_cp14_enable(rtems_debugger_target* target)
0549 {
0550 uint32_t val;
0551 ARM_CP14_READ(val, 7, 14, 6);
0552 if (!arm_debug_authentication(val))
0553 return -1;
0554 ARM_CP14_READ(val, 0, 1, 0);
0555 if ((val & (1 << 15)) == 0) {
0556 switch (debug_version) {
0557 case 1:
0558 case 2:
0559 ARM_CP14_WRITE(val | (1 << 15), 0, 1, 0);
0560 break;
0561 case 3:
0562 case 5:
0563 default:
0564 ARM_CP14_WRITE(val | (1 << 15), 0, 2, 2);
0565 break;
0566 case 4:
0567 rtems_debugger_printf("rtems-db: arm debug: no cp14 access with version 4\n");
0568 return -1;
0569 }
0570 ARM_CP14_READ(val, 0, 1, 0);
0571 if ((val & (1 << 15)) == 0) {
0572 rtems_debugger_printf("rtems-db: arm debug: cannot enter monitor mode\n");
0573 errno = EIO;
0574 return -1;
0575 }
0576 }
0577 rtems_debugger_printf("rtems-db: arm debug: using cp14 register access\n");
0578 return 0;
0579 }
0580
0581
0582
0583
0584
0585 static jmp_buf unlock_abort_jmpbuf;
0586 static size_t arm_debug_retries;
0587
0588 static void
0589 arm_debug_dump_rom_table(uint32_t* rom, size_t depth)
0590 {
0591 uint32_t pidr[7];
0592 uint32_t cidr[4];
0593 uint32_t memtype;
0594 uint32_t pidr4_4KB_count;
0595 size_t r;
0596
0597 static const char *table_class[16] = {
0598 "reserved",
0599 "ROM table",
0600 "reserved", "reserved",
0601 "reserved",
0602 "reserved",
0603 "reserved",
0604 "reserved",
0605 "reserved",
0606 "CoreSight component",
0607 "reserved",
0608 "Peripheral Test Block",
0609 "reserved",
0610 "OptimoDE DESS",
0611 "Generic IP component",
0612 "PrimeCell or System component"
0613 };
0614
0615 #define ROM_READ(b_, o_, r_) b_[((o_) / sizeof(uint32_t)) + (r_)]
0616
0617 if (depth > 16) {
0618 rtems_debugger_printf("]] rom: too deep\n");
0619 return;
0620 }
0621
0622 for (r = 0; r < 4; ++r)
0623 pidr[r] = ROM_READ(rom, 0xfe0, r) & 0xff;
0624 for (r = 0; r < 3; ++r)
0625 pidr[r + 4] = ROM_READ(rom, 0xfd0, r) & 0xff;
0626 for (r = 0; r < 4; ++r)
0627 cidr[r] = ROM_READ(rom, 0xff0, r) & 0xff;
0628 memtype = ROM_READ(rom, 0xfcc, 0);
0629
0630 pidr4_4KB_count = pidr[4] & (((1 << (7 - 4)) - 1) >> 4);
0631
0632 rtems_debugger_printf("]] rom = %p\n", rom);
0633 rtems_debugger_printf(" PIDR: %08x %08x %08x %08x %08x %08x %08x\n",
0634 pidr[0], pidr[1], pidr[2], pidr[3],
0635 pidr[4], pidr[5], pidr[6]);
0636 rtems_debugger_printf(" CIDR: %08x %08x %08x %08x\n",
0637 cidr[0], cidr[1], cidr[2], cidr[3]);
0638 rtems_debugger_printf(" 4KB count: %u\n", pidr4_4KB_count);
0639
0640 if ((memtype & 0x01) != 0)
0641 rtems_debugger_printf(" MEMTYPE sys memory present on bus\n");
0642 else
0643 rtems_debugger_printf(" MEMTYPE sys memory not present: dedicated debug bus\n");
0644
0645
0646
0647
0648 for (r = 0; rom[r] != 0; ++r) {
0649 uint32_t romentry = rom[r];
0650 uint32_t c_pidr[7];
0651 uint32_t c_cidr[4];
0652 uint32_t* c_base;
0653 uint32_t table_type;
0654 size_t i;
0655
0656 c_base = (uint32_t*) ((intptr_t) rom + (romentry & 0xFFFFF000));
0657
0658
0659
0660
0661 for (i = 0; i < 4; ++i)
0662 c_pidr[i] = ROM_READ(c_base, 0xfe0, i) & 0xff;
0663 for (i = 0; i < 3; ++i)
0664 c_pidr[i + 4] = ROM_READ(c_base, 0xfd0, i) & 0xff;
0665 for (i = 0; i < 4; ++i)
0666 c_cidr[i] = ROM_READ(c_base, 0xff0, i) & 0xff;
0667
0668 table_type = ROM_READ(c_base, 0xfcc, 0);
0669
0670 rtems_debugger_printf(" > Base: %p, start: 0x%" PRIx32 "\n",
0671 c_base,
0672
0673 (uint32_t)((intptr_t) c_base - 0x1000 * (c_pidr[4] >> 4)));
0674 rtems_debugger_printf(" Class is 0x%x, %s\n",
0675 (c_cidr[1] >> 4) & 0xf, table_class[(c_cidr[1] >> 4) & 0xf]);
0676
0677 if (((c_cidr[1] >> 4) & 0x0f) == 1) {
0678 arm_debug_dump_rom_table(c_base, depth + 1);
0679 }
0680 else if (((c_cidr[1] >> 4) & 0x0f) == 9) {
0681 const char* major = "reserved";
0682 const char* subtype = "reserved";
0683 unsigned minor = (table_type >> 4) & 0x0f;
0684
0685 switch (table_type & 0x0f) {
0686 case 0:
0687 major = "Miscellaneous";
0688 switch (minor) {
0689 case 0:
0690 subtype = "other";
0691 break;
0692 case 4:
0693 subtype = "Validation component";
0694 break;
0695 }
0696 break;
0697 case 1:
0698 major = "Trace Sink";
0699 switch (minor) {
0700 case 0:
0701 subtype = "other";
0702 break;
0703 case 1:
0704 subtype = "Port";
0705 break;
0706 case 2:
0707 subtype = "Buffer";
0708 break;
0709 case 3:
0710 subtype = "Router";
0711 break;
0712 }
0713 break;
0714 case 2:
0715 major = "Trace Link";
0716 switch (minor) {
0717 case 0:
0718 subtype = "other";
0719 break;
0720 case 1:
0721 subtype = "Funnel, router";
0722 break;
0723 case 2:
0724 subtype = "Filter";
0725 break;
0726 case 3:
0727 subtype = "FIFO, buffer";
0728 break;
0729 }
0730 break;
0731 case 3:
0732 major = "Trace Source";
0733 switch (minor) {
0734 case 0:
0735 subtype = "other";
0736 break;
0737 case 1:
0738 subtype = "Processor";
0739 break;
0740 case 2:
0741 subtype = "DSP";
0742 break;
0743 case 3:
0744 subtype = "Engine/Coprocessor";
0745 break;
0746 case 4:
0747 subtype = "Bus";
0748 break;
0749 case 6:
0750 subtype = "Software";
0751 break;
0752 }
0753 break;
0754 case 4:
0755 major = "Debug Control";
0756 switch (minor) {
0757 case 0:
0758 subtype = "other";
0759 break;
0760 case 1:
0761 subtype = "Trigger Matrix";
0762 break;
0763 case 2:
0764 subtype = "Debug Auth";
0765 break;
0766 case 3:
0767 subtype = "Power Requestor";
0768 break;
0769 }
0770 break;
0771 case 5:
0772 major = "Debug Logic";
0773 switch (minor) {
0774 case 0:
0775 subtype = "other";
0776 break;
0777 case 1:
0778 subtype = "Processor";
0779 break;
0780 case 2:
0781 subtype = "DSP";
0782 break;
0783 case 3:
0784 subtype = "Engine/Coprocessor";
0785 break;
0786 case 4:
0787 subtype = "Bus";
0788 break;
0789 case 5:
0790 subtype = "Memory";
0791 }
0792 break;
0793 case 6:
0794 major = "Perfomance Monitor";
0795 switch (minor) {
0796 case 0:
0797 subtype = "other";
0798 break;
0799 case 1:
0800 subtype = "Processor";
0801 break;
0802 case 2:
0803 subtype = "DSP";
0804 break;
0805 case 3:
0806 subtype = "Engine/Coprocessor";
0807 break;
0808 case 4:
0809 subtype = "Bus";
0810 break;
0811 case 5:
0812 subtype = "Memory";
0813 break;
0814 }
0815 break;
0816 }
0817
0818 rtems_debugger_printf(" Type: 0x%02" PRIx32 ", %s, %s\n",
0819 table_type & 0xff, major, subtype);
0820 rtems_debugger_printf(" PID[4..0]: %02x %02x %02x %02x %02x\n",
0821 c_pidr[4], c_pidr[3], c_pidr[2], c_pidr[1], c_pidr[0]);
0822
0823 if (((c_cidr[1] >> 4) & 0x0f) == 1) {
0824 arm_debug_dump_rom_table(c_base, depth + 1);
0825 }
0826 }
0827 }
0828 }
0829
0830 static int
0831 arm_debug_rom_discover(uint32_t* rom, uint32_t comp, uint32_t** addr, int* index)
0832 {
0833 size_t r = 0;
0834 *addr = 0;
0835 while ((rom[r] & 1) != 0) {
0836 uint32_t* c_base = (uint32_t*) ((intptr_t) rom + (rom[r] & 0xfffff000));
0837 uint32_t c_cid1 = c_base[0xff4 / sizeof(uint32_t)];
0838 uint32_t type;
0839 if (((c_cid1 >> 4) & 0x0f) == 1) {
0840 if (arm_debug_rom_discover(c_base, comp, addr, index))
0841 return true;
0842 }
0843 type = c_base[0xfcc / sizeof(uint32_t)] & 0xff;
0844 if (comp == type) {
0845 if (*index > 0)
0846 --(*index);
0847 else {
0848 *addr = c_base;
0849 return true;
0850 }
0851 }
0852 ++r;
0853 }
0854 return false;
0855 }
0856
0857 static int
0858 arm_debug_mmap_enable(rtems_debugger_target* target, uint32_t dbgdidr)
0859 {
0860 uint32_t val;
0861 int rc = -1;
0862
0863 #if ARM_CP15
0864 void* abort_handler;
0865 #endif
0866
0867
0868
0869
0870 arm_debug_retries = 5;
0871
0872
0873
0874
0875
0876
0877 ARM_CP14_READ(val, 1, 0, 0);
0878 if ((val & 3) == 3) {
0879 uint32_t* rom = (uint32_t*) (val & 0xfffff000);
0880 uint32_t* comp_base = NULL;
0881 int core = (int) _SMP_Get_current_processor();
0882
0883 if (ARM_DUMP_ROM_TABLES)
0884 arm_debug_dump_rom_table(rom, 0);
0885
0886 debug_registers = NULL;
0887
0888 if (arm_debug_rom_discover(rom, 0x15, &comp_base, &core)) {
0889 debug_registers = comp_base;
0890 rtems_debugger_printf("rtems-db: ram debug: ROM Base: %p\n", comp_base);
0891 } else {
0892 ARM_CP14_READ(val, 2, 0, 0);
0893 if ((val & 3) == 3 ) {
0894 debug_registers = (void*) ((intptr_t) rom + (val & ~3));
0895 }
0896 }
0897 }
0898
0899 if (debug_registers == NULL) {
0900 debug_registers = rtems_debugger_arm_debug_registers();
0901 if (debug_registers == NULL) {
0902 rtems_debugger_printf("rtems-db: arm debug: no valid register map\n");
0903 return -1;
0904 }
0905 rtems_debugger_printf("rtems-db: arm debug: BSP Base: %p\n", debug_registers);
0906 }
0907
0908
0909
0910
0911 if (ARM_MMAP_READ(0) != dbgdidr) {
0912 debug_registers = NULL;
0913 rtems_debugger_printf("rtems-db: arm debug: debug reg map not verified: " \
0914 "0x%08x\n", ARM_MMAP_READ(0));
0915 return -1;
0916 }
0917
0918 if (!arm_debug_authentication(ARM_MMAP_READ(1006)))
0919 return -1;
0920
0921 #if ARM_CP15
0922 abort_handler =
0923 arm_cp15_set_exception_handler(ARM_EXCEPTION_DATA_ABORT,
0924 arm_debug_unlock_abort);
0925 #endif
0926
0927 while (arm_debug_retries-- > 0) {
0928 if (setjmp(unlock_abort_jmpbuf) == 0) {
0929
0930
0931
0932
0933
0934
0935 if (ARM_MMAP_READ(1005) == 3) {
0936 ARM_MMAP_WRITE_SYNC(1004, 0xC5ACCE55);
0937 }
0938
0939
0940
0941 val = ARM_MMAP_READ(ARM_MMAP_DBGDSCR);
0942 if ((val & (1 << 15)) == 0) {
0943 rtems_debugger_printf("rtems-db: arm debug: enable debug mode\n");
0944 val = ARM_MMAP_READ(ARM_MMAP_DBGDSCR);
0945 ARM_MMAP_WRITE_SYNC(ARM_MMAP_DBGDSCR,
0946 ARM_MMAP_READ(ARM_MMAP_DBGDSCR) | (1 << 15));
0947 arm_debug_retries = 0;
0948 }
0949 }
0950 }
0951
0952 #if ARM_CP15
0953 arm_cp15_set_exception_handler(ARM_EXCEPTION_DATA_ABORT, abort_handler);
0954 #endif
0955
0956 if (arm_debug_retries > 0) {
0957 rtems_debugger_printf("rtems-db: arm debug: using debug register access\n");
0958 rc = 0;
0959 }
0960 else {
0961 rtems_debugger_printf("rtems-db: arm debug: cannot enter debug mode\n");
0962 }
0963
0964 val = ARM_MMAP_READ(1006);
0965
0966 return rc;
0967 }
0968
0969 static int
0970 arm_debug_probe(rtems_debugger_target* target)
0971 {
0972 #define ID_VALUE(_i, _h, _l) ((_i >> _l) & ((1 << ((_h - _l) + 1)) -1))
0973 uint32_t val;
0974 const char* vl = "[Invalid version]";
0975 const char* const labels[] = {
0976 "ARMv6 [v6]",
0977 "ARMv6 [v6.1]",
0978 "ARMv7 [v7, all CP14 registers]",
0979 "ARMv7 [v7, baseline CP14 registers]",
0980 "ARMv7 [v7.1]"
0981 };
0982 int rc = -1;
0983
0984 #if ARM_CP15
0985 ARM_CP15_READ(val, 0, 0, 0, 0);
0986 rtems_debugger_printf("rtems-db: arm core: Architecture: %d Variant: %d " \
0987 "Implementor: %d Part Number: %d Revision: %d\n",
0988 (val >> 16) & ((1 << (19 - 16 + 1)) - 1),
0989 (val >> 20) & ((1 << (23 - 20 + 1)) - 1),
0990 (val >> 24) & ((1 << (31 - 24 + 1)) - 1),
0991 (val >> 4) & ((1 << (15 - 4 + 1)) - 1),
0992 (val >> 0) & ((1 << ( 3 - 0 + 1)) - 1));
0993 #endif
0994
0995 ARM_CP14_READ(val, 0, 0, 0);
0996
0997 debug_version = ID_VALUE(val, 19, 16);
0998 if (debug_version < 1 || debug_version > 5) {
0999 rtems_debugger_printf("rtems-db: arm debug: (v%d.%d) not supported\n",
1000 debug_version, debug_revision);
1001 errno = EIO;
1002 return -1;
1003 }
1004
1005 vl = labels[debug_version - 1];
1006 debug_revision = ID_VALUE(val, 3, 0);
1007 hw_breakpoints = ID_VALUE(val, 27, 24);
1008 hw_watchpoints = ID_VALUE(val, 31, 28);
1009
1010 rtems_debugger_printf("rtems-db: arm debug: (v%d.%d) %s " \
1011 "breakpoints:%d watchpoints:%d\n",
1012 debug_version, debug_revision, vl,
1013 hw_breakpoints, hw_watchpoints);
1014
1015 if (!rtems_debugger_arm_debug_configure())
1016 return -1;
1017
1018 switch (debug_version) {
1019 case 1:
1020 case 2:
1021 case 3:
1022 case 5:
1023 default:
1024 rc = arm_debug_mmap_enable(target, val);
1025 if (rc != 0)
1026 rc = arm_debug_cp14_enable(target);
1027 break;
1028 case 4:
1029 rc = arm_debug_mmap_enable(target, val);
1030 break;
1031 }
1032
1033 return rc;
1034 }
1035
1036 static inline void
1037 arm_debug_break_setup(int bp,
1038 uint32_t address,
1039 uint32_t type,
1040 uint32_t byte_address_select,
1041 uint32_t privilege)
1042 {
1043 ARM_HWB_BCR(bp) = (((type & 0xf) << 20) |
1044 ((byte_address_select & 0xf) << 5) |
1045 ((privilege & 0x3) << 1) | 1);
1046 ARM_HWB_VCR(bp) = (intptr_t) (address & (~3));
1047 }
1048
1049 static void
1050 arm_debug_break_c14_write_control(int bp, uint32_t control)
1051 {
1052 switch (bp) {
1053 case 0:
1054 ARM_CP14_WRITE(control, 0, 0, 5);
1055 break;
1056 case 1:
1057 ARM_CP14_WRITE(control, 0, 1, 5);
1058 break;
1059 case 2:
1060 ARM_CP14_WRITE(control, 0, 2, 5);
1061 break;
1062 case 3:
1063 ARM_CP14_WRITE(control, 0, 3, 5);
1064 break;
1065 case 4:
1066 ARM_CP14_WRITE(control, 0, 4, 5);
1067 break;
1068 case 5:
1069 ARM_CP14_WRITE(control, 0, 5, 5);
1070 break;
1071 case 6:
1072 ARM_CP14_WRITE(control, 0, 6, 5);
1073 break;
1074 case 7:
1075 ARM_CP14_WRITE(control, 0, 7, 5);
1076 break;
1077 case 8:
1078 ARM_CP14_WRITE(control, 0, 8, 5);
1079 break;
1080 case 9:
1081 ARM_CP14_WRITE(control, 0, 9, 5);
1082 break;
1083 case 10:
1084 ARM_CP14_WRITE(control, 0, 10, 5);
1085 break;
1086 case 11:
1087 ARM_CP14_WRITE(control, 0, 11, 5);
1088 break;
1089 case 12:
1090 ARM_CP14_WRITE(control, 0, 12, 5);
1091 break;
1092 case 13:
1093 ARM_CP14_WRITE(control, 0, 13, 5);
1094 break;
1095 case 14:
1096 ARM_CP14_WRITE(control, 0, 14, 5);
1097 break;
1098 case 15:
1099 ARM_CP14_WRITE(control, 0, 15, 5);
1100 break;
1101 }
1102 }
1103
1104 static void
1105 arm_debug_break_c14_write_value(int bp, uint32_t value)
1106 {
1107 switch (bp) {
1108 case 0:
1109 ARM_CP14_WRITE(value, 0, 0, 4);
1110 break;
1111 case 1:
1112 ARM_CP14_WRITE(value, 0, 1, 4);
1113 break;
1114 case 2:
1115 ARM_CP14_WRITE(value, 0, 2, 4);
1116 break;
1117 case 3:
1118 ARM_CP14_WRITE(value, 0, 3, 4);
1119 break;
1120 case 4:
1121 ARM_CP14_WRITE(value, 0, 4, 4);
1122 break;
1123 case 5:
1124 ARM_CP14_WRITE(value, 0, 5, 4);
1125 break;
1126 case 6:
1127 ARM_CP14_WRITE(value, 0, 6, 4);
1128 break;
1129 case 7:
1130 ARM_CP14_WRITE(value, 0, 7, 4);
1131 break;
1132 case 8:
1133 ARM_CP14_WRITE(value, 0, 8, 4);
1134 break;
1135 case 9:
1136 ARM_CP14_WRITE(value, 0, 9, 4);
1137 break;
1138 case 10:
1139 ARM_CP14_WRITE(value, 0, 10, 4);
1140 break;
1141 case 11:
1142 ARM_CP14_WRITE(value, 0, 11, 4);
1143 break;
1144 case 12:
1145 ARM_CP14_WRITE(value, 0, 12, 4);
1146 break;
1147 case 13:
1148 ARM_CP14_WRITE(value, 0, 13, 4);
1149 break;
1150 case 14:
1151 ARM_CP14_WRITE(value, 0, 14, 4);
1152 break;
1153 case 15:
1154 ARM_CP14_WRITE(value, 0, 15, 4);
1155 break;
1156 }
1157 }
1158
1159 static uint32_t
1160 arm_debug_dbgdscr_read(void)
1161 {
1162 uint32_t val;
1163 if (debug_registers != NULL) {
1164 val = ARM_MMAP_READ(ARM_MMAP_DBGDSCR);
1165 }
1166 else {
1167 ARM_CP14_READ(val, 0, 1, 0);
1168 }
1169 return val;
1170 }
1171
1172 static void
1173 arm_debug_dbgdscr_write(uint32_t val)
1174 {
1175 if (debug_registers != NULL) {
1176 ARM_MMAP_WRITE_SYNC(ARM_MMAP_DBGDSCR, val);
1177 }
1178 else {
1179 ARM_CP14_WRITE(val, 0, 1, 0);
1180 }
1181 }
1182
1183 static uint32_t
1184 arm_debug_method_of_entry(void)
1185 {
1186 return (arm_debug_dbgdscr_read() >> 2) & 0xf;
1187 }
1188
1189 static void
1190 arm_debug_disable_interrupts(void)
1191 {
1192 debug_disable_ints = 1;
1193 }
1194
1195 static void
1196 arm_debug_enable_interrupts(void)
1197 {
1198 arm_debug_dbgdscr_write(arm_debug_dbgdscr_read() & ~(1 << 11));
1199 }
1200
1201 static void
1202 arm_debug_break_clear(int bp)
1203 {
1204 rtems_interrupt_lock_context lock_context;
1205 rtems_interrupt_lock_acquire(&target_lock, &lock_context);
1206 ARM_HWB_CLEAR(bp);
1207 rtems_interrupt_lock_release(&target_lock, &lock_context);
1208 }
1209
1210 static void
1211 arm_debug_break_clear_all(void)
1212 {
1213 rtems_interrupt_lock_context lock_context;
1214 rtems_interrupt_lock_acquire(&target_lock, &lock_context);
1215 ARM_HWB_CLEAR_ALL();
1216 rtems_interrupt_lock_release(&target_lock, &lock_context);
1217 }
1218
1219 static inline void
1220 arm_debug_set_context_id(const uint32_t id)
1221 {
1222 #if ARM_CP15
1223 ARM_CP15_WRITE(id, 0, 13, 0, 1);
1224 #endif
1225 }
1226
1227 static void
1228 arm_debug_break_unload(void)
1229 {
1230 rtems_interrupt_lock_context lock_context;
1231 int i;
1232 rtems_interrupt_lock_acquire(&target_lock, &lock_context);
1233 if (debug_registers != NULL) {
1234 for (i = 0; i < hw_breakpoints; ++i) {
1235 ARM_MMAP_WRITE(ARM_MMAP_DBGBCR + i, 0);
1236 ARM_MMAP_WRITE(ARM_MMAP_DBGBVR + i, 0);
1237 }
1238 } else {
1239 for (i = 0; i < hw_breakpoints; ++i) {
1240 arm_debug_break_c14_write_control(i, 0);
1241 arm_debug_break_c14_write_value(i, 0);
1242 }
1243 }
1244 rtems_interrupt_lock_release(&target_lock, &lock_context);
1245 }
1246
1247 static void
1248 arm_debug_break_exec_enable(int bp, uintptr_t addr, bool thumb, bool step) {
1249 uint32_t bas;
1250
1251
1252
1253
1254
1255
1256 if (thumb) {
1257
1258
1259
1260 if ((addr & (1 << 1)) == 0) {
1261
1262
1263
1264 bas = 0x3;
1265 }
1266 else {
1267
1268
1269
1270 bas = 0xc;
1271 }
1272 }
1273 else {
1274
1275
1276
1277
1278
1279 bas = 0xf;
1280 }
1281
1282 target_printk("[} break: addr:%08x bas:%x thumb:%s\n",
1283 addr, bas, thumb ? "yes" : "no");
1284
1285 arm_debug_break_setup(
1286 bp,
1287 addr,
1288 step ? ARM_HW_BP_UNLINKED_INSTR_MISMATCH : ARM_HW_BP_UNLINKED_INSTR_MATCH,
1289 bas,
1290 ARM_HW_BP_PRIV_PL0_SUP_SYS);
1291 }
1292
1293 static void
1294 arm_debug_break_dump(void)
1295 {
1296 #if TARGET_DEBUG
1297 int i;
1298 for (i = 0; i < hw_breakpoints; ++i) {
1299 if (ARM_HWB_ENALBED(i)) {
1300 target_printk("[} bp: %d: control: %08x addr: %08x\n",
1301 i, ARM_HWB_BCR(i), ARM_HWB_VCR(i));
1302 }
1303 }
1304 #endif
1305 }
1306
1307 #if NOT_USED_BUT_KEEPING
1308 static size_t
1309 arm_debug_break_length(void* pc)
1310 {
1311 arm_debug_hwbreak* bp = &hw_breaks[0];
1312 int i;
1313
1314 for (i = 0; i < hw_breakpoints; ++i, ++bp) {
1315 if (bp->enabled && bp->address == pc) {
1316 return bp->length;
1317 }
1318 }
1319 return sizeof(DB_UINT);
1320 }
1321 #endif
1322
1323 int
1324 rtems_debugger_target_configure(rtems_debugger_target* target)
1325 {
1326 target->capabilities = (RTEMS_DEBUGGER_TARGET_CAP_SWBREAK);
1327 target->reg_num = RTEMS_DEBUGGER_NUMREGS;
1328 target->reg_offset = arm_reg_offsets;
1329 target->breakpoint = &breakpoint[0];
1330 target->breakpoint_size = sizeof(breakpoint);
1331 return arm_debug_probe(target);
1332 }
1333
1334 static void
1335 target_print_frame(CPU_Exception_frame* frame)
1336 {
1337 EXC_FRAME_PRINT(target_printk, "[} ", frame);
1338 }
1339
1340 static const size_t
1341 target_exc_offset(CPU_Exception_frame* frame)
1342 {
1343 size_t thumb = (FRAME_SR(frame) & (1 << 5)) == 0 ? 0 : 1;
1344 return exc_offsets[thumb][frame->vector];
1345 }
1346
1347 static void
1348 target_exception(CPU_Exception_frame* frame)
1349 {
1350 #if TARGET_DEBUG
1351 #if ARM_CP15
1352 const uint32_t ifsr = arm_cp15_get_instruction_fault_status();
1353 const uint32_t dfsr = arm_cp15_get_data_fault_status();
1354 const void* far = arm_cp15_get_fault_address();
1355 #else
1356 const uint32_t ifsr = 0;
1357 #endif
1358 const uint32_t mvector = frame->vector;
1359 const uint32_t dbgdscr = arm_debug_dbgdscr_read();
1360 #endif
1361
1362 const uint32_t moe = arm_debug_method_of_entry();
1363 const size_t exc_offset = target_exc_offset(frame);
1364
1365 switch (moe){
1366 case ARM_HW_DSCR_MOE_BREAKPOINT_EVENT:
1367 case ARM_HW_DSCR_MOE_BREAKPOINT_INSTR:
1368 case ARM_HW_DSCR_MOE_ASYNC_WATCHPOINT:
1369 case ARM_HW_DSCR_MOE_SYNC_WATCHPOINT:
1370 frame->vector = 2;
1371 break;
1372 case ARM_HW_DSCR_MOE_HALT_REQUEST:
1373 case ARM_HW_DSCR_MOE_EXTERNAL:
1374 case ARM_HW_DSCR_MOE_VECTOR_CATCH_EVENT:
1375 case ARM_HW_DSCR_MOE_OS_UNLOCK_EVENT:
1376 default:
1377 break;
1378 }
1379
1380 target_printk("[} > frame = %08" PRIx32 \
1381 " sig=%d vector=%u (%u) dbgdscr=%08" PRIx32 " moe=%s" \
1382 " far=%p ifsr=%08" PRIx32 " dfsr=%08" PRIx32
1383 " exc-ret-pc=%08x\n", (uint32_t) frame,
1384 rtems_debugger_target_exception_to_signal(frame),
1385 frame->vector, mvector, dbgdscr, arm_moe_label(moe),
1386 far, ifsr, dfsr, (intptr_t) frame->register_pc);
1387
1388 arm_debug_break_dump();
1389
1390 frame->register_pc = (void*) ((intptr_t) frame->register_pc - exc_offset);
1391
1392 target_print_frame(frame);
1393
1394 arm_debug_break_clear(0);
1395 arm_debug_enable_interrupts();
1396
1397 if (!debug_session_active)
1398 _ARM_Exception_default(frame);
1399
1400 switch (rtems_debugger_target_exception(frame)) {
1401 case rtems_debugger_target_exc_consumed:
1402 default:
1403 break;
1404 case rtems_debugger_target_exc_step:
1405 break;
1406 case rtems_debugger_target_exc_cascade:
1407 target_printk("rtems-db: unhandled exception: cascading\n");
1408 _ARM_Exception_default(frame);
1409 break;
1410 }
1411
1412 target_printk("[} < resuming frame = %08" PRIx32 \
1413 " PC = %08" PRIxPTR " CPSR = %08" PRIx32 "\n",
1414 (uint32_t) frame, (intptr_t) frame->register_pc, FRAME_SR(frame));
1415 target_print_frame(frame);
1416 }
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431 #define EXCEPTION_FRAME_SIZE (sizeof(CPU_Exception_frame) + sizeof(uint32_t))
1432
1433
1434
1435
1436 #define EXCEPTION_FRAME_FPU_SIZE ARM_VFP_CONTEXT_SIZE
1437 #define EXCEPTION_FRAME_FPU_OFFSET ARM_EXCEPTION_FRAME_VFP_CONTEXT_OFFSET
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455 #define EXCEPTION_ENTRY_EXC() \
1456 __asm__ volatile( \
1457 ASM_ARM_MODE \
1458 "sub sp, %[frame_size]\n" \
1459 "stm sp, {r0-r12}\n" \
1460 : \
1461 : [frame_size] "i" (EXCEPTION_FRAME_SIZE) \
1462 : "cc", "memory")
1463
1464
1465
1466
1467
1468
1469
1470
1471 #if ARM_CP15
1472 #define ARM_HW_BP_UNLOAD(_bp) \
1473 "cmp r0, #" #_bp "\n" \
1474 "ble 3f\n" \
1475 "mcr p14, 0, r1, c0, c" #_bp ", 5\n" \
1476 "mcr p14, 0, r1, c0, c" #_bp ", 4\n"
1477 #define ARM_DGB_ENABLE_INTS \
1478 "mrc p14, 0, r1, c0, c1, 0\n" \
1479 "bic r1, r1, #(1 << 11)\n" \
1480 "mcr p14, 0, r1, c0, c1, 0\n"
1481 #else
1482 #define ARM_HW_BP_UNLOAD(_bp)
1483 #define ARM_DGB_ENABLE_INTS
1484 #endif
1485
1486 #define EXCEPTION_ENTRY_DEBUGGER() \
1487 __asm__ volatile( \
1488 \
1489 "movw r0, #:lower16:hw_breakpoints\n" \
1490 "movt r0, #:upper16:hw_breakpoints\n" \
1491 "ldr r0, [r0]\n" \
1492 "mov r1, #0\n" \
1493 \
1494 "movw r2, #:lower16:debug_registers\n" \
1495 "movt r2, #:upper16:debug_registers\n" \
1496 "ldr r2, [r2]\n" \
1497 "cmp r2, #0\n" \
1498 "beq 2f\n" \
1499 \
1500 "add r3, r2, %[dbgbvr] - 4\n" \
1501 "add r2, r2, %[dbgbcr] - 4\n" \
1502 "1:\n" \
1503 "str r1, [r3, #4]!\n" \
1504 "str r1, [r2, #4]!\n" \
1505 "sub r0, r0, #1\n" \
1506 "cmp r0, #0\n" \
1507 "bne 1b\n" \
1508 "ldr r1, [r2, %[dbgdscr]]\n" \
1509 "bic r1, r1, #(1 << 11)\n" \
1510 "str r1, [r2, %[dbgdscr]]\n" \
1511 "b 4f\n" \
1512 \
1513 "2:\n" \
1514 ARM_HW_BP_UNLOAD(0) \
1515 ARM_HW_BP_UNLOAD(1) \
1516 ARM_HW_BP_UNLOAD(2) \
1517 ARM_HW_BP_UNLOAD(3) \
1518 ARM_HW_BP_UNLOAD(4) \
1519 ARM_HW_BP_UNLOAD(5) \
1520 ARM_HW_BP_UNLOAD(6) \
1521 ARM_HW_BP_UNLOAD(7) \
1522 ARM_HW_BP_UNLOAD(8) \
1523 ARM_HW_BP_UNLOAD(9) \
1524 ARM_HW_BP_UNLOAD(10) \
1525 ARM_HW_BP_UNLOAD(11) \
1526 ARM_HW_BP_UNLOAD(12) \
1527 ARM_HW_BP_UNLOAD(12) \
1528 ARM_HW_BP_UNLOAD(13) \
1529 ARM_HW_BP_UNLOAD(14) \
1530 ARM_HW_BP_UNLOAD(15) \
1531 "3:\n" \
1532 ARM_DGB_ENABLE_INTS \
1533 "4:\n" \
1534 ARM_SYNC_INST \
1535 : \
1536 : [dbgdscr] "i" (ARM_MMAP_DBGDSCR * sizeof(uint32_t)), \
1537 [dbgbcr] "i" (ARM_MMAP_DBGBCR * sizeof(uint32_t)), \
1538 [dbgbvr] "i" (ARM_MMAP_DBGBVR * sizeof(uint32_t)) \
1539 : "cc", "r0", "r1", "r2", "r3", "memory")
1540
1541
1542
1543
1544 #ifdef ARM_MULTILIB_VFP
1545 #ifdef ARM_MULTILIB_VFP_D32
1546 #define FPU_ENTRY_VFP_D32 \
1547 "vstmia r5!, {d16-d31}\n"
1548 #else
1549 #define FPU_ENTRY_VFP_D32 \
1550 "mov r3, #0\n" \
1551 "mov r4, #0\n" \
1552 "adds r6, r5, #128\n" \
1553 "1:\n" \
1554 "stmia r5!, {r3-r4}\n" \
1555 "cmp r5, r6\n" \
1556 "bne 1b\n"
1557 #endif
1558 #define EXCEPTION_ENTRY_FPU(frame_fpu_size) \
1559 "sub sp, %[frame_fpu_size]\n" \
1560 "add r5, sp, #4\n" \
1561 "bic r5, r5, #7\n" \
1562 "str r5, [r2]\n" \
1563 "vmrs r3, FPEXC\n" \
1564 "vmrs r4, FPSCR\n" \
1565 "stmia r5!, {r3-r4}\n" \
1566 "vstmia r5!, {d0-d15}\n" \
1567 FPU_ENTRY_VFP_D32
1568 #else
1569 #define EXCEPTION_ENTRY_FPU(frame_fpu_size)
1570 #endif
1571
1572 #define ARM_CLEAR_THUMB_MODE "bic r1, r1, %[psr_t]\n"
1573
1574 #define EXCEPTION_ENTRY_THREAD(_frame) \
1575 __asm__ volatile( \
1576 "add r0, sp, %[r0_r12_size]\n" \
1577 "mrs r1, spsr\n" \
1578 "mov r6, r1\n" \
1579 ARM_CLEAR_THUMB_MODE \
1580 "orr r1, r1, %[psr_i]\n" \
1581 "mrs r2, cpsr\n" \
1582 "str r2, [sp, %[frame_cpsr]]\n" \
1583 "msr cpsr, r1\n" \
1584 "mov r3, sp\n" \
1585 "mov r4, lr\n" \
1586 "msr cpsr, r2\n" \
1587 "mov r5, lr\n" \
1588 "stm r0, {r3-r6}\n" \
1589 "sub r4, r3, %[frame_size]\n" \
1590 "mov r6, r4\n" \
1591 "sub r4, #1\n" \
1592 "add r3, #1\n" \
1593 "sub r5, sp, #1\n" \
1594 "1:\n" \
1595 "ldrb r0, [r5, #1]!\n" \
1596 "strb r0, [r4, #1]!\n" \
1597 "cmp r3, r4\n" \
1598 "bne 1b\n" \
1599 "add sp, %[frame_size]\n" \
1600 "mrs r1, spsr\n" \
1601 "orr r2, r1, %[psr_i]\n" \
1602 "msr cpsr, r2\n" \
1603 "sub sp, %[frame_size]\n" \
1604 "mov %[o_frame], sp\n" \
1605 "add r2, sp, %[o_frame_fpu]\n" \
1606 "mov r3, #0\n" \
1607 "str r3, [r2]\n" \
1608 EXCEPTION_ENTRY_FPU(frame_fpu_size) \
1609 "bic r1, r1, %[psr_i]\n" \
1610 "msr cpsr, r1\n" \
1611 : \
1612 [o_frame] "=r" (_frame) \
1613 : [psr_t] "i" (ARM_PSR_T), \
1614 [psr_i] "i" (ARM_PSR_I), \
1615 [r0_r12_size] "i" (13 * sizeof(uint32_t)), \
1616 [frame_cpsr] "i" (EXCEPTION_FRAME_SIZE - sizeof(uint32_t)), \
1617 [frame_size] "i" (EXCEPTION_FRAME_SIZE), \
1618 [o_frame_fpu] "i" (EXCEPTION_FRAME_FPU_OFFSET), \
1619 [frame_fpu_size] "i" (EXCEPTION_FRAME_FPU_SIZE + 4) \
1620 : "cc", "r0", "r1", "r2", "r3", "r4", "r5", "r6", "memory")
1621
1622
1623
1624
1625 #ifdef ARM_MULTILIB_VFP
1626 #ifdef ARM_MULTILIB_VFP_D32
1627 #define FPU_EXIT_VFP_D32 \
1628 "vldmia r0, {d16-d31}\n"
1629 #else
1630 #define FPU_EXIT_VFP_D32
1631 #endif
1632 #define EXCEPTION_EXIT_FPU(frame_fpu_size) \
1633 "ldmia r0!, {r1-r2}\n" \
1634 "vldmia r0!, {d0-d15}\n" \
1635 FPU_EXIT_VFP_D32 \
1636 "vmsr FPEXC, r1\n" \
1637 "vmsr FPSCR, r2\n" \
1638 "add sp, %[frame_fpu_size]\n"
1639 #else
1640 #define EXCEPTION_EXIT_FPU(frame_fpu_size)
1641 #endif
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654 #define EXCEPTION_EXIT_THREAD(_frame) \
1655 __asm__ volatile( \
1656 "mov r0, %[i_frame]\n" \
1657 "ldr r0, [r0, %[frame_fpu]]\n" \
1658 EXCEPTION_EXIT_FPU(frame_fpu_size) \
1659 "ldr r2, [sp, %[frame_cpsr]]\n" \
1660 "mov r0, sp\n" \
1661 "msr cpsr, r2\n" \
1662 "add r3, sp, #1\n" \
1663 "sub sp, %[frame_size]\n" \
1664 "sub r4, sp, #1\n" \
1665 "sub r5, r0, #1\n" \
1666 "1:\n" \
1667 "ldrb r1, [r5, #1]!\n" \
1668 "strb r1, [r4, #1]!\n" \
1669 "cmp r3, r4\n" \
1670 "bne 1b\n" \
1671 "mov r0, %[i_frame]\n" \
1672 "add r1, r0, %[r0_r12_size]\n" \
1673 "ldm r1, {r3-r6}\n" \
1674 "orr r1, r6, %[psr_i]\n" \
1675 "msr cpsr, r1\n" \
1676 "mov sp, r3\n" \
1677 "mov lr, r4\n" \
1678 "msr cpsr, r2\n" \
1679 "msr spsr, r6\n" \
1680 "mov lr, r5\n" \
1681 : \
1682 : [psr_i] "i" (ARM_PSR_I), \
1683 [r0_r12_size] "i" (13 * sizeof(uint32_t)), \
1684 [frame_cpsr] "i" (EXCEPTION_FRAME_SIZE - sizeof(uint32_t)), \
1685 [frame_size] "i" (EXCEPTION_FRAME_SIZE), \
1686 [frame_fpu] "i" (EXCEPTION_FRAME_FPU_OFFSET), \
1687 [frame_fpu_size] "i" (EXCEPTION_FRAME_FPU_SIZE + 4), \
1688 [i_frame] "r" (_frame) \
1689 : "cc", "r0", "r1", "r2", "r3", "r4", "r5", "r6", "memory")
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699 #if ARM_CP15
1700 #define ARM_HW_BP_LOAD(_bp) \
1701 "cmp r0, #" #_bp "\n" \
1702 "ble 5f\n" \
1703 "ldm r1!, {r2-r3}\n" \
1704 "mcr p14, 0, r2, c0, c" #_bp ", 4\n" \
1705 "mcr p14, 0, r3, c0, c" #_bp ", 5\n"
1706 #define ARM_DGB_DISABLE_INTS \
1707 "mrc p14, 0, r4, c0, c1, 0\n" \
1708 "orr r4, r4, #(1 << 11)\n" \
1709 "mcr p14, 0, r4, c0, c1, 0\n"
1710 #else
1711 #define ARM_HW_BP_LOAD(_bp)
1712 #define ARM_DGB_DISABLE_INTS
1713 #endif
1714
1715 #define EXCEPTION_EXIT_DEBUGGER() \
1716 __asm__ volatile( \
1717 \
1718 "movw r0, #:lower16:hw_breakpoints\n" \
1719 "movt r0, #:upper16:hw_breakpoints\n" \
1720 "ldr r0, [r0]\n" \
1721 "movw r1, #:lower16:hw_breaks\n" \
1722 "movt r1, #:upper16:hw_breaks\n" \
1723 "movw r4, #:lower16:debug_disable_ints\n" \
1724 "movt r4, #:upper16:debug_disable_ints\n" \
1725 "ldr r5, [r4]\n" \
1726 "mov r3, #0\n" \
1727 "str r3, [r4]\n" \
1728 \
1729 "movw r2, #:lower16:debug_registers\n" \
1730 "movt r2, #:upper16:debug_registers\n" \
1731 "ldr r2, [r2]\n" \
1732 "cmp r2, #0\n" \
1733 "beq 3f\n" \
1734 \
1735 "cmp r5, #0\n" \
1736 "beq 1f\n" \
1737 "ldr r4, [r2, %[dbgdscr]]\n" \
1738 "orr r4, r4, #(1 << 11)\n" \
1739 "str r4, [r2, %[dbgdscr]]\n" \
1740 "1:\n" \
1741 "add r3, r2, %[dbgbvr] - 4\n" \
1742 "add r2, r2, %[dbgbcr] - 4\n" \
1743 "2:\n" \
1744 "ldm r1!, {r4-r5}\n" \
1745 "str r4, [r3, #4]!\n" \
1746 "str r5, [r2, #4]!\n" \
1747 "sub r0, r0, #1\n" \
1748 "cmp r0, #1\n" \
1749 "bne 2b\n" \
1750 "b 5f\n" \
1751 \
1752 "3:\n" \
1753 "cmp r5, #0\n" \
1754 "beq 4f\n" \
1755 ARM_DGB_DISABLE_INTS \
1756 "4:\n" \
1757 ARM_HW_BP_LOAD(0) \
1758 ARM_HW_BP_LOAD(1) \
1759 ARM_HW_BP_LOAD(2) \
1760 ARM_HW_BP_LOAD(3) \
1761 ARM_HW_BP_LOAD(4) \
1762 ARM_HW_BP_LOAD(5) \
1763 ARM_HW_BP_LOAD(6) \
1764 ARM_HW_BP_LOAD(7) \
1765 ARM_HW_BP_LOAD(8) \
1766 ARM_HW_BP_LOAD(9) \
1767 ARM_HW_BP_LOAD(10) \
1768 ARM_HW_BP_LOAD(11) \
1769 ARM_HW_BP_LOAD(12) \
1770 ARM_HW_BP_LOAD(13) \
1771 ARM_HW_BP_LOAD(14) \
1772 ARM_HW_BP_LOAD(15) \
1773 "5:\n" \
1774 ARM_SYNC_INST \
1775 : \
1776 : [disints] "X" (debug_disable_ints), \
1777 [dbgdscr] "i" (ARM_MMAP_DBGDSCR * sizeof(uint32_t)), \
1778 [dbgbcr] "i" (ARM_MMAP_DBGBCR * sizeof(uint32_t)), \
1779 [dbgbvr] "i" (ARM_MMAP_DBGBVR * sizeof(uint32_t)) \
1780 : "cc", "r0", "r1", "r2", "r3", "r4", "r5", "memory")
1781
1782 #define EXCEPTION_EXIT_EXC() \
1783 __asm__ volatile( \
1784 "ldm sp, {r0-r12}\n" \
1785 "add sp, %[frame_size]\n" \
1786 "subs pc, lr, #0\n" \
1787 ARM_SYNC_INST \
1788 : \
1789 : [frame_size] "i" (EXCEPTION_FRAME_SIZE) \
1790 : "cc", "memory")
1791
1792 #define ARM_PUSH_LR() \
1793 __asm__ volatile( \
1794 "push {lr}\n" \
1795 : : : )
1796
1797 #define ARM_POP_LR() \
1798 __asm__ volatile( \
1799 "pop {lr}\n" \
1800 : : : )
1801
1802
1803
1804
1805 #define EXCEPTION_ENTRY(_frame) \
1806 EXCEPTION_ENTRY_EXC(); \
1807 EXCEPTION_ENTRY_DEBUGGER(); \
1808 EXCEPTION_ENTRY_THREAD(_frame); \
1809 ARM_THUMB_MODE() \
1810 ARM_PUSH_LR()
1811
1812 #define EXCEPTION_EXIT(_frame) \
1813 ARM_POP_LR(); \
1814 ARM_ARM_MODE(); \
1815 EXCEPTION_EXIT_THREAD(_frame); \
1816 EXCEPTION_EXIT_DEBUGGER(); \
1817 EXCEPTION_EXIT_EXC()
1818
1819
1820
1821
1822 #if ARM_CP15
1823 static void __attribute__((naked))
1824 arm_debug_unlock_abort(void)
1825 {
1826 CPU_Exception_frame* frame;
1827 ARM_SWITCH_REGISTERS;
1828 EXCEPTION_ENTRY_EXC();
1829 EXCEPTION_ENTRY_THREAD(frame);
1830 ARM_SWITCH_BACK;
1831 longjmp(unlock_abort_jmpbuf, -1);
1832 }
1833 #endif
1834
1835 static void __attribute__((naked))
1836 target_exception_undefined_instruction(void)
1837 {
1838 CPU_Exception_frame* frame;
1839 ARM_SWITCH_REG;
1840 EXCEPTION_ENTRY(frame);
1841 frame->vector = 1;
1842 target_exception(frame);
1843 EXCEPTION_EXIT(frame);
1844 }
1845
1846 static void __attribute__((naked))
1847 target_exception_supervisor_call(void)
1848 {
1849 CPU_Exception_frame* frame;
1850 ARM_SWITCH_REG;
1851
1852
1853
1854
1855
1856
1857 EXCEPTION_ENTRY(frame);
1858 frame->vector = 2;
1859 target_exception(frame);
1860 EXCEPTION_EXIT(frame);
1861 }
1862
1863 static void __attribute__((naked))
1864 target_exception_prefetch_abort(void)
1865 {
1866 CPU_Exception_frame* frame;
1867 ARM_SWITCH_REG;
1868 EXCEPTION_ENTRY(frame);
1869 frame->vector = 3;
1870 target_exception(frame);
1871 EXCEPTION_EXIT(frame);
1872 }
1873
1874 static void __attribute__((naked))
1875 target_exception_data_abort(void)
1876 {
1877 CPU_Exception_frame* frame;
1878 ARM_SWITCH_REG;
1879 EXCEPTION_ENTRY(frame);
1880 frame->vector = 4;
1881 target_exception(frame);
1882 EXCEPTION_EXIT(frame);
1883 }
1884
1885 #if ARM_CP15
1886 #if __ARM_ARCH_PROFILE == 'A'
1887
1888
1889
1890 static uint32_t text_section_flags;
1891
1892
1893 extern char bsp_section_text_begin[];
1894 extern char bsp_section_text_end[];
1895
1896 static void
1897 rtems_debugger_target_set_mmu(void)
1898 {
1899 void* text_begin;
1900 void* text_end;
1901 text_begin = &bsp_section_text_begin[0];
1902 text_end = &bsp_section_text_end[0];
1903 target_printk("[} MMU edit: text_begin: %p text_end: %p\n",
1904 text_begin, text_end);
1905 text_section_flags =
1906 arm_cp15_set_translation_table_entries(text_begin,
1907 text_end,
1908 ARMV7_MMU_DATA_READ_WRITE_CACHED);
1909 }
1910 #else
1911 static void
1912 rtems_debugger_target_set_mmu(void)
1913 {
1914 }
1915 #endif
1916
1917 static void
1918 rtems_debugger_target_set_vectors(void)
1919 {
1920 arm_cp15_set_exception_handler(ARM_EXCEPTION_UNDEF,
1921 target_exception_undefined_instruction);
1922 arm_cp15_set_exception_handler(ARM_EXCEPTION_SWI,
1923 target_exception_supervisor_call);
1924 arm_cp15_set_exception_handler(ARM_EXCEPTION_PREF_ABORT,
1925 target_exception_prefetch_abort);
1926 arm_cp15_set_exception_handler(ARM_EXCEPTION_DATA_ABORT,
1927 target_exception_data_abort);
1928 }
1929 #else
1930 static void
1931 rtems_debugger_target_set_vectors(void)
1932 {
1933
1934
1935
1936 void* ui = target_exception_undefined_instruction;
1937 void* sc = target_exception_supervisor_call;
1938 void* pa = target_exception_prefetch_abort;
1939 void* da = target_exception_data_abort;
1940 (void) ui;
1941 (void) sc;
1942 (void) pa;
1943 (void) da;
1944 }
1945
1946 static void
1947 rtems_debugger_target_set_mmu(void)
1948 {
1949 }
1950 #endif
1951
1952 static bool
1953 rtems_debugger_is_int_reg(size_t reg)
1954 {
1955 const size_t size = arm_reg_offsets[reg + 1] - arm_reg_offsets[reg];
1956 return size == RTEMS_DEBUGGER_REG_BYTES;
1957 }
1958
1959 static void
1960 rtems_debugger_set_int_reg(rtems_debugger_thread* thread,
1961 size_t reg,
1962 const uint32_t value)
1963 {
1964 const size_t offset = arm_reg_offsets[reg];
1965
1966
1967
1968 memcpy(&thread->registers[offset], &value, sizeof(uint32_t));
1969 }
1970
1971 static const uint32_t
1972 rtems_debugger_get_int_reg(rtems_debugger_thread* thread, size_t reg)
1973 {
1974 const size_t offset = arm_reg_offsets[reg];
1975 uint32_t value;
1976 memcpy(&value, &thread->registers[offset], sizeof(uint32_t));
1977 return value;
1978 }
1979
1980 int
1981 rtems_debugger_target_enable(void)
1982 {
1983 rtems_interrupt_lock_context lock_context;
1984 arm_debug_break_unload();
1985 arm_debug_break_clear_all();
1986 rtems_interrupt_lock_acquire(&target_lock, &lock_context);
1987 rtems_debugger_target_set_mmu();
1988 rtems_debugger_target_set_vectors();
1989 rtems_interrupt_lock_release(&target_lock, &lock_context);
1990 debug_session_active = true;
1991 return 0;
1992 }
1993
1994 int
1995 rtems_debugger_target_disable(void)
1996 {
1997 rtems_interrupt_lock_context lock_context;
1998 #if DOES_NOT_WORK
1999 void* text_begin;
2000 void* text_end;
2001 #endif
2002 arm_debug_break_unload();
2003 arm_debug_break_clear_all();
2004 rtems_interrupt_lock_acquire(&target_lock, &lock_context);
2005 debug_disable_ints = 0;
2006 debug_session_active = false;
2007 #if DOES_NOT_WORK
2008 text_begin = &bsp_section_text_begin[0];
2009 text_end = &bsp_section_text_end[0];
2010 arm_cp15_set_translation_table_entries(text_begin,
2011 text_end,
2012 text_section_flags);
2013 #endif
2014 rtems_interrupt_lock_release(&target_lock, &lock_context);
2015 return 0;
2016 }
2017
2018 int
2019 rtems_debugger_target_read_regs(rtems_debugger_thread* thread)
2020 {
2021 if (!rtems_debugger_thread_flag(thread,
2022 RTEMS_DEBUGGER_THREAD_FLAG_REG_VALID)) {
2023 static const uint32_t good_address = (uint32_t) &good_address;
2024 int i;
2025
2026 memset(&thread->registers[0], 0, RTEMS_DEBUGGER_NUMREGBYTES);
2027
2028 for (i = 0; i < RTEMS_DEBUGGER_NUMREGS; ++i) {
2029 if (rtems_debugger_is_int_reg(i))
2030 rtems_debugger_set_int_reg(thread, i, (uint32_t) &good_address);
2031 }
2032
2033 if (thread->frame) {
2034 CPU_Exception_frame* frame = thread->frame;
2035
2036
2037
2038
2039
2040 FRAME_SR(frame) &= ~CPSR_INTS_MASK;
2041
2042 if (rtems_debugger_thread_flag(thread,
2043 RTEMS_DEBUGGER_THREAD_FLAG_INTS_DISABLED)) {
2044 FRAME_SR(frame) |=
2045 (thread->flags >> RTEMS_DEBUGGER_THREAD_FLAG_TARGET_BASE) & CPSR_INTS_MASK;
2046 thread->flags &= ~RTEMS_DEBUGGER_THREAD_FLAG_INTS_DISABLED;
2047 }
2048
2049 rtems_debugger_set_int_reg(thread, REG_R0, frame->register_r0);
2050 rtems_debugger_set_int_reg(thread, REG_R1, frame->register_r1);
2051 rtems_debugger_set_int_reg(thread, REG_R2, frame->register_r2);
2052 rtems_debugger_set_int_reg(thread, REG_R3, frame->register_r3);
2053 rtems_debugger_set_int_reg(thread, REG_R4, frame->register_r4);
2054 rtems_debugger_set_int_reg(thread, REG_R5, frame->register_r5);
2055 rtems_debugger_set_int_reg(thread, REG_R6, frame->register_r6);
2056 rtems_debugger_set_int_reg(thread, REG_R7, frame->register_r7);
2057 rtems_debugger_set_int_reg(thread, REG_R8, frame->register_r8);
2058 rtems_debugger_set_int_reg(thread, REG_R9, frame->register_r9);
2059 rtems_debugger_set_int_reg(thread, REG_R10, frame->register_r10);
2060 rtems_debugger_set_int_reg(thread, REG_R11, frame->register_r11);
2061 rtems_debugger_set_int_reg(thread, REG_R12, frame->register_r12);
2062 rtems_debugger_set_int_reg(thread, REG_SP, frame->register_sp);
2063 rtems_debugger_set_int_reg(thread, REG_LR, (uint32_t) frame->register_lr);
2064 rtems_debugger_set_int_reg(thread, REG_PC, (uint32_t) frame->register_pc);
2065 rtems_debugger_set_int_reg(thread, REG_CPSR, FRAME_SR(frame));
2066
2067
2068
2069 thread->signal = rtems_debugger_target_exception_to_signal(frame);
2070 }
2071 else {
2072 #if defined(ARM_MULTILIB_ARCH_V4)
2073 rtems_debugger_set_int_reg(thread, REG_R4, thread->tcb->Registers.register_r4);
2074 rtems_debugger_set_int_reg(thread, REG_R5, thread->tcb->Registers.register_r5);
2075 rtems_debugger_set_int_reg(thread, REG_R6, thread->tcb->Registers.register_r6);
2076 rtems_debugger_set_int_reg(thread, REG_R7, thread->tcb->Registers.register_r7);
2077 rtems_debugger_set_int_reg(thread, REG_R8, thread->tcb->Registers.register_r8);
2078 rtems_debugger_set_int_reg(thread, REG_R9, thread->tcb->Registers.register_r9);
2079 rtems_debugger_set_int_reg(thread, REG_R10, thread->tcb->Registers.register_r10);
2080 rtems_debugger_set_int_reg(thread, REG_R11, thread->tcb->Registers.register_fp);
2081 rtems_debugger_set_int_reg(thread, REG_LR, (intptr_t) thread->tcb->Registers.register_lr);
2082 rtems_debugger_set_int_reg(thread, REG_PC, (intptr_t) thread->tcb->Registers.register_lr);
2083 rtems_debugger_set_int_reg(thread, REG_SP, (intptr_t) thread->tcb->Registers.register_sp);
2084 #elif defined(ARM_MULTILIB_ARCH_V7M)
2085 rtems_debugger_set_int_reg(thread, REG_R4, thread->tcb->Registers.register_r4);
2086 rtems_debugger_set_int_reg(thread, REG_R5, thread->tcb->Registers.register_r5);
2087 rtems_debugger_set_int_reg(thread, REG_R6, thread->tcb->Registers.register_r6);
2088 rtems_debugger_set_int_reg(thread, REG_R7, thread->tcb->Registers.register_r7);
2089 rtems_debugger_set_int_reg(thread, REG_R8, thread->tcb->Registers.register_r8);
2090 rtems_debugger_set_int_reg(thread, REG_R9, thread->tcb->Registers.register_r9);
2091 rtems_debugger_set_int_reg(thread, REG_R10, thread->tcb->Registers.register_r10);
2092 rtems_debugger_set_int_reg(thread, REG_R11, thread->tcb->Registers.register_r11);
2093 rtems_debugger_set_int_reg(thread, REG_LR, (intptr_t) thread->tcb->Registers.register_lr);
2094 rtems_debugger_set_int_reg(thread, REG_PC, (intptr_t) thread->tcb->Registers.register_lr);
2095 rtems_debugger_set_int_reg(thread, REG_SP, (intptr_t) thread->tcb->Registers.register_sp);
2096 #endif
2097
2098
2099
2100 thread->signal = 0;
2101 }
2102
2103 thread->flags |= RTEMS_DEBUGGER_THREAD_FLAG_REG_VALID;
2104 thread->flags &= ~RTEMS_DEBUGGER_THREAD_FLAG_REG_DIRTY;
2105 }
2106
2107 return 0;
2108 }
2109
2110 int
2111 rtems_debugger_target_write_regs(rtems_debugger_thread* thread)
2112 {
2113 if (rtems_debugger_thread_flag(thread,
2114 RTEMS_DEBUGGER_THREAD_FLAG_REG_DIRTY)) {
2115
2116
2117
2118
2119 if (rtems_debugger_thread_flag(thread,
2120 RTEMS_DEBUGGER_THREAD_FLAG_EXCEPTION)) {
2121 CPU_Exception_frame* frame = thread->frame;
2122 frame->register_r0 = rtems_debugger_get_int_reg(thread, REG_R0);
2123 frame->register_r1 = rtems_debugger_get_int_reg(thread, REG_R1);
2124 frame->register_r2 = rtems_debugger_get_int_reg(thread, REG_R2);
2125 frame->register_r3 = rtems_debugger_get_int_reg(thread, REG_R3);
2126 frame->register_r4 = rtems_debugger_get_int_reg(thread, REG_R4);
2127 frame->register_r5 = rtems_debugger_get_int_reg(thread, REG_R5);
2128 frame->register_r6 = rtems_debugger_get_int_reg(thread, REG_R6);
2129 frame->register_r7 = rtems_debugger_get_int_reg(thread, REG_R7);
2130 frame->register_r8 = rtems_debugger_get_int_reg(thread, REG_R8);
2131 frame->register_r9 = rtems_debugger_get_int_reg(thread, REG_R9);
2132 frame->register_r10 = rtems_debugger_get_int_reg(thread, REG_R10);
2133 frame->register_r11 = rtems_debugger_get_int_reg(thread, REG_R11);
2134 frame->register_r12 = rtems_debugger_get_int_reg(thread, REG_R12);
2135 frame->register_sp = rtems_debugger_get_int_reg(thread, REG_SP);
2136 frame->register_lr = (void*) rtems_debugger_get_int_reg(thread, REG_LR);
2137 frame->register_pc = (void*) rtems_debugger_get_int_reg(thread, REG_PC);
2138 FRAME_SR(frame) = rtems_debugger_get_int_reg(thread, REG_CPSR);
2139 }
2140 thread->flags &= ~RTEMS_DEBUGGER_THREAD_FLAG_REG_DIRTY;
2141 }
2142 return 0;
2143 }
2144
2145 DB_UINT
2146 rtems_debugger_target_reg_pc(rtems_debugger_thread* thread)
2147 {
2148 int r;
2149 r = rtems_debugger_target_read_regs(thread);
2150 if (r >= 0) {
2151 return rtems_debugger_get_int_reg(thread, REG_PC);
2152 }
2153 return 0;
2154 }
2155
2156 DB_UINT
2157 rtems_debugger_target_frame_pc(CPU_Exception_frame* frame)
2158 {
2159 return (DB_UINT) frame->register_pc;
2160 }
2161
2162 DB_UINT
2163 rtems_debugger_target_reg_sp(rtems_debugger_thread* thread)
2164 {
2165 int r;
2166 r = rtems_debugger_target_read_regs(thread);
2167 if (r >= 0) {
2168 return rtems_debugger_get_int_reg(thread, REG_SP);
2169 }
2170 return 0;
2171 }
2172
2173 DB_UINT
2174 rtems_debugger_target_tcb_sp(rtems_debugger_thread* thread)
2175 {
2176 return (DB_UINT) thread->tcb->Registers.register_sp;
2177 }
2178
2179 int
2180 rtems_debugger_target_thread_stepping(rtems_debugger_thread* thread)
2181 {
2182 if (rtems_debugger_thread_flag(thread, RTEMS_DEBUGGER_THREAD_FLAG_STEP_INSTR)) {
2183
2184
2185
2186
2187 CPU_Exception_frame* frame = thread->frame;
2188
2189 target_printk("[} stepping: hbp[0] enabled: %s\n", ARM_HWB_ENALBED(0) ? "yes" : "no");
2190
2191 if (!ARM_HWB_ENALBED(0)) {
2192 const uint32_t addr = (intptr_t) frame->register_pc;
2193 const bool thumb = (FRAME_SR(frame) & (1 << 5)) != 0 ? true : false;
2194 arm_debug_break_exec_enable(0, addr, thumb, true);
2195 arm_debug_disable_interrupts();
2196 }
2197 }
2198 return 0;
2199 }
2200
2201 int
2202 rtems_debugger_target_exception_to_signal(CPU_Exception_frame* frame)
2203 {
2204 int sig = RTEMS_DEBUGGER_SIGNAL_HUP;
2205 #if defined(ARM_MULTILIB_ARCH_V4)
2206 switch (frame->vector) {
2207 case ARM_EXCEPTION_RESET:
2208 case ARM_EXCEPTION_SWI:
2209 sig = RTEMS_DEBUGGER_SIGNAL_TRAP;
2210 break;
2211 case ARM_EXCEPTION_UNDEF:
2212 sig = RTEMS_DEBUGGER_SIGNAL_ILL;
2213 break;
2214 case ARM_EXCEPTION_FIQ:
2215 sig = RTEMS_DEBUGGER_SIGNAL_FPE;
2216 break;
2217 case ARM_EXCEPTION_PREF_ABORT:
2218 case ARM_EXCEPTION_DATA_ABORT:
2219 sig = RTEMS_DEBUGGER_SIGNAL_SEGV;
2220 break;
2221 case ARM_EXCEPTION_RESERVED:
2222 case ARM_EXCEPTION_IRQ:
2223 sig = RTEMS_DEBUGGER_SIGNAL_BUS;
2224 break;
2225 default:
2226 break;
2227 }
2228 #endif
2229 return sig;
2230 }
2231
2232 void
2233 rtems_debugger_target_exception_print(CPU_Exception_frame* frame)
2234 {
2235 EXC_FRAME_PRINT(rtems_debugger_printf, "", frame);
2236 }
2237
2238 int
2239 rtems_debugger_target_hwbreak_insert(void)
2240 {
2241
2242
2243
2244 return 0;
2245 }
2246
2247 int
2248 rtems_debugger_target_hwbreak_remove(void)
2249 {
2250 target_printk("[} hbreak: remove: unload\n");
2251 arm_debug_break_unload();
2252 return 0;
2253 }
2254
2255 int
2256 rtems_debugger_target_hwbreak_control(rtems_debugger_target_watchpoint wp,
2257 bool insert,
2258 DB_UINT addr,
2259 DB_UINT kind)
2260 {
2261 rtems_interrupt_lock_context lock_context;
2262 int i;
2263 if (wp != rtems_debugger_target_hw_execute) {
2264 errno = EIO;
2265 return -1;
2266 }
2267 rtems_interrupt_lock_acquire(&target_lock, &lock_context);
2268 for (i = 1; i < hw_breakpoints; ++i) {
2269 if (insert && !ARM_HWB_ENALBED(i)) {
2270 arm_debug_break_exec_enable(i, addr, kind == 1, false);
2271 break;
2272 } else if (!insert && ARM_HWB_ENALBED(i) && ARM_HWB_VCR(i) == (addr & ~3)) {
2273 arm_debug_break_clear(i);
2274 break;
2275 }
2276 }
2277 rtems_interrupt_lock_release(&target_lock, &lock_context);
2278 if (!insert && i == hw_breakpoints) {
2279 errno = EIO;
2280 return -1;
2281 }
2282 return 0;
2283 }
2284
2285 int
2286 rtems_debugger_target_cache_sync(rtems_debugger_target_swbreak* swbreak)
2287 {
2288 target_printk("[} cache: sync: %p\n", swbreak->address);
2289
2290
2291
2292 rtems_cache_flush_multiple_data_lines(swbreak->address,
2293 sizeof(breakpoint));
2294 rtems_cache_instruction_sync_after_code_change(swbreak->address,
2295 sizeof(breakpoint));
2296 return 0;
2297 }