mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2025-02-22 02:21:19 +00:00
* remote-est.c: New file supports EST-300 CPU32 background
mode ICE. * remote-utils.c (sr_com): Call registers_changed. * configure.in (m68*-*-est*): New configuration. * config/m68k/tm-est.h: New file.
This commit is contained in:
parent
8eac0979a0
commit
93584146c5
@ -228,6 +228,7 @@ remote-bug.c
|
||||
remote-e7000.c
|
||||
remote-eb.c
|
||||
remote-es.c
|
||||
remote-est.c
|
||||
remote-hms.c
|
||||
remote-mips.c
|
||||
remote-mm.c
|
||||
|
@ -1,3 +1,11 @@
|
||||
Fri Dec 23 17:03:13 1994 Steve Chamberlain (sac@jonny.cygnus.com)
|
||||
|
||||
* remote-est.c: New file supports EST-300 CPU32 background
|
||||
mode ICE.
|
||||
* remote-utils.c (sr_com): Call registers_changed.
|
||||
* configure.in (m68*-*-est*): New configuration.
|
||||
* config/m68k/tm-est.h: New file.
|
||||
|
||||
Fri Dec 23 16:18:50 1994 Stu Grossman (grossman@cygnus.com)
|
||||
|
||||
* Makefile.in (CLIBS): Put LIBIBERTY last.
|
||||
|
@ -273,6 +273,7 @@ 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 ;;
|
||||
|
589
gdb/remote-est.c
Normal file
589
gdb/remote-est.c
Normal file
@ -0,0 +1,589 @@
|
||||
/* Remote debugging interface for EST-300 ICE, for GDB
|
||||
Copyright 1994 Free Software Foundation, Inc.
|
||||
Contributed by Cygnus Support.
|
||||
|
||||
Written by Steve Chamberlain for 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., 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 "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
|
||||
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 ()
|
||||
{
|
||||
int regno;
|
||||
|
||||
for (regno = 0; regno < 18; regno++)
|
||||
est_store_register (regno);
|
||||
registers_changed ();
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
est_store_registers ();
|
||||
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 ();
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
||||
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;
|
||||
{
|
||||
int count;
|
||||
int c;
|
||||
char buf[20];
|
||||
/* Starting address of this pass. */
|
||||
|
||||
if (((memaddr - 1) + len) < memaddr)
|
||||
{
|
||||
errno = EIO;
|
||||
return 0;
|
||||
}
|
||||
|
||||
sprintf (buf, ".dmb %x %x", memaddr, len);
|
||||
write_and_expect (buf);
|
||||
count = 0;
|
||||
|
||||
c = sr_readchar ();
|
||||
|
||||
while (count < len)
|
||||
{
|
||||
while (!isdigit (c) && !isalpha (c)) {
|
||||
if (c == '!')
|
||||
{
|
||||
expect_prompt();
|
||||
errno =EIO;
|
||||
return 0;
|
||||
|
||||
}
|
||||
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 */
|
||||
{
|
||||
if (write)
|
||||
{
|
||||
return est_write_memory (memaddr, myaddr, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
return est_read_memory (memaddr, myaddr, len);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#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)
|
||||
char *args;
|
||||
int from_tty;
|
||||
{
|
||||
gr_open (args, from_tty, &est_settings);
|
||||
}
|
||||
|
||||
/* 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 ()
|
||||
{
|
||||
add_target (&est_ops);
|
||||
}
|
@ -396,6 +396,7 @@ sr_com (args, fromtty)
|
||||
|
||||
sr_write_cr (args);
|
||||
sr_write ("\030", 1);
|
||||
registers_changed ();
|
||||
gr_expect_prompt ();
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user