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 #ifdef HAVE_CONFIG_H
0030 #include "config.h"
0031 #endif
0032
0033 #include <errno.h>
0034 #include <inttypes.h>
0035 #include <stdlib.h>
0036
0037
0038 extern char bsp_section_start_begin[];
0039 extern char bsp_section_start_end[];
0040 extern char bsp_section_text_begin[];
0041 extern char bsp_section_text_end[];
0042 extern char bsp_section_fast_text_begin[];
0043 extern char bsp_section_fast_text_end[];
0044
0045 #include <libcpu/mmu-vmsav8-64.h>
0046
0047 #include <rtems.h>
0048 #include <rtems/score/aarch64-system-registers.h>
0049 #include <rtems/score/cpu.h>
0050 #include <rtems/score/threadimpl.h>
0051
0052 #include <rtems/debugger/rtems-debugger-bsp.h>
0053
0054 #include "rtems-debugger-target.h"
0055 #include "rtems-debugger-threads.h"
0056
0057 #if TARGET_DEBUG
0058 #include <rtems/bspIo.h>
0059 #endif
0060
0061
0062
0063
0064
0065 typedef struct {
0066 rtems_id allCPUsBarrier;
0067 rtems_task_entry work_function;
0068 rtems_task_argument arg;
0069 rtems_status_code sc;
0070 } run_across_cpus_context;
0071
0072
0073
0074
0075
0076 static rtems_task run_across_cpus_task( rtems_task_argument arg )
0077 {
0078 uint32_t released = 0;
0079 rtems_status_code sc;
0080 run_across_cpus_context *ctx = (run_across_cpus_context *) arg;
0081 cpu_set_t set;
0082 cpu_set_t scheduler_set;
0083 rtems_id scheduler_id;
0084
0085 sc = rtems_task_get_scheduler( RTEMS_SELF, &scheduler_id );
0086
0087 if ( sc != RTEMS_SUCCESSFUL ) {
0088 ctx->sc = sc;
0089 rtems_task_exit();
0090 }
0091
0092 CPU_ZERO( &scheduler_set );
0093 sc = rtems_scheduler_get_processor_set(
0094 scheduler_id,
0095 sizeof( scheduler_set ),
0096 &scheduler_set
0097 );
0098
0099 if ( sc != RTEMS_SUCCESSFUL ) {
0100 ctx->sc = sc;
0101 rtems_task_exit();
0102 }
0103
0104 for (
0105 int cpu_index = 0;
0106 cpu_index < rtems_scheduler_get_processor_maximum();
0107 cpu_index++
0108 ) {
0109 if ( !CPU_ISSET( cpu_index, &scheduler_set ) ) {
0110 continue;
0111 }
0112
0113 CPU_ZERO( &set );
0114 CPU_SET( cpu_index, &set );
0115 sc = rtems_task_set_affinity( RTEMS_SELF, sizeof( set ), &set );
0116
0117 if ( sc != RTEMS_SUCCESSFUL ) {
0118 ctx->sc = sc;
0119 rtems_task_exit();
0120 }
0121
0122
0123 ctx->work_function( ctx->arg );
0124 }
0125
0126 sc = rtems_barrier_release( ctx->allCPUsBarrier, &released );
0127
0128 if ( sc != RTEMS_SUCCESSFUL ) {
0129 ctx->sc = sc;
0130 }
0131
0132 rtems_task_exit();
0133 }
0134
0135
0136
0137
0138
0139
0140
0141 static rtems_status_code run_across_cpus(
0142 rtems_task_entry task_entry,
0143 rtems_task_argument arg
0144 )
0145 {
0146 rtems_status_code sc;
0147 rtems_id Task_id;
0148 run_across_cpus_context ctx;
0149
0150 ctx.work_function = task_entry;
0151 ctx.arg = arg;
0152 ctx.sc = RTEMS_SUCCESSFUL;
0153
0154 memset( &ctx.allCPUsBarrier, 0, sizeof( ctx.allCPUsBarrier ) );
0155 sc = rtems_barrier_create(
0156 rtems_build_name( 'B', 'c', 'p', 'u' ),
0157 RTEMS_BARRIER_MANUAL_RELEASE,
0158 2,
0159 &ctx.allCPUsBarrier
0160 );
0161
0162 if ( sc != RTEMS_SUCCESSFUL ) {
0163 return sc;
0164 }
0165
0166 sc = rtems_task_create(
0167 rtems_build_name( 'T', 'c', 'p', 'u' ),
0168 1,
0169 RTEMS_MINIMUM_STACK_SIZE * 2,
0170 RTEMS_DEFAULT_MODES,
0171 RTEMS_FLOATING_POINT | RTEMS_DEFAULT_ATTRIBUTES,
0172 &Task_id
0173 );
0174
0175 if ( sc != RTEMS_SUCCESSFUL ) {
0176 rtems_barrier_delete( ctx.allCPUsBarrier );
0177 return sc;
0178 }
0179
0180 sc = rtems_task_start(
0181 Task_id,
0182 run_across_cpus_task,
0183 ( rtems_task_argument ) & ctx
0184 );
0185
0186 if ( sc != RTEMS_SUCCESSFUL ) {
0187 rtems_task_delete( Task_id );
0188 rtems_barrier_delete( ctx.allCPUsBarrier );
0189 return sc;
0190 }
0191
0192
0193 sc = rtems_barrier_wait( ctx.allCPUsBarrier, RTEMS_NO_TIMEOUT );
0194
0195 if ( sc != RTEMS_SUCCESSFUL ) {
0196 rtems_task_delete( Task_id );
0197 rtems_barrier_delete( ctx.allCPUsBarrier );
0198 return sc;
0199 }
0200
0201 rtems_barrier_delete( ctx.allCPUsBarrier );
0202
0203 if ( ctx.sc != RTEMS_SUCCESSFUL ) {
0204 return ctx.sc;
0205 }
0206
0207 return sc;
0208 }
0209
0210
0211
0212
0213 #define RTEMS_DEBUGGER_NUMREGS 68
0214
0215
0216
0217
0218 #define RTEMS_DEBUGGER_REG_BYTES 8
0219
0220
0221 #define REG_X0 0
0222 #define REG_X1 1
0223 #define REG_X2 2
0224 #define REG_X3 3
0225 #define REG_X4 4
0226 #define REG_X5 5
0227 #define REG_X6 6
0228 #define REG_X7 7
0229 #define REG_X8 8
0230 #define REG_X9 9
0231 #define REG_X10 10
0232 #define REG_X11 11
0233 #define REG_X12 12
0234 #define REG_X13 13
0235 #define REG_X14 14
0236 #define REG_X15 15
0237 #define REG_X16 16
0238 #define REG_X17 17
0239 #define REG_X18 18
0240 #define REG_X19 19
0241 #define REG_X20 20
0242 #define REG_X21 21
0243 #define REG_X22 22
0244 #define REG_X23 23
0245 #define REG_X24 24
0246 #define REG_X25 25
0247 #define REG_X26 26
0248 #define REG_X27 27
0249 #define REG_X28 28
0250 #define REG_FP 29
0251 #define REG_LR 30
0252 #define REG_SP 31
0253
0254
0255
0256
0257 #define REG_PC 32
0258
0259 #define REG_CPS 33
0260
0261 #define REG_V0 34
0262 #define REG_V1 35
0263 #define REG_V2 36
0264 #define REG_V3 37
0265 #define REG_V4 38
0266 #define REG_V5 39
0267 #define REG_V6 40
0268 #define REG_V7 41
0269 #define REG_V8 42
0270 #define REG_V9 43
0271 #define REG_V10 44
0272 #define REG_V11 45
0273 #define REG_V12 46
0274 #define REG_V13 47
0275 #define REG_V14 48
0276 #define REG_V15 49
0277 #define REG_V16 50
0278 #define REG_V17 51
0279 #define REG_V18 52
0280 #define REG_V19 53
0281 #define REG_V20 54
0282 #define REG_V21 55
0283 #define REG_V22 56
0284 #define REG_V23 57
0285 #define REG_V24 58
0286 #define REG_V25 59
0287 #define REG_V26 60
0288 #define REG_V27 61
0289 #define REG_V28 62
0290 #define REG_V29 63
0291 #define REG_V30 64
0292 #define REG_V31 65
0293
0294 #define REG_FPS 66
0295 #define REG_FPC 67
0296
0297
0298
0299
0300
0301
0302
0303
0304 static const size_t aarch64_reg_offsets[ RTEMS_DEBUGGER_NUMREGS + 1 ] = {
0305 REG_X0 * 8,
0306 REG_X1 * 8,
0307 REG_X2 * 8,
0308 REG_X3 * 8,
0309 REG_X4 * 8,
0310 REG_X5 * 8,
0311 REG_X6 * 8,
0312 REG_X7 * 8,
0313 REG_X8 * 8,
0314 REG_X9 * 8,
0315 REG_X10 * 8,
0316 REG_X11 * 8,
0317 REG_X12 * 8,
0318 REG_X13 * 8,
0319 REG_X14 * 8,
0320 REG_X15 * 8,
0321 REG_X16 * 8,
0322 REG_X17 * 8,
0323 REG_X18 * 8,
0324 REG_X19 * 8,
0325 REG_X20 * 8,
0326 REG_X21 * 8,
0327 REG_X22 * 8,
0328 REG_X23 * 8,
0329 REG_X24 * 8,
0330 REG_X25 * 8,
0331 REG_X26 * 8,
0332 REG_X27 * 8,
0333 REG_X28 * 8,
0334 REG_FP * 8,
0335 REG_LR * 8,
0336 REG_SP * 8,
0337 REG_PC * 8,
0338 REG_CPS * 8,
0339
0340 #define V0_OFFSET ( REG_CPS * 8 + 4 )
0341 V0_OFFSET,
0342 V0_OFFSET + 16 * ( REG_V1 - REG_V0 ),
0343 V0_OFFSET + 16 * ( REG_V2 - REG_V0 ),
0344 V0_OFFSET + 16 * ( REG_V3 - REG_V0 ),
0345 V0_OFFSET + 16 * ( REG_V4 - REG_V0 ),
0346 V0_OFFSET + 16 * ( REG_V5 - REG_V0 ),
0347 V0_OFFSET + 16 * ( REG_V6 - REG_V0 ),
0348 V0_OFFSET + 16 * ( REG_V7 - REG_V0 ),
0349 V0_OFFSET + 16 * ( REG_V8 - REG_V0 ),
0350 V0_OFFSET + 16 * ( REG_V9 - REG_V0 ),
0351 V0_OFFSET + 16 * ( REG_V10 - REG_V0 ),
0352 V0_OFFSET + 16 * ( REG_V11 - REG_V0 ),
0353 V0_OFFSET + 16 * ( REG_V12 - REG_V0 ),
0354 V0_OFFSET + 16 * ( REG_V13 - REG_V0 ),
0355 V0_OFFSET + 16 * ( REG_V14 - REG_V0 ),
0356 V0_OFFSET + 16 * ( REG_V15 - REG_V0 ),
0357 V0_OFFSET + 16 * ( REG_V16 - REG_V0 ),
0358 V0_OFFSET + 16 * ( REG_V17 - REG_V0 ),
0359 V0_OFFSET + 16 * ( REG_V18 - REG_V0 ),
0360 V0_OFFSET + 16 * ( REG_V19 - REG_V0 ),
0361 V0_OFFSET + 16 * ( REG_V20 - REG_V0 ),
0362 V0_OFFSET + 16 * ( REG_V21 - REG_V0 ),
0363 V0_OFFSET + 16 * ( REG_V22 - REG_V0 ),
0364 V0_OFFSET + 16 * ( REG_V23 - REG_V0 ),
0365 V0_OFFSET + 16 * ( REG_V24 - REG_V0 ),
0366 V0_OFFSET + 16 * ( REG_V25 - REG_V0 ),
0367 V0_OFFSET + 16 * ( REG_V26 - REG_V0 ),
0368 V0_OFFSET + 16 * ( REG_V27 - REG_V0 ),
0369 V0_OFFSET + 16 * ( REG_V28 - REG_V0 ),
0370 V0_OFFSET + 16 * ( REG_V29 - REG_V0 ),
0371 V0_OFFSET + 16 * ( REG_V30 - REG_V0 ),
0372 V0_OFFSET + 16 * ( REG_V31 - REG_V0 ),
0373
0374 #define FPS_OFFSET ( V0_OFFSET + 16 * ( REG_V31 - REG_V0 ) + 16 )
0375 FPS_OFFSET,
0376
0377 FPS_OFFSET + 4,
0378
0379 FPS_OFFSET + 8,
0380 };
0381
0382
0383
0384
0385 #define RTEMS_DEBUGGER_NUMREGBYTES \
0386 aarch64_reg_offsets[ RTEMS_DEBUGGER_NUMREGS ]
0387
0388
0389
0390
0391 #define EXC_FRAME_PRINT( _out, _prefix, _frame ) \
0392 do { \
0393 _out( \
0394 _prefix " X0 = %016" PRIx64 " X1 = %016" PRIx64 \
0395 " X2 = %016" PRIx64 " X3 = %016" PRIx64 "\n", \
0396 _frame->register_x0, \
0397 _frame->register_x1, \
0398 _frame->register_x2, \
0399 _frame->register_x3 \
0400 ); \
0401 _out( \
0402 _prefix " X4 = %016" PRIx64 " X5 = %016" PRIx64 \
0403 " X6 = %016" PRIx64 " X7 = %016" PRIx64 "\n", \
0404 _frame->register_x4, \
0405 _frame->register_x5, \
0406 _frame->register_x6, \
0407 _frame->register_x7 \
0408 ); \
0409 _out( \
0410 _prefix " X8 = %016" PRIx64 " X9 = %016" PRIx64 \
0411 " X10 = %016" PRIx64 " X11 = %016" PRIx64 "\n", \
0412 _frame->register_x8, \
0413 _frame->register_x9, \
0414 _frame->register_x10, \
0415 _frame->register_x11 \
0416 ); \
0417 _out( \
0418 _prefix " X12 = %016" PRIx64 " X13 = %016" PRIx64 \
0419 " X14 = %016" PRIx64 " X15 = %016" PRIx64 "\n", \
0420 _frame->register_x12, \
0421 _frame->register_x13, \
0422 _frame->register_x14, \
0423 _frame->register_x15 \
0424 ); \
0425 _out( \
0426 _prefix " X16 = %016" PRIx64 " X17 = %016" PRIx64 \
0427 " X18 = %016" PRIx64 " X19 = %016" PRIx64 "\n", \
0428 _frame->register_x16, \
0429 _frame->register_x17, \
0430 _frame->register_x18, \
0431 _frame->register_x19 \
0432 ); \
0433 _out( \
0434 _prefix " X20 = %016" PRIx64 " X21 = %016" PRIx64 \
0435 " X22 = %016" PRIx64 " X23 = %016" PRIx64 "\n", \
0436 _frame->register_x20, \
0437 _frame->register_x21, \
0438 _frame->register_x22, \
0439 _frame->register_x23 \
0440 ); \
0441 _out( \
0442 _prefix " X24 = %016" PRIx64 " X25 = %016" PRIx64 \
0443 " X26 = %016" PRIx64 " X27 = %016" PRIx64 "\n", \
0444 _frame->register_x24, \
0445 _frame->register_x25, \
0446 _frame->register_x26, \
0447 _frame->register_x27 \
0448 ); \
0449 _out( \
0450 _prefix " X28 = %016" PRIx64 " FP = %016" PRIx64 \
0451 " LR = %016" PRIxPTR " SP = %016" PRIxPTR "\n", \
0452 _frame->register_x28, \
0453 _frame->register_fp, \
0454 (intptr_t) _frame->register_lr, \
0455 (intptr_t) _frame->register_sp \
0456 ); \
0457 _out( \
0458 _prefix " PC = %016" PRIxPTR "\n", \
0459 (intptr_t) _frame->register_pc \
0460 ); \
0461 _out( \
0462 _prefix " CPSR = %08" PRIx64 " %c%c%c%c%c%c%c%c%c" \
0463 " M:%" PRIx64 " %s\n", \
0464 _frame->register_cpsr, \
0465 ( _frame->register_cpsr & ( 1 << 31 ) ) != 0 ? 'N' : '-', \
0466 ( _frame->register_cpsr & ( 1 << 30 ) ) != 0 ? 'Z' : '-', \
0467 ( _frame->register_cpsr & ( 1 << 29 ) ) != 0 ? 'C' : '-', \
0468 ( _frame->register_cpsr & ( 1 << 28 ) ) != 0 ? 'V' : '-', \
0469 ( _frame->register_cpsr & ( 1 << 21 ) ) != 0 ? 'S' : '-', \
0470 ( _frame->register_cpsr & ( 1 << 9 ) ) != 0 ? 'D' : '-', \
0471 ( _frame->register_cpsr & ( 1 << 8 ) ) != 0 ? 'A' : '-', \
0472 ( _frame->register_cpsr & ( 1 << 7 ) ) != 0 ? 'I' : '-', \
0473 ( _frame->register_cpsr & ( 1 << 6 ) ) != 0 ? 'F' : '-', \
0474 _frame->register_cpsr & 0x1f, \
0475 aarch64_mode_label( _frame->register_cpsr & 0x1f ) \
0476 ); \
0477 } while ( 0 )
0478
0479
0480
0481
0482 static const uint8_t breakpoint[ 4 ] = { 0x00, 0x00, 0x20, 0xd4 };
0483
0484
0485
0486
0487 RTEMS_INTERRUPT_LOCK_DEFINE( static, target_lock, "target_lock" )
0488
0489
0490
0491
0492 static bool debug_session_active;
0493
0494
0495
0496
0497 static uint64_t hw_breakpoints;
0498 static uint64_t hw_watchpoints;
0499
0500 #ifdef HARDWARE_BREAKPOINTS_NOT_USED
0501
0502
0503
0504 typedef struct {
0505 bool enabled;
0506 bool loaded;
0507 void *address;
0508 size_t length;
0509 CPU_Exception_frame *frame;
0510 uint64_t control;
0511 uint64_t value;
0512 } aarch64_debug_hwbreak;
0513
0514
0515
0516
0517
0518
0519
0520
0521
0522
0523
0524
0525
0526
0527
0528
0529
0530 #define AARCH64_HW_BREAKPOINT_MAX ( 16 )
0531
0532
0533
0534
0535 #define AARCH64_HW_BP_TYPE_UNLINKED_INSTR_MATCH ( 0x0 << 20 )
0536 #define AARCH64_HW_BP_TYPE_UNLINKED_INSTR_MISMATCH ( 0x4 << 20 )
0537
0538
0539
0540
0541 #define AARCH64_HW_BP_BAS_A64 ( 0xF << 5 )
0542
0543
0544
0545
0546 #define AARCH64_HW_BP_PRIV_EL1 ( 0x1 << 1 )
0547
0548
0549
0550
0551 #define AARCH64_HW_BP_ENABLE ( 0x1 )
0552
0553 static aarch64_debug_hwbreak hw_breaks[ AARCH64_HW_BREAKPOINT_MAX ];
0554 #endif
0555
0556
0557
0558
0559 #if TARGET_DEBUG
0560
0561 void rtems_debugger_printk_lock( rtems_interrupt_lock_context *lock_context );
0562
0563 void rtems_debugger_printk_unlock(
0564 rtems_interrupt_lock_context *lock_context
0565 );
0566
0567 static void target_printk( const char *format, ... ) RTEMS_PRINTFLIKE( 1, 2 );
0568
0569 static void target_printk( const char *format, ... )
0570 {
0571 rtems_interrupt_lock_context lock_context;
0572 va_list ap;
0573
0574 va_start( ap, format );
0575 rtems_debugger_printk_lock( &lock_context );
0576 vprintk( format, ap );
0577 rtems_debugger_printk_unlock( &lock_context );
0578 va_end( ap );
0579 }
0580
0581 #else
0582 #define target_printk( _fmt, ... )
0583 #endif
0584
0585 static const char *aarch64_mode_label( int mode )
0586 {
0587 switch ( mode ) {
0588 case 0x0:
0589 return "EL0t";
0590 case 0x4:
0591 return "EL1t";
0592 case 0x5:
0593 return "EL1h";
0594 }
0595
0596 return "---";
0597 }
0598
0599 static int aarch64_debug_probe( rtems_debugger_target *target )
0600 {
0601 int debug_version;
0602 uint64_t val;
0603 const char *vl = "[Invalid version]";
0604 const char * const labels[] = {
0605 NULL,
0606 NULL,
0607 NULL,
0608 NULL,
0609 NULL,
0610 NULL,
0611 "ARMv8.0",
0612 "ARMv8.0+VHE",
0613 "ARMv8.2",
0614 "ARMv8.4"
0615 };
0616
0617 val = _AArch64_Read_midr_el1();
0618 rtems_debugger_printf(
0619 "rtems-db: aarch64 core: Architecture: %" PRIu64 " Variant: %" PRIu64 " " \
0620 "Implementor: %" PRIu64 " Part Number: %" PRIu64 " Revision: %" PRIu64 "\n",
0621 AARCH64_MIDR_EL1_ARCHITECTURE_GET( val ),
0622 AARCH64_MIDR_EL1_VARIANT_GET( val ),
0623 AARCH64_MIDR_EL1_IMPLEMENTER_GET( val ),
0624 AARCH64_MIDR_EL1_PARTNUM_GET( val ),
0625 AARCH64_MIDR_EL1_REVISION_GET( val )
0626 );
0627
0628 val = _AArch64_Read_id_aa64dfr0_el1();
0629
0630 debug_version = AARCH64_ID_AA64DFR0_EL1_DEBUGVER_GET( val );
0631
0632 if ( debug_version < 6 || debug_version > 9 ) {
0633 rtems_debugger_printf(
0634 "rtems-db: aarch64 debug: %d not supported\n",
0635 debug_version
0636 );
0637 errno = EIO;
0638 return -1;
0639 }
0640
0641 vl = labels[ debug_version ];
0642 hw_breakpoints = AARCH64_ID_AA64DFR0_EL1_BRPS_GET( val );
0643 hw_watchpoints = AARCH64_ID_AA64DFR0_EL1_WRPS_GET( val );
0644
0645 rtems_debugger_printf(
0646 "rtems-db: aarch64 debug: %s (%d) " \
0647 "breakpoints:%" PRIu64 " watchpoints:%" PRIu64 "\n",
0648 vl,
0649 debug_version,
0650 hw_breakpoints,
0651 hw_watchpoints
0652 );
0653
0654 return 0;
0655 }
0656
0657 #ifdef HARDWARE_BREAKPOINTS_NOT_USED
0658 static void aarch64_debug_break_write_control( int bp, uint64_t control )
0659 {
0660 if ( bp < 15 ) {
0661 switch ( bp ) {
0662 case 0:
0663 _AArch64_Write_dbgbcr0_el1( control );
0664 break;
0665 case 1:
0666 _AArch64_Write_dbgbcr1_el1( control );
0667 break;
0668 case 2:
0669 _AArch64_Write_dbgbcr2_el1( control );
0670 break;
0671 case 3:
0672 _AArch64_Write_dbgbcr3_el1( control );
0673 break;
0674 case 4:
0675 _AArch64_Write_dbgbcr4_el1( control );
0676 break;
0677 case 5:
0678 _AArch64_Write_dbgbcr5_el1( control );
0679 break;
0680 case 6:
0681 _AArch64_Write_dbgbcr6_el1( control );
0682 break;
0683 case 7:
0684 _AArch64_Write_dbgbcr7_el1( control );
0685 break;
0686 case 8:
0687 _AArch64_Write_dbgbcr8_el1( control );
0688 break;
0689 case 9:
0690 _AArch64_Write_dbgbcr9_el1( control );
0691 break;
0692 case 10:
0693 _AArch64_Write_dbgbcr10_el1( control );
0694 break;
0695 case 11:
0696 _AArch64_Write_dbgbcr11_el1( control );
0697 break;
0698 case 12:
0699 _AArch64_Write_dbgbcr12_el1( control );
0700 break;
0701 case 13:
0702 _AArch64_Write_dbgbcr13_el1( control );
0703 break;
0704 case 14:
0705 _AArch64_Write_dbgbcr14_el1( control );
0706 break;
0707 case 15:
0708 _AArch64_Write_dbgbcr15_el1( control );
0709 break;
0710 }
0711 }
0712 }
0713
0714 static void aarch64_debug_break_write_value( int bp, uint64_t value )
0715 {
0716 if ( bp < 15 ) {
0717 switch ( bp ) {
0718 case 0:
0719 _AArch64_Write_dbgbvr0_el1( value );
0720 break;
0721 case 1:
0722 _AArch64_Write_dbgbvr1_el1( value );
0723 break;
0724 case 2:
0725 _AArch64_Write_dbgbvr2_el1( value );
0726 break;
0727 case 3:
0728 _AArch64_Write_dbgbvr3_el1( value );
0729 break;
0730 case 4:
0731 _AArch64_Write_dbgbvr4_el1( value );
0732 break;
0733 case 5:
0734 _AArch64_Write_dbgbvr5_el1( value );
0735 break;
0736 case 6:
0737 _AArch64_Write_dbgbvr6_el1( value );
0738 break;
0739 case 7:
0740 _AArch64_Write_dbgbvr7_el1( value );
0741 break;
0742 case 8:
0743 _AArch64_Write_dbgbvr8_el1( value );
0744 break;
0745 case 9:
0746 _AArch64_Write_dbgbvr9_el1( value );
0747 break;
0748 case 10:
0749 _AArch64_Write_dbgbvr10_el1( value );
0750 break;
0751 case 11:
0752 _AArch64_Write_dbgbvr11_el1( value );
0753 break;
0754 case 12:
0755 _AArch64_Write_dbgbvr12_el1( value );
0756 break;
0757 case 13:
0758 _AArch64_Write_dbgbvr13_el1( value );
0759 break;
0760 case 14:
0761 _AArch64_Write_dbgbvr14_el1( value );
0762 break;
0763 case 15:
0764 _AArch64_Write_dbgbvr15_el1( value );
0765 break;
0766 }
0767 }
0768 }
0769
0770 static inline void aarch64_debug_break_setup(
0771 uint8_t index,
0772 uint64_t address
0773 )
0774 {
0775 aarch64_debug_hwbreak *bp = &hw_breaks[ index ];
0776
0777 bp->control = AARCH64_HW_BP_TYPE_UNLINKED_INSTR_MISMATCH |
0778 AARCH64_HW_BP_BAS_A64 |
0779 AARCH64_HW_BP_PRIV_EL1 |
0780 AARCH64_HW_BP_ENABLE;
0781 uint64_t address_mask = 0x3;
0782
0783 bp->value = (intptr_t) ( address & ~address_mask );
0784 aarch64_debug_break_write_value( index, bp->value );
0785 aarch64_debug_break_write_control( index, bp->control );
0786 }
0787
0788 static void aarch64_debug_break_clear( void )
0789 {
0790 rtems_interrupt_lock_context lock_context;
0791 aarch64_debug_hwbreak *bp = &hw_breaks[ 0 ];
0792 int i;
0793
0794 rtems_interrupt_lock_acquire( &target_lock, &lock_context );
0795
0796 for ( i = 0; i < hw_breakpoints; ++i, ++bp ) {
0797 bp->enabled = false;
0798 bp->loaded = false;
0799 }
0800
0801 rtems_interrupt_lock_release( &target_lock, &lock_context );
0802 }
0803
0804 static void aarch64_debug_break_load( void )
0805 {
0806 rtems_interrupt_lock_context lock_context;
0807 aarch64_debug_hwbreak *bp = &hw_breaks[ 0 ];
0808 int i;
0809
0810 rtems_interrupt_lock_acquire( &target_lock, &lock_context );
0811
0812 if ( bp->enabled && !bp->loaded ) {
0813 aarch64_debug_set_context_id( 0xdead1111 );
0814 aarch64_debug_break_write_value( 0, bp->value );
0815 aarch64_debug_break_write_control( 0, bp->control );
0816 }
0817
0818 ++bp;
0819
0820 for ( i = 1; i < hw_breakpoints; ++i, ++bp ) {
0821 if ( bp->enabled && !bp->loaded ) {
0822 bp->loaded = true;
0823 aarch64_debug_break_write_value( i, bp->value );
0824 aarch64_debug_break_write_control( i, bp->control );
0825 }
0826 }
0827
0828 rtems_interrupt_lock_release( &target_lock, &lock_context );
0829 }
0830
0831 static void aarch64_debug_break_unload( void )
0832 {
0833 rtems_interrupt_lock_context lock_context;
0834 aarch64_debug_hwbreak *bp = &hw_breaks[ 0 ];
0835 int i;
0836
0837 rtems_interrupt_lock_acquire( &target_lock, &lock_context );
0838 aarch64_debug_set_context_id( 0 );
0839
0840 for ( i = 0; i < hw_breakpoints; ++i, ++bp ) {
0841 bp->loaded = false;
0842 aarch64_debug_break_write_control( i, 0 );
0843 }
0844
0845 rtems_interrupt_lock_release( &target_lock, &lock_context );
0846 }
0847
0848 static void aarch64_debug_break_dump( void )
0849 {
0850 #if TARGET_DEBUG
0851 aarch64_debug_hwbreak *bp = &hw_breaks[ 0 ];
0852 int i;
0853
0854 for ( i = 0; i < hw_breakpoints; ++i, ++bp ) {
0855 if ( bp->enabled ) {
0856 target_printk(
0857 "[} bp: %d: control: %016" PRIx64 " addr: %016" PRIxPTR "\n",
0858 i,
0859 bp->control,
0860 (uintptr_t) bp->value
0861 );
0862 }
0863 }
0864
0865 #endif
0866 }
0867 #endif
0868
0869 static void aarch64_debug_disable_interrupts( void )
0870 {
0871 __asm__ volatile ( "msr DAIFSet, #0x2" );
0872 }
0873
0874 static void aarch64_debug_enable_interrupts( void )
0875 {
0876 __asm__ volatile ( "msr DAIFClr, #2\n" );
0877 }
0878
0879 static void aarch64_debug_disable_debug_exceptions( void )
0880 {
0881 __asm__ volatile ( "msr DAIFSet, #0x8" );
0882 }
0883
0884 static inline void aarch64_debug_set_context_id( const uint32_t id )
0885 {
0886 _AArch64_Write_contextidr_el1( id );
0887 }
0888
0889 int rtems_debugger_target_configure( rtems_debugger_target *target )
0890 {
0891 target->capabilities = ( RTEMS_DEBUGGER_TARGET_CAP_SWBREAK );
0892 target->reg_num = RTEMS_DEBUGGER_NUMREGS;
0893 target->reg_offset = aarch64_reg_offsets;
0894 target->breakpoint = &breakpoint[ 0 ];
0895 target->breakpoint_size = sizeof( breakpoint );
0896 return aarch64_debug_probe( target );
0897 }
0898
0899 static void target_print_frame( CPU_Exception_frame *frame )
0900 {
0901 EXC_FRAME_PRINT( target_printk, "[} ", frame );
0902 }
0903
0904
0905 static bool target_exception( CPU_Exception_frame *frame )
0906 {
0907 target_printk(
0908 "[} > frame = %016" PRIxPTR \
0909 " sig=%d" \
0910 " pra=%016" PRIxPTR "\n" \
0911 "[} > esr=%016" PRIx64 \
0912 " far=%016" PRIxPTR "\n",
0913 (uintptr_t) frame,
0914 rtems_debugger_target_exception_to_signal( frame ),
0915 (uintptr_t) frame->register_pc,
0916 (uint64_t) frame->register_syndrome,
0917 (uintptr_t) frame->register_fault_address
0918 );
0919
0920 target_print_frame( frame );
0921
0922 switch ( rtems_debugger_target_exception( frame ) ) {
0923 case rtems_debugger_target_exc_consumed:
0924 default:
0925 break;
0926 case rtems_debugger_target_exc_step:
0927 break;
0928 case rtems_debugger_target_exc_cascade:
0929 target_printk( "rtems-db: unhandled exception: cascading\n" );
0930
0931 return true;
0932 break;
0933 }
0934
0935 target_printk(
0936 "[} < resuming frame = %016" PRIxPTR "\n",
0937 (uintptr_t) frame
0938 );
0939 target_print_frame( frame );
0940
0941 #if TARGET_DEBUG
0942 uint64_t mdscr = _AArch64_Read_mdscr_el1();
0943 #endif
0944 target_printk(
0945 "[} global stepping: %s\n",
0946 mdscr & AARCH64_MDSCR_EL1_SS ? "yes" : "no"
0947 );
0948 target_printk(
0949 "[} kernel self-debug: %s\n",
0950 mdscr & AARCH64_MDSCR_EL1_KDE ? "yes" : "no"
0951 );
0952 target_printk(
0953 "[} non-step/non-BRK debug events: %s\n",
0954 mdscr & AARCH64_MDSCR_EL1_MDE ? "yes" : "no"
0955 );
0956 target_printk(
0957 "[} OSLSR(should be 0x8): 0x%016" PRIx64 "\n",
0958 _AArch64_Read_oslsr_el1()
0959 );
0960 #ifdef HARDWARE_BREAKPOINTS_NOT_USED
0961 aarch64_debug_break_dump();
0962 #endif
0963 return false;
0964 }
0965
0966 #define xstr( a ) str( a )
0967 #define str( a ) #a
0968 #define FRAME_SIZE_STR xstr( AARCH64_EXCEPTION_FRAME_SIZE )
0969
0970
0971
0972
0973
0974
0975
0976 #define SWITCH_STACKS_AND_ALLOC( new_mode, old_frame, jump_target ) \
0977 __asm__ volatile ( \
0978 "msr spsel, #" new_mode "\n" \
0979 "sub sp, sp, #" FRAME_SIZE_STR "\n" \
0980 "mov x0, sp\n" \
0981 "mov x1, %[old_frame]\n" \
0982 "b " #jump_target "\n" \
0983 : \
0984 : [ old_frame ] "r" ( old_frame ) \
0985 : "x0", "x1" )
0986
0987 #define SWITCH_STACKS_AND_ALLOC_WITH_CASCADE( new_mode, app_frame, \
0988 jump_target ) \
0989 __asm__ volatile ( \
0990 "msr spsel, #" new_mode "\n" \
0991 "sub sp, sp, #" FRAME_SIZE_STR "\n" \
0992 "mov x0, sp\n" \
0993 "mov x1, %[app_frame]\n" \
0994 "mov x2, %[needs_cascade]\n" \
0995 "b " #jump_target "\n" \
0996 : \
0997 : [ app_frame ] "r" ( app_frame ), \
0998 [ needs_cascade ] "r" ( needs_cascade ) \
0999 : "x0", "x1" )
1000
1001
1002
1003
1004
1005 #define DROP_OLD_FRAME( old_frame, old_mode, new_mode ) \
1006 __asm__ volatile ( \
1007 "msr spsel, #" old_mode "\n" \
1008 "mov sp, %0\n" \
1009 "add sp, sp, #" FRAME_SIZE_STR "\n" \
1010 "msr spsel, #" new_mode "\n" \
1011 : \
1012 : "r" ( old_frame ) ) \
1013
1014 #define THREAD_MODE "1"
1015 #define EXCEPTION_MODE "0"
1016
1017 void target_exception_stack_stage_3(
1018 CPU_Exception_frame *exc_frame,
1019 CPU_Exception_frame *app_frame,
1020 bool needs_cascade
1021 );
1022
1023 void target_exception_stack_stage_3(
1024 CPU_Exception_frame *exc_frame,
1025 CPU_Exception_frame *app_frame,
1026 bool needs_cascade
1027 )
1028 {
1029 _AArch64_Exception_frame_copy( exc_frame, app_frame );
1030 DROP_OLD_FRAME( app_frame, THREAD_MODE, EXCEPTION_MODE );
1031
1032 if ( needs_cascade ) {
1033
1034 _AArch64_Exception_default( exc_frame );
1035 }
1036
1037
1038 _CPU_Exception_resume( exc_frame );
1039 }
1040
1041 void target_exception_stack_stage_2(
1042 CPU_Exception_frame *app_frame,
1043 CPU_Exception_frame *exc_frame
1044 );
1045
1046 void target_exception_stack_stage_2(
1047 CPU_Exception_frame *app_frame,
1048 CPU_Exception_frame *exc_frame
1049 )
1050 {
1051 _AArch64_Exception_frame_copy( app_frame, exc_frame );
1052 DROP_OLD_FRAME( exc_frame, EXCEPTION_MODE, THREAD_MODE );
1053
1054 #ifdef HARDWARE_BREAKPOINTS_NOT_USED
1055 aarch64_debug_break_unload();
1056 #endif
1057
1058 aarch64_debug_enable_interrupts();
1059 bool needs_cascade = target_exception( app_frame );
1060
1061
1062 aarch64_debug_disable_interrupts();
1063
1064 #ifdef HARDWARE_BREAKPOINTS_NOT_USED
1065 aarch64_debug_break_load();
1066 #endif
1067 SWITCH_STACKS_AND_ALLOC_WITH_CASCADE(
1068 EXCEPTION_MODE,
1069 app_frame,
1070 target_exception_stack_stage_3
1071 );
1072 }
1073
1074
1075 static void target_exception_thread_stack( CPU_Exception_frame *old_frame )
1076 {
1077 SWITCH_STACKS_AND_ALLOC(
1078 THREAD_MODE,
1079 old_frame,
1080 target_exception_stack_stage_2
1081 );
1082 }
1083
1084 static void target_exception_application( CPU_Exception_frame *ef )
1085 {
1086
1087 if ( !debug_session_active ) {
1088
1089 _AArch64_Exception_default( ef );
1090 }
1091
1092
1093
1094
1095
1096 ef->register_cpsr |= AARCH64_DSPSR_EL0_D;
1097
1098
1099
1100
1101
1102
1103 if ( AARCH64_ESR_EL1_EC_GET( ef->register_syndrome ) == 0x26 ) {
1104 if ( target_exception( ef ) ) {
1105
1106 _AArch64_Exception_default( ef );
1107 }
1108
1109
1110 _CPU_Exception_resume( ef );
1111 }
1112
1113 target_exception_thread_stack( ef );
1114 }
1115
1116 static void target_exception_kernel( CPU_Exception_frame *ef )
1117 {
1118
1119
1120
1121
1122 if ( !debug_session_active ) {
1123
1124 _AArch64_Exception_default( ef );
1125 }
1126
1127
1128
1129
1130
1131 ef->register_cpsr |= AARCH64_DSPSR_EL0_D;
1132
1133 if ( target_exception( ef ) ) {
1134
1135 _AArch64_Exception_default( ef );
1136 }
1137
1138
1139 _CPU_Exception_resume( ef );
1140 }
1141
1142 static void rtems_debugger_target_set_vectors( void )
1143 {
1144
1145 AArch64_set_exception_handler(
1146 AARCH64_EXCEPTION_SPx_SYNCHRONOUS,
1147 (void *) target_exception_application
1148 );
1149 AArch64_set_exception_handler(
1150 AARCH64_EXCEPTION_SP0_SYNCHRONOUS,
1151 (void *) target_exception_kernel
1152 );
1153 }
1154
1155 static bool rtems_debugger_is_int_reg( size_t reg )
1156 {
1157 const size_t size = aarch64_reg_offsets[ reg + 1 ] -
1158 aarch64_reg_offsets[ reg ];
1159
1160 return size == RTEMS_DEBUGGER_REG_BYTES;
1161 }
1162
1163 static void rtems_debugger_set_int_reg(
1164 rtems_debugger_thread *thread,
1165 size_t reg,
1166 const uint64_t value
1167 )
1168 {
1169 const size_t offset = aarch64_reg_offsets[ reg ];
1170
1171 memcpy( &thread->registers[ offset ], &value, sizeof( uint64_t ) );
1172 }
1173
1174 static const uint64_t rtems_debugger_get_int_reg(
1175 rtems_debugger_thread *thread,
1176 size_t reg
1177 )
1178 {
1179 const size_t offset = aarch64_reg_offsets[ reg ];
1180 uint64_t value;
1181
1182 memcpy( &value, &thread->registers[ offset ], sizeof( uint64_t ) );
1183 return value;
1184 }
1185
1186 static void rtems_debugger_set_halfint_reg(
1187 rtems_debugger_thread *thread,
1188 size_t reg,
1189 const uint32_t value
1190 )
1191 {
1192 const size_t offset = aarch64_reg_offsets[ reg ];
1193
1194 memcpy( &thread->registers[ offset ], &value, sizeof( uint32_t ) );
1195 }
1196
1197 static const uint32_t rtems_debugger_get_halfint_reg(
1198 rtems_debugger_thread *thread,
1199 size_t reg
1200 )
1201 {
1202 const size_t offset = aarch64_reg_offsets[ reg ];
1203 uint32_t value;
1204
1205 memcpy( &value, &thread->registers[ offset ], sizeof( uint32_t ) );
1206 return value;
1207 }
1208
1209 static void rtems_debugger_set_fp_reg(
1210 rtems_debugger_thread *thread,
1211 size_t reg,
1212 const uint128_t value
1213 )
1214 {
1215 const size_t offset = aarch64_reg_offsets[ reg ];
1216
1217 memcpy( &thread->registers[ offset ], &value, sizeof( uint128_t ) );
1218 }
1219
1220 static const uint128_t rtems_debugger_get_fp_reg(
1221 rtems_debugger_thread *thread,
1222 size_t reg
1223 )
1224 {
1225 const size_t offset = aarch64_reg_offsets[ reg ];
1226 uint128_t value;
1227
1228 memcpy( &value, &thread->registers[ offset ], sizeof( uint128_t ) );
1229 return value;
1230 }
1231
1232 static rtems_status_code rtems_debugger_target_set_text_writable(
1233 bool writable
1234 )
1235 {
1236 uintptr_t start_begin = (uintptr_t) bsp_section_start_begin;
1237 uintptr_t start_end = (uintptr_t) bsp_section_start_end;
1238 uintptr_t text_begin = (uintptr_t) bsp_section_text_begin;
1239 uintptr_t text_end = (uintptr_t) bsp_section_text_end;
1240 uintptr_t fast_text_begin = (uintptr_t) bsp_section_fast_text_begin;
1241 uintptr_t fast_text_end = (uintptr_t) bsp_section_fast_text_end;
1242 uint64_t mmu_flags = AARCH64_MMU_CODE_RW_CACHED;
1243 rtems_status_code sc;
1244
1245 if ( !writable ) {
1246 mmu_flags = AARCH64_MMU_CODE_CACHED;
1247 }
1248
1249 target_printk(
1250 "[} MMU edit: start_begin: 0x%016" PRIxPTR
1251 " start_end: 0x%016" PRIxPTR "\n",
1252 start_begin,
1253 start_end
1254 );
1255 sc = aarch64_mmu_map(
1256 start_begin,
1257 start_end - start_begin,
1258 mmu_flags
1259 );
1260
1261 if ( sc != RTEMS_SUCCESSFUL ) {
1262 target_printk( "[} MMU edit failed\n" );
1263 return sc;
1264 }
1265
1266 target_printk(
1267 "[} MMU edit: text_begin: 0x%016" PRIxPTR
1268 " text_end: 0x%016" PRIxPTR "\n",
1269 text_begin,
1270 text_end
1271 );
1272 sc = aarch64_mmu_map(
1273 text_begin,
1274 text_end - text_begin,
1275 mmu_flags
1276 );
1277
1278 if ( sc != RTEMS_SUCCESSFUL ) {
1279 target_printk( "[} MMU edit failed\n" );
1280 return sc;
1281 }
1282
1283 target_printk(
1284 "[} MMU edit: fast_text_begin: 0x%016" PRIxPTR
1285 " fast_text_end: 0x%016" PRIxPTR "\n",
1286 fast_text_begin,
1287 fast_text_end
1288 );
1289 sc = aarch64_mmu_map(
1290 fast_text_begin,
1291 fast_text_end - fast_text_begin,
1292 mmu_flags
1293 );
1294
1295 if ( sc != RTEMS_SUCCESSFUL ) {
1296 target_printk( "[} MMU edit failed\n" );
1297 }
1298
1299 return sc;
1300 }
1301
1302 static rtems_task setup_debugger_on_cpu( rtems_task_argument arg )
1303 {
1304 rtems_status_code sc;
1305 rtems_status_code *init_error = (rtems_status_code *) arg;
1306 rtems_interrupt_lock_context lock_context;
1307
1308 rtems_interrupt_lock_acquire( &target_lock, &lock_context );
1309 sc = rtems_debugger_target_set_text_writable( true );
1310
1311 if ( sc != RTEMS_SUCCESSFUL ) {
1312 *init_error = sc;
1313 }
1314
1315 rtems_debugger_target_set_vectors();
1316
1317
1318 uint64_t mdscr = _AArch64_Read_mdscr_el1();
1319
1320 mdscr |= AARCH64_MDSCR_EL1_SS;
1321 mdscr |= AARCH64_MDSCR_EL1_KDE;
1322 mdscr |= AARCH64_MDSCR_EL1_MDE;
1323 _AArch64_Write_mdscr_el1( mdscr );
1324
1325
1326 _AArch64_Write_oslar_el1( 0 );
1327 rtems_interrupt_lock_release( &target_lock, &lock_context );
1328 }
1329
1330 int rtems_debugger_target_enable( void )
1331 {
1332 rtems_status_code sc;
1333 rtems_status_code init_error = RTEMS_SUCCESSFUL;
1334
1335 debug_session_active = true;
1336 #ifdef HARDWARE_BREAKPOINTS_NOT_USED
1337 aarch64_debug_break_unload();
1338 aarch64_debug_break_clear();
1339 #endif
1340 aarch64_debug_disable_debug_exceptions();
1341 sc = run_across_cpus(
1342 setup_debugger_on_cpu,
1343 ( rtems_task_argument ) & init_error
1344 );
1345
1346 if ( init_error != RTEMS_SUCCESSFUL ) {
1347 return init_error;
1348 }
1349
1350 return sc;
1351 }
1352
1353 static rtems_task teardown_debugger_on_cpu( rtems_task_argument arg )
1354 {
1355 rtems_status_code sc;
1356 rtems_status_code *deinit_error = (rtems_status_code *) arg;
1357 rtems_interrupt_lock_context lock_context;
1358
1359 rtems_interrupt_lock_acquire( &target_lock, &lock_context );
1360 sc = rtems_debugger_target_set_text_writable( false );
1361
1362 if ( sc != RTEMS_SUCCESSFUL ) {
1363 *deinit_error = sc;
1364 }
1365
1366
1367 uint64_t mdscr = _AArch64_Read_mdscr_el1();
1368
1369 mdscr &= ~AARCH64_MDSCR_EL1_SS;
1370 mdscr &= ~AARCH64_MDSCR_EL1_KDE;
1371 mdscr &= ~AARCH64_MDSCR_EL1_MDE;
1372 _AArch64_Write_mdscr_el1( mdscr );
1373
1374 rtems_interrupt_lock_release( &target_lock, &lock_context );
1375 }
1376
1377 int rtems_debugger_target_disable( void )
1378 {
1379 rtems_status_code sc;
1380 rtems_status_code deinit_error = RTEMS_SUCCESSFUL;
1381
1382 debug_session_active = false;
1383 #ifdef HARDWARE_BREAKPOINTS_NOT_USED
1384 aarch64_debug_break_unload();
1385 aarch64_debug_break_clear();
1386 #endif
1387 sc = run_across_cpus(
1388 teardown_debugger_on_cpu,
1389 ( rtems_task_argument ) & deinit_error
1390 );
1391
1392 if ( deinit_error != RTEMS_SUCCESSFUL ) {
1393 return deinit_error;
1394 }
1395
1396 return sc;
1397 }
1398
1399 int rtems_debugger_target_read_regs( rtems_debugger_thread *thread )
1400 {
1401 if (
1402 !rtems_debugger_thread_flag(
1403 thread,
1404 RTEMS_DEBUGGER_THREAD_FLAG_REG_VALID
1405 )
1406 ) {
1407 static const uintptr_t good_address = (uintptr_t) &good_address;
1408 int i;
1409
1410 memset( &thread->registers[ 0 ], 0, RTEMS_DEBUGGER_NUMREGBYTES );
1411
1412
1413 for ( i = 0; i < RTEMS_DEBUGGER_NUMREGS; ++i ) {
1414 if ( rtems_debugger_is_int_reg( i ) ) {
1415 rtems_debugger_set_int_reg( thread, i, (uintptr_t) &good_address );
1416 }
1417 }
1418
1419 if ( thread->frame ) {
1420 CPU_Exception_frame *frame = thread->frame;
1421
1422 *( (CPU_Exception_frame *) thread->registers ) = *frame;
1423 rtems_debugger_set_int_reg( thread, REG_X0, frame->register_x0 );
1424 rtems_debugger_set_int_reg( thread, REG_X1, frame->register_x1 );
1425 rtems_debugger_set_int_reg( thread, REG_X2, frame->register_x2 );
1426 rtems_debugger_set_int_reg( thread, REG_X3, frame->register_x3 );
1427 rtems_debugger_set_int_reg( thread, REG_X4, frame->register_x4 );
1428 rtems_debugger_set_int_reg( thread, REG_X5, frame->register_x5 );
1429 rtems_debugger_set_int_reg( thread, REG_X6, frame->register_x6 );
1430 rtems_debugger_set_int_reg( thread, REG_X7, frame->register_x7 );
1431 rtems_debugger_set_int_reg( thread, REG_X8, frame->register_x8 );
1432 rtems_debugger_set_int_reg( thread, REG_X9, frame->register_x9 );
1433 rtems_debugger_set_int_reg( thread, REG_X10, frame->register_x10 );
1434 rtems_debugger_set_int_reg( thread, REG_X11, frame->register_x11 );
1435 rtems_debugger_set_int_reg( thread, REG_X12, frame->register_x12 );
1436 rtems_debugger_set_int_reg( thread, REG_X13, frame->register_x13 );
1437 rtems_debugger_set_int_reg( thread, REG_X14, frame->register_x14 );
1438 rtems_debugger_set_int_reg( thread, REG_X15, frame->register_x15 );
1439 rtems_debugger_set_int_reg( thread, REG_X16, frame->register_x16 );
1440 rtems_debugger_set_int_reg( thread, REG_X17, frame->register_x17 );
1441 rtems_debugger_set_int_reg( thread, REG_X18, frame->register_x18 );
1442 rtems_debugger_set_int_reg( thread, REG_X19, frame->register_x19 );
1443 rtems_debugger_set_int_reg( thread, REG_X20, frame->register_x20 );
1444 rtems_debugger_set_int_reg( thread, REG_X21, frame->register_x21 );
1445 rtems_debugger_set_int_reg( thread, REG_X22, frame->register_x22 );
1446 rtems_debugger_set_int_reg( thread, REG_X23, frame->register_x23 );
1447 rtems_debugger_set_int_reg( thread, REG_X24, frame->register_x24 );
1448 rtems_debugger_set_int_reg( thread, REG_X25, frame->register_x25 );
1449 rtems_debugger_set_int_reg( thread, REG_X26, frame->register_x26 );
1450 rtems_debugger_set_int_reg( thread, REG_X27, frame->register_x27 );
1451 rtems_debugger_set_int_reg( thread, REG_X28, frame->register_x28 );
1452 rtems_debugger_set_int_reg( thread, REG_FP, frame->register_fp );
1453 rtems_debugger_set_int_reg(
1454 thread,
1455 REG_LR,
1456 (intptr_t) frame->register_lr
1457 );
1458 rtems_debugger_set_int_reg(
1459 thread,
1460 REG_SP,
1461 (intptr_t) frame->register_sp
1462 );
1463 rtems_debugger_set_int_reg(
1464 thread,
1465 REG_PC,
1466 (intptr_t) frame->register_pc
1467 );
1468
1469 rtems_debugger_set_halfint_reg(
1470 thread,
1471 REG_CPS,
1472 (uint32_t) frame->register_cpsr
1473 );
1474 rtems_debugger_set_fp_reg( thread, REG_V0, frame->register_q0 );
1475 rtems_debugger_set_fp_reg( thread, REG_V1, frame->register_q1 );
1476 rtems_debugger_set_fp_reg( thread, REG_V2, frame->register_q2 );
1477 rtems_debugger_set_fp_reg( thread, REG_V3, frame->register_q3 );
1478 rtems_debugger_set_fp_reg( thread, REG_V4, frame->register_q4 );
1479 rtems_debugger_set_fp_reg( thread, REG_V5, frame->register_q5 );
1480 rtems_debugger_set_fp_reg( thread, REG_V6, frame->register_q6 );
1481 rtems_debugger_set_fp_reg( thread, REG_V7, frame->register_q7 );
1482 rtems_debugger_set_fp_reg( thread, REG_V8, frame->register_q8 );
1483 rtems_debugger_set_fp_reg( thread, REG_V9, frame->register_q9 );
1484 rtems_debugger_set_fp_reg( thread, REG_V10, frame->register_q10 );
1485 rtems_debugger_set_fp_reg( thread, REG_V11, frame->register_q11 );
1486 rtems_debugger_set_fp_reg( thread, REG_V12, frame->register_q12 );
1487 rtems_debugger_set_fp_reg( thread, REG_V13, frame->register_q13 );
1488 rtems_debugger_set_fp_reg( thread, REG_V14, frame->register_q14 );
1489 rtems_debugger_set_fp_reg( thread, REG_V15, frame->register_q15 );
1490 rtems_debugger_set_fp_reg( thread, REG_V16, frame->register_q16 );
1491 rtems_debugger_set_fp_reg( thread, REG_V17, frame->register_q17 );
1492 rtems_debugger_set_fp_reg( thread, REG_V18, frame->register_q18 );
1493 rtems_debugger_set_fp_reg( thread, REG_V19, frame->register_q19 );
1494 rtems_debugger_set_fp_reg( thread, REG_V20, frame->register_q20 );
1495 rtems_debugger_set_fp_reg( thread, REG_V21, frame->register_q21 );
1496 rtems_debugger_set_fp_reg( thread, REG_V22, frame->register_q22 );
1497 rtems_debugger_set_fp_reg( thread, REG_V23, frame->register_q23 );
1498 rtems_debugger_set_fp_reg( thread, REG_V24, frame->register_q24 );
1499 rtems_debugger_set_fp_reg( thread, REG_V25, frame->register_q25 );
1500 rtems_debugger_set_fp_reg( thread, REG_V26, frame->register_q26 );
1501 rtems_debugger_set_fp_reg( thread, REG_V27, frame->register_q27 );
1502 rtems_debugger_set_fp_reg( thread, REG_V28, frame->register_q28 );
1503 rtems_debugger_set_fp_reg( thread, REG_V29, frame->register_q29 );
1504 rtems_debugger_set_fp_reg( thread, REG_V30, frame->register_q30 );
1505 rtems_debugger_set_fp_reg( thread, REG_V31, frame->register_q31 );
1506
1507 rtems_debugger_set_halfint_reg( thread, REG_FPS, frame->register_fpsr );
1508 rtems_debugger_set_halfint_reg( thread, REG_FPC, frame->register_fpcr );
1509
1510
1511
1512 thread->signal = rtems_debugger_target_exception_to_signal( frame );
1513 } else {
1514 rtems_debugger_set_int_reg(
1515 thread,
1516 REG_X19,
1517 thread->tcb->Registers.register_x19
1518 );
1519 rtems_debugger_set_int_reg(
1520 thread,
1521 REG_X20,
1522 thread->tcb->Registers.register_x20
1523 );
1524 rtems_debugger_set_int_reg(
1525 thread,
1526 REG_X21,
1527 thread->tcb->Registers.register_x21
1528 );
1529 rtems_debugger_set_int_reg(
1530 thread,
1531 REG_X22,
1532 thread->tcb->Registers.register_x22
1533 );
1534 rtems_debugger_set_int_reg(
1535 thread,
1536 REG_X23,
1537 thread->tcb->Registers.register_x23
1538 );
1539 rtems_debugger_set_int_reg(
1540 thread,
1541 REG_X24,
1542 thread->tcb->Registers.register_x24
1543 );
1544 rtems_debugger_set_int_reg(
1545 thread,
1546 REG_X25,
1547 thread->tcb->Registers.register_x25
1548 );
1549 rtems_debugger_set_int_reg(
1550 thread,
1551 REG_X26,
1552 thread->tcb->Registers.register_x26
1553 );
1554 rtems_debugger_set_int_reg(
1555 thread,
1556 REG_X27,
1557 thread->tcb->Registers.register_x27
1558 );
1559 rtems_debugger_set_int_reg(
1560 thread,
1561 REG_X28,
1562 thread->tcb->Registers.register_x28
1563 );
1564 rtems_debugger_set_int_reg(
1565 thread,
1566 REG_FP,
1567 thread->tcb->Registers.register_fp
1568 );
1569 rtems_debugger_set_int_reg(
1570 thread,
1571 REG_LR,
1572 (intptr_t) thread->tcb->Registers.register_lr
1573 );
1574 rtems_debugger_set_int_reg(
1575 thread,
1576 REG_SP,
1577 (intptr_t) thread->tcb->Registers.register_sp
1578 );
1579 rtems_debugger_set_int_reg(
1580 thread,
1581 REG_PC,
1582 (intptr_t) thread->tcb->Registers.register_lr
1583 );
1584 rtems_debugger_set_int_reg(
1585 thread,
1586 REG_V8,
1587 thread->tcb->Registers.register_d8
1588 );
1589 rtems_debugger_set_int_reg(
1590 thread,
1591 REG_V9,
1592 thread->tcb->Registers.register_d9
1593 );
1594 rtems_debugger_set_int_reg(
1595 thread,
1596 REG_V10,
1597 thread->tcb->Registers.register_d10
1598 );
1599 rtems_debugger_set_int_reg(
1600 thread,
1601 REG_V11,
1602 thread->tcb->Registers.register_d11
1603 );
1604 rtems_debugger_set_int_reg(
1605 thread,
1606 REG_V12,
1607 thread->tcb->Registers.register_d12
1608 );
1609 rtems_debugger_set_int_reg(
1610 thread,
1611 REG_V13,
1612 thread->tcb->Registers.register_d13
1613 );
1614 rtems_debugger_set_int_reg(
1615 thread,
1616 REG_V14,
1617 thread->tcb->Registers.register_d14
1618 );
1619 rtems_debugger_set_int_reg(
1620 thread,
1621 REG_V15,
1622 thread->tcb->Registers.register_d15
1623 );
1624
1625
1626
1627 thread->signal = 0;
1628 }
1629
1630 thread->flags |= RTEMS_DEBUGGER_THREAD_FLAG_REG_VALID;
1631 thread->flags &= ~RTEMS_DEBUGGER_THREAD_FLAG_REG_DIRTY;
1632 }
1633
1634 return 0;
1635 }
1636
1637 int rtems_debugger_target_write_regs( rtems_debugger_thread *thread )
1638 {
1639 if (
1640 rtems_debugger_thread_flag(
1641 thread,
1642 RTEMS_DEBUGGER_THREAD_FLAG_REG_DIRTY
1643 )
1644 ) {
1645
1646
1647
1648
1649 if (
1650 rtems_debugger_thread_flag(
1651 thread,
1652 RTEMS_DEBUGGER_THREAD_FLAG_EXCEPTION
1653 )
1654 ) {
1655 CPU_Exception_frame *frame = thread->frame;
1656 frame->register_x0 = rtems_debugger_get_int_reg( thread, REG_X0 );
1657 frame->register_x1 = rtems_debugger_get_int_reg( thread, REG_X1 );
1658 frame->register_x2 = rtems_debugger_get_int_reg( thread, REG_X2 );
1659 frame->register_x3 = rtems_debugger_get_int_reg( thread, REG_X3 );
1660 frame->register_x4 = rtems_debugger_get_int_reg( thread, REG_X4 );
1661 frame->register_x5 = rtems_debugger_get_int_reg( thread, REG_X5 );
1662 frame->register_x6 = rtems_debugger_get_int_reg( thread, REG_X6 );
1663 frame->register_x7 = rtems_debugger_get_int_reg( thread, REG_X7 );
1664 frame->register_x8 = rtems_debugger_get_int_reg( thread, REG_X8 );
1665 frame->register_x9 = rtems_debugger_get_int_reg( thread, REG_X9 );
1666 frame->register_x10 = rtems_debugger_get_int_reg( thread, REG_X10 );
1667 frame->register_x11 = rtems_debugger_get_int_reg( thread, REG_X11 );
1668 frame->register_x12 = rtems_debugger_get_int_reg( thread, REG_X12 );
1669 frame->register_x13 = rtems_debugger_get_int_reg( thread, REG_X13 );
1670 frame->register_x14 = rtems_debugger_get_int_reg( thread, REG_X14 );
1671 frame->register_x15 = rtems_debugger_get_int_reg( thread, REG_X15 );
1672 frame->register_x16 = rtems_debugger_get_int_reg( thread, REG_X16 );
1673 frame->register_x17 = rtems_debugger_get_int_reg( thread, REG_X17 );
1674 frame->register_x18 = rtems_debugger_get_int_reg( thread, REG_X18 );
1675 frame->register_x19 = rtems_debugger_get_int_reg( thread, REG_X19 );
1676 frame->register_x20 = rtems_debugger_get_int_reg( thread, REG_X20 );
1677 frame->register_x21 = rtems_debugger_get_int_reg( thread, REG_X21 );
1678 frame->register_x22 = rtems_debugger_get_int_reg( thread, REG_X22 );
1679 frame->register_x23 = rtems_debugger_get_int_reg( thread, REG_X23 );
1680 frame->register_x24 = rtems_debugger_get_int_reg( thread, REG_X24 );
1681 frame->register_x25 = rtems_debugger_get_int_reg( thread, REG_X25 );
1682 frame->register_x26 = rtems_debugger_get_int_reg( thread, REG_X26 );
1683 frame->register_x27 = rtems_debugger_get_int_reg( thread, REG_X27 );
1684 frame->register_x28 = rtems_debugger_get_int_reg( thread, REG_X28 );
1685 frame->register_fp = (uintptr_t) rtems_debugger_get_int_reg(
1686 thread,
1687 REG_FP
1688 );
1689 frame->register_lr = (void *) (uintptr_t) rtems_debugger_get_int_reg(
1690 thread,
1691 REG_LR
1692 );
1693 frame->register_sp = (uintptr_t) rtems_debugger_get_int_reg(
1694 thread,
1695 REG_SP
1696 );
1697 frame->register_pc = (void *) (uintptr_t) rtems_debugger_get_int_reg(
1698 thread,
1699 REG_PC
1700 );
1701 frame->register_cpsr = rtems_debugger_get_halfint_reg( thread, REG_CPS );
1702 frame->register_q0 = rtems_debugger_get_fp_reg( thread, REG_V0 );
1703 frame->register_q1 = rtems_debugger_get_fp_reg( thread, REG_V1 );
1704 frame->register_q2 = rtems_debugger_get_fp_reg( thread, REG_V2 );
1705 frame->register_q3 = rtems_debugger_get_fp_reg( thread, REG_V3 );
1706 frame->register_q4 = rtems_debugger_get_fp_reg( thread, REG_V4 );
1707 frame->register_q5 = rtems_debugger_get_fp_reg( thread, REG_V5 );
1708 frame->register_q6 = rtems_debugger_get_fp_reg( thread, REG_V6 );
1709 frame->register_q7 = rtems_debugger_get_fp_reg( thread, REG_V7 );
1710 frame->register_q8 = rtems_debugger_get_fp_reg( thread, REG_V8 );
1711 frame->register_q9 = rtems_debugger_get_fp_reg( thread, REG_V9 );
1712 frame->register_q10 = rtems_debugger_get_fp_reg( thread, REG_V10 );
1713 frame->register_q11 = rtems_debugger_get_fp_reg( thread, REG_V11 );
1714 frame->register_q12 = rtems_debugger_get_fp_reg( thread, REG_V12 );
1715 frame->register_q13 = rtems_debugger_get_fp_reg( thread, REG_V13 );
1716 frame->register_q14 = rtems_debugger_get_fp_reg( thread, REG_V14 );
1717 frame->register_q15 = rtems_debugger_get_fp_reg( thread, REG_V15 );
1718 frame->register_q16 = rtems_debugger_get_fp_reg( thread, REG_V16 );
1719 frame->register_q17 = rtems_debugger_get_fp_reg( thread, REG_V17 );
1720 frame->register_q18 = rtems_debugger_get_fp_reg( thread, REG_V18 );
1721 frame->register_q19 = rtems_debugger_get_fp_reg( thread, REG_V19 );
1722 frame->register_q20 = rtems_debugger_get_fp_reg( thread, REG_V20 );
1723 frame->register_q21 = rtems_debugger_get_fp_reg( thread, REG_V21 );
1724 frame->register_q22 = rtems_debugger_get_fp_reg( thread, REG_V22 );
1725 frame->register_q23 = rtems_debugger_get_fp_reg( thread, REG_V23 );
1726 frame->register_q24 = rtems_debugger_get_fp_reg( thread, REG_V24 );
1727 frame->register_q25 = rtems_debugger_get_fp_reg( thread, REG_V25 );
1728 frame->register_q26 = rtems_debugger_get_fp_reg( thread, REG_V26 );
1729 frame->register_q27 = rtems_debugger_get_fp_reg( thread, REG_V27 );
1730 frame->register_q28 = rtems_debugger_get_fp_reg( thread, REG_V28 );
1731 frame->register_q29 = rtems_debugger_get_fp_reg( thread, REG_V29 );
1732 frame->register_q30 = rtems_debugger_get_fp_reg( thread, REG_V30 );
1733 frame->register_q31 = rtems_debugger_get_fp_reg( thread, REG_V31 );
1734 frame->register_fpsr = rtems_debugger_get_halfint_reg( thread, REG_FPS );
1735 frame->register_fpcr = rtems_debugger_get_halfint_reg( thread, REG_FPC );
1736 }
1737
1738 thread->flags &= ~RTEMS_DEBUGGER_THREAD_FLAG_REG_DIRTY;
1739 }
1740
1741 return 0;
1742 }
1743
1744 uintptr_t rtems_debugger_target_reg_pc( rtems_debugger_thread *thread )
1745 {
1746 int r;
1747
1748 r = rtems_debugger_target_read_regs( thread );
1749
1750 if ( r >= 0 ) {
1751 return rtems_debugger_get_int_reg( thread, REG_PC );
1752 }
1753
1754 return 0;
1755 }
1756
1757 uintptr_t rtems_debugger_target_frame_pc( CPU_Exception_frame *frame )
1758 {
1759 return (uintptr_t) frame->register_pc;
1760 }
1761
1762 uintptr_t rtems_debugger_target_reg_sp( rtems_debugger_thread *thread )
1763 {
1764 int r;
1765
1766 r = rtems_debugger_target_read_regs( thread );
1767
1768 if ( r >= 0 ) {
1769 return rtems_debugger_get_int_reg( thread, REG_SP );
1770 }
1771
1772 return 0;
1773 }
1774
1775 uintptr_t rtems_debugger_target_tcb_sp( rtems_debugger_thread *thread )
1776 {
1777 return (uintptr_t) thread->tcb->Registers.register_sp;
1778 }
1779
1780 int rtems_debugger_target_thread_stepping( rtems_debugger_thread *thread )
1781 {
1782 CPU_Exception_frame *frame = thread->frame;
1783
1784 if ( rtems_debugger_thread_flag(
1785 thread,
1786 RTEMS_DEBUGGER_THREAD_FLAG_STEP_INSTR
1787 ) ) {
1788
1789 if ( frame == NULL ) {
1790 return -1;
1791 }
1792
1793
1794
1795
1796
1797
1798
1799 uint64_t stepping_enabled =
1800 !( frame->register_cpsr & AARCH64_DSPSR_EL0_D );
1801
1802 target_printk( "[} stepping: %s\n", stepping_enabled ? "yes" : "no" );
1803
1804
1805
1806
1807
1808
1809
1810 frame->register_cpsr |= AARCH64_DSPSR_EL0_SS;
1811
1812 if ( !stepping_enabled ) {
1813
1814
1815
1816
1817
1818
1819 frame->register_cpsr &= ~AARCH64_DSPSR_EL0_D;
1820 }
1821 }
1822
1823 return 0;
1824 }
1825
1826 int rtems_debugger_target_exception_to_signal( CPU_Exception_frame *frame )
1827 {
1828 uint64_t EC = AARCH64_ESR_EL1_EC_GET( frame->register_syndrome );
1829
1830 switch ( EC ) {
1831 case 0x1:
1832 case 0x7:
1833 case 0xa:
1834 case 0x15:
1835 case 0x18:
1836 case 0x19:
1837 case 0x31:
1838 case 0x33:
1839 case 0x35:
1840 case 0x3c:
1841 return RTEMS_DEBUGGER_SIGNAL_TRAP;
1842
1843 case 0x2c:
1844 return RTEMS_DEBUGGER_SIGNAL_FPE;
1845
1846 case 0x21:
1847 case 0x25:
1848 return RTEMS_DEBUGGER_SIGNAL_SEGV;
1849
1850 default:
1851
1852
1853
1854
1855 return RTEMS_DEBUGGER_SIGNAL_ILL;
1856 }
1857 }
1858
1859 void rtems_debugger_target_exception_print( CPU_Exception_frame *frame )
1860 {
1861 EXC_FRAME_PRINT( rtems_debugger_printf, "", frame );
1862 }
1863
1864 int rtems_debugger_target_hwbreak_insert( void )
1865 {
1866
1867
1868
1869 return 0;
1870 }
1871
1872 int rtems_debugger_target_hwbreak_remove( void )
1873 {
1874 #ifdef HARDWARE_BREAKPOINTS_NOT_USED
1875 aarch64_debug_break_unload();
1876 #endif
1877 return 0;
1878 }
1879
1880 int rtems_debugger_target_hwbreak_control(
1881 rtems_debugger_target_watchpoint wp,
1882 bool insert,
1883 uintptr_t addr,
1884 DB_UINT kind
1885 )
1886 {
1887
1888 return 0;
1889 }
1890
1891 int rtems_debugger_target_cache_sync( rtems_debugger_target_swbreak *swbreak )
1892 {
1893
1894
1895
1896 rtems_cache_flush_multiple_data_lines(
1897 swbreak->address,
1898 sizeof( breakpoint )
1899 );
1900 rtems_cache_instruction_sync_after_code_change(
1901 swbreak->address,
1902 sizeof( breakpoint )
1903 );
1904 return 0;
1905 }