OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [newlib-1.17.0/] [libgloss/] [debug.c] - Diff between revs 158 and 816

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 158 Rev 816
/*
/*
 * Copyright (c) 1995, 1996 Cygnus Support
 * Copyright (c) 1995, 1996 Cygnus Support
 *
 *
 * The authors hereby grant permission to use, copy, modify, distribute,
 * The authors hereby grant permission to use, copy, modify, distribute,
 * and license this software and its documentation for any purpose, provided
 * and license this software and its documentation for any purpose, provided
 * that existing copyright notices are retained in all copies and that this
 * that existing copyright notices are retained in all copies and that this
 * notice is included verbatim in any distributions. No written agreement,
 * notice is included verbatim in any distributions. No written agreement,
 * license, or royalty fee is required for any of the authorized uses.
 * license, or royalty fee is required for any of the authorized uses.
 * Modifications to this software may be copyrighted by their authors
 * Modifications to this software may be copyrighted by their authors
 * and need not follow the licensing terms described here, provided that
 * and need not follow the licensing terms described here, provided that
 * the new terms are clearly indicated on the first page of each file where
 * the new terms are clearly indicated on the first page of each file where
 * they apply.
 * they apply.
 */
 */
 
 
/*
/*
 *   A debug packet whose contents are <data> looks like:
 *   A debug packet whose contents are <data> looks like:
 *
 *
 *        $ <data> # CSUM1 CSUM2
 *        $ <data> # CSUM1 CSUM2
 *
 *
 *        <data> must be ASCII alphanumeric and cannot include characters
 *        <data> must be ASCII alphanumeric and cannot include characters
 *        '$' or '#'.  If <data> starts with two characters followed by
 *        '$' or '#'.  If <data> starts with two characters followed by
 *        ':', then the existing stubs interpret this as a sequence number.
 *        ':', then the existing stubs interpret this as a sequence number.
 *
 *
 *       CSUM1 and CSUM2 are ascii hex representation of an 8-bit
 *       CSUM1 and CSUM2 are ascii hex representation of an 8-bit
 *        checksum of <data>, the most significant nibble is sent first.
 *        checksum of <data>, the most significant nibble is sent first.
 *        the hex digits 0-9,a-f are used.
 *        the hex digits 0-9,a-f are used.
 *
 *
 *   We respond with:
 *   We respond with:
 *
 *
 *        +       - if CSUM is correct and ready for next packet
 *        +       - if CSUM is correct and ready for next packet
 *        -       - if CSUM is incorrect
 *        -       - if CSUM is incorrect
 *
 *
 *   <data> is as follows:
 *   <data> is as follows:
 *   Most values are encoded in ascii hex digits.
 *   Most values are encoded in ascii hex digits.
 */
 */
 
 
#include "debug.h"
#include "debug.h"
#include <signal.h>
#include <signal.h>
 
 
/*
/*
 * buffers that hold the packets while they're being constructed.
 * buffers that hold the packets while they're being constructed.
 */
 */
char packet_in_buf[BUFMAX];
char packet_in_buf[BUFMAX];
char packet_out_buf[BUFMAX];
char packet_out_buf[BUFMAX];
int packet_index;
int packet_index;
 
 
/*
/*
 * indicate to caller of mem2hex or hex2mem that there has been an error.
 * indicate to caller of mem2hex or hex2mem that there has been an error.
 * 0 means ok, 1 means error
 * 0 means ok, 1 means error
 */
 */
volatile int mem_err = 0;
volatile int mem_err = 0;
 
 
/*
/*
 * 1 means print debugging messages from the target, 0 means be quiet. This is
 * 1 means print debugging messages from the target, 0 means be quiet. This is
 * changed by gdb_debug().
 * changed by gdb_debug().
 */
 */
int remote_debug = 0;
int remote_debug = 0;
 
 
/*
/*
 * indicate whether the debug vectors ahave been initialized
 * indicate whether the debug vectors ahave been initialized
 * 0 means not yet, 1 means yep, it's ready.
 * 0 means not yet, 1 means yep, it's ready.
 */
 */
int initialized = 0;
int initialized = 0;
 
 
/*
/*
 * These variables are instantialted in the GDB stub code.
 * These variables are instantialted in the GDB stub code.
 */
 */
 
 
/* this is a list of signal to exception mappings. */
/* this is a list of signal to exception mappings. */
extern struct trap_info hard_trap_info[];
extern struct trap_info hard_trap_info[];
 
 
/* this is a memory fault exception handler, used by mem2hex & hex2mem */
/* this is a memory fault exception handler, used by mem2hex & hex2mem */
extern void set_mem_fault_trap();
extern void set_mem_fault_trap();
 
 
/*
/*
 * print debugging messages. This uses print, rather than one of the
 * print debugging messages. This uses print, rather than one of the
 * stdio routines, cause if there are stack or memory problems, the
 * stdio routines, cause if there are stack or memory problems, the
 * stdio routines don't work.
 * stdio routines don't work.
 *      params are the debug level, and the string to print
 *      params are the debug level, and the string to print
 *      it doesn't return anything.
 *      it doesn't return anything.
 */
 */
