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 #include <rtems.h>
0038 #include <rtems/score/threadimpl.h>
0039
0040 #include "rtems-debugger-target.h"
0041 #include "rtems-debugger-threads.h"
0042
0043 #include <rtems/powerpc/registers.h>
0044
0045
0046
0047
0048 #define RTEMS_DEBUGGER_HWBREAK_NUM 4
0049
0050
0051
0052
0053 #define RTEMS_DEBUGGER_NUMREGS 72
0054
0055
0056
0057
0058 #define REG_R0 0
0059 #define REG_R1 1
0060 #define REG_R2 2
0061 #define REG_R3 3
0062 #define REG_R4 4
0063 #define REG_R5 5
0064 #define REG_R6 6
0065 #define REG_R7 7
0066 #define REG_R8 8
0067 #define REG_R9 9
0068 #define REG_R10 10
0069 #define REG_R11 11
0070 #define REG_R12 12
0071 #define REG_R13 13
0072 #define REG_R14 14
0073 #define REG_R15 15
0074 #define REG_R16 16
0075 #define REG_R17 17
0076 #define REG_R18 18
0077 #define REG_R19 19
0078 #define REG_R20 20
0079 #define REG_R21 21
0080 #define REG_R22 22
0081 #define REG_R23 23
0082 #define REG_R24 24
0083 #define REG_R25 25
0084 #define REG_R26 26
0085 #define REG_R27 27
0086 #define REG_R28 28
0087 #define REG_R29 29
0088 #define REG_R30 30
0089 #define REG_R31 31
0090 #define REG_F0 32
0091 #define REG_F1 33
0092 #define REG_F2 34
0093 #define REG_F3 35
0094 #define REG_F4 36
0095 #define REG_F5 37
0096 #define REG_F6 38
0097 #define REG_F7 39
0098 #define REG_F8 40
0099 #define REG_F9 41
0100 #define REG_F10 42
0101 #define REG_F11 43
0102 #define REG_F12 44
0103 #define REG_F13 45
0104 #define REG_F14 46
0105 #define REG_F15 47
0106 #define REG_F16 48
0107 #define REG_F17 49
0108 #define REG_F18 50
0109 #define REG_F19 51
0110 #define REG_F20 52
0111 #define REG_F21 53
0112 #define REG_F22 54
0113 #define REG_F23 55
0114 #define REG_F24 56
0115 #define REG_F25 57
0116 #define REG_F26 58
0117 #define REG_F27 59
0118 #define REG_F28 60
0119 #define REG_F29 61
0120 #define REG_F30 62
0121 #define REG_F31 63
0122 #define REG_PC 64
0123 #define REG_MSR 65
0124 #define REG_CND 66
0125 #define REG_LR 67
0126 #define REG_CNT 68
0127 #define REG_XER 69
0128 #define REG_ACC 70
0129 #define REG_SPEFSCR 71
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149 static const size_t ppc_common_reg_offsets[RTEMS_DEBUGGER_NUMREGS + 1] =
0150 {
0151 0,
0152 4,
0153 8,
0154 12,
0155 16,
0156 20,
0157 24,
0158 28,
0159 32,
0160 36,
0161 40,
0162 44,
0163 48,
0164 52,
0165 56,
0166 60,
0167 64,
0168 68,
0169 72,
0170 76,
0171 80,
0172 84,
0173 88,
0174 92,
0175 96,
0176 100,
0177 104,
0178 108,
0179 112,
0180 116,
0181 120,
0182 124,
0183 128,
0184 136,
0185 144,
0186 152,
0187 160,
0188 168,
0189 176,
0190 184,
0191 192,
0192 200,
0193 208,
0194 216,
0195 224,
0196 232,
0197 240,
0198 248,
0199 256,
0200 264,
0201 272,
0202 280,
0203 288,
0204 296,
0205 304,
0206 312,
0207 320,
0208 328,
0209 336,
0210 344,
0211 352,
0212 360,
0213 368,
0214 376,
0215 384,
0216 388,
0217 392,
0218 396,
0219 400,
0220 404,
0221 408,
0222 408,
0223 412
0224 };
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240 static const size_t ppc_e500_reg_offsets[RTEMS_DEBUGGER_NUMREGS + 1] =
0241 {
0242 0,
0243 4,
0244 8,
0245 12,
0246 16,
0247 20,
0248 24,
0249 28,
0250 32,
0251 36,
0252 40,
0253 44,
0254 48,
0255 52,
0256 56,
0257 60,
0258 64,
0259 68,
0260 72,
0261 76,
0262 80,
0263 84,
0264 88,
0265 92,
0266 96,
0267 100,
0268 104,
0269 108,
0270 112,
0271 116,
0272 120,
0273 124,
0274 128,
0275 132,
0276 136,
0277 140,
0278 144,
0279 148,
0280 152,
0281 156,
0282 160,
0283 164,
0284 168,
0285 172,
0286 176,
0287 180,
0288 184,
0289 188,
0290 192,
0291 196,
0292 200,
0293 204,
0294 208,
0295 212,
0296 216,
0297 220,
0298 224,
0299 228,
0300 232,
0301 236,
0302 240,
0303 244,
0304 248,
0305 252,
0306 256,
0307 260,
0308 264,
0309 268,
0310 272,
0311 276,
0312 280,
0313 288,
0314 292
0315 };
0316
0317 static const size_t* ppc_reg_offsets;
0318
0319
0320
0321
0322 #define RTEMS_DEBUGGER_NUMREGBYTES ppc_reg_offsets[RTEMS_DEBUGGER_NUMREGS]
0323
0324
0325
0326
0327 typedef CPU_Exception_frame BSP_Exception_frame;
0328 typedef void (*exception_handler_t)(BSP_Exception_frame*);
0329 extern exception_handler_t globalExceptHdl;
0330
0331
0332
0333
0334 #define TARGET_BKPT 0x0ce00000
0335 static const uint8_t breakpoint[4] = { 0x0c, 0xe0, 0x00, 0x00 };
0336
0337
0338
0339
0340 RTEMS_INTERRUPT_LOCK_DEFINE(static, target_lock, "target_lock")
0341
0342
0343
0344
0345 static void (*orig_currentExcHandler)(CPU_Exception_frame* frame);
0346
0347 #if TARGET_DEBUG
0348 #include <rtems/bspIo.h>
0349 static void target_printk(const char* format, ...) RTEMS_PRINTFLIKE(1, 2);
0350 static void
0351 target_printk(const char* format, ...)
0352 {
0353 va_list ap;
0354 va_start(ap, format);
0355 vprintk(format, ap);
0356 va_end(ap);
0357 }
0358 #else
0359 #define target_printk(_fmt, ...)
0360 #endif
0361
0362
0363
0364
0365
0366
0367 #define ASM_RESET_VECTOR 0x01
0368 #define ASM_MACH_VECTOR 0x02
0369 #define ASM_PROT_VECTOR 0x03
0370 #define ASM_ISI_VECTOR 0x04
0371 #define ASM_EXT_VECTOR 0x05
0372 #define ASM_ALIGN_VECTOR 0x06
0373 #define ASM_PROG_VECTOR 0x07
0374 #define ASM_FLOAT_VECTOR 0x08
0375 #define ASM_DEC_VECTOR 0x09
0376 #define ASM_SYS_VECTOR 0x0C
0377 #define ASM_TRACE_VECTOR 0x0D
0378
0379 #define ASM_60X_VEC_VECTOR 0x0A
0380 #define ASM_60X_PERFMON_VECTOR 0x0F
0381 #define ASM_60X_IMISS_VECTOR 0x10
0382 #define ASM_60X_DLMISS_VECTOR 0x11
0383 #define ASM_60X_DSMISS_VECTOR 0x12
0384 #define ASM_60X_ADDR_VECTOR 0x13
0385 #define ASM_60X_SYSMGMT_VECTOR 0x14
0386 #define ASM_60X_VEC_ASSIST_VECTOR 0x16
0387 #define ASM_60X_ITM_VECTOR 0x17
0388
0389 #define LAST_VALID_EXC 0x1F
0390
0391 typedef enum
0392 {
0393 PPC_601 = 0x1,
0394 PPC_5XX = 0x2,
0395 PPC_603 = 0x3,
0396 PPC_604 = 0x4,
0397 PPC_603e = 0x6,
0398 PPC_603ev = 0x7,
0399 PPC_750 = 0x8,
0400 PPC_750_IBM = 0x7000,
0401 PPC_604e = 0x9,
0402 PPC_604r = 0xA,
0403 PPC_7400 = 0xC,
0404 PPC_405 = 0x2001,
0405 PPC_405EX = 0x1291,
0406 PPC_405GP = 0x4011,
0407 PPC_405GPr = 0x5091,
0408 PPC_405EZ = 0x4151,
0409 PPC_405EP = 0x5121,
0410 PPC_440 = 0x7ff2,
0411 PPC_7455 = 0x8001,
0412 PPC_7457 = 0x8002,
0413 PPC_620 = 0x16,
0414 PPC_860 = 0x50,
0415 PPC_821 = PPC_860,
0416 PPC_823 = PPC_860,
0417 PPC_8260 = 0x81,
0418 PPC_8240 = PPC_8260,
0419 PPC_8245 = 0x8081,
0420 PPC_8540 = 0x8020,
0421 PPC_e500v2 = 0x8021,
0422 PPC_e6500 = 0x8040,
0423 PPC_603le = 0x8082,
0424 PPC_e300c1 = 0x8083,
0425 PPC_e300c2 = 0x8084,
0426 PPC_e300c3 = 0x8085,
0427 PPC_e200z0 = 0x8170,
0428 PPC_e200z1 = 0x8140,
0429 PPC_e200z4 = 0x8150,
0430 PPC_e200z6 = 0x8110,
0431 PPC_e200z7 = 0x8160,
0432 PPC_PSIM = 0xfffe,
0433 PPC_UNKNOWN = 0xffff
0434 } ppc_cpu_id;
0435
0436 #define PPC_BOOKE_405 1
0437 #define PPC_BOOKE_STD 2
0438 #define PPC_BOOKE_E500 3
0439
0440 typedef struct {
0441 volatile bool type_1_complete;
0442 volatile uint32_t msr;
0443 } powerpc_stepping;
0444
0445 static ppc_cpu_id ppc_cpu;
0446 static int is_bookE;
0447 static powerpc_stepping stepping_instr;
0448
0449 #define xppc_read_spr(reg, val) \
0450 __asm__ __volatile__("mfspr %0,"#reg : "=r" (val))
0451 #define xppc_write_spr(reg, val) \
0452 __asm__ __volatile__("mtspr "#reg",%0" : : "r" (val))
0453 #define ppc_read_spr(reg, val) xppc_read_spr(reg, val)
0454 #define ppc_write_spr(reg, val) xppc_write_spr(reg, val)
0455
0456 static const char *ppc_get_cpu_type_name(ppc_cpu_id cpu)
0457 {
0458 switch (cpu) {
0459 case PPC_405: return "PPC405";
0460 case PPC_405GP: return "PPC405GP";
0461 case PPC_405EX: return "PPC405EX";
0462 case PPC_440: return "PPC440";
0463 case PPC_601: return "MPC601";
0464 case PPC_5XX: return "MPC5XX";
0465 case PPC_603: return "MPC603";
0466 case PPC_603ev: return "MPC603ev";
0467 case PPC_604: return "MPC604";
0468 case PPC_750: return "MPC750";
0469 case PPC_750_IBM: return "IBM PPC750";
0470 case PPC_7400: return "MPC7400";
0471 case PPC_7455: return "MPC7455";
0472 case PPC_7457: return "MPC7457";
0473 case PPC_603le: return "MPC603le";
0474 case PPC_604e: return "MPC604e";
0475 case PPC_604r: return "MPC604r";
0476 case PPC_620: return "MPC620";
0477 case PPC_860: return "MPC860";
0478 case PPC_8260: return "MPC8260";
0479 case PPC_8245: return "MPC8245";
0480 case PPC_8540: return "MPC8540";
0481 case PPC_PSIM: return "PSIM";
0482 case PPC_e200z0: return "e200z0";
0483 case PPC_e200z1: return "e200z1";
0484 case PPC_e200z4: return "e200z4";
0485 case PPC_e200z6: return "e200z6";
0486 case PPC_e200z7: return "e200z7";
0487 case PPC_e500v2: return "e500v2";
0488 case PPC_e6500: return "e6500";
0489 default:
0490 break;
0491 }
0492 return "unknown";
0493 }
0494
0495 static bool ppc_is_bookE(void)
0496 {
0497 return is_bookE != 0;
0498 }
0499
0500 static bool ppc_is_bookE_405(void)
0501 {
0502 return is_bookE == PPC_BOOKE_405;
0503 }
0504
0505 static int ppc_probe_cpu_type(void)
0506 {
0507
0508
0509
0510
0511 const uint32_t ppc_cpu_id_version_nibble[] = {
0512 PPC_e200z0,
0513 PPC_e200z1,
0514 PPC_e200z4,
0515 PPC_e200z6,
0516 PPC_e200z7
0517 };
0518 #define NUM_CPU_ID_VERSION \
0519 (sizeof(ppc_cpu_id_version_nibble) / sizeof(ppc_cpu_id_version_nibble[0]))
0520
0521 uint32_t pvr;
0522 int i;
0523
0524 ppc_read_spr(PPC_PVR, pvr);
0525 pvr >>= 16;
0526
0527
0528
0529
0530 for (i = 0; i < NUM_CPU_ID_VERSION; ++i) {
0531 if ((pvr & 0xfff0) == (ppc_cpu_id_version_nibble[i] & 0xfff0)) {
0532 pvr = ppc_cpu_id_version_nibble[i];
0533 break;
0534 }
0535 }
0536
0537 ppc_cpu = (ppc_cpu_id) pvr;
0538
0539 switch (pvr) {
0540 case PPC_405:
0541 case PPC_405GP:
0542 case PPC_405EX:
0543 case PPC_440:
0544 case PPC_601:
0545 case PPC_5XX:
0546 case PPC_603:
0547 case PPC_603ev:
0548 case PPC_603le:
0549 case PPC_604:
0550 case PPC_604r:
0551 case PPC_750:
0552 case PPC_750_IBM:
0553 case PPC_7400:
0554 case PPC_7455:
0555 case PPC_7457:
0556 case PPC_604e:
0557 case PPC_620:
0558 case PPC_860:
0559 case PPC_8260:
0560 case PPC_8245:
0561 case PPC_PSIM:
0562 case PPC_8540:
0563 case PPC_e200z0:
0564 case PPC_e200z1:
0565 case PPC_e200z4:
0566 case PPC_e200z6:
0567 case PPC_e200z7:
0568 case PPC_e300c1:
0569 case PPC_e300c2:
0570 case PPC_e300c3:
0571 case PPC_e500v2:
0572 case PPC_e6500:
0573 break;
0574 default:
0575 rtems_debugger_printf("rtems-db: powerpc: unknown CPU\n");
0576 return -1;
0577 }
0578
0579 switch (ppc_cpu) {
0580 case PPC_405:
0581 case PPC_405GP:
0582 case PPC_405EX:
0583 is_bookE = PPC_BOOKE_405;
0584 break;
0585 case PPC_440:
0586 is_bookE = PPC_BOOKE_STD;
0587 break;
0588 case PPC_8540:
0589 case PPC_e200z0:
0590 case PPC_e200z1:
0591 case PPC_e200z4:
0592 case PPC_e200z6:
0593 case PPC_e200z7:
0594 case PPC_e500v2:
0595 case PPC_e6500:
0596 is_bookE = PPC_BOOKE_E500;
0597 break;
0598 default:
0599 break;
0600 }
0601
0602 rtems_debugger_printf("rtems-db: powerpc: %s %s\n",
0603 ppc_get_cpu_type_name(ppc_cpu),
0604 ppc_is_bookE() ? "(book E)" : "");
0605
0606 return 0;
0607 }
0608
0609 static void ppc_set_dbsr(uint32_t dbsr)
0610 {
0611 if (ppc_is_bookE()) {
0612 if (ppc_is_bookE_405()) {
0613 ppc_write_spr(0x3f0, dbsr);
0614 } else {
0615 ppc_write_spr(BOOKE_DBSR, dbsr);
0616 }
0617 }
0618 }
0619
0620 static void ppc_set_dbcr0(uint32_t dbcr)
0621 {
0622 if (ppc_is_bookE()) {
0623 if (ppc_is_bookE_405()) {
0624 ppc_write_spr(0x3f2, dbcr);
0625 } else {
0626 ppc_write_spr(BOOKE_DBCR0, dbcr);
0627 }
0628 }
0629 }
0630
0631 static int ppc_debug_probe(rtems_debugger_target* target)
0632 {
0633 if (ppc_probe_cpu_type() != 0) {
0634 return -1;
0635 }
0636 ppc_set_dbsr(0xffffffffUL);
0637 ppc_set_dbcr0(0);
0638 return 0;
0639 }
0640
0641 static int ppc_code_writer(void* address, const void* data, size_t size) {
0642 uint32_t current_level;
0643 uint32_t addr;
0644 uint32_t val;
0645 addr = (uint32_t) (intptr_t) address;
0646 val = *((uint32_t*) data);
0647 target_printk("[] powerpc: code_ writer: %08x -> %p size=%zu\n", val, address, size);
0648 if (size != 4) {
0649 rtems_debugger_printf("rtems-db: powerpc: invalid code write size: size=%zu\n", size);
0650 return -1;
0651 }
0652
0653
0654
0655
0656
0657
0658
0659
0660
0661
0662
0663 current_level = ppc_interrupt_disable();
0664 asm volatile(
0665 " mfmsr 0 \n"
0666 " andc 7,0,%0 \n"
0667 " mtmsr 7 \n"
0668 " isync \n"
0669 " stw %2,0(%1) \n"
0670 " dcbst 0,%1 \n"
0671 " icbi 0,%1 \n"
0672 " mtmsr 0 \n"
0673 " sync \n"
0674 " isync \n"
0675
0676
0677
0678 ::"r"(ppc_is_bookE() ? 0 : MSR_DR), "b"(addr), "r"(val), "r"(current_level)
0679 :"r0","r7");
0680 ppc_interrupt_enable(current_level);
0681 return 0;
0682 }
0683
0684 int
0685 rtems_debugger_target_configure(rtems_debugger_target* target)
0686 {
0687 if (is_bookE) {
0688 ppc_reg_offsets = ppc_e500_reg_offsets;
0689 } else {
0690 ppc_reg_offsets = ppc_common_reg_offsets;
0691 }
0692 target->capabilities = (RTEMS_DEBUGGER_TARGET_CAP_SWBREAK);
0693 target->reg_num = RTEMS_DEBUGGER_NUMREGS;
0694 target->reg_offset = ppc_reg_offsets;
0695 target->breakpoint = &breakpoint[0];
0696 target->breakpoint_size = sizeof(breakpoint);
0697 target->code_writer = ppc_code_writer;
0698 return ppc_debug_probe(target);
0699 }
0700
0701 static void powerpc_print_exception_frame(CPU_Exception_frame* frame) {
0702 uintptr_t* gpr;
0703 int r;
0704 target_printk("[} frame = %08" PRIx32 " sig=%d (0x%" PRIx32 ")\n",
0705 (uint32_t) frame,
0706 rtems_debugger_target_exception_to_signal(frame),
0707 frame->_EXC_number);
0708 #ifndef __SPE__
0709 target_printk("[} SRR0 = %08" PRIx32 " SRR1 = %08" PRIx32 "\n",
0710 frame->EXC_SRR0, frame->EXC_SRR1);
0711 #else
0712 target_printk("[} SRR0 = %08" PRIx32 " SRR1 = %08" PRIx32 \
0713 " SPEFSCR = %08" PRIx32 " ACC = %08" PRIx32 "\n",
0714 frame->EXC_SRR0, frame->EXC_SRR1,
0715 frame->EXC_SPEFSCR, frame->EXC_ACC);
0716 #endif
0717 target_printk("[} LR = %08" PRIx32 " CR = %08" PRIx32 \
0718 " XER = %08" PRIx32 " CTR = %08" PRIx32 "\n",
0719 frame->EXC_LR, frame->EXC_CR, frame->EXC_XER, frame->EXC_CTR);
0720 gpr = &frame->GPR0;
0721 for (r= 0; r < 32; r += 4, gpr += 4) {
0722 target_printk("[} R%-2d = %08" PRIx32 " R%-2d = %08" PRIx32 \
0723 " R%-2d = %08" PRIx32 " R%-2d = %08" PRIx32 "\n",
0724 r, *gpr, r + 1, *(gpr + 1), r + 2,
0725 *(gpr + 2), r + 3, *(gpr + 3));
0726 }
0727 }
0728
0729
0730
0731
0732
0733
0734
0735
0736
0737
0738
0739
0740
0741
0742
0743
0744
0745
0746
0747
0748
0749
0750
0751 static bool
0752 powerpc_stepping_exception(CPU_Exception_frame* frame)
0753 {
0754 bool r = false;
0755 frame->EXC_SRR1 &= ~MSR_SE;
0756 switch (frame->_EXC_number) {
0757 default:
0758 stepping_instr.type_1_complete = false;
0759 break;
0760 case ASM_TRACE_VECTOR:
0761 if (stepping_instr.type_1_complete) {
0762
0763
0764
0765 stepping_instr.type_1_complete = false;
0766 frame->EXC_SRR1 |= stepping_instr.msr;
0767 } else {
0768 stepping_instr.type_1_complete = true;
0769 frame->EXC_SRR1 &= ~ppc_interrupt_get_disable_mask();
0770 frame->EXC_SRR1 |= MSR_SE;
0771 r = true;
0772 }
0773 break;
0774 case ASM_PROG_VECTOR:
0775
0776
0777
0778 break;
0779 }
0780 return r;
0781 }
0782
0783 static void
0784 powerpc_stepping_frame(CPU_Exception_frame* frame)
0785 {
0786 if (ppc_is_bookE()) {
0787 stepping_instr.type_1_complete = false;
0788 } else {
0789 stepping_instr.type_1_complete = true;
0790 }
0791 stepping_instr.msr =
0792 frame->EXC_SRR1 & ppc_interrupt_get_disable_mask();;
0793 frame->EXC_SRR1 &= ~ppc_interrupt_get_disable_mask();
0794 frame->EXC_SRR1 |= MSR_SE;
0795 }
0796
0797 static void
0798 target_exception(BSP_Exception_frame* bsp_frame)
0799 {
0800 CPU_Exception_frame* frame = bsp_frame;
0801
0802 target_printk("[} powerpc target exc: entry\n");
0803 powerpc_print_exception_frame(frame);
0804
0805 if (!powerpc_stepping_exception(bsp_frame)) {
0806 switch (rtems_debugger_target_exception(frame)) {
0807 case rtems_debugger_target_exc_consumed:
0808 default:
0809 break;
0810 case rtems_debugger_target_exc_step:
0811 powerpc_stepping_frame(frame);
0812 break;
0813 case rtems_debugger_target_exc_cascade:
0814 if (orig_currentExcHandler != NULL) {
0815 orig_currentExcHandler(bsp_frame);
0816 }
0817 break;
0818 }
0819 }
0820 }
0821
0822 static bool
0823 rtems_debugger_is_int_reg(size_t reg)
0824 {
0825 const size_t size = ppc_reg_offsets[reg + 1] - ppc_reg_offsets[reg];
0826 return size == RTEMS_DEBUGGER_NUMREGBYTES;
0827 }
0828
0829 static void
0830 rtems_debugger_set_int_reg(rtems_debugger_thread* thread,
0831 const uintptr_t reg,
0832 const uint32_t value)
0833 {
0834 const size_t offset = ppc_reg_offsets[reg];
0835
0836
0837
0838 memcpy(&thread->registers[offset], &value, sizeof(uintptr_t));
0839 }
0840
0841 static const uintptr_t
0842 rtems_debugger_get_int_reg(rtems_debugger_thread* thread, const size_t reg)
0843 {
0844 const size_t offset = ppc_reg_offsets[reg];
0845 uintptr_t value;
0846 memcpy(&value, &thread->registers[offset], sizeof(uintptr_t));
0847 return value;
0848 }
0849
0850 static void rtems_debugger_acquire_exc(void) {
0851 if (orig_currentExcHandler == NULL) {
0852 orig_currentExcHandler = globalExceptHdl;
0853 globalExceptHdl = target_exception;
0854 }
0855 }
0856
0857 static void rtems_debugger_release_exc(void) {
0858 if (orig_currentExcHandler != NULL) {
0859 globalExceptHdl = orig_currentExcHandler;
0860 }
0861 }
0862
0863 int
0864 rtems_debugger_target_enable(void)
0865 {
0866 target_printk("]] rtems-db: powerpc: %s\n", __func__);
0867 rtems_interrupt_lock_context lock_context;
0868 rtems_interrupt_lock_acquire(&target_lock, &lock_context);
0869 rtems_debugger_acquire_exc();
0870 rtems_interrupt_lock_release(&target_lock, &lock_context);
0871 return 0;
0872 }
0873
0874 int
0875 rtems_debugger_target_disable(void)
0876 {
0877 target_printk("]] rtems-db: powerpc: %s\n", __func__);
0878 rtems_interrupt_lock_context lock_context;
0879 rtems_interrupt_lock_acquire(&target_lock, &lock_context);
0880 ppc_set_dbsr(0xffffffffUL);
0881 ppc_set_dbcr0(0);
0882 rtems_debugger_release_exc();
0883 rtems_interrupt_lock_release(&target_lock, &lock_context);
0884 return 0;
0885 }
0886
0887 int
0888 rtems_debugger_target_read_regs(rtems_debugger_thread* thread)
0889 {
0890 target_printk("]] rtems-db: powerpc: %s\n", __func__);
0891 if (!rtems_debugger_thread_flag(thread,
0892 RTEMS_DEBUGGER_THREAD_FLAG_REG_VALID)) {
0893 static const uintptr_t good_address = (uintptr_t) &good_address;
0894 size_t i;
0895
0896 for (i = 0; i < rtems_debugger_target_reg_num(); ++i) {
0897 if (rtems_debugger_is_int_reg(i)) {
0898 rtems_debugger_set_int_reg(thread, i, (uintptr_t) &good_address);
0899 }
0900 }
0901
0902 if (thread->frame) {
0903 CPU_Exception_frame* frame = thread->frame;
0904 rtems_debugger_set_int_reg(thread, REG_R0, frame->GPR0);
0905 rtems_debugger_set_int_reg(thread, REG_R1, frame->GPR1);
0906 rtems_debugger_set_int_reg(thread, REG_R2, frame->GPR2);
0907 rtems_debugger_set_int_reg(thread, REG_R3, frame->GPR3);
0908 rtems_debugger_set_int_reg(thread, REG_R4, frame->GPR4);
0909 rtems_debugger_set_int_reg(thread, REG_R5, frame->GPR5);
0910 rtems_debugger_set_int_reg(thread, REG_R6, frame->GPR6);
0911 rtems_debugger_set_int_reg(thread, REG_R7, frame->GPR7);
0912 rtems_debugger_set_int_reg(thread, REG_R8, frame->GPR8);
0913 rtems_debugger_set_int_reg(thread, REG_R9, frame->GPR9);
0914 rtems_debugger_set_int_reg(thread, REG_R10, frame->GPR10);
0915 rtems_debugger_set_int_reg(thread, REG_R11, frame->GPR11);
0916 rtems_debugger_set_int_reg(thread, REG_R12, frame->GPR12);
0917 rtems_debugger_set_int_reg(thread, REG_R13, frame->GPR13);
0918 rtems_debugger_set_int_reg(thread, REG_R14, frame->GPR14);
0919 rtems_debugger_set_int_reg(thread, REG_R15, frame->GPR15);
0920 rtems_debugger_set_int_reg(thread, REG_R16, frame->GPR16);
0921 rtems_debugger_set_int_reg(thread, REG_R17, frame->GPR17);
0922 rtems_debugger_set_int_reg(thread, REG_R18, frame->GPR18);
0923 rtems_debugger_set_int_reg(thread, REG_R19, frame->GPR19);
0924 rtems_debugger_set_int_reg(thread, REG_R20, frame->GPR20);
0925 rtems_debugger_set_int_reg(thread, REG_R21, frame->GPR21);
0926 rtems_debugger_set_int_reg(thread, REG_R22, frame->GPR22);
0927 rtems_debugger_set_int_reg(thread, REG_R23, frame->GPR23);
0928 rtems_debugger_set_int_reg(thread, REG_R24, frame->GPR24);
0929 rtems_debugger_set_int_reg(thread, REG_R25, frame->GPR25);
0930 rtems_debugger_set_int_reg(thread, REG_R26, frame->GPR26);
0931 rtems_debugger_set_int_reg(thread, REG_R27, frame->GPR27);
0932 rtems_debugger_set_int_reg(thread, REG_R28, frame->GPR28);
0933 rtems_debugger_set_int_reg(thread, REG_R29, frame->GPR29);
0934 rtems_debugger_set_int_reg(thread, REG_R30, frame->GPR30);
0935 rtems_debugger_set_int_reg(thread, REG_R31, frame->GPR31);
0936
0937 rtems_debugger_set_int_reg(thread, REG_PC, frame->EXC_SRR0);
0938 rtems_debugger_set_int_reg(thread, REG_MSR, frame->EXC_SRR1);
0939 rtems_debugger_set_int_reg(thread, REG_CND, frame->EXC_CR);
0940 rtems_debugger_set_int_reg(thread, REG_LR, frame->EXC_LR);
0941 rtems_debugger_set_int_reg(thread, REG_CNT, frame->EXC_CTR);
0942 rtems_debugger_set_int_reg(thread, REG_XER, frame->EXC_XER);
0943
0944
0945
0946
0947 thread->signal = rtems_debugger_target_exception_to_signal(frame);
0948 }
0949 else {
0950 ppc_context* thread_ctx = ppc_get_context(&thread->tcb->Registers);
0951 rtems_debugger_set_int_reg(thread, REG_R1, thread_ctx->gpr1);
0952 rtems_debugger_set_int_reg(thread, REG_R14, thread_ctx->gpr14);
0953 rtems_debugger_set_int_reg(thread, REG_R15, thread_ctx->gpr15);
0954 rtems_debugger_set_int_reg(thread, REG_R16, thread_ctx->gpr16);
0955 rtems_debugger_set_int_reg(thread, REG_R17, thread_ctx->gpr17);
0956 rtems_debugger_set_int_reg(thread, REG_R18, thread_ctx->gpr18);
0957 rtems_debugger_set_int_reg(thread, REG_R19, thread_ctx->gpr19);
0958 rtems_debugger_set_int_reg(thread, REG_R20, thread_ctx->gpr20);
0959 rtems_debugger_set_int_reg(thread, REG_R21, thread_ctx->gpr21);
0960 rtems_debugger_set_int_reg(thread, REG_R22, thread_ctx->gpr22);
0961 rtems_debugger_set_int_reg(thread, REG_R23, thread_ctx->gpr23);
0962 rtems_debugger_set_int_reg(thread, REG_R24, thread_ctx->gpr24);
0963 rtems_debugger_set_int_reg(thread, REG_R25, thread_ctx->gpr25);
0964 rtems_debugger_set_int_reg(thread, REG_R26, thread_ctx->gpr26);
0965 rtems_debugger_set_int_reg(thread, REG_R27, thread_ctx->gpr27);
0966 rtems_debugger_set_int_reg(thread, REG_R28, thread_ctx->gpr28);
0967 rtems_debugger_set_int_reg(thread, REG_R29, thread_ctx->gpr29);
0968 rtems_debugger_set_int_reg(thread, REG_R30, thread_ctx->gpr30);
0969 rtems_debugger_set_int_reg(thread, REG_R31, thread_ctx->gpr31);
0970
0971 rtems_debugger_set_int_reg(thread, REG_PC, thread_ctx->lr);
0972 rtems_debugger_set_int_reg(thread, REG_MSR, thread_ctx->msr);
0973 rtems_debugger_set_int_reg(thread, REG_CND, thread_ctx->cr);
0974 rtems_debugger_set_int_reg(thread, REG_LR, thread_ctx->lr);
0975 rtems_debugger_set_int_reg(thread, REG_CNT, 0);
0976 rtems_debugger_set_int_reg(thread, REG_XER, 0);
0977 rtems_debugger_set_int_reg(thread, REG_SPEFSCR, 0);
0978
0979
0980
0981
0982 thread->signal = 0;
0983 }
0984
0985 thread->flags |= RTEMS_DEBUGGER_THREAD_FLAG_REG_VALID;
0986 thread->flags &= ~RTEMS_DEBUGGER_THREAD_FLAG_REG_DIRTY;
0987 }
0988
0989 return 0;
0990 }
0991
0992 int
0993 rtems_debugger_target_write_regs(rtems_debugger_thread* thread)
0994 {
0995 target_printk("]] rtems-db: powerpc: %s\n", __func__);
0996 if (rtems_debugger_thread_flag(thread,
0997 RTEMS_DEBUGGER_THREAD_FLAG_REG_DIRTY)) {
0998
0999
1000
1001
1002 if (rtems_debugger_thread_flag(thread,
1003 RTEMS_DEBUGGER_THREAD_FLAG_EXCEPTION)) {
1004 CPU_Exception_frame* frame = thread->frame;
1005 frame->GPR0 = rtems_debugger_get_int_reg(thread, REG_R0);
1006 frame->GPR1 = rtems_debugger_get_int_reg(thread, REG_R1);
1007 frame->GPR2 = rtems_debugger_get_int_reg(thread, REG_R2);
1008 frame->GPR3 = rtems_debugger_get_int_reg(thread, REG_R3);
1009 frame->GPR4 = rtems_debugger_get_int_reg(thread, REG_R4);
1010 frame->GPR5 = rtems_debugger_get_int_reg(thread, REG_R5);
1011 frame->GPR6 = rtems_debugger_get_int_reg(thread, REG_R6);
1012 frame->GPR7 = rtems_debugger_get_int_reg(thread, REG_R7);
1013 frame->GPR8 = rtems_debugger_get_int_reg(thread, REG_R8);
1014 frame->GPR9 = rtems_debugger_get_int_reg(thread, REG_R9);
1015 frame->GPR10 = rtems_debugger_get_int_reg(thread, REG_R10);
1016 frame->GPR11 = rtems_debugger_get_int_reg(thread, REG_R11);
1017 frame->GPR12 = rtems_debugger_get_int_reg(thread, REG_R12);
1018 frame->GPR13 = rtems_debugger_get_int_reg(thread, REG_R13);
1019 frame->GPR14 = rtems_debugger_get_int_reg(thread, REG_R14);
1020 frame->GPR15 = rtems_debugger_get_int_reg(thread, REG_R15);
1021 frame->GPR16 = rtems_debugger_get_int_reg(thread, REG_R16);
1022 frame->GPR17 = rtems_debugger_get_int_reg(thread, REG_R17);
1023 frame->GPR18 = rtems_debugger_get_int_reg(thread, REG_R18);
1024 frame->GPR19 = rtems_debugger_get_int_reg(thread, REG_R19);
1025 frame->GPR20 = rtems_debugger_get_int_reg(thread, REG_R20);
1026 frame->GPR21 = rtems_debugger_get_int_reg(thread, REG_R21);
1027 frame->GPR22 = rtems_debugger_get_int_reg(thread, REG_R22);
1028 frame->GPR23 = rtems_debugger_get_int_reg(thread, REG_R23);
1029 frame->GPR24 = rtems_debugger_get_int_reg(thread, REG_R24);
1030 frame->GPR25 = rtems_debugger_get_int_reg(thread, REG_R25);
1031 frame->GPR26 = rtems_debugger_get_int_reg(thread, REG_R26);
1032 frame->GPR27 = rtems_debugger_get_int_reg(thread, REG_R27);
1033 frame->GPR28 = rtems_debugger_get_int_reg(thread, REG_R28);
1034 frame->GPR29 = rtems_debugger_get_int_reg(thread, REG_R29);
1035 frame->GPR30 = rtems_debugger_get_int_reg(thread, REG_R30);
1036 frame->GPR31 = rtems_debugger_get_int_reg(thread, REG_R31);
1037
1038 frame->EXC_SRR0 = rtems_debugger_get_int_reg(thread, REG_PC);
1039 frame->EXC_SRR1 = rtems_debugger_get_int_reg(thread, REG_MSR);
1040 frame->EXC_CR = rtems_debugger_get_int_reg(thread, REG_CND);
1041 frame->EXC_LR = rtems_debugger_get_int_reg(thread, REG_LR);
1042 frame->EXC_CTR = rtems_debugger_get_int_reg(thread, REG_CNT);
1043 frame->EXC_XER = rtems_debugger_get_int_reg(thread, REG_XER);
1044 }
1045 thread->flags &= ~RTEMS_DEBUGGER_THREAD_FLAG_REG_DIRTY;
1046 }
1047 return 0;
1048 }
1049
1050 uintptr_t
1051 rtems_debugger_target_reg_pc(rtems_debugger_thread* thread)
1052 {
1053 int r;
1054 r = rtems_debugger_target_read_regs(thread);
1055 if (r >= 0) {
1056 return rtems_debugger_get_int_reg(thread, REG_PC);
1057 }
1058 return 0;
1059 }
1060
1061 uintptr_t
1062 rtems_debugger_target_frame_pc(CPU_Exception_frame* frame)
1063 {
1064 return (uintptr_t) frame->EXC_SRR0;
1065 }
1066
1067 uintptr_t
1068 rtems_debugger_target_reg_sp(rtems_debugger_thread* thread)
1069 {
1070 int r;
1071 r = rtems_debugger_target_read_regs(thread);
1072 if (r >= 0) {
1073 return rtems_debugger_get_int_reg(thread, REG_R1);
1074 }
1075 return 0;
1076 }
1077
1078 uintptr_t
1079 rtems_debugger_target_tcb_sp(rtems_debugger_thread* thread)
1080 {
1081 ppc_context* thread_ctx = ppc_get_context(&thread->tcb->Registers);
1082 return (DB_UINT) thread_ctx->gpr1;
1083 }
1084
1085 int
1086 rtems_debugger_target_thread_stepping(rtems_debugger_thread* thread)
1087 {
1088 target_printk("]] rtems-db: powerpc: %s\n", __func__);
1089 if (rtems_debugger_thread_flag(thread,
1090 RTEMS_DEBUGGER_THREAD_FLAG_STEP_INSTR)) {
1091 CPU_Exception_frame* frame = thread->frame;
1092
1093
1094
1095 if (frame != NULL) {
1096
1097
1098
1099
1100 if ((frame->EXC_SRR1 & MSR_EE) == 0) {
1101 thread->flags |= RTEMS_DEBUGGER_THREAD_FLAG_INTS_DISABLED;
1102 }
1103 powerpc_stepping_frame(frame);
1104 }
1105 }
1106 return 0;
1107 }
1108
1109 int
1110 rtems_debugger_target_exception_to_signal(CPU_Exception_frame* frame)
1111 {
1112 int sig = RTEMS_DEBUGGER_SIGNAL_HUP;
1113 switch (frame->_EXC_number) {
1114 case ASM_MACH_VECTOR:
1115 sig = RTEMS_DEBUGGER_SIGNAL_BUS;
1116 break;
1117 case ASM_PROT_VECTOR:
1118 case ASM_ISI_VECTOR:
1119 case ASM_ALIGN_VECTOR:
1120 case ASM_60X_IMISS_VECTOR:
1121 case ASM_60X_DLMISS_VECTOR:
1122 case ASM_60X_DSMISS_VECTOR:
1123 sig = RTEMS_DEBUGGER_SIGNAL_SEGV;
1124 break;
1125 case ASM_PROG_VECTOR:
1126 sig = RTEMS_DEBUGGER_SIGNAL_TRAP;
1127 break;
1128 case ASM_FLOAT_VECTOR:
1129 sig = RTEMS_DEBUGGER_SIGNAL_FPE;
1130 break;
1131 case ASM_DEC_VECTOR:
1132 sig = RTEMS_DEBUGGER_SIGNAL_ALRM;
1133 break;
1134 case ASM_SYS_VECTOR:
1135 case ASM_TRACE_VECTOR:
1136 sig = RTEMS_DEBUGGER_SIGNAL_TRAP;
1137 break;
1138 default:
1139 break;
1140 }
1141 return sig;
1142 }
1143
1144 void
1145 rtems_debugger_target_exception_print(CPU_Exception_frame* frame)
1146 {
1147 uintptr_t* gpr = &frame->GPR0;
1148 int r = 0;
1149 #ifndef __SPE__
1150 rtems_debugger_printf("SRR0 = %08" PRIx32 " SRR1 = %08" PRIx32 "\n",
1151 frame->EXC_SRR0, frame->EXC_SRR1);
1152 #else
1153 rtems_debugger_printf("SRR0 = %08" PRIx32 " SRR1 = %08" PRIx32 \
1154 " SPEFSCR = %08" PRIx32 " ACC = %08" PRIx32 "\n",
1155 frame->EXC_SRR0, frame->EXC_SRR1,
1156 frame->EXC_SPEFSCR, frame->EXC_ACC);
1157 #endif
1158 rtems_debugger_printf("LR = %08" PRIx32 " CR = %08" PRIx32 \
1159 " XER = %08" PRIx32 " CTR = %08" PRIx32 "\n",
1160 frame->EXC_LR, frame->EXC_CR,
1161 frame->EXC_XER, frame->EXC_CTR);
1162 gpr = &frame->GPR0;
1163 for (r= 0; r < 32; r += 4, gpr += 4) {
1164 rtems_debugger_printf("R%-2d = %08" PRIx32 " R%-2d = %08" PRIx32 \
1165 " R%-2d = %08" PRIx32 " R%-2d = %08" PRIx32 "\n",
1166 r, *gpr, r + 1, *(gpr + 1), r + 2,
1167 *(gpr + 2), r + 3, *(gpr + 3));
1168 }
1169 }
1170
1171 int
1172 rtems_debugger_target_hwbreak_insert(void)
1173 {
1174 target_printk("]] rtems-db: powerpc: %s\n", __func__);
1175
1176
1177
1178 return 0;
1179 }
1180
1181 int
1182 rtems_debugger_target_hwbreak_remove(void)
1183 {
1184 target_printk("]] rtems-db: powerpc: %s\n", __func__);
1185 return 0;
1186 }
1187
1188 int
1189 rtems_debugger_target_hwbreak_control(rtems_debugger_target_watchpoint wp,
1190 bool insert,
1191 uintptr_t addr,
1192 DB_UINT kind)
1193 {
1194 target_printk("]] rtems-db: powerpc: %s\n", __func__);
1195
1196
1197
1198 return 0;
1199 }
1200
1201 int
1202 rtems_debugger_target_cache_sync(rtems_debugger_target_swbreak* swbreak)
1203 {
1204
1205
1206
1207 rtems_cache_flush_multiple_data_lines(
1208 swbreak->address,
1209 sizeof( breakpoint )
1210 );
1211 rtems_cache_instruction_sync_after_code_change(
1212 swbreak->address,
1213 sizeof( breakpoint )
1214 );
1215 return 0;
1216 }