OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

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

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

Rev 96 Rev 97
/* jtag.c -- JTAG modeling
/* jtag.c -- JTAG modeling
 
 
   Copyright (C) 2008 Embecosm Limited
   Copyright (C) 2008 Embecosm Limited
 
 
   Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
   Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
 
 
   This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator.
   This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator.
 
 
   This program is free software; you can redistribute it and/or modify it
   This program is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by the Free
   under the terms of the GNU General Public License as published by the Free
   Software Foundation; either version 3 of the License, or (at your option)
   Software Foundation; either version 3 of the License, or (at your option)
   any later version.
   any later version.
 
 
   This program is distributed in the hope that it will be useful, but WITHOUT
   This program is distributed in the hope that it will be useful, but WITHOUT
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   more details.
   more details.
 
 
   You should have received a copy of the GNU General Public License along
   You should have received a copy of the GNU General Public License along
   with this program.  If not, see <http://www.gnu.org/licenses/>.  */
   with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 
/* This program is commented throughout in a fashion suitable for processing
/* This program is commented throughout in a fashion suitable for processing
   with Doxygen. */
   with Doxygen. */
 
 
 
 
/* Autoconf and/or portability configuration */
/* Autoconf and/or portability configuration */
#include "config.h"
#include "config.h"
#include "port.h"
#include "port.h"
 
 
/* System includes */
/* System includes */
#include <stdlib.h>
#include <stdlib.h>
#include <unistd.h>
#include <unistd.h>
#include <stddef.h>
#include <stddef.h>
#include <stdint.h>
#include <stdint.h>
#include <string.h>
#include <string.h>
 
 
/* Package includes */
/* Package includes */
#include "sim-config.h"
#include "sim-config.h"
#include "sprs.h"
#include "sprs.h"
#include "debug-unit.h"
#include "debug-unit.h"
#include "spr-defs.h"
#include "spr-defs.h"
#include "jtag.h"
#include "jtag.h"
#include "abstract.h"
#include "abstract.h"
#include "toplevel-support.h"
#include "toplevel-support.h"
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Calculate an ongoing 32-bit CRC for a value
/*!Calculate an ongoing 32-bit CRC for a value
 
 
   Utility function. This is for a CRC, where the value is presented in normal
   Utility function. This is for a CRC, where the value is presented in normal
   order (i.e its most significant bit is at the most significant positions,
   order (i.e its most significant bit is at the most significant positions,
   it has not been reversed for incorporating ina JTAG register).
   it has not been reversed for incorporating ina JTAG register).
 
 
   The function can be used for values with more than 64 bits, but will treat
   The function can be used for values with more than 64 bits, but will treat
   the supplied value as the most-significant 64 bits, with all other bits
   the supplied value as the most-significant 64 bits, with all other bits
   zero. In practice this is only of use when shifting in a large number of
   zero. In practice this is only of use when shifting in a large number of
   zeros.
   zeros.
 
 
   The CRC used is the IEEE 802.3 32-bit CRC using the polynomial:
   The CRC used is the IEEE 802.3 32-bit CRC using the polynomial:
 
 
   x^32 + x^26 + x^23 +x^22 +x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 +
   x^32 + x^26 + x^23 +x^22 +x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 +
   x^4 + x^2 + x^1 + 1
   x^4 + x^2 + x^1 + 1
 
 
   In this implementation, the CRC is initialized to all ones (outside this
   In this implementation, the CRC is initialized to all ones (outside this
   function), to catch leading zeros.
   function), to catch leading zeros.
 
 
   The function is designed to be used in a continuing calculation if
   The function is designed to be used in a continuing calculation if
   desired. It takes a partially computed CRC and shifts in the appropriate
   desired. It takes a partially computed CRC and shifts in the appropriate
   new bits for the value supplied. For a new calculation, this value should
   new bits for the value supplied. For a new calculation, this value should
   be 0xffffffff.
   be 0xffffffff.
 
 
  @param[in] value     The number whose CRC is wanted (MSB first)
  @param[in] value     The number whose CRC is wanted (MSB first)
  @param[in] num_bits  The number of bits to use from value
  @param[in] num_bits  The number of bits to use from value
  @param[in] crc_in    The value of the CRC computed so far
  @param[in] crc_in    The value of the CRC computed so far
 
 
  @return  The updated CRC value                                             */
  @return  The updated CRC value                                             */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static uint32_t
static uint32_t
crc32 (uint64_t  value,
crc32 (uint64_t  value,
       int       num_bits,
       int       num_bits,
       uint32_t  crc_in)
       uint32_t  crc_in)
{
{
  static const uint32_t  CRC32_POLY = 0x04c11db7;
  static const uint32_t  CRC32_POLY = 0x04c11db7;
 
 
  /* Incorporate the bits, MS bit first. */
  /* Incorporate the bits, MS bit first. */
  int  i;
  int  i;
 
 
  for (i = num_bits - 1; i >= 0; i--)
  for (i = num_bits - 1; i >= 0; i--)
    {
    {
      uint32_t  d = (1 == ((value >> i) & 1))   ? 0xfffffff : 0x0000000;
      uint32_t  d = (1 == ((value >> i) & 1))   ? 0xfffffff : 0x0000000;
      uint32_t  t = (1 == ((crc_in >> 31) & 1)) ? 0xfffffff : 0x0000000;
      uint32_t  t = (1 == ((crc_in >> 31) & 1)) ? 0xfffffff : 0x0000000;
 
 
      crc_in <<= 1;
      crc_in <<= 1;
      crc_in  ^= (d ^ t) & CRC32_POLY;
      crc_in  ^= (d ^ t) & CRC32_POLY;
    }
    }
 
 
  return  crc_in;
  return  crc_in;
 
 
}       /* crc32 () */
}       /* crc32 () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Reverse up to 64 bits in a word
/*!Reverse up to 64 bits in a word
 
 
   Utility function. Uses the "reverse" algorithm from the University of
   Utility function. Uses the "reverse" algorithm from the University of
   Kentucky Aggregate Magic Algorithms.
   Kentucky Aggregate Magic Algorithms.
 
 
   @param[in] val      The long word to reverse
   @param[in] val      The long word to reverse
   @param[in] numBits  Number of bits to reverse
   @param[in] numBits  Number of bits to reverse
 
 
   @return  The reversed word.                                               */
   @return  The reversed word.                                               */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static uint64_t
