* mon960-rom.c: New file; support mon960 rom monitor on i960.

* monitor.c (monitor_debug): Change remotedebug to buffer strings.
       * monitor.c (monitor_open): Add test for flag MO_NO_ECHO_ON_OPEN before
       epecting prompt and echo during open.
       * monitor.c (monitor_stop): Add test for flag MO_SEND_BREAK_ON_OPEN to
       determine if break should be sent as stop command.
       * monitor.h: Add flags MO_NO_ECHO_ON_OPEN and MO_SEND_BREAK_ON_OPEN.
       * i960-tdep.c (mon960_frame_chain_valid): New function for getting
       stack frame on mon960.
       * Makefile.in: Add mon960 files.
       * configure.in: Changed i960-*-coff* and i960-*-elf* to target mon960;
       added i960-nindy-coff* and i960-nindy-elf* for target nindy.
       * configure: Regenerated.
       * config/i960/mon960.mt, config/i960/tm-mon960.h: New files;
       support mon960 rom monitor on i960.
This commit is contained in:
Dawn Perchik 1996-03-11 23:49:22 +00:00
parent 5d06fa80b2
commit 2e665cd3ad
7 changed files with 425 additions and 4 deletions

View File

@ -0,0 +1,4 @@
# Target: Intel 960 rom monitor
TDEPFILES= i960-tdep.o monitor.o mon960-rom.o ttyflush.o xmodem.o dsrec.o
TM_FILE= tm-mon960.h

View File

@ -0,0 +1,92 @@
/* Parameters for Intel 960 running MON960 monitor, for GDB, the GNU debugger.
Copyright (C) 1990-1991 Free Software Foundation, Inc.
Contributed by Intel Corporation and Cygnus Support.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/*****************************************************************************
* Definitions to target GDB to an i960 debugged over a serial line.
******************************************************************************/
#include "i960/tm-i960.h"
/* redefined from tm-i960.h */
/* Number of machine registers */
#undef NUM_REGS
#define NUM_REGS 40
/* Initializer for an array of names of registers.
There should be NUM_REGS strings in this initializer. */
#undef REGISTER_NAMES
#define REGISTER_NAMES { \
/* 0 */ "pfp", "sp", "rip", "r3", "r4", "r5", "r6", "r7", \
/* 8 */ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",\
/* 16 */ "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7", \
/* 24 */ "g8", "g9", "g10", "g11", "g12", "g13", "g14", "fp", \
/* 32 */ "pc", "ac", "tc", "ip", "fp0", "fp1", "fp2", "fp3",\
}
/* Override the standard gdb prompt when compiled for this target. */
#define DEFAULT_PROMPT "(gdb960) "
/* Additional command line options accepted by mon960 gdb's, for handling
the remote-mon960.c interface. These should really be target-specific
rather than architecture-specific. */
/* FIXME - should use this instead of the "send_break" hack in monitor.c */
extern int mon960_initial_brk; /* Send a BREAK to reset board first */
extern char *mon960_ttyname; /* Name of serial port to talk to mon960 */
#define ADDITIONAL_OPTIONS \
/* FIXME {"brk", no_argument, &mon960_initial_brk, 1}, */ \
{"ser", required_argument, 0, 1004}, /* 1004 is magic cookie for ADDL_CASES */
#define ADDITIONAL_OPTION_CASES \
case 1004: /* -ser option: remote mon960 auto-start */ \
mon960_ttyname = optarg; \
break;
#define ADDITIONAL_OPTION_HELP \
"\
/* FIXME - -brk Send a break to a Mon960 target to reset it.\n*/\
-ser SERIAL Open remote Mon960 session to SERIAL port.\n\
"
/* FRAME_CHAIN_VALID returns zero if the given frame is the outermost one
and has no caller.
On the i960, each various target system type defines FRAME_CHAIN_VALID,
since it differs between Nindy, Mon960 and VxWorks, the currently supported
targets types. */
#define FRAME_CHAIN_VALID(chain, thisframe) \
mon960_frame_chain_valid (chain, thisframe)
extern int
mon960_frame_chain_valid(); /* See i960-tdep.c */
/* Sequence of bytes for breakpoint instruction */
#define BREAKPOINT {0x00, 0x3e, 0x00, 0x66}
/* Amount ip must be decremented by after a breakpoint.
* This is often the number of bytes in BREAKPOINT but not always.
*/
#define DECR_PC_AFTER_BREAK 4

