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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [jtag/] [jp2.c] - Diff between revs 1380 and 1765

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

Rev 1380 Rev 1765
/* jp2-linux.c -- JTAG protocol via parallel port for linux
/* jp2-linux.c -- JTAG protocol via parallel port for linux
   Copyright(C) 2001 Marko Mlinar, markom@opencores.org
   Copyright(C) 2001 Marko Mlinar, markom@opencores.org
   Code for TCP/IP copied from gdb, by Chris Ziomkowski
   Code for TCP/IP copied from gdb, by Chris Ziomkowski
 
 
This file is part of OpenRISC 1000 Architectural Simulator.
This file is part of OpenRISC 1000 Architectural Simulator.
 
 
This program is free software; you can redistribute it and/or modify
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
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
(at your option) any later version.
 
 
This program is distributed in the hope that it will be useful,
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
GNU General Public License for more details.
 
 
You should have received a copy of the GNU General Public License
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 
/* Establishes jtag proxy server and communicates with parallel
/* Establishes jtag proxy server and communicates with parallel
 port directly.  Requires root access. */
 port directly.  Requires root access. */
 
 
#include <assert.h>
#include <assert.h>
#include <stdio.h>
#include <stdio.h>
#include <ctype.h>
#include <ctype.h>
#include <string.h>
#include <string.h>
#include <stdlib.h>
#include <stdlib.h>
#include <unistd.h>
#include <unistd.h>
#include <stdarg.h>
#include <stdarg.h>
#include <sys/stat.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/types.h>
 
 
#include "mc.h"
#include "mc.h"
#include "gdb.h"
#include "gdb.h"
#include "jp2.h"
#include "jp2.h"
#include "jp.h"
#include "jp.h"
 
 
#define TC_RESET           0
#define TC_RESET           0
#define TC_BRIGHT          1
#define TC_BRIGHT          1
#define TC_DIM             2
#define TC_DIM             2
#define TC_UNDERLINE       3
#define TC_UNDERLINE       3
#define TC_BLINK           4
#define TC_BLINK           4
#define TC_REVERSE         7
#define TC_REVERSE         7
#define TC_HIDDEN          8
#define TC_HIDDEN          8
 
 
#define TC_BLACK           0
#define TC_BLACK           0
#define TC_RED             1
#define TC_RED             1
#define TC_GREEN           2
#define TC_GREEN           2
#define TC_YELLOW          3
#define TC_YELLOW          3
#define TC_BLUE            4
#define TC_BLUE            4
#define TC_MAGENTA         5
#define TC_MAGENTA         5
#define TC_CYAN            6
#define TC_CYAN            6
#define TC_WHITE           7
#define TC_WHITE           7
 
 
#define SDRAM_BASE       0x00000000
#define SDRAM_BASE       0x00000000
#define SDRAM_SIZE       0x04000000
#define SDRAM_SIZE       0x04000000
#define SRAM_BASE        0x40000000
#define SRAM_BASE        0x40000000
#define SRAM_SIZE        0x04000000 // This is not ok
#define SRAM_SIZE        0x04000000 // This is not ok
 
 
 
 
int err = 0;
int err = 0;
int set_pc = 0;
int set_pc = 0;
int set_step = 0;
int set_step = 0;
int waiting = 0;
int waiting = 0;
 
 
/* Scan chain info. */
/* Scan chain info. */
static int chain_addr_size[] = { 0,  32, 0,  0,  5,  32, 32};
static int chain_addr_size[] = { 0,  32, 0,  0,  5,  32, 32};
static int chain_data_size[] = { 0,  32, 0,  32, 32, 32, 32};
static int chain_data_size[] = { 0,  32, 0,  32, 32, 32, 32};
static int chain_is_valid[]  = { 0,  1,  0,  1,  1,  1,   1};
static int chain_is_valid[]  = { 0,  1,  0,  1,  1,  1,   1};
static int chain_has_crc[]   = { 0,  1,  0,  1,  1,  1,   1};
static int chain_has_crc[]   = { 0,  1,  0,  1,  1,  1,   1};
static int chain_has_rw[]    = { 0,  1,  0,  0,  1,  1,   1};
static int chain_has_rw[]    = { 0,  1,  0,  0,  1,  1,   1};
 
 
/* Currently selected scan chain - just to prevent unnecessary
/* Currently selected scan chain - just to prevent unnecessary
   transfers. */
   transfers. */
static int current_chain = -1;
static int current_chain = -1;
 
 
/* The chain that should be currently selected. */
/* The chain that should be currently selected. */
static int dbg_chain = -1;
static int dbg_chain = -1;
 
 
/* Crc of current read or written data.  */
/* Crc of current read or written data.  */
static int crc_r, crc_w = 0;
static int crc_r, crc_w = 0;
 
 
/* Address of previous read */
/* Address of previous read */
static unsigned long prev_regno = 0;
static unsigned long prev_regno = 0;
 
 
/* Generates new crc, sending in new bit input_bit */
/* Generates new crc, sending in new bit input_bit */
static unsigned long crc_calc(unsigned long crc, int input_bit) {
static unsigned long crc_calc(unsigned long crc, int input_bit) {
  unsigned long d = (input_bit&1) ? 0xfffffff : 0x0000000;
  unsigned long d = (input_bit&1) ? 0xfffffff : 0x0000000;
  unsigned long crc_32 = ((crc >> 31)&1) ? 0xfffffff : 0x0000000;
  unsigned long crc_32 = ((crc >> 31)&1) ? 0xfffffff : 0x0000000;
  crc <<= 1;
  crc <<= 1;
  return crc ^ (d ^ crc_32) & DBG_CRC_POLY;
  return crc ^ (d ^ crc_32) & DBG_CRC_POLY;
}
}
 
 
/* Writes TCLK=0, TRST=1, TMS=bit1, TDI=bit0
/* Writes TCLK=0, TRST=1, TMS=bit1, TDI=bit0
   and    TCLK=1, TRST=1, TMS=bit1, TDI=bit0 */
   and    TCLK=1, TRST=1, TMS=bit1, TDI=bit0 */
static void jp2_write_JTAG(uint8_t packet) {
static void jp2_write_JTAG(uint8_t packet) {
  uint8_t data = TRST_BIT;
  uint8_t data = TRST_BIT;
  if(packet & 1) data |= TDI_BIT;
  if(packet & 1) data |= TDI_BIT;
  if(packet & 2) data |= TMS_BIT;
  if(packet & 2) data |= TMS_BIT;
 
 
  jp_out(data);
  jp_out(data);
  jp_wait();
  jp_wait();
  crc_w = crc_calc(crc_w, packet&1);
  crc_w = crc_calc(crc_w, packet&1);
 
 
  /* rise clock */
  /* rise clock */
  jp_out(data | TCLK_BIT);
  jp_out(data | TCLK_BIT);
  jp_wait();
  jp_wait();
}
}
 
 
/* Reads TDI.  */
/* Reads TDI.  */
static int jp2_read_JTAG() {
static int jp2_read_JTAG() {
  uint8_t data;
  uint8_t data;
  data = jp_in();
  data = jp_in();
  crc_r = crc_calc(crc_r, data);
  crc_r = crc_calc(crc_r, data);
  return data;
  return data;
}
}
 
 
/* Writes bitstream.  LS bit first if len < 0, MS bit first if len > 0.  */
/* Writes bitstream.  LS bit first if len < 0, MS bit first if len > 0.  */
static void jp2_write_stream(ULONGEST stream, int len, int set_last_bit) {
static void jp2_write_stream(ULONGEST stream, int len, int set_last_bit) {
  int i;
  int i;
  if (len < 0) {
  if (len < 0) {
    len = -len;
    len = -len;
    debug("writeL%d(", len);
    debug("writeL%d(", len);
    for(i = 0; i < len - 1; i++)
    for(i = 0; i < len - 1; i++)
      jp2_write_JTAG((stream >> i) & 1);
      jp2_write_JTAG((stream >> i) & 1);
 
 
    if(set_last_bit) jp2_write_JTAG((stream >>(len - 1))& 1 | TMS);
    if(set_last_bit) jp2_write_JTAG((stream >>(len - 1))& 1 | TMS);
    else jp2_write_JTAG((stream >>(len - 1))& 1);
    else jp2_write_JTAG((stream >>(len - 1))& 1);
  } else {
  } else {
    debug("write%d(", len);
    debug("write%d(", len);
    for(i = 0; i < len - 1; i++)
    for(i = 0; i < len - 1; i++)
      jp2_write_JTAG((stream >> (len - 1 - i)) & 1);
      jp2_write_JTAG((stream >> (len - 1 - i)) & 1);
 
 
    if(set_last_bit) jp2_write_JTAG((stream >> 0) & 1 | TMS);
    if(set_last_bit) jp2_write_JTAG((stream >> 0) & 1 | TMS);
    else jp2_write_JTAG((stream >> 0)& 1);
    else jp2_write_JTAG((stream >> 0)& 1);
  }
  }
  debug(")\n");
  debug(")\n");
}
}
 
 
/* Gets bitstream.  LS bit first if len < 0, MS bit first if len > 0.  */
/* Gets bitstream.  LS bit first if len < 0, MS bit first if len > 0.  */
static ULONGEST jp2_read_stream(unsigned long stream, int len, int set_last_bit) {
static ULONGEST jp2_read_stream(unsigned long stream, int len, int set_last_bit) {
  int i;
  int i;
  ULONGEST data = 0;
  ULONGEST data = 0;
  if (len < 0) {
  if (len < 0) {
    debug("readL(");
    debug("readL(");
    for(i = 0; i < len - 1; i++) {
    for(i = 0; i < len - 1; i++) {
      jp2_write_JTAG((stream >> i) & 1);   /* LSB first */
      jp2_write_JTAG((stream >> i) & 1);   /* LSB first */
      data |= jp2_read_JTAG() << i; /* LSB first */
      data |= jp2_read_JTAG() << i; /* LSB first */
    }
    }
 
 
    if (set_last_bit) jp2_write_JTAG((stream >> (len - 1)) & 1 | TMS);
    if (set_last_bit) jp2_write_JTAG((stream >> (len - 1)) & 1 | TMS);
    else jp2_write_JTAG((stream >> (len - 1)) & 1);
    else jp2_write_JTAG((stream >> (len - 1)) & 1);
    data |= jp2_read_JTAG() << (len - 1);
    data |= jp2_read_JTAG() << (len - 1);
  } else {
  } else {
    debug("read(");
    debug("read(");
    for(i = 0; i < len - 1; i++) {
    for(i = 0; i < len - 1; i++) {
      jp2_write_JTAG((stream >> (len - 1 - i)) & 1);   /* MSB first */
      jp2_write_JTAG((stream >> (len - 1 - i)) & 1);   /* MSB first */
      data |= jp2_read_JTAG() << (len - 1 - i); /* MSB first */
      data |= jp2_read_JTAG() << (len - 1 - i); /* MSB first */
    }
    }
 
 
    if (set_last_bit) jp2_write_JTAG((stream >> 0) & 1 | TMS);
    if (set_last_bit) jp2_write_JTAG((stream >> 0) & 1 | TMS);
    else jp2_write_JTAG((stream >> 0) & 1);
    else jp2_write_JTAG((stream >> 0) & 1);
    data |= jp2_read_JTAG() << 0;
    data |= jp2_read_JTAG() << 0;
  }
  }
  debug(")\n");
  debug(")\n");
  return data;
  return data;
}
}
 
 
/* Sets scan chain.  */
/* Sets scan chain.  */
void jtag_set_ir(int ir) {
void jtag_set_ir(int ir) {
  jp2_write_JTAG(TMS); /* SELECT_DR SCAN */
  jp2_write_JTAG(TMS); /* SELECT_DR SCAN */
  jp2_write_JTAG(TMS); /* SELECT_IR SCAN */
  jp2_write_JTAG(TMS); /* SELECT_IR SCAN */
 
 
  jp2_write_JTAG(0); /* CAPTURE_IR */
  jp2_write_JTAG(0); /* CAPTURE_IR */
  jp2_write_JTAG(0); /* SHIFT_IR */
  jp2_write_JTAG(0); /* SHIFT_IR */
 
 
  /* write data, EXIT1_IR */
  /* write data, EXIT1_IR */
  jp2_write_stream(ir, -JI_SIZE, 1);
  jp2_write_stream(ir, -JI_SIZE, 1);
 
 
  jp2_write_JTAG(TMS); /* UPDATE_IR */
  jp2_write_JTAG(TMS); /* UPDATE_IR */
  jp2_write_JTAG(0); /* IDLE */
  jp2_write_JTAG(0); /* IDLE */
  current_chain = -1;
  current_chain = -1;
}
}
 
 
/* Resets JTAG
/* Resets JTAG
   Writes TRST=0
   Writes TRST=0
   and    TRST=1 */
   and    TRST=1 */