void
void
debuglog(int level, char *msg)
debuglog(int level, char *msg)
{
{
  char *p;
  char *p;
  unsigned char buf[BUFMAX];
  unsigned char buf[BUFMAX];
  char newmsg[BUFMAX];
  char newmsg[BUFMAX];
  int i;
  int i;
 
 
  if (level > remote_debug)
  if (level > remote_debug)
    return;
    return;
 
 
  if ((level <0) || (level > 100)) {
  if ((level <0) || (level > 100)) {
    print ("ERROR: debug print level out of range");
    print ("ERROR: debug print level out of range");
    return;
    return;
  }
  }
 
 
  /* convert some characters so it'll look right in the log */
  /* convert some characters so it'll look right in the log */
  p = newmsg;
  p = newmsg;
  for (i = 0 ; msg[i] != '\0'; i++) {
  for (i = 0 ; msg[i] != '\0'; i++) {
    if (i > BUFMAX)
    if (i > BUFMAX)
      print ("\r\nERROR: Debug message too long\r\n");
      print ("\r\nERROR: Debug message too long\r\n");
    switch (msg[i]) {
    switch (msg[i]) {
    case '\n':                                  /* newlines */
    case '\n':                                  /* newlines */
      *p++ = '\\';
      *p++ = '\\';
      *p++ = 'n';
      *p++ = 'n';
      continue;
      continue;
    case '\r':                                  /* carriage returns */
    case '\r':                                  /* carriage returns */
      *p++ = '\\';
      *p++ = '\\';
      *p++ = 'r';
      *p++ = 'r';
      continue;
      continue;
    case '\033':                                /* escape */
    case '\033':                                /* escape */
      *p++ = '\\';
      *p++ = '\\';
      *p++ = 'e';
      *p++ = 'e';
      continue;
      continue;
    case '\t':                                  /* tab */
    case '\t':                                  /* tab */
      *p++ = '\\';
      *p++ = '\\';
      *p++ = 't';
      *p++ = 't';
      continue;
      continue;
    case '\b':                                  /* backspace */
    case '\b':                                  /* backspace */
      *p++ = '\\';
      *p++ = '\\';
      *p++ = 'b';
      *p++ = 'b';
      continue;
      continue;
    default:                                    /* no change */
    default:                                    /* no change */
      *p++ = msg[i];
      *p++ = msg[i];
    }
    }
 
 
    if (msg[i] < 26) {                          /* modify control characters */
    if (msg[i] < 26) {                          /* modify control characters */
      *p++ = '^';
      *p++ = '^';
      *p++ = msg[i] + 'A';
      *p++ = msg[i] + 'A';
      continue;
      continue;
    }
    }
    if (msg[i] >= 127) {                        /* modify control characters */
    if (msg[i] >= 127) {                        /* modify control characters */
      *p++ = '!';
      *p++ = '!';
      *p++ = msg[i] + 'A';
      *p++ = msg[i] + 'A';
      continue;
      continue;
    }
    }
  }
  }
  *p = '\0';                                    /* terminate the string */
  *p = '\0';                                    /* terminate the string */
  print (newmsg);
  print (newmsg);
  print ("\r\n");
  print ("\r\n");
}
}
 
 
/*
/*
 * convert an ascii hex digit to a number.
 * convert an ascii hex digit to a number.
 *      param is hex digit.
 *      param is hex digit.
 *      returns a decimal digit.
 *      returns a decimal digit.
 */
 */
int
int
hex2digit (int digit)
hex2digit (int digit)
{
{
  if (digit == 0)
  if (digit == 0)
    return 0;
    return 0;
 
 
  if (digit >= '0' && digit <= '9')
  if (digit >= '0' && digit <= '9')
    return digit - '0';
    return digit - '0';
  if (digit >= 'a' && digit <= 'f')
  if (digit >= 'a' && digit <= 'f')
    return digit - 'a' + 10;
    return digit - 'a' + 10;
  if (digit >= 'A' && digit <= 'F')
  if (digit >= 'A' && digit <= 'F')
    return digit - 'A' + 10;
    return digit - 'A' + 10;
 
 
  /* shouldn't ever get this far */
  /* shouldn't ever get this far */
  return ERROR;
  return ERROR;
}
}
 
 
/*
/*
 * convert number NIB to a hex digit.
 * convert number NIB to a hex digit.
 *      param is a decimal digit.
 *      param is a decimal digit.
 *      returns a hex digit.
 *      returns a hex digit.
 */
 */
char
char
digit2hex(int digit)
digit2hex(int digit)
{
{
  if (digit < 10)
  if (digit < 10)
    return '0' + digit;
    return '0' + digit;
  else
  else
    return 'a' + digit - 10;
    return 'a' + digit - 10;
}
}
 
 
/*
/*
 * Convert the memory pointed to by mem into hex, placing result in buf.
 * Convert the memory pointed to by mem into hex, placing result in buf.
 * Return a pointer to the last char put in buf (null), in case of mem fault,
 * Return a pointer to the last char put in buf (null), in case of mem fault,
 * return 0.
 * return 0.
 * If MAY_FAULT is non-zero, then we will handle memory faults by returning
 * If MAY_FAULT is non-zero, then we will handle memory faults by returning
 * a 0, else treat a fault like any other fault in the stub.
 * a 0, else treat a fault like any other fault in the stub.
 */
 */
