1 /***************************************************************************
2 * Copyright 2016,2017 Sony Video & Sound Products Inc. *
3 * Masatoshi Tateishi - Masatoshi.Tateishi@jp.sony.com *
4 * Masayuki Ishikawa - Masayuki.Ishikawa@jp.sony.com *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
18 ***************************************************************************/
24 #include <jtag/jtag.h>
25 #include "target/target.h"
26 #include "target/target_type.h"
27 #include "target/armv7m.h"
28 #include "target/cortex_m.h"
30 #include "helper/log.h"
31 #include "helper/types.h"
32 #include "server/gdb_server.h"
34 #include "nuttx_header.h"
37 int rtos_thread_packet(struct connection
*connection
, const char *packet
, int packet_size
);
39 #ifdef CONFIG_DISABLE_SIGNALS
40 #define SIG_QUEUE_NUM 0
42 #define SIG_QUEUE_NUM 1
43 #endif /* CONFIG_DISABLE_SIGNALS */
45 #ifdef CONFIG_DISABLE_MQUEUE
49 #endif /* CONFIG_DISABLE_MQUEUE */
52 #define PAGING_QUEUE_NUM 1
54 #define PAGING_QUEUE_NUM 0
55 #endif /* CONFIG_PAGING */
58 #define TASK_QUEUE_NUM (6 + SIG_QUEUE_NUM + M_QUEUE_NUM + PAGING_QUEUE_NUM)
61 /* see nuttx/sched/os_start.c */
62 static char *nuttx_symbol_list
[] = {
63 "g_readytorun", /* 0: must be top of this array */
68 /* see nuttx/include/nuttx/sched.h */
78 } g_tasklist
[TASK_QUEUE_NUM
];
80 static char *task_state_str
[] = {
87 #ifndef CONFIG_DISABLE_SIGNALS
89 #endif /* CONFIG_DISABLE_SIGNALS */
90 #ifndef CONFIG_DISABLE_MQUEUE
93 #endif /* CONFIG_DISABLE_MQUEUE */
96 #endif /* CONFIG_PAGING */
99 /* see arch/arm/include/armv7-m/irq_cmnvector.h */
100 static const struct stack_register_offset nuttx_stack_offsets_cortex_m
[] = {
101 { ARMV7M_R0
, 0x28, 32 }, /* r0 */
102 { ARMV7M_R1
, 0x2c, 32 }, /* r1 */
103 { ARMV7M_R2
, 0x30, 32 }, /* r2 */
104 { ARMV7M_R3
, 0x34, 32 }, /* r3 */
105 { ARMV7M_R4
, 0x08, 32 }, /* r4 */
106 { ARMV7M_R5
, 0x0c, 32 }, /* r5 */
107 { ARMV7M_R6
, 0x10, 32 }, /* r6 */
108 { ARMV7M_R7
, 0x14, 32 }, /* r7 */
109 { ARMV7M_R8
, 0x18, 32 }, /* r8 */
110 { ARMV7M_R9
, 0x1c, 32 }, /* r9 */
111 { ARMV7M_R10
, 0x20, 32 }, /* r10 */
112 { ARMV7M_R11
, 0x24, 32 }, /* r11 */
113 { ARMV7M_R12
, 0x38, 32 }, /* r12 */
114 { ARMV7M_R13
, 0, 32 }, /* sp */
115 { ARMV7M_R14
, 0x3c, 32 }, /* lr */
116 { ARMV7M_PC
, 0x40, 32 }, /* pc */
117 { ARMV7M_xPSR
, 0x44, 32 }, /* xPSR */
121 static const struct rtos_register_stacking nuttx_stacking_cortex_m
= {
122 0x48, /* stack_registers_size */
123 -1, /* stack_growth_direction */
124 17, /* num_output_registers */
125 0, /* stack_alignment */
126 nuttx_stack_offsets_cortex_m
/* register_offsets */
129 static const struct stack_register_offset nuttx_stack_offsets_cortex_m_fpu
[] = {
130 { ARMV7M_R0
, 0x6c, 32 }, /* r0 */
131 { ARMV7M_R1
, 0x70, 32 }, /* r1 */
132 { ARMV7M_R2
, 0x74, 32 }, /* r2 */
133 { ARMV7M_R3
, 0x78, 32 }, /* r3 */
134 { ARMV7M_R4
, 0x08, 32 }, /* r4 */
135 { ARMV7M_R5
, 0x0c, 32 }, /* r5 */
136 { ARMV7M_R6
, 0x10, 32 }, /* r6 */
137 { ARMV7M_R7
, 0x14, 32 }, /* r7 */
138 { ARMV7M_R8
, 0x18, 32 }, /* r8 */
139 { ARMV7M_R9
, 0x1c, 32 }, /* r9 */
140 { ARMV7M_R10
, 0x20, 32 }, /* r10 */
141 { ARMV7M_R11
, 0x24, 32 }, /* r11 */
142 { ARMV7M_R12
, 0x7c, 32 }, /* r12 */
143 { ARMV7M_R13
, 0, 32 }, /* sp */
144 { ARMV7M_R14
, 0x80, 32 }, /* lr */
145 { ARMV7M_PC
, 0x84, 32 }, /* pc */
146 { ARMV7M_xPSR
, 0x88, 32 }, /* xPSR */
149 static const struct rtos_register_stacking nuttx_stacking_cortex_m_fpu
= {
150 0x8c, /* stack_registers_size */
151 -1, /* stack_growth_direction */
152 17, /* num_output_registers */
153 0, /* stack_alignment */
154 nuttx_stack_offsets_cortex_m_fpu
/* register_offsets */
157 static int pid_offset
= PID
;
158 static int state_offset
= STATE
;
159 static int name_offset
= NAME
;
160 static int xcpreg_offset
= XCPREG
;
161 static int name_size
= NAME_SIZE
;
163 static int rcmd_offset(const char *cmd
, const char *name
)
165 if (strncmp(cmd
, name
, strlen(name
)))
168 if (strlen(cmd
) <= strlen(name
) + 1)
171 return atoi(cmd
+ strlen(name
));
174 static int nuttx_thread_packet(struct connection
*connection
,
175 char const *packet
, int packet_size
)
177 char cmd
[GDB_BUFFER_SIZE
/ 2 + 1] = ""; /* Extra byte for nul-termination */
179 if (!strncmp(packet
, "qRcmd", 5)) {
180 size_t len
= unhexify((uint8_t *)cmd
, packet
+ 6, sizeof(cmd
));
186 offset
= rcmd_offset(cmd
, "nuttx.pid_offset");
189 LOG_INFO("pid_offset: %d", offset
);
194 offset
= rcmd_offset(cmd
, "nuttx.state_offset");
197 LOG_INFO("state_offset: %d", offset
);
198 state_offset
= offset
;
202 offset
= rcmd_offset(cmd
, "nuttx.name_offset");
205 LOG_INFO("name_offset: %d", offset
);
206 name_offset
= offset
;
210 offset
= rcmd_offset(cmd
, "nuttx.xcpreg_offset");
213 LOG_INFO("xcpreg_offset: %d", offset
);
214 xcpreg_offset
= offset
;
218 offset
= rcmd_offset(cmd
, "nuttx.name_size");
221 LOG_INFO("name_size: %d", offset
);
227 return rtos_thread_packet(connection
, packet
, packet_size
);
229 gdb_put_packet(connection
, "OK", 2);
234 static bool nuttx_detect_rtos(struct target
*target
)
236 if ((target
->rtos
->symbols
!= NULL
) &&
237 (target
->rtos
->symbols
[0].address
!= 0) &&
238 (target
->rtos
->symbols
[1].address
!= 0)) {
244 static int nuttx_create(struct target
*target
)
247 target
->rtos
->gdb_thread_packet
= nuttx_thread_packet
;
248 LOG_INFO("target type name = %s", target
->type
->name
);
252 static int nuttx_update_threads(struct rtos
*rtos
)
254 uint32_t thread_count
;
262 if (rtos
->symbols
== NULL
) {
263 LOG_ERROR("No symbols for NuttX");
267 /* free previous thread details */
268 rtos_free_threadlist(rtos
);
270 ret
= target_read_buffer(rtos
->target
, rtos
->symbols
[1].address
,
271 sizeof(g_tasklist
), (uint8_t *)&g_tasklist
);
273 LOG_ERROR("target_read_buffer : ret = %d\n", ret
);
279 for (i
= 0; i
< TASK_QUEUE_NUM
; i
++) {
281 if (g_tasklist
[i
].addr
== 0)
284 ret
= target_read_u32(rtos
->target
, g_tasklist
[i
].addr
,
288 LOG_ERROR("target_read_u32 : ret = %d\n", ret
);
292 /* readytorun head is current thread */
293 if (g_tasklist
[i
].addr
== rtos
->symbols
[0].address
)
294 rtos
->current_thread
= head
;
299 struct thread_detail
*thread
;
300 ret
= target_read_buffer(rtos
->target
, tcb_addr
,
301 sizeof(tcb
), (uint8_t *)&tcb
);
303 LOG_ERROR("target_read_buffer : ret = %d\n",
309 rtos
->thread_details
= realloc(rtos
->thread_details
,
310 sizeof(struct thread_detail
) * thread_count
);
311 thread
= &rtos
->thread_details
[thread_count
- 1];
312 thread
->threadid
= tcb_addr
;
313 thread
->exists
= true;
315 state
= tcb
.dat
[state_offset
- 8];
316 thread
->extra_info_str
= NULL
;
317 if (state
< sizeof(task_state_str
)/sizeof(char *)) {
318 thread
->extra_info_str
= malloc(256);
319 snprintf(thread
->extra_info_str
, 256, "pid:%d, %s",
320 tcb
.dat
[pid_offset
- 8] |
321 tcb
.dat
[pid_offset
- 8 + 1] << 8,
322 task_state_str
[state
]);
326 thread
->thread_name_str
= malloc(name_size
+ 1);
327 snprintf(thread
->thread_name_str
, name_size
,
328 "%s", (char *)&tcb
.dat
[name_offset
- 8]);
330 thread
->thread_name_str
= malloc(sizeof("None"));
331 strcpy(thread
->thread_name_str
, "None");
334 tcb_addr
= tcb
.flink
;
337 rtos
->thread_count
= thread_count
;
344 * thread_id = tcb address;
346 static int nuttx_get_thread_reg_list(struct rtos
*rtos
, int64_t thread_id
,
347 struct rtos_reg
**reg_list
, int *num_regs
)
351 /* Check for armv7m with *enabled* FPU, i.e. a Cortex-M4F */
352 bool cm4_fpu_enabled
= false;
353 struct armv7m_common
*armv7m_target
= target_to_armv7m(rtos
->target
);
354 if (is_armv7m(armv7m_target
)) {
355 if (armv7m_target
->fp_feature
== FPv4_SP
) {
356 /* Found ARM v7m target which includes a FPU */
359 retval
= target_read_u32(rtos
->target
, FPU_CPACR
, &cpacr
);
360 if (retval
!= ERROR_OK
) {
361 LOG_ERROR("Could not read CPACR register to check FPU state");
365 /* Check if CP10 and CP11 are set to full access. */
366 if (cpacr
& 0x00F00000) {
367 /* Found target with enabled FPU */
373 const struct rtos_register_stacking
*stacking
;
375 stacking
= &nuttx_stacking_cortex_m_fpu
;
377 stacking
= &nuttx_stacking_cortex_m
;
379 return rtos_generic_stack_read(rtos
->target
, stacking
,
380 (uint32_t)thread_id
+ xcpreg_offset
, reg_list
, num_regs
);
383 static int nuttx_get_symbol_list_to_lookup(symbol_table_elem_t
*symbol_list
[])
387 *symbol_list
= (symbol_table_elem_t
*) calloc(1,
388 sizeof(symbol_table_elem_t
) * ARRAY_SIZE(nuttx_symbol_list
));
390 for (i
= 0; i
< ARRAY_SIZE(nuttx_symbol_list
); i
++)
391 (*symbol_list
)[i
].symbol_name
= nuttx_symbol_list
[i
];
396 struct rtos_type nuttx_rtos
= {
398 .detect_rtos
= nuttx_detect_rtos
,
399 .create
= nuttx_create
,
400 .update_threads
= nuttx_update_threads
,
401 .get_thread_reg_list
= nuttx_get_thread_reg_list
,
402 .get_symbol_list_to_lookup
= nuttx_get_symbol_list_to_lookup
,
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)