static void jp2_reset_JTAG() {
static void jp2_reset_JTAG() {
  int i;
  int i;
  debug2("\nreset(");
  debug2("\nreset(");
  jp_out(0);
  jp_out(0);
  JTAG_RETRY_WAIT();
  JTAG_RETRY_WAIT();
  /* In case we don't have TRST reset it manually */
  /* In case we don't have TRST reset it manually */
  for(i = 0; i < 8; i++) jp2_write_JTAG(TMS);
  for(i = 0; i < 8; i++) jp2_write_JTAG(TMS);
  jp_out(TRST_BIT);
  jp_out(TRST_BIT);
  JTAG_RETRY_WAIT();
  JTAG_RETRY_WAIT();
  jp2_write_JTAG(0);
  jp2_write_JTAG(0);
  debug2(")\n");
  debug2(")\n");
}
}
 
 
/* Resets JTAG, and sets DEBUG scan chain */
/* Resets JTAG, and sets DEBUG scan chain */
static int dbg_reset() {
static int dbg_reset() {
  int err;
  int err;
  unsigned long id;
  unsigned long id;
  jp2_reset_JTAG();
  jp2_reset_JTAG();
 
 
  /* read ID */
  /* read ID */
  jtag_set_ir(JI_IDCODE);
  jtag_set_ir(JI_IDCODE);
  jp2_write_JTAG(TMS); /* SELECT_DR SCAN */
  jp2_write_JTAG(TMS); /* SELECT_DR SCAN */
  jp2_write_JTAG(0); /* CAPTURE_DR */
  jp2_write_JTAG(0); /* CAPTURE_DR */
  jp2_write_JTAG(0); /* SHIFT_DR */
  jp2_write_JTAG(0); /* SHIFT_DR */
  /* read ID, EXIT1_DR */
  /* read ID, EXIT1_DR */
  crc_w = 0xffffffff;
  crc_w = 0xffffffff;
  id = jp2_read_stream(0, 32, 1);
  id = jp2_read_stream(0, 32, 1);
  jp2_write_JTAG(TMS); /* UPDATE_DR */
  jp2_write_JTAG(TMS); /* UPDATE_DR */
  jp2_write_JTAG(0); /* IDLE */
  jp2_write_JTAG(0); /* IDLE */
  printf("JTAG ID = %08x\n", id);
  printf("JTAG ID = %08x\n", id);
 
 
  /* select debug scan chain and stay in it forever */
  /* select debug scan chain and stay in it forever */
  jtag_set_ir(JI_DEBUG);
  jtag_set_ir(JI_DEBUG);
  current_chain = -1;
  current_chain = -1;
  return DBG_ERR_OK;
  return DBG_ERR_OK;
}
}
 
 
/* counts retries and returns zero if we should abort */
/* counts retries and returns zero if we should abort */
/* TODO: dinamically adjust timings for jp2 */
/* TODO: dinamically adjust timings for jp2 */
static int retry_no = 0;
static int retry_no = 0;
int retry_do() {
int retry_do() {
  int i, err;
  int i, err;
  printf("RETRY\n");
  printf("RETRY\n");
  //exit(2);
  //exit(2);
  if (retry_no >= NUM_SOFT_RETRIES) {
  if (retry_no >= NUM_SOFT_RETRIES) {
    if ((err = dbg_reset())) return err;
    if ((err = dbg_reset())) return err;
  } else { /* quick reset */
  } else { /* quick reset */
    for(i = 0; i < 8; i++) jp2_write_JTAG(TMS);
    for(i = 0; i < 8; i++) jp2_write_JTAG(TMS);
    jp2_write_JTAG(0); /* go into IDLE state */
    jp2_write_JTAG(0); /* go into IDLE state */
  }
  }
  if (retry_no >= NUM_SOFT_RETRIES + NUM_HARD_RETRIES) {
  if (retry_no >= NUM_SOFT_RETRIES + NUM_HARD_RETRIES) {
    retry_no = 0;
    retry_no = 0;
    return 0;
    return 0;
  }
  }
  retry_no++;
  retry_no++;
  return 1;
  return 1;
}
}
 
 
/* resets retry counter */
/* resets retry counter */
void retry_ok() {
void retry_ok() {
  retry_no = 0;
  retry_no = 0;
}
}
 
 
/* Sets scan chain.  */
/* Sets scan chain.  */
int dbg_set_chain(int chain) {
int dbg_set_chain(int chain) {
  int status, crc_generated, crc_read;
  int status, crc_generated, crc_read;
  dbg_chain = chain;
  dbg_chain = chain;
 
 
try_again:
try_again:
  if (current_chain == chain) return DBG_ERR_OK;
  if (current_chain == chain) return DBG_ERR_OK;
  current_chain = -1;
  current_chain = -1;
  debug("\n");
  debug("\n");
  debug2("set_chain %i\n", chain);
  debug2("set_chain %i\n", chain);
  jp2_write_JTAG(TMS); /* SELECT_DR SCAN */
  jp2_write_JTAG(TMS); /* SELECT_DR SCAN */
  jp2_write_JTAG(0); /* CAPTURE_DR */
  jp2_write_JTAG(0); /* CAPTURE_DR */
  jp2_write_JTAG(0); /* SHIFT_DR */
  jp2_write_JTAG(0); /* SHIFT_DR */
 
 
  /* write data, EXIT1_DR */
  /* write data, EXIT1_DR */
  crc_w = 0xffffffff;
  crc_w = 0xffffffff;
  jp2_write_stream((chain & 0xf | (1<<DC_SIZE)), DC_SIZE + 1, 0);
  jp2_write_stream((chain & 0xf | (1<<DC_SIZE)), DC_SIZE + 1, 0);
  jp2_write_stream(crc_w, DBG_CRC_SIZE, 0);
  jp2_write_stream(crc_w, DBG_CRC_SIZE, 0);
  crc_r = 0xffffffff;
  crc_r = 0xffffffff;
  status = jp2_read_stream(0, DC_STATUS_SIZE, 0);
  status = jp2_read_stream(0, DC_STATUS_SIZE, 0);
  crc_generated = crc_r;
  crc_generated = crc_r;
  crc_read = jp2_read_stream(0, DBG_CRC_SIZE, 1);
  crc_read = jp2_read_stream(0, DBG_CRC_SIZE, 1);
 
 
  //printf("%x %x %x\n", status, crc_read, crc_generated);
  //printf("%x %x %x\n", status, crc_read, crc_generated);
  /* CRCs must match, otherwise retry */
  /* CRCs must match, otherwise retry */
  if (crc_read != crc_generated) {
  if (crc_read != crc_generated) {
    if (retry_do()) goto try_again;
    if (retry_do()) goto try_again;
    else return DBG_ERR_CRC;
    else return DBG_ERR_CRC;
  }
  }
  /* we should read expected status value, otherwise retry */
  /* we should read expected status value, otherwise retry */
  if (status != 0) {
  if (status != 0) {
    if (retry_do()) goto try_again;
    if (retry_do()) goto try_again;
    else return status;
    else return status;
  }
  }
 
 
  /* reset retry counter */
  /* reset retry counter */
  retry_ok();
  retry_ok();
 
 
  jp2_write_JTAG(TMS); /* UPDATE_DR */
  jp2_write_JTAG(TMS); /* UPDATE_DR */
  jp2_write_JTAG(0); /* IDLE */
  jp2_write_JTAG(0); /* IDLE */
  current_chain = chain;
  current_chain = chain;
  return DBG_ERR_OK;
  return DBG_ERR_OK;
}
}
 
 
/* sends out a command with 32bit address and 16bit length, if len >= 0 */
/* sends out a command with 32bit address and 16bit length, if len >= 0 */
int dbg_command(int type, unsigned long adr, int len) {
int dbg_command(int type, unsigned long adr, int len) {
  int status, crc_generated, crc_read;
  int status, crc_generated, crc_read;
 
 
try_again:
try_again:
  dbg_set_chain(dbg_chain);
  dbg_set_chain(dbg_chain);
  debug("\n");
  debug("\n");
  debug2("comm %i\n", type);
  debug2("comm %i\n", type);
 
 
  /***** WRITEx *****/
  /***** WRITEx *****/
  jp2_write_JTAG(TMS); /* SELECT_DR SCAN */
  jp2_write_JTAG(TMS); /* SELECT_DR SCAN */
  jp2_write_JTAG(0); /* CAPTURE_DR */
  jp2_write_JTAG(0); /* CAPTURE_DR */
  jp2_write_JTAG(0); /* SHIFT_DR */
  jp2_write_JTAG(0); /* SHIFT_DR */
 
 
  /* write data, EXIT1_DR */
  /* write data, EXIT1_DR */
  crc_w = 0xffffffff;
  crc_w = 0xffffffff;
  jp2_write_stream((DI_WRITE_CMD & 0xf | (0<<DC_SIZE)), DC_SIZE + 1, 0);
  jp2_write_stream((DI_WRITE_CMD & 0xf | (0<<DC_SIZE)), DC_SIZE + 1, 0);
  jp2_write_stream(type, 4, 0);
  jp2_write_stream(type, 4, 0);
  jp2_write_stream(adr, 32, 0);
  jp2_write_stream(adr, 32, 0);
  assert(len > 0);
  assert(len > 0);
  jp2_write_stream(len - 1, 16, 0);
  jp2_write_stream(len - 1, 16, 0);
  jp2_write_stream(crc_w, DBG_CRC_SIZE, 0);
  jp2_write_stream(crc_w, DBG_CRC_SIZE, 0);
  crc_r = 0xffffffff;
  crc_r = 0xffffffff;
  status = jp2_read_stream(0, DC_STATUS_SIZE, 0);
  status = jp2_read_stream(0, DC_STATUS_SIZE, 0);
  crc_generated = crc_r;
  crc_generated = crc_r;
  crc_read = jp2_read_stream(0, DBG_CRC_SIZE, 1);
  crc_read = jp2_read_stream(0, DBG_CRC_SIZE, 1);
 
 
  /* CRCs must match, otherwise retry */
  /* CRCs must match, otherwise retry */
  if (crc_read != crc_generated) {
  if (crc_read != crc_generated) {
    if (retry_do()) goto try_again;
    if (retry_do()) goto try_again;
    else return DBG_ERR_CRC;
    else return DBG_ERR_CRC;
  }
  }
  /* we should read expected status value, otherwise retry */
  /* we should read expected status value, otherwise retry */
  if (status != 0) {
  if (status != 0) {
    if (retry_do()) goto try_again;
    if (retry_do()) goto try_again;
    else return status;
    else return status;
  }
  }
  jp2_write_JTAG(TMS); /* UPDATE_DR */
  jp2_write_JTAG(TMS); /* UPDATE_DR */
  jp2_write_JTAG(0); /* IDLE */
  jp2_write_JTAG(0); /* IDLE */
 
 
  /* reset retry counter */
  /* reset retry counter */
  retry_ok();
  retry_ok();
  return DBG_ERR_OK;
  return DBG_ERR_OK;
}
}
 
 
/* writes a ctrl reg */
/* writes a ctrl reg */
int dbg_ctrl(int reset, int stall) {
int dbg_ctrl(int reset, int stall) {
  int status, crc_generated, crc_read;
  int status, crc_generated, crc_read;
 
 
try_again:
try_again:
  dbg_set_chain(dbg_chain);
  dbg_set_chain(dbg_chain);
  debug("\n");
  debug("\n");
  debug2("ctrl\n");
  debug2("ctrl\n");
 
 
  /***** WRITEx *****/
  /***** WRITEx *****/
  jp2_write_JTAG(TMS); /* SELECT_DR SCAN */
  jp2_write_JTAG(TMS); /* SELECT_DR SCAN */
  jp2_write_JTAG(0); /* CAPTURE_DR */
  jp2_write_JTAG(0); /* CAPTURE_DR */
  jp2_write_JTAG(0); /* SHIFT_DR */
  jp2_write_JTAG(0); /* SHIFT_DR */
 
 
  /* write data, EXIT1_DR */
  /* write data, EXIT1_DR */
  crc_w = 0xffffffff;
  crc_w = 0xffffffff;
  jp2_write_stream((DI_WRITE_CTRL & 0xf | (0<<DC_SIZE)), DC_SIZE + 1, 0);
  jp2_write_stream((DI_WRITE_CTRL & 0xf | (0<<DC_SIZE)), DC_SIZE + 1, 0);
  jp2_write_stream(reset, 1, 0);
  jp2_write_stream(reset, 1, 0);
  jp2_write_stream(stall, 1, 0);
  jp2_write_stream(stall, 1, 0);
  jp2_write_stream(0, 50, 0);
  jp2_write_stream(0, 50, 0);
  jp2_write_stream(crc_w, DBG_CRC_SIZE, 0);
  jp2_write_stream(crc_w, DBG_CRC_SIZE, 0);
  crc_r = 0xffffffff;
  crc_r = 0xffffffff;
  status = jp2_read_stream(0, DC_STATUS_SIZE, 0);
  status = jp2_read_stream(0, DC_STATUS_SIZE, 0);
  crc_generated = crc_r;
  crc_generated = crc_r;
  crc_read = jp2_read_stream(0, DBG_CRC_SIZE, 1);
  crc_read = jp2_read_stream(0, DBG_CRC_SIZE, 1);
 
 
  /* CRCs must match, otherwise retry */
  /* CRCs must match, otherwise retry */
  //printf("%x %x %x\n", status, crc_read, crc_generated);
  //printf("%x %x %x\n", status, crc_read, crc_generated);
  if (crc_read != crc_generated) {
  if (crc_read != crc_generated) {
    if (retry_do()) goto try_again;
    if (retry_do()) goto try_again;
    else return DBG_ERR_CRC;
    else return DBG_ERR_CRC;
  }
  }
  /* we should read expected status value, otherwise retry */
  /* we should read expected status value, otherwise retry */
  if (status != 0) {
  if (status != 0) {
    if (retry_do()) goto try_again;
    if (retry_do()) goto try_again;
    else return status;
    else return status;
  }
  }
  jp2_write_JTAG(TMS); /* UPDATE_DR */
  jp2_write_JTAG(TMS); /* UPDATE_DR */
  jp2_write_JTAG(0); /* IDLE */
  jp2_write_JTAG(0); /* IDLE */
 
 
  /* reset retry counter */
  /* reset retry counter */
  retry_ok();
  retry_ok();
  return DBG_ERR_OK;
  return DBG_ERR_OK;
}
}
 
 
/* reads control register */
/* reads control register */
int dbg_ctrl_read(int *reset, int *stall) {
int dbg_ctrl_read(int *reset, int *stall) {
  int status, crc_generated, crc_read;
  int status, crc_generated, crc_read;
 
 
try_again:
try_again:
  dbg_set_chain(dbg_chain);
  dbg_set_chain(dbg_chain);
  debug("\n");
  debug("\n");
  debug2("ctrl_read\n");
  debug2("ctrl_read\n");
 
 
  jp2_write_JTAG(TMS); /* SELECT_DR SCAN */
  jp2_write_JTAG(TMS); /* SELECT_DR SCAN */
  jp2_write_JTAG(0); /* CAPTURE_DR */
  jp2_write_JTAG(0); /* CAPTURE_DR */
  jp2_write_JTAG(0); /* SHIFT_DR */
  jp2_write_JTAG(0); /* SHIFT_DR */
 
 
  /* write data, EXIT1_DR */
  /* write data, EXIT1_DR */
  crc_w = 0xffffffff;
  crc_w = 0xffffffff;
  jp2_write_stream(DI_READ_CTRL | (0<<DC_SIZE), DC_SIZE + 1, 0);
  jp2_write_stream(DI_READ_CTRL | (0<<DC_SIZE), DC_SIZE + 1, 0);
  jp2_write_stream(crc_w, DBG_CRC_SIZE, 0);
  jp2_write_stream(crc_w, DBG_CRC_SIZE, 0);
  crc_r = 0xffffffff;
  crc_r = 0xffffffff;
  *reset = jp2_read_stream(0, 1, 0);
  *reset = jp2_read_stream(0, 1, 0);
  *stall = jp2_read_stream(0, 1, 0);
  *stall = jp2_read_stream(0, 1, 0);
  jp2_read_stream(0, 50, 0);
  jp2_read_stream(0, 50, 0);
  status = jp2_read_stream(0, DC_STATUS_SIZE, 0);
  status = jp2_read_stream(0, DC_STATUS_SIZE, 0);
  crc_generated = crc_r;
  crc_generated = crc_r;
  crc_read = jp2_read_stream(0, DBG_CRC_SIZE, 1);
  crc_read = jp2_read_stream(0, DBG_CRC_SIZE, 1);
 
 
  /* CRCs must match, otherwise retry */
  /* CRCs must match, otherwise retry */
  //printf("%x %x %x\n", status, crc_read, crc_generated);
  //printf("%x %x %x\n", status, crc_read, crc_generated);
  if (crc_read != crc_generated) {
  if (crc_read != crc_generated) {
    if (retry_do()) goto try_again;
    if (retry_do()) goto try_again;
    else return DBG_ERR_CRC;
    else return DBG_ERR_CRC;
  }
  }
  /* we should read expected status value, otherwise retry */
  /* we should read expected status value, otherwise retry */
  if (status != 0) {
  if (status != 0) {
    if (retry_do()) goto try_again;
    if (retry_do()) goto try_again;
    else return status;
    else return status;
  }
  }
  jp2_write_JTAG(TMS); /* UPDATE_DR */
  jp2_write_JTAG(TMS); /* UPDATE_DR */
  jp2_write_JTAG(0); /* IDLE */
  jp2_write_JTAG(0); /* IDLE */
 
 
  /* reset retry counter */
  /* reset retry counter */
  retry_ok();
  retry_ok();
  return DBG_ERR_OK;
  return DBG_ERR_OK;
}
}
/* issues a burst read/write */
/* issues a burst read/write */
int dbg_go(unsigned char *data, unsigned short len, int read) {
int dbg_go(unsigned char *data, unsigned short len, int read) {
  int status, crc_generated, crc_read;
  int status, crc_generated, crc_read;
  int i;
  int i;
 
 
try_again:
try_again:
  dbg_set_chain(dbg_chain);
  dbg_set_chain(dbg_chain);
  debug("\n");
  debug("\n");
  debug2("go len = %d\n", len);
  debug2("go len = %d\n", len);
 
 
  jp2_write_JTAG(TMS); /* SELECT_DR SCAN */
  jp2_write_JTAG(TMS); /* SELECT_DR SCAN */
  jp2_write_JTAG(0); /* CAPTURE_DR */
  jp2_write_JTAG(0); /* CAPTURE_DR */
  jp2_write_JTAG(0); /* SHIFT_DR */
  jp2_write_JTAG(0); /* SHIFT_DR */
 
 
  /* write data, EXIT1_DR */
  /* write data, EXIT1_DR */
  crc_w = 0xffffffff;
  crc_w = 0xffffffff;
  jp2_write_stream(DI_GO | (0<<DC_SIZE), DC_SIZE + 1, 0);
  jp2_write_stream(DI_GO | (0<<DC_SIZE), DC_SIZE + 1, 0);
  if (!read) {
  if (!read) {
    /* reverse byte ordering, since we must send in big endian */
    /* reverse byte ordering, since we must send in big endian */
    for (i = 0; i < len; i++)
    for (i = 0; i < len; i++)
      jp2_write_stream(data[i], 8, 0);
      jp2_write_stream(data[i], 8, 0);
  }
  }
  jp2_write_stream(crc_w, DBG_CRC_SIZE, 0);
  jp2_write_stream(crc_w, DBG_CRC_SIZE, 0);
  crc_r = 0xffffffff;
  crc_r = 0xffffffff;
  if (read) {
  if (read) {
    /* reverse byte ordering, since we must send in big endian */
    /* reverse byte ordering, since we must send in big endian */
    for (i = 0; i < len; i++)
    for (i = 0; i < len; i++)
      data[i] = jp2_read_stream(data[i], 8, 0);
      data[i] = jp2_read_stream(data[i], 8, 0);
  }
  }
  status = jp2_read_stream(0, DC_STATUS_SIZE, 0);
  status = jp2_read_stream(0, DC_STATUS_SIZE, 0);
  crc_generated = crc_r;
  crc_generated = crc_r;
  crc_read = jp2_read_stream(0, DBG_CRC_SIZE, 1);
  crc_read = jp2_read_stream(0, DBG_CRC_SIZE, 1);
 
 
  /* CRCs must match, otherwise retry */
  /* CRCs must match, otherwise retry */
  //printf("%x %x %x\n", status, crc_read, crc_generated);
  //printf("%x %x %x\n", status, crc_read, crc_generated);
  if (crc_read != crc_generated) {
  if (crc_read != crc_generated) {
    if (retry_do()) goto try_again;
    if (retry_do()) goto try_again;
    else return DBG_ERR_CRC;
    else return DBG_ERR_CRC;
  }
  }
  /* we should read expected status value, otherwise retry */
  /* we should read expected status value, otherwise retry */
  if (status != 0) {
  if (status != 0) {
    if (retry_do()) goto try_again;
    if (retry_do()) goto try_again;
    else return status;
    else return status;
  }
  }
  jp2_write_JTAG(TMS); /* UPDATE_DR */
  jp2_write_JTAG(TMS); /* UPDATE_DR */
  jp2_write_JTAG(0); /* IDLE */
  jp2_write_JTAG(0); /* IDLE */
 
 
  /* reset retry counter */
  /* reset retry counter */
  retry_ok();
  retry_ok();
  return DBG_ERR_OK;
  return DBG_ERR_OK;
}
}
 
 
/* read a word from wishbone */
/* read a word from wishbone */
int dbg_wb_read32(unsigned long adr, unsigned long *data) {
int dbg_wb_read32(unsigned long adr, unsigned long *data) {
  int err;
  int err;
  if ((err = dbg_set_chain(DC_WISHBONE))) return err;
  if ((err = dbg_set_chain(DC_WISHBONE))) return err;
  if ((err = dbg_command(0x6, adr, 4))) return err;
  if ((err = dbg_command(0x6, adr, 4))) return err;
  if ((err = dbg_go((unsigned char*)data, 4, 1))) return err;
  if ((err = dbg_go((unsigned char*)data, 4, 1))) return err;
  *data = ntohl(*data);
  *data = ntohl(*data);
  return err;
  return err;
}
}
 
 
/* write a word to wishbone */
/* write a word to wishbone */
int dbg_wb_write32(unsigned long adr, unsigned long data) {
int dbg_wb_write32(unsigned long adr, unsigned long data) {
  int err;
  int err;
  data = ntohl(data);
  data = ntohl(data);
  if ((err = dbg_set_chain(DC_WISHBONE))) return err;
  if ((err = dbg_set_chain(DC_WISHBONE))) return err;
  if ((err = dbg_command(0x2, adr, 4))) return err;
  if ((err = dbg_command(0x2, adr, 4))) return err;
  if ((err = dbg_go((unsigned char*)&data, 4, 0))) return err;
  if ((err = dbg_go((unsigned char*)&data, 4, 0))) return err;
  return DBG_ERR_OK;
  return DBG_ERR_OK;
}
}
 
 
/* write a word to wishbone */
/* write a word to wishbone */
int dbg_wb_write16(unsigned long adr, unsigned short data) {
int dbg_wb_write16(unsigned long adr, unsigned short data) {
  int err;
  int err;
  data = ntohs(data);
  data = ntohs(data);
  if ((err = dbg_set_chain(DC_WISHBONE))) return err;
  if ((err = dbg_set_chain(DC_WISHBONE))) return err;
  if ((err = dbg_command(0x1, adr, 2))) return err;
  if ((err = dbg_command(0x1, adr, 2))) return err;
  if ((err = dbg_go((unsigned char*)&data, 2, 0))) return err;
  if ((err = dbg_go((unsigned char*)&data, 2, 0))) return err;
  return DBG_ERR_OK;
  return DBG_ERR_OK;
}
}
 
 
/* write a word to wishbone */
/* write a word to wishbone */
int dbg_wb_write8(unsigned long adr, unsigned long data) {
int dbg_wb_write8(unsigned long adr, unsigned long data) {
  int err;
  int err;
  if ((err = dbg_set_chain(DC_WISHBONE))) return err;
  if ((err = dbg_set_chain(DC_WISHBONE))) return err;
  if ((err = dbg_command(0x0, adr, 1))) return err;
  if ((err = dbg_command(0x0, adr, 1))) return err;
  if ((err = dbg_go((unsigned char*)&data, 1, 0))) return err;
  if ((err = dbg_go((unsigned char*)&data, 1, 0))) return err;
  return DBG_ERR_OK;
  return DBG_ERR_OK;
}
}
 
 
/* read a block from wishbone */
/* read a block from wishbone */
int dbg_wb_read_block32(unsigned long adr, unsigned long *data, int len) {
int dbg_wb_read_block32(unsigned long adr, unsigned long *data, int len) {
  int i, err;
  int i, err;
  //printf("%08x %08x\n", adr, len);
  //printf("%08x %08x\n", adr, len);
  if ((err = dbg_set_chain(DC_WISHBONE))) return err;
  if ((err = dbg_set_chain(DC_WISHBONE))) return err;
  if ((err = dbg_command(0x6, adr, len))) return err;
  if ((err = dbg_command(0x6, adr, len))) return err;
  if ((err = dbg_go((unsigned char*)data, len, 1))) return err;
  if ((err = dbg_go((unsigned char*)data, len, 1))) return err;
  for (i = 0; i < len / 4; i ++) data[i] = ntohl(data[i]);
  for (i = 0; i < len / 4; i ++) data[i] = ntohl(data[i]);
  //printf("%08x\n", err);
  //printf("%08x\n", err);
  return DBG_ERR_OK;
  return DBG_ERR_OK;
}
}
 
 
/* read a block from wishbone */
/* read a block from wishbone */
int dbg_wb_read_block16(unsigned long adr, unsigned short *data, int len) {
int dbg_wb_read_block16(unsigned long adr, unsigned short *data, int len) {
  int i, err;
  int i, err;
  //printf("%08x %08x\n", adr, len);
  //printf("%08x %08x\n", adr, len);
  if ((err = dbg_set_chain(DC_WISHBONE))) return err;
  if ((err = dbg_set_chain(DC_WISHBONE))) return err;
  if ((err = dbg_command(0x5, adr, len))) return err;
  if ((err = dbg_command(0x5, adr, len))) return err;
  if ((err = dbg_go((unsigned char*)data, len, 1))) return err;
  if ((err = dbg_go((unsigned char*)data, len, 1))) return err;
  for (i = 0; i < len / 2; i ++) data[i] = ntohs(data[i]);
  for (i = 0; i < len / 2; i ++) data[i] = ntohs(data[i]);
  //printf("%08x\n", err);
  //printf("%08x\n", err);
  return DBG_ERR_OK;
  return DBG_ERR_OK;
}
}
 
 
/* read a block from wishbone */
/* read a block from wishbone */
int dbg_wb_read_block8(unsigned long adr, unsigned char *data, int len) {
int dbg_wb_read_block8(unsigned long adr, unsigned char *data, int len) {
  int i, err;
  int i, err;
  //printf("%08x %08x\n", adr, len);
  //printf("%08x %08x\n", adr, len);
  if ((err = dbg_set_chain(DC_WISHBONE))) return err;
  if ((err = dbg_set_chain(DC_WISHBONE))) return err;
  if ((err = dbg_command(0x4, adr, len))) return err;
  if ((err = dbg_command(0x4, adr, len))) return err;
  if ((err = dbg_go((unsigned char*)data, len, 1))) return err;
  if ((err = dbg_go((unsigned char*)data, len, 1))) return err;
  //printf("%08x\n", err);
  //printf("%08x\n", err);
  return DBG_ERR_OK;
  return DBG_ERR_OK;
}
}
 
 
/* write a block to wishbone */
/* write a block to wishbone */
int dbg_wb_write_block32(unsigned long adr, unsigned long *data, int len) {
int dbg_wb_write_block32(unsigned long adr, unsigned long *data, int len) {
  int i, err;
  int i, err;
  for (i = 0; i < len / 4; i ++) data[i] = ntohl(data[i]);
  for (i = 0; i < len / 4; i ++) data[i] = ntohl(data[i]);
  if ((err = dbg_set_chain(DC_WISHBONE))) return err;
  if ((err = dbg_set_chain(DC_WISHBONE))) return err;
  if ((err = dbg_command(0x2, adr, len))) return err;
  if ((err = dbg_command(0x2, adr, len))) return err;
  if ((err = dbg_go((unsigned char*)data, len, 0))) return err;
  if ((err = dbg_go((unsigned char*)data, len, 0))) return err;
  return DBG_ERR_OK;
  return DBG_ERR_OK;
}
}
 
 
/* write a block to wishbone */
/* write a block to wishbone */
int dbg_wb_write_block16(unsigned long adr, unsigned short *data, int len) {
int dbg_wb_write_block16(unsigned long adr, unsigned short *data, int len) {
  int i, err;
  int i, err;
  for (i = 0; i < len / 2; i ++) data[i] = ntohs(data[i]);
  for (i = 0; i < len / 2; i ++) data[i] = ntohs(data[i]);
  if ((err = dbg_set_chain(DC_WISHBONE))) return err;
  if ((err = dbg_set_chain(DC_WISHBONE))) return err;
  if ((err = dbg_command(0x1, adr, len))) return err;
  if ((err = dbg_command(0x1, adr, len))) return err;
  if ((err = dbg_go((unsigned char*)data, len, 0))) return err;
  if ((err = dbg_go((unsigned char*)data, len, 0))) return err;
  return DBG_ERR_OK;
  return DBG_ERR_OK;
}
}
 
 
/* write a block to wishbone */
/* write a block to wishbone */
int dbg_wb_write_block8(unsigned long adr, unsigned char *data, int len) {
int dbg_wb_write_block8(unsigned long adr, unsigned char *data, int len) {
  int i, err;
  int i, err;
  if ((err = dbg_set_chain(DC_WISHBONE))) return err;
  if ((err = dbg_set_chain(DC_WISHBONE))) return err;
  if ((err = dbg_command(0x0, adr, len))) return err;
  if ((err = dbg_command(0x0, adr, len))) return err;
  if ((err = dbg_go((unsigned char*)data, len, 0))) return err;
  if ((err = dbg_go((unsigned char*)data, len, 0))) return err;
  return DBG_ERR_OK;
  return DBG_ERR_OK;
}
}
 
 
/* read a register from cpu */
/* read a register from cpu */
int dbg_cpu0_read(unsigned long adr, unsigned long *data) {
int dbg_cpu0_read(unsigned long adr, unsigned long *data) {
  int err;
  int err;
  if ((err = dbg_set_chain(DC_CPU0))) return err;
  if ((err = dbg_set_chain(DC_CPU0))) return err;
  if ((err = dbg_command(0x6, adr, 4))) return err;
  if ((err = dbg_command(0x6, adr, 4))) return err;
  if ((err = dbg_go((unsigned char*)data, 4, 1))) return err;
  if ((err = dbg_go((unsigned char*)data, 4, 1))) return err;
  *data = ntohl(*data);
  *data = ntohl(*data);
  return DBG_ERR_OK;
  return DBG_ERR_OK;
}
}
 
 
/* write a cpu register */
/* write a cpu register */
int dbg_cpu0_write(unsigned long adr, unsigned long data) {
int dbg_cpu0_write(unsigned long adr, unsigned long data) {
  int err;
  int err;
  data = ntohl(data);
  data = ntohl(data);
  if ((err = dbg_set_chain(DC_CPU0))) return err;
  if ((err = dbg_set_chain(DC_CPU0))) return err;
  if ((err = dbg_command(0x2, adr, 4))) return err;
  if ((err = dbg_command(0x2, adr, 4))) return err;
  if ((err = dbg_go((unsigned char*)&data, 4, 0))) return err;
  if ((err = dbg_go((unsigned char*)&data, 4, 0))) return err;
  return DBG_ERR_OK;
  return DBG_ERR_OK;
}
}
 
 
/* read a register from cpu */
/* read a register from cpu */
int dbg_cpu1_read(unsigned long adr, unsigned long *data) {
int dbg_cpu1_read(unsigned long adr, unsigned long *data) {
  int err;
  int err;
  if ((err = dbg_set_chain(DC_CPU1))) return err;
  if ((err = dbg_set_chain(DC_CPU1))) return err;
  if ((err = dbg_command(0x6, adr, 4))) return err;
  if ((err = dbg_command(0x6, adr, 4))) return err;
  if ((err = dbg_go((unsigned char*)data, 4, 1))) return err;
  if ((err = dbg_go((unsigned char*)data, 4, 1))) return err;
  *data = ntohl(*data);
  *data = ntohl(*data);
  return DBG_ERR_OK;
  return DBG_ERR_OK;
}
}
 
 
/* write a cpu register */
/* write a cpu register */
int dbg_cpu1_write(unsigned long adr, unsigned long data) {
int dbg_cpu1_write(unsigned long adr, unsigned long data) {
  int err;
  int err;
  data = ntohl(data);
  data = ntohl(data);
  if ((err = dbg_set_chain(DC_CPU1))) return err;
  if ((err = dbg_set_chain(DC_CPU1))) return err;
  if ((err = dbg_command(0x2, adr, 4))) return err;
  if ((err = dbg_command(0x2, adr, 4))) return err;
  if ((err = dbg_go((unsigned char*)&data, 4, 0))) return err;
  if ((err = dbg_go((unsigned char*)&data, 4, 0))) return err;
  return DBG_ERR_OK;
  return DBG_ERR_OK;
}
}
 
 
/* write a cpu module register */
/* write a cpu module register */
int dbg_cpu1_write_reg(unsigned long adr, unsigned char data) {
int dbg_cpu1_write_reg(unsigned long adr, unsigned char data) {
  int err;
  int err;
  if ((err = dbg_set_chain(DC_CPU1))) return err;
  if ((err = dbg_set_chain(DC_CPU1))) return err;
  if ((err = dbg_ctrl(data & 2, data &1))) return err;
  if ((err = dbg_ctrl(data & 2, data &1))) return err;
  return DBG_ERR_OK;
  return DBG_ERR_OK;
}
}
 
 
/* read a register from cpu module */
/* read a register from cpu module */
int dbg_cpu1_read_ctrl(unsigned long adr, unsigned char *data) {
int dbg_cpu1_read_ctrl(unsigned long adr, unsigned char *data) {
  int err;
  int err;
  int r, s;
  int r, s;
  if ((err = dbg_set_chain(DC_CPU1))) return err;
  if ((err = dbg_set_chain(DC_CPU1))) return err;
  if ((err = dbg_ctrl_read(&r, &s))) return err;
  if ((err = dbg_ctrl_read(&r, &s))) return err;
  *data = (r << 1) | s;
  *data = (r << 1) | s;
  return DBG_ERR_OK;
  return DBG_ERR_OK;
}
}
 
 
/* write a cpu module register */
/* write a cpu module register */
int dbg_cpu0_write_ctrl(unsigned long adr, unsigned char data) {
int dbg_cpu0_write_ctrl(unsigned long adr, unsigned char data) {
  int err;
  int err;
  if ((err = dbg_set_chain(DC_CPU0))) return err;
  if ((err = dbg_set_chain(DC_CPU0))) return err;
  if ((err = dbg_ctrl(data & 2, data &1))) return err;
  if ((err = dbg_ctrl(data & 2, data &1))) return err;
  return DBG_ERR_OK;
  return DBG_ERR_OK;
}
}
 
 
/* read a register from cpu module */
/* read a register from cpu module */
int dbg_cpu0_read_ctrl(unsigned long adr, unsigned char *data) {
int dbg_cpu0_read_ctrl(unsigned long adr, unsigned char *data) {
  int err;
  int err;
  int r, s;
  int r, s;
  if ((err = dbg_set_chain(DC_CPU0))) return err;
  if ((err = dbg_set_chain(DC_CPU0))) return err;
  if ((err = dbg_ctrl_read(&r, &s))) return err;
  if ((err = dbg_ctrl_read(&r, &s))) return err;
  *data = (r << 1) | s;
  *data = (r << 1) | s;
  return DBG_ERR_OK;
  return DBG_ERR_OK;
}
}
 
 
void check(char *fn, int l, int i) {
void check(char *fn, int l, int i) {
  if (i != DBG_ERR_OK) {
  if (i != DBG_ERR_OK) {
    fprintf(stderr, "%s:%d: Jtag error %d occured; exiting.\n", fn, l, i);
    fprintf(stderr, "%s:%d: Jtag error %d occured; exiting.\n", fn, l, i);
    exit(1);
    exit(1);
  }
  }
}
}
 
 
 
 
void test_sdram (void) {
void test_sdram (void) {
  unsigned long insn;
  unsigned long insn;
  unsigned long i;
  unsigned long i;
  unsigned long data4_out[0x08];
  unsigned long data4_out[0x08];
  unsigned long data4_in[0x08];
  unsigned long data4_in[0x08];
  unsigned short data2_out[0x10];
  unsigned short data2_out[0x10];
  unsigned short data2_in[0x10];
  unsigned short data2_in[0x10];
  unsigned char data1_out[0x20];
  unsigned char data1_out[0x20];
  unsigned char data1_in[0x20];
  unsigned char data1_in[0x20];
 
 
  printf("Start SDRAM WR\n");
  printf("Start SDRAM WR\n");
  for (i=0x10; i<(SDRAM_SIZE+SDRAM_BASE); i=i<<1) {
  for (i=0x10; i<(SDRAM_SIZE+SDRAM_BASE); i=i<<1) {
    //printf("0x%x: 0x%x\n", SDRAM_BASE+i, i);
    //printf("0x%x: 0x%x\n", SDRAM_BASE+i, i);
    CHECK(dbg_wb_write32(SDRAM_BASE+i, i));
    CHECK(dbg_wb_write32(SDRAM_BASE+i, i));
  }
  }
 
 
  printf("Start SDRAM RD\n");
  printf("Start SDRAM RD\n");
  for (i=0x10; i<(SDRAM_SIZE+SDRAM_BASE); i=i<<1) {
  for (i=0x10; i<(SDRAM_SIZE+SDRAM_BASE); i=i<<1) {
    CHECK(dbg_wb_read32(SDRAM_BASE+i, &insn));
    CHECK(dbg_wb_read32(SDRAM_BASE+i, &insn));
    //printf("0x%x: 0x%x\n", SDRAM_BASE+i, insn);
    //printf("0x%x: 0x%x\n", SDRAM_BASE+i, insn);
    if (i != insn) {
    if (i != insn) {
      printf("SDRAM not OK");
      printf("SDRAM not OK");
      exit (1);
      exit (1);
    }
    }
  }
  }
 
 
  printf("32-bit block write from %x to %x\n", SDRAM_BASE, SDRAM_BASE + 0x20);
  printf("32-bit block write from %x to %x\n", SDRAM_BASE, SDRAM_BASE + 0x20);
  for (i=0; i<(0x20/4); i++) {
  for (i=0; i<(0x20/4); i++) {
    data4_out[i] = data4_in[i] = ((4*i+3)<<24) | ((4*i+2)<<16) | ((4*i+1)<<8) | (4*i);
    data4_out[i] = data4_in[i] = ((4*i+3)<<24) | ((4*i+2)<<16) | ((4*i+1)<<8) | (4*i);
    //printf("data_out = %0x\n", data4_out[i]);
    //printf("data_out = %0x\n", data4_out[i]);
  }
  }
 
 
  //printf("Press a key for write\n"); getchar();
  //printf("Press a key for write\n"); getchar();
  CHECK(dbg_wb_write_block32(SDRAM_BASE, &data4_out[0], 0x20));
  CHECK(dbg_wb_write_block32(SDRAM_BASE, &data4_out[0], 0x20));
 
 
  // 32-bit block read is used for checking
  // 32-bit block read is used for checking
  printf("32-bit block read from %x to %x\n", SDRAM_BASE, SDRAM_BASE + 0x20);
  printf("32-bit block read from %x to %x\n", SDRAM_BASE, SDRAM_BASE + 0x20);
  CHECK(dbg_wb_read_block32(SDRAM_BASE, &data4_out[0], 0x20));
  CHECK(dbg_wb_read_block32(SDRAM_BASE, &data4_out[0], 0x20));
  for (i=0; i<(0x20/4); i++) {
  for (i=0; i<(0x20/4); i++) {
    //printf("0x%x: 0x%x\n", SDRAM_BASE+(i*4), data_out[i]);
    //printf("0x%x: 0x%x\n", SDRAM_BASE+(i*4), data_out[i]);
    if (data4_in[i] != data4_out[i]) {
    if (data4_in[i] != data4_out[i]) {
      printf("SDRAM data differs. Expected: 0x%0x, read: 0x%0x\n", data4_in[i], data4_out[i]);
      printf("SDRAM data differs. Expected: 0x%0x, read: 0x%0x\n", data4_in[i], data4_out[i]);
      exit(1);
      exit(1);
    }
    }
  }
  }
 
 
  printf("16-bit block write from %x to %x\n", SDRAM_BASE, SDRAM_BASE + 0x20);
  printf("16-bit block write from %x to %x\n", SDRAM_BASE, SDRAM_BASE + 0x20);
  for (i=0; i<(0x20/2); i++) {
  for (i=0; i<(0x20/2); i++) {
    data2_out[i] = data2_in[i] = ((4*i+1)<<8) | (4*i);
    data2_out[i] = data2_in[i] = ((4*i+1)<<8) | (4*i);
    //printf("data_out = %0x\n", data_out[i]);
    //printf("data_out = %0x\n", data_out[i]);
  }
  }
  CHECK(dbg_wb_write_block16(SDRAM_BASE, &data2_out[0], 0x20));
  CHECK(dbg_wb_write_block16(SDRAM_BASE, &data2_out[0], 0x20));
 
 
  // 16-bit block read is used for checking
  // 16-bit block read is used for checking
  printf("16-bit block read from %x to %x\n", SDRAM_BASE, SDRAM_BASE + 0x20);
  printf("16-bit block read from %x to %x\n", SDRAM_BASE, SDRAM_BASE + 0x20);
  CHECK(dbg_wb_read_block16(SDRAM_BASE, &data2_out[0], 0x20));
  CHECK(dbg_wb_read_block16(SDRAM_BASE, &data2_out[0], 0x20));
  for (i=0; i<(0x20/2); i++) {
  for (i=0; i<(0x20/2); i++) {
    //printf("0x%x: 0x%x\n", SDRAM_BASE+(i*4), data_out[i]);
    //printf("0x%x: 0x%x\n", SDRAM_BASE+(i*4), data_out[i]);
    if (data2_in[i] != data2_out[i]) {
    if (data2_in[i] != data2_out[i]) {
      printf("SDRAM data differs. Expected: 0x%0x, read: 0x%0x\n", data2_in[i], data2_out[i]);
      printf("SDRAM data differs. Expected: 0x%0x, read: 0x%0x\n", data2_in[i], data2_out[i]);
      exit(1);
      exit(1);
    }
    }
  }
  }
 
 
  printf("8-bit block write from %x to %x\n", SDRAM_BASE, SDRAM_BASE + 0x20);
  printf("8-bit block write from %x to %x\n", SDRAM_BASE, SDRAM_BASE + 0x20);
  for (i=0; i<(0x20/1); i++) {
  for (i=0; i<(0x20/1); i++) {
    data1_out[i] = data1_in[i] = (4*i);
    data1_out[i] = data1_in[i] = (4*i);
    //printf("data_out = %0x\n", data_out[i]);
    //printf("data_out = %0x\n", data_out[i]);
  }
  }
  CHECK(dbg_wb_write_block8(SDRAM_BASE, &data1_out[0], 0x20));
  CHECK(dbg_wb_write_block8(SDRAM_BASE, &data1_out[0], 0x20));
 
 
  // 32-bit block read is used for checking
  // 32-bit block read is used for checking
  printf("8-bit block read from %x to %x\n", SDRAM_BASE, SDRAM_BASE + 0x20);
  printf("8-bit block read from %x to %x\n", SDRAM_BASE, SDRAM_BASE + 0x20);
  CHECK(dbg_wb_read_block8(SDRAM_BASE, &data1_out[0], 0x20));
  CHECK(dbg_wb_read_block8(SDRAM_BASE, &data1_out[0], 0x20));
  for (i=0; i<(0x20/1); i++) {
  for (i=0; i<(0x20/1); i++) {
    //printf("0x%x: 0x%x\n", SDRAM_BASE+(i*4), data_out[i]);
    //printf("0x%x: 0x%x\n", SDRAM_BASE+(i*4), data_out[i]);
    if (data1_in[i] != data1_out[i]) {
    if (data1_in[i] != data1_out[i]) {
      printf("SDRAM data differs. Expected: 0x%0x, read: 0x%0x\n", data1_in[i], data1_out[i]);
      printf("SDRAM data differs. Expected: 0x%0x, read: 0x%0x\n", data1_in[i], data1_out[i]);
      exit(1);
      exit(1);
    }
    }
  }
  }
}
}
 
 
 
 
void dbg_test() {
void dbg_test() {
  int i;
  int i;
  unsigned long npc, ppc, r1, insn, result;
  unsigned long npc, ppc, r1, insn, result;
  unsigned char stalled;
  unsigned char stalled;
#if 1
#if 1
#define MC_BASE_ADDR     0x93000000
#define MC_BASE_ADDR     0x93000000
#define FLASH_BASE_ADDR  0xf0000000
#define FLASH_BASE_ADDR  0xf0000000
#define FLASH_BAR_VAL    FLASH_BASE_ADDR
#define FLASH_BAR_VAL    FLASH_BASE_ADDR
#define FLASH_AMR_VAL    0xf0000000
#define FLASH_AMR_VAL    0xf0000000
#define FLASH_WTR_VAL    0x00011009
#define FLASH_WTR_VAL    0x00011009
#define FLASH_RTR_VAL    0x01002009
#define FLASH_RTR_VAL    0x01002009
#define SDRAM_BASE_ADDR  0x00000000
#define SDRAM_BASE_ADDR  0x00000000
#define SDRAM_BAR_VAL    SDRAM_BASE_ADDR
#define SDRAM_BAR_VAL    SDRAM_BASE_ADDR
//#define SDRAM_SIZE       0x04000000  defined at the start of this program
//#define SDRAM_SIZE       0x04000000  defined at the start of this program
#define SDRAM_AMR_VAL    (~(SDRAM_SIZE -1))
#define SDRAM_AMR_VAL    (~(SDRAM_SIZE -1))
#define SDRAM_RATR_VAL   0x00000006
#define SDRAM_RATR_VAL   0x00000006
#define SDRAM_RCDR_VAL   0x00000002
#define SDRAM_RCDR_VAL   0x00000002
#define SDRAM_RCTR_VAL   0x00000006
#define SDRAM_RCTR_VAL   0x00000006
#define SDRAM_REFCTR_VAL 0x00000006
#define SDRAM_REFCTR_VAL 0x00000006
#define SDRAM_PTR_VAL    0x00000001
#define SDRAM_PTR_VAL    0x00000001
#define SDRAM_RRDR_VAL   0x00000000
#define SDRAM_RRDR_VAL   0x00000000
#define SDRAM_RIR_VAL    0x000000C0
#define SDRAM_RIR_VAL    0x000000C0
 
 
#define MC_BAR_0         0x00
#define MC_BAR_0         0x00
#define MC_AMR_0         0x04
#define MC_AMR_0         0x04
#define MC_WTR_0         0x30
#define MC_WTR_0         0x30
#define MC_RTR_0         0x34
#define MC_RTR_0         0x34
#define MC_OSR           0xe8
#define MC_OSR           0xe8
#define MC_BAR_1         0x08
#define MC_BAR_1         0x08
#define MC_BAR_4         0x80
#define MC_BAR_4         0x80
#define MC_AMR_1         0x0c
#define MC_AMR_1         0x0c
#define MC_AMR_4         0x84
#define MC_AMR_4         0x84
#define MC_CCR_1         0x24
#define MC_CCR_1         0x24
#define MC_CCR_4         0xa0
#define MC_CCR_4         0xa0
#define MC_RATR          0xb0
#define MC_RATR          0xb0
#define MC_RCDR          0xc8
#define MC_RCDR          0xc8
#define MC_RCTR          0xb4
#define MC_RCTR          0xb4
#define MC_REFCTR        0xc4
#define MC_REFCTR        0xc4
#define MC_PTR           0xbc
#define MC_PTR           0xbc
#define MC_RRDR          0xb8
#define MC_RRDR          0xb8
#define MC_RIR           0xcc
#define MC_RIR           0xcc
#define MC_ORR           0xe4
#define MC_ORR           0xe4
 
 
  //usleep(1000000);
  //usleep(1000000);
 
 
  printf("Stall 8051\n");
  printf("Stall 8051\n");
  CHECK(dbg_cpu1_write_reg(0, 0x01)); // stall 8051
  CHECK(dbg_cpu1_write_reg(0, 0x01)); // stall 8051
 
 
  printf("Stall or1k\n");
  printf("Stall or1k\n");
  CHECK(dbg_cpu0_write_ctrl(0, 0x01));      // stall or1k
  CHECK(dbg_cpu0_write_ctrl(0, 0x01));      // stall or1k
 
 
  CHECK(dbg_cpu1_read_ctrl(0, &stalled));
  CHECK(dbg_cpu1_read_ctrl(0, &stalled));
  if (!(stalled & 0x1)) {
  if (!(stalled & 0x1)) {
    printf("8051 should be stalled\n");   // check stall 8051
    printf("8051 should be stalled\n");   // check stall 8051
    exit(1);
    exit(1);
  }
  }
 
 
  CHECK(dbg_cpu0_read_ctrl(0, &stalled));
  CHECK(dbg_cpu0_read_ctrl(0, &stalled));
  if (!(stalled & 0x1)) {
  if (!(stalled & 0x1)) {
    printf("or1k should be stalled\n");   // check stall or1k
    printf("or1k should be stalled\n");   // check stall or1k
    exit(1);
    exit(1);
  }
  }
 
 
  printf("Initialize Memory Controller\n");
  printf("Initialize Memory Controller\n");
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_BAR_0, FLASH_BAR_VAL & 0xffff0000));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_BAR_0, FLASH_BAR_VAL & 0xffff0000));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_AMR_0, FLASH_AMR_VAL & 0xffff0000));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_AMR_0, FLASH_AMR_VAL & 0xffff0000));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_WTR_0, FLASH_WTR_VAL));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_WTR_0, FLASH_WTR_VAL));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_RTR_0, FLASH_RTR_VAL));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_RTR_0, FLASH_RTR_VAL));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_OSR, 0x40000000));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_OSR, 0x40000000));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_BAR_4, SDRAM_BAR_VAL & 0xffff0000));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_BAR_4, SDRAM_BAR_VAL & 0xffff0000));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_AMR_4, SDRAM_AMR_VAL & 0xffff0000));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_AMR_4, SDRAM_AMR_VAL & 0xffff0000));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_CCR_4, 0x00bf0005));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_CCR_4, 0x00bf0005));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_RATR, SDRAM_RATR_VAL));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_RATR, SDRAM_RATR_VAL));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_RCDR, SDRAM_RCDR_VAL));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_RCDR, SDRAM_RCDR_VAL));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_RCTR, SDRAM_RCTR_VAL));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_RCTR, SDRAM_RCTR_VAL));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_REFCTR, SDRAM_REFCTR_VAL));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_REFCTR, SDRAM_REFCTR_VAL));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_PTR, SDRAM_PTR_VAL));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_PTR, SDRAM_PTR_VAL));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_RRDR, SDRAM_RRDR_VAL));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_RRDR, SDRAM_RRDR_VAL));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_RIR, SDRAM_RIR_VAL));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_RIR, SDRAM_RIR_VAL));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_OSR, 0x5e000000));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_OSR, 0x5e000000));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_ORR, 0x5e000000));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_ORR, 0x5e000000));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_OSR, 0x6e000000));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_OSR, 0x6e000000));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_ORR, 0x6e000000));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_ORR, 0x6e000000));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_ORR, 0x6e000000));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_ORR, 0x6e000000));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_ORR, 0x6e000000));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_ORR, 0x6e000000));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_ORR, 0x6e000000));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_ORR, 0x6e000000));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_ORR, 0x6e000000));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_ORR, 0x6e000000));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_ORR, 0x6e000000));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_ORR, 0x6e000000));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_ORR, 0x6e000000));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_ORR, 0x6e000000));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_ORR, 0x6e000000));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_ORR, 0x6e000000));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_OSR, 0x7e000033));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_OSR, 0x7e000033));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_ORR, 0x7e000033));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_ORR, 0x7e000033));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_CCR_4, 0xc0bf0005));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_CCR_4, 0xc0bf0005));
 
 
  CHECK(dbg_wb_read32(MC_BASE_ADDR+MC_CCR_4, &insn));
  CHECK(dbg_wb_read32(MC_BASE_ADDR+MC_CCR_4, &insn));
  printf("expected %x, read %x\n", 0xc0bf0005, insn);
  printf("expected %x, read %x\n", 0xc0bf0005, insn);
 
 
  // SRAM initialized to 0x40000000
  // SRAM initialized to 0x40000000
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_BAR_1, SRAM_BASE & 0xffff0000));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_BAR_1, SRAM_BASE & 0xffff0000));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_AMR_1, ~(SRAM_SIZE - 1) & 0xffff0000));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_AMR_1, ~(SRAM_SIZE - 1) & 0xffff0000));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_CCR_1, 0xc020001f));
  CHECK(dbg_wb_write32(MC_BASE_ADDR + MC_CCR_1, 0xc020001f));
