1 // SPDX-License-Identifier: GPL-2.0-or-later
3 /***************************************************************************
4 * Copyright (C) 2013 by Andes Technology *
5 * Hsiangkai Wang <hkwang@andestech.com> *
6 ***************************************************************************/
11 #include <helper/system.h>
19 #include <helper/log.h>
20 #include <helper/time_support.h>
21 #include "aice_port.h"
22 #include "aice_pipe.h"
24 #define AICE_PIPE_MAXLINE 8192
27 PROCESS_INFORMATION proc_info
;
29 static HANDLE aice_pipe_output
[2];
30 static HANDLE aice_pipe_input
[2];
32 static int aice_pipe_write(const void *buffer
, int count
)
37 success
= WriteFile(aice_pipe_output
[1], buffer
, count
, &written
, NULL
);
39 LOG_ERROR("(WIN32) write to pipe failed, error code: 0x%08l" PRIx32
, GetLastError());
46 static int aice_pipe_read(void *buffer
, int count
)
51 success
= ReadFile(aice_pipe_input
[0], buffer
, count
, &has_read
, NULL
);
52 if (!success
|| (has_read
== 0)) {
53 LOG_ERROR("(WIN32) read from pipe failed, error code: 0x%08l" PRIx32
, GetLastError());
60 static int aice_pipe_child_init(struct aice_port_param_s
*param
)
62 STARTUPINFO start_info
;
65 ZeroMemory(&proc_info
, sizeof(PROCESS_INFORMATION
));
66 ZeroMemory(&start_info
, sizeof(STARTUPINFO
));
67 start_info
.cb
= sizeof(STARTUPINFO
);
68 start_info
.hStdError
= aice_pipe_input
[1];
69 start_info
.hStdOutput
= aice_pipe_input
[1];
70 start_info
.hStdInput
= aice_pipe_output
[0];
71 start_info
.dwFlags
|= STARTF_USESTDHANDLES
;
73 success
= CreateProcess(NULL
,
85 LOG_ERROR("Create new process failed");
92 static int aice_pipe_parent_init(struct aice_port_param_s
*param
)
94 /* send open to adapter */
95 char line
[AICE_PIPE_MAXLINE
];
96 char command
[AICE_PIPE_MAXLINE
];
98 command
[0] = AICE_OPEN
;
99 set_u16(command
+ 1, param
->vid
);
100 set_u16(command
+ 3, param
->pid
);
102 if (aice_pipe_write(command
, 5) != 5) {
103 LOG_ERROR("write failed\n");
107 if (aice_pipe_read(line
, AICE_PIPE_MAXLINE
) < 0) {
108 LOG_ERROR("read failed\n");
112 if (line
[0] == AICE_OK
)
118 static int aice_pipe_open(struct aice_port_param_s
*param
)
120 SECURITY_ATTRIBUTES attribute
;
122 attribute
.nLength
= sizeof(SECURITY_ATTRIBUTES
);
123 attribute
.bInheritHandle
= TRUE
;
124 attribute
.lpSecurityDescriptor
= NULL
;
126 if (!CreatePipe(&aice_pipe_output
[0], &aice_pipe_output
[1],
127 &attribute
, AICE_PIPE_MAXLINE
)) {
128 LOG_ERROR("Create pipes failed");
131 if (!CreatePipe(&aice_pipe_input
[0], &aice_pipe_input
[1],
132 &attribute
, AICE_PIPE_MAXLINE
)) {
133 LOG_ERROR("Create pipes failed");
137 /* do not inherit aice_pipe_output[1] & aice_pipe_input[0] to child process */
138 if (!SetHandleInformation(aice_pipe_output
[1], HANDLE_FLAG_INHERIT
, 0))
140 if (!SetHandleInformation(aice_pipe_input
[0], HANDLE_FLAG_INHERIT
, 0))
143 aice_pipe_child_init(param
);
145 aice_pipe_parent_init(param
);
152 static int aice_pipe_output
[2];
153 static int aice_pipe_input
[2];
155 static int aice_pipe_write(const void *buffer
, int count
)
157 if (write(aice_pipe_output
[1], buffer
, count
) != count
) {
158 LOG_ERROR("write to pipe failed");
165 static int aice_pipe_read(void *buffer
, int count
)
173 n
= read(aice_pipe_input
[0], buffer
, count
);
175 if ((n
== -1) && (errno
== EAGAIN
)) {
177 if (cur
- then
> 500)
183 LOG_ERROR("read from pipe failed");
191 static int aice_pipe_child_init(struct aice_port_param_s
*param
)
193 close(aice_pipe_output
[1]);
194 close(aice_pipe_input
[0]);
196 if (aice_pipe_output
[0] != STDIN_FILENO
) {
197 if (dup2(aice_pipe_output
[0], STDIN_FILENO
) != STDIN_FILENO
) {
198 LOG_ERROR("Map aice_pipe to STDIN failed");
201 close(aice_pipe_output
[0]);
204 if (aice_pipe_input
[1] != STDOUT_FILENO
) {
205 if (dup2(aice_pipe_input
[1], STDOUT_FILENO
) != STDOUT_FILENO
) {
206 LOG_ERROR("Map aice_pipe to STDOUT failed");
209 close(aice_pipe_input
[1]);
212 if (execl(param
->adapter_name
, param
->adapter_name
, (char *)0) < 0) {
213 LOG_ERROR("Execute aice_pipe failed");
220 static int aice_pipe_parent_init(struct aice_port_param_s
*param
)
222 close(aice_pipe_output
[0]);
223 close(aice_pipe_input
[1]);
225 /* set read end of pipe as non-blocking */
226 if (fcntl(aice_pipe_input
[0], F_SETFL
, O_NONBLOCK
))
229 /* send open to adapter */
230 char line
[AICE_PIPE_MAXLINE
];
231 char command
[AICE_PIPE_MAXLINE
];
233 command
[0] = AICE_OPEN
;
234 set_u16(command
+ 1, param
->vid
);
235 set_u16(command
+ 3, param
->pid
);
237 if (aice_pipe_write(command
, 5) != 5) {
238 LOG_ERROR("write failed\n");
242 if (aice_pipe_read(line
, AICE_PIPE_MAXLINE
) < 0) {
243 LOG_ERROR("read failed\n");
247 if (line
[0] == AICE_OK
)
253 static void sig_pipe(int signo
)
258 static int aice_pipe_open(struct aice_port_param_s
*param
)
262 if (signal(SIGPIPE
, sig_pipe
) == SIG_ERR
) {
263 LOG_ERROR("Register SIGPIPE handler failed");
267 if (pipe(aice_pipe_output
) < 0 || pipe(aice_pipe_input
) < 0) {
268 LOG_ERROR("Create pipes failed");
274 LOG_ERROR("Fork new process failed");
276 } else if (pid
== 0) {
277 if (aice_pipe_child_init(param
) != ERROR_OK
) {
278 LOG_ERROR("AICE_PIPE child process initial error");
281 if (aice_pipe_parent_init(param
) != ERROR_OK
) {
282 LOG_ERROR("AICE_PIPE parent process initial error");
292 static int aice_pipe_close(void)
294 char line
[AICE_PIPE_MAXLINE
];
295 char command
[AICE_PIPE_MAXLINE
];
297 command
[0] = AICE_CLOSE
;
299 if (aice_pipe_write(command
, 1) != 1)
302 if (aice_pipe_read(line
, AICE_PIPE_MAXLINE
) < 0)
305 if (line
[0] == AICE_OK
) {
307 WaitForSingleObject(proc_info
.hProcess
, INFINITE
);
308 CloseHandle(proc_info
.hProcess
);
309 CloseHandle(proc_info
.hThread
);
316 static int aice_pipe_idcode(uint32_t *idcode
, uint8_t *num_of_idcode
)
318 char line
[AICE_PIPE_MAXLINE
];
319 char command
[AICE_PIPE_MAXLINE
];
321 command
[0] = AICE_IDCODE
;
323 if (aice_pipe_write(command
, 1) != 1)
326 if (aice_pipe_read(line
, AICE_PIPE_MAXLINE
) < 0)
329 *num_of_idcode
= line
[0];
331 if ((*num_of_idcode
== 0) || (*num_of_idcode
>= 16))
334 for (int i
= 0 ; i
< *num_of_idcode
; i
++)
335 idcode
[i
] = get_u32(line
+ i
* 4 + 1);
340 static int aice_pipe_state(uint32_t coreid
, enum aice_target_state_s
*state
)
342 char line
[AICE_PIPE_MAXLINE
];
343 char command
[AICE_PIPE_MAXLINE
];
345 command
[0] = AICE_STATE
;
347 if (aice_pipe_write(command
, 1) != 1)
350 if (aice_pipe_read(line
, AICE_PIPE_MAXLINE
) < 0)
353 *state
= (enum aice_target_state_s
)line
[0];
358 static int aice_pipe_reset(void)
360 char line
[AICE_PIPE_MAXLINE
];
361 char command
[AICE_PIPE_MAXLINE
];
363 command
[0] = AICE_RESET
;
365 if (aice_pipe_write(command
, 1) != 1)
368 if (aice_pipe_read(line
, AICE_PIPE_MAXLINE
) < 0)
371 if (line
[0] == AICE_OK
)
377 static int aice_pipe_assert_srst(uint32_t coreid
, enum aice_srst_type_s srst
)
379 char line
[AICE_PIPE_MAXLINE
];
380 char command
[AICE_PIPE_MAXLINE
];
382 command
[0] = AICE_ASSERT_SRST
;
385 if (aice_pipe_write(command
, 2) != 2)
388 if (aice_pipe_read(line
, AICE_PIPE_MAXLINE
) < 0)
391 if (line
[0] == AICE_OK
)
397 static int aice_pipe_run(uint32_t coreid
)
399 char line
[AICE_PIPE_MAXLINE
];
400 char command
[AICE_PIPE_MAXLINE
];
402 command
[0] = AICE_RUN
;
404 if (aice_pipe_write(command
, 1) != 1)
407 if (aice_pipe_read(line
, AICE_PIPE_MAXLINE
) < 0)
410 if (line
[0] == AICE_OK
)
416 static int aice_pipe_halt(uint32_t coreid
)
418 char line
[AICE_PIPE_MAXLINE
];
419 char command
[AICE_PIPE_MAXLINE
];
421 command
[0] = AICE_HALT
;
423 if (aice_pipe_write(command
, 1) != 1)
426 if (aice_pipe_read(line
, AICE_PIPE_MAXLINE
) < 0)
429 if (line
[0] == AICE_OK
)
435 static int aice_pipe_read_reg(uint32_t coreid
, uint32_t num
, uint32_t *val
)
437 char line
[AICE_PIPE_MAXLINE
];
438 char command
[AICE_PIPE_MAXLINE
];
440 command
[0] = AICE_READ_REG
;
441 set_u32(command
+ 1, num
);
443 if (aice_pipe_write(command
, 5) != 5)
446 if (aice_pipe_read(line
, AICE_PIPE_MAXLINE
) < 0)
449 *val
= get_u32(line
);
454 static int aice_pipe_write_reg(uint32_t coreid
, uint32_t num
, uint32_t val
)
456 char line
[AICE_PIPE_MAXLINE
];
457 char command
[AICE_PIPE_MAXLINE
];
459 command
[0] = AICE_WRITE_REG
;
460 set_u32(command
+ 1, num
);
461 set_u32(command
+ 5, val
);
463 if (aice_pipe_write(command
, 9) != 9)
466 if (aice_pipe_read(line
, AICE_PIPE_MAXLINE
) < 0)
469 if (line
[0] == AICE_OK
)
475 static int aice_pipe_read_reg_64(uint32_t coreid
, uint32_t num
, uint64_t *val
)
477 char line
[AICE_PIPE_MAXLINE
];
478 char command
[AICE_PIPE_MAXLINE
];
480 command
[0] = AICE_READ_REG_64
;
481 set_u32(command
+ 1, num
);
483 if (aice_pipe_write(command
, 5) != 5)
486 if (aice_pipe_read(line
, AICE_PIPE_MAXLINE
) < 0)
489 *val
= (((uint64_t)get_u32(line
+ 4)) << 32) | get_u32(line
);
494 static int aice_pipe_write_reg_64(uint32_t coreid
, uint32_t num
, uint64_t val
)
496 char line
[AICE_PIPE_MAXLINE
];
497 char command
[AICE_PIPE_MAXLINE
];
499 command
[0] = AICE_WRITE_REG_64
;
500 set_u32(command
+ 1, num
);
501 set_u32(command
+ 5, val
& 0xFFFFFFFF);
502 set_u32(command
+ 9, (val
>> 32) & 0xFFFFFFFF);
504 if (aice_pipe_write(command
, 13) != 9)
507 if (aice_pipe_read(line
, AICE_PIPE_MAXLINE
) < 0)
510 if (line
[0] == AICE_OK
)
516 static int aice_pipe_step(uint32_t coreid
)
518 char line
[AICE_PIPE_MAXLINE
];
519 char command
[AICE_PIPE_MAXLINE
];
521 command
[0] = AICE_STEP
;
523 if (aice_pipe_write(command
, 1) != 1)
526 if (aice_pipe_read(line
, AICE_PIPE_MAXLINE
) < 0)
529 if (line
[0] == AICE_OK
)
535 static int aice_pipe_read_mem_unit(uint32_t coreid
, uint32_t addr
, uint32_t size
,
536 uint32_t count
, uint8_t *buffer
)
538 char command
[AICE_PIPE_MAXLINE
];
540 command
[0] = AICE_READ_MEM_UNIT
;
541 set_u32(command
+ 1, addr
);
542 set_u32(command
+ 5, size
);
543 set_u32(command
+ 9, count
);
545 if (aice_pipe_write(command
, 13) != 13)
548 if (aice_pipe_read(buffer
, size
* count
) < 0)
554 static int aice_pipe_write_mem_unit(uint32_t coreid
, uint32_t addr
, uint32_t size
,
555 uint32_t count
, const uint8_t *buffer
)
557 char line
[AICE_PIPE_MAXLINE
];
558 char command
[AICE_PIPE_MAXLINE
];
560 command
[0] = AICE_WRITE_MEM_UNIT
;
561 set_u32(command
+ 1, addr
);
562 set_u32(command
+ 5, size
);
563 set_u32(command
+ 9, count
);
565 /* WRITE_MEM_UNIT|addr|size|count|data */
566 memcpy(command
+ 13, buffer
, size
* count
);
568 if (aice_pipe_write(command
, 13 + size
* count
) < 0)
571 if (aice_pipe_read(line
, AICE_PIPE_MAXLINE
) < 0)
574 if (line
[0] == AICE_OK
)
582 static int aice_pipe_read_mem_bulk(uint32_t coreid
, uint32_t addr
,
583 uint32_t length
, uint8_t *buffer
)
585 char line
[AICE_PIPE_MAXLINE
+ 1];
586 char command
[AICE_PIPE_MAXLINE
];
587 uint32_t remain_len
= length
;
588 uint32_t prepare_len
;
590 uint32_t received_len
;
593 command
[0] = AICE_READ_MEM_BULK
;
594 set_u32(command
+ 1, addr
);
595 set_u32(command
+ 5, length
);
597 if (aice_pipe_write(command
, 9) < 0)
600 while (remain_len
> 0) {
601 if (remain_len
> AICE_PIPE_MAXLINE
)
602 prepare_len
= AICE_PIPE_MAXLINE
;
604 prepare_len
= remain_len
;
608 received_line
= line
;
610 read_len
= aice_pipe_read(received_line
, prepare_len
- received_len
);
613 received_line
+= read_len
;
614 received_len
+= read_len
;
615 } while (received_len
< prepare_len
);
617 if (line
[0] != AICE_OK
)
621 memcpy(buffer
, line
+ 1, prepare_len
);
622 remain_len
-= prepare_len
;
623 buffer
+= prepare_len
;
629 static int aice_pipe_write_mem_bulk(uint32_t coreid
, uint32_t addr
,
630 uint32_t length
, const uint8_t *buffer
)
632 char line
[AICE_PIPE_MAXLINE
];
633 char command
[AICE_PIPE_MAXLINE
+ 4];
634 uint32_t remain_len
= length
;
635 uint32_t written_len
= 0;
638 command
[0] = AICE_WRITE_MEM_BULK
;
639 set_u32(command
+ 1, addr
);
640 set_u32(command
+ 5, length
);
642 /* Send command first */
643 if (aice_pipe_write(command
, 9) < 0)
646 if (aice_pipe_read(line
, AICE_PIPE_MAXLINE
) < 0)
649 if (line
[0] == AICE_ERROR
)
652 while (remain_len
> 0) {
653 if (remain_len
> AICE_PIPE_MAXLINE
)
654 write_len
= AICE_PIPE_MAXLINE
;
656 write_len
= remain_len
;
658 set_u32(command
, write_len
);
659 memcpy(command
+ 4, buffer
+ written_len
, write_len
); /* data only */
661 if (aice_pipe_write(command
, write_len
+ 4) < 0)
664 if (aice_pipe_read(line
, AICE_PIPE_MAXLINE
) < 0)
667 if (line
[0] == AICE_ERROR
)
670 remain_len
-= write_len
;
671 written_len
+= write_len
;
674 if (line
[0] == AICE_OK
)
680 static int aice_pipe_read_debug_reg(uint32_t coreid
, uint32_t addr
, uint32_t *val
)
682 char line
[AICE_PIPE_MAXLINE
];
683 char command
[AICE_PIPE_MAXLINE
];
685 command
[0] = AICE_READ_DEBUG_REG
;
686 set_u32(command
+ 1, addr
);
688 if (aice_pipe_write(command
, 5) != 5)
691 if (aice_pipe_read(line
, AICE_PIPE_MAXLINE
) < 0)
694 *val
= get_u32(line
);
699 static int aice_pipe_write_debug_reg(uint32_t coreid
, uint32_t addr
, const uint32_t val
)
701 char line
[AICE_PIPE_MAXLINE
];
702 char command
[AICE_PIPE_MAXLINE
];
704 command
[0] = AICE_WRITE_DEBUG_REG
;
705 set_u32(command
+ 1, addr
);
706 set_u32(command
+ 5, val
);
708 if (aice_pipe_write(command
, 9) != 9)
711 if (aice_pipe_read(line
, AICE_PIPE_MAXLINE
) < 0)
714 if (line
[0] == AICE_OK
)
720 static int aice_pipe_set_jtag_clock(uint32_t a_clock
)
722 char line
[AICE_PIPE_MAXLINE
];
723 char command
[AICE_PIPE_MAXLINE
];
725 command
[0] = AICE_SET_JTAG_CLOCK
;
726 set_u32(command
+ 1, a_clock
);
728 if (aice_pipe_write(command
, 5) != 5)
731 if (aice_pipe_read(line
, AICE_PIPE_MAXLINE
) < 0)
734 if (line
[0] == AICE_OK
)
740 static int aice_pipe_memory_access(uint32_t coreid
, enum nds_memory_access access_channel
)
742 char line
[AICE_PIPE_MAXLINE
];
743 char command
[AICE_PIPE_MAXLINE
];
745 command
[0] = AICE_MEMORY_ACCESS
;
746 set_u32(command
+ 1, access_channel
);
748 if (aice_pipe_write(command
, 5) != 5)
751 if (aice_pipe_read(line
, AICE_PIPE_MAXLINE
) < 0)
754 if (line
[0] == AICE_OK
)
760 static int aice_pipe_memory_mode(uint32_t coreid
, enum nds_memory_select mem_select
)
762 char line
[AICE_PIPE_MAXLINE
];
763 char command
[AICE_PIPE_MAXLINE
];
765 command
[0] = AICE_MEMORY_MODE
;
766 set_u32(command
+ 1, mem_select
);
768 if (aice_pipe_write(command
, 5) != 5)
771 if (aice_pipe_read(line
, AICE_PIPE_MAXLINE
) < 0)
774 if (line
[0] == AICE_OK
)
780 static int aice_pipe_read_tlb(uint32_t coreid
, target_addr_t virtual_address
,
781 target_addr_t
*physical_address
)
783 char line
[AICE_PIPE_MAXLINE
];
784 char command
[AICE_PIPE_MAXLINE
];
786 command
[0] = AICE_READ_TLB
;
787 set_u32(command
+ 1, virtual_address
);
789 if (aice_pipe_write(command
, 5) != 5)
792 if (aice_pipe_read(line
, AICE_PIPE_MAXLINE
) < 0)
795 if (line
[0] == AICE_OK
) {
796 *physical_address
= get_u32(line
+ 1);
802 static int aice_pipe_cache_ctl(uint32_t coreid
, uint32_t subtype
, uint32_t address
)
804 char line
[AICE_PIPE_MAXLINE
];
805 char command
[AICE_PIPE_MAXLINE
];
807 command
[0] = AICE_CACHE_CTL
;
808 set_u32(command
+ 1, subtype
);
809 set_u32(command
+ 5, address
);
811 if (aice_pipe_write(command
, 9) != 9)
814 if (aice_pipe_read(line
, AICE_PIPE_MAXLINE
) < 0)
817 if (line
[0] == AICE_OK
)
823 static int aice_pipe_set_retry_times(uint32_t a_retry_times
)
829 struct aice_port_api_s aice_pipe
= {
831 .open
= aice_pipe_open
,
833 .close
= aice_pipe_close
,
835 .idcode
= aice_pipe_idcode
,
837 .set_jtag_clock
= aice_pipe_set_jtag_clock
,
839 .state
= aice_pipe_state
,
841 .reset
= aice_pipe_reset
,
843 .assert_srst
= aice_pipe_assert_srst
,
845 .run
= aice_pipe_run
,
847 .halt
= aice_pipe_halt
,
849 .step
= aice_pipe_step
,
851 .read_reg
= aice_pipe_read_reg
,
853 .write_reg
= aice_pipe_write_reg
,
855 .read_reg_64
= aice_pipe_read_reg_64
,
857 .write_reg_64
= aice_pipe_write_reg_64
,
859 .read_mem_unit
= aice_pipe_read_mem_unit
,
861 .write_mem_unit
= aice_pipe_write_mem_unit
,
863 .read_mem_bulk
= aice_pipe_read_mem_bulk
,
865 .write_mem_bulk
= aice_pipe_write_mem_bulk
,
867 .read_debug_reg
= aice_pipe_read_debug_reg
,
869 .write_debug_reg
= aice_pipe_write_debug_reg
,
872 .memory_access
= aice_pipe_memory_access
,
874 .memory_mode
= aice_pipe_memory_mode
,
877 .read_tlb
= aice_pipe_read_tlb
,
880 .cache_ctl
= aice_pipe_cache_ctl
,
883 .set_retry_times
= aice_pipe_set_retry_times
,
Linking to existing account procedure
If you already have an account and want to add another login method
you
MUST first sign in with your existing account and
then change URL to read
https://review.openocd.org/login/?link
to get to this page again but this time it'll work for linking. Thank you.
SSH host keys fingerprints
1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=.. |
|+o.. . |
|*.o . . |
|+B . . . |
|Bo. = o S |
|Oo.+ + = |
|oB=.* = . o |
| =+=.+ + E |
|. .=o . o |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)