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

Subversion Repositories openrisc

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

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

Rev 97 Rev 98
Line 121... Line 121...
  val = (((val & 0xf0f0f0f0f0f0f0f0ULL) >>  4) |
  val = (((val & 0xf0f0f0f0f0f0f0f0ULL) >>  4) |
         ((val & 0x0f0f0f0f0f0f0f0fULL) <<  4));
         ((val & 0x0f0f0f0f0f0f0f0fULL) <<  4));
  val = (((val & 0xff00ff00ff00ff00ULL) >>  8) |
  val = (((val & 0xff00ff00ff00ff00ULL) >>  8) |
         ((val & 0x00ff00ff00ff00ffULL) <<  8));
         ((val & 0x00ff00ff00ff00ffULL) <<  8));
  val = (((val & 0xffff0000ffff0000ULL) >> 16) |
  val = (((val & 0xffff0000ffff0000ULL) >> 16) |
         ((val & 0x00000fff0000ffffULL) << 16));
         ((val & 0x0000ffff0000ffffULL) << 16));
  val = ((val >> 32) | (val << 32));
  val = ((val >> 32) | (val << 32));
 
 
  return  val >> (64 - numBits);        /* Only the bits we want */
  return  val >> (64 - numBits);        /* Only the bits we want */
 
 
}       /* reverse_bits () */
}       /* reverse_bits () */
Line 173... Line 173...
 
 
   @param[out] jreg       The buffer for the constructed register
   @param[out] jreg       The buffer for the constructed register
   @param[in]  status     The status bits
   @param[in]  status     The status bits
   @param[in]  crc_in     CRC computed so far (set to 0xffffffff if none)
   @param[in]  crc_in     CRC computed so far (set to 0xffffffff if none)
   @param[in]  ign_bits   The number of bits to ignore
   @param[in]  ign_bits   The number of bits to ignore
   @param[in]  zero_bits  The number of bits to zero
   @param[in]  zero_bits  The number of bits to zero                         */
 
 
   @return  The register length in bits                                      */
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static int
static void
construct_response (unsigned char *jreg,
construct_response (unsigned char *jreg,
                    uint8_t        status,
                    uint8_t        status,
                    uint32_t       crc_in,
                    uint32_t       crc_in,
                    unsigned int   ign_bits,
                    unsigned int   ign_bits,
                    unsigned int   zero_bits)
                    unsigned int   zero_bits)
Line 240... Line 238...
      jreg[skip_bytes + 5]  =  (crc_out_r >> (36 - bit_off)) & 0xff;
      jreg[skip_bytes + 5]  =  (crc_out_r >> (36 - bit_off)) & 0xff;
    }
    }
  else
  else
    {
    {
      fprintf (stderr, "*** ABORT ***: construct_response: impossible bit "
      fprintf (stderr, "*** ABORT ***: construct_response: impossible bit "
               "offset: %u\n", bit_off);
               "offset: %u.\n", bit_off);
      abort ();
      abort ();
    }
    }
 
 
  /* Result is the register length in bits */
 
  return  32 + 4 + skip_bytes;
 
 
 
}       /* construct_response () */
}       /* construct_response () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Select a module for debug
/*!Select a module for debug
Line 277... Line 271...
 
 
 
 
   Fields are always shifted in MS bit first, so must be reversed. The CRC in
   Fields are always shifted in MS bit first, so must be reversed. The CRC in
   is computed on the first 5 bits, the CRC out on the 4 status bits.
   is computed on the first 5 bits, the CRC out on the 4 status bits.
 
 
 
   This is a register of a fixed size, which we verify initially.
 
 
   @param[in,out] jreg  The register to shift in, and the register shifted
   @param[in,out] jreg  The register to shift in, and the register shifted
                        back out.
                        back out.
 
   @param[in]     num_bits  The number of bits supplied.
 
 
   @return  The number of cycles the shift took, which in turn is the number
   @return  The number of cycles the shift took, which in turn is the number
            of bits in the register                                          */
            of bits in the register                                          */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static int
static void
module_select (unsigned char *jreg)
select_module (unsigned char *jreg,
 
               int            num_bits)
{
{
 
  /* Validate register size, which is fixed */
 
  const int  REG_BITS = 36 + 32 + 4 + 1;
 
 
 
  if (REG_BITS != num_bits)
 
    {
 
      fprintf (stderr,
 
               "ERROR: JTAG module select %d bits, when %d bits expected.\n",
 
              num_bits, REG_BITS);
 
      return;
 
    }
 
 
  /* 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) |
Line 304... Line 313...
 
 
  /* Status flags */
  /* Status flags */
  enum jtag_status  status = JS_OK;
  enum jtag_status  status = JS_OK;
 
 
  /* Validate the CRC */
  /* Validate the CRC */
  if (crc_computed != crc_in)
  if (crc_computed == crc_in)
    {
 
      /* Mismatch: record the error */
 
      status |= JS_CRC_IN_ERROR;
 
    }
 
  else
 
    {
    {
      /* Is it a valid module? */
      /* Is it a valid module? */
      switch (mod_id)
      switch (mod_id)
        {
        {
        case JM_WISHBONE:
        case JM_WISHBONE:
Line 323... Line 327...
          runtime.debug.mod_id = mod_id;
          runtime.debug.mod_id = mod_id;
 
 
          break;
          break;
 
 
        default:
        default:
          /* Bad module: record the error */
          /* Bad module: record the error. Set the module to JM_UNDEFINED,
 
             which will trigger more errors in the future, rather than
 
             leaving the module unchanged, which might allow such errors to
 
             slip by undetected. */
          status |= JS_MODULE_MISSING;
          status |= JS_MODULE_MISSING;
 
          runtime.debug.mod_id = JM_UNDEFINED;
          break;
          break;
        }
        }
    }
    }
 
  else
 
    {
 
      /* CRC Mismatch: record the error */
 
      status |= JS_CRC_IN_ERROR;
 
    }
 
 
  /* Construct the outgoing register and return the JTAG cycles taken (the
  /* Construct the outgoing register and return the JTAG cycles taken (the
     register length) */
     register length) */
  return  construct_response (jreg, status, 0xffffffff, 0, 37);
  return  construct_response (jreg, status, 0xffffffff, 0, 37);
 
 
}       /* module_select */
}       /* select_module */
 
 
 
 
/*---------------------------------------------------------------------------*/
 
/*!Validate WRITE_COMMAND fields for WishBone
 
 
 
   Check that a WRITE_COMMAND's fields are valid for WishBone access.
 
 
 
   - 16 and 32-bit access must be correctly aligned. If not a warning is
 
     printed and validation fails.
 
 
 
   - size must be a multiple of 2 for 16-bit access, and a multiple of 4 for
 
     32-bit access
 
 
 
   Validation is carried out when executing a GO_COMMAND, rather than when
 
   setting the WRITE_COMMAND, because only the GO_COMMAND can set the status
 
   error if there is a problem.
 
 
 
   Warning messages are printed to explain any validation problems.
 
 
 
   @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
 
         original WRITE_COMMAND.
 
 
 
   @return  1 (TRUE) if validation is OK, 0 (FALSE) if validation fails.     */
 
/*---------------------------------------------------------------------------*/
 
static int
 
validate_wb_fields ()
 
{
 
  /* Determine the size of the access */
 
  uint32_t  access_bits;
 
 
 
  switch (runtime.debug.acc_type)
 
    {
 
    case JAT_WRITE8:
 
    case JAT_READ8:
 
      access_bits =  8;
 
      break;
 
 
 
    case JAT_WRITE16:
 
    case JAT_READ16:
 
      access_bits = 16;
 
      break;
 
 
 
    case JAT_WRITE32:
 
    case JAT_READ32:
 
      access_bits = 32;
 
      break;
 
 
 
    default:
 
      fprintf (stderr, "Warning: validate_wb_fields: unknown access "
 
               "type %u\n", runtime.debug.acc_type);
 
      return  0;
 
    }
 
 
 
  /* Check for validity. This works for 8-bit, although the tests will always
 
     pass. */
 
  uint32_t  access_bytes = access_bits / 8;
 
 
 
  if (0 != (runtime.debug.addr % access_bytes))
 
    {
 
      fprintf (stderr, "Warning: JTAG WishBone %d-bit access must be %d-byte "
 
               "aligned\n", access_bits, access_bytes);
 
      return  0;
 
    }
 
  else if (0 != (runtime.debug.size % access_bytes))
 
    {
 
      fprintf (stderr, "Warning: JTAG %d-bit WishBone access must be multiple "
 
               "of %d bytes in length\n", access_bits, access_bytes);
 
      return  0;
 
    }
 
  else
 
    {
 
      return  1;                        /* No problems */
 
    }
 
}       /* validate_wb_fields () */
 
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Read WishBone data
/*!Read WishBone data
 
 
   Read memory from WishBone. The WRITE_COMMAND address is updated to reflect
   Read memory from WishBone. The WRITE_COMMAND address is updated to reflect
   the completed read if successful.
   the completed read if successful.
 
 
 
   The data follows an initial 37 bits corresponding to the incoming command
 
   and CRC. We use the smaller of the data size in the original WRITE_COMMAND
 
   and the size of the data in the GO_COMMAND_WRITE packet, so we can handle
 
   over/under-run.
 
 
   The result is the CRC of the data read. The status flag is supplied as a
   The result is the CRC of the data read. The status flag is supplied as a
   pointer, since this can also be updated if there is a problem reading the
   pointer, since this can also be updated if there is a problem reading the
   data.
   data.
 
 
   @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
Line 434... Line 376...
          register is inefficient. We should instead clear the whole area
          register is inefficient. We should instead clear the whole area
          before starting.
          before starting.
 
 
   @param[out] jreg        The JTAG register buffer where data is to be
   @param[out] jreg        The JTAG register buffer where data is to be
                           stored.
                           stored.
   @param[in]  skip_bits   Bits to skip before storing data in jreg.
   @param[in]  jreg_bytes   The number of bytes expected in the JTAG register
 
                           (may be different to that in the prior READ/WRITE
 
                           if we have over- or under-run).
   @param[in]  status_ptr  Pointer to the status register.
   @param[in]  status_ptr  Pointer to the status register.
 
 
   @return  The CRC of the data read                                         */
   @return  The CRC of the data read                                         */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static uint32_t