#endif
#endif
 
 
#if 1
#if 1
#define CPU_OP_ADR  0
#define CPU_OP_ADR  0
#define CPU_SEL_ADR 1
#define CPU_SEL_ADR 1
 
 
  /* unstall the or1200 in highland_sys */
  /* unstall the or1200 in highland_sys */
  printf("Unstall or1k\n");
  printf("Unstall or1k\n");
  CHECK(dbg_wb_write32(0xb8070000, 2));
  CHECK(dbg_wb_write32(0xb8070000, 2));
 
 
  CHECK(dbg_cpu1_read_ctrl(0, &stalled));
  CHECK(dbg_cpu1_read_ctrl(0, &stalled));
  if (!(stalled & 0x1)) {
  if (!(stalled & 0x1)) {
    printf("8051 should be stalled\n");   // check stall 8051
    printf("8051 should be stalled\n");   // check stall 8051
    exit(1);
    exit(1);
  }
  }
 
 
  printf("Stall or1k\n");
  printf("Stall or1k\n");
  CHECK(dbg_cpu0_write_ctrl(0, 0x01));         // stall or1k
  CHECK(dbg_cpu0_write_ctrl(0, 0x01));         // stall or1k
 
 
  printf("SDRAM test: \n");
  printf("SDRAM test: \n");
  CHECK(dbg_wb_write32(SDRAM_BASE+0x00, 0x12345678));
  CHECK(dbg_wb_write32(SDRAM_BASE+0x00, 0x12345678));
  CHECK(dbg_wb_read32(SDRAM_BASE+0x00, &insn));
  CHECK(dbg_wb_read32(SDRAM_BASE+0x00, &insn));
  printf("expected %x, read %x\n", 0x12345678, insn);
  printf("expected %x, read %x\n", 0x12345678, insn);
  if (insn != 0x12345678) exit(1);
  if (insn != 0x12345678) exit(1);
 
 
  CHECK(dbg_wb_write32(SDRAM_BASE+0x0000, 0x11112222));
  CHECK(dbg_wb_write32(SDRAM_BASE+0x0000, 0x11112222));
  CHECK(dbg_wb_read32(SDRAM_BASE+0x0000, &insn));
  CHECK(dbg_wb_read32(SDRAM_BASE+0x0000, &insn));
  printf("expected %x, read %x\n", 0x11112222, insn);
  printf("expected %x, read %x\n", 0x11112222, insn);
  if (insn != 0x11112222) exit(1);
  if (insn != 0x11112222) exit(1);
 
 
  CHECK(dbg_wb_write32(SDRAM_BASE+0x0004, 0x33334444));
  CHECK(dbg_wb_write32(SDRAM_BASE+0x0004, 0x33334444));
  CHECK(dbg_wb_write32(SDRAM_BASE+0x0008, 0x55556666));
  CHECK(dbg_wb_write32(SDRAM_BASE+0x0008, 0x55556666));
  CHECK(dbg_wb_write32(SDRAM_BASE+0x000c, 0x77778888));
  CHECK(dbg_wb_write32(SDRAM_BASE+0x000c, 0x77778888));
  CHECK(dbg_wb_write32(SDRAM_BASE+0x0010, 0x9999aaaa));
  CHECK(dbg_wb_write32(SDRAM_BASE+0x0010, 0x9999aaaa));
  CHECK(dbg_wb_write32(SDRAM_BASE+0x0014, 0xbbbbcccc));
  CHECK(dbg_wb_write32(SDRAM_BASE+0x0014, 0xbbbbcccc));
  CHECK(dbg_wb_write32(SDRAM_BASE+0x0018, 0xddddeeee));
  CHECK(dbg_wb_write32(SDRAM_BASE+0x0018, 0xddddeeee));
  CHECK(dbg_wb_write32(SDRAM_BASE+0x001c, 0xffff0000));
  CHECK(dbg_wb_write32(SDRAM_BASE+0x001c, 0xffff0000));
  CHECK(dbg_wb_write32(SDRAM_BASE+0x0020, 0xdeadbeef));
  CHECK(dbg_wb_write32(SDRAM_BASE+0x0020, 0xdeadbeef));
 
 
  CHECK(dbg_wb_read32(SDRAM_BASE+0x0000, &insn));
  CHECK(dbg_wb_read32(SDRAM_BASE+0x0000, &insn));
  printf("expected %x, read %x\n", 0x11112222, insn);
  printf("expected %x, read %x\n", 0x11112222, insn);
  CHECK(dbg_wb_read32(SDRAM_BASE+0x0004, &insn));
  CHECK(dbg_wb_read32(SDRAM_BASE+0x0004, &insn));
  printf("expected %x, read %x\n", 0x33334444, insn);
  printf("expected %x, read %x\n", 0x33334444, insn);
  CHECK(dbg_wb_read32(SDRAM_BASE+0x0008, &insn));
  CHECK(dbg_wb_read32(SDRAM_BASE+0x0008, &insn));
  printf("expected %x, read %x\n", 0x55556666, insn);
  printf("expected %x, read %x\n", 0x55556666, insn);
  CHECK(dbg_wb_read32(SDRAM_BASE+0x000c, &insn));
  CHECK(dbg_wb_read32(SDRAM_BASE+0x000c, &insn));
  printf("expected %x, read %x\n", 0x77778888, insn);
  printf("expected %x, read %x\n", 0x77778888, insn);
  CHECK(dbg_wb_read32(SDRAM_BASE+0x0010, &insn));
  CHECK(dbg_wb_read32(SDRAM_BASE+0x0010, &insn));
  printf("expected %x, read %x\n", 0x9999aaaa, insn);
  printf("expected %x, read %x\n", 0x9999aaaa, insn);
  CHECK(dbg_wb_read32(SDRAM_BASE+0x0014, &insn));
  CHECK(dbg_wb_read32(SDRAM_BASE+0x0014, &insn));
  printf("expected %x, read %x\n", 0xbbbbcccc, insn);
  printf("expected %x, read %x\n", 0xbbbbcccc, insn);
  CHECK(dbg_wb_read32(SDRAM_BASE+0x0018, &insn));
  CHECK(dbg_wb_read32(SDRAM_BASE+0x0018, &insn));
  printf("expected %x, read %x\n", 0xddddeeee, insn);
  printf("expected %x, read %x\n", 0xddddeeee, insn);
  CHECK(dbg_wb_read32(SDRAM_BASE+0x001c, &insn));
  CHECK(dbg_wb_read32(SDRAM_BASE+0x001c, &insn));
  printf("expected %x, read %x\n", 0xffff0000, insn);
  printf("expected %x, read %x\n", 0xffff0000, insn);
  CHECK(dbg_wb_read32(SDRAM_BASE+0x0020, &insn));
  CHECK(dbg_wb_read32(SDRAM_BASE+0x0020, &insn));
  printf("expected %x, read %x\n", 0xdeadbeef, insn);
  printf("expected %x, read %x\n", 0xdeadbeef, insn);
 
 
  if (insn != 0xdeadbeef) {
  if (insn != 0xdeadbeef) {
    printf("SDRAM test failed !!!\n");
    printf("SDRAM test failed !!!\n");
    exit(1);
    exit(1);
  }
  }
    else
    else
    printf("SDRAM test passed\n");
    printf("SDRAM test passed\n");
 
 
  printf("SRAM test: \n");
  printf("SRAM test: \n");
  CHECK(dbg_wb_write32(SRAM_BASE+0x0000, 0x11112222));
  CHECK(dbg_wb_write32(SRAM_BASE+0x0000, 0x11112222));
  CHECK(dbg_wb_write32(SRAM_BASE+0x0004, 0x33334444));
  CHECK(dbg_wb_write32(SRAM_BASE+0x0004, 0x33334444));
  CHECK(dbg_wb_write32(SRAM_BASE+0x0008, 0x55556666));
  CHECK(dbg_wb_write32(SRAM_BASE+0x0008, 0x55556666));
  CHECK(dbg_wb_write32(SRAM_BASE+0x000c, 0x77778888));
  CHECK(dbg_wb_write32(SRAM_BASE+0x000c, 0x77778888));
  CHECK(dbg_wb_write32(SRAM_BASE+0x0010, 0x9999aaaa));
  CHECK(dbg_wb_write32(SRAM_BASE+0x0010, 0x9999aaaa));
  CHECK(dbg_wb_write32(SRAM_BASE+0x0014, 0xbbbbcccc));
  CHECK(dbg_wb_write32(SRAM_BASE+0x0014, 0xbbbbcccc));
  CHECK(dbg_wb_write32(SRAM_BASE+0x0018, 0xddddeeee));
  CHECK(dbg_wb_write32(SRAM_BASE+0x0018, 0xddddeeee));
  CHECK(dbg_wb_write32(SRAM_BASE+0x001c, 0xffff0000));
  CHECK(dbg_wb_write32(SRAM_BASE+0x001c, 0xffff0000));
  CHECK(dbg_wb_write32(SRAM_BASE+0x0020, 0xdedababa));
  CHECK(dbg_wb_write32(SRAM_BASE+0x0020, 0xdedababa));
 
 
  CHECK(dbg_wb_read32(SRAM_BASE+0x0000, &insn));
  CHECK(dbg_wb_read32(SRAM_BASE+0x0000, &insn));
  printf("expected %x, read %x\n", 0x11112222, insn);
  printf("expected %x, read %x\n", 0x11112222, insn);
  CHECK(dbg_wb_read32(SRAM_BASE+0x0004, &insn));
  CHECK(dbg_wb_read32(SRAM_BASE+0x0004, &insn));
  printf("expected %x, read %x\n", 0x33334444, insn);
  printf("expected %x, read %x\n", 0x33334444, insn);
  CHECK(dbg_wb_read32(SRAM_BASE+0x0008, &insn));
  CHECK(dbg_wb_read32(SRAM_BASE+0x0008, &insn));
  printf("expected %x, read %x\n", 0x55556666, insn);
  printf("expected %x, read %x\n", 0x55556666, insn);
  CHECK(dbg_wb_read32(SRAM_BASE+0x000c, &insn));
  CHECK(dbg_wb_read32(SRAM_BASE+0x000c, &insn));
  printf("expected %x, read %x\n", 0x77778888, insn);
  printf("expected %x, read %x\n", 0x77778888, insn);
  CHECK(dbg_wb_read32(SRAM_BASE+0x0010, &insn));
  CHECK(dbg_wb_read32(SRAM_BASE+0x0010, &insn));
  printf("expected %x, read %x\n", 0x9999aaaa, insn);
  printf("expected %x, read %x\n", 0x9999aaaa, insn);
  CHECK(dbg_wb_read32(SRAM_BASE+0x0014, &insn));
  CHECK(dbg_wb_read32(SRAM_BASE+0x0014, &insn));
  printf("expected %x, read %x\n", 0xbbbbcccc, insn);
  printf("expected %x, read %x\n", 0xbbbbcccc, insn);
  CHECK(dbg_wb_read32(SRAM_BASE+0x0018, &insn));
  CHECK(dbg_wb_read32(SRAM_BASE+0x0018, &insn));
  printf("expected %x, read %x\n", 0xddddeeee, insn);
  printf("expected %x, read %x\n", 0xddddeeee, insn);
  CHECK(dbg_wb_read32(SRAM_BASE+0x001c, &insn));
  CHECK(dbg_wb_read32(SRAM_BASE+0x001c, &insn));
  printf("expected %x, read %x\n", 0xffff0000, insn);
  printf("expected %x, read %x\n", 0xffff0000, insn);
  CHECK(dbg_wb_read32(SRAM_BASE+0x0020, &insn));
  CHECK(dbg_wb_read32(SRAM_BASE+0x0020, &insn));
  printf("expected %x, read %x\n", 0xdedababa, insn);
  printf("expected %x, read %x\n", 0xdedababa, insn);
 
 
  if (insn != 0xdedababa) {
  if (insn != 0xdedababa) {
    printf("SRAN test failed!!!\n");
    printf("SRAN test failed!!!\n");
    exit(1);
    exit(1);
  }
  }
    else
    else
    printf("SRAM test passed\n");
    printf("SRAM test passed\n");
 
 
  #if 1
  #if 1
    test_sdram();
    test_sdram();
  #endif
  #endif
 
 
  CHECK(dbg_wb_write32(SDRAM_BASE+0x00, 0xe0000005));   /* l.xor   r0,r0,r0   */
  CHECK(dbg_wb_write32(SDRAM_BASE+0x00, 0xe0000005));   /* l.xor   r0,r0,r0   */
  CHECK(dbg_wb_write32(SDRAM_BASE+0x04, 0x9c200000));   /* l.addi  r1,r0,0x0  */
  CHECK(dbg_wb_write32(SDRAM_BASE+0x04, 0x9c200000));   /* l.addi  r1,r0,0x0  */
  CHECK(dbg_wb_write32(SDRAM_BASE+0x08, 0x18400000));   /* l.movhi r2,0x4000  */
  CHECK(dbg_wb_write32(SDRAM_BASE+0x08, 0x18400000));   /* l.movhi r2,0x4000  */
  CHECK(dbg_wb_write32(SDRAM_BASE+0x0c, 0xa8420030));   /* l.ori   r2,r2,0x30 */
  CHECK(dbg_wb_write32(SDRAM_BASE+0x0c, 0xa8420030));   /* l.ori   r2,r2,0x30 */
  CHECK(dbg_wb_write32(SDRAM_BASE+0x10, 0x9c210001));   /* l.addi  r1,r1,1    */
  CHECK(dbg_wb_write32(SDRAM_BASE+0x10, 0x9c210001));   /* l.addi  r1,r1,1    */
  CHECK(dbg_wb_write32(SDRAM_BASE+0x14, 0x9c210001));   /* l.addi  r1,r1,1    */
  CHECK(dbg_wb_write32(SDRAM_BASE+0x14, 0x9c210001));   /* l.addi  r1,r1,1    */
  CHECK(dbg_wb_write32(SDRAM_BASE+0x18, 0xd4020800));   /* l.sw    0(r2),r1   */
  CHECK(dbg_wb_write32(SDRAM_BASE+0x18, 0xd4020800));   /* l.sw    0(r2),r1   */
  CHECK(dbg_wb_write32(SDRAM_BASE+0x1c, 0x9c210001));   /* l.addi  r1,r1,1    */
  CHECK(dbg_wb_write32(SDRAM_BASE+0x1c, 0x9c210001));   /* l.addi  r1,r1,1    */
  CHECK(dbg_wb_write32(SDRAM_BASE+0x20, 0x84620000));   /* l.lwz   r3,0(r2)   */
  CHECK(dbg_wb_write32(SDRAM_BASE+0x20, 0x84620000));   /* l.lwz   r3,0(r2)   */
  CHECK(dbg_wb_write32(SDRAM_BASE+0x24, 0x03fffffb));   /* l.j     loop2      */
  CHECK(dbg_wb_write32(SDRAM_BASE+0x24, 0x03fffffb));   /* l.j     loop2      */
  CHECK(dbg_wb_write32(SDRAM_BASE+0x28, 0xe0211800));   /* l.add   r1,r1,r3   */
  CHECK(dbg_wb_write32(SDRAM_BASE+0x28, 0xe0211800));   /* l.add   r1,r1,r3   */
 
 
  CHECK(dbg_cpu0_write((0 << 11) + 17, 0x01));  /* Enable exceptions */
  CHECK(dbg_cpu0_write((0 << 11) + 17, 0x01));  /* Enable exceptions */
  CHECK(dbg_cpu0_write((6 << 11) + 20, 0x2000));  /* Trap causes stall */
  CHECK(dbg_cpu0_write((6 << 11) + 20, 0x2000));  /* Trap causes stall */
  CHECK(dbg_cpu0_write((0 << 11) + 16, SDRAM_BASE));  /* Set PC */
  CHECK(dbg_cpu0_write((0 << 11) + 16, SDRAM_BASE));  /* Set PC */
  CHECK(dbg_cpu0_write((6 << 11) + 16, 1 << 22));  /* Set step bit */
  CHECK(dbg_cpu0_write((6 << 11) + 16, 1 << 22));  /* Set step bit */
  for(i = 0; i < 11; i++) {
  for(i = 0; i < 11; i++) {
    CHECK(dbg_cpu0_write_ctrl(CPU_OP_ADR, 0x00));  /* 11x Unstall */
    CHECK(dbg_cpu0_write_ctrl(CPU_OP_ADR, 0x00));  /* 11x Unstall */
    do CHECK(dbg_cpu0_read_ctrl(CPU_OP_ADR, &stalled)); while (!(stalled & 1));
    do CHECK(dbg_cpu0_read_ctrl(CPU_OP_ADR, &stalled)); while (!(stalled & 1));
  }
  }
 
 
  CHECK(dbg_cpu0_read((0 << 11) + 16, &npc));  /* Read NPC */
  CHECK(dbg_cpu0_read((0 << 11) + 16, &npc));  /* Read NPC */
  CHECK(dbg_cpu0_read((0 << 11) + 18, &ppc));  /* Read PPC */
  CHECK(dbg_cpu0_read((0 << 11) + 18, &ppc));  /* Read PPC */
  CHECK(dbg_cpu0_read(0x401, &r1));  /* Read R1 */
  CHECK(dbg_cpu0_read(0x401, &r1));  /* Read R1 */
  printf("Read      npc = %.8lx ppc = %.8lx r1 = %.8lx\n", npc, ppc, r1);
  printf("Read      npc = %.8lx ppc = %.8lx r1 = %.8lx\n", npc, ppc, r1);
  printf("Expected  npc = %.8lx ppc = %.8lx r1 = %.8lx\n", 0x00000010, 0x00000028, 5);
  printf("Expected  npc = %.8lx ppc = %.8lx r1 = %.8lx\n", 0x00000010, 0x00000028, 5);
  result = npc + ppc + r1;
  result = npc + ppc + r1;
 
 
  CHECK(dbg_cpu0_write((6 << 11) + 16, 0));  /* Reset step bit */
  CHECK(dbg_cpu0_write((6 << 11) + 16, 0));  /* Reset step bit */
  CHECK(dbg_wb_read32(SDRAM_BASE + 0x28, &insn));  /* Set trap insn in delay slot */
  CHECK(dbg_wb_read32(SDRAM_BASE + 0x28, &insn));  /* Set trap insn in delay slot */
  CHECK(dbg_wb_write32(SDRAM_BASE + 0x28, 0x21000001));
  CHECK(dbg_wb_write32(SDRAM_BASE + 0x28, 0x21000001));
  CHECK(dbg_cpu0_write_ctrl(CPU_OP_ADR, 0x00));  /* Unstall */
  CHECK(dbg_cpu0_write_ctrl(CPU_OP_ADR, 0x00));  /* Unstall */
  do CHECK(dbg_cpu0_read_ctrl(CPU_OP_ADR, &stalled)); while (!(stalled & 1));
  do CHECK(dbg_cpu0_read_ctrl(CPU_OP_ADR, &stalled)); while (!(stalled & 1));
  CHECK(dbg_cpu0_read((0 << 11) + 16, &npc));  /* Read NPC */
  CHECK(dbg_cpu0_read((0 << 11) + 16, &npc));  /* Read NPC */
  CHECK(dbg_cpu0_read((0 << 11) + 18, &ppc));  /* Read PPC */
  CHECK(dbg_cpu0_read((0 << 11) + 18, &ppc));  /* Read PPC */
  CHECK(dbg_cpu0_read(0x401, &r1));  /* Read R1 */
  CHECK(dbg_cpu0_read(0x401, &r1));  /* Read R1 */
  CHECK(dbg_wb_write32(SDRAM_BASE + 0x28, insn));  /* Set back original insn */
  CHECK(dbg_wb_write32(SDRAM_BASE + 0x28, insn));  /* Set back original insn */
  printf("Read      npc = %.8lx ppc = %.8lx r1 = %.8lx\n", npc, ppc, r1);
  printf("Read      npc = %.8lx ppc = %.8lx r1 = %.8lx\n", npc, ppc, r1);
  printf("Expected  npc = %.8lx ppc = %.8lx r1 = %.8lx\n", 0x00000010, 0x00000028, 8);
  printf("Expected  npc = %.8lx ppc = %.8lx r1 = %.8lx\n", 0x00000010, 0x00000028, 8);
  result = npc + ppc + r1 + result;
  result = npc + ppc + r1 + result;
 
 
  CHECK(dbg_wb_read32(SDRAM_BASE + 0x24, &insn));  /* Set trap insn in place of branch insn */
  CHECK(dbg_wb_read32(SDRAM_BASE + 0x24, &insn));  /* Set trap insn in place of branch insn */
  CHECK(dbg_wb_write32(SDRAM_BASE + 0x24, 0x21000001));
  CHECK(dbg_wb_write32(SDRAM_BASE + 0x24, 0x21000001));
  CHECK(dbg_cpu0_write((0 << 11) + 16, SDRAM_BASE + 0x10));  /* Set PC */
  CHECK(dbg_cpu0_write((0 << 11) + 16, SDRAM_BASE + 0x10));  /* Set PC */
  CHECK(dbg_cpu0_write_ctrl(CPU_OP_ADR, 0x00));  /* Unstall */
  CHECK(dbg_cpu0_write_ctrl(CPU_OP_ADR, 0x00));  /* Unstall */
  do CHECK(dbg_cpu0_read_ctrl(CPU_OP_ADR, &stalled)); while (!(stalled & 1));
  do CHECK(dbg_cpu0_read_ctrl(CPU_OP_ADR, &stalled)); while (!(stalled & 1));
  CHECK(dbg_cpu0_read((0 << 11) + 16, &npc));  /* Read NPC */
  CHECK(dbg_cpu0_read((0 << 11) + 16, &npc));  /* Read NPC */
  CHECK(dbg_cpu0_read((0 << 11) + 18, &ppc));  /* Read PPC */
  CHECK(dbg_cpu0_read((0 << 11) + 18, &ppc));  /* Read PPC */
  CHECK(dbg_cpu0_read(0x401, &r1));  /* Read R1 */
  CHECK(dbg_cpu0_read(0x401, &r1));  /* Read R1 */
  CHECK(dbg_wb_write32(SDRAM_BASE + 0x24, insn));  /* Set back original insn */
  CHECK(dbg_wb_write32(SDRAM_BASE + 0x24, insn));  /* Set back original insn */
  printf("Read      npc = %.8lx ppc = %.8lx r1 = %.8lx\n", npc, ppc, r1);
  printf("Read      npc = %.8lx ppc = %.8lx r1 = %.8lx\n", npc, ppc, r1);
  printf("Expected  npc = %.8lx ppc = %.8lx r1 = %.8lx\n", 0x00000028, 0x00000024, 11);
  printf("Expected  npc = %.8lx ppc = %.8lx r1 = %.8lx\n", 0x00000028, 0x00000024, 11);
  result = npc + ppc + r1 + result;
  result = npc + ppc + r1 + result;
 
 
  CHECK(dbg_wb_read32(SDRAM_BASE + 0x20, &insn));  /* Set trap insn before branch insn */
  CHECK(dbg_wb_read32(SDRAM_BASE + 0x20, &insn));  /* Set trap insn before branch insn */
  CHECK(dbg_wb_write32(SDRAM_BASE + 0x20, 0x21000001));
  CHECK(dbg_wb_write32(SDRAM_BASE + 0x20, 0x21000001));
  CHECK(dbg_cpu0_write((0 << 11) + 16, SDRAM_BASE + 0x24));  /* Set PC */
  CHECK(dbg_cpu0_write((0 << 11) + 16, SDRAM_BASE + 0x24));  /* Set PC */
  CHECK(dbg_cpu0_write_ctrl(CPU_OP_ADR, 0x00));  /* Unstall */
  CHECK(dbg_cpu0_write_ctrl(CPU_OP_ADR, 0x00));  /* Unstall */
  do CHECK(dbg_cpu0_read_ctrl(CPU_OP_ADR, &stalled)); while (!(stalled & 1));
  do CHECK(dbg_cpu0_read_ctrl(CPU_OP_ADR, &stalled)); while (!(stalled & 1));
  CHECK(dbg_cpu0_read((0 << 11) + 16, &npc));  /* Read NPC */
  CHECK(dbg_cpu0_read((0 << 11) + 16, &npc));  /* Read NPC */
  CHECK(dbg_cpu0_read((0 << 11) + 18, &ppc));  /* Read PPC */
  CHECK(dbg_cpu0_read((0 << 11) + 18, &ppc));  /* Read PPC */
  CHECK(dbg_cpu0_read(0x401, &r1));  /* Read R1 */
  CHECK(dbg_cpu0_read(0x401, &r1));  /* Read R1 */
  CHECK(dbg_wb_write32(SDRAM_BASE + 0x20, insn));  /* Set back original insn */
  CHECK(dbg_wb_write32(SDRAM_BASE + 0x20, insn));  /* Set back original insn */
  printf("Read      npc = %.8lx ppc = %.8lx r1 = %.8lx\n", npc, ppc, r1);
  printf("Read      npc = %.8lx ppc = %.8lx r1 = %.8lx\n", npc, ppc, r1);
  printf("Expected  npc = %.8lx ppc = %.8lx r1 = %.8lx\n", 0x00000024, 0x00000020, 24);
  printf("Expected  npc = %.8lx ppc = %.8lx r1 = %.8lx\n", 0x00000024, 0x00000020, 24);
  result = npc + ppc + r1 + result;
  result = npc + ppc + r1 + result;
 
 
  CHECK(dbg_wb_read32(SDRAM_BASE + 0x1c, &insn));  /* Set trap insn behind lsu insn */
  CHECK(dbg_wb_read32(SDRAM_BASE + 0x1c, &insn));  /* Set trap insn behind lsu insn */
  CHECK(dbg_wb_write32(SDRAM_BASE + 0x1c, 0x21000001));
  CHECK(dbg_wb_write32(SDRAM_BASE + 0x1c, 0x21000001));
  CHECK(dbg_cpu0_write((0 << 11) + 16, SDRAM_BASE + 0x20));  /* Set PC */
  CHECK(dbg_cpu0_write((0 << 11) + 16, SDRAM_BASE + 0x20));  /* Set PC */
  CHECK(dbg_cpu0_write_ctrl(CPU_OP_ADR, 0x00));  /* Unstall */
  CHECK(dbg_cpu0_write_ctrl(CPU_OP_ADR, 0x00));  /* Unstall */
  do CHECK(dbg_cpu0_read_ctrl(CPU_OP_ADR, &stalled)); while (!(stalled & 1));
  do CHECK(dbg_cpu0_read_ctrl(CPU_OP_ADR, &stalled)); while (!(stalled & 1));
  CHECK(dbg_cpu0_read((0 << 11) + 16, &npc));  /* Read NPC */
  CHECK(dbg_cpu0_read((0 << 11) + 16, &npc));  /* Read NPC */
  CHECK(dbg_cpu0_read((0 << 11) + 18, &ppc));  /* Read PPC */
  CHECK(dbg_cpu0_read((0 << 11) + 18, &ppc));  /* Read PPC */
  CHECK(dbg_cpu0_read(0x401, &r1));  /* Read R1 */
  CHECK(dbg_cpu0_read(0x401, &r1));  /* Read R1 */
  CHECK(dbg_wb_write32(SDRAM_BASE + 0x1c, insn));  /* Set back original insn */
  CHECK(dbg_wb_write32(SDRAM_BASE + 0x1c, insn));  /* Set back original insn */
  printf("Read      npc = %.8lx ppc = %.8lx r1 = %.8lx\n", npc, ppc, r1);
  printf("Read      npc = %.8lx ppc = %.8lx r1 = %.8lx\n", npc, ppc, r1);
  printf("Expected  npc = %.8lx ppc = %.8lx r1 = %.8lx\n", 0x00000020, 0x0000001c, 49);
  printf("Expected  npc = %.8lx ppc = %.8lx r1 = %.8lx\n", 0x00000020, 0x0000001c, 49);
  result = npc + ppc + r1 + result;
  result = npc + ppc + r1 + result;
 
 
  CHECK(dbg_wb_read32(SDRAM_BASE + 0x20, &insn));  /* Set trap insn very near previous one */
  CHECK(dbg_wb_read32(SDRAM_BASE + 0x20, &insn));  /* Set trap insn very near previous one */
  CHECK(dbg_wb_write32(SDRAM_BASE + 0x20, 0x21000001));
  CHECK(dbg_wb_write32(SDRAM_BASE + 0x20, 0x21000001));
  CHECK(dbg_cpu0_write((0 << 11) + 16, SDRAM_BASE + 0x1c));  /* Set PC */
  CHECK(dbg_cpu0_write((0 << 11) + 16, SDRAM_BASE + 0x1c));  /* Set PC */
  CHECK(dbg_cpu0_write_ctrl(CPU_OP_ADR, 0x00));  /* Unstall */
  CHECK(dbg_cpu0_write_ctrl(CPU_OP_ADR, 0x00));  /* Unstall */
  do CHECK(dbg_cpu0_read_ctrl(CPU_OP_ADR, &stalled)); while (!(stalled & 1));
  do CHECK(dbg_cpu0_read_ctrl(CPU_OP_ADR, &stalled)); while (!(stalled & 1));
  CHECK(dbg_cpu0_read((0 << 11) + 16, &npc));  /* Read NPC */
  CHECK(dbg_cpu0_read((0 << 11) + 16, &npc));  /* Read NPC */
  CHECK(dbg_cpu0_read((0 << 11) + 18, &ppc));  /* Read PPC */
  CHECK(dbg_cpu0_read((0 << 11) + 18, &ppc));  /* Read PPC */
  CHECK(dbg_cpu0_read(0x401, &r1));  /* Read R1 */
  CHECK(dbg_cpu0_read(0x401, &r1));  /* Read R1 */
  CHECK(dbg_wb_write32(SDRAM_BASE + 0x20, insn));  /* Set back original insn */
  CHECK(dbg_wb_write32(SDRAM_BASE + 0x20, insn));  /* Set back original insn */
  printf("Read      npc = %.8lx ppc = %.8lx r1 = %.8lx\n", npc, ppc, r1);
  printf("Read      npc = %.8lx ppc = %.8lx r1 = %.8lx\n", npc, ppc, r1);
  printf("Expected  npc = %.8lx ppc = %.8lx r1 = %.8lx\n", 0x00000024, 0x00000020, 50);
  printf("Expected  npc = %.8lx ppc = %.8lx r1 = %.8lx\n", 0x00000024, 0x00000020, 50);
  result = npc + ppc + r1 + result;
  result = npc + ppc + r1 + result;
 
 
  CHECK(dbg_wb_read32(SDRAM_BASE + 0x10, &insn));  /* Set trap insn to the start */
  CHECK(dbg_wb_read32(SDRAM_BASE + 0x10, &insn));  /* Set trap insn to the start */
  CHECK(dbg_wb_write32(SDRAM_BASE + 0x10, 0x21000001));
  CHECK(dbg_wb_write32(SDRAM_BASE + 0x10, 0x21000001));
  CHECK(dbg_cpu0_write((0 << 11) + 16, SDRAM_BASE + 0x20)  /* Set PC */);
  CHECK(dbg_cpu0_write((0 << 11) + 16, SDRAM_BASE + 0x20)  /* Set PC */);
  CHECK(dbg_cpu0_write_ctrl(CPU_OP_ADR, 0x00));  /* Unstall */
  CHECK(dbg_cpu0_write_ctrl(CPU_OP_ADR, 0x00));  /* Unstall */
  do CHECK(dbg_cpu0_read_ctrl(CPU_OP_ADR, &stalled)); while (!(stalled & 1));
  do CHECK(dbg_cpu0_read_ctrl(CPU_OP_ADR, &stalled)); while (!(stalled & 1));
  CHECK(dbg_cpu0_read((0 << 11) + 16, &npc));  /* Read NPC */
  CHECK(dbg_cpu0_read((0 << 11) + 16, &npc));  /* Read NPC */
  CHECK(dbg_cpu0_read((0 << 11) + 18, &ppc));  /* Read PPC */
  CHECK(dbg_cpu0_read((0 << 11) + 18, &ppc));  /* Read PPC */
  CHECK(dbg_cpu0_read(0x401, &r1));  /* Read R1 */
  CHECK(dbg_cpu0_read(0x401, &r1));  /* Read R1 */
  CHECK(dbg_wb_write32(SDRAM_BASE + 0x10, insn));  /* Set back original insn */
  CHECK(dbg_wb_write32(SDRAM_BASE + 0x10, insn));  /* Set back original insn */
  printf("Read      npc = %.8lx ppc = %.8lx r1 = %.8lx\n", npc, ppc, r1);
  printf("Read      npc = %.8lx ppc = %.8lx r1 = %.8lx\n", npc, ppc, r1);
  printf("Expected  npc = %.8lx ppc = %.8lx r1 = %.8lx\n", 0x00000014, 0x00000010, 99);
  printf("Expected  npc = %.8lx ppc = %.8lx r1 = %.8lx\n", 0x00000014, 0x00000010, 99);
  result = npc + ppc + r1 + result;
  result = npc + ppc + r1 + result;
 
 
  CHECK(dbg_cpu0_write((6 << 11) + 16, 1 << 22));  /* Set step bit */
  CHECK(dbg_cpu0_write((6 << 11) + 16, 1 << 22));  /* Set step bit */
  for(i = 0; i < 5; i++) {
  for(i = 0; i < 5; i++) {
    CHECK(dbg_cpu0_write_ctrl(CPU_OP_ADR, 0x00));  /* Unstall */
    CHECK(dbg_cpu0_write_ctrl(CPU_OP_ADR, 0x00));  /* Unstall */
    do CHECK(dbg_cpu0_read_ctrl(CPU_OP_ADR, &stalled)); while (!(stalled & 1));
    do CHECK(dbg_cpu0_read_ctrl(CPU_OP_ADR, &stalled)); while (!(stalled & 1));
  }
  }
  CHECK(dbg_cpu0_read((0 << 11) + 16, &npc));  /* Read NPC */
  CHECK(dbg_cpu0_read((0 << 11) + 16, &npc));  /* Read NPC */
  CHECK(dbg_cpu0_read((0 << 11) + 18, &ppc));  /* Read PPC */
  CHECK(dbg_cpu0_read((0 << 11) + 18, &ppc));  /* Read PPC */
  CHECK(dbg_cpu0_read(0x401, &r1));  /* Read R1 */
  CHECK(dbg_cpu0_read(0x401, &r1));  /* Read R1 */
  printf("Read      npc = %.8lx ppc = %.8lx r1 = %.8lx\n", npc, ppc, r1);
  printf("Read      npc = %.8lx ppc = %.8lx r1 = %.8lx\n", npc, ppc, r1);
  printf("Expected  npc = %.8lx ppc = %.8lx r1 = %.8lx\n", 0x00000028, 0x00000024, 101);
  printf("Expected  npc = %.8lx ppc = %.8lx r1 = %.8lx\n", 0x00000028, 0x00000024, 101);
  result = npc + ppc + r1 + result;
  result = npc + ppc + r1 + result;
 
 
  CHECK(dbg_cpu0_write((0 << 11) + 16, SDRAM_BASE + 0x24));  /* Set PC */
  CHECK(dbg_cpu0_write((0 << 11) + 16, SDRAM_BASE + 0x24));  /* Set PC */
  for(i = 0; i < 2; i++) {
  for(i = 0; i < 2; i++) {
    CHECK(dbg_cpu0_write_ctrl(CPU_OP_ADR, 0x00));  /* Unstall */
    CHECK(dbg_cpu0_write_ctrl(CPU_OP_ADR, 0x00));  /* Unstall */
    do CHECK(dbg_cpu0_read_ctrl(CPU_OP_ADR, &stalled)); while (!(stalled & 1));
    do CHECK(dbg_cpu0_read_ctrl(CPU_OP_ADR, &stalled)); while (!(stalled & 1));
  }
  }
  CHECK(dbg_cpu0_read((0 << 11) + 16, &npc));  /* Read NPC */
  CHECK(dbg_cpu0_read((0 << 11) + 16, &npc));  /* Read NPC */
  CHECK(dbg_cpu0_read((0 << 11) + 18, &ppc));  /* Read PPC */
  CHECK(dbg_cpu0_read((0 << 11) + 18, &ppc));  /* Read PPC */
  CHECK(dbg_cpu0_read(0x401, &r1));  /* Read R1 */
  CHECK(dbg_cpu0_read(0x401, &r1));  /* Read R1 */
  printf("Read      npc = %.8lx ppc = %.8lx r1 = %.8lx\n", npc, ppc, r1);
  printf("Read      npc = %.8lx ppc = %.8lx r1 = %.8lx\n", npc, ppc, r1);
  printf("Expected  npc = %.8lx ppc = %.8lx r1 = %.8lx\n", 0x00000010, 0x00000028, 201);
  printf("Expected  npc = %.8lx ppc = %.8lx r1 = %.8lx\n", 0x00000010, 0x00000028, 201);
  result = npc + ppc + r1 + result;
  result = npc + ppc + r1 + result;
  printf("result = %.8lx\n", result ^ 0xdeaddae1);
  printf("result = %.8lx\n", result ^ 0xdeaddae1);
 
 
 
 
  { // 8051 TEST
  { // 8051 TEST
    unsigned long npc[3], tmp;
    unsigned long npc[3], tmp;
 
 
    // WRITE ACC
    // WRITE ACC
    CHECK(dbg_cpu1_write(0x20e0, 0xa6));
    CHECK(dbg_cpu1_write(0x20e0, 0xa6));
 
 
    // READ ACC
    // READ ACC
    CHECK(dbg_cpu1_read(0x20e0, &tmp));   // select SFR space
    CHECK(dbg_cpu1_read(0x20e0, &tmp));   // select SFR space
    printf("Read  8051   ACC = %0x (expected a6)\n", tmp);
    printf("Read  8051   ACC = %0x (expected a6)\n", tmp);
    result = result + tmp;
    result = result + tmp;
 
 
    // set exception to single step to jump over a loop
    // set exception to single step to jump over a loop
    CHECK(dbg_cpu1_write(0x3010, 0xa0)); // set single step and global enable in EER
    CHECK(dbg_cpu1_write(0x3010, 0xa0)); // set single step and global enable in EER
    CHECK(dbg_cpu1_write(0x3011, 0x40)); // set evec = 24'h000040
    CHECK(dbg_cpu1_write(0x3011, 0x40)); // set evec = 24'h000040
    CHECK(dbg_cpu1_write(0x3012, 0x00)); // (already reset value)
    CHECK(dbg_cpu1_write(0x3012, 0x00)); // (already reset value)
    CHECK(dbg_cpu1_write(0x3013, 0x00)); // (already reset value)
    CHECK(dbg_cpu1_write(0x3013, 0x00)); // (already reset value)
 
 
    // set HW breakpoint at PC == 0x41
    // set HW breakpoint at PC == 0x41
    CHECK(dbg_cpu1_write(0x3020, 0x41)); // DVR0 = 24'h000041
    CHECK(dbg_cpu1_write(0x3020, 0x41)); // DVR0 = 24'h000041
    CHECK(dbg_cpu1_write(0x3023, 0x39)); // DCR0 = valid, == PC
    CHECK(dbg_cpu1_write(0x3023, 0x39)); // DCR0 = valid, == PC
    CHECK(dbg_cpu1_write(0x3001, 0x04)); // DSR = watchpoint
    CHECK(dbg_cpu1_write(0x3001, 0x04)); // DSR = watchpoint
 
 
    // flush 8051 instruction cache
    // flush 8051 instruction cache
    CHECK(dbg_cpu1_write(0x209f, 0x00));
    CHECK(dbg_cpu1_write(0x209f, 0x00));
 
 
    // Put some instructions in ram (8-bit mode on wishbone)
    // Put some instructions in ram (8-bit mode on wishbone)
    CHECK(dbg_wb_write8 (0x40, 0x04));  // inc a
    CHECK(dbg_wb_write8 (0x40, 0x04));  // inc a
    CHECK(dbg_wb_write8 (0x41, 0x03));  // rr a;
    CHECK(dbg_wb_write8 (0x41, 0x03));  // rr a;
    CHECK(dbg_wb_write8 (0x42, 0x14));  // dec a; 
    CHECK(dbg_wb_write8 (0x42, 0x14));  // dec a; 
    CHECK(dbg_wb_write8 (0x43, 0xf5));  // mov 0e5h, a;
    CHECK(dbg_wb_write8 (0x43, 0xf5));  // mov 0e5h, a;
    CHECK(dbg_wb_write8 (0x44, 0xe5));
    CHECK(dbg_wb_write8 (0x44, 0xe5));
 
 
    // unstall just 8051
    // unstall just 8051
    CHECK(dbg_cpu1_write_reg(0, 0));
    CHECK(dbg_cpu1_write_reg(0, 0));
 
 
    // read PC
    // read PC
    CHECK(dbg_cpu1_read(0, &npc[0]));
    CHECK(dbg_cpu1_read(0, &npc[0]));
    CHECK(dbg_cpu1_read(1, &npc[1]));
    CHECK(dbg_cpu1_read(1, &npc[1]));
    CHECK(dbg_cpu1_read(2, &npc[2]));
    CHECK(dbg_cpu1_read(2, &npc[2]));
    printf("Read  8051   npc = %02x%02x%02x (expected 41)\n", npc[2], npc[1], npc[0]);
    printf("Read  8051   npc = %02x%02x%02x (expected 41)\n", npc[2], npc[1], npc[0]);
    result = result + (npc[2] << 16) + (npc[1] << 8) + npc[0];
    result = result + (npc[2] << 16) + (npc[1] << 8) + npc[0];
 
 
    // READ ACC
    // READ ACC
    CHECK(dbg_cpu1_read(0x20e0, &tmp));   // select SFR space
    CHECK(dbg_cpu1_read(0x20e0, &tmp));   // select SFR space
    printf("Read  8051   ACC = %0x (expected a7)\n", tmp);
    printf("Read  8051   ACC = %0x (expected a7)\n", tmp);
    result = result + tmp;
    result = result + tmp;
 
 
    // set sigle step to stop execution
    // set sigle step to stop execution
    CHECK(dbg_cpu1_write(0x3001, 0x20)); // set single step and global enable in DSR
    CHECK(dbg_cpu1_write(0x3001, 0x20)); // set single step and global enable in DSR
 
 
    // clear DRR
    // clear DRR
    CHECK(dbg_cpu1_write(0x3000, 0x00)); // set single step and global enable in DRR
    CHECK(dbg_cpu1_write(0x3000, 0x00)); // set single step and global enable in DRR
 
 
    // unstall just 8051
    // unstall just 8051
    CHECK(dbg_cpu1_write_reg(0, 0));
    CHECK(dbg_cpu1_write_reg(0, 0));
 
 
    // read PC
    // read PC
    CHECK(dbg_cpu1_read(0, &npc[0]));
    CHECK(dbg_cpu1_read(0, &npc[0]));
    CHECK(dbg_cpu1_read(1, &npc[1]));
    CHECK(dbg_cpu1_read(1, &npc[1]));
    CHECK(dbg_cpu1_read(2, &npc[2]));
    CHECK(dbg_cpu1_read(2, &npc[2]));
    printf("Read  8051   npc = %02x%02x%02x (expected 42)\n", npc[2], npc[1], npc[0]);
    printf("Read  8051   npc = %02x%02x%02x (expected 42)\n", npc[2], npc[1], npc[0]);
    result = result + (npc[2] << 16) + (npc[1] << 8) + npc[0];
    result = result + (npc[2] << 16) + (npc[1] << 8) + npc[0];
 
 
    // READ ACC
    // READ ACC
    CHECK(dbg_cpu1_read(0x20e0, &tmp));   // select SFR space
    CHECK(dbg_cpu1_read(0x20e0, &tmp));   // select SFR space
    printf("Read  8051   ACC = %0x (expected d3)\n", tmp);
    printf("Read  8051   ACC = %0x (expected d3)\n", tmp);
    result = result + tmp;
    result = result + tmp;
 
 
    printf("report (%x)\n", result ^ 0x6c1 ^ 0xdeaddead);
    printf("report (%x)\n", result ^ 0x6c1 ^ 0xdeaddead);
  }
  }
