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

Subversion Repositories openrisc

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

Only display areas with differences | Details | Blame | View Log

Rev 158 Rev 816
/* -*-C-*-
/* -*-C-*-
*******************************************************************************
*******************************************************************************
*
*
* File:         pa_stub.c
* File:         pa_stub.c
* RCS:          $Header: /cvs/src/src/libgloss/hp74x/pa_stub.c,v 1.1 2000/03/17 22:48:50 ranjith Exp $
* RCS:          $Header: /cvs/src/src/libgloss/hp74x/pa_stub.c,v 1.1 2000/03/17 22:48:50 ranjith Exp $
* Description:  main routines for PA RISC monitor stub
* Description:  main routines for PA RISC monitor stub
* Author:       Robert Quist
* Author:       Robert Quist
* Created:      Mon Nov  1 10:00:36 1993
* Created:      Mon Nov  1 10:00:36 1993
* Modified:     Fri Nov 12 15:14:23 1993 (Robert Quist) quist@hpfcrdq
* Modified:     Fri Nov 12 15:14:23 1993 (Robert Quist) quist@hpfcrdq
* Language:     C
* Language:     C
* Package:      N/A
* Package:      N/A
* Status:       Experimental (Do Not Distribute)
* Status:       Experimental (Do Not Distribute)
*
*
*******************************************************************************
*******************************************************************************
*/
*/
 
 
/****************************************************************************
/****************************************************************************
 
 
                THIS SOFTWARE IS NOT COPYRIGHTED
                THIS SOFTWARE IS NOT COPYRIGHTED
 
 
   HP offers the following for use in the public domain.  HP makes no
   HP offers the following for use in the public domain.  HP makes no
   warranty with regard to the software or it's performance and the
   warranty with regard to the software or it's performance and the
   user accepts the software "AS IS" with all faults.
   user accepts the software "AS IS" with all faults.
 
 
   HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD
   HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD
   TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
   TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 
 
****************************************************************************/
****************************************************************************/
 
 
/****************************************************************************
/****************************************************************************
 *
 *
 *  Description:     low level support for gdb debugger. $
 *  Description:     low level support for gdb debugger. $
 *
 *
 *  Considerations:  only works on target hardware $
 *  Considerations:  only works on target hardware $
 *
 *
 *  NOTES:           See Below $
 *  NOTES:           See Below $
 *
 *
 *    To enable debugger support, two things need to happen.
 *    To enable debugger support, two things need to happen.
 *
 *
 *  One, a call to set_debug_traps() is necessary in order to allow
 *  One, a call to set_debug_traps() is necessary in order to allow
 *  any breakpoints or error conditions to be properly intercepted and
 *  any breakpoints or error conditions to be properly intercepted and
 *  reported to gdb.
 *  reported to gdb.
 *
 *
 *  Two, a breakpoint needs to be generated to begin communication.
 *  Two, a breakpoint needs to be generated to begin communication.
 *  This is most easily accomplished by a call to breakpoint().
 *  This is most easily accomplished by a call to breakpoint().
 *  breakpoint() simulates a breakpoint
 *  breakpoint() simulates a breakpoint
 
 
 
 
 *************
 *************
 *
 *
 *    The following gdb commands are supported:
 *    The following gdb commands are supported:
 *
 *
 * command          function                               Return value
 * command          function                               Return value
 *
 *
 *    g             return the value of the CPU registers  hex data or ENN
 *    g             return the value of the CPU registers  hex data or ENN
 *    G             set the value of the CPU registers     OK or ENN
 *    G             set the value of the CPU registers     OK or ENN
 *
 *
 *    mAA..AA,LLLL  Read LLLL bytes at address AA..AA      hex data or ENN
 *    mAA..AA,LLLL  Read LLLL bytes at address AA..AA      hex data or ENN
 *    MAA..AA,LLLL: Write LLLL bytes at address AA.AA      OK or ENN
 *    MAA..AA,LLLL: Write LLLL bytes at address AA.AA      OK or ENN
 *
 *
 *    c             Resume at current address              SNN   ( signal NN)
 *    c             Resume at current address              SNN   ( signal NN)
 *    cAA..AA       Continue at address AA..AA             SNN
 *    cAA..AA       Continue at address AA..AA             SNN
 *
 *
 *    s             Step one instruction                   SNN
 *    s             Step one instruction                   SNN
 *    sAA..AA       Step one instruction from AA..AA       SNN
 *    sAA..AA       Step one instruction from AA..AA       SNN
 *
 *
 *    k             kill
 *    k             kill
 *
 *
 *    ?             What was the last sigval ?             SNN   (signal NN)
 *    ?             What was the last sigval ?             SNN   (signal NN)
 *
 *
 *    bBB..BB       Set baud rate to BB..BB                OK or BNN, then sets
 *    bBB..BB       Set baud rate to BB..BB                OK or BNN, then sets
 *                                                         baud rate
 *                                                         baud rate
 *
 *
 
 
 ************
 ************
 * All commands and responses are sent with a packet which includes a
 * All commands and responses are sent with a packet which includes a
 * checksum.  A packet consists of :
 * checksum.  A packet consists of :
 *
 *
 * $<packet info>#<checksum>.
 * $<packet info>#<checksum>.
 *
 *
 * where
 * where
 * <packet info> :: <characters representing the command or response>
 * <packet info> :: <characters representing the command or response>
 * <checksum>    :: < two hex digits computed as modulo 256 sum of <packetinfo>>
 * <checksum>    :: < two hex digits computed as modulo 256 sum of <packetinfo>>
 *
 *
 * When a packet is received, it is first acknowledged with either '+' or '-'.
 * When a packet is received, it is first acknowledged with either '+' or '-'.
 * '+' indicates a successful transfer.  '-' indicates a failed transfer.
 * '+' indicates a successful transfer.  '-' indicates a failed transfer.
 *
 *
 * Example:
 * Example:
 *
 *
 * Host:                  Reply:
 * Host:                  Reply:
 * $m0,10#2a               +$00010203040506070809101112131415#42
 * $m0,10#2a               +$00010203040506070809101112131415#42
 *
 *
 ****************************************************************************/
 ****************************************************************************/