unsigned char *
unsigned char *
mem2hex(unsigned char *mem, unsigned char *buf, int count, int may_fault)
mem2hex(unsigned char *mem, unsigned char *buf, int count, int may_fault)
{
{
  unsigned char ch;
  unsigned char ch;
 
 
  DEBUG (1, "In mem2hex");
  DEBUG (1, "In mem2hex");
 
 
  set_mem_fault_trap(MAY_FAULT);
  set_mem_fault_trap(MAY_FAULT);
 
 
  while (count-- > 0) {
  while (count-- > 0) {
    ch = *mem++;
    ch = *mem++;
    if (mem_err) {
    if (mem_err) {
      DEBUG (1, "memory fault in mem2hex");
      DEBUG (1, "memory fault in mem2hex");
      return 0;
      return 0;
    }
    }
    *buf++ = digit2hex(ch >> 4);
    *buf++ = digit2hex(ch >> 4);
    *buf++ = digit2hex(ch & 0xf);
    *buf++ = digit2hex(ch & 0xf);
  }
  }
 
 
  *buf = 0;
  *buf = 0;
 
 
  set_mem_fault_trap(OK);
  set_mem_fault_trap(OK);
 
 
  return buf;
  return buf;
}
}
 
 
/*
/*
 * Convert the hex array pointed to by buf into binary to be placed in mem
 * Convert the hex array pointed to by buf into binary to be placed in mem
 * return a pointer to the character AFTER the last byte written
 * return a pointer to the character AFTER the last byte written
 */
 */
unsigned char *
unsigned char *
hex2mem(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;
  int i;
  unsigned char ch;
  unsigned char ch;
 
 
  DEBUG (1, "In hex2mem");
  DEBUG (1, "In hex2mem");
 
 
  set_mem_fault_trap(may_fault);
  set_mem_fault_trap(may_fault);
 
 
  for (i=0; i<count; i++) {
  for (i=0; i<count; i++) {
    ch = hex2digit(*buf++) << 4;
    ch = hex2digit(*buf++) << 4;
    ch |= hex2digit(*buf++);
    ch |= hex2digit(*buf++);
    *mem++ = ch;
    *mem++ = ch;
    if (mem_err)
    if (mem_err)
      return 0;
      return 0;
  }
  }
 
 
  set_mem_fault_trap(0);
  set_mem_fault_trap(0);
 
 
  return mem;
  return mem;
}
}
 
 
/*
/*
 * while we find nice hex chars, build an int.
 * while we find nice hex chars, build an int.
 *      param is a pointer to the string.
 *      param is a pointer to the string.
 *      returns the int in the param field, and the number of chars processed.
 *      returns the int in the param field, and the number of chars processed.
 */
 */
int
int
hex2int (char **ptr, int *intValue)
hex2int (char **ptr, int *intValue)
{
{
  int numChars = 0;
  int numChars = 0;
  int hexValue;
  int hexValue;
 
 
  *intValue = 0;
  *intValue = 0;
 
 
  while (**ptr)
  while (**ptr)
    {
    {
      hexValue = hex2digit(**ptr);
      hexValue = hex2digit(**ptr);
      if (hexValue < 0)
      if (hexValue < 0)
        break;
        break;
 
 
      *intValue = (*intValue << 4) | hexValue;
      *intValue = (*intValue << 4) | hexValue;
      numChars ++;
      numChars ++;
      (*ptr)++;
      (*ptr)++;
    }
    }
  return (numChars);
  return (numChars);
}
}
 
 
/*
/*
 * Scan for the sequence $<data>#<checksum>
 * Scan for the sequence $<data>#<checksum>
 */
 */
