Andes AICE uses USB to transfer packets between OpenOCD and AICE. It uses high-level USB commands to control targets instead of using JTAG signals. I define an interface as aice_port_api_s. It contains all basic operations needed by target-dependent code. Change-Id: I117bc4f938fab2732e44c509ea68b30172d6fdb9 Signed-off-by: Hsiangkai Wang <hsiangkai@gmail.com> Reviewed-on: http://openocd.zylin.com/1256 Tested-by: jenkins Reviewed-by: Spencer Oliver <spen@spen-soft.co.uk>tags/v0.8.0-rc1
@@ -507,6 +507,10 @@ AC_ARG_ENABLE([libusb0], | |||||
AS_HELP_STRING([--enable-libusb0], [Use libusb-0.1 library for USB JTAG devices]), | AS_HELP_STRING([--enable-libusb0], [Use libusb-0.1 library for USB JTAG devices]), | ||||
[check_libusb0=$enableval], [check_libusb0=no]) | [check_libusb0=$enableval], [check_libusb0=no]) | ||||
AC_ARG_ENABLE([aice], | |||||
AS_HELP_STRING([--enable-aice], [Enable building support for the Andes JTAG Programmer]), | |||||
[build_aice=$enableval], [build_aice=no]) | |||||
build_minidriver=no | build_minidriver=no | ||||
AC_MSG_CHECKING([whether to enable ZY1000 minidriver]) | AC_MSG_CHECKING([whether to enable ZY1000 minidriver]) | ||||
if test $build_zy1000 = yes; then | if test $build_zy1000 = yes; then | ||||
@@ -762,6 +766,12 @@ else | |||||
AC_DEFINE([BUILD_JLINK], [0], [0 if you don't want the J-Link JTAG driver.]) | AC_DEFINE([BUILD_JLINK], [0], [0 if you don't want the J-Link JTAG driver.]) | ||||
fi | fi | ||||
if test $build_aice = yes; then | |||||
AC_DEFINE([BUILD_AICE], [1], [1 if you want the AICE JTAG driver.]) | |||||
else | |||||
AC_DEFINE([BUILD_AICE], [0], [0 if you don't want the AICE JTAG driver.]) | |||||
fi | |||||
if test $build_vsllink = yes; then | if test $build_vsllink = yes; then | ||||
AC_DEFINE([BUILD_VSLLINK], [1], [1 if you want the Versaloon-Link JTAG driver.]) | AC_DEFINE([BUILD_VSLLINK], [1], [1 if you want the Versaloon-Link JTAG driver.]) | ||||
else | else | ||||
@@ -1137,7 +1147,8 @@ fi | |||||
# check for usb.h when a driver will require it | # check for usb.h when a driver will require it | ||||
build_usb=no | build_usb=no | ||||
if test $build_vsllink = yes -o $build_usbprog = yes -o \ | if test $build_vsllink = yes -o $build_usbprog = yes -o \ | ||||
$build_rlink = yes -o $build_ulink = yes -o $build_armjtagew = yes | |||||
$build_rlink = yes -o $build_ulink = yes -o $build_armjtagew = yes -o \ | |||||
$build_aice = yes | |||||
then | then | ||||
build_usb=yes | build_usb=yes | ||||
fi | fi | ||||
@@ -1189,6 +1200,7 @@ AM_CONDITIONAL([PRESTO_DRIVER], [test $build_presto_ftd2xx = yes -o $build_prest | |||||
AM_CONDITIONAL([USBPROG], [test $build_usbprog = yes]) | AM_CONDITIONAL([USBPROG], [test $build_usbprog = yes]) | ||||
AM_CONDITIONAL([OOCD_TRACE], [test $build_oocd_trace = yes]) | AM_CONDITIONAL([OOCD_TRACE], [test $build_oocd_trace = yes]) | ||||
AM_CONDITIONAL([JLINK], [test $build_jlink = yes]) | AM_CONDITIONAL([JLINK], [test $build_jlink = yes]) | ||||
AM_CONDITIONAL([AICE], [test $build_aice = yes]) | |||||
AM_CONDITIONAL([VSLLINK], [test $build_vsllink = yes]) | AM_CONDITIONAL([VSLLINK], [test $build_vsllink = yes]) | ||||
AM_CONDITIONAL([RLINK], [test $build_rlink = yes]) | AM_CONDITIONAL([RLINK], [test $build_rlink = yes]) | ||||
AM_CONDITIONAL([ULINK], [test $build_ulink = yes]) | AM_CONDITIONAL([ULINK], [test $build_ulink = yes]) | ||||
@@ -1313,6 +1325,7 @@ AC_CONFIG_FILES([ | |||||
src/jtag/drivers/Makefile | src/jtag/drivers/Makefile | ||||
src/jtag/drivers/usb_blaster/Makefile | src/jtag/drivers/usb_blaster/Makefile | ||||
src/jtag/hla/Makefile | src/jtag/hla/Makefile | ||||
src/jtag/aice/Makefile | |||||
src/transport/Makefile | src/transport/Makefile | ||||
src/xsvf/Makefile | src/xsvf/Makefile | ||||
src/svf/Makefile | src/svf/Makefile | ||||
@@ -44,6 +44,11 @@ SUBDIRS += hla | |||||
libjtag_la_LIBADD += $(top_builddir)/src/jtag/hla/libocdhla.la | libjtag_la_LIBADD += $(top_builddir)/src/jtag/hla/libocdhla.la | ||||
endif | endif | ||||
if AICE | |||||
SUBDIRS += aice | |||||
libjtag_la_LIBADD += $(top_builddir)/src/jtag/aice/libocdaice.la | |||||
endif | |||||
SUBDIRS += drivers | SUBDIRS += drivers | ||||
libjtag_la_LIBADD += $(top_builddir)/src/jtag/drivers/libocdjtagdrivers.la | libjtag_la_LIBADD += $(top_builddir)/src/jtag/drivers/libocdjtagdrivers.la | ||||
@@ -0,0 +1,27 @@ | |||||
include $(top_srcdir)/common.mk | |||||
AM_CPPFLAGS += -I$(top_srcdir)/src/jtag/drivers | |||||
noinst_LTLIBRARIES = libocdaice.la | |||||
libocdaice_la_SOURCES = \ | |||||
$(AICEFILES) | |||||
AICEFILES = | |||||
if AICE | |||||
AICEFILES += aice_transport.c | |||||
AICEFILES += aice_interface.c | |||||
AICEFILES += aice_port.c | |||||
AICEFILES += aice_usb.c | |||||
AICEFILES += aice_pipe.c | |||||
endif | |||||
noinst_HEADERS = \ | |||||
aice_transport.h \ | |||||
aice_interface.h \ | |||||
aice_port.h \ | |||||
aice_usb.h \ | |||||
aice_pipe.h | |||||
MAINTAINERCLEANFILES = $(srcdir)/Makefile.in |
@@ -0,0 +1,500 @@ | |||||
/*************************************************************************** | |||||
* Copyright (C) 2013 by Andes Technology * | |||||
* Hsiangkai Wang <hkwang@andestech.com> * | |||||
* * | |||||
* 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, write to the * | |||||
* Free Software Foundation, Inc., * | |||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * | |||||
***************************************************************************/ | |||||
#ifdef HAVE_CONFIG_H | |||||
#include "config.h" | |||||
#endif | |||||
#include <jtag/interface.h> | |||||
#include <jtag/commands.h> | |||||
#include <transport/transport.h> | |||||
#include <target/target.h> | |||||
#include <jtag/aice/aice_transport.h> | |||||
#include <jtag/drivers/libusb_common.h> | |||||
#include "aice_usb.h" | |||||
#define AICE_KHZ_TO_SPEED_MAP_SIZE 16 | |||||
static int aice_khz_to_speed_map[AICE_KHZ_TO_SPEED_MAP_SIZE] = { | |||||
30000, | |||||
15000, | |||||
7500, | |||||
3750, | |||||
1875, | |||||
937, | |||||
468, | |||||
234, | |||||
48000, | |||||
24000, | |||||
12000, | |||||
6000, | |||||
3000, | |||||
1500, | |||||
750, | |||||
375, | |||||
}; | |||||
static struct aice_port_s aice; | |||||
/***************************************************************************/ | |||||
/* External interface implementation */ | |||||
#define AICE_MAX_TARGET_ID_CODES 0x10 | |||||
static uint32_t aice_target_id_codes[AICE_MAX_TARGET_ID_CODES]; | |||||
static uint8_t aice_num_of_target_id_codes; | |||||
/***************************************************************************/ | |||||
/* AICE operations */ | |||||
int aice_init_target(struct target *t) | |||||
{ | |||||
int res; | |||||
LOG_DEBUG("aice_init_target"); | |||||
if (aice_num_of_target_id_codes == 0) { | |||||
res = aice.port->api->idcode(aice_target_id_codes, &aice_num_of_target_id_codes); | |||||
if (res != ERROR_OK) { | |||||
LOG_ERROR("<-- TARGET ERROR! Failed to identify AndesCore " | |||||
"JTAG Manufacture ID in the JTAG scan chain. " | |||||
"Failed to access EDM registers. -->"); | |||||
return res; | |||||
} | |||||
} | |||||
t->tap->idcode = aice_target_id_codes[t->tap->abs_chain_position]; | |||||
unsigned ii, limit = t->tap->expected_ids_cnt; | |||||
int found = 0; | |||||
for (ii = 0; ii < limit; ii++) { | |||||
uint32_t expected = t->tap->expected_ids[ii]; | |||||
/* treat "-expected-id 0" as a "don't-warn" wildcard */ | |||||
if (!expected || (t->tap->idcode == expected)) { | |||||
found = 1; | |||||
break; | |||||
} | |||||
} | |||||
if (found == 0) { | |||||
LOG_ERROR | |||||
("aice_init_target: target not found: idcode: %x ", | |||||
t->tap->idcode); | |||||
return ERROR_FAIL; | |||||
} | |||||
t->tap->priv = &aice; | |||||
t->tap->hasidcode = 1; | |||||
return ERROR_OK; | |||||
} | |||||
/***************************************************************************/ | |||||
/* End of External interface implementation */ | |||||
/* initial aice | |||||
* 1. open usb | |||||
* 2. get/show version number | |||||
* 3. reset | |||||
*/ | |||||
static int aice_init(void) | |||||
{ | |||||
if (ERROR_OK != aice.port->api->open(&(aice.param))) { | |||||
LOG_ERROR("Cannot find AICE Interface! Please check " | |||||
"connection and permissions."); | |||||
return ERROR_JTAG_INIT_FAILED; | |||||
} | |||||
aice.port->api->set_retry_times(aice.retry_times); | |||||
aice.port->api->set_count_to_check_dbger(aice.count_to_check_dbger); | |||||
LOG_INFO("AICE JTAG Interface ready"); | |||||
return ERROR_OK; | |||||
} | |||||
/* cleanup aice resource | |||||
* close usb | |||||
*/ | |||||
static int aice_quit(void) | |||||
{ | |||||
aice.port->api->close(); | |||||
return ERROR_OK; | |||||
} | |||||
static int aice_execute_reset(struct jtag_command *cmd) | |||||
{ | |||||
static int last_trst; | |||||
int retval = ERROR_OK; | |||||
DEBUG_JTAG_IO("reset trst: %i", cmd->cmd.reset->trst); | |||||
if (cmd->cmd.reset->trst != last_trst) { | |||||
if (cmd->cmd.reset->trst) | |||||
retval = aice.port->api->reset(); | |||||
last_trst = cmd->cmd.reset->trst; | |||||
} | |||||
return retval; | |||||
} | |||||
static int aice_execute_command(struct jtag_command *cmd) | |||||
{ | |||||
int retval; | |||||
switch (cmd->type) { | |||||
case JTAG_RESET: | |||||
retval = aice_execute_reset(cmd); | |||||
break; | |||||
default: | |||||
retval = ERROR_OK; | |||||
break; | |||||
} | |||||
return retval; | |||||
} | |||||
/* aice has no need to implement jtag execution model | |||||
*/ | |||||
static int aice_execute_queue(void) | |||||
{ | |||||
struct jtag_command *cmd = jtag_command_queue; /* currently processed command */ | |||||
int retval; | |||||
retval = ERROR_OK; | |||||
while (cmd) { | |||||
if (aice_execute_command(cmd) != ERROR_OK) | |||||
retval = ERROR_JTAG_QUEUE_FAILED; | |||||
cmd = cmd->next; | |||||
} | |||||
return retval; | |||||
} | |||||
/* set jtag frequency(base frequency/frequency divider) to your jtag adapter */ | |||||
static int aice_speed(int speed) | |||||
{ | |||||
return aice.port->api->set_jtag_clock(speed); | |||||
} | |||||
/* convert jtag adapter frequency(base frequency/frequency divider) to | |||||
* human readable KHz value */ | |||||
static int aice_speed_div(int speed, int *khz) | |||||
{ | |||||
*khz = aice_khz_to_speed_map[speed]; | |||||
return ERROR_OK; | |||||
} | |||||
/* convert human readable KHz value to jtag adapter frequency | |||||
* (base frequency/frequency divider) */ | |||||
static int aice_khz(int khz, int *jtag_speed) | |||||
{ | |||||
int i; | |||||
for (i = 0 ; i < AICE_KHZ_TO_SPEED_MAP_SIZE ; i++) { | |||||
if (khz == aice_khz_to_speed_map[i]) { | |||||
if (8 <= i) | |||||
*jtag_speed = i | AICE_TCK_CONTROL_TCK3048; | |||||
else | |||||
*jtag_speed = i; | |||||
break; | |||||
} | |||||
} | |||||
if (i == AICE_KHZ_TO_SPEED_MAP_SIZE) { | |||||
LOG_INFO("No support the jtag clock: %d", khz); | |||||
LOG_INFO("Supported jtag clocks are:"); | |||||
for (i = 0 ; i < AICE_KHZ_TO_SPEED_MAP_SIZE ; i++) | |||||
LOG_INFO("* %d", aice_khz_to_speed_map[i]); | |||||
return ERROR_FAIL; | |||||
} | |||||
return ERROR_OK; | |||||
} | |||||
/***************************************************************************/ | |||||
/* Command handlers */ | |||||
COMMAND_HANDLER(aice_handle_aice_info_command) | |||||
{ | |||||
LOG_DEBUG("aice_handle_aice_info_command"); | |||||
command_print(CMD_CTX, "Description: %s", aice.param.device_desc); | |||||
command_print(CMD_CTX, "Serial number: %s", aice.param.serial); | |||||
if (strncmp(aice.port->name, "aice_pipe", 9) == 0) | |||||
command_print(CMD_CTX, "Adapter: %s", aice.param.adapter_name); | |||||
return ERROR_OK; | |||||
} | |||||
COMMAND_HANDLER(aice_handle_aice_port_command) | |||||
{ | |||||
LOG_DEBUG("aice_handle_aice_port_command"); | |||||
if (CMD_ARGC != 1) { | |||||
LOG_ERROR("Need exactly one argument to 'aice port'"); | |||||
return ERROR_COMMAND_SYNTAX_ERROR; | |||||
} | |||||
for (const struct aice_port *l = aice_port_get_list(); l->name; l++) { | |||||
if (strcmp(l->name, CMD_ARGV[0]) == 0) { | |||||
aice.port = l; | |||||
return ERROR_OK; | |||||
} | |||||
} | |||||
LOG_ERROR("No AICE port '%s' found", CMD_ARGV[0]); | |||||
return ERROR_FAIL; | |||||
} | |||||
COMMAND_HANDLER(aice_handle_aice_desc_command) | |||||
{ | |||||
LOG_DEBUG("aice_handle_aice_desc_command"); | |||||
if (CMD_ARGC == 1) | |||||
aice.param.device_desc = strdup(CMD_ARGV[0]); | |||||
else | |||||
LOG_ERROR("expected exactly one argument to aice desc <description>"); | |||||
return ERROR_OK; | |||||
} | |||||
COMMAND_HANDLER(aice_handle_aice_serial_command) | |||||
{ | |||||
LOG_DEBUG("aice_handle_aice_serial_command"); | |||||
if (CMD_ARGC == 1) | |||||
aice.param.serial = strdup(CMD_ARGV[0]); | |||||
else | |||||
LOG_ERROR("expected exactly one argument to aice serial <serial-number>"); | |||||
return ERROR_OK; | |||||
} | |||||
COMMAND_HANDLER(aice_handle_aice_vid_pid_command) | |||||
{ | |||||
LOG_DEBUG("aice_handle_aice_vid_pid_command"); | |||||
if (CMD_ARGC != 2) { | |||||
LOG_WARNING("ignoring extra IDs in aice vid_pid (maximum is 1 pair)"); | |||||
return ERROR_COMMAND_SYNTAX_ERROR; | |||||
} | |||||
COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], aice.param.vid); | |||||
COMMAND_PARSE_NUMBER(u16, CMD_ARGV[1], aice.param.pid); | |||||
return ERROR_OK; | |||||
} | |||||
COMMAND_HANDLER(aice_handle_aice_adapter_command) | |||||
{ | |||||
LOG_DEBUG("aice_handle_aice_adapter_command"); | |||||
if (CMD_ARGC == 1) | |||||
aice.param.adapter_name = strdup(CMD_ARGV[0]); | |||||
else | |||||
LOG_ERROR("expected exactly one argument to aice adapter <adapter-name>"); | |||||
return ERROR_OK; | |||||
} | |||||
COMMAND_HANDLER(aice_handle_aice_retry_times_command) | |||||
{ | |||||
LOG_DEBUG("aice_handle_aice_retry_times_command"); | |||||
if (CMD_ARGC == 1) | |||||
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], aice.retry_times); | |||||
else | |||||
LOG_ERROR("expected exactly one argument to aice retry_times <num_of_retry>"); | |||||
return ERROR_OK; | |||||
} | |||||
COMMAND_HANDLER(aice_handle_aice_count_to_check_dbger_command) | |||||
{ | |||||
LOG_DEBUG("aice_handle_aice_count_to_check_dbger_command"); | |||||
if (CMD_ARGC == 1) | |||||
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], aice.count_to_check_dbger); | |||||
else | |||||
LOG_ERROR("expected exactly one argument to aice count_to_check_dbger " | |||||
"<count_of_checking>"); | |||||
return ERROR_OK; | |||||
} | |||||
COMMAND_HANDLER(aice_handle_aice_custom_srst_script_command) | |||||
{ | |||||
LOG_DEBUG("aice_handle_aice_custom_srst_script_command"); | |||||
if (CMD_ARGC > 0) { | |||||
aice.port->api->set_custom_srst_script(CMD_ARGV[0]); | |||||
return ERROR_OK; | |||||
} | |||||
return ERROR_FAIL; | |||||
} | |||||
COMMAND_HANDLER(aice_handle_aice_custom_trst_script_command) | |||||
{ | |||||
LOG_DEBUG("aice_handle_aice_custom_trst_script_command"); | |||||
if (CMD_ARGC > 0) { | |||||
aice.port->api->set_custom_trst_script(CMD_ARGV[0]); | |||||
return ERROR_OK; | |||||
} | |||||
return ERROR_FAIL; | |||||
} | |||||
COMMAND_HANDLER(aice_handle_aice_custom_restart_script_command) | |||||
{ | |||||
LOG_DEBUG("aice_handle_aice_custom_restart_script_command"); | |||||
if (CMD_ARGC > 0) { | |||||
aice.port->api->set_custom_restart_script(CMD_ARGV[0]); | |||||
return ERROR_OK; | |||||
} | |||||
return ERROR_FAIL; | |||||
} | |||||
COMMAND_HANDLER(aice_handle_aice_reset_command) | |||||
{ | |||||
LOG_DEBUG("aice_handle_aice_reset_command"); | |||||
return aice.port->api->reset(); | |||||
} | |||||
static const struct command_registration aice_subcommand_handlers[] = { | |||||
{ | |||||
.name = "info", | |||||
.handler = &aice_handle_aice_info_command, | |||||
.mode = COMMAND_EXEC, | |||||
.help = "show aice info", | |||||
.usage = "aice info", | |||||
}, | |||||
{ | |||||
.name = "port", | |||||
.handler = &aice_handle_aice_port_command, | |||||
.mode = COMMAND_CONFIG, | |||||
.help = "set the port of the AICE", | |||||
.usage = "aice port ['aice_pipe'|'aice_usb']", | |||||
}, | |||||
{ | |||||
.name = "desc", | |||||
.handler = &aice_handle_aice_desc_command, | |||||
.mode = COMMAND_CONFIG, | |||||
.help = "set the aice device description", | |||||
.usage = "aice desc [desciption string]", | |||||
}, | |||||
{ | |||||
.name = "serial", | |||||
.handler = &aice_handle_aice_serial_command, | |||||
.mode = COMMAND_CONFIG, | |||||
.help = "set the serial number of the AICE device", | |||||
.usage = "aice serial [serial string]", | |||||
}, | |||||
{ | |||||
.name = "vid_pid", | |||||
.handler = &aice_handle_aice_vid_pid_command, | |||||
.mode = COMMAND_CONFIG, | |||||
.help = "the vendor and product ID of the AICE device", | |||||
.usage = "aice vid_pid (vid pid)*", | |||||
}, | |||||
{ | |||||
.name = "adapter", | |||||
.handler = &aice_handle_aice_adapter_command, | |||||
.mode = COMMAND_CONFIG, | |||||
.help = "set the file name of adapter", | |||||
.usage = "aice adapter [adapter name]", | |||||
}, | |||||
{ | |||||
.name = "retry_times", | |||||
.handler = &aice_handle_aice_retry_times_command, | |||||
.mode = COMMAND_CONFIG, | |||||
.help = "set retry times as AICE timeout", | |||||
.usage = "aice retry_times num_of_retry", | |||||
}, | |||||
{ | |||||
.name = "count_to_check_dbger", | |||||
.handler = &aice_handle_aice_count_to_check_dbger_command, | |||||
.mode = COMMAND_CONFIG, | |||||
.help = "set retry times as checking $DBGER status", | |||||
.usage = "aice count_to_check_dbger count_of_checking", | |||||
}, | |||||
{ | |||||
.name = "custom_srst_script", | |||||
.handler = &aice_handle_aice_custom_srst_script_command, | |||||
.mode = COMMAND_CONFIG, | |||||
.usage = "custom_srst_script script_file_name", | |||||
.help = "set custom srst script", | |||||
}, | |||||
{ | |||||
.name = "custom_trst_script", | |||||
.handler = &aice_handle_aice_custom_trst_script_command, | |||||
.mode = COMMAND_CONFIG, | |||||
.usage = "custom_trst_script script_file_name", | |||||
.help = "set custom trst script", | |||||
}, | |||||
{ | |||||
.name = "custom_restart_script", | |||||
.handler = &aice_handle_aice_custom_restart_script_command, | |||||
.mode = COMMAND_CONFIG, | |||||
.usage = "custom_restart_script script_file_name", | |||||
.help = "set custom restart script", | |||||
}, | |||||
{ | |||||
.name = "reset", | |||||
.handler = &aice_handle_aice_reset_command, | |||||
.mode = COMMAND_EXEC, | |||||
.usage = "aice reset", | |||||
.help = "reset AICE", | |||||
}, | |||||
COMMAND_REGISTRATION_DONE | |||||
}; | |||||
static const struct command_registration aice_command_handlers[] = { | |||||
{ | |||||
.name = "aice", | |||||
.mode = COMMAND_ANY, | |||||
.help = "perform aice management", | |||||
.usage = "aice [subcommand]", | |||||
.chain = aice_subcommand_handlers, | |||||
}, | |||||
COMMAND_REGISTRATION_DONE | |||||
}; | |||||
/***************************************************************************/ | |||||
/* End of Command handlers */ | |||||
struct jtag_interface aice_interface = { | |||||
.name = "aice", | |||||
.commands = aice_command_handlers, | |||||
.transports = aice_transports, | |||||
.init = aice_init, | |||||
.quit = aice_quit, | |||||
.execute_queue = aice_execute_queue, | |||||
.speed = aice_speed, /* set interface speed */ | |||||
.speed_div = aice_speed_div, /* return readable value */ | |||||
.khz = aice_khz, /* convert khz to interface speed value */ | |||||
}; | |||||
@@ -0,0 +1,36 @@ | |||||
/*************************************************************************** | |||||
* Copyright (C) 2013 by Andes Technology * | |||||
* Hsiangkai Wang <hkwang@andestech.com> * | |||||
* * | |||||
* 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, write to the * | |||||
* Free Software Foundation, Inc., * | |||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * | |||||
***************************************************************************/ | |||||
#ifndef __AICE_INTERFACE_H__ | |||||
#define __AICE_INTERFACE_H__ | |||||
struct aice_interface_param_s { | |||||
/** */ | |||||
char *device_desc; | |||||
/** */ | |||||
char *serial; | |||||
/** */ | |||||
uint16_t vid; | |||||
/** */ | |||||
uint16_t pid; | |||||
}; | |||||
int aice_init_target(struct target *t); | |||||
#endif |
@@ -0,0 +1,915 @@ | |||||
/*************************************************************************** | |||||
* Copyright (C) 2013 by Andes Technology * | |||||
* Hsiangkai Wang <hkwang@andestech.com> * | |||||
* * | |||||
* 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, write to the * | |||||
* Free Software Foundation, Inc., * | |||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * | |||||
***************************************************************************/ | |||||
#ifdef HAVE_CONFIG_H | |||||
#include "config.h" | |||||
#endif | |||||
#ifdef _WIN32 | |||||
#include <windows.h> | |||||
#else | |||||
#include <signal.h> | |||||
#endif | |||||
#include <helper/log.h> | |||||
#include <helper/time_support.h> | |||||
#include "aice_port.h" | |||||
#include "aice_pipe.h" | |||||
#define AICE_PIPE_MAXLINE 8192 | |||||
#ifdef _WIN32 | |||||
PROCESS_INFORMATION proc_info; | |||||
HANDLE aice_pipe_output[2]; | |||||
HANDLE aice_pipe_input[2]; | |||||
static int aice_pipe_write(const void *buffer, int count) | |||||
{ | |||||
BOOL success; | |||||
DWORD written; | |||||
success = WriteFile(aice_pipe_output[1], buffer, count, &written, NULL); | |||||
if (!success) { | |||||
LOG_ERROR("(WIN32) write to pipe failed, error code: 0x%08lx", GetLastError()); | |||||
return -1; | |||||
} | |||||
return written; | |||||
} | |||||
static int aice_pipe_read(void *buffer, int count) | |||||
{ | |||||
BOOL success; | |||||
DWORD has_read; | |||||
success = ReadFile(aice_pipe_input[0], buffer, count, &has_read, NULL); | |||||
if (!success || (has_read == 0)) { | |||||
LOG_ERROR("(WIN32) read from pipe failed, error code: 0x%08lx", GetLastError()); | |||||
return -1; | |||||
} | |||||
return has_read; | |||||
} | |||||
static int aice_pipe_child_init(struct aice_port_param_s *param) | |||||
{ | |||||
STARTUPINFO start_info; | |||||
BOOL success; | |||||
ZeroMemory(&proc_info, sizeof(PROCESS_INFORMATION)); | |||||
ZeroMemory(&start_info, sizeof(STARTUPINFO)); | |||||
start_info.cb = sizeof(STARTUPINFO); | |||||
start_info.hStdError = aice_pipe_input[1]; | |||||
start_info.hStdOutput = aice_pipe_input[1]; | |||||
start_info.hStdInput = aice_pipe_output[0]; | |||||
start_info.dwFlags |= STARTF_USESTDHANDLES; | |||||
success = CreateProcess(NULL, | |||||
param->adapter_name, | |||||
NULL, | |||||
NULL, | |||||
TRUE, | |||||
0, | |||||
NULL, | |||||
NULL, | |||||
&start_info, | |||||
&proc_info); | |||||
if (!success) { | |||||
LOG_ERROR("Create new process failed"); | |||||
return ERROR_FAIL; | |||||
} | |||||
return ERROR_OK; | |||||
} | |||||
static int aice_pipe_parent_init(struct aice_port_param_s *param) | |||||
{ | |||||
/* send open to adapter */ | |||||
char line[AICE_PIPE_MAXLINE]; | |||||
char command[AICE_PIPE_MAXLINE]; | |||||
command[0] = AICE_OPEN; | |||||
set_u16(command + 1, param->vid); | |||||
set_u16(command + 3, param->pid); | |||||
if (aice_pipe_write(command, 5) != 5) { | |||||
LOG_ERROR("write failed\n"); | |||||
return ERROR_FAIL; | |||||
} | |||||
if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) { | |||||
LOG_ERROR("read failed\n"); | |||||
return ERROR_FAIL; | |||||
} | |||||
if (line[0] == AICE_OK) | |||||
return ERROR_OK; | |||||
else | |||||
return ERROR_FAIL; | |||||
} | |||||
static int aice_pipe_open(struct aice_port_param_s *param) | |||||
{ | |||||
SECURITY_ATTRIBUTES attribute; | |||||
attribute.nLength = sizeof(SECURITY_ATTRIBUTES); | |||||
attribute.bInheritHandle = TRUE; | |||||
attribute.lpSecurityDescriptor = NULL; | |||||
if (!CreatePipe(&aice_pipe_output[0], &aice_pipe_output[1], | |||||
&attribute, AICE_PIPE_MAXLINE)) { | |||||
LOG_ERROR("Create pipes failed"); | |||||
return ERROR_FAIL; | |||||
} | |||||
if (!CreatePipe(&aice_pipe_input[0], &aice_pipe_input[1], | |||||
&attribute, AICE_PIPE_MAXLINE)) { | |||||
LOG_ERROR("Create pipes failed"); | |||||
return ERROR_FAIL; | |||||
} | |||||
/* do not inherit aice_pipe_output[1] & aice_pipe_input[0] to child process */ | |||||
if (!SetHandleInformation(aice_pipe_output[1], HANDLE_FLAG_INHERIT, 0)) | |||||
return ERROR_FAIL; | |||||
if (!SetHandleInformation(aice_pipe_input[0], HANDLE_FLAG_INHERIT, 0)) | |||||
return ERROR_FAIL; | |||||
aice_pipe_child_init(param); | |||||
aice_pipe_parent_init(param); | |||||
return ERROR_OK; | |||||
} | |||||
#else | |||||
int aice_pipe_output[2]; | |||||
int aice_pipe_input[2]; | |||||
static int aice_pipe_write(const void *buffer, int count) | |||||
{ | |||||
if (write(aice_pipe_output[1], buffer, count) != count) { | |||||
LOG_ERROR("write to pipe failed"); | |||||
return -1; | |||||
} | |||||
return count; | |||||
} | |||||
static int aice_pipe_read(void *buffer, int count) | |||||
{ | |||||
int n; | |||||
long long then, cur; | |||||
then = timeval_ms(); | |||||
while (1) { | |||||
n = read(aice_pipe_input[0], buffer, count); | |||||
if ((n == -1) && (errno == EAGAIN)) { | |||||
cur = timeval_ms(); | |||||
if (cur - then > 500) | |||||
keep_alive(); | |||||
continue; | |||||
} else if (n > 0) | |||||
break; | |||||
else { | |||||
LOG_ERROR("read from pipe failed"); | |||||
break; | |||||
} | |||||
} | |||||
return n; | |||||
} | |||||
static int aice_pipe_child_init(struct aice_port_param_s *param) | |||||
{ | |||||
close(aice_pipe_output[1]); | |||||
close(aice_pipe_input[0]); | |||||
if (aice_pipe_output[0] != STDIN_FILENO) { | |||||
if (dup2(aice_pipe_output[0], STDIN_FILENO) != STDIN_FILENO) { | |||||
LOG_ERROR("Map aice_pipe to STDIN failed"); | |||||
return ERROR_FAIL; | |||||
} | |||||
close(aice_pipe_output[0]); | |||||
} | |||||
if (aice_pipe_input[1] != STDOUT_FILENO) { | |||||
if (dup2(aice_pipe_input[1], STDOUT_FILENO) != STDOUT_FILENO) { | |||||
LOG_ERROR("Map aice_pipe to STDOUT failed"); | |||||
return ERROR_FAIL; | |||||
} | |||||
close(aice_pipe_input[1]); | |||||
} | |||||
if (execl(param->adapter_name, param->adapter_name, (char *)0) < 0) { | |||||
LOG_ERROR("Execute aice_pipe failed"); | |||||
return ERROR_FAIL; | |||||
} | |||||
return ERROR_OK; | |||||
} | |||||
static int aice_pipe_parent_init(struct aice_port_param_s *param) | |||||
{ | |||||
close(aice_pipe_output[0]); | |||||
close(aice_pipe_input[1]); | |||||
/* set read end of pipe as non-blocking */ | |||||
if (fcntl(aice_pipe_input[0], F_SETFL, O_NONBLOCK)) | |||||
return ERROR_FAIL; | |||||
/* send open to adapter */ | |||||
char line[AICE_PIPE_MAXLINE]; | |||||
char command[AICE_PIPE_MAXLINE]; | |||||
command[0] = AICE_OPEN; | |||||
set_u16(command + 1, param->vid); | |||||
set_u16(command + 3, param->pid); | |||||
if (aice_pipe_write(command, 5) != 5) { | |||||
LOG_ERROR("write failed\n"); | |||||
return ERROR_FAIL; | |||||
} | |||||
if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) { | |||||
LOG_ERROR("read failed\n"); | |||||
return ERROR_FAIL; | |||||
} | |||||
if (line[0] == AICE_OK) | |||||
return ERROR_OK; | |||||
else | |||||
return ERROR_FAIL; | |||||
} | |||||
static void sig_pipe(int signo) | |||||
{ | |||||
exit(1); | |||||
} | |||||
static int aice_pipe_open(struct aice_port_param_s *param) | |||||
{ | |||||
pid_t pid; | |||||
if (signal(SIGPIPE, sig_pipe) == SIG_ERR) { | |||||
LOG_ERROR("Register SIGPIPE handler failed"); | |||||
return ERROR_FAIL; | |||||
} | |||||
if (pipe(aice_pipe_output) < 0 || pipe(aice_pipe_input) < 0) { | |||||
LOG_ERROR("Create pipes failed"); | |||||
return ERROR_FAIL; | |||||
} | |||||
pid = fork(); | |||||
if (pid < 0) { | |||||
LOG_ERROR("Fork new process failed"); | |||||
return ERROR_FAIL; | |||||
} else if (pid == 0) { | |||||
if (aice_pipe_child_init(param) != ERROR_OK) { | |||||
LOG_ERROR("AICE_PIPE child process initial error"); | |||||
return ERROR_FAIL; | |||||
} else { | |||||
if (aice_pipe_parent_init(param) != ERROR_OK) { | |||||
LOG_ERROR("AICE_PIPE parent process initial error"); | |||||
return ERROR_FAIL; | |||||
} | |||||
} | |||||
} | |||||
return ERROR_OK; | |||||
} | |||||
#endif | |||||
static int aice_pipe_close(void) | |||||
{ | |||||
char line[AICE_PIPE_MAXLINE]; | |||||
char command[AICE_PIPE_MAXLINE]; | |||||
command[0] = AICE_CLOSE; | |||||
if (aice_pipe_write(command, 1) != 1) | |||||
return ERROR_FAIL; | |||||
if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) | |||||
return ERROR_FAIL; | |||||
if (line[0] == AICE_OK) { | |||||
#ifdef _WIN32 | |||||
WaitForSingleObject(proc_info.hProcess, INFINITE); | |||||
CloseHandle(proc_info.hProcess); | |||||
CloseHandle(proc_info.hThread); | |||||
#endif | |||||
return ERROR_OK; | |||||
} else | |||||
return ERROR_FAIL; | |||||
} | |||||
static int aice_pipe_idcode(uint32_t *idcode, uint8_t *num_of_idcode) | |||||
{ | |||||
char line[AICE_PIPE_MAXLINE]; | |||||
char command[AICE_PIPE_MAXLINE]; | |||||
command[0] = AICE_IDCODE; | |||||
if (aice_pipe_write(command, 1) != 1) | |||||
return ERROR_FAIL; | |||||
if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) | |||||
return ERROR_FAIL; | |||||
*num_of_idcode = line[0]; | |||||
if ((*num_of_idcode == 0) || (*num_of_idcode >= 16)) | |||||
return ERROR_FAIL; | |||||
for (int i = 0 ; i < *num_of_idcode ; i++) | |||||
idcode[i] = get_u32(line + i * 4 + 1); | |||||
return ERROR_OK; | |||||
} | |||||
static int aice_pipe_state(enum aice_target_state_s *state) | |||||
{ | |||||
char line[AICE_PIPE_MAXLINE]; | |||||
char command[AICE_PIPE_MAXLINE]; | |||||
command[0] = AICE_STATE; | |||||
if (aice_pipe_write(command, 1) != 1) | |||||
return ERROR_FAIL; | |||||
if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) | |||||
return ERROR_FAIL; | |||||
*state = (enum aice_target_state_s)line[0]; | |||||
return ERROR_OK; | |||||
} | |||||
static int aice_pipe_reset(void) | |||||
{ | |||||
char line[AICE_PIPE_MAXLINE]; | |||||
char command[AICE_PIPE_MAXLINE]; | |||||
command[0] = AICE_RESET; | |||||
if (aice_pipe_write(command, 1) != 1) | |||||
return ERROR_FAIL; | |||||
if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) | |||||
return ERROR_FAIL; | |||||
if (line[0] == AICE_OK) | |||||
return ERROR_OK; | |||||
else | |||||
return ERROR_FAIL; | |||||
} | |||||
static int aice_pipe_assert_srst(enum aice_srst_type_s srst) | |||||
{ | |||||
char line[AICE_PIPE_MAXLINE]; | |||||
char command[AICE_PIPE_MAXLINE]; | |||||
command[0] = AICE_ASSERT_SRST; | |||||
command[1] = srst; | |||||
if (aice_pipe_write(command, 2) != 2) | |||||
return ERROR_FAIL; | |||||
if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) | |||||
return ERROR_FAIL; | |||||
if (line[0] == AICE_OK) | |||||
return ERROR_OK; | |||||
else | |||||
return ERROR_FAIL; | |||||
} | |||||
static int aice_pipe_run(void) | |||||
{ | |||||
char line[AICE_PIPE_MAXLINE]; | |||||
char command[AICE_PIPE_MAXLINE]; | |||||
command[0] = AICE_RUN; | |||||
if (aice_pipe_write(command, 1) != 1) | |||||
return ERROR_FAIL; | |||||
if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) | |||||
return ERROR_FAIL; | |||||
if (line[0] == AICE_OK) | |||||
return ERROR_OK; | |||||
else | |||||
return ERROR_FAIL; | |||||
} | |||||
static int aice_pipe_halt(void) | |||||
{ | |||||
char line[AICE_PIPE_MAXLINE]; | |||||
char command[AICE_PIPE_MAXLINE]; | |||||
command[0] = AICE_HALT; | |||||
if (aice_pipe_write(command, 1) != 1) | |||||
return ERROR_FAIL; | |||||
if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) | |||||
return ERROR_FAIL; | |||||
if (line[0] == AICE_OK) | |||||
return ERROR_OK; | |||||
else | |||||
return ERROR_FAIL; | |||||
} | |||||
static int aice_pipe_read_reg(uint32_t num, uint32_t *val) | |||||
{ | |||||
char line[AICE_PIPE_MAXLINE]; | |||||
char command[AICE_PIPE_MAXLINE]; | |||||
command[0] = AICE_READ_REG; | |||||
set_u32(command + 1, num); | |||||
if (aice_pipe_write(command, 5) != 5) | |||||
return ERROR_FAIL; | |||||
if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) | |||||
return ERROR_FAIL; | |||||
*val = get_u32(line); | |||||
return ERROR_OK; | |||||
} | |||||
static int aice_pipe_write_reg(uint32_t num, uint32_t val) | |||||
{ | |||||
char line[AICE_PIPE_MAXLINE]; | |||||
char command[AICE_PIPE_MAXLINE]; | |||||
command[0] = AICE_WRITE_REG; | |||||
set_u32(command + 1, num); | |||||
set_u32(command + 5, val); | |||||
if (aice_pipe_write(command, 9) != 9) | |||||
return ERROR_FAIL; | |||||
if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) | |||||
return ERROR_FAIL; | |||||
if (line[0] == AICE_OK) | |||||
return ERROR_OK; | |||||
else | |||||
return ERROR_FAIL; | |||||
} | |||||
static int aice_pipe_read_reg_64(uint32_t num, uint64_t *val) | |||||
{ | |||||
char line[AICE_PIPE_MAXLINE]; | |||||
char command[AICE_PIPE_MAXLINE]; | |||||
command[0] = AICE_READ_REG_64; | |||||
set_u32(command + 1, num); | |||||
if (aice_pipe_write(command, 5) != 5) | |||||
return ERROR_FAIL; | |||||
if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) | |||||
return ERROR_FAIL; | |||||
*val = (((uint64_t)get_u32(line + 4)) << 32) | get_u32(line); | |||||
return ERROR_OK; | |||||
} | |||||
static int aice_pipe_write_reg_64(uint32_t num, uint64_t val) | |||||
{ | |||||
char line[AICE_PIPE_MAXLINE]; | |||||
char command[AICE_PIPE_MAXLINE]; | |||||
command[0] = AICE_WRITE_REG_64; | |||||
set_u32(command + 1, num); | |||||
set_u32(command + 5, val & 0xFFFFFFFF); | |||||
set_u32(command + 9, (val >> 32) & 0xFFFFFFFF); | |||||
if (aice_pipe_write(command, 13) != 9) | |||||
return ERROR_FAIL; | |||||
if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) | |||||
return ERROR_FAIL; | |||||
if (line[0] == AICE_OK) | |||||
return ERROR_OK; | |||||
else | |||||
return ERROR_FAIL; | |||||
} | |||||
static int aice_pipe_step(void) | |||||
{ | |||||
char line[AICE_PIPE_MAXLINE]; | |||||
char command[AICE_PIPE_MAXLINE]; | |||||
command[0] = AICE_STEP; | |||||
if (aice_pipe_write(command, 1) != 1) | |||||
return ERROR_FAIL; | |||||
if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) | |||||
return ERROR_FAIL; | |||||
if (line[0] == AICE_OK) | |||||
return ERROR_OK; | |||||
else | |||||
return ERROR_FAIL; | |||||
} | |||||
static int aice_pipe_read_mem_unit(uint32_t addr, uint32_t size, | |||||
uint32_t count, uint8_t *buffer) | |||||
{ | |||||
char command[AICE_PIPE_MAXLINE]; | |||||
command[0] = AICE_READ_MEM_UNIT; | |||||
set_u32(command + 1, addr); | |||||
set_u32(command + 5, size); | |||||
set_u32(command + 9, count); | |||||
if (aice_pipe_write(command, 13) != 13) | |||||
return ERROR_FAIL; | |||||
if (aice_pipe_read(buffer, size * count) < 0) | |||||
return ERROR_FAIL; | |||||
return ERROR_OK; | |||||
} | |||||
static int aice_pipe_write_mem_unit(uint32_t addr, uint32_t size, | |||||
uint32_t count, const uint8_t *buffer) | |||||
{ | |||||
char line[AICE_PIPE_MAXLINE]; | |||||
char command[AICE_PIPE_MAXLINE]; | |||||
command[0] = AICE_WRITE_MEM_UNIT; | |||||
set_u32(command + 1, addr); | |||||
set_u32(command + 5, size); | |||||
set_u32(command + 9, count); | |||||
/* WRITE_MEM_UNIT|addr|size|count|data */ | |||||
memcpy(command + 13, buffer, size * count); | |||||
if (aice_pipe_write(command, 13 + size * count) < 0) | |||||
return ERROR_FAIL; | |||||
if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) | |||||
return ERROR_FAIL; | |||||
if (line[0] == AICE_OK) | |||||
return ERROR_OK; | |||||
else | |||||
return ERROR_FAIL; | |||||
return ERROR_OK; | |||||
} | |||||
static int aice_pipe_read_mem_bulk(uint32_t addr, uint32_t length, uint8_t *buffer) | |||||
{ | |||||
char line[AICE_PIPE_MAXLINE + 1]; | |||||
char command[AICE_PIPE_MAXLINE]; | |||||
uint32_t remain_len = length; | |||||
uint32_t prepare_len; | |||||
char *received_line; | |||||
uint32_t received_len; | |||||
int read_len; | |||||
command[0] = AICE_READ_MEM_BULK; | |||||
set_u32(command + 1, addr); | |||||
set_u32(command + 5, length); | |||||
if (aice_pipe_write(command, 9) < 0) | |||||
return ERROR_FAIL; | |||||
while (remain_len > 0) { | |||||
if (remain_len > AICE_PIPE_MAXLINE) | |||||
prepare_len = AICE_PIPE_MAXLINE; | |||||
else | |||||
prepare_len = remain_len; | |||||
prepare_len++; | |||||
received_len = 0; | |||||
received_line = line; | |||||
do { | |||||
read_len = aice_pipe_read(received_line, prepare_len - received_len); | |||||
if (read_len < 0) | |||||
return ERROR_FAIL; | |||||
received_line += read_len; | |||||
received_len += read_len; | |||||
} while (received_len < prepare_len); | |||||
if (line[0] != AICE_OK) | |||||
return ERROR_FAIL; | |||||
prepare_len--; | |||||
memcpy(buffer, line + 1, prepare_len); | |||||
remain_len -= prepare_len; | |||||
buffer += prepare_len; | |||||
} | |||||
return ERROR_OK; | |||||
} | |||||
static int aice_pipe_write_mem_bulk(uint32_t addr, uint32_t length, const uint8_t *buffer) | |||||
{ | |||||
char line[AICE_PIPE_MAXLINE]; | |||||
char command[AICE_PIPE_MAXLINE + 4]; | |||||
uint32_t remain_len = length; | |||||
uint32_t written_len = 0; | |||||
uint32_t write_len; | |||||
command[0] = AICE_WRITE_MEM_BULK; | |||||
set_u32(command + 1, addr); | |||||
set_u32(command + 5, length); | |||||
/* Send command first */ | |||||
if (aice_pipe_write(command, 9) < 0) | |||||
return ERROR_FAIL; | |||||
if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) | |||||
return ERROR_FAIL; | |||||
if (line[0] == AICE_ERROR) | |||||
return ERROR_FAIL; | |||||
while (remain_len > 0) { | |||||
if (remain_len > AICE_PIPE_MAXLINE) | |||||
write_len = AICE_PIPE_MAXLINE; | |||||
else | |||||
write_len = remain_len; | |||||
set_u32(command, write_len); | |||||
memcpy(command + 4, buffer + written_len, write_len); /* data only */ | |||||
if (aice_pipe_write(command, write_len + 4) < 0) | |||||
return ERROR_FAIL; | |||||
if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) | |||||
return ERROR_FAIL; | |||||
if (line[0] == AICE_ERROR) | |||||
return ERROR_FAIL; | |||||
remain_len -= write_len; | |||||
written_len += write_len; | |||||
} | |||||
if (line[0] == AICE_OK) | |||||
return ERROR_OK; | |||||
else | |||||
return ERROR_FAIL; | |||||
} | |||||
static int aice_pipe_read_debug_reg(uint32_t addr, uint32_t *val) | |||||
{ | |||||
char line[AICE_PIPE_MAXLINE]; | |||||
char command[AICE_PIPE_MAXLINE]; | |||||
command[0] = AICE_READ_DEBUG_REG; | |||||
set_u32(command + 1, addr); | |||||
if (aice_pipe_write(command, 5) != 5) | |||||
return ERROR_FAIL; | |||||
if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) | |||||
return ERROR_FAIL; | |||||
*val = get_u32(line); | |||||
return ERROR_OK; | |||||
} | |||||
static int aice_pipe_write_debug_reg(uint32_t addr, const uint32_t val) | |||||
{ | |||||
char line[AICE_PIPE_MAXLINE]; | |||||
char command[AICE_PIPE_MAXLINE]; | |||||
command[0] = AICE_WRITE_DEBUG_REG; | |||||
set_u32(command + 1, addr); | |||||
set_u32(command + 5, val); | |||||
if (aice_pipe_write(command, 9) != 9) | |||||
return ERROR_FAIL; | |||||
if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) | |||||
return ERROR_FAIL; | |||||
if (line[0] == AICE_OK) | |||||
return ERROR_OK; | |||||
else | |||||
return ERROR_FAIL; | |||||
} | |||||
static int aice_pipe_set_jtag_clock(uint32_t a_clock) | |||||
{ | |||||
char line[AICE_PIPE_MAXLINE]; | |||||
char command[AICE_PIPE_MAXLINE]; | |||||
command[0] = AICE_SET_JTAG_CLOCK; | |||||
set_u32(command + 1, a_clock); | |||||
if (aice_pipe_write(command, 5) != 5) | |||||
return ERROR_FAIL; | |||||
if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) | |||||
return ERROR_FAIL; | |||||
if (line[0] == AICE_OK) | |||||
return ERROR_OK; | |||||
else | |||||
return ERROR_FAIL; | |||||
} | |||||
static int aice_pipe_select_target(uint32_t target_id) | |||||
{ | |||||
char line[AICE_PIPE_MAXLINE]; | |||||
char command[AICE_PIPE_MAXLINE]; | |||||
command[0] = AICE_SELECT_TARGET; | |||||
set_u32(command + 1, target_id); | |||||
if (aice_pipe_write(command, 5) != 5) | |||||
return ERROR_FAIL; | |||||
if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) | |||||
return ERROR_FAIL; | |||||
if (line[0] == AICE_OK) | |||||
return ERROR_OK; | |||||
else | |||||
return ERROR_FAIL; | |||||
} | |||||
static int aice_pipe_memory_access(enum nds_memory_access access_channel) | |||||
{ | |||||
char line[AICE_PIPE_MAXLINE]; | |||||
char command[AICE_PIPE_MAXLINE]; | |||||
command[0] = AICE_MEMORY_ACCESS; | |||||
set_u32(command + 1, access_channel); | |||||
if (aice_pipe_write(command, 5) != 5) | |||||
return ERROR_FAIL; | |||||
if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) | |||||
return ERROR_FAIL; | |||||
if (line[0] == AICE_OK) | |||||
return ERROR_OK; | |||||
else | |||||
return ERROR_FAIL; | |||||
} | |||||
static int aice_pipe_memory_mode(enum nds_memory_select mem_select) | |||||
{ | |||||
char line[AICE_PIPE_MAXLINE]; | |||||
char command[AICE_PIPE_MAXLINE]; | |||||
command[0] = AICE_MEMORY_MODE; | |||||
set_u32(command + 1, mem_select); | |||||
if (aice_pipe_write(command, 5) != 5) | |||||
return ERROR_FAIL; | |||||
if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) | |||||
return ERROR_FAIL; | |||||
if (line[0] == AICE_OK) | |||||
return ERROR_OK; | |||||
else | |||||
return ERROR_FAIL; | |||||
} | |||||
static int aice_pipe_read_tlb(uint32_t virtual_address, uint32_t *physical_address) | |||||
{ | |||||
char line[AICE_PIPE_MAXLINE]; | |||||
char command[AICE_PIPE_MAXLINE]; | |||||
command[0] = AICE_READ_TLB; | |||||
set_u32(command + 1, virtual_address); | |||||
if (aice_pipe_write(command, 5) != 5) | |||||
return ERROR_FAIL; | |||||
if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) | |||||
return ERROR_FAIL; | |||||
if (line[0] == AICE_OK) { | |||||
*physical_address = get_u32(line + 1); | |||||
return ERROR_OK; | |||||
} else | |||||
return ERROR_FAIL; | |||||
} | |||||
static int aice_pipe_cache_ctl(uint32_t subtype, uint32_t address) | |||||
{ | |||||
char line[AICE_PIPE_MAXLINE]; | |||||
char command[AICE_PIPE_MAXLINE]; | |||||
command[0] = AICE_CACHE_CTL; | |||||
set_u32(command + 1, subtype); | |||||
set_u32(command + 5, address); | |||||
if (aice_pipe_write(command, 9) != 9) | |||||
return ERROR_FAIL; | |||||
if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) | |||||
return ERROR_FAIL; | |||||
if (line[0] == AICE_OK) | |||||
return ERROR_OK; | |||||
else | |||||
return ERROR_FAIL; | |||||
} | |||||
static int aice_pipe_set_retry_times(uint32_t a_retry_times) | |||||
{ | |||||
return ERROR_OK; | |||||
} | |||||
/** */ | |||||
struct aice_port_api_s aice_pipe = { | |||||
/** */ | |||||
.open = aice_pipe_open, | |||||
/** */ | |||||
.close = aice_pipe_close, | |||||
/** */ | |||||
.idcode = aice_pipe_idcode, | |||||
/** */ | |||||
.state = aice_pipe_state, | |||||
/** */ | |||||
.reset = aice_pipe_reset, | |||||
/** */ | |||||
.assert_srst = aice_pipe_assert_srst, | |||||
/** */ | |||||
.run = aice_pipe_run, | |||||
/** */ | |||||
.halt = aice_pipe_halt, | |||||
/** */ | |||||
.step = aice_pipe_step, | |||||
/** */ | |||||
.read_reg = aice_pipe_read_reg, | |||||
/** */ | |||||
.write_reg = aice_pipe_write_reg, | |||||
/** */ | |||||
.read_reg_64 = aice_pipe_read_reg_64, | |||||
/** */ | |||||
.write_reg_64 = aice_pipe_write_reg_64, | |||||
/** */ | |||||
.read_mem_unit = aice_pipe_read_mem_unit, | |||||
/** */ | |||||
.write_mem_unit = aice_pipe_write_mem_unit, | |||||
/** */ | |||||
.read_mem_bulk = aice_pipe_read_mem_bulk, | |||||
/** */ | |||||
.write_mem_bulk = aice_pipe_write_mem_bulk, | |||||
/** */ | |||||
.read_debug_reg = aice_pipe_read_debug_reg, | |||||
/** */ | |||||
.write_debug_reg = aice_pipe_write_debug_reg, | |||||
/** */ | |||||
.set_jtag_clock = aice_pipe_set_jtag_clock, | |||||
/** */ | |||||
.select_target = aice_pipe_select_target, | |||||
/** */ | |||||
.memory_access = aice_pipe_memory_access, | |||||
/** */ | |||||
.memory_mode = aice_pipe_memory_mode, | |||||
/** */ | |||||
.read_tlb = aice_pipe_read_tlb, | |||||
/** */ | |||||
.cache_ctl = aice_pipe_cache_ctl, | |||||
/** */ | |||||
.set_retry_times = aice_pipe_set_retry_times, | |||||
}; |
@@ -0,0 +1,32 @@ | |||||
/*************************************************************************** | |||||
* Copyright (C) 2013 by Andes Technology * | |||||
* Hsiangkai Wang <hkwang@andestech.com> * | |||||
* * | |||||
* 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, write to the * | |||||
* Free Software Foundation, Inc., * | |||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * | |||||
***************************************************************************/ | |||||
#ifndef _AICE_PIPE_H_ | |||||
#define _AICE_PIPE_H_ | |||||
#include <helper/types.h> | |||||
#define set_u32(buffer, value) h_u32_to_le((uint8_t *)buffer, value) | |||||
#define set_u16(buffer, value) h_u16_to_le((uint8_t *)buffer, value) | |||||
#define get_u32(buffer) le_to_h_u32((const uint8_t *)buffer) | |||||
#define get_u16(buffer) le_to_h_u16((const uint8_t *)buffer) | |||||
extern struct aice_port_api_s aice_pipe; | |||||
#endif |
@@ -0,0 +1,47 @@ | |||||
/*************************************************************************** | |||||
* Copyright (C) 2013 by Andes Technology * | |||||
* Hsiangkai Wang <hkwang@andestech.com> * | |||||
* * | |||||
* 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, write to the * | |||||
* Free Software Foundation, Inc., * | |||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * | |||||
***************************************************************************/ | |||||
#ifdef HAVE_CONFIG_H | |||||
#include "config.h" | |||||
#endif | |||||
#include <helper/log.h> | |||||
#include "aice_usb.h" | |||||
#include "aice_pipe.h" | |||||
#include "aice_port.h" | |||||
static const struct aice_port aice_ports[] = { | |||||
{ | |||||
.name = "aice_usb", | |||||
.type = AICE_PORT_AICE_USB, | |||||
.api = &aice_usb_api, | |||||
}, | |||||
{ | |||||
.name = "aice_pipe", | |||||
.type = AICE_PORT_AICE_PIPE, | |||||
.api = &aice_pipe, | |||||
}, | |||||
{.name = NULL, /* END OF TABLE */ }, | |||||
}; | |||||
/** */ | |||||
const struct aice_port *aice_port_get_list(void) | |||||
{ | |||||
return aice_ports; | |||||
} |
@@ -0,0 +1,234 @@ | |||||
/*************************************************************************** | |||||
* Copyright (C) 2013 by Andes Technology * | |||||
* Hsiangkai Wang <hkwang@andestech.com> * | |||||
* * | |||||
* 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, write to the * | |||||
* Free Software Foundation, Inc., * | |||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * | |||||
***************************************************************************/ | |||||
#ifndef _AICE_PORT_H_ | |||||
#define _AICE_PORT_H_ | |||||
#include <target/nds32_edm.h> | |||||
#define ERROR_AICE_DISCONNECT (-200) | |||||
#define ERROR_AICE_TIMEOUT (-201) | |||||
enum aice_target_state_s { | |||||
AICE_DISCONNECT = 0, | |||||
AICE_TARGET_DETACH, | |||||
AICE_TARGET_UNKNOWN, | |||||
AICE_TARGET_RUNNING, | |||||
AICE_TARGET_HALTED, | |||||
AICE_TARGET_RESET, | |||||
AICE_TARGET_DEBUG_RUNNING, | |||||
}; | |||||
enum aice_srst_type_s { | |||||
AICE_SRST = 0x1, | |||||
AICE_RESET_HOLD = 0x8, | |||||
}; | |||||
enum aice_target_endian { | |||||
AICE_LITTLE_ENDIAN = 0, | |||||
AICE_BIG_ENDIAN, | |||||
}; | |||||
enum aice_api_s { | |||||
AICE_OPEN = 0x0, | |||||
AICE_CLOSE, | |||||
AICE_RESET, | |||||
AICE_ASSERT_SRST, | |||||
AICE_RUN, | |||||
AICE_HALT, | |||||
AICE_STEP, | |||||
AICE_READ_REG, | |||||
AICE_WRITE_REG, | |||||
AICE_READ_REG_64, | |||||
AICE_WRITE_REG_64, | |||||
AICE_READ_MEM_UNIT, | |||||
AICE_WRITE_MEM_UNIT, | |||||
AICE_READ_MEM_BULK, | |||||
AICE_WRITE_MEM_BULK, | |||||
AICE_READ_DEBUG_REG, | |||||
AICE_WRITE_DEBUG_REG, | |||||
AICE_IDCODE, | |||||
AICE_STATE, | |||||
AICE_SET_JTAG_CLOCK, | |||||
AICE_SELECT_TARGET, | |||||
AICE_MEMORY_ACCESS, | |||||
AICE_MEMORY_MODE, | |||||
AICE_READ_TLB, | |||||
AICE_CACHE_CTL, | |||||
AICE_SET_RETRY_TIMES, | |||||
AICE_PROGRAM_EDM, | |||||
AICE_PACK_COMMAND, | |||||
AICE_EXECUTE, | |||||
AICE_SET_CUSTOM_SRST_SCRIPT, | |||||
AICE_SET_CUSTOM_TRST_SCRIPT, | |||||
AICE_SET_CUSTOM_RESTART_SCRIPT, | |||||
AICE_SET_COUNT_TO_CHECK_DBGER, | |||||
AICE_SET_DATA_ENDIAN, | |||||
}; | |||||
enum aice_error_s { | |||||
AICE_OK, | |||||
AICE_ACK, | |||||
AICE_ERROR, | |||||
}; | |||||
enum aice_cache_ctl_type { | |||||
AICE_CACHE_CTL_L1D_INVALALL = 0, | |||||
AICE_CACHE_CTL_L1D_VA_INVAL, | |||||
AICE_CACHE_CTL_L1D_WBALL, | |||||
AICE_CACHE_CTL_L1D_VA_WB, | |||||
AICE_CACHE_CTL_L1I_INVALALL, | |||||
AICE_CACHE_CTL_L1I_VA_INVAL, | |||||
}; | |||||
struct aice_port_param_s { | |||||
/** */ | |||||
char *device_desc; | |||||
/** */ | |||||
char *serial; | |||||
/** */ | |||||
uint16_t vid; | |||||
/** */ | |||||
uint16_t pid; | |||||
/** */ | |||||
char *adapter_name; | |||||
}; | |||||
struct aice_port_s { | |||||
/** */ | |||||
struct aice_port_param_s param; | |||||
/** */ | |||||
const struct aice_port *port; | |||||
/** */ | |||||
uint32_t retry_times; | |||||
/** */ | |||||
uint32_t count_to_check_dbger; | |||||
}; | |||||
/** */ | |||||
extern struct aice_port_api_s aice_usb_layout_api; | |||||
/** */ | |||||
struct aice_port_api_s { | |||||
/** */ | |||||
int (*open)(struct aice_port_param_s *param); | |||||
/** */ | |||||
int (*close)(void); | |||||
/** */ | |||||
int (*reset)(void); | |||||
/** */ | |||||
int (*assert_srst)(enum aice_srst_type_s srst); | |||||
/** */ | |||||
int (*run)(void); | |||||
/** */ | |||||
int (*halt)(void); | |||||
/** */ | |||||
int (*step)(void); | |||||
/** */ | |||||
int (*read_reg)(uint32_t num, uint32_t *val); | |||||
/** */ | |||||
int (*write_reg)(uint32_t num, uint32_t val); | |||||
/** */ | |||||
int (*read_reg_64)(uint32_t num, uint64_t *val); | |||||
/** */ | |||||
int (*write_reg_64)(uint32_t num, uint64_t val); | |||||
/** */ | |||||
int (*read_mem_unit)(uint32_t addr, uint32_t size, uint32_t count, | |||||
uint8_t *buffer); | |||||
/** */ | |||||
int (*write_mem_unit)(uint32_t addr, uint32_t size, uint32_t count, | |||||
const uint8_t *buffer); | |||||
/** */ | |||||
int (*read_mem_bulk)(uint32_t addr, uint32_t length, | |||||
uint8_t *buffer); | |||||
/** */ | |||||
int (*write_mem_bulk)(uint32_t addr, uint32_t length, | |||||
const uint8_t *buffer); | |||||
/** */ | |||||
int (*read_debug_reg)(uint32_t addr, uint32_t *val); | |||||
/** */ | |||||
int (*write_debug_reg)(uint32_t addr, const uint32_t val); | |||||
/** */ | |||||
int (*idcode)(uint32_t *idcode, uint8_t *num_of_idcode); | |||||
/** */ | |||||
int (*state)(enum aice_target_state_s *state); | |||||
/** */ | |||||
int (*set_jtag_clock)(uint32_t a_clock); | |||||
/** */ | |||||
int (*select_target)(uint32_t target_id); | |||||
/** */ | |||||
int (*memory_access)(enum nds_memory_access a_access); | |||||
/** */ | |||||
int (*memory_mode)(enum nds_memory_select mem_select); | |||||
/** */ | |||||
int (*read_tlb)(uint32_t virtual_address, uint32_t *physical_address); | |||||
/** */ | |||||
int (*cache_ctl)(uint32_t subtype, uint32_t address); | |||||
/** */ | |||||
int (*set_retry_times)(uint32_t a_retry_times); | |||||
/** */ | |||||
int (*program_edm)(char *command_sequence); | |||||
/** */ | |||||
int (*pack_command)(bool enable_pack_command); | |||||
/** */ | |||||
int (*execute)(uint32_t *instructions, uint32_t instruction_num); | |||||
/** */ | |||||
int (*set_custom_srst_script)(const char *script); | |||||
/** */ | |||||
int (*set_custom_trst_script)(const char *script); | |||||
/** */ | |||||
int (*set_custom_restart_script)(const char *script); | |||||
/** */ | |||||
int (*set_count_to_check_dbger)(uint32_t count_to_check); | |||||
/** */ | |||||
int (*set_data_endian)(enum aice_target_endian target_data_endian); | |||||
}; | |||||
#define AICE_PORT_UNKNOWN 0 | |||||
#define AICE_PORT_AICE_USB 1 | |||||
#define AICE_PORT_AICE_PIPE 2 | |||||
/** */ | |||||
struct aice_port { | |||||
/** */ | |||||
char *name; | |||||
/** */ | |||||
int type; | |||||
/** */ | |||||
struct aice_port_api_s *api; | |||||
}; | |||||
/** */ | |||||
const struct aice_port *aice_port_get_list(void); | |||||
#endif |
@@ -0,0 +1,385 @@ | |||||
/*************************************************************************** | |||||
* Copyright (C) 2013 by Andes Technology * | |||||
* Hsiangkai Wang <hkwang@andestech.com> * | |||||
* * | |||||
* 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, write to the * | |||||
* Free Software Foundation, Inc., * | |||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * | |||||
***************************************************************************/ | |||||
#ifdef HAVE_CONFIG_H | |||||
#include "config.h" | |||||
#endif | |||||
/* project specific includes */ | |||||
#include <jtag/interface.h> | |||||
#include <jtag/tcl.h> | |||||
#include <transport/transport.h> | |||||
#include <target/target.h> | |||||
#include <jtag/aice/aice_interface.h> | |||||
#include <jtag/aice/aice_transport.h> | |||||
/* */ | |||||
static int jim_newtap_expected_id(Jim_Nvp *n, Jim_GetOptInfo *goi, | |||||
struct jtag_tap *pTap) | |||||
{ | |||||
jim_wide w; | |||||
int e = Jim_GetOpt_Wide(goi, &w); | |||||
if (e != JIM_OK) { | |||||
Jim_SetResultFormatted(goi->interp, "option: %s bad parameter", | |||||
n->name); | |||||
return e; | |||||
} | |||||
unsigned expected_len = sizeof(uint32_t) * pTap->expected_ids_cnt; | |||||
uint32_t *new_expected_ids = malloc(expected_len + sizeof(uint32_t)); | |||||
if (new_expected_ids == NULL) { | |||||
Jim_SetResultFormatted(goi->interp, "no memory"); | |||||
return JIM_ERR; | |||||
} | |||||
memcpy(new_expected_ids, pTap->expected_ids, expected_len); | |||||
new_expected_ids[pTap->expected_ids_cnt] = w; | |||||
free(pTap->expected_ids); | |||||
pTap->expected_ids = new_expected_ids; | |||||
pTap->expected_ids_cnt++; | |||||
return JIM_OK; | |||||
} | |||||
#define NTAP_OPT_EXPECTED_ID 0 | |||||
/* */ | |||||
static int jim_aice_newtap_cmd(Jim_GetOptInfo *goi) | |||||
{ | |||||
struct jtag_tap *pTap; | |||||
int x; | |||||
int e; | |||||
Jim_Nvp *n; | |||||
char *cp; | |||||
const Jim_Nvp opts[] = { | |||||
{.name = "-expected-id", .value = NTAP_OPT_EXPECTED_ID}, | |||||
{.name = NULL, .value = -1}, | |||||
}; | |||||
pTap = calloc(1, sizeof(struct jtag_tap)); | |||||
if (!pTap) { | |||||
Jim_SetResultFormatted(goi->interp, "no memory"); | |||||
return JIM_ERR; | |||||
} | |||||
/* | |||||
* we expect CHIP + TAP + OPTIONS | |||||
* */ | |||||
if (goi->argc < 3) { | |||||
Jim_SetResultFormatted(goi->interp, | |||||
"Missing CHIP TAP OPTIONS ...."); | |||||
free(pTap); | |||||
return JIM_ERR; | |||||
} | |||||
Jim_GetOpt_String(goi, &cp, NULL); | |||||
pTap->chip = strdup(cp); | |||||
Jim_GetOpt_String(goi, &cp, NULL); | |||||
pTap->tapname = strdup(cp); | |||||
/* name + dot + name + null */ | |||||
x = strlen(pTap->chip) + 1 + strlen(pTap->tapname) + 1; | |||||
cp = malloc(x); | |||||
sprintf(cp, "%s.%s", pTap->chip, pTap->tapname); | |||||
pTap->dotted_name = cp; | |||||
LOG_DEBUG("Creating New Tap, Chip: %s, Tap: %s, Dotted: %s, %d params", | |||||
pTap->chip, pTap->tapname, pTap->dotted_name, goi->argc); | |||||
while (goi->argc) { | |||||
e = Jim_GetOpt_Nvp(goi, opts, &n); | |||||
if (e != JIM_OK) { | |||||
Jim_GetOpt_NvpUnknown(goi, opts, 0); | |||||
free((void *)pTap->dotted_name); | |||||
free(pTap); | |||||
return e; | |||||
} | |||||
LOG_DEBUG("Processing option: %s", n->name); | |||||
switch (n->value) { | |||||
case NTAP_OPT_EXPECTED_ID: | |||||
e = jim_newtap_expected_id(n, goi, pTap); | |||||
if (JIM_OK != e) { | |||||
free((void *)pTap->dotted_name); | |||||
free(pTap); | |||||
return e; | |||||
} | |||||
break; | |||||
} /* switch (n->value) */ | |||||
} /* while (goi->argc) */ | |||||
/* default is enabled-after-reset */ | |||||
pTap->enabled = !pTap->disabled_after_reset; | |||||
jtag_tap_init(pTap); | |||||
return JIM_OK; | |||||
} | |||||
/* */ | |||||
static int jim_aice_newtap(Jim_Interp *interp, int argc, Jim_Obj * const *argv) | |||||
{ | |||||
Jim_GetOptInfo goi; | |||||
Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1); | |||||
return jim_aice_newtap_cmd(&goi); | |||||
} | |||||
/* */ | |||||
COMMAND_HANDLER(handle_aice_init_command) | |||||
{ | |||||
if (CMD_ARGC != 0) | |||||
return ERROR_COMMAND_SYNTAX_ERROR; | |||||
static bool jtag_initialized; | |||||
if (jtag_initialized) { | |||||
LOG_INFO("'jtag init' has already been called"); | |||||
return ERROR_OK; | |||||
} | |||||
jtag_initialized = true; | |||||
LOG_DEBUG("Initializing jtag devices..."); | |||||
return jtag_init(CMD_CTX); | |||||
} | |||||
static int jim_aice_arp_init(Jim_Interp *interp, int argc, Jim_Obj * const *argv) | |||||
{ | |||||
LOG_DEBUG("No implement: jim_aice_arp_init"); | |||||
return JIM_OK; | |||||
} | |||||
/* */ | |||||
static int aice_init_reset(struct command_context *cmd_ctx) | |||||
{ | |||||
LOG_DEBUG("Initializing with hard TRST+SRST reset"); | |||||
int retval; | |||||
enum reset_types jtag_reset_config = jtag_get_reset_config(); | |||||
jtag_add_reset(1, 0); /* TAP_RESET */ | |||||
if (jtag_reset_config & RESET_HAS_SRST) { | |||||
jtag_add_reset(1, 1); | |||||
if ((jtag_reset_config & RESET_SRST_PULLS_TRST) == 0) | |||||
jtag_add_reset(0, 1); | |||||
} | |||||
jtag_add_reset(0, 0); | |||||
retval = jtag_execute_queue(); | |||||
if (retval != ERROR_OK) | |||||
return retval; | |||||
return ERROR_OK; | |||||
} | |||||
/* */ | |||||
static int jim_aice_arp_init_reset(Jim_Interp *interp, int argc, Jim_Obj * const *argv) | |||||
{ | |||||
int e = ERROR_OK; | |||||
Jim_GetOptInfo goi; | |||||
Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1); | |||||
if (goi.argc != 0) { | |||||
Jim_WrongNumArgs(goi.interp, 1, goi.argv - 1, "(no params)"); | |||||
return JIM_ERR; | |||||
} | |||||
struct command_context *context = current_command_context(interp); | |||||
e = aice_init_reset(context); | |||||
if (e != ERROR_OK) { | |||||
Jim_Obj *eObj = Jim_NewIntObj(goi.interp, e); | |||||
Jim_SetResultFormatted(goi.interp, "error: %#s", eObj); | |||||
Jim_FreeNewObj(goi.interp, eObj); | |||||
return JIM_ERR; | |||||
} | |||||
return JIM_OK; | |||||
} | |||||
static int jim_aice_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv) | |||||
{ | |||||
Jim_GetOptInfo goi; | |||||
Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1); | |||||
if (goi.argc != 0) { | |||||
Jim_WrongNumArgs(goi.interp, 1, goi.argv, "Too many parameters"); | |||||
return JIM_ERR; | |||||
} | |||||
Jim_SetResult(goi.interp, Jim_NewListObj(goi.interp, NULL, 0)); | |||||
struct jtag_tap *tap; | |||||
for (tap = jtag_all_taps(); tap; tap = tap->next_tap) | |||||
Jim_ListAppendElement(goi.interp, | |||||
Jim_GetResult(goi.interp), | |||||
Jim_NewStringObj(goi.interp, | |||||
tap->dotted_name, -1)); | |||||
return JIM_OK; | |||||
} | |||||
/* */ | |||||
static const struct command_registration | |||||
aice_transport_jtag_subcommand_handlers[] = { | |||||
{ | |||||
.name = "init", | |||||
.mode = COMMAND_ANY, | |||||
.handler = handle_aice_init_command, | |||||
.help = "initialize jtag scan chain", | |||||
.usage = "" | |||||
}, | |||||
{ | |||||
.name = "arp_init", | |||||
.mode = COMMAND_ANY, | |||||
.jim_handler = jim_aice_arp_init, | |||||
.help = "Validates JTAG scan chain against the list of " | |||||
"declared TAPs.", | |||||
}, | |||||
{ | |||||
.name = "arp_init-reset", | |||||
.mode = COMMAND_ANY, | |||||
.jim_handler = jim_aice_arp_init_reset, | |||||
.help = "Uses TRST and SRST to try resetting everything on " | |||||
"the JTAG scan chain, then performs 'jtag arp_init'." | |||||
}, | |||||
{ | |||||
.name = "newtap", | |||||
.mode = COMMAND_CONFIG, | |||||
.jim_handler = jim_aice_newtap, | |||||
.help = "Create a new TAP instance named basename.tap_type, " | |||||
"and appends it to the scan chain.", | |||||
.usage = "basename tap_type ['-expected_id' number]" | |||||
}, | |||||
{ | |||||
.name = "tapisenabled", | |||||
.mode = COMMAND_EXEC, | |||||
.jim_handler = jim_jtag_tap_enabler, | |||||
.help = "Returns a Tcl boolean (0/1) indicating whether " | |||||
"the TAP is enabled (1) or not (0).", | |||||
.usage = "tap_name", | |||||
}, | |||||
{ | |||||
.name = "tapenable", | |||||
.mode = COMMAND_EXEC, | |||||
.jim_handler = jim_jtag_tap_enabler, | |||||
.help = "Try to enable the specified TAP using the " | |||||
"'tap-enable' TAP event.", | |||||
.usage = "tap_name", | |||||
}, | |||||
{ | |||||
.name = "tapdisable", | |||||
.mode = COMMAND_EXEC, | |||||
.jim_handler = jim_jtag_tap_enabler, | |||||
.help = "Try to disable the specified TAP using the " | |||||
"'tap-disable' TAP event.", | |||||
.usage = "tap_name", | |||||
}, | |||||
{ | |||||
.name = "configure", | |||||
.mode = COMMAND_EXEC, | |||||
.jim_handler = jim_jtag_configure, | |||||
.help = "Provide a Tcl handler for the specified " | |||||
"TAP event.", | |||||
.usage = "tap_name '-event' event_name handler", | |||||
}, | |||||
{ | |||||
.name = "cget", | |||||
.mode = COMMAND_EXEC, | |||||
.jim_handler = jim_jtag_configure, | |||||
.help = "Return any Tcl handler for the specified " | |||||
"TAP event.", | |||||
.usage = "tap_name '-event' event_name", | |||||
}, | |||||
{ | |||||
.name = "names", | |||||
.mode = COMMAND_ANY, | |||||
.jim_handler = jim_aice_names, | |||||
.help = "Returns list of all JTAG tap names.", | |||||
}, | |||||
COMMAND_REGISTRATION_DONE | |||||
}; | |||||
/* */ | |||||
static const struct command_registration aice_transport_command_handlers[] = { | |||||
{ | |||||
.name = "jtag", | |||||
.mode = COMMAND_ANY, | |||||
.usage = "", | |||||
.chain = aice_transport_jtag_subcommand_handlers, | |||||
}, | |||||
COMMAND_REGISTRATION_DONE | |||||
}; | |||||
/* */ | |||||
static int aice_transport_register_commands(struct command_context *cmd_ctx) | |||||
{ | |||||
return register_commands(cmd_ctx, NULL, | |||||
aice_transport_command_handlers); | |||||
} | |||||
/* */ | |||||
static int aice_transport_init(struct command_context *cmd_ctx) | |||||
{ | |||||
LOG_DEBUG("aice_transport_init"); | |||||
struct target *t = get_current_target(cmd_ctx); | |||||
struct transport *transport; | |||||
if (!t) { | |||||
LOG_ERROR("no current target"); | |||||
return ERROR_FAIL; | |||||
} | |||||
transport = get_current_transport(); | |||||
if (!transport) { | |||||
LOG_ERROR("no transport selected"); | |||||
return ERROR_FAIL; | |||||
} | |||||
LOG_DEBUG("current transport %s", transport->name); | |||||
return aice_init_target(t); | |||||
} | |||||
/* */ | |||||
static int aice_transport_select(struct command_context *ctx) | |||||
{ | |||||
LOG_DEBUG("aice_transport_select"); | |||||
int retval; | |||||
retval = aice_transport_register_commands(ctx); | |||||
if (retval != ERROR_OK) | |||||
return retval; | |||||
return ERROR_OK; | |||||
} | |||||
static struct transport aice_jtag_transport = { | |||||
.name = "aice_jtag", | |||||
.select = aice_transport_select, | |||||
.init = aice_transport_init, | |||||
}; | |||||
const char *aice_transports[] = { "aice_jtag", NULL }; | |||||
static void aice_constructor(void) __attribute__((constructor)); | |||||
static void aice_constructor(void) | |||||
{ | |||||
transport_register(&aice_jtag_transport); | |||||
} | |||||
@@ -0,0 +1,26 @@ | |||||
/*************************************************************************** | |||||
* Copyright (C) 2013 by Andes Technology * | |||||
* Hsiangkai Wang <hkwang@andestech.com> * | |||||
* * | |||||
* 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, write to the * | |||||
* Free Software Foundation, Inc., * | |||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * | |||||
***************************************************************************/ | |||||
#ifndef _AICE_TRANSPORT_ | |||||
#define _AICE_TRANSPORT_ | |||||
extern const char *aice_transports[]; | |||||
#endif |
@@ -0,0 +1,140 @@ | |||||
/*************************************************************************** | |||||
* Copyright (C) 2013 by Andes Technology * | |||||
* Hsiangkai Wang <hkwang@andestech.com> * | |||||
* * | |||||
* 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, write to the * | |||||
* Free Software Foundation, Inc., * | |||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * | |||||
***************************************************************************/ | |||||
#ifndef __AICE_USB_H__ | |||||
#define __AICE_USB_H__ | |||||
#include "aice_port.h" | |||||
/* AICE USB timeout value */ | |||||
#define AICE_USB_TIMEOUT 5000 | |||||
/* AICE USB buffer size */ | |||||
#define AICE_IN_BUFFER_SIZE 2048 | |||||
#define AICE_OUT_BUFFER_SIZE 2048 | |||||
#define AICE_IN_PACKETS_BUFFER_SIZE 2048 | |||||
#define AICE_OUT_PACKETS_BUFFER_SIZE 2048 | |||||
/* Constants for AICE command */ | |||||
#define AICE_CMD_SCAN_CHAIN 0x00 | |||||
#define AICE_CMD_SELECT_TARGET 0x01 | |||||
#define AICE_CMD_READ_DIM 0x02 | |||||
#define AICE_CMD_READ_EDMSR 0x03 | |||||
#define AICE_CMD_READ_DTR 0x04 | |||||
#define AICE_CMD_READ_MEM 0x05 | |||||
#define AICE_CMD_READ_MISC 0x06 | |||||
#define AICE_CMD_FASTREAD_MEM 0x07 | |||||
#define AICE_CMD_WRITE_DIM 0x08 | |||||
#define AICE_CMD_WRITE_EDMSR 0x09 | |||||
#define AICE_CMD_WRITE_DTR 0x0A | |||||
#define AICE_CMD_WRITE_MEM 0x0B | |||||
#define AICE_CMD_WRITE_MISC 0x0C | |||||
#define AICE_CMD_FASTWRITE_MEM 0x0D | |||||
#define AICE_CMD_EXECUTE 0x0E | |||||
#define AICE_CMD_READ_MEM_B 0x14 | |||||
#define AICE_CMD_READ_MEM_H 0x15 | |||||
#define AICE_CMD_T_READ_MISC 0x20 | |||||
#define AICE_CMD_T_READ_EDMSR 0x21 | |||||
#define AICE_CMD_T_READ_DTR 0x22 | |||||
#define AICE_CMD_T_READ_DIM 0x23 | |||||
#define AICE_CMD_T_READ_MEM_B 0x24 | |||||
#define AICE_CMD_T_READ_MEM_H 0x25 | |||||
#define AICE_CMD_T_READ_MEM 0x26 | |||||
#define AICE_CMD_T_FASTREAD_MEM 0x27 | |||||
#define AICE_CMD_T_WRITE_MISC 0x28 | |||||
#define AICE_CMD_T_WRITE_EDMSR 0x29 | |||||
#define AICE_CMD_T_WRITE_DTR 0x2A | |||||
#define AICE_CMD_T_WRITE_DIM 0x2B | |||||
#define AICE_CMD_T_WRITE_MEM_B 0x2C | |||||
#define AICE_CMD_T_WRITE_MEM_H 0x2D | |||||
#define AICE_CMD_T_WRITE_MEM 0x2E | |||||
#define AICE_CMD_T_FASTWRITE_MEM 0x2F | |||||
#define AICE_CMD_T_GET_TRACE_STATUS 0x36 | |||||
#define AICE_CMD_T_EXECUTE 0x3E | |||||
#define AICE_CMD_AICE_PROGRAM_READ 0x40 | |||||
#define AICE_CMD_AICE_PROGRAM_WRITE 0x41 | |||||
#define AICE_CMD_AICE_PROGRAM_CONTROL 0x42 | |||||
#define AICE_CMD_READ_CTRL 0x50 | |||||
#define AICE_CMD_WRITE_CTRL 0x51 | |||||
#define AICE_CMD_BATCH_BUFFER_READ 0x60 | |||||
#define AICE_CMD_READ_DTR_TO_BUFFER 0x61 | |||||
#define AICE_CMD_BATCH_BUFFER_WRITE 0x68 | |||||
#define AICE_CMD_WRITE_DTR_FROM_BUFFER 0x69 | |||||
/* Constants for AICE command format length */ | |||||
#define AICE_FORMAT_HTDA 3 | |||||
#define AICE_FORMAT_HTDB 6 | |||||
#define AICE_FORMAT_HTDC 7 | |||||
#define AICE_FORMAT_HTDD 10 | |||||
#define AICE_FORMAT_HTDMA 4 | |||||
#define AICE_FORMAT_HTDMB 8 | |||||
#define AICE_FORMAT_HTDMC 8 | |||||
#define AICE_FORMAT_HTDMD 12 | |||||
#define AICE_FORMAT_DTHA 6 | |||||
#define AICE_FORMAT_DTHB 2 | |||||
#define AICE_FORMAT_DTHMA 8 | |||||
#define AICE_FORMAT_DTHMB 4 | |||||
/* Constants for AICE command READ_CTRL */ | |||||
#define AICE_READ_CTRL_GET_ICE_STATE 0x00 | |||||
#define AICE_READ_CTRL_GET_HARDWARE_VERSION 0x01 | |||||
#define AICE_READ_CTRL_GET_FPGA_VERSION 0x02 | |||||
#define AICE_READ_CTRL_GET_FIRMWARE_VERSION 0x03 | |||||
#define AICE_READ_CTRL_GET_JTAG_PIN_STATUS 0x04 | |||||
/* Constants for AICE command WRITE_CTRL */ | |||||
#define AICE_WRITE_CTRL_TCK_CONTROL 0x00 | |||||
#define AICE_WRITE_CTRL_JTAG_PIN_CONTROL 0x01 | |||||
#define AICE_WRITE_CTRL_CLEAR_TIMEOUT_STATUS 0x02 | |||||
#define AICE_WRITE_CTRL_RESERVED 0x03 | |||||
#define AICE_WRITE_CTRL_JTAG_PIN_STATUS 0x04 | |||||
#define AICE_WRITE_CTRL_CUSTOM_DELAY 0x0d | |||||
/* Constants for AICE command WRITE_CTRL:TCK_CONTROL */ | |||||
#define AICE_TCK_CONTROL_TCK3048 0x08 | |||||
/* Constants for AICE command WRITE_CTRL:JTAG_PIN_CONTROL */ | |||||
#define AICE_JTAG_PIN_CONTROL_SRST 0x01 | |||||
#define AICE_JTAG_PIN_CONTROL_TRST 0x02 | |||||
#define AICE_JTAG_PIN_CONTROL_STOP 0x04 | |||||
#define AICE_JTAG_PIN_CONTROL_RESTART 0x08 | |||||
/* Constants for AICE command WRITE_CTRL:TCK_CONTROL */ | |||||
#define AICE_TCK_CONTROL_TCK_SCAN 0x10 | |||||
/* Custom SRST/DBGI/TRST */ | |||||
#define AICE_CUSTOM_DELAY_SET_SRST 0x01 | |||||
#define AICE_CUSTOM_DELAY_CLEAN_SRST 0x02 | |||||
#define AICE_CUSTOM_DELAY_SET_DBGI 0x04 | |||||
#define AICE_CUSTOM_DELAY_CLEAN_DBGI 0x08 | |||||
#define AICE_CUSTOM_DELAY_SET_TRST 0x10 | |||||
#define AICE_CUSTOM_DELAY_CLEAN_TRST 0x20 | |||||
struct aice_usb_handler_s { | |||||
unsigned int usb_read_ep; | |||||
unsigned int usb_write_ep; | |||||
struct jtag_libusb_device_handle *usb_handle; | |||||
}; | |||||
extern struct aice_port_api_s aice_usb_api; | |||||
int aice_read_ctrl(uint32_t address, uint32_t *data); | |||||
int aice_write_ctrl(uint32_t address, uint32_t data); | |||||
#endif |
@@ -116,6 +116,9 @@ extern struct jtag_interface opendous_interface; | |||||
#if BUILD_SYSFSGPIO == 1 | #if BUILD_SYSFSGPIO == 1 | ||||
extern struct jtag_interface sysfsgpio_interface; | extern struct jtag_interface sysfsgpio_interface; | ||||
#endif | #endif | ||||
#if BUILD_AICE == 1 | |||||
extern struct jtag_interface aice_interface; | |||||
#endif | |||||
#endif /* standard drivers */ | #endif /* standard drivers */ | ||||
/** | /** | ||||
@@ -200,6 +203,9 @@ struct jtag_interface *jtag_interfaces[] = { | |||||
#if BUILD_SYSFSGPIO == 1 | #if BUILD_SYSFSGPIO == 1 | ||||
&sysfsgpio_interface, | &sysfsgpio_interface, | ||||
#endif | #endif | ||||
#if BUILD_AICE == 1 | |||||
&aice_interface, | |||||
#endif | |||||
#endif /* standard drivers */ | #endif /* standard drivers */ | ||||
NULL, | NULL, | ||||
}; | }; | ||||
@@ -31,6 +31,7 @@ libtarget_la_SOURCES = \ | |||||
$(ARM_MISC_SRC) \ | $(ARM_MISC_SRC) \ | ||||
$(AVR32_SRC) \ | $(AVR32_SRC) \ | ||||
$(MIPS32_SRC) \ | $(MIPS32_SRC) \ | ||||
$(NDS32_SRC) \ | |||||
avrt.c \ | avrt.c \ | ||||
dsp563xx.c \ | dsp563xx.c \ | ||||
dsp563xx_once.c \ | dsp563xx_once.c \ | ||||
@@ -107,6 +108,9 @@ MIPS32_SRC = \ | |||||
mips32_dmaacc.c \ | mips32_dmaacc.c \ | ||||
mips_ejtag.c | mips_ejtag.c | ||||
NDS32_SRC = \ | |||||
nds32_reg.c | |||||
noinst_HEADERS = \ | noinst_HEADERS = \ | ||||
algorithm.h \ | algorithm.h \ | ||||
@@ -162,7 +166,11 @@ noinst_HEADERS = \ | |||||
avr32_ap7k.h \ | avr32_ap7k.h \ | ||||
avr32_jtag.h \ | avr32_jtag.h \ | ||||
avr32_mem.h \ | avr32_mem.h \ | ||||
avr32_regs.h | |||||
avr32_regs.h \ | |||||
nds32.h \ | |||||
nds32_edm.h \ | |||||
nds32_insn.h \ | |||||
nds32_reg.h | |||||
ocddatadir = $(pkglibdir) | ocddatadir = $(pkglibdir) | ||||
nobase_dist_ocddata_DATA = | nobase_dist_ocddata_DATA = | ||||
@@ -0,0 +1,432 @@ | |||||
/*************************************************************************** | |||||
* Copyright (C) 2013 by Andes Technology * | |||||
* Hsiangkai Wang <hkwang@andestech.com> * | |||||
* * | |||||
* 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, write to the * | |||||
* Free Software Foundation, Inc., * | |||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * | |||||
***************************************************************************/ | |||||
#ifndef __NDS32_H__ | |||||
#define __NDS32_H__ | |||||
#include <jtag/jtag.h> | |||||
#include <jtag/aice/aice_port.h> | |||||
#include "target.h" | |||||
#include "target_type.h" | |||||
#include "register.h" | |||||
#include "breakpoints.h" | |||||
#include "nds32_reg.h" | |||||
#include "nds32_insn.h" | |||||
#include "nds32_edm.h" | |||||
#define CHECK_RETVAL(action) \ | |||||
do { \ | |||||
int __retval = (action); \ | |||||
if (__retval != ERROR_OK) { \ | |||||
LOG_DEBUG("error while calling \"%s\"", \ | |||||
# action); \ | |||||
return __retval; \ | |||||
} \ | |||||
} while (0) | |||||
/** | |||||
* @file | |||||
* Holds the interface to Andes cores. | |||||
*/ | |||||
extern const char *nds32_debug_type_name[11]; | |||||
enum nds32_debug_reason { | |||||
NDS32_DEBUG_BREAK = 0, | |||||
NDS32_DEBUG_BREAK_16, | |||||
NDS32_DEBUG_INST_BREAK, | |||||
NDS32_DEBUG_DATA_ADDR_WATCHPOINT_PRECISE, | |||||
NDS32_DEBUG_DATA_VALUE_WATCHPOINT_PRECISE, | |||||
NDS32_DEBUG_DATA_VALUE_WATCHPOINT_IMPRECISE, | |||||
NDS32_DEBUG_DEBUG_INTERRUPT, | |||||
NDS32_DEBUG_HARDWARE_SINGLE_STEP, | |||||
NDS32_DEBUG_DATA_ADDR_WATCHPOINT_NEXT_PRECISE, | |||||
NDS32_DEBUG_DATA_VALUE_WATCHPOINT_NEXT_PRECISE, | |||||
NDS32_DEBUG_LOAD_STORE_GLOBAL_STOP, | |||||
}; | |||||
enum nds32_tdesc_type { | |||||
NDS32_CORE_TDESC = 0, | |||||
NDS32_SYSTEM_TDESC, | |||||
NDS32_AUDIO_TDESC, | |||||
NDS32_FPU_TDESC, | |||||
NDS32_NUM_TDESC, | |||||
}; | |||||
#define NDS32_STRUCT_STAT_SIZE 60 | |||||
#define NDS32_STRUCT_TIMEVAL_SIZE 8 | |||||
enum nds32_syscall_id { | |||||
NDS32_SYSCALL_EXIT = 1, | |||||
NDS32_SYSCALL_OPEN = 2, | |||||
NDS32_SYSCALL_CLOSE = 3, | |||||
NDS32_SYSCALL_READ = 4, | |||||
NDS32_SYSCALL_WRITE = 5, | |||||
NDS32_SYSCALL_LSEEK = 6, | |||||
NDS32_SYSCALL_UNLINK = 7, | |||||
NDS32_SYSCALL_RENAME = 3001, | |||||
NDS32_SYSCALL_FSTAT = 10, | |||||
NDS32_SYSCALL_STAT = 15, | |||||
NDS32_SYSCALL_GETTIMEOFDAY = 19, | |||||
NDS32_SYSCALL_ISATTY = 3002, | |||||
NDS32_SYSCALL_SYSTEM = 3003, | |||||
NDS32_SYSCALL_ERRNO = 6001, | |||||
}; | |||||
#define NDS32_COMMON_MAGIC (int)0xADE5ADE5 | |||||
struct nds32_edm { | |||||
/** EDM_CFG.VER, indicate the EDM version */ | |||||
int version; | |||||
/** The number of hardware breakpoints */ | |||||
int breakpoint_num; | |||||
/** EDM_CFG.DALM, indicate if direct local memory access feature is supported or not */ | |||||
bool direct_access_local_memory; | |||||
/** Support ACC_CTL register */ | |||||
bool access_control; | |||||
/** */ | |||||
bool support_max_stop; | |||||
}; | |||||
struct nds32_cache { | |||||
/** enable cache or not */ | |||||
bool enable; | |||||
/** cache sets per way */ | |||||
int set; | |||||
/** cache ways */ | |||||
int way; | |||||
/** cache line size */ | |||||
int line_size; | |||||
/** cache locking support */ | |||||
bool lock_support; | |||||
}; | |||||
struct nds32_memory { | |||||
/** ICache */ | |||||
struct nds32_cache icache; | |||||
/** DCache */ | |||||
struct nds32_cache dcache; | |||||
/** On-chip instruction local memory base */ | |||||
int ilm_base; | |||||
/** On-chip instruction local memory size */ | |||||
int ilm_size; | |||||
/** ILM base register alignment version */ | |||||
int ilm_align_ver; | |||||
/** DLM is enabled or not */ | |||||
bool ilm_enable; | |||||
/** DLM start address */ | |||||
int ilm_start; | |||||
/** DLM end address */ | |||||
int ilm_end; | |||||
/** On-chip data local memory base */ | |||||
int dlm_base; | |||||
/** On-chip data local memory size */ | |||||
int dlm_size; | |||||
/** DLM base register alignment version */ | |||||
int dlm_align_ver; | |||||
/** DLM is enabled or not */ | |||||
bool dlm_enable; | |||||
/** DLM start address */ | |||||
int dlm_start; | |||||
/** DLM end address */ | |||||
int dlm_end; | |||||
/** Memory access method */ | |||||
enum aice_memory_access access_channel; | |||||
/** Memory access mode */ | |||||
enum aice_memory_mode mode; | |||||
/** Address translation */ | |||||
bool address_translation; | |||||
}; | |||||
struct nds32_cpu_version { | |||||
bool performance_extension; | |||||
bool _16bit_extension; | |||||
bool performance_extension_2; | |||||
bool cop_fpu_extension; | |||||
bool string_extension; | |||||
int revision; | |||||
int cpu_id_family; | |||||
int cpu_id_version; | |||||
}; | |||||
struct nds32_mmu_config { | |||||
int memory_protection; | |||||
int memory_protection_version; | |||||
bool fully_associative_tlb; | |||||
int tlb_size; | |||||
int tlb_ways; | |||||
int tlb_sets; | |||||
bool _8k_page_support; | |||||
int extra_page_size_support; | |||||
bool tlb_lock; | |||||
bool hardware_page_table_walker; | |||||
bool default_endian; | |||||
int partition_num; | |||||
bool invisible_tlb; | |||||
bool vlpt; | |||||
bool ntme; | |||||
bool drde; | |||||
int default_min_page_size; | |||||
bool multiple_page_size_in_use; | |||||
}; | |||||
struct nds32_misc_config { | |||||
bool edm; | |||||
bool local_memory_dma; | |||||
bool performance_monitor; | |||||
bool high_speed_memory_port; | |||||
bool debug_tracer; | |||||
bool div_instruction; | |||||
bool mac_instruction; | |||||
int audio_isa; | |||||
bool L2_cache; | |||||
bool reduce_register; | |||||
bool addr_24; | |||||
bool interruption_level; | |||||
int baseline_instruction; | |||||
bool no_dx_register; | |||||
bool implement_dependant_register; | |||||
bool implement_dependant_sr_encoding; | |||||
bool ifc; | |||||
bool mcu; | |||||
bool ex9; | |||||
int shadow; | |||||
}; | |||||
/** | |||||
* Represents a generic Andes core. | |||||
*/ | |||||
struct nds32 { | |||||
int common_magic; | |||||
struct reg_cache *core_cache; | |||||
/** Handle for the debug module. */ | |||||
struct nds32_edm edm; | |||||
/** Memory information */ | |||||
struct nds32_memory memory; | |||||
/** cpu version */ | |||||
struct nds32_cpu_version cpu_version; | |||||
/** MMU configuration */ | |||||
struct nds32_mmu_config mmu_config; | |||||
/** Misc configuration */ | |||||
struct nds32_misc_config misc_config; | |||||
/** Retrieve all core registers, for display. */ | |||||
int (*full_context)(struct nds32 *nds32); | |||||
/** Register mappings */ | |||||
int (*register_map)(struct nds32 *nds32, int reg_no); | |||||
/** Get debug exception virtual address */ | |||||
int (*get_debug_reason)(struct nds32 *nds32, uint32_t *reason); | |||||
/** Restore target registers may be modified in debug state */ | |||||
int (*leave_debug_state)(struct nds32 *nds32, bool enable_watchpoint); | |||||
/** Backup target registers may be modified in debug state */ | |||||
int (*enter_debug_state)(struct nds32 *nds32, bool enable_watchpoint); | |||||
/** Get address hitted watchpoint */ | |||||
int (*get_watched_address)(struct nds32 *nds32, uint32_t *address, uint32_t reason); | |||||
/** maximum interrupt level */ | |||||
uint32_t max_interrupt_level; | |||||
/** current interrupt level */ | |||||
uint32_t current_interrupt_level; | |||||
uint32_t watched_address; | |||||
/** Flag reporting whether virtual hosting is active. */ | |||||
bool virtual_hosting; | |||||
/** Flag reporting whether continue/step hits syscall or not */ | |||||
bool hit_syscall; | |||||
/** Value to be returned by virtual hosting SYS_ERRNO request. */ | |||||
int virtual_hosting_errno; | |||||
/** Flag reporting whether syscall is aborted */ | |||||
bool virtual_hosting_ctrl_c; | |||||
/** Record syscall ID for other operations to do special processing for target */ | |||||
int active_syscall_id; | |||||
/** Flag reporting whether global stop is active. */ | |||||
bool global_stop; | |||||
/** reset-halt as target examine */ | |||||
bool reset_halt_as_examine; | |||||
/** Period to wait after SRST. */ | |||||
uint32_t boot_time; | |||||
/** Flag to indicate HSS steps into ISR or not */ | |||||
bool step_isr_enable; | |||||
/** Flag to indicate register table is ready or not */ | |||||
bool init_arch_info_after_halted; | |||||
/** Flag to indicate audio-extension is enabled or not */ | |||||
bool audio_enable; | |||||
/** Flag to indicate fpu-extension is enabled or not */ | |||||
bool fpu_enable; | |||||
/** Flag to indicate if auto convert software breakpoints to | |||||
* hardware breakpoints or not in ROM */ | |||||
bool auto_convert_hw_bp; | |||||
int (*setup_virtual_hosting)(struct target *target, int enable); | |||||
/** Backpointer to the target. */ | |||||
struct target *target; | |||||
void *arch_info; | |||||
}; | |||||
struct nds32_reg { | |||||
uint32_t num; | |||||
uint32_t value; | |||||
uint64_t value_64; | |||||
struct target *target; | |||||
struct nds32 *nds32; | |||||
bool enable; | |||||
}; | |||||
extern int nds32_config(struct nds32 *nds32); | |||||
extern int nds32_init_arch_info(struct target *target, struct nds32 *nds32); | |||||
extern int nds32_full_context(struct nds32 *nds32); | |||||
extern int nds32_arch_state(struct target *target); | |||||
extern int nds32_add_software_breakpoint(struct target *target, | |||||
struct breakpoint *breakpoint); | |||||
extern int nds32_remove_software_breakpoint(struct target *target, | |||||
struct breakpoint *breakpoint); | |||||
extern int nds32_get_gdb_general_reg_list(struct target *target, | |||||
struct reg **reg_list[], int *reg_list_size); | |||||
extern int nds32_get_gdb_reg_list(struct target *target, | |||||
struct reg **reg_list[], int *reg_list_size); | |||||
extern int nds32_get_gdb_target_description(struct target *target, char **xml, | |||||
char *annex, int32_t offset, uint32_t length); | |||||
extern int nds32_write_buffer(struct target *target, uint32_t address, | |||||
uint32_t size, const uint8_t *buffer); | |||||
extern int nds32_read_buffer(struct target *target, uint32_t address, | |||||
uint32_t size, uint8_t *buffer); | |||||
extern int nds32_bulk_write_memory(struct target *target, | |||||
uint32_t address, uint32_t count, const uint8_t *buffer); | |||||
extern int nds32_read_memory(struct target *target, uint32_t address, | |||||
uint32_t size, uint32_t count, uint8_t *buffer); | |||||
extern int nds32_write_memory(struct target *target, uint32_t address, | |||||
uint32_t size, uint32_t count, const uint8_t *buffer); | |||||
extern int nds32_init_register_table(struct nds32 *nds32); | |||||
extern int nds32_init_memory_info(struct nds32 *nds32); | |||||
extern int nds32_restore_context(struct target *target); | |||||
extern int nds32_get_mapped_reg(struct nds32 *nds32, unsigned regnum, uint32_t *value); | |||||
extern int nds32_set_mapped_reg(struct nds32 *nds32, unsigned regnum, uint32_t value); | |||||
extern int nds32_edm_config(struct nds32 *nds32); | |||||
extern int nds32_check_extension(struct nds32 *nds32); | |||||
extern int nds32_cache_sync(struct target *target, uint32_t address, uint32_t length); | |||||
extern int nds32_mmu(struct target *target, int *enabled); | |||||
extern int nds32_virtual_to_physical(struct target *target, uint32_t address, uint32_t *physical); | |||||
extern int nds32_read_phys_memory(struct target *target, uint32_t address, | |||||
uint32_t size, uint32_t count, uint8_t *buffer); | |||||
extern int nds32_write_phys_memory(struct target *target, uint32_t address, | |||||
uint32_t size, uint32_t count, const uint8_t *buffer); | |||||
extern int nds32_soft_reset_halt(struct target *target); | |||||
extern uint32_t nds32_nextpc(struct nds32 *nds32, int current, uint32_t address); | |||||
extern int nds32_examine_debug_reason(struct nds32 *nds32); | |||||
extern int nds32_step(struct target *target, int current, | |||||
uint32_t address, int handle_breakpoints); | |||||
extern int nds32_target_state(struct nds32 *nds32, enum target_state *state); | |||||
extern int nds32_halt(struct target *target); | |||||
extern int nds32_poll(struct target *target); | |||||
extern int nds32_resume(struct target *target, int current, | |||||
uint32_t address, int handle_breakpoints, int debug_execution); | |||||
extern int nds32_assert_reset(struct target *target); | |||||
extern int nds32_init(struct nds32 *nds32); | |||||
extern int nds32_get_gdb_fileio_info(struct target *target, struct gdb_fileio_info *fileio_info); | |||||
extern int nds32_gdb_fileio_write_memory(struct nds32 *nds32, uint32_t address, | |||||
uint32_t size, const uint8_t *buffer); | |||||
extern int nds32_gdb_fileio_end(struct target *target, int retcode, int fileio_errno, bool ctrl_c); | |||||
extern int nds32_reset_halt(struct nds32 *nds32); | |||||
/** Convert target handle to generic Andes target state handle. */ | |||||
static inline struct nds32 *target_to_nds32(struct target *target) | |||||
{ | |||||
assert(target != NULL); | |||||
return target->arch_info; | |||||
} | |||||
/** */ | |||||
static inline struct aice_port_s *target_to_aice(struct target *target) | |||||
{ | |||||
assert(target != NULL); | |||||
return target->tap->priv; | |||||
} | |||||
static inline bool is_nds32(struct nds32 *nds32) | |||||
{ | |||||
assert(nds32 != NULL); | |||||
return nds32->common_magic == NDS32_COMMON_MAGIC; | |||||
} | |||||
static inline bool nds32_reach_max_interrupt_level(struct nds32 *nds32) | |||||
{ | |||||
assert(nds32 != NULL); | |||||
return nds32->max_interrupt_level == nds32->current_interrupt_level; | |||||
} | |||||
#endif /* __NDS32_H__ */ |
@@ -0,0 +1,116 @@ | |||||
/*************************************************************************** | |||||
* Copyright (C) 2013 by Andes Technology * | |||||
* Hsiangkai Wang <hkwang@andestech.com> * | |||||
* * | |||||
* 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, write to the * | |||||
* Free Software Foundation, Inc., * | |||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * | |||||
***************************************************************************/ | |||||
#ifndef __NDS32_EDM_H__ | |||||
#define __NDS32_EDM_H__ | |||||
/** | |||||
* @file | |||||
* This is the interface to the Embedded Debug Module for Andes cores. | |||||
*/ | |||||
/* EDM misc registers */ | |||||
enum nds_edm_misc_reg { | |||||
NDS_EDM_MISC_DIMIR = 0x0, | |||||
NDS_EDM_MISC_SBAR, | |||||
NDS_EDM_MISC_EDM_CMDR, | |||||
NDS_EDM_MISC_DBGER, | |||||
NDS_EDM_MISC_ACC_CTL, | |||||
NDS_EDM_MISC_EDM_PROBE, | |||||
NDS_EDM_MISC_GEN_PORT0, | |||||
NDS_EDM_MISC_GEN_PORT1, | |||||
}; | |||||
/* EDM system registers */ | |||||
enum nds_edm_system_reg { | |||||
NDS_EDM_SR_BPC0 = 0x00, | |||||
NDS_EDM_SR_BPC1, | |||||
NDS_EDM_SR_BPC2, | |||||
NDS_EDM_SR_BPC3, | |||||
NDS_EDM_SR_BPC4, | |||||
NDS_EDM_SR_BPC5, | |||||
NDS_EDM_SR_BPC6, | |||||
NDS_EDM_SR_BPC7, | |||||
NDS_EDM_SR_BPA0 = 0x08, | |||||
NDS_EDM_SR_BPA1, | |||||
NDS_EDM_SR_BPA2, | |||||
NDS_EDM_SR_BPA3, | |||||
NDS_EDM_SR_BPA4, | |||||
NDS_EDM_SR_BPA5, | |||||
NDS_EDM_SR_BPA6, | |||||
NDS_EDM_SR_BPA7, | |||||
NDS_EDM_SR_BPAM0 = 0x10, | |||||
NDS_EDM_SR_BPAM1, | |||||
NDS_EDM_SR_BPAM2, | |||||
NDS_EDM_SR_BPAM3, | |||||
NDS_EDM_SR_BPAM4, | |||||
NDS_EDM_SR_BPAM5, | |||||
NDS_EDM_SR_BPAM6, | |||||
NDS_EDM_SR_BPAM7, | |||||
NDS_EDM_SR_BPV0 = 0x18, | |||||
NDS_EDM_SR_BPV1, | |||||
NDS_EDM_SR_BPV2, | |||||
NDS_EDM_SR_BPV3, | |||||
NDS_EDM_SR_BPV4, | |||||
NDS_EDM_SR_BPV5, | |||||
NDS_EDM_SR_BPV6, | |||||
NDS_EDM_SR_BPV7, | |||||
NDS_EDM_SR_BPCID0 = 0x20, | |||||
NDS_EDM_SR_BPCID1, | |||||
NDS_EDM_SR_BPCID2, | |||||
NDS_EDM_SR_BPCID3, | |||||
NDS_EDM_SR_BPCID4, | |||||
NDS_EDM_SR_BPCID5, | |||||
NDS_EDM_SR_BPCID6, | |||||
NDS_EDM_SR_BPCID7, | |||||
NDS_EDM_SR_EDM_CFG = 0x28, | |||||
NDS_EDM_SR_EDMSW = 0x30, | |||||
NDS_EDM_SR_EDM_CTL = 0x38, | |||||
NDS_EDM_SR_EDM_DTR = 0x40, | |||||
NDS_EDM_SR_BPMTV = 0x48, | |||||
NDS_EDM_SR_DIMBR = 0x50, | |||||
NDS_EDM_SR_TECR0 = 0x70, | |||||
NDS_EDM_SR_TECR1 = 0x71, | |||||
}; | |||||
enum nds_memory_access { | |||||
NDS_MEMORY_ACC_BUS = 0, | |||||
NDS_MEMORY_ACC_CPU, | |||||
}; | |||||
enum nds_memory_select { | |||||
NDS_MEMORY_SELECT_AUTO = 0, | |||||
NDS_MEMORY_SELECT_MEM = 1, | |||||
NDS_MEMORY_SELECT_ILM = 2, | |||||
NDS_MEMORY_SELECT_DLM = 3, | |||||
}; | |||||
#define NDS_DBGER_DEX (0x1) | |||||
#define NDS_DBGER_DPED (0x2) | |||||
#define NDS_DBGER_CRST (0x4) | |||||
#define NDS_DBGER_AT_MAX (0x8) | |||||
#define NDS_DBGER_ILL_SEC_ACC (0x10) | |||||
#define NDS_DBGER_ALL_SUPRS_EX (0x40000000) | |||||
#define NDS_DBGER_RESACC (0x80000000) | |||||
#define NDS_DBGER_CLEAR_ALL (0x1F) | |||||
#define NDS_EDMSW_WDV (1 << 0) | |||||
#define NDS_EDMSW_RDV (1 << 1) | |||||
#endif /* __NDS32_EDM_H__ */ |
@@ -0,0 +1,81 @@ | |||||
/*************************************************************************** | |||||
* Copyright (C) 2013 by Andes Technology * | |||||
* Hsiangkai Wang <hkwang@andestech.com> * | |||||
* * | |||||
* 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, write to the * | |||||
* Free Software Foundation, Inc., * | |||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * | |||||
***************************************************************************/ | |||||
#ifndef __NDS32_INSN_H__ | |||||
#define __NDS32_INSN_H__ | |||||
#define NOP (0x40000009) | |||||
#define DSB (0x64000008) | |||||
#define ISB (0x64000009) | |||||
#define BEQ_MINUS_12 (0x4C000000 | 0x3FFA) | |||||
#define MTSR_DTR(a) (0x64000003 | (((0x03 << 7) | (0x08 << 3) | (0x00 << 0)) << 10) | (((a) & 0x1F) << 20)) | |||||
#define MFSR_DTR(a) (0x64000002 | (((0x03 << 7) | (0x08 << 3) | (0x00 << 0)) << 10) | (((a) & 0x1F) << 20)) | |||||
#define SETHI(a, b) (0x46000000 | ((a) << 20) | (b)) | |||||
#define ORI(a, b, c) (0x58000000 | ((a) << 20) | ((b) << 15) | (c)) | |||||
#define LWI_BI(a, b) (0x0C000001 | (a << 20) | (b << 15)) | |||||
#define LHI_BI(a, b) (0x0A000001 | (a << 20) | (b << 15)) | |||||
#define LBI_BI(a, b) (0x08000001 | (a << 20) | (b << 15)) | |||||
#define SWI_BI(a, b) (0x1C000001 | (a << 20) | (b << 15)) | |||||
#define SHI_BI(a, b) (0x1A000001 | (a << 20) | (b << 15)) | |||||
#define SBI_BI(a, b) (0x18000001 | (a << 20) | (b << 15)) | |||||
#define IRET (0x64000004) | |||||
#define L1D_IX_WB(a) (0x64000021 | ((a) << 15)) | |||||
#define L1D_IX_INVAL(a) (0x64000001 | ((a) << 15)) | |||||
#define L1D_VA_INVAL(a) (0x64000101 | ((a) << 15)) | |||||
#define L1D_VA_WB(a) (0x64000121 | ((a) << 15)) | |||||
#define L1D_IX_RTAG(a) (0x64000061 | ((a) << 15)) | |||||
#define L1D_IX_RWD(a) (0x64000081 | ((a) << 15)) | |||||
#define L1I_IX_INVAL(a) (0x64000201 | ((a) << 15)) | |||||
#define L1I_VA_INVAL(a) (0x64000301 | ((a) << 15)) | |||||
#define L1I_IX_RTAG(a) (0x64000261 | ((a) << 15)) | |||||
#define L1I_IX_RWD(a) (0x64000281 | ((a) << 15)) | |||||
#define L1I_VA_FILLCK(a) (0x64000361 | ((a) << 15)) | |||||
#define ISYNC(a) (0x6400000d | ((a) << 20)) | |||||
#define MSYNC_STORE (0x6400002c) | |||||
#define MSYNC_ALL (0x6400000c) | |||||
#define TLBOP_TARGET_READ(a) (0x6400000e | ((a) << 15)) | |||||
#define TLBOP_TARGET_PROBE(a, b) (0x640000AE | ((a) << 20) | ((b) << 15)) | |||||
#define MFCPD(a, b, c) (0x6A000041 | (a << 20) | (b << 8) | (c << 4)) | |||||
#define MFCPW(a, b, c) (0x6A000001 | (a << 20) | (b << 8) | (c << 4)) | |||||
#define MTCPD(a, b, c) (0x6A000049 | (a << 20) | (b << 8) | (c << 4)) | |||||
#define MTCPW(a, b, c) (0x6A000009 | (a << 20) | (b << 8) | (c << 4)) | |||||
#define MOVI_(a, b) (0x44000000 | (a << 20) | (b & 0xFFFFF)) | |||||
#define MFUSR_G0(a, b) (0x42000020 | (a << 20) | (b << 15)) | |||||
#define MTUSR_G0(a, b) (0x42000021 | (a << 20) | (b << 15)) | |||||
#define MFSR(a, b) (0x64000002 | (b << 10) | (a << 20)) | |||||
#define MTSR(a, b) (0x64000003 | (b << 10) | (a << 20)) | |||||
#define AMFAR(a, b) (0x60300060 | (a << 15) | b) | |||||
#define AMTAR(a, b) (0x60300040 | (a << 15) | b) | |||||
#define AMFAR2(a, b) (0x60300260 | (a << 15) | b) | |||||
#define AMTAR2(a, b) (0x60300240 | (a << 15) | b) | |||||
#define FMFCSR (0x6A000701) | |||||
#define FMTCSR (0x6A000709) | |||||
#define FMFCFG (0x6A000301) | |||||
#define FMFSR(a, b) (0x6A000001 | ((a) << 20) | ((b) << 15)) | |||||
#define FMTSR(a, b) (0x6A000009 | ((a) << 20) | ((b) << 15)) | |||||
#define FMFDR(a, b) (0x6A000041 | ((a) << 20) | ((b) << 15)) | |||||
#define FMTDR(a, b) (0x6A000049 | ((a) << 20) | ((b) << 15)) | |||||
/* break instructions */ | |||||
extern const int NDS32_BREAK_16; | |||||
extern const int NDS32_BREAK_32; | |||||
#endif /* __NDS32_INSN_H__ */ |
@@ -0,0 +1,337 @@ | |||||
/*************************************************************************** | |||||
* Copyright (C) 2013 by Andes Technology * | |||||
* Hsiangkai Wang <hkwang@andestech.com> * | |||||
* * | |||||
* 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, write to the * | |||||
* Free Software Foundation, Inc., * | |||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * | |||||
***************************************************************************/ | |||||
#ifdef HAVE_CONFIG_H | |||||
#include "config.h" | |||||
#endif | |||||
#include "nds32_reg.h" | |||||
static bool nds32_reg_init_done; | |||||
static struct nds32_reg_s nds32_regs[TOTAL_REG_NUM]; | |||||
static inline void nds32_reg_set(uint32_t number, const char *simple_mnemonic, | |||||
const char *symbolic_mnemonic, uint32_t sr_index, | |||||
enum nds32_reg_type_s type, uint8_t size) | |||||
{ | |||||
nds32_regs[number].simple_mnemonic = simple_mnemonic; | |||||
nds32_regs[number].symbolic_mnemonic = symbolic_mnemonic; | |||||
nds32_regs[number].sr_index = sr_index; | |||||
nds32_regs[number].type = type; | |||||
nds32_regs[number].size = size; | |||||
} | |||||
void nds32_reg_init(void) | |||||
{ | |||||
if (nds32_reg_init_done == true) | |||||
return; | |||||
nds32_reg_set(R0, "r0", "r0", 0, NDS32_REG_TYPE_GPR, 32); | |||||
nds32_reg_set(R1, "r1", "r1", 0, NDS32_REG_TYPE_GPR, 32); | |||||
nds32_reg_set(R2, "r2", "r2", 0, NDS32_REG_TYPE_GPR, 32); | |||||
nds32_reg_set(R3, "r3", "r3", 0, NDS32_REG_TYPE_GPR, 32); | |||||
nds32_reg_set(R4, "r4", "r4", 0, NDS32_REG_TYPE_GPR, 32); | |||||
nds32_reg_set(R5, "r5", "r5", 0, NDS32_REG_TYPE_GPR, 32); | |||||
nds32_reg_set(R6, "r6", "r6", 0, NDS32_REG_TYPE_GPR, 32); | |||||
nds32_reg_set(R7, "r7", "r7", 0, NDS32_REG_TYPE_GPR, 32); | |||||
nds32_reg_set(R8, "r8", "r8", 0, NDS32_REG_TYPE_GPR, 32); | |||||
nds32_reg_set(R9, "r9", "r9", 0, NDS32_REG_TYPE_GPR, 32); | |||||
nds32_reg_set(R10, "r10", "r10", 0, NDS32_REG_TYPE_GPR, 32); | |||||
nds32_reg_set(R11, "r11", "r11", 0, NDS32_REG_TYPE_GPR, 32); | |||||
nds32_reg_set(R12, "r12", "r12", 0, NDS32_REG_TYPE_GPR, 32); | |||||
nds32_reg_set(R13, "r13", "r13", 0, NDS32_REG_TYPE_GPR, 32); | |||||
nds32_reg_set(R14, "r14", "r14", 0, NDS32_REG_TYPE_GPR, 32); | |||||
nds32_reg_set(R15, "r15", "r15", 0, NDS32_REG_TYPE_GPR, 32); | |||||
nds32_reg_set(R16, "r16", "r16", 0, NDS32_REG_TYPE_GPR, 32); | |||||
nds32_reg_set(R17, "r17", "r17", 0, NDS32_REG_TYPE_GPR, 32); | |||||
nds32_reg_set(R18, "r18", "r18", 0, NDS32_REG_TYPE_GPR, 32); | |||||
nds32_reg_set(R19, "r19", "r19", 0, NDS32_REG_TYPE_GPR, 32); | |||||
nds32_reg_set(R20, "r20", "r20", 0, NDS32_REG_TYPE_GPR, 32); | |||||
nds32_reg_set(R21, "r21", "r21", 0, NDS32_REG_TYPE_GPR, 32); | |||||
nds32_reg_set(R22, "r22", "r22", 0, NDS32_REG_TYPE_GPR, 32); | |||||
nds32_reg_set(R23, "r23", "r23", 0, NDS32_REG_TYPE_GPR, 32); | |||||
nds32_reg_set(R24, "r24", "r24", 0, NDS32_REG_TYPE_GPR, 32); | |||||
nds32_reg_set(R25, "r25", "r25", 0, NDS32_REG_TYPE_GPR, 32); | |||||
nds32_reg_set(R26, "r26", "p0", 0, NDS32_REG_TYPE_GPR, 32); | |||||
nds32_reg_set(R27, "r27", "p1", 0, NDS32_REG_TYPE_GPR, 32); | |||||
nds32_reg_set(R28, "fp", "fp", 0, NDS32_REG_TYPE_GPR, 32); | |||||
nds32_reg_set(R29, "gp", "gp", 0, NDS32_REG_TYPE_GPR, 32); | |||||
nds32_reg_set(R30, "lp", "lp", 0, NDS32_REG_TYPE_GPR, 32); | |||||
nds32_reg_set(R31, "sp", "sp", 0, NDS32_REG_TYPE_GPR, 32); | |||||
nds32_reg_set(PC, "pc", "pc", 31, NDS32_REG_TYPE_SPR, 32); | |||||
nds32_reg_set(D0LO, "d0lo", "d0lo", 0, NDS32_REG_TYPE_SPR, 32); | |||||
nds32_reg_set(D0HI, "d0hi", "d0hi", 1, NDS32_REG_TYPE_SPR, 32); | |||||
nds32_reg_set(D1LO, "d1lo", "d1lo", 2, NDS32_REG_TYPE_SPR, 32); | |||||
nds32_reg_set(D1HI, "d1hi", "d1hi", 3, NDS32_REG_TYPE_SPR, 32); | |||||
nds32_reg_set(ITB, "itb", "itb", 28, NDS32_REG_TYPE_SPR, 32); | |||||
nds32_reg_set(IFC_LP, "ifc_lp", "ifc_lp", 29, NDS32_REG_TYPE_SPR, 32); | |||||
nds32_reg_set(CR0, "cr0", "CPU_VER", SRIDX(0, 0, 0), NDS32_REG_TYPE_CR, 32); | |||||
nds32_reg_set(CR1, "cr1", "ICM_CFG", SRIDX(0, 1, 0), NDS32_REG_TYPE_CR, 32); | |||||
nds32_reg_set(CR2, "cr2", "DCM_CFG", SRIDX(0, 2, 0), NDS32_REG_TYPE_CR, 32); | |||||
nds32_reg_set(CR3, "cr3", "MMU_CFG", SRIDX(0, 3, 0), NDS32_REG_TYPE_CR, 32); | |||||
nds32_reg_set(CR4, "cr4", "MSC_CFG", SRIDX(0, 4, 0), NDS32_REG_TYPE_CR, 32); | |||||
nds32_reg_set(CR5, "cr5", "CORE_ID", SRIDX(0, 0, 1), NDS32_REG_TYPE_CR, 32); | |||||
nds32_reg_set(CR6, "cr6", "FUCOP_EXIST", SRIDX(0, 5, 0), NDS32_REG_TYPE_CR, 32); | |||||
nds32_reg_set(IR0, "ir0", "PSW", SRIDX(1, 0, 0), NDS32_REG_TYPE_IR, 32); | |||||
nds32_reg_set(IR1, "ir1", "IPSW", SRIDX(1, 0, 1), NDS32_REG_TYPE_IR, 32); | |||||
nds32_reg_set(IR2, "ir2", "P_IPSW", SRIDX(1, 0, 2), NDS32_REG_TYPE_IR, 32); | |||||
nds32_reg_set(IR3, "ir3", "IVB", SRIDX(1, 1, 1), NDS32_REG_TYPE_IR, 32); | |||||
nds32_reg_set(IR4, "ir4", "EVA", SRIDX(1, 2, 1), NDS32_REG_TYPE_IR, 32); | |||||
nds32_reg_set(IR5, "ir5", "P_EVA", SRIDX(1, 2, 2), NDS32_REG_TYPE_IR, 32); | |||||
nds32_reg_set(IR6, "ir6", "ITYPE", SRIDX(1, 3, 1), NDS32_REG_TYPE_IR, 32); | |||||
nds32_reg_set(IR7, "ir7", "P_ITYPE", SRIDX(1, 3, 2), NDS32_REG_TYPE_IR, 32); | |||||
nds32_reg_set(IR8, "ir8", "MERR", SRIDX(1, 4, 1), NDS32_REG_TYPE_IR, 32); | |||||
nds32_reg_set(IR9, "ir9", "IPC", SRIDX(1, 5, 1), NDS32_REG_TYPE_IR, 32); | |||||
nds32_reg_set(IR10, "ir10", "P_IPC", SRIDX(1, 5, 2), NDS32_REG_TYPE_IR, 32); | |||||
nds32_reg_set(IR11, "ir11", "OIPC", SRIDX(1, 5, 3), NDS32_REG_TYPE_IR, 32); | |||||
nds32_reg_set(IR12, "ir12", "P_P0", SRIDX(1, 6, 2), NDS32_REG_TYPE_IR, 32); | |||||
nds32_reg_set(IR13, "ir13", "P_P1", SRIDX(1, 7, 2), NDS32_REG_TYPE_IR, 32); | |||||
nds32_reg_set(IR14, "ir14", "INT_MASK", SRIDX(1, 8, 0), NDS32_REG_TYPE_IR, 32); | |||||
nds32_reg_set(IR15, "ir15", "INT_PEND", SRIDX(1, 9, 0), NDS32_REG_TYPE_IR, 32); | |||||
nds32_reg_set(IR16, "ir16", "", SRIDX(1, 10, 0), NDS32_REG_TYPE_IR, 32); | |||||
nds32_reg_set(IR17, "ir17", "", SRIDX(1, 10, 1), NDS32_REG_TYPE_IR, 32); | |||||
nds32_reg_set(IR18, "ir18", "", SRIDX(1, 11, 0), NDS32_REG_TYPE_IR, 32); | |||||
nds32_reg_set(IR19, "ir19", "", SRIDX(1, 1, 2), NDS32_REG_TYPE_IR, 32); | |||||
nds32_reg_set(IR20, "ir20", "", SRIDX(1, 10, 2), NDS32_REG_TYPE_IR, 32); | |||||
nds32_reg_set(IR21, "ir21", "", SRIDX(1, 10, 3), NDS32_REG_TYPE_IR, 32); | |||||
nds32_reg_set(IR22, "ir22", "", SRIDX(1, 10, 4), NDS32_REG_TYPE_IR, 32); | |||||
nds32_reg_set(IR23, "ir23", "", SRIDX(1, 10, 5), NDS32_REG_TYPE_IR, 32); | |||||
nds32_reg_set(IR24, "ir24", "", SRIDX(1, 10, 6), NDS32_REG_TYPE_IR, 32); | |||||
nds32_reg_set(IR25, "ir25", "", SRIDX(1, 10, 7), NDS32_REG_TYPE_IR, 32); | |||||
nds32_reg_set(MR0, "mr0", "MMU_CTL", SRIDX(2, 0, 0), NDS32_REG_TYPE_MR, 32); | |||||
nds32_reg_set(MR1, "mr1", "L1_PPTB", SRIDX(2, 1, 0), NDS32_REG_TYPE_MR, 32); | |||||
nds32_reg_set(MR2, "mr2", "TLB_VPN", SRIDX(2, 2, 0), NDS32_REG_TYPE_MR, 32); | |||||
nds32_reg_set(MR3, "mr3", "TLB_DATA", SRIDX(2, 3, 0), NDS32_REG_TYPE_MR, 32); | |||||
nds32_reg_set(MR4, "mr4", "TLB_MISC", SRIDX(2, 4, 0), NDS32_REG_TYPE_MR, 32); | |||||
nds32_reg_set(MR5, "mr5", "VLPT_IDX", SRIDX(2, 5, 0), NDS32_REG_TYPE_MR, 32); | |||||
nds32_reg_set(MR6, "mr6", "ILMB", SRIDX(2, 6, 0), NDS32_REG_TYPE_MR, 32); | |||||
nds32_reg_set(MR7, "mr7", "DLMB", SRIDX(2, 7, 0), NDS32_REG_TYPE_MR, 32); | |||||
nds32_reg_set(MR8, "mr8", "CACHE_CTL", SRIDX(2, 8, 0), NDS32_REG_TYPE_MR, 32); | |||||
nds32_reg_set(MR9, "mr9", "HSMP_SADDR", SRIDX(2, 9, 0), NDS32_REG_TYPE_MR, 32); | |||||
nds32_reg_set(MR10, "mr10", "HSMP_EADDR", SRIDX(2, 9, 1), NDS32_REG_TYPE_MR, 32); | |||||
nds32_reg_set(MR11, "mr11", "", SRIDX(2, 0, 1), NDS32_REG_TYPE_MR, 32); | |||||
nds32_reg_set(DR0, "dr0", "BPC0", SRIDX(3, 0, 0), NDS32_REG_TYPE_DR, 32); | |||||
nds32_reg_set(DR1, "dr1", "BPA0", SRIDX(3, 1, 0), NDS32_REG_TYPE_DR, 32); | |||||
nds32_reg_set(DR2, "dr2", "BPAM0", SRIDX(3, 2, 0), NDS32_REG_TYPE_DR, 32); | |||||
nds32_reg_set(DR3, "dr3", "BPV0", SRIDX(3, 3, 0), NDS32_REG_TYPE_DR, 32); | |||||
nds32_reg_set(DR4, "dr4", "BPCID0", SRIDX(3, 4, 0), NDS32_REG_TYPE_DR, 32); | |||||
nds32_reg_set(DR5, "dr5", "BPC1", SRIDX(3, 0, 1), NDS32_REG_TYPE_DR, 32); | |||||
nds32_reg_set(DR6, "dr6", "BPA1", SRIDX(3, 1, 1), NDS32_REG_TYPE_DR, 32); | |||||
nds32_reg_set(DR7, "dr7", "BPAM1", SRIDX(3, 2, 1), NDS32_REG_TYPE_DR, 32); | |||||
nds32_reg_set(DR8, "dr8", "BPV1", SRIDX(3, 3, 1), NDS32_REG_TYPE_DR, 32); | |||||
nds32_reg_set(DR9, "dr9", "BPCID1", SRIDX(3, 4, 1), NDS32_REG_TYPE_DR, 32); | |||||
nds32_reg_set(DR10, "dr10", "BPC2", SRIDX(3, 0, 2), NDS32_REG_TYPE_DR, 32); | |||||
nds32_reg_set(DR11, "dr11", "BPA2", SRIDX(3, 1, 2), NDS32_REG_TYPE_DR, 32); | |||||
nds32_reg_set(DR12, "dr12", "BPAM2", SRIDX(3, 2, 2), NDS32_REG_TYPE_DR, 32); | |||||
nds32_reg_set(DR13, "dr13", "BPV2", SRIDX(3, 3, 2), NDS32_REG_TYPE_DR, 32); | |||||
nds32_reg_set(DR14, "dr14", "BPCID2", SRIDX(3, 4, 2), NDS32_REG_TYPE_DR, 32); | |||||
nds32_reg_set(DR15, "dr15", "BPC3", SRIDX(3, 0, 3), NDS32_REG_TYPE_DR, 32); | |||||
nds32_reg_set(DR16, "dr16", "BPA3", SRIDX(3, 1, 3), NDS32_REG_TYPE_DR, 32); | |||||
nds32_reg_set(DR17, "dr17", "BPAM3", SRIDX(3, 2, 3), NDS32_REG_TYPE_DR, 32); | |||||
nds32_reg_set(DR18, "dr18", "BPV3", SRIDX(3, 3, 3), NDS32_REG_TYPE_DR, 32); | |||||
nds32_reg_set(DR19, "dr19", "BPCID3", SRIDX(3, 4, 3), NDS32_REG_TYPE_DR, 32); | |||||
nds32_reg_set(DR20, "dr20", "BPC4", SRIDX(3, 0, 4), NDS32_REG_TYPE_DR, 32); | |||||
nds32_reg_set(DR21, "dr21", "BPA4", SRIDX(3, 1, 4), NDS32_REG_TYPE_DR, 32); | |||||
nds32_reg_set(DR22, "dr22", "BPAM4", SRIDX(3, 2, 4), NDS32_REG_TYPE_DR, 32); | |||||
nds32_reg_set(DR23, "dr23", "BPV4", SRIDX(3, 3, 4), NDS32_REG_TYPE_DR, 32); | |||||
nds32_reg_set(DR24, "dr24", "BPCID4", SRIDX(3, 4, 4), NDS32_REG_TYPE_DR, 32); | |||||
nds32_reg_set(DR25, "dr25", "BPC5", SRIDX(3, 0, 5), NDS32_REG_TYPE_DR, 32); | |||||
nds32_reg_set(DR26, "dr26", "BPA5", SRIDX(3, 1, 5), NDS32_REG_TYPE_DR, 32); | |||||
nds32_reg_set(DR27, "dr27", "BPAM5", SRIDX(3, 2, 5), NDS32_REG_TYPE_DR, 32); | |||||
nds32_reg_set(DR28, "dr28", "BPV5", SRIDX(3, 3, 5), NDS32_REG_TYPE_DR, 32); | |||||
nds32_reg_set(DR29, "dr29", "BPCID5", SRIDX(3, 4, 5), NDS32_REG_TYPE_DR, 32); | |||||
nds32_reg_set(DR30, "dr30", "BPC6", SRIDX(3, 0, 6), NDS32_REG_TYPE_DR, 32); | |||||
nds32_reg_set(DR31, "dr31", "BPA6", SRIDX(3, 1, 6), NDS32_REG_TYPE_DR, 32); | |||||
nds32_reg_set(DR32, "dr32", "BPAM6", SRIDX(3, 2, 6), NDS32_REG_TYPE_DR, 32); | |||||
nds32_reg_set(DR33, "dr33", "BPV6", SRIDX(3, 3, 6), NDS32_REG_TYPE_DR, 32); | |||||
nds32_reg_set(DR34, "dr34", "BPCID6", SRIDX(3, 4, 6), NDS32_REG_TYPE_DR, 32); | |||||
nds32_reg_set(DR35, "dr35", "BPC7", SRIDX(3, 0, 7), NDS32_REG_TYPE_DR, 32); | |||||
nds32_reg_set(DR36, "dr36", "BPA7", SRIDX(3, 1, 7), NDS32_REG_TYPE_DR, 32); | |||||
nds32_reg_set(DR37, "dr37", "BPAM7", SRIDX(3, 2, 7), NDS32_REG_TYPE_DR, 32); | |||||
nds32_reg_set(DR38, "dr38", "BPV7", SRIDX(3, 3, 7), NDS32_REG_TYPE_DR, 32); | |||||
nds32_reg_set(DR39, "dr39", "BPCID7", SRIDX(3, 4, 7), NDS32_REG_TYPE_DR, 32); | |||||
nds32_reg_set(DR40, "dr40", "EDM_CFG", SRIDX(3, 5, 0), NDS32_REG_TYPE_DR, 32); | |||||
nds32_reg_set(DR41, "dr41", "EDMSW", SRIDX(3, 6, 0), NDS32_REG_TYPE_DR, 32); | |||||
nds32_reg_set(DR42, "dr42", "EDM_CTL", SRIDX(3, 7, 0), NDS32_REG_TYPE_DR, 32); | |||||
nds32_reg_set(DR43, "dr43", "EDM_DTR", SRIDX(3, 8, 0), NDS32_REG_TYPE_DR, 32); | |||||
nds32_reg_set(DR44, "dr44", "BPMTC", SRIDX(3, 9, 0), NDS32_REG_TYPE_DR, 32); | |||||
nds32_reg_set(DR45, "dr45", "DIMBR", SRIDX(3, 10, 0), NDS32_REG_TYPE_DR, 32); | |||||
nds32_reg_set(DR46, "dr46", "TECR0", SRIDX(3, 14, 0), NDS32_REG_TYPE_DR, 32); | |||||
nds32_reg_set(DR47, "dr47", "TECR1", SRIDX(3, 14, 1), NDS32_REG_TYPE_DR, 32); | |||||
nds32_reg_set(DR48, "dr48", "", SRIDX(3, 11, 0), NDS32_REG_TYPE_DR, 32); | |||||
nds32_reg_set(PFR0, "pfr0", "PFMC0", SRIDX(4, 0, 0), NDS32_REG_TYPE_PFR, 32); | |||||
nds32_reg_set(PFR1, "pfr1", "PFMC1", SRIDX(4, 0, 1), NDS32_REG_TYPE_PFR, 32); | |||||
nds32_reg_set(PFR2, "pfr2", "PFMC2", SRIDX(4, 0, 2), NDS32_REG_TYPE_PFR, 32); | |||||
nds32_reg_set(PFR3, "pfr3", "PFM_CTL", SRIDX(4, 1, 0), NDS32_REG_TYPE_PFR, 32); | |||||
nds32_reg_set(DMAR0, "dmar0", "DMA_CFG", SRIDX(5, 0, 0), NDS32_REG_TYPE_DMAR, 32); | |||||
nds32_reg_set(DMAR1, "dmar1", "DMA_GCSW", SRIDX(5, 1, 0), NDS32_REG_TYPE_DMAR, 32); | |||||
nds32_reg_set(DMAR2, "dmar2", "DMA_CHNSEL", SRIDX(5, 2, 0), NDS32_REG_TYPE_DMAR, 32); | |||||
nds32_reg_set(DMAR3, "dmar3", "DMA_ACT", SRIDX(5, 3, 0), NDS32_REG_TYPE_DMAR, 32); | |||||
nds32_reg_set(DMAR4, "dmar4", "DMA_SETUP", SRIDX(5, 4, 0), NDS32_REG_TYPE_DMAR, 32); | |||||
nds32_reg_set(DMAR5, "dmar5", "DMA_ISADDR", SRIDX(5, 5, 0), NDS32_REG_TYPE_DMAR, 32); | |||||
nds32_reg_set(DMAR6, "dmar6", "DMA_ESADDR", SRIDX(5, 6, 0), NDS32_REG_TYPE_DMAR, 32); | |||||
nds32_reg_set(DMAR7, "dmar7", "DMA_TCNT", SRIDX(5, 7, 0), NDS32_REG_TYPE_DMAR, 32); | |||||
nds32_reg_set(DMAR8, "dmar8", "DMA_STATUS", SRIDX(5, 8, 0), NDS32_REG_TYPE_DMAR, 32); | |||||
nds32_reg_set(DMAR9, "dmar9", "DMA_2DSET", SRIDX(5, 9, 0), NDS32_REG_TYPE_DMAR, 32); | |||||
nds32_reg_set(DMAR10, "dmar10", "DMA_2DSCTL", SRIDX(5, 9, 1), NDS32_REG_TYPE_DMAR, 32); | |||||
nds32_reg_set(RACR, "racr", "PRUSR_ACC_CTL", SRIDX(4, 4, 0), NDS32_REG_TYPE_RACR, 32); | |||||
nds32_reg_set(FUCPR, "fucpr", "FUCOP_CTL", SRIDX(4, 5, 0), NDS32_REG_TYPE_RACR, 32); | |||||
nds32_reg_set(IDR0, "idr0", "SDZ_CTL", SRIDX(2, 15, 0), NDS32_REG_TYPE_IDR, 32); | |||||
nds32_reg_set(IDR1, "idr1", "MISC_CTL", SRIDX(2, 15, 1), NDS32_REG_TYPE_IDR, 32); | |||||
nds32_reg_set(SECUR0, "secur0", "", SRIDX(6, 0, 0), NDS32_REG_TYPE_SECURE, 32); | |||||
nds32_reg_set(D0L24, "D0L24", "D0L24", 0x10, NDS32_REG_TYPE_AUMR, 32); | |||||
nds32_reg_set(D1L24, "D1L24", "D1L24", 0x11, NDS32_REG_TYPE_AUMR, 32); | |||||
nds32_reg_set(I0, "I0", "I0", 0x0, NDS32_REG_TYPE_AUMR, 32); | |||||
nds32_reg_set(I1, "I1", "I1", 0x1, NDS32_REG_TYPE_AUMR, 32); | |||||
nds32_reg_set(I2, "I2", "I2", 0x2, NDS32_REG_TYPE_AUMR, 32); | |||||
nds32_reg_set(I3, "I3", "I3", 0x3, NDS32_REG_TYPE_AUMR, 32); | |||||
nds32_reg_set(I4, "I4", "I4", 0x4, NDS32_REG_TYPE_AUMR, 32); | |||||
nds32_reg_set(I5, "I5", "I5", 0x5, NDS32_REG_TYPE_AUMR, 32); | |||||
nds32_reg_set(I6, "I6", "I6", 0x6, NDS32_REG_TYPE_AUMR, 32); | |||||
nds32_reg_set(I7, "I7", "I7", 0x7, NDS32_REG_TYPE_AUMR, 32); | |||||
nds32_reg_set(M1, "M1", "M1", 0x9, NDS32_REG_TYPE_AUMR, 32); | |||||
nds32_reg_set(M2, "M2", "M2", 0xA, NDS32_REG_TYPE_AUMR, 32); | |||||
nds32_reg_set(M3, "M3", "M3", 0xB, NDS32_REG_TYPE_AUMR, 32); | |||||
nds32_reg_set(M5, "M5", "M5", 0xD, NDS32_REG_TYPE_AUMR, 32); | |||||
nds32_reg_set(M6, "M6", "M6", 0xE, NDS32_REG_TYPE_AUMR, 32); | |||||
nds32_reg_set(M7, "M7", "M7", 0xF, NDS32_REG_TYPE_AUMR, 32); | |||||
nds32_reg_set(MOD, "MOD", "MOD", 0x8, NDS32_REG_TYPE_AUMR, 32); | |||||
nds32_reg_set(LBE, "LBE", "LBE", 0x18, NDS32_REG_TYPE_AUMR, 32); | |||||
nds32_reg_set(LE, "LE", "LE", 0x19, NDS32_REG_TYPE_AUMR, 32); | |||||
nds32_reg_set(LC, "LC", "LC", 0x1A, NDS32_REG_TYPE_AUMR, 32); | |||||
nds32_reg_set(ADM_VBASE, "ADM_VBASE", "ADM_VBASE", 0x1B, NDS32_REG_TYPE_AUMR, 32); | |||||
nds32_reg_set(SHFT_CTL0, "SHFT_CTL0", "SHFT_CTL0", 0x12, NDS32_REG_TYPE_AUMR, 32); | |||||
nds32_reg_set(SHFT_CTL1, "SHFT_CTL1", "SHFT_CTL1", 0x13, NDS32_REG_TYPE_AUMR, 32); | |||||
nds32_reg_set(CB_CTL, "CB_CTL", "CB_CTL", 0x1F, NDS32_REG_TYPE_AUMR, 32); | |||||
nds32_reg_set(CBB0, "CBB0", "CBB0", 0x0, NDS32_REG_TYPE_AUMR, 32); | |||||
nds32_reg_set(CBB1, "CBB1", "CBB1", 0x1, NDS32_REG_TYPE_AUMR, 32); | |||||
nds32_reg_set(CBB2, "CBB2", "CBB2", 0x2, NDS32_REG_TYPE_AUMR, 32); | |||||
nds32_reg_set(CBB3, "CBB3", "CBB3", 0x3, NDS32_REG_TYPE_AUMR, 32); | |||||
nds32_reg_set(CBE0, "CBE0", "CBE0", 0x4, NDS32_REG_TYPE_AUMR, 32); | |||||
nds32_reg_set(CBE1, "CBE1", "CBE1", 0x5, NDS32_REG_TYPE_AUMR, 32); | |||||
nds32_reg_set(CBE2, "CBE2", "CBE2", 0x6, NDS32_REG_TYPE_AUMR, 32); | |||||
nds32_reg_set(CBE3, "CBE3", "CBE3", 0x7, NDS32_REG_TYPE_AUMR, 32); | |||||
nds32_reg_set(FPCSR, "fpcsr", "FPCSR", 0x7, NDS32_REG_TYPE_FPU, 32); | |||||
nds32_reg_set(FPCFG, "fpcfg", "FPCFG", 0x7, NDS32_REG_TYPE_FPU, 32); | |||||
nds32_reg_set(FS0, "fs0", "FS0", 0, NDS32_REG_TYPE_FPU, 32); | |||||
nds32_reg_set(FS1, "fs1", "FS1", 1, NDS32_REG_TYPE_FPU, 32); | |||||
nds32_reg_set(FS2, "fs2", "FS2", 2, NDS32_REG_TYPE_FPU, 32); | |||||
nds32_reg_set(FS3, "fs3", "FS3", 3, NDS32_REG_TYPE_FPU, 32); | |||||
nds32_reg_set(FS4, "fs4", "FS4", 4, NDS32_REG_TYPE_FPU, 32); | |||||
nds32_reg_set(FS5, "fs5", "FS5", 5, NDS32_REG_TYPE_FPU, 32); | |||||
nds32_reg_set(FS6, "fs6", "FS6", 6, NDS32_REG_TYPE_FPU, 32); | |||||
nds32_reg_set(FS7, "fs7", "FS7", 7, NDS32_REG_TYPE_FPU, 32); | |||||
nds32_reg_set(FS8, "fs8", "FS8", 8, NDS32_REG_TYPE_FPU, 32); | |||||
nds32_reg_set(FS9, "fs9", "FS9", 9, NDS32_REG_TYPE_FPU, 32); | |||||
nds32_reg_set(FS10, "fs10", "FS10", 10, NDS32_REG_TYPE_FPU, 32); | |||||
nds32_reg_set(FS11, "fs11", "FS11", 11, NDS32_REG_TYPE_FPU, 32); | |||||
nds32_reg_set(FS12, "fs12", "FS12", 12, NDS32_REG_TYPE_FPU, 32); | |||||
nds32_reg_set(FS13, "fs13", "FS13", 13, NDS32_REG_TYPE_FPU, 32); | |||||
nds32_reg_set(FS14, "fs14", "FS14", 14, NDS32_REG_TYPE_FPU, 32); | |||||
nds32_reg_set(FS15, "fs15", "FS15", 15, NDS32_REG_TYPE_FPU, 32); | |||||
nds32_reg_set(FS16, "fs16", "FS16", 16, NDS32_REG_TYPE_FPU, 32); | |||||
nds32_reg_set(FS17, "fs17", "FS17", 17, NDS32_REG_TYPE_FPU, 32); | |||||
nds32_reg_set(FS18, "fs18", "FS18", 18, NDS32_REG_TYPE_FPU, 32); | |||||
nds32_reg_set(FS19, "fs19", "FS19", 19, NDS32_REG_TYPE_FPU, 32); | |||||
nds32_reg_set(FS20, "fs20", "FS20", 20, NDS32_REG_TYPE_FPU, 32); | |||||
nds32_reg_set(FS21, "fs21", "FS21", 21, NDS32_REG_TYPE_FPU, 32); | |||||
nds32_reg_set(FS22, "fs22", "FS22", 22, NDS32_REG_TYPE_FPU, 32); | |||||
nds32_reg_set(FS23, "fs23", "FS23", 23, NDS32_REG_TYPE_FPU, 32); | |||||
nds32_reg_set(FS24, "fs24", "FS24", 24, NDS32_REG_TYPE_FPU, 32); | |||||
nds32_reg_set(FS25, "fs25", "FS25", 25, NDS32_REG_TYPE_FPU, 32); | |||||
nds32_reg_set(FS26, "fs26", "FS26", 26, NDS32_REG_TYPE_FPU, 32); | |||||
nds32_reg_set(FS27, "fs27", "FS27", 27, NDS32_REG_TYPE_FPU, 32); | |||||
nds32_reg_set(FS28, "fs28", "FS28", 28, NDS32_REG_TYPE_FPU, 32); | |||||
nds32_reg_set(FS29, "fs29", "FS29", 29, NDS32_REG_TYPE_FPU, 32); | |||||
nds32_reg_set(FS30, "fs30", "FS30", 30, NDS32_REG_TYPE_FPU, 32); | |||||
nds32_reg_set(FS31, "fs31", "FS31", 31, NDS32_REG_TYPE_FPU, 32); | |||||
nds32_reg_set(FD0, "fd0", "FD0", 0, NDS32_REG_TYPE_FPU, 64); | |||||
nds32_reg_set(FD1, "fd1", "FD1", 1, NDS32_REG_TYPE_FPU, 64); | |||||
nds32_reg_set(FD2, "fd2", "FD2", 2, NDS32_REG_TYPE_FPU, 64); | |||||
nds32_reg_set(FD3, "fd3", "FD3", 3, NDS32_REG_TYPE_FPU, 64); | |||||
nds32_reg_set(FD4, "fd4", "FD4", 4, NDS32_REG_TYPE_FPU, 64); | |||||
nds32_reg_set(FD5, "fd5", "FD5", 5, NDS32_REG_TYPE_FPU, 64); | |||||
nds32_reg_set(FD6, "fd6", "FD6", 6, NDS32_REG_TYPE_FPU, 64); | |||||
nds32_reg_set(FD7, "fd7", "FD7", 7, NDS32_REG_TYPE_FPU, 64); | |||||
nds32_reg_set(FD8, "fd8", "FD8", 8, NDS32_REG_TYPE_FPU, 64); | |||||
nds32_reg_set(FD9, "fd9", "FD9", 9, NDS32_REG_TYPE_FPU, 64); | |||||
nds32_reg_set(FD10, "fd10", "FD10", 10, NDS32_REG_TYPE_FPU, 64); | |||||
nds32_reg_set(FD11, "fd11", "FD11", 11, NDS32_REG_TYPE_FPU, 64); | |||||
nds32_reg_set(FD12, "fd12", "FD12", 12, NDS32_REG_TYPE_FPU, 64); | |||||
nds32_reg_set(FD13, "fd13", "FD13", 13, NDS32_REG_TYPE_FPU, 64); | |||||
nds32_reg_set(FD14, "fd14", "FD14", 14, NDS32_REG_TYPE_FPU, 64); | |||||
nds32_reg_set(FD15, "fd15", "FD15", 15, NDS32_REG_TYPE_FPU, 64); | |||||
nds32_reg_set(FD16, "fd16", "FD16", 16, NDS32_REG_TYPE_FPU, 64); | |||||
nds32_reg_set(FD17, "fd17", "FD17", 17, NDS32_REG_TYPE_FPU, 64); | |||||
nds32_reg_set(FD18, "fd18", "FD18", 18, NDS32_REG_TYPE_FPU, 64); | |||||
nds32_reg_set(FD19, "fd19", "FD19", 19, NDS32_REG_TYPE_FPU, 64); | |||||
nds32_reg_set(FD20, "fd20", "FD20", 20, NDS32_REG_TYPE_FPU, 64); | |||||
nds32_reg_set(FD21, "fd21", "FD21", 21, NDS32_REG_TYPE_FPU, 64); | |||||
nds32_reg_set(FD22, "fd22", "FD22", 22, NDS32_REG_TYPE_FPU, 64); | |||||
nds32_reg_set(FD23, "fd23", "FD23", 23, NDS32_REG_TYPE_FPU, 64); | |||||
nds32_reg_set(FD24, "fd24", "FD24", 24, NDS32_REG_TYPE_FPU, 64); | |||||
nds32_reg_set(FD25, "fd25", "FD25", 25, NDS32_REG_TYPE_FPU, 64); | |||||
nds32_reg_set(FD26, "fd26", "FD26", 26, NDS32_REG_TYPE_FPU, 64); | |||||
nds32_reg_set(FD27, "fd27", "FD27", 27, NDS32_REG_TYPE_FPU, 64); | |||||
nds32_reg_set(FD28, "fd28", "FD28", 28, NDS32_REG_TYPE_FPU, 64); | |||||
nds32_reg_set(FD29, "fd29", "FD29", 29, NDS32_REG_TYPE_FPU, 64); | |||||
nds32_reg_set(FD30, "fd30", "FD30", 30, NDS32_REG_TYPE_FPU, 64); | |||||
nds32_reg_set(FD31, "fd31", "FD31", 31, NDS32_REG_TYPE_FPU, 64); | |||||
nds32_reg_init_done = true; | |||||
} | |||||
uint32_t nds32_reg_sr_index(uint32_t number) | |||||
{ | |||||
return nds32_regs[number].sr_index; | |||||
} | |||||
enum nds32_reg_type_s nds32_reg_type(uint32_t number) | |||||
{ | |||||
return nds32_regs[number].type; | |||||
} | |||||
uint8_t nds32_reg_size(uint32_t number) | |||||
{ | |||||
return nds32_regs[number].size; | |||||
} | |||||
const char *nds32_reg_simple_name(uint32_t number) | |||||
{ | |||||
return nds32_regs[number].simple_mnemonic; | |||||
} | |||||
const char *nds32_reg_symbolic_name(uint32_t number) | |||||
{ | |||||
return nds32_regs[number].symbolic_mnemonic; | |||||
} |
@@ -0,0 +1,320 @@ | |||||
/*************************************************************************** | |||||
* Copyright (C) 2013 by Andes Technology * | |||||
* Hsiangkai Wang <hkwang@andestech.com> * | |||||
* * | |||||
* 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, write to the * | |||||
* Free Software Foundation, Inc., * | |||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * | |||||
***************************************************************************/ | |||||
#ifndef __NDS32_REG_H__ | |||||
#define __NDS32_REG_H__ | |||||
#define SRIDX(a, b, c) ((a << 7) | (b << 3) | c) | |||||
#define NDS32_REGISTER_DISABLE (0x0) | |||||
enum nds32_reg_number_s { | |||||
/* general registers */ | |||||
R0 = 0, | |||||
R1, | |||||
R2, | |||||
R3, | |||||
R4, | |||||
R5, | |||||
R6, | |||||
R7, | |||||
R8, | |||||
R9, | |||||
R10, | |||||
R11, | |||||
R12, | |||||
R13, | |||||
R14, | |||||
R15, | |||||
R16, | |||||
R17, | |||||
R18, | |||||
R19, | |||||
R20, | |||||
R21, | |||||
R22, | |||||
R23, | |||||
R24, | |||||
R25, | |||||
R26, | |||||
R27, | |||||
R28, | |||||
R29, | |||||
R30, | |||||
R31, | |||||
PC, | |||||
D0LO, | |||||
D0HI, | |||||
D1LO, | |||||
D1HI, | |||||
ITB, | |||||
IFC_LP, | |||||
/* system registers */ | |||||
CR0, | |||||
CR1, | |||||
CR2, | |||||
CR3, | |||||
CR4, | |||||
CR5, | |||||
CR6, | |||||
IR0, | |||||
IR1, | |||||
IR2, | |||||
IR3, | |||||
IR4, | |||||
IR5, | |||||
IR6, | |||||
IR7, | |||||
IR8, | |||||
IR9, | |||||
IR10, | |||||
IR11, | |||||
IR12, | |||||
IR13, | |||||
IR14, | |||||
IR15, | |||||
IR16, | |||||
IR17, | |||||
IR18, | |||||
IR19, | |||||
IR20, | |||||
IR21, | |||||
IR22, | |||||
IR23, | |||||
IR24, | |||||
IR25, | |||||
MR0, | |||||
MR1, | |||||
MR2, | |||||
MR3, | |||||
MR4, | |||||
MR5, | |||||
MR6, | |||||
MR7, | |||||
MR8, | |||||
MR9, | |||||
MR10, | |||||
MR11, | |||||
DR0, | |||||
DR1, | |||||
DR2, | |||||
DR3, | |||||
DR4, | |||||
DR5, | |||||
DR6, | |||||
DR7, | |||||
DR8, | |||||
DR9, | |||||
DR10, | |||||
DR11, | |||||
DR12, | |||||
DR13, | |||||
DR14, | |||||
DR15, | |||||
DR16, | |||||
DR17, | |||||
DR18, | |||||
DR19, | |||||
DR20, | |||||
DR21, | |||||
DR22, | |||||
DR23, | |||||
DR24, | |||||
DR25, | |||||
DR26, | |||||
DR27, | |||||
DR28, | |||||
DR29, | |||||
DR30, | |||||
DR31, | |||||
DR32, | |||||
DR33, | |||||
DR34, | |||||
DR35, | |||||
DR36, | |||||
DR37, | |||||
DR38, | |||||
DR39, | |||||
DR40, | |||||
DR41, | |||||
DR42, | |||||
DR43, | |||||
DR44, | |||||
DR45, | |||||
DR46, | |||||
DR47, | |||||
DR48, | |||||
PFR0, | |||||
PFR1, | |||||
PFR2, | |||||
PFR3, | |||||
DMAR0, | |||||
DMAR1, | |||||
DMAR2, | |||||
DMAR3, | |||||
DMAR4, | |||||
DMAR5, | |||||
DMAR6, | |||||
DMAR7, | |||||
DMAR8, | |||||
DMAR9, | |||||
DMAR10, | |||||
RACR, | |||||
FUCPR, | |||||
IDR0, | |||||
IDR1, | |||||
SECUR0, | |||||
/* audio registers */ | |||||
D0L24, | |||||
D1L24, | |||||
I0, | |||||
I1, | |||||
I2, | |||||
I3, | |||||
I4, | |||||
I5, | |||||
I6, | |||||
I7, | |||||
M1, | |||||
M2, | |||||
M3, | |||||
M5, | |||||
M6, | |||||
M7, | |||||
MOD, | |||||
LBE, | |||||
LE, | |||||
LC, | |||||
ADM_VBASE, | |||||
SHFT_CTL0, | |||||
SHFT_CTL1, | |||||
CB_CTL, | |||||
CBB0, | |||||
CBB1, | |||||
CBB2, | |||||
CBB3, | |||||
CBE0, | |||||
CBE1, | |||||
CBE2, | |||||
CBE3, | |||||
/* fpu */ | |||||
FPCSR, | |||||
FPCFG, | |||||
FS0, | |||||
FS1, | |||||
FS2, | |||||
FS3, | |||||
FS4, | |||||
FS5, | |||||
FS6, | |||||
FS7, | |||||
FS8, | |||||
FS9, | |||||
FS10, | |||||
FS11, | |||||
FS12, | |||||
FS13, | |||||
FS14, | |||||
FS15, | |||||
FS16, | |||||
FS17, | |||||
FS18, | |||||
FS19, | |||||
FS20, | |||||
FS21, | |||||
FS22, | |||||
FS23, | |||||
FS24, | |||||
FS25, | |||||
FS26, | |||||
FS27, | |||||
FS28, | |||||
FS29, | |||||
FS30, | |||||
FS31, | |||||
FD0, | |||||
FD1, | |||||
FD2, | |||||
FD3, | |||||
FD4, | |||||
FD5, | |||||
FD6, | |||||
FD7, | |||||
FD8, | |||||
FD9, | |||||
FD10, | |||||
FD11, | |||||
FD12, | |||||
FD13, | |||||
FD14, | |||||
FD15, | |||||
FD16, | |||||
FD17, | |||||
FD18, | |||||
FD19, | |||||
FD20, | |||||
FD21, | |||||
FD22, | |||||
FD23, | |||||
FD24, | |||||
FD25, | |||||
FD26, | |||||
FD27, | |||||
FD28, | |||||
FD29, | |||||
FD30, | |||||
FD31, | |||||
TOTAL_REG_NUM, | |||||
}; | |||||
enum nds32_reg_type_s { | |||||
NDS32_REG_TYPE_GPR = 0, | |||||
NDS32_REG_TYPE_SPR, | |||||
NDS32_REG_TYPE_CR, | |||||
NDS32_REG_TYPE_IR, | |||||
NDS32_REG_TYPE_MR, | |||||
NDS32_REG_TYPE_DR, | |||||
NDS32_REG_TYPE_PFR, | |||||
NDS32_REG_TYPE_DMAR, | |||||
NDS32_REG_TYPE_RACR, | |||||
NDS32_REG_TYPE_IDR, | |||||
NDS32_REG_TYPE_AUMR, | |||||
NDS32_REG_TYPE_SECURE, | |||||
NDS32_REG_TYPE_FPU, | |||||
}; | |||||
struct nds32_reg_s { | |||||
const char *simple_mnemonic; | |||||
const char *symbolic_mnemonic; | |||||
uint32_t sr_index; | |||||
enum nds32_reg_type_s type; | |||||
uint8_t size; | |||||
}; | |||||
void nds32_reg_init(void); | |||||
uint32_t nds32_reg_sr_index(uint32_t number); | |||||
enum nds32_reg_type_s nds32_reg_type(uint32_t number); | |||||
uint8_t nds32_reg_size(uint32_t number); | |||||
const char *nds32_reg_simple_name(uint32_t number); | |||||
const char *nds32_reg_symbolic_name(uint32_t number); | |||||
#endif |
@@ -0,0 +1,15 @@ | |||||
# | |||||
# Andes AICE | |||||
# | |||||
# http://www.andestech.com | |||||
# | |||||
interface aice | |||||
aice desc "Andes AICE adapter" | |||||
aice serial "C001-42163" | |||||
aice vid_pid 0x1CFC 0x0000 | |||||
aice port aice_usb | |||||
reset_config trst_and_srst | |||||
adapter_khz 24000 | |||||
aice retry_times 50 | |||||
aice count_to_check_dbger 30 |