#include <signal.h>
#include <signal.h>
#include "hppa-defs.h"
#include "hppa-defs.h"
 
 
/************************************************************************
/************************************************************************
 *
 *
 * external low-level support
 * external low-level support
 */
 */
#define OPT_PDC_CACHE        5
#define OPT_PDC_CACHE        5
#define OPT_PDC_ADD_VALID   12
#define OPT_PDC_ADD_VALID   12
#define PGZ_MEM_PDC     0x0388  /* location of PDC_ENTRY in memory    */
#define PGZ_MEM_PDC     0x0388  /* location of PDC_ENTRY in memory    */
#define CALL_PDC        (*(int (*)())((int *)(*((int *)PGZ_MEM_PDC))))
#define CALL_PDC        (*(int (*)())((int *)(*((int *)PGZ_MEM_PDC))))
 
 
extern putDebugChar();   /* write a single character      */
extern putDebugChar();   /* write a single character      */
extern getDebugChar();   /* read and return a single char */
extern getDebugChar();   /* read and return a single char */
extern FICE();           /* flush i cache entry */
extern FICE();           /* flush i cache entry */
extern INLINE_BREAK();   /* break for user call */
extern INLINE_BREAK();   /* break for user call */
 
 
#define RADDR_ALIGN(s,r) (s = ((unsigned int *) ((((int) r ) + 7 ) & 0xFFFFFFF8)))
#define RADDR_ALIGN(s,r) (s = ((unsigned int *) ((((int) r ) + 7 ) & 0xFFFFFFF8)))
 
 
/************************************************************************/
/************************************************************************/
/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/
/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/
/* at least NUMREGBYTES*2 are needed for register packets */
/* at least NUMREGBYTES*2 are needed for register packets */
 
 
#define BUFMAX 2048
#define BUFMAX 2048
 
 
#define NUMGPRS   32
#define NUMGPRS   32
#define NUMSRS     8
#define NUMSRS     8
#define NUMCRS    32
#define NUMCRS    32
#define NUMSPCLS   3
#define NUMSPCLS   3
#define NUMFPRS   32
#define NUMFPRS   32
 
 
#define NUMGPRBYTES     4
#define NUMGPRBYTES     4
#define NUMSRBYTES      4
#define NUMSRBYTES      4
#define NUMCRBYTES      4
#define NUMCRBYTES      4
#define NUMSPCLBYTES    4
#define NUMSPCLBYTES    4
#define NUMFPRBYTES     8
#define NUMFPRBYTES     8
 
 
/* Number of bytes of registers.  */
/* Number of bytes of registers.  */
#define NUMREGBYTES \
#define NUMREGBYTES \
        (  (NUMGPRS * NUMGPRBYTES) \
        (  (NUMGPRS * NUMGPRBYTES) \
         + (NUMSRS * NUMSRBYTES)   \
         + (NUMSRS * NUMSRBYTES)   \
         + (NUMCRS * NUMCRBYTES)   \
         + (NUMCRS * NUMCRBYTES)   \
         + (NUMSPCLS * NUMSPCLBYTES) \
         + (NUMSPCLS * NUMSPCLBYTES) \
         + (NUMFPRS * NUMFPRBYTES) \
         + (NUMFPRS * NUMFPRBYTES) \
        )
        )
 
 
 
 