6
gdb/configure vendored
View File

@ -3078,8 +3078,10 @@ i[3456]86-*-netware*) gdb_target=i386nw
i[3456]86-*-osf1mk*) gdb_target=i386mk ;;
i[3456]86-*-cygwin32) gdb_target=cygwin32 ;;
i960-*-bout*) gdb_target=vxworks960 ;;
i960-*-coff*) gdb_target=nindy960 ;;
i960-*-elf*) gdb_target=nindy960 ;;
i960-nindy-coff*) gdb_target=nindy960 ;;
i960-*-coff*) gdb_target=mon960 ;;
i960-nindy-elf*) gdb_target=nindy960 ;;
i960-*-elf*) gdb_target=mon960 ;;
i960-*-nindy*) gdb_target=nindy960 ;;
i960-*-vxworks*) gdb_target=vxworks960 ;;

View File

@ -472,8 +472,10 @@ i[3456]86-*-netware*) gdb_target=i386nw
i[3456]86-*-osf1mk*) gdb_target=i386mk ;;
i[3456]86-*-cygwin32) gdb_target=cygwin32 ;;
i960-*-bout*) gdb_target=vxworks960 ;;
i960-*-coff*) gdb_target=nindy960 ;;
i960-*-elf*) gdb_target=nindy960 ;;
i960-nindy-coff*) gdb_target=nindy960 ;;
i960-*-coff*) gdb_target=mon960 ;;
i960-nindy-elf*) gdb_target=nindy960 ;;
i960-*-elf*) gdb_target=mon960 ;;
i960-*-nindy*) gdb_target=nindy960 ;;
i960-*-vxworks*) gdb_target=vxworks960 ;;

View File