static uint32_t
wishbone_read (unsigned char    *jreg,
wishbone_read (unsigned char    *jreg,
               unsigned int      skip_bits,
               unsigned long int  jreg_bytes,
               enum jtag_status *status_ptr)
               enum jtag_status *status_ptr)
{
{
  /* Compute the CRC as we go */
  const unsigned int  BIT_OFF  = 37 % 8;        /* Skip initial fields */
 
  const unsigned int  BYTE_OFF = 37 / 8;
 
 
 
  /* Transfer each byte in turn, computing the CRC as we go. We must supply
 
     jreg_bytes. If there is overrun, we use zero for the remaining bytes. */
  uint32_t  crc_out  = 0xffffffff;
  uint32_t  crc_out  = 0xffffffff;
 
  unsigned long int  i;
 
 
  /* Validate the fields for the wishbone read. If this fails we stop here,
  for (i = 0; i < jreg_bytes; i++)
     setting an error in the status_ptr. */
 
  if (!validate_wb_fields())
 
    {
    {
      *status_ptr |= JS_WISHBONE_ERROR;
      unsigned char  byte = 0;
      return  crc_out;
 
    }
 
 
 
  /* Transfer each byte in turn, computing the CRC as we go */
 
  unsigned  byte_off = skip_bits / 8;
 
  unsigned  bit_off  = skip_bits % 8;
 
 
 
  uint32_t  i;                          /* Index into the data being read */
      /* Get a byte if available */
 
      if (i < runtime.debug.size)
  for (i = 0; i < runtime.debug.size; i++)
 
    {
    {
      /* Error if we can't access this byte */
      /* Error if we can't access this byte */
      if (NULL == verify_memoryarea (runtime.debug.addr + i))
      if (NULL == verify_memoryarea (runtime.debug.addr + i))
        {
        {
          *status_ptr |= JS_WISHBONE_ERROR;
          *status_ptr |= JS_WISHBONE_ERROR;
          return  crc_out;
            }
 
          else
 
            {
 
              /* Get the data with no cache or VM translation */
 
              byte = eval_direct8 (runtime.debug.addr + i, 0, 0);
 
            }
        }
        }
 
 
      /* Get the data with no cache or VM translation and update the CRC */
      /* Update the CRC, reverse, then store the byte in the register, without
      unsigned char  byte = eval_direct8 (runtime.debug.addr + i, 0, 0);
         trampling adjacent bits. Simplified version when the bit offset is
 
         zero. */
      crc_out = crc32 (byte, 8, crc_out);
      crc_out = crc32 (byte, 8, crc_out);
 
 
      /* Reverse, then store the byte in the register, without trampling
 
         adjacent bits. Simplified version when the bit offset is zero. */
 
      byte = reverse_byte (byte);
      byte = reverse_byte (byte);
 
 
      if (0 == bit_off)
 
        {
 
          jreg[byte_off + i] = byte;
 
        }
 
      else
 
        {
 
          /* Clear the bits (only) we are setting */
          /* Clear the bits (only) we are setting */
          jreg[byte_off + i]     <<= bit_off;
      jreg[BYTE_OFF + i]     <<= 8 - BIT_OFF;
          jreg[byte_off + i]     >>= bit_off;
      jreg[BYTE_OFF + i]     >>= 8 - BIT_OFF;
          jreg[byte_off + i + 1] >>= 8 - bit_off;
      jreg[BYTE_OFF + i + 1] >>= BIT_OFF;
          jreg[byte_off + i + 1] <<= 8 - bit_off;
      jreg[BYTE_OFF + i + 1] <<= BIT_OFF;
 
 
          /* OR in the bits */
          /* OR in the bits */
          jreg[byte_off + i]     |= (byte <<      bit_off)  & 0xff;
      jreg[BYTE_OFF + i]     |= (byte <<      BIT_OFF)  & 0xff;
          jreg[byte_off + i + 1] |= (byte >> (8 - bit_off)) & 0xff;
      jreg[BYTE_OFF + i + 1] |= (byte >> (8 - BIT_OFF)) & 0xff;
        }
 
    }
    }
 
 
 
  /* Only advance if there we no errors (including over/under-run. */
 
  if (JS_OK == *status_ptr)
 
    {
    runtime.debug.addr += runtime.debug.size;
    runtime.debug.addr += runtime.debug.size;
 
    }
 
 
  return  crc_out;
  return  crc_out;
 
 
}       /* wishbone_read () */
}       /* wishbone_read () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Validate WRITE_COMMAND fields for SPR
 
 
 
   Check that a WRITE_COMMAND's fields are valid for SPR access. Only prints
 
   messages, since the protocol does not allow for any errors.
 
 
 
   - 8 and 16-bit access is only permitted for WishBone. If they are specified
 
     for SPR, they are treated as their 32 bit equivalent. A warning is
 
     printed.
 
 
 
   - size must be 1 word. If a larger value is specified that is treated as 1
 
     with a warning.
 
 
 
   - address must be less than MAX_SPRS. If a larger value is specified, it is
 
     reduced module MAX_SPRS (which is hopefully a power of 2).
 
 
 
   Where errors are found, the data is updated.
 
 
 
   Validation is carried out with the GO_COMMAND, rather than with the
 
   WRITE_COMMAND, for consistency with WishBone error checking, for which
 
   only the GO_COMMAND can set the status error if there is a problem.
 
 
 
   Warning messages are printed to explain any validation problems.
 
 
 
   @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
 
         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 int
 
validate_spr_fields ()
 
{
 
  int  access_bits;
 
  int  is_read_p;
 
 
 
  switch (runtime.debug.acc_type)
 
    {
 
    case JAT_WRITE8:  access_bits =  8; is_read_p = 0; break;
 
    case JAT_READ8:   access_bits =  8; is_read_p = 1; break;
 
    case JAT_WRITE16: access_bits = 16; is_read_p = 0; break;
 
    case JAT_READ16:  access_bits = 16; is_read_p = 1; break;
 
    case JAT_WRITE32: access_bits = 32; is_read_p = 0; break;
 
    case JAT_READ32:  access_bits = 32; is_read_p = 1; break;
 
 
 
    default:
 
      fprintf (stderr, "Warning: validate_spr_fields: unknown access "
 
               "type %u\n", runtime.debug.acc_type);
 
      return  0;
 
    }
 
 
 
  /* Validate and correct if necessary access width */
 
  if (32 != access_bits)
 
    {
 
      fprintf (stderr, "Warning: JTAG %d-bit access not permitted for SPR: "
 
               "corrected\n", access_bits);
 
      runtime.debug.acc_type = is_read_p ? JAT_READ32 : JAT_WRITE32;
 
    }
 
 
 
  /* Validate and correct if necessary access size */
 
  if (1 != runtime.debug.size)
 
    {
 
      fprintf (stderr, "Warning: JTAG SPR access must be 1 word in length: "
 
               "corrected\n");
 
      runtime.debug.size = 1;
 
    }
 
 
 
  /* Validate and correct if necessary access size */
 
  if (runtime.debug.addr >= MAX_SPRS)
 
    {
 
      fprintf (stderr, "Warning: JTAG SPR address exceeds MAX_SPRS: "
 
               "truncated\n");
 
      runtime.debug.addr %= MAX_SPRS;
 
    }
 
 
 
  return  0;                     /* Success */
 
 
 
}       /* validate_spr_fields () */
 
 
 
 
 
/*---------------------------------------------------------------------------*/
 
/*!Read SPR data
/*!Read SPR data
 
 
   Read memory from WishBone. The WRITE_COMMAND address is updated to reflect
   Read memory from a SPR. The WRITE_COMMAND address is updated to reflect the
   the completed read if successful.
   completed read if successful.
 
 
 
   The data follows an initial 37 bits corresponding to the incoming command
 
   and CRC. We use the smaller of the data size in the original WRITE_COMMAND
 
   and the size of the data in the GO_COMMAND_WRITE packet, so we can handle
 
   over/under-run.
 
 
   The result is the CRC of the data read.
   The result is the CRC of the data read.
 
 
   Unlike with Wishbone, there is no concept of any errors possible when
   Unlike with Wishbone, there is no concept of any errors possible when
   reading an SPR.
   reading an SPR.
Line 608... Line 471...
         that seems to be a poor basis for modeling, and more to do with the
         that seems to be a poor basis for modeling, and more to do with the
         debug unit only ever being used with big-endian architectures. We
         debug unit only ever being used with big-endian architectures. We
         transfer the bytes in the endianness of the OR1K.
         transfer the bytes in the endianness of the OR1K.
 
 
   @param[out] jreg       The JTAG register buffer where data is to be stored.
   @param[out] jreg       The JTAG register buffer where data is to be stored.
   @param[in]  skip_bits  Bits to skip before storing data in jreg.
   @param[in]  jreg_bytes   The number of bytes expected in the JTAG register
 
                           (may be different to that in the prior READ/WRITE
 
                           if we have over- or under-run).
 
   @param[in]  status_ptr  Pointer to the status register.
 
 
   @return  The CRC of the data read                                         */
   @return  The CRC of the data read                                         */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static uint32_t