enum regnames   {GR0,  GR1,  GR2,  GR3,  GR4,  GR5,  GR6,  GR7,
enum regnames   {GR0,  GR1,  GR2,  GR3,  GR4,  GR5,  GR6,  GR7,
                 GR8,  GR9,  GR10, GR11, GR12, GR13, GR14, GR15,
                 GR8,  GR9,  GR10, GR11, GR12, GR13, GR14, GR15,
                 GR16, GR17, GR18, GR19, GR20, GR21, GR22, GR23,
                 GR16, GR17, GR18, GR19, GR20, GR21, GR22, GR23,
                 GR24, GR25, GR26, GR27, GR28, GR29, GR30, GR31,
                 GR24, GR25, GR26, GR27, GR28, GR29, GR30, GR31,
 
 
                 SR0,  SR1,  SR2,  SR3,  SR4,  SR5,  SR6,  SR7,
                 SR0,  SR1,  SR2,  SR3,  SR4,  SR5,  SR6,  SR7,
 
 
                 CR0,  CR1,  CR2,  CR3,  CR4,  CR5,  CR6,  CR7,
                 CR0,  CR1,  CR2,  CR3,  CR4,  CR5,  CR6,  CR7,
                 CR8,  CR9,  CR10, CR11, CR12, CR13, CR14, CR15,
                 CR8,  CR9,  CR10, CR11, CR12, CR13, CR14, CR15,
                 CR16, CR17H,CR18H,CR19, CR20, CR21, CR22, CR23,
                 CR16, CR17H,CR18H,CR19, CR20, CR21, CR22, CR23,
                 CR24, CR25, CR26, CR27, CR28, CR29, CR30, CR31,
                 CR24, CR25, CR26, CR27, CR28, CR29, CR30, CR31,
 
 
                 CR17T,CR18T,CPUD0 };
                 CR17T,CR18T,CPUD0 };
 
 
enum fregnames  {FPR0,  FPR1,  FPR2,  FPR3,  FPR4,  FPR5,  FPR6,  FPR7,
enum fregnames  {FPR0,  FPR1,  FPR2,  FPR3,  FPR4,  FPR5,  FPR6,  FPR7,
                 FPR8,  FPR9,  FPR10, FPR11, FPR12, FPR13, FPR14, FPR15,
                 FPR8,  FPR9,  FPR10, FPR11, FPR12, FPR13, FPR14, FPR15,
                 FPR16, FPR17, FPR18, FPR19, FPR20, FPR21, FPR22, FPR23,
                 FPR16, FPR17, FPR18, FPR19, FPR20, FPR21, FPR22, FPR23,
                 FPR24, FPR25, FPR26, FPR27, FPR28, FPR29, FPR30, FPR31 };
                 FPR24, FPR25, FPR26, FPR27, FPR28, FPR29, FPR30, FPR31 };
 
 
#define PC  CR18H
#define PC  CR18H
#define NPC CR18T
#define NPC CR18T
#define SP  GR30
#define SP  GR30
 
 
struct registers {
struct registers {
       int intregs[NUMGPRS + NUMSRS + NUMCRS + NUMSPCLS];
       int intregs[NUMGPRS + NUMSRS + NUMCRS + NUMSPCLS];
       int fpregs [NUMFPRS * 2];
       int fpregs [NUMFPRS * 2];
                 };
                 };