@ -760,6 +760,53 @@ next_insn (memaddr, pword1, pword2)
return 0;
}
/* 'start_frame' is a variable in the MON960 runtime startup routine
that contains the frame pointer of the 'start' routine (the routine
that calls 'main'). By reading its contents out of remote memory,
we can tell where the frame chain ends: backtraces should halt before
they display this frame. */
int
mon960_frame_chain_valid (chain, curframe)
unsigned int chain;
struct frame_info *curframe;
{
struct symbol *sym;
struct minimal_symbol *msymbol;
/* crtmon960.o is an assembler module that is assumed to be linked
* first in an i80960 executable. It contains the true entry point;
* it performs startup up initialization and then calls 'main'.
*
* 'sf' is the name of a variable in crtmon960.o that is set
* during startup to the address of the first frame.
*
* 'a' is the address of that variable in 80960 memory.
*/
static char sf[] = "start_frame";
CORE_ADDR a;
chain &= ~0x3f; /* Zero low 6 bits because previous frame pointers
contain return status info in them. */
if ( chain == 0 ){
return 0;
}
sym = lookup_symbol(sf, 0, VAR_NAMESPACE, (int *)NULL,
(struct symtab **)NULL);
if ( sym != 0 ){
a = SYMBOL_VALUE (sym);
} else {
msymbol = lookup_minimal_symbol (sf, NULL, NULL);
if (msymbol == NULL)
return 0;
a = SYMBOL_VALUE_ADDRESS (msymbol);
}
return ( chain != read_memory_integer(a,4) );
}
void
_initialize_i960_tdep ()
{

270
gdb/mon960-rom.c Normal file
View File

@ -0,0 +1,270 @@
/* Remote target glue for the Intel 960 ROM monitor.
Copyright 1995, 1996 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "defs.h"
#include "gdbcore.h"
#include "target.h"
#include "monitor.h"
#include "serial.h"
#include "srec.h"
#include "xmodem.h"
#if !defined (HAVE_TERMIOS) && !defined (HAVE_TERMIO) && !defined (HAVE_SGTTY)
#define HAVE_SGTTY
#endif
#ifdef HAVE_SGTTY
#include <sys/ioctl.h>
#endif
#include <sys/types.h> /* Needed by file.h on Sys V */
#include <sys/file.h>
#include <signal.h>
#include <sys/stat.h>
#define USE_GENERIC_LOAD
int quiet = 0; /* 1 => stifle unnecessary messages */
serial_t mon960_serial;
char *mon960_ttyname; /* name of tty to talk to mon960 on, or null */
static struct monitor_ops mon960_cmds;
#ifdef USE_GENERIC_LOAD
extern void generic_load PARAMS ((char* filename, int from_tty));
#endif
static void mon960_open PARAMS ((char *args, int from_tty));
#ifdef USE_GENERIC_LOAD
static void
mon960_load_gen (filename, from_tty)
char *filename;
int from_tty;
{
extern int inferior_pid;
generic_load (filename, from_tty);
/* Finally, make the PC point at the start address */
if (exec_bfd)
write_pc (bfd_get_start_address (exec_bfd));
inferior_pid = 0; /* No process now */
}
#else
static void
mon960_load (desc, file, hashmark)
serial_t desc;
char *file;
int hashmark;
{
bfd *abfd;
asection *s;
char *buffer;
int i;
buffer = alloca (XMODEM_PACKETSIZE);
abfd = bfd_openr (file, 0);
if (!abfd)
{
printf_filtered ("Unable to open file %s\n", file);
return;
}
if (bfd_check_format (abfd, bfd_object) == 0)
{
printf_filtered ("File is not an object file\n");
return;
}
for (s = abfd->sections; s; s = s->next)
if (s->flags & SEC_LOAD)
{
bfd_size_type section_size;
printf_filtered ("%s\t: 0x%4x .. 0x%4x ", s->name, s->vma,
s->vma + s->_raw_size);
gdb_flush (gdb_stdout);
monitor_printf (mon960_cmds.load, s->vma);
if (mon960_cmds.loadresp)
monitor_expect (mon960_cmds.loadresp, NULL, 0);
xmodem_init_xfer (desc);
section_size = bfd_section_size (abfd, s);
for (i = 0; i < section_size; i += XMODEM_DATASIZE)
{
int numbytes;
numbytes = min (XMODEM_DATASIZE, section_size - i);
bfd_get_section_contents (abfd, s, buffer + XMODEM_DATAOFFSET, i,
numbytes);
xmodem_send_packet (desc, buffer, numbytes, hashmark);
if (hashmark)
{
putchar_unfiltered ('#');
gdb_flush (gdb_stdout);
}
} /* Per-packet (or S-record) loop */
xmodem_finish_xfer (desc);
monitor_expect_prompt (NULL, 0);
putchar_unfiltered ('\n');
} /* Loadable sections */
if (hashmark)
putchar_unfiltered ('\n');
}
#endif
/* This array of registers need to match the indexes used by GDB.
This exists because the various ROM monitors use different strings
than does GDB, and don't necessarily support all the registers
either. So, typing "info reg sp" becomes a "r30". */
/* these correspond to the offsets from tm-* files from config directories */
/* g0-g14, fp, pfp, sp, rip,r3-15, pc, ac, tc, fp0-3 */
/* NOTE: "ip" is documented as "ir" in the Mon960 UG. */
/* NOTE: "ir" can't be accessed... but there's an ip and rip. */
static char *mon960_regnames[NUM_REGS] = {
/* 0 */ "pfp", "sp", "rip", "r3", "r4", "r5", "r6", "r7", \
/* 8 */ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",\
/* 16 */ "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7", \
/* 24 */ "g8", "g9", "g10", "g11", "g12", "g13", "g14", "fp", \
/* 32 */ "pc", "ac", "tc", "ip", "fp0", "fp1", "fp2", "fp3",\
};
/* Define the monitor command strings. Since these are passed directly
through to a printf style function, we may include formatting
strings. We also need a CR or LF on the end. */
static struct target_ops mon960_ops;
/* need to pause the monitor for timing reasons, so slow it down */
static char *mon960_inits[] = {"\n\r\r\r\r\r\r\r\r\r\r\r\r\r\r\n\r\n\r\n", NULL}; /* Exits sub-command mode & download cmds */
static struct monitor_ops mon960_cmds =
{
MO_CLR_BREAK_USES_ADDR
| MO_NO_ECHO_ON_OPEN
| MO_SEND_BREAK_ON_STOP
| MO_GETMEM_READ_SINGLE, /* flags */
mon960_inits, /* Init strings */
"go\n\r", /* continue command */
"st\n\r", /* single step */
"\n\r", /* break interrupts the program */
NULL, /* set a breakpoint */
/* can't use "br" because only 2 hw bps are supported */
NULL, /* clear a breakpoint - "de" is for hw bps */
NULL, /* clear all breakpoints */
NULL, /* fill (start end val) */
/* can't use "fi" because it takes words, not bytes */
{
/* can't use "mb", "md" or "mo" because they require interaction */
NULL, /* setmem.cmdb (addr, value) */
"md %x %x\n\r", /* setmem.cmdw (addr, value) */
NULL, /* setmem.cmdl (addr, value) */
NULL, /* setmem.cmdll (addr, value) */
NULL, /* setmem.resp_delim */
NULL, /* setmem.term */
NULL, /* setmem.term_cmd */
},
{
/* since the parsing of multiple bytes is difficult due to
interspersed addresses, we'll only read 1 value at a time,
even tho these can handle a count */
"db %x\n\r", /* getmem.cmdb (addr, #bytes) */
"ds %x\n\r", /* getmem.cmdw (addr, #swords) */
"di %x\n\r", /* getmem.cmdl (addr, #words) */
"dd %x\n\r", /* getmem.cmdll (addr, #dwords) */
" : ", /* getmem.resp_delim */
NULL, /* getmem.term */
NULL, /* getmem.term_cmd */
},
{
"md %s %x\n\r", /* setreg.cmd (name, value) */
NULL, /* setreg.resp_delim */
NULL, /* setreg.term */
NULL /* setreg.term_cmd */
},
{
"di %s\n\r", /* getreg.cmd (name) */
" : ", /* getreg.resp_delim */
NULL, /* getreg.term */
NULL, /* getreg.term_cmd */
},
"re\n\r", /* dump_registers */
"\\(\\w+\\)=\\([0-9a-fA-F]+\\)", /* register_pattern */
NULL, /* supply_register */
#ifdef USE_GENERIC_LOAD
NULL, /* load_routine (defaults to SRECs) */
NULL, /* download command */
NULL, /* load response */
#else
mon960_load, /* load_routine (defaults to SRECs) */
"do\n\r", /* download command */
"Downloading\n\r", /* load response */
#endif
"=>", /* monitor command prompt */
"\n\r", /* end-of-command delimitor */
NULL, /* optional command terminator */
&mon960_ops, /* target operations */
SERIAL_1_STOPBITS, /* number of stop bits */
mon960_regnames, /* registers names */
MONITOR_OPS_MAGIC /* magic */
};
/* invoked from monitor.c - opens the serial port */
static void
mon960_open (args, from_tty)
char *args;
int from_tty;
{
char *serial_port_name = args;
if (args)
{
char *cursor = serial_port_name = strsave (args);
while (*cursor && *cursor != ' ')
cursor++;
if (*cursor)
*cursor++ = 0;
while (*cursor == ' ')
cursor++;
}
monitor_open (serial_port_name, &mon960_cmds, from_tty);
}
void
_initialize_mon960 ()
{
init_monitor_ops (&mon960_ops);
mon960_ops.to_shortname = "mon960"; /* for the target command */
mon960_ops.to_longname = "Intel 960 rom monitor";
#ifdef USE_GENERIC_LOAD
mon960_ops.to_load = mon960_load_gen; /* FIXME - should go back and try "do" */
#endif
/* use SW breaks; target only supports 2 HW breakpoints */
mon960_ops.to_insert_breakpoint = memory_insert_breakpoint;
mon960_ops.to_remove_breakpoint = memory_remove_breakpoint;
mon960_ops.to_doc =
"Debug on an Intel 960 eval board running the Mon960 rom monitor.\n"
"Specify the serial device it is connected to (e.g. /dev/ttya).";
mon960_ops.to_open = mon960_open;
add_target (&mon960_ops);
}

View File

@ -121,6 +121,10 @@ struct monitor_ops
#define MO_GETMEM_READ_SINGLE 0x10 /* getmem can only read one loc at a time */
#define MO_HANDLE_NL 0x20 /* handle \r\n combinations */
#define MO_NO_ECHO_ON_OPEN 0x40 /* don't expect echos in monitor_open */
#define MO_SEND_BREAK_ON_STOP 0x80 /* If set, send break to stop monitor */
extern struct monitor_ops *current_monitor;
#define LOADTYPES (current_monitor->loadtypes)