#endif
#endif
}
}
 
 
int main(int argc,  char *argv[]) {
int main(int argc,  char *argv[]) {
  char *redirstr;
  char *redirstr;
  int trace_fd = 0;
  int trace_fd = 0;
  char *s;
  char *s;
  int err = DBG_ERR_OK;
  int err = DBG_ERR_OK;
 
 
  int c;
  int c;
  const char *args;
  const char *args;
  char *port;
  char *port;
  char *cable;
  char *cable;
 
 
  srand(getpid());
  srand(getpid());
  if ((argc < 3) || (argv[1][0] == '-') || (argv[2][0] == '-')) {
  if ((argc < 3) || (argv[1][0] == '-') || (argv[2][0] == '-')) {
    printf("JTAG protocol via parallel port for linux.\n");
    printf("JTAG protocol via parallel port for linux.\n");
    printf("Copyright (C) 2001 Marko Mlinar, markom@opencores.org\n\n");
    printf("Copyright (C) 2001 Marko Mlinar, markom@opencores.org\n\n");
    printf("Usage: %s [cable] [JTAG port_number]\n", argv[0]);
    printf("Usage: %s [cable] [JTAG port_number]\n", argv[0]);
    jp_print_cable_help();
    jp_print_cable_help();
    return -1;
    return -1;
  }
  }
 
 
  cable = argv[1];
  cable = argv[1];
  port = argv[2];
  port = argv[2];
 
 
  if (!jp_select_cable(cable)) {
  if (!jp_select_cable(cable)) {
    fprintf(stderr,"Error selecting cable %s\n", cable);
    fprintf(stderr,"Error selecting cable %s\n", cable);
    return -1;
    return -1;
  }
  }
 
 
  /* Get the cable-arguments */
  /* Get the cable-arguments */
  args = jp_get_cable_args();
  args = jp_get_cable_args();
 
 
  /* Parse the cable arguments (if-any) */
  /* Parse the cable arguments (if-any) */
  for(;;) {
  for(;;) {
    c = getopt(argc, argv, args);
    c = getopt(argc, argv, args);
    if(c == -1)
    if(c == -1)
      break;
      break;
    if(c == '?')
    if(c == '?')
      return 1;
      return 1;
    if(!jp_cable_opt(c, optarg))
    if(!jp_cable_opt(c, optarg))
      return 1;
      return 1;
  }
  }
  if(!jp_init_cable())
  if(!jp_init_cable())
    return 1;
    return 1;
 
 
  /* Initialize a new connection to the or1k board, and make sure we are
  /* Initialize a new connection to the or1k board, and make sure we are
     really connected.  */
     really connected.  */
  current_chain = -1;
  current_chain = -1;
  if ((err = dbg_reset())) goto error;
  if ((err = dbg_reset())) goto error;
 
 
  /* Test the connection.  */
  /* Test the connection.  */
  dbg_test();
  dbg_test();
 
 
  /* We have a connection.  Establish server.  */
  /* We have a connection.  Establish server.  */
  serverPort = strtol(port,&s,10);
  serverPort = strtol(port,&s,10);
  if(*s) return -1;
  if(*s) return -1;
 
 
  if(server_fd = GetServerSocket("or1ksim","tcp", serverPort)) {
  if(server_fd = GetServerSocket("or1ksim","tcp", serverPort)) {
    printf("JTAG Proxy server started on port %d\n", serverPort);
    printf("JTAG Proxy server started on port %d\n", serverPort);
    printf("Press CTRL+c to exit.\n");
    printf("Press CTRL+c to exit.\n");
  } else {
  } else {
    fprintf(stderr,"Cannot start JTAG Proxy server on port %d\n", serverPort);
    fprintf(stderr,"Cannot start JTAG Proxy server on port %d\n", serverPort);
    exit(-1);
    exit(-1);
  }
  }
 
 
  /* Do endless loop of checking and handle GDB requests.  Ctrl-c exits.  */
  /* Do endless loop of checking and handle GDB requests.  Ctrl-c exits.  */
  HandleServerSocket(true);
  HandleServerSocket(true);
  return 0;
  return 0;
error:
error:
  fprintf(stderr,"Connection with jtag via parallel port failed (err = %d).\n", err);
  fprintf(stderr,"Connection with jtag via parallel port failed (err = %d).\n", err);
  exit(-1);
  exit(-1);
}
}
 
 
 
 

powered by: WebSVN 2.1.0

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