static uint32_t
spr_read (unsigned char *jreg,
spr_read (unsigned char *jreg,
          unsigned int   skip_bits)
          unsigned long int  jreg_bytes,
{
          enum jtag_status  *status_ptr)
  /* Compute the CRC as we go */
 
  uint32_t  crc_out  = 0xffffffff;
 
 
 
  /* Validate the fields for the SPR read. This mostly just prints
 
     out warnings and corrects the problems. However if the access type
 
     cannot be worked out, we must use empty data. */
 
  uint32_t  spr;
 
 
 
  if (validate_spr_fields())
 
    {
 
      /* Transfer the SPR */
 
      spr = mfspr (runtime.debug.addr);
 
    }
 
  else
 
    {
    {
      spr = 0;
  const unsigned int  BIT_OFF  = 37 % 8;        /* Skip initial fields */
    }
  const unsigned int  BYTE_OFF = 37 / 8;
 
 
  runtime.debug.addr++;
 
 
 
  /* Store the SPR in the register, without trampling adjacent
  /* Store the SPR in the register, without trampling adjacent bits, computing
     bits. Simplified version when the bit offset is zero. Compute the CRC as
     the CRC as we go. We have to fill all the JTAG register bytes. If there
     we go. */
     is overrun, we pack in zeros. */
  unsigned  byte_off = skip_bits / 8;
  uint32_t           spr      = mfspr (runtime.debug.addr);
  unsigned  bit_off  = skip_bits % 8;
  uint32_t           crc_out  = 0xffffffff;
 
  unsigned long int  i;
 
 
  if (0 == bit_off)
  for (i = 0; i < jreg_bytes; i++)
    {
    {
      /* Each byte in turn */
      unsigned char  byte = 0;
      int  i;
 
 
 
      for (i = 0; i < 4; i++)
      /* Get the byte from the SPR if available, otherwise use zero */
 
      if (i < 4)
        {
        {
#ifdef OR32_BIG_ENDIAN
#ifdef OR32_BIG_ENDIAN
          uint8_t byte = (spr >> 8 * i) & 0xff;
          byte = (spr >> 8 * i) & 0xff;
#else /* !OR32_BIG_ENDIAN */
#else /* !OR32_BIG_ENDIAN */
          uint8_t byte = (spr >> (24 - (8 * i))) & 0xff;
          byte = (spr >> (24 - (8 * i))) & 0xff;
#endif /* OR32_BIG_ENDIAN */
#endif /* OR32_BIG_ENDIAN */
 
        }
 
 
          jreg[byte_off + i] =  byte;
      /* Update the CRC */
          crc_out = crc32 (byte, 8, crc_out);
          crc_out = crc32 (byte, 8, crc_out);
        }
 
    }
 
  else
 
    {
 
      /* Each byte in turn */
 
      int  i;
 
 
 
      for (i = 0; i < 4; i++)
      /* Reverse, then store the byte in the register, without trampling
        {
         adjacent bits. */
#ifdef OR32_BIG_ENDIAN
      byte = reverse_byte (byte);
          uint8_t byte = (spr >> 8 * i) & 0xff;
 
#else /* !OR32_BIG_ENDIAN */
 
          uint8_t byte = (spr >> (24 - (8 * i))) & 0xff;
 
#endif /* OR32_BIG_ENDIAN */
 
 
 
          /* Clear the bits (only) we are setting */
          /* Clear the bits (only) we are setting */
          jreg[byte_off + i]     <<= bit_off;
      jreg[BYTE_OFF + i]     <<= 8 - BIT_OFF;
          jreg[byte_off + i]     >>= bit_off;
      jreg[BYTE_OFF + i]     >>= 8 - BIT_OFF;
          jreg[byte_off + i + 1] >>= 8 - bit_off;
      jreg[BYTE_OFF + i + 1] >>= BIT_OFF;
          jreg[byte_off + i + 1] <<= 8 - bit_off;
      jreg[BYTE_OFF + i + 1] <<= BIT_OFF;
 
 
          /* OR in the bits */
          /* OR in the bits */
          jreg[byte_off + i]     |= (byte <<      bit_off)  & 0xff;
      jreg[BYTE_OFF + i]     |= (byte <<      BIT_OFF)  & 0xff;
          jreg[byte_off + i + 1] |= (byte >> (8 - bit_off)) & 0xff;
      jreg[BYTE_OFF + i + 1] |= (byte >> (8 - BIT_OFF)) & 0xff;
 
 
          crc_out = crc32 (byte, 8, crc_out);
 
        }
        }
 
 
 
  /* Only advance if there we no errors (including over/under-run). */
 
  if (JS_OK == *status_ptr)
 
    {
 
      runtime.debug.addr++;
    }
    }
 
 
  return  crc_out;
  return  crc_out;
 
 
}       /* spr_read () */
}       /* spr_read () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
 
/*!Set up null data.
 
 
 
   When there is an error in GO_COMMAND_READ, the data fields must be
 
   populated and the CRC set up, to ensure a correct return.
 
 
 
   The data follows an initial 37 bits corresponding to the incoming command
 
   and CRC. We use the smaller of the data size in the original WRITE_COMMAND
 
   and the size of the data in the GO_COMMAND_WRITE packet, so we can handle
 
   over/under-run.
 
 
 
   @param[out] jreg       The JTAG register buffer where data is to be stored.
 
   @param[in]  jreg_bytes   The number of bytes expected in the JTAG register
 
                           (may be different to that in the prior READ/WRITE
 
                           if we have over- or under-run).
 
 
 
   @return  The CRC of the data read                                         */
 
/*---------------------------------------------------------------------------*/
 
static uint32_t
 
null_read (unsigned char     *jreg,
 
           unsigned long int  jreg_bytes)
 
{
 
  const unsigned int  BIT_OFF  = 37 % 8;        /* Skip initial fields */
 
  const unsigned int  BYTE_OFF = 37 / 8;
 
 
 
  /* Store each null byte in turn, computing the CRC as we go */
 
  uint32_t           crc_out  = 0xffffffff;
 
  unsigned long int  i;
 
 
 
  for (i = 0; i < jreg_bytes; i++)
 
    {
 
      crc_out = crc32 (0, 8, crc_out);   /* Compute the CRC for null byte */
 
 
 
      /* Store null byte in the register, without trampling adjacent
 
         bits. */
 
      jreg[BYTE_OFF + i]     <<= 8 - BIT_OFF;
 
      jreg[BYTE_OFF + i]     >>= 8 - BIT_OFF;
 
      jreg[BYTE_OFF + i + 1] >>= BIT_OFF;
 
      jreg[BYTE_OFF + i + 1] <<= BIT_OFF;
 
    }
 
 
 
  return  crc_out;
 
 
 
}       /* null_read () */
 
 
 
 
 
/*---------------------------------------------------------------------------*/
/*!Carry out a read from WishBone or SPR
/*!Carry out a read from WishBone or SPR
 
 
   Process a GO_COMMAND register for read. The format is:
   Process a GO_COMMAND register for read. The format is:
 
 
          +-------------+-------+---------+---+
          +-------------+-------+---------+---+
Line 723... Line 614...
   @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.
 
 
   @param[in,out] jreg  The register to shift in, and the register shifted
   @param[in,out] jreg  The register to shift in, and the register shifted
                        back out.
                        back out.
 
   @param[in]     num_bits  The number of bits supplied.                     */
   @return  The number of cycles the shift took, which in turn is the number
 
            of bits in the register                                          */
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static int
static void
go_command_read (unsigned char *jreg)
go_command_read (unsigned char *jreg,
 
                 int            num_bits)
{
{
 
  /* Check the length is consistent with the prior WRITE_COMMAND. If not we
 
     have overrun or underrun and flag accordingly. */
 
  const int          REG_BITS = 36 + 8 * runtime.debug.size + 32 + 4 + 1;
 
  unsigned long int  jreg_bytes;
 
  enum jtag_status   status;
 
 
 
  if (REG_BITS == num_bits)
 
    {
 
      jreg_bytes = runtime.debug.size;
 
      status    = JS_OK;
 
    }
 
  else
 
    {
 
      /* Size will round down for safety */
 
      jreg_bytes = (runtime.debug.size * 8 + num_bits - REG_BITS) / 8;
 
      status    = JS_OVER_UNDERRUN;
 
    }
 
 
  /* Break out the fields */
  /* Break out the fields */
  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) |
Line 743... Line 651...
  uint32_t  crc_computed;
  uint32_t  crc_computed;
 
 
  crc_computed = crc32 (0,                1, 0xffffffff);
  crc_computed = crc32 (0,                1, 0xffffffff);
  crc_computed = crc32 (JCMD_GO_COMMAND,  4, crc_computed);
  crc_computed = crc32 (JCMD_GO_COMMAND,  4, crc_computed);
 
 
  /* Status flags */
 
  enum jtag_status  status = JS_OK;
 
 
 
  /* CRC to go out */
  /* CRC to go out */
  uint32_t  crc_out = 0;
  uint32_t  crc_out = 0;
 
 
  /* Validate the CRC */
  /* Validate the CRC */
  if (crc_computed == crc_in)
  if (crc_computed == crc_in)
    {
    {
      /* Read the data. */
      /* Read the data. Module errors will have been detected earlier, so we
 
         do nothing more here. */
      switch (runtime.debug.mod_id)
      switch (runtime.debug.mod_id)
        {
        {
        case JM_WISHBONE:
        case JM_WISHBONE:
          crc_out = wishbone_read (jreg, 37, &status);
          crc_out = wishbone_read (jreg, jreg_bytes, &status);
          break;
          break;
 
 
        case JM_CPU0:
        case JM_CPU0:
          crc_out = spr_read (jreg, 37);
          crc_out = spr_read (jreg, jreg_bytes, &status);
          break;
 
 
 
        case JM_CPU1:
 
          fprintf (stderr, "Warning: JTAG attempt to read from CPU1: Not "
 
                   "supported.\n");
 
          break;
          break;
 
 
        default:
        default:
          fprintf (stderr, "Warning: go_command_read: invalid module 0x%lx\n",
          crc_out = null_read (jreg, jreg_bytes);
                   runtime.debug.mod_id);
 
          break;
          break;
        }
        }
    }
    }
  else
  else
    {
    {
Line 782... Line 682...
      status |= JS_CRC_IN_ERROR;
      status |= JS_CRC_IN_ERROR;
    }
    }
 
 
  /* Construct the outgoing register, skipping the data read and returning the
  /* Construct the outgoing register, skipping the data read and returning the
     number of JTAG cycles taken (the register length). */
     number of JTAG cycles taken (the register length). */
  return  construct_response (jreg, status, crc_out, 8 * runtime.debug.size,
  construct_response (jreg, status, crc_out, 8UL * jreg_bytes, 37);
                              37);
 
 
 
}       /* go_command_read () */
}       /* go_command_read () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Write WishBone data
/*!Write WishBone data
 
 
   Write memory to WishBone. The WRITE_COMMAND address is updated to reflect
   Write memory to WishBone. The WRITE_COMMAND address is updated to reflect
   the completed write if successful.
   the completed write if successful.
 
 
 
   The data follows an initial 5 bits specifying the command. We use the
 
   smaller of the data size in the original WRITE_COMMAND and the size of the
 
   data in the GO_COMMAND_WRITE packet, so we can handle over/under-run.
 
 
   @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.
 
 
   @todo For now we always write a byte a time. In the future, we ought to use
   @todo For now we always write a byte a time. In the future, we ought to use
         16 and 32-bit accesses for greater efficiency.
         16 and 32-bit accesses for greater efficiency and to correctly model
 
         the use of different access types.
   @todo  The algorithm for ensuring we only set the bits of interest in the
 
          register is inefficient. We should instead clear the whole area
 
          before starting.
 
 
 
   @param[out] jreg        The JTAG register buffer where data is to be
   @param[in]  jreg        The JTAG register buffer where data is found.
                           stored.
   @param[in]  jreg_bytes   The number of bytes expected in the JTAG register
   @param[in]  skip_bits   Bits to skip before reading data from jreg.
                           (may be different to that in the prior READ/WRITE
   @param[in]  status_ptr  Pointer to the status register.                   */
                           if we have over- or under-run).
 
   @param[out] status_ptr  Pointer to the status register.                   */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static void
