aboutsummaryrefslogtreecommitdiff
path: root/src/jtag/aice/aice_pipe.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/jtag/aice/aice_pipe.c')
-rw-r--r--src/jtag/aice/aice_pipe.c915
1 files changed, 915 insertions, 0 deletions
diff --git a/src/jtag/aice/aice_pipe.c b/src/jtag/aice/aice_pipe.c
new file mode 100644
index 00000000..02caa3fe
--- /dev/null
+++ b/src/jtag/aice/aice_pipe.c
@@ -0,0 +1,915 @@
+/***************************************************************************
+ * Copyright (C) 2013 by Andes Technology *
+ * Hsiangkai Wang <hkwang@andestech.com> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef _WIN32
+#include <windows.h>
+#else
+#include <signal.h>
+#endif
+
+#include <helper/log.h>
+#include <helper/time_support.h>
+#include "aice_port.h"
+#include "aice_pipe.h"
+
+#define AICE_PIPE_MAXLINE 8192
+
+#ifdef _WIN32
+PROCESS_INFORMATION proc_info;
+
+HANDLE aice_pipe_output[2];
+HANDLE aice_pipe_input[2];
+
+static int aice_pipe_write(const void *buffer, int count)
+{
+ BOOL success;
+ DWORD written;
+
+ success = WriteFile(aice_pipe_output[1], buffer, count, &written, NULL);
+ if (!success) {
+ LOG_ERROR("(WIN32) write to pipe failed, error code: 0x%08lx", GetLastError());
+ return -1;
+ }
+
+ return written;
+}
+
+static int aice_pipe_read(void *buffer, int count)
+{
+ BOOL success;
+ DWORD has_read;
+
+ success = ReadFile(aice_pipe_input[0], buffer, count, &has_read, NULL);
+ if (!success || (has_read == 0)) {
+ LOG_ERROR("(WIN32) read from pipe failed, error code: 0x%08lx", GetLastError());
+ return -1;
+ }
+
+ return has_read;
+}
+
+static int aice_pipe_child_init(struct aice_port_param_s *param)
+{
+ STARTUPINFO start_info;
+ BOOL success;
+
+ ZeroMemory(&proc_info, sizeof(PROCESS_INFORMATION));
+ ZeroMemory(&start_info, sizeof(STARTUPINFO));
+ start_info.cb = sizeof(STARTUPINFO);
+ start_info.hStdError = aice_pipe_input[1];
+ start_info.hStdOutput = aice_pipe_input[1];
+ start_info.hStdInput = aice_pipe_output[0];
+ start_info.dwFlags |= STARTF_USESTDHANDLES;
+
+ success = CreateProcess(NULL,
+ param->adapter_name,
+ NULL,
+ NULL,
+ TRUE,
+ 0,
+ NULL,
+ NULL,
+ &start_info,
+ &proc_info);
+
+ if (!success) {
+ LOG_ERROR("Create new process failed");
+ return ERROR_FAIL;
+ }
+
+ return ERROR_OK;
+}
+
+static int aice_pipe_parent_init(struct aice_port_param_s *param)
+{
+ /* send open to adapter */
+ char line[AICE_PIPE_MAXLINE];
+ char command[AICE_PIPE_MAXLINE];
+
+ command[0] = AICE_OPEN;
+ set_u16(command + 1, param->vid);
+ set_u16(command + 3, param->pid);
+
+ if (aice_pipe_write(command, 5) != 5) {
+ LOG_ERROR("write failed\n");
+ return ERROR_FAIL;
+ }
+
+ if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) {
+ LOG_ERROR("read failed\n");
+ return ERROR_FAIL;
+ }
+
+ if (line[0] == AICE_OK)
+ return ERROR_OK;
+ else
+ return ERROR_FAIL;
+}
+
+static int aice_pipe_open(struct aice_port_param_s *param)
+{
+ SECURITY_ATTRIBUTES attribute;
+
+ attribute.nLength = sizeof(SECURITY_ATTRIBUTES);
+ attribute.bInheritHandle = TRUE;
+ attribute.lpSecurityDescriptor = NULL;
+
+ if (!CreatePipe(&aice_pipe_output[0], &aice_pipe_output[1],
+ &attribute, AICE_PIPE_MAXLINE)) {
+ LOG_ERROR("Create pipes failed");
+ return ERROR_FAIL;
+ }
+ if (!CreatePipe(&aice_pipe_input[0], &aice_pipe_input[1],
+ &attribute, AICE_PIPE_MAXLINE)) {
+ LOG_ERROR("Create pipes failed");
+ return ERROR_FAIL;
+ }
+
+ /* do not inherit aice_pipe_output[1] & aice_pipe_input[0] to child process */
+ if (!SetHandleInformation(aice_pipe_output[1], HANDLE_FLAG_INHERIT, 0))
+ return ERROR_FAIL;
+ if (!SetHandleInformation(aice_pipe_input[0], HANDLE_FLAG_INHERIT, 0))
+ return ERROR_FAIL;
+
+ aice_pipe_child_init(param);
+
+ aice_pipe_parent_init(param);
+
+ return ERROR_OK;
+}
+
+#else
+
+int aice_pipe_output[2];
+int aice_pipe_input[2];
+
+static int aice_pipe_write(const void *buffer, int count)
+{
+ if (write(aice_pipe_output[1], buffer, count) != count) {
+ LOG_ERROR("write to pipe failed");
+ return -1;
+ }
+
+ return count;
+}
+
+static int aice_pipe_read(void *buffer, int count)
+{
+ int n;
+ long long then, cur;
+
+ then = timeval_ms();
+
+ while (1) {
+ n = read(aice_pipe_input[0], buffer, count);
+
+ if ((n == -1) && (errno == EAGAIN)) {
+ cur = timeval_ms();
+ if (cur - then > 500)
+ keep_alive();
+ continue;
+ } else if (n > 0)
+ break;
+ else {
+ LOG_ERROR("read from pipe failed");
+ break;
+ }
+ }
+
+ return n;
+}
+
+static int aice_pipe_child_init(struct aice_port_param_s *param)
+{
+ close(aice_pipe_output[1]);
+ close(aice_pipe_input[0]);
+
+ if (aice_pipe_output[0] != STDIN_FILENO) {
+ if (dup2(aice_pipe_output[0], STDIN_FILENO) != STDIN_FILENO) {
+ LOG_ERROR("Map aice_pipe to STDIN failed");
+ return ERROR_FAIL;
+ }
+ close(aice_pipe_output[0]);
+ }
+
+ if (aice_pipe_input[1] != STDOUT_FILENO) {
+ if (dup2(aice_pipe_input[1], STDOUT_FILENO) != STDOUT_FILENO) {
+ LOG_ERROR("Map aice_pipe to STDOUT failed");
+ return ERROR_FAIL;
+ }
+ close(aice_pipe_input[1]);
+ }
+
+ if (execl(param->adapter_name, param->adapter_name, (char *)0) < 0) {
+ LOG_ERROR("Execute aice_pipe failed");
+ return ERROR_FAIL;
+ }
+
+ return ERROR_OK;
+}
+
+static int aice_pipe_parent_init(struct aice_port_param_s *param)
+{
+ close(aice_pipe_output[0]);
+ close(aice_pipe_input[1]);
+
+ /* set read end of pipe as non-blocking */
+ if (fcntl(aice_pipe_input[0], F_SETFL, O_NONBLOCK))
+ return ERROR_FAIL;
+
+ /* send open to adapter */
+ char line[AICE_PIPE_MAXLINE];
+ char command[AICE_PIPE_MAXLINE];
+
+ command[0] = AICE_OPEN;
+ set_u16(command + 1, param->vid);
+ set_u16(command + 3, param->pid);
+
+ if (aice_pipe_write(command, 5) != 5) {
+ LOG_ERROR("write failed\n");
+ return ERROR_FAIL;
+ }
+
+ if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) {
+ LOG_ERROR("read failed\n");
+ return ERROR_FAIL;
+ }
+
+ if (line[0] == AICE_OK)
+ return ERROR_OK;
+ else
+ return ERROR_FAIL;
+}
+
+static void sig_pipe(int signo)
+{
+ exit(1);
+}
+
+static int aice_pipe_open(struct aice_port_param_s *param)
+{
+ pid_t pid;
+
+ if (signal(SIGPIPE, sig_pipe) == SIG_ERR) {
+ LOG_ERROR("Register SIGPIPE handler failed");
+ return ERROR_FAIL;
+ }
+
+ if (pipe(aice_pipe_output) < 0 || pipe(aice_pipe_input) < 0) {
+ LOG_ERROR("Create pipes failed");
+ return ERROR_FAIL;
+ }
+
+ pid = fork();
+ if (pid < 0) {
+ LOG_ERROR("Fork new process failed");
+ return ERROR_FAIL;
+ } else if (pid == 0) {
+ if (aice_pipe_child_init(param) != ERROR_OK) {
+ LOG_ERROR("AICE_PIPE child process initial error");
+ return ERROR_FAIL;
+ } else {
+ if (aice_pipe_parent_init(param) != ERROR_OK) {
+ LOG_ERROR("AICE_PIPE parent process initial error");
+ return ERROR_FAIL;
+ }
+ }
+ }
+
+ return ERROR_OK;
+}
+#endif
+
+static int aice_pipe_close(void)
+{
+ char line[AICE_PIPE_MAXLINE];
+ char command[AICE_PIPE_MAXLINE];
+
+ command[0] = AICE_CLOSE;
+
+ if (aice_pipe_write(command, 1) != 1)
+ return ERROR_FAIL;
+
+ if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0)
+ return ERROR_FAIL;
+
+ if (line[0] == AICE_OK) {
+#ifdef _WIN32
+ WaitForSingleObject(proc_info.hProcess, INFINITE);
+ CloseHandle(proc_info.hProcess);
+ CloseHandle(proc_info.hThread);
+#endif
+ return ERROR_OK;
+ } else
+ return ERROR_FAIL;
+}
+
+static int aice_pipe_idcode(uint32_t *idcode, uint8_t *num_of_idcode)
+{
+ char line[AICE_PIPE_MAXLINE];
+ char command[AICE_PIPE_MAXLINE];
+
+ command[0] = AICE_IDCODE;
+
+ if (aice_pipe_write(command, 1) != 1)
+ return ERROR_FAIL;
+
+ if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0)
+ return ERROR_FAIL;
+
+ *num_of_idcode = line[0];
+
+ if ((*num_of_idcode == 0) || (*num_of_idcode >= 16))
+ return ERROR_FAIL;
+
+ for (int i = 0 ; i < *num_of_idcode ; i++)
+ idcode[i] = get_u32(line + i * 4 + 1);
+
+ return ERROR_OK;
+}
+
+static int aice_pipe_state(enum aice_target_state_s *state)
+{
+ char line[AICE_PIPE_MAXLINE];
+ char command[AICE_PIPE_MAXLINE];
+
+ command[0] = AICE_STATE;
+
+ if (aice_pipe_write(command, 1) != 1)
+ return ERROR_FAIL;
+
+ if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0)
+ return ERROR_FAIL;
+
+ *state = (enum aice_target_state_s)line[0];
+
+ return ERROR_OK;
+}
+
+static int aice_pipe_reset(void)
+{
+ char line[AICE_PIPE_MAXLINE];
+ char command[AICE_PIPE_MAXLINE];
+
+ command[0] = AICE_RESET;
+
+ if (aice_pipe_write(command, 1) != 1)
+ return ERROR_FAIL;
+
+ if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0)
+ return ERROR_FAIL;
+
+ if (line[0] == AICE_OK)
+ return ERROR_OK;
+ else
+ return ERROR_FAIL;
+}
+
+static int aice_pipe_assert_srst(enum aice_srst_type_s srst)
+{
+ char line[AICE_PIPE_MAXLINE];
+ char command[AICE_PIPE_MAXLINE];
+
+ command[0] = AICE_ASSERT_SRST;
+ command[1] = srst;
+
+ if (aice_pipe_write(command, 2) != 2)
+ return ERROR_FAIL;
+
+ if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0)
+ return ERROR_FAIL;
+
+ if (line[0] == AICE_OK)
+ return ERROR_OK;
+ else
+ return ERROR_FAIL;
+}
+
+static int aice_pipe_run(void)
+{
+ char line[AICE_PIPE_MAXLINE];
+ char command[AICE_PIPE_MAXLINE];
+
+ command[0] = AICE_RUN;
+
+ if (aice_pipe_write(command, 1) != 1)
+ return ERROR_FAIL;
+
+ if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0)
+ return ERROR_FAIL;
+
+ if (line[0] == AICE_OK)
+ return ERROR_OK;
+ else
+ return ERROR_FAIL;
+}
+
+static int aice_pipe_halt(void)
+{
+ char line[AICE_PIPE_MAXLINE];
+ char command[AICE_PIPE_MAXLINE];
+
+ command[0] = AICE_HALT;
+
+ if (aice_pipe_write(command, 1) != 1)
+ return ERROR_FAIL;
+
+ if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0)
+ return ERROR_FAIL;
+
+ if (line[0] == AICE_OK)
+ return ERROR_OK;
+ else
+ return ERROR_FAIL;
+}
+
+static int aice_pipe_read_reg(uint32_t num, uint32_t *val)
+{
+ char line[AICE_PIPE_MAXLINE];
+ char command[AICE_PIPE_MAXLINE];
+
+ command[0] = AICE_READ_REG;
+ set_u32(command + 1, num);
+
+ if (aice_pipe_write(command, 5) != 5)
+ return ERROR_FAIL;
+
+ if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0)
+ return ERROR_FAIL;
+
+ *val = get_u32(line);
+
+ return ERROR_OK;
+}
+
+static int aice_pipe_write_reg(uint32_t num, uint32_t val)
+{
+ char line[AICE_PIPE_MAXLINE];
+ char command[AICE_PIPE_MAXLINE];
+
+ command[0] = AICE_WRITE_REG;
+ set_u32(command + 1, num);
+ set_u32(command + 5, val);
+
+ if (aice_pipe_write(command, 9) != 9)
+ return ERROR_FAIL;
+
+ if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0)
+ return ERROR_FAIL;
+
+ if (line[0] == AICE_OK)
+ return ERROR_OK;
+ else
+ return ERROR_FAIL;
+}
+
+static int aice_pipe_read_reg_64(uint32_t num, uint64_t *val)
+{
+ char line[AICE_PIPE_MAXLINE];
+ char command[AICE_PIPE_MAXLINE];
+
+ command[0] = AICE_READ_REG_64;
+ set_u32(command + 1, num);
+
+ if (aice_pipe_write(command, 5) != 5)
+ return ERROR_FAIL;
+
+ if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0)
+ return ERROR_FAIL;
+
+ *val = (((uint64_t)get_u32(line + 4)) << 32) | get_u32(line);
+
+ return ERROR_OK;
+}
+
+static int aice_pipe_write_reg_64(uint32_t num, uint64_t val)
+{
+ char line[AICE_PIPE_MAXLINE];
+ char command[AICE_PIPE_MAXLINE];
+
+ command[0] = AICE_WRITE_REG_64;
+ set_u32(command + 1, num);
+ set_u32(command + 5, val & 0xFFFFFFFF);
+ set_u32(command + 9, (val >> 32) & 0xFFFFFFFF);
+
+ if (aice_pipe_write(command, 13) != 9)
+ return ERROR_FAIL;
+
+ if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0)
+ return ERROR_FAIL;
+
+ if (line[0] == AICE_OK)
+ return ERROR_OK;
+ else
+ return ERROR_FAIL;
+}
+
+static int aice_pipe_step(void)
+{
+ char line[AICE_PIPE_MAXLINE];
+ char command[AICE_PIPE_MAXLINE];
+
+ command[0] = AICE_STEP;
+
+ if (aice_pipe_write(command, 1) != 1)
+ return ERROR_FAIL;
+
+ if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0)
+ return ERROR_FAIL;
+
+ if (line[0] == AICE_OK)
+ return ERROR_OK;
+ else
+ return ERROR_FAIL;
+}
+
+static int aice_pipe_read_mem_unit(uint32_t addr, uint32_t size,
+ uint32_t count, uint8_t *buffer)
+{
+ char command[AICE_PIPE_MAXLINE];
+
+ command[0] = AICE_READ_MEM_UNIT;
+ set_u32(command + 1, addr);
+ set_u32(command + 5, size);
+ set_u32(command + 9, count);
+
+ if (aice_pipe_write(command, 13) != 13)
+ return ERROR_FAIL;
+
+ if (aice_pipe_read(buffer, size * count) < 0)
+ return ERROR_FAIL;
+
+ return ERROR_OK;
+}
+
+static int aice_pipe_write_mem_unit(uint32_t addr, uint32_t size,
+ uint32_t count, const uint8_t *buffer)
+{
+ char line[AICE_PIPE_MAXLINE];
+ char command[AICE_PIPE_MAXLINE];
+
+ command[0] = AICE_WRITE_MEM_UNIT;
+ set_u32(command + 1, addr);
+ set_u32(command + 5, size);
+ set_u32(command + 9, count);
+
+ /* WRITE_MEM_UNIT|addr|size|count|data */
+ memcpy(command + 13, buffer, size * count);
+
+ if (aice_pipe_write(command, 13 + size * count) < 0)
+ return ERROR_FAIL;
+
+ if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0)
+ return ERROR_FAIL;
+
+ if (line[0] == AICE_OK)
+ return ERROR_OK;
+ else
+ return ERROR_FAIL;
+
+ return ERROR_OK;
+}
+
+static int aice_pipe_read_mem_bulk(uint32_t addr, uint32_t length, uint8_t *buffer)
+{
+ char line[AICE_PIPE_MAXLINE + 1];
+ char command[AICE_PIPE_MAXLINE];
+ uint32_t remain_len = length;
+ uint32_t prepare_len;
+ char *received_line;
+ uint32_t received_len;
+ int read_len;
+
+ command[0] = AICE_READ_MEM_BULK;
+ set_u32(command + 1, addr);
+ set_u32(command + 5, length);
+
+ if (aice_pipe_write(command, 9) < 0)
+ return ERROR_FAIL;
+
+ while (remain_len > 0) {
+ if (remain_len > AICE_PIPE_MAXLINE)
+ prepare_len = AICE_PIPE_MAXLINE;
+ else
+ prepare_len = remain_len;
+
+ prepare_len++;
+ received_len = 0;
+ received_line = line;
+ do {
+ read_len = aice_pipe_read(received_line, prepare_len - received_len);
+ if (read_len < 0)
+ return ERROR_FAIL;
+ received_line += read_len;
+ received_len += read_len;
+ } while (received_len < prepare_len);
+
+ if (line[0] != AICE_OK)
+ return ERROR_FAIL;
+
+ prepare_len--;
+ memcpy(buffer, line + 1, prepare_len);
+ remain_len -= prepare_len;
+ buffer += prepare_len;
+ }
+
+ return ERROR_OK;
+}
+
+static int aice_pipe_write_mem_bulk(uint32_t addr, uint32_t length, const uint8_t *buffer)
+{
+ char line[AICE_PIPE_MAXLINE];
+ char command[AICE_PIPE_MAXLINE + 4];
+ uint32_t remain_len = length;
+ uint32_t written_len = 0;
+ uint32_t write_len;
+
+ command[0] = AICE_WRITE_MEM_BULK;
+ set_u32(command + 1, addr);
+ set_u32(command + 5, length);
+
+ /* Send command first */
+ if (aice_pipe_write(command, 9) < 0)
+ return ERROR_FAIL;
+
+ if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0)
+ return ERROR_FAIL;
+
+ if (line[0] == AICE_ERROR)
+ return ERROR_FAIL;
+
+ while (remain_len > 0) {
+ if (remain_len > AICE_PIPE_MAXLINE)
+ write_len = AICE_PIPE_MAXLINE;
+ else
+ write_len = remain_len;
+
+ set_u32(command, write_len);
+ memcpy(command + 4, buffer + written_len, write_len); /* data only */
+
+ if (aice_pipe_write(command, write_len + 4) < 0)
+ return ERROR_FAIL;
+
+ if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0)
+ return ERROR_FAIL;
+
+ if (line[0] == AICE_ERROR)
+ return ERROR_FAIL;
+
+ remain_len -= write_len;
+ written_len += write_len;
+ }
+
+ if (line[0] == AICE_OK)
+ return ERROR_OK;
+ else
+ return ERROR_FAIL;
+}
+
+static int aice_pipe_read_debug_reg(uint32_t addr, uint32_t *val)
+{
+ char line[AICE_PIPE_MAXLINE];
+ char command[AICE_PIPE_MAXLINE];
+
+ command[0] = AICE_READ_DEBUG_REG;
+ set_u32(command + 1, addr);
+
+ if (aice_pipe_write(command, 5) != 5)
+ return ERROR_FAIL;
+
+ if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0)
+ return ERROR_FAIL;
+
+ *val = get_u32(line);
+
+ return ERROR_OK;
+}
+
+static int aice_pipe_write_debug_reg(uint32_t addr, const uint32_t val)
+{
+ char line[AICE_PIPE_MAXLINE];
+ char command[AICE_PIPE_MAXLINE];
+
+ command[0] = AICE_WRITE_DEBUG_REG;
+ set_u32(command + 1, addr);
+ set_u32(command + 5, val);
+
+ if (aice_pipe_write(command, 9) != 9)
+ return ERROR_FAIL;
+
+ if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0)
+ return ERROR_FAIL;
+
+ if (line[0] == AICE_OK)
+ return ERROR_OK;
+ else
+ return ERROR_FAIL;
+}
+
+static int aice_pipe_set_jtag_clock(uint32_t a_clock)
+{
+ char line[AICE_PIPE_MAXLINE];
+ char command[AICE_PIPE_MAXLINE];
+
+ command[0] = AICE_SET_JTAG_CLOCK;
+ set_u32(command + 1, a_clock);
+
+ if (aice_pipe_write(command, 5) != 5)
+ return ERROR_FAIL;
+
+ if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0)
+ return ERROR_FAIL;
+
+ if (line[0] == AICE_OK)
+ return ERROR_OK;
+ else
+ return ERROR_FAIL;
+}
+
+static int aice_pipe_select_target(uint32_t target_id)
+{
+ char line[AICE_PIPE_MAXLINE];
+ char command[AICE_PIPE_MAXLINE];
+
+ command[0] = AICE_SELECT_TARGET;
+ set_u32(command + 1, target_id);
+
+ if (aice_pipe_write(command, 5) != 5)
+ return ERROR_FAIL;
+
+ if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0)
+ return ERROR_FAIL;
+
+ if (line[0] == AICE_OK)
+ return ERROR_OK;
+ else
+ return ERROR_FAIL;
+}
+
+static int aice_pipe_memory_access(enum nds_memory_access access_channel)
+{
+ char line[AICE_PIPE_MAXLINE];
+ char command[AICE_PIPE_MAXLINE];
+
+ command[0] = AICE_MEMORY_ACCESS;
+ set_u32(command + 1, access_channel);
+
+ if (aice_pipe_write(command, 5) != 5)
+ return ERROR_FAIL;
+
+ if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0)
+ return ERROR_FAIL;
+
+ if (line[0] == AICE_OK)
+ return ERROR_OK;
+ else
+ return ERROR_FAIL;
+}
+
+static int aice_pipe_memory_mode(enum nds_memory_select mem_select)
+{
+ char line[AICE_PIPE_MAXLINE];
+ char command[AICE_PIPE_MAXLINE];
+
+ command[0] = AICE_MEMORY_MODE;
+ set_u32(command + 1, mem_select);
+
+ if (aice_pipe_write(command, 5) != 5)
+ return ERROR_FAIL;
+
+ if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0)
+ return ERROR_FAIL;
+
+ if (line[0] == AICE_OK)
+ return ERROR_OK;
+ else
+ return ERROR_FAIL;
+}
+
+static int aice_pipe_read_tlb(uint32_t virtual_address, uint32_t *physical_address)
+{
+ char line[AICE_PIPE_MAXLINE];
+ char command[AICE_PIPE_MAXLINE];
+
+ command[0] = AICE_READ_TLB;
+ set_u32(command + 1, virtual_address);
+
+ if (aice_pipe_write(command, 5) != 5)
+ return ERROR_FAIL;
+
+ if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0)
+ return ERROR_FAIL;
+
+ if (line[0] == AICE_OK) {
+ *physical_address = get_u32(line + 1);
+ return ERROR_OK;
+ } else
+ return ERROR_FAIL;
+}
+
+static int aice_pipe_cache_ctl(uint32_t subtype, uint32_t address)
+{
+ char line[AICE_PIPE_MAXLINE];
+ char command[AICE_PIPE_MAXLINE];
+
+ command[0] = AICE_CACHE_CTL;
+ set_u32(command + 1, subtype);
+ set_u32(command + 5, address);
+
+ if (aice_pipe_write(command, 9) != 9)
+ return ERROR_FAIL;
+
+ if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0)
+ return ERROR_FAIL;
+
+ if (line[0] == AICE_OK)
+ return ERROR_OK;
+ else
+ return ERROR_FAIL;
+}
+
+static int aice_pipe_set_retry_times(uint32_t a_retry_times)
+{
+ return ERROR_OK;
+}
+
+/** */
+struct aice_port_api_s aice_pipe = {
+ /** */
+ .open = aice_pipe_open,
+ /** */
+ .close = aice_pipe_close,
+ /** */
+ .idcode = aice_pipe_idcode,
+ /** */
+ .state = aice_pipe_state,
+ /** */
+ .reset = aice_pipe_reset,
+ /** */
+ .assert_srst = aice_pipe_assert_srst,
+ /** */
+ .run = aice_pipe_run,
+ /** */
+ .halt = aice_pipe_halt,
+ /** */
+ .step = aice_pipe_step,
+ /** */
+ .read_reg = aice_pipe_read_reg,
+ /** */
+ .write_reg = aice_pipe_write_reg,
+ /** */
+ .read_reg_64 = aice_pipe_read_reg_64,
+ /** */
+ .write_reg_64 = aice_pipe_write_reg_64,
+ /** */
+ .read_mem_unit = aice_pipe_read_mem_unit,
+ /** */
+ .write_mem_unit = aice_pipe_write_mem_unit,
+ /** */
+ .read_mem_bulk = aice_pipe_read_mem_bulk,
+ /** */
+ .write_mem_bulk = aice_pipe_write_mem_bulk,
+ /** */
+ .read_debug_reg = aice_pipe_read_debug_reg,
+ /** */
+ .write_debug_reg = aice_pipe_write_debug_reg,
+
+ /** */
+ .set_jtag_clock = aice_pipe_set_jtag_clock,
+ /** */
+ .select_target = aice_pipe_select_target,
+
+ /** */
+ .memory_access = aice_pipe_memory_access,
+ /** */
+ .memory_mode = aice_pipe_memory_mode,
+
+ /** */
+ .read_tlb = aice_pipe_read_tlb,
+
+ /** */
+ .cache_ctl = aice_pipe_cache_ctl,
+
+ /** */
+ .set_retry_times = aice_pipe_set_retry_times,
+};