static uint64_t
reverse_bits (uint64_t  val,
reverse_bits (uint64_t  val,
              int       numBits)
              int       numBits)
{
{
  val = (((val & 0xaaaaaaaaaaaaaaaaULL) >>  1) |
  val = (((val & 0xaaaaaaaaaaaaaaaaULL) >>  1) |
         ((val & 0x5555555555555555ULL) <<  1));
         ((val & 0x5555555555555555ULL) <<  1));
  val = (((val & 0xccccccccccccccccULL) >>  2) |
  val = (((val & 0xccccccccccccccccULL) >>  2) |
         ((val & 0x3333333333333333ULL) <<  2));
         ((val & 0x3333333333333333ULL) <<  2));
  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 & 0x00000fff0000ffffULL) << 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 () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Reverse a byte
/*!Reverse a byte
 
 
   Utility function. Uses the "reverse" algorithm from the University of
   Utility function. Uses the "reverse" algorithm from the University of
   Kentucky Aggregate Magic Algorithms.
   Kentucky Aggregate Magic Algorithms.
 
 
   @param[in] byte  The byte to reverse
   @param[in] byte  The byte to reverse
 
 
   @return  The reversed byte.                                               */
   @return  The reversed byte.                                               */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static uint8_t
static uint8_t
reverse_byte (uint8_t  byte)
reverse_byte (uint8_t  byte)
{
{
  byte = (((byte & 0xaa) >> 1) | ((byte & 0x55) << 1));
  byte = (((byte & 0xaa) >> 1) | ((byte & 0x55) << 1));
  byte = (((byte & 0xcc) >> 2) | ((byte & 0x33) << 2));
  byte = (((byte & 0xcc) >> 2) | ((byte & 0x33) << 2));
 
 
  return ((byte >> 4) | (byte << 4));
  return ((byte >> 4) | (byte << 4));
 
 
}       /* reverse_byte () */
}       /* reverse_byte () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Construct a response register to shift out.
/*!Construct a response register to shift out.
 
 
   The generic format is:
   The generic format is:
 
 
          +-------+--------+---------+---------+
          +-------+--------+---------+---------+
          |       |        |         |         |
          |       |        |         |         |
   TDI -> |  CRC  | Status |  XX..XX |  00..00 | -> TDO
   TDI -> |  CRC  | Status |  XX..XX |  00..00 | -> TDO
          |       |        |         |         |
          |       |        |         |         |
          +-------+--------+---------+---------+
          +-------+--------+---------+---------+
              32       4    "ignored"   "zero"
              32       4    "ignored"   "zero"
             bits    bits      bits      bits
             bits    bits      bits      bits
 
 
 
 
   Fields are always shifted in MS bit first, so must be reversed. The CRC is
   Fields are always shifted in MS bit first, so must be reversed. The CRC is
   on the 4 status bits. Only the "zero" bits are zeroed. This allows for
   on the 4 status bits. Only the "zero" bits are zeroed. This allows for
   other fields to be specified in the "ignored" bits region, which are
   other fields to be specified in the "ignored" bits region, which are
   guaranteed to be left untouched.
   guaranteed to be left untouched.
 
 
   @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                                      */
   @return  The register length in bits                                      */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static int
static int
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)
{
{
  /* Construct the outgoing CRC */
  /* Construct the outgoing CRC */
  uint32_t  crc_out = crc32 (status, 4, crc_in);
  uint32_t  crc_out = crc32 (status, 4, crc_in);
 
 
  /* Reversed versions of fields ready for insertion */
  /* Reversed versions of fields ready for insertion */
  uint8_t   status_r  = reverse_bits (status, 4);
  uint8_t   status_r  = reverse_bits (status, 4);
  uint32_t  crc_out_r = reverse_bits (crc_out, 32);
  uint32_t  crc_out_r = reverse_bits (crc_out, 32);
 
 
  /* Construct the response register */
  /* Construct the response register */
  unsigned int  zero_bytes = zero_bits / 8;
  unsigned int  zero_bytes = zero_bits / 8;
  unsigned int  zero_off   = zero_bits % 8;
  unsigned int  zero_off   = zero_bits % 8;
 
 
  /* Clear the zero bits */
  /* Clear the zero bits */
  if (zero_bytes > 0)
  if (zero_bytes > 0)
    {
    {
      memset (jreg, 0, zero_bytes);
      memset (jreg, 0, zero_bytes);
    }
    }
 
 
  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
       the first and second free bytes.
       the first and second free bytes.
 
 
     For completeness we deal with what should be the impossible case of
     For completeness we deal with what should be the impossible case of
     bit_off > 7. */
     bit_off > 7. */
  if (bit_off <= 4)
  if (bit_off <= 4)
    {
    {
      /* Note that this works even if bit_off == 4, since there will be no CRC
      /* Note that this works even if bit_off == 4, since there will be no CRC
         remaining to OR into the first byte. */
         remaining to OR into the first byte. */
      jreg[skip_bytes]     |=  ((status_r & 0xf) << bit_off) |
      jreg[skip_bytes]     |=  ((status_r & 0xf) << bit_off) |
                              ((crc_out_r << (4 + bit_off)) & 0xff);
                              ((crc_out_r << (4 + bit_off)) & 0xff);
      jreg[skip_bytes + 1]  =  (crc_out_r >> ( 4 - bit_off)) & 0xff;
      jreg[skip_bytes + 1]  =  (crc_out_r >> ( 4 - bit_off)) & 0xff;
      jreg[skip_bytes + 2]  =  (crc_out_r >> (12 - bit_off)) & 0xff;
      jreg[skip_bytes + 2]  =  (crc_out_r >> (12 - bit_off)) & 0xff;
      jreg[skip_bytes + 3]  =  (crc_out_r >> (20 - bit_off)) & 0xff;
      jreg[skip_bytes + 3]  =  (crc_out_r >> (20 - bit_off)) & 0xff;
      jreg[skip_bytes + 4]  =  (crc_out_r >> (28 - bit_off)) & 0xff;
      jreg[skip_bytes + 4]  =  (crc_out_r >> (28 - bit_off)) & 0xff;
    }
    }
  else if (bit_off < 8)
  else if (bit_off < 8)
    {
    {
      jreg[skip_bytes]     |=   status_r << bit_off;
      jreg[skip_bytes]     |=   status_r << bit_off;
      jreg[skip_bytes + 1]  =  (status_r >> (8 - bit_off)) |
      jreg[skip_bytes + 1]  =  (status_r >> (8 - bit_off)) |
                              ((crc_out_r << (bit_off - 4)) & 0xff);
                              ((crc_out_r << (bit_off - 4)) & 0xff);
      jreg[skip_bytes + 2]  =  (crc_out_r >> (12 - bit_off)) & 0xff;
      jreg[skip_bytes + 2]  =  (crc_out_r >> (12 - bit_off)) & 0xff;
      jreg[skip_bytes + 3]  =  (crc_out_r >> (20 - bit_off)) & 0xff;
      jreg[skip_bytes + 3]  =  (crc_out_r >> (20 - bit_off)) & 0xff;
      jreg[skip_bytes + 4]  =  (crc_out_r >> (28 - bit_off)) & 0xff;
      jreg[skip_bytes + 4]  =  (crc_out_r >> (28 - bit_off)) & 0xff;
      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 */
  /* Result is the register length in bits */
  return  32 + 4 + skip_bytes;
  return  32 + 4 + skip_bytes;
 
 
}       /* construct_response () */
}       /* construct_response () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Select a module for debug
/*!Select a module for debug
 
 
   Process a module selection register. The format is:
   Process a module selection register. The format is:
 
 
          +---------+-------+--------+---+
          +---------+-------+--------+---+
          |         |       |        |   |
          |         |       |        |   |
   TDI -> | Ignored |  CRC  | Module | 1 | -> TDO
   TDI -> | Ignored |  CRC  | Module | 1 | -> TDO
          |         |       |   ID   |   |
          |         |       |   ID   |   |
          +---------+-------+--------+---+
          +---------+-------+--------+---+
              36        32       4
              36        32       4
             bits      bits    bits
             bits      bits    bits
 
 
   The returned register has the format:
   The returned register has the format:
 
 
          +-------+--------+---------+
          +-------+--------+---------+
          |       |        |         |
          |       |        |         |
   TDI -> |  CRC  | Status |  00..00 | -> TDO
   TDI -> |  CRC  | Status |  00..00 | -> TDO
          |       |        |         |
          |       |        |         |
          +-------+--------+---------+
          +-------+--------+---------+
              32       4        37
              32       4        37
             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 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.
 
 
   @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.
 
 
   @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 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);
 
 
  /* Compute the expected CRC */
  /* Compute the expected CRC */
  uint32_t  crc_computed;
  uint32_t  crc_computed;
 
 
  crc_computed = crc32 (1,      1, 0xffffffff);
  crc_computed = crc32 (1,      1, 0xffffffff);
  crc_computed = crc32 (mod_id, 4, crc_computed);
  crc_computed = crc32 (mod_id, 4, crc_computed);
 
 
  /* 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 */
      /* Mismatch: record the error */
      status |= JS_CRC_IN_ERROR;
      status |= JS_CRC_IN_ERROR;
    }
    }
  else
  else
    {
    {
      /* Is it a valid module? */
      /* Is it a valid module? */
      switch (mod_id)
      switch (mod_id)
        {
        {
        case JM_WISHBONE:
        case JM_WISHBONE:
        case JM_CPU0:
        case JM_CPU0:
        case JM_CPU1:
        case JM_CPU1:
          /* All valid. Record the module */
          /* All valid. Record the module */
          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 */
          status |= JS_MODULE_MISSING;
          status |= JS_MODULE_MISSING;
          break;
          break;
        }
        }
    }
    }
 
 
  /* 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 */
}       /* module_select */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Validate WRITE_COMMAND fields for WishBone
/*!Validate WRITE_COMMAND fields for WishBone
 
 
   Check that a WRITE_COMMAND's fields are valid for WishBone access.
   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
   - 16 and 32-bit access must be correctly aligned. If not a warning is
     printed and validation fails.
     printed and validation fails.
 
 
   - size must be a multiple of 2 for 16-bit access, and a multiple of 4 for
   - size must be a multiple of 2 for 16-bit access, and a multiple of 4 for
     32-bit access
     32-bit access
 
 
   Validation is carried out when executing a GO_COMMAND, rather than when
   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
   setting the WRITE_COMMAND, because only the GO_COMMAND can set the status
   error if there is a problem.
   error if there is a problem.
 
 
   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 validation is OK, 0 (FALSE) if validation fails.     */
   @return  1 (TRUE) if validation is OK, 0 (FALSE) if validation fails.     */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static int