/* Global Variables */
/* Global Variables */
 
 
static int initialized = 0;      /* !0 means we've been initialized */
static int initialized = 0;      /* !0 means we've been initialized */
static unsigned char hexchars[]="0123456789abcdef";
static unsigned char hexchars[]="0123456789abcdef";
static unsigned char remcomInBuffer[BUFMAX];
static unsigned char remcomInBuffer[BUFMAX];
static unsigned char remcomOutBuffer[BUFMAX];
static unsigned char remcomOutBuffer[BUFMAX];
static unsigned int  i_cache_params[6];
static unsigned int  i_cache_params[6];
 
 
/* This table contains the mapping between PA hardware exception
/* This table contains the mapping between PA hardware exception
   types, and signals, which are primarily what GDB understands.  It also
   types, and signals, which are primarily what GDB understands.  It also
   indicates which hardware traps we need to commandeer when initializing
   indicates which hardware traps we need to commandeer when initializing
   the stub.
   the stub.
 
 
   The only two currently used are Recovery counter (single stepping)
   The only two currently used are Recovery counter (single stepping)
   and Break trap ( break points ).
   and Break trap ( break points ).
*/
*/
 
 
static struct hard_trap_info
static struct hard_trap_info
{
{
  unsigned char tt;             /* Trap number for PA-RISC */
  unsigned char tt;             /* Trap number for PA-RISC */
  unsigned char signo;          /* Signal that we map this trap into */
  unsigned char signo;          /* Signal that we map this trap into */
} hard_trap_info[] = {
} hard_trap_info[] = {
/* 1  High priority machine check */
/* 1  High priority machine check */
/* 2  Power failure interrupt*/
/* 2  Power failure interrupt*/
/* 3  Recovery counter -- init */
/* 3  Recovery counter -- init */
/* 4  External interrupt */
/* 4  External interrupt */
/* 5  Low priority machine check */
/* 5  Low priority machine check */
  {6, SIGSEGV},                 /* Instruction TLB miss/page fault */
  {6, SIGSEGV},                 /* Instruction TLB miss/page fault */
  {7, SIGSEGV},                 /* Memory protection */
  {7, SIGSEGV},                 /* Memory protection */
  {8, SIGILL},                  /* Illegal instruction */
  {8, SIGILL},                  /* Illegal instruction */
  {9, SIGTRAP},                 /* Break instruction -- init */
  {9, SIGTRAP},                 /* Break instruction -- init */
  {10,SIGILL},                  /* Privileged instruction */
  {10,SIGILL},                  /* Privileged instruction */
  {11,SIGILL},                  /* Privileged register */
  {11,SIGILL},                  /* Privileged register */
  {12,SIGUSR1},                 /* Overflow */
  {12,SIGUSR1},                 /* Overflow */
  {13,SIGUSR2},                 /* Conditional */
  {13,SIGUSR2},                 /* Conditional */
  {14,SIGEMT},                  /* Assist Exception */
  {14,SIGEMT},                  /* Assist Exception */
  {15,SIGSEGV},                 /* Data TLB miss/page fault */
  {15,SIGSEGV},                 /* Data TLB miss/page fault */
  {16,SIGSEGV},                 /* Non-access Instruction TLB miss */
  {16,SIGSEGV},                 /* Non-access Instruction TLB miss */
  {17,SIGSEGV},                 /* Non-access Data TLB miss/page fault */
  {17,SIGSEGV},                 /* Non-access Data TLB miss/page fault */
  {18,SIGSEGV},                 /* Data memory protection/ unaligned data reference */
  {18,SIGSEGV},                 /* Data memory protection/ unaligned data reference */
  {19,SIGTRAP},                 /* Data memory break */
  {19,SIGTRAP},                 /* Data memory break */
  {20,SIGSEGV},                 /* TLB dirty bit */
  {20,SIGSEGV},                 /* TLB dirty bit */
  {21,SIGSEGV},                 /* Page reference */
  {21,SIGSEGV},                 /* Page reference */
  {22,SIGEMT},                  /* Assist emulation */
  {22,SIGEMT},                  /* Assist emulation */
  {23,SIGILL},                  /* Higher-privilege */
  {23,SIGILL},                  /* Higher-privilege */
  {24,SIGILL},                  /* Lower-privilege */
  {24,SIGILL},                  /* Lower-privilege */
  {25,SIGTRAP},                 /* Taken branch */
  {25,SIGTRAP},                 /* Taken branch */
  {0, 0}                  /* Must be last */
  {0, 0}                  /* Must be last */
};
};
 
 
/* Functions */
/* Functions */
/*========================================================================== */
/*========================================================================== */
 
 
/* Convert ch from a hex digit to an int */
/* Convert ch from a hex digit to an int */
 
 
static int
static int
hex(ch)
hex(ch)
     unsigned char ch;
     unsigned char ch;
{
{
  if (ch >= 'a' && ch <= 'f')
  if (ch >= 'a' && ch <= 'f')
    return ch-'a'+10;
    return ch-'a'+10;
  if (ch >= '0' && ch <= '9')
  if (ch >= '0' && ch <= '9')
    return ch-'0';
    return ch-'0';
  if (ch >= 'A' && ch <= 'F')
  if (ch >= 'A' && ch <= 'F')
    return ch-'A'+10;
    return ch-'A'+10;
  return -1;
  return -1;
}
}
 
 
/* scan for the sequence $<data>#<checksum>     */
/* scan for the sequence $<data>#<checksum>     */
 
 
static void
static void
getpacket(buffer)
getpacket(buffer)
     char *buffer;
     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 */
      strobe();
      strobe();
      while ((ch = getDebugChar()) != '$') ;
      while ((ch = getDebugChar()) != '$') ;
 
 
      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 = getDebugChar();
          ch = getDebugChar();
          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 = hex(getDebugChar()) << 4;
          xmitcsum = hex(getDebugChar()) << 4;
          xmitcsum |= hex(getDebugChar());
          xmitcsum |= hex(getDebugChar());
 
 