void
void
getpacket(unsigned char *buffer)
getpacket(unsigned char *buffer)
{
{
  unsigned char checksum;
  unsigned char checksum;
  unsigned char xmitcsum;
  unsigned char xmitcsum;
  int i;
  int i;
  int count;
  int count;
  unsigned char ch;
  unsigned char ch;
 
 
  do {
  do {
    /* wait around for the start character, ignore all other characters */
    /* wait around for the start character, ignore all other characters */
    while ((ch = (inbyte() & 0x7f)) != '$') ;
    while ((ch = (inbyte() & 0x7f)) != '$') ;
 
 
    checksum = 0;
    checksum = 0;
    xmitcsum = -1;
    xmitcsum = -1;
 
 
    count = 0;
    count = 0;
 
 
    /* now, read until a # or end of buffer is found */
    /* now, read until a # or end of buffer is found */
    while (count < BUFMAX) {
    while (count < BUFMAX) {
      ch = inbyte() & 0x7f;
      ch = inbyte() & 0x7f;
      if (ch == '#')
      if (ch == '#')
        break;
        break;
      checksum = checksum + ch;
      checksum = checksum + ch;
      buffer[count] = ch;
      buffer[count] = ch;
      count = count + 1;
      count = count + 1;
    }
    }
 
 
    if (count >= BUFMAX)
    if (count >= BUFMAX)
      continue;
      continue;
 
 
    buffer[count] = 0;
    buffer[count] = 0;
 
 
    if (ch == '#') {
    if (ch == '#') {
      xmitcsum = hex2digit(inbyte() & 0x7f) << 4;
      xmitcsum = hex2digit(inbyte() & 0x7f) << 4;
      xmitcsum |= hex2digit(inbyte() & 0x7f);
      xmitcsum |= hex2digit(inbyte() & 0x7f);
#if 1
#if 1
      /* Humans shouldn't have to figure out checksums to type to it. */
      /* Humans shouldn't have to figure out checksums to type to it. */
      outbyte ('+');
      outbyte ('+');
      return;
      return;
#endif
#endif
      if (checksum != xmitcsum)
      if (checksum != xmitcsum)
        outbyte('-');   /* failed checksum */
        outbyte('-');   /* failed checksum */
      else {
      else {
        outbyte('+'); /* successful transfer */
        outbyte('+'); /* successful transfer */
        /* if a sequence char is present, reply the sequence ID */
        /* if a sequence char is present, reply the sequence ID */
        if (buffer[2] == ':') {
        if (buffer[2] == ':') {
          outbyte(buffer[0]);
          outbyte(buffer[0]);
          outbyte(buffer[1]);
          outbyte(buffer[1]);
          /* remove sequence chars from buffer */
          /* remove sequence chars from buffer */
          count = strlen(buffer);
          count = strlen(buffer);
          for (i=3; i <= count; i++)
          for (i=3; i <= count; i++)
            buffer[i-3] = buffer[i];
            buffer[i-3] = buffer[i];
        }
        }
      }
      }
    }
    }
  }
  }
  while (checksum != xmitcsum);
  while (checksum != xmitcsum);
}
}
 
 
/*
/*
 * Send the packet in buffer.
 * Send the packet in buffer.
 */
 */
void
void
putpacket(unsigned char *buffer)
putpacket(unsigned char *buffer)
{
{
  unsigned char checksum;
  unsigned char checksum;
  int count;
  int count;
  unsigned char ch;
  unsigned char ch;
 
 
  /*  $<packet info>#<checksum>. */
  /*  $<packet info>#<checksum>. */
  do {
  do {
    outbyte('$');
    outbyte('$');
    checksum = 0;
    checksum = 0;
    count = 0;
    count = 0;
 
 
    while (ch = buffer[count]) {
    while (ch = buffer[count]) {
      if (! outbyte(ch))
      if (! outbyte(ch))
        return;
        return;
      checksum += ch;
      checksum += ch;
      count += 1;
      count += 1;
    }
    }
 
 
    outbyte('#');
    outbyte('#');
    outbyte(digit2hex(checksum >> 4));
    outbyte(digit2hex(checksum >> 4));
    outbyte(digit2hex(checksum & 0xf));
    outbyte(digit2hex(checksum & 0xf));
 
 
  }
  }
  while ((inbyte() & 0x7f) != '+');
  while ((inbyte() & 0x7f) != '+');
}
}
 
 
/*
/*
 *
 *
 */
 */