static void
wishbone_write (unsigned char   *jreg,
wishbone_write (unsigned char   *jreg,
               unsigned int      skip_bits,
                unsigned long int  jreg_bytes,
               enum jtag_status *status_ptr)
               enum jtag_status *status_ptr)
{
{
  /* Validate the fields for the wishbone write. If this fails we stop here,
  const unsigned int  BIT_OFF  = 5;     /* Skip initial command */
     setting an error in the status_ptr. */
 
  if (!validate_wb_fields())
 
    {
 
      *status_ptr |= JS_WISHBONE_ERROR;
 
      return;
 
    }
 
 
 
  /* Transfer each byte in turn, computing the CRC as we go */
 
  unsigned  byte_off = skip_bits / 8;
 
  unsigned  bit_off  = skip_bits % 8;
 
 
 
  uint32_t  i;                          /* Index into the data being write */
  /* Transfer each byte in turn, computing the CRC as we go. We must supply
 
     jreg_bytes. If there is overrun, we ignore the remaining bytes. */
 
  unsigned long int  i;
 
 
  for (i = 0; i < runtime.debug.size; i++)
  for (i = 0; i < jreg_bytes; i++)
 
    {
 
      /* Set a byte if available */
 
      if (i < runtime.debug.size)
    {
    {
      /* Error if we can't access this byte */
      /* Error if we can't access this byte */
      if (NULL == verify_memoryarea (runtime.debug.addr + i))
      if (NULL == verify_memoryarea (runtime.debug.addr + i))
        {
        {
          *status_ptr |= JS_WISHBONE_ERROR;
          *status_ptr |= JS_WISHBONE_ERROR;
          return;
 
        }
        }
 
          else
      /* Extract the byte from the register. Simplified version when the bit
            {
         offset is zero. */
              /* Extract the byte from the register, reverse it and write it,
 
                 circumventing the usual checks by pretending this is program
 
                 memory. */
      unsigned char  byte;
      unsigned char  byte;
 
 
      if (0 == bit_off)
              byte = (jreg[i] >> BIT_OFF) | (jreg[i + 1] << (8 - BIT_OFF));
        {
              byte = reverse_byte (byte);
          byte = jreg[byte_off + i];
 
 
              set_program8 (runtime.debug.addr + i, byte);
        }
        }
      else
 
        {
 
          byte = jreg[byte_off + i]     >>      bit_off  |
 
                 jreg[byte_off + i + 1] << (8 - bit_off);
 
        }
        }
 
 
      /* Circumvent the read-only check usually done for mem accesses. */
 
      set_program8 (runtime.debug.addr + i, reverse_byte (byte));
 
    }
    }
 
 
 
  if (JS_OK == *status_ptr)
 
    {
  runtime.debug.addr += runtime.debug.size;
  runtime.debug.addr += runtime.debug.size;
 
    }
}       /* wishbone_write () */
}       /* wishbone_write () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Write SPR data
/*!Write SPR data
 
 
   Write memory to WishBone. The WRITE_COMMAND address is updated to reflect
   Write memory to WishBone. The WRITE_COMMAND address is updated to reflect
   the completed write if successful.
   the completed write if successful.
 
 
 
   The data follows an initial 5 bits specifying the command. We use the
 
   smaller of the data size in the original WRITE_COMMAND and the size of the
 
   data in the GO_COMMAND_WRITE packet, so we can handle over/under-run.
 
 
   Unlike with Wishbone, there is no concept of any errors possible when
   Unlike with Wishbone, there is no concept of any errors possible when
   writeing an SPR.
   writing an SPR.
 
 
   @todo The algorithm for ensuring we only set the bits of interest in the
   @todo The algorithm for ensuring we only set the bits of interest in the
         register is inefficient. We should instead clear the whole area
         register is inefficient. We should instead clear the whole area
         before starting.
         before starting.
 
 
Line 881... Line 778...
         that seems to be a poor basis for modeling, and more to do with the
         that seems to be a poor basis for modeling, and more to do with the
         debug unit only ever being used with big-endian architectures. We
         debug unit only ever being used with big-endian architectures. We
         transfer the bytes in the endianness of the OR1K.
         transfer the bytes in the endianness of the OR1K.
 
 
   @param[out] jreg       The JTAG register buffer where data is to be stored.
   @param[out] jreg       The JTAG register buffer where data is to be stored.
   @param[in]  skip_bits  Bits to skip before reading data from jreg.        */
   @param[in]  jreg_bytes   The number of bytes expected in the JTAG register
 
                           (may be different to that in the prior READ/WRITE
 
                           if we have over- or under-run).
 
   @param[out] status_ptr  Pointer to the status register.                   */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static void
