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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [or1ksim/] [debug/] [jtag.c] - Diff between revs 96 and 97

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 96 Rev 97
Line 205... Line 205...
 
 
  jreg[zero_bytes] >>= zero_off;
  jreg[zero_bytes] >>= zero_off;
  jreg[zero_bytes] <<= zero_off;
  jreg[zero_bytes] <<= zero_off;
 
 
  /* Determine how much to skip in total */
  /* Determine how much to skip in total */
  unsigned int  skip_bytes = ign_bits + zero_bits / 8;
  unsigned int  skip_bytes = (ign_bits + zero_bits) / 8;
  unsigned int  bit_off    = ign_bits + zero_bits % 8;
  unsigned int  bit_off    = (ign_bits + zero_bits) % 8;
 
 
  /* Simplify by dealing separately with two cases:
  /* Simplify by dealing separately with two cases:
     - the bit offset is less than or equal to 4, so the status goes in the
     - the bit offset is less than or equal to 4, so the status goes in the
       first free byte, with some CRC.
       first free byte, with some CRC.
     - the bit offset is greater than 4 but less than 8, so the status goes in
     - the bit offset is greater than 4 but less than 8, so the status goes in
Line 288... Line 288...
static int
static int
module_select (unsigned char *jreg)
module_select (unsigned char *jreg)
{
{
  /* Break out the fields */
  /* Break out the fields */
  uint8_t   mod_id = reverse_bits ((jreg[0] >> 1) & 0xf, 4);
  uint8_t   mod_id = reverse_bits ((jreg[0] >> 1) & 0xf, 4);
  uint32_t  crc_in = reverse_bits (((uint32_t )  jreg[0] & 0xe0  >>  5) |
  uint32_t  crc_in = reverse_bits (((uint32_t ) (jreg[0] & 0xe0) >>  5) |
                                   ((uint32_t )  jreg[1]         <<  3) |
                                   ((uint32_t )  jreg[1]         <<  3) |
                                   ((uint32_t )  jreg[2]         << 11) |
                                   ((uint32_t )  jreg[2]         << 11) |
                                   ((uint32_t )  jreg[3]         << 19) |
                                   ((uint32_t )  jreg[3]         << 19) |
                                   ((uint32_t ) (jreg[4] & 0x1f) << 27), 32);
                                   ((uint32_t ) (jreg[4] & 0x1f) << 27), 32);
 
 
Line 384... Line 384...
    case JAT_READ32:
    case JAT_READ32:
      access_bits = 32;
      access_bits = 32;
      break;
      break;
 
 
    default:
    default:
      fprintf (stderr, "*** ABORT ***: validate_wb_fields: unknown access "
      fprintf (stderr, "Warning: validate_wb_fields: unknown access "
               "type %u\n", runtime.debug.acc_type);
               "type %u\n", runtime.debug.acc_type);
      abort ();
      return  0;
    }
    }
 
 
  /* Check for validity. This works for 8-bit, although the tests will always
  /* Check for validity. This works for 8-bit, although the tests will always
     pass. */
     pass. */
  uint32_t  access_bytes = access_bits / 8;
  uint32_t  access_bytes = access_bits / 8;
Line 474... Line 474...
 
 
      /* Get the data with no cache or VM translation and update the CRC */
      /* Get the data with no cache or VM translation and update the CRC */
      unsigned char  byte = eval_direct8 (runtime.debug.addr + i, 0, 0);
      unsigned char  byte = eval_direct8 (runtime.debug.addr + i, 0, 0);
      crc_out = crc32 (byte, 8, crc_out);
      crc_out = crc32 (byte, 8, crc_out);
 
 
      /* Store the byte in the register, without trampling adjacent
      /* Reverse, then store the byte in the register, without trampling
         bits. Simplified version when the bit offset is zero. */
         adjacent bits. Simplified version when the bit offset is zero. */
 
      byte = reverse_byte (byte);
 
 
      if (0 == bit_off)
      if (0 == bit_off)
        {
        {
          jreg[byte_off + i] = byte;
          jreg[byte_off + i] = byte;
        }
        }
      else
      else