void
void
gdb_event_loop(int sigval, unsigned long *registers)
gdb_event_loop(int sigval, unsigned long *registers)
{
{
  int addr;
  int addr;
  int length;
  int length;
  unsigned char *ptr;
  unsigned char *ptr;
  ptr = packet_out_buf;
  ptr = packet_out_buf;
 
 
  DEBUG (1, "In gdb_event_loop");
  DEBUG (1, "In gdb_event_loop");
 
 
  while (1) {
  while (1) {
    packet_out_buf[0] = 0;
    packet_out_buf[0] = 0;
 
 
    getpacket(packet_in_buf);
    getpacket(packet_in_buf);
    ptr = &packet_in_buf[1];
    ptr = &packet_in_buf[1];
 
 
    switch (packet_in_buf[0]) {
    switch (packet_in_buf[0]) {
    case '?':           /* get the last known signal */
    case '?':           /* get the last known signal */
      gdb_last_signal(sigval);
      gdb_last_signal(sigval);
      break;
      break;
 
 
    case 'd':           /* toggle debug messages from the stub */
    case 'd':           /* toggle debug messages from the stub */
      gdb_toggle();
      gdb_toggle();
      break;
      break;
 
 
    case 'g':           /* return the value of the CPU registers */
    case 'g':           /* return the value of the CPU registers */
      target_read_registers(registers);
      target_read_registers(registers);
      break;
      break;
 
 
    case 'G':      /* set the value of the CPU registers - return OK */
    case 'G':      /* set the value of the CPU registers - return OK */
      target_write_registers(registers);
      target_write_registers(registers);
      break;
      break;
 
 
    case 'm':     /* mAA..AA,LLLL  Read LLLL bytes at address AA..AA */
    case 'm':     /* mAA..AA,LLLL  Read LLLL bytes at address AA..AA */
      /* Try to read %x,%x.  */
      /* Try to read %x,%x.  */
      if (hex2int((char **)&ptr, &addr)
      if (hex2int((char **)&ptr, &addr)
          && *ptr++ == ','
          && *ptr++ == ','
          && hex2int((char **)&ptr, &length)) {
          && hex2int((char **)&ptr, &length)) {
        gdb_read_memory(addr, length);
        gdb_read_memory(addr, length);
      } else {
      } else {
        make_return_packet(1);
        make_return_packet(1);
      }
      }
      break;
      break;
 
 
    case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
    case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
      /* Try to read '%x,%x:'.  */
      /* Try to read '%x,%x:'.  */
      if (hex2int((char **)&ptr, &addr)
      if (hex2int((char **)&ptr, &addr)
          && *ptr++ == ','
          && *ptr++ == ','
          && hex2int((char **)&ptr, &length)
          && hex2int((char **)&ptr, &length)
          && *ptr++ == ':') {
          && *ptr++ == ':') {
        gdb_write_memory (addr, length, ptr);
        gdb_write_memory (addr, length, ptr);
      } else {
      } else {
        make_return_packet(2);
        make_return_packet(2);
      }
      }
      break;
      break;
 
 
    case 'c':    /* cAA..AA    Continue at address AA..AA(optional) */
    case 'c':    /* cAA..AA    Continue at address AA..AA(optional) */
      /* try to read optional parameter, pc unchanged if no parm */
      /* try to read optional parameter, pc unchanged if no parm */
      if (hex2int((char **)&ptr, &addr)) {
      if (hex2int((char **)&ptr, &addr)) {
        write_pc(registers, addr);
        write_pc(registers, addr);
      }
      }
 
 
      /*
      /*
       * we need to flush the instruction cache here, as we may have
       * we need to flush the instruction cache here, as we may have
       * deposited a breakpoint, and the icache probably has no way of
       * deposited a breakpoint, and the icache probably has no way of
       * knowing that a data ref to some location may have changed
       * knowing that a data ref to some location may have changed
       * something that is in the instruction cache.
       * something that is in the instruction cache.
       */
       */
 
 
      flush_i_cache();
      flush_i_cache();
      /* by returning, we pick up execution where we left off */
      /* by returning, we pick up execution where we left off */
      return;
      return;
 
 
      /* kill the program */
      /* kill the program */
    case 'k' :
    case 'k' :
      gdb_kill();
      gdb_kill();
      break;
      break;
    case 'r':           /* Reset */
    case 'r':           /* Reset */
      target_reset();
      target_reset();
      break;
      break;
    }                   /* switch */
    }                   /* switch */
 
 
    /* reply to the request */
    /* reply to the request */
    putpacket(packet_out_buf);
    putpacket(packet_out_buf);
  }
  }
  DEBUG (1, "Leaving handle_exception()");
  DEBUG (1, "Leaving handle_exception()");
}
}
 
 
/* Convert the hardware trap type code to a unix signal number. */
/* Convert the hardware trap type code to a unix signal number. */
 
 
int
int
computeSignal(int tt)
computeSignal(int tt)
{
{
  struct trap_info *ht;
  struct trap_info *ht;
 
 
  for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
  for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
    if (ht->tt == tt)
    if (ht->tt == tt)
      return ht->signo;
      return ht->signo;
 
 
  return SIGHUP;                /* default for things we don't know about */
  return SIGHUP;                /* default for things we don't know about */
}
}
 
 
/*
/*
 * Set up exception handlers for tracing and breakpoints
 * Set up exception handlers for tracing and breakpoints
 */
 */
void
void
set_debug_traps()
set_debug_traps()
{
{
  struct trap_info *ht;
  struct trap_info *ht;
 
 
  DEBUG (1, "Entering set_debug_traps()");
  DEBUG (1, "Entering set_debug_traps()");
 
 
  if (hard_trap_info->tt == 0) {
  if (hard_trap_info->tt == 0) {
    print ("ERROR: ARG#$@%^&*!! no hard trap info!!\r\n");
    print ("ERROR: ARG#$@%^&*!! no hard trap info!!\r\n");
  }
  }
 
 
  for (ht = hard_trap_info; ht->tt && ht->signo; ht++) {
  for (ht = hard_trap_info; ht->tt && ht->signo; ht++) {
    exception_handler(ht->tt, (unsigned long)default_trap_hook);
    exception_handler(ht->tt, (unsigned long)default_trap_hook);
  }
  }
 
 
  /* In case GDB is started before us, ack any packets (presumably
  /* In case GDB is started before us, ack any packets (presumably
     "$?#xx") sitting there.  */
     "$?#xx") sitting there.  */
 
 
  outbyte ('+');
  outbyte ('+');
  initialized = 1;
  initialized = 1;
 
 
  DEBUG (1, "Leaving set_debug_traps()");
  DEBUG (1, "Leaving set_debug_traps()");
}
}
 
 
/*
/*
 * make a return packet.
 * make a return packet.
 *      param is the value to return.
 *      param is the value to return.
 *              0 = OK, any other value is converted to a two digit hex number.
 *              0 = OK, any other value is converted to a two digit hex number.
 *      returns a string or "OK" or "ENN", where NN is the error number. Each N
 *      returns a string or "OK" or "ENN", where NN is the error number. Each N
 *              is an ASCII encoded hex digit.
 *              is an ASCII encoded hex digit.
 */
 */
