/***************************************************************************
* Copyright (C) 2013-2014 by Franck Jullien *
* elec4fun@gmail.com *
* *
* Inspired from adv_jtag_bridge which is: *
* Copyright (C) 2008-2010 Nathan Yawn *
* nyawn@opencores.net *
* *
* And the Mohor interface version of this file which is: *
* Copyright (C) 2011 by Julius Baxter *
* julius@opencores.org *
* *
* 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 Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "or1k_tap.h"
#include "or1k.h"
#include "or1k_du.h"
#include "jsp_server.h"
#include <target/target.h>
#include <jtag/jtag.h>
#define JSP_BANNER "\n\r" \
"******************************\n\r" \
"** JTAG Serial Port **\n\r" \
"******************************\n\r" \
"\n\r"
#define NO_OPTION 0
/* This an option to the adv debug unit.
* If this is defined, status bits will be skipped on burst
* reads and writes to improve download speeds.
* This option must match the RTL configured option.
*/
#define ADBG_USE_HISPEED 1
/* This an option to the adv debug unit.
* If this is defined, the JTAG Serial Port Server is started.
* This option must match the RTL configured option.
*/
#define ENABLE_JSP_SERVER 2
/* Define this if you intend to use the JSP in a system with multiple
* devices on the JTAG chain
*/
#define ENABLE_JSP_MULTI 4
/* Definitions for the top-level debug unit. This really just consists
* of a single register, used to select the active debug module ("chain").
*/
#define DBG_MODULE_SELECT_REG_SIZE 2
#define DBG_MAX_MODULES 4
#define DC_NONE -1
#define DC_WISHBONE 0
#define DC_CPU0 1
#define DC_CPU1 2
#define DC_JSP 3
/* CPU control register bits mask */
#define DBG_CPU_CR_STALL 0x01
#define DBG_CPU_CR_RESET 0x02
/* Polynomial for the CRC calculation
* Yes, it's backwards. Yes, this is on purpose.
* The hardware is designed this way to save on logic and routing,
* and it's really all the same to us here.
*/
#define ADBG_CRC_POLY 0xedb88320
/* These are for the internal registers in the Wishbone module
* The first is the length of the index register,
* the indexes of the various registers are defined after that.
*/
#define DBG_WB_REG_SEL_LEN 1
#define DBG_WB_REG_ERROR 0
/* Opcode definitions for the Wishbone module. */
#define DBG_WB_OPCODE_LEN 4
#define DBG_WB_CMD_NOP 0x0
#define DBG_WB_CMD_BWRITE8 0x1
#define DBG_WB_CMD_BWRITE16 0x2
#define DBG_WB_CMD_BWRITE32 0x3
#define DBG_WB_CMD_BREAD8 0x5
#define DBG_WB_CMD_BREAD16 0x6
#define DBG_WB_CMD_BREAD32 0x7
#define DBG_WB_CMD_IREG_WR 0x9
#define DBG_WB_CMD_IREG_SEL 0xd
/* Internal register definitions for the CPU0 module. */
#define DBG_CPU0_REG_SEL_LEN 1
#define DBG_CPU0_REG_STATUS 0
/* Opcode definitions for the first CPU module. */
#define DBG_CPU0_OPCODE_LEN 4
#define DBG_CPU0_CMD_NOP 0x0
#define DBG_CPU0_CMD_BWRITE32 0x3
#define DBG_CPU0_CMD_BREAD32 0x7
#define DBG_CPU0_CMD_IREG_WR 0x9
#define DBG_CPU0_CMD_IREG_SEL 0xd
/* Internal register definitions for the CPU1 module. */
#define DBG_CPU1_REG_SEL_LEN 1
#define DBG_CPU1_REG_STATUS 0
/* Opcode definitions for the second CPU module. */
#define DBG_CPU1_OPCODE_LEN 4
#define DBG_CPU1_CMD_NOP 0x0
#define DBG_CPU1_CMD_BWRITE32 0x3
#define DBG_CPU1_CMD_BREAD32 0x7
#define DBG_CPU1_CMD_IREG_WR 0x9
#define DBG_CPU1_CMD_IREG_SEL 0xd
#define MAX_READ_STATUS_WAIT 10
#define MAX_READ_BUSY_RETRY 2
#define MAX_READ_CRC_RETRY 2
#define MAX_WRITE_CRC_RETRY 2
#define BURST_READ_READY 1
#define MAX_BUS_ERRORS 2
#define MAX_BURST_SIZE (4 * 1024)
#define STATUS_BYTES 1
#define CRC_LEN 4
static struct or1k_du or1k_du_adv;
static const char * const chain_name[] = {"WISHBONE", "CPU0", "CPU1", "JSP"};
static uint32_t adbg_compute_crc(uint32_t crc, uint32_t data_in,
int length_bits)
{
for (int i = 0; i < length_bits; i++) {
uint32_t d, c;
d = ((data_in >> i) & 0x1) ? 0xffffffff : 0;
c = (crc & 0x1) ? 0xffffffff : 0;
crc = crc >> 1;
crc = crc ^ ((d ^ c) & ADBG_CRC_POLY);
}
return crc;
}
static int find_status_bit(void *_buf, int len)
{
int i = 0;
int count = 0;
int ret = -1;
uint8_t *buf = _buf;
while (!(buf[i] & (1 << count++)) && (i < len)) {
if (count == 8) {
count = 0;
i++;
}
}
if (i < len)
ret = (i * 8) + count;
return ret;
}
static int or1k_adv_jtag_init(struct or1k_jtag *jtag_info)
{
struct or1k_tap_ip *tap_ip = jtag_info->tap_ip;
int retval = tap_ip->init(jtag_info);
if (retval != ERROR_OK) {
LOG_ERROR("TAP initialization failed");
return retval;
}
/* TAP is now configured to communicate with debug interface */
jtag_info->or1k_jtag_inited = 1;
/* TAP reset - not sure what state debug module chain is in now */
jtag_info->or1k_jtag_module_selected = DC_NONE;
jtag_info->current_reg_idx = malloc