static void
spr_write (unsigned char *jreg,
spr_write (unsigned char *jreg,
          unsigned int   skip_bits)
           unsigned long int  jreg_bytes,
{
           enum jtag_status  *status_ptr)
  /* Validate the fields for the SPR write. This doesn't stop us most of the
 
     time, just prints out warnings and corrects the problems. However if we
 
     don't know the access type, then it will fail and we do nothing. */
 
  if (!validate_spr_fields ())
 
    {
    {
      return;
  const unsigned int  BIT_OFF  = 5;     /* Skip initial command */
    }
 
 
 
  /* Construct the SPR value one byte at a time. */
  /* Construct the SPR value one byte at a time. If there is overrun, ignore
 
     the excess bytes. */
  uint32_t  spr = 0;
  uint32_t  spr = 0;
 
  unsigned long int  i;
 
 
  unsigned  byte_off = skip_bits / 8;
  for (i = 0; i < jreg_bytes; i++)
  unsigned  bit_off  = skip_bits % 8;
    {
 
      if (i < 4)
  /* Each byte in turn */
 
  int  i;
 
 
 
  for (i = 0; i < 4; i++)
 
    {
    {
      uint8_t byte;
      uint8_t byte;
 
 
      /* Simplified version when the bit offset is zero */
          byte = (jreg[i] >> BIT_OFF) | (jreg[i + 1] << (8 - BIT_OFF));
      if (0 == bit_off)
          byte = reverse_byte (byte);
        {
 
          byte = reverse_byte (jreg[byte_off + i]);
 
        }
 
      else
 
        {
 
          byte = reverse_byte ((jreg[byte_off + i]     >>      bit_off) |
 
                               (jreg[byte_off + i + 1] << (8 - bit_off)));
 
        }
 
 
 
#ifdef OR32_BIG_ENDIAN
#ifdef OR32_BIG_ENDIAN
      spr |= ((uint32_t) (byte)) << (8 * i);
      spr |= ((uint32_t) (byte)) << (8 * i);
#else /* !OR32_BIG_ENDIAN */
#else /* !OR32_BIG_ENDIAN */
      spr |= ((uint32_t) (byte)) << (24 - (8 * i));
      spr |= ((uint32_t) (byte)) << (24 - (8 * i));
#endif /* OR32_BIG_ENDIAN */
#endif /* OR32_BIG_ENDIAN */
    }
    }
 
    }
 
 
  /* Transfer the SPR */
  /* Transfer the SPR */
  mtspr (runtime.debug.addr, spr);
  mtspr (runtime.debug.addr, spr);
  runtime.debug.addr++;
 
 
 
 
  /* Only advance if there we no errors (including over/under-run). */
 
  if (JS_OK == *status_ptr)
 
    {
 
      runtime.debug.addr++;
 
    }
}       /* spr_write () */
}       /* spr_write () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Carry out a write to WishBone or SPR
/*!Carry out a write to WishBone or SPR
Line 969... Line 859...
         here. However it would be better to do that at WRITE_COMMAND time and
         here. However it would be better to do that at WRITE_COMMAND time and
         save the result for here, to avoid using duff data.
         save the result for here, to avoid using duff data.
 
 
   @param[in,out] jreg  The register to shift in, and the register shifted
   @param[in,out] jreg  The register to shift in, and the register shifted
                        back out.
                        back out.
 
   @param[in]     num_bits  The number of bits supplied.                     */
   @return  The number of cycles the shift took, which in turn is the number
 
            of bits in the register                                          */
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static int
static void
go_command_write (unsigned char *jreg)
go_command_write (unsigned char *jreg,
 
                  int            num_bits)
{
{
 
  /* Check the length is consistent with the prior WRITE_COMMAND. If not we
 
     have overrun or underrun and flag accordingly. */
 
  const int          REG_BITS = 36 + 32 + 8 * runtime.debug.size + 4 + 1;
 
  unsigned long int  real_size;
 
  enum jtag_status   status;
 
 
 
  if (REG_BITS == num_bits)
 
    {
 
      real_size = runtime.debug.size;
 
      status    = JS_OK;
 
    }
 
  else
 
    {
 
      /* Size will round down for safety */
 
      real_size = (runtime.debug.size * 8UL + num_bits - REG_BITS) / 8UL;
 
      status    = JS_OVER_UNDERRUN;
 
    }
 
 
  /* Break out the fields */
  /* Break out the fields */
  uint32_t  crc_in =
  uint32_t  crc_in =
    reverse_bits (((uint32_t) (jreg[runtime.debug.size + 0] & 0xe0) >>  5) |
    reverse_bits (((uint32_t) (jreg[real_size + 0] & 0xe0) >>  5) |
                  ((uint32_t)  jreg[runtime.debug.size + 1]         <<  3) |
                  ((uint32_t)  jreg[real_size + 1]         <<  3) |
                  ((uint32_t)  jreg[runtime.debug.size + 2]         << 11) |
                  ((uint32_t)  jreg[real_size + 2]         << 11) |
                  ((uint32_t)  jreg[runtime.debug.size + 3]         << 19) |
                  ((uint32_t)  jreg[real_size + 3]         << 19) |
                  ((uint32_t) (jreg[runtime.debug.size + 4] & 0x1f) << 27),
                  ((uint32_t) (jreg[real_size + 4] & 0x1f) << 27),
                  32);
                  32);
 
 
  /* Compute the expected CRC */
  /* Compute the expected CRC */
  uint32_t  crc_computed;
  uint32_t  crc_computed;
 
 
  crc_computed = crc32 (0,                1, 0xffffffff);
  crc_computed = crc32 (0,                1, 0xffffffff);
  crc_computed = crc32 (JCMD_GO_COMMAND,  4, crc_computed);
  crc_computed = crc32 (JCMD_GO_COMMAND,  4, crc_computed);
 
 
  int  i;
  unsigned long int  i;
 
 
  for (i = 0; i < runtime.debug.size; i++)
  for (i = 0; i < real_size; i++)
    {
    {
      uint8_t  byte = reverse_bits (((jreg[i] & 0xe0) >> 5) |
      uint8_t  byte = reverse_bits (((jreg[i] & 0xe0) >> 5) |
                      ((jreg[i + 1] & 0x1f) << 3), 8);
                      ((jreg[i + 1] & 0x1f) << 3), 8);
      crc_computed = crc32 (byte, 8, crc_computed);
      crc_computed = crc32 (byte, 8, crc_computed);
    }
    }
 
 
  /* Status flags */
 
  enum jtag_status  status = JS_OK;
 
 
 
  /* Validate the CRC */
  /* Validate the CRC */
  if (crc_computed == crc_in)
  if (crc_computed == crc_in)
    {
    {
      /* Read the data. */
      /* Write the data. Module errors will have been detected earlier, so we
 
         do nothing more here. */
      switch (runtime.debug.mod_id)
      switch (runtime.debug.mod_id)
        {
        {
        case JM_WISHBONE:
        case JM_WISHBONE:
          wishbone_write (jreg, 5, &status);
          wishbone_write (jreg, real_size, &status);
          break;
          break;
 
 
        case JM_CPU0:
        case JM_CPU0:
          spr_write (jreg, 5);
          spr_write (jreg, real_size, &status);
          break;
 
 
 
        case JM_CPU1:
 
          fprintf (stderr, "Warning: JTAG attempt to write to CPU1: Not "
 
                   "supported.\n");
 
          break;
          break;
 
 
        default:
        default:
          fprintf (stderr, "Warning: go_command_write: invalid module 0x%lx\n",
 
                   runtime.debug.mod_id);
 
          break;
          break;
        }
        }
    }
    }
  else
  else
    {
    {
Line 1036... Line 934...
      status |= JS_CRC_IN_ERROR;
      status |= JS_CRC_IN_ERROR;
    }
    }
 
 
  /* Construct the outgoing register, skipping the data read and returning the
  /* Construct the outgoing register, skipping the data read and returning the
     number of JTAG cycles taken (the register length). */
     number of JTAG cycles taken (the register length). */
  return  construct_response (jreg, status, 0xffffffff, 0,
  construct_response (jreg, status, 0xffffffff, 0, 37UL + 8UL * real_size);
                              37 + 8 * runtime.debug.size);
 
 
 
}       /* go_command_write () */
}       /* go_command_write () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
Line 1054... Line 951...
 
 
   This function breaks this out.
   This function breaks this out.
 
 
   @param[in,out] jreg  The register to shift in, and the register shifted
   @param[in,out] jreg  The register to shift in, and the register shifted
                        back out.
                        back out.
 
   @param[in]     num_bits  The number of bits supplied.                     */
   @return  The number of cycles the shift took, which in turn is the number
 
            of bits in the register                                          */
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static int
static void
go_command (unsigned char *jreg)
go_command (unsigned char *jreg,
 
            int            num_bits)
{
{
  /* Have we even had a WRITE_COMMAND? */
  /* Have we even had a WRITE_COMMAND? */
  if (!runtime.debug.write_defined_p)
  if (!runtime.debug.write_defined_p)
    {
    {
      fprintf (stderr, "Warning: JTAG GO_COMMAND with no prior WRITE_COMMAND: "
      memset (jreg, 0, (num_bits + 7) / 8);
               "ignored\n");
      fprintf (stderr, "ERROR: JTAG GO_COMMAND with no prior WRITE_COMMAND.\n");
      return 4 + 1;                     /* Only the first 5 bits meaningful */
      return;
    }
    }
 
 
  /* Whether to read or write depends on the access type */
  /* Whether to read or write depends on the access type. We don't put an
 
     error message if it's invalid here - we rely on the prior WRITE_COMMAND
 
     to do that. We just silently ignore. */
  switch (runtime.debug.acc_type)
  switch (runtime.debug.acc_type)
    {
    {
    case JAT_WRITE8:
    case JAT_WRITE8:
    case JAT_WRITE16:
    case JAT_WRITE16:
    case JAT_WRITE32:
    case JAT_WRITE32:
      return  go_command_write (jreg);
      go_command_write (jreg, num_bits);
 
      break;
 
 
    case JAT_READ8:
    case JAT_READ8:
    case JAT_READ16:
    case JAT_READ16:
    case JAT_READ32:
    case JAT_READ32:
      return  go_command_read (jreg);
      go_command_read (jreg, num_bits);
 
      break;
 
 
    default:
    default:
      fprintf (stderr, "Warning: JTAG GO_COMMAND: invalid access type: "
      break;
               "ignored\n");
 
      return 4 + 1;                     /* Only the first 5 bits meaningful */
 
    }
    }
}       /* go_command () */
}       /* go_command () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
Line 1117... Line 1015...
 
 
   Fields are always shifted in MS bit first, so must be reversed. The CRC in
   Fields are always shifted in MS bit first, so must be reversed. The CRC in
   is computed on the first 5 bits, the CRC out on the 56 status, length,
   is computed on the first 5 bits, the CRC out on the 56 status, length,
   address and access type bits.
   address and access type bits.
 
 
 
   This is a register of a fixed size, which we verify initially.
 
 
   @param[in,out] jreg  The register to shift in, and the register shifted
   @param[in,out] jreg  The register to shift in, and the register shifted
                        back out.
                        back out.
 
   @param[in]     num_bits  The number of bits supplied.                     */
   @return  The number of cycles the shift took, which in turn is the number
 
            of bits in the register                                          */
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static int
static void
read_command (unsigned char *jreg)
read_command (unsigned char *jreg,
 
              int            num_bits)
{
{
 
  /* Validate register size, which is fixed */
 
  const int  REG_BITS = 88 + 32 + 4 + 1;
 
 
 
  if (REG_BITS != num_bits)
 
    {
 
      fprintf (stderr,
 
               "ERROR: JTAG READ_COMMAND %d bits, when %d bits expected.\n",
 
               num_bits, REG_BITS);
 
      return;
 
    }
 
 
  /* Break out the fields */
  /* Break out the fields */
  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) |
Line 1145... Line 1055...
  uint32_t  crc_out = 0xffffffff;
  uint32_t  crc_out = 0xffffffff;
 
 
  /* Status flags */
  /* Status flags */
  enum jtag_status  status = JS_OK;
  enum jtag_status  status = JS_OK;
 
 
  /* Validate the CRC */
  /* Only do anything with this if the CRC's match */
  if (crc_computed != crc_in)
  if (crc_computed == crc_in)
    {
    {
      /* Mismatch: record the error */
 
      status |= JS_CRC_IN_ERROR;
 
    }
 
 
 
  /* If we haven't had a previous WRITE_COMMAND, then we return empty
  /* 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
     data. There is no valid status flag we can use, but we print a rude
     message. */
     message. */
  uint8_t   acc_type_r;
      uint8_t   acc_type;
  uint32_t  addr_r;
      uint32_t  addr;
  uint16_t  len_r;
      uint16_t  len;
 
 
  if (runtime.debug.write_defined_p)
  if (runtime.debug.write_defined_p)
    {
    {
 
          acc_type = runtime.debug.acc_type;
 
          addr     = runtime.debug.addr;
 
          len      = runtime.debug.size - 1;
 
        }
 
      else
 
        {
 
          fprintf (stderr, "ERROR: JTAG READ_COMMAND finds no data.\n");
 
 
 
          acc_type = 0;
 
          addr     = 0;
 
          len      = 0;
 
        }
 
 
      /* Compute the CRC */
      /* Compute the CRC */
      crc_out = crc32 (runtime.debug.acc_type,  4, crc_out);
      crc_out = crc32 (acc_type,  4, crc_out);
      crc_out = crc32 (runtime.debug.addr,     32, crc_out);
      crc_out = crc32 (addr,     32, crc_out);
      crc_out = crc32 (runtime.debug.size - 1, 16, crc_out);
      crc_out = crc32 (len,      16, crc_out);
 
 
      /* Reverse the bit fields */
      /* Reverse the bit fields */
      acc_type_r = reverse_bits (runtime.debug.acc_type,  4);
      acc_type = reverse_bits (acc_type,  4);
      addr_r     = reverse_bits (runtime.debug.addr,     32);
      addr     = reverse_bits (addr,     32);
      len_r      = reverse_bits (runtime.debug.size - 1, 16);
      len      = reverse_bits (len,      16);
 
 
 
      /* Construct the outgoing register. */
 
      jreg[ 4] |= (acc_type <<  5) & 0xe0;
 
      jreg[ 5] |= (acc_type >>  3) & 0x01;
 
      jreg[ 5] |= (addr     <<  1) & 0xfe;
 
      jreg[ 6] |= (addr     >>  7) & 0xff;
 
      jreg[ 7] |= (addr     >> 15) & 0xff;
 
      jreg[ 8] |= (addr     >> 23) & 0xff;
 
      jreg[ 9] |= (addr     >> 31) & 0x01;
 
      jreg[ 9] |= (len      <<  1) & 0xfe;
 
      jreg[10] |= (len      >>  7) & 0xff;
 
      jreg[11] |= (len      >> 15) & 0x01;
    }
    }
  else
  else
    {
    {
      fprintf (stderr, "Warning: JTAG READ_COMMAND finds no data\n");
      /* CRC Mismatch: record the error */
 
      status |= JS_CRC_IN_ERROR;
      /* 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
 
     are available */
 
  jreg[ 4] |= (acc_type_r <<  5) & 0xf8;
 
  jreg[ 5] |= (acc_type_r >>  3) & 0x07;
 
  jreg[ 5] |= (addr_r     <<  1) & 0xfe;
 
  jreg[ 6] |= (addr_r     >>  7) & 0xff;
 
  jreg[ 7] |= (addr_r     >> 15) & 0xff;
 
  jreg[ 8] |= (addr_r     >> 23) & 0xff;
 
  jreg[ 9] |= (addr_r     >> 31) & 0x01;
 
  jreg[ 9] |= (len_r      <<  1) & 0xfe;
 
  jreg[10] |= (len_r      >>  7) & 0xff;
 
  jreg[11] |= (len_r      >> 15) & 0x01;
 
 
 
  /* 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 written. */
  return  construct_response (jreg, status, crc_out, 52, 37);
  return  construct_response (jreg, status, crc_out, 52, 37);
 
 
}       /* read_command () */
}       /* read_command () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Specify details for a subsequence GO_COMMAND
/*!Validate WRITE_COMMAND fields for WishBone
 
 
 
   Check that a WRITE_COMMAND's fields are valid for WishBone access.
 
 
 
   - 16 and 32-bit access must be correctly aligned.
 
 
 
   - size must be a multiple of 2 for 16-bit access, and a multiple of 4 for
 
     32-bit access.
 
 
 
   Error messages are printed to explain any validation problems.
 
 
 
   @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
 
         original WRITE_COMMAND.
 
 
 
   @param[in] acc_type  The access type field
 
   @param[in] addr      The address field
 
   @param[in] size      The number of bytes to transfer (field is 1 less than
 
                        this).
 
 
 
   @return  1 (TRUE) if validation is OK, 0 (FALSE) if validation fails.     */
 
/*---------------------------------------------------------------------------*/
 
static int
 
validate_wb_fields (unsigned char      acc_type,
 
                    unsigned long int  addr,
 
                    unsigned long int  size)
 
{
 
  int  res_p = 1;                       /* Result */
 
 
 
  /* Determine the size of the access */
 
  uint32_t  access_bytes = 1;
 
 
 
  switch (acc_type)
 
    {
 
    case JAT_WRITE8:
 
    case JAT_READ8:
 
      access_bytes = 1;
 
      break;
 
 
 
    case JAT_WRITE16:
 
    case JAT_READ16:
 
      access_bytes = 2;
 
      break;
 
 
 
    case JAT_WRITE32:
 
    case JAT_READ32:
 
      access_bytes = 4;
 
      break;
 
 
 
    default:
 
      fprintf (stderr, "ERROR: JTAG WRITE_COMMAND unknown access type %u.\n",
 
               acc_type);
 
      res_p = 0;
 
      break;
 
    }
 
 
 
  /* Check for alignment. This works for 8-bit and undefined access type,
 
     although the tests will always pass. */
 
 
 
  if (0 != (addr % access_bytes))
 
    {
 
      fprintf (stderr, "ERROR: JTAG WishBone %d-bit access must be %d-byte "
 
               "aligned.\n", access_bytes * 8, access_bytes);
 
      res_p = 0;
 
    }
 
 
 
  /* Check byte length is multiple of access width */
 
  if (0 != (size % access_bytes))
 
    {
 
      fprintf (stderr, "ERROR: JTAG %d-bit WishBone access must be multiple "
 
               "of %d bytes in length.\n", access_bytes * 8, access_bytes);
 
      res_p = 0;
 
    }
 
 
 
  return  res_p;
 
 
 
}       /* validate_wb_fields () */
 
 
 
 
 
/*---------------------------------------------------------------------------*/
 
/*!Validate WRITE_COMMAND fields for SPR
 
 
 
   Check that a WRITE_COMMAND's fields are valid for SPR access. Only prints
 
   messages, since the protocol does not allow for any errors.
 
 
 
   - 8 and 16-bit access is not permitted.
 
 
 
   - size must be 4 bytes (1 word). Any other value is an error.
 
 
 
   - address must be less than MAX_SPRS. If a larger value is specified, it
 
     will be reduced module MAX_SPRS (which is hopefully a power of 2). This
 
     is only a warning, not an error.
 
 
 
   Error/warning messages are printed to explain any validation problems.
 
 
 
   @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
 
         original WRITE_COMMAND.
 
 
 
   @param[in] acc_type  The access type field
 
   @param[in] addr      The address field
 
   @param[in] size      The number of bytes to transfer (field is 1 less than
 
                        this).
 
 
 
   @return  1 (TRUE) if we could validate (even if addr needs truncating),
 
            0 (FALSE) otherwise.                                             */
 
/*---------------------------------------------------------------------------*/
 
static int
 
validate_spr_fields (unsigned char      acc_type,
 
                     unsigned long int  addr,
 
                     unsigned long int  size)
 
{
 
  int  res_p = 1;                       /* Result */
 
 
 
  /* Determine the size and direction of the access */
 
  switch (acc_type)
 
    {
 
    case JAT_WRITE8:
 
    case JAT_READ8:
 
      fprintf (stderr, "ERROR: JTAG 8-bit access for SPR not supported.\n");
 
      res_p = 0;
 
      break;
 
 
 
    case JAT_WRITE16:
 
    case JAT_READ16:
 
      fprintf (stderr, "ERROR: JTAG 16-bit access for SPR not supported.\n");
 
      res_p = 0;
 
      break;
 
 
 
    case JAT_WRITE32:
 
    case JAT_READ32:
 
      break;
 
 
 
    default:
 
      fprintf (stderr, "ERROR: unknown JTAG SPR access type %u.\n",
 
               acc_type);
 
      res_p = 0;
 
      break;
 
    }
 
 
 
  /* Validate access size */
 
  if (4 != size)
 
    {
 
      fprintf (stderr, "ERROR: JTAG SPR access 0x%lx bytes not supported.\n",
 
               size);
 
      res_p = 0;
 
    }
 
 
 
  /* Validate address. This will be truncated if wrong, so not an error. */
 
  if (addr >= MAX_SPRS)
 
    {
 
      fprintf (stderr, "Warning: truncated JTAG SPR address 0x%08lx.\n",
 
               addr);
 
    }
 
 
 
  return  res_p;                        /* Success */
 
 
 
}       /* validate_spr_fields () */
 
 
 
 
 
/*---------------------------------------------------------------------------*/
 
/*!Specify details for a subsequent GO_COMMAND
 
 
   Process a WRITE_COMMAND register. The format is:
   Process a WRITE_COMMAND register. The format is:
 
 
          +---------+-------+--------+---------+--------+---------+---+
          +---------+-------+--------+---------+--------+---------+---+
          |         |       |        |         |        |  WRITE  |   |
          |         |       |        |         |        |  WRITE  |   |
Line 1233... Line 1305...
 
 
 
 
   Fields are always shifted in MS bit first, so must be reversed. The CRC in
   Fields are always shifted in MS bit first, so must be reversed. The CRC in
   is computed on the first 57 bits, the CRC out on the 4 status bits.
   is computed on the first 57 bits, the CRC out on the 4 status bits.
 
 
 
   There are no bits for reporting bit specification errors other than CRC
 
   mismatch. The subsequent GO_COMMAND will report an error in reading from
 
   Wishbone or over/under-run. We report any inconsistencies here with warning
 
   messages, correcting them if possible.
 
 
 
   All errors invalidate any prior data. This will ensure any subsequent usage
 
   continues to trigger faults, rather than a failed WRITE_COMMAND being
 
   missed.
 
 
 
   This is a register of a fixed size, which we verify initially.
 
 
   @param[in,out] jreg  The register to shift in, and the register shifted
   @param[in,out] jreg  The register to shift in, and the register shifted
                        back out.
                        back out.
 
   @param[in]     num_bits  The number of bits supplied.                     */
   @return  The number of cycles the shift took, which in turn is the number
 
            of bits in the register                                          */
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static int
static void
write_command (unsigned char *jreg)
write_command (unsigned char *jreg,
 
               int            num_bits)
 
{
 
  /* Validate register size, which is fixed */
 
  const int  REG_BITS = 36 + 32 +16 + 32 + 4 + 4 + 1;
 
 
 
  if (REG_BITS != num_bits)
{
{
 
      runtime.debug.write_defined_p = 0;
 
      fprintf (stderr,
 
               "ERROR: JTAG WRITE_COMMAND %d bits, when %d bits expected.\n",
 
               num_bits, REG_BITS);
 
      return;
 
    }
 
 
  /* Break out the fields */
  /* Break out the fields */
  uint8_t   acc_type = reverse_bits (((jreg[0] & 0xe0) >> 5) |
  uint8_t   acc_type = reverse_bits (((jreg[0] & 0xe0) >> 5) |
                                     ((jreg[1] & 0x01) << 3) , 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) |
Line 1271... Line 1365...
  crc_computed = crc32 (len,                16, crc_computed);
  crc_computed = crc32 (len,                16, crc_computed);
 
 
  /* Status flags */
  /* Status flags */
  enum jtag_status  status = JS_OK;
  enum jtag_status  status = JS_OK;
 
 
  /* Validate the CRC */
  /* We only do anything with this packet if the CRC's match */
  if (crc_computed != crc_in)
  if (crc_computed == crc_in)
    {
    {
      /* Mismatch: record the error */
      unsigned long int  data_size = (unsigned long int) len + 1UL;
      status |= JS_CRC_IN_ERROR;
 
 
      switch (runtime.debug.mod_id)
 
        {
 
        case JM_WISHBONE:
 
 
 
          if (validate_wb_fields (acc_type, addr, data_size))
 
            {
 
              runtime.debug.write_defined_p = 1;
 
              runtime.debug.acc_type        = acc_type;
 
              runtime.debug.addr            = addr;
 
              runtime.debug.size            = data_size;
    }
    }
  else
  else
    {
    {
      /* All OK. All other errors can only occur when the GO_COMMAND tries to
              runtime.debug.write_defined_p = 0;
         execute the write. Record the information for next GO_COMMAND */
            }
 
 
 
          break;
 
 
 
        case JM_CPU0:
 
 
 
          /* Oversize addresses are permitted, but cause a validation warning
 
             and are truncated here. */
 
          if (validate_spr_fields (acc_type, addr, data_size))
 
            {
      runtime.debug.write_defined_p = 1;
      runtime.debug.write_defined_p = 1;
      runtime.debug.acc_type        = acc_type;
      runtime.debug.acc_type        = acc_type;
      runtime.debug.addr            = addr;
              runtime.debug.addr            = addr % MAX_SPRS;
      runtime.debug.size            = (unsigned long int) len + 1UL;
              runtime.debug.size            = data_size;
 
            }
 
          else
 
            {
 
              runtime.debug.write_defined_p = 0;
    }
    }
 
 
  /* Construct the outgoing register and return the JTAG cycles taken (the
          break;
     register length) */
 
  return  construct_response (jreg, status, 0xffffffff, 0, 89);
        case JM_CPU1:
 
 
 
          runtime.debug.write_defined_p = 0;
 
          fprintf (stderr,
 
                   "ERROR: JTAG WRITE_COMMAND for CPU1 not supported.\n");
 
          break;
 
 
 
        case JM_UNDEFINED:
 
 
 
          runtime.debug.write_defined_p = 0;
 
          fprintf (stderr,
 
                   "ERROR: JTAG WRITE_COMMAND with no module selected.\n");
 
          break;
 
 
 
        default:
 
 
 
          /* All other modules will have triggered an error on selection. */
 
          runtime.debug.write_defined_p = 0;
 
          break;
 
        }
 
    }
 
  else
 
    {
 
      /* CRC Mismatch: record the error */
 
      runtime.debug.write_defined_p  = 0;
 
      status                        |= JS_CRC_IN_ERROR;
 
    }
 
 
 
 
 
  /* Construct the outgoing register */
 
  construct_response (jreg, status, 0xffffffff, 0, 89);
 
 
}       /* write_command () */
}       /* write_command () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
Line 1304... Line 1451...
          +---------+-------+---------+---+
          +---------+-------+---------+---+
          |         |       |  READ   |   |
          |         |       |  READ   |   |
   TDI -> | Ignored |  CRC  | CONTROL | 0 | -> TDO
   TDI -> | Ignored |  CRC  | CONTROL | 0 | -> TDO
          |         |       |  (0x3)  |   |
          |         |       |  (0x3)  |   |
          +---------+-------+---------+---+
          +---------+-------+---------+---+
              36        32       4
              88        32       4
             bits      bits    bits
             bits      bits    bits
 
 
   The returned register has the format:
   The returned register has the format:
 
 
          +-------+--------+--------+---------+
          +-------+--------+--------+---------+
Line 1320... Line 1467...
             bits    bits     bits      bits
             bits    bits     bits      bits
 
 
   Fields are always shifted in MS bit first, so must be reversed. The CRC in
   Fields are always shifted in MS bit first, so must be reversed. The CRC in
   is computed on the first 57 bits, the CRC out on the 4 status bits.
   is computed on the first 57 bits, the CRC out on the 4 status bits.
 
 
 
   This is a register of a fixed size, which we verify initially.
 
 
   @param[in,out] jreg  The register to shift in, and the register shifted
   @param[in,out] jreg  The register to shift in, and the register shifted
                        back out.
                        back out.
 
   @param[in]     num_bits  The number of bits supplied.                     */
   @return  The number of cycles the shift took, which in turn is the number
 
            of bits in the register                                          */
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static int
static void
read_control (unsigned char *jreg)
read_control (unsigned char *jreg,
 
              int            num_bits)
 
{
 
  /* Validate register size, which is fixed */
 
  const int  REG_BITS = 88 + 32 + 4 + 1;
 
 
 
  if (REG_BITS != num_bits)
{
{
 
      fprintf (stderr,
 
               "ERROR: JTAG READ_CONTROL %d bits, when %d bits expected.\n",
 
               num_bits, REG_BITS);
 
      return;
 
    }
 
 
  /* Break out the fields. */
  /* Break out the fields. */
  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) |
Line 1348... Line 1507...
  uint32_t  crc_out = 0xffffffff;
  uint32_t  crc_out = 0xffffffff;
 
 
  /* Status flags */
  /* Status flags */
  enum jtag_status  status = JS_OK;
  enum jtag_status  status = JS_OK;
 
 
  /* Validate the CRC */
  /* Only do anything if the CRC's match */
  if (crc_computed != crc_in)
  if (crc_computed == crc_in)
    {
    {
      /* Mismatch: record the error */
      uint64_t  data = 0;
      status |= JS_CRC_IN_ERROR;
 
    }
      switch (runtime.debug.mod_id)
  else if (JM_CPU0 == runtime.debug.mod_id)
 
    {
    {
      /* Valid module. Only bit we can sensibly read is the stall bit. */
        case JM_CPU0:
      uint64_t  data = (uint64_t) runtime.cpu.stalled << JCB_STALL;
 
 
 
      /* Compute the CRC */
          /* Valid module. Only bit we can sensibly read is the stall
      crc_out = crc32 (data,  52, crc_out);
             bit. Compute the CRC, reverse the data and construct the
 
             outgoing register. */
 
          data    = (uint64_t) runtime.cpu.stalled << JCB_STALL;
 
          break;
 
 
      /* Construct the outgoing register. */
        case JM_UNDEFINED:
      uint64_t  data_r = reverse_bits (data, 52);
          fprintf (stderr,
 
                   "ERROR: JTAG READ_CONTROL with no module selected.\n");
 
          break;
 
 
      jreg[ 4] |= (data_r <<  5) & 0xf8;
        case JM_WISHBONE:
      jreg[ 5] |= (data_r >>  3) & 0x07;
          fprintf (stderr,
      jreg[ 5] |= (data_r >> 11) & 0xff;
                   "ERROR: JTAG READ_CONTROL of WishBone not supported.\n");
      jreg[ 5] |= (data_r >> 19) & 0xff;
          break;
      jreg[ 5] |= (data_r >> 27) & 0xff;
 
      jreg[ 5] |= (data_r >> 35) & 0xff;
        case JM_CPU1:
      jreg[ 5] |= (data_r >> 43) & 0xff;
          fprintf (stderr,
      jreg[ 5] |= (data_r >> 51) & 0x01;
                   "ERROR: JTAG READ_CONTROL of CPU1 not supported.\n");
 
          break;
 
 
 
        default:
 
          /* All other modules will have triggered an error on selection. */
 
          break;
 
        }
 
 
 
      /* Compute the CRC, reverse and store the data, and construct the
 
         response with the status. */
 
      crc_out = crc32 (data,  52, crc_out);
 
      data    = reverse_bits (data, 52);
 
 
 
      jreg[ 4] |= (data <<  5) & 0xf8;
 
      jreg[ 5] |= (data >>  3) & 0x07;
 
      jreg[ 6] |= (data >> 11) & 0xff;
 
      jreg[ 7] |= (data >> 19) & 0xff;
 
      jreg[ 8] |= (data >> 27) & 0xff;
 
      jreg[ 9] |= (data >> 35) & 0xff;
 
      jreg[10] |= (data >> 43) & 0xff;
 
      jreg[11] |= (data >> 51) & 0x01;
    }
    }
  else
  else
    {
    {
      /* Not a valid module */
      /* CRC Mismatch: record the error */
      fprintf (stderr, "ERROR: JTAG attempt to read control data for module "
      status |= JS_CRC_IN_ERROR;
               "other than CPU0: ignored\n");
 
    }
    }
 
 
 
 
  /* Construct the response with the status */
  /* Construct the response with the status */
  return  construct_response (jreg, status, crc_out, 52, 37);
  return  construct_response (jreg, status, crc_out, 52, 37);
 
 
}       /* read_control () */
}       /* read_control () */
 
 
Line 1413... Line 1595...
             bits    bits      bits
             bits    bits      bits
 
 
   Fields are always shifted in MS bit first, so must be reversed. The CRC in
   Fields are always shifted in MS bit first, so must be reversed. The CRC in
   is computed on the first 57 bits, the CRC out on the 4 status bits.
   is computed on the first 57 bits, the CRC out on the 4 status bits.
 
 
 
   This is a register of a fixed size, which we verify initially.
 
 
   @param[in,out] jreg  The register to shift in, and the register shifted
   @param[in,out] jreg  The register to shift in, and the register shifted
                        back out.
                        back out.
 
   @param[in]     num_bits  The number of bits supplied.                     */
   @return  The number of cycles the shift took, which in turn is the number
 
            of bits in the register                                          */
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static int
static void
write_control (unsigned char *jreg)
write_control (unsigned char *jreg,
 
               int            num_bits)
 
{
 
  /* Validate register size, which is fixed */
 
  const int  REG_BITS = 36 + 32 + 52 + 4 + 1;
 
 
 
  if (REG_BITS != num_bits)
{
{
 
      fprintf (stderr,
 
               "ERROR: JTAG WRITE_CONTROL %d bits, when %d bits expected.\n",
 
               num_bits, REG_BITS);
 
      return;
 
    }
 
 
  /* Break out the fields. */
  /* Break out the fields. */
  uint64_t  data   = reverse_bits (((uint64_t) (jreg[ 0] & 0xe0) >>  5) |
  uint64_t  data   = reverse_bits (((uint64_t) (jreg[ 0] & 0xe0) >>  5) |
                                   ((uint64_t)  jreg[ 1]         <<  3) |
                                   ((uint64_t)  jreg[ 1]         <<  3) |
                                   ((uint64_t)  jreg[ 2]         << 11) |
                                   ((uint64_t)  jreg[ 2]         << 11) |
                                   ((uint64_t)  jreg[ 3]         << 19) |
                                   ((uint64_t)  jreg[ 3]         << 19) |
Line 1447... Line 1641...
  crc_computed = crc32 (data,               52, crc_computed);
  crc_computed = crc32 (data,               52, crc_computed);
 
 
  /* Status flags */
  /* Status flags */
  enum jtag_status  status = JS_OK;
  enum jtag_status  status = JS_OK;
 
 
  /* Validate the CRC */
  /* Only use the data if CRC's match */
  if (crc_computed != crc_in)
  if (crc_computed == crc_in)
    {
    {
      /* Mismatch: record the error */
      int  reset_bit;
      status |= JS_CRC_IN_ERROR;
      int  stall_bit;
    }
 
  else if (JM_CPU0 == runtime.debug.mod_id)
      switch (runtime.debug.mod_id)
    {
    {
      /* Good data and valid module. Reset, stall or unstall the register as
        case JM_CPU0:
         required. If reset is requested, there is no point considering
 
 
          /* Good data and valid module. Reset, stall or unstall the register
 
             as required. If reset is requested, there is no point considering
         stalling! */
         stalling! */
      int  reset_bit = (0x1 == ((data >> JCB_RESET) & 0x1));
          reset_bit = (0x1 == ((data >> JCB_RESET) & 0x1));
      int  stall_bit = (0x1 == ((data >> JCB_STALL) & 0x1));
          stall_bit = (0x1 == ((data >> JCB_STALL) & 0x1));
 
 
      if (reset_bit)
      if (reset_bit)
        {
        {
          sim_reset ();
          sim_reset ();
        }
        }
      else
      else
        {
        {
          set_stall_state (stall_bit);
          set_stall_state (stall_bit);
        }
        }
 
 
 
          break;
 
 
 
        case JM_UNDEFINED:
 
          fprintf (stderr,
 
                   "ERROR: JTAG WRITE_CONTROL with no module selected.\n");
 
          break;
 
 
 
        case JM_WISHBONE:
 
          fprintf (stderr,
 
                   "ERROR: JTAG WRITE_CONTROL of WishBone not supported.\n");
 
          break;
 
 
 
        case JM_CPU1:
 
          fprintf (stderr,
 
                   "ERROR: JTAG WRITE_CONTROL of CPU1 not supported.\n");
 
          break;
 
 
 
        default:
 
          /* All other modules will have triggered an error on selection. */
 
          break;
 
        }
    }
    }
  else
  else
    {
    {
      /* Not a valid module */
      /* CRC Mismatch: record the error */
      fprintf (stderr, "ERROR: JTAG attempt to control module other than "
      status |= JS_CRC_IN_ERROR;
               "CPU0: ignored\n");
 
    }
    }
 
 
  /* Construct the response with the status */
  /* Construct the response with the status */
  return  construct_response (jreg, status, 0xffffffff, 0, 89);
  return  construct_response (jreg, status, 0xffffffff, 0, 89);
 
 
Line 1499... Line 1716...
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Reset the JTAG interface
/*!Reset the JTAG interface
 
 
   Mark the current JTAG instruction as undefined.
   Mark the current JTAG instruction as undefined.                           */
 
 
   @return  The number of cycles the reset took.                             */
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
int
void
jtag_reset ()
jtag_reset ()
{
{
  runtime.debug.instr = JI_UNDEFINED;
  runtime.debug.instr = JI_UNDEFINED;
 
 
  return  JTAG_RESET_CYCLES;
 
 
 
}       /* jtag_reset () */
}       /* jtag_reset () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Shift a JTAG instruction register
/*!Shift a JTAG instruction register
Line 1536... Line 1749...
          |             |
          |             |
          +-------------+
          +-------------+
                 4
                 4
               bits
               bits
 
 
 
   We first verify that we have received the correct number of bits. If not we
 
   put out a warning, and for consistency return the number of bits supplied
 
   as the number of cycles the shift took.
 
 
   With this debug interface, registers are shifted MS bit first, so we must
   With this debug interface, registers are shifted MS bit first, so we must
   reverse the bits to get the actual value.
   reverse the bits to get the actual value.
 
 
   We record the selected instruction. For completeness the register is parsed
   We record the selected instruction. For completeness the register is parsed
   and a warning given if any register other than DEBUG is shifted.
   and a warning given if any register other than DEBUG is shifted.
 
 
   @param[in,out] jreg  The register to shift in, and the register shifted
   @param[in,out] jreg  The register to shift in, and the register shifted
                        back out.
                        back out.
 
   @param[in]     num_bits  The number of bits supplied.                     */
   @return  The number of cycles the shift took, which in turn is the number
 
            of bits in the register                                          */
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
int
void
jtag_shift_ir (unsigned char *jreg)
jtag_shift_ir (unsigned char *jreg,
 
               int            num_bits)
{
{
 
  if (4 != num_bits)
 
    {
 
      fprintf (stderr, "ERROR: Invalid JTAG instruction length %d bits.\n",
 
               num_bits);
 
      return;
 
    }
 
 
  runtime.debug.instr = reverse_bits (jreg[0] & 0xf, 4);
  runtime.debug.instr = reverse_bits (jreg[0] & 0xf, 4);
 
 
  switch (runtime.debug.instr)
  switch (runtime.debug.instr)
    {
    {
    case JI_EXTEST:
    case JI_EXTEST:
      fprintf (stderr, "Warning: JTAG EXTEST shifted\n");
      fprintf (stderr, "Warning: JTAG EXTEST shifted.\n");
      break;
      break;
 
 
    case JI_SAMPLE_PRELOAD:
    case JI_SAMPLE_PRELOAD:
      fprintf (stderr, "Warning: JTAG SAMPLE/PRELOAD shifted\n");
      fprintf (stderr, "Warning: JTAG SAMPLE/PRELOAD shifted.\n");
      break;
      break;
 
 
    case JI_IDCODE:
    case JI_IDCODE:
      fprintf (stderr, "Warning: JTAG IDCODE shifted\n");
      fprintf (stderr, "Warning: JTAG IDCODE shifted.\n");
      break;
      break;
 
 
    case JI_DEBUG:
    case JI_DEBUG:
      /* Do nothing for this one */
      /* Do nothing for this one */
      break;
      break;
 
 
    case JI_MBIST:
    case JI_MBIST:
      fprintf (stderr, "Warning: JTAG MBIST shifted\n");
      fprintf (stderr, "Warning: JTAG MBIST shifted.\n");
      break;
      break;
 
 
    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 0x%1x shifted\n",
      fprintf (stderr, "ERROR: Unknown JTAG instruction 0x%1x shifted.\n",
               runtime.debug.instr);
               runtime.debug.instr);
      break;
      break;
    }
    }
 
 
  return  4;                    /* Register length */
 
 
 
}       /* jtag_shift_ir () */
}       /* jtag_shift_ir () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Shift a JTAG data register
/*!Shift a JTAG data register
Line 1608... Line 1828...
   This is only meaningful if the DEBUG register instruction is already
   This is only meaningful if the DEBUG register instruction is already
   selected. If not, the data register is rejected.
   selected. If not, the data register is rejected.
 
 
   The register is parsed to determine which of the six possible register
   The register is parsed to determine which of the six possible register
   types it could be.
   types it could be.
   - MODULE_SELECT
   - SELECT_MODULE
   - WRITE_COMMNAND
   - WRITE_COMMNAND
   - READ_COMMAND
   - READ_COMMAND
   - GO_COMMAND
   - GO_COMMAND
   - WRITE_CONTROL
   - WRITE_CONTROL
   - READ_CONTROL
   - READ_CONTROL
 
 
   @note In practice READ_COMMAND is not used. However the functionality is
   @note In practice READ_COMMAND is not used. However the functionality is
         provided for future compatibility.
         provided for future compatibility.
 
 
   The parsing is hierarchical. The first bit determines if we have
   The parsing is hierarchical. The first bit determines if we have
   MODULE_SELECT, if not, the next 4 bits determine the command.
   SELECT_MODULE, if not, the next 4 bits determine the command.
 
 
   @param[in,out] jreg  The register to shift in, and the register shifted
   @param[in,out] jreg  The register to shift in, and the register shifted
                        back out.
                        back out.
 
   @param[in]     num_bits  The number of bits supplied.                     */
   @return  The number of cycles the shift took, which in turn is the number
 
            of bits in the register                                          */
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
int
void
jtag_shift_dr (unsigned char *jreg)
jtag_shift_dr (unsigned char *jreg,
 
               int            num_bits)
{
{
  if (JI_DEBUG != runtime.debug.instr)
  if (JI_DEBUG != runtime.debug.instr)
    {
    {
      fprintf (stderr, "ERROR: Attempt to shift JTAG data register when "
      fprintf (stderr, "ERROR: Attempt to shift JTAG data register when "
               "DEBUG not instruction: ignored\n");
               "DEBUG not instruction.\n");
      return  0;
      return;
    }
    }
 
 
  int  module_select_p = (1 == (jreg[0] & 0x1));
  int  select_module_p = (1 == (jreg[0] & 0x1));
 
 
  if (module_select_p)
  if (select_module_p)
    {
    {
      return  module_select (jreg);
      select_module (jreg, num_bits);
    }
    }
  else
  else
    {
    {
      enum jtag_cmd  cmd = reverse_bits ((jreg[0] >> 1) & 0xf, 4);
      switch (reverse_bits ((jreg[0] >> 1) & 0xf, 4))
 
 
      switch (cmd)
 
        {
        {
        case JCMD_GO_COMMAND:    return  go_command (jreg);
        case JCMD_GO_COMMAND:    go_command (jreg, num_bits); break;
        case JCMD_READ_COMMAND:  return  read_command (jreg);
        case JCMD_READ_COMMAND:  read_command (jreg, num_bits); break;
        case JCMD_WRITE_COMMAND: return  write_command (jreg);
        case JCMD_WRITE_COMMAND: write_command (jreg, num_bits); break;
        case JCMD_READ_CONTROL:  return  read_control (jreg);
        case JCMD_READ_CONTROL:  read_control (jreg, num_bits); break;
        case JCMD_WRITE_CONTROL: return  write_control (jreg);
        case JCMD_WRITE_CONTROL: write_control (jreg, num_bits); break;
 
 
        default:
        default:
          /* Not a command we recognize. Decide this after we've read just
          /* Not a command we recognize. */
             the module and command bits */
          fprintf (stderr, "ERROR: DEBUG command not recognized.\n");
          return  4 + 1;
          break;
        }
        }
    }
    }
}       /* jtag_shift_dr () */
}       /* jtag_shift_dr () */
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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