* rom68k-rom.c: New file. Replaces the old remote-mon.c and uses
the new generic ROM interface in monitor.c. * config/m68k/monitor.mt: Use new ROM support. * monitor.c: Add support for xmodem download protocol.
This commit is contained in:
parent
f449d250be
commit
06b8f5e406
3 changed files with 497 additions and 159 deletions
|
@ -1,3 +1,10 @@
|
||||||
|
Thu Nov 10 15:16:21 1994 Rob Savoye <rob@rtl.cygnus.com>
|
||||||
|
|
||||||
|
* rom68k-rom.c: New file. Replaces the old remote-mon.c and uses
|
||||||
|
the new generic ROM interface in monitor.c.
|
||||||
|
* config/m68k/monitor.mt: Use new ROM support.
|
||||||
|
* monitor.c: Add support for xmodem download protocol.
|
||||||
|
|
||||||
Wed Nov 9 18:46:24 1994 Stan Shebs (shebs@andros.cygnus.com)
|
Wed Nov 9 18:46:24 1994 Stan Shebs (shebs@andros.cygnus.com)
|
||||||
|
|
||||||
* findvar.c (find_saved_register): Fix a frame variable name.
|
* findvar.c (find_saved_register): Fix a frame variable name.
|
||||||
|
|
500
gdb/monitor.c
500
gdb/monitor.c
|
@ -48,6 +48,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
# define TERMINAL struct sgttyb
|
# define TERMINAL struct sgttyb
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
extern void make_xmodem_packet();
|
||||||
|
extern void print_xmodem_packet();
|
||||||
|
|
||||||
struct monitor_ops *current_monitor;
|
struct monitor_ops *current_monitor;
|
||||||
extern struct cmd_list_element *setlist;
|
extern struct cmd_list_element *setlist;
|
||||||
extern struct cmd_list_element *unsetlist;
|
extern struct cmd_list_element *unsetlist;
|
||||||
|
@ -58,7 +61,6 @@ extern char *target_name;
|
||||||
|
|
||||||
static int hashmark; /* flag set by "set hash" */
|
static int hashmark; /* flag set by "set hash" */
|
||||||
|
|
||||||
/* FIXME: Replace with sr_get_debug (). */
|
|
||||||
#define LOG_FILE "monitor.log"
|
#define LOG_FILE "monitor.log"
|
||||||
#if defined (LOG_FILE)
|
#if defined (LOG_FILE)
|
||||||
FILE *log_file;
|
FILE *log_file;
|
||||||
|
@ -66,9 +68,10 @@ FILE *log_file;
|
||||||
|
|
||||||
static int timeout = 24;
|
static int timeout = 24;
|
||||||
|
|
||||||
/* Descriptor for I/O to remote machine. Initialize it to NULL so that
|
/*
|
||||||
monitor_open knows that we don't have a file open when the program starts.
|
* Descriptor for I/O to remote machine. Initialize it to NULL so that
|
||||||
*/
|
* monitor_open knows that we don't have a file open when the program starts.
|
||||||
|
*/
|
||||||
static serial_t monitor_desc = NULL;
|
static serial_t monitor_desc = NULL;
|
||||||
|
|
||||||
/* sets the download protocol, choices are srec, generic, boot */
|
/* sets the download protocol, choices are srec, generic, boot */
|
||||||
|
@ -78,6 +81,20 @@ static void set_loadtype_command();
|
||||||
static void monitor_load_srec();
|
static void monitor_load_srec();
|
||||||
static int monitor_write_srec();
|
static int monitor_write_srec();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* these definitions are for xmodem protocol
|
||||||
|
*/
|
||||||
|
#define SOH 0x01
|
||||||
|
#define ACK 0x06
|
||||||
|
#define NAK 0x15
|
||||||
|
#define EOT 0x04
|
||||||
|
#define CANCEL 0x18
|
||||||
|
#define GETACK getacknak(ACK)
|
||||||
|
#define GETNAK getacknak(NAK)
|
||||||
|
#define XMODEM_DATASIZE 128 /* the data size is ALWAYS 128 */
|
||||||
|
#define XMODEM_PACKETSIZE 131 /* the packet size is ALWAYS 132 (zero based) */
|
||||||
|
#define XMODEM 1
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* set_loadtype_command -- set the type for downloading. Check to make
|
* set_loadtype_command -- set the type for downloading. Check to make
|
||||||
* sure you have a support protocol for this target.
|
* sure you have a support protocol for this target.
|
||||||
|
@ -134,6 +151,21 @@ printf_monitor(va_alist)
|
||||||
if (SERIAL_WRITE(monitor_desc, buf, strlen(buf)))
|
if (SERIAL_WRITE(monitor_desc, buf, strlen(buf)))
|
||||||
fprintf(stderr, "SERIAL_WRITE failed: %s\n", safe_strerror(errno));
|
fprintf(stderr, "SERIAL_WRITE failed: %s\n", safe_strerror(errno));
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* write_monitor -- send raw data to monitor.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
write_monitor(data, len)
|
||||||
|
char data[];
|
||||||
|
int len;
|
||||||
|
{
|
||||||
|
if (SERIAL_WRITE(monitor_desc, data, len))
|
||||||
|
fprintf(stderr, "SERIAL_WRITE failed: %s\n", safe_strerror(errno));
|
||||||
|
|
||||||
|
*(data + len+1) = '\0';
|
||||||
|
debuglogs (1, "write_monitor(), Sending: \"%s\".", data);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* debuglogs -- deal with debugging info to multiple sources. This takes
|
* debuglogs -- deal with debugging info to multiple sources. This takes
|
||||||
|
@ -155,7 +187,7 @@ debuglogs(va_alist)
|
||||||
|
|
||||||
level = va_arg(args, int); /* get the debug level */
|
level = va_arg(args, int); /* get the debug level */
|
||||||
if ((level <0) || (level > 100)) {
|
if ((level <0) || (level > 100)) {
|
||||||
error ("Bad argument passed to debuglogs()");
|
error ("Bad argument passed to debuglogs(), needs debug level");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,7 +254,7 @@ readchar(timeout)
|
||||||
|
|
||||||
c = SERIAL_READCHAR(monitor_desc, timeout);
|
c = SERIAL_READCHAR(monitor_desc, timeout);
|
||||||
|
|
||||||
if (sr_get_debug() > 4)
|
if (sr_get_debug() > 5)
|
||||||
putchar(c & 0x7f);
|
putchar(c & 0x7f);
|
||||||
|
|
||||||
#ifdef LOG_FILE
|
#ifdef LOG_FILE
|
||||||
|
@ -238,7 +270,7 @@ readchar(timeout)
|
||||||
return c; /* Polls shouldn't generate timeout errors */
|
return c; /* Polls shouldn't generate timeout errors */
|
||||||
error("Timeout reading from remote system.");
|
error("Timeout reading from remote system.");
|
||||||
#ifdef LOG_FILE
|
#ifdef LOG_FILE
|
||||||
fputc ("ERROR: Timeout reading from remote system", log_file);
|
fputs ("ERROR: Timeout reading from remote system", log_file);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
perror_with_name("remote-monitor");
|
perror_with_name("remote-monitor");
|
||||||
|
@ -300,11 +332,6 @@ static void
|
||||||
expect_prompt(discard)
|
expect_prompt(discard)
|
||||||
int discard;
|
int discard;
|
||||||
{
|
{
|
||||||
#if defined (LOG_FILE)
|
|
||||||
/* This is a convenient place to do this. The idea is to do it often
|
|
||||||
enough that we never lose much data if we terminate abnormally. */
|
|
||||||
fflush(log_file);
|
|
||||||
#endif
|
|
||||||
expect (PROMPT, discard);
|
expect (PROMPT, discard);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -316,6 +343,7 @@ junk(ch)
|
||||||
char ch;
|
char ch;
|
||||||
{
|
{
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
|
case '\0':
|
||||||
case ' ':
|
case ' ':
|
||||||
case '-':
|
case '-':
|
||||||
case '\t':
|
case '\t':
|
||||||
|
@ -357,7 +385,7 @@ get_hex_digit(ignore)
|
||||||
;
|
;
|
||||||
else {
|
else {
|
||||||
expect_prompt(1);
|
expect_prompt(1);
|
||||||
error("Invalid hex digit from remote system.");
|
error("Invalid hex digit from remote system. (0x%x)", ch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -963,7 +991,8 @@ monitor_remove_breakpoint (addr, shadow)
|
||||||
/* monitor_load -- load a file. This file determines which of the
|
/* monitor_load -- load a file. This file determines which of the
|
||||||
* supported formats to use. The current types are:
|
* supported formats to use. The current types are:
|
||||||
* FIXME: not all types supported yet.
|
* FIXME: not all types supported yet.
|
||||||
* default - reads any file using bfd and writes it to memory.
|
* default - reads any file using bfd and writes it to memory. This
|
||||||
|
* is really slow.
|
||||||
* srec - reads binary file using bfd and writes it as an
|
* srec - reads binary file using bfd and writes it as an
|
||||||
* ascii srecord.
|
* ascii srecord.
|
||||||
* xmodem-bin - reads a binary file using bfd, and downloads it
|
* xmodem-bin - reads a binary file using bfd, and downloads it
|
||||||
|
@ -990,7 +1019,7 @@ monitor_load (file, fromtty)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (STREQ (loadtype_str, "srec")) { /* load an srecord by converting */
|
if (STREQ (loadtype_str, "srec")) { /* load an srecord by converting */
|
||||||
monitor_load_srec(file, fromtty); /* if from a binary */
|
monitor_load_srec(file, 0); /* if from a binary */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (STREQ (loadtype_str, "ascii-srec")) { /* load an srecord file */
|
if (STREQ (loadtype_str, "ascii-srec")) { /* load an srecord file */
|
||||||
|
@ -998,7 +1027,7 @@ monitor_load (file, fromtty)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (STREQ (loadtype_str, "xmodem-srec")) { /* load an srecord using the */
|
if (STREQ (loadtype_str, "xmodem-srec")) { /* load an srecord using the */
|
||||||
error ("This protocol is not implemented yet."); /* xmodem protocol */
|
monitor_load_srec(file, XMODEM);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1024,7 +1053,7 @@ monitor_load_ascii_srec (file, fromtty)
|
||||||
}
|
}
|
||||||
|
|
||||||
printf_monitor (LOAD_CMD);
|
printf_monitor (LOAD_CMD);
|
||||||
|
sleep(1);
|
||||||
while (!feof (download)) {
|
while (!feof (download)) {
|
||||||
bytes_read = fread (buf, sizeof (char), DOWNLOAD_LINE_SIZE, download);
|
bytes_read = fread (buf, sizeof (char), DOWNLOAD_LINE_SIZE, download);
|
||||||
if (hashmark) {
|
if (hashmark) {
|
||||||
|
@ -1083,17 +1112,41 @@ monitor_command (args, fromtty)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* monitor_load_srec -- download a binary file by converting it to srecords.
|
* monitor_load_srec -- download a binary file by converting it to srecords. This
|
||||||
|
* will also use xmodem to download the resulting file.
|
||||||
|
*
|
||||||
|
* A download goes like this when using xmodem:
|
||||||
|
* Receiver: Sender
|
||||||
|
* NAK ---------->
|
||||||
|
* <-------- (packet) [SOH|1|1|data|SUM]
|
||||||
|
* ACK ---------->
|
||||||
|
* <-------- (packet) [SOH|2|2|data|SUM]
|
||||||
|
* ACK ---------->
|
||||||
|
* <-------- EOT
|
||||||
|
* ACK ---------->
|
||||||
|
*
|
||||||
|
* ACK = 0x06
|
||||||
|
* NAK = 0x15
|
||||||
|
* EOT = 0x04
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
monitor_load_srec (args, fromtty)
|
monitor_load_srec (args, protocol)
|
||||||
char *args;
|
char *args;
|
||||||
int fromtty;
|
int protocol;
|
||||||
{
|
{
|
||||||
bfd *abfd;
|
bfd *abfd;
|
||||||
asection *s;
|
asection *s;
|
||||||
char buffer[1024];
|
char buffer[1024];
|
||||||
int srec_frame = SREC_SIZE;
|
char srec[1024];
|
||||||
|
char packet[XMODEM_PACKETSIZE];
|
||||||
|
int i;
|
||||||
|
int retries;
|
||||||
|
int type = 0; /* default to a type 0, header record */
|
||||||
|
int srec_frame = 57; /* FIXME: this must be 57 There is 12 bytes
|
||||||
|
of header, and 2 bytes of checksum at the end.
|
||||||
|
The problem is an xmodem packet holds exactly
|
||||||
|
128 bytes. */
|
||||||
|
|
||||||
abfd = bfd_openr (args, 0);
|
abfd = bfd_openr (args, 0);
|
||||||
if (!abfd) {
|
if (!abfd) {
|
||||||
|
@ -1106,176 +1159,311 @@ monitor_load_srec (args, fromtty)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf_monitor (LOAD_CMD); /* tell the monitor to load */
|
||||||
|
if (protocol == XMODEM) { /* get the NAK from the target */
|
||||||
|
if (GETNAK) {
|
||||||
|
debuglogs (3, "Got the NAK to start loading");
|
||||||
|
} else {
|
||||||
|
printf_monitor ("%c", EOT);
|
||||||
|
debuglogs (3, "Never got the NAK to start loading");
|
||||||
|
error ("Never got the NAK to start loading");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
s = abfd->sections;
|
s = abfd->sections;
|
||||||
while (s != (asection *) NULL) {
|
while (s != (asection *) NULL) {
|
||||||
srec_frame = SREC_SIZE;
|
|
||||||
if (s->flags & SEC_LOAD) {
|
if (s->flags & SEC_LOAD) {
|
||||||
int i;
|
|
||||||
char *buffer = xmalloc (srec_frame);
|
char *buffer = xmalloc (srec_frame);
|
||||||
printf_filtered ("%s\t: 0x%4x .. 0x%4x ", s->name, s->vma, s->vma + s
|
printf_filtered ("%s\t: 0x%4x .. 0x%4x ", s->name, s->vma, s->vma + s->_raw_size);
|
||||||
->_raw_size);
|
|
||||||
fflush (stdout);
|
fflush (stdout);
|
||||||
for (i = 0; i < s->_raw_size; i += srec_frame) {
|
for (i = 0; i < s->_raw_size; i += srec_frame) {
|
||||||
if (srec_frame > s->_raw_size - i)
|
if (srec_frame > s->_raw_size - i)
|
||||||
srec_frame = s->_raw_size - i;
|
srec_frame = s->_raw_size - i;
|
||||||
|
|
||||||
bfd_get_section_contents (abfd, s, buffer, i, srec_frame);
|
bfd_get_section_contents (abfd, s, buffer, i, srec_frame);
|
||||||
monitor_write_srec (s->vma + i, buffer, srec_frame);
|
monitor_make_srec (srec, type, s->vma + i, buffer, srec_frame);
|
||||||
printf_filtered ("*");
|
if (protocol == XMODEM) { /* send a packet using xmodem */
|
||||||
|
make_xmodem_packet (packet, srec, XMODEM_DATASIZE);
|
||||||
|
write_monitor (packet, XMODEM_PACKETSIZE+1);
|
||||||
|
retries = 0;
|
||||||
|
while (retries++ <= 3) {
|
||||||
|
if (GETNAK) { /* Resend packet */
|
||||||
|
debuglogs (3, "Got a NAK, resending packet");
|
||||||
|
sleep(1);
|
||||||
|
write_monitor (packet, XMODEM_PACKETSIZE+1); /* send it again */
|
||||||
|
if (GETACK) /* ACKnowledged, get next data chunk */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (retries >= 4) { /* too many tries, must be hosed */
|
||||||
|
printf_monitor ("%c", EOT);
|
||||||
|
error ("Never got a ACK after sending an xmodem packet");
|
||||||
|
}
|
||||||
|
} else { /* no protocols at all */
|
||||||
|
printf_monitor ("%s\n", srec);
|
||||||
|
}
|
||||||
|
if (hashmark)
|
||||||
|
printf_filtered ("#");
|
||||||
|
type = 3; /* switch to a 4 byte address record */
|
||||||
fflush (stdout);
|
fflush (stdout);
|
||||||
}
|
}
|
||||||
printf_filtered ("\n");
|
printf_filtered ("\n");
|
||||||
free (buffer);
|
free (buffer);
|
||||||
|
} else {
|
||||||
|
debuglogs (3, "%s doesn't need to be loaded", s->name);
|
||||||
}
|
}
|
||||||
s = s->next;
|
s = s->next;
|
||||||
}
|
}
|
||||||
sprintf (buffer, "rs ip %lx", (unsigned long) abfd->start_address);
|
|
||||||
printf_monitor (buffer);
|
/*
|
||||||
|
write a type 7 terminator record. no data for a type 7,
|
||||||
|
and there is no data, so len is 0.
|
||||||
|
*/
|
||||||
|
monitor_make_srec (srec, 7, abfd->start_address, "", 0);
|
||||||
|
printf_monitor ("%s\n", srec);
|
||||||
|
if (protocol == XMODEM) {
|
||||||
|
printf_monitor ("%c", EOT);
|
||||||
|
if (!GETACK)
|
||||||
|
error ("Never got ACK after sending EOT");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hashmark)
|
||||||
|
putchar ('\n');
|
||||||
|
|
||||||
expect_prompt ();
|
expect_prompt ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* getacknak -- get an ACK or a NAK from the target.
|
||||||
|
* returns 1 (true) or 0 (false) This is
|
||||||
|
* for xmodem. ANy string starting with "***"
|
||||||
|
* is an error message from the target.
|
||||||
|
* Here's a few from the WinBond w89k "Cougar" PA board.
|
||||||
|
* *** Too many errors found.
|
||||||
|
* *** Bad command
|
||||||
|
* *** Command syntax error
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
getacknak (byte)
|
||||||
|
int byte;
|
||||||
|
{
|
||||||
|
char character;
|
||||||
|
int i;
|
||||||
|
|
||||||
static int
|
i = 0;
|
||||||
monitor_write_srec (memaddr, myaddr, len)
|
while (i++ < 60) {
|
||||||
|
character = (char)readchar (0);
|
||||||
|
if (character == 0xfffffffe) { /* empty uart */
|
||||||
|
if (sr_get_debug() > 3)
|
||||||
|
putchar ('.');
|
||||||
|
fflush (stdout);
|
||||||
|
sleep (1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (character == CANCEL) { /* target aborted load */
|
||||||
|
expect_prompt (0);
|
||||||
|
error ("Got a CANCEL from the target.");
|
||||||
|
}
|
||||||
|
if (character == '*') { /* look for missed error message */
|
||||||
|
expect_prompt (0);
|
||||||
|
error ("Got an error message from the target");
|
||||||
|
}
|
||||||
|
debuglogs (3, "Got a %s (0x%x or \'%c\'), expecting a %s.\n",
|
||||||
|
(character == ACK) ? "ACK" : (character == NAK) ? "NAK" : "BOGUS",
|
||||||
|
character, character, (byte == ACK) ? "ACK" : "NAK");
|
||||||
|
if (character == byte) /* got what we wanted */
|
||||||
|
return 1;
|
||||||
|
if (character == ((byte == ACK) ? NAK : ACK)) { /* got the opposite */
|
||||||
|
debuglogs (3, "Got the opposite, wanted 0x%x, got a 0x%x", byte, character);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
sleep (1);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* monitor_make_srec -- make an srecord. This writes each line, one at a
|
||||||
|
* time, each with it's own header and trailer line.
|
||||||
|
* An srecord looks like this:
|
||||||
|
*
|
||||||
|
* byte count-+ address
|
||||||
|
* start ---+ | | data +- checksum
|
||||||
|
* | | | |
|
||||||
|
* S01000006F6B692D746573742E73726563E4
|
||||||
|
* S315000448600000000000000000FC00005900000000E9
|
||||||
|
* S31A0004000023C1400037DE00F023604000377B009020825000348D
|
||||||
|
* S30B0004485A0000000000004E
|
||||||
|
* S70500040000F6
|
||||||
|
*
|
||||||
|
* S<type><length><address><data><checksum>
|
||||||
|
*
|
||||||
|
* Where
|
||||||
|
* - length
|
||||||
|
* is the number of bytes following upto the checksum. Note that
|
||||||
|
* this is not the number of chars following, since it takes two
|
||||||
|
* chars to represent a byte.
|
||||||
|
* - type
|
||||||
|
* is one of:
|
||||||
|
* 0) header record
|
||||||
|
* 1) two byte address data record
|
||||||
|
* 2) three byte address data record
|
||||||
|
* 3) four byte address data record
|
||||||
|
* 7) four byte address termination record
|
||||||
|
* 8) three byte address termination record
|
||||||
|
* 9) two byte address termination record
|
||||||
|
*
|
||||||
|
* - address
|
||||||
|
* is the start address of the data following, or in the case of
|
||||||
|
* a termination record, the start address of the image
|
||||||
|
* - data
|
||||||
|
* is the data.
|
||||||
|
* - checksum
|
||||||
|
* is the sum of all the raw byte data in the record, from the length
|
||||||
|
* upwards, modulo 256 and subtracted from 255.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
monitor_make_srec (buffer, type, memaddr, myaddr, len)
|
||||||
|
char *buffer;
|
||||||
|
int type;
|
||||||
CORE_ADDR memaddr;
|
CORE_ADDR memaddr;
|
||||||
unsigned char *myaddr;
|
unsigned char *myaddr;
|
||||||
int len;
|
int len;
|
||||||
{
|
{
|
||||||
int done;
|
|
||||||
int checksum;
|
int checksum;
|
||||||
int x;
|
int i;
|
||||||
int retries;
|
char *buf;
|
||||||
int srec_bytes = 40;
|
|
||||||
int srec_max_retries = 3;
|
|
||||||
int srec_echo_pace = 0;
|
|
||||||
int srec_sleep = 0;
|
|
||||||
int srec_noise = 0;
|
|
||||||
char *buffer = alloca ((srec_bytes + 8) << 1);
|
|
||||||
|
|
||||||
retries = 0;
|
buf = buffer;
|
||||||
|
debuglogs (4, "monitor_make_srec (buffer=0x%x, type=%d, memaddr=0x%x, len=%d",
|
||||||
|
buffer, type, memaddr, len);
|
||||||
|
checksum = 0;
|
||||||
|
|
||||||
while (1) { /* FIXME !!! */
|
/*
|
||||||
done = 0;
|
create the header for the srec. 4 is the number of bytes in the address,
|
||||||
|
and 1 is the number of bytes in the count.
|
||||||
|
*/
|
||||||
|
if (type == 0) /* FIXME: type 0 is optional */
|
||||||
|
type = 3; /* so use data as it works */
|
||||||
|
sprintf (buf, "S%d%02X%08X", type, len + 4 + 1, memaddr);
|
||||||
|
buf += 12;
|
||||||
|
|
||||||
if (retries > srec_max_retries)
|
checksum += (len + 4 + 1 /* calculate the checksum */
|
||||||
return(-1);
|
+ (memaddr & 0xff)
|
||||||
|
+ ((memaddr >> 8) & 0xff)
|
||||||
|
+ ((memaddr >> 16) & 0xff)
|
||||||
|
+ ((memaddr >> 24) & 0xff));
|
||||||
|
|
||||||
if (retries > 0) {
|
for (i = 0; i < len; i++) { /* build the srecord */
|
||||||
if (sr_get_debug() > 0)
|
sprintf (buf, "%02X", myaddr[i]);
|
||||||
printf("\n<retrying...>\n");
|
checksum += myaddr[i];
|
||||||
|
buf += 2;
|
||||||
/* This gr_expect_prompt call is extremely important. Without
|
|
||||||
it, we will tend to resend our packet so fast that it
|
|
||||||
will arrive before the bug monitor is ready to receive
|
|
||||||
it. This would lead to a very ugly resend loop. */
|
|
||||||
|
|
||||||
gr_expect_prompt();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* FIXME: this is just start_load pasted in... */
|
|
||||||
{ char *command;
|
|
||||||
command = (srec_echo_pace ? "lo 0 ;x" : "lo 0");
|
|
||||||
sr_write_cr (command);
|
|
||||||
sr_expect (command);
|
|
||||||
sr_expect ("\r\n");
|
|
||||||
#if 0
|
|
||||||
bug_srec_write_cr ("S0030000FC");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
/* end of hack */
|
|
||||||
|
|
||||||
while (done < len) {
|
|
||||||
int thisgo;
|
|
||||||
int idx;
|
|
||||||
char *buf = buffer;
|
|
||||||
CORE_ADDR address;
|
|
||||||
|
|
||||||
checksum = 0;
|
|
||||||
thisgo = len - done;
|
|
||||||
if (thisgo > srec_bytes)
|
|
||||||
thisgo = srec_bytes;
|
|
||||||
|
|
||||||
address = memaddr + done;
|
|
||||||
sprintf (buf, "S3%02X%08X", thisgo + 4 + 1, address);
|
|
||||||
buf += 12;
|
|
||||||
|
|
||||||
checksum += (thisgo + 4 + 1
|
|
||||||
+ (address & 0xff)
|
|
||||||
+ ((address >> 8) & 0xff)
|
|
||||||
+ ((address >> 16) & 0xff)
|
|
||||||
+ ((address >> 24) & 0xff));
|
|
||||||
|
|
||||||
for (idx = 0; idx < thisgo; idx++) {
|
|
||||||
sprintf (buf, "%02X", myaddr[idx + done]);
|
|
||||||
checksum += myaddr[idx + done];
|
|
||||||
buf += 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (srec_noise > 0) {
|
|
||||||
/* FIXME-NOW: insert a deliberate error every now and then.
|
|
||||||
This is intended for testing/debugging the error handling
|
|
||||||
stuff. */
|
|
||||||
static int counter = 0;
|
|
||||||
if (++counter > srec_noise) {
|
|
||||||
counter = 0;
|
|
||||||
++checksum;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sprintf(buf, "%02X", ~checksum & 0xff);
|
|
||||||
#if 0
|
|
||||||
bug_srec_write_cr (buffer);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (srec_sleep != 0)
|
|
||||||
sleep(srec_sleep);
|
|
||||||
|
|
||||||
/* This pollchar is probably redundant to the gr_multi_scan
|
|
||||||
below. Trouble is, we can't be sure when or where an
|
|
||||||
error message will appear. Apparently, when running at
|
|
||||||
full speed from a typical sun4, error messages tend to
|
|
||||||
appear to arrive only *after* the s7 record. */
|
|
||||||
|
|
||||||
if ((x = sr_pollchar()) != 0) {
|
|
||||||
if (sr_get_debug() > 0)
|
|
||||||
printf("\n<retrying...>\n");
|
|
||||||
|
|
||||||
++retries;
|
|
||||||
|
|
||||||
/* flush any remaining input and verify that we are back
|
|
||||||
at the prompt level. */
|
|
||||||
gr_expect_prompt();
|
|
||||||
/* start all over again. */
|
|
||||||
/* FIXME: this is just start_load pasted in... */
|
|
||||||
{ char *command;
|
|
||||||
command = (srec_echo_pace ? "lo 0 ;x" : "lo 0");
|
|
||||||
sr_write_cr (command);
|
|
||||||
sr_expect (command);
|
|
||||||
sr_expect ("\r\n");
|
|
||||||
#if 0
|
|
||||||
bug_srec_write_cr ("S0030000FC");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
/* end of hack */
|
|
||||||
|
|
||||||
done = 0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
done += thisgo;
|
|
||||||
}
|
|
||||||
#if 0
|
|
||||||
bug_srec_write_cr("S7060000000000F9");
|
|
||||||
#endif
|
|
||||||
++retries;
|
|
||||||
|
|
||||||
/* Having finished the load, we need to figure out whether we
|
|
||||||
had any errors. */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sprintf(buf, "%02X", ~checksum & 0xff); /* add the checksum */
|
||||||
|
debuglogs (3, "srec is \"%s\"", buffer);
|
||||||
|
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* make_xmodem_packet -- this takes a 128 bytes of data and makes a packet
|
||||||
|
* out of it.
|
||||||
|
*
|
||||||
|
* Each packet looks like this:
|
||||||
|
* +-----+-------+-------+------+-----+
|
||||||
|
* | SOH | Seq1. | Seq2. | data | SUM |
|
||||||
|
* +-----+-------+-------+------+-----+
|
||||||
|
* SOH = 0x01
|
||||||
|
* Seq1 = The sequence number.
|
||||||
|
* Seq2 = The complement of the sequence number.
|
||||||
|
* Data = A 128 bytes of data.
|
||||||
|
* SUM = Add the contents of the 128 bytes and use the low-order
|
||||||
|
* 8 bits of the result.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
make_xmodem_packet (packet, data, len)
|
||||||
|
unsigned char packet[];
|
||||||
|
unsigned char *data;
|
||||||
|
int len;
|
||||||
|
{
|
||||||
|
static int sequence = 1;
|
||||||
|
int i, sum;
|
||||||
|
unsigned char *buf;
|
||||||
|
|
||||||
|
buf = data;
|
||||||
|
/* build the packet header */
|
||||||
|
packet[0] = SOH;
|
||||||
|
packet[1] = sequence;
|
||||||
|
packet[2] = 255 - sequence;
|
||||||
|
sequence++;
|
||||||
|
#if 0
|
||||||
|
packet[2] = ~sequence++; /* the complement is the sequence checksum */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
sum = 0; /* calculate the data checksum */
|
||||||
|
for (i = 3; i <= len + 2; i++) {
|
||||||
|
packet[i] = *buf;
|
||||||
|
sum += *buf;
|
||||||
|
buf++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = len+1 ; i <= XMODEM_DATASIZE ; i++) { /* add padding for the rest of the packet */
|
||||||
|
packet[i] = '0';
|
||||||
|
}
|
||||||
|
|
||||||
|
packet[XMODEM_PACKETSIZE] = sum & 0xff; /* add the checksum */
|
||||||
|
|
||||||
|
if (sr_get_debug() > 4)
|
||||||
|
debuglogs (4, "The xmodem checksum is %d (0x%x)\n", sum & 0xff, sum & 0xff);
|
||||||
|
print_xmodem_packet (packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* print_xmodem_packet -- print the packet as a debug check
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
print_xmodem_packet(packet)
|
||||||
|
char packet[];
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
static int lastseq;
|
||||||
|
int sum;
|
||||||
|
|
||||||
|
/* take apart the packet header the packet header */
|
||||||
|
if (packet[0] == SOH) {
|
||||||
|
("SOH");
|
||||||
|
} else {
|
||||||
|
error ("xmodem: SOH is wrong");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check the sequence */
|
||||||
|
if (packet[1] != 0) {
|
||||||
|
lastseq = packet[1];
|
||||||
|
if (packet[2] != ~lastseq)
|
||||||
|
error ("xmodem: Sequence checksum is wrong");
|
||||||
|
else
|
||||||
|
printf_filtered (" %d %d", lastseq, ~lastseq);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check the data checksum */
|
||||||
|
sum = 0;
|
||||||
|
for (i = 3; i <= XMODEM_DATASIZE; i++) {
|
||||||
|
sum += packet[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ignore the data */
|
||||||
|
#if 0
|
||||||
|
printf (" [128 bytes of data] %d\n", sum & 0xff);
|
||||||
|
#endif
|
||||||
|
printf_filtered (" [%s] %d\n", packet, sum & 0xff);
|
||||||
|
|
||||||
|
if ((packet[XMODEM_PACKETSIZE] & 0xff) != (sum & 0xff)) {
|
||||||
|
debuglogs (4, "xmodem: data checksum wrong, got a %d", packet[XMODEM_PACKETSIZE] & 0xff);
|
||||||
|
}
|
||||||
|
putchar ('\n');
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* _initialize_remote_monitors -- setup a few addtitional commands that
|
* _initialize_remote_monitors -- setup a few addtitional commands that
|
||||||
* are usually only used by monitors.
|
* are usually only used by monitors.
|
||||||
|
|
143
gdb/rom68k-rom.c
Normal file
143
gdb/rom68k-rom.c
Normal file
|
@ -0,0 +1,143 @@
|
||||||
|
#include "defs.h"
|
||||||
|
#include "gdbcore.h"
|
||||||
|
#include "target.h"
|
||||||
|
#include "monitor.h"
|
||||||
|
|
||||||
|
extern int baud_rate;
|
||||||
|
|
||||||
|
void rom68k_open();
|
||||||
|
void monitor_open();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* this array of registers need to match the indexes used by GDB. The
|
||||||
|
* whole reason this exists is cause the various ROM monitors use
|
||||||
|
* different strings than GDB does, and doesn't support all the
|
||||||
|
* registers either. So, typing "info reg sp" becomes a "r30".
|
||||||
|
*/
|
||||||
|
static char *rom68k_regnames[] = {
|
||||||
|
"d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "a0", "a1",
|
||||||
|
"a2", "a3", "a4", "a5", "a6", "usp", "ssp","pc", "", "",
|
||||||
|
"", "", "", "", "", "", "", "", "", "",
|
||||||
|
"", "", "", "", "", "", "",
|
||||||
|
"", "", "", "", "", "", "", "", "", "",
|
||||||
|
"", "", "", "", "", "", "", "", "", "",
|
||||||
|
"", "", "", "", "", "", "",
|
||||||
|
"", "", "", "", "", "", "", "",
|
||||||
|
"", "", "", "", "", "", "", "",
|
||||||
|
"", "", "", "", "", "", "", "",
|
||||||
|
"", "", "", "", "", "", "", "",
|
||||||
|
"", "", "", "", "", "", "", "",
|
||||||
|
"", "", "", "", "", "", "", "",
|
||||||
|
"", "", "", "", "", "", "", "",
|
||||||
|
"", "", "", "", "", "", "", ""
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct target_ops rom68k_ops = {
|
||||||
|
"rom68k",
|
||||||
|
"WinBond's debug monitor for the Rom68k Eval board",
|
||||||
|
"Debug on a Motorola IDP eval board running the ROM68K monitor.\n\
|
||||||
|
Specify the serial device it is connected to (e.g. /dev/ttya).",
|
||||||
|
rom68k_open,
|
||||||
|
monitor_close,
|
||||||
|
monitor_attach,
|
||||||
|
monitor_detach,
|
||||||
|
monitor_resume,
|
||||||
|
monitor_wait,
|
||||||
|
monitor_fetch_register,
|
||||||
|
monitor_store_register,
|
||||||
|
monitor_prepare_to_store,
|
||||||
|
monitor_xfer_inferior_memory,
|
||||||
|
monitor_files_info,
|
||||||
|
monitor_insert_breakpoint,
|
||||||
|
monitor_remove_breakpoint, /* Breakpoints */
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0, /* Terminal handling */
|
||||||
|
monitor_kill,
|
||||||
|
monitor_load, /* load */
|
||||||
|
0, /* lookup_symbol */
|
||||||
|
monitor_create_inferior,
|
||||||
|
monitor_mourn_inferior,
|
||||||
|
0, /* can_run */
|
||||||
|
0, /* notice_signals */
|
||||||
|
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 */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct monitor_ops rom68k_cmds = {
|
||||||
|
1, /* 1 for ASCII, 0 for binary */
|
||||||
|
"\n", /* monitor init string */
|
||||||
|
"go \n", /* execute or usually GO command */
|
||||||
|
"go \n", /* continue command */
|
||||||
|
"st \n", /* single step */
|
||||||
|
"db %x\n", /* set a breakpoint */
|
||||||
|
"cb %x\r", /* clear a breakpoint */
|
||||||
|
0, /* 0 for number, 1 for address */
|
||||||
|
{
|
||||||
|
"pm %x %x\r", /* set memory */
|
||||||
|
"=", /* delimiter */
|
||||||
|
"", /* the result */
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"dm %x 1\r", /* get memory */
|
||||||
|
"", /* delimiter */
|
||||||
|
"", /* the result */
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pr %s %x\r", /* set a register */
|
||||||
|
"", /* delimiter between registers */
|
||||||
|
"", /* the result */
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pr %s\n", /* get a register */
|
||||||
|
":", /* delimiter between registers */
|
||||||
|
"", /* the result */
|
||||||
|
},
|
||||||
|
"dc\n", /* download command */
|
||||||
|
"ROM68K :->", /* monitor command prompt */
|
||||||
|
"=", /* end-of-command delimitor */
|
||||||
|
".\n", /* optional command terminator */
|
||||||
|
&rom68k_ops, /* target operations */
|
||||||
|
"srec,xmodem-ascii,xmodem-srec,default",/* load types */
|
||||||
|
rom68k_regnames /* registers names */
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
rom68k_open(args, from_tty)
|
||||||
|
char *args;
|
||||||
|
int from_tty;
|
||||||
|
{
|
||||||
|
target_preopen(from_tty);
|
||||||
|
push_target (&rom68k_ops);
|
||||||
|
push_monitor (&rom68k_cmds);
|
||||||
|
monitor_open (args, "rom68k", from_tty);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_initialize_rom68k ()
|
||||||
|
{
|
||||||
|
add_target (&rom68k_ops);
|
||||||
|
|
||||||
|
/* this is the default, since it's the only baud rate supported by the hardware */
|
||||||
|
baud_rate = 9600;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue