static int computeSignal(int);
static void putpacket(unsigned char *);
-static void getpacket(unsigned char *);
+static unsigned char *getpacket(void);
static unsigned char *mem2hex(unsigned char *, unsigned char *, int, int);
static unsigned char *hex2mem(unsigned char *, unsigned char *, int, int);
static void restore_registers(void);
static int prepare_to_step(int);
static int finish_from_step(void);
+static unsigned long crc32 (unsigned char *, int, unsigned long);
static void gdb_error(char *, char *);
static int gdb_putchar(int), gdb_puts(char *), gdb_write(char *, int);
void
handle_exception(int exceptionVector)
{
- int sigval;
+ int sigval, stepping;
int addr, length, i;
unsigned char * ptr;
unsigned char buf[16];
putpacket(remcomOutBuffer);
+ stepping = 0;
+
while (1==1) {
remcomOutBuffer[0] = 0;
- getpacket(remcomInBuffer);
+ ptr = getpacket();
binary = 0;
- switch (remcomInBuffer[0]) {
+ switch (*ptr++) {
default: /* Unknown code. Return an empty reply message. */
break;
case 'R':
- ptr = &remcomInBuffer[1];
if (hexToInt (&ptr, &addr))
registers[PC] = addr;
strcpy(remcomOutBuffer, "OK");
case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
/* TRY TO READ '%x,%x:'. IF SUCCEED, SET PTR = 0 */
{
- ptr = &remcomInBuffer[1];
if (hexToInt(&ptr,&addr))
if (*(ptr++) == ',')
if (hexToInt(&ptr,&length))
if (ptr)
{
strcpy(remcomOutBuffer,"E02");
- gdb_error("malformed write memory command: %s",
- remcomInBuffer);
}
}
break;
case 'm': /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */
/* TRY TO READ %x,%x. IF SUCCEED, SET PTR = 0 */
- ptr = &remcomInBuffer[1];
if (hexToInt(&ptr,&addr))
if (*(ptr++) == ',')
if (hexToInt(&ptr,&length))
if (ptr)
{
strcpy(remcomOutBuffer,"E01");
- gdb_error("malformed read memory command: %s",
- remcomInBuffer);
}
break;
case '?':
{
int regno;
- ptr = &remcomInBuffer[1];
if (hexToInt (&ptr, ®no) && *ptr++ == '=')
if (regno >= 0 && regno < NUMREGS)
{
strcpy (remcomOutBuffer, "OK");
break;
}
- strcpy (remcomOutBuffer, "P01");
+ strcpy (remcomOutBuffer, "E01");
break;
}
case 'G': /* set the value of the CPU registers - return OK */
- hex2mem(&remcomInBuffer[1], (unsigned char*) registers, NUMREGBYTES, 0);
+ hex2mem(ptr, (unsigned char*) registers, NUMREGBYTES, 0);
strcpy(remcomOutBuffer,"OK");
break;
case 's': /* sAA..AA Step one instruction from AA..AA(optional) */
+ stepping = 1;
case 'c': /* cAA..AA Continue from address AA..AA(optional) */
/* try to read optional parameter, pc unchanged if no parm */
- ptr = &remcomInBuffer[1];
if (hexToInt(&ptr,&addr))
registers[ PC ] = addr;
- if (remcomInBuffer[0] == 's') /* single-stepping */
+ if (stepping) /* single-stepping */
{
if (!prepare_to_step(0)) /* set up for single-step */
{
if ((registers[PC] & 2) != 0)
prepare_to_step(1);
}
+
return;
case 'D': /* Detach */
+#if 0
/* I am interpreting this to mean, release the board from control
by the remote stub. To do this, I am restoring the original
(or at least previous) exception vectors.
exceptionHandler (i, save_vectors[i]);
putpacket ("OK");
return; /* continue the inferior */
+#else
+ strcpy(remcomOutBuffer,"OK");
+ break;
+#endif
+ case 'q':
+ if (*ptr++ == 'C' &&
+ *ptr++ == 'R' &&
+ *ptr++ == 'C' &&
+ *ptr++ == ':')
+ {
+ unsigned long start, len, our_crc;
+
+ if (hexToInt (&ptr, (int *) &start) &&
+ *ptr++ == ',' &&
+ hexToInt (&ptr, (int *) &len))
+ {
+ remcomOutBuffer[0] = 'C';
+ our_crc = crc32 ((unsigned char *) start, len, 0xffffffff);
+ mem2hex ((char *) &our_crc,
+ &remcomOutBuffer[1],
+ sizeof (long),
+ 0);
+ } /* else do nothing */
+ } /* else do nothing */
+ break;
case 'k': /* kill the program */
continue;
}
}
+/* qCRC support */
+
+/* Table used by the crc32 function to calcuate the checksum. */
+static unsigned long crc32_table[256] = {0, 0};
+
+static unsigned long
+crc32 (unsigned char *buf, int len, unsigned long crc)
+{
+ if (! crc32_table[1])
+ {
+ /* Initialize the CRC table and the decoding table. */
+ int i, j;
+ unsigned long c;
+
+ for (i = 0; i < 256; i++)
+ {
+ for (c = i << 24, j = 8; j > 0; --j)
+ c = c & 0x80000000 ? (c << 1) ^ 0x04c11db7 : (c << 1);
+ crc32_table[i] = c;
+ }
+ }
+
+ while (len--)
+ {
+ crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ *buf) & 255];
+ buf++;
+ }
+ return crc;
+}
+
static int
-hex(ch)
- unsigned char ch;
+hex (unsigned char ch)
{
if ((ch >= 'a') && (ch <= 'f')) return (ch-'a'+10);
if ((ch >= '0') && (ch <= '9')) return (ch-'0');
/* scan for the sequence $<data>#<checksum> */
-static void
-getpacket(buffer)
- unsigned char * buffer;
+unsigned char *
+getpacket (void)
{
+ unsigned char *buffer = &remcomInBuffer[0];
unsigned char checksum;
unsigned char xmitcsum;
- int i;
- int count;
- unsigned char ch;
+ int count;
+ char ch;
- do {
- /* wait around for the start character, ignore all other characters */
- while ((ch = getDebugChar()) != '$');
- checksum = 0;
- xmitcsum = -1;
+ while (1)
+ {
+ /* wait around for the start character, ignore all other characters */
+ while ((ch = getDebugChar ()) != '$')
+ ;
- count = 0;
+retry:
+ checksum = 0;
+ xmitcsum = -1;
+ count = 0;
- /* now, read until a # or end of buffer is found */
- while (count < BUFMAX) {
- ch = getDebugChar();
-
- if (ch == '#' && (count == 0 || buffer[count-1] != 0x7d))
- break;
+ /* now, read until a # or end of buffer is found */
+ while (count < BUFMAX)
+ {
+ ch = getDebugChar ();
+ if (ch == '$')
+ goto retry;
+ if (ch == '#')
+ break;
+ checksum = checksum + ch;
+ buffer[count] = ch;
+ count = count + 1;
+ }
+ buffer[count] = 0;
- checksum = checksum + ch;
- buffer[count] = ch;
- count = count + 1;
- }
- buffer[count] = 0;
-
- if (ch == '#') {
- xmitcsum = hex(getDebugChar()) << 4;
- xmitcsum += hex(getDebugChar());
- if (checksum != xmitcsum) {
- if (remote_debug) {
- unsigned char buf[16];
-
- mem2hex((unsigned char *) &checksum, buf, 4, 0);
- gdb_error("Bad checksum: my count = %s, ", buf);
- mem2hex((unsigned char *) &xmitcsum, buf, 4, 0);
- gdb_error("sent count = %s\n", buf);
- gdb_error(" -- Bad buffer: \"%s\"\n", buffer);
- }
+ if (ch == '#')
+ {
+ ch = getDebugChar ();
+ xmitcsum = hex (ch) << 4;
+ ch = getDebugChar ();
+ xmitcsum += hex (ch);
- putDebugChar('-'); /* failed checksum */
- } else {
- putDebugChar('+'); /* successful transfer */
- /* if a sequence char is present, reply the sequence ID */
- if (buffer[2] == ':') {
- putDebugChar( buffer[0] );
- putDebugChar( buffer[1] );
- /* remove sequence chars from buffer */
- count = strlen(buffer);
- for (i=3; i <= count; i++) buffer[i-3] = buffer[i];
+ if (checksum != xmitcsum)
+ {
+ if (remote_debug)
+ {
+ unsigned char buf[16];
+
+ mem2hex((unsigned char *) &checksum, buf, 4, 0);
+ gdb_error("Bad checksum: my count = %s, ", buf);
+ mem2hex((unsigned char *) &xmitcsum, buf, 4, 0);
+ gdb_error("sent count = %s\n", buf);
+ gdb_error(" -- Bad buffer: \"%s\"\n", buffer);
+ }
+ putDebugChar ('-'); /* failed checksum */
+ }
+ else
+ {
+ putDebugChar ('+'); /* successful transfer */
+
+ /* if a sequence char is present, reply the sequence ID */
+ if (buffer[2] == ':')
+ {
+ putDebugChar (buffer[0]);
+ putDebugChar (buffer[1]);
+
+ return &buffer[3];
+ }
+
+ return &buffer[0];
+ }
}
- }
}
- } while (checksum != xmitcsum);
}
/* send the packet in buffer. */
static void
-putpacket(buffer)
- unsigned char *buffer;
+putpacket (unsigned char *buffer)
{
unsigned char checksum;
int count;
static void (*volatile mem_fault_routine)() = 0;
static void
-set_mem_err ()
+set_mem_err (void)
{
mem_err = 1;
}
whether there's anything connected to the expansion bus. */
static int
-mem_safe (addr)
- unsigned char *addr;
+mem_safe (unsigned char *addr)
{
#define BAD_RANGE_ONE_START ((unsigned char *) 0x600000)
#define BAD_RANGE_ONE_END ((unsigned char *) 0xa00000)
to mem_fault, they won't get restored, so there better not be any
saved). */
static int
-get_char (addr)
- unsigned char *addr;
+get_char (unsigned char *addr)
{
#if 1
if (mem_fault_routine && !mem_safe(addr))
}
static void
-set_char (addr, val)
- unsigned char *addr;
- unsigned char val;
+set_char (unsigned char *addr, unsigned char val)
{
#if 1
if (mem_fault_routine && !mem_safe (addr))
a fault; if zero treat a fault like any other fault in the stub. */
static unsigned char *
-mem2hex(mem, buf, count, may_fault)
- unsigned char* mem;
- unsigned char* buf;
- int count;
- int may_fault;
+mem2hex (unsigned char *mem, unsigned char *buf, int count, int may_fault)
{
int i;
unsigned char ch;
Return a pointer to the character AFTER the last byte written. */
static unsigned char*
-hex2mem(buf, mem, count, may_fault)
- unsigned char* buf;
- unsigned char* mem;
- int count;
- int may_fault;
+hex2mem (unsigned char *buf, unsigned char *mem, int count, int may_fault)
{
int i;
unsigned char ch;
COUNT is the total number of bytes to write into
memory. */
static unsigned char *
-bin2mem (buf, mem, count, may_fault)
- unsigned char *buf;
- unsigned char *mem;
- int count;
- int may_fault;
+bin2mem (unsigned char *buf, unsigned char *mem, int count, int may_fault)
{
int i;
unsigned char ch;
case 0x4: /* $ */
case 0x5d: /* escape char */
buf++;
- *buf += 0x20;
+ *buf |= 0x20;
break;
default:
/* nothing */
translate this number into a unix compatible signal value */
static int
-computeSignal(exceptionVector)
- int exceptionVector;
+computeSignal (int exceptionVector)
{
int sigval;
switch (exceptionVector) {
/* RETURN NUMBER OF CHARS PROCESSED */
/**********************************************/
static int
-hexToInt(ptr, intValue)
- unsigned char **ptr;
- int *intValue;
+hexToInt (unsigned char **ptr, int *intValue)
{
int numChars = 0;
int hexValue;
*/
static int
-isShortBranch(instr)
- unsigned char *instr;
+isShortBranch (unsigned char *instr)
{
unsigned char instr0 = instr[0] & 0x7F; /* mask off high bit */
}
static int
-isLongBranch(instr)
- unsigned char *instr;
+isLongBranch (unsigned char *instr)
{
if (instr[0] == 0xFC || instr[0] == 0xFD || /* BRA, BNC, BL, BC */
instr[0] == 0xFE || instr[0] == 0xFF) /* 24 bit relative */
((((int) addr & 2) || (((unsigned char *) addr)[0] & 0x80) == 0) ? 2 : 4)
static int
-isBranch(instr)
- unsigned char *instr;
+isBranch (unsigned char *instr)
{
if (INSTRUCTION_SIZE(instr) == 2)
return isShortBranch(instr);
}
static int
-willBranch(instr, branchCode)
- unsigned char *instr;
+willBranch (unsigned char *instr, int branchCode)
{
switch (branchCode)
{
}
static int
-branchDestination(instr, branchCode)
- unsigned char *instr;
+branchDestination (unsigned char *instr, int branchCode)
{
switch (branchCode) {
default:
case 2: /* JL or JMP */
return registers[instr[1] & 0x0F] & ~3; /* jump thru a register */
case 3: /* BC, BNC, BL, BRA (short, 8-bit relative offset) */
- return (((int) instr) & ~3) + ((unsigned char) instr[1] << 2);
+ return (((int) instr) & ~3) + ((char) instr[1] << 2);
case 4: /* BC, BNC, BL, BRA (long, 24-bit relative offset) */
return ((int) instr +
- ((((unsigned char) instr[1] << 16) | (instr[2] << 8) | (instr[3])) << 2));
+ ((((char) instr[1] << 16) | (instr[2] << 8) | (instr[3])) << 2));
case 5: /* BNE, BEQ (16-bit relative offset) */
case 6: /* BNEZ, BLTZ, BLEZ, BGTZ, BGEZ ,BEQZ (ditto) */
- return ((int) instr + ((((unsigned char) instr[2] << 8) | (instr[3])) << 2));
+ return ((int) instr + ((((char) instr[2] << 8) | (instr[3])) << 2));
}
/* An explanatory note: in the last three return expressions, I have
}
static void
-branchSideEffects(instr, branchCode)
- unsigned char *instr;
- int branchCode;
+branchSideEffects (unsigned char *instr, int branchCode)
{
switch (branchCode)
{
just "continue continuing". */
static int
-finish_from_step()
+finish_from_step (void)
{
if (stepping.stepping) /* anything to do? */
{
but doing stash_registers in C isn't straightforward. */
static void
-cleanup_stash ()
+cleanup_stash (void)
{
psw = (struct PSWreg *) ®isters[PSW]; /* fields of PSW register */
psw->sm = psw->bsm; /* fix up pre-trap values of psw fields */
NUM is the trap/exception number. */
static void
-process_exception (num)
- int num;
+process_exception (int num)
{
cleanup_stash ();
asm volatile ("
/* this function is used to set up exception handlers for tracing and
breakpoints */
void
-set_debug_traps()
+set_debug_traps (void)
{
/* extern void remcomHandler(); */
int i;
exceptionHandler (16, _catchException16);
/* exceptionHandler (17, _catchException17); */
- /* In case GDB is started before us, ack any packets (presumably
- "$?#xx") sitting there. */
- putDebugChar ('+');
-
initialized = 1;
}
#define BREAKPOINT() asm volatile (" trap #2");
void
-breakpoint()
+breakpoint (void)
{
if (initialized)
BREAKPOINT();
Returns: the char */
static int
-gdb_putchar(ch)
- int ch;
+gdb_putchar (int ch)
{
char buf[4];
Returns: number of bytes written */
static int
-gdb_write(data, len)
- char *data;
- int len;
+gdb_write (char *data, int len)
{
char *buf, *cpy;
int i;
Returns: the length of the string */
static int
-gdb_puts(str)
- char *str;
+gdb_puts (char *str)
{
return gdb_write(str, strlen(str));
}
will cause the optional second string to be inserted. */
static void
-gdb_error(format, parm)
- char * format;
- char * parm;
+gdb_error (char *format, char *parm)
{
char buf[400], *cpy;
int len;