#if TESTING
#if TESTING
          /* Humans shouldn't have to figure out checksums to type to it. */
          /* Humans shouldn't have to figure out checksums to type to it. */
          putDebugChar ('+');
          putDebugChar ('+');
          return;
          return;
#endif
#endif
          if (checksum != xmitcsum)
          if (checksum != xmitcsum)
            putDebugChar('-');  /* failed checksum */
            putDebugChar('-');  /* failed checksum */
          else
          else
            {
            {
              putDebugChar('+'); /* successful transfer */
              putDebugChar('+'); /* 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] == ':')
                {
                {
                  putDebugChar(buffer[0]);
                  putDebugChar(buffer[0]);
                  putDebugChar(buffer[1]);
                  putDebugChar(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.  */
 
 
static void
static void
putpacket(buffer)
putpacket(buffer)
     unsigned char *buffer;
     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
    {
    {
      putDebugChar('$');
      putDebugChar('$');
      checksum = 0;
      checksum = 0;
      count = 0;
      count = 0;
 
 
      while (ch = buffer[count])
      while (ch = buffer[count])
        {
        {
          if (! putDebugChar(ch))
          if (! putDebugChar(ch))
            return;
            return;
          checksum += ch;
          checksum += ch;
          count += 1;
          count += 1;
        }
        }
 
 
      putDebugChar('#');
      putDebugChar('#');
      putDebugChar(hexchars[checksum >> 4]);
      putDebugChar(hexchars[checksum >> 4]);
      putDebugChar(hexchars[checksum & 0xf]);
      putDebugChar(hexchars[checksum & 0xf]);
      } while (getDebugChar() != '+');
      } while (getDebugChar() != '+');
}
}
 
 
/* 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.
 */
 */
 
 