char *
char *
make_return_packet(int val)
make_return_packet(int val)
{
{
  if (val == 0) {
  if (val == 0) {
     packet_out_buf[0] = 'O';
     packet_out_buf[0] = 'O';
     packet_out_buf[1] = 'K';
     packet_out_buf[1] = 'K';
     packet_out_buf[2] = 0;
     packet_out_buf[2] = 0;
  } else {
  } else {
    packet_out_buf[0] = 'E';
    packet_out_buf[0] = 'E';
    packet_out_buf[1] = digit2hex((val >> 4) & 0xf);
    packet_out_buf[1] = digit2hex((val >> 4) & 0xf);
    packet_out_buf[2] = digit2hex(val & 0xf);
    packet_out_buf[2] = digit2hex(val & 0xf);
    packet_out_buf[3] = 0;
    packet_out_buf[3] = 0;
  }
  }
  return(packet_out_buf);
  return(packet_out_buf);
}
}
 
 
/*
/*
 * g - read registers.
 * g - read registers.
 *      no params.
 *      no params.
 *      returns a vector of words, size is NUM_REGS.
 *      returns a vector of words, size is NUM_REGS.
 */
 */
char *
char *
gdb_read_registers()
gdb_read_registers()
{
{
}
}
 
 
/*
/*
 * G - write registers.
 * G - write registers.
 *      param is a vector of words, size is NUM_REGS.
 *      param is a vector of words, size is NUM_REGS.
 *      returns an OK or an error number.
 *      returns an OK or an error number.
 */
 */
char *
char *
gdb_write_registers(char *regs)
gdb_write_registers(char *regs)
{
{
}
}
 
 
/*
/*
 * m - read memory.
 * m - read memory.
 *      params are the address to start the read at and the number of
 *      params are the address to start the read at and the number of
 *              bytes to read.
 *              bytes to read.
 *      returns a vector of nbytes or an error number.
 *      returns a vector of nbytes or an error number.
 *      Can be fewer bytes than requested if able to read only part of the
 *      Can be fewer bytes than requested if able to read only part of the
 *      data.
 *      data.
 */
 */
char *
char *
gdb_read_memory(long addr, int nbytes)
gdb_read_memory(long addr, int nbytes)
{
{
  if (mem2hex((char *)addr, packet_out_buf, nbytes, MAY_FAULT))
  if (mem2hex((char *)addr, packet_out_buf, nbytes, MAY_FAULT))
    return(packet_out_buf);
    return(packet_out_buf);
  else {
  else {
    return(make_return_packet(3));
    return(make_return_packet(3));
  }
  }
}
}
 
 
/*
/*
 * M write memory
 * M write memory
 *      params are the address to start writing to, the number of
 *      params are the address to start writing to, the number of
 *              bytes to write, and the new values of the bytes.
 *              bytes to write, and the new values of the bytes.
 *      returns an OK or an error number.
 *      returns an OK or an error number.
 */
 */
char *
char *
gdb_write_memory(long addr, int nbytes, char *mem)
gdb_write_memory(long addr, int nbytes, char *mem)
{
{
 if (hex2mem(mem, (char *)addr, nbytes, MAY_FAULT))
 if (hex2mem(mem, (char *)addr, nbytes, MAY_FAULT))
    return(make_return_packet(OK));
    return(make_return_packet(OK));
  else {
  else {
    return(make_return_packet(3));
    return(make_return_packet(3));
  }
  }
}
}
 
 
/*
/*
 * c - continue at address.
 * c - continue at address.
 *      param is the address to start at, and an optional signal. If
 *      param is the address to start at, and an optional signal. If
 *              sig is zero, then ignore it.
 *              sig is zero, then ignore it.
 *      returns an OK or an error number.
 *      returns an OK or an error number.
 */
 */
char *
char *
gdb_continue(int sig, long addr)
gdb_continue(int sig, long addr)
{
{
}
}
 
 
/*
/*
 * s - step instruction(s)
 * s - step instruction(s)
 *      param is the address to start at, and an optional signal. If
 *      param is the address to start at, and an optional signal. If
 *              sig is zero, then ignore it.
 *              sig is zero, then ignore it.
 *      returns an OK or an error number.
 *      returns an OK or an error number.
 */
 */
char *
char *
gdb_step(int sig, long addr)
gdb_step(int sig, long addr)
{
{
}
}
 
 
/*
/*
 * k - kill program.
 * k - kill program.
 *      no params.
 *      no params.
 *      returns an OK or an error number.
 *      returns an OK or an error number.
 */
 */
char *
char *
gdb_kill()
gdb_kill()
{
{
  /* generically, we can't do anything for this command */
  /* generically, we can't do anything for this command */
  return(make_return_packet(OK));
  return(make_return_packet(OK));
}
}
 
 
/*
/*
 * ? - last signal.
 * ? - last signal.
 *      no params.
 *      no params.
 *      returns the last signal number.
 *      returns the last signal number.
 */
 */