static int
validate_wb_fields ()
validate_wb_fields ()
{
{
  /* Determine the size of the access */
  /* Determine the size of the access */
  uint32_t  access_bits;
  uint32_t  access_bits;
 
 
  switch (runtime.debug.acc_type)
  switch (runtime.debug.acc_type)
    {
    {
    case JAT_WRITE8:
    case JAT_WRITE8:
    case JAT_READ8:
    case JAT_READ8:
      access_bits =  8;
      access_bits =  8;
      break;
      break;
 
 
    case JAT_WRITE16:
    case JAT_WRITE16:
    case JAT_READ16:
    case JAT_READ16:
      access_bits = 16;
      access_bits = 16;
      break;
      break;
 
 
    case JAT_WRITE32:
    case JAT_WRITE32:
    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;
 
 
  if (0 != (runtime.debug.addr % access_bytes))
  if (0 != (runtime.debug.addr % access_bytes))
    {
    {
      fprintf (stderr, "Warning: JTAG WishBone %d-bit access must be %d-byte "
      fprintf (stderr, "Warning: JTAG WishBone %d-bit access must be %d-byte "
               "aligned\n", access_bits, access_bytes);
               "aligned\n", access_bits, access_bytes);
      return  0;
      return  0;
    }
    }
  else if (0 != (runtime.debug.size % access_bytes))
  else if (0 != (runtime.debug.size % access_bytes))
    {
    {
      fprintf (stderr, "Warning: JTAG %d-bit WishBone access must be multiple "
      fprintf (stderr, "Warning: JTAG %d-bit WishBone access must be multiple "
               "of %d bytes in length\n", access_bits, access_bytes);
               "of %d bytes in length\n", access_bits, access_bytes);
      return  0;
      return  0;
    }
    }
  else
  else
    {
    {
      return  1;                        /* No problems */
      return  1;                        /* No problems */
    }
    }
}       /* validate_wb_fields () */
}       /* 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 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
         original WRITE_COMMAND.
         original WRITE_COMMAND.
 
 
   @todo For now we always read a byte a time. In the future, we ought to use
   @todo For now we always read 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.
 
 
   @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.
 
 
   @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]  skip_bits   Bits to skip before storing data in jreg.
   @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 int      skip_bits,
               enum jtag_status *status_ptr)
               enum jtag_status *status_ptr)
{
{
  /* 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 wishbone read. If this fails we stop here,
  /* Validate the fields for the wishbone read. If this fails we stop here,
     setting an error in the status_ptr. */
     setting an error in the status_ptr. */
  if (!validate_wb_fields())
  if (!validate_wb_fields())
    {
    {
      *status_ptr |= JS_WISHBONE_ERROR;
      *status_ptr |= JS_WISHBONE_ERROR;
      return  crc_out;
      return  crc_out;
    }
    }
 
 
  /* Transfer each byte in turn, computing the CRC as we go */
  /* Transfer each byte in turn, computing the CRC as we go */
  unsigned  byte_off = skip_bits / 8;
  unsigned  byte_off = skip_bits / 8;
  unsigned  bit_off  = skip_bits % 8;
  unsigned  bit_off  = skip_bits % 8;
 
 
  uint32_t  i;                          /* Index into the data being read */
  uint32_t  i;                          /* Index into the data being read */
 
 
  for (i = 0; i < runtime.debug.size; i++)
  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;
          return  crc_out;
        }
        }
 
 
      /* 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
        {
        {
          /* Clear the bits (only) we are setting */
          /* Clear the bits (only) we are setting */
          jreg[byte_off + i]     <<= bit_off;
          jreg[byte_off + i]     <<= bit_off;
          jreg[byte_off + i]     >>= bit_off;
          jreg[byte_off + i]     >>= bit_off;
          jreg[byte_off + i + 1] >>= 8 - bit_off;
          jreg[byte_off + i + 1] >>= 8 - bit_off;
          jreg[byte_off + i + 1] <<= 8 - bit_off;
          jreg[byte_off + i + 1] <<= 8 - 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;
        }
        }
    }
    }
 
 
    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