static unsigned char *
static unsigned char *
mem2hex(mem, buf, count, may_fault)
mem2hex(mem, buf, count, may_fault)
     unsigned char *mem;
     unsigned char *mem;
     unsigned char *buf;
     unsigned char *buf;
     int count;
     int count;
     int may_fault;
     int may_fault;
{
{
  unsigned char ch;
  unsigned char ch;
  int           check_addr,
  int           check_addr,
                new_addr;
                new_addr;
 
 
  check_addr = 0;
  check_addr = 0;
 
 
  while (count-- > 0)
  while (count-- > 0)
    {
    {
      if (may_fault)
      if (may_fault)
      { new_addr = ((int) (mem+3)) & 0xFFFFFFF8;
      { new_addr = ((int) (mem+3)) & 0xFFFFFFF8;
        if (new_addr != check_addr)
        if (new_addr != check_addr)
        { check_addr = new_addr;
        { check_addr = new_addr;
          if (pdc_call(OPT_PDC_ADD_VALID,0,check_addr)) return 0;
          if (pdc_call(OPT_PDC_ADD_VALID,0,check_addr)) return 0;
        }
        }
      }
      }
      ch = *mem++;
      ch = *mem++;
      *buf++ = hexchars[ch >> 4];
      *buf++ = hexchars[ch >> 4];
      *buf++ = hexchars[ch & 0xf];
      *buf++ = hexchars[ch & 0xf];
    }
    }
 
 
  *buf = 0;
  *buf = 0;
 
 
  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 */
 
 
static unsigned char *
static unsigned char *
hex2mem(buf, mem, count, may_fault)
hex2mem(buf, mem, count, may_fault)
     unsigned char *buf;
     unsigned char *buf;
     unsigned char *mem;
     unsigned char *mem;
     int count;
     int count;
     int may_fault;
     int may_fault;
{
{
  int          i;
  int          i;
  unsigned int ch;
  unsigned int ch;
  int          check_addr,
  int          check_addr,
               new_addr;
               new_addr;
 
 
  check_addr = 0;
  check_addr = 0;
 
 
  for (i=0; i<count; i++)
  for (i=0; i<count; i++)
    {
    {
      ch = hex(*buf++) << 4;
      ch = hex(*buf++) << 4;
      ch |= hex(*buf++);
      ch |= hex(*buf++);
      if (may_fault)
      if (may_fault)
      { new_addr = ((int)(mem+3)) & 0xFFFFFFF8;
      { new_addr = ((int)(mem+3)) & 0xFFFFFFF8;
        if (new_addr != check_addr)
        if (new_addr != check_addr)
        { check_addr = new_addr;
        { check_addr = new_addr;
          if (pdc_call(OPT_PDC_ADD_VALID,0,check_addr)) return 0;
          if (pdc_call(OPT_PDC_ADD_VALID,0,check_addr)) return 0;
        }
        }
      }
      }
      *mem++ = ch;
      *mem++ = ch;
    }
    }
 
 
  return mem;
  return mem;
}
}
 
 
/* Set up exception handlers for traceing and breakpoints */
/* Set up exception handlers for traceing and breakpoints */
 
 
void
void
set_debug_traps()
set_debug_traps()
{
{
  unsigned int  R_addr[33];
  unsigned int  R_addr[33];
  unsigned int  *Raddr_ptr;
  unsigned int  *Raddr_ptr;
 
 
  setup_vectors();
  setup_vectors();
 
 
  /* get cache params for use by flush_i_cache */
  /* get cache params for use by flush_i_cache */
  RADDR_ALIGN(Raddr_ptr,R_addr);
  RADDR_ALIGN(Raddr_ptr,R_addr);
 
 
  if (pdc_call(OPT_PDC_CACHE,0,Raddr_ptr,0))
  if (pdc_call(OPT_PDC_CACHE,0,Raddr_ptr,0))
    i_cache_params[0] = -1;
    i_cache_params[0] = -1;
  else
  else
    i_cache_params[0] = R_addr[0];
    i_cache_params[0] = R_addr[0];
 
 
  i_cache_params[1] = Raddr_ptr[1];
  i_cache_params[1] = Raddr_ptr[1];
  i_cache_params[2] = Raddr_ptr[2];
  i_cache_params[2] = Raddr_ptr[2];
  i_cache_params[3] = Raddr_ptr[3];
  i_cache_params[3] = Raddr_ptr[3];
  i_cache_params[4] = Raddr_ptr[4];
  i_cache_params[4] = Raddr_ptr[4];
  i_cache_params[5] = Raddr_ptr[5];
  i_cache_params[5] = Raddr_ptr[5];
 
 
  /* 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.  */
 
 
  putDebugChar ('+');
  putDebugChar ('+');
 
 
  initialized = 1;
  initialized = 1;
}
}
 
 
 
 
/* Convert the PA-RISC hardware trap number to a unix signal number. */
/* Convert the PA-RISC hardware trap number to a unix signal number. */
 
 
static int
static int
computeSignal(tt)
computeSignal(tt)
     int tt;
     int tt;
{
{
  struct hard_trap_info *ht;
  struct hard_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 */
}
}
 
 
/*
/*
 * While we find nice hex chars, build an int.
 * While we find nice hex chars, build an int.
 * Return number of chars processed.
 * Return number of chars processed.
 */
 */
 
 
static int
static int
hexToInt(ptr, intValue)
hexToInt(ptr, intValue)
     unsigned char **ptr;
     unsigned char **ptr;
     int *intValue;
     int *intValue;
{
{
  int numChars = 0;
  int numChars = 0;
  int hexValue;
  int hexValue;
 
 
  *intValue = 0;
  *intValue = 0;
 
 
  while (**ptr)
  while (**ptr)
    {
    {
      hexValue = hex(**ptr);
      hexValue = hex(**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);
}
}
 
 
void
void
flush_i_cache()
flush_i_cache()
 
 
{
{
  unsigned int addr,count,loop;
  unsigned int addr,count,loop;
 
 
  if (i_cache_params[0] <= 0) return;
  if (i_cache_params[0] <= 0) return;
 
 
  addr = i_cache_params[2];
  addr = i_cache_params[2];
  for (count = 0; count < i_cache_params[4]; count++)
  for (count = 0; count < i_cache_params[4]; count++)
    { for ( loop = 0; loop < i_cache_params[5]; loop++) FICE(addr);
    { for ( loop = 0; loop < i_cache_params[5]; loop++) FICE(addr);
      addr = addr + i_cache_params[3];
      addr = addr + i_cache_params[3];
    }
    }
}
}
 
 
/*
/*
 * This function does all command procesing for interfacing to gdb.
 * This function does all command procesing for interfacing to gdb.
   return of 0 will execute DEBUG_GO (continue)
   return of 0 will execute DEBUG_GO (continue)
   return of 1 will execute DEBUG_SS (single step)
   return of 1 will execute DEBUG_SS (single step)
 */
 */
 
 
int
int
handle_exception (registers,tt)
handle_exception (registers,tt)
  unsigned long *registers;
  unsigned long *registers;
  int  tt;                      /* Trap type */
  int  tt;                      /* Trap type */
{
{
  int sigval;
  int sigval;
  int addr;
  int addr;
  int length;
  int length;
  unsigned char *ptr;
  unsigned char *ptr;
 
 
  /* reply to host that an exception has occurred */
  /* reply to host that an exception has occurred */
  sigval = computeSignal(tt);
  sigval = computeSignal(tt);
  ptr = remcomOutBuffer;
  ptr = remcomOutBuffer;
 
 
  *ptr++ = 'T';
  *ptr++ = 'T';
  *ptr++ = hexchars[sigval >> 4];
  *ptr++ = hexchars[sigval >> 4];
  *ptr++ = hexchars[sigval & 0xf];
  *ptr++ = hexchars[sigval & 0xf];
 
 
/* could be lots of stuff here like PC and SP registers */
/* could be lots of stuff here like PC and SP registers */
 
 
  *ptr++ = 0;
  *ptr++ = 0;
 
 
  putpacket(remcomOutBuffer);
  putpacket(remcomOutBuffer);
 
 
  while (1)
  while (1)
    {
    {
      remcomOutBuffer[0] = 0;
      remcomOutBuffer[0] = 0;
 
 
      getpacket(remcomInBuffer);
      getpacket(remcomInBuffer);
      switch (remcomInBuffer[0])
      switch (remcomInBuffer[0])
        {
        {
        case '?':
        case '?':
          remcomOutBuffer[0] = 'S';
          remcomOutBuffer[0] = 'S';
          remcomOutBuffer[1] = hexchars[sigval >> 4];
          remcomOutBuffer[1] = hexchars[sigval >> 4];
          remcomOutBuffer[2] = hexchars[sigval & 0xf];
          remcomOutBuffer[2] = hexchars[sigval & 0xf];
          remcomOutBuffer[3] = 0;
          remcomOutBuffer[3] = 0;
          break;
          break;
 
 
        case 'd':
        case 'd':
          /* toggle debug flag */
          /* toggle debug flag */
          led_putnum (16);
          led_putnum (16);
          break;
          break;
 
 
        case 'g':               /* return the value of the CPU registers */
        case 'g':               /* return the value of the CPU registers */
          {
          {
            ptr = remcomOutBuffer;
            ptr = remcomOutBuffer;
            /* GR0..GR31 SR0..SR7 CR0..CR31 specials */
            /* GR0..GR31 SR0..SR7 CR0..CR31 specials */
            ptr = mem2hex((char *)registers, ptr, NUMREGBYTES, 0);
            ptr = mem2hex((char *)registers, ptr, NUMREGBYTES, 0);
            /* need to add floating point registers */
            /* need to add floating point 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 */
          {
          {
            ptr = &remcomInBuffer[1];
            ptr = &remcomInBuffer[1];
            /* GR0..GR31 SR0..SR7 CR0..CR31 specials */
            /* GR0..GR31 SR0..SR7 CR0..CR31 specials */
            hex2mem(ptr, (char *)registers, NUMREGBYTES, 0);
            hex2mem(ptr, (char *)registers, NUMREGBYTES, 0);
            strcpy(remcomOutBuffer,"OK 1");
            strcpy(remcomOutBuffer,"OK 1");
          }
          }
          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.  */
 
 
          ptr = &remcomInBuffer[1];
          ptr = &remcomInBuffer[1];
 
 
          if (hexToInt(&ptr, &addr)
          if (hexToInt(&ptr, &addr)
              && *ptr++ == ','
              && *ptr++ == ','
              && hexToInt(&ptr, &length))
              && hexToInt(&ptr, &length))
            {
            {
              if (mem2hex((char *)addr, remcomOutBuffer, length, 1))
              if (mem2hex((char *)addr, remcomOutBuffer, length, 1))
                break;
                break;
 
 
              strcpy (remcomOutBuffer, "E03");
              strcpy (remcomOutBuffer, "E03");
            }
            }
          else
          else
            strcpy(remcomOutBuffer,"E01");
            strcpy(remcomOutBuffer,"E01");
          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:'.  */
 
 
          ptr = &remcomInBuffer[1];
          ptr = &remcomInBuffer[1];
 
 
          if (hexToInt(&ptr, &addr)
          if (hexToInt(&ptr, &addr)
              && *ptr++ == ','
              && *ptr++ == ','
              && hexToInt(&ptr, &length)
              && hexToInt(&ptr, &length)
              && *ptr++ == ':')
              && *ptr++ == ':')
            {
            {
              if (hex2mem(ptr, (char *)addr, length, 1))
              if (hex2mem(ptr, (char *)addr, length, 1))
                strcpy(remcomOutBuffer, "OK");
                strcpy(remcomOutBuffer, "OK");
              else
              else
                strcpy(remcomOutBuffer, "E03");
                strcpy(remcomOutBuffer, "E03");
            }
            }
          else
          else
            strcpy(remcomOutBuffer, "E02");
            strcpy(remcomOutBuffer, "E02");
          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 */
 
 
          ptr = &remcomInBuffer[1];
          ptr = &remcomInBuffer[1];
          if (hexToInt(&ptr, &addr))
          if (hexToInt(&ptr, &addr))
            {
            {
              registers[PC] = addr;
              registers[PC] = addr;
              registers[NPC] = addr + 4;
              registers[NPC] = addr + 4;
            }
            }
 
 
/* Need to flush the instruction cache here, as we may have deposited a
/* Need to flush the instruction cache here, as we may have deposited a
   breakpoint, and the icache probably has no way of knowing that a data ref to
   breakpoint, and the icache probably has no way of knowing that a data ref to
   some location may have changed something that is in the instruction cache.
   some location may have changed something that is in the instruction cache.
 */
 */
 
 
          flush_i_cache();
          flush_i_cache();
          return 0;              /* execute GO */
          return 0;              /* execute GO */
 
 
          /* kill the program */
          /* kill the program */
        case 'k' :              /* do nothing */
        case 'k' :              /* do nothing */
          break;
          break;
 
 
        case 's' :              /* single step */
        case 's' :              /* single step */
          /* try to read optional parameter, pc unchanged if no parm */
          /* try to read optional parameter, pc unchanged if no parm */
 
 
          ptr = &remcomInBuffer[1];
          ptr = &remcomInBuffer[1];
          if (hexToInt(&ptr, &addr))
          if (hexToInt(&ptr, &addr))
            {
            {
              registers[PC] = addr;
              registers[PC] = addr;
              registers[NPC] = addr + 4;
              registers[NPC] = addr + 4;
            }
            }
/* Need to flush the instruction cache here, as we may have deposited a
/* Need to flush the instruction cache here, as we may have deposited a
   breakpoint, and the icache probably has no way of knowing that a data ref to
   breakpoint, and the icache probably has no way of knowing that a data ref to
   some location may have changed something that is in the instruction cache.
   some location may have changed something that is in the instruction cache.
 */
 */
          flush_i_cache();
          flush_i_cache();
          return 1;             /* execute Single Step */
          return 1;             /* execute Single Step */
          break;
          break;
 
 
#if TESTING1
#if TESTING1
        case 't':               /* Test feature */
        case 't':               /* Test feature */
          break;
          break;
#endif
#endif
        case 'r':               /* Reset */
        case 'r':               /* Reset */
          break;
          break;
 
 
#if TESTING2
#if TESTING2
Disabled until we can unscrew this properly
Disabled until we can unscrew this properly
 
 
        case 'b':         /* bBB...  Set baud rate to BB... */
        case 'b':         /* bBB...  Set baud rate to BB... */
          {
          {
            int baudrate;
            int baudrate;
            extern void set_timer_3();
            extern void set_timer_3();
 
 
            ptr = &remcomInBuffer[1];
            ptr = &remcomInBuffer[1];
            if (!hexToInt(&ptr, &baudrate))
            if (!hexToInt(&ptr, &baudrate))
              {
              {
                strcpy(remcomOutBuffer,"B01");
                strcpy(remcomOutBuffer,"B01");
                break;
                break;
              }
              }
 
 
            /* Convert baud rate to uart clock divider */
            /* Convert baud rate to uart clock divider */
            switch (baudrate)
            switch (baudrate)
              {
              {
              case 38400:
              case 38400:
                baudrate = 16;
                baudrate = 16;
                break;
                break;
              case 19200:
              case 19200:
                baudrate = 33;
                baudrate = 33;
                break;
                break;
              case 9600:
              case 9600:
                baudrate = 65;
                baudrate = 65;
                break;
                break;
              default:
              default:
                strcpy(remcomOutBuffer,"B02");
                strcpy(remcomOutBuffer,"B02");
                goto x1;
                goto x1;
              }
              }
 
 
            putpacket("OK 2");  /* Ack before changing speed */
            putpacket("OK 2");  /* Ack before changing speed */
            set_timer_3(baudrate); /* Set it */
            set_timer_3(baudrate); /* Set it */
          }
          }
x1:       break;
x1:       break;
#endif
#endif
        }                       /* switch */
        }                       /* switch */
 
 
      /* reply to the request */
      /* reply to the request */
      putpacket(remcomOutBuffer);
      putpacket(remcomOutBuffer);
    }
    }
  print ("\r\nEscaped handle_exception\r\n");
  print ("\r\nEscaped handle_exception\r\n");
}
}
 
 

powered by: WebSVN 2.1.0

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