char *
char *
gdb_last_signal(int val)
gdb_last_signal(int val)
{
{
  DEBUG (1, "Entering gdb_last_signal()");
  DEBUG (1, "Entering gdb_last_signal()");
 
 
  packet_out_buf[0] = 'S';
  packet_out_buf[0] = 'S';
  packet_out_buf[1] = digit2hex(val >> 4);
  packet_out_buf[1] = digit2hex(val >> 4);
  packet_out_buf[2] = digit2hex(val & 0xf);
  packet_out_buf[2] = digit2hex(val & 0xf);
  packet_out_buf[3] = 0;
  packet_out_buf[3] = 0;
 
 
  DEBUG (1, "Leaving gdb_last_signal()");
  DEBUG (1, "Leaving gdb_last_signal()");
  return (packet_out_buf);
  return (packet_out_buf);
}
}
 
 
/*
/*
 * b - change baud rate.
 * b - change baud rate.
 *      param is the new baudrate
 *      param is the new baudrate
 *      returns the baud rate.
 *      returns the baud rate.
 */
 */
char *
char *
gdb_baudrate(int baud)
gdb_baudrate(int baud)
{
{
  /* generically, we can't do anything for this command */
  /* generically, we can't do anything for this command */
  return(make_return_packet(OK));
  return(make_return_packet(OK));
}
}
 
 
/*
/*
 * T - dump state.
 * T - dump state.
 *      no params.
 *      no params.
 *      returns the signal number, the registers, the thread ID, and
 *      returns the signal number, the registers, the thread ID, and
 *              possible extensions in a vector that looks like:
 *              possible extensions in a vector that looks like:
 *                      TAAn...:r...;n...:r...;n...:r...; where:
 *                      TAAn...:r...;n...:r...;n...:r...; where:
 *                       AA = signal number
 *                       AA = signal number
 *                       n... = register number (hex)
 *                       n... = register number (hex)
 *                       r... = register contents
 *                       r... = register contents
 *                       n... = `thread'
 *                       n... = `thread'
 *                       r... = thread process ID.  This is a hex integer.
 *                       r... = thread process ID.  This is a hex integer.
 *                       n... = other string not starting with valid hex digit.
 *                       n... = other string not starting with valid hex digit.
 *                              gdb should ignore this n,r pair and go on to
 *                              gdb should ignore this n,r pair and go on to
 *                              the next. This way we can extend the protocol.
 *                              the next. This way we can extend the protocol.
 */
 */
char *
char *
gdb_dump_state()
gdb_dump_state()
{
{
}
}
 
 
/*
/*
 * D - host requests a detach
 * D - host requests a detach
 *      no params.
 *      no params.
 *      returns either a S, T, W, or X command.
 *      returns either a S, T, W, or X command.
 *      returns an OK or an error number.
 *      returns an OK or an error number.
 */
 */
char *
char *
gdb_detach()
gdb_detach()
{
{
}
}
 
 
/*
/*
 * H - set thread.
 * H - set thread.
 *      params are the command to execute and the thread ID.
 *      params are the command to execute and the thread ID.
 *              cmd = 'c' for thread used in step and continue;
 *              cmd = 'c' for thread used in step and continue;
 *              cmd = 'g' for thread used in other operations.
 *              cmd = 'g' for thread used in other operations.
 *              tid = -1 for all threads.
 *              tid = -1 for all threads.
 *              tid = zero, pick a thread,any thread.
 *              tid = zero, pick a thread,any thread.
 *      returns an OK or an error number.
 *      returns an OK or an error number.
 */
 */
char *
char *
gdb_set_thread(int cmd, int tid)
gdb_set_thread(int cmd, int tid)
{
{
  /* generically, we can't do anything for this command */
  /* generically, we can't do anything for this command */
  return(make_return_packet(OK));
  return(make_return_packet(OK));
}
}
 
 
/*
/*
 * p - read one register.
 * p - read one register.
 *      param is the register number.
 *      param is the register number.
 *      returns the register value or ENN.
 *      returns the register value or ENN.
 */
 */
char *
char *
gdb_read_reg(int reg)
gdb_read_reg(int reg)
{
{
  /* generically, we can't do anything for this command */
  /* generically, we can't do anything for this command */
  return(make_return_packet(OK));
  return(make_return_packet(OK));
}
}
 
 
/*
/*
 * P - write one register.
 * P - write one register.
 *      params are the register number, and it's new value.
 *      params are the register number, and it's new value.
 *      returns the register value or ENN.
 *      returns the register value or ENN.
 */
 */
char *
char *
gdb_write_reg(int reg, long val)
gdb_write_reg(int reg, long val)
{
{
  /* generically, we can't do anything for this command */
  /* generically, we can't do anything for this command */
 
 
  return(make_return_packet(OK));
  return(make_return_packet(OK));
}
}
 
 
/*
/*
 * W - process exited.
 * W - process exited.
 *      no params.
 *      no params.
 *      returns the exit status.
 *      returns the exit status.
 */
 */
char *
char *
gdb_exited()
gdb_exited()
{
{
  /* generically, we can't do anything for this command */
  /* generically, we can't do anything for this command */
  return(make_return_packet(OK));
  return(make_return_packet(OK));
}
}
 
 
/*
/*
 * X - process terminated.
 * X - process terminated.
 *      no params.
 *      no params.
 *      returns the last signal.
 *      returns the last signal.
 */
 */