/*!Validate WRITE_COMMAND fields for SPR
 
 
   Check that a WRITE_COMMAND's fields are valid for SPR access. Only prints
   Check that a WRITE_COMMAND's fields are valid for SPR access. Only prints
   messages, since the protocol does not allow for any errors.
   messages, since the protocol does not allow for any errors.
 
 
   - 8 and 16-bit access is only permitted for WishBone. If they are specified
   - 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
     for SPR, they are treated as their 32 bit equivalent. A warning is
     printed.
     printed.
 
 
   - size must be 1 word. If a larger value is specified that is treated as 1
   - size must be 1 word. If a larger value is specified that is treated as 1
     with a warning.
     with a warning.
 
 
   - address must be less than MAX_SPRS. If a larger value is specified, it is
   - 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).
     reduced module MAX_SPRS (which is hopefully a power of 2).
 
 
   Where errors are found, the data is updated.
   Where errors are found, the data is updated.
 
 
   Validation is carried out with the GO_COMMAND, rather than with the
   Validation is carried out with the GO_COMMAND, rather than with the
   WRITE_COMMAND, for consistency with WishBone error checking, for which
   WRITE_COMMAND, for consistency with WishBone error checking, for which
   only the GO_COMMAND can set the status error if there is a problem.
   only the GO_COMMAND can set the status error if there is a problem.
 
 
   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)
    {
    {
      fprintf (stderr, "Warning: JTAG %d-bit access not permitted for SPR: "
      fprintf (stderr, "Warning: JTAG %d-bit access not permitted for SPR: "
               "corrected\n", access_bits);
               "corrected\n", access_bits);
      runtime.debug.acc_type = is_read_p ? JAT_READ32 : JAT_WRITE32;
      runtime.debug.acc_type = is_read_p ? JAT_READ32 : JAT_WRITE32;
    }
    }
 
 
  /* 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
 
 
   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 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.
 
 
   @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.
 
 
   @note The address is treated as a word address of the SPR.
   @note The address is treated as a word address of the SPR.
 
 
   @note The debug unit is documented as being explicitly Big Endian. However
   @note The debug unit is documented as being explicitly Big Endian. However
         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]  skip_bits  Bits to skip before storing data in jreg.
 
 
   @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 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
     we go. */
     we go. */
  unsigned  byte_off = skip_bits / 8;
  unsigned  byte_off = skip_bits / 8;
  unsigned  bit_off  = skip_bits % 8;
  unsigned  bit_off  = skip_bits % 8;
 
 
  if (0 == bit_off)
  if (0 == bit_off)
    {
    {
      /* Each byte in turn */
      /* Each byte in turn */
      int  i;
      int  i;
 
 
      for (i = 0; i < 4; i++)
      for (i = 0; i < 4; i++)
        {
        {
#ifdef OR32_BIG_ENDIAN
#ifdef OR32_BIG_ENDIAN
          uint8_t byte = (spr >> 8 * i) & 0xff;
          uint8_t byte = (spr >> 8 * i) & 0xff;
#else /* !OR32_BIG_ENDIAN */
#else /* !OR32_BIG_ENDIAN */
          uint8_t byte = (spr >> (24 - (8 * i))) & 0xff;
          uint8_t byte = (spr >> (24 - (8 * i))) & 0xff;
#endif /* OR32_BIG_ENDIAN */
#endif /* OR32_BIG_ENDIAN */
 
 
          jreg[byte_off + i] =  byte;
          jreg[byte_off + i] =  byte;
          crc_out = crc32 (byte, 8, crc_out);
          crc_out = crc32 (byte, 8, crc_out);
        }
        }
    }
    }
  else
  else
    {
    {
      /* Each byte in turn */
      /* Each byte in turn */
      int  i;
      int  i;
 
 
      for (i = 0; i < 4; i++)
      for (i = 0; i < 4; i++)
        {
        {
#ifdef OR32_BIG_ENDIAN
#ifdef OR32_BIG_ENDIAN
          uint8_t byte = (spr >> 8 * i) & 0xff;
          uint8_t byte = (spr >> 8 * i) & 0xff;
#else /* !OR32_BIG_ENDIAN */
#else /* !OR32_BIG_ENDIAN */
          uint8_t byte = (spr >> (24 - (8 * i))) & 0xff;
          uint8_t byte = (spr >> (24 - (8 * i))) & 0xff;
#endif /* OR32_BIG_ENDIAN */
#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]     <<= bit_off;
          jreg[byte_off + i]     >>= bit_off;
          jreg[byte_off + i]     >>= bit_off;
          jreg[byte_off + i + 1] >>= 8 - bit_off;
          jreg[byte_off + i + 1] >>= 8 - bit_off;
          jreg[byte_off + i + 1] <<= 8 - bit_off;
          jreg[byte_off + i + 1] <<= 8 - 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);
          crc_out = crc32 (byte, 8, crc_out);
        }
        }
    }
    }
 
 
  return  crc_out;
  return  crc_out;
 
 
}       /* spr_read () */
}       /* spr_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:
 
 
          +-------------+-------+---------+---+
          +-------------+-------+---------+---+
          |             |       |    GO   |   |
          |             |       |    GO   |   |
   TDI -> |   Ignored   |  CRC  | COMMAND | 0 | -> TDO
   TDI -> |   Ignored   |  CRC  | COMMAND | 0 | -> TDO
          |             |       |  (0x0)  |   |
          |             |       |  (0x0)  |   |
          +-------------+-------+---------+---+
          +-------------+-------+---------+---+
           36 + 8 * size    32       4
           36 + 8 * size    32       4
               bits        bits    bits
               bits        bits    bits
 
 
   The returned register has the format:
   The returned register has the format:
 
 
          +-------+--------+------------+---------+
          +-------+--------+------------+---------+
          |       |        |            |         |
          |       |        |            |         |
   TDI -> |  CRC  | Status |    Data    |  00..00 | -> TDO
   TDI -> |  CRC  | Status |    Data    |  00..00 | -> TDO
          |       |        |            |         |
          |       |        |            |         |
          +-------+--------+------------+---------+
          +-------+--------+------------+---------+
              32       4      8 * size       37
              32       4      8 * size       37
             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 5 bits, the CRC out on the 4 + 8 * size status and
   is computed on the first 5 bits, the CRC out on the 4 + 8 * size status and
   data bits.
   data bits.
 
 
   @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.
 
 
   @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 int
go_command_read (unsigned char *jreg)
go_command_read (unsigned char *jreg)
{
{
  /* 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) |
                                     ((uint32_t) (jreg[4] & 0x1f) << 27), 32);
                                     ((uint32_t) (jreg[4] & 0x1f) << 27), 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);
 
 
  /* Status flags */
  /* Status flags */
  enum jtag_status  status = JS_OK;
  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. */
      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, 37, &status);
          break;
          break;
 
 
        case JM_CPU0:
        case JM_CPU0:
          crc_out = spr_read (jreg, 37);
          crc_out = spr_read (jreg, 37);
          break;
          break;
 
 
        case JM_CPU1:
        case JM_CPU1:
          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 */
      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,
  return  construct_response (jreg, status, crc_out, 8 * runtime.debug.size,
                              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.
 
 
   @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.
 
 
   @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.
 
 
   @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 reading data from jreg.
   @param[in]  skip_bits   Bits to skip before reading data from jreg.
   @param[in]  status_ptr  Pointer to the status register.                   */
   @param[in]  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 int      skip_bits,
               enum jtag_status *status_ptr)
               enum jtag_status *status_ptr)
{
{
  /* Validate the fields for the wishbone write. If this fails we stop here,
  /* Validate the fields for the wishbone write. If this fails we stop here,
     setting an error in the status_ptr. */
     setting an error in the status_ptr. */
  if (!validate_wb_fields())
  if (!validate_wb_fields())
    {
    {
      *status_ptr |= JS_WISHBONE_ERROR;
      *status_ptr |= JS_WISHBONE_ERROR;
      return;
      return;
    }
    }
 
 
  /* Transfer each byte in turn, computing the CRC as we go */
  /* Transfer each byte in turn, computing the CRC as we go */
  unsigned  byte_off = skip_bits / 8;
  unsigned  byte_off = skip_bits / 8;
  unsigned  bit_off  = skip_bits % 8;
  unsigned  bit_off  = skip_bits % 8;
 
 
  uint32_t  i;                          /* Index into the data being write */
  uint32_t  i;                          /* Index into the data being write */
 
 
  for (i = 0; i < runtime.debug.size; i++)
  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;
          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 () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!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.
 
 
   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.
   writeing 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.
 
 
   @note The address is treated as a word address of the SPR.
   @note The address is treated as a word address of the SPR.
 
 
   @note The debug unit is documented as being explicitly Big Endian. However
   @note The debug unit is documented as being explicitly Big Endian. However
         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]  skip_bits  Bits to skip before reading data from jreg.        */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
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;
  unsigned  bit_off  = skip_bits % 8;
  unsigned  bit_off  = skip_bits % 8;
 
 
  /* Each byte in turn */
  /* Each byte in turn */
  int  i;
  int  i;
 
 
  for (i = 0; i < 4; i++)
  for (i = 0; i < 4; i++)
    {
    {
      uint8_t byte;
      uint8_t byte;
 
 
      /* Simplified version when the bit offset is zero */
      /* Simplified version when the bit offset is zero */
      if (0 == bit_off)
      if (0 == bit_off)
        {
        {
          byte = reverse_byte (jreg[byte_off + i]);
          byte = reverse_byte (jreg[byte_off + i]);
        }
        }
      else
      else
        {
        {
          byte = reverse_byte ((jreg[byte_off + i]     >>      bit_off) |
          byte = reverse_byte ((jreg[byte_off + i]     >>      bit_off) |
                               (jreg[byte_off + i + 1] << (8 - 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++;
  runtime.debug.addr++;
 
 
}       /* spr_write () */
}       /* spr_write () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Carry out a write to WishBone or SPR
/*!Carry out a write to WishBone or SPR
 
 
   Process a GO_COMMAND register for write. The format is:
   Process a GO_COMMAND register for write. The format is:
 
 
          +-------------+-------+------------+---------+---+
          +-------------+-------+------------+---------+---+
          |             |       |            |    GO   |   |
          |             |       |            |    GO   |   |
   TDI -> |   Ignored   |  CRC  |    Data    | COMMAND | 0 | -> TDO
   TDI -> |   Ignored   |  CRC  |    Data    | COMMAND | 0 | -> TDO
          |             |       |            |  (0x0)  |   |
          |             |       |            |  (0x0)  |   |
          +-------------+-------+------------+---------+---+
          +-------------+-------+------------+---------+---+
                36          32     8 * size       4
                36          32     8 * size       4
               bits        bits      bits       bits
               bits        bits      bits       bits
 
 
   The returned register has the format:
   The returned register has the format:
 
 
          +-------+--------+-------------+
          +-------+--------+-------------+
          |       |        |             |
          |       |        |             |
   TDI -> |  CRC  | Status |  00......00 | -> TDO
   TDI -> |  CRC  | Status |  00......00 | -> TDO
          |       |        |             |
          |       |        |             |
          +-------+--------+-------------+
          +-------+--------+-------------+
              32       4    8 * size + 37
              32       4    8 * size + 37
             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 5 + 8 * size bits, the CRC out on the 4 status
   is computed on the first 5 + 8 * size bits, the CRC out on the 4 status
   bits.
   bits.
 
 
   @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 The rules say we look for errors in the WRITE_COMMAND spec
   @todo The rules say we look for errors in the WRITE_COMMAND spec
         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.
 
 
   @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 int
go_command_write (unsigned char *jreg)
go_command_write (unsigned char *jreg)
{
{
  /* 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[runtime.debug.size + 0] & 0xe0) >>  5) |
                  ((uint32_t)  jreg[runtime.debug.size + 1]         <<  3) |
                  ((uint32_t)  jreg[runtime.debug.size + 1]         <<  3) |
                  ((uint32_t)  jreg[runtime.debug.size + 2]         << 11) |
                  ((uint32_t)  jreg[runtime.debug.size + 2]         << 11) |
                  ((uint32_t)  jreg[runtime.debug.size + 3]         << 19) |
                  ((uint32_t)  jreg[runtime.debug.size + 3]         << 19) |
                  ((uint32_t) (jreg[runtime.debug.size + 4] & 0x1f) << 27),
                  ((uint32_t) (jreg[runtime.debug.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;
  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;
 
 
  /* Validate the CRC */
  /* Validate the CRC */
  if (crc_computed == crc_in)
  if (crc_computed == crc_in)
    {
    {
      /* Read the data. */
      /* Read the data. */
      switch (runtime.debug.mod_id)
      switch (runtime.debug.mod_id)
        {
        {
        case JM_WISHBONE:
        case JM_WISHBONE:
          wishbone_write (jreg, 5, &status);
          wishbone_write (jreg, 5, &status);
          break;
          break;
 
 
        case JM_CPU0:
        case JM_CPU0:
          spr_write (jreg, 5);
          spr_write (jreg, 5);
          break;
          break;
 
 
        case JM_CPU1:
        case JM_CPU1:
          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 */
      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,
  return  construct_response (jreg, status, 0xffffffff, 0,
                              37 + 8 * runtime.debug.size);
                              37 + 8 * runtime.debug.size);
 
 
}       /* go_command_write () */
}       /* go_command_write () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Invoke the action specified by a prior WRITE_COMMAND register
/*!Invoke the action specified by a prior WRITE_COMMAND register
 
 
   Process a GO_COMMAND register.
   Process a GO_COMMAND register.
 
 
   How this is handled depends on whether a previous WRITE_COMMAND has
   How this is handled depends on whether a previous WRITE_COMMAND has
   selected a read access type or a write access type has been selected.
   selected a read access type or a write access type has been selected.
 
 
   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.
 
 
   @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 int
go_command (unsigned char *jreg)
go_command (unsigned char *jreg)
{
{
  /* 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: "
      fprintf (stderr, "Warning: JTAG GO_COMMAND with no prior WRITE_COMMAND: "
               "ignored\n");
               "ignored\n");
      return 4 + 1;                     /* Only the first 5 bits meaningful */
      return 4 + 1;                     /* Only the first 5 bits meaningful */
    }
    }
 
 
  /* Whether to read or write depends on the access type */
  /* Whether to read or write depends on the access type */
  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);
      return  go_command_write (jreg);
 
 
    case JAT_READ8:
    case JAT_READ8:
    case JAT_READ16:
    case JAT_READ16:
    case JAT_READ32:
    case JAT_READ32:
      return  go_command_read (jreg);
      return  go_command_read (jreg);
 
 
    default:
    default:
      fprintf (stderr, "Warning: JTAG GO_COMMAND: invalid access type: "
      fprintf (stderr, "Warning: JTAG GO_COMMAND: invalid access type: "
               "ignored\n");
               "ignored\n");
      return 4 + 1;                     /* Only the first 5 bits meaningful */
      return 4 + 1;                     /* Only the first 5 bits meaningful */
    }
    }
}       /* go_command () */
}       /* go_command () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Read a previouse WRITE_COMMAND register
/*!Read a previouse WRITE_COMMAND register
 
 
   Process a READ_COMMAND register. The format is:
   Process a READ_COMMAND register. The format is:
 
 
          +---------+-------+---------+---+
          +---------+-------+---------+---+
          |         |       |   READ  |   |
          |         |       |   READ  |   |
   TDI -> | Ignored |  CRC  | COMMAND | 0 | -> TDO
   TDI -> | Ignored |  CRC  | COMMAND | 0 | -> TDO
          |         |       |  (0x1)  |   |
          |         |       |  (0x1)  |   |
          +---------+-------+---------+---+
          +---------+-------+---------+---+
              88        32       4
              88        32       4
             bits      bits    bits
             bits      bits    bits
 
 
   The returned register has the format:
   The returned register has the format:
 
 
          +-------+--------+--------+---------+--------+---------+
          +-------+--------+--------+---------+--------+---------+
          |       |        |        |         |        |         |
          |       |        |        |         |        |         |
   TDI -> |  CRC  | Status | Length | Address | Access |  00..00 | -> TDO
   TDI -> |  CRC  | Status | Length | Address | Access |  00..00 | -> TDO
          |       |        |        |         |  Type  |         |
          |       |        |        |         |  Type  |         |
          +-------+--------+--------+---------+--------+---------+
          +-------+--------+--------+---------+--------+---------+
              32       4       16        32        4        37
              32       4       16        32        4        37
             bits    bits     bits      bits     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 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.
 
 
   @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.
 
 
   @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 int
read_command (unsigned char *jreg)
read_command (unsigned char *jreg)
{
{
  /* 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) |
                                     ((uint32_t) (jreg[4] & 0x1f) << 27), 32);
                                     ((uint32_t) (jreg[4] & 0x1f) << 27), 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_READ_COMMAND,  4, crc_computed);
  crc_computed = crc32 (JCMD_READ_COMMAND,  4, crc_computed);
 
 
  /* CRC to go out */
  /* CRC to go out */
  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 */
  /* Validate the CRC */
  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);
 
 
}       /* read_command () */
}       /* read_command () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Specify details for a subsequence GO_COMMAND
/*!Specify details for a subsequence GO_COMMAND
 
 
   Process a WRITE_COMMAND register. The format is:
   Process a WRITE_COMMAND register. The format is:
 
 
          +---------+-------+--------+---------+--------+---------+---+
          +---------+-------+--------+---------+--------+---------+---+
          |         |       |        |         |        |  WRITE  |   |
          |         |       |        |         |        |  WRITE  |   |
   TDI -> | Ignored |  CRC  | Length | Address | Access | COMMAND | 0 | -> TDO
   TDI -> | Ignored |  CRC  | Length | Address | Access | COMMAND | 0 | -> TDO
          |         |       |        |         |  Type  |  (0x2)  |   |
          |         |       |        |         |  Type  |  (0x2)  |   |
          +---------+-------+--------+---------+--------+---------+---+
          +---------+-------+--------+---------+--------+---------+---+
              36        32      16        32        4         4
              36        32      16        32        4         4
             bits      bits    bits      bits     bits      bits
             bits      bits    bits      bits     bits      bits
 
 
   The returned register has the format:
   The returned register has the format:
 
 
          +-------+--------+---------+
          +-------+--------+---------+
          |       |        |         |
          |       |        |         |
   TDI -> |  CRC  | Status |  00..00 | -> TDO
   TDI -> |  CRC  | Status |  00..00 | -> TDO
          |       |        |         |
          |       |        |         |
          +-------+--------+---------+
          +-------+--------+---------+
              32       4        89
              32       4        89
             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.
 
 
   @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.
 
 
   @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 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);
  uint16_t  len      = reverse_bits (((uint32_t) (jreg[ 5] & 0xfe) >>  1) |
  uint16_t  len      = reverse_bits (((uint32_t) (jreg[ 5] & 0xfe) >>  1) |
                                     ((uint32_t)  jreg[ 6]         <<  7) |
                                     ((uint32_t)  jreg[ 6]         <<  7) |
                                     ((uint32_t) (jreg[ 7] & 0x01) << 15), 16);
                                     ((uint32_t) (jreg[ 7] & 0x01) << 15), 16);
  uint32_t  crc_in   = reverse_bits (((uint32_t) (jreg[ 7] & 0xfe) >>  1) |
  uint32_t  crc_in   = reverse_bits (((uint32_t) (jreg[ 7] & 0xfe) >>  1) |
                                     ((uint32_t)  jreg[ 8]         <<  7) |
                                     ((uint32_t)  jreg[ 8]         <<  7) |
                                     ((uint32_t)  jreg[ 9]         << 15) |
                                     ((uint32_t)  jreg[ 9]         << 15) |
                                     ((uint32_t)  jreg[10]         << 23) |
                                     ((uint32_t)  jreg[10]         << 23) |
                                     ((uint32_t) (jreg[11] & 0x01) << 31), 32);
                                     ((uint32_t) (jreg[11] & 0x01) << 31), 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_WRITE_COMMAND,  4, crc_computed);
  crc_computed = crc32 (JCMD_WRITE_COMMAND,  4, crc_computed);
  crc_computed = crc32 (acc_type,            4, crc_computed);
  crc_computed = crc32 (acc_type,            4, crc_computed);
  crc_computed = crc32 (addr,               32, crc_computed);
  crc_computed = crc32 (addr,               32, crc_computed);
  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 */
  /* Validate the CRC */
  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
  else
    {
    {
      /* All OK. All other errors can only occur when the GO_COMMAND tries to
      /* All OK. All other errors can only occur when the GO_COMMAND tries to
         execute the write. Record the information for next GO_COMMAND */
         execute the write. Record the information for next GO_COMMAND */
      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;
      runtime.debug.size            = (unsigned long int) len + 1UL;
      runtime.debug.size            = (unsigned long int) len + 1UL;
    }
    }
 
 
  /* 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, 89);
  return  construct_response (jreg, status, 0xffffffff, 0, 89);
 
 
}       /* write_command () */
}       /* write_command () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Read the control bits from a CPU.
/*!Read the control bits from a CPU.
 
 
   Process a READ_CONTROL register. The format is:
   Process a READ_CONTROL register. The format is:
 
 
          +---------+-------+---------+---+
          +---------+-------+---------+---+
          |         |       |  READ   |   |
          |         |       |  READ   |   |
   TDI -> | Ignored |  CRC  | CONTROL | 0 | -> TDO
   TDI -> | Ignored |  CRC  | CONTROL | 0 | -> TDO
          |         |       |  (0x3)  |   |
          |         |       |  (0x3)  |   |
          +---------+-------+---------+---+
          +---------+-------+---------+---+
              36        32       4
              36        32       4
             bits      bits    bits
             bits      bits    bits
 
 
   The returned register has the format:
   The returned register has the format:
 
 
          +-------+--------+--------+---------+
          +-------+--------+--------+---------+
          |       |        |        |         |
          |       |        |        |         |
   TDI -> |  CRC  | Status |  Data  |  00..00 | -> TDO
   TDI -> |  CRC  | Status |  Data  |  00..00 | -> TDO
          |       |        |        |         |
          |       |        |        |         |
          +-------+--------+--------+---------+
          +-------+--------+--------+---------+
              32       4       52        37
              32       4       52        37
             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.
 
 
   @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.
 
 
   @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 int
read_control (unsigned char *jreg)
read_control (unsigned char *jreg)
{
{
  /* 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) |
                                   ((uint32_t) (jreg[4] & 0x1f) << 27), 32);
                                   ((uint32_t) (jreg[4] & 0x1f) << 27), 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_READ_CONTROL,  4, crc_computed);
  crc_computed = crc32 (JCMD_READ_CONTROL,  4, crc_computed);
 
 
  /* CRC to go out */
  /* CRC to go out */
  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 */
  /* Validate the CRC */
  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 (JM_CPU0 == runtime.debug.mod_id)
  else if (JM_CPU0 == runtime.debug.mod_id)
    {
    {
      /* Valid module. Only bit we can sensibly read is the stall bit. */
      /* Valid module. Only bit we can sensibly read is the stall bit. */
      uint64_t  data = (uint64_t) runtime.cpu.stalled << JCB_STALL;
      uint64_t  data = (uint64_t) runtime.cpu.stalled << JCB_STALL;
 
 
      /* Compute the CRC */
      /* Compute the CRC */
      crc_out = crc32 (data,  52, crc_out);
      crc_out = crc32 (data,  52, crc_out);
 
 
      /* Construct the outgoing register. */
      /* Construct the outgoing register. */
      uint64_t  data_r = reverse_bits (data, 52);
      uint64_t  data_r = reverse_bits (data, 52);
 
 
      jreg[ 4] |= (data_r <<  5) & 0xf8;
      jreg[ 4] |= (data_r <<  5) & 0xf8;
      jreg[ 5] |= (data_r >>  3) & 0x07;
      jreg[ 5] |= (data_r >>  3) & 0x07;
      jreg[ 5] |= (data_r >> 11) & 0xff;
      jreg[ 5] |= (data_r >> 11) & 0xff;
      jreg[ 5] |= (data_r >> 19) & 0xff;
      jreg[ 5] |= (data_r >> 19) & 0xff;
      jreg[ 5] |= (data_r >> 27) & 0xff;
      jreg[ 5] |= (data_r >> 27) & 0xff;
      jreg[ 5] |= (data_r >> 35) & 0xff;
      jreg[ 5] |= (data_r >> 35) & 0xff;
      jreg[ 5] |= (data_r >> 43) & 0xff;
      jreg[ 5] |= (data_r >> 43) & 0xff;
      jreg[ 5] |= (data_r >> 51) & 0x01;
      jreg[ 5] |= (data_r >> 51) & 0x01;
    }
    }
  else
  else
    {
    {
      /* Not a valid module */
      /* Not a valid module */
      fprintf (stderr, "ERROR: JTAG attempt to read control data for module "
      fprintf (stderr, "ERROR: JTAG attempt to read control data for module "
               "other than CPU0: ignored\n");
               "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 () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Write the control bits to a CPU.
/*!Write the control bits to a CPU.
 
 
   Process a WRITE_CONTROL register. The format is:
   Process a WRITE_CONTROL register. The format is:
 
 
          +---------+-------+--------+---------+---+
          +---------+-------+--------+---------+---+
          |         |       |        |  WRITE  |   |
          |         |       |        |  WRITE  |   |
   TDI -> | Ignored |  CRC  |  Data  | CONTROL | 0 | -> TDO
   TDI -> | Ignored |  CRC  |  Data  | CONTROL | 0 | -> TDO
          |         |       |        |  (0x4)  |   |
          |         |       |        |  (0x4)  |   |
          +---------+-------+--------+---------+---+
          +---------+-------+--------+---------+---+
              36        32      52        4
              36        32      52        4
             bits      bits    bits     bits
             bits      bits    bits     bits
 
 
   The returned register has the format:
   The returned register has the format:
 
 
          +-------+--------+---------+
          +-------+--------+---------+
          |       |        |         |
          |       |        |         |
   TDI -> |  CRC  | Status |  00..00 | -> TDO
   TDI -> |  CRC  | Status |  00..00 | -> TDO
          |       |        |         |
          |       |        |         |
          +-------+--------+---------+
          +-------+--------+---------+
              32       4        89
              32       4        89
             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.
 
 
   @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.
 
 
   @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 int
write_control (unsigned char *jreg)
write_control (unsigned char *jreg)
{
{
  /* 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) |
                                   ((uint64_t)  jreg[ 4]         << 27) |
                                   ((uint64_t)  jreg[ 4]         << 27) |
                                   ((uint64_t)  jreg[ 5]         << 35) |
                                   ((uint64_t)  jreg[ 5]         << 35) |
                                   ((uint64_t)  jreg[ 6]         << 43) |
                                   ((uint64_t)  jreg[ 6]         << 43) |
                                   ((uint64_t) (jreg[ 7] & 0x01) << 51), 52);
                                   ((uint64_t) (jreg[ 7] & 0x01) << 51), 52);
  uint32_t  crc_in = reverse_bits (((uint32_t) (jreg[ 7] & 0xfe) >>  1) |
  uint32_t  crc_in = reverse_bits (((uint32_t) (jreg[ 7] & 0xfe) >>  1) |
                                   ((uint32_t)  jreg[ 8]         <<  7) |
                                   ((uint32_t)  jreg[ 8]         <<  7) |
                                   ((uint32_t)  jreg[ 9]         << 15) |
                                   ((uint32_t)  jreg[ 9]         << 15) |
                                   ((uint32_t)  jreg[10]         << 23) |
                                   ((uint32_t)  jreg[10]         << 23) |
                                   ((uint32_t) (jreg[11] & 0x01) << 31), 32);
                                   ((uint32_t) (jreg[11] & 0x01) << 31), 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_WRITE_CONTROL,  4, crc_computed);
  crc_computed = crc32 (JCMD_WRITE_CONTROL,  4, crc_computed);
  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 */
  /* Validate the CRC */
  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 (JM_CPU0 == runtime.debug.mod_id)
  else if (JM_CPU0 == runtime.debug.mod_id)
    {
    {
      /* Good data and valid module. Reset, stall or unstall the register as
      /* Good data and valid module. Reset, stall or unstall the register as
         required. If reset is requested, there is no point considering
         required. If reset is requested, there is no point considering
         stalling! */
         stalling! */
      int  reset_bit = (0x1 == ((data >> JCB_RESET) & 0x1));
      int  reset_bit = (0x1 == ((data >> JCB_RESET) & 0x1));
      int  stall_bit = (0x1 == ((data >> JCB_STALL) & 0x1));
      int  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);
        }
        }
    }
    }
  else
  else
    {
    {
      /* Not a valid module */
      /* Not a valid module */
      fprintf (stderr, "ERROR: JTAG attempt to control module other than "
      fprintf (stderr, "ERROR: JTAG attempt to control module other than "
               "CPU0: ignored\n");
               "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);
 
 
}       /* write_control () */
}       /* write_control () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Initialize the JTAG system
/*!Initialize the JTAG system
 
 
   For now just reset the JTAG interface                                     */
   For now just reset the JTAG interface                                     */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
void
void
jtag_init ()
jtag_init ()
{
{
  (void) jtag_reset ();
  (void) jtag_reset ();
 
 
}       /* jtag_init () */
}       /* jtag_init () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!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.                             */
   @return  The number of cycles the reset took.                             */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
int
int
jtag_reset ()
jtag_reset ()
{
{
  runtime.debug.instr = JI_UNDEFINED;
  runtime.debug.instr = JI_UNDEFINED;
 
 
  return  JTAG_RESET_CYCLES;
  return  JTAG_RESET_CYCLES;
 
 
}       /* jtag_reset () */
}       /* jtag_reset () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Shift a JTAG instruction register
/*!Shift a JTAG instruction register
 
 
   @note Like all the JTAG interface functions, this must not be called
   @note Like all the JTAG interface functions, this must not be called
         re-entrantly while a call to any other function (e.g. or1kim_run ())
         re-entrantly while a call to any other function (e.g. or1kim_run ())
         is in progress. It is the responsibility of the caller to ensure this
         is in progress. It is the responsibility of the caller to ensure this
         constraint is met, for example by use of a SystemC mutex.
         constraint is met, for example by use of a SystemC mutex.
 
 
   The register is represented as a vector of bytes, with the byte at offset
   The register is represented as a vector of bytes, with the byte at offset
   zero being shifted first, and the least significant bit in each byte being
   zero being shifted first, and the least significant bit in each byte being
   shifted first. Where the register will not fit in an exact number of bytes,
   shifted first. Where the register will not fit in an exact number of bytes,
   the odd bits are in the highest numbered byte, shifted to the low end.
   the odd bits are in the highest numbered byte, shifted to the low end.
 
 
   The format is:
   The format is:
 
 
          +-------------+
          +-------------+
          |             |
          |             |
   TDI -> | Instruction | -> TDO
   TDI -> | Instruction | -> TDO
          |             |
          |             |
          +-------------+
          +-------------+
                 4
                 4
               bits
               bits
 
 
   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.
 
 
   @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                                          */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
int
int
jtag_shift_ir (unsigned char *jreg)
jtag_shift_ir (unsigned char *jreg)
{
{
  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 %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 */
 
 
}       /* jtag_shift_ir () */
}       /* jtag_shift_ir () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Shift a JTAG data register
/*!Shift a JTAG data register
 
 
   @note Like all the JTAG interface functions, this must not be called
   @note Like all the JTAG interface functions, this must not be called
         re-entrantly while a call to any other function (e.g. or1kim_run ())
         re-entrantly while a call to any other function (e.g. or1kim_run ())
         is in progress. It is the responsibility of the caller to ensure this
         is in progress. It is the responsibility of the caller to ensure this
         constraint is met, for example by use of a SystemC mutex.
         constraint is met, for example by use of a SystemC mutex.
 
 
   The register is represented as a vector of bytes, with the byte at offset
   The register is represented as a vector of bytes, with the byte at offset
   zero being shifted first, and the least significant bit in each byte being
   zero being shifted first, and the least significant bit in each byte being
   shifted first. Where the register will not fit in an exact number of bytes,
   shifted first. Where the register will not fit in an exact number of bytes,
   the odd bits are in the highest numbered byte, shifted to the low end.
   the odd bits are in the highest numbered byte, shifted to the low end.
 
 
   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
   - MODULE_SELECT
   - 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.
   MODULE_SELECT, 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.
 
 
   @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                                          */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
int
int
jtag_shift_dr (unsigned char *jreg)
jtag_shift_dr (unsigned char *jreg)
{
{
  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: ignored\n");
      return  0;
      return  0;
    }
    }
 
 
  int  module_select_p = (1 == (jreg[0] & 0x1));
  int  module_select_p = (1 == (jreg[0] & 0x1));
 
 
  if (module_select_p)
  if (module_select_p)
    {
    {
      return  module_select (jreg);
      return  module_select (jreg);
    }
    }
  else
  else
    {
    {
      enum jtag_cmd  cmd = reverse_bits ((jreg[0] >> 1) & 0xf, 4);
      enum jtag_cmd  cmd = reverse_bits ((jreg[0] >> 1) & 0xf, 4);
 
 
      switch (cmd)
      switch (cmd)
        {
        {
        case JCMD_GO_COMMAND:    return  go_command (jreg);
        case JCMD_GO_COMMAND:    return  go_command (jreg);
        case JCMD_READ_COMMAND:  return  read_command (jreg);
        case JCMD_READ_COMMAND:  return  read_command (jreg);
        case JCMD_WRITE_COMMAND: return  write_command (jreg);
        case JCMD_WRITE_COMMAND: return  write_command (jreg);
        case JCMD_READ_CONTROL:  return  read_control (jreg);
        case JCMD_READ_CONTROL:  return  read_control (jreg);
        case JCMD_WRITE_CONTROL: return  write_control (jreg);
        case JCMD_WRITE_CONTROL: return  write_control (jreg);
 
 
        default:
        default:
          /* Not a command we recognize. Decide this after we've read just
          /* Not a command we recognize. Decide this after we've read just
             the module and command bits */
             the module and command bits */
          return  4 + 1;
          return  4 + 1;
        }
        }
    }
    }
}       /* jtag_shift_dr () */
}       /* jtag_shift_dr () */
 
 

powered by: WebSVN 2.1.0

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