Line 528... Line 530...
   Warning messages are printed to explain any validation problems.
   Warning messages are printed to explain any validation problems.
 
 
   @todo Should multiple SPR accesses be allowed in a single access?
   @todo Should multiple SPR accesses be allowed in a single access?
 
 
   @note The size of the data is one greater than the length specified in the
   @note The size of the data is one greater than the length specified in the
         original WRITE_COMMAND.                                             */
         original WRITE_COMMAND.
 
 
 
   @return  1 (TRUE) if we could validate, even if we had to modify a field
 
            with a warning. 0 (FALSE) otherwise.                             */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static void
static int
validate_spr_fields ()
validate_spr_fields ()
{
{
  int  access_bits;
  int  access_bits;
  int  is_read_p;
  int  is_read_p;
 
 
  switch (runtime.debug.acc_type)
  switch (runtime.debug.acc_type)
    {
    {
    case JAT_WRITE8:  access_bits =  8; is_read_p = 0;
    case JAT_WRITE8:  access_bits =  8; is_read_p = 0; break;
    case JAT_READ8:   access_bits =  8; is_read_p = 1;
    case JAT_READ8:   access_bits =  8; is_read_p = 1; break;
    case JAT_WRITE16: access_bits = 16; is_read_p = 0;
    case JAT_WRITE16: access_bits = 16; is_read_p = 0; break;
    case JAT_READ16:  access_bits = 16; is_read_p = 1;
    case JAT_READ16:  access_bits = 16; is_read_p = 1; break;
    case JAT_WRITE32: access_bits = 32; is_read_p = 0;
    case JAT_WRITE32: access_bits = 32; is_read_p = 0; break;
    case JAT_READ32:  access_bits = 32; is_read_p = 1;
    case JAT_READ32:  access_bits = 32; is_read_p = 1; break;
 
 
    default:
    default:
      fprintf (stderr, "*** ABORT ***: validate_spr_fields: unknown access "
      fprintf (stderr, "Warning: validate_spr_fields: unknown access "
               "type %u\n", runtime.debug.acc_type);
               "type %u\n", runtime.debug.acc_type);
      abort ();
      return  0;
    }
    }
 
 
  /* Validate and correct if necessary access width */
  /* Validate and correct if necessary access width */
  if (32 != access_bits)
  if (32 != access_bits)
    {
    {
Line 562... Line 567...
    }
    }
 
 
  /* Validate and correct if necessary access size */
  /* Validate and correct if necessary access size */
  if (1 != runtime.debug.size)
  if (1 != runtime.debug.size)
    {
    {
      fprintf (stderr, "warning: JTAG SPR access must be 1 word in length: "
      fprintf (stderr, "Warning: JTAG SPR access must be 1 word in length: "
               "corrected\n");
               "corrected\n");
      runtime.debug.size = 1;
      runtime.debug.size = 1;
    }
    }
 
 
  /* Validate and correct if necessary access size */
  /* Validate and correct if necessary access size */
  if (runtime.debug.addr >= MAX_SPRS)
  if (runtime.debug.addr >= MAX_SPRS)
    {
    {
      fprintf (stderr, "warning: JTAG SPR address exceeds MAX_SPRS: "
      fprintf (stderr, "Warning: JTAG SPR address exceeds MAX_SPRS: "
               "truncated\n");
               "truncated\n");
      runtime.debug.addr %= MAX_SPRS;
      runtime.debug.addr %= MAX_SPRS;
    }
    }
 
 
 
  return  0;                     /* Success */
 
 
}       /* validate_spr_fields () */
}       /* validate_spr_fields () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Read SPR data
/*!Read SPR data
Line 610... Line 619...
          unsigned int   skip_bits)
          unsigned int   skip_bits)
{
{
  /* Compute the CRC as we go */
  /* Compute the CRC as we go */
  uint32_t  crc_out  = 0xffffffff;
  uint32_t  crc_out  = 0xffffffff;
 
 
  /* Validate the fields for the SPR read. This doesn't stop us - just prints
  /* Validate the fields for the SPR read. This mostly just prints
     out warnings and corrects the problems. */
     out warnings and corrects the problems. However if the access type
  validate_spr_fields();
     cannot be worked out, we must use empty data. */
 
  uint32_t  spr;
 
 
 
  if (validate_spr_fields())
 
    {
  /* Transfer the SPR */
  /* Transfer the SPR */
  uint32_t  spr = mfspr (runtime.debug.addr);
      spr = mfspr (runtime.debug.addr);
 
    }
 
  else
 
    {
 
      spr = 0;
 
    }
 
 
  runtime.debug.addr++;
  runtime.debug.addr++;
 
 
  /* Store the SPR in the register, without trampling adjacent
  /* Store the SPR in the register, without trampling adjacent
     bits. Simplified version when the bit offset is zero. Compute the CRC as
     bits. Simplified version when the bit offset is zero. Compute the CRC as
Line 752... Line 769...
          fprintf (stderr, "Warning: JTAG attempt to read from CPU1: Not "
          fprintf (stderr, "Warning: JTAG attempt to read from CPU1: Not "
                   "supported.\n");
                   "supported.\n");
          break;
          break;
 
 
        default:
        default:
          fprintf (stderr, "*** ABORT ***: go_command_read: invalid "
          fprintf (stderr, "Warning: go_command_read: invalid module 0x%lx\n",
                   "module\n");
                   runtime.debug.mod_id);
          abort ();
          break;
        }
        }
    }
    }
  else
  else
    {
    {
      /* Mismatch: record the error */
      /* Mismatch: record the error */
