* configure.in: Move test for m68*-est-* before m68*-*-coff*.

* findvar.c:  Move default def of CANNOT_STORE_REGISTER closer to
	the beginning of the code.
	* (write_register_gen):  New routine.  Analogous to
	read_register_gen.
	* (write_register_bytes):  Another rewrite!  Make it smarter about
	not updating regs with the same value.
	* monitor.c (printf_monitor readchar):  Use stderr instead of
	stdout to output debug info.  Also cleanup readchar a little.
	* (expect):  Make sure that excessive responses are null
	terminated.
	* (monitor_open):  Check for magic number in monitor_ops struct.
	Allow multiple commands as init strings.  Also, clear all
	breakpoints.
	* (monitor_resume monitor_wait):  Send a command to dump all the
	regs for those targets which don't do so when waking up after a
	continue command.
	* (monitor_wait):  Handle excessive response output better.
	* (monitor_write_memory):  Use block fill, word, and long word
	commands (if they exist) to write memory more efficiently.
	* General cleanups to use flag bits instead of individual flag
	words in monitor_ops struct.
	* (monitor_command):  Return output from command.
	* (monitor_load_srec):  Allocate buffer only once.  Use alloca.
	Wait for load response string instead of using a timeout to start
	sending S-records.  Fix bug where value of srec_frame shrinks.  If
	hashmark is set, print `-' for retransmissions.  General cleanups.
	* (monitor_make_srec):  Get rid of S-record default type kludge.
	* monitor.h:  Use seperate struct for memory and register
	read/write commands.  Memory commands can come in byte, word,
	long, and longlong forms.
	* (monitor_ops):  Change lots of fields.  Generalize some stuff.
	Put all flags into flags word.  Allow init to be a list of commands.
	Add command for clearing all breakpoints, block fill, dumping all
	registers.
	* remote-est.c:  Rewrite to use new monitor conventions.
	* config/m68k/est.mt (TDEPFILES):  Add monitor.o.
	* config/m68k/tm-est.h:  Set NUM_REGS to 18.
	* testsuite/gdb.base/break.exp:  Lots of cleanups.  Use gdb_test
	more thoroughly.
This commit is contained in:
Stu Grossman 1995-03-25 00:36:01 +00:00
parent 1ef0c066d9
commit a25a9f49ca
5 changed files with 180 additions and 563 deletions

View File

@ -1,3 +1,3 @@
# Target: m68k emulator EST-300
TDEPFILES= m68k-tdep.o remote-est.o
TDEPFILES= m68k-tdep.o monitor.o remote-est.o
TM_FILE= tm-est.h

View File

@ -28,6 +28,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* We have more complex, useful breakpoints on the target. */
#define DECR_PC_AFTER_BREAK 0
#define NUM_REGS 18
#include "m68k/tm-m68k.h"
#undef FRAME_CHAIN

View File

@ -269,6 +269,7 @@ m68*-tandem-*) gdb_target=st2000 ;;
m68*-rom68k-*) gdb_target=monitor ;;
m68*-*bug-*) gdb_target=monitor ;;
m68*-monitor-*) gdb_target=monitor ;;
m68*-est-*) gdb_target=est ;;
m68*-*-aout*) gdb_target=monitor ;;
m68*-*-coff*) gdb_target=monitor ;;
m68*-*-elf*) gdb_target=monitor ;;
@ -279,7 +280,6 @@ m68*-*-sunos3*) gdb_target=sun3os3 ;;
m68*-*-sunos4*) gdb_target=sun3os4 ;;
m68*-*-sysv4*) gdb_target=m68kv4 ;;
m68*-*-vxworks*) gdb_target=vxworks68 ;;
m68*-*-est*) gdb_target=est ;;
m88*-harris-cxux*) gdb_target=cxux ;;
m88*-motorola-sysv4*) gdb_target=delta88v4 ;;

View File

@ -56,57 +56,84 @@ struct rom_cmd_data {
ignored if TERM is NULL.
*/
struct cmd_resp {
char *cmd; /* Command to send */
struct memrw_cmd
{
char *cmdb; /* Command to send for byte read/write */
char *cmdw; /* Command for word (16 bit) read/write */
char *cmdl; /* Command for long (32 bit) read/write */
char *cmdll; /* Command for long long (64 bit) read/write */
char *resp_delim; /* String just prior to the desired value */
char *term; /* Terminating string to search for */
char *term_cmd; /* String to get out of sub-mode (if necessary) */
};
struct monitor_ops {
int type; /* 1 is ascii, 0 is GDB remote protocol */
char *init; /* initialize to the monitor */
char *execute; /* execute or usually GO command */
char *resume; /* continue command */
char *step; /* single step */
char *set_break; /* set a breakpoint */
char *clr_break; /* clear a breakpoint */
int clr_type; /* number or address for clearing */
struct cmd_resp setmem; /* set memory to a value */
struct cmd_resp getmem; /* display memory */
struct cmd_resp setreg; /* set a register */
struct cmd_resp getreg; /* get a register */
struct regrw_cmd
{
char *cmd; /* Command to send for reg read/write */
char *resp_delim; /* String just prior to the desired value */
char *term; /* Terminating string to search for */
char *term_cmd; /* String to get out of sub-mode (if necessary) */
};
struct monitor_ops
{
int flags; /* See below */
char **init; /* List of init commands. NULL terminated. */
char *cont; /* continue command */
char *step; /* single step */
char *set_break; /* set a breakpoint */
char *clr_break; /* clear a breakpoint */
char *clr_all_break; /* Clear all breakpoints */
char *fill; /* Memory fill cmd (addr len val) */
struct memrw_cmd setmem; /* set memory to a value */
struct memrw_cmd getmem; /* display memory */
struct regrw_cmd setreg; /* set a register */
struct regrw_cmd getreg; /* get a register */
/* Some commands can dump a bunch of registers
at once. This comes as a set of REG=VAL
pairs. This should be called for each pair
of registers that we can parse to supply
GDB with the value of a register. */
char *dump_registers; /* Command to dump all regs at once */
char *register_pattern; /* Pattern that picks out register from reg dump */
void (*supply_register) PARAMS ((char *name, int namelen, char *val, int vallen));
char *load; /* load command */
char *prompt; /* monitor command prompt */
char *cmd_delim; /* end-of-command delimitor */
char *cmd_end; /* optional command terminator */
void (*supply_register) PARAMS ((char *name, int namelen, char *val, int vallen));
char *load; /* load command */
char *loadresp; /* Response to load command */
char *prompt; /* monitor command prompt */
char *cmd_delim; /* end-of-command delimitor */
char *cmd_end; /* optional command terminator */
struct target_ops *target; /* target operations */
char **loadtypes; /* the load types that are supported */
char **loadprotos; /* the load protocols that are supported */
char *baudrates; /* supported baud rates */
int stopbits; /* number of stop bits */
char **regnames; /* array of register names in ascii */
char **loadtypes; /* the load types that are supported */
char **loadprotos; /* the load protocols that are supported */
char *baudrates; /* supported baud rates */
int stopbits; /* number of stop bits */
char **regnames; /* array of register names in ascii */
int magic; /* Check value */
};
#define MONITOR_OPS_MAGIC 600925
/* Flag defintions */
#define MO_CLR_BREAK_USES_ADDR 0x1 /* If set, then clear breakpoint command
uses address, otherwise it uses an index
returned by the monitor. */
#define MO_FILL_USES_ADDR 0x2 /* If set, then memory fill command uses
STARTADDR, ENDADDR+1, VALUE as args, else it
uses STARTADDR, LENGTH, VALUE as args. */
#define MO_NEED_REGDUMP_AFTER_CONT 0x4 /* If set, then monitor doesn't auto-
matically supply register dump when
coming back after a continue. */
extern struct monitor_ops *current_monitor;
#define PROTO_TYPE (current_monitor->type)
#define LOADTYPES (current_monitor->loadtypes)
#define LOADPROTOS (current_monitor->loadprotos)
#define INIT_CMD (current_monitor->init)
#define GO_CMD (current_monitor->execute)
#define CONT_CMD (current_monitor->resume)
#define CONT_CMD (current_monitor->cont)
#define STEP_CMD (current_monitor->step)
#define SET_BREAK_CMD (current_monitor->set_break)
#define CLR_BREAK_CMD (current_monitor->clr_break)
#define CLR_BREAK_ADDR (current_monitor->clr_type)
#define SET_MEM (current_monitor->setmem)
#define GET_MEM (current_monitor->getmem)
#define LOAD_CMD (current_monitor->load)
@ -127,7 +154,6 @@ extern struct monitor_ops *current_monitor;
#define push_monitor(x) current_monitor = x;
#define SREC_SIZE 160
#define GDBPROTO ((current_monitor->type) ? 0: 1)
/*
* FIXME: These are to temporarily maintain compatability with the

View File

@ -3,6 +3,7 @@
Contributed by Cygnus Support.
Written by Steve Chamberlain for Cygnus Support.
Re-written by Stu Grossman of Cygnus Support
This file is part of GDB.
@ -20,570 +21,158 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "defs.h"
#include "command.h"
#include "gdbcore.h"
#include "target.h"
#include "wait.h"
#include <varargs.h>
#include <signal.h>
#include <string.h>
#include <sys/types.h>
#include "monitor.h"
#include "serial.h"
#include "remote-utils.h"
static void expect_char PARAMS ((int));
static void
write_and_expect (x)
char *x;
{
sr_write_cr (x);
sr_expect (x);
}
static void est_open PARAMS ((char *args, int from_tty));
static void
expect_char (want)
int want;
{
int c = sr_readchar ();
while (c != want)
c = sr_readchar ();
}
static void
expect_prompt ()
{
expect_char ('>');
}
static int
get_hex_digit (ch)
int ch;
{
if (ch >= '0' && ch <= '9')
return ch - '0';
else if (ch >= 'A' && ch <= 'F')
return ch - 'A' + 10;
else if (ch >= 'a' && ch <= 'f')
return ch - 'a' + 10;
return -1;
}
static int
get_hex (start)
int *start;
{
int value = get_hex_digit (*start);
int try;
*start = sr_readchar ();
while ((try = get_hex_digit (*start)) >= 0)
{
value <<= 4;
value += try;
*start = sr_readchar ();
}
return value;
}
/* Tell the remote machine to resume. */
static void
est_resume (pid, step, sig)
int pid, step, sig;
{
write_and_expect (step ? ".SI" : ".GO");
}
/* A reg dump looks like
D0 = 00000000 D1 = 00000000 D2 = 00000000 D3 = 00000000
D4 = 00000000 D5 = 00000000 D6 = 00000000 D7 = 00000000
A0 = 00000000 A1 = 00000000 A2 = 00000000 A3 = 00000000
A4 = 00000000 A5 = 00000000 A6 = 00000000 A7 = 001104FE
USP = 00110400 SSP*= 001104FE PC = 00229BBC SR = 2000
VBR = 00110000 SFC = 0005 DFC = 0005
or
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00001234 00000000 001104FE 00110400 001104FE 00229BBC 2000 00110000 0005 0005
*/
static int
target_to_gdb_rn (rn)
int rn;
{
if (rn < 16)
return rn;
if (rn == 18)
return PC_REGNUM;
if (rn == 19)
return PS_REGNUM;
return -1;
}
static void est_fetch_register ();
static void
est_fetch_registers ()
{
int regno;
unsigned long val;
int c;
int target_rn;
char buf[4];
write_and_expect (".DR");
buf[0] = 0;
buf[1] = 0;
buf[2] = 0;
buf[3] = 0;
for (regno = 0; regno < NUM_REGS; regno++)
supply_register (regno, buf);
c = sr_readchar ();
for (target_rn = 0; target_rn < 23; target_rn++)
{
unsigned long val;
while (!isdigit (c) && !isalpha (c))
c = sr_readchar ();
while (isdigit (c) || (c >= 'A' && c <= 'F'))
{
val <<= 4;
if (isdigit (c))
val = val + c - '0';
else
val = val + c - 'A' + 10;
c = sr_readchar ();
}
regno = target_to_gdb_rn (target_rn);
if (regno >= 0)
{
buf[0] = val >> 24;
buf[1] = val >> 16;
buf[2] = val >> 8;
buf[3] = val >> 0;
supply_register (regno, buf);
}
}
expect_prompt();
}
/* Fetch register REGNO, or all registers if REGNO is -1.
Returns errno value. */
static
void
est_fetch_register (regno)
int regno;
{
est_fetch_registers ();
}
/* Store the remote registers from the contents of the block REGS. */
static void est_store_register ();
static void
est_store_registers ()
est_supply_register (regname, regnamelen, val, vallen)
char *regname;
int regnamelen;
char *val;
int vallen;
{
int regno;
for (regno = 0; regno < 18; regno++)
est_store_register (regno);
registers_changed ();
}
if (regnamelen != 2)
return;
/* Store register REGNO, or all if REGNO == 0.
Return errno value. */
static void
est_store_register (regno)
int regno;
{
char buf[20];
if (regno == -1)
switch (regname[0])
{
est_store_registers ();
case 'S':
if (regname[1] != 'R')
return;
regno = PS_REGNUM;
break;
case 'P':
if (regname[1] != 'C')
return;
regno = PC_REGNUM;
break;
case 'D':
if (regname[1] < '0' || regname[1] > '7')
return;
regno = regname[1] - '0' + D0_REGNUM;
break;
case 'A':
if (regname[1] < '0' || regname[1] > '7')
return;
regno = regname[1] - '0' + A0_REGNUM;
break;
default:
return;
}
if (regno < 8)
sprintf (buf, ".SR D%d %x", regno, read_register (regno));
else if (regno < 16)
sprintf (buf, ".SR A%d %x", regno - 8, read_register (regno));
else if (regno == PC_REGNUM)
sprintf (buf, ".SR PC %x", read_register (regno));
else if (regno == PS_REGNUM)
sprintf (buf, ".SR SR %x", read_register (regno));
else
return;
write_and_expect (buf);
expect_prompt ();
monitor_supply_register (regno, val);
}
/* Get ready to modify the registers array. On machines which store
individual registers, this doesn't need to do anything. On machines
which store all the registers in one fell swoop, this makes sure
that registers contains all the registers from the program being
debugged. */
static
int
stickbyte (where, what)
char *where;
unsigned int what;
{
static CONST char digs[] = "0123456789ABCDEF";
where[0] = digs[(what >> 4) & 0xf];
where[1] = digs[(what & 0xf) & 0xf];
return what;
}
/* Copy LEN bytes of data from debugger memory at MYADDR
to inferior's memory at MEMADDR. Returns length moved. */
static int
est_write_memory (memaddr, myaddr, len)
CORE_ADDR memaddr;
unsigned char *myaddr;
int len;
{
int i;
#define maxstride 128
int stride;
write_and_expect (".DL");
expect_char ('+');
for (i = 0; i < len; i += stride)
{
char compose[maxstride * 2 + 50];
int address = i + memaddr;
int j;
int check_sum;
int where = 0;
int alen;
stride = len - i;
if (stride > maxstride)
stride = maxstride;
compose[where++] = 'S';
check_sum = 0;
if (address >= 0xffffff)
{
alen = 4;
}
else if (address >= 0xffff)
{
alen = 3;
}
else
alen = 2;
compose[where++] = alen - 1 + '0'; /* insert type */
check_sum += stickbyte (compose + where, alen + stride + 1); /* Insert length */
where += 2;
while (alen > 0)
{
alen--;
check_sum += stickbyte (compose + where, address >> (8 * (alen)));
where += 2;
}
for (j = 0; j < stride; j++)
{
check_sum += stickbyte (compose + where, myaddr[i + j]);
where += 2;
}
stickbyte (compose + where, ~check_sum);
where += 2;
compose[where++] = 0;
sr_write_cr (compose);
while (sr_readchar () != '+')
sr_write_cr (compose);
}
/* Send the trailer record */
sr_write_cr ("S70500000000FA");
expect_prompt ();
return len;
}
/*
* This array of registers needs to match the indexes used by GDB. The
* whole reason this exists is because the various ROM monitors use
* different names than GDB does, and don't support all the
* registers either. So, typing "info reg sp" becomes a "r30".
*/
The dump memory command generates output which looks like:
.dmb 0 100
4E 56 FF FC 4E 71 42 AE FF FC 72 09 B2 AE FF FC NV..NqB...r.....
6C 02 60 12 2F 2E FF FC 4E B9 00 00 00 2A 58 4F l.`./...N....*XO
52 AE FF FC 60 E4 4E 5E 4E 75 4E 56 00 00 20 2E R...`.N^NuNV.. .
00 08 D1 B9 00 00 00 00 4E 5E 4E 75 06 46 40 54 ........N^Nu.F@T
04 45 44 4C 54 45 40 56 42 F4 04 64 24 45 05 05 .EDLTE@VB..d$E..
00 6D 04 46 00 45 4C 05 04 46 04 4C 44 CD 00 65 .m.F.EL..F.LD..e
40 45 44 55 45 45 45 46 04 44 44 40 05 4D 00 44 @EDUEEEF.DD@.M.D
*/
static int
est_read_memory (memaddr, myaddr, len)
CORE_ADDR memaddr;
unsigned char *myaddr;
int len;
static char *est_regnames[NUM_REGS] =
{
int count;
int c;
char buf[20];
/* Starting address of this pass. */
"D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
"A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7",
"SR", "PC",
};
if (((memaddr - 1) + len) < memaddr)
{
errno = EIO;
return 0;
}
/*
* Define the monitor command strings. Since these are passed directly
* through to a printf style function, we need can include formatting
* strings. We also need a CR or LF on the end.
*/
sprintf (buf, ".dmb %x %x", memaddr, len);
write_and_expect (buf);
count = 0;
static struct target_ops est_ops;
c = sr_readchar ();
static char *est_loadtypes[] = {"none", "srec", "default", NULL};
static char *est_loadprotos[] = {"none", NULL};
while (count < len)
{
while (!isdigit (c) && !isalpha (c)) {
if (c == '!')
{
expect_prompt();
errno =EIO;
return 0;
static char *est_inits[] = {"he\r", /* Resets the prompt, and clears repeated cmds */
NULL};
}
c = sr_readchar ();
}
myaddr[count++] = get_hex (&c);
c = sr_readchar ();
if (c == ' ')
{
c = sr_readchar ();
if (c == ' ')
while (c != '\r')
c = sr_readchar ();
}
}
expect_prompt ();
return len;
}
static int
est_xfer_inferior_memory (memaddr, myaddr, len, write, target)
CORE_ADDR memaddr;
unsigned char *myaddr;
int len;
int write;
struct target_ops *target; /* ignored */
static struct monitor_ops est_cmds =
{
if (write)
{
return est_write_memory (memaddr, myaddr, len);
}
else
{
return est_read_memory (memaddr, myaddr, len);
}
}
MO_CLR_BREAK_USES_ADDR | MO_FILL_USES_ADDR | MO_NEED_REGDUMP_AFTER_CONT,
est_inits, /* Init strings */
"go\r", /* continue command */
"sidr\r", /* single step */
"sb %x\r", /* set a breakpoint */
"rb %x\r", /* clear a breakpoint */
"rb\r", /* clear all breakpoints */
"bfb %x %x %x\r", /* fill (start end val) */
{
"smb %x %x\r", /* setmem.cmdb (addr, value) */
"smw %x %x\r", /* setmem.cmdw (addr, value) */
"sml %x %x\r", /* setmem.cmdl (addr, value) */
NULL, /* setmem.cmdll (addr, value) */
NULL, /* setreg.resp_delim */
NULL, /* setreg.term */
NULL, /* setreg.term_cmd */
},
{
"dmb %x %x\r", /* getmem.cmdb (addr, len) */
"dmw %x %x\r", /* getmem.cmdw (addr, len) */
"dml %x %x\r", /* getmem.cmdl (addr, len) */
NULL, /* getmem.cmdll (addr, len) */
": ", /* getmem.resp_delim */
NULL, /* getmem.term */
NULL, /* getmem.term_cmd */
},
{
"sr %s %x\r", /* setreg.cmd (name, value) */
NULL, /* setreg.resp_delim */
NULL, /* setreg.term */
NULL /* setreg.term_cmd */
},
{
"dr %s\r", /* getreg.cmd (name) */
" = ", /* getreg.resp_delim */
NULL, /* getreg.term */
NULL /* getreg.term_cmd */
},
"dr\r", /* dump_registers */
"\\(\\w+\\) = \\([0-9a-fA-F]+\\)", /* register_pattern */
est_supply_register, /* supply_register */
"dl\r", /* download command */
"+", /* load response */
">BKM>", /* monitor command prompt */
NULL, /* end-of-command delimitor */
NULL, /* optional command terminator */
&est_ops, /* target operations */
est_loadtypes, /* loadtypes */
est_loadprotos, /* loadprotos */
"9600", /* supported baud rates */
SERIAL_1_STOPBITS, /* number of stop bits */
est_regnames, /* registers names */
MONITOR_OPS_MAGIC /* magic */
};
#define MAX_DEBUG_BREAKPOINTS 100
extern int memory_breakpoint_size;
static CORE_ADDR breakaddr[MAX_DEBUG_BREAKPOINTS] =
{0};
int
est_clear_all_breakpoints ()
{
int i;
for (i = 0; i < MAX_DEBUG_BREAKPOINTS; i++)
{
breakaddr[i] = 0;
}
if (sr_is_open ())
{
write_and_expect (".RB");
expect_prompt ();
}
return 0;
}
static int
est_insert_breakpoint (addr, shadow)
CORE_ADDR addr;
unsigned char *shadow;
{
int i;
for (i = 0; i <= MAX_DEBUG_BREAKPOINTS; i++)
if (breakaddr[i] == 0)
{
char buf[20];
breakaddr[i] = addr;
sprintf (buf, ".SB %x", addr);
write_and_expect (buf);
expect_prompt ();
return 0;
}
error ("Too many breakpoints ( > %d) for the est\n", MAX_DEBUG_BREAKPOINTS);
return 1;
}
static int
est_remove_breakpoint (addr, shadow)
CORE_ADDR addr;
unsigned char *shadow;
{
int i;
for (i = 0; i < MAX_DEBUG_BREAKPOINTS; i++)
if (breakaddr[i] == addr)
{
char buf[20];
breakaddr[i] = 0;
sprintf (buf, ".RB %x", addr);
write_and_expect (buf);
expect_prompt ();
return 0;
}
error ("Can't find breakpoint associated with 0x%x\n", addr);
return 1;
}
/* Wait until the remote machine stops, then return,
storing status in STATUS just as `wait' would. */
static int
est_wait (pid, status)
int pid;
struct target_waitstatus *status;
{
int c = sr_readchar ();
while (c != '!')
c = sr_readchar ();
/* What sort of stop */
c = sr_readchar ();
status->kind = TARGET_WAITKIND_STOPPED;
switch (c)
{
case 'E':
status->value.sig = TARGET_SIGNAL_BUS;
break;
/* Address error */
case 'A':
status->value.sig = TARGET_SIGNAL_BUS;
break;
/* Break */
case 'B':
status->value.sig = TARGET_SIGNAL_TRAP;
break;
}
expect_prompt ();
return 0;
}
void
est_checkin ()
{
write_and_expect (".in");
gr_expect_prompt ();
}
extern struct gr_settings est_settings;
static void
est_open (args, from_tty)
void
est_open(args, from_tty)
char *args;
int from_tty;
{
gr_open (args, from_tty, &est_settings);
monitor_open (args, &est_cmds, from_tty);
}
/* Define the target subroutine names */
struct target_ops est_ops =
{
"est",
"Remote EST-300 target",
"Use a remote EST-300 ICE connected by a serial line,\n\
or a network connection.\n\
Arguments are the name of the device for the serial line,\n\
the speed to connect at in bits per second.\n\
eg\n\
target est /dev/ttya 9600\n\
target est foobar",
est_open,
gr_close,
0,
gr_detach,
est_resume,
est_wait,
est_fetch_register,
est_store_register,
gr_prepare_to_store,
est_xfer_inferior_memory,
gr_files_info,
est_insert_breakpoint,
est_remove_breakpoint, /* Breakpoints */
0,
0,
0,
0,
0, /* Terminal handling */
gr_kill,
gr_load_image, /* load */
0, /* lookup_symbol */
gr_create_inferior,
gr_mourn,
0, /* can_run */
0, /* notice_signals */
0, /* to_stop */
process_stratum,
0, /* next */
1,
1,
1,
1,
1, /* all mem, mem, stack, regs, exec */
0,
0, /* Section pointers */
OPS_MAGIC, /* Always the last thing */
};
static struct gr_settings est_settings =
{
NULL, /* dcache */
">", /* prompt */
&est_ops, /* ops */
est_clear_all_breakpoints,
est_read_memory, /* readfunc */
est_write_memory, /* writefunc */
est_checkin, /* checkin */
};
void
_initialize_remote_est ()
_initialize_est ()
{
init_monitor_ops (&est_ops);
est_ops.to_shortname = "est";
est_ops.to_longname = "EST background debug monitor";
est_ops.to_doc = "Debug via the EST BDM.\n\
Specify the serial device it is connected to (e.g. /dev/ttya).";
est_ops.to_open = est_open;
add_target (&est_ops);
}