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]), | |||
[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 | |||
AC_MSG_CHECKING([whether to enable ZY1000 minidriver]) | |||
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.]) | |||
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 | |||
AC_DEFINE([BUILD_VSLLINK], [1], [1 if you want the Versaloon-Link JTAG driver.]) | |||
else | |||
@@ -1137,7 +1147,8 @@ fi | |||
# check for usb.h when a driver will require it | |||
build_usb=no | |||
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 | |||
build_usb=yes | |||
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([OOCD_TRACE], [test $build_oocd_trace = yes]) | |||
AM_CONDITIONAL([JLINK], [test $build_jlink = yes]) | |||
AM_CONDITIONAL([AICE], [test $build_aice = yes]) | |||
AM_CONDITIONAL([VSLLINK], [test $build_vsllink = yes]) | |||
AM_CONDITIONAL([RLINK], [test $build_rlink = yes]) | |||
AM_CONDITIONAL([ULINK], [test $build_ulink = yes]) | |||
@@ -1313,6 +1325,7 @@ AC_CONFIG_FILES([ | |||
src/jtag/drivers/Makefile | |||
src/jtag/drivers/usb_blaster/Makefile | |||
src/jtag/hla/Makefile | |||
src/jtag/aice/Makefile | |||
src/transport/Makefile | |||
src/xsvf/Makefile | |||
src/svf/Makefile | |||
@@ -44,6 +44,11 @@ SUBDIRS += hla | |||
libjtag_la_LIBADD += $(top_builddir)/src/jtag/hla/libocdhla.la | |||
endif | |||
if AICE | |||
SUBDIRS += aice | |||
libjtag_la_LIBADD += $(top_builddir)/src/jtag/aice/libocdaice.la | |||
endif | |||
SUBDIRS += drivers | |||
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 | |||
extern struct jtag_interface sysfsgpio_interface; | |||
#endif | |||
#if BUILD_AICE == 1 | |||
extern struct jtag_interface aice_interface; | |||
#endif | |||
#endif /* standard drivers */ | |||
/** | |||
@@ -200,6 +203,9 @@ struct jtag_interface *jtag_interfaces[] = { | |||
#if BUILD_SYSFSGPIO == 1 | |||
&sysfsgpio_interface, | |||
#endif | |||
#if BUILD_AICE == 1 | |||
&aice_interface, | |||
#endif | |||
#endif /* standard drivers */ | |||
NULL, | |||
}; | |||
@@ -31,6 +31,7 @@ libtarget_la_SOURCES = \ | |||
$(ARM_MISC_SRC) \ | |||
$(AVR32_SRC) \ | |||
$(MIPS32_SRC) \ | |||
$(NDS32_SRC) \ | |||
avrt.c \ | |||
dsp563xx.c \ | |||
dsp563xx_once.c \ | |||
@@ -107,6 +108,9 @@ MIPS32_SRC = \ | |||
mips32_dmaacc.c \ | |||
mips_ejtag.c | |||
NDS32_SRC = \ | |||
nds32_reg.c | |||
noinst_HEADERS = \ | |||
algorithm.h \ | |||
@@ -162,7 +166,11 @@ noinst_HEADERS = \ | |||
avr32_ap7k.h \ | |||
avr32_jtag.h \ | |||
avr32_mem.h \ | |||
avr32_regs.h | |||
avr32_regs.h \ | |||
nds32.h \ | |||
nds32_edm.h \ | |||
nds32_insn.h \ | |||
nds32_reg.h | |||
ocddatadir = $(pkglibdir) | |||
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 |