Line 822... Line 839...
          return;
          return;
        }
        }
 
 
      /* Extract the byte from the register. Simplified version when the bit
      /* Extract the byte from the register. Simplified version when the bit
         offset is zero. */
         offset is zero. */
      unsigned char  byte_r;
      unsigned char  byte;
 
 
      if (0 == bit_off)
      if (0 == bit_off)
        {
        {
          byte_r = jreg[byte_off + i];
          byte = jreg[byte_off + i];
        }
        }
      else
      else
        {
        {
          byte_r = jreg[byte_off + i]     >>      bit_off  |
          byte = jreg[byte_off + i]     >>      bit_off  |
                   jreg[byte_off + i + 1] >> (8 - bit_off);
                 jreg[byte_off + i + 1] << (8 - bit_off);
        }
        }
 
 
      /* Circumvent the read-only check usually done for mem accesses. */
      /* Circumvent the read-only check usually done for mem accesses. */
      set_program8 (runtime.debug.addr + i, reverse_byte (byte_r));
      set_program8 (runtime.debug.addr + i, reverse_byte (byte));
    }
    }
 
 
  runtime.debug.addr += runtime.debug.size;
  runtime.debug.addr += runtime.debug.size;
 
 
}       /* wishbone_write () */
}       /* wishbone_write () */
Line 870... Line 887...
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static void
static void
spr_write (unsigned char *jreg,
spr_write (unsigned char *jreg,
          unsigned int   skip_bits)
          unsigned int   skip_bits)
{
{
  /* Validate the fields for the SPR write. This doesn't stop us - just prints
  /* Validate the fields for the SPR write. This doesn't stop us most of the
     out warnings and corrects the problems. */
     time, just prints out warnings and corrects the problems. However if we
  validate_spr_fields ();
     don't know the access type, then it will fail and we do nothing. */
 
  if (!validate_spr_fields ())
 
    {
 
      return;
 
    }
 
 
  /* Construct the SPR value one byte at a time. */
  /* Construct the SPR value one byte at a time. */
  uint32_t  spr = 0;
  uint32_t  spr = 0;
 
 
  unsigned  byte_off = skip_bits / 8;
  unsigned  byte_off = skip_bits / 8;
Line 974... Line 995...
 
 
  int  i;
  int  i;
 
 
  for (i = 0; i < runtime.debug.size; i++)
  for (i = 0; i < runtime.debug.size; i++)
    {
    {
      uint8_t  byte = ((jreg[i] & 0xe0) >> 5) | ((jreg[i + 1] & 0x1f) << 3);
      uint8_t  byte = reverse_bits (((jreg[i] & 0xe0) >> 5) |
 
                      ((jreg[i + 1] & 0x1f) << 3), 8);
      crc_computed = crc32 (byte, 8, crc_computed);
      crc_computed = crc32 (byte, 8, crc_computed);
    }
    }
 
 
  /* Status flags */
  /* Status flags */
  enum jtag_status  status = JS_OK;
  enum jtag_status  status = JS_OK;
Line 1001... Line 1023...
          fprintf (stderr, "Warning: JTAG attempt to write to CPU1: Not "
          fprintf (stderr, "Warning: JTAG attempt to write to CPU1: Not "
                   "supported.\n");
                   "supported.\n");
          break;
          break;
 
 
        default:
        default:
          fprintf (stderr, "*** ABORT ***: go_command_write: invalid "
          fprintf (stderr, "Warning: go_command_write: invalid module 0x%lx\n",
                   "module\n");
                   runtime.debug.mod_id);
          abort ();
          break;
        }
        }
    }
    }
  else
  else
    {
    {
      /* Mismatch: record the error */
      /* Mismatch: record the error */
Line 1129... Line 1151...
  if (crc_computed != crc_in)
  if (crc_computed != crc_in)
    {
    {
      /* Mismatch: record the error */
      /* Mismatch: record the error */
      status |= JS_CRC_IN_ERROR;
      status |= JS_CRC_IN_ERROR;
    }
    }
  else if (runtime.debug.write_defined_p)
 
 
  /* If we haven't had a previous WRITE_COMMAND, then we return empty
 
     data. There is no valid status flag we can use, but we print a rude
 
     message. */
 
  uint8_t   acc_type_r;
 
  uint32_t  addr_r;
 
  uint16_t  len_r;
 
 
 
  if (runtime.debug.write_defined_p)
    {
    {
      /* Compute the CRC */
      /* Compute the CRC */
      crc_out = crc32 (runtime.debug.acc_type,  4, crc_out);
      crc_out = crc32 (runtime.debug.acc_type,  4, crc_out);
      crc_out = crc32 (runtime.debug.addr,     32, crc_out);
      crc_out = crc32 (runtime.debug.addr,     32, crc_out);
      crc_out = crc32 (runtime.debug.size - 1, 16, crc_out);
      crc_out = crc32 (runtime.debug.size - 1, 16, crc_out);
 
 
 
      /* Reverse the bit fields */
 
      acc_type_r = reverse_bits (runtime.debug.acc_type,  4);
 
      addr_r     = reverse_bits (runtime.debug.addr,     32);
 
      len_r      = reverse_bits (runtime.debug.size - 1, 16);
 
    }
 
  else
 
    {
 
      fprintf (stderr, "Warning: JTAG READ_COMMAND finds no data\n");
 
 
 
      /* Compute the CRC */
 
      crc_out = crc32 (0,  4, crc_out);
 
      crc_out = crc32 (0, 32, crc_out);
 
      crc_out = crc32 (0, 16, crc_out);
 
 
 
      /* Empty data */
 
      acc_type_r = 0;
 
      addr_r     = 0;
 
      len_r      = 0;
 
    }
 
 
      /* Construct the outgoing register. Fields can only be written if they
      /* Construct the outgoing register. Fields can only be written if they
         are available */
         are available */
      uint8_t   acc_type_r = reverse_bits (runtime.debug.acc_type,  4);
 
      uint32_t  addr_r     = reverse_bits (runtime.debug.addr,     32);
 
      uint16_t  len_r      = reverse_bits (runtime.debug.size - 1, 16);
 
 
 
      jreg[ 4] |= (acc_type_r <<  5) & 0xf8;
      jreg[ 4] |= (acc_type_r <<  5) & 0xf8;
      jreg[ 5] |= (acc_type_r >>  3) & 0x07;
      jreg[ 5] |= (acc_type_r >>  3) & 0x07;
      jreg[ 5] |= (addr_r     <<  1) & 0xfe;
      jreg[ 5] |= (addr_r     <<  1) & 0xfe;
      jreg[ 6] |= (addr_r     >>  7) & 0xff;
      jreg[ 6] |= (addr_r     >>  7) & 0xff;
      jreg[ 7] |= (addr_r     >> 15) & 0xff;
      jreg[ 7] |= (addr_r     >> 15) & 0xff;
      jreg[ 8] |= (addr_r     >> 23) & 0xff;
      jreg[ 8] |= (addr_r     >> 23) & 0xff;
      jreg[ 9] |= (addr_r     >> 31) & 0x01;
      jreg[ 9] |= (addr_r     >> 31) & 0x01;
      jreg[ 9] |= (len_r      <<  1) & 0xfe;
      jreg[ 9] |= (len_r      <<  1) & 0xfe;
      jreg[10] |= (len_r      >>  7) & 0xff;
      jreg[10] |= (len_r      >>  7) & 0xff;
      jreg[11] |= (len_r      >> 15) & 0x01;
      jreg[11] |= (len_r      >> 15) & 0x01;
    }
 
  else
 
    {
 
      fprintf (stderr, "Warning: JTAG attempt to READ_COMMAND without prior "
 
               "WRITE_COMMAND: no data returned\n");
 
    }
 
 
 
  /* Construct the final response with the status, skipping the fields we've
  /* Construct the final response with the status, skipping the fields we've
     just (possibly) written. */
     just (possibly) written. */
  return  construct_response (jreg, status, crc_out, 52, 37);
  return  construct_response (jreg, status, crc_out, 52, 37);
 
 
Line 1203... Line 1243...
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static int
static int
write_command (unsigned char *jreg)
write_command (unsigned char *jreg)
{
{
  /* Break out the fields */
  /* Break out the fields */
  uint8_t   acc_type = reverse_bits (((jreg[0] & 0x0e) >> 5) |
  uint8_t   acc_type = reverse_bits (((jreg[0] & 0xe0) >> 5) |
                                      (jreg[1] & 0x01), 4);
                                     ((jreg[1] & 0x01) << 3) , 4);
  uint32_t  addr     = reverse_bits (((uint32_t) (jreg[ 1] & 0xfe) >>  1) |
  uint32_t  addr     = reverse_bits (((uint32_t) (jreg[ 1] & 0xfe) >>  1) |
                                     ((uint32_t)  jreg[ 2]         <<  7) |
                                     ((uint32_t)  jreg[ 2]         <<  7) |
                                     ((uint32_t)  jreg[ 3]         << 15) |
                                     ((uint32_t)  jreg[ 3]         << 15) |
                                     ((uint32_t)  jreg[ 4]         << 23) |
                                     ((uint32_t)  jreg[ 4]         << 23) |
                                     ((uint32_t) (jreg[ 5] & 0x01) << 31), 32);
                                     ((uint32_t) (jreg[ 5] & 0x01) << 31), 32);
Line 1540... Line 1580...
    case JI_BYPASS:
    case JI_BYPASS:
      fprintf (stderr, "Warning: JTAG BYPASS shifted\n");
      fprintf (stderr, "Warning: JTAG BYPASS shifted\n");
      break;
      break;
 
 
    default:
    default:
      fprintf (stderr, "Warning: Unknown JTAG instruction %04x shifted\n",
      fprintf (stderr, "Warning: Unknown JTAG instruction 0x%1x shifted\n",
               runtime.debug.instr);
               runtime.debug.instr);
      break;
      break;
    }
    }
 
 
  return  4;                    /* Register length */
  return  4;                    /* Register length */

powered by: WebSVN 2.1.0

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