char *
char *
gdb_terminated()
gdb_terminated()
{
{
}
}
 
 
/*
/*
 * O - hex encoding.
 * O - hex encoding.
 *      params are a vector of bytes, and the number of bytes to encode.
 *      params are a vector of bytes, and the number of bytes to encode.
 *      returns a vector of ASCII encoded hex numbers.
 *      returns a vector of ASCII encoded hex numbers.
 */
 */
char *
char *
gdb_hex(char *str, int nbytes)
gdb_hex(char *str, int nbytes)
{
{
}
}
 
 
/*
/*
 * A - tread alive request.
 * A - tread alive request.
 *      param is the thread ID.
 *      param is the thread ID.
 *      returns an OK or an error number.
 *      returns an OK or an error number.
 */
 */
char *
char *
gdb_thread_alive(int tid)
gdb_thread_alive(int tid)
{
{
  /* generically, we can't do anything for this command */
  /* generically, we can't do anything for this command */
  return(make_return_packet(OK));
  return(make_return_packet(OK));
}
}
 
 
/*
/*
 * ! - extended protocol.
 * ! - extended protocol.
 *      no params.
 *      no params.
 *      returns an OK or an error number.
 *      returns an OK or an error number.
 */
 */
char *
char *
gdb_extended()
gdb_extended()
{
{
  /* generically, we can't do anything for this command */
  /* generically, we can't do anything for this command */
  return(make_return_packet(OK));
  return(make_return_packet(OK));
}
}
 
 
/*
/*
 * d - toggle gdb stub diagnostics.
 * d - toggle gdb stub diagnostics.
 *      no params.
 *      no params.
 *      returns an OK or an error number.
 *      returns an OK or an error number.
 */
 */
char *
char *
gdb_debug()
gdb_debug()
{
{
  if (remote_debug > 0)
  if (remote_debug > 0)
    remote_debug = 0;
    remote_debug = 0;
  else
  else
    remote_debug = 1;
    remote_debug = 1;
 
 
  return(make_return_packet(OK));
  return(make_return_packet(OK));
}
}
 
 
/*
/*
 * d - toggle gdb stub.
 * d - toggle gdb stub.
 *      no params.
 *      no params.
 *      returns an OK or an error number.
 *      returns an OK or an error number.
 */
 */
char *
char *
gdb_toggle()
gdb_toggle()
{
{
  static int level = 0;
  static int level = 0;
 
 
  if (remote_debug) {
  if (remote_debug) {
    level = remote_debug;
    level = remote_debug;
    remote_debug = 0;
    remote_debug = 0;
  } else {
  } else {
    remote_debug = level;
    remote_debug = level;
  }
  }
 
 
  return(make_return_packet(OK));
  return(make_return_packet(OK));
}
}
 
 
/*
/*
 * r - reset target
 * r - reset target
 *      no params.
 *      no params.
 *      returns an OK or an error number.
 *      returns an OK or an error number.
 */
 */
char *
char *
gdb_reset()
gdb_reset()
{
{
  /* generically, we can't do anything for this command */
  /* generically, we can't do anything for this command */
  return(make_return_packet(OK));
  return(make_return_packet(OK));
}
}
 
 
/*
/*
 * t - search backwards.
 * t - search backwards.
 *      params are the address to start searching from, a pattern to match, and
 *      params are the address to start searching from, a pattern to match, and
 *              the mask to use.
 *              the mask to use.
 *      FIXME: not entirely sure what this is supposed to return.
 *      FIXME: not entirely sure what this is supposed to return.
 */
 */
char *
char *
gdb_search(long addr, long pat, long mask)
gdb_search(long addr, long pat, long mask)
{
{
  /* generically, we can't do anything for this command */
  /* generically, we can't do anything for this command */
  return(make_return_packet(OK));
  return(make_return_packet(OK));
}
}
 
 
/*
/*
 * q - general get query.
 * q - general get query.
 *      param is a string, that's the query to be executed.
 *      param is a string, that's the query to be executed.
 *      FIXME: not entirely sure what this is supposed to return.
 *      FIXME: not entirely sure what this is supposed to return.
 */
 */
char *
char *
gdb_get_query(char *query)
gdb_get_query(char *query)
{
{
  /* generically, we can't do anything for this command */
  /* generically, we can't do anything for this command */
  return(make_return_packet(OK));
  return(make_return_packet(OK));
}
}
 
 
/*
/*
 * Q - general set query
 * Q - general set query
 *      param is a string, that's the query to be executed.
 *      param is a string, that's the query to be executed.
 *      FIXME: not entirely sure what this means.
 *      FIXME: not entirely sure what this means.
 *      returns an OK or an error number.
 *      returns an OK or an error number.
 */
 */
char *
char *
gdb_set(char *query)
gdb_set(char *query)
{
{
  /* generically, we can't do anything for this command */
  /* generically, we can't do anything for this command */
  return(make_return_packet(OK));
  return(make_return_packet(OK));
}
}
 
 
 
 
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.