diff options
author | John Gilmore <gnu@cygnus> | 1991-04-05 09:01:15 +0000 |
---|---|---|
committer | John Gilmore <gnu@cygnus> | 1991-04-05 09:01:15 +0000 |
commit | 07d021a6ae8d3ed9da9f55c8623739e7a716308e (patch) | |
tree | b89d9ed8acbddfa222437388e1b1c2e5c3226082 /gdb/remote-sa.sparc.c | |
parent | 4e1dc656813c2a5e04f210210977ab748514bd4b (diff) | |
download | gdb-07d021a6ae8d3ed9da9f55c8623739e7a716308e.zip gdb-07d021a6ae8d3ed9da9f55c8623739e7a716308e.tar.gz gdb-07d021a6ae8d3ed9da9f55c8623739e7a716308e.tar.bz2 |
Initial revision
Diffstat (limited to 'gdb/remote-sa.sparc.c')
-rw-r--r-- | gdb/remote-sa.sparc.c | 1146 |
1 files changed, 1146 insertions, 0 deletions
diff --git a/gdb/remote-sa.sparc.c b/gdb/remote-sa.sparc.c new file mode 100644 index 0000000..686699e --- /dev/null +++ b/gdb/remote-sa.sparc.c @@ -0,0 +1,1146 @@ +/* THIS FILE HAS NOT HAD ITS COPYRIGHT CHECKED...FSF SHOULD NOT + DISTRIBUTE IT UNTIL THIS HAPPENS. */ + +/* Memory-access and commands for inferior process, for GDB. +*/ + +#include <sys/errno.h> +#include <setjmp.h> +#include <stdio.h> +#include "defs.h" +#include "param.h" +#include "frame.h" +#include "value.h" +#include "inferior.h" +#include "symtab.h" + +#undef WSTOPSIG +#undef WTERMSIG +#include "wait.h" + +#ifdef USG +#include <sys/types.h> +#include <fcntl.h> +#endif + +#include <signal.h> +#include <sys/file.h> + +#include <termios.h> +#define TERMINAL struct termios + +#define LONGTIMEOUT 5 +#define SHORTTIMEOUT 1 + +#define KD_MINUTAE 1 +#define KD_LINEDISCIPLINE 2 +#define KD_RETRY 4 +#define KD_BLOCKTRANSFER 8 + +#ifndef STDIN +#define STDIN 0 +#endif + +#define GL_READING 0 /* get line is reading data */ +#define GL_OK 1 /* Getline saw the "ok" string */ +#define GL_SUCCESS 2 /* Get line got data */ +#define GL_TIMEOUT 3 /* Get line timed out */ +#define GL_OVERRUN 4 /* Get line filled up the buffer */ +#define GL_EXCEPTION 5 /* Get line saw "Exception" */ +#define GL_PROMLINE 6 /* Get line saw prom specific info */ +#define GL_BLANKLINE 7 /* Get line saw a blank line */ + +static int kiodebug /* = KD_RETRY | KD_BLOCKTRANSFER */; + +static CORE_ADDR remote_pc = 0; +static CORE_ADDR remote_next_pc = 0; +static CORE_ADDR remove_thisbp_next_pc = 0; +static CORE_ADDR remove_thisbp_target = 0; + +enum showDrainage {DONTSHOW , SHOW} ; + + +/* Descriptor for I/O to remote machine. Initialize it to -1 so that + remote_open knows that we don't have a file open when the program + starts. */ +int remote_desc = -1; + +int dontskipcrs = 0; + +#define PBUFSIZ 400 + +unsigned char ignorebuf[PBUFSIZ]; +#define IGNORE &ignorebuf[0] + +/* Maximum number of bytes to read/write at once. The value here + is chosen to fill up a packet (the headers account for the 32). */ +#define MAXBUFBYTES ((PBUFSIZ-32)/2) + +static void remote_send (); +static void putpkt (); +static int getpkt (); + + +/* Open a connection to a remote debugger. + NAME is the filename used for communication. */ +CORE_ADDR breakpoint_regs_addr; + + +void +remote_open (name, from_tty) + char *name; + int from_tty; +{ + extern int frame_file_full_name; + unsigned char buf[PBUFSIZ]; + TERMINAL sg; + + remote_debugging = 0; + + if (remote_desc >= 0) + close (remote_desc); + + breakpoint_regs_addr = parse_and_eval_address("&breakpoint_regs"); + + dontskipcrs = !frame_file_full_name; /* if we are running inside of + emacs, this will be true. + then skip carriage returns */ + + remote_desc = open (name, O_RDWR); + if (remote_desc < 0) + perror_with_name (name); + + setup_remote(); + + if (from_tty) + printf ("Remote debugging using %s\n", name); + remote_debugging = 1; + + +} +static char *boot_cmd = 0; + +static print_boot_cmd() +{ + fprintf(stderr, "boot command set to be \"%s\"\n", boot_cmd); +} + +remote_start() +{ + WAITTYPE ignoredWaitType; + + if (boot_cmd) + { + sendbreak(); + remote_wait (&ignoredWaitType); + putpkt ("reset"); + sleep(10); + sendbreak(); + remote_wait (&ignoredWaitType); + sleep(10); + print_boot_cmd(); + putpkt(boot_cmd); + fprintf(stderr, "rgdb and nucleus synchronized, booting....\n"); + } + else + { + error("The boot command is null. Cannot start the remote kernel/nucleus"); + } +} + +/* Close the open connection to the remote debugger. + Use this when you want to detach and do something else + with your gdb. */ +void +remote_close (from_tty) + int from_tty; +{ + if (!remote_debugging) + error ("Can't close remote connection: not debugging remotely."); + + close (remote_desc); /* This should never be called if + there isn't something valid in + remote_desc. */ + + /* Do not try to close remote_desc again, later in the program. */ + remote_desc = -1; + + if (from_tty) + printf ("Ending remote debugging\n"); + + remote_debugging = 0; +} + +/* Convert hex digit A to a number. */ + +static int +fromhex (a) + int a; +{ + if (a >= '0' && a <= '9') + return a - '0'; + else if (a >= 'a' && a <= 'f') + return a - 'a' + 10; + else + error ("Reply contains invalid hex digit"); +} + +/* Convert number NIB to a hex digit. */ + +static int +tohex (nib) + int nib; +{ + if (nib < 10) + return '0'+nib; + else + return 'a'+nib-10; +} + +/* Tell the remote machine to resume. */ + +extern int one_stepped; /* From machine dependent code */ +static int remote_set_one_stepped; + +int +remote_resume (step, signal) + int step, signal; +{ + if (step) + { + remote_single_step(); + } + remote_set_one_stepped = step; + putpkt("go"); +} + +/* Wait until the remote machine stops, then return, + storing status in STATUS just as `wait' would. */ + +int +remote_wait (status) + WAITTYPE *status; +{ + char last, this; + int pend, saveTheOh = 0; + + user_terminal_raw(); + + WSETEXIT ((*status), 0177); + last = this = 0; + + while (1) + { + char buf[PBUFSIZ]; + int readUser, readProm, state; + + doselect(&readUser, &readProm); + if (readProm) + { + switch (state = getline(buf, PBUFSIZ, SHORTTIMEOUT)) + { + case GL_BLANKLINE: + if (remote_set_one_stepped) + break; + + /* fall through */ + + default: + case GL_READING: + case GL_SUCCESS: + case GL_OVERRUN: + case GL_TIMEOUT: + if (kiodebug & KD_LINEDISCIPLINE) + fprintf(stderr, "%d<%s>\n", state, buf); + else + { + fprintf(stderr, "%s", buf); + fflush(stderr); + } + break; + case GL_OK: + remote_cleanup_after_stop(); + WSETSTOP ((*status), SIGTRAP); + return; + case GL_PROMLINE: + break; + } + } + if (readUser) + shuffleFromUserToProm(); + } +} +static TERMINAL userterminal; + +user_terminal_restore() +{ +#if 0 + int in_desc = fileno (stdin); + ioctl (in_desc, TCSETS, &userterminal); +#endif +} +static void set_term_raw(); + +user_terminal_raw() +{ +#if 0 + TERMINAL tempterminal; + int in_desc = fileno (stdin); + ioctl (in_desc, TCGETS, &userterminal); + tempterminal = userterminal; + + tempterminal.c_lflag &= ~(ICANON|ISIG|IEXTEN); + tempterminal.c_cc[VMIN] = 1; + tempterminal.c_cc[VTIME] = 0; + tempterminal.c_iflag &= ~(INPCK|IXON|IXOFF); + tempterminal.c_oflag = 0; + + ioctl (in_desc, TCSETS, &tempterminal); +#endif +} + +doselect(pReadUser, pReadProm) + int *pReadUser, *pReadProm; +{ + extern FILE *instream; + int in_desc = fileno (stdin); + int instreammask = 1 << in_desc; + int remotemask = 1 << remote_desc; + int rfds = instreammask | remotemask; + + select (32, &rfds, 0, 0, (struct timeval *) 0); /* 0 = Block indefinitely */ + *pReadUser = (rfds & instreammask) == instreammask; + *pReadProm = (rfds & remotemask) == remotemask; +} + + + +/* Read the remote registers into the block pRegisters. +implementation copied largely from fetch_inferior_registers () +in sparc-dep.c */ + +void +remote_fetch_registers(ignored) +int *ignored; +{ + struct regs inferior_registers; + extern char registers[]; + CORE_ADDR breakpoint_regs_target; + + if (breakpoint_regs_addr == 0) + { + error("no address for breakpoint_regs\n"); + return; + } + remote_read_inferior_memory(breakpoint_regs_addr, &breakpoint_regs_target, + sizeof(breakpoint_regs_target)); + + bzero(registers, REGISTER_BYTES); + registers[REGISTER_BYTE (0)] = 0; + + if (breakpoint_regs_target) + { + remote_read_inferior_memory(breakpoint_regs_target, &inferior_registers, + sizeof(inferior_registers)); + registers[REGISTER_BYTE (0)] = 0; + bcopy (&inferior_registers.r_g1, ®isters[REGISTER_BYTE (1)], 15 * 4); + *(int *)®isters[REGISTER_BYTE (PS_REGNUM)] = inferior_registers.r_ps; + *(int *)®isters[REGISTER_BYTE (PC_REGNUM)] = inferior_registers.r_pc; + *(int *)®isters[REGISTER_BYTE (NPC_REGNUM)] = inferior_registers.r_npc; + *(int *)®isters[REGISTER_BYTE (Y_REGNUM)] = inferior_registers.r_y; + remote_pc = inferior_registers.r_pc; + remote_next_pc = inferior_registers.r_npc; + remote_read_inferior_memory (inferior_registers.r_sp, + ®isters[REGISTER_BYTE (16)], + 16*4); + } + else + { + error("breakpoint_regs == 0\n"); + } +} + + + + +/* Write memory data directly to the remote machine. + This does not inform the data cache; the data cache uses this. + MEMADDR is the address in the remote memory space. + MYADDR is the address of the buffer in our space. + LEN is the number of bytes. */ + +int +remote_write_bytes (memaddr, myaddr, len) + CORE_ADDR memaddr; + unsigned char *myaddr; + int len; +{ + char buf[PBUFSIZ]; + int i; + + /* Command describes registers byte by byte, + each byte encoded as two hex characters. */ + + for (i = 0; i < len; i++) + { + sprintf(buf, "%x %x c!", myaddr[i], memaddr + i); + remote_send (buf, buf); + if (strstr(buf, "Exception")) + { + return EFAULT; + } + } + return 0; +} + +/* Copy LEN bytes of data from debugger memory at MYADDR + to inferior's memory at MEMADDR. Returns errno value. */ +int +remote_write_inferior_memory (memaddr, myaddr, len) + CORE_ADDR memaddr; + char *myaddr; + int len; +{ + int xfersize; + int retval; + + while (len > 0) + { + if (len > MAXBUFBYTES) + xfersize = MAXBUFBYTES; + else + xfersize = len; + + retval = remote_write_bytes(memaddr, myaddr, xfersize); + if (retval) + return retval; /* error */ + + memaddr += xfersize; + myaddr += xfersize; + len -= xfersize; + } + return 0; /* no error */ +} + + +/* read a single character */ + +static int +readCharFromProm () +{ + char buf; + + buf = '\0'; + /* termio does the timeout for us. */ + read (remote_desc, &buf, 1); + return buf & 0x7f; +} + +/* Send the command in BUF to the remote machine, + and read the reply into BUF. + Report an error if we get an error reply. */ + +static void +remote_send (buf, buf2) + char *buf, *buf2; +{ + putpkt (buf); + getpkt (buf2); +} + +/* Send a single character out over the wire */ + +static void +putcharacter (ch) + char ch; +{ + + while (1) + { + int i; + + write(remote_desc, &ch, 1); + for (i = 0; i < 100; i++) + { + char nch = 0; + + if (read (remote_desc, &nch, 1) == 0) + i++; + if ((ch == nch) + || (ch == '\n' && nch == '\r') + || (ch == '\r' && nch == '\n')) + return; + if (kiodebug & KD_MINUTAE) + fprintf (stderr, "Sent %c(%d) Received %c(%d)\n", ch, ch, nch, nch); + } + } +} + +/* Send a packet to the remote machine, with error checking. + The data of the packet is in BUF. */ + +static void +putpkt (buf) + char *buf; +{ + int i; + int cnt = strlen (buf); + char ch; + + if (kiodebug & KD_LINEDISCIPLINE) + fprintf(stderr, "putpkt(%s)\n", buf); + + for (i = 0; i < cnt; i++) + putcharacter (buf[i]); + putcharacter ('\n'); +} + +jmp_buf getline_jmpbuf; + +/* Read a line from the remote machine, and store it in BUF. */ +getline_timer() +{ + alarm(0); + + if (kiodebug & KD_RETRY) + fprintf(stderr, "getline timed out\n"); + longjmp(getline_jmpbuf, 1); +} + +static int +getline (buf, size, timeout) + char *buf; + int size, timeout; +{ + int cnt = 0; + int state; + int isspace_state = 1; + + if ((void (*)) signal (SIGALRM, getline_timer) == (void (*)) -1) + perror ("remote_open: error in signal"); + + --size; /* back it up one so that we can read */ + + state = GL_READING; + + if (setjmp(getline_jmpbuf)) + state = GL_TIMEOUT; + else + { + alarm (timeout); + do + { + char ch = readCharFromProm(); + isspace_state = isspace_state && isspace(ch); + if (ch && (dontskipcrs || ch != '\r')) + { + buf[cnt++] = ch; + buf[cnt] = '\0'; + } + if (kiodebug & KD_MINUTAE) + fprintf (stderr,"letter received :%c\n", buf[cnt - 1]); + if (cnt >= 2 && buf[cnt - 2] == 'o' && buf[cnt - 1] == 'k') + state = GL_OK; + else if (buf[cnt - 1] == '\n' ) + state = isspace_state ? GL_BLANKLINE : GL_SUCCESS; + else if (cnt == size) + state = GL_OVERRUN; + else if (strstr(buf, "Type 'go' to resume")) + state = GL_PROMLINE; + else if (strstr(buf, "Type help for more information")) + state = GL_PROMLINE; + else if (strstr(buf, "Exception")) + state = GL_EXCEPTION; + } + while (state == GL_READING); + } + alarm (0); + + if (kiodebug & KD_LINEDISCIPLINE) + fprintf (stderr,"Line received :%s\n", buf); + return state; +} + + +/* Read a packet from the remote machine, and store it in BUF. */ + +static int +getpkt (buf) + char *buf; +{ + int cnt = 0; + + do + { + char ch = readCharFromProm(); + if (ch) + buf[cnt++] = ch; + if (kiodebug & KD_MINUTAE) + fprintf (stderr,"letter received :%c\n", buf[cnt - 1]); + } + while (cnt < 2 || + buf[cnt - 2] != 'o' && + buf[cnt - 1] != 'k'); + + buf[cnt] = '\0'; + if (kiodebug& KD_LINEDISCIPLINE) + fprintf (stderr,"Packet received :%s\n", buf); + return cnt; +} + +void remote_fetch_word (addr) + CORE_ADDR addr; +{ + error ("Internal error: remote_fetch_word is obsolete.\n"); +} +void remote_store_word (addr) + CORE_ADDR addr; +{ + error ("Internal error: remote_store_word is obsolete.\n"); +} +#include <termio.h> + +draininput(showit) +enum showDrainage showit; +{ + unsigned char buf[PBUFSIZ]; + int cnt; + + while ((cnt = read(remote_desc, buf, PBUFSIZ)) > 0) + { + buf[cnt] = 0; + if (kiodebug& KD_LINEDISCIPLINE) + fprintf (stderr,"Draining :%s\n", buf); + else + if (showit == SHOW) + fprintf (stderr,"%s", buf); + } + if (kiodebug& KD_LINEDISCIPLINE) + fprintf (stderr,"Drained\n"); +} +sendbreak() +{ + if (kiodebug & KD_RETRY) + fprintf (stderr,"rgdb sending break to target...\n"); + else + { + fprintf (stderr,"="); + fflush(stderr); + } + + ioctl (remote_desc, TCSBRK, 0); + sleep(5); +} + + +/* shuffle a character from the user to remote debugger */ + +int +shuffleFromUserToProm() +{ + char ch; + static int escape = 0; + + extern FILE *instream; + + ch = 0; + if (read(STDIN, &ch , 1) != 1 || ch == 0) + return; + + if (escape) { + if (ch == '#') + sendbreak(); + else if (ch == '.') + { + while (ch != '\n') + read(STDIN, &ch , 1); + return 1; + } + else { + static char tilde = '~'; + + putcharacter(tilde); + putcharacter(ch); + } + escape = 0; + } else /* not escape */ { + if (ch == '~') + escape = 1; + else + putcharacter(ch); + } + return 0; +} + + + +/* Tell the Prom put a breakpoint at memaddr */ +remote_insert_breakpoint(memaddr) + CORE_ADDR memaddr; +{ + char buf[PBUFSIZ]; + + /* Command describes registers byte by byte, + each byte encoded as two hex characters. */ + + sprintf(buf, "%x +bp", memaddr); + remote_send(buf, buf); + if (strstr(buf, "Exception")) + { + return EFAULT; + } + else + { + return 0; + } +} + +/* Tell the Prom remove the the breakpoint at memaddr */ +remote_remove_breakpoint(memaddr) + CORE_ADDR memaddr; +{ + char buf[PBUFSIZ]; + + /* Command describes registers byte by byte, + each byte encoded as two hex characters. */ + + sprintf(buf, "%x -bp", memaddr); + remote_send(buf, buf); + if (strstr(buf, "Exception")) + { + return EFAULT; + } + else + { + return 0; + } +} + + + + + +/* Read memory data directly from the remote machine. + This does not use the data cache; the data cache uses this. + MEMADDR is the address in the remote memory space. + MYADDR is the address of the buffer in our space. + LEN is the number of words. */ + +long +remote_read(memaddr, myaddr, len, increment, promcommand) + CORE_ADDR memaddr; + unsigned char *myaddr; + int len, increment; + char *promcommand; +{ + char buf[PBUFSIZ]; + char buf2[PBUFSIZ]; + int i; + unsigned long num; + + /* Command describes registers byte by byte, + each byte encoded as two hex characters. */ + + for (i = 0; i < len; i += increment) + { + sprintf(buf, promcommand, memaddr + i) ; + remote_send(buf, buf2); + remote_send(".", buf); + if (strstr(buf2, "Exception")) + { + bzero(&myaddr[i], len - i); + return -i; + } + else + { + char *pBuf; + for (pBuf = &buf[0]; *pBuf == '\r' || *pBuf == '\n'; pBuf++) + ; + sscanf(pBuf, "%x\n", &num); + switch (increment) + { + case 1: myaddr[i] = num; + if (num > 255) + fprintf(stderr, "number out of bounds %x truncating to %x\n", + num, myaddr[i]); + break; + case 4: {unsigned long *p; + p = (unsigned long *) &myaddr[i]; + *p = num; + } + break; + default: fprintf(stderr, "unknown increment\n"); break; + } + } + } + return i; +} + + + +/* Read LEN bytes from inferior memory at MEMADDR. Put the result + at debugger address MYADDR. Returns errno value. */ +int +remote_read_inferior_memory(memaddr, myaddr, len) + CORE_ADDR memaddr; + char *myaddr; + int len; +{ + int xfersize; + while (len > 0) + { + int mod; + + if (len > MAXBUFBYTES) + xfersize = MAXBUFBYTES; + else + xfersize = len; + + mod = memaddr % 4; + if (mod == 0 && xfersize >= 4) + if (mod == 0 && xfersize >= 16) + { + xfersize = remote_read_many(memaddr, myaddr, (len & ~3)); + getpkt(IGNORE); + } + else + xfersize = remote_read(memaddr, myaddr, 4, 4, "%x @"); + else + xfersize = remote_read(memaddr, myaddr, max(mod, 1), 1, "%x c@"); + if (xfersize <= 0) + return EFAULT; /* error */ + memaddr += xfersize; + myaddr += xfersize; + len -= xfersize; + } + return 0; /* no error */ +} +static int baud_rate=B38400; + +static void set_term_raw(pTermio) + TERMINAL *pTermio; +{ + pTermio->c_cflag &= (CREAD|HUPCL|CLOCAL); + pTermio->c_cflag |= baud_rate | CS8; + pTermio->c_iflag = ISTRIP /* | IXON | IXOFF */; + pTermio->c_oflag = 0; + pTermio->c_lflag = 0; + pTermio->c_cc[VMIN] = 0; + pTermio->c_cc[VTIME] = 1; +} + +/* setup the remote termio stream */ +setup_remote() +{ + TERMINAL temptempio; + + ioctl(remote_desc, TCGETS, &temptempio); + set_term_raw(&temptempio); + ioctl(remote_desc, TCSETS, &temptempio); +} + +/* step one machine instruction */ +remote_single_step () +{ + CORE_ADDR next_pc, npc4, target, pc; + typedef enum + { + Error, not_branch, bicc, bicca, ba, baa, ticc, ta, + } branch_type; + branch_type br, isannulled(); + + npc4 = remote_next_pc + 4; /* branch not taken */ + + /* Always set breakpoint for NPC. */ + + remote_insert_breakpoint(remote_next_pc); + remove_thisbp_next_pc = remote_next_pc; + + /* printf ("set break at %x\n",remote_next_pc); */ + + br = isannulled (remote_pc, &target); + + if (br == bicca) + { + /* Conditional annulled branch will either end up at + npc (if taken) or at npc+4 (if not taken). + Trap npc+4. */ + remote_insert_breakpoint(npc4); + remove_thisbp_target = npc4; + } + else if (br == baa && target != remote_next_pc) + { + /* Unconditional annulled branch will always end up at + the target. */ + remote_insert_breakpoint(target); + remove_thisbp_target = target; + } +} + + + + +/* read many words of memory */ +long +remote_read_many(memaddr, myaddr, len) + CORE_ADDR memaddr; + unsigned char *myaddr; + int len; +{ +#define BLOCKSIZE 1024 + static int max_number_of_blocks = 24; + + char buf[PBUFSIZ]; + char buf2[PBUFSIZ]; + int i; + unsigned long *p; +/* Command describes registers byte by byte, + each byte encoded as two hex characters. */ + + len = min(len, max_number_of_blocks * BLOCKSIZE); + + sprintf(buf, "%x %x do i @ . cr 4 +loop", memaddr + len, memaddr); + putpkt(buf); + getline(buf2, PBUFSIZ, LONGTIMEOUT); /* I don't care */ + + p = (unsigned long *) myaddr; + for (i = 0; i < len; i += 4, p++) + { + extern int InspectIt; + + if (!InspectIt && ((i % BLOCKSIZE) == 0)) + fprintf(stderr, "+"); /* let 'em know that we are working */ + switch (getline(buf2, PBUFSIZ, LONGTIMEOUT)) + { + default: + case GL_PROMLINE: + case GL_READING: + case GL_OK: + case GL_OVERRUN: + case GL_TIMEOUT: + case GL_BLANKLINE: + /* resync and retry */ + max_number_of_blocks = max(1, i / BLOCKSIZE); + fprintf(stderr, "-"); /* let 'em know that we are working */ + + if (kiodebug & KD_BLOCKTRANSFER) + fprintf(stderr, "failed read_many %d %d/%d (%s)\n", + max_number_of_blocks, i, len, buf2); + sendbreak(); + return remote_read_many(memaddr, myaddr, len); + case GL_EXCEPTION: + return -i; + case GL_SUCCESS: + sscanf(buf2, "%x\n", p); + break; + } + } + if (kiodebug & KD_BLOCKTRANSFER) + fprintf(stderr, "success read_many %d %d/%d (%s)\n", max_number_of_blocks, + i, len, buf2); + return i; +} +/* + * allow the user to type directly to the prom ! + */ +prom_command() +{ + int readUser, readProm; + + user_terminal_raw(); + fprintf(stderr, "entering prom mode...\n"); + while (1) + { + doselect(&readUser, &readProm); + if (readUser) + if (shuffleFromUserToProm()) + { + fprintf(stderr, "exiting prom mode\n"); + user_terminal_restore(); + return; + } + if (readProm) + fprintf(stderr, "%c", readCharFromProm ()); + } +} +static char *boot_set_msg = "boot needs a string in quotes of the form \"boot vmunix\" "; +static char *baud_set_msg = "baud rate should be of the form \"set baud=9600\""; + +static void +set_boot (arg, from_tty) + char *arg; + int from_tty; +{ + int h, i; + + if (!arg) + { + print_boot_cmd(); + error_no_arg (boot_set_msg); + } + + arg = tilde_expand (arg); + make_cleanup (free, arg); + + i = strlen (arg) - 1; + + free (boot_cmd); + + h = 0; + while (*arg && h < i && (arg[h] == ' ' || arg[h] == '\t')) + { + h++; + arg++; + } + while (i > 0 && (arg[i] == ' ' || arg[i] == '\t')) + i--; + + if (h >= i || !*arg || arg[h] != '"' || arg[i] != '"') + error (boot_set_msg); + else + { + boot_cmd = savestring (++arg, i); + boot_cmd[i - 1] = '\0'; + } + if (from_tty) + print_boot_cmd(); +} + +static int bauds[] = { + 0, 50, 75, 110, 134, 150, 200, 300, 600, + 1200, 1800, 2400, 4800, 9600, 19200, 38400, -1 +}; + + +static int convert_to_baud_B(n) + int n; +{ + register int *p; + + for (p = bauds; *p != -1; p++) + if (*p != 0 && *p == n) + return (p - bauds); + return (NULL); +} + +static void print_acceptable_bauds() +{ + register int *p; + + for (p = bauds; *p != -1; p++) + if (*p != 0 ) + fprintf(stderr, "%d\n", *p); +} + +static void print_baud() +{ +fprintf(stderr, "the baud rate is now %d\n", bauds[baud_rate]); +} + +static void +set_baud (arg, from_tty) + char *arg; + int from_tty; +{ + int temp_baud_rate; + + if (!arg) + { + print_baud(); + print_acceptable_bauds(); + error_no_arg (baud_set_msg); + return; + } + + while (*arg && !isdigit(*arg)) + arg++; + + if (*arg && (temp_baud_rate = convert_to_baud_B(atoi(arg))) != NULL) + { + baud_rate = temp_baud_rate; + if (remote_debugging) + setup_remote(); + } + else + { + fprintf(stderr, "bad baud rate %s, acceptable values are\n", arg); + print_acceptable_bauds(); + } + + print_baud(); +} + + + + +void +_initialize_remote() +{ +/* Chain containing all defined set subcommands */ + +extern struct cmd_list_element *setlist; + + + add_com ("prom", class_obscure, prom_command, + "Conduct a dialogue directly with the prom. \ +only useful after an attach\n\ +Terminate by typing ~."); + + add_cmd ("boot_cmd", class_support, set_boot, boot_set_msg, &setlist); + + add_cmd ("baud", class_support, set_baud, baud_set_msg, &setlist); + + set_boot ("\"boot nucleus -d\"", 0); + } + + +/* Store the remote registers from the contents of the block REGS. */ + +void +remote_store_registers (registers) + char *registers; +{ + CORE_ADDR core; + struct regs inferior_registers; + + core = parse_and_eval_address("breakpoint_regs"); + + bcopy (®isters[REGISTER_BYTE (1)], + &inferior_registers.r_g1, 15 * 4); + + inferior_registers.r_ps = + *(int *)®isters[REGISTER_BYTE (PS_REGNUM)]; + inferior_registers.r_pc = + *(int *)®isters[REGISTER_BYTE (PC_REGNUM)]; + inferior_registers.r_npc = + *(int *)®isters[REGISTER_BYTE (NPC_REGNUM)]; + inferior_registers.r_y = + *(int *)®isters[REGISTER_BYTE (Y_REGNUM)]; + + remote_write_inferior_memory (*(int *)®isters[REGISTER_BYTE (SP_REGNUM)], + ®isters[REGISTER_BYTE (16)], + 16*4); + remote_write_inferior_memory (core, + &inferior_registers, + sizeof(inferior_registers)); +} + + + +/* we have stopped. do some cleanup */ +remote_cleanup_after_stop() +{ + if (remove_thisbp_next_pc) + { + remote_remove_breakpoint (remove_thisbp_next_pc); + remove_thisbp_next_pc = 0; + } + if (remove_thisbp_target) + { + remote_remove_breakpoint (remove_thisbp_target); + remove_thisbp_target = 0; + } + user_terminal_restore(); + + one_stepped = remote_set_one_stepped; +} |