1 // SPDX-License-Identifier: GPL-2.0-or-later
3 /***************************************************************************
4 * Xtensa Target File-I/O Support for OpenOCD *
5 * Copyright (C) 2020-2023 Cadence Design Systems, Inc. *
6 ***************************************************************************/
12 #include "xtensa_chip.h"
13 #include "xtensa_fileio.h"
16 #define XTENSA_SYSCALL(x) XT_INS_BREAK(x, 1, 14)
17 #define XTENSA_SYSCALL_SZ 3
18 #define XTENSA_SYSCALL_LEN_MAX 255
21 int xtensa_fileio_init(struct target
*target
)
23 char *idmem
= malloc(XTENSA_SYSCALL_LEN_MAX
+ 1);
24 target
->fileio_info
= malloc(sizeof(struct gdb_fileio_info
));
25 if (!idmem
|| !target
->fileio_info
) {
26 LOG_TARGET_ERROR(target
, "Out of memory!");
28 free(target
->fileio_info
);
31 target
->fileio_info
->identifier
= idmem
;
36 * Checks for and processes an Xtensa File-IO request.
38 * Return ERROR_OK if request was found and handled; or
39 * return ERROR_FAIL if no request was detected.
41 int xtensa_fileio_detect_proc(struct target
*target
)
43 struct xtensa
*xtensa
= target_to_xtensa(target
);
46 xtensa_reg_val_t dbg_cause
= xtensa_cause_get(target
);
47 if ((dbg_cause
& (DEBUGCAUSE_BI
| DEBUGCAUSE_BN
)) == 0 || xtensa
->halt_request
)
50 uint8_t brk_insn_buf
[sizeof(uint32_t)] = {0};
51 xtensa_reg_val_t pc
= xtensa_reg_get(target
, XT_REG_IDX_PC
);
52 retval
= target_read_memory(target
,
56 (uint8_t *)brk_insn_buf
);
57 if (retval
!= ERROR_OK
) {
58 LOG_ERROR("Failed to read break instruction!");
61 if (buf_get_u32(brk_insn_buf
, 0, 32) != XTENSA_SYSCALL(xtensa
))
64 LOG_TARGET_DEBUG(target
, "File-I/O: syscall breakpoint found at 0x%x", pc
);
65 xtensa
->proc_syscall
= true;
69 int xtensa_get_gdb_fileio_info(struct target
*target
, struct gdb_fileio_info
*fileio_info
)
71 /* fill syscall parameters to file-I/O info */
73 LOG_ERROR("File-I/O data structure uninitialized");
77 struct xtensa
*xtensa
= target_to_xtensa(target
);
78 if (!xtensa
->proc_syscall
)
81 xtensa_reg_val_t syscall
= xtensa_reg_get(target
, XTENSA_SYSCALL_OP_REG
);
82 xtensa_reg_val_t arg0
= xtensa_reg_get(target
, XT_REG_IDX_A6
);
83 xtensa_reg_val_t arg1
= xtensa_reg_get(target
, XT_REG_IDX_A3
);
84 xtensa_reg_val_t arg2
= xtensa_reg_get(target
, XT_REG_IDX_A4
);
85 xtensa_reg_val_t arg3
= xtensa_reg_get(target
, XT_REG_IDX_A5
);
86 int retval
= ERROR_OK
;
88 LOG_TARGET_DEBUG(target
, "File-I/O: syscall 0x%x 0x%x 0x%x 0x%x 0x%x",
89 syscall
, arg0
, arg1
, arg2
, arg3
);
92 case XTENSA_SYSCALL_OPEN
:
93 snprintf(fileio_info
->identifier
, XTENSA_SYSCALL_LEN_MAX
, "open");
94 fileio_info
->param_1
= arg0
; // pathp
95 fileio_info
->param_2
= arg3
; // len
96 fileio_info
->param_3
= arg1
; // flags
97 fileio_info
->param_4
= arg2
; // mode
99 case XTENSA_SYSCALL_CLOSE
:
100 snprintf(fileio_info
->identifier
, XTENSA_SYSCALL_LEN_MAX
, "close");
101 fileio_info
->param_1
= arg0
; // fd
103 case XTENSA_SYSCALL_READ
:
104 snprintf(fileio_info
->identifier
, XTENSA_SYSCALL_LEN_MAX
, "read");
105 fileio_info
->param_1
= arg0
; // fd
106 fileio_info
->param_2
= arg1
; // bufp
107 fileio_info
->param_3
= arg2
; // count
109 case XTENSA_SYSCALL_WRITE
:
110 snprintf(fileio_info
->identifier
, XTENSA_SYSCALL_LEN_MAX
, "write");
111 fileio_info
->param_1
= arg0
; // fd
112 fileio_info
->param_2
= arg1
; // bufp
113 fileio_info
->param_3
= arg2
; // count
115 case XTENSA_SYSCALL_LSEEK
:
116 snprintf(fileio_info
->identifier
, XTENSA_SYSCALL_LEN_MAX
, "lseek");
117 fileio_info
->param_1
= arg0
; // fd
118 fileio_info
->param_2
= arg1
; // offset
119 fileio_info
->param_3
= arg2
; // flags
121 case XTENSA_SYSCALL_RENAME
:
122 snprintf(fileio_info
->identifier
, XTENSA_SYSCALL_LEN_MAX
, "rename");
123 fileio_info
->param_1
= arg0
; // old pathp
124 fileio_info
->param_2
= arg3
; // old len
125 fileio_info
->param_3
= arg1
; // new pathp
126 fileio_info
->param_4
= arg2
; // new len
128 case XTENSA_SYSCALL_UNLINK
:
129 snprintf(fileio_info
->identifier
, XTENSA_SYSCALL_LEN_MAX
, "unlink");
130 fileio_info
->param_1
= arg0
; // pathnamep
131 fileio_info
->param_2
= arg1
; // len
133 case XTENSA_SYSCALL_STAT
:
134 snprintf(fileio_info
->identifier
, XTENSA_SYSCALL_LEN_MAX
, "stat");
135 fileio_info
->param_1
= arg0
; // pathnamep
136 fileio_info
->param_2
= arg2
; // len
137 fileio_info
->param_3
= arg1
; // bufp
139 case XTENSA_SYSCALL_FSTAT
:
140 snprintf(fileio_info
->identifier
, XTENSA_SYSCALL_LEN_MAX
, "fstat");
141 fileio_info
->param_1
= arg0
; // fd
142 fileio_info
->param_2
= arg1
; // bufp
144 case XTENSA_SYSCALL_GETTIMEOFDAY
:
145 snprintf(fileio_info
->identifier
, XTENSA_SYSCALL_LEN_MAX
, "gettimeofday");
146 fileio_info
->param_1
= arg0
; // tvp
147 fileio_info
->param_2
= arg1
; // tzp
149 case XTENSA_SYSCALL_ISATTY
:
150 snprintf(fileio_info
->identifier
, XTENSA_SYSCALL_LEN_MAX
, "isatty");
151 fileio_info
->param_1
= arg0
; // fd
153 case XTENSA_SYSCALL_SYSTEM
:
154 snprintf(fileio_info
->identifier
, XTENSA_SYSCALL_LEN_MAX
, "system");
155 fileio_info
->param_1
= arg0
; // cmdp
156 fileio_info
->param_2
= arg1
; // len
159 snprintf(fileio_info
->identifier
, XTENSA_SYSCALL_LEN_MAX
, "unknown");
160 LOG_TARGET_DEBUG(target
, "File-I/O: syscall unknown (%d), pc=0x%08X",
161 syscall
, xtensa_reg_get(target
, XT_REG_IDX_PC
));
162 LOG_INFO("File-I/O: syscall unknown (%d), pc=0x%08X",
163 syscall
, xtensa_reg_get(target
, XT_REG_IDX_PC
));
171 int xtensa_gdb_fileio_end(struct target
*target
, int retcode
, int fileio_errno
, bool ctrl_c
)
173 struct xtensa
*xtensa
= target_to_xtensa(target
);
174 if (!xtensa
->proc_syscall
)
177 LOG_TARGET_DEBUG(target
, "File-I/O: syscall return code: 0x%x, errno: 0x%x , ctrl_c: %s",
178 retcode
, fileio_errno
, ctrl_c
? "true" : "false");
180 /* If interrupt was requested before FIO completion (ERRNO==4), halt and repeat
181 * syscall. Otherwise, set File-I/O Ax and underlying ARx registers, increment PC.
182 * NOTE: sporadic cases of ((ERRNO==4) && !ctrl_c) were observed; most have ctrl_c.
184 if (fileio_errno
!= 4) {
185 xtensa_reg_set_deep_relgen(target
, XTENSA_SYSCALL_RETVAL_REG
, retcode
);
186 xtensa_reg_set_deep_relgen(target
, XTENSA_SYSCALL_ERRNO_REG
, fileio_errno
);
188 xtensa_reg_val_t pc
= xtensa_reg_get(target
, XT_REG_IDX_PC
);
189 xtensa_reg_set(target
, XT_REG_IDX_PC
, pc
+ XTENSA_SYSCALL_SZ
);
192 xtensa
->proc_syscall
= false;
193 xtensa
->halt_request
= true;
194 return ctrl_c
? ERROR_FAIL
: ERROR_OK
;
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)