* remote-mips.c: New file; implements MIPS remote debugging
protocol. * config/idt.mt: New file; uses remote-mips.c * configure.in (mips-idt-ecoff): New target; uses idt.mt. * mips-tdep.c (mips_fpu): New variable; controls use of MIPS floating point coprocessor. (mips_push_dummy_frame): If not mips_fpu, don't save floating point registers. (mips_pop_frame): If not mips_fpu, don't restore floating point registers. (_initialize_mips_tdep): New function; let the user reset mips_fpu variable. * tm-mips.h (EXTRACT_RETURN_VALUE, STORE_RETURN_VALUE): If not mips_fpu, don't use fp0 as floating point return register. (FIX_CALL_DUMMY): If not mips_fpu, don't save floating point registers. Also added remote-mips.c to .Sanitize file.
This commit is contained in:
parent
20f10b59ff
commit
c2a0f1cb8e
8 changed files with 260 additions and 55 deletions
|
@ -206,6 +206,7 @@ remote-adapt.c
|
||||||
remote-eb.c
|
remote-eb.c
|
||||||
remote-es1800.c
|
remote-es1800.c
|
||||||
remote-hms.c
|
remote-hms.c
|
||||||
|
remote-mips.c
|
||||||
remote-mm.c
|
remote-mm.c
|
||||||
remote-nindy.c
|
remote-nindy.c
|
||||||
remote-sim.c
|
remote-sim.c
|
||||||
|
|
|
@ -1,3 +1,23 @@
|
||||||
|
Mon Feb 22 15:21:54 1993 Ian Lance Taylor (ian@cygnus.com)
|
||||||
|
|
||||||
|
* remote-mips.c: New file; implements MIPS remote debugging
|
||||||
|
protocol.
|
||||||
|
* config/idt.mt: New file; uses remote-mips.c
|
||||||
|
* configure.in (mips-idt-ecoff): New target; uses idt.mt.
|
||||||
|
|
||||||
|
* mips-tdep.c (mips_fpu): New variable; controls use of MIPS
|
||||||
|
floating point coprocessor.
|
||||||
|
(mips_push_dummy_frame): If not mips_fpu, don't save floating
|
||||||
|
point registers.
|
||||||
|
(mips_pop_frame): If not mips_fpu, don't restore floating point
|
||||||
|
registers.
|
||||||
|
(_initialize_mips_tdep): New function; let the user reset mips_fpu
|
||||||
|
variable.
|
||||||
|
* tm-mips.h (EXTRACT_RETURN_VALUE, STORE_RETURN_VALUE): If not
|
||||||
|
mips_fpu, don't use fp0 as floating point return register.
|
||||||
|
(FIX_CALL_DUMMY): If not mips_fpu, don't save floating point
|
||||||
|
registers.
|
||||||
|
|
||||||
Mon Feb 22 07:54:03 1993 Mike Werner (mtw@poseidon.cygnus.com)
|
Mon Feb 22 07:54:03 1993 Mike Werner (mtw@poseidon.cygnus.com)
|
||||||
|
|
||||||
* gdb/testsuite: made modifications to testcases, etc., to allow
|
* gdb/testsuite: made modifications to testcases, etc., to allow
|
||||||
|
|
|
@ -66,6 +66,7 @@ i386v.mt
|
||||||
i386v32.mh
|
i386v32.mh
|
||||||
i386v4.mh
|
i386v4.mh
|
||||||
i386v4.mt
|
i386v4.mt
|
||||||
|
idt.mt
|
||||||
irix3.mh
|
irix3.mh
|
||||||
irix3.mt
|
irix3.mt
|
||||||
irix4.mh
|
irix4.mh
|
||||||
|
|
3
gdb/config/idt.mt
Normal file
3
gdb/config/idt.mt
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# Target: Big-endian IDT board.
|
||||||
|
TDEPFILES= mips-pinsn.o mips-tdep.o exec.o remote-mips.o
|
||||||
|
TM_FILE= tm-bigmips.h
|
|
@ -171,6 +171,7 @@ m88k-*-*) gdb_target=m88k ;;
|
||||||
|
|
||||||
mips-big-*) gdb_target=bigmips ;;
|
mips-big-*) gdb_target=bigmips ;;
|
||||||
mips-dec-*) gdb_target=decstation ;;
|
mips-dec-*) gdb_target=decstation ;;
|
||||||
|
mips-idt-ecoff) gdb_target=idt ;;
|
||||||
mips-little-*) gdb_target=littlemips ;;
|
mips-little-*) gdb_target=littlemips ;;
|
||||||
mips-sgi-*) gdb_target=irix3 ;;
|
mips-sgi-*) gdb_target=irix3 ;;
|
||||||
mips-sony-*) gdb_target=bigmips ;;
|
mips-sony-*) gdb_target=bigmips ;;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* Target-dependent code for the MIPS architecture, for GDB, the GNU Debugger.
|
/* Target-dependent code for the MIPS architecture, for GDB, the GNU Debugger.
|
||||||
Copyright 1988, 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
|
Copyright 1988, 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
|
||||||
Contributed by Alessandro Forin(af@cs.cmu.edu) at CMU
|
Contributed by Alessandro Forin(af@cs.cmu.edu) at CMU
|
||||||
and by Per Bothner(bothner@cs.wisc.edu) at U.Wisconsin.
|
and by Per Bothner(bothner@cs.wisc.edu) at U.Wisconsin.
|
||||||
|
|
||||||
|
@ -55,6 +55,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* Some MIPS boards don't support floating point, so we permit the
|
||||||
|
user to turn it off. */
|
||||||
|
int mips_fpu = 1;
|
||||||
|
|
||||||
#define PROC_LOW_ADDR(proc) ((proc)->pdr.adr) /* least address */
|
#define PROC_LOW_ADDR(proc) ((proc)->pdr.adr) /* least address */
|
||||||
#define PROC_HIGH_ADDR(proc) ((proc)->pdr.iline) /* upper address bound */
|
#define PROC_HIGH_ADDR(proc) ((proc)->pdr.iline) /* upper address bound */
|
||||||
#define PROC_FRAME_OFFSET(proc) ((proc)->pdr.frameoffset)
|
#define PROC_FRAME_OFFSET(proc) ((proc)->pdr.frameoffset)
|
||||||
|
@ -316,8 +320,6 @@ init_extra_frame_info(fci)
|
||||||
/* r0 bit means kernel trap */
|
/* r0 bit means kernel trap */
|
||||||
int kernel_trap = PROC_REG_MASK(proc_desc) & 1;
|
int kernel_trap = PROC_REG_MASK(proc_desc) & 1;
|
||||||
|
|
||||||
if (fci->frame == 0)
|
|
||||||
{
|
|
||||||
/* Fixup frame-pointer - only needed for top frame */
|
/* Fixup frame-pointer - only needed for top frame */
|
||||||
/* This may not be quite right, if proc has a real frame register */
|
/* This may not be quite right, if proc has a real frame register */
|
||||||
if (fci->pc == PROC_LOW_ADDR(proc_desc))
|
if (fci->pc == PROC_LOW_ADDR(proc_desc))
|
||||||
|
@ -325,7 +327,6 @@ init_extra_frame_info(fci)
|
||||||
else
|
else
|
||||||
fci->frame = READ_FRAME_REG(fci, PROC_FRAME_REG(proc_desc))
|
fci->frame = READ_FRAME_REG(fci, PROC_FRAME_REG(proc_desc))
|
||||||
+ PROC_FRAME_OFFSET(proc_desc);
|
+ PROC_FRAME_OFFSET(proc_desc);
|
||||||
}
|
|
||||||
|
|
||||||
if (proc_desc == &temp_proc_desc)
|
if (proc_desc == &temp_proc_desc)
|
||||||
*fci->saved_regs = temp_saved_regs;
|
*fci->saved_regs = temp_saved_regs;
|
||||||
|
@ -381,11 +382,14 @@ init_extra_frame_info(fci)
|
||||||
arguments without difficulty. */
|
arguments without difficulty. */
|
||||||
|
|
||||||
FRAME
|
FRAME
|
||||||
setup_arbitrary_frame (stack, pc)
|
setup_arbitrary_frame (argc, argv)
|
||||||
FRAME_ADDR stack;
|
int argc;
|
||||||
CORE_ADDR pc;
|
FRAME_ADDR *argv;
|
||||||
{
|
{
|
||||||
return create_new_frame (stack, pc);
|
if (argc != 2)
|
||||||
|
error ("MIPS frame specifications require two arguments: sp and pc");
|
||||||
|
|
||||||
|
return create_new_frame (argv[0], argv[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -470,12 +474,12 @@ mips_push_dummy_frame()
|
||||||
* Saved D18 (i.e. F19, F18)
|
* Saved D18 (i.e. F19, F18)
|
||||||
* ...
|
* ...
|
||||||
* Saved D0 (i.e. F1, F0)
|
* Saved D0 (i.e. F1, F0)
|
||||||
* CALL_DUMMY (subroutine stub; see m-mips.h)
|
* CALL_DUMMY (subroutine stub; see tm-mips.h)
|
||||||
* Parameter build area (not yet implemented)
|
* Parameter build area (not yet implemented)
|
||||||
* (low memory)
|
* (low memory)
|
||||||
*/
|
*/
|
||||||
PROC_REG_MASK(proc_desc) = GEN_REG_SAVE_MASK;
|
PROC_REG_MASK(proc_desc) = GEN_REG_SAVE_MASK;
|
||||||
PROC_FREG_MASK(proc_desc) = FLOAT_REG_SAVE_MASK;
|
PROC_FREG_MASK(proc_desc) = mips_fpu ? FLOAT_REG_SAVE_MASK : 0;
|
||||||
PROC_REG_OFFSET(proc_desc) = /* offset of (Saved R31) from FP */
|
PROC_REG_OFFSET(proc_desc) = /* offset of (Saved R31) from FP */
|
||||||
-sizeof(long) - 4 * SPECIAL_REG_SAVE_COUNT;
|
-sizeof(long) - 4 * SPECIAL_REG_SAVE_COUNT;
|
||||||
PROC_FREG_OFFSET(proc_desc) = /* offset of (Saved D18) from FP */
|
PROC_FREG_OFFSET(proc_desc) = /* offset of (Saved D18) from FP */
|
||||||
|
@ -507,9 +511,11 @@ mips_push_dummy_frame()
|
||||||
write_memory (sp - 8, (char *)&buffer, sizeof(REGISTER_TYPE));
|
write_memory (sp - 8, (char *)&buffer, sizeof(REGISTER_TYPE));
|
||||||
buffer = read_register (LO_REGNUM);
|
buffer = read_register (LO_REGNUM);
|
||||||
write_memory (sp - 12, (char *)&buffer, sizeof(REGISTER_TYPE));
|
write_memory (sp - 12, (char *)&buffer, sizeof(REGISTER_TYPE));
|
||||||
buffer = read_register (FCRCS_REGNUM);
|
buffer = read_register (mips_fpu ? FCRCS_REGNUM : ZERO_REGNUM);
|
||||||
write_memory (sp - 16, (char *)&buffer, sizeof(REGISTER_TYPE));
|
write_memory (sp - 16, (char *)&buffer, sizeof(REGISTER_TYPE));
|
||||||
sp -= 4 * (GEN_REG_SAVE_COUNT+FLOAT_REG_SAVE_COUNT+SPECIAL_REG_SAVE_COUNT);
|
sp -= 4 * (GEN_REG_SAVE_COUNT
|
||||||
|
+ (mips_fpu ? FLOAT_REG_SAVE_COUNT : 0)
|
||||||
|
+ SPECIAL_REG_SAVE_COUNT);
|
||||||
write_register (SP_REGNUM, sp);
|
write_register (SP_REGNUM, sp);
|
||||||
PROC_LOW_ADDR(proc_desc) = sp - CALL_DUMMY_SIZE + CALL_DUMMY_START_OFFSET;
|
PROC_LOW_ADDR(proc_desc) = sp - CALL_DUMMY_SIZE + CALL_DUMMY_START_OFFSET;
|
||||||
PROC_HIGH_ADDR(proc_desc) = sp;
|
PROC_HIGH_ADDR(proc_desc) = sp;
|
||||||
|
@ -568,6 +574,7 @@ mips_pop_frame()
|
||||||
|
|
||||||
write_register (HI_REGNUM, read_memory_integer(new_sp - 8, 4));
|
write_register (HI_REGNUM, read_memory_integer(new_sp - 8, 4));
|
||||||
write_register (LO_REGNUM, read_memory_integer(new_sp - 12, 4));
|
write_register (LO_REGNUM, read_memory_integer(new_sp - 12, 4));
|
||||||
|
if (mips_fpu)
|
||||||
write_register (FCRCS_REGNUM, read_memory_integer(new_sp - 16, 4));
|
write_register (FCRCS_REGNUM, read_memory_integer(new_sp - 16, 4));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -686,7 +693,11 @@ isa_NAN(p, len)
|
||||||
}
|
}
|
||||||
else if (len == 8)
|
else if (len == 8)
|
||||||
{
|
{
|
||||||
|
#if TARGET_BYTE_ORDER == BIG_ENDIAN
|
||||||
|
exponent = *p;
|
||||||
|
#else
|
||||||
exponent = *(p+1);
|
exponent = *(p+1);
|
||||||
|
#endif
|
||||||
exponent = exponent << 1 >> (32 - DOUBLE_EXP_BITS - 1);
|
exponent = exponent << 1 >> (32 - DOUBLE_EXP_BITS - 1);
|
||||||
return ((exponent == -1) || (! exponent && *p * *(p+1)));
|
return ((exponent == -1) || (! exponent && *p * *(p+1)));
|
||||||
}
|
}
|
||||||
|
@ -739,3 +750,17 @@ mips_skip_prologue(pc)
|
||||||
|
|
||||||
return pc;
|
return pc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Let the user turn off floating point. */
|
||||||
|
|
||||||
|
void
|
||||||
|
_initialize_mips_tdep ()
|
||||||
|
{
|
||||||
|
add_show_from_set
|
||||||
|
(add_set_cmd ("mips_fpu", class_support, var_boolean,
|
||||||
|
(char *) &mips_fpu,
|
||||||
|
"Set use of floating point coprocessor.\n\
|
||||||
|
Turn off to avoid using floating point instructions when calling functions\n\
|
||||||
|
or dealing with return values.", &setlist),
|
||||||
|
&showlist);
|
||||||
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@ static int mips_cksum PARAMS ((const unsigned char *hdr,
|
||||||
int len));
|
int len));
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mips_send_packet PARAMS ((const char *s));
|
mips_send_packet PARAMS ((const char *s, int get_ack));
|
||||||
|
|
||||||
static int
|
static int
|
||||||
mips_receive_packet PARAMS ((char *buff));
|
mips_receive_packet PARAMS ((char *buff));
|
||||||
|
@ -57,6 +57,9 @@ static int
|
||||||
mips_request PARAMS ((char cmd, unsigned int addr, unsigned int data,
|
mips_request PARAMS ((char cmd, unsigned int addr, unsigned int data,
|
||||||
int *perr));
|
int *perr));
|
||||||
|
|
||||||
|
static void
|
||||||
|
mips_initialize PARAMS ((void));
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mips_open PARAMS ((char *name, int from_tty));
|
mips_open PARAMS ((char *name, int from_tty));
|
||||||
|
|
||||||
|
@ -246,6 +249,9 @@ extern struct target_ops mips_ops;
|
||||||
/* Set to 1 if the target is open. */
|
/* Set to 1 if the target is open. */
|
||||||
static int mips_is_open;
|
static int mips_is_open;
|
||||||
|
|
||||||
|
/* Set to 1 while the connection is being initialized. */
|
||||||
|
static int mips_initializing;
|
||||||
|
|
||||||
/* The next sequence number to send. */
|
/* The next sequence number to send. */
|
||||||
static int mips_send_seq;
|
static int mips_send_seq;
|
||||||
|
|
||||||
|
@ -263,7 +269,7 @@ static int mips_send_retries = 10;
|
||||||
static int mips_syn_garbage = 1050;
|
static int mips_syn_garbage = 1050;
|
||||||
|
|
||||||
/* The time to wait for a packet, in seconds. */
|
/* The time to wait for a packet, in seconds. */
|
||||||
static int mips_receive_wait = 30;
|
static int mips_receive_wait = 5;
|
||||||
|
|
||||||
/* Set if we have sent a packet to the board but have not yet received
|
/* Set if we have sent a packet to the board but have not yet received
|
||||||
a reply. */
|
a reply. */
|
||||||
|
@ -273,13 +279,25 @@ static int mips_need_reply = 0;
|
||||||
static int mips_debug = 0;
|
static int mips_debug = 0;
|
||||||
|
|
||||||
/* Read a character from the remote, aborting on error. Returns -2 on
|
/* Read a character from the remote, aborting on error. Returns -2 on
|
||||||
timeout (since that's what serial_readchar returns). */
|
timeout (since that's what serial_readchar returns). FIXME: If we
|
||||||
|
see the string "<IDT>" from the board, then we are debugging on the
|
||||||
|
main console port, and we have somehow dropped out of remote
|
||||||
|
debugging mode. In this case, we automatically go back in to
|
||||||
|
remote debugging mode. This is a hack, put in because I can't find
|
||||||
|
any way for a program running on the remote board to terminate
|
||||||
|
without also ending remote debugging mode. I assume users won't
|
||||||
|
have any trouble with this; for one thing, the IDT documentation
|
||||||
|
generally assumes that the remote debugging port is not the console
|
||||||
|
port. This is, however, very convenient for DejaGnu when you only
|
||||||
|
have one connected serial port. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
mips_readchar (timeout)
|
mips_readchar (timeout)
|
||||||
int timeout;
|
int timeout;
|
||||||
{
|
{
|
||||||
int ch;
|
int ch;
|
||||||
|
static int state = 0;
|
||||||
|
static char nextstate[5] = { '<', 'I', 'D', 'T', '>' };
|
||||||
|
|
||||||
ch = serial_readchar (timeout);
|
ch = serial_readchar (timeout);
|
||||||
if (ch == EOF)
|
if (ch == EOF)
|
||||||
|
@ -293,6 +311,34 @@ mips_readchar (timeout)
|
||||||
else
|
else
|
||||||
printf_filtered ("Timed out in read\n");
|
printf_filtered ("Timed out in read\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If we have seen <IDT> and we either time out, or we see a @
|
||||||
|
(which was echoed from a packet we sent), reset the board as
|
||||||
|
described above. The first character in a packet after the SYN
|
||||||
|
(which is not echoed) is always an @ unless the packet is more
|
||||||
|
than 64 characters long, which ours never are. */
|
||||||
|
if ((ch == -2 || ch == '@')
|
||||||
|
&& state == 5
|
||||||
|
&& ! mips_initializing)
|
||||||
|
{
|
||||||
|
if (mips_debug > 0)
|
||||||
|
printf_filtered ("Reinitializing MIPS debugging mode\n");
|
||||||
|
serial_write ("\rdb tty0\r", sizeof "\rdb tty0\r" - 1);
|
||||||
|
sleep (1);
|
||||||
|
|
||||||
|
mips_need_reply = 0;
|
||||||
|
mips_initialize ();
|
||||||
|
|
||||||
|
state = 0;
|
||||||
|
|
||||||
|
error ("Remote board reset");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ch == nextstate[state])
|
||||||
|
++state;
|
||||||
|
else
|
||||||
|
state = 0;
|
||||||
|
|
||||||
return ch;
|
return ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -327,7 +373,11 @@ mips_receive_header (hdr, pgarbage, ch, timeout)
|
||||||
what the program is outputting, if the debugging is
|
what the program is outputting, if the debugging is
|
||||||
being done on the console port. FIXME: Perhaps this
|
being done on the console port. FIXME: Perhaps this
|
||||||
should be filtered? */
|
should be filtered? */
|
||||||
|
if (! mips_initializing || mips_debug > 0)
|
||||||
|
{
|
||||||
putchar (ch);
|
putchar (ch);
|
||||||
|
fflush (stdout);
|
||||||
|
}
|
||||||
|
|
||||||
++*pgarbage;
|
++*pgarbage;
|
||||||
if (*pgarbage > mips_syn_garbage)
|
if (*pgarbage > mips_syn_garbage)
|
||||||
|
@ -416,8 +466,9 @@ mips_cksum (hdr, data, len)
|
||||||
/* Send a packet containing the given ASCII string. */
|
/* Send a packet containing the given ASCII string. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mips_send_packet (s)
|
mips_send_packet (s, get_ack)
|
||||||
const char *s;
|
const char *s;
|
||||||
|
int get_ack;
|
||||||
{
|
{
|
||||||
unsigned int len;
|
unsigned int len;
|
||||||
unsigned char *packet;
|
unsigned char *packet;
|
||||||
|
@ -446,6 +497,9 @@ mips_send_packet (s)
|
||||||
the sequence number we expect in the acknowledgement. */
|
the sequence number we expect in the acknowledgement. */
|
||||||
mips_send_seq = (mips_send_seq + 1) % SEQ_MODULOS;
|
mips_send_seq = (mips_send_seq + 1) % SEQ_MODULOS;
|
||||||
|
|
||||||
|
if (! get_ack)
|
||||||
|
return;
|
||||||
|
|
||||||
/* We can only have one outstanding data packet, so we just wait for
|
/* We can only have one outstanding data packet, so we just wait for
|
||||||
the acknowledgement here. Keep retransmitting the packet until
|
the acknowledgement here. Keep retransmitting the packet until
|
||||||
we get one, or until we've tried too many times. */
|
we get one, or until we've tried too many times. */
|
||||||
|
@ -728,7 +782,7 @@ mips_request (cmd, addr, data, perr)
|
||||||
if (mips_need_reply)
|
if (mips_need_reply)
|
||||||
fatal ("mips_request: Trying to send command before reply");
|
fatal ("mips_request: Trying to send command before reply");
|
||||||
sprintf (buff, "0x0 %c 0x%x 0x%x", cmd, addr, data);
|
sprintf (buff, "0x0 %c 0x%x 0x%x", cmd, addr, data);
|
||||||
mips_send_packet (buff);
|
mips_send_packet (buff, 1);
|
||||||
mips_need_reply = 1;
|
mips_need_reply = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -766,6 +820,64 @@ mips_request (cmd, addr, data, perr)
|
||||||
return rresponse;
|
return rresponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Initialize a new connection to the MIPS board, and make sure we are
|
||||||
|
really connected. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
mips_initialize ()
|
||||||
|
{
|
||||||
|
char cr;
|
||||||
|
int hold_wait;
|
||||||
|
int tries;
|
||||||
|
char buff[DATA_MAXLEN + 1];
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (mips_initializing)
|
||||||
|
return;
|
||||||
|
|
||||||
|
mips_initializing = 1;
|
||||||
|
|
||||||
|
mips_send_seq = 0;
|
||||||
|
mips_receive_seq = 0;
|
||||||
|
|
||||||
|
/* The board seems to want to send us a packet. I don't know what
|
||||||
|
it means. The packet seems to be triggered by a carriage return
|
||||||
|
character, although perhaps any character would do. */
|
||||||
|
cr = '\r';
|
||||||
|
serial_write (&cr, 1);
|
||||||
|
|
||||||
|
hold_wait = mips_receive_wait;
|
||||||
|
mips_receive_wait = 3;
|
||||||
|
|
||||||
|
tries = 0;
|
||||||
|
while (catch_errors (mips_receive_packet, buff, (char *) NULL) == 0)
|
||||||
|
{
|
||||||
|
char cc;
|
||||||
|
|
||||||
|
if (tries > 0)
|
||||||
|
error ("Could not connect to target");
|
||||||
|
++tries;
|
||||||
|
|
||||||
|
/* We did not receive the packet we expected; try resetting the
|
||||||
|
board and trying again. */
|
||||||
|
printf_filtered ("Failed to initialize; trying to reset board\n");
|
||||||
|
cc = '\003';
|
||||||
|
serial_write (&cc, 1);
|
||||||
|
sleep (2);
|
||||||
|
serial_write ("\rdb tty0\r", sizeof "\rdb tty0\r" - 1);
|
||||||
|
sleep (1);
|
||||||
|
cr = '\r';
|
||||||
|
serial_write (&cr, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
mips_receive_wait = hold_wait;
|
||||||
|
mips_initializing = 0;
|
||||||
|
|
||||||
|
/* If this doesn't call error, we have connected; we don't care if
|
||||||
|
the request itself succeeds or fails. */
|
||||||
|
mips_request ('r', (unsigned int) 0, (unsigned int) 0, &err);
|
||||||
|
}
|
||||||
|
|
||||||
/* Open a connection to the remote board. */
|
/* Open a connection to the remote board. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -773,10 +885,6 @@ mips_open (name, from_tty)
|
||||||
char *name;
|
char *name;
|
||||||
int from_tty;
|
int from_tty;
|
||||||
{
|
{
|
||||||
int err;
|
|
||||||
char cr;
|
|
||||||
char buff[DATA_MAXLEN + 1];
|
|
||||||
|
|
||||||
if (name == 0)
|
if (name == 0)
|
||||||
error (
|
error (
|
||||||
"To open a MIPS remote debugging connection, you need to specify what serial\n\
|
"To open a MIPS remote debugging connection, you need to specify what serial\n\
|
||||||
|
@ -785,28 +893,20 @@ device is attached to the target board (e.g., /dev/ttya).");
|
||||||
target_preopen (from_tty);
|
target_preopen (from_tty);
|
||||||
|
|
||||||
if (mips_is_open)
|
if (mips_is_open)
|
||||||
mips_close (0);
|
unpush_target (&mips_ops);
|
||||||
|
|
||||||
if (serial_open (name) == 0)
|
if (serial_open (name) == 0)
|
||||||
perror_with_name (name);
|
perror_with_name (name);
|
||||||
|
|
||||||
mips_is_open = 1;
|
mips_is_open = 1;
|
||||||
|
|
||||||
/* The board seems to want to send us a packet. I don't know what
|
mips_initialize ();
|
||||||
it means. */
|
|
||||||
cr = '\r';
|
|
||||||
serial_write (&cr, 1);
|
|
||||||
mips_receive_packet (buff);
|
|
||||||
|
|
||||||
/* If this doesn't call error, we have connected; we don't care if
|
|
||||||
the request itself succeeds or fails. */
|
|
||||||
mips_request ('r', (unsigned int) 0, (unsigned int) 0, &err);
|
|
||||||
|
|
||||||
if (from_tty)
|
if (from_tty)
|
||||||
printf ("Remote MIPS debugging using %s\n", name);
|
printf ("Remote MIPS debugging using %s\n", name);
|
||||||
push_target (&mips_ops); /* Switch to using remote target now */
|
push_target (&mips_ops); /* Switch to using remote target now */
|
||||||
|
|
||||||
start_remote (); /* Initialize gdb process mechanisms */
|
/* FIXME: Should we call start_remote here? */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Close a connection to the remote board. */
|
/* Close a connection to the remote board. */
|
||||||
|
@ -817,11 +917,14 @@ mips_close (quitting)
|
||||||
{
|
{
|
||||||
if (mips_is_open)
|
if (mips_is_open)
|
||||||
{
|
{
|
||||||
/* Get the board out of remote debugging mode. */
|
int err;
|
||||||
mips_request ('x', (unsigned int) 0, (unsigned int) 0,
|
|
||||||
(int *) NULL);
|
|
||||||
serial_close ();
|
|
||||||
mips_is_open = 0;
|
mips_is_open = 0;
|
||||||
|
|
||||||
|
/* Get the board out of remote debugging mode. */
|
||||||
|
mips_request ('x', (unsigned int) 0, (unsigned int) 0, &err);
|
||||||
|
|
||||||
|
serial_close ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -852,7 +955,7 @@ mips_resume (step, siggnal)
|
||||||
siggnal);
|
siggnal);
|
||||||
|
|
||||||
mips_request (step ? 's' : 'c',
|
mips_request (step ? 's' : 'c',
|
||||||
(unsigned int) read_register (PC_REGNUM),
|
(unsigned int) 1,
|
||||||
(unsigned int) 0,
|
(unsigned int) 0,
|
||||||
(int *) NULL);
|
(int *) NULL);
|
||||||
}
|
}
|
||||||
|
@ -1099,6 +1202,28 @@ mips_files_info (ignore)
|
||||||
printf ("Debugging a MIPS board over a serial line.\n");
|
printf ("Debugging a MIPS board over a serial line.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Kill the process running on the board. This will actually only
|
||||||
|
work if we are doing remote debugging over the console input. I
|
||||||
|
think that if IDT/sim had the remote debug interrupt enabled on the
|
||||||
|
right port, we could interrupt the process with a break signal. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
mips_kill ()
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
if (mips_is_open)
|
||||||
|
{
|
||||||
|
char cc;
|
||||||
|
|
||||||
|
/* Send a ^C. */
|
||||||
|
cc = '\003';
|
||||||
|
serial_write (&cc, 1);
|
||||||
|
sleep (1);
|
||||||
|
target_mourn_inferior ();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/* Load an executable onto the board. */
|
/* Load an executable onto the board. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1109,6 +1234,7 @@ mips_load (args, from_tty)
|
||||||
bfd *abfd;
|
bfd *abfd;
|
||||||
asection *s;
|
asection *s;
|
||||||
int err;
|
int err;
|
||||||
|
CORE_ADDR text;
|
||||||
|
|
||||||
abfd = bfd_openr (args, 0);
|
abfd = bfd_openr (args, 0);
|
||||||
if (abfd == (bfd *) NULL)
|
if (abfd == (bfd *) NULL)
|
||||||
|
@ -1117,6 +1243,7 @@ mips_load (args, from_tty)
|
||||||
if (bfd_check_format (abfd, bfd_object) == 0)
|
if (bfd_check_format (abfd, bfd_object) == 0)
|
||||||
error ("%s: Not an object file", args);
|
error ("%s: Not an object file", args);
|
||||||
|
|
||||||
|
text = UINT_MAX;
|
||||||
for (s = abfd->sections; s != (asection *) NULL; s = s->next)
|
for (s = abfd->sections; s != (asection *) NULL; s = s->next)
|
||||||
{
|
{
|
||||||
if ((s->flags & SEC_LOAD) != 0)
|
if ((s->flags & SEC_LOAD) != 0)
|
||||||
|
@ -1140,6 +1267,10 @@ mips_load (args, from_tty)
|
||||||
mips_xfer_memory (vma, buffer, size, 1, &mips_ops);
|
mips_xfer_memory (vma, buffer, size, 1, &mips_ops);
|
||||||
|
|
||||||
do_cleanups (old_chain);
|
do_cleanups (old_chain);
|
||||||
|
|
||||||
|
if ((bfd_get_section_flags (abfd, s) & SEC_CODE) != 0
|
||||||
|
&& vma < text)
|
||||||
|
text = vma;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1152,7 +1283,13 @@ mips_load (args, from_tty)
|
||||||
|
|
||||||
bfd_close (abfd);
|
bfd_close (abfd);
|
||||||
|
|
||||||
/* FIXME: Should we call symbol_file_add here? */
|
/* FIXME: Should we call symbol_file_add here? The local variable
|
||||||
|
text exists just for this call. Making the call seems to confuse
|
||||||
|
gdb if more than one file is loaded in. Perhaps passing MAINLINE
|
||||||
|
as 1 would fix this, but it's not clear that that is correct
|
||||||
|
either since it is possible to load several files onto the board.
|
||||||
|
|
||||||
|
symbol_file_add (args, from_tty, text, 0, 0, 0); */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Start running on the target board. */
|
/* Start running on the target board. */
|
||||||
|
@ -1165,7 +1302,6 @@ mips_create_inferior (execfile, args, env)
|
||||||
{
|
{
|
||||||
CORE_ADDR entry_pt;
|
CORE_ADDR entry_pt;
|
||||||
|
|
||||||
/* FIXME: Actually, we probably could pass arguments. */
|
|
||||||
if (args && *args)
|
if (args && *args)
|
||||||
error ("Can't pass arguments to remote MIPS board.");
|
error ("Can't pass arguments to remote MIPS board.");
|
||||||
|
|
||||||
|
@ -1176,6 +1312,8 @@ mips_create_inferior (execfile, args, env)
|
||||||
|
|
||||||
init_wait_for_inferior ();
|
init_wait_for_inferior ();
|
||||||
|
|
||||||
|
/* FIXME: Should we set inferior_pid here? */
|
||||||
|
|
||||||
proceed (entry_pt, -1, 0);
|
proceed (entry_pt, -1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1213,7 +1351,7 @@ Specify the serial device it is connected to (e.g., /dev/ttya).", /* to_doc */
|
||||||
NULL, /* to_terminal_ours_for_output */
|
NULL, /* to_terminal_ours_for_output */
|
||||||
NULL, /* to_terminal_ours */
|
NULL, /* to_terminal_ours */
|
||||||
NULL, /* to_terminal_info */
|
NULL, /* to_terminal_info */
|
||||||
NULL, /* to_kill */
|
mips_kill, /* to_kill */
|
||||||
mips_load, /* to_load */
|
mips_load, /* to_load */
|
||||||
NULL, /* to_lookup_symbol */
|
NULL, /* to_lookup_symbol */
|
||||||
mips_create_inferior, /* to_create_inferior */
|
mips_create_inferior, /* to_create_inferior */
|
||||||
|
|
|
@ -34,6 +34,11 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
/* Floating point is IEEE compliant */
|
/* Floating point is IEEE compliant */
|
||||||
#define IEEE_FLOAT
|
#define IEEE_FLOAT
|
||||||
|
|
||||||
|
/* Some MIPS boards are provided both with and without a floating
|
||||||
|
point coprocessor; we provide a user settable variable to tell gdb
|
||||||
|
whether there is one or not. */
|
||||||
|
extern int mips_fpu;
|
||||||
|
|
||||||
/* Define this if the C compiler puts an underscore at the front
|
/* Define this if the C compiler puts an underscore at the front
|
||||||
of external names before giving them to the linker. */
|
of external names before giving them to the linker. */
|
||||||
|
|
||||||
|
@ -205,13 +210,13 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
into VALBUF. XXX floats */
|
into VALBUF. XXX floats */
|
||||||
|
|
||||||
#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
|
#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
|
||||||
bcopy (REGBUF+REGISTER_BYTE (TYPE_CODE (TYPE) == TYPE_CODE_FLT ? FP0_REGNUM : 2), VALBUF, TYPE_LENGTH (TYPE))
|
bcopy (REGBUF + REGISTER_BYTE ((TYPE_CODE (TYPE) == TYPE_CODE_FLT && mips_fpu) ? FP0_REGNUM : 2), VALBUF, TYPE_LENGTH (TYPE))
|
||||||
|
|
||||||
/* Write into appropriate registers a function return value
|
/* Write into appropriate registers a function return value
|
||||||
of type TYPE, given in virtual format. */
|
of type TYPE, given in virtual format. */
|
||||||
|
|
||||||
#define STORE_RETURN_VALUE(TYPE,VALBUF) \
|
#define STORE_RETURN_VALUE(TYPE,VALBUF) \
|
||||||
write_register_bytes (REGISTER_BYTE (TYPE_CODE (TYPE) == TYPE_CODE_FLT ? FP0_REGNUM : 2), VALBUF, TYPE_LENGTH (TYPE))
|
write_register_bytes (REGISTER_BYTE ((TYPE_CODE (TYPE) == TYPE_CODE_FLT && mips_fpu) ? FP0_REGNUM : 2), VALBUF, TYPE_LENGTH (TYPE))
|
||||||
|
|
||||||
/* Extract from an array REGBUF containing the (raw) register state
|
/* Extract from an array REGBUF containing the (raw) register state
|
||||||
the address in which a function should return its structure value,
|
the address in which a function should return its structure value,
|
||||||
|
@ -294,11 +299,11 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
0, /* nop # ... to stop raw backtrace*/\
|
0, /* nop # ... to stop raw backtrace*/\
|
||||||
0x27bd0000, /* addu sp,?0 # Pseudo prologue */\
|
0x27bd0000, /* addu sp,?0 # Pseudo prologue */\
|
||||||
/* Start here: */\
|
/* Start here: */\
|
||||||
MK_OP(061,SP_REGNUM,12,0), /* lwc1 $f12,0(sp) # Reload first 4 args*/\
|
MK_OP(061,SP_REGNUM,12,0), /* lwc1 $f12,0(sp) # Reload FP regs*/\
|
||||||
MK_OP(061,SP_REGNUM,13,4), /* lwc1 $f13,4(sp) */\
|
MK_OP(061,SP_REGNUM,13,4), /* lwc1 $f13,4(sp) */\
|
||||||
MK_OP(061,SP_REGNUM,14,8), /* lwc1 $f14,8(sp) */\
|
MK_OP(061,SP_REGNUM,14,8), /* lwc1 $f14,8(sp) */\
|
||||||
MK_OP(061,SP_REGNUM,15,12), /* lwc1 $f15,12(sp) */\
|
MK_OP(061,SP_REGNUM,15,12), /* lwc1 $f15,12(sp) */\
|
||||||
MK_OP(043,SP_REGNUM,4,0), /* lw $r4,0(sp) # Re-load FP regs*/\
|
MK_OP(043,SP_REGNUM,4,0), /* lw $r4,0(sp) # Reload first 4 args*/\
|
||||||
MK_OP(043,SP_REGNUM,5,4), /* lw $r5,4(sp) */\
|
MK_OP(043,SP_REGNUM,5,4), /* lw $r5,4(sp) */\
|
||||||
MK_OP(043,SP_REGNUM,6,8), /* lw $r6,8(sp) */\
|
MK_OP(043,SP_REGNUM,6,8), /* lw $r6,8(sp) */\
|
||||||
MK_OP(043,SP_REGNUM,7,12), /* lw $r7,12(sp) */\
|
MK_OP(043,SP_REGNUM,7,12), /* lw $r7,12(sp) */\
|
||||||
|
@ -315,8 +320,19 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
into a call sequence of the above form stored at DUMMYNAME. */
|
into a call sequence of the above form stored at DUMMYNAME. */
|
||||||
|
|
||||||
#define FIX_CALL_DUMMY(dummyname, start_sp, fun, nargs, args, rettype, gcc_p)\
|
#define FIX_CALL_DUMMY(dummyname, start_sp, fun, nargs, args, rettype, gcc_p)\
|
||||||
(((int*)dummyname)[11] |= (((unsigned long)(fun)) >> 16), \
|
do \
|
||||||
((int*)dummyname)[12] |= (unsigned short)(fun))
|
{ \
|
||||||
|
((int*)(dummyname))[11] |= ((unsigned long)(fun)) >> 16; \
|
||||||
|
((int*)(dummyname))[12] |= (unsigned short)(fun); \
|
||||||
|
if (! mips_fpu) \
|
||||||
|
{ \
|
||||||
|
((int *) (dummyname))[3] = 0; \
|
||||||
|
((int *) (dummyname))[4] = 0; \
|
||||||
|
((int *) (dummyname))[5] = 0; \
|
||||||
|
((int *) (dummyname))[6] = 0; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
while (0)
|
||||||
|
|
||||||
/* There's a mess in stack frame creation. See comments in blockframe.c
|
/* There's a mess in stack frame creation. See comments in blockframe.c
|
||||||
near reference to INIT_FRAME_PC_FIRST. */
|
near reference to INIT_FRAME_PC_FIRST. */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue