diff options
Diffstat (limited to 'src')
41 files changed, 1 insertions, 18420 deletions
diff --git a/src/jtag/Makefile.am b/src/jtag/Makefile.am index 43c6f8b..7ce4adc 100644 --- a/src/jtag/Makefile.am +++ b/src/jtag/Makefile.am @@ -9,11 +9,6 @@ include %D%/hla/Makefile.am %C%_libjtag_la_LIBADD += $(top_builddir)/%D%/hla/libocdhla.la endif -if AICE -include %D%/aice/Makefile.am -%C%_libjtag_la_LIBADD += $(top_builddir)/%D%/aice/libocdaice.la -endif - include %D%/drivers/Makefile.am %C%_libjtag_la_LIBADD += $(top_builddir)/%D%/drivers/libocdjtagdrivers.la diff --git a/src/jtag/aice/Makefile.am b/src/jtag/aice/Makefile.am deleted file mode 100644 index bc5dac1..0000000 --- a/src/jtag/aice/Makefile.am +++ /dev/null @@ -1,16 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-or-later - -noinst_LTLIBRARIES += %D%/libocdaice.la - -%C%_libocdaice_la_CPPFLAGS = -I$(top_srcdir)/src/jtag/drivers $(AM_CPPFLAGS) $(LIBUSB1_CFLAGS) -%C%_libocdaice_la_SOURCES = \ - %D%/aice_transport.c \ - %D%/aice_interface.c \ - %D%/aice_port.c \ - %D%/aice_usb.c \ - %D%/aice_pipe.c \ - %D%/aice_transport.h \ - %D%/aice_interface.h \ - %D%/aice_port.h \ - %D%/aice_usb.h \ - %D%/aice_pipe.h diff --git a/src/jtag/aice/aice_interface.c b/src/jtag/aice/aice_interface.c deleted file mode 100644 index 89f82a0..0000000 --- a/src/jtag/aice/aice_interface.c +++ /dev/null @@ -1,507 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -/*************************************************************************** - * Copyright (C) 2013 by Andes Technology * - * Hsiangkai Wang <hkwang@andestech.com> * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <jtag/adapter.h> -#include <jtag/interface.h> -#include <jtag/commands.h> -#include <transport/transport.h> -#include <target/target.h> -#include <jtag/aice/aice_transport.h> -#include "aice_usb.h" - -#define AICE_KHZ_TO_SPEED_MAP_SIZE 16 -static const 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 const struct aice_port *aice_port; -static struct aice_port_param_s param; -static uint32_t retry_times; -static uint32_t count_to_check_dbger; - -/***************************************************************************/ -/* External interface implementation */ -static uint32_t aice_target_id_codes[AICE_MAX_NUM_CORE]; -static uint8_t aice_num_of_target_id_codes; - -/***************************************************************************/ -/* AICE operations */ -int aice_init_targets(void) -{ - int res; - struct target *target; - struct aice_port_s *aice; - - LOG_DEBUG("aice_init_targets"); - - 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; - } - } - - for (target = all_targets; target; target = target->next) { - target->tap->idcode = aice_target_id_codes[target->tap->abs_chain_position]; - - unsigned ii, limit = target->tap->expected_ids_cnt; - int found = 0; - - for (ii = 0; ii < limit; ii++) { - uint32_t expected = target->tap->expected_ids[ii]; - - /* treat "-expected-id 0" as a "don't-warn" wildcard */ - if (!expected || (target->tap->idcode == expected)) { - found = 1; - break; - } - } - - if (found == 0) { - LOG_ERROR - ("aice_init_targets: target not found: idcode: %" PRIx32, - target->tap->idcode); - return ERROR_FAIL; - } - - aice = calloc(1, sizeof(struct aice_port_s)); - aice->port = aice_port; - aice->coreid = target->tap->abs_chain_position; - - target->tap->priv = aice; - target->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 (aice_port->api->open(¶m) != ERROR_OK) { - LOG_ERROR("Cannot find AICE Interface! Please check " - "connection and permissions."); - return ERROR_JTAG_INIT_FAILED; - } - - aice_port->api->set_retry_times(retry_times); - aice_port->api->set_count_to_check_dbger(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; - - LOG_DEBUG_IO("reset trst: %d", 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 (i >= 8) - *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; -} - -int aice_scan_jtag_chain(void) -{ - LOG_DEBUG("=== %s ===", __func__); - uint8_t num_of_idcode = 0; - struct target *target; - - int res = aice_port->api->idcode(aice_target_id_codes, &num_of_idcode); - 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; - } - - for (unsigned int i = 0; i < num_of_idcode; i++) - LOG_DEBUG("id_codes[%u] = 0x%" PRIx32, i, aice_target_id_codes[i]); - - /* Update tap idcode */ - for (target = all_targets; target; target = target->next) - target->tap->idcode = aice_target_id_codes[target->tap->abs_chain_position]; - - return ERROR_OK; -} - -/***************************************************************************/ -/* Command handlers */ -COMMAND_HANDLER(aice_handle_aice_info_command) -{ - LOG_DEBUG("aice_handle_aice_info_command"); - - command_print(CMD, "Description: %s", param.device_desc); - command_print(CMD, "Serial number: %s", adapter_get_required_serial()); - if (strncmp(aice_port->name, "aice_pipe", 9) == 0) - command_print(CMD, "Adapter: %s", 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) - 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_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], param.vid); - COMMAND_PARSE_NUMBER(u16, CMD_ARGV[1], param.pid); - - return ERROR_OK; -} - -COMMAND_HANDLER(aice_handle_aice_adapter_command) -{ - LOG_DEBUG("aice_handle_aice_adapter_command"); - - if (CMD_ARGC == 1) - 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], 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], 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 = "", - }, - { - .name = "port", - .handler = &aice_handle_aice_port_command, - .mode = COMMAND_CONFIG, - .help = "set the port of the AICE", - .usage = "['aice_pipe'|'aice_usb']", - }, - { - .name = "desc", - .handler = &aice_handle_aice_desc_command, - .mode = COMMAND_CONFIG, - .help = "set the aice device description", - .usage = "[description 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 = "(vid pid)*", - }, - { - .name = "adapter", - .handler = &aice_handle_aice_adapter_command, - .mode = COMMAND_CONFIG, - .help = "set the file name of adapter", - .usage = "[adapter name]", - }, - { - .name = "retry_times", - .handler = &aice_handle_aice_retry_times_command, - .mode = COMMAND_CONFIG, - .help = "set retry times as AICE timeout", - .usage = "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 = "count_of_checking", - }, - { - .name = "custom_srst_script", - .handler = &aice_handle_aice_custom_srst_script_command, - .mode = COMMAND_CONFIG, - .usage = "script_file_name", - .help = "set custom srst script", - }, - { - .name = "custom_trst_script", - .handler = &aice_handle_aice_custom_trst_script_command, - .mode = COMMAND_CONFIG, - .usage = "script_file_name", - .help = "set custom trst script", - }, - { - .name = "custom_restart_script", - .handler = &aice_handle_aice_custom_restart_script_command, - .mode = COMMAND_CONFIG, - .usage = "script_file_name", - .help = "set custom restart script", - }, - { - .name = "reset", - .handler = &aice_handle_aice_reset_command, - .mode = COMMAND_EXEC, - .usage = "", - .help = "reset AICE", - }, - COMMAND_REGISTRATION_DONE -}; - -static const struct command_registration aice_command_handlers[] = { - { - .name = "aice", - .mode = COMMAND_ANY, - .help = "perform aice management", - .usage = "[subcommand]", - .chain = aice_subcommand_handlers, - }, - COMMAND_REGISTRATION_DONE -}; -/***************************************************************************/ -/* End of Command handlers */ - -static struct jtag_interface aice_interface = { - .execute_queue = aice_execute_queue, -}; - -struct adapter_driver aice_adapter_driver = { - .name = "aice", - .transports = aice_transports, - .commands = aice_command_handlers, - - .init = aice_init, - .quit = aice_quit, - .speed = aice_speed, /* set interface speed */ - .khz = aice_khz, /* convert khz to interface speed value */ - .speed_div = aice_speed_div, /* return readable value */ - - .jtag_ops = &aice_interface, -}; diff --git a/src/jtag/aice/aice_interface.h b/src/jtag/aice/aice_interface.h deleted file mode 100644 index 615e90f..0000000 --- a/src/jtag/aice/aice_interface.h +++ /dev/null @@ -1,14 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -/*************************************************************************** - * Copyright (C) 2013 by Andes Technology * - * Hsiangkai Wang <hkwang@andestech.com> * - ***************************************************************************/ - -#ifndef OPENOCD_JTAG_AICE_AICE_INTERFACE_H -#define OPENOCD_JTAG_AICE_AICE_INTERFACE_H - -int aice_init_targets(void); -int aice_scan_jtag_chain(void); - -#endif /* OPENOCD_JTAG_AICE_AICE_INTERFACE_H */ diff --git a/src/jtag/aice/aice_pipe.c b/src/jtag/aice/aice_pipe.c deleted file mode 100644 index 1ee2d88..0000000 --- a/src/jtag/aice/aice_pipe.c +++ /dev/null @@ -1,884 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -/*************************************************************************** - * Copyright (C) 2013 by Andes Technology * - * Hsiangkai Wang <hkwang@andestech.com> * - ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <helper/system.h> - -#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; - -static HANDLE aice_pipe_output[2]; -static 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%08l" PRIx32, 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%08l" PRIx32, 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 - -static int aice_pipe_output[2]; -static 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; - int64_t 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(uint32_t coreid, 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(uint32_t coreid, 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(uint32_t coreid) -{ - 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(uint32_t coreid) -{ - 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 coreid, 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 coreid, 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 coreid, 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 coreid, 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(uint32_t coreid) -{ - 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 coreid, 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 coreid, 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 coreid, 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 coreid, 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 coreid, 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 coreid, 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_memory_access(uint32_t coreid, 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(uint32_t coreid, 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 coreid, target_addr_t virtual_address, - target_addr_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 coreid, 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, - /** */ - .set_jtag_clock = aice_pipe_set_jtag_clock, - /** */ - .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, - - /** */ - .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, -}; diff --git a/src/jtag/aice/aice_pipe.h b/src/jtag/aice/aice_pipe.h deleted file mode 100644 index 5a1f410..0000000 --- a/src/jtag/aice/aice_pipe.h +++ /dev/null @@ -1,20 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -/*************************************************************************** - * Copyright (C) 2013 by Andes Technology * - * Hsiangkai Wang <hkwang@andestech.com> * - ***************************************************************************/ - -#ifndef OPENOCD_JTAG_AICE_AICE_PIPE_H -#define OPENOCD_JTAG_AICE_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 /* OPENOCD_JTAG_AICE_AICE_PIPE_H */ diff --git a/src/jtag/aice/aice_port.c b/src/jtag/aice/aice_port.c deleted file mode 100644 index ac38cec..0000000 --- a/src/jtag/aice/aice_port.c +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -/*************************************************************************** - * Copyright (C) 2013 by Andes Technology * - * Hsiangkai Wang <hkwang@andestech.com> * - ***************************************************************************/ -#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; -} diff --git a/src/jtag/aice/aice_port.h b/src/jtag/aice/aice_port.h deleted file mode 100644 index fb914d8..0000000 --- a/src/jtag/aice/aice_port.h +++ /dev/null @@ -1,224 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -/*************************************************************************** - * Copyright (C) 2013 by Andes Technology * - * Hsiangkai Wang <hkwang@andestech.com> * - ***************************************************************************/ - -#ifndef OPENOCD_JTAG_AICE_AICE_PORT_H -#define OPENOCD_JTAG_AICE_AICE_PORT_H - -#include <target/nds32_edm.h> - -#define AICE_MAX_NUM_CORE (0x10) - -#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_IDCODE, - AICE_SET_JTAG_CLOCK, - 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_STATE, - AICE_MEMORY_ACCESS, - AICE_MEMORY_MODE, - AICE_READ_TLB, - AICE_CACHE_CTL, - AICE_SET_RETRY_TIMES, - AICE_PROGRAM_EDM, - AICE_SET_COMMAND_MODE, - 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, -}; - -enum aice_command_mode { - AICE_COMMAND_MODE_NORMAL, - AICE_COMMAND_MODE_PACK, - AICE_COMMAND_MODE_BATCH, -}; - -struct aice_port_param_s { - /** */ - const char *device_desc; - /** */ - uint16_t vid; - /** */ - uint16_t pid; - /** */ - char *adapter_name; -}; - -struct aice_port_s { - /** */ - uint32_t coreid; - /** */ - const struct aice_port *port; -}; - -/** */ -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 (*idcode)(uint32_t *idcode, uint8_t *num_of_idcode); - /** */ - int (*set_jtag_clock)(uint32_t a_clock); - /** */ - int (*assert_srst)(uint32_t coreid, enum aice_srst_type_s srst); - /** */ - int (*run)(uint32_t coreid); - /** */ - int (*halt)(uint32_t coreid); - /** */ - int (*step)(uint32_t coreid); - /** */ - int (*read_reg)(uint32_t coreid, uint32_t num, uint32_t *val); - /** */ - int (*write_reg)(uint32_t coreid, uint32_t num, uint32_t val); - /** */ - int (*read_reg_64)(uint32_t coreid, uint32_t num, uint64_t *val); - /** */ - int (*write_reg_64)(uint32_t coreid, uint32_t num, uint64_t val); - /** */ - int (*read_mem_unit)(uint32_t coreid, uint32_t addr, uint32_t size, - uint32_t count, uint8_t *buffer); - /** */ - int (*write_mem_unit)(uint32_t coreid, uint32_t addr, uint32_t size, - uint32_t count, const uint8_t *buffer); - /** */ - int (*read_mem_bulk)(uint32_t coreid, uint32_t addr, uint32_t length, - uint8_t *buffer); - /** */ - int (*write_mem_bulk)(uint32_t coreid, uint32_t addr, uint32_t length, - const uint8_t *buffer); - /** */ - int (*read_debug_reg)(uint32_t coreid, uint32_t addr, uint32_t *val); - /** */ - int (*write_debug_reg)(uint32_t coreid, uint32_t addr, const uint32_t val); - - /** */ - int (*state)(uint32_t coreid, enum aice_target_state_s *state); - - /** */ - int (*memory_access)(uint32_t coreid, enum nds_memory_access a_access); - /** */ - int (*memory_mode)(uint32_t coreid, enum nds_memory_select mem_select); - - /** */ - int (*read_tlb)(uint32_t coreid, target_addr_t virtual_address, target_addr_t *physical_address); - - /** */ - int (*cache_ctl)(uint32_t coreid, uint32_t subtype, uint32_t address); - - /** */ - int (*set_retry_times)(uint32_t a_retry_times); - - /** */ - int (*program_edm)(uint32_t coreid, char *command_sequence); - - /** */ - int (*set_command_mode)(enum aice_command_mode command_mode); - - /** */ - int (*execute)(uint32_t coreid, 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)(uint32_t coreid, enum aice_target_endian target_data_endian); - - /** */ - int (*profiling)(uint32_t coreid, uint32_t interval, uint32_t iteration, - uint32_t reg_no, uint32_t *samples, uint32_t *num_samples); -}; - -#define AICE_PORT_UNKNOWN 0 -#define AICE_PORT_AICE_USB 1 -#define AICE_PORT_AICE_PIPE 2 - -/** */ -struct aice_port { - /** */ - const char *name; - /** */ - int type; - /** */ - struct aice_port_api_s *const api; -}; - -/** */ -const struct aice_port *aice_port_get_list(void); - -#endif /* OPENOCD_JTAG_AICE_AICE_PORT_H */ diff --git a/src/jtag/aice/aice_transport.c b/src/jtag/aice/aice_transport.c deleted file mode 100644 index 49f899d..0000000 --- a/src/jtag/aice/aice_transport.c +++ /dev/null @@ -1,432 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -/*************************************************************************** - * Copyright (C) 2013 by Andes Technology * - * Hsiangkai Wang <hkwang@andestech.com> * - ***************************************************************************/ - -#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> -#include <string.h> - -/* */ -static int jim_newtap_expected_id(struct jim_nvp *n, struct jim_getopt_info *goi, - struct jtag_tap *tap) -{ - 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) * tap->expected_ids_cnt; - uint32_t *new_expected_ids = malloc(expected_len + sizeof(uint32_t)); - if (!new_expected_ids) { - Jim_SetResultFormatted(goi->interp, "no memory"); - return JIM_ERR; - } - - assert(tap->expected_ids); - memcpy(new_expected_ids, tap->expected_ids, expected_len); - - new_expected_ids[tap->expected_ids_cnt] = w; - - free(tap->expected_ids); - tap->expected_ids = new_expected_ids; - tap->expected_ids_cnt++; - - return JIM_OK; -} - -#define NTAP_OPT_EXPECTED_ID 0 - -/* */ -static int jim_aice_newtap_cmd(struct jim_getopt_info *goi) -{ - struct jtag_tap *tap; - int x; - int e; - struct jim_nvp *n; - char *cp; - const struct jim_nvp opts[] = { - {.name = "-expected-id", .value = NTAP_OPT_EXPECTED_ID}, - {.name = NULL, .value = -1}, - }; - - tap = calloc(1, sizeof(struct jtag_tap)); - if (!tap) { - 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(tap); - return JIM_ERR; - } - - const char *tmp; - jim_getopt_string(goi, &tmp, NULL); - tap->chip = strdup(tmp); - - jim_getopt_string(goi, &tmp, NULL); - tap->tapname = strdup(tmp); - - /* name + dot + name + null */ - x = strlen(tap->chip) + 1 + strlen(tap->tapname) + 1; - cp = malloc(x); - sprintf(cp, "%s.%s", tap->chip, tap->tapname); - tap->dotted_name = cp; - - LOG_DEBUG("Creating New Tap, Chip: %s, Tap: %s, Dotted: %s, %d params", - tap->chip, tap->tapname, tap->dotted_name, goi->argc); - - while (goi->argc) { - e = jim_getopt_nvp(goi, opts, &n); - if (e != JIM_OK) { - jim_getopt_nvp_unknown(goi, opts, 0); - free(cp); - free(tap); - return e; - } - LOG_DEBUG("Processing option: %s", n->name); - switch (n->value) { - case NTAP_OPT_EXPECTED_ID: - e = jim_newtap_expected_id(n, goi, tap); - if (e != JIM_OK) { - free(cp); - free(tap); - return e; - } - break; - } /* switch (n->value) */ - } /* while (goi->argc) */ - - /* default is enabled-after-reset */ - tap->enabled = !tap->disabled_after_reset; - - jtag_tap_init(tap); - return JIM_OK; -} - -/* */ -static int jim_aice_newtap(Jim_Interp *interp, int argc, Jim_Obj * const *argv) -{ - struct jim_getopt_info 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); -} - -COMMAND_HANDLER(handle_scan_chain_command) -{ - struct jtag_tap *tap; - char expected_id[12]; - - aice_scan_jtag_chain(); - tap = jtag_all_taps(); - command_print(CMD, - " TapName Enabled IdCode Expected IrLen IrCap IrMask"); - command_print(CMD, - "-- ------------------- -------- ---------- ---------- ----- ----- ------"); - - while (tap) { - uint32_t expected, expected_mask, ii; - - snprintf(expected_id, sizeof(expected_id), "0x%08x", - (unsigned)((tap->expected_ids_cnt > 0) - ? tap->expected_ids[0] - : 0)); - if (tap->ignore_version) - expected_id[2] = '*'; - - expected = buf_get_u32(tap->expected, 0, tap->ir_length); - expected_mask = buf_get_u32(tap->expected_mask, 0, tap->ir_length); - - command_print(CMD, - "%2d %-18s %c 0x%08x %s %5d 0x%02x 0x%02x", - tap->abs_chain_position, - tap->dotted_name, - tap->enabled ? 'Y' : 'n', - (unsigned int)(tap->idcode), - expected_id, - (unsigned int)(tap->ir_length), - (unsigned int)(expected), - (unsigned int)(expected_mask)); - - for (ii = 1; ii < tap->expected_ids_cnt; ii++) { - snprintf(expected_id, sizeof(expected_id), "0x%08x", - (unsigned) tap->expected_ids[ii]); - if (tap->ignore_version) - expected_id[2] = '*'; - - command_print(CMD, - " %s", - expected_id); - } - - tap = tap->next_tap; - } - - return ERROR_OK; -} - -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; - struct jim_getopt_info 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 *obj = Jim_NewIntObj(goi.interp, e); - Jim_SetResultFormatted(goi.interp, "error: %#s", obj); - return JIM_ERR; - } - return JIM_OK; -} - -static int jim_aice_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv) -{ - struct jim_getopt_info 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_ANY, - .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.", - }, - { - .name = "scan_chain", - .handler = handle_scan_chain_command, - .mode = COMMAND_ANY, - .help = "print current scan chain configuration", - .usage = "" - }, - - 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_targets(); -} - -/* */ -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); -} diff --git a/src/jtag/aice/aice_transport.h b/src/jtag/aice/aice_transport.h deleted file mode 100644 index b000031..0000000 --- a/src/jtag/aice/aice_transport.h +++ /dev/null @@ -1,13 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -/*************************************************************************** - * Copyright (C) 2013 by Andes Technology * - * Hsiangkai Wang <hkwang@andestech.com> * - ***************************************************************************/ - -#ifndef OPENOCD_JTAG_AICE_AICE_TRANSPORT_H -#define OPENOCD_JTAG_AICE_AICE_TRANSPORT_H - -extern const char *aice_transports[]; - -#endif /* OPENOCD_JTAG_AICE_AICE_TRANSPORT_H */ diff --git a/src/jtag/aice/aice_usb.c b/src/jtag/aice/aice_usb.c deleted file mode 100644 index b5d0f0b..0000000 --- a/src/jtag/aice/aice_usb.c +++ /dev/null @@ -1,4099 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -/*************************************************************************** - * Copyright (C) 2013 by Andes Technology * - * Hsiangkai Wang <hkwang@andestech.com> * - ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <helper/system.h> -#include <jtag/drivers/libusb_helper.h> -#include <helper/log.h> -#include <helper/time_support.h> -#include <target/target.h> -#include <jtag/jtag.h> -#include <target/nds32_insn.h> -#include <target/nds32_reg.h> -#include "aice_usb.h" - - -/* Global USB buffers */ -static uint8_t usb_in_buffer[AICE_IN_BUFFER_SIZE]; -static uint8_t usb_out_buffer[AICE_OUT_BUFFER_SIZE]; -static uint32_t jtag_clock; -static struct aice_usb_handler_s aice_handler; -/* AICE max retry times. If AICE command timeout, retry it. */ -static int aice_max_retry_times = 50; -/* Default endian is little endian. */ -static enum aice_target_endian data_endian; - -/* Constants for AICE command format length */ -#define AICE_FORMAT_HTDA (3) -#define AICE_FORMAT_HTDC (7) -#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 */ -#define AICE_CMD_SCAN_CHAIN 0x00 -#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_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_EXECUTE 0x3E -#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 - -/***************************************************************************/ -/* AICE commands' pack/unpack functions */ -static void aice_pack_htda(uint8_t cmd_code, uint8_t extra_word_length, - uint32_t address) -{ - usb_out_buffer[0] = cmd_code; - usb_out_buffer[1] = extra_word_length; - usb_out_buffer[2] = (uint8_t)(address & 0xFF); -} - -static void aice_pack_htdc(uint8_t cmd_code, uint8_t extra_word_length, - uint32_t address, uint32_t word, enum aice_target_endian access_endian) -{ - usb_out_buffer[0] = cmd_code; - usb_out_buffer[1] = extra_word_length; - usb_out_buffer[2] = (uint8_t)(address & 0xFF); - if (access_endian == AICE_BIG_ENDIAN) { - usb_out_buffer[6] = (uint8_t)((word >> 24) & 0xFF); - usb_out_buffer[5] = (uint8_t)((word >> 16) & 0xFF); - usb_out_buffer[4] = (uint8_t)((word >> 8) & 0xFF); - usb_out_buffer[3] = (uint8_t)(word & 0xFF); - } else { - usb_out_buffer[3] = (uint8_t)((word >> 24) & 0xFF); - usb_out_buffer[4] = (uint8_t)((word >> 16) & 0xFF); - usb_out_buffer[5] = (uint8_t)((word >> 8) & 0xFF); - usb_out_buffer[6] = (uint8_t)(word & 0xFF); - } -} - -static void aice_pack_htdma(uint8_t cmd_code, uint8_t target_id, - uint8_t extra_word_length, uint32_t address) -{ - usb_out_buffer[0] = cmd_code; - usb_out_buffer[1] = target_id; - usb_out_buffer[2] = extra_word_length; - usb_out_buffer[3] = (uint8_t)(address & 0xFF); -} - -static void aice_pack_htdmb(uint8_t cmd_code, uint8_t target_id, - uint8_t extra_word_length, uint32_t address) -{ - usb_out_buffer[0] = cmd_code; - usb_out_buffer[1] = target_id; - usb_out_buffer[2] = extra_word_length; - usb_out_buffer[3] = 0; - usb_out_buffer[4] = (uint8_t)((address >> 24) & 0xFF); - usb_out_buffer[5] = (uint8_t)((address >> 16) & 0xFF); - usb_out_buffer[6] = (uint8_t)((address >> 8) & 0xFF); - usb_out_buffer[7] = (uint8_t)(address & 0xFF); -} - -static void aice_pack_htdmc(uint8_t cmd_code, uint8_t target_id, - uint8_t extra_word_length, uint32_t address, uint32_t word, - enum aice_target_endian access_endian) -{ - usb_out_buffer[0] = cmd_code; - usb_out_buffer[1] = target_id; - usb_out_buffer[2] = extra_word_length; - usb_out_buffer[3] = (uint8_t)(address & 0xFF); - if (access_endian == AICE_BIG_ENDIAN) { - usb_out_buffer[7] = (uint8_t)((word >> 24) & 0xFF); - usb_out_buffer[6] = (uint8_t)((word >> 16) & 0xFF); - usb_out_buffer[5] = (uint8_t)((word >> 8) & 0xFF); - usb_out_buffer[4] = (uint8_t)(word & 0xFF); - } else { - usb_out_buffer[4] = (uint8_t)((word >> 24) & 0xFF); - usb_out_buffer[5] = (uint8_t)((word >> 16) & 0xFF); - usb_out_buffer[6] = (uint8_t)((word >> 8) & 0xFF); - usb_out_buffer[7] = (uint8_t)(word & 0xFF); - } -} - -static void aice_pack_htdmc_multiple_data(uint8_t cmd_code, uint8_t target_id, - uint8_t extra_word_length, uint32_t address, uint32_t *word, - uint8_t num_of_words, enum aice_target_endian access_endian) -{ - usb_out_buffer[0] = cmd_code; - usb_out_buffer[1] = target_id; - usb_out_buffer[2] = extra_word_length; - usb_out_buffer[3] = (uint8_t)(address & 0xFF); - - uint8_t i; - for (i = 0 ; i < num_of_words ; i++, word++) { - if (access_endian == AICE_BIG_ENDIAN) { - usb_out_buffer[7 + i * 4] = (uint8_t)((*word >> 24) & 0xFF); - usb_out_buffer[6 + i * 4] = (uint8_t)((*word >> 16) & 0xFF); - usb_out_buffer[5 + i * 4] = (uint8_t)((*word >> 8) & 0xFF); - usb_out_buffer[4 + i * 4] = (uint8_t)(*word & 0xFF); - } else { - usb_out_buffer[4 + i * 4] = (uint8_t)((*word >> 24) & 0xFF); - usb_out_buffer[5 + i * 4] = (uint8_t)((*word >> 16) & 0xFF); - usb_out_buffer[6 + i * 4] = (uint8_t)((*word >> 8) & 0xFF); - usb_out_buffer[7 + i * 4] = (uint8_t)(*word & 0xFF); - } - } -} - -static void aice_pack_htdmd(uint8_t cmd_code, uint8_t target_id, - uint8_t extra_word_length, uint32_t address, uint32_t word, - enum aice_target_endian access_endian) -{ - usb_out_buffer[0] = cmd_code; - usb_out_buffer[1] = target_id; - usb_out_buffer[2] = extra_word_length; - usb_out_buffer[3] = 0; - usb_out_buffer[4] = (uint8_t)((address >> 24) & 0xFF); - usb_out_buffer[5] = (uint8_t)((address >> 16) & 0xFF); - usb_out_buffer[6] = (uint8_t)((address >> 8) & 0xFF); - usb_out_buffer[7] = (uint8_t)(address & 0xFF); - if (access_endian == AICE_BIG_ENDIAN) { - usb_out_buffer[11] = (uint8_t)((word >> 24) & 0xFF); - usb_out_buffer[10] = (uint8_t)((word >> 16) & 0xFF); - usb_out_buffer[9] = (uint8_t)((word >> 8) & 0xFF); - usb_out_buffer[8] = (uint8_t)(word & 0xFF); - } else { - usb_out_buffer[8] = (uint8_t)((word >> 24) & 0xFF); - usb_out_buffer[9] = (uint8_t)((word >> 16) & 0xFF); - usb_out_buffer[10] = (uint8_t)((word >> 8) & 0xFF); - usb_out_buffer[11] = (uint8_t)(word & 0xFF); - } -} - -static void aice_pack_htdmd_multiple_data(uint8_t cmd_code, uint8_t target_id, - uint8_t extra_word_length, uint32_t address, const uint8_t *word, - enum aice_target_endian access_endian) -{ - usb_out_buffer[0] = cmd_code; - usb_out_buffer[1] = target_id; - usb_out_buffer[2] = extra_word_length; - usb_out_buffer[3] = 0; - usb_out_buffer[4] = (uint8_t)((address >> 24) & 0xFF); - usb_out_buffer[5] = (uint8_t)((address >> 16) & 0xFF); - usb_out_buffer[6] = (uint8_t)((address >> 8) & 0xFF); - usb_out_buffer[7] = (uint8_t)(address & 0xFF); - - uint32_t i; - /* num_of_words may be over 0xFF, so use uint32_t */ - uint32_t num_of_words = extra_word_length + 1; - - for (i = 0 ; i < num_of_words ; i++, word += 4) { - if (access_endian == AICE_BIG_ENDIAN) { - usb_out_buffer[11 + i * 4] = word[3]; - usb_out_buffer[10 + i * 4] = word[2]; - usb_out_buffer[9 + i * 4] = word[1]; - usb_out_buffer[8 + i * 4] = word[0]; - } else { - usb_out_buffer[8 + i * 4] = word[3]; - usb_out_buffer[9 + i * 4] = word[2]; - usb_out_buffer[10 + i * 4] = word[1]; - usb_out_buffer[11 + i * 4] = word[0]; - } - } -} - -static void aice_unpack_dtha(uint8_t *cmd_ack_code, uint8_t *extra_word_length, - uint32_t *word, enum aice_target_endian access_endian) -{ - *cmd_ack_code = usb_in_buffer[0]; - *extra_word_length = usb_in_buffer[1]; - - if (access_endian == AICE_BIG_ENDIAN) { - *word = (usb_in_buffer[5] << 24) | - (usb_in_buffer[4] << 16) | - (usb_in_buffer[3] << 8) | - (usb_in_buffer[2]); - } else { - *word = (usb_in_buffer[2] << 24) | - (usb_in_buffer[3] << 16) | - (usb_in_buffer[4] << 8) | - (usb_in_buffer[5]); - } -} - -static void aice_unpack_dtha_multiple_data(uint8_t *cmd_ack_code, - uint8_t *extra_word_length, uint32_t *word, uint8_t num_of_words, - enum aice_target_endian access_endian) -{ - *cmd_ack_code = usb_in_buffer[0]; - *extra_word_length = usb_in_buffer[1]; - - uint8_t i; - for (i = 0 ; i < num_of_words ; i++, word++) { - if (access_endian == AICE_BIG_ENDIAN) { - *word = (usb_in_buffer[5 + i * 4] << 24) | - (usb_in_buffer[4 + i * 4] << 16) | - (usb_in_buffer[3 + i * 4] << 8) | - (usb_in_buffer[2 + i * 4]); - } else { - *word = (usb_in_buffer[2 + i * 4] << 24) | - (usb_in_buffer[3 + i * 4] << 16) | - (usb_in_buffer[4 + i * 4] << 8) | - (usb_in_buffer[5 + i * 4]); - } - } -} - -static void aice_unpack_dthb(uint8_t *cmd_ack_code, uint8_t *extra_word_length) -{ - *cmd_ack_code = usb_in_buffer[0]; - *extra_word_length = usb_in_buffer[1]; -} - -static void aice_unpack_dthma(uint8_t *cmd_ack_code, uint8_t *target_id, - uint8_t *extra_word_length, uint32_t *word, - enum aice_target_endian access_endian) -{ - *cmd_ack_code = usb_in_buffer[0]; - *target_id = usb_in_buffer[1]; - *extra_word_length = usb_in_buffer[2]; - if (access_endian == AICE_BIG_ENDIAN) { - *word = (usb_in_buffer[7] << 24) | - (usb_in_buffer[6] << 16) | - (usb_in_buffer[5] << 8) | - (usb_in_buffer[4]); - } else { - *word = (usb_in_buffer[4] << 24) | - (usb_in_buffer[5] << 16) | - (usb_in_buffer[6] << 8) | - (usb_in_buffer[7]); - } -} - -static void aice_unpack_dthma_multiple_data(uint8_t *cmd_ack_code, - uint8_t *target_id, uint8_t *extra_word_length, uint8_t *word, - enum aice_target_endian access_endian) -{ - *cmd_ack_code = usb_in_buffer[0]; - *target_id = usb_in_buffer[1]; - *extra_word_length = usb_in_buffer[2]; - if (access_endian == AICE_BIG_ENDIAN) { - word[0] = usb_in_buffer[4]; - word[1] = usb_in_buffer[5]; - word[2] = usb_in_buffer[6]; - word[3] = usb_in_buffer[7]; - } else { - word[0] = usb_in_buffer[7]; - word[1] = usb_in_buffer[6]; - word[2] = usb_in_buffer[5]; - word[3] = usb_in_buffer[4]; - } - word += 4; - - uint8_t i; - for (i = 0; i < *extra_word_length; i++) { - if (access_endian == AICE_BIG_ENDIAN) { - word[0] = usb_in_buffer[8 + i * 4]; - word[1] = usb_in_buffer[9 + i * 4]; - word[2] = usb_in_buffer[10 + i * 4]; - word[3] = usb_in_buffer[11 + i * 4]; - } else { - word[0] = usb_in_buffer[11 + i * 4]; - word[1] = usb_in_buffer[10 + i * 4]; - word[2] = usb_in_buffer[9 + i * 4]; - word[3] = usb_in_buffer[8 + i * 4]; - } - word += 4; - } -} - -static void aice_unpack_dthmb(uint8_t *cmd_ack_code, uint8_t *target_id, - uint8_t *extra_word_length) -{ - *cmd_ack_code = usb_in_buffer[0]; - *target_id = usb_in_buffer[1]; - *extra_word_length = usb_in_buffer[2]; -} - -/***************************************************************************/ -/* End of AICE commands' pack/unpack functions */ - -/* calls the given usb_bulk_* function, allowing for the data to - * trickle in with some timeouts */ -static int usb_bulk_with_retries( - int (*f)(struct libusb_device_handle *, int, char *, int, int, int *), - struct libusb_device_handle *dev, int ep, - char *bytes, int size, int timeout, int *transferred) -{ - int tries = 3, count = 0; - - while (tries && (count < size)) { - int result, ret; - - ret = f(dev, ep, bytes + count, size - count, timeout, &result); - if (ret == ERROR_OK) - count += result; - else if ((ret != ERROR_TIMEOUT_REACHED) || !--tries) - return ret; - } - - *transferred = count; - return ERROR_OK; -} - -static int wrap_usb_bulk_write(struct libusb_device_handle *dev, int ep, - char *buff, int size, int timeout, int *transferred) -{ - - /* usb_bulk_write() takes const char *buff */ - jtag_libusb_bulk_write(dev, ep, buff, size, timeout, transferred); - - return 0; -} - -static inline int usb_bulk_write_ex(struct libusb_device_handle *dev, int ep, - char *bytes, int size, int timeout) -{ - int tr = 0; - - usb_bulk_with_retries(&wrap_usb_bulk_write, - dev, ep, bytes, size, timeout, &tr); - return tr; -} - -static inline int usb_bulk_read_ex(struct libusb_device_handle *dev, int ep, - char *bytes, int size, int timeout) -{ - int tr = 0; - usb_bulk_with_retries(&jtag_libusb_bulk_read, - dev, ep, bytes, size, timeout, &tr); - return tr; -} - -/* Write data from out_buffer to USB. */ -static int aice_usb_write(uint8_t *out_buffer, int out_length) -{ - int result; - - if (out_length > AICE_OUT_BUFFER_SIZE) { - LOG_ERROR("aice_write illegal out_length=%i (max=%i)", - out_length, AICE_OUT_BUFFER_SIZE); - return -1; - } - - result = usb_bulk_write_ex(aice_handler.usb_handle, aice_handler.usb_write_ep, - (char *)out_buffer, out_length, AICE_USB_TIMEOUT); - - LOG_DEBUG_IO("aice_usb_write, out_length = %i, result = %i", - out_length, result); - - return result; -} - -/* Read data from USB into in_buffer. */ -static int aice_usb_read(uint8_t *in_buffer, int expected_size) -{ - int result = usb_bulk_read_ex(aice_handler.usb_handle, aice_handler.usb_read_ep, - (char *)in_buffer, expected_size, AICE_USB_TIMEOUT); - - LOG_DEBUG_IO("aice_usb_read, result = %d", result); - - return result; -} - -static uint8_t usb_out_packets_buffer[AICE_OUT_PACKETS_BUFFER_SIZE]; -static uint8_t usb_in_packets_buffer[AICE_IN_PACKETS_BUFFER_SIZE]; -static uint32_t usb_out_packets_buffer_length; -static uint32_t usb_in_packets_buffer_length; -static enum aice_command_mode aice_command_mode; - -static int aice_batch_buffer_write(uint8_t buf_index, const uint8_t *word, - uint32_t num_of_words); - -static int aice_usb_packet_flush(void) -{ - if (usb_out_packets_buffer_length == 0) - return 0; - - if (aice_command_mode == AICE_COMMAND_MODE_PACK) { - LOG_DEBUG("Flush usb packets (AICE_COMMAND_MODE_PACK)"); - - if (aice_usb_write(usb_out_packets_buffer, - usb_out_packets_buffer_length) < 0) - return ERROR_FAIL; - - if (aice_usb_read(usb_in_packets_buffer, - usb_in_packets_buffer_length) < 0) - return ERROR_FAIL; - - usb_out_packets_buffer_length = 0; - usb_in_packets_buffer_length = 0; - - } else if (aice_command_mode == AICE_COMMAND_MODE_BATCH) { - LOG_DEBUG("Flush usb packets (AICE_COMMAND_MODE_BATCH)"); - - /* use BATCH_BUFFER_WRITE to fill command-batch-buffer */ - if (aice_batch_buffer_write(AICE_BATCH_COMMAND_BUFFER_0, - usb_out_packets_buffer, - (usb_out_packets_buffer_length + 3) / 4) != ERROR_OK) - return ERROR_FAIL; - - usb_out_packets_buffer_length = 0; - usb_in_packets_buffer_length = 0; - - /* enable BATCH command */ - aice_command_mode = AICE_COMMAND_MODE_NORMAL; - if (aice_write_ctrl(AICE_WRITE_CTRL_BATCH_CTRL, 0x80000000) != ERROR_OK) - return ERROR_FAIL; - aice_command_mode = AICE_COMMAND_MODE_BATCH; - - /* wait 1 second (AICE bug, workaround) */ - alive_sleep(1000); - - /* check status */ - uint32_t i; - uint32_t batch_status; - - i = 0; - while (1) { - int retval = aice_read_ctrl(AICE_READ_CTRL_BATCH_STATUS, &batch_status); - if (retval != ERROR_OK) - return retval; - - if (batch_status & 0x1) - return ERROR_OK; - else if (batch_status & 0xE) - return ERROR_FAIL; - - if ((i % 30) == 0) - keep_alive(); - - i++; - } - } - - return ERROR_OK; -} - -static int aice_usb_packet_append(uint8_t *out_buffer, int out_length, int in_length) -{ - uint32_t max_packet_size = AICE_OUT_PACKETS_BUFFER_SIZE; - - if (aice_command_mode == AICE_COMMAND_MODE_PACK) { - max_packet_size = AICE_OUT_PACK_COMMAND_SIZE; - } else if (aice_command_mode == AICE_COMMAND_MODE_BATCH) { - max_packet_size = AICE_OUT_BATCH_COMMAND_SIZE; - } else { - /* AICE_COMMAND_MODE_NORMAL */ - if (aice_usb_packet_flush() != ERROR_OK) - return ERROR_FAIL; - } - - if (usb_out_packets_buffer_length + out_length > max_packet_size) - if (aice_usb_packet_flush() != ERROR_OK) { - LOG_DEBUG("Flush usb packets failed"); - return ERROR_FAIL; - } - - LOG_DEBUG("Append usb packets 0x%02x", out_buffer[0]); - - memcpy(usb_out_packets_buffer + usb_out_packets_buffer_length, out_buffer, out_length); - usb_out_packets_buffer_length += out_length; - usb_in_packets_buffer_length += in_length; - - return ERROR_OK; -} - -/***************************************************************************/ -/* AICE commands */ -static int aice_reset_box(void) -{ - if (aice_write_ctrl(AICE_WRITE_CTRL_CLEAR_TIMEOUT_STATUS, 0x1) != ERROR_OK) - return ERROR_FAIL; - - /* turn off FASTMODE */ - uint32_t pin_status; - if (aice_read_ctrl(AICE_READ_CTRL_GET_JTAG_PIN_STATUS, &pin_status) - != ERROR_OK) - return ERROR_FAIL; - - if (aice_write_ctrl(AICE_WRITE_CTRL_JTAG_PIN_STATUS, pin_status & (~0x2)) - != ERROR_OK) - return ERROR_FAIL; - - return ERROR_OK; -} - -static int aice_scan_chain(uint32_t *id_codes, uint8_t *num_of_ids) -{ - int retry_times = 0; - - if ((aice_command_mode == AICE_COMMAND_MODE_PACK) || - (aice_command_mode == AICE_COMMAND_MODE_BATCH)) - aice_usb_packet_flush(); - - do { - aice_pack_htda(AICE_CMD_SCAN_CHAIN, 0x0F, 0x0); - - aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDA); - - LOG_DEBUG("SCAN_CHAIN, length: 0x0F"); - - /** TODO: modify receive length */ - int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHA); - if (result != AICE_FORMAT_DTHA) { - LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)", - AICE_FORMAT_DTHA, result); - return ERROR_FAIL; - } - - uint8_t cmd_ack_code; - aice_unpack_dtha_multiple_data(&cmd_ack_code, num_of_ids, id_codes, - 0x10, AICE_LITTLE_ENDIAN); - - if (cmd_ack_code != AICE_CMD_SCAN_CHAIN) { - - if (retry_times > aice_max_retry_times) { - LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")", - AICE_CMD_SCAN_CHAIN, cmd_ack_code); - return ERROR_FAIL; - } - - /* clear timeout and retry */ - if (aice_reset_box() != ERROR_OK) - return ERROR_FAIL; - - retry_times++; - continue; - } - - LOG_DEBUG("SCAN_CHAIN response, # of IDs: %" PRIu8, *num_of_ids); - - if (*num_of_ids == 0xFF) { - LOG_ERROR("No target connected"); - return ERROR_FAIL; - } else if (*num_of_ids == AICE_MAX_NUM_CORE) { - LOG_INFO("The ice chain over 16 targets"); - } else { - (*num_of_ids)++; - } - break; - } while (1); - - return ERROR_OK; -} - -int aice_read_ctrl(uint32_t address, uint32_t *data) -{ - if ((aice_command_mode == AICE_COMMAND_MODE_PACK) || - (aice_command_mode == AICE_COMMAND_MODE_BATCH)) - aice_usb_packet_flush(); - - aice_pack_htda(AICE_CMD_READ_CTRL, 0, address); - - aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDA); - - LOG_DEBUG("READ_CTRL, address: 0x%" PRIx32, address); - - int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHA); - if (result != AICE_FORMAT_DTHA) { - LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)", - AICE_FORMAT_DTHA, result); - return ERROR_FAIL; - } - - uint8_t cmd_ack_code; - uint8_t extra_length; - aice_unpack_dtha(&cmd_ack_code, &extra_length, data, AICE_LITTLE_ENDIAN); - - LOG_DEBUG("READ_CTRL response, data: 0x%" PRIx32, *data); - - if (cmd_ack_code != AICE_CMD_READ_CTRL) { - LOG_ERROR("aice command error (command=0x%x, response=0x%" PRIx8 ")", - AICE_CMD_READ_CTRL, cmd_ack_code); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -int aice_write_ctrl(uint32_t address, uint32_t data) -{ - if (aice_command_mode == AICE_COMMAND_MODE_PACK) { - aice_usb_packet_flush(); - } else if (aice_command_mode == AICE_COMMAND_MODE_BATCH) { - aice_pack_htdc(AICE_CMD_WRITE_CTRL, 0, address, data, AICE_LITTLE_ENDIAN); - return aice_usb_packet_append(usb_out_buffer, AICE_FORMAT_HTDC, - AICE_FORMAT_DTHB); - } - - aice_pack_htdc(AICE_CMD_WRITE_CTRL, 0, address, data, AICE_LITTLE_ENDIAN); - - aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDC); - - LOG_DEBUG("WRITE_CTRL, address: 0x%" PRIx32 ", data: 0x%" PRIx32, address, data); - - int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHB); - if (result != AICE_FORMAT_DTHB) { - LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)", - AICE_FORMAT_DTHB, result); - return ERROR_FAIL; - } - - uint8_t cmd_ack_code; - uint8_t extra_length; - aice_unpack_dthb(&cmd_ack_code, &extra_length); - - LOG_DEBUG("WRITE_CTRL response"); - - if (cmd_ack_code != AICE_CMD_WRITE_CTRL) { - LOG_ERROR("aice command error (command=0x%x, response=0x%" PRIx8 ")", - AICE_CMD_WRITE_CTRL, cmd_ack_code); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int aice_read_dtr(uint8_t target_id, uint32_t *data) -{ - int retry_times = 0; - - if ((aice_command_mode == AICE_COMMAND_MODE_PACK) || - (aice_command_mode == AICE_COMMAND_MODE_BATCH)) - aice_usb_packet_flush(); - - do { - aice_pack_htdma(AICE_CMD_T_READ_DTR, target_id, 0, 0); - - aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMA); - - LOG_DEBUG("READ_DTR, COREID: %" PRIu8, target_id); - - int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMA); - if (result != AICE_FORMAT_DTHMA) { - LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)", - AICE_FORMAT_DTHMA, result); - return ERROR_FAIL; - } - - uint8_t cmd_ack_code; - uint8_t extra_length; - uint8_t res_target_id; - aice_unpack_dthma(&cmd_ack_code, &res_target_id, &extra_length, - data, AICE_LITTLE_ENDIAN); - - if (cmd_ack_code == AICE_CMD_T_READ_DTR) { - LOG_DEBUG("READ_DTR response, data: 0x%" PRIx32, *data); - break; - } else { - - if (retry_times > aice_max_retry_times) { - LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")", - AICE_CMD_T_READ_DTR, cmd_ack_code); - return ERROR_FAIL; - } - - /* clear timeout and retry */ - if (aice_reset_box() != ERROR_OK) - return ERROR_FAIL; - - retry_times++; - } - } while (1); - - return ERROR_OK; -} - -static int aice_read_dtr_to_buffer(uint8_t target_id, uint32_t buffer_idx) -{ - int retry_times = 0; - - if (aice_command_mode == AICE_COMMAND_MODE_PACK) { - aice_usb_packet_flush(); - } else if (aice_command_mode == AICE_COMMAND_MODE_BATCH) { - aice_pack_htdma(AICE_CMD_READ_DTR_TO_BUFFER, target_id, 0, buffer_idx); - return aice_usb_packet_append(usb_out_buffer, AICE_FORMAT_HTDMA, - AICE_FORMAT_DTHMB); - } - - do { - aice_pack_htdma(AICE_CMD_READ_DTR_TO_BUFFER, target_id, 0, buffer_idx); - - aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMA); - - LOG_DEBUG("READ_DTR_TO_BUFFER, COREID: %" PRIu8, target_id); - - int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMB); - if (result != AICE_FORMAT_DTHMB) { - LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)", AICE_FORMAT_DTHMB, result); - return ERROR_FAIL; - } - - uint8_t cmd_ack_code; - uint8_t extra_length; - uint8_t res_target_id; - aice_unpack_dthmb(&cmd_ack_code, &res_target_id, &extra_length); - - if (cmd_ack_code == AICE_CMD_READ_DTR_TO_BUFFER) { - break; - } else { - if (retry_times > aice_max_retry_times) { - LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")", - AICE_CMD_READ_DTR_TO_BUFFER, cmd_ack_code); - - return ERROR_FAIL; - } - - /* clear timeout and retry */ - if (aice_reset_box() != ERROR_OK) - return ERROR_FAIL; - - retry_times++; - } - } while (1); - - return ERROR_OK; -} - -static int aice_write_dtr(uint8_t target_id, uint32_t data) -{ - int retry_times = 0; - - if (aice_command_mode == AICE_COMMAND_MODE_PACK) { - aice_usb_packet_flush(); - } else if (aice_command_mode == AICE_COMMAND_MODE_BATCH) { - aice_pack_htdmc(AICE_CMD_T_WRITE_DTR, target_id, 0, 0, data, AICE_LITTLE_ENDIAN); - return aice_usb_packet_append(usb_out_buffer, AICE_FORMAT_HTDMC, - AICE_FORMAT_DTHMB); - } - - do { - aice_pack_htdmc(AICE_CMD_T_WRITE_DTR, target_id, 0, 0, data, AICE_LITTLE_ENDIAN); - - aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMC); - - LOG_DEBUG("WRITE_DTR, COREID: %" PRIu8 ", data: 0x%" PRIx32, target_id, data); - - int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMB); - if (result != AICE_FORMAT_DTHMB) { - LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)", AICE_FORMAT_DTHMB, result); - return ERROR_FAIL; - } - - uint8_t cmd_ack_code; - uint8_t extra_length; - uint8_t res_target_id; - aice_unpack_dthmb(&cmd_ack_code, &res_target_id, &extra_length); - - if (cmd_ack_code == AICE_CMD_T_WRITE_DTR) { - LOG_DEBUG("WRITE_DTR response"); - break; - } else { - if (retry_times > aice_max_retry_times) { - LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")", - AICE_CMD_T_WRITE_DTR, cmd_ack_code); - - return ERROR_FAIL; - } - - /* clear timeout and retry */ - if (aice_reset_box() != ERROR_OK) - return ERROR_FAIL; - - retry_times++; - } - } while (1); - - return ERROR_OK; -} - -static int aice_write_dtr_from_buffer(uint8_t target_id, uint32_t buffer_idx) -{ - int retry_times = 0; - - if (aice_command_mode == AICE_COMMAND_MODE_PACK) { - aice_usb_packet_flush(); - } else if (aice_command_mode == AICE_COMMAND_MODE_BATCH) { - aice_pack_htdma(AICE_CMD_WRITE_DTR_FROM_BUFFER, target_id, 0, buffer_idx); - return aice_usb_packet_append(usb_out_buffer, AICE_FORMAT_HTDMA, - AICE_FORMAT_DTHMB); - } - - do { - aice_pack_htdma(AICE_CMD_WRITE_DTR_FROM_BUFFER, target_id, 0, buffer_idx); - - aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMA); - - LOG_DEBUG("WRITE_DTR_FROM_BUFFER, COREID: %" PRIu8 "", target_id); - - int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMB); - if (result != AICE_FORMAT_DTHMB) { - LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)", AICE_FORMAT_DTHMB, result); - return ERROR_FAIL; - } - - uint8_t cmd_ack_code; - uint8_t extra_length; - uint8_t res_target_id; - aice_unpack_dthmb(&cmd_ack_code, &res_target_id, &extra_length); - - if (cmd_ack_code == AICE_CMD_WRITE_DTR_FROM_BUFFER) { - break; - } else { - if (retry_times > aice_max_retry_times) { - LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")", - AICE_CMD_WRITE_DTR_FROM_BUFFER, cmd_ack_code); - - return ERROR_FAIL; - } - - /* clear timeout and retry */ - if (aice_reset_box() != ERROR_OK) - return ERROR_FAIL; - - retry_times++; - } - } while (1); - - return ERROR_OK; -} - -static int aice_read_misc(uint8_t target_id, uint32_t address, uint32_t *data) -{ - int retry_times = 0; - - if ((aice_command_mode == AICE_COMMAND_MODE_PACK) || - (aice_command_mode == AICE_COMMAND_MODE_BATCH)) - aice_usb_packet_flush(); - - do { - aice_pack_htdma(AICE_CMD_T_READ_MISC, target_id, 0, address); - - aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMA); - - LOG_DEBUG("READ_MISC, COREID: %" PRIu8 ", address: 0x%" PRIx32, target_id, address); - - int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMA); - if (result != AICE_FORMAT_DTHMA) { - LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)", - AICE_FORMAT_DTHMA, result); - return ERROR_AICE_DISCONNECT; - } - - uint8_t cmd_ack_code; - uint8_t extra_length; - uint8_t res_target_id; - aice_unpack_dthma(&cmd_ack_code, &res_target_id, &extra_length, - data, AICE_LITTLE_ENDIAN); - - if (cmd_ack_code == AICE_CMD_T_READ_MISC) { - LOG_DEBUG("READ_MISC response, data: 0x%" PRIx32, *data); - break; - } else { - if (retry_times > aice_max_retry_times) { - LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")", - AICE_CMD_T_READ_MISC, cmd_ack_code); - return ERROR_FAIL; - } - - /* clear timeout and retry */ - if (aice_reset_box() != ERROR_OK) - return ERROR_FAIL; - - retry_times++; - } - } while (1); - - return ERROR_OK; -} - -static int aice_write_misc(uint8_t target_id, uint32_t address, uint32_t data) -{ - int retry_times = 0; - - if (aice_command_mode == AICE_COMMAND_MODE_PACK) { - aice_usb_packet_flush(); - } else if (aice_command_mode == AICE_COMMAND_MODE_BATCH) { - aice_pack_htdmc(AICE_CMD_T_WRITE_MISC, target_id, 0, address, data, - AICE_LITTLE_ENDIAN); - return aice_usb_packet_append(usb_out_buffer, AICE_FORMAT_HTDMC, - AICE_FORMAT_DTHMB); - } - - do { - aice_pack_htdmc(AICE_CMD_T_WRITE_MISC, target_id, 0, address, - data, AICE_LITTLE_ENDIAN); - - aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMC); - - LOG_DEBUG("WRITE_MISC, COREID: %" PRIu8 ", address: 0x%" PRIx32 ", data: 0x%" PRIx32, - target_id, address, data); - - int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMB); - if (result != AICE_FORMAT_DTHMB) { - LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)", - AICE_FORMAT_DTHMB, result); - return ERROR_FAIL; - } - - uint8_t cmd_ack_code; - uint8_t extra_length; - uint8_t res_target_id; - aice_unpack_dthmb(&cmd_ack_code, &res_target_id, &extra_length); - - if (cmd_ack_code == AICE_CMD_T_WRITE_MISC) { - LOG_DEBUG("WRITE_MISC response"); - break; - } else { - if (retry_times > aice_max_retry_times) { - LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")", - AICE_CMD_T_WRITE_MISC, cmd_ack_code); - - return ERROR_FAIL; - } - - /* clear timeout and retry */ - if (aice_reset_box() != ERROR_OK) - return ERROR_FAIL; - - retry_times++; - } - } while (1); - - return ERROR_OK; -} - -static int aice_read_edmsr(uint8_t target_id, uint32_t address, uint32_t *data) -{ - int retry_times = 0; - - if ((aice_command_mode == AICE_COMMAND_MODE_PACK) || - (aice_command_mode == AICE_COMMAND_MODE_BATCH)) - aice_usb_packet_flush(); - - do { - aice_pack_htdma(AICE_CMD_T_READ_EDMSR, target_id, 0, address); - - aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMA); - - LOG_DEBUG("READ_EDMSR, COREID: %" PRIu8 ", address: 0x%" PRIx32, target_id, address); - - int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMA); - if (result != AICE_FORMAT_DTHMA) { - LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)", - AICE_FORMAT_DTHMA, result); - return ERROR_FAIL; - } - - uint8_t cmd_ack_code; - uint8_t extra_length; - uint8_t res_target_id; - aice_unpack_dthma(&cmd_ack_code, &res_target_id, &extra_length, - data, AICE_LITTLE_ENDIAN); - - if (cmd_ack_code == AICE_CMD_T_READ_EDMSR) { - LOG_DEBUG("READ_EDMSR response, data: 0x%" PRIx32, *data); - break; - } else { - if (retry_times > aice_max_retry_times) { - LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")", - AICE_CMD_T_READ_EDMSR, cmd_ack_code); - - return ERROR_FAIL; - } - - /* clear timeout and retry */ - if (aice_reset_box() != ERROR_OK) - return ERROR_FAIL; - - retry_times++; - } - } while (1); - - return ERROR_OK; -} - -static int aice_write_edmsr(uint8_t target_id, uint32_t address, uint32_t data) -{ - int retry_times = 0; - - if (aice_command_mode == AICE_COMMAND_MODE_PACK) { - aice_usb_packet_flush(); - } else if (aice_command_mode == AICE_COMMAND_MODE_BATCH) { - aice_pack_htdmc(AICE_CMD_T_WRITE_EDMSR, target_id, 0, address, data, - AICE_LITTLE_ENDIAN); - return aice_usb_packet_append(usb_out_buffer, AICE_FORMAT_HTDMC, - AICE_FORMAT_DTHMB); - } - - do { - aice_pack_htdmc(AICE_CMD_T_WRITE_EDMSR, target_id, 0, address, - data, AICE_LITTLE_ENDIAN); - - aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMC); - - LOG_DEBUG("WRITE_EDMSR, COREID: %" PRIu8 ", address: 0x%" PRIx32 ", data: 0x%" PRIx32, - target_id, address, data); - - int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMB); - if (result != AICE_FORMAT_DTHMB) { - LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)", - AICE_FORMAT_DTHMB, result); - return ERROR_FAIL; - } - - uint8_t cmd_ack_code; - uint8_t extra_length; - uint8_t res_target_id; - aice_unpack_dthmb(&cmd_ack_code, &res_target_id, &extra_length); - - if (cmd_ack_code == AICE_CMD_T_WRITE_EDMSR) { - LOG_DEBUG("WRITE_EDMSR response"); - break; - } else { - if (retry_times > aice_max_retry_times) { - LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")", - AICE_CMD_T_WRITE_EDMSR, cmd_ack_code); - - return ERROR_FAIL; - } - - /* clear timeout and retry */ - if (aice_reset_box() != ERROR_OK) - return ERROR_FAIL; - - retry_times++; - } - } while (1); - - return ERROR_OK; -} - -static int aice_switch_to_big_endian(uint32_t *word, uint8_t num_of_words) -{ - uint32_t tmp; - - for (uint8_t i = 0 ; i < num_of_words ; i++) { - tmp = ((word[i] >> 24) & 0x000000FF) | - ((word[i] >> 8) & 0x0000FF00) | - ((word[i] << 8) & 0x00FF0000) | - ((word[i] << 24) & 0xFF000000); - word[i] = tmp; - } - - return ERROR_OK; -} - -static int aice_write_dim(uint8_t target_id, uint32_t *word, uint8_t num_of_words) -{ - uint32_t big_endian_word[4]; - int retry_times = 0; - - /** instruction is big-endian */ - memcpy(big_endian_word, word, sizeof(big_endian_word)); - aice_switch_to_big_endian(big_endian_word, num_of_words); - - if (aice_command_mode == AICE_COMMAND_MODE_PACK) { - aice_usb_packet_flush(); - } else if (aice_command_mode == AICE_COMMAND_MODE_BATCH) { - aice_pack_htdmc_multiple_data(AICE_CMD_T_WRITE_DIM, target_id, - num_of_words - 1, 0, big_endian_word, num_of_words, - AICE_LITTLE_ENDIAN); - return aice_usb_packet_append(usb_out_buffer, - AICE_FORMAT_HTDMC + (num_of_words - 1) * 4, - AICE_FORMAT_DTHMB); - } - - do { - aice_pack_htdmc_multiple_data(AICE_CMD_T_WRITE_DIM, target_id, num_of_words - 1, 0, - big_endian_word, num_of_words, AICE_LITTLE_ENDIAN); - - aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMC + (num_of_words - 1) * 4); - - LOG_DEBUG("WRITE_DIM, COREID: %" PRIu8 - ", data: 0x%08" PRIx32 ", 0x%08" PRIx32 ", 0x%08" PRIx32 ", 0x%08" PRIx32, - target_id, - big_endian_word[0], - big_endian_word[1], - big_endian_word[2], - big_endian_word[3]); - - int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMB); - if (result != AICE_FORMAT_DTHMB) { - LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)", AICE_FORMAT_DTHMB, result); - return ERROR_FAIL; - } - - uint8_t cmd_ack_code; - uint8_t extra_length; - uint8_t res_target_id; - aice_unpack_dthmb(&cmd_ack_code, &res_target_id, &extra_length); - - - if (cmd_ack_code == AICE_CMD_T_WRITE_DIM) { - LOG_DEBUG("WRITE_DIM response"); - break; - } else { - if (retry_times > aice_max_retry_times) { - LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")", - AICE_CMD_T_WRITE_DIM, cmd_ack_code); - - return ERROR_FAIL; - } - - /* clear timeout and retry */ - if (aice_reset_box() != ERROR_OK) - return ERROR_FAIL; - - retry_times++; - } - } while (1); - - return ERROR_OK; -} - -static int aice_do_execute(uint8_t target_id) -{ - int retry_times = 0; - - if (aice_command_mode == AICE_COMMAND_MODE_PACK) { - aice_usb_packet_flush(); - } else if (aice_command_mode == AICE_COMMAND_MODE_BATCH) { - aice_pack_htdmc(AICE_CMD_T_EXECUTE, target_id, 0, 0, 0, AICE_LITTLE_ENDIAN); - return aice_usb_packet_append(usb_out_buffer, - AICE_FORMAT_HTDMC, - AICE_FORMAT_DTHMB); - } - - do { - aice_pack_htdmc(AICE_CMD_T_EXECUTE, target_id, 0, 0, 0, AICE_LITTLE_ENDIAN); - - aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMC); - - LOG_DEBUG("EXECUTE, COREID: %" PRIu8 "", target_id); - - int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMB); - if (result != AICE_FORMAT_DTHMB) { - LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)", - AICE_FORMAT_DTHMB, result); - return ERROR_FAIL; - } - - uint8_t cmd_ack_code; - uint8_t extra_length; - uint8_t res_target_id; - aice_unpack_dthmb(&cmd_ack_code, &res_target_id, &extra_length); - - if (cmd_ack_code == AICE_CMD_T_EXECUTE) { - LOG_DEBUG("EXECUTE response"); - break; - } else { - if (retry_times > aice_max_retry_times) { - LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")", - AICE_CMD_T_EXECUTE, cmd_ack_code); - - return ERROR_FAIL; - } - - /* clear timeout and retry */ - if (aice_reset_box() != ERROR_OK) - return ERROR_FAIL; - - retry_times++; - } - } while (1); - - return ERROR_OK; -} - -static int aice_write_mem_b(uint8_t target_id, uint32_t address, uint32_t data) -{ - int retry_times = 0; - - LOG_DEBUG("WRITE_MEM_B, COREID: %" PRIu8 ", ADDRESS %08" PRIx32 " VALUE %08" PRIx32, - target_id, - address, - data); - - if ((aice_command_mode == AICE_COMMAND_MODE_PACK) || - (aice_command_mode == AICE_COMMAND_MODE_BATCH)) { - aice_pack_htdmd(AICE_CMD_T_WRITE_MEM_B, target_id, 0, address, - data & 0x000000FF, data_endian); - return aice_usb_packet_append(usb_out_buffer, AICE_FORMAT_HTDMD, - AICE_FORMAT_DTHMB); - } else { - do { - aice_pack_htdmd(AICE_CMD_T_WRITE_MEM_B, target_id, 0, - address, data & 0x000000FF, data_endian); - aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMD); - - int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMB); - if (result != AICE_FORMAT_DTHMB) { - LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)", AICE_FORMAT_DTHMB, result); - return ERROR_FAIL; - } - - uint8_t cmd_ack_code; - uint8_t extra_length; - uint8_t res_target_id; - aice_unpack_dthmb(&cmd_ack_code, &res_target_id, &extra_length); - - if (cmd_ack_code == AICE_CMD_T_WRITE_MEM_B) { - break; - } else { - if (retry_times > aice_max_retry_times) { - LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")", - AICE_CMD_T_WRITE_MEM_B, cmd_ack_code); - - return ERROR_FAIL; - } - - /* clear timeout and retry */ - if (aice_reset_box() != ERROR_OK) - return ERROR_FAIL; - - retry_times++; - } - } while (1); - } - - return ERROR_OK; -} - -static int aice_write_mem_h(uint8_t target_id, uint32_t address, uint32_t data) -{ - int retry_times = 0; - - LOG_DEBUG("WRITE_MEM_H, COREID: %" PRIu8 ", ADDRESS %08" PRIx32 " VALUE %08" PRIx32, - target_id, - address, - data); - - if ((aice_command_mode == AICE_COMMAND_MODE_PACK) || - (aice_command_mode == AICE_COMMAND_MODE_BATCH)) { - aice_pack_htdmd(AICE_CMD_T_WRITE_MEM_H, target_id, 0, - (address >> 1) & 0x7FFFFFFF, data & 0x0000FFFF, data_endian); - return aice_usb_packet_append(usb_out_buffer, AICE_FORMAT_HTDMD, - AICE_FORMAT_DTHMB); - } else { - do { - aice_pack_htdmd(AICE_CMD_T_WRITE_MEM_H, target_id, 0, - (address >> 1) & 0x7FFFFFFF, data & 0x0000FFFF, data_endian); - aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMD); - - int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMB); - if (result != AICE_FORMAT_DTHMB) { - LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)", - AICE_FORMAT_DTHMB, result); - return ERROR_FAIL; - } - - uint8_t cmd_ack_code; - uint8_t extra_length; - uint8_t res_target_id; - aice_unpack_dthmb(&cmd_ack_code, &res_target_id, &extra_length); - - if (cmd_ack_code == AICE_CMD_T_WRITE_MEM_H) { - break; - } else { - if (retry_times > aice_max_retry_times) { - LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")", - AICE_CMD_T_WRITE_MEM_H, cmd_ack_code); - - return ERROR_FAIL; - } - - /* clear timeout and retry */ - if (aice_reset_box() != ERROR_OK) - return ERROR_FAIL; - - retry_times++; - } - } while (1); - } - - return ERROR_OK; -} - -static int aice_write_mem(uint8_t target_id, uint32_t address, uint32_t data) -{ - int retry_times = 0; - - LOG_DEBUG("WRITE_MEM, COREID: %" PRIu8 ", ADDRESS %08" PRIx32 " VALUE %08" PRIx32, - target_id, - address, - data); - - if ((aice_command_mode == AICE_COMMAND_MODE_PACK) || - (aice_command_mode == AICE_COMMAND_MODE_BATCH)) { - aice_pack_htdmd(AICE_CMD_T_WRITE_MEM, target_id, 0, - (address >> 2) & 0x3FFFFFFF, data, data_endian); - return aice_usb_packet_append(usb_out_buffer, AICE_FORMAT_HTDMD, - AICE_FORMAT_DTHMB); - } else { - do { - aice_pack_htdmd(AICE_CMD_T_WRITE_MEM, target_id, 0, - (address >> 2) & 0x3FFFFFFF, data, data_endian); - aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMD); - - int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMB); - if (result != AICE_FORMAT_DTHMB) { - LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)", - AICE_FORMAT_DTHMB, result); - return ERROR_FAIL; - } - - uint8_t cmd_ack_code; - uint8_t extra_length; - uint8_t res_target_id; - aice_unpack_dthmb(&cmd_ack_code, &res_target_id, &extra_length); - - if (cmd_ack_code == AICE_CMD_T_WRITE_MEM) { - break; - } else { - if (retry_times > aice_max_retry_times) { - LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")", - AICE_CMD_T_WRITE_MEM, cmd_ack_code); - - return ERROR_FAIL; - } - - /* clear timeout and retry */ - if (aice_reset_box() != ERROR_OK) - return ERROR_FAIL; - - retry_times++; - } - } while (1); - } - - return ERROR_OK; -} - -static int aice_fastread_mem(uint8_t target_id, uint8_t *word, uint32_t num_of_words) -{ - int retry_times = 0; - - if ((aice_command_mode == AICE_COMMAND_MODE_PACK) || - (aice_command_mode == AICE_COMMAND_MODE_BATCH)) - aice_usb_packet_flush(); - - do { - aice_pack_htdmb(AICE_CMD_T_FASTREAD_MEM, target_id, num_of_words - 1, 0); - - aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMB); - - LOG_DEBUG("FASTREAD_MEM, COREID: %" PRIu8 ", # of DATA %08" PRIx32, - target_id, num_of_words); - - int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMA + (num_of_words - 1) * 4); - if (result < 0) { - LOG_ERROR("aice_usb_read failed (requested=%" PRIu32 ", result=%d)", - AICE_FORMAT_DTHMA + (num_of_words - 1) * 4, result); - return ERROR_FAIL; - } - - uint8_t cmd_ack_code; - uint8_t extra_length; - uint8_t res_target_id; - aice_unpack_dthma_multiple_data(&cmd_ack_code, &res_target_id, - &extra_length, word, data_endian); - - if (cmd_ack_code == AICE_CMD_T_FASTREAD_MEM) { - break; - } else { - if (retry_times > aice_max_retry_times) { - LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")", - AICE_CMD_T_FASTREAD_MEM, cmd_ack_code); - - return ERROR_FAIL; - } - - /* clear timeout and retry */ - if (aice_reset_box() != ERROR_OK) - return ERROR_FAIL; - - retry_times++; - } - } while (1); - - return ERROR_OK; -} - -static int aice_fastwrite_mem(uint8_t target_id, const uint8_t *word, uint32_t num_of_words) -{ - int retry_times = 0; - - if (aice_command_mode == AICE_COMMAND_MODE_PACK) { - aice_usb_packet_flush(); - } else if (aice_command_mode == AICE_COMMAND_MODE_BATCH) { - aice_pack_htdmd_multiple_data(AICE_CMD_T_FASTWRITE_MEM, target_id, - num_of_words - 1, 0, word, data_endian); - return aice_usb_packet_append(usb_out_buffer, - AICE_FORMAT_HTDMD + (num_of_words - 1) * 4, - AICE_FORMAT_DTHMB); - } - - do { - aice_pack_htdmd_multiple_data(AICE_CMD_T_FASTWRITE_MEM, target_id, - num_of_words - 1, 0, word, data_endian); - - aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMD + (num_of_words - 1) * 4); - - LOG_DEBUG("FASTWRITE_MEM, COREID: %" PRIu8 ", # of DATA %08" PRIx32, - target_id, num_of_words); - - int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMB); - if (result != AICE_FORMAT_DTHMB) { - LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)", - AICE_FORMAT_DTHMB, result); - return ERROR_FAIL; - } - - uint8_t cmd_ack_code; - uint8_t extra_length; - uint8_t res_target_id; - aice_unpack_dthmb(&cmd_ack_code, &res_target_id, &extra_length); - - if (cmd_ack_code == AICE_CMD_T_FASTWRITE_MEM) { - break; - } else { - if (retry_times > aice_max_retry_times) { - LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")", - AICE_CMD_T_FASTWRITE_MEM, cmd_ack_code); - - return ERROR_FAIL; - } - - /* clear timeout and retry */ - if (aice_reset_box() != ERROR_OK) - return ERROR_FAIL; - - retry_times++; - } - } while (1); - - return ERROR_OK; -} - -static int aice_read_mem_b(uint8_t target_id, uint32_t address, uint32_t *data) -{ - int retry_times = 0; - - if ((aice_command_mode == AICE_COMMAND_MODE_PACK) || - (aice_command_mode == AICE_COMMAND_MODE_BATCH)) - aice_usb_packet_flush(); - - do { - aice_pack_htdmb(AICE_CMD_T_READ_MEM_B, target_id, 0, address); - - aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMB); - - LOG_DEBUG("READ_MEM_B, COREID: %" PRIu8 "", target_id); - - int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMA); - if (result != AICE_FORMAT_DTHMA) { - LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)", - AICE_FORMAT_DTHMA, result); - return ERROR_FAIL; - } - - uint8_t cmd_ack_code; - uint8_t extra_length; - uint8_t res_target_id; - aice_unpack_dthma(&cmd_ack_code, &res_target_id, &extra_length, - data, data_endian); - - if (cmd_ack_code == AICE_CMD_T_READ_MEM_B) { - LOG_DEBUG("READ_MEM_B response, data: 0x%02" PRIx32, *data); - break; - } else { - if (retry_times > aice_max_retry_times) { - LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")", - AICE_CMD_T_READ_MEM_B, cmd_ack_code); - - return ERROR_FAIL; - } - - /* clear timeout and retry */ - if (aice_reset_box() != ERROR_OK) - return ERROR_FAIL; - - retry_times++; - } - } while (1); - - return ERROR_OK; -} - -static int aice_read_mem_h(uint8_t target_id, uint32_t address, uint32_t *data) -{ - int retry_times = 0; - - if ((aice_command_mode == AICE_COMMAND_MODE_PACK) || - (aice_command_mode == AICE_COMMAND_MODE_BATCH)) - aice_usb_packet_flush(); - - do { - aice_pack_htdmb(AICE_CMD_T_READ_MEM_H, target_id, 0, (address >> 1) & 0x7FFFFFFF); - - aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMB); - - LOG_DEBUG("READ_MEM_H, CORE_ID: %" PRIu8 "", target_id); - - int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMA); - if (result != AICE_FORMAT_DTHMA) { - LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)", - AICE_FORMAT_DTHMA, result); - return ERROR_FAIL; - } - - uint8_t cmd_ack_code; - uint8_t extra_length; - uint8_t res_target_id; - aice_unpack_dthma(&cmd_ack_code, &res_target_id, &extra_length, - data, data_endian); - - if (cmd_ack_code == AICE_CMD_T_READ_MEM_H) { - LOG_DEBUG("READ_MEM_H response, data: 0x%" PRIx32, *data); - break; - } else { - if (retry_times > aice_max_retry_times) { - LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")", - AICE_CMD_T_READ_MEM_H, cmd_ack_code); - - return ERROR_FAIL; - } - - /* clear timeout and retry */ - if (aice_reset_box() != ERROR_OK) - return ERROR_FAIL; - - retry_times++; - } - } while (1); - - return ERROR_OK; -} - -static int aice_read_mem(uint8_t target_id, uint32_t address, uint32_t *data) -{ - int retry_times = 0; - - if ((aice_command_mode == AICE_COMMAND_MODE_PACK) || - (aice_command_mode == AICE_COMMAND_MODE_BATCH)) - aice_usb_packet_flush(); - - do { - aice_pack_htdmb(AICE_CMD_T_READ_MEM, target_id, 0, - (address >> 2) & 0x3FFFFFFF); - - aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMB); - - LOG_DEBUG("READ_MEM, COREID: %" PRIu8 "", target_id); - - int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMA); - if (result != AICE_FORMAT_DTHMA) { - LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)", - AICE_FORMAT_DTHMA, result); - return ERROR_FAIL; - } - - uint8_t cmd_ack_code; - uint8_t extra_length; - uint8_t res_target_id; - aice_unpack_dthma(&cmd_ack_code, &res_target_id, &extra_length, - data, data_endian); - - if (cmd_ack_code == AICE_CMD_T_READ_MEM) { - LOG_DEBUG("READ_MEM response, data: 0x%" PRIx32, *data); - break; - } else { - if (retry_times > aice_max_retry_times) { - LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")", - AICE_CMD_T_READ_MEM, cmd_ack_code); - - return ERROR_FAIL; - } - - /* clear timeout and retry */ - if (aice_reset_box() != ERROR_OK) - return ERROR_FAIL; - - retry_times++; - } - } while (1); - - return ERROR_OK; -} - -static int aice_batch_buffer_read(uint8_t buf_index, uint32_t *word, uint32_t num_of_words) -{ - int retry_times = 0; - - do { - aice_pack_htdma(AICE_CMD_BATCH_BUFFER_READ, 0, num_of_words - 1, buf_index); - - aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMA); - - LOG_DEBUG("BATCH_BUFFER_READ, # of DATA %08" PRIx32, num_of_words); - - int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMA + (num_of_words - 1) * 4); - if (result < 0) { - LOG_ERROR("aice_usb_read failed (requested=%" PRIu32 ", result=%d)", - AICE_FORMAT_DTHMA + (num_of_words - 1) * 4, result); - return ERROR_FAIL; - } - - uint8_t cmd_ack_code; - uint8_t extra_length; - uint8_t res_target_id; - aice_unpack_dthma_multiple_data(&cmd_ack_code, &res_target_id, - &extra_length, (uint8_t *)word, data_endian); - - if (cmd_ack_code == AICE_CMD_BATCH_BUFFER_READ) { - break; - } else { - if (retry_times > aice_max_retry_times) { - LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")", - AICE_CMD_BATCH_BUFFER_READ, cmd_ack_code); - - return ERROR_FAIL; - } - - /* clear timeout and retry */ - if (aice_reset_box() != ERROR_OK) - return ERROR_FAIL; - - retry_times++; - } - } while (1); - - return ERROR_OK; -} - -int aice_batch_buffer_write(uint8_t buf_index, const uint8_t *word, uint32_t num_of_words) -{ - int retry_times = 0; - - if (num_of_words == 0) - return ERROR_OK; - - do { - /* only pack AICE_CMD_BATCH_BUFFER_WRITE command header */ - aice_pack_htdmc(AICE_CMD_BATCH_BUFFER_WRITE, 0, num_of_words - 1, buf_index, - 0, data_endian); - - /* use append instead of pack */ - memcpy(usb_out_buffer + 4, word, num_of_words * 4); - - aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMC + (num_of_words - 1) * 4); - - LOG_DEBUG("BATCH_BUFFER_WRITE, # of DATA %08" PRIx32, num_of_words); - - int result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMB); - if (result != AICE_FORMAT_DTHMB) { - LOG_ERROR("aice_usb_read failed (requested=%d, result=%d)", - AICE_FORMAT_DTHMB, result); - return ERROR_FAIL; - } - - uint8_t cmd_ack_code; - uint8_t extra_length; - uint8_t res_target_id; - aice_unpack_dthmb(&cmd_ack_code, &res_target_id, &extra_length); - - if (cmd_ack_code == AICE_CMD_BATCH_BUFFER_WRITE) { - break; - } else { - if (retry_times > aice_max_retry_times) { - LOG_ERROR("aice command timeout (command=0x%x, response=0x%" PRIx8 ")", - AICE_CMD_BATCH_BUFFER_WRITE, cmd_ack_code); - - return ERROR_FAIL; - } - - /* clear timeout and retry */ - if (aice_reset_box() != ERROR_OK) - return ERROR_FAIL; - - retry_times++; - } - } while (1); - - return ERROR_OK; -} - -/***************************************************************************/ -/* End of AICE commands */ - -typedef int (*read_mem_func_t)(uint32_t coreid, uint32_t address, uint32_t *data); -typedef int (*write_mem_func_t)(uint32_t coreid, uint32_t address, uint32_t data); - -static struct aice_nds32_info core_info[AICE_MAX_NUM_CORE]; -static uint8_t total_num_of_core; - -static char *custom_srst_script; -static char *custom_trst_script; -static char *custom_restart_script; -static uint32_t aice_count_to_check_dbger = 30; - -static int aice_read_reg(uint32_t coreid, uint32_t num, uint32_t *val); -static int aice_write_reg(uint32_t coreid, uint32_t num, uint32_t val); - -static int check_suppressed_exception(uint32_t coreid, uint32_t dbger_value) -{ - uint32_t ir4_value = 0; - uint32_t ir6_value = 0; - /* the default value of handling_suppressed_exception is false */ - static bool handling_suppressed_exception; - - if (handling_suppressed_exception) - return ERROR_OK; - - if ((dbger_value & NDS_DBGER_ALL_SUPRS_EX) == NDS_DBGER_ALL_SUPRS_EX) { - LOG_ERROR("<-- TARGET WARNING! Exception is detected and suppressed. -->"); - handling_suppressed_exception = true; - - aice_read_reg(coreid, IR4, &ir4_value); - /* Clear IR6.SUPRS_EXC, IR6.IMP_EXC */ - aice_read_reg(coreid, IR6, &ir6_value); - /* - * For MCU version(MSC_CFG.MCU == 1) like V3m - * | SWID[30:16] | Reserved[15:10] | SUPRS_EXC[9] | IMP_EXC[8] - * |VECTOR[7:5] | INST[4] | Exc Type[3:0] | - * - * For non-MCU version(MSC_CFG.MCU == 0) like V3 - * | SWID[30:16] | Reserved[15:14] | SUPRS_EXC[13] | IMP_EXC[12] - * | VECTOR[11:5] | INST[4] | Exc Type[3:0] | - */ - LOG_INFO("EVA: 0x%08" PRIx32, ir4_value); - LOG_INFO("ITYPE: 0x%08" PRIx32, ir6_value); - - ir6_value = ir6_value & (~0x300); /* for MCU */ - ir6_value = ir6_value & (~0x3000); /* for non-MCU */ - aice_write_reg(coreid, IR6, ir6_value); - - handling_suppressed_exception = false; - } - - return ERROR_OK; -} - -static int check_privilege(uint32_t coreid, uint32_t dbger_value) -{ - if ((dbger_value & NDS_DBGER_ILL_SEC_ACC) == NDS_DBGER_ILL_SEC_ACC) { - LOG_ERROR("<-- TARGET ERROR! Insufficient security privilege " - "to execute the debug operations. -->"); - - /* Clear DBGER.ILL_SEC_ACC */ - if (aice_write_misc(coreid, NDS_EDM_MISC_DBGER, - NDS_DBGER_ILL_SEC_ACC) != ERROR_OK) - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int aice_check_dbger(uint32_t coreid, uint32_t expect_status) -{ - uint32_t i = 0; - uint32_t value_dbger = 0; - - while (1) { - aice_read_misc(coreid, NDS_EDM_MISC_DBGER, &value_dbger); - - if ((value_dbger & expect_status) == expect_status) { - if (check_suppressed_exception(coreid, value_dbger) != ERROR_OK) - return ERROR_FAIL; - if (check_privilege(coreid, value_dbger) != ERROR_OK) - return ERROR_FAIL; - return ERROR_OK; - } - - if ((i % 30) == 0) - keep_alive(); - - int64_t then = 0; - if (i == aice_count_to_check_dbger) - then = timeval_ms(); - if (i >= aice_count_to_check_dbger) { - if ((timeval_ms() - then) > 1000) { - LOG_ERROR("Timeout (1000ms) waiting for $DBGER status " - "being 0x%08" PRIx32, expect_status); - return ERROR_FAIL; - } - } - i++; - } - - return ERROR_FAIL; -} - -static int aice_execute_dim(uint32_t coreid, uint32_t *insts, uint8_t n_inst) -{ - /** fill DIM */ - if (aice_write_dim(coreid, insts, n_inst) != ERROR_OK) - return ERROR_FAIL; - - /** clear DBGER.DPED */ - if (aice_write_misc(coreid, NDS_EDM_MISC_DBGER, NDS_DBGER_DPED) != ERROR_OK) - return ERROR_FAIL; - - /** execute DIM */ - if (aice_do_execute(coreid) != ERROR_OK) - return ERROR_FAIL; - - /** read DBGER.DPED */ - if (aice_check_dbger(coreid, NDS_DBGER_DPED) != ERROR_OK) { - LOG_ERROR("<-- TARGET ERROR! Debug operations do not finish properly: " - "0x%08" PRIx32 "0x%08" PRIx32 "0x%08" PRIx32 "0x%08" PRIx32 ". -->", - insts[0], - insts[1], - insts[2], - insts[3]); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int aice_read_reg(uint32_t coreid, uint32_t num, uint32_t *val) -{ - LOG_DEBUG("aice_read_reg, reg_no: 0x%08" PRIx32, num); - - uint32_t instructions[4]; /** execute instructions in DIM */ - - if (nds32_reg_type(num) == NDS32_REG_TYPE_GPR) { /* general registers */ - instructions[0] = MTSR_DTR(num); - instructions[1] = DSB; - instructions[2] = NOP; - instructions[3] = BEQ_MINUS_12; - } else if (nds32_reg_type(num) == NDS32_REG_TYPE_SPR) { /* user special registers */ - instructions[0] = MFUSR_G0(0, nds32_reg_sr_index(num)); - instructions[1] = MTSR_DTR(0); - instructions[2] = DSB; - instructions[3] = BEQ_MINUS_12; - } else if (nds32_reg_type(num) == NDS32_REG_TYPE_AUMR) { /* audio registers */ - if ((num >= CB_CTL) && (num <= CBE3)) { - instructions[0] = AMFAR2(0, nds32_reg_sr_index(num)); - instructions[1] = MTSR_DTR(0); - instructions[2] = DSB; - instructions[3] = BEQ_MINUS_12; - } else { - instructions[0] = AMFAR(0, nds32_reg_sr_index(num)); - instructions[1] = MTSR_DTR(0); - instructions[2] = DSB; - instructions[3] = BEQ_MINUS_12; - } - } else if (nds32_reg_type(num) == NDS32_REG_TYPE_FPU) { /* fpu registers */ - if (num == FPCSR) { - instructions[0] = FMFCSR; - instructions[1] = MTSR_DTR(0); - instructions[2] = DSB; - instructions[3] = BEQ_MINUS_12; - } else if (num == FPCFG) { - instructions[0] = FMFCFG; - instructions[1] = MTSR_DTR(0); - instructions[2] = DSB; - instructions[3] = BEQ_MINUS_12; - } else { - if (num >= FS0 && num <= FS31) { /* single precision */ - instructions[0] = FMFSR(0, nds32_reg_sr_index(num)); - instructions[1] = MTSR_DTR(0); - instructions[2] = DSB; - instructions[3] = BEQ_MINUS_12; - } else if (num >= FD0 && num <= FD31) { /* double precision */ - instructions[0] = FMFDR(0, nds32_reg_sr_index(num)); - instructions[1] = MTSR_DTR(0); - instructions[2] = DSB; - instructions[3] = BEQ_MINUS_12; - } - } - } else { /* system registers */ - instructions[0] = MFSR(0, nds32_reg_sr_index(num)); - instructions[1] = MTSR_DTR(0); - instructions[2] = DSB; - instructions[3] = BEQ_MINUS_12; - } - - aice_execute_dim(coreid, instructions, 4); - - uint32_t value_edmsw = 0; - aice_read_edmsr(coreid, NDS_EDM_SR_EDMSW, &value_edmsw); - if (value_edmsw & NDS_EDMSW_WDV) - aice_read_dtr(coreid, val); - else { - LOG_ERROR("<-- TARGET ERROR! The debug target failed to update " - "the DTR register. -->"); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int aice_usb_read_reg(uint32_t coreid, uint32_t num, uint32_t *val) -{ - LOG_DEBUG("aice_usb_read_reg"); - - if (num == R0) { - *val = core_info[coreid].r0_backup; - } else if (num == R1) { - *val = core_info[coreid].r1_backup; - } else if (num == DR41) { - /* As target is halted, OpenOCD will backup DR41/DR42/DR43. - * As user wants to read these registers, OpenOCD should return - * the backup values, instead of reading the real values. - * As user wants to write these registers, OpenOCD should write - * to the backup values, instead of writing to real registers. */ - *val = core_info[coreid].edmsw_backup; - } else if (num == DR42) { - *val = core_info[coreid].edm_ctl_backup; - } else if ((core_info[coreid].target_dtr_valid == true) && (num == DR43)) { - *val = core_info[coreid].target_dtr_backup; - } else { - if (aice_read_reg(coreid, num, val) != ERROR_OK) - *val = 0xBBADBEEF; - } - - return ERROR_OK; -} - -static int aice_write_reg(uint32_t coreid, uint32_t num, uint32_t val) -{ - LOG_DEBUG("aice_write_reg, reg_no: 0x%08" PRIx32 ", value: 0x%08" PRIx32, num, val); - - uint32_t instructions[4]; /** execute instructions in DIM */ - uint32_t value_edmsw = 0; - - aice_write_dtr(coreid, val); - aice_read_edmsr(coreid, NDS_EDM_SR_EDMSW, &value_edmsw); - if (0 == (value_edmsw & NDS_EDMSW_RDV)) { - LOG_ERROR("<-- TARGET ERROR! AICE failed to write to the DTR register. -->"); - return ERROR_FAIL; - } - - if (nds32_reg_type(num) == NDS32_REG_TYPE_GPR) { /* general registers */ - instructions[0] = MFSR_DTR(num); - instructions[1] = DSB; - instructions[2] = NOP; - instructions[3] = BEQ_MINUS_12; - } else if (nds32_reg_type(num) == NDS32_REG_TYPE_SPR) { /* user special registers */ - instructions[0] = MFSR_DTR(0); - instructions[1] = MTUSR_G0(0, nds32_reg_sr_index(num)); - instructions[2] = DSB; - instructions[3] = BEQ_MINUS_12; - } else if (nds32_reg_type(num) == NDS32_REG_TYPE_AUMR) { /* audio registers */ - if ((num >= CB_CTL) && (num <= CBE3)) { - instructions[0] = MFSR_DTR(0); - instructions[1] = AMTAR2(0, nds32_reg_sr_index(num)); - instructions[2] = DSB; - instructions[3] = BEQ_MINUS_12; - } else { - instructions[0] = MFSR_DTR(0); - instructions[1] = AMTAR(0, nds32_reg_sr_index(num)); - instructions[2] = DSB; - instructions[3] = BEQ_MINUS_12; - } - } else if (nds32_reg_type(num) == NDS32_REG_TYPE_FPU) { /* fpu registers */ - if (num == FPCSR) { - instructions[0] = MFSR_DTR(0); - instructions[1] = FMTCSR; - instructions[2] = DSB; - instructions[3] = BEQ_MINUS_12; - } else if (num == FPCFG) { - /* FPCFG is readonly */ - } else { - if (num >= FS0 && num <= FS31) { /* single precision */ - instructions[0] = MFSR_DTR(0); - instructions[1] = FMTSR(0, nds32_reg_sr_index(num)); - instructions[2] = DSB; - instructions[3] = BEQ_MINUS_12; - } else if (num >= FD0 && num <= FD31) { /* double precision */ - instructions[0] = MFSR_DTR(0); - instructions[1] = FMTDR(0, nds32_reg_sr_index(num)); - instructions[2] = DSB; - instructions[3] = BEQ_MINUS_12; - } - } - } else { - instructions[0] = MFSR_DTR(0); - instructions[1] = MTSR(0, nds32_reg_sr_index(num)); - instructions[2] = DSB; - instructions[3] = BEQ_MINUS_12; - } - - return aice_execute_dim(coreid, instructions, 4); -} - -static int aice_usb_write_reg(uint32_t coreid, uint32_t num, uint32_t val) -{ - LOG_DEBUG("aice_usb_write_reg"); - - if (num == R0) - core_info[coreid].r0_backup = val; - else if (num == R1) - core_info[coreid].r1_backup = val; - else if (num == DR42) - /* As target is halted, OpenOCD will backup DR41/DR42/DR43. - * As user wants to read these registers, OpenOCD should return - * the backup values, instead of reading the real values. - * As user wants to write these registers, OpenOCD should write - * to the backup values, instead of writing to real registers. */ - core_info[coreid].edm_ctl_backup = val; - else if ((core_info[coreid].target_dtr_valid == true) && (num == DR43)) - core_info[coreid].target_dtr_backup = val; - else - return aice_write_reg(coreid, num, val); - - return ERROR_OK; -} - -static int aice_usb_open(struct aice_port_param_s *param) -{ - const uint16_t vids[] = { param->vid, 0 }; - const uint16_t pids[] = { param->pid, 0 }; - struct libusb_device_handle *devh; - - if (jtag_libusb_open(vids, pids, &devh, NULL) != ERROR_OK) - return ERROR_FAIL; - - /* BE ***VERY CAREFUL*** ABOUT MAKING CHANGES IN THIS - * AREA!!!!!!!!!!! The behavior of libusb is not completely - * consistent across Windows, Linux, and Mac OS X platforms. - * The actions taken in the following compiler conditionals may - * not agree with published documentation for libusb, but were - * found to be necessary through trials and tribulations. Even - * little tweaks can break one or more platforms, so if you do - * make changes test them carefully on all platforms before - * committing them! - */ - -#if IS_WIN32 == 0 - - libusb_reset_device(devh); - -#if IS_DARWIN == 0 - - int timeout = 5; - /* reopen jlink after usb_reset - * on win32 this may take a second or two to re-enumerate */ - int retval; - while ((retval = jtag_libusb_open(vids, pids, &devh, NULL)) != ERROR_OK) { - usleep(1000); - timeout--; - if (!timeout) - break; - } - if (retval != ERROR_OK) - return ERROR_FAIL; -#endif - -#endif - - /* usb_set_configuration required under win32 */ - libusb_set_configuration(devh, 0); - libusb_claim_interface(devh, 0); - - unsigned int aice_read_ep; - unsigned int aice_write_ep; - - jtag_libusb_choose_interface(devh, &aice_read_ep, &aice_write_ep, -1, -1, -1, LIBUSB_TRANSFER_TYPE_BULK); - LOG_DEBUG("aice_read_ep=0x%x, aice_write_ep=0x%x", aice_read_ep, aice_write_ep); - - aice_handler.usb_read_ep = aice_read_ep; - aice_handler.usb_write_ep = aice_write_ep; - aice_handler.usb_handle = devh; - - return ERROR_OK; -} - -static int aice_usb_read_reg_64(uint32_t coreid, uint32_t num, uint64_t *val) -{ - LOG_DEBUG("aice_usb_read_reg_64, %s", nds32_reg_simple_name(num)); - - uint32_t value; - uint32_t high_value; - - if (aice_read_reg(coreid, num, &value) != ERROR_OK) - value = 0xBBADBEEF; - - aice_read_reg(coreid, R1, &high_value); - - LOG_DEBUG("low: 0x%08" PRIx32 ", high: 0x%08" PRIx32 "\n", value, high_value); - - if (data_endian == AICE_BIG_ENDIAN) - *val = (((uint64_t)high_value) << 32) | value; - else - *val = (((uint64_t)value) << 32) | high_value; - - return ERROR_OK; -} - -static int aice_usb_write_reg_64(uint32_t coreid, uint32_t num, uint64_t val) -{ - uint32_t value; - uint32_t high_value; - - if (data_endian == AICE_BIG_ENDIAN) { - value = val & 0xFFFFFFFF; - high_value = (val >> 32) & 0xFFFFFFFF; - } else { - high_value = val & 0xFFFFFFFF; - value = (val >> 32) & 0xFFFFFFFF; - } - - LOG_DEBUG("aice_usb_write_reg_64, %s, low: 0x%08" PRIx32 ", high: 0x%08" PRIx32 "\n", - nds32_reg_simple_name(num), value, high_value); - - aice_write_reg(coreid, R1, high_value); - return aice_write_reg(coreid, num, value); -} - -static int aice_get_version_info(void) -{ - uint32_t hardware_version; - uint32_t firmware_version; - uint32_t fpga_version; - - if (aice_read_ctrl(AICE_READ_CTRL_GET_HARDWARE_VERSION, &hardware_version) != ERROR_OK) - return ERROR_FAIL; - - if (aice_read_ctrl(AICE_READ_CTRL_GET_FIRMWARE_VERSION, &firmware_version) != ERROR_OK) - return ERROR_FAIL; - - if (aice_read_ctrl(AICE_READ_CTRL_GET_FPGA_VERSION, &fpga_version) != ERROR_OK) - return ERROR_FAIL; - - LOG_INFO("AICE version: hw_ver = 0x%" PRIx32 ", fw_ver = 0x%" PRIx32 ", fpga_ver = 0x%" PRIx32, - hardware_version, firmware_version, fpga_version); - - return ERROR_OK; -} - -#define LINE_BUFFER_SIZE 1024 - -static int aice_execute_custom_script(const char *script) -{ - FILE *script_fd; - char line_buffer[LINE_BUFFER_SIZE]; - char *op_str; - char *reset_str; - uint32_t delay; - uint32_t write_ctrl_value; - bool set_op; - - script_fd = fopen(script, "r"); - if (!script_fd) { - return ERROR_FAIL; - } else { - while (fgets(line_buffer, LINE_BUFFER_SIZE, script_fd)) { - /* execute operations */ - set_op = false; - op_str = strstr(line_buffer, "set"); - if (op_str) { - set_op = true; - goto get_reset_type; - } - - op_str = strstr(line_buffer, "clear"); - if (!op_str) - continue; -get_reset_type: - reset_str = strstr(op_str, "srst"); - if (reset_str) { - if (set_op) - write_ctrl_value = AICE_CUSTOM_DELAY_SET_SRST; - else - write_ctrl_value = AICE_CUSTOM_DELAY_CLEAN_SRST; - goto get_delay; - } - reset_str = strstr(op_str, "dbgi"); - if (reset_str) { - if (set_op) - write_ctrl_value = AICE_CUSTOM_DELAY_SET_DBGI; - else - write_ctrl_value = AICE_CUSTOM_DELAY_CLEAN_DBGI; - goto get_delay; - } - reset_str = strstr(op_str, "trst"); - if (reset_str) { - if (set_op) - write_ctrl_value = AICE_CUSTOM_DELAY_SET_TRST; - else - write_ctrl_value = AICE_CUSTOM_DELAY_CLEAN_TRST; - goto get_delay; - } - continue; -get_delay: - /* get delay */ - delay = strtoul(reset_str + 4, NULL, 0); - write_ctrl_value |= (delay << 16); - - if (aice_write_ctrl(AICE_WRITE_CTRL_CUSTOM_DELAY, - write_ctrl_value) != ERROR_OK) { - fclose(script_fd); - return ERROR_FAIL; - } - } - fclose(script_fd); - } - - return ERROR_OK; -} - -static int aice_usb_set_clock(int set_clock) -{ - if (set_clock & AICE_TCK_CONTROL_TCK_SCAN) { - if (aice_write_ctrl(AICE_WRITE_CTRL_TCK_CONTROL, - AICE_TCK_CONTROL_TCK_SCAN) != ERROR_OK) - return ERROR_FAIL; - - /* Read out TCK_SCAN clock value */ - uint32_t scan_clock; - if (aice_read_ctrl(AICE_READ_CTRL_GET_ICE_STATE, &scan_clock) != ERROR_OK) - return ERROR_FAIL; - - scan_clock &= 0x0F; - - uint32_t scan_base_freq; - if (scan_clock & 0x8) - scan_base_freq = 48000; /* 48 MHz */ - else - scan_base_freq = 30000; /* 30 MHz */ - - uint32_t set_base_freq; - if (set_clock & 0x8) - set_base_freq = 48000; - else - set_base_freq = 30000; - - uint32_t set_freq; - uint32_t scan_freq; - set_freq = set_base_freq >> (set_clock & 0x7); - scan_freq = scan_base_freq >> (scan_clock & 0x7); - - if (scan_freq < set_freq) { - LOG_ERROR("User specifies higher jtag clock than TCK_SCAN clock"); - return ERROR_FAIL; - } - } - - if (aice_write_ctrl(AICE_WRITE_CTRL_TCK_CONTROL, set_clock) != ERROR_OK) - return ERROR_FAIL; - - uint32_t check_speed; - if (aice_read_ctrl(AICE_READ_CTRL_GET_ICE_STATE, &check_speed) != ERROR_OK) - return ERROR_FAIL; - - if (((int)check_speed & 0x0F) != set_clock) { - LOG_ERROR("Set jtag clock failed"); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int aice_edm_init(uint32_t coreid) -{ - aice_write_edmsr(coreid, NDS_EDM_SR_DIMBR, 0xFFFF0000); - aice_write_misc(coreid, NDS_EDM_MISC_DIMIR, 0); - - /* unconditionally try to turn on V3_EDM_MODE */ - uint32_t edm_ctl_value; - aice_read_edmsr(coreid, NDS_EDM_SR_EDM_CTL, &edm_ctl_value); - aice_write_edmsr(coreid, NDS_EDM_SR_EDM_CTL, edm_ctl_value | 0x00000040); - - /* clear DBGER */ - aice_write_misc(coreid, NDS_EDM_MISC_DBGER, - NDS_DBGER_DPED | NDS_DBGER_CRST | NDS_DBGER_AT_MAX); - - /* get EDM version */ - uint32_t value_edmcfg; - aice_read_edmsr(coreid, NDS_EDM_SR_EDM_CFG, &value_edmcfg); - core_info[coreid].edm_version = (value_edmcfg >> 16) & 0xFFFF; - - return ERROR_OK; -} - -static bool is_v2_edm(uint32_t coreid) -{ - if ((core_info[coreid].edm_version & 0x1000) == 0) - return true; - else - return false; -} - -static int aice_init_edm_registers(uint32_t coreid, bool clear_dex_use_psw) -{ - /* enable DEH_SEL & MAX_STOP & V3_EDM_MODE & DBGI_MASK */ - uint32_t host_edm_ctl = core_info[coreid].edm_ctl_backup | 0xA000004F; - if (clear_dex_use_psw) - /* After entering debug mode, OpenOCD may set - * DEX_USE_PSW accidentally through backup value - * of target EDM_CTL. - * So, clear DEX_USE_PSW by force. */ - host_edm_ctl &= ~(0x40000000); - - LOG_DEBUG("aice_init_edm_registers - EDM_CTL: 0x%08" PRIx32, host_edm_ctl); - - int result = aice_write_edmsr(coreid, NDS_EDM_SR_EDM_CTL, host_edm_ctl); - - return result; -} - -/** - * EDM_CTL will be modified by OpenOCD as debugging. OpenOCD has the - * responsibility to keep EDM_CTL untouched after debugging. - * - * There are two scenarios to consider: - * 1. single step/running as debugging (running under debug session) - * 2. detached from gdb (exit debug session) - * - * So, we need to bakcup EDM_CTL before halted and restore it after - * running. The difference of these two scenarios is EDM_CTL.DEH_SEL - * is on for scenario 1, and off for scenario 2. - */ -static int aice_backup_edm_registers(uint32_t coreid) -{ - int result = aice_read_edmsr(coreid, NDS_EDM_SR_EDM_CTL, - &core_info[coreid].edm_ctl_backup); - - /* To call aice_backup_edm_registers() after DEX on, DEX_USE_PSW - * may be not correct. (For example, hit breakpoint, then backup - * EDM_CTL. EDM_CTL.DEX_USE_PSW will be cleared.) Because debug - * interrupt will clear DEX_USE_PSW, DEX_USE_PSW is always off after - * DEX is on. It only backups correct value before OpenOCD issues DBGI. - * (Backup EDM_CTL, then issue DBGI actively (refer aice_usb_halt())) */ - if (core_info[coreid].edm_ctl_backup & 0x40000000) - core_info[coreid].dex_use_psw_on = true; - else - core_info[coreid].dex_use_psw_on = false; - - LOG_DEBUG("aice_backup_edm_registers - EDM_CTL: 0x%08" PRIx32 ", DEX_USE_PSW: %s", - core_info[coreid].edm_ctl_backup, - core_info[coreid].dex_use_psw_on ? "on" : "off"); - - return result; -} - -static int aice_restore_edm_registers(uint32_t coreid) -{ - LOG_DEBUG("aice_restore_edm_registers -"); - - /* set DEH_SEL, because target still under EDM control */ - int result = aice_write_edmsr(coreid, NDS_EDM_SR_EDM_CTL, - core_info[coreid].edm_ctl_backup | 0x80000000); - - return result; -} - -static int aice_backup_tmp_registers(uint32_t coreid) -{ - LOG_DEBUG("backup_tmp_registers -"); - - /* backup target DTR first(if the target DTR is valid) */ - uint32_t value_edmsw = 0; - aice_read_edmsr(coreid, NDS_EDM_SR_EDMSW, &value_edmsw); - core_info[coreid].edmsw_backup = value_edmsw; - if (value_edmsw & 0x1) { /* EDMSW.WDV == 1 */ - aice_read_dtr(coreid, &core_info[coreid].target_dtr_backup); - core_info[coreid].target_dtr_valid = true; - - LOG_DEBUG("Backup target DTR: 0x%08" PRIx32, core_info[coreid].target_dtr_backup); - } else { - core_info[coreid].target_dtr_valid = false; - } - - /* Target DTR has been backup, then backup $R0 and $R1 */ - aice_read_reg(coreid, R0, &core_info[coreid].r0_backup); - aice_read_reg(coreid, R1, &core_info[coreid].r1_backup); - - /* backup host DTR(if the host DTR is valid) */ - if (value_edmsw & 0x2) { /* EDMSW.RDV == 1*/ - /* read out host DTR and write into target DTR, then use aice_read_edmsr to - * read out */ - uint32_t instructions[4] = { - MFSR_DTR(R0), /* R0 has already been backup */ - DSB, - MTSR_DTR(R0), - BEQ_MINUS_12 - }; - aice_execute_dim(coreid, instructions, 4); - - aice_read_dtr(coreid, &core_info[coreid].host_dtr_backup); - core_info[coreid].host_dtr_valid = true; - - LOG_DEBUG("Backup host DTR: 0x%08" PRIx32, core_info[coreid].host_dtr_backup); - } else { - core_info[coreid].host_dtr_valid = false; - } - - LOG_DEBUG("r0: 0x%08" PRIx32 ", r1: 0x%08" PRIx32, - core_info[coreid].r0_backup, core_info[coreid].r1_backup); - - return ERROR_OK; -} - -static int aice_restore_tmp_registers(uint32_t coreid) -{ - LOG_DEBUG("restore_tmp_registers - r0: 0x%08" PRIx32 ", r1: 0x%08" PRIx32, - core_info[coreid].r0_backup, core_info[coreid].r1_backup); - - if (core_info[coreid].target_dtr_valid) { - uint32_t instructions[4] = { - SETHI(R0, core_info[coreid].target_dtr_backup >> 12), - ORI(R0, R0, core_info[coreid].target_dtr_backup & 0x00000FFF), - NOP, - BEQ_MINUS_12 - }; - aice_execute_dim(coreid, instructions, 4); - - instructions[0] = MTSR_DTR(R0); - instructions[1] = DSB; - instructions[2] = NOP; - instructions[3] = BEQ_MINUS_12; - aice_execute_dim(coreid, instructions, 4); - - LOG_DEBUG("Restore target DTR: 0x%08" PRIx32, core_info[coreid].target_dtr_backup); - } - - aice_write_reg(coreid, R0, core_info[coreid].r0_backup); - aice_write_reg(coreid, R1, core_info[coreid].r1_backup); - - if (core_info[coreid].host_dtr_valid) { - aice_write_dtr(coreid, core_info[coreid].host_dtr_backup); - - LOG_DEBUG("Restore host DTR: 0x%08" PRIx32, core_info[coreid].host_dtr_backup); - } - - return ERROR_OK; -} - -static int aice_open_device(struct aice_port_param_s *param) -{ - if (aice_usb_open(param) != ERROR_OK) - return ERROR_FAIL; - - if (aice_get_version_info() == ERROR_FAIL) { - LOG_ERROR("Cannot get AICE version!"); - return ERROR_FAIL; - } - - LOG_INFO("AICE initialization started"); - - /* attempt to reset Andes EDM */ - if (aice_reset_box() == ERROR_FAIL) { - LOG_ERROR("Cannot initial AICE box!"); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int aice_usb_set_jtag_clock(uint32_t a_clock) -{ - jtag_clock = a_clock; - - if (aice_usb_set_clock(a_clock) != ERROR_OK) { - LOG_ERROR("Cannot set AICE JTAG clock!"); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int aice_usb_close(void) -{ - jtag_libusb_close(aice_handler.usb_handle); - - free(custom_srst_script); - free(custom_trst_script); - free(custom_restart_script); - return ERROR_OK; -} - -static int aice_core_init(uint32_t coreid) -{ - core_info[coreid].access_channel = NDS_MEMORY_ACC_CPU; - core_info[coreid].memory_select = NDS_MEMORY_SELECT_AUTO; - core_info[coreid].core_state = AICE_TARGET_UNKNOWN; - - return ERROR_OK; -} - -static int aice_usb_idcode(uint32_t *idcode, uint8_t *num_of_idcode) -{ - int retval; - - retval = aice_scan_chain(idcode, num_of_idcode); - if (retval == ERROR_OK) { - for (int i = 0; i < *num_of_idcode; i++) { - aice_core_init(i); - aice_edm_init(i); - } - total_num_of_core = *num_of_idcode; - } - - return retval; -} - -static int aice_usb_halt(uint32_t coreid) -{ - if (core_info[coreid].core_state == AICE_TARGET_HALTED) { - LOG_DEBUG("aice_usb_halt check halted"); - return ERROR_OK; - } - - LOG_DEBUG("aice_usb_halt"); - - /** backup EDM registers */ - aice_backup_edm_registers(coreid); - /** init EDM for host debugging */ - /** no need to clear dex_use_psw, because dbgi will clear it */ - aice_init_edm_registers(coreid, false); - - /** Clear EDM_CTL.DBGIM & EDM_CTL.DBGACKM */ - uint32_t edm_ctl_value = 0; - aice_read_edmsr(coreid, NDS_EDM_SR_EDM_CTL, &edm_ctl_value); - if (edm_ctl_value & 0x3) - aice_write_edmsr(coreid, NDS_EDM_SR_EDM_CTL, edm_ctl_value & ~(0x3)); - - uint32_t dbger = 0; - uint32_t acc_ctl_value = 0; - - core_info[coreid].debug_under_dex_on = false; - aice_read_misc(coreid, NDS_EDM_MISC_DBGER, &dbger); - - if (dbger & NDS_DBGER_AT_MAX) - LOG_ERROR("<-- TARGET ERROR! Reaching the max interrupt stack level. -->"); - - if (dbger & NDS_DBGER_DEX) { - if (is_v2_edm(coreid) == false) { - /** debug 'debug mode'. use force_debug to issue dbgi */ - aice_read_misc(coreid, NDS_EDM_MISC_ACC_CTL, &acc_ctl_value); - acc_ctl_value |= 0x8; - aice_write_misc(coreid, NDS_EDM_MISC_ACC_CTL, acc_ctl_value); - core_info[coreid].debug_under_dex_on = true; - - aice_write_misc(coreid, NDS_EDM_MISC_EDM_CMDR, 0); - /* If CPU stalled due to AT_MAX, clear AT_MAX status. */ - if (dbger & NDS_DBGER_AT_MAX) - aice_write_misc(coreid, NDS_EDM_MISC_DBGER, NDS_DBGER_AT_MAX); - } - } else { - /** Issue DBGI normally */ - aice_write_misc(coreid, NDS_EDM_MISC_EDM_CMDR, 0); - /* If CPU stalled due to AT_MAX, clear AT_MAX status. */ - if (dbger & NDS_DBGER_AT_MAX) - aice_write_misc(coreid, NDS_EDM_MISC_DBGER, NDS_DBGER_AT_MAX); - } - - if (aice_check_dbger(coreid, NDS_DBGER_DEX) != ERROR_OK) { - LOG_ERROR("<-- TARGET ERROR! Unable to stop the debug target through DBGI. -->"); - return ERROR_FAIL; - } - - if (core_info[coreid].debug_under_dex_on) { - if (core_info[coreid].dex_use_psw_on == false) { - /* under debug 'debug mode', force $psw to 'debug mode' behavior */ - /* !!!NOTICE!!! this is workaround for debug 'debug mode'. - * it is only for debugging 'debug exception handler' purpose. - * after openocd detaches from target, target behavior is - * undefined. */ - uint32_t ir0_value = 0; - uint32_t debug_mode_ir0_value; - aice_read_reg(coreid, IR0, &ir0_value); - debug_mode_ir0_value = ir0_value | 0x408; /* turn on DEX, set POM = 1 */ - debug_mode_ir0_value &= ~(0x000000C1); /* turn off DT/IT/GIE */ - aice_write_reg(coreid, IR0, debug_mode_ir0_value); - } - } - - /** set EDM_CTL.DBGIM & EDM_CTL.DBGACKM after halt */ - if (edm_ctl_value & 0x3) - aice_write_edmsr(coreid, NDS_EDM_SR_EDM_CTL, edm_ctl_value); - - /* backup r0 & r1 */ - aice_backup_tmp_registers(coreid); - core_info[coreid].core_state = AICE_TARGET_HALTED; - - return ERROR_OK; -} - -static int aice_usb_state(uint32_t coreid, enum aice_target_state_s *state) -{ - uint32_t dbger_value; - uint32_t ice_state; - - int result = aice_read_misc(coreid, NDS_EDM_MISC_DBGER, &dbger_value); - - if (result == ERROR_AICE_TIMEOUT) { - if (aice_read_ctrl(AICE_READ_CTRL_GET_ICE_STATE, &ice_state) != ERROR_OK) { - LOG_ERROR("<-- AICE ERROR! AICE is unplugged. -->"); - return ERROR_FAIL; - } - - if ((ice_state & 0x20) == 0) { - LOG_ERROR("<-- TARGET ERROR! Target is disconnected with AICE. -->"); - return ERROR_FAIL; - } else { - return ERROR_FAIL; - } - } else if (result == ERROR_AICE_DISCONNECT) { - LOG_ERROR("<-- AICE ERROR! AICE is unplugged. -->"); - return ERROR_FAIL; - } - - if ((dbger_value & NDS_DBGER_ILL_SEC_ACC) == NDS_DBGER_ILL_SEC_ACC) { - LOG_ERROR("<-- TARGET ERROR! Insufficient security privilege. -->"); - - /* Clear ILL_SEC_ACC */ - aice_write_misc(coreid, NDS_EDM_MISC_DBGER, NDS_DBGER_ILL_SEC_ACC); - - *state = AICE_TARGET_RUNNING; - core_info[coreid].core_state = AICE_TARGET_RUNNING; - } else if ((dbger_value & NDS_DBGER_AT_MAX) == NDS_DBGER_AT_MAX) { - /* Issue DBGI to exit cpu stall */ - aice_usb_halt(coreid); - - /* Read OIPC to find out the trigger point */ - uint32_t ir11_value; - aice_read_reg(coreid, IR11, &ir11_value); - - LOG_ERROR("<-- TARGET ERROR! Reaching the max interrupt stack level; " - "CPU is stalled at 0x%08" PRIx32 " for debugging. -->", ir11_value); - - *state = AICE_TARGET_HALTED; - } else if ((dbger_value & NDS_DBGER_CRST) == NDS_DBGER_CRST) { - LOG_DEBUG("DBGER.CRST is on."); - - *state = AICE_TARGET_RESET; - core_info[coreid].core_state = AICE_TARGET_RUNNING; - - /* Clear CRST */ - aice_write_misc(coreid, NDS_EDM_MISC_DBGER, NDS_DBGER_CRST); - } else if ((dbger_value & NDS_DBGER_DEX) == NDS_DBGER_DEX) { - if (core_info[coreid].core_state == AICE_TARGET_RUNNING) { - /* enter debug mode, init EDM registers */ - /* backup EDM registers */ - aice_backup_edm_registers(coreid); - /* init EDM for host debugging */ - aice_init_edm_registers(coreid, true); - aice_backup_tmp_registers(coreid); - core_info[coreid].core_state = AICE_TARGET_HALTED; - } else if (core_info[coreid].core_state == AICE_TARGET_UNKNOWN) { - /* debug 'debug mode', use force debug to halt core */ - aice_usb_halt(coreid); - } - *state = AICE_TARGET_HALTED; - } else { - *state = AICE_TARGET_RUNNING; - core_info[coreid].core_state = AICE_TARGET_RUNNING; - } - - return ERROR_OK; -} - -static int aice_usb_reset(void) -{ - if (aice_reset_box() != ERROR_OK) - return ERROR_FAIL; - - /* issue TRST */ - if (!custom_trst_script) { - if (aice_write_ctrl(AICE_WRITE_CTRL_JTAG_PIN_CONTROL, - AICE_JTAG_PIN_CONTROL_TRST) != ERROR_OK) - return ERROR_FAIL; - } else { - /* custom trst operations */ - if (aice_execute_custom_script(custom_trst_script) != ERROR_OK) - return ERROR_FAIL; - } - - if (aice_usb_set_clock(jtag_clock) != ERROR_OK) - return ERROR_FAIL; - - return ERROR_OK; -} - -static int aice_issue_srst(uint32_t coreid) -{ - LOG_DEBUG("aice_issue_srst"); - - /* After issuing srst, target will be running. So we need to restore EDM_CTL. */ - aice_restore_edm_registers(coreid); - - if (!custom_srst_script) { - if (aice_write_ctrl(AICE_WRITE_CTRL_JTAG_PIN_CONTROL, - AICE_JTAG_PIN_CONTROL_SRST) != ERROR_OK) - return ERROR_FAIL; - } else { - /* custom srst operations */ - if (aice_execute_custom_script(custom_srst_script) != ERROR_OK) - return ERROR_FAIL; - } - - /* wait CRST infinitely */ - uint32_t dbger_value; - int i = 0; - while (1) { - if (aice_read_misc(coreid, - NDS_EDM_MISC_DBGER, &dbger_value) != ERROR_OK) - return ERROR_FAIL; - - if (dbger_value & NDS_DBGER_CRST) - break; - - if ((i % 30) == 0) - keep_alive(); - i++; - } - - core_info[coreid].host_dtr_valid = false; - core_info[coreid].target_dtr_valid = false; - - core_info[coreid].core_state = AICE_TARGET_RUNNING; - return ERROR_OK; -} - -static int aice_issue_reset_hold(uint32_t coreid) -{ - LOG_DEBUG("aice_issue_reset_hold"); - - /* set no_dbgi_pin to 0 */ - uint32_t pin_status; - aice_read_ctrl(AICE_READ_CTRL_GET_JTAG_PIN_STATUS, &pin_status); - if (pin_status & 0x4) - aice_write_ctrl(AICE_WRITE_CTRL_JTAG_PIN_STATUS, pin_status & (~0x4)); - - /* issue restart */ - if (!custom_restart_script) { - if (aice_write_ctrl(AICE_WRITE_CTRL_JTAG_PIN_CONTROL, - AICE_JTAG_PIN_CONTROL_RESTART) != ERROR_OK) - return ERROR_FAIL; - } else { - /* custom restart operations */ - if (aice_execute_custom_script(custom_restart_script) != ERROR_OK) - return ERROR_FAIL; - } - - if (aice_check_dbger(coreid, NDS_DBGER_CRST | NDS_DBGER_DEX) == ERROR_OK) { - aice_backup_tmp_registers(coreid); - core_info[coreid].core_state = AICE_TARGET_HALTED; - - return ERROR_OK; - } else { - /* set no_dbgi_pin to 1 */ - aice_write_ctrl(AICE_WRITE_CTRL_JTAG_PIN_STATUS, pin_status | 0x4); - - /* issue restart again */ - if (!custom_restart_script) { - if (aice_write_ctrl(AICE_WRITE_CTRL_JTAG_PIN_CONTROL, - AICE_JTAG_PIN_CONTROL_RESTART) != ERROR_OK) - return ERROR_FAIL; - } else { - /* custom restart operations */ - if (aice_execute_custom_script(custom_restart_script) != ERROR_OK) - return ERROR_FAIL; - } - - if (aice_check_dbger(coreid, NDS_DBGER_CRST | NDS_DBGER_DEX) == ERROR_OK) { - aice_backup_tmp_registers(coreid); - core_info[coreid].core_state = AICE_TARGET_HALTED; - - return ERROR_OK; - } - - /* do software reset-and-hold */ - aice_issue_srst(coreid); - aice_usb_halt(coreid); - - uint32_t value_ir3; - aice_read_reg(coreid, IR3, &value_ir3); - aice_write_reg(coreid, PC, value_ir3 & 0xFFFF0000); - } - - return ERROR_FAIL; -} - -static int aice_issue_reset_hold_multi(void) -{ - uint32_t write_ctrl_value = 0; - - /* set SRST */ - write_ctrl_value = AICE_CUSTOM_DELAY_SET_SRST; - write_ctrl_value |= (0x200 << 16); - if (aice_write_ctrl(AICE_WRITE_CTRL_CUSTOM_DELAY, - write_ctrl_value) != ERROR_OK) - return ERROR_FAIL; - - for (uint8_t i = 0 ; i < total_num_of_core ; i++) - aice_write_misc(i, NDS_EDM_MISC_EDM_CMDR, 0); - - /* clear SRST */ - write_ctrl_value = AICE_CUSTOM_DELAY_CLEAN_SRST; - write_ctrl_value |= (0x200 << 16); - if (aice_write_ctrl(AICE_WRITE_CTRL_CUSTOM_DELAY, - write_ctrl_value) != ERROR_OK) - return ERROR_FAIL; - - for (uint8_t i = 0; i < total_num_of_core; i++) - aice_edm_init(i); - - return ERROR_FAIL; -} - -static int aice_usb_assert_srst(uint32_t coreid, enum aice_srst_type_s srst) -{ - if ((srst != AICE_SRST) && (srst != AICE_RESET_HOLD)) - return ERROR_FAIL; - - /* clear DBGER */ - if (aice_write_misc(coreid, NDS_EDM_MISC_DBGER, - NDS_DBGER_CLEAR_ALL) != ERROR_OK) - return ERROR_FAIL; - - int result = ERROR_OK; - if (srst == AICE_SRST) - result = aice_issue_srst(coreid); - else { - if (total_num_of_core == 1) - result = aice_issue_reset_hold(coreid); - else - result = aice_issue_reset_hold_multi(); - } - - /* Clear DBGER.CRST after reset to avoid 'core-reset checking' errors. - * assert_srst is user-intentional reset behavior, so we could - * clear DBGER.CRST safely. - */ - if (aice_write_misc(coreid, - NDS_EDM_MISC_DBGER, NDS_DBGER_CRST) != ERROR_OK) - return ERROR_FAIL; - - return result; -} - -static int aice_usb_run(uint32_t coreid) -{ - LOG_DEBUG("aice_usb_run"); - - uint32_t dbger_value; - if (aice_read_misc(coreid, - NDS_EDM_MISC_DBGER, &dbger_value) != ERROR_OK) - return ERROR_FAIL; - - if ((dbger_value & NDS_DBGER_DEX) != NDS_DBGER_DEX) { - LOG_WARNING("<-- TARGET WARNING! The debug target exited " - "the debug mode unexpectedly. -->"); - return ERROR_FAIL; - } - - /* restore r0 & r1 before free run */ - aice_restore_tmp_registers(coreid); - core_info[coreid].core_state = AICE_TARGET_RUNNING; - - /* clear DBGER */ - aice_write_misc(coreid, NDS_EDM_MISC_DBGER, - NDS_DBGER_CLEAR_ALL); - - /** restore EDM registers */ - /** OpenOCD should restore EDM_CTL **before** to exit debug state. - * Otherwise, following instruction will read wrong EDM_CTL value. - * - * pc -> mfsr $p0, EDM_CTL (single step) - * slli $p0, $p0, 1 - * slri $p0, $p0, 31 - */ - aice_restore_edm_registers(coreid); - - /** execute instructions in DIM */ - uint32_t instructions[4] = { - NOP, - NOP, - NOP, - IRET - }; - int result = aice_execute_dim(coreid, instructions, 4); - - return result; -} - -static int aice_usb_step(uint32_t coreid) -{ - LOG_DEBUG("aice_usb_step"); - - uint32_t ir0_value; - uint32_t ir0_reg_num; - - if (is_v2_edm(coreid) == true) - /* V2 EDM will push interrupt stack as debug exception */ - ir0_reg_num = IR1; - else - ir0_reg_num = IR0; - - /** enable HSS */ - aice_read_reg(coreid, ir0_reg_num, &ir0_value); - if ((ir0_value & 0x800) == 0) { - /** set PSW.HSS */ - ir0_value |= (0x01 << 11); - aice_write_reg(coreid, ir0_reg_num, ir0_value); - } - - if (aice_usb_run(coreid) == ERROR_FAIL) - return ERROR_FAIL; - - int i = 0; - enum aice_target_state_s state; - while (1) { - /* read DBGER */ - if (aice_usb_state(coreid, &state) != ERROR_OK) - return ERROR_FAIL; - - if (state == AICE_TARGET_HALTED) - break; - - int64_t then = 0; - if (i == 30) - then = timeval_ms(); - - if (i >= 30) { - if ((timeval_ms() - then) > 1000) - LOG_WARNING("Timeout (1000ms) waiting for halt to complete"); - - return ERROR_FAIL; - } - i++; - } - - /** disable HSS */ - aice_read_reg(coreid, ir0_reg_num, &ir0_value); - ir0_value &= ~(0x01 << 11); - aice_write_reg(coreid, ir0_reg_num, ir0_value); - - return ERROR_OK; -} - -static int aice_usb_read_mem_b_bus(uint32_t coreid, uint32_t address, uint32_t *data) -{ - return aice_read_mem_b(coreid, address, data); -} - -static int aice_usb_read_mem_h_bus(uint32_t coreid, uint32_t address, uint32_t *data) -{ - return aice_read_mem_h(coreid, address, data); -} - -static int aice_usb_read_mem_w_bus(uint32_t coreid, uint32_t address, uint32_t *data) -{ - return aice_read_mem(coreid, address, data); -} - -static int aice_usb_read_mem_b_dim(uint32_t coreid, uint32_t address, uint32_t *data) -{ - uint32_t value; - uint32_t instructions[4] = { - LBI_BI(R1, R0), - MTSR_DTR(R1), - DSB, - BEQ_MINUS_12 - }; - - aice_execute_dim(coreid, instructions, 4); - - aice_read_dtr(coreid, &value); - *data = value & 0xFF; - - return ERROR_OK; -} - -static int aice_usb_read_mem_h_dim(uint32_t coreid, uint32_t address, uint32_t *data) -{ - uint32_t value; - uint32_t instructions[4] = { - LHI_BI(R1, R0), - MTSR_DTR(R1), - DSB, - BEQ_MINUS_12 - }; - - aice_execute_dim(coreid, instructions, 4); - - aice_read_dtr(coreid, &value); - *data = value & 0xFFFF; - - return ERROR_OK; -} - -static int aice_usb_read_mem_w_dim(uint32_t coreid, uint32_t address, uint32_t *data) -{ - uint32_t instructions[4] = { - LWI_BI(R1, R0), - MTSR_DTR(R1), - DSB, - BEQ_MINUS_12 - }; - - aice_execute_dim(coreid, instructions, 4); - - aice_read_dtr(coreid, data); - - return ERROR_OK; -} - -static int aice_usb_set_address_dim(uint32_t coreid, uint32_t address) -{ - uint32_t instructions[4] = { - SETHI(R0, address >> 12), - ORI(R0, R0, address & 0x00000FFF), - NOP, - BEQ_MINUS_12 - }; - - return aice_execute_dim(coreid, instructions, 4); -} - -static int aice_usb_read_memory_unit(uint32_t coreid, uint32_t addr, uint32_t size, - uint32_t count, uint8_t *buffer) -{ - LOG_DEBUG("aice_usb_read_memory_unit, addr: 0x%08" PRIx32 - ", size: %" PRIu32 ", count: %" PRIu32 "", - addr, size, count); - - if (core_info[coreid].access_channel == NDS_MEMORY_ACC_CPU) - aice_usb_set_address_dim(coreid, addr); - - uint32_t value; - size_t i; - read_mem_func_t read_mem_func; - - switch (size) { - case 1: - if (core_info[coreid].access_channel == NDS_MEMORY_ACC_BUS) - read_mem_func = aice_usb_read_mem_b_bus; - else - read_mem_func = aice_usb_read_mem_b_dim; - - for (i = 0; i < count; i++) { - read_mem_func(coreid, addr, &value); - *buffer++ = (uint8_t)value; - addr++; - } - break; - case 2: - if (core_info[coreid].access_channel == NDS_MEMORY_ACC_BUS) - read_mem_func = aice_usb_read_mem_h_bus; - else - read_mem_func = aice_usb_read_mem_h_dim; - - for (i = 0; i < count; i++) { - read_mem_func(coreid, addr, &value); - uint16_t svalue = value; - memcpy(buffer, &svalue, sizeof(uint16_t)); - buffer += 2; - addr += 2; - } - break; - case 4: - if (core_info[coreid].access_channel == NDS_MEMORY_ACC_BUS) - read_mem_func = aice_usb_read_mem_w_bus; - else - read_mem_func = aice_usb_read_mem_w_dim; - - for (i = 0; i < count; i++) { - read_mem_func(coreid, addr, &value); - memcpy(buffer, &value, sizeof(uint32_t)); - buffer += 4; - addr += 4; - } - break; - } - - return ERROR_OK; -} - -static int aice_usb_write_mem_b_bus(uint32_t coreid, uint32_t address, uint32_t data) -{ - return aice_write_mem_b(coreid, address, data); -} - -static int aice_usb_write_mem_h_bus(uint32_t coreid, uint32_t address, uint32_t data) -{ - return aice_write_mem_h(coreid, address, data); -} - -static int aice_usb_write_mem_w_bus(uint32_t coreid, uint32_t address, uint32_t data) -{ - return aice_write_mem(coreid, address, data); -} - -static int aice_usb_write_mem_b_dim(uint32_t coreid, uint32_t address, uint32_t data) -{ - uint32_t instructions[4] = { - MFSR_DTR(R1), - SBI_BI(R1, R0), - DSB, - BEQ_MINUS_12 - }; - - aice_write_dtr(coreid, data & 0xFF); - aice_execute_dim(coreid, instructions, 4); - - return ERROR_OK; -} - -static int aice_usb_write_mem_h_dim(uint32_t coreid, uint32_t address, uint32_t data) -{ - uint32_t instructions[4] = { - MFSR_DTR(R1), - SHI_BI(R1, R0), - DSB, - BEQ_MINUS_12 - }; - - aice_write_dtr(coreid, data & 0xFFFF); - aice_execute_dim(coreid, instructions, 4); - - return ERROR_OK; -} - -static int aice_usb_write_mem_w_dim(uint32_t coreid, uint32_t address, uint32_t data) -{ - uint32_t instructions[4] = { - MFSR_DTR(R1), - SWI_BI(R1, R0), - DSB, - BEQ_MINUS_12 - }; - - aice_write_dtr(coreid, data); - aice_execute_dim(coreid, instructions, 4); - - return ERROR_OK; -} - -static int aice_usb_write_memory_unit(uint32_t coreid, uint32_t addr, uint32_t size, - uint32_t count, const uint8_t *buffer) -{ - LOG_DEBUG("aice_usb_write_memory_unit, addr: 0x%08" PRIx32 - ", size: %" PRIu32 ", count: %" PRIu32 "", - addr, size, count); - - if (core_info[coreid].access_channel == NDS_MEMORY_ACC_CPU) - aice_usb_set_address_dim(coreid, addr); - - size_t i; - write_mem_func_t write_mem_func; - - switch (size) { - case 1: - if (core_info[coreid].access_channel == NDS_MEMORY_ACC_BUS) - write_mem_func = aice_usb_write_mem_b_bus; - else - write_mem_func = aice_usb_write_mem_b_dim; - - for (i = 0; i < count; i++) { - write_mem_func(coreid, addr, *buffer); - buffer++; - addr++; - } - break; - case 2: - if (core_info[coreid].access_channel == NDS_MEMORY_ACC_BUS) - write_mem_func = aice_usb_write_mem_h_bus; - else - write_mem_func = aice_usb_write_mem_h_dim; - - for (i = 0; i < count; i++) { - uint16_t value; - memcpy(&value, buffer, sizeof(uint16_t)); - - write_mem_func(coreid, addr, value); - buffer += 2; - addr += 2; - } - break; - case 4: - if (core_info[coreid].access_channel == NDS_MEMORY_ACC_BUS) - write_mem_func = aice_usb_write_mem_w_bus; - else - write_mem_func = aice_usb_write_mem_w_dim; - - for (i = 0; i < count; i++) { - uint32_t value; - memcpy(&value, buffer, sizeof(uint32_t)); - - write_mem_func(coreid, addr, value); - buffer += 4; - addr += 4; - } - break; - } - - return ERROR_OK; -} - -static int aice_bulk_read_mem(uint32_t coreid, uint32_t addr, uint32_t count, - uint8_t *buffer) -{ - uint32_t packet_size; - - while (count > 0) { - packet_size = (count >= 0x100) ? 0x100 : count; - - /** set address */ - addr &= 0xFFFFFFFC; - if (aice_write_misc(coreid, NDS_EDM_MISC_SBAR, addr) != ERROR_OK) - return ERROR_FAIL; - - if (aice_fastread_mem(coreid, buffer, - packet_size) != ERROR_OK) - return ERROR_FAIL; - - buffer += (packet_size * 4); - addr += (packet_size * 4); - count -= packet_size; - } - - return ERROR_OK; -} - -static int aice_bulk_write_mem(uint32_t coreid, uint32_t addr, uint32_t count, - const uint8_t *buffer) -{ - uint32_t packet_size; - - while (count > 0) { - packet_size = (count >= 0x100) ? 0x100 : count; - - /** set address */ - addr &= 0xFFFFFFFC; - if (aice_write_misc(coreid, NDS_EDM_MISC_SBAR, addr | 1) != ERROR_OK) - return ERROR_FAIL; - - if (aice_fastwrite_mem(coreid, buffer, - packet_size) != ERROR_OK) - return ERROR_FAIL; - - buffer += (packet_size * 4); - addr += (packet_size * 4); - count -= packet_size; - } - - return ERROR_OK; -} - -static int aice_usb_bulk_read_mem(uint32_t coreid, uint32_t addr, - uint32_t length, uint8_t *buffer) -{ - LOG_DEBUG("aice_usb_bulk_read_mem, addr: 0x%08" PRIx32 ", length: 0x%08" PRIx32, addr, length); - - int retval; - - if (core_info[coreid].access_channel == NDS_MEMORY_ACC_CPU) - aice_usb_set_address_dim(coreid, addr); - - if (core_info[coreid].access_channel == NDS_MEMORY_ACC_CPU) - retval = aice_usb_read_memory_unit(coreid, addr, 4, length / 4, buffer); - else - retval = aice_bulk_read_mem(coreid, addr, length / 4, buffer); - - return retval; -} - -static int aice_usb_bulk_write_mem(uint32_t coreid, uint32_t addr, - uint32_t length, const uint8_t *buffer) -{ - LOG_DEBUG("aice_usb_bulk_write_mem, addr: 0x%08" PRIx32 ", length: 0x%08" PRIx32, addr, length); - - int retval; - - if (core_info[coreid].access_channel == NDS_MEMORY_ACC_CPU) - aice_usb_set_address_dim(coreid, addr); - - if (core_info[coreid].access_channel == NDS_MEMORY_ACC_CPU) - retval = aice_usb_write_memory_unit(coreid, addr, 4, length / 4, buffer); - else - retval = aice_bulk_write_mem(coreid, addr, length / 4, buffer); - - return retval; -} - -static int aice_usb_read_debug_reg(uint32_t coreid, uint32_t addr, uint32_t *val) -{ - if (core_info[coreid].core_state == AICE_TARGET_HALTED) { - if (addr == NDS_EDM_SR_EDMSW) { - *val = core_info[coreid].edmsw_backup; - } else if (addr == NDS_EDM_SR_EDM_DTR) { - if (core_info[coreid].target_dtr_valid) { - /* if EDM_DTR has read out, clear it. */ - *val = core_info[coreid].target_dtr_backup; - core_info[coreid].edmsw_backup &= (~0x1); - core_info[coreid].target_dtr_valid = false; - } else { - *val = 0; - } - } - } - - return aice_read_edmsr(coreid, addr, val); -} - -static int aice_usb_write_debug_reg(uint32_t coreid, uint32_t addr, const uint32_t val) -{ - if (core_info[coreid].core_state == AICE_TARGET_HALTED) { - if (addr == NDS_EDM_SR_EDM_DTR) { - core_info[coreid].host_dtr_backup = val; - core_info[coreid].edmsw_backup |= 0x2; - core_info[coreid].host_dtr_valid = true; - } - } - - return aice_write_edmsr(coreid, addr, val); -} - -static int aice_usb_memory_access(uint32_t coreid, enum nds_memory_access channel) -{ - LOG_DEBUG("aice_usb_memory_access, access channel: %u", channel); - - core_info[coreid].access_channel = channel; - - return ERROR_OK; -} - -static int aice_usb_memory_mode(uint32_t coreid, enum nds_memory_select mem_select) -{ - if (core_info[coreid].memory_select == mem_select) - return ERROR_OK; - - LOG_DEBUG("aice_usb_memory_mode, memory select: %u", mem_select); - - core_info[coreid].memory_select = mem_select; - - if (core_info[coreid].memory_select != NDS_MEMORY_SELECT_AUTO) - aice_write_misc(coreid, NDS_EDM_MISC_ACC_CTL, - core_info[coreid].memory_select - 1); - else - aice_write_misc(coreid, NDS_EDM_MISC_ACC_CTL, - NDS_MEMORY_SELECT_MEM - 1); - - return ERROR_OK; -} - -static int aice_usb_read_tlb(uint32_t coreid, target_addr_t virtual_address, - target_addr_t *physical_address) -{ - LOG_DEBUG("aice_usb_read_tlb, virtual address: 0x%08" TARGET_PRIxADDR, virtual_address); - - uint32_t instructions[4]; - uint32_t probe_result; - uint32_t value_mr3; - uint32_t value_mr4; - uint32_t access_page_size; - uint32_t virtual_offset; - uint32_t physical_page_number; - - aice_write_dtr(coreid, virtual_address); - - /* probe TLB first */ - instructions[0] = MFSR_DTR(R0); - instructions[1] = TLBOP_TARGET_PROBE(R1, R0); - instructions[2] = DSB; - instructions[3] = BEQ_MINUS_12; - aice_execute_dim(coreid, instructions, 4); - - aice_read_reg(coreid, R1, &probe_result); - - if (probe_result & 0x80000000) - return ERROR_FAIL; - - /* read TLB entry */ - aice_write_dtr(coreid, probe_result & 0x7FF); - - /* probe TLB first */ - instructions[0] = MFSR_DTR(R0); - instructions[1] = TLBOP_TARGET_READ(R0); - instructions[2] = DSB; - instructions[3] = BEQ_MINUS_12; - aice_execute_dim(coreid, instructions, 4); - - /* TODO: it should backup mr3, mr4 */ - aice_read_reg(coreid, MR3, &value_mr3); - aice_read_reg(coreid, MR4, &value_mr4); - - access_page_size = value_mr4 & 0xF; - if (access_page_size == 0) { /* 4K page */ - virtual_offset = virtual_address & 0x00000FFF; - physical_page_number = value_mr3 & 0xFFFFF000; - } else if (access_page_size == 1) { /* 8K page */ - virtual_offset = virtual_address & 0x00001FFF; - physical_page_number = value_mr3 & 0xFFFFE000; - } else if (access_page_size == 5) { /* 1M page */ - virtual_offset = virtual_address & 0x000FFFFF; - physical_page_number = value_mr3 & 0xFFF00000; - } else { - return ERROR_FAIL; - } - - *physical_address = physical_page_number | virtual_offset; - - return ERROR_OK; -} - -static int aice_usb_init_cache(uint32_t coreid) -{ - LOG_DEBUG("aice_usb_init_cache"); - - uint32_t value_cr1; - uint32_t value_cr2; - - aice_read_reg(coreid, CR1, &value_cr1); - aice_read_reg(coreid, CR2, &value_cr2); - - struct cache_info *icache = &core_info[coreid].icache; - - icache->set = value_cr1 & 0x7; - icache->log2_set = icache->set + 6; - icache->set = 64 << icache->set; - icache->way = ((value_cr1 >> 3) & 0x7) + 1; - icache->line_size = (value_cr1 >> 6) & 0x7; - if (icache->line_size != 0) { - icache->log2_line_size = icache->line_size + 2; - icache->line_size = 8 << (icache->line_size - 1); - } else { - icache->log2_line_size = 0; - } - - LOG_DEBUG("\ticache set: %" PRIu32 ", way: %" PRIu32 ", line size: %" PRIu32 ", " - "log2(set): %" PRIu32 ", log2(line_size): %" PRIu32 "", - icache->set, icache->way, icache->line_size, - icache->log2_set, icache->log2_line_size); - - struct cache_info *dcache = &core_info[coreid].dcache; - - dcache->set = value_cr2 & 0x7; - dcache->log2_set = dcache->set + 6; - dcache->set = 64 << dcache->set; - dcache->way = ((value_cr2 >> 3) & 0x7) + 1; - dcache->line_size = (value_cr2 >> 6) & 0x7; - if (dcache->line_size != 0) { - dcache->log2_line_size = dcache->line_size + 2; - dcache->line_size = 8 << (dcache->line_size - 1); - } else { - dcache->log2_line_size = 0; - } - - LOG_DEBUG("\tdcache set: %" PRIu32 ", way: %" PRIu32 ", line size: %" PRIu32 ", " - "log2(set): %" PRIu32 ", log2(line_size): %" PRIu32 "", - dcache->set, dcache->way, dcache->line_size, - dcache->log2_set, dcache->log2_line_size); - - core_info[coreid].cache_init = true; - - return ERROR_OK; -} - -static int aice_usb_dcache_inval_all(uint32_t coreid) -{ - LOG_DEBUG("aice_usb_dcache_inval_all"); - - uint32_t set_index; - uint32_t way_index; - uint32_t cache_index; - uint32_t instructions[4]; - - instructions[0] = MFSR_DTR(R0); - instructions[1] = L1D_IX_INVAL(R0); - instructions[2] = DSB; - instructions[3] = BEQ_MINUS_12; - - struct cache_info *dcache = &core_info[coreid].dcache; - - for (set_index = 0; set_index < dcache->set; set_index++) { - for (way_index = 0; way_index < dcache->way; way_index++) { - cache_index = (way_index << (dcache->log2_set + dcache->log2_line_size)) | - (set_index << dcache->log2_line_size); - - if (aice_write_dtr(coreid, cache_index) != ERROR_OK) - return ERROR_FAIL; - - if (aice_execute_dim(coreid, instructions, 4) != ERROR_OK) - return ERROR_FAIL; - } - } - - return ERROR_OK; -} - -static int aice_usb_dcache_va_inval(uint32_t coreid, uint32_t address) -{ - LOG_DEBUG("aice_usb_dcache_va_inval"); - - uint32_t instructions[4]; - - aice_write_dtr(coreid, address); - - instructions[0] = MFSR_DTR(R0); - instructions[1] = L1D_VA_INVAL(R0); - instructions[2] = DSB; - instructions[3] = BEQ_MINUS_12; - - return aice_execute_dim(coreid, instructions, 4); -} - -static int aice_usb_dcache_wb_all(uint32_t coreid) -{ - LOG_DEBUG("aice_usb_dcache_wb_all"); - - uint32_t set_index; - uint32_t way_index; - uint32_t cache_index; - uint32_t instructions[4]; - - instructions[0] = MFSR_DTR(R0); - instructions[1] = L1D_IX_WB(R0); - instructions[2] = DSB; - instructions[3] = BEQ_MINUS_12; - - struct cache_info *dcache = &core_info[coreid].dcache; - - for (set_index = 0; set_index < dcache->set; set_index++) { - for (way_index = 0; way_index < dcache->way; way_index++) { - cache_index = (way_index << (dcache->log2_set + dcache->log2_line_size)) | - (set_index << dcache->log2_line_size); - - if (aice_write_dtr(coreid, cache_index) != ERROR_OK) - return ERROR_FAIL; - - if (aice_execute_dim(coreid, instructions, 4) != ERROR_OK) - return ERROR_FAIL; - } - } - - return ERROR_OK; -} - -static int aice_usb_dcache_va_wb(uint32_t coreid, uint32_t address) -{ - LOG_DEBUG("aice_usb_dcache_va_wb"); - - uint32_t instructions[4]; - - aice_write_dtr(coreid, address); - - instructions[0] = MFSR_DTR(R0); - instructions[1] = L1D_VA_WB(R0); - instructions[2] = DSB; - instructions[3] = BEQ_MINUS_12; - - return aice_execute_dim(coreid, instructions, 4); -} - -static int aice_usb_icache_inval_all(uint32_t coreid) -{ - LOG_DEBUG("aice_usb_icache_inval_all"); - - uint32_t set_index; - uint32_t way_index; - uint32_t cache_index; - uint32_t instructions[4]; - - instructions[0] = MFSR_DTR(R0); - instructions[1] = L1I_IX_INVAL(R0); - instructions[2] = ISB; - instructions[3] = BEQ_MINUS_12; - - struct cache_info *icache = &core_info[coreid].icache; - - for (set_index = 0; set_index < icache->set; set_index++) { - for (way_index = 0; way_index < icache->way; way_index++) { - cache_index = (way_index << (icache->log2_set + icache->log2_line_size)) | - (set_index << icache->log2_line_size); - - if (aice_write_dtr(coreid, cache_index) != ERROR_OK) - return ERROR_FAIL; - - if (aice_execute_dim(coreid, instructions, 4) != ERROR_OK) - return ERROR_FAIL; - } - } - - return ERROR_OK; -} - -static int aice_usb_icache_va_inval(uint32_t coreid, uint32_t address) -{ - LOG_DEBUG("aice_usb_icache_va_inval"); - - uint32_t instructions[4]; - - aice_write_dtr(coreid, address); - - instructions[0] = MFSR_DTR(R0); - instructions[1] = L1I_VA_INVAL(R0); - instructions[2] = ISB; - instructions[3] = BEQ_MINUS_12; - - return aice_execute_dim(coreid, instructions, 4); -} - -static int aice_usb_cache_ctl(uint32_t coreid, uint32_t subtype, uint32_t address) -{ - LOG_DEBUG("aice_usb_cache_ctl"); - - int result; - - if (core_info[coreid].cache_init == false) - aice_usb_init_cache(coreid); - - switch (subtype) { - case AICE_CACHE_CTL_L1D_INVALALL: - result = aice_usb_dcache_inval_all(coreid); - break; - case AICE_CACHE_CTL_L1D_VA_INVAL: - result = aice_usb_dcache_va_inval(coreid, address); - break; - case AICE_CACHE_CTL_L1D_WBALL: - result = aice_usb_dcache_wb_all(coreid); - break; - case AICE_CACHE_CTL_L1D_VA_WB: - result = aice_usb_dcache_va_wb(coreid, address); - break; - case AICE_CACHE_CTL_L1I_INVALALL: - result = aice_usb_icache_inval_all(coreid); - break; - case AICE_CACHE_CTL_L1I_VA_INVAL: - result = aice_usb_icache_va_inval(coreid, address); - break; - default: - result = ERROR_FAIL; - break; - } - - return result; -} - -static int aice_usb_set_retry_times(uint32_t a_retry_times) -{ - aice_max_retry_times = a_retry_times; - return ERROR_OK; -} - -static int aice_usb_program_edm(uint32_t coreid, char *command_sequence) -{ - char *command_str; - char *reg_name_0; - char *reg_name_1; - uint32_t data_value; - int i; - - /* init strtok() */ - command_str = strtok(command_sequence, ";"); - if (!command_str) - return ERROR_OK; - - do { - i = 0; - /* process one command */ - while (command_str[i] == ' ' || - command_str[i] == '\n' || - command_str[i] == '\r' || - command_str[i] == '\t') - i++; - - /* skip ' ', '\r', '\n', '\t' */ - command_str = command_str + i; - - if (strncmp(command_str, "write_misc", 10) == 0) { - reg_name_0 = strstr(command_str, "gen_port0"); - reg_name_1 = strstr(command_str, "gen_port1"); - - if (reg_name_0) { - data_value = strtoul(reg_name_0 + 9, NULL, 0); - - if (aice_write_misc(coreid, - NDS_EDM_MISC_GEN_PORT0, data_value) != ERROR_OK) - return ERROR_FAIL; - - } else if (reg_name_1) { - data_value = strtoul(reg_name_1 + 9, NULL, 0); - - if (aice_write_misc(coreid, - NDS_EDM_MISC_GEN_PORT1, data_value) != ERROR_OK) - return ERROR_FAIL; - } else { - LOG_ERROR("program EDM, unsupported misc register: %s", command_str); - } - } else { - LOG_ERROR("program EDM, unsupported command: %s", command_str); - } - - /* update command_str */ - command_str = strtok(NULL, ";"); - - } while (command_str); - - return ERROR_OK; -} - -static int aice_usb_set_command_mode(enum aice_command_mode command_mode) -{ - int retval = ERROR_OK; - - /* flush usb_packets_buffer as users change mode */ - retval = aice_usb_packet_flush(); - - if (command_mode == AICE_COMMAND_MODE_BATCH) { - /* reset batch buffer */ - aice_command_mode = AICE_COMMAND_MODE_NORMAL; - retval = aice_write_ctrl(AICE_WRITE_CTRL_BATCH_CMD_BUF0_CTRL, 0x40000); - } - - aice_command_mode = command_mode; - - return retval; -} - -static int aice_usb_execute(uint32_t coreid, uint32_t *instructions, - uint32_t instruction_num) -{ - uint32_t i, j; - uint8_t current_instruction_num; - uint32_t dim_instructions[4] = {NOP, NOP, NOP, BEQ_MINUS_12}; - - /* To execute 4 instructions as a special case */ - if (instruction_num == 4) - return aice_execute_dim(coreid, instructions, 4); - - for (i = 0 ; i < instruction_num ; i += 3) { - if (instruction_num - i < 3) { - current_instruction_num = instruction_num - i; - for (j = current_instruction_num ; j < 3 ; j++) - dim_instructions[j] = NOP; - } else { - current_instruction_num = 3; - } - - memcpy(dim_instructions, instructions + i, - current_instruction_num * sizeof(uint32_t)); - - /** fill DIM */ - if (aice_write_dim(coreid, - dim_instructions, - 4) != ERROR_OK) - return ERROR_FAIL; - - /** clear DBGER.DPED */ - if (aice_write_misc(coreid, - NDS_EDM_MISC_DBGER, NDS_DBGER_DPED) != ERROR_OK) - return ERROR_FAIL; - - /** execute DIM */ - if (aice_do_execute(coreid) != ERROR_OK) - return ERROR_FAIL; - - /** check DBGER.DPED */ - if (aice_check_dbger(coreid, NDS_DBGER_DPED) != ERROR_OK) { - - LOG_ERROR("<-- TARGET ERROR! Debug operations do not finish properly:" - "0x%08" PRIx32 " 0x%08" PRIx32 " 0x%08" PRIx32 " 0x%08" PRIx32 ". -->", - dim_instructions[0], - dim_instructions[1], - dim_instructions[2], - dim_instructions[3]); - return ERROR_FAIL; - } - } - - return ERROR_OK; -} - -static int aice_usb_set_custom_srst_script(const char *script) -{ - custom_srst_script = strdup(script); - - return ERROR_OK; -} - -static int aice_usb_set_custom_trst_script(const char *script) -{ - custom_trst_script = strdup(script); - - return ERROR_OK; -} - -static int aice_usb_set_custom_restart_script(const char *script) -{ - custom_restart_script = strdup(script); - - return ERROR_OK; -} - -static int aice_usb_set_count_to_check_dbger(uint32_t count_to_check) -{ - aice_count_to_check_dbger = count_to_check; - - return ERROR_OK; -} - -static int aice_usb_set_data_endian(uint32_t coreid, - enum aice_target_endian target_data_endian) -{ - data_endian = target_data_endian; - - return ERROR_OK; -} - -static int fill_profiling_batch_commands(uint32_t coreid, uint32_t reg_no) -{ - uint32_t dim_instructions[4]; - - aice_usb_set_command_mode(AICE_COMMAND_MODE_BATCH); - - /* halt */ - if (aice_write_misc(coreid, NDS_EDM_MISC_EDM_CMDR, 0) != ERROR_OK) - return ERROR_FAIL; - - /* backup $r0 */ - dim_instructions[0] = MTSR_DTR(0); - dim_instructions[1] = DSB; - dim_instructions[2] = NOP; - dim_instructions[3] = BEQ_MINUS_12; - if (aice_write_dim(coreid, dim_instructions, 4) != ERROR_OK) - return ERROR_FAIL; - aice_read_dtr_to_buffer(coreid, AICE_BATCH_DATA_BUFFER_0); - - /* get samples */ - if (nds32_reg_type(reg_no) == NDS32_REG_TYPE_GPR) { - /* general registers */ - dim_instructions[0] = MTSR_DTR(reg_no); - dim_instructions[1] = DSB; - dim_instructions[2] = NOP; - dim_instructions[3] = BEQ_MINUS_12; - } else if (nds32_reg_type(reg_no) == NDS32_REG_TYPE_SPR) { - /* user special registers */ - dim_instructions[0] = MFUSR_G0(0, nds32_reg_sr_index(reg_no)); - dim_instructions[1] = MTSR_DTR(0); - dim_instructions[2] = DSB; - dim_instructions[3] = BEQ_MINUS_12; - } else { /* system registers */ - dim_instructions[0] = MFSR(0, nds32_reg_sr_index(reg_no)); - dim_instructions[1] = MTSR_DTR(0); - dim_instructions[2] = DSB; - dim_instructions[3] = BEQ_MINUS_12; - } - if (aice_write_dim(coreid, dim_instructions, 4) != ERROR_OK) - return ERROR_FAIL; - aice_read_dtr_to_buffer(coreid, AICE_BATCH_DATA_BUFFER_1); - - /* restore $r0 */ - aice_write_dtr_from_buffer(coreid, AICE_BATCH_DATA_BUFFER_0); - dim_instructions[0] = MFSR_DTR(0); - dim_instructions[1] = DSB; - dim_instructions[2] = NOP; - dim_instructions[3] = IRET; /* free run */ - if (aice_write_dim(coreid, dim_instructions, 4) != ERROR_OK) - return ERROR_FAIL; - - aice_command_mode = AICE_COMMAND_MODE_NORMAL; - - /* use BATCH_BUFFER_WRITE to fill command-batch-buffer */ - if (aice_batch_buffer_write(AICE_BATCH_COMMAND_BUFFER_0, - usb_out_packets_buffer, - (usb_out_packets_buffer_length + 3) / 4) != ERROR_OK) - return ERROR_FAIL; - - usb_out_packets_buffer_length = 0; - usb_in_packets_buffer_length = 0; - - return ERROR_OK; -} - -static int aice_usb_profiling(uint32_t coreid, uint32_t interval, uint32_t iteration, - uint32_t reg_no, uint32_t *samples, uint32_t *num_samples) -{ - uint32_t iteration_count; - uint32_t this_iteration; - int retval = ERROR_OK; - const uint32_t MAX_ITERATION = 250; - - *num_samples = 0; - - /* init DIM size */ - if (aice_write_ctrl(AICE_WRITE_CTRL_BATCH_DIM_SIZE, 4) != ERROR_OK) - return ERROR_FAIL; - - /* Use AICE_BATCH_DATA_BUFFER_0 to read/write $DTR. - * Set it to circular buffer */ - if (aice_write_ctrl(AICE_WRITE_CTRL_BATCH_DATA_BUF0_CTRL, 0xC0000) != ERROR_OK) - return ERROR_FAIL; - - fill_profiling_batch_commands(coreid, reg_no); - - iteration_count = 0; - while (iteration_count < iteration) { - if (iteration - iteration_count < MAX_ITERATION) - this_iteration = iteration - iteration_count; - else - this_iteration = MAX_ITERATION; - - /* set number of iterations */ - uint32_t val_iteration; - val_iteration = interval << 16 | this_iteration; - if (aice_write_ctrl(AICE_WRITE_CTRL_BATCH_ITERATION, - val_iteration) != ERROR_OK) { - retval = ERROR_FAIL; - goto end_profiling; - } - - /* init AICE_WRITE_CTRL_BATCH_DATA_BUF1_CTRL to store $PC */ - if (aice_write_ctrl(AICE_WRITE_CTRL_BATCH_DATA_BUF1_CTRL, - 0x40000) != ERROR_OK) { - retval = ERROR_FAIL; - goto end_profiling; - } - - aice_usb_run(coreid); - - /* enable BATCH command */ - if (aice_write_ctrl(AICE_WRITE_CTRL_BATCH_CTRL, - 0x80000000) != ERROR_OK) { - aice_usb_halt(coreid); - retval = ERROR_FAIL; - goto end_profiling; - } - - /* wait a while (AICE bug, workaround) */ - alive_sleep(this_iteration); - - /* check status */ - uint32_t i; - uint32_t batch_status = 0; - - i = 0; - while (1) { - aice_read_ctrl(AICE_READ_CTRL_BATCH_STATUS, &batch_status); - - if (batch_status & 0x1) { - break; - } else if (batch_status & 0xE) { - aice_usb_halt(coreid); - retval = ERROR_FAIL; - goto end_profiling; - } - - if ((i % 30) == 0) - keep_alive(); - - i++; - } - - aice_usb_halt(coreid); - - /* get samples from batch data buffer */ - if (aice_batch_buffer_read(AICE_BATCH_DATA_BUFFER_1, - samples + iteration_count, this_iteration) != ERROR_OK) { - retval = ERROR_FAIL; - goto end_profiling; - } - - iteration_count += this_iteration; - } - -end_profiling: - *num_samples = iteration_count; - - return retval; -} - -/** */ -struct aice_port_api_s aice_usb_api = { - /** */ - .open = aice_open_device, - /** */ - .close = aice_usb_close, - /** */ - .idcode = aice_usb_idcode, - /** */ - .state = aice_usb_state, - /** */ - .reset = aice_usb_reset, - /** */ - .assert_srst = aice_usb_assert_srst, - /** */ - .run = aice_usb_run, - /** */ - .halt = aice_usb_halt, - /** */ - .step = aice_usb_step, - /** */ - .read_reg = aice_usb_read_reg, - /** */ - .write_reg = aice_usb_write_reg, - /** */ - .read_reg_64 = aice_usb_read_reg_64, - /** */ - .write_reg_64 = aice_usb_write_reg_64, - /** */ - .read_mem_unit = aice_usb_read_memory_unit, - /** */ - .write_mem_unit = aice_usb_write_memory_unit, - /** */ - .read_mem_bulk = aice_usb_bulk_read_mem, - /** */ - .write_mem_bulk = aice_usb_bulk_write_mem, - /** */ - .read_debug_reg = aice_usb_read_debug_reg, - /** */ - .write_debug_reg = aice_usb_write_debug_reg, - /** */ - .set_jtag_clock = aice_usb_set_jtag_clock, - /** */ - .memory_access = aice_usb_memory_access, - /** */ - .memory_mode = aice_usb_memory_mode, - /** */ - .read_tlb = aice_usb_read_tlb, - /** */ - .cache_ctl = aice_usb_cache_ctl, - /** */ - .set_retry_times = aice_usb_set_retry_times, - /** */ - .program_edm = aice_usb_program_edm, - /** */ - .set_command_mode = aice_usb_set_command_mode, - /** */ - .execute = aice_usb_execute, - /** */ - .set_custom_srst_script = aice_usb_set_custom_srst_script, - /** */ - .set_custom_trst_script = aice_usb_set_custom_trst_script, - /** */ - .set_custom_restart_script = aice_usb_set_custom_restart_script, - /** */ - .set_count_to_check_dbger = aice_usb_set_count_to_check_dbger, - /** */ - .set_data_endian = aice_usb_set_data_endian, - /** */ - .profiling = aice_usb_profiling, -}; diff --git a/src/jtag/aice/aice_usb.h b/src/jtag/aice/aice_usb.h deleted file mode 100644 index d85d25f..0000000 --- a/src/jtag/aice/aice_usb.h +++ /dev/null @@ -1,122 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -/*************************************************************************** - * Copyright (C) 2013 by Andes Technology * - * Hsiangkai Wang <hkwang@andestech.com> * - ***************************************************************************/ - -#ifndef OPENOCD_JTAG_AICE_AICE_USB_H -#define OPENOCD_JTAG_AICE_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 -#define AICE_IN_BATCH_COMMAND_SIZE 512 -#define AICE_OUT_BATCH_COMMAND_SIZE 512 -#define AICE_IN_PACK_COMMAND_SIZE 2048 -#define AICE_OUT_PACK_COMMAND_SIZE 2048 - -/* 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 -#define AICE_READ_CTRL_BATCH_BUF_INFO 0x22 -#define AICE_READ_CTRL_BATCH_STATUS 0x23 -#define AICE_READ_CTRL_BATCH_BUF0_STATE 0x31 -#define AICE_READ_CTRL_BATCH_BUF4_STATE 0x39 -#define AICE_READ_CTRL_BATCH_BUF5_STATE 0x3b - -/* 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 -#define AICE_WRITE_CTRL_BATCH_CTRL 0x20 -#define AICE_WRITE_CTRL_BATCH_ITERATION 0x21 -#define AICE_WRITE_CTRL_BATCH_DIM_SIZE 0x22 -#define AICE_WRITE_CTRL_BATCH_CMD_BUF0_CTRL 0x30 -#define AICE_WRITE_CTRL_BATCH_DATA_BUF0_CTRL 0x38 -#define AICE_WRITE_CTRL_BATCH_DATA_BUF1_CTRL 0x3a - -#define AICE_BATCH_COMMAND_BUFFER_0 0x0 -#define AICE_BATCH_COMMAND_BUFFER_1 0x1 -#define AICE_BATCH_COMMAND_BUFFER_2 0x2 -#define AICE_BATCH_COMMAND_BUFFER_3 0x3 -#define AICE_BATCH_DATA_BUFFER_0 0x4 -#define AICE_BATCH_DATA_BUFFER_1 0x5 -#define AICE_BATCH_DATA_BUFFER_2 0x6 -#define AICE_BATCH_DATA_BUFFER_3 0x7 - -/* Constants for AICE command WRITE_CTRL:TCK_CONTROL */ -#define AICE_TCK_CONTROL_TCK3048 0x08 -#define AICE_TCK_CONTROL_TCK_SCAN 0x10 - -/* 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 libusb_device_handle *usb_handle; -}; - -struct cache_info { - uint32_t set; - uint32_t way; - uint32_t line_size; - - uint32_t log2_set; - uint32_t log2_line_size; -}; - -struct aice_nds32_info { - uint32_t edm_version; - uint32_t r0_backup; - uint32_t r1_backup; - uint32_t host_dtr_backup; - uint32_t target_dtr_backup; - uint32_t edmsw_backup; - uint32_t edm_ctl_backup; - bool debug_under_dex_on; - bool dex_use_psw_on; - bool host_dtr_valid; - bool target_dtr_valid; - enum nds_memory_access access_channel; - enum nds_memory_select memory_select; - enum aice_target_state_s core_state; - bool cache_init; - struct cache_info icache; - struct cache_info dcache; -}; - -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 /* OPENOCD_JTAG_AICE_AICE_USB_H */ diff --git a/src/jtag/interfaces.c b/src/jtag/interfaces.c index 67bbb3b..12848be 100644 --- a/src/jtag/interfaces.c +++ b/src/jtag/interfaces.c @@ -118,9 +118,6 @@ extern struct adapter_driver linuxgpiod_adapter_driver; #if BUILD_XLNX_PCIE_XVC == 1 extern struct adapter_driver xlnx_pcie_xvc_adapter_driver; #endif -#if BUILD_AICE == 1 -extern struct adapter_driver aice_adapter_driver; -#endif #if BUILD_BCM2835GPIO == 1 extern struct adapter_driver bcm2835gpio_adapter_driver; #endif @@ -238,9 +235,6 @@ struct adapter_driver *adapter_drivers[] = { #if BUILD_XLNX_PCIE_XVC == 1 &xlnx_pcie_xvc_adapter_driver, #endif -#if BUILD_AICE == 1 - &aice_adapter_driver, -#endif #if BUILD_BCM2835GPIO == 1 &bcm2835gpio_adapter_driver, #endif diff --git a/src/jtag/startup.tcl b/src/jtag/startup.tcl index aeb42ed..b74775a 100644 --- a/src/jtag/startup.tcl +++ b/src/jtag/startup.tcl @@ -865,12 +865,6 @@ proc ft232r_restore_serial args { eval ft232r restore_serial $args } -lappend _telnet_autocomplete_skip "aice serial" -proc "aice serial" {args} { - echo "DEPRECATED! use 'adapter serial' not 'aice serial'" - eval adapter serial $args -} - lappend _telnet_autocomplete_skip cmsis_dap_serial proc cmsis_dap_serial args { echo "DEPRECATED! use 'adapter serial' not 'cmsis_dap_serial'" diff --git a/src/rtos/FreeRTOS.c b/src/rtos/FreeRTOS.c index 8403a48..945c4b8 100644 --- a/src/rtos/FreeRTOS.c +++ b/src/rtos/FreeRTOS.c @@ -71,20 +71,6 @@ static const struct freertos_params freertos_params_list[] = { &rtos_standard_cortex_m4f_stacking, &rtos_standard_cortex_m4f_fpu_stacking, }, - { - "nds32_v3", /* target_name */ - 4, /* thread_count_width; */ - 4, /* pointer_width; */ - 16, /* list_next_offset; */ - 20, /* list_width; */ - 8, /* list_elem_next_offset; */ - 12, /* list_elem_content_offset */ - 0, /* thread_stack_offset; */ - 52, /* thread_name_offset; */ - &rtos_standard_nds32_n1068_stacking, /* stacking_info */ - &rtos_standard_cortex_m4f_stacking, - &rtos_standard_cortex_m4f_fpu_stacking, - }, }; static bool freertos_detect_rtos(struct target *target); diff --git a/src/rtos/rtos_standard_stackings.c b/src/rtos/rtos_standard_stackings.c index 5945117..f83f0a1 100644 --- a/src/rtos/rtos_standard_stackings.c +++ b/src/rtos/rtos_standard_stackings.c @@ -102,45 +102,6 @@ static const struct stack_register_offset rtos_standard_cortex_r4_stack_offsets[ { 26, 0x04, 32 }, /* CSPR */ }; -static const struct stack_register_offset rtos_standard_nds32_n1068_stack_offsets[] = { - { 0, 0x88, 32 }, /* R0 */ - { 1, 0x8C, 32 }, /* R1 */ - { 2, 0x14, 32 }, /* R2 */ - { 3, 0x18, 32 }, /* R3 */ - { 4, 0x1C, 32 }, /* R4 */ - { 5, 0x20, 32 }, /* R5 */ - { 6, 0x24, 32 }, /* R6 */ - { 7, 0x28, 32 }, /* R7 */ - { 8, 0x2C, 32 }, /* R8 */ - { 9, 0x30, 32 }, /* R9 */ - { 10, 0x34, 32 }, /* R10 */ - { 11, 0x38, 32 }, /* R11 */ - { 12, 0x3C, 32 }, /* R12 */ - { 13, 0x40, 32 }, /* R13 */ - { 14, 0x44, 32 }, /* R14 */ - { 15, 0x48, 32 }, /* R15 */ - { 16, 0x4C, 32 }, /* R16 */ - { 17, 0x50, 32 }, /* R17 */ - { 18, 0x54, 32 }, /* R18 */ - { 19, 0x58, 32 }, /* R19 */ - { 20, 0x5C, 32 }, /* R20 */ - { 21, 0x60, 32 }, /* R21 */ - { 22, 0x64, 32 }, /* R22 */ - { 23, 0x68, 32 }, /* R23 */ - { 24, 0x6C, 32 }, /* R24 */ - { 25, 0x70, 32 }, /* R25 */ - { 26, 0x74, 32 }, /* R26 */ - { 27, 0x78, 32 }, /* R27 */ - { 28, 0x7C, 32 }, /* R28 */ - { 29, 0x80, 32 }, /* R29 */ - { 30, 0x84, 32 }, /* R30 (LP) */ - { 31, 0x00, 32 }, /* R31 (SP) */ - { 32, 0x04, 32 }, /* PSW */ - { 33, 0x08, 32 }, /* IPC */ - { 34, 0x0C, 32 }, /* IPSW */ - { 35, 0x10, 32 }, /* IFC_LP */ -}; - static target_addr_t rtos_generic_stack_align(struct target *target, const uint8_t *stack_data, const struct rtos_register_stacking *stacking, target_addr_t stack_ptr, int align) @@ -268,11 +229,3 @@ const struct rtos_register_stacking rtos_standard_cortex_r4_stacking = { .calculate_process_stack = rtos_generic_stack_align8, .register_offsets = rtos_standard_cortex_r4_stack_offsets }; - -const struct rtos_register_stacking rtos_standard_nds32_n1068_stacking = { - .stack_registers_size = 0x90, - .stack_growth_direction = -1, - .num_output_registers = 32, - .calculate_process_stack = rtos_generic_stack_align8, - .register_offsets = rtos_standard_nds32_n1068_stack_offsets -}; diff --git a/src/rtos/rtos_standard_stackings.h b/src/rtos/rtos_standard_stackings.h index 83ca07f..2477fff 100644 --- a/src/rtos/rtos_standard_stackings.h +++ b/src/rtos/rtos_standard_stackings.h @@ -18,7 +18,6 @@ extern const struct rtos_register_stacking rtos_standard_cortex_m3_stacking; extern const struct rtos_register_stacking rtos_standard_cortex_m4f_stacking; extern const struct rtos_register_stacking rtos_standard_cortex_m4f_fpu_stacking; extern const struct rtos_register_stacking rtos_standard_cortex_r4_stacking; -extern const struct rtos_register_stacking rtos_standard_nds32_n1068_stacking; target_addr_t rtos_generic_stack_align8(struct target *target, const uint8_t *stack_data, const struct rtos_register_stacking *stacking, target_addr_t stack_ptr); diff --git a/src/target/Makefile.am b/src/target/Makefile.am index 4687092..2084de6 100644 --- a/src/target/Makefile.am +++ b/src/target/Makefile.am @@ -19,7 +19,6 @@ noinst_LTLIBRARIES += %D%/libtarget.la $(ARM_MISC_SRC) \ $(AVR32_SRC) \ $(MIPS32_SRC) \ - $(NDS32_SRC) \ $(STM8_SRC) \ $(INTEL_IA32_SRC) \ $(ESIRISC_SRC) \ @@ -134,18 +133,6 @@ MIPS64_SRC = \ %D%/trace.c \ %D%/mips_ejtag.c -NDS32_SRC = \ - %D%/nds32.c \ - %D%/nds32_reg.c \ - %D%/nds32_cmd.c \ - %D%/nds32_disassembler.c \ - %D%/nds32_tlb.c \ - %D%/nds32_v2.c \ - %D%/nds32_v3_common.c \ - %D%/nds32_v3.c \ - %D%/nds32_v3m.c \ - %D%/nds32_aice.c - STM8_SRC = \ %D%/stm8.c @@ -235,18 +222,6 @@ ARC_SRC = \ %D%/avr32_jtag.h \ %D%/avr32_mem.h \ %D%/avr32_regs.h \ - %D%/nds32.h \ - %D%/nds32_cmd.h \ - %D%/nds32_disassembler.h \ - %D%/nds32_edm.h \ - %D%/nds32_insn.h \ - %D%/nds32_reg.h \ - %D%/nds32_tlb.h \ - %D%/nds32_v2.h \ - %D%/nds32_v3_common.h \ - %D%/nds32_v3.h \ - %D%/nds32_v3m.h \ - %D%/nds32_aice.h \ %D%/semihosting_common.h \ %D%/stm8.h \ %D%/lakemont.h \ @@ -265,4 +240,4 @@ ARC_SRC = \ include %D%/openrisc/Makefile.am include %D%/riscv/Makefile.am include %D%/xtensa/Makefile.am -include %D%/espressif/Makefile.am
\ No newline at end of file +include %D%/espressif/Makefile.am diff --git a/src/target/nds32.c b/src/target/nds32.c deleted file mode 100644 index bd30976..0000000 --- a/src/target/nds32.c +++ /dev/null @@ -1,2613 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -/*************************************************************************** - * Copyright (C) 2013 Andes Technology * - * Hsiangkai Wang <hkwang@andestech.com> * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <helper/log.h> -#include <helper/binarybuffer.h> -#include "nds32.h" -#include "nds32_aice.h" -#include "nds32_tlb.h" -#include "nds32_disassembler.h" - -struct nds32_edm_operation nds32_edm_ops[NDS32_EDM_OPERATION_MAX_NUM]; -uint32_t nds32_edm_ops_num; - -const char *nds32_debug_type_name[11] = { - "SOFTWARE BREAK", - "SOFTWARE BREAK_16", - "HARDWARE BREAKPOINT", - "DATA ADDR WATCHPOINT PRECISE", - "DATA VALUE WATCHPOINT PRECISE", - "DATA VALUE WATCHPOINT IMPRECISE", - "DEBUG INTERRUPT", - "HARDWARE SINGLE STEP", - "DATA ADDR WATCHPOINT NEXT PRECISE", - "DATA VALUE WATCHPOINT NEXT PRECISE", - "LOAD STORE GLOBAL STOP", -}; - -static const int nds32_lm_size_table[16] = { - 4 * 1024, - 8 * 1024, - 16 * 1024, - 32 * 1024, - 64 * 1024, - 128 * 1024, - 256 * 1024, - 512 * 1024, - 1024 * 1024, - 1 * 1024, - 2 * 1024, -}; - -static const int nds32_line_size_table[6] = { - 0, - 8, - 16, - 32, - 64, - 128, -}; - -static int nds32_get_core_reg(struct reg *reg) -{ - int retval; - struct nds32_reg *reg_arch_info = reg->arch_info; - struct target *target = reg_arch_info->target; - struct nds32 *nds32 = target_to_nds32(target); - struct aice_port_s *aice = target_to_aice(target); - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (reg->valid) { - uint32_t val = buf_get_u32(reg_arch_info->value, 0, 32); - LOG_DEBUG("reading register(cached) %" PRIi32 "(%s), value: 0x%8.8" PRIx32, - reg_arch_info->num, reg->name, val); - return ERROR_OK; - } - - int mapped_regnum = nds32->register_map(nds32, reg_arch_info->num); - - if (reg_arch_info->enable == false) { - buf_set_u32(reg_arch_info->value, 0, 32, NDS32_REGISTER_DISABLE); - retval = ERROR_FAIL; - } else { - uint32_t val = 0; - if ((nds32->fpu_enable == false) - && (nds32_reg_type(mapped_regnum) == NDS32_REG_TYPE_FPU)) { - retval = ERROR_OK; - } else if ((nds32->audio_enable == false) - && (nds32_reg_type(mapped_regnum) == NDS32_REG_TYPE_AUMR)) { - retval = ERROR_OK; - } else { - retval = aice_read_register(aice, mapped_regnum, &val); - } - buf_set_u32(reg_arch_info->value, 0, 32, val); - - LOG_DEBUG("reading register %" PRIi32 "(%s), value: 0x%8.8" PRIx32, - reg_arch_info->num, reg->name, val); - } - - if (retval == ERROR_OK) { - reg->valid = true; - reg->dirty = false; - } - - return retval; -} - -static int nds32_get_core_reg_64(struct reg *reg) -{ - int retval; - struct nds32_reg *reg_arch_info = reg->arch_info; - struct target *target = reg_arch_info->target; - struct nds32 *nds32 = target_to_nds32(target); - struct aice_port_s *aice = target_to_aice(target); - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (reg->valid) - return ERROR_OK; - - if (reg_arch_info->enable == false) { - buf_set_u64(reg_arch_info->value, 0, 64, NDS32_REGISTER_DISABLE); - retval = ERROR_FAIL; - } else { - uint64_t val = 0; - if ((nds32->fpu_enable == false) - && ((reg_arch_info->num >= FD0) && (reg_arch_info->num <= FD31))) { - retval = ERROR_OK; - } else { - retval = aice_read_reg_64(aice, reg_arch_info->num, &val); - } - buf_set_u64(reg_arch_info->value, 0, 64, val); - } - - if (retval == ERROR_OK) { - reg->valid = true; - reg->dirty = false; - } - - return retval; -} - -static int nds32_update_psw(struct nds32 *nds32) -{ - uint32_t value_ir0; - struct aice_port_s *aice = target_to_aice(nds32->target); - - nds32_get_mapped_reg(nds32, IR0, &value_ir0); - - /* Save data memory endian */ - if ((value_ir0 >> 5) & 0x1) { - nds32->data_endian = TARGET_BIG_ENDIAN; - aice_set_data_endian(aice, AICE_BIG_ENDIAN); - } else { - nds32->data_endian = TARGET_LITTLE_ENDIAN; - aice_set_data_endian(aice, AICE_LITTLE_ENDIAN); - } - - /* Save translation status */ - nds32->memory.address_translation = ((value_ir0 >> 7) & 0x1) ? true : false; - - return ERROR_OK; -} - -static int nds32_update_mmu_info(struct nds32 *nds32) -{ - uint32_t value; - - /* Update MMU control status */ - nds32_get_mapped_reg(nds32, MR0, &value); - nds32->mmu_config.default_min_page_size = value & 0x1; - nds32->mmu_config.multiple_page_size_in_use = (value >> 10) & 0x1; - - return ERROR_OK; -} - -static int nds32_update_cache_info(struct nds32 *nds32) -{ - uint32_t value; - - if (nds32_get_mapped_reg(nds32, MR8, &value) == ERROR_OK) { - if (value & 0x1) - nds32->memory.icache.enable = true; - else - nds32->memory.icache.enable = false; - - if (value & 0x2) - nds32->memory.dcache.enable = true; - else - nds32->memory.dcache.enable = false; - } else { - nds32->memory.icache.enable = false; - nds32->memory.dcache.enable = false; - } - - return ERROR_OK; -} - -static int nds32_update_lm_info(struct nds32 *nds32) -{ - struct nds32_memory *memory = &(nds32->memory); - uint32_t value_mr6; - uint32_t value_mr7; - - nds32_get_mapped_reg(nds32, MR6, &value_mr6); - if (value_mr6 & 0x1) - memory->ilm_enable = true; - else - memory->ilm_enable = false; - - if (memory->ilm_align_ver == 0) { /* 1MB aligned */ - memory->ilm_start = value_mr6 & 0xFFF00000; - memory->ilm_end = memory->ilm_start + memory->ilm_size; - } else if (memory->ilm_align_ver == 1) { /* aligned to local memory size */ - memory->ilm_start = value_mr6 & 0xFFFFFC00; - memory->ilm_end = memory->ilm_start + memory->ilm_size; - } else { - memory->ilm_start = -1; - memory->ilm_end = -1; - } - - nds32_get_mapped_reg(nds32, MR7, &value_mr7); - if (value_mr7 & 0x1) - memory->dlm_enable = true; - else - memory->dlm_enable = false; - - if (memory->dlm_align_ver == 0) { /* 1MB aligned */ - memory->dlm_start = value_mr7 & 0xFFF00000; - memory->dlm_end = memory->dlm_start + memory->dlm_size; - } else if (memory->dlm_align_ver == 1) { /* aligned to local memory size */ - memory->dlm_start = value_mr7 & 0xFFFFFC00; - memory->dlm_end = memory->dlm_start + memory->dlm_size; - } else { - memory->dlm_start = -1; - memory->dlm_end = -1; - } - - return ERROR_OK; -} - -/** - * If fpu/audio is disabled, to access fpu/audio registers will cause - * exceptions. So, we need to check if fpu/audio is enabled or not as - * target is halted. If fpu/audio is disabled, as users access fpu/audio - * registers, OpenOCD will return fake value 0 instead of accessing - * registers through DIM. - */ -static int nds32_check_extension(struct nds32 *nds32) -{ - uint32_t value; - - nds32_get_mapped_reg(nds32, FUCPR, &value); - if (value == NDS32_REGISTER_DISABLE) { - nds32->fpu_enable = false; - nds32->audio_enable = false; - return ERROR_OK; - } - - if (value & 0x1) - nds32->fpu_enable = true; - else - nds32->fpu_enable = false; - - if (value & 0x80000000) - nds32->audio_enable = true; - else - nds32->audio_enable = false; - - return ERROR_OK; -} - -static int nds32_set_core_reg(struct reg *reg, uint8_t *buf) -{ - struct nds32_reg *reg_arch_info = reg->arch_info; - struct target *target = reg_arch_info->target; - struct nds32 *nds32 = target_to_nds32(target); - struct aice_port_s *aice = target_to_aice(target); - uint32_t value = buf_get_u32(buf, 0, 32); - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - int mapped_regnum = nds32->register_map(nds32, reg_arch_info->num); - - /* ignore values that will generate exception */ - if (nds32_reg_exception(mapped_regnum, value)) - return ERROR_OK; - - LOG_DEBUG("writing register %" PRIi32 "(%s) with value 0x%8.8" PRIx32, - reg_arch_info->num, reg->name, value); - - if ((nds32->fpu_enable == false) && - (nds32_reg_type(mapped_regnum) == NDS32_REG_TYPE_FPU)) { - - buf_set_u32(reg->value, 0, 32, 0); - } else if ((nds32->audio_enable == false) && - (nds32_reg_type(mapped_regnum) == NDS32_REG_TYPE_AUMR)) { - - buf_set_u32(reg->value, 0, 32, 0); - } else { - buf_set_u32(reg->value, 0, 32, value); - uint32_t val = buf_get_u32(reg_arch_info->value, 0, 32); - aice_write_register(aice, mapped_regnum, val); - - /* After set value to registers, read the value from target - * to avoid W1C inconsistency. */ - aice_read_register(aice, mapped_regnum, &val); - buf_set_u32(reg_arch_info->value, 0, 32, val); - } - - reg->valid = true; - reg->dirty = false; - - /* update registers to take effect right now */ - if (mapped_regnum == IR0) { - nds32_update_psw(nds32); - } else if (mapped_regnum == MR0) { - nds32_update_mmu_info(nds32); - } else if ((mapped_regnum == MR6) || (mapped_regnum == MR7)) { - /* update lm information */ - nds32_update_lm_info(nds32); - } else if (mapped_regnum == MR8) { - nds32_update_cache_info(nds32); - } else if (mapped_regnum == FUCPR) { - /* update audio/fpu setting */ - nds32_check_extension(nds32); - } - - return ERROR_OK; -} - -static int nds32_set_core_reg_64(struct reg *reg, uint8_t *buf) -{ - struct nds32_reg *reg_arch_info = reg->arch_info; - struct target *target = reg_arch_info->target; - struct nds32 *nds32 = target_to_nds32(target); - uint32_t low_part = buf_get_u32(buf, 0, 32); - uint32_t high_part = buf_get_u32(buf, 32, 32); - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if ((nds32->fpu_enable == false) && - ((reg_arch_info->num >= FD0) && (reg_arch_info->num <= FD31))) { - - buf_set_u32(reg->value, 0, 32, 0); - buf_set_u32(reg->value, 32, 32, 0); - - reg->valid = true; - reg->dirty = false; - } else { - buf_set_u32(reg->value, 0, 32, low_part); - buf_set_u32(reg->value, 32, 32, high_part); - - reg->valid = true; - reg->dirty = true; - } - - return ERROR_OK; -} - -static const struct reg_arch_type nds32_reg_access_type = { - .get = nds32_get_core_reg, - .set = nds32_set_core_reg, -}; - -static const struct reg_arch_type nds32_reg_access_type_64 = { - .get = nds32_get_core_reg_64, - .set = nds32_set_core_reg_64, -}; - -static struct reg_cache *nds32_build_reg_cache(struct target *target, - struct nds32 *nds32) -{ - struct reg_cache *cache = calloc(sizeof(struct reg_cache), 1); - struct reg *reg_list = calloc(TOTAL_REG_NUM, sizeof(struct reg)); - struct nds32_reg *reg_arch_info = calloc(TOTAL_REG_NUM, sizeof(struct nds32_reg)); - int i; - - if (!cache || !reg_list || !reg_arch_info) { - free(cache); - free(reg_list); - free(reg_arch_info); - return NULL; - } - - cache->name = "Andes registers"; - cache->next = NULL; - cache->reg_list = reg_list; - cache->num_regs = 0; - - for (i = 0; i < TOTAL_REG_NUM; i++) { - reg_arch_info[i].num = i; - reg_arch_info[i].target = target; - reg_arch_info[i].nds32 = nds32; - reg_arch_info[i].enable = false; - - reg_list[i].name = nds32_reg_simple_name(i); - reg_list[i].number = reg_arch_info[i].num; - reg_list[i].size = nds32_reg_size(i); - reg_list[i].arch_info = ®_arch_info[i]; - - reg_list[i].reg_data_type = calloc(sizeof(struct reg_data_type), 1); - - if (reg_arch_info[i].num >= FD0 && reg_arch_info[i].num <= FD31) { - reg_list[i].value = reg_arch_info[i].value; - reg_list[i].type = &nds32_reg_access_type_64; - - reg_list[i].reg_data_type->type = REG_TYPE_IEEE_DOUBLE; - reg_list[i].reg_data_type->id = "ieee_double"; - reg_list[i].group = "float"; - } else { - reg_list[i].value = reg_arch_info[i].value; - reg_list[i].type = &nds32_reg_access_type; - reg_list[i].group = "general"; - - if ((reg_arch_info[i].num >= FS0) && (reg_arch_info[i].num <= FS31)) { - reg_list[i].reg_data_type->type = REG_TYPE_IEEE_SINGLE; - reg_list[i].reg_data_type->id = "ieee_single"; - reg_list[i].group = "float"; - } else if ((reg_arch_info[i].num == FPCSR) || - (reg_arch_info[i].num == FPCFG)) { - reg_list[i].group = "float"; - } else if ((reg_arch_info[i].num == R28) || - (reg_arch_info[i].num == R29) || - (reg_arch_info[i].num == R31)) { - reg_list[i].reg_data_type->type = REG_TYPE_DATA_PTR; - reg_list[i].reg_data_type->id = "data_ptr"; - } else if ((reg_arch_info[i].num == R30) || - (reg_arch_info[i].num == PC)) { - reg_list[i].reg_data_type->type = REG_TYPE_CODE_PTR; - reg_list[i].reg_data_type->id = "code_ptr"; - } else { - reg_list[i].reg_data_type->type = REG_TYPE_UINT32; - reg_list[i].reg_data_type->id = "uint32"; - } - } - - if (reg_arch_info[i].num >= R16 && reg_arch_info[i].num <= R25) - reg_list[i].caller_save = true; - else - reg_list[i].caller_save = false; - - reg_list[i].feature = malloc(sizeof(struct reg_feature)); - - if (reg_arch_info[i].num >= R0 && reg_arch_info[i].num <= IFC_LP) - reg_list[i].feature->name = "org.gnu.gdb.nds32.core"; - else if (reg_arch_info[i].num >= CR0 && reg_arch_info[i].num <= SECUR0) - reg_list[i].feature->name = "org.gnu.gdb.nds32.system"; - else if (reg_arch_info[i].num >= D0L24 && reg_arch_info[i].num <= CBE3) - reg_list[i].feature->name = "org.gnu.gdb.nds32.audio"; - else if (reg_arch_info[i].num >= FPCSR && reg_arch_info[i].num <= FD31) - reg_list[i].feature->name = "org.gnu.gdb.nds32.fpu"; - - cache->num_regs++; - } - - nds32->core_cache = cache; - - return cache; -} - -static int nds32_reg_cache_init(struct target *target, struct nds32 *nds32) -{ - struct reg_cache *cache; - - cache = nds32_build_reg_cache(target, nds32); - if (!cache) - return ERROR_FAIL; - - *register_get_last_cache_p(&target->reg_cache) = cache; - - return ERROR_OK; -} - -static struct reg *nds32_reg_current(struct nds32 *nds32, unsigned regnum) -{ - struct reg *r; - - r = nds32->core_cache->reg_list + regnum; - - return r; -} - -int nds32_full_context(struct nds32 *nds32) -{ - uint32_t value, value_ir0; - - /* save $pc & $psw */ - nds32_get_mapped_reg(nds32, PC, &value); - nds32_get_mapped_reg(nds32, IR0, &value_ir0); - - nds32_update_psw(nds32); - nds32_update_mmu_info(nds32); - nds32_update_cache_info(nds32); - nds32_update_lm_info(nds32); - - nds32_check_extension(nds32); - - return ERROR_OK; -} - -/* get register value internally */ -int nds32_get_mapped_reg(struct nds32 *nds32, unsigned regnum, uint32_t *value) -{ - struct reg_cache *reg_cache = nds32->core_cache; - struct reg *r; - - if (regnum > reg_cache->num_regs) - return ERROR_FAIL; - - r = nds32_reg_current(nds32, regnum); - - if (r->type->get(r) != ERROR_OK) - return ERROR_FAIL; - - *value = buf_get_u32(r->value, 0, 32); - - return ERROR_OK; -} - -/** set register internally */ -int nds32_set_mapped_reg(struct nds32 *nds32, unsigned regnum, uint32_t value) -{ - struct reg_cache *reg_cache = nds32->core_cache; - struct reg *r; - uint8_t set_value[4]; - - if (regnum > reg_cache->num_regs) - return ERROR_FAIL; - - r = nds32_reg_current(nds32, regnum); - - buf_set_u32(set_value, 0, 32, value); - - return r->type->set(r, set_value); -} - -/** get general register list */ -static int nds32_get_general_reg_list(struct nds32 *nds32, - struct reg **reg_list[], int *reg_list_size) -{ - struct reg *reg_current; - int i; - int current_idx; - - /** freed in gdb_server.c */ - *reg_list = malloc(sizeof(struct reg *) * (IFC_LP - R0 + 1)); - current_idx = 0; - - for (i = R0; i < IFC_LP + 1; i++) { - reg_current = nds32_reg_current(nds32, i); - if (((struct nds32_reg *)reg_current->arch_info)->enable) { - (*reg_list)[current_idx] = reg_current; - current_idx++; - } - } - *reg_list_size = current_idx; - - return ERROR_OK; -} - -/** get all register list */ -static int nds32_get_all_reg_list(struct nds32 *nds32, - struct reg **reg_list[], int *reg_list_size) -{ - struct reg_cache *reg_cache = nds32->core_cache; - struct reg *reg_current; - unsigned int i; - - *reg_list_size = reg_cache->num_regs; - - /** freed in gdb_server.c */ - *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size)); - - for (i = 0; i < reg_cache->num_regs; i++) { - reg_current = nds32_reg_current(nds32, i); - reg_current->exist = ((struct nds32_reg *) - reg_current->arch_info)->enable; - (*reg_list)[i] = reg_current; - } - - return ERROR_OK; -} - -/** get all register list */ -int nds32_get_gdb_reg_list(struct target *target, - struct reg **reg_list[], int *reg_list_size, - enum target_register_class reg_class) -{ - struct nds32 *nds32 = target_to_nds32(target); - - switch (reg_class) { - case REG_CLASS_ALL: - return nds32_get_all_reg_list(nds32, reg_list, reg_list_size); - case REG_CLASS_GENERAL: - return nds32_get_general_reg_list(nds32, reg_list, reg_list_size); - default: - return ERROR_FAIL; - } - - return ERROR_FAIL; -} - -static int nds32_select_memory_mode(struct target *target, uint32_t address, - uint32_t length, uint32_t *end_address) -{ - struct nds32 *nds32 = target_to_nds32(target); - struct aice_port_s *aice = target_to_aice(target); - struct nds32_memory *memory = &(nds32->memory); - struct nds32_edm *edm = &(nds32->edm); - uint32_t dlm_start, dlm_end; - uint32_t ilm_start, ilm_end; - uint32_t address_end = address + length; - - /* init end_address */ - *end_address = address_end; - - if (memory->access_channel == NDS_MEMORY_ACC_CPU) - return ERROR_OK; - - if (edm->access_control == false) { - LOG_DEBUG("EDM does not support ACC_CTL"); - return ERROR_OK; - } - - if (edm->direct_access_local_memory == false) { - LOG_DEBUG("EDM does not support DALM"); - aice_memory_mode(aice, NDS_MEMORY_SELECT_MEM); - return ERROR_OK; - } - - if (memory->mode != NDS_MEMORY_SELECT_AUTO) { - LOG_DEBUG("Memory mode is not AUTO"); - return ERROR_OK; - } - - /* set default mode */ - aice_memory_mode(aice, NDS_MEMORY_SELECT_MEM); - - if ((memory->ilm_base != 0) && (memory->ilm_enable == true)) { - ilm_start = memory->ilm_start; - ilm_end = memory->ilm_end; - - /* case 1, address < ilm_start */ - if (address < ilm_start) { - if (ilm_start < address_end) { - /* update end_address to split non-ILM from ILM */ - *end_address = ilm_start; - } - /* MEM mode */ - aice_memory_mode(aice, NDS_MEMORY_SELECT_MEM); - } else if ((ilm_start <= address) && (address < ilm_end)) { - /* case 2, ilm_start <= address < ilm_end */ - if (ilm_end < address_end) { - /* update end_address to split non-ILM from ILM */ - *end_address = ilm_end; - } - /* ILM mode */ - aice_memory_mode(aice, NDS_MEMORY_SELECT_ILM); - } else { /* case 3, ilm_end <= address */ - /* MEM mode */ - aice_memory_mode(aice, NDS_MEMORY_SELECT_MEM); - } - - return ERROR_OK; - } else { - LOG_DEBUG("ILM is not enabled"); - } - - if ((memory->dlm_base != 0) && (memory->dlm_enable == true)) { - dlm_start = memory->dlm_start; - dlm_end = memory->dlm_end; - - /* case 1, address < dlm_start */ - if (address < dlm_start) { - if (dlm_start < address_end) { - /* update end_address to split non-DLM from DLM */ - *end_address = dlm_start; - } - /* MEM mode */ - aice_memory_mode(aice, NDS_MEMORY_SELECT_MEM); - } else if ((dlm_start <= address) && (address < dlm_end)) { - /* case 2, dlm_start <= address < dlm_end */ - if (dlm_end < address_end) { - /* update end_address to split non-DLM from DLM */ - *end_address = dlm_end; - } - /* DLM mode */ - aice_memory_mode(aice, NDS_MEMORY_SELECT_DLM); - } else { /* case 3, dlm_end <= address */ - /* MEM mode */ - aice_memory_mode(aice, NDS_MEMORY_SELECT_MEM); - } - - return ERROR_OK; - } else { - LOG_DEBUG("DLM is not enabled"); - } - - return ERROR_OK; -} - -int nds32_read_buffer(struct target *target, uint32_t address, - uint32_t size, uint8_t *buffer) -{ - struct nds32 *nds32 = target_to_nds32(target); - struct nds32_memory *memory = &(nds32->memory); - - if ((memory->access_channel == NDS_MEMORY_ACC_CPU) && - (target->state != TARGET_HALTED)) { - LOG_WARNING("target was not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - LOG_DEBUG("READ BUFFER: ADDR %08" PRIx32 " SIZE %08" PRIx32, - address, - size); - - int retval = ERROR_OK; - struct aice_port_s *aice = target_to_aice(target); - uint32_t end_address; - - if (((address % 2) == 0) && (size == 2)) { - nds32_select_memory_mode(target, address, 2, &end_address); - return aice_read_mem_unit(aice, address, 2, 1, buffer); - } - - /* handle unaligned head bytes */ - if (address % 4) { - uint32_t unaligned = 4 - (address % 4); - - if (unaligned > size) - unaligned = size; - - nds32_select_memory_mode(target, address, unaligned, &end_address); - retval = aice_read_mem_unit(aice, address, 1, unaligned, buffer); - if (retval != ERROR_OK) - return retval; - - buffer += unaligned; - address += unaligned; - size -= unaligned; - } - - /* handle aligned words */ - if (size >= 4) { - int aligned = size - (size % 4); - int read_len; - - do { - nds32_select_memory_mode(target, address, aligned, &end_address); - - read_len = end_address - address; - - if (read_len > 8) - retval = aice_read_mem_bulk(aice, address, read_len, buffer); - else - retval = aice_read_mem_unit(aice, address, 4, read_len / 4, buffer); - - if (retval != ERROR_OK) - return retval; - - buffer += read_len; - address += read_len; - size -= read_len; - aligned -= read_len; - - } while (aligned != 0); - } - - /*prevent byte access when possible (avoid AHB access limitations in some cases)*/ - if (size >= 2) { - int aligned = size - (size % 2); - nds32_select_memory_mode(target, address, aligned, &end_address); - retval = aice_read_mem_unit(aice, address, 2, aligned / 2, buffer); - if (retval != ERROR_OK) - return retval; - - buffer += aligned; - address += aligned; - size -= aligned; - } - /* handle tail writes of less than 4 bytes */ - if (size > 0) { - nds32_select_memory_mode(target, address, size, &end_address); - retval = aice_read_mem_unit(aice, address, 1, size, buffer); - if (retval != ERROR_OK) - return retval; - } - - return ERROR_OK; -} - -int nds32_read_memory(struct target *target, uint32_t address, - uint32_t size, uint32_t count, uint8_t *buffer) -{ - struct aice_port_s *aice = target_to_aice(target); - - return aice_read_mem_unit(aice, address, size, count, buffer); -} - -int nds32_read_phys_memory(struct target *target, target_addr_t address, - uint32_t size, uint32_t count, uint8_t *buffer) -{ - struct aice_port_s *aice = target_to_aice(target); - struct nds32 *nds32 = target_to_nds32(target); - struct nds32_memory *memory = &(nds32->memory); - enum nds_memory_access orig_channel; - int result; - - /* switch to BUS access mode to skip MMU */ - orig_channel = memory->access_channel; - memory->access_channel = NDS_MEMORY_ACC_BUS; - aice_memory_access(aice, memory->access_channel); - - /* The input address is physical address. No need to do address translation. */ - result = aice_read_mem_unit(aice, address, size, count, buffer); - - /* restore to origin access mode */ - memory->access_channel = orig_channel; - aice_memory_access(aice, memory->access_channel); - - return result; -} - -int nds32_write_buffer(struct target *target, uint32_t address, - uint32_t size, const uint8_t *buffer) -{ - struct nds32 *nds32 = target_to_nds32(target); - struct nds32_memory *memory = &(nds32->memory); - - if ((memory->access_channel == NDS_MEMORY_ACC_CPU) && - (target->state != TARGET_HALTED)) { - LOG_WARNING("target was not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - LOG_DEBUG("WRITE BUFFER: ADDR %08" PRIx32 " SIZE %08" PRIx32, - address, - size); - - struct aice_port_s *aice = target_to_aice(target); - int retval = ERROR_OK; - uint32_t end_address; - - if (((address % 2) == 0) && (size == 2)) { - nds32_select_memory_mode(target, address, 2, &end_address); - return aice_write_mem_unit(aice, address, 2, 1, buffer); - } - - /* handle unaligned head bytes */ - if (address % 4) { - uint32_t unaligned = 4 - (address % 4); - - if (unaligned > size) - unaligned = size; - - nds32_select_memory_mode(target, address, unaligned, &end_address); - retval = aice_write_mem_unit(aice, address, 1, unaligned, buffer); - if (retval != ERROR_OK) - return retval; - - buffer += unaligned; - address += unaligned; - size -= unaligned; - } - - /* handle aligned words */ - if (size >= 4) { - int aligned = size - (size % 4); - int write_len; - - do { - nds32_select_memory_mode(target, address, aligned, &end_address); - - write_len = end_address - address; - if (write_len > 8) - retval = aice_write_mem_bulk(aice, address, write_len, buffer); - else - retval = aice_write_mem_unit(aice, address, 4, write_len / 4, buffer); - if (retval != ERROR_OK) - return retval; - - buffer += write_len; - address += write_len; - size -= write_len; - aligned -= write_len; - - } while (aligned != 0); - } - - /* handle tail writes of less than 4 bytes */ - if (size > 0) { - nds32_select_memory_mode(target, address, size, &end_address); - retval = aice_write_mem_unit(aice, address, 1, size, buffer); - if (retval != ERROR_OK) - return retval; - } - - return retval; -} - -int nds32_write_memory(struct target *target, uint32_t address, - uint32_t size, uint32_t count, const uint8_t *buffer) -{ - struct aice_port_s *aice = target_to_aice(target); - - return aice_write_mem_unit(aice, address, size, count, buffer); -} - -int nds32_write_phys_memory(struct target *target, target_addr_t address, - uint32_t size, uint32_t count, const uint8_t *buffer) -{ - struct aice_port_s *aice = target_to_aice(target); - struct nds32 *nds32 = target_to_nds32(target); - struct nds32_memory *memory = &(nds32->memory); - enum nds_memory_access orig_channel; - int result; - - /* switch to BUS access mode to skip MMU */ - orig_channel = memory->access_channel; - memory->access_channel = NDS_MEMORY_ACC_BUS; - aice_memory_access(aice, memory->access_channel); - - /* The input address is physical address. No need to do address translation. */ - result = aice_write_mem_unit(aice, address, size, count, buffer); - - /* restore to origin access mode */ - memory->access_channel = orig_channel; - aice_memory_access(aice, memory->access_channel); - - return result; -} - -int nds32_mmu(struct target *target, int *enabled) -{ - if (target->state != TARGET_HALTED) { - LOG_ERROR("%s: target not halted", __func__); - return ERROR_TARGET_INVALID; - } - - struct nds32 *nds32 = target_to_nds32(target); - struct nds32_memory *memory = &(nds32->memory); - struct nds32_mmu_config *mmu_config = &(nds32->mmu_config); - - if ((mmu_config->memory_protection == 2) && (memory->address_translation == true)) - *enabled = 1; - else - *enabled = 0; - - return ERROR_OK; -} - -int nds32_arch_state(struct target *target) -{ - struct nds32 *nds32 = target_to_nds32(target); - - if (nds32->common_magic != NDS32_COMMON_MAGIC) { - LOG_ERROR("BUG: called for a non-Andes target"); - return ERROR_FAIL; - } - - uint32_t value_pc, value_psw; - - nds32_get_mapped_reg(nds32, PC, &value_pc); - nds32_get_mapped_reg(nds32, IR0, &value_psw); - - LOG_USER("target halted due to %s\n" - "psw: 0x%8.8" PRIx32 " pc: 0x%8.8" PRIx32 "%s", - debug_reason_name(target), - value_psw, - value_pc, - nds32->virtual_hosting ? ", virtual hosting" : ""); - - /* save pc value to pseudo register pc */ - struct reg *reg = register_get_by_name(target->reg_cache, "pc", true); - buf_set_u32(reg->value, 0, 32, value_pc); - - return ERROR_OK; -} - -static void nds32_init_must_have_registers(struct nds32 *nds32) -{ - struct reg_cache *reg_cache = nds32->core_cache; - - /** MUST have general registers */ - ((struct nds32_reg *)reg_cache->reg_list[R0].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R1].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R2].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R3].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R4].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R5].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R6].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R7].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R8].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R9].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R10].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R15].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R28].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R29].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R30].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R31].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[PC].arch_info)->enable = true; - - /** MUST have configuration system registers */ - ((struct nds32_reg *)reg_cache->reg_list[CR0].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[CR1].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[CR2].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[CR3].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[CR4].arch_info)->enable = true; - - /** MUST have interrupt system registers */ - ((struct nds32_reg *)reg_cache->reg_list[IR0].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[IR1].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[IR3].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[IR4].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[IR6].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[IR9].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[IR11].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[IR14].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[IR15].arch_info)->enable = true; - - /** MUST have MMU system registers */ - ((struct nds32_reg *)reg_cache->reg_list[MR0].arch_info)->enable = true; - - /** MUST have EDM system registers */ - ((struct nds32_reg *)reg_cache->reg_list[DR40].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[DR42].arch_info)->enable = true; -} - -static int nds32_init_memory_config(struct nds32 *nds32) -{ - uint32_t value_cr1; /* ICM_CFG */ - uint32_t value_cr2; /* DCM_CFG */ - struct nds32_memory *memory = &(nds32->memory); - - /* read $cr1 to init instruction memory information */ - nds32_get_mapped_reg(nds32, CR1, &value_cr1); - memory->icache.set = value_cr1 & 0x7; - memory->icache.way = (value_cr1 >> 3) & 0x7; - memory->icache.line_size = (value_cr1 >> 6) & 0x7; - memory->icache.lock_support = (value_cr1 >> 9) & 0x1; - - memory->ilm_base = (value_cr1 >> 10) & 0x7; - memory->ilm_align_ver = (value_cr1 >> 13) & 0x3; - - /* read $cr2 to init data memory information */ - nds32_get_mapped_reg(nds32, CR2, &value_cr2); - memory->dcache.set = value_cr2 & 0x7; - memory->dcache.way = (value_cr2 >> 3) & 0x7; - memory->dcache.line_size = (value_cr2 >> 6) & 0x7; - memory->dcache.lock_support = (value_cr2 >> 9) & 0x1; - - memory->dlm_base = (value_cr2 >> 10) & 0x7; - memory->dlm_align_ver = (value_cr2 >> 13) & 0x3; - - return ERROR_OK; -} - -static void nds32_init_config(struct nds32 *nds32) -{ - uint32_t value_cr0; - uint32_t value_cr3; - uint32_t value_cr4; - struct nds32_cpu_version *cpu_version = &(nds32->cpu_version); - struct nds32_mmu_config *mmu_config = &(nds32->mmu_config); - struct nds32_misc_config *misc_config = &(nds32->misc_config); - - nds32_get_mapped_reg(nds32, CR0, &value_cr0); - nds32_get_mapped_reg(nds32, CR3, &value_cr3); - nds32_get_mapped_reg(nds32, CR4, &value_cr4); - - /* config cpu version */ - cpu_version->performance_extension = value_cr0 & 0x1; - cpu_version->_16bit_extension = (value_cr0 >> 1) & 0x1; - cpu_version->performance_extension_2 = (value_cr0 >> 2) & 0x1; - cpu_version->cop_fpu_extension = (value_cr0 >> 3) & 0x1; - cpu_version->string_extension = (value_cr0 >> 4) & 0x1; - cpu_version->revision = (value_cr0 >> 16) & 0xFF; - cpu_version->cpu_id_family = (value_cr0 >> 24) & 0xF; - cpu_version->cpu_id_version = (value_cr0 >> 28) & 0xF; - - /* config MMU */ - mmu_config->memory_protection = value_cr3 & 0x3; - mmu_config->memory_protection_version = (value_cr3 >> 2) & 0x1F; - mmu_config->fully_associative_tlb = (value_cr3 >> 7) & 0x1; - if (mmu_config->fully_associative_tlb) { - mmu_config->tlb_size = (value_cr3 >> 8) & 0x7F; - } else { - mmu_config->tlb_ways = (value_cr3 >> 8) & 0x7; - mmu_config->tlb_sets = (value_cr3 >> 11) & 0x7; - } - mmu_config->_8k_page_support = (value_cr3 >> 15) & 0x1; - mmu_config->extra_page_size_support = (value_cr3 >> 16) & 0xFF; - mmu_config->tlb_lock = (value_cr3 >> 24) & 0x1; - mmu_config->hardware_page_table_walker = (value_cr3 >> 25) & 0x1; - mmu_config->default_endian = (value_cr3 >> 26) & 0x1; - mmu_config->partition_num = (value_cr3 >> 27) & 0x1; - mmu_config->invisible_tlb = (value_cr3 >> 28) & 0x1; - mmu_config->vlpt = (value_cr3 >> 29) & 0x1; - mmu_config->ntme = (value_cr3 >> 30) & 0x1; - mmu_config->drde = (value_cr3 >> 31) & 0x1; - - /* config misc */ - misc_config->edm = value_cr4 & 0x1; - misc_config->local_memory_dma = (value_cr4 >> 1) & 0x1; - misc_config->performance_monitor = (value_cr4 >> 2) & 0x1; - misc_config->high_speed_memory_port = (value_cr4 >> 3) & 0x1; - misc_config->debug_tracer = (value_cr4 >> 4) & 0x1; - misc_config->div_instruction = (value_cr4 >> 5) & 0x1; - misc_config->mac_instruction = (value_cr4 >> 6) & 0x1; - misc_config->audio_isa = (value_cr4 >> 7) & 0x3; - misc_config->l2_cache = (value_cr4 >> 9) & 0x1; - misc_config->reduce_register = (value_cr4 >> 10) & 0x1; - misc_config->addr_24 = (value_cr4 >> 11) & 0x1; - misc_config->interruption_level = (value_cr4 >> 12) & 0x1; - misc_config->baseline_instruction = (value_cr4 >> 13) & 0x7; - misc_config->no_dx_register = (value_cr4 >> 16) & 0x1; - misc_config->implement_dependant_register = (value_cr4 >> 17) & 0x1; - misc_config->implement_dependant_sr_encoding = (value_cr4 >> 18) & 0x1; - misc_config->ifc = (value_cr4 >> 19) & 0x1; - misc_config->mcu = (value_cr4 >> 20) & 0x1; - misc_config->shadow = (value_cr4 >> 21) & 0x7; - misc_config->ex9 = (value_cr4 >> 24) & 0x1; - - nds32_init_memory_config(nds32); -} - -static int nds32_init_option_registers(struct nds32 *nds32) -{ - struct reg_cache *reg_cache = nds32->core_cache; - struct nds32_cpu_version *cpu_version = &(nds32->cpu_version); - struct nds32_mmu_config *mmu_config = &(nds32->mmu_config); - struct nds32_misc_config *misc_config = &(nds32->misc_config); - struct nds32_memory *memory_config = &(nds32->memory); - - bool no_cr5; - bool mr10_exist; - bool no_racr0; - - if (((cpu_version->cpu_id_family == 0xC) || (cpu_version->cpu_id_family == 0xD)) && - ((cpu_version->revision & 0xFC) == 0)) { - no_cr5 = true; - mr10_exist = true; - no_racr0 = true; - } else { - no_cr5 = false; - mr10_exist = false; - no_racr0 = false; - } - - if (misc_config->reduce_register == false) { - ((struct nds32_reg *)reg_cache->reg_list[R11].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R12].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R13].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R14].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R16].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R17].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R18].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R19].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R20].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R21].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R22].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R23].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R24].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R25].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R26].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R27].arch_info)->enable = true; - } - - if (misc_config->no_dx_register == false) { - ((struct nds32_reg *)reg_cache->reg_list[D0LO].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[D0HI].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[D1LO].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[D1HI].arch_info)->enable = true; - } - - if (misc_config->ex9) - ((struct nds32_reg *)reg_cache->reg_list[ITB].arch_info)->enable = true; - - if (no_cr5 == false) - ((struct nds32_reg *)reg_cache->reg_list[CR5].arch_info)->enable = true; - - if (cpu_version->cop_fpu_extension) { - ((struct nds32_reg *)reg_cache->reg_list[CR6].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[FPCSR].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[FPCFG].arch_info)->enable = true; - } - - if (mmu_config->memory_protection == 1) { - /* Secure MPU has no IPC, IPSW, P_ITYPE */ - ((struct nds32_reg *)reg_cache->reg_list[IR1].arch_info)->enable = false; - ((struct nds32_reg *)reg_cache->reg_list[IR9].arch_info)->enable = false; - } - - if (nds32->privilege_level != 0) - ((struct nds32_reg *)reg_cache->reg_list[IR3].arch_info)->enable = false; - - if (misc_config->mcu == true) - ((struct nds32_reg *)reg_cache->reg_list[IR4].arch_info)->enable = false; - - if (misc_config->interruption_level == false) { - ((struct nds32_reg *)reg_cache->reg_list[IR2].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[IR5].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[IR10].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[IR12].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[IR13].arch_info)->enable = true; - - /* Secure MPU has no IPC, IPSW, P_ITYPE */ - if (mmu_config->memory_protection != 1) - ((struct nds32_reg *)reg_cache->reg_list[IR7].arch_info)->enable = true; - } - - if ((cpu_version->cpu_id_family == 0x9) || - (cpu_version->cpu_id_family == 0xA) || - (cpu_version->cpu_id_family == 0xC) || - (cpu_version->cpu_id_family == 0xD)) - ((struct nds32_reg *)reg_cache->reg_list[IR8].arch_info)->enable = true; - - if (misc_config->shadow == 1) { - ((struct nds32_reg *)reg_cache->reg_list[IR16].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[IR17].arch_info)->enable = true; - } - - if (misc_config->ifc) - ((struct nds32_reg *)reg_cache->reg_list[IFC_LP].arch_info)->enable = true; - - if (nds32->privilege_level != 0) - ((struct nds32_reg *)reg_cache->reg_list[MR0].arch_info)->enable = false; - - if (mmu_config->memory_protection == 1) { - if (mmu_config->memory_protection_version == 24) - ((struct nds32_reg *)reg_cache->reg_list[MR4].arch_info)->enable = true; - - if (nds32->privilege_level == 0) { - if ((mmu_config->memory_protection_version == 16) || - (mmu_config->memory_protection_version == 24)) { - ((struct nds32_reg *)reg_cache->reg_list[MR11].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[SECUR0].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[IR20].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[IR22].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[IR24].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[IR30].arch_info)->enable = true; - - if (misc_config->shadow == 1) { - ((struct nds32_reg *)reg_cache->reg_list[IR21].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[IR23].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[IR25].arch_info)->enable = true; - } - } - } - } else if (mmu_config->memory_protection == 2) { - ((struct nds32_reg *)reg_cache->reg_list[MR1].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[MR4].arch_info)->enable = true; - - if ((cpu_version->cpu_id_family != 0xA) && (cpu_version->cpu_id_family != 0xC) && - (cpu_version->cpu_id_family != 0xD)) - ((struct nds32_reg *)reg_cache->reg_list[MR5].arch_info)->enable = true; - } - - if (mmu_config->memory_protection > 0) { - ((struct nds32_reg *)reg_cache->reg_list[MR2].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[MR3].arch_info)->enable = true; - } - - if (memory_config->ilm_base != 0) - if (nds32->privilege_level == 0) - ((struct nds32_reg *)reg_cache->reg_list[MR6].arch_info)->enable = true; - - if (memory_config->dlm_base != 0) - if (nds32->privilege_level == 0) - ((struct nds32_reg *)reg_cache->reg_list[MR7].arch_info)->enable = true; - - if ((memory_config->icache.line_size != 0) && (memory_config->dcache.line_size != 0)) - ((struct nds32_reg *)reg_cache->reg_list[MR8].arch_info)->enable = true; - - if (misc_config->high_speed_memory_port) - ((struct nds32_reg *)reg_cache->reg_list[MR9].arch_info)->enable = true; - - if (mr10_exist) - ((struct nds32_reg *)reg_cache->reg_list[MR10].arch_info)->enable = true; - - if (misc_config->edm) { - int dr_reg_n = nds32->edm.breakpoint_num * 5; - - for (int i = 0 ; i < dr_reg_n ; i++) - ((struct nds32_reg *)reg_cache->reg_list[DR0 + i].arch_info)->enable = true; - - ((struct nds32_reg *)reg_cache->reg_list[DR41].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[DR43].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[DR44].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[DR45].arch_info)->enable = true; - } - - if (misc_config->debug_tracer) { - ((struct nds32_reg *)reg_cache->reg_list[DR46].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[DR47].arch_info)->enable = true; - } - - if (misc_config->performance_monitor) { - ((struct nds32_reg *)reg_cache->reg_list[PFR0].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[PFR1].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[PFR2].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[PFR3].arch_info)->enable = true; - } - - if (misc_config->local_memory_dma) { - ((struct nds32_reg *)reg_cache->reg_list[DMAR0].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[DMAR1].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[DMAR2].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[DMAR3].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[DMAR4].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[DMAR5].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[DMAR6].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[DMAR7].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[DMAR8].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[DMAR9].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[DMAR10].arch_info)->enable = true; - } - - if ((misc_config->local_memory_dma || misc_config->performance_monitor) && - (no_racr0 == false)) - ((struct nds32_reg *)reg_cache->reg_list[RACR].arch_info)->enable = true; - - if (cpu_version->cop_fpu_extension || (misc_config->audio_isa != 0)) - ((struct nds32_reg *)reg_cache->reg_list[FUCPR].arch_info)->enable = true; - - if (misc_config->audio_isa != 0) { - if (misc_config->audio_isa > 1) { - ((struct nds32_reg *)reg_cache->reg_list[D0L24].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[D1L24].arch_info)->enable = true; - } - - ((struct nds32_reg *)reg_cache->reg_list[I0].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[I1].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[I2].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[I3].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[I4].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[I5].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[I6].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[I7].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[M1].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[M2].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[M3].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[M5].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[M6].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[M7].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[MOD].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[LBE].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[LE].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[LC].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[ADM_VBASE].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[SHFT_CTL0].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[SHFT_CTL1].arch_info)->enable = true; - - uint32_t value_mod; - uint32_t fucpr_backup; - /* enable fpu and get configuration */ - nds32_get_mapped_reg(nds32, FUCPR, &fucpr_backup); - if ((fucpr_backup & 0x80000000) == 0) - nds32_set_mapped_reg(nds32, FUCPR, fucpr_backup | 0x80000000); - nds32_get_mapped_reg(nds32, MOD, &value_mod); - /* restore origin fucpr value */ - if ((fucpr_backup & 0x80000000) == 0) - nds32_set_mapped_reg(nds32, FUCPR, fucpr_backup); - - if ((value_mod >> 6) & 0x1) { - ((struct nds32_reg *)reg_cache->reg_list[CB_CTL].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[CBB0].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[CBB1].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[CBB2].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[CBB3].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[CBE0].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[CBE1].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[CBE2].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[CBE3].arch_info)->enable = true; - } - } - - if ((cpu_version->cpu_id_family == 0x9) || - (cpu_version->cpu_id_family == 0xA) || - (cpu_version->cpu_id_family == 0xC)) { - - ((struct nds32_reg *)reg_cache->reg_list[IDR0].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[IDR1].arch_info)->enable = true; - - if ((cpu_version->cpu_id_family == 0xC) && (cpu_version->revision == 0x0C)) - ((struct nds32_reg *)reg_cache->reg_list[IDR0].arch_info)->enable = false; - } - - uint32_t ir3_value; - uint32_t ivb_prog_pri_lvl; - uint32_t ivb_ivic_ver; - - nds32_get_mapped_reg(nds32, IR3, &ir3_value); - ivb_prog_pri_lvl = ir3_value & 0x1; - ivb_ivic_ver = (ir3_value >> 11) & 0x3; - - if ((ivb_prog_pri_lvl == 1) || (ivb_ivic_ver >= 1)) { - ((struct nds32_reg *)reg_cache->reg_list[IR18].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[IR19].arch_info)->enable = true; - } - - if (ivb_ivic_ver >= 1) { - ((struct nds32_reg *)reg_cache->reg_list[IR26].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[IR27].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[IR28].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[IR29].arch_info)->enable = true; - } - - return ERROR_OK; -} - -int nds32_init_register_table(struct nds32 *nds32) -{ - nds32_init_must_have_registers(nds32); - - return ERROR_OK; -} - -int nds32_add_software_breakpoint(struct target *target, - struct breakpoint *breakpoint) -{ - uint32_t data; - uint32_t check_data; - uint32_t break_insn; - - /* check the breakpoint size */ - target->type->read_buffer(target, breakpoint->address, 4, (uint8_t *)&data); - - /* backup origin instruction - * instruction is big-endian */ - if (*(char *)&data & 0x80) { /* 16-bits instruction */ - breakpoint->length = 2; - break_insn = NDS32_BREAK_16; - } else { /* 32-bits instruction */ - breakpoint->length = 4; - break_insn = NDS32_BREAK_32; - } - - free(breakpoint->orig_instr); - - breakpoint->orig_instr = malloc(breakpoint->length); - memcpy(breakpoint->orig_instr, &data, breakpoint->length); - - /* self-modified code */ - target->type->write_buffer(target, breakpoint->address, breakpoint->length, (const uint8_t *)&break_insn); - /* write_back & invalidate dcache & invalidate icache */ - nds32_cache_sync(target, breakpoint->address, breakpoint->length); - - /* read back to check */ - target->type->read_buffer(target, breakpoint->address, breakpoint->length, (uint8_t *)&check_data); - if (memcmp(&check_data, &break_insn, breakpoint->length) == 0) - return ERROR_OK; - - return ERROR_FAIL; -} - -int nds32_remove_software_breakpoint(struct target *target, - struct breakpoint *breakpoint) -{ - uint32_t check_data; - uint32_t break_insn; - - if (breakpoint->length == 2) - break_insn = NDS32_BREAK_16; - else if (breakpoint->length == 4) - break_insn = NDS32_BREAK_32; - else - return ERROR_FAIL; - - target->type->read_buffer(target, breakpoint->address, breakpoint->length, - (uint8_t *)&check_data); - - /* break instruction is modified */ - if (memcmp(&check_data, &break_insn, breakpoint->length) != 0) - return ERROR_FAIL; - - /* self-modified code */ - target->type->write_buffer(target, breakpoint->address, breakpoint->length, - breakpoint->orig_instr); - - /* write_back & invalidate dcache & invalidate icache */ - nds32_cache_sync(target, breakpoint->address, breakpoint->length); - - return ERROR_OK; -} - -/** - * Restore the processor context on an Andes target. The full processor - * context is analyzed to see if any of the registers are dirty on this end, but - * have a valid new value. If this is the case, the processor is changed to the - * appropriate mode and the new register values are written out to the - * processor. If there happens to be a dirty register with an invalid value, an - * error will be logged. - * - * @param target Pointer to the Andes target to have its context restored - * @return Error status if the target is not halted. - */ -int nds32_restore_context(struct target *target) -{ - struct nds32 *nds32 = target_to_nds32(target); - struct aice_port_s *aice = target_to_aice(target); - struct reg_cache *reg_cache = nds32->core_cache; - struct reg *reg; - struct nds32_reg *reg_arch_info; - unsigned int i; - - LOG_DEBUG("-"); - - if (target->state != TARGET_HALTED) { - LOG_WARNING("target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* check if there are dirty registers */ - for (i = 0; i < reg_cache->num_regs; i++) { - reg = &(reg_cache->reg_list[i]); - if (reg->dirty == true) { - if (reg->valid == true) { - - LOG_DEBUG("examining dirty reg: %s", reg->name); - LOG_DEBUG("writing register %d with value 0x%8.8" PRIx32, - i, buf_get_u32(reg->value, 0, 32)); - - reg_arch_info = reg->arch_info; - if (reg_arch_info->num >= FD0 && reg_arch_info->num <= FD31) { - uint64_t val = buf_get_u64(reg_arch_info->value, 0, 64); - aice_write_reg_64(aice, reg_arch_info->num, val); - } else { - uint32_t val = buf_get_u32(reg_arch_info->value, 0, 32); - aice_write_register(aice, reg_arch_info->num, val); - } - - reg->valid = true; - reg->dirty = false; - } - } - } - - return ERROR_OK; -} - -int nds32_edm_config(struct nds32 *nds32) -{ - struct target *target = nds32->target; - struct aice_port_s *aice = target_to_aice(target); - uint32_t edm_cfg; - uint32_t edm_ctl; - - aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CFG, &edm_cfg); - - nds32->edm.version = (edm_cfg >> 16) & 0xFFFF; - LOG_INFO("EDM version 0x%04x", nds32->edm.version); - - nds32->edm.breakpoint_num = (edm_cfg & 0x7) + 1; - - if ((nds32->edm.version & 0x1000) || (nds32->edm.version >= 0x60)) - nds32->edm.access_control = true; - else - nds32->edm.access_control = false; - - if ((edm_cfg >> 4) & 0x1) - nds32->edm.direct_access_local_memory = true; - else - nds32->edm.direct_access_local_memory = false; - - if (nds32->edm.version <= 0x20) - nds32->edm.direct_access_local_memory = false; - - aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CTL, &edm_ctl); - if (edm_ctl & (0x1 << 29)) - nds32->edm.support_max_stop = true; - else - nds32->edm.support_max_stop = false; - - /* set passcode for secure MCU */ - nds32_login(nds32); - - return ERROR_OK; -} - -int nds32_config(struct nds32 *nds32) -{ - nds32_init_config(nds32); - - /* init optional system registers according to config registers */ - nds32_init_option_registers(nds32); - - /* get max interrupt level */ - if (nds32->misc_config.interruption_level) - nds32->max_interrupt_level = 2; - else - nds32->max_interrupt_level = 3; - - /* get ILM/DLM size from MR6/MR7 */ - uint32_t value_mr6, value_mr7; - uint32_t size_index; - nds32_get_mapped_reg(nds32, MR6, &value_mr6); - size_index = (value_mr6 >> 1) & 0xF; - nds32->memory.ilm_size = nds32_lm_size_table[size_index]; - - nds32_get_mapped_reg(nds32, MR7, &value_mr7); - size_index = (value_mr7 >> 1) & 0xF; - nds32->memory.dlm_size = nds32_lm_size_table[size_index]; - - return ERROR_OK; -} - -int nds32_init_arch_info(struct target *target, struct nds32 *nds32) -{ - target->arch_info = nds32; - nds32->target = target; - - nds32->common_magic = NDS32_COMMON_MAGIC; - nds32->init_arch_info_after_halted = false; - nds32->auto_convert_hw_bp = true; - nds32->global_stop = false; - nds32->soft_reset_halt = false; - nds32->edm_passcode = NULL; - nds32->privilege_level = 0; - nds32->boot_time = 1500; - nds32->reset_halt_as_examine = false; - nds32->keep_target_edm_ctl = false; - nds32->word_access_mem = false; - nds32->virtual_hosting = true; - nds32->hit_syscall = false; - nds32->active_syscall_id = NDS32_SYSCALL_UNDEFINED; - nds32->virtual_hosting_errno = 0; - nds32->virtual_hosting_ctrl_c = false; - nds32->attached = false; - - nds32->syscall_break.asid = 0; - nds32->syscall_break.length = 4; - nds32->syscall_break.is_set = false; - nds32->syscall_break.orig_instr = NULL; - nds32->syscall_break.next = NULL; - nds32->syscall_break.unique_id = 0x515CAll + target->target_number; - nds32->syscall_break.linked_brp = 0; - - nds32_reg_init(); - - if (nds32_reg_cache_init(target, nds32) == ERROR_FAIL) - return ERROR_FAIL; - - if (nds32_init_register_table(nds32) != ERROR_OK) - return ERROR_FAIL; - - return ERROR_OK; -} - -int nds32_virtual_to_physical(struct target *target, target_addr_t address, target_addr_t *physical) -{ - struct nds32 *nds32 = target_to_nds32(target); - - if (nds32->memory.address_translation == false) { - *physical = address; - return ERROR_OK; - } - - if (nds32_probe_tlb(nds32, address, physical) == ERROR_OK) - return ERROR_OK; - - if (nds32_walk_page_table(nds32, address, physical) == ERROR_OK) - return ERROR_OK; - - return ERROR_FAIL; -} - -int nds32_cache_sync(struct target *target, target_addr_t address, uint32_t length) -{ - struct aice_port_s *aice = target_to_aice(target); - struct nds32 *nds32 = target_to_nds32(target); - struct nds32_cache *dcache = &(nds32->memory.dcache); - struct nds32_cache *icache = &(nds32->memory.icache); - uint32_t dcache_line_size = nds32_line_size_table[dcache->line_size]; - uint32_t icache_line_size = nds32_line_size_table[icache->line_size]; - uint32_t cur_address; - int result; - uint32_t start_line, end_line; - uint32_t cur_line; - - if ((dcache->line_size != 0) && (dcache->enable == true)) { - /* address / dcache_line_size */ - start_line = address >> (dcache->line_size + 2); - /* (address + length - 1) / dcache_line_size */ - end_line = (address + length - 1) >> (dcache->line_size + 2); - - for (cur_address = address, cur_line = start_line; - cur_line <= end_line; - cur_address += dcache_line_size, cur_line++) { - /* D$ write back */ - result = aice_cache_ctl(aice, AICE_CACHE_CTL_L1D_VA_WB, cur_address); - if (result != ERROR_OK) - return result; - - /* D$ invalidate */ - result = aice_cache_ctl(aice, AICE_CACHE_CTL_L1D_VA_INVAL, cur_address); - if (result != ERROR_OK) - return result; - } - } - - if ((icache->line_size != 0) && (icache->enable == true)) { - /* address / icache_line_size */ - start_line = address >> (icache->line_size + 2); - /* (address + length - 1) / icache_line_size */ - end_line = (address + length - 1) >> (icache->line_size + 2); - - for (cur_address = address, cur_line = start_line; - cur_line <= end_line; - cur_address += icache_line_size, cur_line++) { - /* Because PSW.IT is turned off under debug exception, address MUST - * be physical address. L1I_VA_INVALIDATE uses PSW.IT to decide - * address translation or not. */ - target_addr_t physical_addr; - if (target->type->virt2phys(target, cur_address, &physical_addr) == ERROR_FAIL) - return ERROR_FAIL; - - /* I$ invalidate */ - result = aice_cache_ctl(aice, AICE_CACHE_CTL_L1I_VA_INVAL, physical_addr); - if (result != ERROR_OK) - return result; - } - } - - return ERROR_OK; -} - -uint32_t nds32_nextpc(struct nds32 *nds32, int current, uint32_t address) -{ - if (!current) - nds32_set_mapped_reg(nds32, PC, address); - else - nds32_get_mapped_reg(nds32, PC, &address); - - return address; -} - -int nds32_step(struct target *target, int current, - target_addr_t address, int handle_breakpoints) -{ - LOG_DEBUG("target->state: %s", - target_state_name(target)); - - if (target->state != TARGET_HALTED) { - LOG_WARNING("target was not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - struct nds32 *nds32 = target_to_nds32(target); - - address = nds32_nextpc(nds32, current, address); - - LOG_DEBUG("STEP PC %08" TARGET_PRIxADDR "%s", address, !current ? "!" : ""); - - /** set DSSIM */ - uint32_t ir14_value; - nds32_get_mapped_reg(nds32, IR14, &ir14_value); - if (nds32->step_isr_enable) - ir14_value |= (0x1 << 31); - else - ir14_value &= ~(0x1 << 31); - nds32_set_mapped_reg(nds32, IR14, ir14_value); - - /* check hit_syscall before leave_debug_state() because - * leave_debug_state() may clear hit_syscall flag */ - bool no_step = false; - if (nds32->hit_syscall) - /* step after hit_syscall should be ignored because - * leave_debug_state will step implicitly to skip the - * syscall */ - no_step = true; - - /********* TODO: maybe create another function to handle this part */ - CHECK_RETVAL(nds32->leave_debug_state(nds32, true)); - CHECK_RETVAL(target_call_event_callbacks(target, TARGET_EVENT_RESUMED)); - - if (no_step == false) { - struct aice_port_s *aice = target_to_aice(target); - if (aice_step(aice) != ERROR_OK) - return ERROR_FAIL; - } - - /* save state */ - CHECK_RETVAL(nds32->enter_debug_state(nds32, true)); - /********* TODO: maybe create another function to handle this part */ - - /* restore DSSIM */ - if (nds32->step_isr_enable) { - nds32_get_mapped_reg(nds32, IR14, &ir14_value); - ir14_value &= ~(0x1 << 31); - nds32_set_mapped_reg(nds32, IR14, ir14_value); - } - - CHECK_RETVAL(target_call_event_callbacks(target, TARGET_EVENT_HALTED)); - - return ERROR_OK; -} - -static int nds32_step_without_watchpoint(struct nds32 *nds32) -{ - struct target *target = nds32->target; - - if (target->state != TARGET_HALTED) { - LOG_WARNING("target was not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /** set DSSIM */ - uint32_t ir14_value; - nds32_get_mapped_reg(nds32, IR14, &ir14_value); - if (nds32->step_isr_enable) - ir14_value |= (0x1 << 31); - else - ir14_value &= ~(0x1 << 31); - nds32_set_mapped_reg(nds32, IR14, ir14_value); - - /********* TODO: maybe create another function to handle this part */ - CHECK_RETVAL(nds32->leave_debug_state(nds32, false)); - - struct aice_port_s *aice = target_to_aice(target); - - if (aice_step(aice) != ERROR_OK) - return ERROR_FAIL; - - /* save state */ - CHECK_RETVAL(nds32->enter_debug_state(nds32, false)); - /********* TODO: maybe create another function to handle this part */ - - /* restore DSSIM */ - if (nds32->step_isr_enable) { - nds32_get_mapped_reg(nds32, IR14, &ir14_value); - ir14_value &= ~(0x1 << 31); - nds32_set_mapped_reg(nds32, IR14, ir14_value); - } - - return ERROR_OK; -} - -int nds32_target_state(struct nds32 *nds32, enum target_state *state) -{ - struct aice_port_s *aice = target_to_aice(nds32->target); - enum aice_target_state_s nds32_state; - - if (aice_state(aice, &nds32_state) != ERROR_OK) - return ERROR_FAIL; - - switch (nds32_state) { - case AICE_DISCONNECT: - LOG_INFO("USB is disconnected"); - return ERROR_FAIL; - case AICE_TARGET_DETACH: - LOG_INFO("Target is disconnected"); - return ERROR_FAIL; - case AICE_TARGET_UNKNOWN: - *state = TARGET_UNKNOWN; - break; - case AICE_TARGET_RUNNING: - *state = TARGET_RUNNING; - break; - case AICE_TARGET_HALTED: - *state = TARGET_HALTED; - break; - case AICE_TARGET_RESET: - *state = TARGET_RESET; - break; - case AICE_TARGET_DEBUG_RUNNING: - *state = TARGET_DEBUG_RUNNING; - break; - default: - return ERROR_FAIL; - } - - return ERROR_OK; -} - -int nds32_examine_debug_reason(struct nds32 *nds32) -{ - uint32_t reason; - struct target *target = nds32->target; - - if (nds32->hit_syscall == true) { - LOG_DEBUG("Hit syscall breakpoint"); - target->debug_reason = DBG_REASON_BREAKPOINT; - return ERROR_OK; - } - - nds32->get_debug_reason(nds32, &reason); - - LOG_DEBUG("nds32 examines debug reason: %s", nds32_debug_type_name[reason]); - - /* Examine debug reason */ - switch (reason) { - case NDS32_DEBUG_BREAK: - case NDS32_DEBUG_BREAK_16: - case NDS32_DEBUG_INST_BREAK: - { - uint32_t value_pc; - uint32_t opcode; - struct nds32_instruction instruction; - - nds32_get_mapped_reg(nds32, PC, &value_pc); - - if (nds32_read_opcode(nds32, value_pc, &opcode) != ERROR_OK) - return ERROR_FAIL; - if (nds32_evaluate_opcode(nds32, opcode, value_pc, &instruction) != ERROR_OK) - return ERROR_FAIL; - - /* hit 'break 0x7FFF' */ - if ((instruction.info.opc_6 == 0x32) && - (instruction.info.sub_opc == 0xA) && - (instruction.info.imm == 0x7FFF)) { - target->debug_reason = DBG_REASON_EXIT; - } else - target->debug_reason = DBG_REASON_BREAKPOINT; - } - break; - case NDS32_DEBUG_DATA_ADDR_WATCHPOINT_PRECISE: - case NDS32_DEBUG_DATA_VALUE_WATCHPOINT_PRECISE: - case NDS32_DEBUG_LOAD_STORE_GLOBAL_STOP: /* GLOBAL_STOP is precise exception */ - { - int result; - - result = nds32->get_watched_address(nds32, - &(nds32->watched_address), reason); - /* do single step(without watchpoints) to skip the "watched" instruction */ - nds32_step_without_watchpoint(nds32); - - /* before single_step, save exception address */ - if (result != ERROR_OK) - return ERROR_FAIL; - - target->debug_reason = DBG_REASON_WATCHPOINT; - } - break; - case NDS32_DEBUG_DEBUG_INTERRUPT: - target->debug_reason = DBG_REASON_DBGRQ; - break; - case NDS32_DEBUG_HARDWARE_SINGLE_STEP: - target->debug_reason = DBG_REASON_SINGLESTEP; - break; - case NDS32_DEBUG_DATA_VALUE_WATCHPOINT_IMPRECISE: - case NDS32_DEBUG_DATA_ADDR_WATCHPOINT_NEXT_PRECISE: - case NDS32_DEBUG_DATA_VALUE_WATCHPOINT_NEXT_PRECISE: - if (nds32->get_watched_address(nds32, &(nds32->watched_address), reason) != ERROR_OK) - return ERROR_FAIL; - - target->debug_reason = DBG_REASON_WATCHPOINT; - break; - default: - target->debug_reason = DBG_REASON_UNDEFINED; - break; - } - - return ERROR_OK; -} - -int nds32_login(struct nds32 *nds32) -{ - struct target *target = nds32->target; - struct aice_port_s *aice = target_to_aice(target); - uint32_t passcode_length; - char command_sequence[129]; - char command_str[33]; - char code_str[9]; - uint32_t copy_length; - uint32_t code; - uint32_t i; - - LOG_DEBUG("nds32_login"); - - if (nds32->edm_passcode) { - /* convert EDM passcode to command sequences */ - passcode_length = strlen(nds32->edm_passcode); - command_sequence[0] = '\0'; - for (i = 0; i < passcode_length; i += 8) { - if (passcode_length - i < 8) - copy_length = passcode_length - i; - else - copy_length = 8; - - strncpy(code_str, nds32->edm_passcode + i, copy_length); - code_str[copy_length] = '\0'; - code = strtoul(code_str, NULL, 16); - - sprintf(command_str, "write_misc gen_port0 0x%" PRIx32 ";", code); - strcat(command_sequence, command_str); - } - - if (aice_program_edm(aice, command_sequence) != ERROR_OK) - return ERROR_FAIL; - - /* get current privilege level */ - uint32_t value_edmsw; - aice_read_debug_reg(aice, NDS_EDM_SR_EDMSW, &value_edmsw); - nds32->privilege_level = (value_edmsw >> 16) & 0x3; - LOG_INFO("Current privilege level: %d", nds32->privilege_level); - } - - if (nds32_edm_ops_num > 0) { - const char *reg_name; - for (i = 0 ; i < nds32_edm_ops_num ; i++) { - code = nds32_edm_ops[i].value; - if (nds32_edm_ops[i].reg_no == 6) - reg_name = "gen_port0"; - else if (nds32_edm_ops[i].reg_no == 7) - reg_name = "gen_port1"; - else - return ERROR_FAIL; - - sprintf(command_str, "write_misc %s 0x%" PRIx32 ";", reg_name, code); - if (aice_program_edm(aice, command_str) != ERROR_OK) - return ERROR_FAIL; - } - } - - return ERROR_OK; -} - -int nds32_halt(struct target *target) -{ - struct nds32 *nds32 = target_to_nds32(target); - struct aice_port_s *aice = target_to_aice(target); - enum target_state state; - - LOG_DEBUG("target->state: %s", - target_state_name(target)); - - if (target->state == TARGET_HALTED) { - LOG_DEBUG("target was already halted"); - return ERROR_OK; - } - - if (nds32_target_state(nds32, &state) != ERROR_OK) - return ERROR_FAIL; - - if (state != TARGET_HALTED) - /* TODO: if state == TARGET_HALTED, check ETYPE is DBGI or not */ - if (aice_halt(aice) != ERROR_OK) - return ERROR_FAIL; - - CHECK_RETVAL(nds32->enter_debug_state(nds32, true)); - - CHECK_RETVAL(target_call_event_callbacks(target, TARGET_EVENT_HALTED)); - - return ERROR_OK; -} - -/* poll current target status */ -int nds32_poll(struct target *target) -{ - struct nds32 *nds32 = target_to_nds32(target); - enum target_state state; - - if (nds32_target_state(nds32, &state) != ERROR_OK) - return ERROR_FAIL; - - if (state == TARGET_HALTED) { - if (target->state != TARGET_HALTED) { - /* if false_hit, continue free_run */ - if (nds32->enter_debug_state(nds32, true) != ERROR_OK) { - struct aice_port_s *aice = target_to_aice(target); - aice_run(aice); - return ERROR_OK; - } - - LOG_DEBUG("Change target state to TARGET_HALTED."); - - target_call_event_callbacks(target, TARGET_EVENT_HALTED); - } - } else if (state == TARGET_RESET) { - if (target->state == TARGET_HALTED) { - /* similar to assert srst */ - register_cache_invalidate(nds32->core_cache); - target->state = TARGET_RESET; - - /* TODO: deassert srst */ - } else if (target->state == TARGET_RUNNING) { - /* reset as running */ - LOG_WARNING("<-- TARGET WARNING! The debug target has been reset. -->"); - } - } else { - if (target->state != TARGET_RUNNING && target->state != TARGET_DEBUG_RUNNING) { - LOG_DEBUG("Change target state to TARGET_RUNNING."); - target->state = TARGET_RUNNING; - target->debug_reason = DBG_REASON_NOTHALTED; - } - } - - return ERROR_OK; -} - -int nds32_resume(struct target *target, int current, - target_addr_t address, int handle_breakpoints, int debug_execution) -{ - LOG_DEBUG("current %d address %08" TARGET_PRIxADDR - " handle_breakpoints %d" - " debug_execution %d", - current, address, handle_breakpoints, debug_execution); - - struct nds32 *nds32 = target_to_nds32(target); - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - address = nds32_nextpc(nds32, current, address); - - LOG_DEBUG("RESUME PC %08" TARGET_PRIxADDR "%s", address, !current ? "!" : ""); - - if (!debug_execution) - target_free_all_working_areas(target); - - /* Disable HSS to avoid users misuse HSS */ - if (nds32_reach_max_interrupt_level(nds32) == false) { - uint32_t value_ir0; - nds32_get_mapped_reg(nds32, IR0, &value_ir0); - value_ir0 &= ~(0x1 << 11); - nds32_set_mapped_reg(nds32, IR0, value_ir0); - } - - CHECK_RETVAL(nds32->leave_debug_state(nds32, true)); - CHECK_RETVAL(target_call_event_callbacks(target, TARGET_EVENT_RESUMED)); - - if (nds32->virtual_hosting_ctrl_c == false) { - struct aice_port_s *aice = target_to_aice(target); - aice_run(aice); - } else - nds32->virtual_hosting_ctrl_c = false; - - target->debug_reason = DBG_REASON_NOTHALTED; - if (!debug_execution) - target->state = TARGET_RUNNING; - else - target->state = TARGET_DEBUG_RUNNING; - - LOG_DEBUG("target->state: %s", - target_state_name(target)); - - return ERROR_OK; -} - -static int nds32_soft_reset_halt(struct target *target) -{ - /* TODO: test it */ - struct nds32 *nds32 = target_to_nds32(target); - struct aice_port_s *aice = target_to_aice(target); - - aice_assert_srst(aice, AICE_SRST); - - /* halt core and set pc to 0x0 */ - int retval = target_halt(target); - if (retval != ERROR_OK) - return retval; - - /* start fetching from IVB */ - uint32_t value_ir3; - nds32_get_mapped_reg(nds32, IR3, &value_ir3); - nds32_set_mapped_reg(nds32, PC, value_ir3 & 0xFFFF0000); - - return ERROR_OK; -} - -int nds32_assert_reset(struct target *target) -{ - struct nds32 *nds32 = target_to_nds32(target); - struct aice_port_s *aice = target_to_aice(target); - struct nds32_cpu_version *cpu_version = &(nds32->cpu_version); - - /* TODO: apply hw reset signal in not examined state */ - if (!(target_was_examined(target))) { - LOG_WARNING("Reset is not asserted because the target is not examined."); - LOG_WARNING("Use a reset button or power cycle the target."); - return ERROR_TARGET_NOT_EXAMINED; - } - - if (target->reset_halt) { - if ((nds32->soft_reset_halt) - || (nds32->edm.version < 0x51) - || ((nds32->edm.version == 0x51) - && (cpu_version->revision == 0x1C) - && (cpu_version->cpu_id_family == 0xC) - && (cpu_version->cpu_id_version == 0x0))) - nds32_soft_reset_halt(target); - else - aice_assert_srst(aice, AICE_RESET_HOLD); - } else { - aice_assert_srst(aice, AICE_SRST); - alive_sleep(nds32->boot_time); - } - - /* set passcode for secure MCU after core reset */ - nds32_login(nds32); - - /* registers are now invalid */ - register_cache_invalidate(nds32->core_cache); - - target->state = TARGET_RESET; - - return ERROR_OK; -} - -static int nds32_gdb_attach(struct nds32 *nds32) -{ - LOG_DEBUG("nds32_gdb_attach, target coreid: %" PRId32, nds32->target->coreid); - - if (nds32->attached == false) { - - if (nds32->keep_target_edm_ctl) { - /* backup target EDM_CTL */ - struct aice_port_s *aice = target_to_aice(nds32->target); - aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CTL, &nds32->backup_edm_ctl); - } - - target_halt(nds32->target); - - nds32->attached = true; - } - - return ERROR_OK; -} - -static int nds32_gdb_detach(struct nds32 *nds32) -{ - LOG_DEBUG("nds32_gdb_detach"); - bool backup_virtual_hosting_setting; - - if (nds32->attached) { - - backup_virtual_hosting_setting = nds32->virtual_hosting; - /* turn off virtual hosting before resume as gdb-detach */ - nds32->virtual_hosting = false; - target_resume(nds32->target, 1, 0, 0, 0); - nds32->virtual_hosting = backup_virtual_hosting_setting; - - if (nds32->keep_target_edm_ctl) { - /* restore target EDM_CTL */ - struct aice_port_s *aice = target_to_aice(nds32->target); - aice_write_debug_reg(aice, NDS_EDM_SR_EDM_CTL, nds32->backup_edm_ctl); - } - - nds32->attached = false; - } - - return ERROR_OK; -} - -static int nds32_callback_event_handler(struct target *target, - enum target_event event, void *priv) -{ - int retval = ERROR_OK; - int target_number = *(int *)priv; - - if (target_number != target->target_number) - return ERROR_OK; - - struct nds32 *nds32 = target_to_nds32(target); - - switch (event) { - case TARGET_EVENT_GDB_ATTACH: - retval = nds32_gdb_attach(nds32); - break; - case TARGET_EVENT_GDB_DETACH: - retval = nds32_gdb_detach(nds32); - break; - default: - break; - } - - return retval; -} - -int nds32_init(struct nds32 *nds32) -{ - /* Initialize anything we can set up without talking to the target */ - nds32->memory.access_channel = NDS_MEMORY_ACC_CPU; - - /* register event callback */ - target_register_event_callback(nds32_callback_event_handler, - &(nds32->target->target_number)); - - return ERROR_OK; -} - -int nds32_get_gdb_fileio_info(struct target *target, struct gdb_fileio_info *fileio_info) -{ - /* fill syscall parameters to file-I/O info */ - if (!fileio_info) { - LOG_ERROR("Target has not initial file-I/O data structure"); - return ERROR_FAIL; - } - - struct nds32 *nds32 = target_to_nds32(target); - uint32_t value_ir6; - uint32_t syscall_id; - - if (nds32->hit_syscall == false) - return ERROR_FAIL; - - nds32_get_mapped_reg(nds32, IR6, &value_ir6); - syscall_id = (value_ir6 >> 16) & 0x7FFF; - nds32->active_syscall_id = syscall_id; - - LOG_DEBUG("hit syscall ID: 0x%" PRIx32, syscall_id); - - /* free previous identifier storage */ - free(fileio_info->identifier); - fileio_info->identifier = NULL; - - uint32_t reg_r0, reg_r1, reg_r2; - nds32_get_mapped_reg(nds32, R0, ®_r0); - nds32_get_mapped_reg(nds32, R1, ®_r1); - nds32_get_mapped_reg(nds32, R2, ®_r2); - - switch (syscall_id) { - case NDS32_SYSCALL_EXIT: - fileio_info->identifier = malloc(5); - sprintf(fileio_info->identifier, "exit"); - fileio_info->param_1 = reg_r0; - break; - case NDS32_SYSCALL_OPEN: - { - uint8_t filename[256]; - fileio_info->identifier = malloc(5); - sprintf(fileio_info->identifier, "open"); - fileio_info->param_1 = reg_r0; - /* reserve fileio_info->param_2 for length of path */ - fileio_info->param_3 = reg_r1; - fileio_info->param_4 = reg_r2; - - target->type->read_buffer(target, reg_r0, 256, filename); - fileio_info->param_2 = strlen((char *)filename); - } - break; - case NDS32_SYSCALL_CLOSE: - fileio_info->identifier = malloc(6); - sprintf(fileio_info->identifier, "close"); - fileio_info->param_1 = reg_r0; - break; - case NDS32_SYSCALL_READ: - fileio_info->identifier = malloc(5); - sprintf(fileio_info->identifier, "read"); - fileio_info->param_1 = reg_r0; - fileio_info->param_2 = reg_r1; - fileio_info->param_3 = reg_r2; - break; - case NDS32_SYSCALL_WRITE: - fileio_info->identifier = malloc(6); - sprintf(fileio_info->identifier, "write"); - fileio_info->param_1 = reg_r0; - fileio_info->param_2 = reg_r1; - fileio_info->param_3 = reg_r2; - break; - case NDS32_SYSCALL_LSEEK: - fileio_info->identifier = malloc(6); - sprintf(fileio_info->identifier, "lseek"); - fileio_info->param_1 = reg_r0; - fileio_info->param_2 = reg_r1; - fileio_info->param_3 = reg_r2; - break; - case NDS32_SYSCALL_UNLINK: - { - uint8_t filename[256]; - fileio_info->identifier = malloc(7); - sprintf(fileio_info->identifier, "unlink"); - fileio_info->param_1 = reg_r0; - /* reserve fileio_info->param_2 for length of path */ - - target->type->read_buffer(target, reg_r0, 256, filename); - fileio_info->param_2 = strlen((char *)filename); - } - break; - case NDS32_SYSCALL_RENAME: - { - uint8_t filename[256]; - fileio_info->identifier = malloc(7); - sprintf(fileio_info->identifier, "rename"); - fileio_info->param_1 = reg_r0; - /* reserve fileio_info->param_2 for length of old path */ - fileio_info->param_3 = reg_r1; - /* reserve fileio_info->param_4 for length of new path */ - - target->type->read_buffer(target, reg_r0, 256, filename); - fileio_info->param_2 = strlen((char *)filename); - - target->type->read_buffer(target, reg_r1, 256, filename); - fileio_info->param_4 = strlen((char *)filename); - } - break; - case NDS32_SYSCALL_FSTAT: - fileio_info->identifier = malloc(6); - sprintf(fileio_info->identifier, "fstat"); - fileio_info->param_1 = reg_r0; - fileio_info->param_2 = reg_r1; - break; - case NDS32_SYSCALL_STAT: - { - uint8_t filename[256]; - fileio_info->identifier = malloc(5); - sprintf(fileio_info->identifier, "stat"); - fileio_info->param_1 = reg_r0; - /* reserve fileio_info->param_2 for length of old path */ - fileio_info->param_3 = reg_r1; - - target->type->read_buffer(target, reg_r0, 256, filename); - fileio_info->param_2 = strlen((char *)filename) + 1; - } - break; - case NDS32_SYSCALL_GETTIMEOFDAY: - fileio_info->identifier = malloc(13); - sprintf(fileio_info->identifier, "gettimeofday"); - fileio_info->param_1 = reg_r0; - fileio_info->param_2 = reg_r1; - break; - case NDS32_SYSCALL_ISATTY: - fileio_info->identifier = malloc(7); - sprintf(fileio_info->identifier, "isatty"); - fileio_info->param_1 = reg_r0; - break; - case NDS32_SYSCALL_SYSTEM: - { - uint8_t command[256]; - fileio_info->identifier = malloc(7); - sprintf(fileio_info->identifier, "system"); - fileio_info->param_1 = reg_r0; - /* reserve fileio_info->param_2 for length of old path */ - - target->type->read_buffer(target, reg_r0, 256, command); - fileio_info->param_2 = strlen((char *)command); - } - break; - case NDS32_SYSCALL_ERRNO: - fileio_info->identifier = malloc(6); - sprintf(fileio_info->identifier, "errno"); - nds32_set_mapped_reg(nds32, R0, nds32->virtual_hosting_errno); - break; - default: - fileio_info->identifier = malloc(8); - sprintf(fileio_info->identifier, "unknown"); - break; - } - - return ERROR_OK; -} - -int nds32_gdb_fileio_end(struct target *target, int retcode, int fileio_errno, bool ctrl_c) -{ - LOG_DEBUG("syscall return code: 0x%x, errno: 0x%x , ctrl_c: %s", - retcode, fileio_errno, ctrl_c ? "true" : "false"); - - struct nds32 *nds32 = target_to_nds32(target); - - nds32_set_mapped_reg(nds32, R0, (uint32_t)retcode); - - nds32->virtual_hosting_errno = fileio_errno; - nds32->virtual_hosting_ctrl_c = ctrl_c; - nds32->active_syscall_id = NDS32_SYSCALL_UNDEFINED; - - return ERROR_OK; -} - -int nds32_profiling(struct target *target, uint32_t *samples, - uint32_t max_num_samples, uint32_t *num_samples, uint32_t seconds) -{ - /* sample $PC every 10 milliseconds */ - uint32_t iteration = seconds * 100; - struct aice_port_s *aice = target_to_aice(target); - struct nds32 *nds32 = target_to_nds32(target); - - /* REVISIT: can nds32 profile without halting? */ - if (target->state != TARGET_HALTED) { - LOG_WARNING("target %s is not halted (profiling)", target->cmd_name); - return ERROR_TARGET_NOT_HALTED; - } - - if (max_num_samples < iteration) - iteration = max_num_samples; - - int pc_regnum = nds32->register_map(nds32, PC); - aice_profiling(aice, 10, iteration, pc_regnum, samples, num_samples); - - register_cache_invalidate(nds32->core_cache); - - return ERROR_OK; -} - -int nds32_gdb_fileio_write_memory(struct nds32 *nds32, uint32_t address, - uint32_t size, const uint8_t *buffer) -{ - if ((nds32->active_syscall_id == NDS32_SYSCALL_FSTAT) || - (nds32->active_syscall_id == NDS32_SYSCALL_STAT)) { - /* If doing GDB file-I/O, target should convert 'struct stat' - * from gdb-format to target-format */ - uint8_t stat_buffer[NDS32_STRUCT_STAT_SIZE]; - /* st_dev 2 */ - stat_buffer[0] = buffer[3]; - stat_buffer[1] = buffer[2]; - /* st_ino 2 */ - stat_buffer[2] = buffer[7]; - stat_buffer[3] = buffer[6]; - /* st_mode 4 */ - stat_buffer[4] = buffer[11]; - stat_buffer[5] = buffer[10]; - stat_buffer[6] = buffer[9]; - stat_buffer[7] = buffer[8]; - /* st_nlink 2 */ - stat_buffer[8] = buffer[15]; - stat_buffer[9] = buffer[16]; - /* st_uid 2 */ - stat_buffer[10] = buffer[19]; - stat_buffer[11] = buffer[18]; - /* st_gid 2 */ - stat_buffer[12] = buffer[23]; - stat_buffer[13] = buffer[22]; - /* st_rdev 2 */ - stat_buffer[14] = buffer[27]; - stat_buffer[15] = buffer[26]; - /* st_size 4 */ - stat_buffer[16] = buffer[35]; - stat_buffer[17] = buffer[34]; - stat_buffer[18] = buffer[33]; - stat_buffer[19] = buffer[32]; - /* st_atime 4 */ - stat_buffer[20] = buffer[55]; - stat_buffer[21] = buffer[54]; - stat_buffer[22] = buffer[53]; - stat_buffer[23] = buffer[52]; - /* st_spare1 4 */ - stat_buffer[24] = 0; - stat_buffer[25] = 0; - stat_buffer[26] = 0; - stat_buffer[27] = 0; - /* st_mtime 4 */ - stat_buffer[28] = buffer[59]; - stat_buffer[29] = buffer[58]; - stat_buffer[30] = buffer[57]; - stat_buffer[31] = buffer[56]; - /* st_spare2 4 */ - stat_buffer[32] = 0; - stat_buffer[33] = 0; - stat_buffer[34] = 0; - stat_buffer[35] = 0; - /* st_ctime 4 */ - stat_buffer[36] = buffer[63]; - stat_buffer[37] = buffer[62]; - stat_buffer[38] = buffer[61]; - stat_buffer[39] = buffer[60]; - /* st_spare3 4 */ - stat_buffer[40] = 0; - stat_buffer[41] = 0; - stat_buffer[42] = 0; - stat_buffer[43] = 0; - /* st_blksize 4 */ - stat_buffer[44] = buffer[43]; - stat_buffer[45] = buffer[42]; - stat_buffer[46] = buffer[41]; - stat_buffer[47] = buffer[40]; - /* st_blocks 4 */ - stat_buffer[48] = buffer[51]; - stat_buffer[49] = buffer[50]; - stat_buffer[50] = buffer[49]; - stat_buffer[51] = buffer[48]; - /* st_spare4 8 */ - stat_buffer[52] = 0; - stat_buffer[53] = 0; - stat_buffer[54] = 0; - stat_buffer[55] = 0; - stat_buffer[56] = 0; - stat_buffer[57] = 0; - stat_buffer[58] = 0; - stat_buffer[59] = 0; - - return nds32_write_buffer(nds32->target, address, NDS32_STRUCT_STAT_SIZE, stat_buffer); - } else if (nds32->active_syscall_id == NDS32_SYSCALL_GETTIMEOFDAY) { - /* If doing GDB file-I/O, target should convert 'struct timeval' - * from gdb-format to target-format */ - uint8_t timeval_buffer[NDS32_STRUCT_TIMEVAL_SIZE]; - timeval_buffer[0] = buffer[3]; - timeval_buffer[1] = buffer[2]; - timeval_buffer[2] = buffer[1]; - timeval_buffer[3] = buffer[0]; - timeval_buffer[4] = buffer[11]; - timeval_buffer[5] = buffer[10]; - timeval_buffer[6] = buffer[9]; - timeval_buffer[7] = buffer[8]; - - return nds32_write_buffer(nds32->target, address, NDS32_STRUCT_TIMEVAL_SIZE, timeval_buffer); - } - - return nds32_write_buffer(nds32->target, address, size, buffer); -} - -int nds32_reset_halt(struct nds32 *nds32) -{ - LOG_INFO("reset halt as init"); - - struct aice_port_s *aice = target_to_aice(nds32->target); - aice_assert_srst(aice, AICE_RESET_HOLD); - - return ERROR_OK; -} diff --git a/src/target/nds32.h b/src/target/nds32.h deleted file mode 100644 index d0b680a..0000000 --- a/src/target/nds32.h +++ /dev/null @@ -1,447 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -/*************************************************************************** - * Copyright (C) 2013 Andes Technology * - * Hsiangkai Wang <hkwang@andestech.com> * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_NDS32_H -#define OPENOCD_TARGET_NDS32_H - -#include <jtag/jtag.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 NDS32_EDM_OPERATION_MAX_NUM 64 - -#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, -}; - -#define NDS32_STRUCT_STAT_SIZE 60 -#define NDS32_STRUCT_TIMEVAL_SIZE 8 - -enum nds32_syscall_id { - NDS32_SYSCALL_UNDEFINED = 0, - 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 0xADE5ADE5U - -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 nds_memory_access access_channel; - - /** Memory access mode */ - enum nds_memory_select 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 { - unsigned 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 hit 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; - - struct breakpoint syscall_break; - - /** Flag reporting whether global stop is active. */ - bool global_stop; - - /** Flag reporting whether to use soft-reset-halt or not as issuing reset-halt. */ - bool soft_reset_halt; - - /** reset-halt as target examine */ - bool reset_halt_as_examine; - - /** backup/restore target EDM_CTL value. As debugging target debug - * handler, it should be true. */ - bool keep_target_edm_ctl; - - /* Value of $EDM_CTL before target enters debug mode */ - uint32_t backup_edm_ctl; - - /** always use word-aligned address to access memory */ - bool word_access_mem; - - /** EDM passcode for debugging secure MCU */ - char *edm_passcode; - - /** current privilege_level if using secure MCU. value 0 is the highest level. */ - int privilege_level; - - /** 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; - - /* Andes Core has mixed endian model. Instruction is always big-endian. - * Data may be big or little endian. Device registers may have different - * endian from data and instruction. */ - /** Endian of data memory */ - enum target_endianness data_endian; - - /** Endian of device registers */ - enum target_endianness device_reg_endian; - - /** Flag to indicate if auto convert software breakpoints to - * hardware breakpoints or not in ROM */ - bool auto_convert_hw_bp; - - /* Flag to indicate the target is attached by debugger or not */ - bool attached; - - /** Backpointer to the target. */ - struct target *target; - - void *arch_info; -}; - -struct nds32_reg { - int32_t num; - uint8_t value[8]; - struct target *target; - struct nds32 *nds32; - bool enable; -}; - -struct nds32_edm_operation { - uint32_t reg_no; - uint32_t value; -}; - -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_reg_list(struct target *target, - struct reg **reg_list[], int *reg_list_size, - enum target_register_class reg_class); - -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_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_cache_sync(struct target *target, target_addr_t address, uint32_t length); -extern int nds32_mmu(struct target *target, int *enabled); -extern int nds32_virtual_to_physical(struct target *target, target_addr_t address, - target_addr_t *physical); -extern int nds32_read_phys_memory(struct target *target, target_addr_t address, - uint32_t size, uint32_t count, uint8_t *buffer); -extern int nds32_write_phys_memory(struct target *target, target_addr_t address, - uint32_t size, uint32_t count, const uint8_t *buffer); -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, - target_addr_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, - target_addr_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); -extern int nds32_login(struct nds32 *nds32); -extern int nds32_profiling(struct target *target, uint32_t *samples, - uint32_t max_num_samples, uint32_t *num_samples, uint32_t seconds); - -/** Convert target handle to generic Andes target state handle. */ -static inline struct nds32 *target_to_nds32(struct target *target) -{ - assert(target); - return target->arch_info; -} - -/** */ -static inline struct aice_port_s *target_to_aice(struct target *target) -{ - assert(target); - return target->tap->priv; -} - -static inline bool is_nds32(struct nds32 *nds32) -{ - assert(nds32); - return nds32->common_magic == NDS32_COMMON_MAGIC; -} - -static inline bool nds32_reach_max_interrupt_level(struct nds32 *nds32) -{ - assert(nds32); - return nds32->max_interrupt_level == nds32->current_interrupt_level; -} - -#endif /* OPENOCD_TARGET_NDS32_H */ diff --git a/src/target/nds32_aice.c b/src/target/nds32_aice.c deleted file mode 100644 index 8dc4d77..0000000 --- a/src/target/nds32_aice.c +++ /dev/null @@ -1,147 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -/*************************************************************************** - * Copyright (C) 2013 Andes technology. * - * Hsiangkai Wang <hkwang@andestech.com> * - ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <helper/log.h> -#include "nds32_aice.h" - -int aice_read_reg_64(struct aice_port_s *aice, uint32_t num, uint64_t *val) -{ - if (!aice->port->api->read_reg_64) { - LOG_WARNING("Not implemented: %s", __func__); - return ERROR_FAIL; - } - - return aice->port->api->read_reg_64(aice->coreid, num, val); -} - -int aice_write_reg_64(struct aice_port_s *aice, uint32_t num, uint64_t val) -{ - if (!aice->port->api->write_reg_64) { - LOG_WARNING("Not implemented: %s", __func__); - return ERROR_FAIL; - } - - return aice->port->api->write_reg_64(aice->coreid, num, val); -} - -int aice_read_tlb(struct aice_port_s *aice, target_addr_t virtual_address, - target_addr_t *physical_address) -{ - if (!aice->port->api->read_tlb) { - LOG_WARNING("Not implemented: %s", __func__); - return ERROR_FAIL; - } - - return aice->port->api->read_tlb(aice->coreid, virtual_address, physical_address); -} - -int aice_cache_ctl(struct aice_port_s *aice, uint32_t subtype, uint32_t address) -{ - if (!aice->port->api->cache_ctl) { - LOG_WARNING("Not implemented: %s", __func__); - return ERROR_FAIL; - } - - return aice->port->api->cache_ctl(aice->coreid, subtype, address); -} - -int aice_set_retry_times(struct aice_port_s *aice, uint32_t a_retry_times) -{ - if (!aice->port->api->set_retry_times) { - LOG_WARNING("Not implemented: %s", __func__); - return ERROR_FAIL; - } - - return aice->port->api->set_retry_times(a_retry_times); -} - -int aice_program_edm(struct aice_port_s *aice, char *command_sequence) -{ - if (!aice->port->api->program_edm) { - LOG_WARNING("Not implemented: %s", __func__); - return ERROR_FAIL; - } - - return aice->port->api->program_edm(aice->coreid, command_sequence); -} - -int aice_set_command_mode(struct aice_port_s *aice, - enum aice_command_mode command_mode) -{ - if (!aice->port->api->set_command_mode) { - LOG_WARNING("Not implemented: %s", __func__); - return ERROR_FAIL; - } - - return aice->port->api->set_command_mode(command_mode); -} - -int aice_execute(struct aice_port_s *aice, uint32_t *instructions, - uint32_t instruction_num) -{ - if (!aice->port->api->execute) { - LOG_WARNING("Not implemented: %s", __func__); - return ERROR_FAIL; - } - - return aice->port->api->execute(aice->coreid, instructions, instruction_num); -} - -int aice_set_custom_srst_script(struct aice_port_s *aice, const char *script) -{ - if (!aice->port->api->set_custom_srst_script) { - LOG_WARNING("Not implemented: %s", __func__); - return ERROR_FAIL; - } - - return aice->port->api->set_custom_srst_script(script); -} - -int aice_set_custom_trst_script(struct aice_port_s *aice, const char *script) -{ - if (!aice->port->api->set_custom_trst_script) { - LOG_WARNING("Not implemented: %s", __func__); - return ERROR_FAIL; - } - - return aice->port->api->set_custom_trst_script(script); -} - -int aice_set_custom_restart_script(struct aice_port_s *aice, const char *script) -{ - if (!aice->port->api->set_custom_restart_script) { - LOG_WARNING("Not implemented: %s", __func__); - return ERROR_FAIL; - } - - return aice->port->api->set_custom_restart_script(script); -} - -int aice_set_count_to_check_dbger(struct aice_port_s *aice, uint32_t count_to_check) -{ - if (!aice->port->api->set_count_to_check_dbger) { - LOG_WARNING("Not implemented: %s", __func__); - return ERROR_FAIL; - } - - return aice->port->api->set_count_to_check_dbger(count_to_check); -} - -int aice_profiling(struct aice_port_s *aice, uint32_t interval, uint32_t iteration, - uint32_t reg_no, uint32_t *samples, uint32_t *num_samples) -{ - if (!aice->port->api->profiling) { - LOG_WARNING("Not implemented: %s", __func__); - return ERROR_FAIL; - } - - return aice->port->api->profiling(aice->coreid, interval, iteration, - reg_no, samples, num_samples); -} diff --git a/src/target/nds32_aice.h b/src/target/nds32_aice.h deleted file mode 100644 index 2a6c879..0000000 --- a/src/target/nds32_aice.h +++ /dev/null @@ -1,150 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -/*************************************************************************** - * Copyright (C) 2013 Andes technology. * - * Hsiangkai Wang <hkwang@andestech.com> * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_NDS32_AICE_H -#define OPENOCD_TARGET_NDS32_AICE_H - -#include <jtag/aice/aice_port.h> - -int aice_read_reg_64(struct aice_port_s *aice, uint32_t num, uint64_t *val); -int aice_write_reg_64(struct aice_port_s *aice, uint32_t num, uint64_t val); -int aice_read_tlb(struct aice_port_s *aice, target_addr_t virtual_address, - target_addr_t *physical_address); -int aice_cache_ctl(struct aice_port_s *aice, uint32_t subtype, uint32_t address); -int aice_set_retry_times(struct aice_port_s *aice, uint32_t a_retry_times); -int aice_program_edm(struct aice_port_s *aice, char *command_sequence); -int aice_set_command_mode(struct aice_port_s *aice, - enum aice_command_mode command_mode); -int aice_execute(struct aice_port_s *aice, uint32_t *instructions, - uint32_t instruction_num); -int aice_set_custom_srst_script(struct aice_port_s *aice, const char *script); -int aice_set_custom_trst_script(struct aice_port_s *aice, const char *script); -int aice_set_custom_restart_script(struct aice_port_s *aice, const char *script); -int aice_set_count_to_check_dbger(struct aice_port_s *aice, uint32_t count_to_check); -int aice_profiling(struct aice_port_s *aice, uint32_t interval, uint32_t iteration, - uint32_t reg_no, uint32_t *samples, uint32_t *num_samples); - -static inline int aice_open(struct aice_port_s *aice, struct aice_port_param_s *param) -{ - return aice->port->api->open(param); -} - -static inline int aice_close(struct aice_port_s *aice) -{ - return aice->port->api->close(); -} - -static inline int aice_reset(struct aice_port_s *aice) -{ - return aice->port->api->reset(); -} - -static inline int aice_assert_srst(struct aice_port_s *aice, - enum aice_srst_type_s srst) -{ - return aice->port->api->assert_srst(aice->coreid, srst); -} - -static inline int aice_run(struct aice_port_s *aice) -{ - return aice->port->api->run(aice->coreid); -} - -static inline int aice_halt(struct aice_port_s *aice) -{ - return aice->port->api->halt(aice->coreid); -} - -static inline int aice_step(struct aice_port_s *aice) -{ - return aice->port->api->step(aice->coreid); -} - -static inline int aice_read_register(struct aice_port_s *aice, uint32_t num, - uint32_t *val) -{ - return aice->port->api->read_reg(aice->coreid, num, val); -} - -static inline int aice_write_register(struct aice_port_s *aice, uint32_t num, - uint32_t val) -{ - return aice->port->api->write_reg(aice->coreid, num, val); -} - -static inline int aice_read_debug_reg(struct aice_port_s *aice, uint32_t addr, - uint32_t *val) -{ - return aice->port->api->read_debug_reg(aice->coreid, addr, val); -} - -static inline int aice_write_debug_reg(struct aice_port_s *aice, uint32_t addr, - const uint32_t val) -{ - return aice->port->api->write_debug_reg(aice->coreid, addr, val); -} - -static inline int aice_read_mem_unit(struct aice_port_s *aice, uint32_t addr, - uint32_t size, uint32_t count, uint8_t *buffer) -{ - return aice->port->api->read_mem_unit(aice->coreid, addr, size, count, buffer); -} - -static inline int aice_write_mem_unit(struct aice_port_s *aice, uint32_t addr, - uint32_t size, uint32_t count, const uint8_t *buffer) -{ - return aice->port->api->write_mem_unit(aice->coreid, addr, size, count, buffer); -} - -static inline int aice_read_mem_bulk(struct aice_port_s *aice, uint32_t addr, - uint32_t length, uint8_t *buffer) -{ - return aice->port->api->read_mem_bulk(aice->coreid, addr, length, buffer); -} - -static inline int aice_write_mem_bulk(struct aice_port_s *aice, uint32_t addr, - uint32_t length, const uint8_t *buffer) -{ - return aice->port->api->write_mem_bulk(aice->coreid, addr, length, buffer); -} - -static inline int aice_idcode(struct aice_port_s *aice, uint32_t *idcode, - uint8_t *num_of_idcode) -{ - return aice->port->api->idcode(idcode, num_of_idcode); -} - -static inline int aice_state(struct aice_port_s *aice, - enum aice_target_state_s *state) -{ - return aice->port->api->state(aice->coreid, state); -} - -static inline int aice_set_jtag_clock(struct aice_port_s *aice, uint32_t a_clock) -{ - return aice->port->api->set_jtag_clock(a_clock); -} - -static inline int aice_memory_access(struct aice_port_s *aice, - enum nds_memory_access a_access) -{ - return aice->port->api->memory_access(aice->coreid, a_access); -} - -static inline int aice_memory_mode(struct aice_port_s *aice, - enum nds_memory_select mem_select) -{ - return aice->port->api->memory_mode(aice->coreid, mem_select); -} - -static inline int aice_set_data_endian(struct aice_port_s *aice, - enum aice_target_endian target_data_endian) -{ - return aice->port->api->set_data_endian(aice->coreid, target_data_endian); -} - -#endif /* OPENOCD_TARGET_NDS32_AICE_H */ diff --git a/src/target/nds32_cmd.c b/src/target/nds32_cmd.c deleted file mode 100644 index 37f7648..0000000 --- a/src/target/nds32_cmd.c +++ /dev/null @@ -1,1123 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -/*************************************************************************** - * Copyright (C) 2013 Andes Technology * - * Hsiangkai Wang <hkwang@andestech.com> * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <helper/command.h> -#include "nds32.h" -#include "nds32_aice.h" -#include "nds32_disassembler.h" - -extern struct nds32_edm_operation nds32_edm_ops[NDS32_EDM_OPERATION_MAX_NUM]; -extern uint32_t nds32_edm_ops_num; - -static const char *const nds_memory_access_name[] = { - "BUS", - "CPU", -}; - -static const char *const nds_memory_select_name[] = { - "AUTO", - "MEM", - "ILM", - "DLM", -}; - -COMMAND_HANDLER(handle_nds32_dssim_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct nds32 *nds32 = target_to_nds32(target); - - if (!is_nds32(nds32)) { - command_print(CMD, "current target isn't an Andes core"); - return ERROR_FAIL; - } - - if (CMD_ARGC > 0) { - if (strcmp(CMD_ARGV[0], "on") == 0) - nds32->step_isr_enable = true; - if (strcmp(CMD_ARGV[0], "off") == 0) - nds32->step_isr_enable = false; - } - - command_print(CMD, "%s: $INT_MASK.DSSIM: %d", target_name(target), - nds32->step_isr_enable); - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_nds32_memory_access_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct nds32 *nds32 = target_to_nds32(target); - struct aice_port_s *aice = target_to_aice(target); - struct nds32_memory *memory = &(nds32->memory); - - if (!is_nds32(nds32)) { - command_print(CMD, "current target isn't an Andes core"); - return ERROR_FAIL; - } - - if (CMD_ARGC > 0) { - if (strcmp(CMD_ARGV[0], "bus") == 0) - memory->access_channel = NDS_MEMORY_ACC_BUS; - else if (strcmp(CMD_ARGV[0], "cpu") == 0) - memory->access_channel = NDS_MEMORY_ACC_CPU; - else /* default access channel is NDS_MEMORY_ACC_CPU */ - memory->access_channel = NDS_MEMORY_ACC_CPU; - - LOG_DEBUG("memory access channel is changed to %s", - nds_memory_access_name[memory->access_channel]); - - aice_memory_access(aice, memory->access_channel); - } else { - command_print(CMD, "%s: memory access channel: %s", - target_name(target), - nds_memory_access_name[memory->access_channel]); - } - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_nds32_memory_mode_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct nds32 *nds32 = target_to_nds32(target); - struct aice_port_s *aice = target_to_aice(target); - - if (!is_nds32(nds32)) { - command_print(CMD, "current target isn't an Andes core"); - return ERROR_FAIL; - } - - if (CMD_ARGC > 0) { - - if (nds32->edm.access_control == false) { - command_print(CMD, "%s does not support ACC_CTL. " - "Set memory mode to MEMORY", target_name(target)); - nds32->memory.mode = NDS_MEMORY_SELECT_MEM; - } else if (nds32->edm.direct_access_local_memory == false) { - command_print(CMD, "%s does not support direct access " - "local memory. Set memory mode to MEMORY", - target_name(target)); - nds32->memory.mode = NDS_MEMORY_SELECT_MEM; - - /* set to ACC_CTL */ - aice_memory_mode(aice, nds32->memory.mode); - } else { - if (strcmp(CMD_ARGV[0], "auto") == 0) { - nds32->memory.mode = NDS_MEMORY_SELECT_AUTO; - } else if (strcmp(CMD_ARGV[0], "mem") == 0) { - nds32->memory.mode = NDS_MEMORY_SELECT_MEM; - } else if (strcmp(CMD_ARGV[0], "ilm") == 0) { - if (nds32->memory.ilm_base == 0) - command_print(CMD, "%s does not support ILM", - target_name(target)); - else - nds32->memory.mode = NDS_MEMORY_SELECT_ILM; - } else if (strcmp(CMD_ARGV[0], "dlm") == 0) { - if (nds32->memory.dlm_base == 0) - command_print(CMD, "%s does not support DLM", - target_name(target)); - else - nds32->memory.mode = NDS_MEMORY_SELECT_DLM; - } - - /* set to ACC_CTL */ - aice_memory_mode(aice, nds32->memory.mode); - } - } - - command_print(CMD, "%s: memory mode: %s", - target_name(target), - nds_memory_select_name[nds32->memory.mode]); - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_nds32_cache_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct nds32 *nds32 = target_to_nds32(target); - struct aice_port_s *aice = target_to_aice(target); - struct nds32_cache *icache = &(nds32->memory.icache); - struct nds32_cache *dcache = &(nds32->memory.dcache); - int result; - - if (!is_nds32(nds32)) { - command_print(CMD, "current target isn't an Andes core"); - return ERROR_FAIL; - } - - if (CMD_ARGC > 0) { - - if (strcmp(CMD_ARGV[0], "invalidate") == 0) { - if ((dcache->line_size != 0) && (dcache->enable == true)) { - /* D$ write back */ - result = aice_cache_ctl(aice, AICE_CACHE_CTL_L1D_WBALL, 0); - if (result != ERROR_OK) { - command_print(CMD, "%s: Write back data cache...failed", - target_name(target)); - return result; - } - - command_print(CMD, "%s: Write back data cache...done", - target_name(target)); - - /* D$ invalidate */ - result = aice_cache_ctl(aice, AICE_CACHE_CTL_L1D_INVALALL, 0); - if (result != ERROR_OK) { - command_print(CMD, "%s: Invalidate data cache...failed", - target_name(target)); - return result; - } - - command_print(CMD, "%s: Invalidate data cache...done", - target_name(target)); - } else { - if (dcache->line_size == 0) - command_print(CMD, "%s: No data cache", - target_name(target)); - else - command_print(CMD, "%s: Data cache disabled", - target_name(target)); - } - - if ((icache->line_size != 0) && (icache->enable == true)) { - /* I$ invalidate */ - result = aice_cache_ctl(aice, AICE_CACHE_CTL_L1I_INVALALL, 0); - if (result != ERROR_OK) { - command_print(CMD, "%s: Invalidate instruction cache...failed", - target_name(target)); - return result; - } - - command_print(CMD, "%s: Invalidate instruction cache...done", - target_name(target)); - } else { - if (icache->line_size == 0) - command_print(CMD, "%s: No instruction cache", - target_name(target)); - else - command_print(CMD, "%s: Instruction cache disabled", - target_name(target)); - } - } else - command_print(CMD, "No valid parameter"); - } - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_nds32_icache_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct nds32 *nds32 = target_to_nds32(target); - struct aice_port_s *aice = target_to_aice(target); - struct nds32_cache *icache = &(nds32->memory.icache); - int result; - - if (!is_nds32(nds32)) { - command_print(CMD, "current target isn't an Andes core"); - return ERROR_FAIL; - } - - if (CMD_ARGC > 0) { - - if (icache->line_size == 0) { - command_print(CMD, "%s: No instruction cache", - target_name(target)); - return ERROR_OK; - } - - if (strcmp(CMD_ARGV[0], "invalidate") == 0) { - if (icache->enable == true) { - /* I$ invalidate */ - result = aice_cache_ctl(aice, AICE_CACHE_CTL_L1I_INVALALL, 0); - if (result != ERROR_OK) { - command_print(CMD, "%s: Invalidate instruction cache...failed", - target_name(target)); - return result; - } - - command_print(CMD, "%s: Invalidate instruction cache...done", - target_name(target)); - } else { - command_print(CMD, "%s: Instruction cache disabled", - target_name(target)); - } - } else if (strcmp(CMD_ARGV[0], "enable") == 0) { - uint32_t value; - nds32_get_mapped_reg(nds32, IR8, &value); - nds32_set_mapped_reg(nds32, IR8, value | 0x1); - } else if (strcmp(CMD_ARGV[0], "disable") == 0) { - uint32_t value; - nds32_get_mapped_reg(nds32, IR8, &value); - nds32_set_mapped_reg(nds32, IR8, value & ~0x1); - } else if (strcmp(CMD_ARGV[0], "dump") == 0) { - /* TODO: dump cache content */ - } else { - command_print(CMD, "%s: No valid parameter", target_name(target)); - } - } - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_nds32_dcache_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct nds32 *nds32 = target_to_nds32(target); - struct aice_port_s *aice = target_to_aice(target); - struct nds32_cache *dcache = &(nds32->memory.dcache); - int result; - - if (!is_nds32(nds32)) { - command_print(CMD, "current target isn't an Andes core"); - return ERROR_FAIL; - } - - if (CMD_ARGC > 0) { - - if (dcache->line_size == 0) { - command_print(CMD, "%s: No data cache", target_name(target)); - return ERROR_OK; - } - - if (strcmp(CMD_ARGV[0], "invalidate") == 0) { - if (dcache->enable == true) { - /* D$ write back */ - result = aice_cache_ctl(aice, AICE_CACHE_CTL_L1D_WBALL, 0); - if (result != ERROR_OK) { - command_print(CMD, "%s: Write back data cache...failed", - target_name(target)); - return result; - } - - command_print(CMD, "%s: Write back data cache...done", - target_name(target)); - - /* D$ invalidate */ - result = aice_cache_ctl(aice, AICE_CACHE_CTL_L1D_INVALALL, 0); - if (result != ERROR_OK) { - command_print(CMD, "%s: Invalidate data cache...failed", - target_name(target)); - return result; - } - - command_print(CMD, "%s: Invalidate data cache...done", - target_name(target)); - } else { - command_print(CMD, "%s: Data cache disabled", - target_name(target)); - } - } else if (strcmp(CMD_ARGV[0], "enable") == 0) { - uint32_t value; - nds32_get_mapped_reg(nds32, IR8, &value); - nds32_set_mapped_reg(nds32, IR8, value | 0x2); - } else if (strcmp(CMD_ARGV[0], "disable") == 0) { - uint32_t value; - nds32_get_mapped_reg(nds32, IR8, &value); - nds32_set_mapped_reg(nds32, IR8, value & ~0x2); - } else if (strcmp(CMD_ARGV[0], "dump") == 0) { - /* TODO: dump cache content */ - } else { - command_print(CMD, "%s: No valid parameter", target_name(target)); - } - } - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_nds32_auto_break_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct nds32 *nds32 = target_to_nds32(target); - - if (!is_nds32(nds32)) { - command_print(CMD, "current target isn't an Andes core"); - return ERROR_FAIL; - } - - if (CMD_ARGC > 0) { - if (strcmp(CMD_ARGV[0], "on") == 0) - nds32->auto_convert_hw_bp = true; - if (strcmp(CMD_ARGV[0], "off") == 0) - nds32->auto_convert_hw_bp = false; - } - - if (nds32->auto_convert_hw_bp) - command_print(CMD, "%s: convert sw break to hw break on ROM: on", - target_name(target)); - else - command_print(CMD, "%s: convert sw break to hw break on ROM: off", - target_name(target)); - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_nds32_virtual_hosting_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct nds32 *nds32 = target_to_nds32(target); - - if (!is_nds32(nds32)) { - command_print(CMD, "current target isn't an Andes core"); - return ERROR_FAIL; - } - - if (CMD_ARGC > 0) { - if (strcmp(CMD_ARGV[0], "on") == 0) - nds32->virtual_hosting = true; - if (strcmp(CMD_ARGV[0], "off") == 0) - nds32->virtual_hosting = false; - } - - if (nds32->virtual_hosting) - command_print(CMD, "%s: virtual hosting: on", target_name(target)); - else - command_print(CMD, "%s: virtual hosting: off", target_name(target)); - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_nds32_global_stop_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct nds32 *nds32 = target_to_nds32(target); - - if (!is_nds32(nds32)) { - command_print(CMD, "current target isn't an Andes core"); - return ERROR_FAIL; - } - - if (CMD_ARGC > 0) { - if (strcmp(CMD_ARGV[0], "on") == 0) - nds32->global_stop = true; - if (strcmp(CMD_ARGV[0], "off") == 0) - nds32->global_stop = false; - } - - if (nds32->global_stop) - LOG_INFO("%s: global stop: on", target_name(target)); - else - LOG_INFO("%s: global stop: off", target_name(target)); - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_nds32_soft_reset_halt_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct nds32 *nds32 = target_to_nds32(target); - - if (!is_nds32(nds32)) { - command_print(CMD, "current target isn't an Andes core"); - return ERROR_FAIL; - } - - if (CMD_ARGC > 0) { - if (strcmp(CMD_ARGV[0], "on") == 0) - nds32->soft_reset_halt = true; - if (strcmp(CMD_ARGV[0], "off") == 0) - nds32->soft_reset_halt = false; - } - - if (nds32->soft_reset_halt) - LOG_INFO("%s: soft-reset-halt: on", target_name(target)); - else - LOG_INFO("%s: soft-reset-halt: off", target_name(target)); - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_nds32_boot_time_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct nds32 *nds32 = target_to_nds32(target); - - if (!is_nds32(nds32)) { - command_print(CMD, "current target isn't an Andes core"); - return ERROR_FAIL; - } - - if (CMD_ARGC > 0) - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], nds32->boot_time); - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_nds32_login_edm_passcode_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct nds32 *nds32 = target_to_nds32(target); - - if (!is_nds32(nds32)) { - command_print(CMD, "current target isn't an Andes core"); - return ERROR_FAIL; - } - - nds32->edm_passcode = strdup(CMD_ARGV[0]); - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_nds32_login_edm_operation_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct nds32 *nds32 = target_to_nds32(target); - - if (!is_nds32(nds32)) { - command_print(CMD, "current target isn't an Andes core"); - return ERROR_FAIL; - } - - if (CMD_ARGC > 1) { - - uint32_t misc_reg_no; - uint32_t data; - - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], misc_reg_no); - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], data); - - if (nds32_edm_ops_num >= NDS32_EDM_OPERATION_MAX_NUM) - return ERROR_FAIL; - - /* Just save the operation. Execute it in nds32_login() */ - nds32_edm_ops[nds32_edm_ops_num].reg_no = misc_reg_no; - nds32_edm_ops[nds32_edm_ops_num].value = data; - nds32_edm_ops_num++; - } else - return ERROR_FAIL; - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_nds32_reset_halt_as_init_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct nds32 *nds32 = target_to_nds32(target); - - if (!is_nds32(nds32)) { - command_print(CMD, "current target isn't an Andes core"); - return ERROR_FAIL; - } - - if (CMD_ARGC > 0) { - if (strcmp(CMD_ARGV[0], "on") == 0) - nds32->reset_halt_as_examine = true; - if (strcmp(CMD_ARGV[0], "off") == 0) - nds32->reset_halt_as_examine = false; - } - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_nds32_keep_target_edm_ctl_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct nds32 *nds32 = target_to_nds32(target); - - if (!is_nds32(nds32)) { - command_print(CMD, "current target isn't an Andes core"); - return ERROR_FAIL; - } - - if (CMD_ARGC > 0) { - if (strcmp(CMD_ARGV[0], "on") == 0) - nds32->keep_target_edm_ctl = true; - if (strcmp(CMD_ARGV[0], "off") == 0) - nds32->keep_target_edm_ctl = false; - } - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_nds32_decode_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct nds32 *nds32 = target_to_nds32(target); - - if (!is_nds32(nds32)) { - command_print(CMD, "current target isn't an Andes core"); - return ERROR_FAIL; - } - - if (CMD_ARGC > 1) { - - uint32_t addr; - uint32_t insn_count; - uint32_t opcode; - uint32_t read_addr; - uint32_t i; - struct nds32_instruction instruction; - - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], addr); - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], insn_count); - - read_addr = addr; - i = 0; - while (i < insn_count) { - if (nds32_read_opcode(nds32, read_addr, &opcode) != ERROR_OK) - return ERROR_FAIL; - if (nds32_evaluate_opcode(nds32, opcode, read_addr, &instruction) != ERROR_OK) - return ERROR_FAIL; - - command_print(CMD, "%s", instruction.text); - - read_addr += instruction.instruction_size; - i++; - } - } else if (CMD_ARGC == 1) { - - uint32_t addr; - uint32_t opcode; - struct nds32_instruction instruction; - - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], addr); - - if (nds32_read_opcode(nds32, addr, &opcode) != ERROR_OK) - return ERROR_FAIL; - if (nds32_evaluate_opcode(nds32, opcode, addr, &instruction) != ERROR_OK) - return ERROR_FAIL; - - command_print(CMD, "%s", instruction.text); - } else - return ERROR_FAIL; - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_nds32_word_access_mem_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct nds32 *nds32 = target_to_nds32(target); - - if (!is_nds32(nds32)) { - command_print(CMD, "current target isn't an Andes core"); - return ERROR_FAIL; - } - - if (CMD_ARGC > 0) { - if (strcmp(CMD_ARGV[0], "on") == 0) - nds32->word_access_mem = true; - if (strcmp(CMD_ARGV[0], "off") == 0) - nds32->word_access_mem = false; - } - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_nds32_query_target_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct nds32 *nds32 = target_to_nds32(target); - - if (!is_nds32(nds32)) { - command_print(CMD, "current target isn't an Andes core"); - return ERROR_FAIL; - } - - command_print(CMD, "OCD"); - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_nds32_query_endian_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct nds32 *nds32 = target_to_nds32(target); - - if (!is_nds32(nds32)) { - command_print(CMD, "current target isn't an Andes core"); - return ERROR_FAIL; - } - - uint32_t value_psw; - nds32_get_mapped_reg(nds32, IR0, &value_psw); - - if (value_psw & 0x20) - command_print(CMD, "%s: BE", target_name(target)); - else - command_print(CMD, "%s: LE", target_name(target)); - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_nds32_query_cpuid_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct nds32 *nds32 = target_to_nds32(target); - - if (!is_nds32(nds32)) { - command_print(CMD, "current target isn't an Andes core"); - return ERROR_FAIL; - } - - command_print(CMD, "CPUID: %s", target_name(target)); - - return ERROR_OK; -} - -static int jim_nds32_bulk_write(Jim_Interp *interp, int argc, Jim_Obj * const *argv) -{ - const char *cmd_name = Jim_GetString(argv[0], NULL); - - struct jim_getopt_info goi; - jim_getopt_setup(&goi, interp, argc - 1, argv + 1); - - if (goi.argc < 3) { - Jim_SetResultFormatted(goi.interp, - "usage: %s <address> <count> <data>", cmd_name); - return JIM_ERR; - } - - int e; - jim_wide address; - e = jim_getopt_wide(&goi, &address); - if (e != JIM_OK) - return e; - - jim_wide count; - e = jim_getopt_wide(&goi, &count); - if (e != JIM_OK) - return e; - - uint32_t *data = malloc(count * sizeof(uint32_t)); - if (!data) - return JIM_ERR; - - jim_wide i; - for (i = 0; i < count; i++) { - jim_wide tmp; - e = jim_getopt_wide(&goi, &tmp); - if (e != JIM_OK) { - free(data); - return e; - } - data[i] = (uint32_t)tmp; - } - - /* all args must be consumed */ - if (goi.argc != 0) { - free(data); - return JIM_ERR; - } - - struct command_context *cmd_ctx = current_command_context(interp); - assert(cmd_ctx); - struct target *target = get_current_target(cmd_ctx); - int result; - - result = target_write_buffer(target, address, count * 4, (const uint8_t *)data); - - free(data); - - return result; -} - -static int jim_nds32_multi_write(Jim_Interp *interp, int argc, Jim_Obj * const *argv) -{ - const char *cmd_name = Jim_GetString(argv[0], NULL); - - struct jim_getopt_info goi; - jim_getopt_setup(&goi, interp, argc - 1, argv + 1); - - if (goi.argc < 3) { - Jim_SetResultFormatted(goi.interp, - "usage: %s # of pairs [<address> <data>]+", cmd_name); - return JIM_ERR; - } - - int e; - jim_wide num_of_pairs; - e = jim_getopt_wide(&goi, &num_of_pairs); - if (e != JIM_OK) - return e; - - struct command_context *cmd_ctx = current_command_context(interp); - assert(cmd_ctx); - struct target *target = get_current_target(cmd_ctx); - struct aice_port_s *aice = target_to_aice(target); - int result; - uint32_t address; - uint32_t data; - jim_wide i; - - aice_set_command_mode(aice, AICE_COMMAND_MODE_PACK); - for (i = 0; i < num_of_pairs; i++) { - jim_wide tmp; - e = jim_getopt_wide(&goi, &tmp); - if (e != JIM_OK) - break; - address = (uint32_t)tmp; - - e = jim_getopt_wide(&goi, &tmp); - if (e != JIM_OK) - break; - data = (uint32_t)tmp; - - result = target_write_buffer(target, address, 4, (const uint8_t *)&data); - if (result != ERROR_OK) - break; - } - aice_set_command_mode(aice, AICE_COMMAND_MODE_NORMAL); - - /* all args must be consumed */ - if (goi.argc != 0) - return JIM_ERR; - - return ERROR_OK; -} - -static int jim_nds32_bulk_read(Jim_Interp *interp, int argc, Jim_Obj * const *argv) -{ - const char *cmd_name = Jim_GetString(argv[0], NULL); - - struct jim_getopt_info goi; - jim_getopt_setup(&goi, interp, argc - 1, argv + 1); - - if (goi.argc < 2) { - Jim_SetResultFormatted(goi.interp, - "usage: %s <address> <count>", cmd_name); - return JIM_ERR; - } - - int e; - jim_wide address; - e = jim_getopt_wide(&goi, &address); - if (e != JIM_OK) - return e; - - jim_wide count; - e = jim_getopt_wide(&goi, &count); - if (e != JIM_OK) - return e; - - /* all args must be consumed */ - if (goi.argc != 0) - return JIM_ERR; - - struct command_context *cmd_ctx = current_command_context(interp); - assert(cmd_ctx); - struct target *target = get_current_target(cmd_ctx); - uint32_t *data = malloc(count * sizeof(uint32_t)); - int result; - result = target_read_buffer(target, address, count * 4, (uint8_t *)data); - char data_str[12]; - - jim_wide i; - Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); - for (i = 0; i < count; i++) { - sprintf(data_str, "0x%08" PRIx32 " ", data[i]); - Jim_AppendStrings(interp, Jim_GetResult(interp), data_str, NULL); - } - - free(data); - - return result; -} - -static int jim_nds32_read_edm_sr(Jim_Interp *interp, int argc, Jim_Obj * const *argv) -{ - const char *cmd_name = Jim_GetString(argv[0], NULL); - - struct jim_getopt_info goi; - jim_getopt_setup(&goi, interp, argc - 1, argv + 1); - - if (goi.argc < 1) { - Jim_SetResultFormatted(goi.interp, - "usage: %s <edm_sr_name>", cmd_name); - return JIM_ERR; - } - - int e; - const char *edm_sr_name; - int edm_sr_name_len; - e = jim_getopt_string(&goi, &edm_sr_name, &edm_sr_name_len); - if (e != JIM_OK) - return e; - - /* all args must be consumed */ - if (goi.argc != 0) - return JIM_ERR; - - uint32_t edm_sr_number; - uint32_t edm_sr_value; - if (strncmp(edm_sr_name, "edm_dtr", edm_sr_name_len) == 0) - edm_sr_number = NDS_EDM_SR_EDM_DTR; - else if (strncmp(edm_sr_name, "edmsw", edm_sr_name_len) == 0) - edm_sr_number = NDS_EDM_SR_EDMSW; - else - return ERROR_FAIL; - - struct command_context *cmd_ctx = current_command_context(interp); - assert(cmd_ctx); - struct target *target = get_current_target(cmd_ctx); - struct aice_port_s *aice = target_to_aice(target); - char data_str[11]; - - aice_read_debug_reg(aice, edm_sr_number, &edm_sr_value); - - sprintf(data_str, "0x%08" PRIx32, edm_sr_value); - Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); - Jim_AppendStrings(interp, Jim_GetResult(interp), data_str, NULL); - - return ERROR_OK; -} - -static int jim_nds32_write_edm_sr(Jim_Interp *interp, int argc, Jim_Obj * const *argv) -{ - const char *cmd_name = Jim_GetString(argv[0], NULL); - - struct jim_getopt_info goi; - jim_getopt_setup(&goi, interp, argc - 1, argv + 1); - - if (goi.argc < 2) { - Jim_SetResultFormatted(goi.interp, - "usage: %s <edm_sr_name> <value>", cmd_name); - return JIM_ERR; - } - - int e; - const char *edm_sr_name; - int edm_sr_name_len; - e = jim_getopt_string(&goi, &edm_sr_name, &edm_sr_name_len); - if (e != JIM_OK) - return e; - - jim_wide value; - e = jim_getopt_wide(&goi, &value); - if (e != JIM_OK) - return e; - - /* all args must be consumed */ - if (goi.argc != 0) - return JIM_ERR; - - uint32_t edm_sr_number; - if (strncmp(edm_sr_name, "edm_dtr", edm_sr_name_len) == 0) - edm_sr_number = NDS_EDM_SR_EDM_DTR; - else - return ERROR_FAIL; - - struct command_context *cmd_ctx = current_command_context(interp); - assert(cmd_ctx); - struct target *target = get_current_target(cmd_ctx); - struct aice_port_s *aice = target_to_aice(target); - - aice_write_debug_reg(aice, edm_sr_number, value); - - return ERROR_OK; -} - -static const struct command_registration nds32_query_command_handlers[] = { - { - .name = "target", - .handler = handle_nds32_query_target_command, - .mode = COMMAND_EXEC, - .usage = "", - .help = "reply 'OCD' for gdb to identify server-side is OpenOCD", - }, - { - .name = "endian", - .handler = handle_nds32_query_endian_command, - .mode = COMMAND_EXEC, - .usage = "", - .help = "query target endian", - }, - { - .name = "cpuid", - .handler = handle_nds32_query_cpuid_command, - .mode = COMMAND_EXEC, - .usage = "", - .help = "query CPU ID", - }, - - COMMAND_REGISTRATION_DONE -}; - -static const struct command_registration nds32_exec_command_handlers[] = { - { - .name = "dssim", - .handler = handle_nds32_dssim_command, - .mode = COMMAND_EXEC, - .usage = "['on'|'off']", - .help = "display/change $INT_MASK.DSSIM status", - }, - { - .name = "mem_access", - .handler = handle_nds32_memory_access_command, - .mode = COMMAND_EXEC, - .usage = "['bus'|'cpu']", - .help = "display/change memory access channel", - }, - { - .name = "mem_mode", - .handler = handle_nds32_memory_mode_command, - .mode = COMMAND_EXEC, - .usage = "['auto'|'mem'|'ilm'|'dlm']", - .help = "display/change memory mode", - }, - { - .name = "cache", - .handler = handle_nds32_cache_command, - .mode = COMMAND_EXEC, - .usage = "['invalidate']", - .help = "cache control", - }, - { - .name = "icache", - .handler = handle_nds32_icache_command, - .mode = COMMAND_EXEC, - .usage = "['invalidate'|'enable'|'disable'|'dump']", - .help = "icache control", - }, - { - .name = "dcache", - .handler = handle_nds32_dcache_command, - .mode = COMMAND_EXEC, - .usage = "['invalidate'|'enable'|'disable'|'dump']", - .help = "dcache control", - }, - { - .name = "auto_break", - .handler = handle_nds32_auto_break_command, - .mode = COMMAND_EXEC, - .usage = "['on'|'off']", - .help = "convert software breakpoints to hardware breakpoints if needed", - }, - { - .name = "virtual_hosting", - .handler = handle_nds32_virtual_hosting_command, - .mode = COMMAND_ANY, - .usage = "['on'|'off']", - .help = "turn on/off virtual hosting", - }, - { - .name = "global_stop", - .handler = handle_nds32_global_stop_command, - .mode = COMMAND_ANY, - .usage = "['on'|'off']", - .help = "turn on/off global stop. After turning on, every load/store " - "instructions will be stopped to check memory access.", - }, - { - .name = "soft_reset_halt", - .handler = handle_nds32_soft_reset_halt_command, - .mode = COMMAND_ANY, - .usage = "['on'|'off']", - .help = "as issuing rest-halt, to use soft-reset-halt or not." - "the feature is for backward-compatible.", - }, - { - .name = "boot_time", - .handler = handle_nds32_boot_time_command, - .mode = COMMAND_CONFIG, - .usage = "milliseconds", - .help = "set the period to wait after srst.", - }, - { - .name = "login_edm_passcode", - .handler = handle_nds32_login_edm_passcode_command, - .mode = COMMAND_CONFIG, - .usage = "passcode", - .help = "set EDM passcode for secure MCU debugging.", - }, - { - .name = "login_edm_operation", - .handler = handle_nds32_login_edm_operation_command, - .mode = COMMAND_CONFIG, - .usage = "misc_reg_no value", - .help = "add EDM operations for secure MCU debugging.", - }, - { - .name = "reset_halt_as_init", - .handler = handle_nds32_reset_halt_as_init_command, - .mode = COMMAND_CONFIG, - .usage = "['on'|'off']", - .help = "reset halt as openocd init.", - }, - { - .name = "keep_target_edm_ctl", - .handler = handle_nds32_keep_target_edm_ctl_command, - .mode = COMMAND_CONFIG, - .usage = "['on'|'off']", - .help = "Backup/Restore target EDM_CTL register.", - }, - { - .name = "decode", - .handler = handle_nds32_decode_command, - .mode = COMMAND_EXEC, - .usage = "address icount", - .help = "decode instruction.", - }, - { - .name = "word_access_mem", - .handler = handle_nds32_word_access_mem_command, - .mode = COMMAND_ANY, - .usage = "['on'|'off']", - .help = "Always use word-aligned address to access memory.", - }, - { - .name = "bulk_write", - .jim_handler = jim_nds32_bulk_write, - .mode = COMMAND_EXEC, - .help = "Write multiple 32-bit words to target memory", - .usage = "address count data", - }, - { - .name = "multi_write", - .jim_handler = jim_nds32_multi_write, - .mode = COMMAND_EXEC, - .help = "Write multiple addresses/words to target memory", - .usage = "num_of_pairs [address data]+", - }, - { - .name = "bulk_read", - .jim_handler = jim_nds32_bulk_read, - .mode = COMMAND_EXEC, - .help = "Read multiple 32-bit words from target memory", - .usage = "address count", - }, - { - .name = "read_edmsr", - .jim_handler = jim_nds32_read_edm_sr, - .mode = COMMAND_EXEC, - .help = "Read EDM system register", - .usage = "['edmsw'|'edm_dtr']", - }, - { - .name = "write_edmsr", - .jim_handler = jim_nds32_write_edm_sr, - .mode = COMMAND_EXEC, - .help = "Write EDM system register", - .usage = "['edm_dtr'] value", - }, - { - .name = "query", - .mode = COMMAND_EXEC, - .help = "Andes query command group", - .usage = "", - .chain = nds32_query_command_handlers, - }, - - COMMAND_REGISTRATION_DONE -}; - -const struct command_registration nds32_command_handlers[] = { - { - .name = "nds", - .mode = COMMAND_ANY, - .help = "Andes command group", - .usage = "", - .chain = nds32_exec_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; diff --git a/src/target/nds32_cmd.h b/src/target/nds32_cmd.h deleted file mode 100644 index 1593243..0000000 --- a/src/target/nds32_cmd.h +++ /dev/null @@ -1,15 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -/*************************************************************************** - * Copyright (C) 2013 Andes Technology * - * Hsiangkai Wang <hkwang@andestech.com> * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_NDS32_CMD_H -#define OPENOCD_TARGET_NDS32_CMD_H - -#include <helper/command.h> - -extern const struct command_registration nds32_command_handlers[]; - -#endif /* OPENOCD_TARGET_NDS32_CMD_H */ diff --git a/src/target/nds32_disassembler.c b/src/target/nds32_disassembler.c deleted file mode 100644 index eebbfe1..0000000 --- a/src/target/nds32_disassembler.c +++ /dev/null @@ -1,3847 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -/*************************************************************************** - * Copyright (C) 2013 Andes Technology * - * Hsiangkai Wang <hkwang@andestech.com> * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <helper/log.h> -#include <target/target.h> -#include "nds32_disassembler.h" - -static const int enable4_bits[] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4}; - -int nds32_read_opcode(struct nds32 *nds32, uint32_t address, uint32_t *value) -{ - struct target *target = nds32->target; - uint8_t value_buf[4]; - - if (!target_was_examined(target)) { - LOG_ERROR("Target not examined yet"); - return ERROR_FAIL; - } - - int retval = target_read_buffer(target, address, 4, value_buf); - - if (retval == ERROR_OK) { - /* instructions are always big-endian */ - *value = be_to_h_u32(value_buf); - - LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%8.8" PRIx32 "", - address, - *value); - } else { - *value = 0x0; - LOG_DEBUG("address: 0x%8.8" PRIx32 " failed", - address); - } - - return retval; -} - -static int nds32_parse_type_0(uint32_t opcode, int32_t *imm) -{ - *imm = opcode & 0x1FFFFFF; - - return ERROR_OK; -} - -static int nds32_parse_type_1(uint32_t opcode, uint8_t *rt, int32_t *imm) -{ - *rt = (opcode >> 20) & 0x1F; - *imm = opcode & 0xFFFFF; - - return ERROR_OK; -} - -static int nds32_parse_type_2(uint32_t opcode, uint8_t *rt, uint8_t *ra, int32_t *imm) -{ - *rt = (opcode >> 20) & 0x1F; - *ra = (opcode >> 15) & 0x1F; - *imm = opcode & 0x7FFF; - - return ERROR_OK; -} - -static int nds32_parse_type_3(uint32_t opcode, uint8_t *rt, uint8_t *ra, - uint8_t *rb, int32_t *imm) -{ - *rt = (opcode >> 20) & 0x1F; - *ra = (opcode >> 15) & 0x1F; - *rb = (opcode >> 10) & 0x1F; - *imm = opcode & 0x3FF; - - return ERROR_OK; -} - -static int nds32_parse_type_4(uint32_t opcode, uint8_t *rt, uint8_t *ra, - uint8_t *rb, uint8_t *rd, uint8_t *sub_opc) -{ - *rt = (opcode >> 20) & 0x1F; - *ra = (opcode >> 15) & 0x1F; - *rb = (opcode >> 10) & 0x1F; - *rd = (opcode >> 5) & 0x1F; - *sub_opc = opcode & 0x1F; - - return ERROR_OK; -} - -/* LBI, LHI, LWI, LBI.bi, LHI.bi, LWI.bi */ -static int nds32_parse_group_0_insn(struct nds32 *nds32, uint32_t opcode, - uint32_t address, - struct nds32_instruction *instruction) -{ - uint8_t opc_6; - - opc_6 = instruction->info.opc_6; - - switch (opc_6 & 0x7) { - case 0: /* LBI */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 17) >> 17; /* sign-extend */ - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_start += instruction->info.imm; - instruction->access_end = instruction->access_start + 1; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLBI\t$r%" PRIu8 ",[$r%" PRIu8 "+#%" PRId32 "]", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - case 1: /* LHI */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 17) >> 16; /* sign-extend */ - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_start += instruction->info.imm; - instruction->access_end = instruction->access_start + 2; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLHI\t$r%" PRIu8 ",[$r%" PRIu8 "+#%" PRId32 "]", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - case 2: /* LWI */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 17) >> 15; /* sign-extend */ - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_start += instruction->info.imm; - instruction->access_end = instruction->access_start + 4; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLWI\t$r%" PRIu8 ",[$r%" PRIu8 "+#%" PRId32 "]", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - case 4: /* LBI.bi */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 17) >> 17; /* sign-extend */ - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_end = instruction->access_start + 1; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLBI.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - case 5: /* LHI.bi */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 17) >> 16; /* sign-extend */ - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_end = instruction->access_start + 2; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLHI.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - case 6: /* LWI.bi */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 17) >> 15; /* sign-extend */ - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_end = instruction->access_start + 4; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLWI.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],#%" PRId32 "", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - default: - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", - address, - opcode); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int nds32_parse_group_1_insn(struct nds32 *nds32, uint32_t opcode, - uint32_t address, struct nds32_instruction *instruction) -{ - uint8_t opc_6; - - opc_6 = instruction->info.opc_6; - - switch (opc_6 & 0x7) { - case 0: /* SBI */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 17) >> 17; /* sign-extend */ - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_start += instruction->info.imm; - instruction->access_end = instruction->access_start + 1; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSBI\t$r%" PRIu8 ",[$r%" PRIu8 "+#%" PRId32 "]", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - case 1: /* SHI */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 17) >> 16; /* sign-extend */ - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_start += instruction->info.imm; - instruction->access_end = instruction->access_start + 2; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSHI\t$r%" PRIu8 ",[$r%" PRIu8 "+#%" PRId32 "]", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - case 2: /* SWI */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 17) >> 15; /* sign-extend */ - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_start += instruction->info.imm; - instruction->access_end = instruction->access_start + 4; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSWI\t$r%" PRIu8 ",[$r%" PRIu8 "+#%" PRId32 "]", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - case 4: /* SBI.bi */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 17) >> 17; /* sign-extend */ - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_end = instruction->access_start + 1; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSBI.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - case 5: /* SHI.bi */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 17) >> 16; /* sign-extend */ - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_end = instruction->access_start + 2; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSHI.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - case 6: /* SWI.bi */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 17) >> 15; /* sign-extend */ - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_end = instruction->access_start + 4; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSWI.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - default: - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", - address, - opcode); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int nds32_parse_group_2_insn(struct nds32 *nds32, uint32_t opcode, - uint32_t address, struct nds32_instruction *instruction) -{ - uint8_t opc_6; - - opc_6 = instruction->info.opc_6; - - switch (opc_6 & 0x7) { - case 0: /* LBSI */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 17) >> 17; /* sign-extend */ - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_start += instruction->info.imm; - instruction->access_end = instruction->access_start + 1; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLBSI\t$r%" PRIu8 ",[$r%" PRIu8 "+#%" PRId32 "]", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - case 1: /* LHSI */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 17) >> 16; /* sign-extend */ - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_start += instruction->info.imm; - instruction->access_end = instruction->access_start + 2; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLHSI\t$r%" PRIu8 ",[$r%" PRIu8 "+#%" PRId32 "]", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - case 3: { /* DPREFI */ - uint8_t sub_type; - nds32_parse_type_2(opcode, &sub_type, &(instruction->info.ra), - &(instruction->info.imm)); - instruction->info.sub_opc = sub_type & 0xF; - instruction->type = NDS32_INSN_MISC; - if (sub_type & 0x10) { /* DPREFI.d */ - /* sign-extend */ - instruction->info.imm = (instruction->info.imm << 17) >> 14; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tDPREFI.d\t%" PRIu8 ",[$r%" PRIu8 "+#%" PRId32 "]", - address, - opcode, instruction->info.sub_opc, - instruction->info.ra, instruction->info.imm); - } else { /* DPREFI.w */ - /* sign-extend */ - instruction->info.imm = (instruction->info.imm << 17) >> 15; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tDPREFI.w\t%" PRIu8 ",[$r%" PRIu8 "+#%" PRId32 "]", - address, - opcode, instruction->info.sub_opc, - instruction->info.ra, instruction->info.imm); - } - } - break; - case 4: /* LBSI.bi */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 17) >> 17; /* sign-extend */ - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_end = instruction->access_start + 1; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLBSI.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - case 5: /* LHSI.bi */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 17) >> 16; /* sign-extend */ - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_end = instruction->access_start + 2; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLHSI.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - case 6: /* LBGP */ - nds32_parse_type_1(opcode, &(instruction->info.rt), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - if ((instruction->info.imm >> 19) & 0x1) { /* LBSI.gp */ - instruction->info.imm = (instruction->info.imm << 13) >> 13; - nds32_get_mapped_reg(nds32, R29, &(instruction->access_start)); - instruction->access_start += instruction->info.imm; - instruction->access_end = instruction->access_start + 1; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLBSI.gp\t$r%" PRIu8 ",[#%" PRId32 "]", - address, - opcode, instruction->info.rt, instruction->info.imm); - } else { /* LBI.gp */ - instruction->info.imm = (instruction->info.imm << 13) >> 13; - nds32_get_mapped_reg(nds32, R29, &(instruction->access_start)); - instruction->access_start += instruction->info.imm; - instruction->access_end = instruction->access_start + 1; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLBI.gp\t$r%" PRIu8 ",[#%" PRId32 "]", - address, - opcode, instruction->info.rt, instruction->info.imm); - } - break; - default: - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", - address, - opcode); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int nds32_parse_mem(struct nds32 *nds32, uint32_t opcode, uint32_t address, - struct nds32_instruction *instruction) -{ - uint32_t sub_opcode = opcode & 0x3F; - uint32_t val_ra, val_rb; - switch (sub_opcode >> 3) { - case 0: - switch (sub_opcode & 0x7) { - case 0: /* LB */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra); - nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb); - instruction->access_start = val_ra + - (val_rb << ((instruction->info.imm >> 8) & 0x3)); - instruction->access_end = instruction->access_start + 1; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLB\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - (instruction->info.imm >> 8) & 0x3); - break; - case 1: /* LH */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra); - nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb); - instruction->access_start = val_ra + - (val_rb << ((instruction->info.imm >> 8) & 0x3)); - instruction->access_end = instruction->access_start + 2; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLH\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - (instruction->info.imm >> 8) & 0x3); - break; - case 2: /* LW */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra); - nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb); - instruction->access_start = val_ra + - (val_rb << ((instruction->info.imm >> 8) & 0x3)); - instruction->access_end = instruction->access_start + 4; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLW\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - (instruction->info.imm >> 8) & 0x3); - break; - case 4: /* LB.bi */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_end = instruction->access_start + 1; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLB.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],($r%" PRIu8 "<<%" PRId32 ")", - address, - opcode, instruction->info.rt, - instruction->info.ra, instruction->info.rb, - (instruction->info.imm >> 8) & 0x3); - break; - case 5: /* LH.bi */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_end = instruction->access_start + 2; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLH.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],($r%" PRIu8 "<<%" PRId32 ")", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - (instruction->info.imm >> 8) & 0x3); - break; - case 6: /* LW.bi */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_end = instruction->access_start + 4; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLW.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],($r%" PRIu8 "<<%" PRId32 ")", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - (instruction->info.imm >> 8) & 0x3); - break; - } - break; - case 1: - switch (sub_opcode & 0x7) { - case 0: /* SB */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra); - nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb); - instruction->access_start = val_ra + - (val_rb << ((instruction->info.imm >> 8) & 0x3)); - instruction->access_end = instruction->access_start + 1; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSB\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]", - address, - opcode, instruction->info.rt, - instruction->info.ra, instruction->info.rb, - (instruction->info.imm >> 8) & 0x3); - break; - case 1: /* SH */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra); - nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb); - instruction->access_start = val_ra + - (val_rb << ((instruction->info.imm >> 8) & 0x3)); - instruction->access_end = instruction->access_start + 2; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSH\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - (instruction->info.imm >> 8) & 0x3); - break; - case 2: /* SW */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra); - nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb); - instruction->access_start = val_ra + - (val_rb << ((instruction->info.imm >> 8) & 0x3)); - instruction->access_end = instruction->access_start + 4; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSW\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]", - address, - opcode, instruction->info.rt, - instruction->info.ra, instruction->info.rb, - (instruction->info.imm >> 8) & 0x3); - break; - case 4: /* SB.bi */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_end = instruction->access_start + 1; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSB.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],($r%" PRIu8 "<<%" PRId32 ")", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - (instruction->info.imm >> 8) & 0x3); - break; - case 5: /* SH.bi */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_end = instruction->access_start + 2; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSH.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],($r%" PRIu8 "<<%" PRId32 ")", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - (instruction->info.imm >> 8) & 0x3); - break; - case 6: /* SW.bi */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_end = instruction->access_start + 4; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSW.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],($r%" PRIu8 "<<%" PRId32 ")", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - (instruction->info.imm >> 8) & 0x3); - break; - } - break; - case 2: - switch (sub_opcode & 0x7) { - case 0: /* LBS */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra); - nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb); - instruction->access_start = val_ra + - (val_rb << ((instruction->info.imm >> 8) & 0x3)); - instruction->access_end = instruction->access_start + 1; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLBS\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]", - address, - opcode, instruction->info.rt, - instruction->info.ra, instruction->info.rb, - (instruction->info.imm >> 8) & 0x3); - break; - case 1: /* LHS */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra); - nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb); - instruction->access_start = val_ra + - (val_rb << ((instruction->info.imm >> 8) & 0x3)); - instruction->access_end = instruction->access_start + 2; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLHS\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - (instruction->info.imm >> 8) & 0x3); - break; - case 3: /* DPREF */ - nds32_parse_type_3(opcode, &(instruction->info.sub_opc), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_MISC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tDPREF\t#%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<#%" PRId32 ")]", - address, - opcode, instruction->info.sub_opc, - instruction->info.ra, instruction->info.rb, - (instruction->info.imm >> 8) & 0x3); - break; - case 4: /* LBS.bi */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_end = instruction->access_start + 1; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLBS.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],($r%" PRIu8 "<<%" PRId32 ")", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - (instruction->info.imm >> 8) & 0x3); - break; - case 5: /* LHS.bi */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_end = instruction->access_start + 2; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLHS.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],($r%" PRIu8 "<<%" PRId32 ")", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - (instruction->info.imm >> 8) & 0x3); - break; - } - break; - case 3: - switch (sub_opcode & 0x7) { - case 0: /* LLW */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra); - nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb); - instruction->access_start = val_ra + - (val_rb << ((instruction->info.imm >> 8) & 0x3)); - instruction->access_end = instruction->access_start + 4; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLLW\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - (instruction->info.imm >> 8) & 0x3); - break; - case 1: /* SCW */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra); - nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb); - instruction->access_start = val_ra + - (val_rb << ((instruction->info.imm >> 8) & 0x3)); - instruction->access_end = instruction->access_start + 4; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSCW\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - (instruction->info.imm >> 8) & 0x3); - break; - } - break; - case 4: - switch (sub_opcode & 0x7) { - case 0: /* LBUP */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra); - nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb); - instruction->access_start = val_ra + - (val_rb << ((instruction->info.imm >> 8) & 0x3)); - instruction->access_end = instruction->access_start + 1; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLBUP\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - (instruction->info.imm >> 8) & 0x3); - break; - case 2: /* LWUP */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra); - nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb); - instruction->access_start = val_ra + - (val_rb << ((instruction->info.imm >> 8) & 0x3)); - instruction->access_end = instruction->access_start + 4; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLWUP\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - (instruction->info.imm >> 8) & 0x3); - break; - } - break; - case 5: - switch (sub_opcode & 0x7) { - case 0: /* SBUP */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra); - nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb); - instruction->access_start = val_ra + - (val_rb << ((instruction->info.imm >> 8) & 0x3)); - instruction->access_end = instruction->access_start + 1; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSBUP\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - (instruction->info.imm >> 8) & 0x3); - break; - case 2: /* SWUP */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra); - nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb); - instruction->access_start = val_ra + - (val_rb << ((instruction->info.imm >> 8) & 0x3)); - instruction->access_end = instruction->access_start + 4; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSWUP\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - (instruction->info.imm >> 8) & 0x3); - break; - } - break; - default: - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", - address, - opcode); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int nds32_calculate_lsmw_access_range(struct nds32 *nds32, - struct nds32_instruction *instruction) -{ - uint8_t ba; - uint8_t id; - uint8_t enable4; - - enable4 = (instruction->info.imm >> 6) & 0xF; - ba = (instruction->info.imm >> 4) & 0x1; - id = (instruction->info.imm >> 3) & 0x1; - - if (ba) { - nds32_get_mapped_reg(nds32, instruction->info.ra, &(instruction->access_start)); - if (id) { /* decrease */ - /* access_end is the (last_element+1), so no need to minus 4 */ - /* instruction->access_end -= 4; */ - instruction->access_end = instruction->access_start; - } else { /* increase */ - instruction->access_start += 4; - } - } else { - nds32_get_mapped_reg(nds32, instruction->info.ra, &(instruction->access_start)); - instruction->access_end = instruction->access_start - 4; - } - - if (id) { /* decrease */ - instruction->access_start = instruction->access_end - - 4 * (instruction->info.rd - instruction->info.rb + 1); - instruction->access_start -= (4 * enable4_bits[enable4]); - } else { /* increase */ - instruction->access_end = instruction->access_start + - 4 * (instruction->info.rd - instruction->info.rb + 1); - instruction->access_end += (4 * enable4_bits[enable4]); - } - - return ERROR_OK; -} - -static int nds32_parse_lsmw(struct nds32 *nds32, uint32_t opcode, uint32_t address, - struct nds32_instruction *instruction) -{ - if (opcode & 0x20) { /* SMW, SMWA, SMWZB */ - switch (opcode & 0x3) { - /* TODO */ - case 0: /* SMW */ - /* use rd as re */ - nds32_parse_type_3(opcode, &(instruction->info.rb), - &(instruction->info.ra), - &(instruction->info.rd), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_calculate_lsmw_access_range(nds32, instruction); - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSMW\t$r%" PRIu8 ",[$r%" PRIu8 "],$r%" PRIu8 ",%" PRId32, - address, - opcode, instruction->info.rb, instruction->info.ra, - instruction->info.rd, - (instruction->info.imm >> 6) & 0xF); - break; - case 1: /* SMWA */ - nds32_parse_type_3(opcode, &(instruction->info.rb), - &(instruction->info.ra), - &(instruction->info.rd), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_calculate_lsmw_access_range(nds32, instruction); - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSMWA\t$r%" PRIu8 ",[$r%" PRIu8 "],$r%" PRIu8 ",%" PRId32, - address, - opcode, instruction->info.rb, instruction->info.ra, - instruction->info.rd, - (instruction->info.imm >> 6) & 0xF); - break; - case 2: /* SMWZB */ - nds32_parse_type_3(opcode, &(instruction->info.rb), - &(instruction->info.ra), - &(instruction->info.rd), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - /* TODO: calculate access_start/access_end */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSMWZB\t$r%" PRIu8 ",[$r%" PRIu8 "],$r%" PRIu8 ",%" PRId32, - address, - opcode, instruction->info.rb, instruction->info.ra, - instruction->info.rd, - (instruction->info.imm >> 6) & 0xF); - break; - default: - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", - address, - opcode); - return ERROR_FAIL; - } - } else { /* LMW, LMWA, LMWZB */ - switch (opcode & 0x3) { - case 0: /* LMW */ - nds32_parse_type_3(opcode, &(instruction->info.rb), - &(instruction->info.ra), - &(instruction->info.rd), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_calculate_lsmw_access_range(nds32, instruction); - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLMW\t$r%" PRIu8 ",[$r%" PRIu8 "],$r%" PRIu8 ",%" PRId32, - address, - opcode, instruction->info.rb, instruction->info.ra, - instruction->info.rd, - (instruction->info.imm >> 6) & 0xF); - break; - case 1: /* LMWA */ - nds32_parse_type_3(opcode, &(instruction->info.rb), - &(instruction->info.ra), - &(instruction->info.rd), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_calculate_lsmw_access_range(nds32, instruction); - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLMWA\t$r%" PRIu8 ",[$r%" PRIu8 "],$r%" PRIu8 ",%" PRId32, - address, - opcode, instruction->info.rb, instruction->info.ra, - instruction->info.rd, - (instruction->info.imm >> 6) & 0xF); - break; - case 2: /* LMWZB */ - nds32_parse_type_3(opcode, &(instruction->info.rb), - &(instruction->info.ra), - &(instruction->info.rd), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - /* TODO: calculate access_start/access_end */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLMWZB\t$r%" PRIu8 ",[$r%" PRIu8 "],$r%" PRIu8 ",%" PRId32, - address, - opcode, instruction->info.rb, instruction->info.ra, - instruction->info.rd, - (instruction->info.imm >> 6) & 0xF); - break; - default: - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", - address, - opcode); - return ERROR_FAIL; - } - } - - return ERROR_OK; -} - -static int nds32_parse_hwgp(struct nds32 *nds32, uint32_t opcode, uint32_t address, - struct nds32_instruction *instruction) -{ - switch ((opcode >> 18) & 0x3) { - case 0: /* LHI.gp */ - nds32_parse_type_1(opcode, &(instruction->info.rt), &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 14) >> 13; /* sign-extend */ - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, R29, &(instruction->access_start)); - instruction->access_start += instruction->info.imm; - instruction->access_end = instruction->access_start + 2; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLHI.gp\t$r%" PRIu8 ",[#%" PRId32"]", - address, - opcode, instruction->info.rt, instruction->info.imm); - break; - case 1: /* LHSI.gp */ - nds32_parse_type_1(opcode, &(instruction->info.rt), &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 14) >> 13; /* sign-extend */ - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, R29, &(instruction->access_start)); - instruction->access_start += instruction->info.imm; - instruction->access_end = instruction->access_start + 2; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLHSI.gp\t$r%" PRIu8 ",[#%" PRId32 "]", - address, - opcode, instruction->info.rt, instruction->info.imm); - break; - case 2: /* SHI.gp */ - nds32_parse_type_1(opcode, &(instruction->info.rt), &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 14) >> 13; /* sign-extend */ - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, R29, &(instruction->access_start)); - instruction->access_start += instruction->info.imm; - instruction->access_end = instruction->access_start + 2; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSHI.gp\t$r%" PRIu8 ",[#%" PRId32 "]", - address, - opcode, instruction->info.rt, instruction->info.imm); - break; - case 3: - instruction->type = NDS32_INSN_LOAD_STORE; - if ((opcode >> 17) & 0x1) { /* SWI.gp */ - nds32_parse_type_1(opcode, &(instruction->info.rt), - &(instruction->info.imm)); - /* sign-extend */ - instruction->info.imm = (instruction->info.imm << 15) >> 13; - nds32_get_mapped_reg(nds32, R29, &(instruction->access_start)); - instruction->access_start += instruction->info.imm; - instruction->access_end = instruction->access_start + 4; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSWI.gp\t$r%" PRIu8 ",[#%" PRId32 "]", - address, - opcode, instruction->info.rt, instruction->info.imm); - } else { /* LWI.gp */ - nds32_parse_type_1(opcode, &(instruction->info.rt), - &(instruction->info.imm)); - /* sign-extend */ - instruction->info.imm = (instruction->info.imm << 15) >> 13; - nds32_get_mapped_reg(nds32, R29, &(instruction->access_start)); - instruction->access_start += instruction->info.imm; - instruction->access_end = instruction->access_start + 4; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLWI.gp\t$r%" PRIu8 ",[#%" PRId32 "]", - address, - opcode, instruction->info.rt, instruction->info.imm); - } - - break; - default: - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", - address, - opcode); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int nds32_parse_sbgp(struct nds32 *nds32, uint32_t opcode, uint32_t address, - struct nds32_instruction *instruction) -{ - switch ((opcode >> 19) & 0x1) { - case 0: /* SBI.gp */ - nds32_parse_type_1(opcode, &(instruction->info.rt), &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 13) >> 13; /* sign-extend */ - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, R29, &(instruction->access_start)); - instruction->access_start += instruction->info.imm; - instruction->access_end = instruction->access_start + 1; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSBI.gp\t$r%" PRIu8 ",[#%" PRId32 "]", - address, - opcode, instruction->info.rt, instruction->info.imm); - break; - case 1: /* ADDI.gp */ - nds32_parse_type_1(opcode, &(instruction->info.rt), &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 13) >> 13; /* sign-extend */ - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tADDI.gp\t$r%" PRIu8 ",#%" PRId32 "", - address, - opcode, instruction->info.rt, instruction->info.imm); - break; - default: - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", - address, - opcode); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int nds32_parse_group_3_insn(struct nds32 *nds32, uint32_t opcode, uint32_t address, - struct nds32_instruction *instruction) -{ - uint8_t opc_6; - - opc_6 = instruction->info.opc_6; - - switch (opc_6 & 0x7) { - case 4: /* MEM */ - nds32_parse_mem(nds32, opcode, address, instruction); - break; - case 5: /* LSMW */ - nds32_parse_lsmw(nds32, opcode, address, instruction); - break; - case 6: /* HWGP */ - nds32_parse_hwgp(nds32, opcode, address, instruction); - break; - case 7: /* SBGP */ - nds32_parse_sbgp(nds32, opcode, address, instruction); - break; - default: - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", - address, - opcode); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int nds32_parse_alu_1(uint32_t opcode, uint32_t address, - struct nds32_instruction *instruction) -{ - switch (opcode & 0x1F) { - case 0: /* ADD */ - nds32_parse_type_3(opcode, &(instruction->info.rt), &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - instruction->info.imm = (instruction->info.imm >> 5) & 0x1F; - if (instruction->info.imm) - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tADD_SLLI\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 ",%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - instruction->info.imm); - else - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tADD\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - break; - case 1: /* SUB */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - instruction->info.imm = (instruction->info.imm >> 5) & 0x1F; - if (instruction->info.imm) - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSUB_SLLI\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 ",%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - instruction->info.imm); - else - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSUB\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 "", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - break; - case 2: /* AND */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - instruction->info.imm = (instruction->info.imm >> 5) & 0x1F; - if (instruction->info.imm) - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tAND_SLLI\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 ",%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - instruction->info.imm); - else - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tAND\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 "", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - break; - case 3: /* XOR */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - instruction->info.imm = (instruction->info.imm >> 5) & 0x1F; - if (instruction->info.imm) - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tXOR_SLLI\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 ",%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - instruction->info.imm); - else - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tXOR\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - break; - case 4: /* OR */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - instruction->info.imm = (instruction->info.imm >> 5) & 0x1F; - if (instruction->info.imm) - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tOR_SLLI\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 ",%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - instruction->info.imm); - else - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tOR\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - break; - case 5: /* NOR */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tNOR\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - break; - case 6: /* SLT */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSLT\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - break; - case 7: /* SLTS */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSLTS\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - break; - case 8: { /* SLLI */ - uint8_t imm; - int32_t sub_op; - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &imm, &sub_op); - instruction->info.imm = imm; - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSLLI\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - } - break; - case 9: { /* SRLI */ - uint8_t imm; - int32_t sub_op; - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &imm, &sub_op); - instruction->info.imm = imm; - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSRLI\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - } - break; - case 10: { /* SRAI */ - uint8_t imm; - int32_t sub_op; - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &imm, &sub_op); - instruction->info.imm = imm; - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSRAI\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - } - break; - case 11: { /* ROTRI */ - uint8_t imm; - int32_t sub_op; - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &imm, &sub_op); - instruction->info.imm = imm; - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tROTRI\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - } - break; - case 12: { /* SLL */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSLL\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - } - break; - case 13: { /* SRL */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSRL\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - } - break; - case 14: { /* SRA */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSRA\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - } - break; - case 15: { /* ROTR */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tROTR\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - } - break; - case 16: { /* SEB */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSEB\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra); - } - break; - case 17: { /* SEH */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSEH\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra); - } - break; - case 18: /* BITC */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tBITC\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - break; - case 19: { /* ZEH */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tZEH\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra); - } - break; - case 20: { /* WSBH */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tWSBH\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra); - } - break; - case 21: /* OR_SRLI */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - instruction->info.imm = (instruction->info.imm >> 5) & 0x1F; - if (instruction->info.imm) - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tOR_SRLI\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 ",%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - instruction->info.imm); - else - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tOR\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - break; - case 22: { /* DIVSR */ - nds32_parse_type_4(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.rd), - &(instruction->info.sub_opc)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tDIVSR\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - instruction->info.rd); - } - break; - case 23: { /* DIVR */ - nds32_parse_type_4(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.rd), - &(instruction->info.sub_opc)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tDIVR\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - instruction->info.rd); - } - break; - case 24: { /* SVA */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSVA\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - } - break; - case 25: { /* SVS */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSVS\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - } - break; - case 26: { /* CMOVZ */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_MISC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tCMOVZ\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - } - break; - case 27: { /* CMOVN */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_MISC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tCMOVN\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - } - break; - case 28: /* ADD_SRLI */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - instruction->info.imm = (instruction->info.imm >> 5) & 0x1F; - if (instruction->info.imm) - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tADD_SRLI\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 ",%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - instruction->info.imm); - else - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tADD\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - break; - case 29: /* SUB_SRLI */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - instruction->info.imm = (instruction->info.imm >> 5) & 0x1F; - if (instruction->info.imm) - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSUB_SRLI\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 ",%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - instruction->info.imm); - else - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSUB\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - break; - case 30: /* AND_SRLI */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - instruction->info.imm = (instruction->info.imm >> 5) & 0x1F; - if (instruction->info.imm) - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tAND_SRLI\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 ",%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - instruction->info.imm); - else - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tAND\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - break; - case 31: /* XOR_SRLI */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - instruction->info.imm = (instruction->info.imm >> 5) & 0x1F; - if (instruction->info.imm) - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tXOR_SRLI\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 ",%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - instruction->info.imm); - else - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tXOR\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - break; - default: - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", - address, - opcode); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int nds32_parse_alu_2(uint32_t opcode, uint32_t address, - struct nds32_instruction *instruction) -{ - switch (opcode & 0x3F) { - case 0: /* MAX */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tMAX\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - break; - case 1: /* MIN */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tMIN\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - break; - case 2: /* AVE */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tAVE\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - break; - case 3: /* ABS */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tAVE\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra); - break; - case 4: { /* CLIPS */ - uint8_t imm; - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &imm, &(instruction->info.imm)); - instruction->info.imm = imm; - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tCLIPS\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - } - break; - case 5: { /* CLIP */ - uint8_t imm; - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &imm, &(instruction->info.imm)); - instruction->info.imm = imm; - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tCLIP\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - } - break; - case 6: /* CLO */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tCLO\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra); - break; - case 7: /* CLZ */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tCLZ\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra); - break; - case 8: { /* BSET */ - uint8_t imm; - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &imm, &(instruction->info.imm)); - instruction->info.imm = imm; - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tBSET\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - } - break; - case 9: { /* BCLR */ - uint8_t imm; - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &imm, &(instruction->info.imm)); - instruction->info.imm = imm; - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tBCLR\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - } - break; - case 10: { /* BTGL */ - uint8_t imm; - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &imm, &(instruction->info.imm)); - instruction->info.imm = imm; - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tBTGL\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - } - break; - case 11: { /* BTST */ - uint8_t imm; - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &imm, &(instruction->info.imm)); - instruction->info.imm = imm; - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tBTST\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - } - break; - case 12: /* BSE */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tBSE\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - break; - case 13: /* BSP */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tBSP\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - break; - case 14: /* FFB */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tFFB\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - break; - case 15: /* FFMISM */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tFFMISM\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - break; - case 23: /* FFZMISM */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tFFZMISM\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - break; - case 32: /* MFUSR */ - nds32_parse_type_1(opcode, &(instruction->info.rt), - &(instruction->info.imm)); - instruction->type = NDS32_INSN_RESOURCE_ACCESS; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tMFUSR\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, - (instruction->info.imm >> 10) & 0x3FF); - break; - case 33: /* MTUSR */ - nds32_parse_type_1(opcode, &(instruction->info.rt), - &(instruction->info.imm)); - instruction->type = NDS32_INSN_RESOURCE_ACCESS; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tMTUSR\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, - (instruction->info.imm >> 10) & 0x3FF); - break; - case 36: /* MUL */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tMUL\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - break; - case 40: { /* MULTS64 */ - uint8_t dt_val; - nds32_parse_type_3(opcode, &dt_val, - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tMULTS64\t$D%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, (uint8_t)((dt_val >> 1) & 0x1), instruction->info.ra, - instruction->info.rb); - } - break; - case 41: { /* MULT64 */ - uint8_t dt_val; - nds32_parse_type_3(opcode, &dt_val, - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tMULT64\t$D%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, (uint8_t)((dt_val >> 1) & 0x1), instruction->info.ra, - instruction->info.rb); - } - break; - case 42: { /* MADDS64 */ - uint8_t dt_val; - nds32_parse_type_3(opcode, &dt_val, &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tMADDS64\t$D%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, (uint8_t)((dt_val >> 1) & 0x1), instruction->info.ra, - instruction->info.rb); - } - break; - case 43: { /* MADD64 */ - uint8_t dt_val; - nds32_parse_type_3(opcode, &dt_val, &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tMADD64\t$D%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, (uint8_t)((dt_val >> 1) & 0x1), instruction->info.ra, - instruction->info.rb); - } - break; - case 44: { /* MSUBS64 */ - uint8_t dt_val; - nds32_parse_type_3(opcode, &dt_val, &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tMSUBS64\t$D%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, (uint8_t)((dt_val >> 1) & 0x1), instruction->info.ra, - instruction->info.rb); - } - break; - case 45: { /* MSUB64 */ - uint8_t dt_val; - nds32_parse_type_3(opcode, &dt_val, &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tMSUB64\t$D%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, (uint8_t)((dt_val >> 1) & 0x1), instruction->info.ra, - instruction->info.rb); - } - break; - case 46: { /* DIVS */ - uint8_t dt_val; - nds32_parse_type_3(opcode, &dt_val, &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tDIVS\t$D%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, (uint8_t)((dt_val >> 1) & 0x1), instruction->info.ra, - instruction->info.rb); - } - break; - case 47: { /* DIV */ - uint8_t dt_val; - nds32_parse_type_3(opcode, &dt_val, &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tDIV\t$D%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, (uint8_t)((dt_val >> 1) & 0x1), instruction->info.ra, - instruction->info.rb); - } - break; - case 49: { /* MULT32 */ - uint8_t dt_val; - nds32_parse_type_3(opcode, &dt_val, &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tMULT32\t$D%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, (uint8_t)((dt_val >> 1) & 0x1), instruction->info.ra, - instruction->info.rb); - } - break; - case 51: { /* MADD32 */ - uint8_t dt_val; - nds32_parse_type_3(opcode, &dt_val, &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tMADD32\t$D%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, (uint8_t)((dt_val >> 1) & 0x1), instruction->info.ra, - instruction->info.rb); - } - break; - case 53: { /* MSUB32 */ - uint8_t dt_val; - nds32_parse_type_3(opcode, &dt_val, &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tMSUB32\t$D%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, (uint8_t)((dt_val >> 1) & 0x1), instruction->info.ra, - instruction->info.rb); - } - break; - default: - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", - address, - opcode); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int nds32_parse_group_4_insn(struct nds32 *nds32, uint32_t opcode, - uint32_t address, struct nds32_instruction *instruction) -{ - uint8_t opc_6; - - opc_6 = instruction->info.opc_6; - - switch (opc_6 & 0x7) { - case 0: /* ALU_1 */ - nds32_parse_alu_1(opcode, address, instruction); - break; - case 1: /* ALU_2 */ - nds32_parse_alu_2(opcode, address, instruction); - break; - case 2: /* MOVI */ - nds32_parse_type_1(opcode, &(instruction->info.rt), - &(instruction->info.imm)); - /* sign-extend */ - instruction->info.imm = (instruction->info.imm << 12) >> 12; - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tMOVI\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.imm); - break; - case 3: /* SETHI */ - nds32_parse_type_1(opcode, &(instruction->info.rt), - &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSETHI\t$r%" PRIu8 ",0x%8.8" PRIx32, - address, - opcode, instruction->info.rt, instruction->info.imm); - break; - case 4: /* JI */ - nds32_parse_type_0(opcode, &(instruction->info.imm)); - /* sign-extend */ - instruction->info.imm = (instruction->info.imm << 8) >> 8; - instruction->type = NDS32_INSN_JUMP_BRANCH; - if ((instruction->info.imm >> 24) & 0x1) { /* JAL */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tJAL\t#%" PRId32, - address, - opcode, instruction->info.imm); - } else { /* J */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tJ\t#%" PRId32, - address, - opcode, instruction->info.imm); - } - break; - case 5: { /* JREG */ - int32_t imm; - nds32_parse_type_0(opcode, &imm); - instruction->info.rb = (imm >> 10) & 0x1F; - instruction->type = NDS32_INSN_JUMP_BRANCH; - switch (imm & 0x1F) { - /* TODO */ - case 0: /* JR */ - if (imm & 0x20) { /* RET */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tRET\t$r%" PRIu8, - address, - opcode, instruction->info.rb); - } else { /* JR */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tJR\t$r%" PRIu8, - address, - opcode, instruction->info.rb); - } - break; - case 1: /* JRAL */ - instruction->info.rt = (imm >> 20) & 0x1F; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tJRAL\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.rb); - break; - case 2: /* JRNEZ */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tJRNEZ\t$r%" PRIu8, - address, - opcode, instruction->info.rb); - break; - case 3: /* JRALNEZ */ - instruction->info.rt = (imm >> 20) & 0x1F; - if (instruction->info.rt == R30) - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tJRALNEZ\t$r%" PRIu8, - address, - opcode, instruction->info.rb); - else - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tJRALNEZ\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, - instruction->info.rt, - instruction->info.rb); - break; - } - } - break; - case 6: { /* BR1 */ - int32_t imm; - - nds32_parse_type_0(opcode, &imm); - instruction->type = NDS32_INSN_JUMP_BRANCH; - if ((imm >> 14) & 0x1) { /* BNE */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), &(instruction->info.imm)); - /* sign-extend */ - instruction->info.imm = (instruction->info.imm << 18) >> 18; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tBNE\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - } else { /* BEQ */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), &(instruction->info.imm)); - /* sign-extend */ - instruction->info.imm = (instruction->info.imm << 18) >> 18; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tBEQ\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, - instruction->info.ra, - instruction->info.imm); - } - } - break; - case 7: { /* BR2 */ - int32_t imm; - - nds32_parse_type_0(opcode, &imm); - instruction->type = NDS32_INSN_JUMP_BRANCH; - switch ((imm >> 16) & 0xF) { - case 2: /* BEQZ */ - nds32_parse_type_1(opcode, &(instruction->info.rt), - &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 16) >> 16; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tBEQZ\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.imm); - break; - case 3: /* BNEZ */ - nds32_parse_type_1(opcode, &(instruction->info.rt), - &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 16) >> 16; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tBNEZ\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.imm); - break; - case 4: /* BGEZ */ - nds32_parse_type_1(opcode, &(instruction->info.rt), - &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 16) >> 16; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tBGEZ\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.imm); - break; - case 5: /* BLTZ */ - nds32_parse_type_1(opcode, &(instruction->info.rt), - &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 16) >> 16; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tBLTZ\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.imm); - break; - case 6: /* BGTZ */ - nds32_parse_type_1(opcode, &(instruction->info.rt), - &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 16) >> 16; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tBGTZ\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.imm); - break; - case 7: /* BLEZ */ - nds32_parse_type_1(opcode, &(instruction->info.rt), - &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 16) >> 16; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tBLEZ\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.imm); - break; - case 12: /* BGEZAL */ - nds32_parse_type_1(opcode, &(instruction->info.rt), - &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 16) >> 16; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tBGEZAL\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.imm); - break; - case 13: /* BLTZAL */ - nds32_parse_type_1(opcode, &(instruction->info.rt), - &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 16) >> 16; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tBLTZAL\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.imm); - break; - } - } - break; - default: - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", - address, - opcode); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int nds32_parse_group_5_insn(struct nds32 *nds32, uint32_t opcode, - uint32_t address, struct nds32_instruction *instruction) -{ - uint8_t opc_6; - - opc_6 = instruction->info.opc_6; - - switch (opc_6 & 0x7) { - case 0: /* ADDI */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 17) >> 17; /* sign-extend */ - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tADDI\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - case 1: /* SUBRI */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 17) >> 17; /* sign-extend */ - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSUBRI\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - case 2: /* ANDI */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tANDI\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - case 3: /* XORI */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tXORI\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - case 4: /* ORI */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tORI\t$r%" PRIu8 ",$r%" PRIu8 ",0x%8.8" PRIx32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - case 6: /* SLTI */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 17) >> 17; /* sign-extend */ - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSLTI\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - case 7: /* SLTSI */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 17) >> 17; /* sign-extend */ - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSLTSI\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - default: - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", - address, - opcode); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int nds32_parse_group_6_insn(struct nds32 *nds32, uint32_t opcode, - uint32_t address, struct nds32_instruction *instruction) -{ - uint8_t opc_6; - - opc_6 = instruction->info.opc_6; - - switch (opc_6 & 0x7) { - case 2: { /* MISC */ - int32_t imm; - uint8_t sub_opc; - - nds32_parse_type_0(opcode, &imm); - - sub_opc = imm & 0x1F; - switch (sub_opc) { - case 0: /* STANDBY */ - instruction->type = NDS32_INSN_MISC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSTANDBY\t#%" PRIu32, - address, - opcode, (opcode >> 5) & 0x3); - break; - case 1: /* CCTL */ - /* TODO */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), &(instruction->info.imm)); - instruction->type = NDS32_INSN_MISC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tCCTL", - address, - opcode); - break; - case 2: /* MFSR */ - nds32_parse_type_1(opcode, &(instruction->info.rt), - &(instruction->info.imm)); - instruction->type = NDS32_INSN_RESOURCE_ACCESS; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tMFSR\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, - (instruction->info.imm >> 10) & 0x3FF); - break; - case 3: /* MTSR */ - nds32_parse_type_1(opcode, &(instruction->info.ra), - &(instruction->info.imm)); - instruction->type = NDS32_INSN_RESOURCE_ACCESS; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tMTSR\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.ra, - (instruction->info.imm >> 10) & 0x3FF); - break; - case 4: /* IRET */ - instruction->type = NDS32_INSN_MISC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tIRET", - address, - opcode); - break; - case 5: /* TRAP */ - instruction->type = NDS32_INSN_MISC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tTRAP\t#%" PRId32, - address, - opcode, (imm >> 5) & 0x7FFF); - break; - case 6: /* TEQZ */ - nds32_parse_type_1(opcode, &(instruction->info.ra), - &(instruction->info.imm)); - instruction->type = NDS32_INSN_MISC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tTEQZ\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.ra, - (instruction->info.imm >> 5) & 0x7FFF); - break; - case 7: /* TNEZ */ - nds32_parse_type_1(opcode, &(instruction->info.ra), - &(instruction->info.imm)); - instruction->type = NDS32_INSN_MISC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tTNEZ\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.ra, - (instruction->info.imm >> 5) & 0x7FFF); - break; - case 8: /* DSB */ - instruction->type = NDS32_INSN_MISC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tDSB", - address, - opcode); - break; - case 9: /* ISB */ - instruction->type = NDS32_INSN_MISC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tISB", - address, - opcode); - break; - case 10: /* BREAK */ - instruction->type = NDS32_INSN_MISC; - instruction->info.sub_opc = imm & 0x1F; - instruction->info.imm = (imm >> 5) & 0x7FFF; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tBREAK\t#%" PRId32, - address, - opcode, instruction->info.imm); - break; - case 11: /* SYSCALL */ - instruction->type = NDS32_INSN_MISC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSYSCALL\t#%" PRId32, - address, - opcode, (imm >> 5) & 0x7FFF); - break; - case 12: /* MSYNC */ - instruction->type = NDS32_INSN_MISC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tMSYNC\t#%" PRId32, - address, - opcode, (imm >> 5) & 0x7); - break; - case 13: /* ISYNC */ - nds32_parse_type_1(opcode, &(instruction->info.ra), - &(instruction->info.imm)); - instruction->type = NDS32_INSN_MISC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tISYNC\t$r%" PRIu8, - address, - opcode, instruction->info.ra); - break; - case 14: /* TLBOP */ - /* TODO */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), &(instruction->info.imm)); - instruction->type = NDS32_INSN_RESOURCE_ACCESS; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tTLBOP", - address, - opcode); - break; - } - - break; - } - default: - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", - address, - opcode); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static uint32_t field_mask[9] = { - 0x0, - 0x1, - 0x3, - 0x7, - 0xF, - 0x1F, - 0x3F, - 0x7F, - 0xFF, -}; - -static uint8_t nds32_extract_field_8u(uint16_t opcode, uint32_t start, uint32_t length) -{ - if (length > 0 && length < 9) - return (opcode >> start) & field_mask[length]; - - return 0; -} - -static int nds32_parse_group_0_insn_16(struct nds32 *nds32, uint16_t opcode, - uint32_t address, struct nds32_instruction *instruction) -{ - switch ((opcode >> 10) & 0x7) { - case 0: /* MOV55 */ - instruction->info.rt = nds32_extract_field_8u(opcode, 5, 5); - instruction->info.ra = nds32_extract_field_8u(opcode, 0, 5); - instruction->type = NDS32_INSN_MISC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tMOV55\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra); - break; - case 1: /* MOVI55 */ - instruction->info.rt = nds32_extract_field_8u(opcode, 5, 5); - instruction->info.imm = nds32_extract_field_8u(opcode, 0, 5); - instruction->info.imm = (instruction->info.imm << 27) >> 27; - instruction->type = NDS32_INSN_MISC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tMOVI55\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.imm); - break; - case 2: /* ADD45, SUB45 */ - instruction->info.rt = nds32_extract_field_8u(opcode, 5, 4); - instruction->info.rb = nds32_extract_field_8u(opcode, 0, 5); - instruction->type = NDS32_INSN_DATA_PROC; - if (nds32_extract_field_8u(opcode, 9, 1) == 0) { /* ADD45 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tADD45\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.rb); - } else { /* SUB45 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tSUB45\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.rb); - } - - break; - case 3: /* ADDI45, SUBI45 */ - instruction->info.rt = nds32_extract_field_8u(opcode, 5, 4); - instruction->info.imm = nds32_extract_field_8u(opcode, 0, 5); - instruction->type = NDS32_INSN_DATA_PROC; - if (nds32_extract_field_8u(opcode, 9, 1) == 0) { /* ADDI45 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tADDI45\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.imm); - } else { /* SUBI45 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tSUBI45\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.imm); - } - break; - case 4: /* SRAI45, SRLI45 */ - instruction->info.rt = nds32_extract_field_8u(opcode, 5, 4); - instruction->info.imm = nds32_extract_field_8u(opcode, 0, 5); - instruction->type = NDS32_INSN_DATA_PROC; - if (nds32_extract_field_8u(opcode, 9, 1) == 0) { /* SRAI45 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tSRAI45\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.imm); - } else { /* SRLI45 */ - if ((instruction->info.rt == 0) && (instruction->info.imm == 0)) { - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 "\t\tNOP", - address, - opcode); - } else { - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tSRLI45\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.imm); - } - } - break; - case 5: - instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3); - instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3); - instruction->type = NDS32_INSN_DATA_PROC; - if (nds32_extract_field_8u(opcode, 9, 1) == 0) { /* SLLI333 */ - instruction->info.imm = nds32_extract_field_8u(opcode, 0, 3); - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tSLLI333\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - } else { - instruction->info.sub_opc = nds32_extract_field_8u(opcode, 0, 3); - switch (instruction->info.sub_opc) { - case 0: /* ZEB33 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tZEB33\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra); - break; - case 1: /* ZEH33 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tZEH33\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra); - break; - case 2: /* SEB33 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tSEB33\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra); - break; - case 3: /* SEH33 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tSEH33\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra); - break; - case 4: /* XLSB33 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tXLSB33\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra); - break; - case 5: /* XLLB33 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tXLLB33\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra); - break; - case 6: /* BMSKI33 */ - instruction->info.ra = 0; - instruction->info.imm = nds32_extract_field_8u(opcode, 3, 3); - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tBMSKI33\t$r%" PRIu8 ",$r%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.imm); - break; - case 7: /* FEXTI33 */ - instruction->info.ra = 0; - instruction->info.imm = nds32_extract_field_8u(opcode, 3, 3); - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tFEXTI33\t$r%" PRIu8 ",$r%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.imm); - break; - default: - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx16 - "\tUNDEFINED INSTRUCTION", - address, - opcode); - return ERROR_FAIL; - } - } - break; - case 6: /* ADD333, SUB333 */ - instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3); - instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3); - instruction->info.rb = nds32_extract_field_8u(opcode, 0, 3); - instruction->type = NDS32_INSN_DATA_PROC; - if (nds32_extract_field_8u(opcode, 9, 1) == 0) { /* ADD333 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tADD333\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - } else { /* SUB333 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tSUB333\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - } - break; - case 7: /* ADDI333, SUBI333 */ - instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3); - instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3); - instruction->info.imm = nds32_extract_field_8u(opcode, 0, 3); - instruction->type = NDS32_INSN_DATA_PROC; - if (nds32_extract_field_8u(opcode, 9, 1) == 0) { /* ADDI333 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tADDI333\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - } else { /* SUBI333 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tSUBI333\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - } - break; - default: - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx16 "\tUNDEFINED INSTRUCTION", - address, - opcode); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int nds32_parse_group_1_insn_16(struct nds32 *nds32, uint16_t opcode, - uint32_t address, struct nds32_instruction *instruction) -{ - switch ((opcode >> 9) & 0xF) { - case 0: /* LWI333 */ - instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3); - instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3); - instruction->info.imm = nds32_extract_field_8u(opcode, 0, 3) << 2; - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_start += instruction->info.imm; - instruction->access_end = instruction->access_start + 4; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tLWI333\t$r%" PRIu8 ",[$r%" PRIu8 "+(#%" PRId32 ")]", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - case 1: /* LWI333.BI */ - instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3); - instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3); - instruction->info.imm = nds32_extract_field_8u(opcode, 0, 3); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_end = instruction->access_start + 4; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tLWI333.BI\t$r%" PRIu8 ",[$r%" PRIu8 "],#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm << 2); - break; - case 2: /* LHI333 */ - instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3); - instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3); - instruction->info.imm = nds32_extract_field_8u(opcode, 0, 3) << 1; - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_start += instruction->info.imm; - instruction->access_end = instruction->access_start + 2; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tLHI333\t$r%" PRIu8 ",[$r%" PRIu8 "+(#%" PRId32 ")]", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - case 3: /* LBI333 */ - instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3); - instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3); - instruction->info.imm = nds32_extract_field_8u(opcode, 0, 3); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_start += instruction->info.imm; - instruction->access_end = instruction->access_start + 1; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tLBI333\t$r%" PRIu8 ",[$r%" PRIu8 "+(#%" PRId32 ")]", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - case 4: /* SWI333 */ - instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3); - instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3); - instruction->info.imm = nds32_extract_field_8u(opcode, 0, 3) << 2; - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_start += instruction->info.imm; - instruction->access_end = instruction->access_start + 4; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tSWI333\t$r%" PRIu8 ",[$r%" PRIu8 "+(#%" PRId32 ")]", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - case 5: /* SWI333.BI */ - instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3); - instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3); - instruction->info.imm = nds32_extract_field_8u(opcode, 0, 3) << 2; - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_end = instruction->access_start + 4; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tSWI333.BI\t$r%" PRIu8 ",[$r%" PRIu8 "],#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - case 6: /* SHI333 */ - instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3); - instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3); - instruction->info.imm = nds32_extract_field_8u(opcode, 0, 3) << 1; - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_start += instruction->info.imm; - instruction->access_end = instruction->access_start + 2; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tSHI333\t$r%" PRIu8 ",[$r%" PRIu8 "+(#%" PRId32 ")]", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - case 7: /* SBI333 */ - instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3); - instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3); - instruction->info.imm = nds32_extract_field_8u(opcode, 0, 3); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_start += instruction->info.imm; - instruction->access_end = instruction->access_start + 1; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tSHI333\t$r%" PRIu8 ",[$r%" PRIu8 "+(#%" PRId32 ")]", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - case 8: /* ADDRI36.SP */ - instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3); - instruction->info.imm = nds32_extract_field_8u(opcode, 0, 6) << 2; - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tADDRI36.SP\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.imm); - break; - case 9: /* LWI45.FE */ - instruction->info.rt = nds32_extract_field_8u(opcode, 5, 4); - instruction->info.imm = nds32_extract_field_8u(opcode, 0, 5); - instruction->info.imm -= 32; - instruction->info.imm <<= 2; - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, R8, &(instruction->access_start)); - instruction->access_start += instruction->info.imm; - instruction->access_end = instruction->access_start + 4; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tLWI45.FE\t$r%" PRIu8 ",[#%" PRId32 "]", - address, - opcode, instruction->info.rt, instruction->info.imm); - break; - case 10: /* LWI450 */ - instruction->info.rt = nds32_extract_field_8u(opcode, 5, 4); - instruction->info.ra = nds32_extract_field_8u(opcode, 0, 5); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_end = instruction->access_start + 4; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tLWI450\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra); - break; - case 11: /* SWI450 */ - instruction->info.rt = nds32_extract_field_8u(opcode, 5, 4); - instruction->info.ra = nds32_extract_field_8u(opcode, 0, 5); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_end = instruction->access_start + 4; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tSWI450\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra); - break; - case 12: - case 13: - case 14: - case 15: /* LWI37, SWI37 */ - instruction->info.rt = nds32_extract_field_8u(opcode, 8, 3); - instruction->info.imm = nds32_extract_field_8u(opcode, 0, 7) << 2; - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, R28, &(instruction->access_start)); - instruction->access_start += instruction->info.imm; - instruction->access_end = instruction->access_start + 4; - if (nds32_extract_field_8u(opcode, 7, 1) == 0) { /* LWI37 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tLWI37\t$r%" PRIu8 ",[fp+#%" PRId32 "]", - address, - opcode, instruction->info.rt, instruction->info.imm); - } else { /* SWI37 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tSWI37\t$r%" PRIu8 ",[fp+#%" PRId32 "]", - address, - opcode, instruction->info.rt, instruction->info.imm); - } - break; - default: /* ERROR */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx16 "\tUNDEFINED INSTRUCTION", - address, - opcode); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int nds32_parse_group_2_insn_16(struct nds32 *nds32, uint16_t opcode, - uint32_t address, struct nds32_instruction *instruction) -{ - switch ((opcode >> 11) & 0x3) { - case 0: /* BEQZ38 */ - instruction->info.rt = nds32_extract_field_8u(opcode, 8, 3); - instruction->info.imm = nds32_extract_field_8u(opcode, 0, 8); - instruction->info.imm = (instruction->info.imm << 24) >> 24; - instruction->type = NDS32_INSN_JUMP_BRANCH; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tBEQZ38\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.imm); - break; - case 1: /* BNEZ38 */ - instruction->info.rt = nds32_extract_field_8u(opcode, 8, 3); - instruction->info.imm = nds32_extract_field_8u(opcode, 0, 8); - instruction->info.imm = (instruction->info.imm << 24) >> 24; - instruction->type = NDS32_INSN_JUMP_BRANCH; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tBNEZ38\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.imm); - break; - case 2: /* BEQS38,J8 */ - instruction->info.rt = nds32_extract_field_8u(opcode, 8, 3); - instruction->info.imm = nds32_extract_field_8u(opcode, 0, 8); - instruction->info.imm = (instruction->info.imm << 24) >> 24; - instruction->type = NDS32_INSN_JUMP_BRANCH; - if (instruction->info.rt == 5) { /* J8 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tJ8\t#%" PRId32, - address, - opcode, instruction->info.imm); - } else { /* BEQS38 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tBEQS38\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.imm); - } - break; - case 3: /* BNES38, JR5, RET5, JRAL5 */ - instruction->info.rt = nds32_extract_field_8u(opcode, 8, 3); - instruction->info.imm = nds32_extract_field_8u(opcode, 0, 8); - instruction->info.imm = (instruction->info.imm << 24) >> 24; - instruction->type = NDS32_INSN_JUMP_BRANCH; - if (instruction->info.rt == 5) { - instruction->info.imm = 0; - instruction->info.rb = nds32_extract_field_8u(opcode, 0, 5); - switch (nds32_extract_field_8u(opcode, 5, 3)) { - case 0: /* JR5 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tJR5\t$r%" PRIu8, - address, - opcode, instruction->info.rb); - break; - case 1: /* JRAL5 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tJRAL5\t$r%" PRIu8, - address, - opcode, instruction->info.rb); - break; - case 2: /* EX9.IT */ - instruction->info.rb = 0; - instruction->info.imm = nds32_extract_field_8u(opcode, 0, 5); - /* TODO: implement real instruction semantics */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tEX9.IT\t#%" PRId32, - address, - opcode, instruction->info.imm); - break; - case 4: /* RET5 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tRET5\t$r%" PRIu8, - address, - opcode, instruction->info.rb); - break; - case 5: /* ADD5.PC */ - instruction->info.rt = 0; - instruction->info.rt = nds32_extract_field_8u(opcode, 0, 5); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tADD5.PC\t$r%" PRIu8, - address, - opcode, instruction->info.rt); - break; - default: - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx16 - "\tUNDEFINED INSTRUCTION", - address, - opcode); - return ERROR_FAIL; - } - } else { /* BNES38 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tBNES38\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.imm); - } - break; - } - - return ERROR_OK; -} - -static int nds32_parse_group_3_insn_16(struct nds32 *nds32, uint16_t opcode, - uint32_t address, struct nds32_instruction *instruction) -{ - switch ((opcode >> 11) & 0x3) { - case 0: - switch ((opcode >> 9) & 0x3) { - case 0: /* SLTS45 */ - instruction->info.ra = nds32_extract_field_8u(opcode, 5, 4); - instruction->info.rb = nds32_extract_field_8u(opcode, 0, 5); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tSLTS45\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.ra, instruction->info.rb); - break; - case 1: /* SLT45 */ - instruction->info.ra = nds32_extract_field_8u(opcode, 5, 4); - instruction->info.rb = nds32_extract_field_8u(opcode, 0, 5); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tSLT45\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.ra, instruction->info.rb); - break; - case 2: /* SLTSI45 */ - instruction->info.ra = nds32_extract_field_8u(opcode, 5, 4); - instruction->info.imm = nds32_extract_field_8u(opcode, 0, 5); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tSLTSI45\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.ra, instruction->info.imm); - break; - case 3: /* SLTI45 */ - instruction->info.ra = nds32_extract_field_8u(opcode, 5, 4); - instruction->info.imm = nds32_extract_field_8u(opcode, 0, 5); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tSLTI45\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.ra, instruction->info.imm); - break; - } - break; - case 1: - switch ((opcode >> 9) & 0x3) { - case 0: - instruction->info.imm = nds32_extract_field_8u(opcode, 0, 8); - instruction->info.imm = (instruction->info.imm << 24) >> 24; - instruction->type = NDS32_INSN_JUMP_BRANCH; - if (nds32_extract_field_8u(opcode, 8, 1) == 0) { /* BEQZS8 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tBEQZS8\t#%" PRId32, - address, - opcode, instruction->info.imm); - } else { /* BNEZS8 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tBNEZS8\t#%" PRId32, - address, - opcode, instruction->info.imm); - } - break; - case 1: /* BREAK16 */ - if (((opcode >> 5) & 0xF) == 0) { - instruction->type = NDS32_INSN_MISC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tBREAK16\t#%" PRId16, - address, - opcode, (int16_t)(opcode & 0x1F)); - } else { /* EX9.IT */ - instruction->type = NDS32_INSN_MISC; - /* TODO: implement real instruction semantics */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tEX9.IT\t#%" PRId16, - address, - opcode, (int16_t)(opcode & 0x1FF)); - } - break; - case 2: /* ADDI10S */ - case 3: - instruction->info.imm = opcode & 0x3FF; - instruction->info.imm = (instruction->info.imm << 22) >> 22; - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tADDI10.SP\t#%" PRId32, - address, - opcode, instruction->info.imm); - break; - } - break; - case 2: - instruction->info.rt = nds32_extract_field_8u(opcode, 8, 3); - instruction->info.imm = nds32_extract_field_8u(opcode, 0, 7) << 2; - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, R31, &(instruction->access_start)); - instruction->access_start += instruction->info.imm; - instruction->access_end = instruction->access_start + 4; - if (nds32_extract_field_8u(opcode, 7, 1) == 0) { /* LWI37.SP */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tLWI37.SP\t$r%" PRIu8 ",[+#%" PRId32 "]", - address, - opcode, instruction->info.rt, instruction->info.imm); - } else { /* SWI37.SP */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tSWI37.SP\t$r%" PRIu8 ",[+#%" PRId32 "]", - address, - opcode, instruction->info.rt, instruction->info.imm); - } - break; - case 3: - switch ((opcode >> 9) & 0x3) { - case 0: /* IFCALL9 */ - instruction->info.imm = opcode & 0x1FF; - instruction->type = NDS32_INSN_JUMP_BRANCH; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tIFCALL9\t#%" PRId32 "", - address, - opcode, instruction->info.imm); - break; - case 1: /* MOVPI45 */ - instruction->info.imm = nds32_extract_field_8u(opcode, 0, 5) + 16; - instruction->info.rt = nds32_extract_field_8u(opcode, 5, 4); - instruction->type = NDS32_INSN_MISC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tMOVPI45\t$r%" PRIu8 ",#%" PRId32 "", - address, - opcode, instruction->info.rt, instruction->info.imm); - break; - case 2: /* PUSH25, POP25, MOVD44 */ - switch ((opcode >> 7) & 0x3) { - case 0: /* PUSH25 */ - { - uint8_t re; - uint8_t gpr_count; - - instruction->type = NDS32_INSN_LOAD_STORE; - instruction->info.imm = - nds32_extract_field_8u(opcode, 0, 5) << 3; - re = nds32_extract_field_8u(opcode, 5, 2); - - if (re == 0) - re = 6; - else if (re == 1) - re = 8; - else if (re == 2) - re = 10; - else if (re == 3) - re = 14; - - instruction->info.rd = re; - /* GPRs list: R6 ~ Re and fp, gp, lp */ - gpr_count = 3 + (re - 5); - - nds32_get_mapped_reg(nds32, R31, - &(instruction->access_end)); - instruction->access_start = - instruction->access_end - (gpr_count * 4); - - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tPUSH25\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rd, - instruction->info.imm); - } - break; - case 1: /* POP25 */ - { - uint8_t re; - uint8_t gpr_count; - - instruction->type = NDS32_INSN_LOAD_STORE; - instruction->info.imm = - nds32_extract_field_8u(opcode, 0, 5) << 3; - re = nds32_extract_field_8u(opcode, 5, 2); - - if (re == 0) - re = 6; - else if (re == 1) - re = 8; - else if (re == 2) - re = 10; - else if (re == 3) - re = 14; - - instruction->info.rd = re; - /* GPRs list: R6 ~ Re and fp, gp, lp */ - gpr_count = 3 + (re - 5); - - nds32_get_mapped_reg(nds32, R31, - &(instruction->access_start)); - instruction->access_start += instruction->info.imm; - instruction->access_end = - instruction->access_start + (gpr_count * 4); - - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tPOP25\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rd, - instruction->info.imm); - } - break; - case 2: /* MOVD44 */ - case 3: - instruction->info.ra = - nds32_extract_field_8u(opcode, 0, 4) * 2; - instruction->info.rt = - nds32_extract_field_8u(opcode, 4, 4) * 2; - instruction->type = NDS32_INSN_MISC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tMOVD44\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra); - break; - } - break; - case 3: /* NEG33, NOT33, MUL33, XOR33, AND33, OR33 */ - instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3); - instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3); - instruction->type = NDS32_INSN_DATA_PROC; - switch (opcode & 0x7) { - case 2: /* NEG33 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tNEG33\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra); - break; - case 3: /* NOT33 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tNOT33\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra); - break; - case 4: /* MUL33 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tMUL33\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra); - break; - case 5: /* XOR33 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tXOR33\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra); - break; - case 6: /* AND33 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tAND33\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra); - break; - case 7: /* OR33 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tOR33\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra); - break; - } - break; - } - break; - default: - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx16 "\tUNDEFINED INSTRUCTION", - address, - opcode); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -int nds32_evaluate_opcode(struct nds32 *nds32, uint32_t opcode, uint32_t address, - struct nds32_instruction *instruction) -{ - int retval = ERROR_OK; - - /* clear fields, to avoid confusion */ - memset(instruction, 0, sizeof(struct nds32_instruction)); - - if (opcode >> 31) { - /* 16 bits instruction */ - instruction->instruction_size = 2; - opcode = (opcode >> 16) & 0xFFFF; - instruction->opcode = opcode; - - switch ((opcode >> 13) & 0x3) { - case 0: - retval = nds32_parse_group_0_insn_16(nds32, opcode, address, instruction); - break; - case 1: - retval = nds32_parse_group_1_insn_16(nds32, opcode, address, instruction); - break; - case 2: - retval = nds32_parse_group_2_insn_16(nds32, opcode, address, instruction); - break; - case 3: - retval = nds32_parse_group_3_insn_16(nds32, opcode, address, instruction); - break; - default: - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", - address, - opcode); - return ERROR_FAIL; - } - } else { - /* 32 bits instruction */ - instruction->instruction_size = 4; - instruction->opcode = opcode; - - uint8_t opc_6; - opc_6 = opcode >> 25; - instruction->info.opc_6 = opc_6; - - switch ((opc_6 >> 3) & 0x7) { - case 0: /* LBI, LHI, LWI, LBI.bi, LHI.bi, LWI.bi */ - retval = nds32_parse_group_0_insn(nds32, opcode, address, instruction); - break; - case 1: /* SBI, SHI, SWI, SBI.bi, SHI.bi, SWI.bi */ - retval = nds32_parse_group_1_insn(nds32, opcode, address, instruction); - break; - case 2: /* LBSI, LHSI, DPREFI, LBSI.bi, LHSI.bi, LBGP */ - retval = nds32_parse_group_2_insn(nds32, opcode, address, instruction); - break; - case 3: /* MEM, LSMW, HWGP, SBGP */ - retval = nds32_parse_group_3_insn(nds32, opcode, address, instruction); - break; - case 4: /* ALU_1, ALU_2, MOVI, SETHI, JI, JREG, BR1, BR2 */ - retval = nds32_parse_group_4_insn(nds32, opcode, address, instruction); - break; - case 5: /* ADDI, SUBRI, ANDI, XORI, ORI, SLTI, SLTSI */ - retval = nds32_parse_group_5_insn(nds32, opcode, address, instruction); - break; - case 6: /* MISC */ - retval = nds32_parse_group_6_insn(nds32, opcode, address, instruction); - break; - default: /* ERROR */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", - address, - opcode); - return ERROR_FAIL; - } - } - - return retval; -} diff --git a/src/target/nds32_disassembler.h b/src/target/nds32_disassembler.h deleted file mode 100644 index f2c8e85..0000000 --- a/src/target/nds32_disassembler.h +++ /dev/null @@ -1,45 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -/*************************************************************************** - * Copyright (C) 2013 Andes Technology * - * Hsiangkai Wang <hkwang@andestech.com> * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_NDS32_DISASSEMBLER_H -#define OPENOCD_TARGET_NDS32_DISASSEMBLER_H - -#include <target/nds32.h> - -enum nds32_instruction_type { - NDS32_INSN_DATA_PROC = 0, - NDS32_INSN_LOAD_STORE, - NDS32_INSN_JUMP_BRANCH, - NDS32_INSN_RESOURCE_ACCESS, - NDS32_INSN_MISC, -}; - -struct nds32_instruction { - enum nds32_instruction_type type; - char text[128]; - uint32_t opcode; - uint8_t instruction_size; - uint32_t access_start; - uint32_t access_end; - - struct { - uint8_t opc_6; - uint8_t rt; - uint8_t ra; - uint8_t rb; - uint8_t rd; - uint8_t sub_opc; - int32_t imm; - } info; - -}; - -int nds32_read_opcode(struct nds32 *nds32, uint32_t address, uint32_t *value); -int nds32_evaluate_opcode(struct nds32 *nds32, uint32_t opcode, uint32_t address, - struct nds32_instruction *instruction); - -#endif /* OPENOCD_TARGET_NDS32_DISASSEMBLER_H */ diff --git a/src/target/nds32_edm.h b/src/target/nds32_edm.h deleted file mode 100644 index 3213604..0000000 --- a/src/target/nds32_edm.h +++ /dev/null @@ -1,106 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -/*************************************************************************** - * Copyright (C) 2013 Andes Technology * - * Hsiangkai Wang <hkwang@andestech.com> * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_NDS32_EDM_H -#define OPENOCD_TARGET_NDS32_EDM_H - -#include "helper/types.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 /* OPENOCD_TARGET_NDS32_EDM_H */ diff --git a/src/target/nds32_insn.h b/src/target/nds32_insn.h deleted file mode 100644 index 25eb9ab..0000000 --- a/src/target/nds32_insn.h +++ /dev/null @@ -1,67 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -/*************************************************************************** - * Copyright (C) 2013 Andes Technology * - * Hsiangkai Wang <hkwang@andestech.com> * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_NDS32_INSN_H -#define OPENOCD_TARGET_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 */ -#define NDS32_BREAK_16 (0x00EA) -#define NDS32_BREAK_32 (0x0A000064) - -#endif /* OPENOCD_TARGET_NDS32_INSN_H */ diff --git a/src/target/nds32_reg.c b/src/target/nds32_reg.c deleted file mode 100644 index 1687e69..0000000 --- a/src/target/nds32_reg.c +++ /dev/null @@ -1,369 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -/*************************************************************************** - * Copyright (C) 2013 Andes Technology * - * Hsiangkai Wang <hkwang@andestech.com> * - ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <helper/log.h> -#include "nds32_reg.h" - -static bool nds32_reg_init_done; -static struct nds32_reg_s nds32_regs[TOTAL_REG_NUM]; -static const struct nds32_reg_exception_s nds32_ex_reg_values[] = { - {IR0, 3, 0x3, 2}, - {IR0, 3, 0x3, 3}, - {IR1, 3, 0x3, 2}, - {IR1, 3, 0x3, 3}, - {IR2, 3, 0x3, 2}, - {IR2, 3, 0x3, 3}, - {MR3, 1, 0x7, 0}, - {MR3, 1, 0x7, 4}, - {MR3, 1, 0x7, 6}, - {MR3, 8, 0x7, 3}, - {0, 0, 0, 0}, -}; - -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(IR26, "ir26", "", SRIDX(1, 8, 1), NDS32_REG_TYPE_IR, 32); - nds32_reg_set(IR27, "ir27", "", SRIDX(1, 9, 1), NDS32_REG_TYPE_IR, 32); - nds32_reg_set(IR28, "ir28", "", SRIDX(1, 11, 1), NDS32_REG_TYPE_IR, 32); - nds32_reg_set(IR29, "ir29", "", SRIDX(1, 9, 4), NDS32_REG_TYPE_IR, 32); - nds32_reg_set(IR30, "ir30", "", SRIDX(1, 1, 3), 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; -} - -bool nds32_reg_exception(uint32_t number, uint32_t value) -{ - int i; - const struct nds32_reg_exception_s *ex_reg_value; - uint32_t field_value; - - i = 0; - while (nds32_ex_reg_values[i].reg_num != 0) { - ex_reg_value = nds32_ex_reg_values + i; - - if (ex_reg_value->reg_num == number) { - field_value = (value >> ex_reg_value->ex_value_bit_pos) & - ex_reg_value->ex_value_mask; - if (field_value == ex_reg_value->ex_value) { - LOG_WARNING("It will generate exceptions as setting %" PRIu32 " to %s", - value, nds32_regs[number].simple_mnemonic); - return true; - } - } - - i++; - } - - return false; -} diff --git a/src/target/nds32_reg.h b/src/target/nds32_reg.h deleted file mode 100644 index 30cd241..0000000 --- a/src/target/nds32_reg.h +++ /dev/null @@ -1,314 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -/*************************************************************************** - * Copyright (C) 2013 Andes Technology * - * Hsiangkai Wang <hkwang@andestech.com> * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_NDS32_REG_H -#define OPENOCD_TARGET_NDS32_REG_H - -#define SRIDX(a, b, c) ((a << 7) | (b << 3) | c) -#define NDS32_REGISTER_DISABLE (0x0) - -enum nds32_reg_number_s { - R0 = 0, /* general registers */ - 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, - CR0, /* system registers */ - 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, - IR26, - IR27, - IR28, - IR29, - IR30, - 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, - D0L24, /* audio registers */ - 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, - FPCSR, /* fpu */ - 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; -}; - -struct nds32_reg_exception_s { - uint32_t reg_num; - uint32_t ex_value_bit_pos; - uint32_t ex_value_mask; - uint32_t ex_value; -}; - -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); -bool nds32_reg_exception(uint32_t number, uint32_t value); - -#endif /* OPENOCD_TARGET_NDS32_REG_H */ diff --git a/src/target/nds32_tlb.c b/src/target/nds32_tlb.c deleted file mode 100644 index a533e59..0000000 --- a/src/target/nds32_tlb.c +++ /dev/null @@ -1,67 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -/*************************************************************************** - * Copyright (C) 2013 Andes Technology * - * Hsiangkai Wang <hkwang@andestech.com> * - ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "nds32_aice.h" -#include "nds32_tlb.h" - -int nds32_probe_tlb(struct nds32 *nds32, const target_addr_t virtual_address, - target_addr_t *physical_address) -{ - struct target *target = nds32->target; - struct aice_port_s *aice = target_to_aice(target); - - return aice_read_tlb(aice, virtual_address, physical_address); -} - -static struct page_table_walker_info_s page_table_info[PAGE_SIZE_NUM] = { - /* 4K page */ - {0xFFC00000, 20, 0x003FF000, 10, 0x00000FFF, 0xFFFFF000, 0xFFFFF000, 0xFFFFF000}, - /* 8K page */ - {0xFF000000, 22, 0x00FFE000, 11, 0x00001FFF, 0xFFFFF000, 0xFFFFE000, 0xFFFFE000}, -}; - -int nds32_walk_page_table(struct nds32 *nds32, const target_addr_t virtual_address, - target_addr_t *physical_address) -{ - struct target *target = nds32->target; - uint32_t value_mr1; - uint32_t load_address; - uint32_t l1_page_table_entry; - uint32_t l2_page_table_entry; - uint32_t page_size_index = nds32->mmu_config.default_min_page_size; - struct page_table_walker_info_s *page_table_info_p = - &(page_table_info[page_size_index]); - - /* Read L1 Physical Page Table */ - nds32_get_mapped_reg(nds32, MR1, &value_mr1); - load_address = (value_mr1 & page_table_info_p->l1_base_mask) | - ((virtual_address & page_table_info_p->l1_offset_mask) >> - page_table_info_p->l1_offset_shift); - /* load_address is physical address */ - nds32_read_buffer(target, load_address, 4, (uint8_t *)&l1_page_table_entry); - - /* Read L2 Physical Page Table */ - if (l1_page_table_entry & 0x1) /* L1_PTE not present */ - return ERROR_FAIL; - - load_address = (l1_page_table_entry & page_table_info_p->l2_base_mask) | - ((virtual_address & page_table_info_p->l2_offset_mask) >> - page_table_info_p->l2_offset_shift); - /* load_address is physical address */ - nds32_read_buffer(target, load_address, 4, (uint8_t *)&l2_page_table_entry); - - if ((l2_page_table_entry & 0x1) != 0x1) /* L2_PTE not valid */ - return ERROR_FAIL; - - *physical_address = (l2_page_table_entry & page_table_info_p->ppn_mask) | - (virtual_address & page_table_info_p->va_offset_mask); - - return ERROR_OK; -} diff --git a/src/target/nds32_tlb.h b/src/target/nds32_tlb.h deleted file mode 100644 index 1edff29..0000000 --- a/src/target/nds32_tlb.h +++ /dev/null @@ -1,36 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -/*************************************************************************** - * Copyright (C) 2013 Andes Technology * - * Hsiangkai Wang <hkwang@andestech.com> * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_NDS32_TLB_H -#define OPENOCD_TARGET_NDS32_TLB_H - -#include "nds32.h" - -enum { - PAGE_SIZE_4K = 0, - PAGE_SIZE_8K, - PAGE_SIZE_NUM, -}; - -struct page_table_walker_info_s { - - uint32_t l1_offset_mask; - uint32_t l1_offset_shift; - uint32_t l2_offset_mask; - uint32_t l2_offset_shift; - uint32_t va_offset_mask; - uint32_t l1_base_mask; - uint32_t l2_base_mask; - uint32_t ppn_mask; -}; - -extern int nds32_probe_tlb(struct nds32 *nds32, const target_addr_t virtual_address, - target_addr_t *physical_address); -extern int nds32_walk_page_table(struct nds32 *nds32, const target_addr_t virtual_address, - target_addr_t *physical_address); - -#endif /* OPENOCD_TARGET_NDS32_TLB_H */ diff --git a/src/target/nds32_v2.c b/src/target/nds32_v2.c deleted file mode 100644 index 2149291..0000000 --- a/src/target/nds32_v2.c +++ /dev/null @@ -1,774 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -/*************************************************************************** - * Copyright (C) 2013 Andes Technology * - * Hsiangkai Wang <hkwang@andestech.com> * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <helper/time_support.h> -#include <helper/binarybuffer.h> -#include "breakpoints.h" -#include "nds32_insn.h" -#include "nds32_reg.h" -#include "nds32_edm.h" -#include "nds32_cmd.h" -#include "nds32_v2.h" -#include "nds32_aice.h" -#include "target_type.h" - -static int nds32_v2_register_mapping(struct nds32 *nds32, int reg_no) -{ - uint32_t max_level = nds32->max_interrupt_level; - uint32_t cur_level = nds32->current_interrupt_level; - - if ((cur_level >= 1) && (cur_level < max_level)) { - if (reg_no == IR0) { - LOG_DEBUG("Map PSW to IPSW"); - return IR1; - } else if (reg_no == PC) { - LOG_DEBUG("Map PC to IPC"); - return IR9; - } - } else if ((cur_level >= 2) && (cur_level < max_level)) { - if (reg_no == R26) { - LOG_DEBUG("Mapping P0 to P_P0"); - return IR12; - } else if (reg_no == R27) { - LOG_DEBUG("Mapping P1 to P_P1"); - return IR13; - } else if (reg_no == IR1) { - LOG_DEBUG("Mapping IPSW to P_IPSW"); - return IR2; - } else if (reg_no == IR4) { - LOG_DEBUG("Mapping EVA to P_EVA"); - return IR5; - } else if (reg_no == IR6) { - LOG_DEBUG("Mapping ITYPE to P_ITYPE"); - return IR7; - } else if (reg_no == IR9) { - LOG_DEBUG("Mapping IPC to P_IPC"); - return IR10; - } - } else if (cur_level == max_level) { - if (reg_no == PC) { - LOG_DEBUG("Mapping PC to O_IPC"); - return IR11; - } - } - - return reg_no; -} - -static int nds32_v2_get_debug_reason(struct nds32 *nds32, uint32_t *reason) -{ - uint32_t val_itype; - struct aice_port_s *aice = target_to_aice(nds32->target); - - aice_read_register(aice, IR6, &val_itype); - - *reason = val_itype & 0x0F; - - return ERROR_OK; -} - -static int nds32_v2_activate_hardware_breakpoint(struct target *target) -{ - struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target); - struct aice_port_s *aice = target_to_aice(target); - struct breakpoint *bp; - int32_t hbr_index = 0; - - for (bp = target->breakpoints; bp; bp = bp->next) { - if (bp->type == BKPT_SOFT) { - /* already set at nds32_v2_add_breakpoint() */ - continue; - } else if (bp->type == BKPT_HARD) { - /* set address */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPA0 + hbr_index, bp->address); - /* set mask */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPAM0 + hbr_index, 0); - /* set value */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPV0 + hbr_index, 0); - - if (nds32_v2->nds32.memory.address_translation) - /* enable breakpoint (virtual address) */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + hbr_index, 0x2); - else - /* enable breakpoint (physical address) */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + hbr_index, 0xA); - - LOG_DEBUG("Add hardware BP %" PRId32 " at %08" TARGET_PRIxADDR, hbr_index, - bp->address); - - hbr_index++; - } else { - return ERROR_FAIL; - } - } - - return ERROR_OK; -} - -static int nds32_v2_deactivate_hardware_breakpoint(struct target *target) -{ - struct aice_port_s *aice = target_to_aice(target); - struct breakpoint *bp; - int32_t hbr_index = 0; - - for (bp = target->breakpoints; bp; bp = bp->next) { - if (bp->type == BKPT_SOFT) - continue; - else if (bp->type == BKPT_HARD) - /* disable breakpoint */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + hbr_index, 0x0); - else - return ERROR_FAIL; - - LOG_DEBUG("Remove hardware BP %" PRId32 " at %08" TARGET_PRIxADDR, hbr_index, - bp->address); - - hbr_index++; - } - - return ERROR_OK; -} - -static int nds32_v2_activate_hardware_watchpoint(struct target *target) -{ - struct aice_port_s *aice = target_to_aice(target); - struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target); - struct watchpoint *wp; - int32_t wp_num = nds32_v2->next_hbr_index; - uint32_t wp_config = 0; - - for (wp = target->watchpoints; wp; wp = wp->next) { - - wp_num--; - wp->mask = wp->length - 1; - if ((wp->address % wp->length) != 0) - wp->mask = (wp->mask << 1) + 1; - - if (wp->rw == WPT_READ) - wp_config = 0x3; - else if (wp->rw == WPT_WRITE) - wp_config = 0x5; - else if (wp->rw == WPT_ACCESS) - wp_config = 0x7; - - /* set/unset physical address bit of BPCn according to PSW.DT */ - if (nds32_v2->nds32.memory.address_translation == false) - wp_config |= 0x8; - - /* set address */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPA0 + wp_num, - wp->address - (wp->address % wp->length)); - /* set mask */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPAM0 + wp_num, wp->mask); - /* enable watchpoint */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + wp_num, wp_config); - /* set value */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPV0 + wp_num, 0); - - LOG_DEBUG("Add hardware watchpoint %" PRId32 " at %08" TARGET_PRIxADDR " mask %08" PRIx32, wp_num, - wp->address, wp->mask); - - } - - return ERROR_OK; -} - -static int nds32_v2_deactivate_hardware_watchpoint(struct target *target) -{ - struct aice_port_s *aice = target_to_aice(target); - struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target); - int32_t wp_num = nds32_v2->next_hbr_index; - struct watchpoint *wp; - - for (wp = target->watchpoints; wp; wp = wp->next) { - wp_num--; - /* disable watchpoint */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + wp_num, 0x0); - - LOG_DEBUG("Remove hardware watchpoint %" PRId32 " at %08" TARGET_PRIxADDR " mask %08" PRIx32, - wp_num, wp->address, wp->mask); - } - - return ERROR_OK; -} - -static int nds32_v2_check_interrupt_stack(struct nds32_v2_common *nds32_v2) -{ - struct nds32 *nds32 = &(nds32_v2->nds32); - struct aice_port_s *aice = target_to_aice(nds32->target); - uint32_t val_ir0; - uint32_t val_ir1; - uint32_t val_ir2; - uint32_t modified_psw; - - /* Save interrupt level */ - aice_read_register(aice, IR0, &val_ir0); /* get $IR0 directly */ - - /* backup $IR0 */ - nds32_v2->backup_ir0 = val_ir0; - - nds32->current_interrupt_level = (val_ir0 >> 1) & 0x3; - - if (nds32_reach_max_interrupt_level(nds32)) { - LOG_ERROR("<-- TARGET ERROR! Reaching the max interrupt stack level %" PRIu32 ". -->", - nds32->current_interrupt_level); - - /* decrease interrupt level */ - modified_psw = val_ir0 - 0x2; - - /* disable GIE, IT, DT, HSS */ - modified_psw &= (~0x8C1); - - aice_write_register(aice, IR0, modified_psw); - - return ERROR_OK; - } - - /* There is a case that single step also trigger another interrupt, - then HSS bit in psw(ir0) will push to ipsw(ir1). - Then hit debug interrupt HSS bit in ipsw(ir1) will push to (p_ipsw)ir2 - Therefore, HSS bit in p_ipsw(ir2) also need clear. - - Only update $ir2 as current interrupt level is 2, because $ir2 will be random - value if the target never reaches interrupt level 2. */ - if ((nds32->max_interrupt_level == 3) && (nds32->current_interrupt_level == 2)) { - aice_read_register(aice, IR2, &val_ir2); /* get $IR2 directly */ - val_ir2 &= ~(0x01 << 11); - aice_write_register(aice, IR2, val_ir2); - } - - /* get original DT bit and set to current state let debugger has same memory view - PSW.IT MUST be turned off. Otherwise, DIM could not operate normally. */ - aice_read_register(aice, IR1, &val_ir1); - modified_psw = val_ir0 | (val_ir1 & 0x80); - aice_write_register(aice, IR0, modified_psw); - - return ERROR_OK; -} - -static int nds32_v2_restore_interrupt_stack(struct nds32_v2_common *nds32_v2) -{ - struct nds32 *nds32 = &(nds32_v2->nds32); - struct aice_port_s *aice = target_to_aice(nds32->target); - - /* restore origin $IR0 */ - aice_write_register(aice, IR0, nds32_v2->backup_ir0); - - return ERROR_OK; -} - -/** - * Save processor state. This is called after a HALT instruction - * succeeds, and on other occasions the processor enters debug mode - * (breakpoint, watchpoint, etc). - */ -static int nds32_v2_debug_entry(struct nds32 *nds32, bool enable_watchpoint) -{ - LOG_DEBUG("nds32_v2_debug_entry"); - - if (nds32->virtual_hosting) - LOG_WARNING("<-- TARGET WARNING! Virtual hosting is not supported " - "under V1/V2 architecture. -->"); - - enum target_state backup_state = nds32->target->state; - nds32->target->state = TARGET_HALTED; - - if (nds32->init_arch_info_after_halted == false) { - /* init architecture info according to config registers */ - CHECK_RETVAL(nds32_config(nds32)); - - nds32->init_arch_info_after_halted = true; - } - - /* REVISIT entire cache should already be invalid !!! */ - register_cache_invalidate(nds32->core_cache); - - /* deactivate all hardware breakpoints */ - CHECK_RETVAL(nds32_v2_deactivate_hardware_breakpoint(nds32->target)); - - if (enable_watchpoint) - CHECK_RETVAL(nds32_v2_deactivate_hardware_watchpoint(nds32->target)); - - if (nds32_examine_debug_reason(nds32) != ERROR_OK) { - nds32->target->state = backup_state; - - /* re-activate all hardware breakpoints & watchpoints */ - CHECK_RETVAL(nds32_v2_activate_hardware_breakpoint(nds32->target)); - - if (enable_watchpoint) { - /* activate all watchpoints */ - CHECK_RETVAL(nds32_v2_activate_hardware_watchpoint(nds32->target)); - } - - return ERROR_FAIL; - } - - /* check interrupt level before .full_context(), because - * get_mapped_reg() in nds32_full_context() needs current_interrupt_level - * information */ - struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(nds32->target); - nds32_v2_check_interrupt_stack(nds32_v2); - - /* Save registers. */ - nds32_full_context(nds32); - - return ERROR_OK; -} - -/* target request support */ -static int nds32_v2_target_request_data(struct target *target, - uint32_t size, uint8_t *buffer) -{ - /* AndesCore could use DTR register to communicate with OpenOCD - * to output messages - * Target data will be put in buffer - * The format of DTR is as follow - * DTR[31:16] => length, DTR[15:8] => size, DTR[7:0] => target_req_cmd - * target_req_cmd has three possible values: - * TARGET_REQ_TRACEMSG - * TARGET_REQ_DEBUGMSG - * TARGET_REQ_DEBUGCHAR - * if size == 0, target will call target_asciimsg(), - * else call target_hexmsg() - */ - LOG_WARNING("Not implemented: %s", __func__); - - return ERROR_OK; -} - -/** - * Restore processor state. - */ -static int nds32_v2_leave_debug_state(struct nds32 *nds32, bool enable_watchpoint) -{ - LOG_DEBUG("nds32_v2_leave_debug_state"); - - struct target *target = nds32->target; - - /* activate all hardware breakpoints */ - CHECK_RETVAL(nds32_v2_activate_hardware_breakpoint(nds32->target)); - - if (enable_watchpoint) { - /* activate all watchpoints */ - CHECK_RETVAL(nds32_v2_activate_hardware_watchpoint(nds32->target)); - } - - /* restore interrupt stack */ - struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(nds32->target); - nds32_v2_restore_interrupt_stack(nds32_v2); - - /* restore PSW, PC, and R0 ... after flushing any modified - * registers. - */ - CHECK_RETVAL(nds32_restore_context(target)); - - register_cache_invalidate(nds32->core_cache); - - return ERROR_OK; -} - -static int nds32_v2_deassert_reset(struct target *target) -{ - int retval; - - CHECK_RETVAL(nds32_poll(target)); - - if (target->state != TARGET_HALTED) { - /* reset only */ - LOG_WARNING("%s: ran after reset and before halt ...", - target_name(target)); - retval = target_halt(target); - if (retval != ERROR_OK) - return retval; - } - - return ERROR_OK; -} - -static int nds32_v2_checksum_memory(struct target *target, - target_addr_t address, uint32_t count, uint32_t *checksum) -{ - LOG_WARNING("Not implemented: %s", __func__); - - return ERROR_FAIL; -} - -static int nds32_v2_add_breakpoint(struct target *target, - struct breakpoint *breakpoint) -{ - struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target); - struct nds32 *nds32 = &(nds32_v2->nds32); - int result; - - if (breakpoint->type == BKPT_HARD) { - /* check hardware resource */ - if (nds32_v2->n_hbr <= nds32_v2->next_hbr_index) { - LOG_WARNING("<-- TARGET WARNING! Insert too many hardware " - "breakpoints/watchpoints! The limit of " - "combined hardware breakpoints/watchpoints " - "is %" PRId32 ". -->", nds32_v2->n_hbr); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - /* update next place to put hardware breakpoint */ - nds32_v2->next_hbr_index++; - - /* hardware breakpoint insertion occurs before 'continue' actually */ - return ERROR_OK; - } else if (breakpoint->type == BKPT_SOFT) { - result = nds32_add_software_breakpoint(target, breakpoint); - if (result != ERROR_OK) { - /* auto convert to hardware breakpoint if failed */ - if (nds32->auto_convert_hw_bp) { - /* convert to hardware breakpoint */ - breakpoint->type = BKPT_HARD; - - return nds32_v2_add_breakpoint(target, breakpoint); - } - } - - return result; - } else /* unrecognized breakpoint type */ - return ERROR_FAIL; - - return ERROR_OK; -} - -static int nds32_v2_remove_breakpoint(struct target *target, - struct breakpoint *breakpoint) -{ - struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target); - - if (breakpoint->type == BKPT_HARD) { - if (nds32_v2->next_hbr_index <= 0) - return ERROR_FAIL; - - /* update next place to put hardware breakpoint */ - nds32_v2->next_hbr_index--; - - /* hardware breakpoint removal occurs after 'halted' actually */ - return ERROR_OK; - } else if (breakpoint->type == BKPT_SOFT) { - return nds32_remove_software_breakpoint(target, breakpoint); - } else /* unrecognized breakpoint type */ - return ERROR_FAIL; - - return ERROR_OK; -} - -static int nds32_v2_add_watchpoint(struct target *target, - struct watchpoint *watchpoint) -{ - struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target); - - /* check hardware resource */ - if (nds32_v2->n_hbr <= nds32_v2->next_hbr_index) { - LOG_WARNING("<-- TARGET WARNING! Insert too many hardware " - "breakpoints/watchpoints! The limit of " - "combined hardware breakpoints/watchpoints is %" PRId32 ". -->", nds32_v2->n_hbr); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - /* update next place to put hardware watchpoint */ - nds32_v2->next_hbr_index++; - - return ERROR_OK; -} - -static int nds32_v2_remove_watchpoint(struct target *target, - struct watchpoint *watchpoint) -{ - struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target); - - if (nds32_v2->next_hbr_index <= 0) - return ERROR_FAIL; - - /* update next place to put hardware breakpoint */ - nds32_v2->next_hbr_index--; - - return ERROR_OK; -} - -static int nds32_v2_get_exception_address(struct nds32 *nds32, - uint32_t *address, uint32_t reason) -{ - struct aice_port_s *aice = target_to_aice(nds32->target); - - aice_read_register(aice, IR4, address); /* read $EVA directly */ - - /* TODO: hit multiple watchpoints */ - - return ERROR_OK; -} - -/** - * find out which watchpoint hits - * get exception address and compare the address to watchpoints - */ -static int nds32_v2_hit_watchpoint(struct target *target, - struct watchpoint **hit_watchpoint) -{ - uint32_t exception_address; - struct watchpoint *wp; - static struct watchpoint scan_all_watchpoint; - struct nds32 *nds32 = target_to_nds32(target); - - scan_all_watchpoint.address = 0; - scan_all_watchpoint.rw = WPT_WRITE; - scan_all_watchpoint.next = 0; - scan_all_watchpoint.unique_id = 0x5CA8; - - exception_address = nds32->watched_address; - - if (exception_address == 0) { - /* send watch:0 to tell GDB to do software scan for hitting multiple watchpoints */ - *hit_watchpoint = &scan_all_watchpoint; - return ERROR_OK; - } - - for (wp = target->watchpoints; wp; wp = wp->next) { - if (((exception_address ^ wp->address) & (~wp->mask)) == 0) { - /* TODO: dispel false match */ - *hit_watchpoint = wp; - return ERROR_OK; - } - } - - return ERROR_FAIL; -} - -static int nds32_v2_run_algorithm(struct target *target, - int num_mem_params, - struct mem_param *mem_params, - int num_reg_params, - struct reg_param *reg_params, - target_addr_t entry_point, - target_addr_t exit_point, - int timeout_ms, - void *arch_info) -{ - LOG_WARNING("Not implemented: %s", __func__); - - return ERROR_FAIL; -} - -static int nds32_v2_target_create(struct target *target, Jim_Interp *interp) -{ - struct nds32_v2_common *nds32_v2; - - nds32_v2 = calloc(1, sizeof(*nds32_v2)); - if (!nds32_v2) - return ERROR_FAIL; - - nds32_v2->nds32.register_map = nds32_v2_register_mapping; - nds32_v2->nds32.get_debug_reason = nds32_v2_get_debug_reason; - nds32_v2->nds32.enter_debug_state = nds32_v2_debug_entry; - nds32_v2->nds32.leave_debug_state = nds32_v2_leave_debug_state; - nds32_v2->nds32.get_watched_address = nds32_v2_get_exception_address; - - nds32_init_arch_info(target, &(nds32_v2->nds32)); - - return ERROR_OK; -} - -static int nds32_v2_init_target(struct command_context *cmd_ctx, - struct target *target) -{ - /* Initialize anything we can set up without talking to the target */ - - struct nds32 *nds32 = target_to_nds32(target); - - nds32_init(nds32); - - return ERROR_OK; -} - -/* talk to the target and set things up */ -static int nds32_v2_examine(struct target *target) -{ - struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target); - struct nds32 *nds32 = &(nds32_v2->nds32); - struct aice_port_s *aice = target_to_aice(target); - - if (!target_was_examined(target)) { - CHECK_RETVAL(nds32_edm_config(nds32)); - - if (nds32->reset_halt_as_examine) - CHECK_RETVAL(nds32_reset_halt(nds32)); - } - - uint32_t edm_cfg; - aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CFG, &edm_cfg); - - /* get the number of hardware breakpoints */ - nds32_v2->n_hbr = (edm_cfg & 0x7) + 1; - - nds32_v2->next_hbr_index = 0; - - LOG_INFO("%s: total hardware breakpoint %" PRId32, target_name(target), - nds32_v2->n_hbr); - - nds32->target->state = TARGET_RUNNING; - nds32->target->debug_reason = DBG_REASON_NOTHALTED; - - target_set_examined(target); - - return ERROR_OK; -} - -static int nds32_v2_translate_address(struct target *target, target_addr_t *address) -{ - struct nds32 *nds32 = target_to_nds32(target); - struct nds32_memory *memory = &(nds32->memory); - target_addr_t physical_address; - - /* Following conditions need to do address translation - * 1. BUS mode - * 2. CPU mode under maximum interrupt level */ - if ((memory->access_channel == NDS_MEMORY_ACC_BUS) || - ((memory->access_channel == NDS_MEMORY_ACC_CPU) && - nds32_reach_max_interrupt_level(nds32))) { - if (target->type->virt2phys(target, *address, &physical_address) == ERROR_OK) - *address = physical_address; - else - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int nds32_v2_read_buffer(struct target *target, target_addr_t address, - uint32_t size, uint8_t *buffer) -{ - struct nds32 *nds32 = target_to_nds32(target); - struct nds32_memory *memory = &(nds32->memory); - - if ((memory->access_channel == NDS_MEMORY_ACC_CPU) && - (target->state != TARGET_HALTED)) { - LOG_WARNING("target was not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* BUG: If access range crosses multiple pages, the translation will not correct - * for second page or so. */ - - nds32_v2_translate_address(target, &address); - - return nds32_read_buffer(target, address, size, buffer); -} - -static int nds32_v2_write_buffer(struct target *target, target_addr_t address, - uint32_t size, const uint8_t *buffer) -{ - struct nds32 *nds32 = target_to_nds32(target); - struct nds32_memory *memory = &(nds32->memory); - - if ((memory->access_channel == NDS_MEMORY_ACC_CPU) && - (target->state != TARGET_HALTED)) { - LOG_WARNING("target was not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* BUG: If access range crosses multiple pages, the translation will not correct - * for second page or so. */ - - nds32_v2_translate_address(target, &address); - - return nds32_write_buffer(target, address, size, buffer); -} - -static int nds32_v2_read_memory(struct target *target, target_addr_t address, - uint32_t size, uint32_t count, uint8_t *buffer) -{ - struct nds32 *nds32 = target_to_nds32(target); - struct nds32_memory *memory = &(nds32->memory); - - if ((memory->access_channel == NDS_MEMORY_ACC_CPU) && - (target->state != TARGET_HALTED)) { - LOG_WARNING("target was not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* BUG: If access range crosses multiple pages, the translation will not correct - * for second page or so. */ - - nds32_v2_translate_address(target, &address); - - return nds32_read_memory(target, address, size, count, buffer); -} - -static int nds32_v2_write_memory(struct target *target, target_addr_t address, - uint32_t size, uint32_t count, const uint8_t *buffer) -{ - struct nds32 *nds32 = target_to_nds32(target); - struct nds32_memory *memory = &(nds32->memory); - - if ((memory->access_channel == NDS_MEMORY_ACC_CPU) && - (target->state != TARGET_HALTED)) { - LOG_WARNING("target was not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* BUG: If access range crosses multiple pages, the translation will not correct - * for second page or so. */ - - nds32_v2_translate_address(target, &address); - - return nds32_write_memory(target, address, size, count, buffer); -} - -/** Holds methods for V2 targets. */ -struct target_type nds32_v2_target = { - .name = "nds32_v2", - - .poll = nds32_poll, - .arch_state = nds32_arch_state, - - .target_request_data = nds32_v2_target_request_data, - - .halt = nds32_halt, - .resume = nds32_resume, - .step = nds32_step, - - .assert_reset = nds32_assert_reset, - .deassert_reset = nds32_v2_deassert_reset, - - /* register access */ - .get_gdb_reg_list = nds32_get_gdb_reg_list, - - /* memory access */ - .read_buffer = nds32_v2_read_buffer, - .write_buffer = nds32_v2_write_buffer, - .read_memory = nds32_v2_read_memory, - .write_memory = nds32_v2_write_memory, - - .checksum_memory = nds32_v2_checksum_memory, - - /* breakpoint/watchpoint */ - .add_breakpoint = nds32_v2_add_breakpoint, - .remove_breakpoint = nds32_v2_remove_breakpoint, - .add_watchpoint = nds32_v2_add_watchpoint, - .remove_watchpoint = nds32_v2_remove_watchpoint, - .hit_watchpoint = nds32_v2_hit_watchpoint, - - /* MMU */ - .mmu = nds32_mmu, - .virt2phys = nds32_virtual_to_physical, - .read_phys_memory = nds32_read_phys_memory, - .write_phys_memory = nds32_write_phys_memory, - - .run_algorithm = nds32_v2_run_algorithm, - - .commands = nds32_command_handlers, - .target_create = nds32_v2_target_create, - .init_target = nds32_v2_init_target, - .examine = nds32_v2_examine, -}; diff --git a/src/target/nds32_v2.h b/src/target/nds32_v2.h deleted file mode 100644 index 3c30108..0000000 --- a/src/target/nds32_v2.h +++ /dev/null @@ -1,31 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -/*************************************************************************** - * Copyright (C) 2013 Andes Technology * - * Hsiangkai Wang <hkwang@andestech.com> * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_NDS32_V2_H -#define OPENOCD_TARGET_NDS32_V2_H - -#include "nds32.h" - -struct nds32_v2_common { - struct nds32 nds32; - - uint32_t backup_ir0; - - /** number of hardware breakpoints */ - int32_t n_hbr; - - /** next hardware breakpoint index */ - /** increase from low index to high index */ - int32_t next_hbr_index; -}; - -static inline struct nds32_v2_common *target_to_nds32_v2(struct target *target) -{ - return container_of(target->arch_info, struct nds32_v2_common, nds32); -} - -#endif /* OPENOCD_TARGET_NDS32_V2_H */ diff --git a/src/target/nds32_v3.c b/src/target/nds32_v3.c deleted file mode 100644 index 9d02e5a..0000000 --- a/src/target/nds32_v3.c +++ /dev/null @@ -1,510 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -/*************************************************************************** - * Copyright (C) 2013 Andes Technology * - * Hsiangkai Wang <hkwang@andestech.com> * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "breakpoints.h" -#include "nds32_cmd.h" -#include "nds32_aice.h" -#include "nds32_v3.h" -#include "nds32_v3_common.h" - -static int nds32_v3_activate_hardware_breakpoint(struct target *target) -{ - struct nds32_v3_common *nds32_v3 = target_to_nds32_v3(target); - struct aice_port_s *aice = target_to_aice(target); - struct breakpoint *bp; - int32_t hbr_index = nds32_v3->next_hbr_index; - - for (bp = target->breakpoints; bp; bp = bp->next) { - if (bp->type == BKPT_SOFT) { - /* already set at nds32_v3_add_breakpoint() */ - continue; - } else if (bp->type == BKPT_HARD) { - hbr_index--; - /* set address */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPA0 + hbr_index, bp->address); - /* set mask */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPAM0 + hbr_index, 0); - /* set value */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPV0 + hbr_index, 0); - - if (nds32_v3->nds32.memory.address_translation) - /* enable breakpoint (virtual address) */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + hbr_index, 0x2); - else - /* enable breakpoint (physical address) */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + hbr_index, 0xA); - - LOG_DEBUG("Add hardware BP %" PRId32 " at %08" TARGET_PRIxADDR, hbr_index, - bp->address); - } else { - return ERROR_FAIL; - } - } - - return ERROR_OK; -} - -static int nds32_v3_deactivate_hardware_breakpoint(struct target *target) -{ - struct nds32_v3_common *nds32_v3 = target_to_nds32_v3(target); - struct aice_port_s *aice = target_to_aice(target); - struct breakpoint *bp; - int32_t hbr_index = nds32_v3->next_hbr_index; - - for (bp = target->breakpoints; bp; bp = bp->next) { - if (bp->type == BKPT_SOFT) { - continue; - } else if (bp->type == BKPT_HARD) { - hbr_index--; - /* disable breakpoint */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + hbr_index, 0x0); - } else { - return ERROR_FAIL; - } - - LOG_DEBUG("Remove hardware BP %" PRId32 " at %08" TARGET_PRIxADDR, hbr_index, - bp->address); - } - - return ERROR_OK; -} - -static int nds32_v3_activate_hardware_watchpoint(struct target *target) -{ - struct aice_port_s *aice = target_to_aice(target); - struct nds32_v3_common *nds32_v3 = target_to_nds32_v3(target); - struct watchpoint *wp; - int32_t wp_num = 0; - uint32_t wp_config = 0; - bool ld_stop, st_stop; - - if (nds32_v3->nds32.global_stop) - ld_stop = st_stop = false; - - for (wp = target->watchpoints; wp; wp = wp->next) { - - if (wp_num < nds32_v3->used_n_wp) { - wp->mask = wp->length - 1; - if ((wp->address % wp->length) != 0) - wp->mask = (wp->mask << 1) + 1; - - if (wp->rw == WPT_READ) - wp_config = 0x3; - else if (wp->rw == WPT_WRITE) - wp_config = 0x5; - else if (wp->rw == WPT_ACCESS) - wp_config = 0x7; - - /* set/unset physical address bit of BPCn according to PSW.DT */ - if (nds32_v3->nds32.memory.address_translation == false) - wp_config |= 0x8; - - /* set address */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPA0 + wp_num, - wp->address - (wp->address % wp->length)); - /* set mask */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPAM0 + wp_num, wp->mask); - /* enable watchpoint */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + wp_num, wp_config); - /* set value */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPV0 + wp_num, 0); - - LOG_DEBUG("Add hardware watchpoint %" PRId32 " at %08" TARGET_PRIxADDR " mask %08" PRIx32, - wp_num, wp->address, wp->mask); - - wp_num++; - } else if (nds32_v3->nds32.global_stop) { - if (wp->rw == WPT_READ) - ld_stop = true; - else if (wp->rw == WPT_WRITE) - st_stop = true; - else if (wp->rw == WPT_ACCESS) - ld_stop = st_stop = true; - } - } - - if (nds32_v3->nds32.global_stop) { - uint32_t edm_ctl; - aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CTL, &edm_ctl); - if (ld_stop) - edm_ctl |= 0x10; - if (st_stop) - edm_ctl |= 0x20; - aice_write_debug_reg(aice, NDS_EDM_SR_EDM_CTL, edm_ctl); - } - - return ERROR_OK; -} - -static int nds32_v3_deactivate_hardware_watchpoint(struct target *target) -{ - struct aice_port_s *aice = target_to_aice(target); - struct nds32_v3_common *nds32_v3 = target_to_nds32_v3(target); - int32_t wp_num = 0; - struct watchpoint *wp; - bool clean_global_stop = false; - - for (wp = target->watchpoints; wp; wp = wp->next) { - - if (wp_num < nds32_v3->used_n_wp) { - /* disable watchpoint */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + wp_num, 0x0); - - LOG_DEBUG("Remove hardware watchpoint %" PRId32 " at %08" TARGET_PRIxADDR - " mask %08" PRIx32, wp_num, - wp->address, wp->mask); - wp_num++; - } else if (nds32_v3->nds32.global_stop) { - clean_global_stop = true; - } - } - - if (clean_global_stop) { - uint32_t edm_ctl; - aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CTL, &edm_ctl); - edm_ctl = edm_ctl & (~0x30); - aice_write_debug_reg(aice, NDS_EDM_SR_EDM_CTL, edm_ctl); - } - - return ERROR_OK; -} - -static int nds32_v3_check_interrupt_stack(struct nds32 *nds32) -{ - uint32_t val_ir0; - uint32_t value; - - /* Save interrupt level */ - nds32_get_mapped_reg(nds32, IR0, &val_ir0); - nds32->current_interrupt_level = (val_ir0 >> 1) & 0x3; - - if (nds32_reach_max_interrupt_level(nds32)) - LOG_ERROR("<-- TARGET ERROR! Reaching the max interrupt stack level %" PRIu32 ". -->", - nds32->current_interrupt_level); - - /* backup $ir4 & $ir6 to avoid suppressed exception overwrite */ - nds32_get_mapped_reg(nds32, IR4, &value); - nds32_get_mapped_reg(nds32, IR6, &value); - - return ERROR_OK; -} - -static int nds32_v3_restore_interrupt_stack(struct nds32 *nds32) -{ - uint32_t value; - - /* get backup value from cache */ - /* then set back to make the register dirty */ - nds32_get_mapped_reg(nds32, IR0, &value); - nds32_set_mapped_reg(nds32, IR0, value); - - nds32_get_mapped_reg(nds32, IR4, &value); - nds32_set_mapped_reg(nds32, IR4, value); - - nds32_get_mapped_reg(nds32, IR6, &value); - nds32_set_mapped_reg(nds32, IR6, value); - - return ERROR_OK; -} - -static int nds32_v3_deassert_reset(struct target *target) -{ - int retval; - struct aice_port_s *aice = target_to_aice(target); - bool switch_to_v3_stack = false; - uint32_t value_edm_ctl; - - aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CTL, &value_edm_ctl); - if (((value_edm_ctl >> 6) & 0x1) == 0) { /* reset to V2 EDM mode */ - aice_write_debug_reg(aice, NDS_EDM_SR_EDM_CTL, value_edm_ctl | (0x1 << 6)); - aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CTL, &value_edm_ctl); - if (((value_edm_ctl >> 6) & 0x1) == 1) - switch_to_v3_stack = true; - } else - switch_to_v3_stack = false; - - CHECK_RETVAL(nds32_poll(target)); - - if (target->state != TARGET_HALTED) { - /* reset only */ - LOG_WARNING("%s: ran after reset and before halt ...", - target_name(target)); - retval = target_halt(target); - if (retval != ERROR_OK) - return retval; - - } else { - /* reset-halt */ - struct nds32_v3_common *nds32_v3 = target_to_nds32_v3(target); - struct nds32 *nds32 = &(nds32_v3->nds32); - uint32_t value; - uint32_t interrupt_level; - - if (switch_to_v3_stack == true) { - /* PSW.INTL-- */ - nds32_get_mapped_reg(nds32, IR0, &value); - interrupt_level = (value >> 1) & 0x3; - interrupt_level--; - value &= ~(0x6); - value |= (interrupt_level << 1); - value |= 0x400; /* set PSW.DEX */ - nds32_set_mapped_reg(nds32, IR0, value); - - /* copy IPC to OIPC */ - if ((interrupt_level + 1) < nds32->max_interrupt_level) { - nds32_get_mapped_reg(nds32, IR9, &value); - nds32_set_mapped_reg(nds32, IR11, value); - } - } - } - - return ERROR_OK; -} - -static int nds32_v3_add_breakpoint(struct target *target, - struct breakpoint *breakpoint) -{ - struct nds32_v3_common *nds32_v3 = target_to_nds32_v3(target); - struct nds32 *nds32 = &(nds32_v3->nds32); - int result; - - if (breakpoint->type == BKPT_HARD) { - /* check hardware resource */ - if (nds32_v3->n_hbr <= nds32_v3->next_hbr_index) { - LOG_WARNING("<-- TARGET WARNING! Insert too many " - "hardware breakpoints/watchpoints! " - "The limit of combined hardware " - "breakpoints/watchpoints is %" PRId32 ". -->", - nds32_v3->n_hbr); - LOG_WARNING("<-- TARGET STATUS: Inserted number of " - "hardware breakpoint: %" PRId32 ", hardware " - "watchpoints: %" PRId32 ". -->", - nds32_v3->next_hbr_index - nds32_v3->used_n_wp, - nds32_v3->used_n_wp); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - /* update next place to put hardware breakpoint */ - nds32_v3->next_hbr_index++; - - /* hardware breakpoint insertion occurs before 'continue' actually */ - return ERROR_OK; - } else if (breakpoint->type == BKPT_SOFT) { - result = nds32_add_software_breakpoint(target, breakpoint); - if (result != ERROR_OK) { - /* auto convert to hardware breakpoint if failed */ - if (nds32->auto_convert_hw_bp) { - /* convert to hardware breakpoint */ - breakpoint->type = BKPT_HARD; - - return nds32_v3_add_breakpoint(target, breakpoint); - } - } - - return result; - } else /* unrecognized breakpoint type */ - return ERROR_FAIL; - - return ERROR_OK; -} - -static int nds32_v3_remove_breakpoint(struct target *target, - struct breakpoint *breakpoint) -{ - struct nds32_v3_common *nds32_v3 = target_to_nds32_v3(target); - - if (breakpoint->type == BKPT_HARD) { - if (nds32_v3->next_hbr_index <= 0) - return ERROR_FAIL; - - /* update next place to put hardware breakpoint */ - nds32_v3->next_hbr_index--; - - /* hardware breakpoint removal occurs after 'halted' actually */ - return ERROR_OK; - } else if (breakpoint->type == BKPT_SOFT) { - return nds32_remove_software_breakpoint(target, breakpoint); - } else /* unrecognized breakpoint type */ - return ERROR_FAIL; - - return ERROR_OK; -} - -static int nds32_v3_add_watchpoint(struct target *target, - struct watchpoint *watchpoint) -{ - struct nds32_v3_common *nds32_v3 = target_to_nds32_v3(target); - - /* check hardware resource */ - if (nds32_v3->n_hbr <= nds32_v3->next_hbr_index) { - /* No hardware resource */ - if (nds32_v3->nds32.global_stop) { - LOG_WARNING("<-- TARGET WARNING! The number of " - "watchpoints exceeds the hardware " - "resources. Stop at every load/store " - "instruction to check for watchpoint matches. -->"); - return ERROR_OK; - } - - LOG_WARNING("<-- TARGET WARNING! Insert too many hardware " - "breakpoints/watchpoints! The limit of combined " - "hardware breakpoints/watchpoints is %" PRId32 ". -->", - nds32_v3->n_hbr); - LOG_WARNING("<-- TARGET STATUS: Inserted number of " - "hardware breakpoint: %" PRId32 ", hardware " - "watchpoints: %" PRId32 ". -->", - nds32_v3->next_hbr_index - nds32_v3->used_n_wp, - nds32_v3->used_n_wp); - - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - /* update next place to put hardware watchpoint */ - nds32_v3->next_hbr_index++; - nds32_v3->used_n_wp++; - - return ERROR_OK; -} - -static int nds32_v3_remove_watchpoint(struct target *target, - struct watchpoint *watchpoint) -{ - struct nds32_v3_common *nds32_v3 = target_to_nds32_v3(target); - - if (nds32_v3->next_hbr_index <= 0) { - if (nds32_v3->nds32.global_stop) - return ERROR_OK; - - return ERROR_FAIL; - } - - /* update next place to put hardware breakpoint */ - nds32_v3->next_hbr_index--; - nds32_v3->used_n_wp--; - - return ERROR_OK; -} - -static struct nds32_v3_common_callback nds32_v3_common_callback = { - .check_interrupt_stack = nds32_v3_check_interrupt_stack, - .restore_interrupt_stack = nds32_v3_restore_interrupt_stack, - .activate_hardware_breakpoint = nds32_v3_activate_hardware_breakpoint, - .activate_hardware_watchpoint = nds32_v3_activate_hardware_watchpoint, - .deactivate_hardware_breakpoint = nds32_v3_deactivate_hardware_breakpoint, - .deactivate_hardware_watchpoint = nds32_v3_deactivate_hardware_watchpoint, -}; - -static int nds32_v3_target_create(struct target *target, Jim_Interp *interp) -{ - struct nds32_v3_common *nds32_v3; - - nds32_v3 = calloc(1, sizeof(*nds32_v3)); - if (!nds32_v3) - return ERROR_FAIL; - - nds32_v3_common_register_callback(&nds32_v3_common_callback); - nds32_v3_target_create_common(target, &(nds32_v3->nds32)); - - return ERROR_OK; -} - -/* talk to the target and set things up */ -static int nds32_v3_examine(struct target *target) -{ - struct nds32_v3_common *nds32_v3 = target_to_nds32_v3(target); - struct nds32 *nds32 = &(nds32_v3->nds32); - struct aice_port_s *aice = target_to_aice(target); - - if (!target_was_examined(target)) { - CHECK_RETVAL(nds32_edm_config(nds32)); - - if (nds32->reset_halt_as_examine) - CHECK_RETVAL(nds32_reset_halt(nds32)); - } - - uint32_t edm_cfg; - aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CFG, &edm_cfg); - - /* get the number of hardware breakpoints */ - nds32_v3->n_hbr = (edm_cfg & 0x7) + 1; - - /* low interference profiling */ - if (edm_cfg & 0x100) - nds32_v3->low_interference_profile = true; - else - nds32_v3->low_interference_profile = false; - - nds32_v3->next_hbr_index = 0; - nds32_v3->used_n_wp = 0; - - LOG_INFO("%s: total hardware breakpoint %" PRId32, target_name(target), - nds32_v3->n_hbr); - - nds32->target->state = TARGET_RUNNING; - nds32->target->debug_reason = DBG_REASON_NOTHALTED; - - target_set_examined(target); - - return ERROR_OK; -} - -/** Holds methods for Andes1337 targets. */ -struct target_type nds32_v3_target = { - .name = "nds32_v3", - - .poll = nds32_poll, - .arch_state = nds32_arch_state, - - .target_request_data = nds32_v3_target_request_data, - - .halt = nds32_halt, - .resume = nds32_resume, - .step = nds32_step, - - .assert_reset = nds32_assert_reset, - .deassert_reset = nds32_v3_deassert_reset, - - /* register access */ - .get_gdb_reg_list = nds32_get_gdb_reg_list, - - /* memory access */ - .read_buffer = nds32_v3_read_buffer, - .write_buffer = nds32_v3_write_buffer, - .read_memory = nds32_v3_read_memory, - .write_memory = nds32_v3_write_memory, - - .checksum_memory = nds32_v3_checksum_memory, - - /* breakpoint/watchpoint */ - .add_breakpoint = nds32_v3_add_breakpoint, - .remove_breakpoint = nds32_v3_remove_breakpoint, - .add_watchpoint = nds32_v3_add_watchpoint, - .remove_watchpoint = nds32_v3_remove_watchpoint, - .hit_watchpoint = nds32_v3_hit_watchpoint, - - /* MMU */ - .mmu = nds32_mmu, - .virt2phys = nds32_virtual_to_physical, - .read_phys_memory = nds32_read_phys_memory, - .write_phys_memory = nds32_write_phys_memory, - - .run_algorithm = nds32_v3_run_algorithm, - - .commands = nds32_command_handlers, - .target_create = nds32_v3_target_create, - .init_target = nds32_v3_init_target, - .examine = nds32_v3_examine, - - .get_gdb_fileio_info = nds32_get_gdb_fileio_info, - .gdb_fileio_end = nds32_gdb_fileio_end, - - .profiling = nds32_profiling, -}; diff --git a/src/target/nds32_v3.h b/src/target/nds32_v3.h deleted file mode 100644 index 389838d..0000000 --- a/src/target/nds32_v3.h +++ /dev/null @@ -1,34 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -/*************************************************************************** - * Copyright (C) 2013 Andes Technology * - * Hsiangkai Wang <hkwang@andestech.com> * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_NDS32_V3_H -#define OPENOCD_TARGET_NDS32_V3_H - -#include "nds32.h" - -struct nds32_v3_common { - struct nds32 nds32; - - /** number of hardware breakpoints */ - int32_t n_hbr; - - /** number of used hardware watchpoints */ - int32_t used_n_wp; - - /** next hardware breakpoint index */ - int32_t next_hbr_index; - - /** low interference profiling */ - bool low_interference_profile; -}; - -static inline struct nds32_v3_common *target_to_nds32_v3(struct target *target) -{ - return container_of(target->arch_info, struct nds32_v3_common, nds32); -} - -#endif /* OPENOCD_TARGET_NDS32_V3_H */ diff --git a/src/target/nds32_v3_common.c b/src/target/nds32_v3_common.c deleted file mode 100644 index f2efab4..0000000 --- a/src/target/nds32_v3_common.c +++ /dev/null @@ -1,664 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -/*************************************************************************** - * Copyright (C) 2013 Andes Technology * - * Hsiangkai Wang <hkwang@andestech.com> * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "breakpoints.h" -#include "nds32_reg.h" -#include "nds32_disassembler.h" -#include "nds32.h" -#include "nds32_aice.h" -#include "nds32_v3_common.h" - -static struct nds32_v3_common_callback *v3_common_callback; - -static int nds32_v3_register_mapping(struct nds32 *nds32, int reg_no) -{ - if (reg_no == PC) - return IR11; - - return reg_no; -} - -static int nds32_v3_get_debug_reason(struct nds32 *nds32, uint32_t *reason) -{ - uint32_t edmsw; - struct aice_port_s *aice = target_to_aice(nds32->target); - aice_read_debug_reg(aice, NDS_EDM_SR_EDMSW, &edmsw); - - *reason = (edmsw >> 12) & 0x0F; - - return ERROR_OK; -} - -/** - * Save processor state. This is called after a HALT instruction - * succeeds, and on other occasions the processor enters debug mode - * (breakpoint, watchpoint, etc). - */ -static int nds32_v3_debug_entry(struct nds32 *nds32, bool enable_watchpoint) -{ - LOG_DEBUG("nds32_v3_debug_entry"); - - enum target_state backup_state = nds32->target->state; - nds32->target->state = TARGET_HALTED; - - if (nds32->init_arch_info_after_halted == false) { - /* init architecture info according to config registers */ - CHECK_RETVAL(nds32_config(nds32)); - - nds32->init_arch_info_after_halted = true; - } - - /* REVISIT entire cache should already be invalid !!! */ - register_cache_invalidate(nds32->core_cache); - - /* deactivate all hardware breakpoints */ - CHECK_RETVAL(v3_common_callback->deactivate_hardware_breakpoint(nds32->target)); - - if (enable_watchpoint) - CHECK_RETVAL(v3_common_callback->deactivate_hardware_watchpoint(nds32->target)); - - struct breakpoint *syscall_break = &(nds32->syscall_break); - if (nds32->virtual_hosting) { - if (syscall_break->is_set) { - /** disable virtual hosting */ - - /* remove breakpoint at syscall entry */ - target_remove_breakpoint(nds32->target, syscall_break); - syscall_break->is_set = false; - - uint32_t value_pc; - nds32_get_mapped_reg(nds32, PC, &value_pc); - if (value_pc == syscall_break->address) - /** process syscall for virtual hosting */ - nds32->hit_syscall = true; - } - } - - if (nds32_examine_debug_reason(nds32) != ERROR_OK) { - nds32->target->state = backup_state; - - /* re-activate all hardware breakpoints & watchpoints */ - CHECK_RETVAL(v3_common_callback->activate_hardware_breakpoint(nds32->target)); - - if (enable_watchpoint) - CHECK_RETVAL(v3_common_callback->activate_hardware_watchpoint(nds32->target)); - - return ERROR_FAIL; - } - - /* Save registers. */ - nds32_full_context(nds32); - - /* check interrupt level */ - v3_common_callback->check_interrupt_stack(nds32); - - return ERROR_OK; -} - -/** - * Restore processor state. - */ -static int nds32_v3_leave_debug_state(struct nds32 *nds32, bool enable_watchpoint) -{ - LOG_DEBUG("nds32_v3_leave_debug_state"); - - struct target *target = nds32->target; - - /* activate all hardware breakpoints */ - CHECK_RETVAL(v3_common_callback->activate_hardware_breakpoint(target)); - - if (enable_watchpoint) { - /* activate all watchpoints */ - CHECK_RETVAL(v3_common_callback->activate_hardware_watchpoint(target)); - } - - /* restore interrupt stack */ - v3_common_callback->restore_interrupt_stack(nds32); - - /* REVISIT once we start caring about MMU and cache state, - * address it here ... - */ - - /* restore PSW, PC, and R0 ... after flushing any modified - * registers. - */ - CHECK_RETVAL(nds32_restore_context(target)); - - if (nds32->virtual_hosting) { - /** enable virtual hosting */ - uint32_t value_ir3; - uint32_t entry_size; - uint32_t syscall_address; - - /* get syscall entry address */ - nds32_get_mapped_reg(nds32, IR3, &value_ir3); - entry_size = 0x4 << (((value_ir3 >> 14) & 0x3) << 1); - syscall_address = (value_ir3 & 0xFFFF0000) + entry_size * 8; /* The index of SYSCALL is 8 */ - - if (nds32->hit_syscall) { - /* single step to skip syscall entry */ - /* use IRET to skip syscall */ - struct aice_port_s *aice = target_to_aice(target); - uint32_t value_ir9; - uint32_t value_ir6; - uint32_t syscall_id; - - nds32_get_mapped_reg(nds32, IR6, &value_ir6); - syscall_id = (value_ir6 >> 16) & 0x7FFF; - - if (syscall_id == NDS32_SYSCALL_EXIT) { - /* If target hits exit syscall, do not use IRET to skip handler. */ - aice_step(aice); - } else { - /* use api->read/write_reg to skip nds32 register cache */ - uint32_t value_dimbr; - aice_read_debug_reg(aice, NDS_EDM_SR_DIMBR, &value_dimbr); - aice_write_register(aice, IR11, value_dimbr + 0xC); - - aice_read_register(aice, IR9, &value_ir9); - value_ir9 += 4; /* syscall is always 4 bytes */ - aice_write_register(aice, IR9, value_ir9); - - /* backup hardware breakpoint 0 */ - uint32_t backup_bpa, backup_bpam, backup_bpc; - aice_read_debug_reg(aice, NDS_EDM_SR_BPA0, &backup_bpa); - aice_read_debug_reg(aice, NDS_EDM_SR_BPAM0, &backup_bpam); - aice_read_debug_reg(aice, NDS_EDM_SR_BPC0, &backup_bpc); - - /* use hardware breakpoint 0 to stop cpu after skipping syscall */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPA0, value_ir9); - aice_write_debug_reg(aice, NDS_EDM_SR_BPAM0, 0); - aice_write_debug_reg(aice, NDS_EDM_SR_BPC0, 0xA); - - /* Execute two IRET. - * First IRET is used to quit debug mode. - * Second IRET is used to quit current syscall. */ - uint32_t dim_inst[4] = {NOP, NOP, IRET, IRET}; - aice_execute(aice, dim_inst, 4); - - /* restore origin hardware breakpoint 0 */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPA0, backup_bpa); - aice_write_debug_reg(aice, NDS_EDM_SR_BPAM0, backup_bpam); - aice_write_debug_reg(aice, NDS_EDM_SR_BPC0, backup_bpc); - } - - nds32->hit_syscall = false; - } - - /* insert breakpoint at syscall entry */ - struct breakpoint *syscall_break = &(nds32->syscall_break); - - syscall_break->address = syscall_address; - syscall_break->type = BKPT_SOFT; - syscall_break->is_set = true; - target_add_breakpoint(target, syscall_break); - } - - return ERROR_OK; -} - -static int nds32_v3_get_exception_address(struct nds32 *nds32, - uint32_t *address, uint32_t reason) -{ - LOG_DEBUG("nds32_v3_get_exception_address"); - - struct aice_port_s *aice = target_to_aice(nds32->target); - struct target *target = nds32->target; - uint32_t edmsw; - uint32_t edm_cfg; - uint32_t match_bits; - uint32_t match_count; - int32_t i; - static int32_t number_of_hard_break; - uint32_t bp_control; - - if (number_of_hard_break == 0) { - aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CFG, &edm_cfg); - number_of_hard_break = (edm_cfg & 0x7) + 1; - } - - aice_read_debug_reg(aice, NDS_EDM_SR_EDMSW, &edmsw); - /* clear matching bits (write-one-clear) */ - aice_write_debug_reg(aice, NDS_EDM_SR_EDMSW, edmsw); - match_bits = (edmsw >> 4) & 0xFF; - match_count = 0; - for (i = 0 ; i < number_of_hard_break ; i++) { - if (match_bits & (1 << i)) { - aice_read_debug_reg(aice, NDS_EDM_SR_BPA0 + i, address); - match_count++; - - /* If target hits multiple read/access watchpoint, - * select the first one. */ - aice_read_debug_reg(aice, NDS_EDM_SR_BPC0 + i, &bp_control); - if (0x3 == (bp_control & 0x3)) { - match_count = 1; - break; - } - } - } - - if (match_count > 1) { /* multiple hits */ - *address = 0; - return ERROR_OK; - } else if (match_count == 1) { - uint32_t val_pc; - uint32_t opcode; - struct nds32_instruction instruction; - struct watchpoint *wp; - bool hit; - - nds32_get_mapped_reg(nds32, PC, &val_pc); - - if ((reason == NDS32_DEBUG_DATA_ADDR_WATCHPOINT_NEXT_PRECISE) || - (reason == NDS32_DEBUG_DATA_VALUE_WATCHPOINT_NEXT_PRECISE)) { - if (edmsw & 0x4) /* check EDMSW.IS_16BIT */ - val_pc -= 2; - else - val_pc -= 4; - } - - nds32_read_opcode(nds32, val_pc, &opcode); - nds32_evaluate_opcode(nds32, opcode, val_pc, &instruction); - - LOG_DEBUG("PC: 0x%08" PRIx32 ", access start: 0x%08" PRIx32 ", end: 0x%08" PRIx32, - val_pc, instruction.access_start, instruction.access_end); - - /* check if multiple hits in the access range */ - uint32_t in_range_watch_count = 0; - for (wp = target->watchpoints; wp; wp = wp->next) { - if ((instruction.access_start <= wp->address) && - (wp->address < instruction.access_end)) - in_range_watch_count++; - } - if (in_range_watch_count > 1) { - /* Hit LSMW instruction. */ - *address = 0; - return ERROR_OK; - } - - /* dispel false match */ - hit = false; - for (wp = target->watchpoints; wp; wp = wp->next) { - if (((*address ^ wp->address) & (~wp->mask)) == 0) { - uint32_t watch_start; - uint32_t watch_end; - - watch_start = wp->address; - watch_end = wp->address + wp->length; - - if ((watch_end <= instruction.access_start) || - (instruction.access_end <= watch_start)) - continue; - - hit = true; - break; - } - } - - if (hit) - return ERROR_OK; - else - return ERROR_FAIL; - } else if (match_count == 0) { - /* global stop is precise exception */ - if ((reason == NDS32_DEBUG_LOAD_STORE_GLOBAL_STOP) && nds32->global_stop) { - /* parse instruction to get correct access address */ - uint32_t val_pc; - uint32_t opcode; - struct nds32_instruction instruction; - - nds32_get_mapped_reg(nds32, PC, &val_pc); - nds32_read_opcode(nds32, val_pc, &opcode); - nds32_evaluate_opcode(nds32, opcode, val_pc, &instruction); - - *address = instruction.access_start; - - return ERROR_OK; - } - } - - *address = 0xFFFFFFFF; - return ERROR_FAIL; -} - -void nds32_v3_common_register_callback(struct nds32_v3_common_callback *callback) -{ - v3_common_callback = callback; -} - -/** target_type functions: */ -/* target request support */ -int nds32_v3_target_request_data(struct target *target, - uint32_t size, uint8_t *buffer) -{ - /* AndesCore could use DTR register to communicate with OpenOCD - * to output messages - * Target data will be put in buffer - * The format of DTR is as follow - * DTR[31:16] => length, DTR[15:8] => size, DTR[7:0] => target_req_cmd - * target_req_cmd has three possible values: - * TARGET_REQ_TRACEMSG - * TARGET_REQ_DEBUGMSG - * TARGET_REQ_DEBUGCHAR - * if size == 0, target will call target_asciimsg(), - * else call target_hexmsg() - */ - LOG_WARNING("Not implemented: %s", __func__); - - return ERROR_OK; -} - -int nds32_v3_checksum_memory(struct target *target, - target_addr_t address, uint32_t count, uint32_t *checksum) -{ - LOG_WARNING("Not implemented: %s", __func__); - - return ERROR_FAIL; -} - -/** - * find out which watchpoint hits - * get exception address and compare the address to watchpoints - */ -int nds32_v3_hit_watchpoint(struct target *target, - struct watchpoint **hit_watchpoint) -{ - static struct watchpoint scan_all_watchpoint; - - uint32_t exception_address; - struct watchpoint *wp; - struct nds32 *nds32 = target_to_nds32(target); - - exception_address = nds32->watched_address; - - if (exception_address == 0xFFFFFFFF) - return ERROR_FAIL; - - if (exception_address == 0) { - scan_all_watchpoint.address = 0; - scan_all_watchpoint.rw = WPT_WRITE; - scan_all_watchpoint.next = 0; - scan_all_watchpoint.unique_id = 0x5CA8; - - *hit_watchpoint = &scan_all_watchpoint; - return ERROR_OK; - } - - for (wp = target->watchpoints; wp; wp = wp->next) { - if (((exception_address ^ wp->address) & (~wp->mask)) == 0) { - *hit_watchpoint = wp; - - return ERROR_OK; - } - } - - return ERROR_FAIL; -} - -int nds32_v3_target_create_common(struct target *target, struct nds32 *nds32) -{ - nds32->register_map = nds32_v3_register_mapping; - nds32->get_debug_reason = nds32_v3_get_debug_reason; - nds32->enter_debug_state = nds32_v3_debug_entry; - nds32->leave_debug_state = nds32_v3_leave_debug_state; - nds32->get_watched_address = nds32_v3_get_exception_address; - - /* Init target->arch_info in nds32_init_arch_info(). - * After this, user could use target_to_nds32() to get nds32 object */ - nds32_init_arch_info(target, nds32); - - return ERROR_OK; -} - -int nds32_v3_run_algorithm(struct target *target, - int num_mem_params, - struct mem_param *mem_params, - int num_reg_params, - struct reg_param *reg_params, - target_addr_t entry_point, - target_addr_t exit_point, - int timeout_ms, - void *arch_info) -{ - LOG_WARNING("Not implemented: %s", __func__); - - return ERROR_FAIL; -} - -int nds32_v3_read_buffer(struct target *target, target_addr_t address, - uint32_t size, uint8_t *buffer) -{ - struct nds32 *nds32 = target_to_nds32(target); - struct nds32_memory *memory = &(nds32->memory); - - if ((memory->access_channel == NDS_MEMORY_ACC_CPU) && - (target->state != TARGET_HALTED)) { - LOG_WARNING("target was not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - target_addr_t physical_address; - /* BUG: If access range crosses multiple pages, the translation will not correct - * for second page or so. */ - - /* When DEX is set to one, hardware will enforce the following behavior without - * modifying the corresponding control bits in PSW. - * - * Disable all interrupts - * Become superuser mode - * Turn off IT/DT - * Use MMU_CFG.DE as the data access endian - * Use MMU_CFG.DRDE as the device register access endian if MMU_CTL.DREE is asserted - * Disable audio special features - * Disable inline function call - * - * Because hardware will turn off IT/DT by default, it MUST translate virtual address - * to physical address. - */ - if (target->type->virt2phys(target, address, &physical_address) == ERROR_OK) - address = physical_address; - else - return ERROR_FAIL; - - int result; - struct aice_port_s *aice = target_to_aice(target); - /* give arbitrary initial value to avoid warning messages */ - enum nds_memory_access origin_access_channel = NDS_MEMORY_ACC_CPU; - - if (nds32->hit_syscall) { - /* Use bus mode to access memory during virtual hosting */ - origin_access_channel = memory->access_channel; - memory->access_channel = NDS_MEMORY_ACC_BUS; - aice_memory_access(aice, NDS_MEMORY_ACC_BUS); - } - - result = nds32_read_buffer(target, address, size, buffer); - - if (nds32->hit_syscall) { - /* Restore access_channel after virtual hosting */ - memory->access_channel = origin_access_channel; - aice_memory_access(aice, origin_access_channel); - } - - return result; -} - -int nds32_v3_write_buffer(struct target *target, target_addr_t address, - uint32_t size, const uint8_t *buffer) -{ - struct nds32 *nds32 = target_to_nds32(target); - struct nds32_memory *memory = &(nds32->memory); - - if ((memory->access_channel == NDS_MEMORY_ACC_CPU) && - (target->state != TARGET_HALTED)) { - LOG_WARNING("target was not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - target_addr_t physical_address; - /* BUG: If access range crosses multiple pages, the translation will not correct - * for second page or so. */ - - /* When DEX is set to one, hardware will enforce the following behavior without - * modifying the corresponding control bits in PSW. - * - * Disable all interrupts - * Become superuser mode - * Turn off IT/DT - * Use MMU_CFG.DE as the data access endian - * Use MMU_CFG.DRDE as the device register access endian if MMU_CTL.DREE is asserted - * Disable audio special features - * Disable inline function call - * - * Because hardware will turn off IT/DT by default, it MUST translate virtual address - * to physical address. - */ - if (target->type->virt2phys(target, address, &physical_address) == ERROR_OK) - address = physical_address; - else - return ERROR_FAIL; - - if (nds32->hit_syscall) { - struct aice_port_s *aice = target_to_aice(target); - enum nds_memory_access origin_access_channel; - origin_access_channel = memory->access_channel; - - /* If target has no cache, use BUS mode to access memory. */ - if ((memory->dcache.line_size == 0) - || (memory->dcache.enable == false)) { - /* There is no Dcache or Dcache is disabled. */ - memory->access_channel = NDS_MEMORY_ACC_BUS; - aice_memory_access(aice, NDS_MEMORY_ACC_BUS); - } - - int result; - result = nds32_gdb_fileio_write_memory(nds32, address, size, buffer); - - if (origin_access_channel == NDS_MEMORY_ACC_CPU) { - memory->access_channel = NDS_MEMORY_ACC_CPU; - aice_memory_access(aice, NDS_MEMORY_ACC_CPU); - } - - return result; - } - - return nds32_write_buffer(target, address, size, buffer); -} - -int nds32_v3_read_memory(struct target *target, target_addr_t address, - uint32_t size, uint32_t count, uint8_t *buffer) -{ - struct nds32 *nds32 = target_to_nds32(target); - struct nds32_memory *memory = &(nds32->memory); - - if ((memory->access_channel == NDS_MEMORY_ACC_CPU) && - (target->state != TARGET_HALTED)) { - LOG_WARNING("target was not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - target_addr_t physical_address; - /* BUG: If access range crosses multiple pages, the translation will not correct - * for second page or so. */ - - /* When DEX is set to one, hardware will enforce the following behavior without - * modifying the corresponding control bits in PSW. - * - * Disable all interrupts - * Become superuser mode - * Turn off IT/DT - * Use MMU_CFG.DE as the data access endian - * Use MMU_CFG.DRDE as the device register access endian if MMU_CTL.DREE is asserted - * Disable audio special features - * Disable inline function call - * - * Because hardware will turn off IT/DT by default, it MUST translate virtual address - * to physical address. - */ - if (target->type->virt2phys(target, address, &physical_address) == ERROR_OK) - address = physical_address; - else - return ERROR_FAIL; - - struct aice_port_s *aice = target_to_aice(target); - /* give arbitrary initial value to avoid warning messages */ - enum nds_memory_access origin_access_channel = NDS_MEMORY_ACC_CPU; - int result; - - if (nds32->hit_syscall) { - /* Use bus mode to access memory during virtual hosting */ - origin_access_channel = memory->access_channel; - memory->access_channel = NDS_MEMORY_ACC_BUS; - aice_memory_access(aice, NDS_MEMORY_ACC_BUS); - } - - result = nds32_read_memory(target, address, size, count, buffer); - - if (nds32->hit_syscall) { - /* Restore access_channel after virtual hosting */ - memory->access_channel = origin_access_channel; - aice_memory_access(aice, origin_access_channel); - } - - return result; -} - -int nds32_v3_write_memory(struct target *target, target_addr_t address, - uint32_t size, uint32_t count, const uint8_t *buffer) -{ - struct nds32 *nds32 = target_to_nds32(target); - struct nds32_memory *memory = &(nds32->memory); - - if ((memory->access_channel == NDS_MEMORY_ACC_CPU) && - (target->state != TARGET_HALTED)) { - LOG_WARNING("target was not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - target_addr_t physical_address; - /* BUG: If access range crosses multiple pages, the translation will not correct - * for second page or so. */ - - /* When DEX is set to one, hardware will enforce the following behavior without - * modifying the corresponding control bits in PSW. - * - * Disable all interrupts - * Become superuser mode - * Turn off IT/DT - * Use MMU_CFG.DE as the data access endian - * Use MMU_CFG.DRDE as the device register access endian if MMU_CTL.DREE is asserted - * Disable audio special features - * Disable inline function call - * - * Because hardware will turn off IT/DT by default, it MUST translate virtual address - * to physical address. - */ - if (target->type->virt2phys(target, address, &physical_address) == ERROR_OK) - address = physical_address; - else - return ERROR_FAIL; - - return nds32_write_memory(target, address, size, count, buffer); -} - -int nds32_v3_init_target(struct command_context *cmd_ctx, - struct target *target) -{ - /* Initialize anything we can set up without talking to the target */ - struct nds32 *nds32 = target_to_nds32(target); - - nds32_init(nds32); - - target->fileio_info = malloc(sizeof(struct gdb_fileio_info)); - target->fileio_info->identifier = NULL; - - return ERROR_OK; -} diff --git a/src/target/nds32_v3_common.h b/src/target/nds32_v3_common.h deleted file mode 100644 index a98988e..0000000 --- a/src/target/nds32_v3_common.h +++ /dev/null @@ -1,50 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -/*************************************************************************** - * Copyright (C) 2013 Andes Technology * - * Hsiangkai Wang <hkwang@andestech.com> * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_NDS32_V3_COMMON_H -#define OPENOCD_TARGET_NDS32_V3_COMMON_H - -#include "target.h" - -struct nds32_v3_common_callback { - int (*check_interrupt_stack)(struct nds32 *nds32); - int (*restore_interrupt_stack)(struct nds32 *nds32); - int (*activate_hardware_breakpoint)(struct target *target); - int (*activate_hardware_watchpoint)(struct target *target); - int (*deactivate_hardware_breakpoint)(struct target *target); - int (*deactivate_hardware_watchpoint)(struct target *target); -}; - -void nds32_v3_common_register_callback(struct nds32_v3_common_callback *callback); -int nds32_v3_target_request_data(struct target *target, - uint32_t size, uint8_t *buffer); -int nds32_v3_checksum_memory(struct target *target, - target_addr_t address, uint32_t count, uint32_t *checksum); -int nds32_v3_hit_watchpoint(struct target *target, - struct watchpoint **hit_watchpoint); -int nds32_v3_target_create_common(struct target *target, struct nds32 *nds32); -int nds32_v3_run_algorithm(struct target *target, - int num_mem_params, - struct mem_param *mem_params, - int num_reg_params, - struct reg_param *reg_params, - target_addr_t entry_point, - target_addr_t exit_point, - int timeout_ms, - void *arch_info); -int nds32_v3_read_buffer(struct target *target, target_addr_t address, - uint32_t size, uint8_t *buffer); -int nds32_v3_write_buffer(struct target *target, target_addr_t address, - uint32_t size, const uint8_t *buffer); -int nds32_v3_read_memory(struct target *target, target_addr_t address, - uint32_t size, uint32_t count, uint8_t *buffer); -int nds32_v3_write_memory(struct target *target, target_addr_t address, - uint32_t size, uint32_t count, const uint8_t *buffer); -int nds32_v3_init_target(struct command_context *cmd_ctx, - struct target *target); - -#endif /* OPENOCD_TARGET_NDS32_V3_COMMON_H */ diff --git a/src/target/nds32_v3m.c b/src/target/nds32_v3m.c deleted file mode 100644 index 6bc549f..0000000 --- a/src/target/nds32_v3m.c +++ /dev/null @@ -1,495 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -/*************************************************************************** - * Copyright (C) 2013 Andes Technology * - * Hsiangkai Wang <hkwang@andestech.com> * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "breakpoints.h" -#include "nds32_cmd.h" -#include "nds32_aice.h" -#include "nds32_v3m.h" -#include "nds32_v3_common.h" - -static int nds32_v3m_activate_hardware_breakpoint(struct target *target) -{ - struct nds32_v3m_common *nds32_v3m = target_to_nds32_v3m(target); - struct aice_port_s *aice = target_to_aice(target); - struct breakpoint *bp; - unsigned brp_num = nds32_v3m->n_hbr - 1; - - for (bp = target->breakpoints; bp; bp = bp->next) { - if (bp->type == BKPT_SOFT) { - /* already set at nds32_v3m_add_breakpoint() */ - continue; - } else if (bp->type == BKPT_HARD) { - /* set address */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPA0 + brp_num, bp->address); - /* set mask */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPAM0 + brp_num, 0); - - if (nds32_v3m->nds32.memory.address_translation) - /* enable breakpoint (virtual address) */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + brp_num, 0x2); - else - /* enable breakpoint (physical address) */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + brp_num, 0xA); - - LOG_DEBUG("Add hardware BP %u at %08" TARGET_PRIxADDR, brp_num, - bp->address); - - brp_num--; - } else { - return ERROR_FAIL; - } - } - - return ERROR_OK; -} - -static int nds32_v3m_deactivate_hardware_breakpoint(struct target *target) -{ - struct nds32_v3m_common *nds32_v3m = target_to_nds32_v3m(target); - struct aice_port_s *aice = target_to_aice(target); - struct breakpoint *bp; - unsigned brp_num = nds32_v3m->n_hbr - 1; - - for (bp = target->breakpoints; bp; bp = bp->next) { - if (bp->type == BKPT_SOFT) - continue; - else if (bp->type == BKPT_HARD) - /* disable breakpoint */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + brp_num, 0x0); - else - return ERROR_FAIL; - - LOG_DEBUG("Remove hardware BP %u at %08" TARGET_PRIxADDR, brp_num, - bp->address); - - brp_num--; - } - - return ERROR_OK; -} - -static int nds32_v3m_activate_hardware_watchpoint(struct target *target) -{ - struct aice_port_s *aice = target_to_aice(target); - struct nds32_v3m_common *nds32_v3m = target_to_nds32_v3m(target); - struct watchpoint *wp; - int32_t wp_num = 0; - uint32_t wp_config = 0; - bool ld_stop, st_stop; - - if (nds32_v3m->nds32.global_stop) - ld_stop = st_stop = false; - - for (wp = target->watchpoints; wp; wp = wp->next) { - - if (wp_num < nds32_v3m->used_n_wp) { - wp->mask = wp->length - 1; - if ((wp->address % wp->length) != 0) - wp->mask = (wp->mask << 1) + 1; - - if (wp->rw == WPT_READ) - wp_config = 0x3; - else if (wp->rw == WPT_WRITE) - wp_config = 0x5; - else if (wp->rw == WPT_ACCESS) - wp_config = 0x7; - - /* set/unset physical address bit of BPCn according to PSW.DT */ - if (nds32_v3m->nds32.memory.address_translation == false) - wp_config |= 0x8; - - /* set address */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPA0 + wp_num, - wp->address - (wp->address % wp->length)); - /* set mask */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPAM0 + wp_num, wp->mask); - /* enable watchpoint */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + wp_num, wp_config); - - LOG_DEBUG("Add hardware watchpoint %" PRId32 " at %08" TARGET_PRIxADDR - " mask %08" PRIx32, wp_num, wp->address, wp->mask); - - wp_num++; - } else if (nds32_v3m->nds32.global_stop) { - if (wp->rw == WPT_READ) - ld_stop = true; - else if (wp->rw == WPT_WRITE) - st_stop = true; - else if (wp->rw == WPT_ACCESS) - ld_stop = st_stop = true; - } - } - - if (nds32_v3m->nds32.global_stop) { - uint32_t edm_ctl; - aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CTL, &edm_ctl); - if (ld_stop) - edm_ctl |= 0x10; - if (st_stop) - edm_ctl |= 0x20; - aice_write_debug_reg(aice, NDS_EDM_SR_EDM_CTL, edm_ctl); - } - - return ERROR_OK; -} - -static int nds32_v3m_deactivate_hardware_watchpoint(struct target *target) -{ - struct nds32_v3m_common *nds32_v3m = target_to_nds32_v3m(target); - struct aice_port_s *aice = target_to_aice(target); - struct watchpoint *wp; - int32_t wp_num = 0; - bool clean_global_stop = false; - - for (wp = target->watchpoints; wp; wp = wp->next) { - - if (wp_num < nds32_v3m->used_n_wp) { - /* disable watchpoint */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + wp_num, 0x0); - - LOG_DEBUG("Remove hardware watchpoint %" PRId32 " at %08" TARGET_PRIxADDR - " mask %08" PRIx32, wp_num, wp->address, wp->mask); - wp_num++; - } else if (nds32_v3m->nds32.global_stop) { - clean_global_stop = true; - } - } - - if (clean_global_stop) { - uint32_t edm_ctl; - aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CTL, &edm_ctl); - edm_ctl = edm_ctl & (~0x30); - aice_write_debug_reg(aice, NDS_EDM_SR_EDM_CTL, edm_ctl); - } - - return ERROR_OK; -} - -static int nds32_v3m_check_interrupt_stack(struct nds32 *nds32) -{ - uint32_t val_ir0; - uint32_t value; - - /* Save interrupt level */ - nds32_get_mapped_reg(nds32, IR0, &val_ir0); - nds32->current_interrupt_level = (val_ir0 >> 1) & 0x3; - - if (nds32_reach_max_interrupt_level(nds32)) - LOG_ERROR("<-- TARGET ERROR! Reaching the max interrupt stack level %" PRIu32 ". -->", - nds32->current_interrupt_level); - - /* backup $ir6 to avoid suppressed exception overwrite */ - nds32_get_mapped_reg(nds32, IR6, &value); - - return ERROR_OK; -} - -static int nds32_v3m_restore_interrupt_stack(struct nds32 *nds32) -{ - uint32_t value; - - /* get backup value from cache */ - /* then set back to make the register dirty */ - nds32_get_mapped_reg(nds32, IR0, &value); - nds32_set_mapped_reg(nds32, IR0, value); - - nds32_get_mapped_reg(nds32, IR6, &value); - nds32_set_mapped_reg(nds32, IR6, value); - - return ERROR_OK; -} - -static int nds32_v3m_deassert_reset(struct target *target) -{ - int retval; - - CHECK_RETVAL(nds32_poll(target)); - - if (target->state != TARGET_HALTED) { - /* reset only */ - LOG_WARNING("%s: ran after reset and before halt ...", - target_name(target)); - retval = target_halt(target); - if (retval != ERROR_OK) - return retval; - - } - - return ERROR_OK; -} - -static int nds32_v3m_add_breakpoint(struct target *target, - struct breakpoint *breakpoint) -{ - struct nds32_v3m_common *nds32_v3m = target_to_nds32_v3m(target); - struct nds32 *nds32 = &(nds32_v3m->nds32); - int result; - - if (breakpoint->type == BKPT_HARD) { - /* check hardware resource */ - if (nds32_v3m->next_hbr_index < nds32_v3m->next_hwp_index) { - LOG_WARNING("<-- TARGET WARNING! Insert too many " - "hardware breakpoints/watchpoints! " - "The limit of combined hardware " - "breakpoints/watchpoints is %" PRId32 ". -->", - nds32_v3m->n_hbr); - LOG_WARNING("<-- TARGET STATUS: Inserted number of " - "hardware breakpoint: %" PRId32 ", hardware " - "watchpoints: %" PRId32 ". -->", - nds32_v3m->n_hbr - nds32_v3m->next_hbr_index - 1, - nds32_v3m->used_n_wp); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - /* update next place to put hardware breakpoint */ - nds32_v3m->next_hbr_index--; - - /* hardware breakpoint insertion occurs before 'continue' actually */ - return ERROR_OK; - } else if (breakpoint->type == BKPT_SOFT) { - result = nds32_add_software_breakpoint(target, breakpoint); - if (result != ERROR_OK) { - /* auto convert to hardware breakpoint if failed */ - if (nds32->auto_convert_hw_bp) { - /* convert to hardware breakpoint */ - breakpoint->type = BKPT_HARD; - - return nds32_v3m_add_breakpoint(target, breakpoint); - } - } - - return result; - } else /* unrecognized breakpoint type */ - return ERROR_FAIL; - - return ERROR_OK; -} - -static int nds32_v3m_remove_breakpoint(struct target *target, - struct breakpoint *breakpoint) -{ - struct nds32_v3m_common *nds32_v3m = target_to_nds32_v3m(target); - - if (breakpoint->type == BKPT_HARD) { - if (nds32_v3m->next_hbr_index >= nds32_v3m->n_hbr - 1) - return ERROR_FAIL; - - /* update next place to put hardware breakpoint */ - nds32_v3m->next_hbr_index++; - - /* hardware breakpoint removal occurs after 'halted' actually */ - return ERROR_OK; - } else if (breakpoint->type == BKPT_SOFT) { - return nds32_remove_software_breakpoint(target, breakpoint); - } else /* unrecognized breakpoint type */ - return ERROR_FAIL; - - return ERROR_OK; -} - -static int nds32_v3m_add_watchpoint(struct target *target, - struct watchpoint *watchpoint) -{ - struct nds32_v3m_common *nds32_v3m = target_to_nds32_v3m(target); - - /* check hardware resource */ - if (nds32_v3m->next_hwp_index >= nds32_v3m->n_hwp) { - /* No hardware resource */ - if (nds32_v3m->nds32.global_stop) { - LOG_WARNING("<-- TARGET WARNING! The number of " - "watchpoints exceeds the hardware " - "resources. Stop at every load/store " - "instruction to check for watchpoint matches. -->"); - return ERROR_OK; - } - - LOG_WARNING("<-- TARGET WARNING! Insert too many hardware " - "watchpoints! The limit of hardware watchpoints " - "is %" PRId32 ". -->", nds32_v3m->n_hwp); - LOG_WARNING("<-- TARGET STATUS: Inserted number of " - "hardware watchpoint: %" PRId32 ". -->", - nds32_v3m->used_n_wp); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - if (nds32_v3m->next_hwp_index > nds32_v3m->next_hbr_index) { - /* No hardware resource */ - if (nds32_v3m->nds32.global_stop) { - LOG_WARNING("<-- TARGET WARNING! The number of " - "watchpoints exceeds the hardware " - "resources. Stop at every load/store " - "instruction to check for watchpoint matches. -->"); - return ERROR_OK; - } - - LOG_WARNING("<-- TARGET WARNING! Insert too many hardware " - "breakpoints/watchpoints! The limit of combined " - "hardware breakpoints/watchpoints is %" PRId32 ". -->", - nds32_v3m->n_hbr); - LOG_WARNING("<-- TARGET STATUS: Inserted number of " - "hardware breakpoint: %" PRId32 ", hardware " - "watchpoints: %" PRId32 ". -->", - nds32_v3m->n_hbr - nds32_v3m->next_hbr_index - 1, - nds32_v3m->used_n_wp); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - /* update next place to put hardware watchpoint */ - nds32_v3m->next_hwp_index++; - nds32_v3m->used_n_wp++; - - return ERROR_OK; -} - -static int nds32_v3m_remove_watchpoint(struct target *target, - struct watchpoint *watchpoint) -{ - struct nds32_v3m_common *nds32_v3m = target_to_nds32_v3m(target); - - if (nds32_v3m->next_hwp_index <= 0) { - if (nds32_v3m->nds32.global_stop) - return ERROR_OK; - - return ERROR_FAIL; - } - - /* update next place to put hardware watchpoint */ - nds32_v3m->next_hwp_index--; - nds32_v3m->used_n_wp--; - - return ERROR_OK; -} - -static struct nds32_v3_common_callback nds32_v3m_common_callback = { - .check_interrupt_stack = nds32_v3m_check_interrupt_stack, - .restore_interrupt_stack = nds32_v3m_restore_interrupt_stack, - .activate_hardware_breakpoint = nds32_v3m_activate_hardware_breakpoint, - .activate_hardware_watchpoint = nds32_v3m_activate_hardware_watchpoint, - .deactivate_hardware_breakpoint = nds32_v3m_deactivate_hardware_breakpoint, - .deactivate_hardware_watchpoint = nds32_v3m_deactivate_hardware_watchpoint, -}; - -static int nds32_v3m_target_create(struct target *target, Jim_Interp *interp) -{ - struct nds32_v3m_common *nds32_v3m; - - nds32_v3m = calloc(1, sizeof(*nds32_v3m)); - if (!nds32_v3m) - return ERROR_FAIL; - - nds32_v3_common_register_callback(&nds32_v3m_common_callback); - nds32_v3_target_create_common(target, &(nds32_v3m->nds32)); - - return ERROR_OK; -} - -/* talk to the target and set things up */ -static int nds32_v3m_examine(struct target *target) -{ - struct nds32_v3m_common *nds32_v3m = target_to_nds32_v3m(target); - struct nds32 *nds32 = &(nds32_v3m->nds32); - struct aice_port_s *aice = target_to_aice(target); - - if (!target_was_examined(target)) { - CHECK_RETVAL(nds32_edm_config(nds32)); - - if (nds32->reset_halt_as_examine) - CHECK_RETVAL(nds32_reset_halt(nds32)); - } - - uint32_t edm_cfg; - aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CFG, &edm_cfg); - - /* get the number of hardware breakpoints */ - nds32_v3m->n_hbr = (edm_cfg & 0x7) + 1; - nds32_v3m->used_n_wp = 0; - - /* get the number of hardware watchpoints */ - /* If the WP field is hardwired to zero, it means this is a - * simple breakpoint. Otherwise, if the WP field is writable - * then it means this is a regular watchpoints. */ - nds32_v3m->n_hwp = 0; - for (int32_t i = 0 ; i < nds32_v3m->n_hbr ; i++) { - /** check the hardware breakpoint is simple or not */ - uint32_t tmp_value; - aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + i, 0x1); - aice_read_debug_reg(aice, NDS_EDM_SR_BPC0 + i, &tmp_value); - - if (tmp_value) - nds32_v3m->n_hwp++; - } - /* hardware breakpoint is inserted from high index to low index */ - nds32_v3m->next_hbr_index = nds32_v3m->n_hbr - 1; - /* hardware watchpoint is inserted from low index to high index */ - nds32_v3m->next_hwp_index = 0; - - LOG_INFO("%s: total hardware breakpoint %" PRId32 " (simple breakpoint %" PRId32 ")", - target_name(target), nds32_v3m->n_hbr, nds32_v3m->n_hbr - nds32_v3m->n_hwp); - LOG_INFO("%s: total hardware watchpoint %" PRId32, target_name(target), nds32_v3m->n_hwp); - - nds32->target->state = TARGET_RUNNING; - nds32->target->debug_reason = DBG_REASON_NOTHALTED; - - target_set_examined(target); - - return ERROR_OK; -} - -/** Holds methods for NDS32 V3m targets. */ -struct target_type nds32_v3m_target = { - .name = "nds32_v3m", - - .poll = nds32_poll, - .arch_state = nds32_arch_state, - - .target_request_data = nds32_v3_target_request_data, - - .halt = nds32_halt, - .resume = nds32_resume, - .step = nds32_step, - - .assert_reset = nds32_assert_reset, - .deassert_reset = nds32_v3m_deassert_reset, - - /* register access */ - .get_gdb_reg_list = nds32_get_gdb_reg_list, - - /* memory access */ - .read_buffer = nds32_v3_read_buffer, - .write_buffer = nds32_v3_write_buffer, - .read_memory = nds32_v3_read_memory, - .write_memory = nds32_v3_write_memory, - - .checksum_memory = nds32_v3_checksum_memory, - - /* breakpoint/watchpoint */ - .add_breakpoint = nds32_v3m_add_breakpoint, - .remove_breakpoint = nds32_v3m_remove_breakpoint, - .add_watchpoint = nds32_v3m_add_watchpoint, - .remove_watchpoint = nds32_v3m_remove_watchpoint, - .hit_watchpoint = nds32_v3_hit_watchpoint, - - /* MMU */ - .mmu = nds32_mmu, - .virt2phys = nds32_virtual_to_physical, - .read_phys_memory = nds32_read_phys_memory, - .write_phys_memory = nds32_write_phys_memory, - - .run_algorithm = nds32_v3_run_algorithm, - - .commands = nds32_command_handlers, - .target_create = nds32_v3m_target_create, - .init_target = nds32_v3_init_target, - .examine = nds32_v3m_examine, - - .get_gdb_fileio_info = nds32_get_gdb_fileio_info, - .gdb_fileio_end = nds32_gdb_fileio_end, -}; diff --git a/src/target/nds32_v3m.h b/src/target/nds32_v3m.h deleted file mode 100644 index f21dd62..0000000 --- a/src/target/nds32_v3m.h +++ /dev/null @@ -1,40 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -/*************************************************************************** - * Copyright (C) 2013 Andes Technology * - * Hsiangkai Wang <hkwang@andestech.com> * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_NDS32_V3M_H -#define OPENOCD_TARGET_NDS32_V3M_H - -#include "nds32.h" - -struct nds32_v3m_common { - struct nds32 nds32; - - /** number of hardware breakpoints */ - int32_t n_hbr; - - /** number of hardware watchpoints */ - int32_t n_hwp; - - /** number of used hardware watchpoints */ - int32_t used_n_wp; - - /** next hardware breakpoint index */ - /** for simple breakpoints, hardware breakpoints are inserted - * from high index to low index */ - int32_t next_hbr_index; - - /** next hardware watchpoint index */ - /** increase from low index to high index */ - int32_t next_hwp_index; -}; - -static inline struct nds32_v3m_common *target_to_nds32_v3m(struct target *target) -{ - return container_of(target->arch_info, struct nds32_v3m_common, nds32); -} - -#endif /* OPENOCD_TARGET_NDS32_V3M_H */ diff --git a/src/target/target.c b/src/target/target.c index e3a6f95..ae419ac 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -92,9 +92,6 @@ extern struct target_type dsp5680xx_target; extern struct target_type testee_target; extern struct target_type avr32_ap7k_target; extern struct target_type hla_target; -extern struct target_type nds32_v2_target; -extern struct target_type nds32_v3_target; -extern struct target_type nds32_v3m_target; extern struct target_type esp32_target; extern struct target_type esp32s2_target; extern struct target_type esp32s3_target; @@ -132,9 +129,6 @@ static struct target_type *target_types[] = { &testee_target, &avr32_ap7k_target, &hla_target, - &nds32_v2_target, - &nds32_v3_target, - &nds32_v3m_target, &esp32_target, &esp32s2_target, &esp32s3_target, |