File indexing completed on 2025-05-11 08:23:51
0001 #define GDB_STUB_ENABLE_THREAD_SUPPORT 1
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
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121 #include <string.h>
0122 #include <signal.h>
0123 #include "mips_opcode.h"
0124
0125 #include <rtems.h>
0126 #include <rtems/bspIo.h>
0127 #include "gdb_if.h"
0128
0129
0130 #undef ASSERT
0131 #define ASSERT(x) if(!(x)) printk("ASSERT: stub: %d\n", __LINE__)
0132
0133
0134
0135 #define EXC_INT 0
0136 #define EXC_MOD 1
0137 #define EXC_TLBL 2
0138 #define EXC_TLBS 3
0139 #define EXC_ADEL 4
0140 #define EXC_ADES 5
0141 #define EXC_IBE 6
0142 #define EXC_DBE 7
0143 #define EXC_SYS 8
0144 #define EXC_BP 9
0145 #define EXC_RI 10
0146 #define EXC_CPU 11
0147 #define EXC_OVF 12
0148 #define EXC_TRAP 13
0149 #define EXC_FPE 15
0150
0151
0152 #define CSR_FS 0x01000000
0153 #define CSR_C 0x00800000
0154
0155 #define CSR_CMASK (0x3f<<12)
0156 #define CSR_CE 0x00020000
0157 #define CSR_CV 0x00010000
0158 #define CSR_CZ 0x00008000
0159 #define CSR_CO 0x00004000
0160 #define CSR_CU 0x00002000
0161 #define CSR_CI 0x00001000
0162
0163 #define CSR_EMASK (0x1f<<7)
0164 #define CSR_EV 0x00000800
0165 #define CSR_EZ 0x00000400
0166 #define CSR_EO 0x00000200
0167 #define CSR_EU 0x00000100
0168 #define CSR_EI 0x00000080
0169
0170 #define CSR_FMASK (0x1f<<2)
0171 #define CSR_FV 0x00000040
0172 #define CSR_FZ 0x00000020
0173 #define CSR_FO 0x00000010
0174 #define CSR_FU 0x00000008
0175 #define CSR_FI 0x00000004
0176
0177 #define CSR_RMODE_MASK (0x3<<0)
0178 #define CSR_RM 0x00000003
0179 #define CSR_RP 0x00000002
0180 #define CSR_RZ 0x00000001
0181 #define CSR_RN 0x00000000
0182
0183
0184
0185
0186
0187
0188
0189 #if (__mips == 3)
0190 typedef long long mips_register_t;
0191 #define R_SZ 8
0192 #elif (__mips == 1)
0193 typedef unsigned int mips_register_t;
0194 #define R_SZ 4
0195 #else
0196 #error "unknown MIPS ISA"
0197 #endif
0198 static mips_register_t *registers;
0199
0200 #if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)
0201 static char do_threads;
0202 #endif
0203
0204
0205
0206
0207 extern char getDebugChar (void);
0208 extern void putDebugChar (char);
0209
0210
0211
0212
0213 void handle_exception (rtems_vector_number vector, CPU_Interrupt_frame *frame);
0214
0215
0216
0217
0218 void rtems_interrupt_catch( rtems_isr_entry, int, rtems_isr_entry *);
0219
0220
0221
0222
0223 struct memseg
0224 {
0225 unsigned begin, end, opts;
0226 };
0227
0228 static int is_readable(unsigned,unsigned);
0229 static int is_writeable(unsigned,unsigned);
0230 static int is_steppable(unsigned);
0231
0232
0233
0234
0235
0236
0237 #define BUFMAX 1500
0238
0239 static char inBuffer[BUFMAX];
0240 static char outBuffer[BUFMAX];
0241
0242
0243 #define BREAKNUM 32
0244
0245 struct z0break
0246 {
0247
0248 struct z0break *next;
0249 struct z0break *prev;
0250
0251
0252
0253
0254
0255
0256
0257
0258 unsigned char *address;
0259 unsigned instr;
0260 };
0261
0262 static struct z0break z0break_arr[BREAKNUM];
0263 static struct z0break *z0break_avail = NULL;
0264 static struct z0break *z0break_list = NULL;
0265
0266
0267
0268
0269
0270 const char gdb_hexchars[] = "0123456789abcdef";
0271
0272 #define highhex(x) gdb_hexchars [(x >> 4) & 0xf]
0273 #define lowhex(x) gdb_hexchars [x & 0xf]
0274
0275
0276
0277
0278
0279 static char *
0280 mem2hex (void *_addr, int length, char *buf)
0281 {
0282 unsigned int addr = (unsigned int) _addr;
0283
0284 if (((addr & 0x7) == 0) && ((length & 0x7) == 0))
0285 {
0286 long long *source = (long long *) (addr);
0287 long long *limit = (long long *) (addr + length);
0288
0289 while (source < limit)
0290 {
0291 int i;
0292 long long k = *source++;
0293
0294 for (i = 15; i >= 0; i--)
0295 *buf++ = gdb_hexchars [(k >> (i*4)) & 0xf];
0296 }
0297 }
0298 else if (((addr & 0x3) == 0) && ((length & 0x3) == 0))
0299 {
0300 int *source = (int *) (addr);
0301 int *limit = (int *) (addr + length);
0302
0303 while (source < limit)
0304 {
0305 int i;
0306 int k = *source++;
0307
0308 for (i = 7; i >= 0; i--)
0309 *buf++ = gdb_hexchars [(k >> (i*4)) & 0xf];
0310 }
0311 }
0312 else if (((addr & 0x1) == 0) && ((length & 0x1) == 0))
0313 {
0314 short *source = (short *) (addr);
0315 short *limit = (short *) (addr + length);
0316
0317 while (source < limit)
0318 {
0319 int i;
0320 short k = *source++;
0321
0322 for (i = 3; i >= 0; i--)
0323 *buf++ = gdb_hexchars [(k >> (i*4)) & 0xf];
0324 }
0325 }
0326 else
0327 {
0328 char *source = (char *) (addr);
0329 char *limit = (char *) (addr + length);
0330
0331 while (source < limit)
0332 {
0333 int i;
0334 char k = *source++;
0335
0336 for (i = 1; i >= 0; i--)
0337 *buf++ = gdb_hexchars [(k >> (i*4)) & 0xf];
0338 }
0339 }
0340
0341 *buf = '\0';
0342 return (buf);
0343 }
0344
0345
0346
0347
0348
0349 static int
0350 hex (char ch)
0351 {
0352 if ((ch >= 'a') && (ch <= 'f'))
0353 return (ch - 'a' + 10);
0354 if ((ch >= '0') && (ch <= '9'))
0355 return (ch - '0');
0356 if ((ch >= 'A') && (ch <= 'F'))
0357 return (ch - 'A' + 10);
0358 return (-1);
0359 }
0360
0361
0362
0363
0364
0365 static int
0366 hexToInt (char **ptr, int *intValue)
0367 {
0368 int numChars = 0;
0369 int hexValue;
0370
0371 *intValue = 0;
0372
0373 while (**ptr)
0374 {
0375 hexValue = hex (**ptr);
0376 if (hexValue >= 0)
0377 {
0378 *intValue = (*intValue << 4) | hexValue;
0379 numChars++;
0380 }
0381 else
0382 break;
0383
0384 (*ptr)++;
0385 }
0386
0387 return (numChars);
0388 }
0389
0390
0391
0392
0393
0394 static int
0395 hexToLongLong (char **ptr, long long *intValue)
0396 {
0397 int numChars = 0;
0398 int hexValue;
0399
0400 *intValue = 0;
0401
0402 while (**ptr)
0403 {
0404 hexValue = hex (**ptr);
0405 if (hexValue >= 0)
0406 {
0407 *intValue = (*intValue << 4) | hexValue;
0408 numChars++;
0409 }
0410 else
0411 break;
0412
0413 (*ptr)++;
0414 }
0415
0416 return (numChars);
0417 }
0418
0419
0420
0421
0422
0423
0424
0425 static int
0426 hex2mem (char *buf, void *_addr, int length)
0427 {
0428 unsigned int addr = (unsigned int) _addr;
0429 if (((addr & 0x7) == 0) && ((length & 0x7) == 0))
0430 {
0431 long long *target = (long long *) (addr);
0432 long long *limit = (long long *) (addr + length);
0433
0434 while (target < limit)
0435 {
0436 int i, j;
0437 long long k = 0;
0438
0439 for (i = 0; i < 16; i++)
0440 if ((j = hex(*buf++)) < 0)
0441 return 0;
0442 else
0443 k = (k << 4) + j;
0444 *target++ = k;
0445 }
0446 }
0447 else if (((addr & 0x3) == 0) && ((length & 0x3) == 0))
0448 {
0449 int *target = (int *) (addr);
0450 int *limit = (int *) (addr + length);
0451
0452 while (target < limit)
0453 {
0454 int i, j;
0455 int k = 0;
0456
0457 for (i = 0; i < 8; i++)
0458 if ((j = hex(*buf++)) < 0)
0459 return 0;
0460 else
0461 k = (k << 4) + j;
0462 *target++ = k;
0463 }
0464 }
0465 else if (((addr & 0x1) == 0) && ((length & 0x1) == 0))
0466 {
0467 short *target = (short *) (addr);
0468 short *limit = (short *) (addr + length);
0469
0470 while (target < limit)
0471 {
0472 int i, j;
0473 short k = 0;
0474
0475 for (i = 0; i < 4; i++)
0476 if ((j = hex(*buf++)) < 0)
0477 return 0;
0478 else
0479 k = (k << 4) + j;
0480 *target++ = k;
0481 }
0482 }
0483 else
0484 {
0485 char *target = (char *) (addr);
0486 char *limit = (char *) (addr + length);
0487
0488 while (target < limit)
0489 {
0490 int i, j;
0491 char k = 0;
0492
0493 for (i = 0; i < 2; i++)
0494 if ((j = hex(*buf++)) < 0)
0495 return 0;
0496 else
0497 k = (k << 4) + j;
0498 *target++ = k;
0499 }
0500 }
0501
0502 return 1;
0503 }
0504
0505
0506
0507
0508
0509
0510 static unsigned char *
0511 bin2mem (
0512 char *buf,
0513 unsigned char *mem,
0514 int count
0515 )
0516 {
0517 int i;
0518
0519 for (i = 0; i < count; i++) {
0520
0521
0522 if (*buf == 0x7d) {
0523 switch (*(buf+1)) {
0524 case 0x3:
0525 case 0x4:
0526 case 0x5d:
0527 buf++;
0528 *buf |= 0x20;
0529 break;
0530 default:
0531
0532 break;
0533 }
0534 }
0535
0536 *mem++ = *buf++;
0537 }
0538
0539 return mem;
0540 }
0541
0542
0543
0544
0545
0546 static void
0547 getpacket (char *buffer)
0548 {
0549 unsigned char checksum;
0550 unsigned char xmitcsum;
0551 int i;
0552 int count;
0553 char ch;
0554 do
0555 {
0556
0557 while ((ch = getDebugChar ()) != '$');
0558 checksum = 0;
0559 xmitcsum = -1;
0560
0561 count = 0;
0562
0563
0564 while ( (count < BUFMAX-1) && ((ch = getDebugChar ()) != '#') )
0565 checksum += (buffer[count++] = ch);
0566
0567
0568 buffer[count] = '\0';
0569
0570 if (ch == '#')
0571 {
0572 xmitcsum = hex (getDebugChar ()) << 4;
0573 xmitcsum += hex (getDebugChar ());
0574 if (checksum != xmitcsum)
0575 putDebugChar ('-');
0576 else
0577 {
0578 putDebugChar ('+');
0579
0580 if (buffer[2] == ':')
0581 {
0582 putDebugChar (buffer[0]);
0583 putDebugChar (buffer[1]);
0584
0585 for (i = 3; i <= count; i++)
0586 buffer[i - 3] = buffer[i];
0587 }
0588 }
0589 }
0590 }
0591 while (checksum != xmitcsum);
0592 }
0593
0594
0595
0596
0597 static char
0598 getAck (void)
0599 {
0600 char c;
0601
0602 do
0603 {
0604 c = getDebugChar ();
0605 }
0606 while ((c != '+') && (c != '-'));
0607
0608 return c;
0609 }
0610
0611
0612
0613
0614 static void
0615 putpacket (char *buffer)
0616 {
0617 int checksum;
0618
0619
0620 do
0621 {
0622 char *src = buffer;
0623 putDebugChar ('$');
0624 checksum = 0;
0625
0626 while (*src != '\0')
0627 {
0628 int runlen = 0;
0629
0630
0631 while ((src[runlen] == src[0]) && (runlen < 99))
0632 runlen++;
0633 if (runlen > 3)
0634 {
0635 int encode;
0636
0637 putDebugChar (*src);
0638 checksum += *src;
0639 putDebugChar ('*');
0640 checksum += '*';
0641 checksum += (encode = (runlen - 4) + ' ');
0642 putDebugChar (encode);
0643 src += runlen;
0644 }
0645 else
0646 {
0647 putDebugChar (*src);
0648 checksum += *src;
0649 src++;
0650 }
0651 }
0652
0653 putDebugChar ('#');
0654 putDebugChar (highhex (checksum));
0655 putDebugChar (lowhex (checksum));
0656 }
0657 while (getAck () != '+');
0658 }
0659
0660
0661
0662
0663
0664 static struct
0665 {
0666 unsigned *targetAddr;
0667 unsigned savedInstr;
0668 }
0669 instrBuffer;
0670
0671
0672
0673
0674 static void
0675 undoSStep (void)
0676 {
0677 if (instrBuffer.targetAddr != NULL)
0678 {
0679 *instrBuffer.targetAddr = instrBuffer.savedInstr;
0680 instrBuffer.targetAddr = NULL;
0681 }
0682 instrBuffer.savedInstr = NOP_INSTR;
0683 }
0684
0685
0686
0687
0688
0689
0690
0691
0692
0693
0694
0695 static void
0696 doSStep (void)
0697 {
0698 InstFmt inst;
0699
0700 instrBuffer.targetAddr = (unsigned *)(registers[PC]+4);
0701
0702 inst.word = *(unsigned *)registers[PC];
0703
0704 switch (inst.RType.op) {
0705 case OP_SPECIAL:
0706 switch (inst.RType.func) {
0707 case OP_JR:
0708 case OP_JALR:
0709 instrBuffer.targetAddr =
0710 (unsigned *)registers[inst.RType.rs];
0711 break;
0712 };
0713 break;
0714
0715 case OP_REGIMM:
0716 switch (inst.IType.rt) {
0717 case OP_BLTZ:
0718 case OP_BLTZL:
0719 case OP_BLTZAL:
0720 case OP_BLTZALL:
0721 if (registers[inst.IType.rs] < 0 )
0722 instrBuffer.targetAddr =
0723 (unsigned *)(((signed short)inst.IType.imm<<2)
0724 + (registers[PC]+4));
0725 else
0726 instrBuffer.targetAddr = (unsigned*)(registers[PC]+8);
0727 break;
0728 case OP_BGEZ:
0729 case OP_BGEZL:
0730 case OP_BGEZAL:
0731 case OP_BGEZALL:
0732 if (registers[inst.IType.rs] >= 0 )
0733 instrBuffer.targetAddr =
0734 (unsigned *)(((signed short)inst.IType.imm<<2)
0735 + (registers[PC]+4));
0736 else
0737 instrBuffer.targetAddr = (unsigned*)(registers[PC]+8);
0738 break;
0739 };
0740 break;
0741
0742 case OP_J:
0743 case OP_JAL:
0744 instrBuffer.targetAddr =
0745 (unsigned *)((inst.JType.target<<2) + ((registers[PC]+4)&0xf0000000));
0746 break;
0747
0748 case OP_BEQ:
0749 case OP_BEQL:
0750 if (registers[inst.IType.rs] == registers[inst.IType.rt])
0751 instrBuffer.targetAddr =
0752 (unsigned *)(((signed short)inst.IType.imm<<2) + (registers[PC]+4));
0753 else
0754 instrBuffer.targetAddr = (unsigned*)(registers[PC]+8);
0755 break;
0756 case OP_BNE:
0757 case OP_BNEL:
0758 if (registers[inst.IType.rs] != registers[inst.IType.rt])
0759 instrBuffer.targetAddr =
0760 (unsigned *)(((signed short)inst.IType.imm<<2) + (registers[PC]+4));
0761 else
0762 instrBuffer.targetAddr = (unsigned*)(registers[PC]+8);
0763 break;
0764 case OP_BLEZ:
0765 case OP_BLEZL:
0766 if (registers[inst.IType.rs] <= 0)
0767 instrBuffer.targetAddr =
0768 (unsigned *)(((signed short)inst.IType.imm<<2) + (registers[PC]+4));
0769 else
0770 instrBuffer.targetAddr = (unsigned*)(registers[PC]+8);
0771 break;
0772 case OP_BGTZ:
0773 case OP_BGTZL:
0774 if (registers[inst.IType.rs] > 0)
0775 instrBuffer.targetAddr =
0776 (unsigned *)(((signed short)inst.IType.imm<<2) + (registers[PC]+4));
0777 else
0778 instrBuffer.targetAddr = (unsigned*)(registers[PC]+8);
0779 break;
0780
0781 case OP_COP1:
0782 if (inst.RType.rs == OP_BC)
0783 switch (inst.RType.rt) {
0784 case COPz_BCF:
0785 case COPz_BCFL:
0786 if (registers[FCSR] & CSR_C)
0787 instrBuffer.targetAddr = (unsigned*)(registers[PC]+8);
0788 else
0789 instrBuffer.targetAddr =
0790 (unsigned *)(((signed short)inst.IType.imm<<2)
0791 + (registers[PC]+4));
0792 break;
0793 case COPz_BCT:
0794 case COPz_BCTL:
0795 if (registers[FCSR] & CSR_C)
0796 instrBuffer.targetAddr =
0797 (unsigned *)(((signed short)inst.IType.imm<<2)
0798 + (registers[PC]+4));
0799 else
0800 instrBuffer.targetAddr = (unsigned*)(registers[PC]+8);
0801 break;
0802 };
0803 break;
0804 }
0805
0806 if( is_steppable((unsigned)instrBuffer.targetAddr) && *(instrBuffer.targetAddr) != BREAK_INSTR )
0807 {
0808 instrBuffer.savedInstr = *instrBuffer.targetAddr;
0809 *instrBuffer.targetAddr = BREAK_INSTR;
0810 }
0811 else
0812 {
0813 instrBuffer.targetAddr = NULL;
0814 instrBuffer.savedInstr = NOP_INSTR;
0815 }
0816 return;
0817 }
0818
0819
0820
0821
0822
0823 static int
0824 computeSignal (void)
0825 {
0826 int exceptionCode = (registers[CAUSE] & CAUSE_EXCMASK) >> CAUSE_EXCSHIFT;
0827
0828 switch (exceptionCode)
0829 {
0830 case EXC_INT:
0831
0832 return SIGINT;
0833
0834 case EXC_RI:
0835
0836 case EXC_CPU:
0837
0838 return SIGILL;
0839
0840 case EXC_BP:
0841
0842 return SIGTRAP;
0843
0844 case EXC_OVF:
0845
0846 case EXC_TRAP:
0847
0848 case EXC_FPE:
0849
0850 return SIGFPE;
0851
0852 case EXC_IBE:
0853
0854 case EXC_DBE:
0855
0856 return SIGBUS;
0857
0858 case EXC_MOD:
0859
0860 case EXC_TLBL:
0861
0862 case EXC_TLBS:
0863
0864 case EXC_ADEL:
0865
0866 case EXC_ADES:
0867
0868 return SIGSEGV;
0869
0870 case EXC_SYS:
0871
0872 return SIGSYS;
0873
0874 default:
0875 return SIGTERM;
0876 }
0877 }
0878
0879
0880
0881
0882
0883 static void gdb_stub_report_exception_info(
0884 rtems_vector_number vector,
0885 CPU_Interrupt_frame *frame,
0886 int thread
0887 )
0888 {
0889 char *optr;
0890 int sigval;
0891
0892 optr = outBuffer;
0893 *optr++ = 'T';
0894 sigval = computeSignal ();
0895 *optr++ = highhex (sigval);
0896 *optr++ = lowhex (sigval);
0897
0898 *optr++ = highhex(SP);
0899 *optr++ = lowhex(SP);
0900 *optr++ = ':';
0901 optr = mem2hstr(optr, (unsigned char *)&frame->sp, R_SZ );
0902 *optr++ = ';';
0903
0904 *optr++ = highhex(PC);
0905 *optr++ = lowhex(PC);
0906 *optr++ = ':';
0907 optr = mem2hstr(optr, (unsigned char *)&frame->epc, R_SZ );
0908 *optr++ = ';';
0909
0910 #if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)
0911 if (do_threads)
0912 {
0913 *optr++ = 't';
0914 *optr++ = 'h';
0915 *optr++ = 'r';
0916 *optr++ = 'e';
0917 *optr++ = 'a';
0918 *optr++ = 'd';
0919 *optr++ = ':';
0920 optr = thread2vhstr(optr, thread);
0921 *optr++ = ';';
0922 }
0923 #endif
0924 *optr++ = '\0';
0925 }
0926
0927
0928
0929
0930
0931
0932
0933 CPU_Interrupt_frame current_thread_registers;
0934
0935
0936
0937
0938
0939
0940
0941 extern void clear_cache(void);
0942 void handle_exception (rtems_vector_number vector, CPU_Interrupt_frame *frame)
0943 {
0944 int host_has_detached = 0;
0945 int regno, addr, length;
0946 char *ptr;
0947 int current_thread;
0948 int thread;
0949
0950 long long regval;
0951 void *regptr;
0952 int binary;
0953
0954 registers = (mips_register_t *)frame;
0955
0956 thread = 0;
0957 #if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)
0958 if (do_threads) {
0959 thread = rtems_gdb_stub_get_current_thread();
0960 }
0961 #endif
0962 current_thread = thread;
0963
0964 {
0965
0966 struct z0break *z0, *zother;
0967
0968 for (zother=z0break_list; zother!=NULL; zother=zother->next)
0969 {
0970 if( zother->instr == 0xffffffff )
0971 {
0972
0973 zother->instr = *(zother->address);
0974
0975 *(zother->address) = BREAK_INSTR;
0976 }
0977 }
0978
0979
0980 if( *((unsigned *)frame->epc) == BREAK_INSTR )
0981 {
0982
0983 for (z0=z0break_list; z0!=NULL; z0=z0->next)
0984 {
0985 if( (unsigned)z0->address == frame->epc)
0986 break;
0987 }
0988 if( z0 )
0989 {
0990
0991 *(z0->address) = z0->instr;
0992
0993 z0->instr = 0xffffffff;
0994
0995
0996
0997
0998
0999
1000
1001 }
1002 else
1003 {
1004
1005
1006
1007
1008
1009
1010 undoSStep();
1011 }
1012 }
1013 }
1014
1015
1016 gdb_stub_report_exception_info(vector, frame, thread);
1017 putpacket (outBuffer);
1018
1019 while (!(host_has_detached)) {
1020 outBuffer[0] = '\0';
1021 getpacket (inBuffer);
1022 binary = 0;
1023
1024 switch (inBuffer[0]) {
1025 case '?':
1026 gdb_stub_report_exception_info(vector, frame, thread);
1027 break;
1028
1029 case 'd':
1030
1031 break;
1032
1033 case 'D':
1034
1035 strcpy (outBuffer, "OK");
1036 host_has_detached = 1;
1037 break;
1038
1039 case 'g':
1040 regptr = registers;
1041 #if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)
1042 if (do_threads && current_thread != thread )
1043 regptr = ¤t_thread_registers;
1044 #endif
1045 mem2hex (regptr, NUM_REGS * (sizeof registers), outBuffer);
1046 break;
1047
1048 case 'G':
1049 regptr = registers;
1050 #if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)
1051 if (do_threads && current_thread != thread )
1052 regptr = ¤t_thread_registers;
1053 #endif
1054 if (hex2mem (&inBuffer[1], regptr, NUM_REGS * (sizeof registers)))
1055 strcpy (outBuffer, "OK");
1056 else
1057 strcpy (outBuffer, "E00");
1058 break;
1059
1060 case 'P':
1061
1062 ptr = &inBuffer[1];
1063 if (hexToInt(&ptr, ®no) &&
1064 *ptr++ == '=' &&
1065 hexToLongLong(&ptr, ®val))
1066 {
1067 registers[regno] = regval;
1068 strcpy (outBuffer, "OK");
1069 }
1070 else
1071 strcpy (outBuffer, "E00");
1072 break;
1073
1074 case 'm':
1075
1076 ptr = &inBuffer[1];
1077 if (hexToInt (&ptr, &addr)
1078 && *ptr++ == ','
1079 && hexToInt (&ptr, &length)
1080 && is_readable (addr, length)
1081 && (length < (BUFMAX - 4)/2))
1082 mem2hex ((void *)addr, length, outBuffer);
1083 else
1084 strcpy (outBuffer, "E01");
1085 break;
1086
1087 case 'X':
1088 binary = 1;
1089 case 'M':
1090
1091 ptr = &inBuffer[1];
1092 if (hexToInt (&ptr, &addr)
1093 && *ptr++ == ','
1094 && hexToInt (&ptr, &length)
1095 && *ptr++ == ':'
1096 && is_writeable (addr, length) ) {
1097 if ( binary )
1098 hex2mem (ptr, (void *)addr, length);
1099 else
1100 bin2mem (ptr, (void *)addr, length);
1101 strcpy (outBuffer, "OK");
1102 }
1103 else
1104 strcpy (outBuffer, "E02");
1105 break;
1106
1107 case 'c':
1108
1109 case 's':
1110
1111 {
1112
1113 ptr = &inBuffer[1];
1114 if (hexToInt (&ptr, &addr))
1115 registers[PC] = addr;
1116
1117 if (inBuffer[0] == 's')
1118 doSStep ();
1119 }
1120 goto stubexit;
1121
1122 case 'k':
1123 dumpzbreaks:
1124 {
1125 {
1126
1127 struct z0break *z0, *znxt;
1128
1129 while( (z0= z0break_list) )
1130 {
1131
1132
1133 if( z0->instr != 0xffffffff )
1134 *(z0->address) = z0->instr;
1135
1136
1137 znxt = z0->next;
1138 if( znxt ) znxt->prev = NULL;
1139 z0break_list = znxt;
1140
1141
1142 z0->prev = NULL;
1143 z0->next = z0break_avail;
1144 z0break_avail = z0;
1145 }
1146 }
1147
1148 strcpy(outBuffer, "OK");
1149 }
1150 break;
1151
1152 case 'q':
1153 #if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)
1154 rtems_gdb_process_query( inBuffer, outBuffer, do_threads, thread );
1155 #endif
1156 break;
1157
1158 #if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)
1159 case 'T':
1160 {
1161 int testThread;
1162
1163 if( vhstr2thread(&inBuffer[1], &testThread) == NULL )
1164 {
1165 strcpy(outBuffer, "E01");
1166 break;
1167 }
1168
1169 if( rtems_gdb_index_to_stub_id(testThread) == NULL )
1170 {
1171 strcpy(outBuffer, "E02");
1172 }
1173 else
1174 {
1175 strcpy(outBuffer, "OK");
1176 }
1177 }
1178 break;
1179 #endif
1180
1181 case 'H':
1182 #if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)
1183 if (inBuffer[1] != 'g') {
1184 break;
1185 }
1186
1187 if (!do_threads) {
1188 break;
1189 }
1190
1191 {
1192 int tmp, ret;
1193
1194
1195 if (vhstr2thread(&inBuffer[2], &tmp) == NULL) {
1196 strcpy(outBuffer, "E01");
1197 break;
1198 }
1199
1200
1201 if (tmp == 0) {
1202 tmp = thread;
1203 }
1204
1205 if (tmp == current_thread) {
1206
1207 strcpy(outBuffer, "OK");
1208 break;
1209 }
1210
1211
1212 if (current_thread != thread) {
1213 ret = rtems_gdb_stub_set_thread_regs(
1214 current_thread,
1215 (unsigned int *) (void *)¤t_thread_registers);
1216 ASSERT(ret);
1217 }
1218
1219
1220 if (tmp != thread) {
1221 ret = rtems_gdb_stub_get_thread_regs(
1222 tmp, (unsigned int *) (void *)¤t_thread_registers);
1223
1224 if (!ret) {
1225
1226 strcpy(outBuffer, "E02");
1227 break;
1228 }
1229 }
1230
1231 current_thread = tmp;
1232 strcpy(outBuffer, "OK");
1233 }
1234 #endif
1235 break;
1236
1237 case 'Z':
1238 {
1239 int ret, type, len;
1240 unsigned char *address;
1241 struct z0break *z0;
1242
1243 ret = parse_zbreak(inBuffer, &type, &address, &len);
1244 if (!ret) {
1245 strcpy(outBuffer, "E01");
1246 break;
1247 }
1248
1249 if (type != 0) {
1250
1251 strcpy(outBuffer, "E02");
1252 break;
1253 }
1254
1255 if (len != R_SZ) {
1256 strcpy(outBuffer, "E03");
1257 break;
1258 }
1259
1260
1261 for (z0=z0break_list; z0!=NULL; z0=z0->next) {
1262 if (z0->address == address) {
1263 break;
1264 }
1265 }
1266
1267 if (z0 != NULL) {
1268
1269 strcpy(outBuffer, "E04");
1270 break;
1271 }
1272
1273
1274 if (z0break_avail == NULL) {
1275 strcpy(outBuffer, "E05");
1276 break;
1277 }
1278
1279
1280 z0 = z0break_avail;
1281 z0break_avail = z0break_avail->next;
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296 z0->address = address;
1297
1298 if( z0->address == (unsigned char *) frame->epc )
1299 {
1300
1301
1302
1303 z0->instr = 0xffffffff;
1304 }
1305 else
1306 {
1307
1308 z0->instr = *(z0->address);
1309
1310 *(z0->address) = BREAK_INSTR;
1311 }
1312
1313
1314 {
1315 struct z0break *znxt = z0break_list;
1316
1317 z0->prev = NULL;
1318 z0->next = znxt;
1319
1320 if( znxt ) znxt->prev = z0;
1321 z0break_list = z0;
1322 }
1323
1324 strcpy(outBuffer, "OK");
1325 }
1326 break;
1327
1328 case 'z':
1329 if (inBuffer[1] == 'z')
1330 {
1331 goto dumpzbreaks;
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360 }
1361 else
1362 {
1363 int ret, type, len;
1364 unsigned char *address;
1365 struct z0break *z0;
1366
1367 ret = parse_zbreak(inBuffer, &type, &address, &len);
1368 if (!ret) {
1369 strcpy(outBuffer, "E01");
1370 break;
1371 }
1372
1373 if (type != 0) {
1374
1375 break;
1376 }
1377
1378 if (len != R_SZ) {
1379 strcpy(outBuffer, "E02");
1380 break;
1381 }
1382
1383
1384 for (z0=z0break_list; z0!=NULL; z0=z0->next) {
1385 if (z0->address == address) {
1386 break;
1387 }
1388 }
1389
1390 if (z0 == NULL) {
1391
1392 strcpy(outBuffer, "E03");
1393 break;
1394 }
1395
1396
1397
1398
1399
1400
1401
1402 if( z0->instr != 0xffffffff )
1403 {
1404
1405 *(z0->address) = z0->instr;
1406 }
1407
1408
1409 {
1410 struct z0break *zprv = z0->prev, *znxt = z0->next;
1411
1412 if( zprv ) zprv->next = znxt;
1413 if( znxt ) znxt->prev = zprv;
1414
1415 if( !zprv ) z0break_list = znxt;
1416
1417 znxt = z0break_avail;
1418
1419 z0break_avail = z0;
1420 z0->prev = NULL;
1421 z0->next = znxt;
1422 }
1423
1424 strcpy(outBuffer, "OK");
1425 }
1426 break;
1427
1428 default:
1429 break;
1430 }
1431
1432
1433 putpacket (outBuffer);
1434 }
1435
1436 stubexit:
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450 clear_cache();
1451 }
1452
1453 static int numsegs;
1454 static struct memseg memsegments[NUM_MEMSEGS];
1455
1456 int gdbstub_add_memsegment( unsigned base, unsigned end, int opts )
1457 {
1458 if( numsegs == NUM_MEMSEGS ) return -1;
1459
1460 memsegments[numsegs].begin = base;
1461 memsegments[numsegs].end = end;
1462 memsegments[numsegs].opts = opts;
1463
1464 ++numsegs;
1465 return RTEMS_SUCCESSFUL;
1466 }
1467
1468 static int is_readable(unsigned ptr, unsigned len)
1469 {
1470 struct memseg *ms;
1471 int i;
1472
1473 if( (ptr & 0x3) ) return -1;
1474
1475 for(i=0; i<numsegs; i++)
1476 {
1477 ms= &memsegments[i];
1478
1479 if( ms->begin <= ptr && ptr+len <= ms->end && (ms->opts & MEMOPT_READABLE) )
1480 return -1;
1481 }
1482 return 0;
1483 }
1484
1485 static int is_writeable(unsigned ptr, unsigned len)
1486 {
1487 struct memseg *ms;
1488 int i;
1489
1490 if( (ptr & 0x3) ) return -1;
1491
1492 for(i=0; i<numsegs; i++)
1493 {
1494 ms= &memsegments[i];
1495
1496 if( ms->begin <= ptr && ptr+len <= ms->end && (ms->opts & MEMOPT_WRITEABLE) )
1497 return -1;
1498 }
1499 return 0;
1500 }
1501
1502 static int is_steppable(unsigned ptr)
1503 {
1504 struct memseg *ms;
1505 int i;
1506
1507 if( (ptr & 0x3) ) return -1;
1508
1509 for(i=0; i<numsegs; i++)
1510 {
1511 ms= &memsegments[i];
1512
1513 if( ms->begin <= ptr && ptr <= ms->end && (ms->opts & MEMOPT_WRITEABLE) )
1514 return -1;
1515 }
1516 return 0;
1517 }
1518
1519 static char initialized = 0;
1520
1521 void mips_gdb_stub_install(int enableThreads)
1522 {
1523
1524
1525
1526 int exceptionVector[]= { MIPS_EXCEPTION_MOD, \
1527 MIPS_EXCEPTION_TLBL, \
1528 MIPS_EXCEPTION_TLBS, \
1529 MIPS_EXCEPTION_ADEL, \
1530 MIPS_EXCEPTION_ADES, \
1531 MIPS_EXCEPTION_IBE, \
1532 MIPS_EXCEPTION_DBE, \
1533 MIPS_EXCEPTION_SYSCALL, \
1534 MIPS_EXCEPTION_BREAK, \
1535 MIPS_EXCEPTION_RI, \
1536 MIPS_EXCEPTION_CPU, \
1537 MIPS_EXCEPTION_OVERFLOW, \
1538 MIPS_EXCEPTION_TRAP, \
1539 MIPS_EXCEPTION_VCEI, \
1540 MIPS_EXCEPTION_FPE, \
1541 MIPS_EXCEPTION_C2E, \
1542 MIPS_EXCEPTION_WATCH, \
1543 MIPS_EXCEPTION_VCED, \
1544 -1 };
1545 int i;
1546 rtems_isr_entry old;
1547
1548 if (initialized)
1549 {
1550 ASSERT(0);
1551 return;
1552 }
1553
1554 memset( memsegments,0,sizeof(struct memseg)*NUM_MEMSEGS );
1555 numsegs = 0;
1556
1557 #if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)
1558 if( enableThreads )
1559 do_threads = 1;
1560 else
1561 do_threads = 0;
1562 #endif
1563
1564 {
1565 struct z0break *z0;
1566
1567 z0break_avail = NULL;
1568 z0break_list = NULL;
1569
1570
1571 for (i=0; i<BREAKNUM; i++)
1572 {
1573 memset( (z0= &z0break_arr[i]), 0, sizeof(struct z0break));
1574
1575 z0->next = z0break_avail;
1576 z0break_avail = z0;
1577 }
1578 }
1579
1580 for(i=0; exceptionVector[i] > -1; i++)
1581 {
1582 rtems_interrupt_catch( (rtems_isr_entry) handle_exception, exceptionVector[i], &old );
1583 }
1584
1585 initialized = 1;
1586
1587
1588
1589 }