1 // Modified for uClinux - Vic - Apr 2002
4 // File: nios_gdb_stub.c
6 // Author dvb \ Altera Santa Cruz
11 #include <linux/kernel.h>
12 #include <linux/sched.h>
16 #include "nios_gdb_stub.h"
18 #define na_debug_peripheral_irq 8
22 na_BreakpointTrap
= 3,
23 na_SingleStepTrap
= 4,
32 static void puts( unsigned char *s
)
35 while (!(nasys_printf_uart
->np_uartstatus
& np_uartstatus_trdy_mask
));
36 nasys_printf_uart
->np_uarttxdata
= *s
++;
42 // --------------------------------
47 static void StringFit(char *s
,int w
);
49 // --------------------------------
50 // Debugging The Debugger
52 void GDB_RawMessage(char *s
)
55 nr_pio_lcdwritescreen(s
);
58 #define GDB_RawMessage(a,b,c) // define away to nothing
62 void GDB_Print2(char *s
,int n1
,int n2
)
70 #define GDB_Print2(a,b,c) // define away to nothing
73 // If string is longer than w, cut out the middle.
76 int StringLen(char *s
)
85 static void StringFit(char *s
,int w
)
94 for(i
= 0; i
< w
; i
++)
96 s
[i
+ w
] = s
[StringLen(s
) - w
+ i
];
103 // ---------------------------------------------
104 // Generic routines for dealing with
105 // hex input, output, and parsing
106 // (Adapted from other stubs.)
108 NiosGDBGlobals gdb
= {0}; // not static: the ISR uses it!
110 static char dHexChars
[16] = "0123456789abcdef";
113 * HexCharToValue -- convert a characters
114 * to its hex value, or -1 if not.
116 char HexCharToValue(char c
)
120 if(c
>= '0' && c
<= '9')
122 else if(c
>= 'a' && c
<= 'f')
123 result
= c
- 'a' + 10;
124 else if(c
>= 'A' && c
<= 'F')
125 result
= c
- 'A' + 10;
132 * HexStringToValue -- convert a 2*byte_width string of characters
133 * to its little endian hex value,
135 * This routine is for strings of hex values
137 unsigned long HexStringToValue(char *c
, int byte_width
)
139 unsigned long result
=0;
143 while (i
< byte_width
)
145 a
= HexCharToValue(*c
++);
146 if (a
& 0x80) return a
;
147 b
= HexCharToValue(*c
++);
148 if (b
& 0x80) return b
;
149 b
= (a
<<4) | (b
&0x0f);
150 result
|= b
<< (i
*8);
157 * Hex2Value -- convert a non-hex char delimited string
158 * to its big endian hex value.
159 * This routine is for address and byte count values
162 char *Hex2Value(char *hexIn
, int *valueOut
)
171 digitValue
= HexCharToValue(c
);
178 value
= (value
<< 4) + digitValue
;
183 * HexToMem -- convert a string to a specified
184 * number of bytes in memory.
186 * JMB -- make this thing a bit smarter so
187 * that it selects the byte width to
188 * write based on the number of bytes
189 * and the destination address alignment.
190 * This is to support writes to non-byte enabled
191 * peripheral registers...I don't like it.
192 * Beware! there are cases where it wont work
194 char *HexToMem(char *hexIn
, char *memOut
, int memByteCount
)
202 //determine maximum byte width
203 if (((memByteCount
%2) != 0) || (((unsigned int)memOut
%2) != 0))
205 else if (((memByteCount
% 4) != 0) || (((unsigned int)memOut
% 4) != 0))
208 memOutS
= (short *)memOut
;
213 memOutL
= (long *)memOut
;
215 for(i
= 0; i
< memByteCount
; i
+=byte_width
)
217 x
= HexStringToValue(hexIn
,byte_width
);
218 hexIn
+= byte_width
*2;
222 *memOut
++ = (unsigned char) 0x000000ff & x
;
225 *memOutS
++ = (unsigned short) 0x0000ffff & x
;
231 //How could this ever happen???
239 char *MemToHex(char *memIn
, char *hexOut
, int memByteCount
)
244 unsigned short *memInS
=0;
245 unsigned long *memInL
=0;
247 //determine maximum byte width
248 if (((memByteCount
% 2) != 0) || (((unsigned int)memIn
% 2) != 0))
250 else if (((memByteCount
% 4) != 0) || (((unsigned int)memIn
% 4) != 0))
253 memInS
= (short *)memIn
;
258 memInL
= (long *)memIn
;
261 for(i
= 0; i
< memByteCount
; i
+=byte_width
)
275 //How would we get here?
279 for (j
=0; j
<byte_width
; j
++)
281 *hexOut
++ = dHexChars
[(x
&0x000000f0)>>4];
282 *hexOut
++ = dHexChars
[x
&0x0000000f];
292 //Send just the + or - to indicate
294 void GDBPutAck (char ack
)
296 if (gdb
.comlink
== ne_gdb_serial
)
299 #ifdef ethernet_exists
302 if (gdb
.host_ip_address
!= 0)
303 nr_plugs_send_to (gdb
.gdb_eth_plug
, &ack
, 1, 0,
305 gdb
.host_port_number
);
312 * Once a $ comes in, use GetGDBPacket to
313 * retrieve a full gdb packet, and verify
314 * checksum, and reply + or -.
316 int GetGDBPacket(char *aBuffer
)
323 if (gdb
.comlink
== ne_gdb_serial
)
325 while ((c
= GDBGetChar ()) != '$') ;
330 while(((c
= GDBGetChar()) != '#') && (length
< kTextBufferSize
))
335 aBuffer
[length
++] = c
;
340 x
= HexCharToValue(c
) << 4;
342 x
+= HexCharToValue(c
);
347 GDB_Print2("GetPacket %d",length
,0);
350 #ifdef ethernet_exists
354 // wait till beginning of packet
355 while (gdb
.textBuffer
[0] != '$') nr_plugs_idle();
361 //loop until packet terminator
362 //leave enough room for the checksum at the end
363 while (((c
= gdb
.textBuffer
[srcidx
++]) != '#') && (srcidx
< kTextBufferSize
-2))
369 aBuffer
[length
++] = c
;
372 c
= gdb
.textBuffer
[srcidx
++];
373 x
= HexCharToValue(c
) << 4;
374 c
= gdb
.textBuffer
[srcidx
++];
375 x
+= HexCharToValue (c
);
377 aBuffer
[length
++] = 0;
381 GDB_Print2("GetPacket %d",length
,0);
398 //Wait for acknowledgement
399 //Should we have some way of timing out???
401 //return FALSE if NACK
405 if (gdb
.comlink
== ne_gdb_serial
)
410 if (c
== '+') return (1);
411 else if (c
== '-') return (0);
416 #ifdef ethernet_exists
419 gdb
.ACKstatus
= ne_gdb_ack_waiting
;
423 if (gdb
.ACKstatus
== ne_gdb_ack_acked
)
425 gdb
.ACKstatus
= ne_gdb_ack_notwaiting
;
428 else if (gdb
.ACKstatus
== ne_gdb_ack_nacked
)
430 gdb
.ACKstatus
= ne_gdb_ack_notwaiting
;
441 * Send a packet, preceded by $,
442 * and followed by #checksum.
444 void PutGDBPacket(char *aBuffer
)
451 origPtr
= aBuffer
; // Remember in case we get a NACK
452 if (gdb
.comlink
== ne_gdb_serial
)
457 while((c
= *aBuffer
++) != 0)
463 GDBPutChar(dHexChars
[(checksum
>> 4) & 15]);
464 GDBPutChar(dHexChars
[checksum
& 15]);
469 if (++cnt
< GDB_RETRY_CNT
) goto startPutSerial
;
473 #ifdef ethernet_exists
476 if (gdb
.host_ip_address
!= 0)
484 if (c
==0) return; //there is no data in packet, so why bother sending
496 aBuffer
[i
++] = dHexChars
[(checksum
>> 4) & 15];
497 aBuffer
[i
++] = dHexChars
[checksum
& 15];
500 result
= nr_plugs_send_to (gdb
.gdb_eth_plug
, aBuffer
, i
, 0,
502 gdb
.host_port_number
);
506 if (++cnt
< GDB_RETRY_CNT
) goto startPutEth
;
508 aBuffer
[0] = 0; //clear packet to
515 int PutTracePacket(char *aBuffer
, int size
)
518 #ifdef ethernet_exists
524 if (gdb
.comlink
== ne_gdb_serial
)
529 for (i
=0; i
<size
; i
++)
531 checksum
+= aBuffer
[i
];
532 GDBPutChar (aBuffer
[i
]);
535 GDBPutChar(dHexChars
[(checksum
>> 4) & 15]);
536 GDBPutChar(dHexChars
[checksum
& 15]);
540 if (++cnt
< GDB_RETRY_CNT
) goto startPutSerial
;
544 #ifdef ethernet_exists
552 for (i
=0; i
<size
; i
++)
554 checksum
+= aBuffer
[i
];
562 aBuffer
[i
++] = dHexChars
[(checksum
>> 4) & 15];
563 aBuffer
[i
++] = dHexChars
[checksum
& 15];
566 if (gdb
.host_ip_address
!= 0)
568 result
= nr_plugs_send_to (gdb
.gdb_eth_plug
, aBuffer
, i
, 0,
570 gdb
.host_port_number
);
574 if (++cnt
< GDB_RETRY_CNT
) goto ethResend
;
580 if (cnt
< GDB_RETRY_CNT
) return 1;
584 void PutGDBOKPacket(char *aBuffer
)
589 PutGDBPacket(aBuffer
);
594 //some defines used exclusively for TRACE data xfer
595 //stepsize is the ascii hex step value i.e. twice the binary length
596 #define stepsize (2*(2*sizeof(int) + sizeof (char)))
597 #define MAX_TRACE_BYTES (((int)((2*MAX_DATA_SIZE-2)/stepsize))*stepsize)
599 int Trace_Read_Intercept (char *aBuffer
)
606 unsigned short dataAccumulate
;
610 w
++; //skip past the m
611 if (*w
++ == 't') //see if this is a special "memory trace" packet
613 w
= Hex2Value(w
,&byteCount
); //get the number of bytes to transfer
615 //turn byteCount to a multiple of stepsize
616 byteCount
= ((int)(byteCount
/stepsize
))*stepsize
;
618 //wait until fifo empties
619 nm_debug_get_reg(status
, np_debug_write_status
);
620 while (status
&np_debug_write_status_writing_mask
) nm_debug_get_reg(status
,np_debug_write_status
);
622 // loop through total size
623 while (byteCount
> 0)
625 w
=aBuffer
; //reset w to beginning of buffer
627 //calculate the number of bytes in this packet
628 if (byteCount
> MAX_TRACE_BYTES
) dataAccumulate
= MAX_TRACE_BYTES
;
629 else dataAccumulate
= byteCount
;
631 //insert data size at beginning of packet
632 w
= MemToHex((char *)&dataAccumulate
, w
, sizeof (dataAccumulate
));
634 byteCount
-= dataAccumulate
; //decrement byteCount
636 // accumulate a full buffer
637 for (cnt
=0; cnt
<dataAccumulate
; cnt
+=stepsize
)
640 nm_debug_set_reg (1, np_debug_read_sample
); //begin transaction
642 //wait until data is ready
643 nm_debug_get_reg (valid
, np_debug_data_valid
);
644 while (!valid
) nm_debug_get_reg(valid
,np_debug_data_valid
) ;
646 nm_debug_get_reg (data
, np_debug_trace_address
);
647 w
= MemToHex ((char *)&data
, w
, sizeof (int));
649 nm_debug_get_reg (data
, np_debug_trace_data
);
650 w
= MemToHex ((char *)&data
, w
, sizeof (int));
652 nm_debug_get_reg (data
, np_debug_trace_code
);
653 w
= MemToHex ((char *)&data
, w
, sizeof (char));
656 //if one of our data packets doesn't make it, stop sending them
657 //if (PutTracePacket (aBuffer,dataAccumulate+4) != 1) //+4 for size filed
659 /* kenw - My module can't handle the incoming data fast enough. So
660 * send this one packet, and wait for another mt command.
662 PutTracePacket (aBuffer
,dataAccumulate
+4);
672 #undef MAX_TRACE_BYTES
677 void DoGDBCommand_m(char *aBuffer
)
680 int startAddr
,byteCount
;
683 /* intercept some access to the dbg peripheral */
684 if (Trace_Read_Intercept (aBuffer
)) return;
689 w
= Hex2Value(w
,&startAddr
);
691 w
= Hex2Value(w
,&byteCount
);
693 if (byteCount
> MAX_DATA_SIZE
) byteCount
= MAX_DATA_SIZE
;
695 // mA,L -- request memory
697 w
= MemToHex((char *)startAddr
,w
,byteCount
);
698 PutGDBPacket(aBuffer
);
701 void DoGDBCommand_M(char *aBuffer
)
704 int startAddr
,byteCount
;
708 w
= Hex2Value(w
,&startAddr
);
710 w
= Hex2Value(w
,&byteCount
);
713 GDB_Print2("M from %x to %x",startAddr
,byteCount
);
715 // MA,L:values -- write to memory
717 w
= HexToMem(w
,(char *)startAddr
,byteCount
);
720 PutGDBOKPacket(aBuffer
);
723 int Debug_Read_Intercept (char *aBuffer
)
730 w
++; //skip past the g
731 if (*w
++ == 'g') //see if this is a special "register read" packet
733 w
= Hex2Value(w
,&index
); //get the index of the register to be read
735 nm_debug_get_reg (data
, index
);
737 //assemble the output packet
738 w
=aBuffer
; //reset w to beginning of buffer
739 w
= MemToHex((char *)&data
, w
, sizeof (data
));
743 PutTracePacket (aBuffer
,sizeof (data
) * 2);
750 // Return the values of all the registers
751 void DoGDBCommand_g(NiosGDBGlobals
*g
)
755 if (Debug_Read_Intercept (g
->textBuffer
)) return;
759 w
= MemToHex((char *)(&g
->registers
),w
,sizeof(g
->registers
));
760 PutGDBPacket(g
->textBuffer
);
761 GDB_Print2("Sent Registers",0,0);
764 int Debug_Write_Intercept (char *aBuffer
)
771 w
++; //skip past the g
772 if (*w
++ == 'g') //see if this is a special "register read" packet
774 w
= Hex2Value(w
,&index
); //get the index of the register to be written
776 w
= Hex2Value(w
,&data
);
778 nm_debug_set_reg (data
, index
);
782 PutGDBOKPacket(aBuffer
);
789 void DoGDBCommand_G(NiosGDBGlobals
*g
)
793 if (Debug_Write_Intercept (g
->textBuffer
)) return;
796 w
++; // skip past 'G'
797 w
= HexToMem(w
,(char *)(&g
->registers
), sizeof(g
->registers
) );
800 PutGDBOKPacket(g
->textBuffer
);
802 GDB_Print2("Received Registers",0,0);
805 // Return last signal value
806 void DoGDBCommand_qm(NiosGDBGlobals
*g
)
814 *w
++ = '3'; // make up a signal for now...
816 PutGDBPacket(g
->textBuffer
);
819 void DoGDBCommand_q(NiosGDBGlobals
*g
)
821 #ifdef na_ssram_detect_in
822 short int* ssram_exists
;
827 w
++; /* skip past the q */
832 /* handle intialization information */
833 /* is nios_ocd available? */
834 #ifdef nasys_debug_core
835 *w
++ = nasys_debug_core
+ '0';
841 /* determine if the SSRAM debugger board is
842 * physically present */
843 #ifdef na_ssram_detect_in
844 ssram_exists
= (short int*) na_ssram_detect_in
;
845 *w
++ = !(*ssram_exists
) + '0';
851 /* print out the max size of a trace packet */
853 sprintf (w
, "%04x", MAX_TRACE_BYTES
);
862 /* returns 1 if it was an OCD interrupt
863 * returns 0 if it was software breakpoint */
864 if (gdb
.trapNumber
== nasys_debug_core_irq
) {
879 PutGDBPacket(g
->textBuffer
);
883 void GDBInsertBreakpoint(NiosGDBGlobals
*g
,short *address
)
885 NiosGDBBreakpoint
*b
;
887 GDB_Print2("breakpoint 0x%x",(int)address
,0);
888 if(g
->breakpointCount
< kMaximumBreakpoints
)
890 b
= &g
->breakpoint
[g
->breakpointCount
++];
891 b
->address
= address
;
892 b
->oldContents
= *b
->address
;
893 *b
->address
= 0x7904;
897 void GDBRemoveBreakpoints(NiosGDBGlobals
*g
)
899 NiosGDBBreakpoint
*b
;
902 for(i
= 0; i
< g
->breakpointCount
; i
++)
904 b
= &g
->breakpoint
[i
];
905 *b
->address
= b
->oldContents
;
909 g
->breakpointCount
= 0;
912 int NiosInstructionIsTrap5(unsigned short instruction
)
914 return instruction
== 0x7905;
917 int NiosInstructionIsPrefix(unsigned short instruction
)
919 return (instruction
>> 11) == 0x13;
922 int NiosInstructionIsSkip(unsigned short instruction
)
927 op6
= (instruction
>> 10);
928 op11
= (instruction
>> 5);
930 return (op6
== 0x14 // SKP0
931 || op6
== 0x15 // SKP1
932 || op11
== 0x3f6 // SKPRz
933 || op11
== 0x3f7 // SKPS
934 || op11
== 0x3fa); // SKPRnz
937 int NiosInstructionIsBranch(unsigned short instruction
,short *pc
,short **branchTargetOut
)
942 short *branchTarget
= 0;
945 op4
= (instruction
>> 12);
946 op7
= (instruction
>> 9);
947 op10
= (instruction
>> 6);
949 if(op4
== 0x08) // BR, BSR
954 offset
= instruction
& 0x07ff;
955 if(offset
& 0x400) // sign extend
956 offset
|= 0xffffF800;
957 branchTarget
= pc
+ offset
+ 1; // short * gets x2 scaling automatically
959 else if(op10
== 0x1ff) // JMP, CALL
962 branchTarget
= (short *)(gdb
.registers
.r
[instruction
& 31] * 2);
964 else if(op7
== 0x3d) // JMPC, CALLC
967 branchTarget
= pc
+ 1 + (instruction
& 0x0ffff);
969 branchTarget
= (short *)((int)branchTarget
& 0xffffFFFc); // align 32...
971 branchTarget
= (short *)((int)branchTarget
& 0xFFFe); // align 16...
973 branchTarget
= (short *)(*(int *)branchTarget
);
977 *branchTargetOut
= branchTarget
;
982 // -------------------------
985 // "stepping" involves inserting a
986 // breakpoint at some reasonable
987 // spot later than the current program
990 // On the Nios processor, this is
991 // nontrivial. For example, we should
992 // not break up a PFX instruction.
994 void DoGDBCommand_s(NiosGDBGlobals
*g
)
1000 unsigned short instruction
;
1004 * First, if there's an argument to the packet,
1005 * set the new program-counter value
1010 if(HexCharToValue(*w
) >= 0)
1012 w
= Hex2Value(w
,&x
);
1013 g
->registers
.pc
= x
;
1017 * Scan forward to see what the
1018 * most appropriate location(s) for
1019 * a breakpoint will be.
1022 * 1. If *pc == PFX, break after modified instruction.
1023 * 2. If *pc == BR,BSR,JMP,CALL, break at destination
1024 * 3. If *pc == SKIP, break right after SKIP AND after optional instruction,
1025 which might, of course, be prefixed.
1026 * 4. Anything else, just drop in the breakpoint.
1029 pc
= (short *)(int)g
->registers
.pc
;
1034 if(NiosInstructionIsPrefix(instruction
))
1037 * PFX instruction: skip til after it
1039 while(NiosInstructionIsPrefix(instruction
))
1045 GDBInsertBreakpoint(g
,pc
+ 1);
1048 else if(NiosInstructionIsBranch(instruction
,pc
,&branchTarget
))
1050 GDBInsertBreakpoint(g
,branchTarget
);
1053 else if(NiosInstructionIsSkip(instruction
))
1059 * Skip gets to breaks: one after the skippable instruction,
1060 * and the skippable instruction itself.
1062 * Since Skips know how to skip over PFX's, we have to, too.
1064 pc2
= pc
; // the Skip instruction
1068 } while(NiosInstructionIsPrefix(*pc2
));
1069 // pc2 now points to first non-PFX after Skip
1070 GDBInsertBreakpoint(g
,pc2
+1);
1071 GDBInsertBreakpoint(g
,pc
+1);
1074 GDBInsertBreakpoint(g
,pc
+1); // the genericest case
1076 GDB_Print2("Program Steppingat 0x%x (%d)",g
->registers
.pc
,stepType
);
1079 // -----------------------------
1080 // Continue at address
1082 void DoGDBCommand_c(NiosGDBGlobals
*g
)
1088 w
++; // past command
1090 // Anything in the packet? if so,
1091 // use it to set the PC value
1093 if(HexCharToValue(*w
) >= 0)
1095 w
= Hex2Value(w
,&x
);
1096 g
->registers
.pc
= x
;
1099 GDB_Print2("Program Running at 0x%x",g
->registers
.pc
,0);
1102 // ----------------------
1105 void DoGDBCommand_k(NiosGDBGlobals
*g
)
1112 * If we've somehow skidded
1113 * to a stop just after a PFX instruction
1114 * back up the program counter by one.
1116 * That way, we can't end up with an accidentally-unprefixed
1119 * We do this just before we begin running
1120 * again, so that when the host queries our
1121 * registers, we report the place we actually
1125 void MaybeAdjustProgramCounter(NiosGDBGlobals
*g
)
1130 instruction
= *(short *)(int)(g
->registers
.pc
- 2);
1131 if(NiosInstructionIsPrefix(instruction
))
1132 g
->registers
.pc
-= 2;
1135 // If the *current* instruction is Trap5, we must skip it!
1136 instruction
= *(short *)(int)(g
->registers
.pc
);
1137 if(NiosInstructionIsTrap5(instruction
))
1138 g
->registers
.pc
+= 2;
1144 * GDBMainLoop - this is the main processing loop
1147 void GDBMainLoop (void)
1151 if (GetGDBPacket(gdb
.textBuffer
) > 0)
1154 GDB_Print2(gdb
.textBuffer
,0,0);
1155 switch(gdb
.textBuffer
[0])
1158 DoGDBCommand_s(&gdb
);
1162 case 'c': // continue
1163 DoGDBCommand_c(&gdb
);
1165 // if the PC is something other than 0, it's
1166 // probably ok to exit and go there
1169 if(gdb
.registers
.pc
)
1171 MaybeAdjustProgramCounter(&gdb
);
1176 case 'm': // memory read
1177 DoGDBCommand_m(gdb
.textBuffer
);
1180 case 'M': // memory set
1181 DoGDBCommand_M(gdb
.textBuffer
);
1184 case 'g': // registers read
1185 DoGDBCommand_g(&gdb
);
1188 case 'G': //registers set
1189 DoGDBCommand_G(&gdb
);
1192 case 'k': //kill process
1193 DoGDBCommand_k(&gdb
);
1196 case '?': // last exception value
1197 DoGDBCommand_qm(&gdb
);
1201 DoGDBCommand_q(&gdb
);
1204 default: // return empty packet, means "yeah yeah".
1205 gdb
.textBuffer
[0] = 0;
1206 PutGDBPacket(gdb
.textBuffer
);
1214 // ----------main------------
1219 for(i
= 0; i
< kTextBufferSize
; i
++)
1220 gdb
.textBuffer
[i
] = i
;
1222 GDBRemoveBreakpoints(&gdb
);
1226 * Inform the user that they need to add the symbol file for the application
1227 * that is just starting up. Display the .text .data .bss regions.
1229 if (gdb
.trapNumber
== 5) {
1230 extern struct task_struct
*_current_task
;
1231 sprintf(gdb
.textBuffer
,
1232 "\r\n\nGDB: trap 5 at 0x%08lX", gdb
.registers
.pc
);
1233 puts(gdb
.textBuffer
);
1234 if (_current_task
) {
1235 if ( _current_task
->mm
->start_code
> _etext
)
1236 sprintf(gdb
.textBuffer
,
1237 "\r\nGDB: Enter the following command in the nios-elf-gdb Console Window:"
1238 "\r\nGDB: add-symbol-file %s.abself 0x%08lX 0x%08lX 0x%08lX\r\n\n",
1239 _current_task
->comm
,
1240 (unsigned long)_current_task
->mm
->start_code
,
1241 (unsigned long)_current_task
->mm
->start_data
,
1242 (unsigned long)_current_task
->mm
->end_data
);
1244 sprintf(gdb
.textBuffer
,
1245 ", kernel process: %s\r\n", _current_task
->comm
);
1247 sprintf(gdb
.textBuffer
,
1248 ", kernel process unknown\r\n" );
1249 puts(gdb
.textBuffer
);
1253 // Send trapnumber for breakpoint encountered. No other signals.
1255 gdb
.textBuffer
[0] = 'S';
1256 gdb
.textBuffer
[1] = '0';
1258 #if nasys_debug_core
1259 if (gdb
.trapNumber
== nasys_debug_core_irq
)
1261 /* gdb.textBuffer[2] = '8'; */
1262 gdb
.textBuffer
[2] = '5';
1266 gdb
.textBuffer
[2] = '5';
1269 gdb
.textBuffer
[2] = '5';
1271 gdb
.textBuffer
[3] = 0;
1272 PutGDBPacket(gdb
.textBuffer
);
1274 GDB_Print2("Trap %2d At 0x%x",
1275 gdb
.trapNumber
,gdb
.registers
.pc
);
1276 // printf ("Trap %d at 0x%x\n",gdb.trapNumber,gdb.registers.pc);
1277 // for (i=0;i<32;i++) printf (" register[%d] = 0x%x\n",i,gdb.registers.r[i]);
1282 // +----------------------------------
1283 // | gdb_eth_proc -- gets called for udp packets
1284 // | from the host bound for gdb stub
1286 #ifdef ethernet_exists
1287 int gdb_eth_proc(int plug_handle
,
1294 char *buf
= (char *)payload
;
1295 // if this is a stop request, set a flag to stop after nr_plugs_idle
1296 // leave it up to the host to prevent stops from being sent while stub is running???
1298 if (*buf
== 3) gdb
.stop
= 1;
1300 // if we're waiting for an ack, check that here
1301 if (gdb
.ACKstatus
== ne_gdb_ack_waiting
)
1305 gdb
.ACKstatus
= ne_gdb_ack_acked
;
1308 else if (buf
[0] == '-')
1310 gdb
.ACKstatus
= ne_gdb_ack_nacked
;
1314 strcpy (gdb
.textBuffer
, buf
); //all commands should be zero terminated strings
1316 gdb
.textBuffer
[payload_length
] = 0; //terminate string
1318 gdb
.host_ip_address
=((ns_plugs_ip_packet
*)(p
[ne_plugs_ip
].header
))->source_ip_address
;
1319 gdb
.host_port_number
=((ns_plugs_udp_packet
*)(p
[ne_plugs_udp
].header
))->source_port
;
1324 int nr_dbg_plugs_idle (void)
1328 result
= nr_plugs_idle ();
1332 //;dgt2;tmp; asm ("TRAP #5");
1343 * All we really do here is install our trap # 3,
1344 * and call it once, so that we're living down in
1345 * the GDBMain, trap handler.
1348 extern int StubBreakpointHandler
;
1349 extern int StubHarmlessHandler
;
1350 #if nasys_debug_core
1351 extern int StubHWBreakpointHandler
;
1353 #ifdef nasys_debug_uart
1354 extern int StubUartHandler
;
1357 void gdb_local_install(int active
)
1359 unsigned int *vectorTable
;
1360 unsigned int stubBreakpointHandler
;
1361 unsigned int stubHarmlessHandler
;
1362 #if nasys_debug_core
1363 unsigned int stubHWBreakpointHandler
;
1366 gdb
.breakpointCount
= 0;
1367 gdb
.textBuffer
[0] = 0;
1369 vectorTable
= (int *)nasys_vector_table
;
1370 stubBreakpointHandler
= ( (unsigned int)(&StubBreakpointHandler
) ) >> 1;
1371 stubHarmlessHandler
= ( (unsigned int)(&StubHarmlessHandler
) ) >> 1;
1372 #if nasys_debug_core
1373 stubHWBreakpointHandler
= ( (unsigned int)(&StubHWBreakpointHandler
) ) >> 1;
1377 * Breakpoint & single step both go here
1379 vectorTable
[na_BreakpointTrap
] = stubBreakpointHandler
;
1380 vectorTable
[na_SingleStepTrap
] = stubBreakpointHandler
;
1381 vectorTable
[na_StartGDBTrap
] = active
? stubBreakpointHandler
: stubHarmlessHandler
;
1383 * If it exists, Hardware Breakpoint has a different entry point
1385 #if nasys_debug_core
1386 vectorTable
[na_debug_peripheral_irq
] = stubHWBreakpointHandler
;
1390 #ifdef nasys_debug_uart
1391 if (gdb
.comlink
== ne_gdb_serial
)
1393 np_uart
*uart
= (np_uart
*)nasys_debug_uart
;
1394 unsigned int stubUartHandler
= ((unsigned int)(&StubUartHandler
)) >> 1;
1396 vectorTable
[nasys_debug_uart_irq
] = stubUartHandler
; //set Uart int vector
1397 uart
->np_uartcontrol
= np_uartcontrol_irrdy_mask
; //enable Rx intr
1403 void nios_gdb_install(int active
)
1405 gdb
.comlink
= ne_gdb_serial
;
1406 gdb_local_install (active
);
1410 #ifdef ethernet_exists
1411 void nios_gdb_install_ethernet (int active
)
1414 host_16 host_port
= GDB_ETH_PORT
;
1416 gdb
.comlink
= ne_gdb_ethernet
;
1417 gdb_local_install (active
);
1419 result
= nr_plugs_create (&gdb
.gdb_eth_plug
, ne_plugs_udp
, host_port
, gdb_eth_proc
, 0, 0);
1420 //if unabled to open ethernet plug, switch back to default serial interface
1423 printf ("nr_plugs_create failed %d\n",result
);
1424 gdb
.comlink
= ne_gdb_serial
;
1427 result
= nr_plugs_connect (gdb
.gdb_eth_plug
, 0, -1, -1);
1430 printf ("nr_plugs_connect fialed %d\n",result
);
1431 gdb
.comlink
= ne_gdb_serial
;
1438 #ifdef nios_gdb_breakpoint
1439 #undef nios_gdb_breakpoint
1442 void nios_gdb_breakpoint(void)
1445 * If you arrived here, you didn't include
1446 * the file "nios_peripherals.h", which
1447 * defines nios_gdb_breakpoint as a
1448 * macro that expands to TRAP 5.
1450 * (No problem, you can step out
1453 //;dgt2;tmp; asm("TRAP 5");