1 // SPDX-License-Identifier: GPL-2.0-or-later
3 /***************************************************************************
4 * Copyright (C) 2011 by STEricsson *
5 * Heythem Bouhaja heythem.bouhaja@stericsson.com : creation *
6 * Michel JAOUEN michel.jaouen@stericsson.com : adaptation to rtos *
7 ***************************************************************************/
13 #include <helper/time_support.h>
14 #include <jtag/jtag.h>
15 #include "target/target.h"
16 #include "target/target_type.h"
17 #include "helper/log.h"
18 #include "helper/types.h"
20 #include "rtos_standard_stackings.h"
21 #include <target/register.h>
22 #include <target/smp.h>
23 #include "server/gdb_server.h"
25 #define LINUX_USER_KERNEL_BORDER 0xc0000000
26 #include "linux_header.h"
28 #define MAX_THREADS 200
32 uint32_t init_task_addr
;
35 int preupdtate_threadid_count
;
38 int threads_needs_update
;
39 struct current_thread
*current_threads
;
40 struct threads
*thread_list
;
41 /* virt2phys parameter */
46 struct current_thread
{
53 struct current_thread
*next
;
58 uint32_t base_addr
; /* address to read magic */
59 uint32_t state
; /* magic value : filled only at creation */
60 uint32_t pid
; /* linux pid : id for identifying a thread */
61 uint32_t oncpu
; /* content cpu number in current thread */
62 uint32_t asid
; /* filled only at creation */
64 int status
; /* dead = 1 alive = 2 current = 3 alive and current */
65 /* value that should not change during the live of a thread ? */
66 uint32_t thread_info_addr
; /* contain latest thread_info_addr computed */
67 /* retrieve from thread_info */
68 struct cpu_context
*context
;
83 uint32_t preempt_count
;
85 static struct cpu_context
*cpu_context_read(struct target
*target
, uint32_t base_addr
,
87 static int insert_into_threadlist(struct target
*target
, struct threads
*t
);
89 static int linux_os_create(struct target
*target
);
91 static int linux_os_dummy_update(struct rtos
*rtos
)
93 /* update is done only when thread request come
94 * too many thread to do it on each stop */
98 static int linux_compute_virt2phys(struct target
*target
, target_addr_t address
)
100 struct linux_os
*linux_os
= (struct linux_os
*)
101 target
->rtos
->rtos_specific_params
;
102 target_addr_t pa
= 0;
103 int retval
= target
->type
->virt2phys(target
, address
, &pa
);
104 if (retval
!= ERROR_OK
) {
105 LOG_ERROR("Cannot compute linux virt2phys translation");
106 /* fixes default address */
107 linux_os
->phys_base
= 0;
111 linux_os
->init_task_addr
= address
;
112 address
= address
& linux_os
->phys_mask
;
113 linux_os
->phys_base
= pa
- address
;
117 static int linux_read_memory(struct target
*target
,
118 uint32_t address
, uint32_t size
, uint32_t count
,
122 struct linux_os
*linux_os
= (struct linux_os
*)
123 target
->rtos
->rtos_specific_params
;
124 uint32_t pa
= (address
& linux_os
->phys_mask
) + linux_os
->phys_base
;
126 if (address
< 0xc0000000) {
127 LOG_ERROR("linux awareness : address in user space");
131 target_read_phys_memory(target
, pa
, size
, count
, buffer
);
133 target_read_memory(target
, address
, size
, count
, buffer
);
137 static int fill_buffer(struct target
*target
, uint32_t addr
, uint8_t *buffer
)
140 if ((addr
& 0xfffffffc) != addr
)
141 LOG_INFO("unaligned address %" PRIx32
"!!", addr
);
143 int retval
= linux_read_memory(target
, addr
, 4, 1, buffer
);
148 static uint32_t get_buffer(struct target
*target
, const uint8_t *buffer
)
151 const uint8_t *value_ptr
= buffer
;
152 value
= target_buffer_get_u32(target
, value_ptr
);
156 static int linux_os_thread_reg_list(struct rtos
*rtos
,
157 int64_t thread_id
, struct rtos_reg
**reg_list
, int *num_regs
)
159 struct target
*target
= rtos
->target
;
160 struct linux_os
*linux_os
= (struct linux_os
*)
161 target
->rtos
->rtos_specific_params
;
162 struct current_thread
*tmp
= linux_os
->current_threads
;
163 struct current_thread
*next
;
166 /* check if a current thread is requested */
170 if (next
->threadid
== thread_id
)
174 } while ((found
== 0) && (next
!= tmp
) && (next
));
177 LOG_ERROR("could not find thread: %" PRIx64
, thread_id
);
181 /* search target to perform the access */
182 struct reg
**gdb_reg_list
;
183 struct target_list
*head
;
185 foreach_smp_target(head
, target
->smp_targets
) {
186 if (head
->target
->coreid
== next
->core_id
) {
187 target
= head
->target
;
196 "current thread %" PRIx64
": no target to perform access of core id %" PRIx32
,
202 /*LOG_INFO("thread %lx current on core %x",thread_id, target->coreid);*/
203 retval
= target_get_gdb_reg_list(target
, &gdb_reg_list
, num_regs
, REG_CLASS_GENERAL
);
204 if (retval
!= ERROR_OK
)
207 *reg_list
= calloc(*num_regs
, sizeof(struct rtos_reg
));
209 for (int i
= 0; i
< *num_regs
; ++i
) {
210 if (!gdb_reg_list
[i
]->valid
)
211 gdb_reg_list
[i
]->type
->get(gdb_reg_list
[i
]);
213 (*reg_list
)[i
].number
= gdb_reg_list
[i
]->number
;
214 (*reg_list
)[i
].size
= gdb_reg_list
[i
]->size
;
216 buf_cpy(gdb_reg_list
[i
]->value
, (*reg_list
)[i
].value
, (*reg_list
)[i
].size
);
222 static bool linux_os_detect(struct target
*target
)
224 LOG_INFO("should no be called");
228 static int linux_os_smp_init(struct target
*target
);
229 static int linux_os_clean(struct target
*target
);
231 static const char * const linux_symbol_list
[] = {
236 static int linux_get_symbol_list_to_lookup(struct symbol_table_elem
*symbol_list
[])
239 *symbol_list
= (struct symbol_table_elem
*)
240 calloc(ARRAY_SIZE(linux_symbol_list
), sizeof(struct symbol_table_elem
));
242 for (i
= 0; i
< ARRAY_SIZE(linux_symbol_list
); i
++)
243 (*symbol_list
)[i
].symbol_name
= linux_symbol_list
[i
];
248 static char *linux_ps_command(struct target
*target
);
250 const struct rtos_type linux_rtos
= {
252 .detect_rtos
= linux_os_detect
,
253 .create
= linux_os_create
,
254 .smp_init
= linux_os_smp_init
,
255 .update_threads
= linux_os_dummy_update
,
256 .get_thread_reg_list
= linux_os_thread_reg_list
,
257 .get_symbol_list_to_lookup
= linux_get_symbol_list_to_lookup
,
258 .clean
= linux_os_clean
,
259 .ps_command
= linux_ps_command
,
262 static int linux_thread_packet(struct connection
*connection
, char const *packet
,
264 static void linux_identify_current_threads(struct target
*target
);
267 int fill_task_pid(struct target
*target
, struct threads
*t
)
269 uint32_t pid_addr
= t
->base_addr
+ PID
;
271 int retval
= fill_buffer(target
, pid_addr
, buffer
);
273 if (retval
== ERROR_OK
) {
274 uint32_t val
= get_buffer(target
, buffer
);
277 LOG_ERROR("fill_task_pid: unable to read memory");
283 static int fill_task(struct target
*target
, struct threads
*t
)
286 uint32_t pid_addr
= t
->base_addr
+ PID
;
287 uint32_t mem_addr
= t
->base_addr
+ MEM
;
288 uint32_t on_cpu
= t
->base_addr
+ ONCPU
;
289 uint8_t *buffer
= calloc(1, 4);
290 retval
= fill_buffer(target
, t
->base_addr
, buffer
);
292 if (retval
== ERROR_OK
) {
293 uint32_t val
= get_buffer(target
, buffer
);
296 LOG_ERROR("fill_task: unable to read memory");
298 retval
= fill_buffer(target
, pid_addr
, buffer
);
300 if (retval
== ERROR_OK
) {
301 uint32_t val
= get_buffer(target
, buffer
);
304 LOG_ERROR("fill task: unable to read memory");
306 retval
= fill_buffer(target
, on_cpu
, buffer
);
308 if (retval
== ERROR_OK
) {
309 uint32_t val
= get_buffer(target
, buffer
);
312 LOG_ERROR("fill task: unable to read memory");
314 retval
= fill_buffer(target
, mem_addr
, buffer
);
316 if (retval
== ERROR_OK
) {
317 uint32_t val
= get_buffer(target
, buffer
);
320 uint32_t asid_addr
= val
+ MM_CTX
;
321 retval
= fill_buffer(target
, asid_addr
, buffer
);
323 if (retval
== ERROR_OK
) {
324 val
= get_buffer(target
, buffer
);
328 ("fill task: unable to read memory -- ASID");
332 LOG_ERROR("fill task: unable to read memory");
339 static int get_name(struct target
*target
, struct threads
*t
)
342 uint32_t full_name
[4];
343 uint32_t comm
= t
->base_addr
+ COMM
;
346 for (i
= 0; i
< 17; i
++)
349 retval
= linux_read_memory(target
, comm
, 4, 4, (uint8_t *) full_name
);
351 if (retval
!= ERROR_OK
) {
352 LOG_ERROR("get_name: unable to read memory\n");
356 uint32_t raw_name
= target_buffer_get_u32(target
,
359 t
->name
[3] = raw_name
>> 24;
360 t
->name
[2] = raw_name
>> 16;
361 t
->name
[1] = raw_name
>> 8;
362 t
->name
[0] = raw_name
;
364 target_buffer_get_u32(target
, (const uint8_t *)&full_name
[1]);
365 t
->name
[7] = raw_name
>> 24;
366 t
->name
[6] = raw_name
>> 16;
367 t
->name
[5] = raw_name
>> 8;
368 t
->name
[4] = raw_name
;
370 target_buffer_get_u32(target
, (const uint8_t *)&full_name
[2]);
371 t
->name
[11] = raw_name
>> 24;
372 t
->name
[10] = raw_name
>> 16;
373 t
->name
[9] = raw_name
>> 8;
374 t
->name
[8] = raw_name
;
376 target_buffer_get_u32(target
, (const uint8_t *)&full_name
[3]);
377 t
->name
[15] = raw_name
>> 24;
378 t
->name
[14] = raw_name
>> 16;
379 t
->name
[13] = raw_name
>> 8;
380 t
->name
[12] = raw_name
;
385 static int get_current(struct target
*target
, int create
)
387 struct target_list
*head
;
391 uint8_t *buffer
= calloc(1, 4);
392 struct linux_os
*linux_os
= (struct linux_os
*)
393 target
->rtos
->rtos_specific_params
;
394 struct current_thread
*ctt
= linux_os
->current_threads
;
396 /* invalid current threads content */
399 ctt
->TS
= 0xdeadbeef;
403 foreach_smp_target(head
, target
->smp_targets
) {
404 struct reg
**reg_list
;
408 if (target_get_gdb_reg_list(head
->target
, ®_list
,
409 ®_list_size
, REG_CLASS_GENERAL
) != ERROR_OK
) {
411 return ERROR_TARGET_FAILURE
;
414 if (!reg_list
[13]->valid
)
415 reg_list
[13]->type
->get(reg_list
[13]);
417 buf
= reg_list
[13]->value
;
418 val
= get_buffer(target
, buf
);
419 ti_addr
= (val
& 0xffffe000);
420 uint32_t ts_addr
= ti_addr
+ 0xc;
421 retval
= fill_buffer(target
, ts_addr
, buffer
);
423 if (retval
== ERROR_OK
) {
424 uint32_t TS
= get_buffer(target
, buffer
);
425 uint32_t cpu
, on_cpu
= TS
+ ONCPU
;
426 retval
= fill_buffer(target
, on_cpu
, buffer
);
428 if (retval
== ERROR_OK
) {
429 /*uint32_t cpu = get_buffer(target, buffer);*/
430 struct current_thread
*ct
=
431 linux_os
->current_threads
;
432 cpu
= head
->target
->coreid
;
434 while ((ct
) && (ct
->core_id
!= (int32_t) cpu
))
437 if ((ct
) && (ct
->TS
== 0xdeadbeef))
441 ("error in linux current thread update");
445 t
= calloc(1, sizeof(struct threads
));
446 t
->base_addr
= ct
->TS
;
447 fill_task(target
, t
);
450 insert_into_threadlist(target
, t
);
452 t
->thread_info_addr
= 0xdeadbeef;
453 ct
->threadid
= t
->threadid
;
454 linux_os
->thread_count
++;
458 /*LOG_INFO("Creation of current thread %s",t->name);*/
471 static struct cpu_context
*cpu_context_read(struct target
*target
, uint32_t base_addr
,
472 uint32_t *thread_info_addr_old
)
474 struct cpu_context
*context
= calloc(1, sizeof(struct cpu_context
));
475 uint32_t preempt_count_addr
= 0;
476 uint32_t registers
[10];
477 uint8_t *buffer
= calloc(1, 4);
478 uint32_t stack
= base_addr
+ QAT
;
479 uint32_t thread_info_addr
= 0;
480 uint32_t thread_info_addr_update
= 0;
481 int retval
= ERROR_FAIL
;
482 context
->R4
= 0xdeadbeef;
483 context
->R5
= 0xdeadbeef;
484 context
->R6
= 0xdeadbeef;
485 context
->R7
= 0xdeadbeef;
486 context
->R8
= 0xdeadbeef;
487 context
->R9
= 0xdeadbeef;
488 context
->IP
= 0xdeadbeef;
489 context
->FP
= 0xdeadbeef;
490 context
->SP
= 0xdeadbeef;
491 context
->PC
= 0xdeadbeef;
494 if (*thread_info_addr_old
== 0xdeadbeef) {
495 retval
= fill_buffer(target
, stack
, buffer
);
497 if (retval
== ERROR_OK
)
498 thread_info_addr
= get_buffer(target
, buffer
);
500 LOG_ERROR("cpu_context: unable to read memory");
502 thread_info_addr_update
= thread_info_addr
;
504 thread_info_addr
= *thread_info_addr_old
;
506 preempt_count_addr
= thread_info_addr
+ PREEMPT
;
507 retval
= fill_buffer(target
, preempt_count_addr
, buffer
);
509 if (retval
== ERROR_OK
)
510 context
->preempt_count
= get_buffer(target
, buffer
);
512 if (*thread_info_addr_old
!= 0xdeadbeef) {
514 ("cpu_context: cannot read at thread_info_addr");
516 if (*thread_info_addr_old
< LINUX_USER_KERNEL_BORDER
)
518 ("cpu_context : thread_info_addr in userspace!!!");
520 *thread_info_addr_old
= 0xdeadbeef;
524 LOG_ERROR("cpu_context: unable to read memory");
527 thread_info_addr
+= CPU_CONT
;
529 retval
= linux_read_memory(target
, thread_info_addr
, 4, 10,
530 (uint8_t *) registers
);
532 if (retval
!= ERROR_OK
) {
534 LOG_ERROR("cpu_context: unable to read memory\n");
539 target_buffer_get_u32(target
, (const uint8_t *)®isters
[0]);
541 target_buffer_get_u32(target
, (const uint8_t *)®isters
[1]);
543 target_buffer_get_u32(target
, (const uint8_t *)®isters
[2]);
545 target_buffer_get_u32(target
, (const uint8_t *)®isters
[3]);
547 target_buffer_get_u32(target
, (const uint8_t *)®isters
[4]);
549 target_buffer_get_u32(target
, (const uint8_t *)®isters
[5]);
551 target_buffer_get_u32(target
, (const uint8_t *)®isters
[6]);
553 target_buffer_get_u32(target
, (const uint8_t *)®isters
[7]);
555 target_buffer_get_u32(target
, (const uint8_t *)®isters
[8]);
557 target_buffer_get_u32(target
, (const uint8_t *)®isters
[9]);
559 if (*thread_info_addr_old
== 0xdeadbeef)
560 *thread_info_addr_old
= thread_info_addr_update
;
567 static uint32_t next_task(struct target
*target
, struct threads
*t
)
569 uint8_t *buffer
= calloc(1, 4);
570 uint32_t next_addr
= t
->base_addr
+ NEXT
;
571 int retval
= fill_buffer(target
, next_addr
, buffer
);
573 if (retval
== ERROR_OK
) {
574 uint32_t val
= get_buffer(target
, buffer
);
579 LOG_ERROR("next task: unable to read memory");
586 static struct current_thread
*add_current_thread(struct current_thread
*currents
,
587 struct current_thread
*ct
)
595 struct current_thread
*temp
= currents
;
605 static struct threads
*liste_del_task(struct threads
*task_list
, struct threads
**t
,
606 struct threads
*prev
)
608 LOG_INFO("del task %" PRId64
, (*t
)->threadid
);
610 prev
->next
= (*t
)->next
;
612 task_list
= (*t
)->next
;
614 /* free content of threads */
618 *t
= prev
? prev
: task_list
;
622 static struct threads
*liste_add_task(struct threads
*task_list
, struct threads
*t
,
623 struct threads
**last
)
632 struct threads
*temp
= task_list
;
648 static int current_pid(struct linux_os
*linux_os
, uint32_t pid
)
650 static int current_base_addr(struct linux_os
*linux_os
, uint32_t base_addr
)
653 struct current_thread
*ct
= linux_os
->current_threads
;
656 while ((ct
) && (ct
->pid
!= pid
))
658 while ((ct
) && (ct
->TS
!= base_addr
))
662 if ((ct
) && (ct
->pid
== pid
))
664 if ((ct
) && (ct
->TS
== base_addr
))
671 static int linux_get_tasks(struct target
*target
, int context
)
675 struct linux_os
*linux_os
= (struct linux_os
*)
676 target
->rtos
->rtos_specific_params
;
677 linux_os
->thread_list
= NULL
;
678 linux_os
->thread_count
= 0;
680 if (linux_os
->init_task_addr
== 0xdeadbeef) {
681 LOG_INFO("no init symbol\n");
685 int64_t start
= timeval_ms();
687 struct threads
*t
= calloc(1, sizeof(struct threads
));
688 struct threads
*last
= NULL
;
689 t
->base_addr
= linux_os
->init_task_addr
;
690 /* retrieve the thread id , currently running in the different smp core */
691 get_current(target
, 1);
693 while (((t
->base_addr
!= linux_os
->init_task_addr
) &&
694 (t
->base_addr
!= 0)) || (loop
== 0)) {
696 fill_task(target
, t
);
697 retval
= get_name(target
, t
);
699 if (loop
> MAX_THREADS
) {
701 LOG_INFO("more than %d threads !!", MAX_THREADS
);
705 if (retval
!= ERROR_OK
) {
710 /* check that this thread is not one the current threads already
715 if (!current_pid(linux_os
, t
->pid
)) {
717 if (!current_base_addr(linux_os
, t
->base_addr
)) {
719 t
->threadid
= linux_os
->threadid_count
;
721 linux_os
->threadid_count
++;
723 linux_os
->thread_list
=
724 liste_add_task(linux_os
->thread_list
, t
, &last
);
725 /* no interest to fill the context if it is a current thread. */
726 linux_os
->thread_count
++;
727 t
->thread_info_addr
= 0xdeadbeef;
731 cpu_context_read(target
, t
->base_addr
,
732 &t
->thread_info_addr
);
733 base_addr
= next_task(target
, t
);
735 /*LOG_INFO("thread %s is a current thread already created",t->name); */
736 base_addr
= next_task(target
, t
);
740 t
= calloc(1, sizeof(struct threads
));
741 t
->base_addr
= base_addr
;
744 linux_os
->threads_lookup
= 1;
745 linux_os
->threads_needs_update
= 0;
746 linux_os
->preupdtate_threadid_count
= linux_os
->threadid_count
- 1;
747 /* check that all current threads have been identified */
749 LOG_INFO("complete time %" PRId64
", thread mean %" PRId64
"\n",
750 (timeval_ms() - start
),
751 (timeval_ms() - start
) / linux_os
->threadid_count
);
753 LOG_INFO("threadid count %d", linux_os
->threadid_count
);
759 static int clean_threadlist(struct target
*target
)
761 struct linux_os
*linux_os
= (struct linux_os
*)
762 target
->rtos
->rtos_specific_params
;
763 struct threads
*old
, *temp
= linux_os
->thread_list
;
777 static int linux_os_clean(struct target
*target
)
779 struct linux_os
*os_linux
= (struct linux_os
*)
780 target
->rtos
->rtos_specific_params
;
781 clean_threadlist(target
);
782 os_linux
->init_task_addr
= 0xdeadbeef;
783 os_linux
->name
= "linux";
784 os_linux
->thread_list
= NULL
;
785 os_linux
->thread_count
= 0;
786 os_linux
->nr_cpus
= 0;
787 os_linux
->threads_lookup
= 0;
788 os_linux
->threads_needs_update
= 0;
789 os_linux
->threadid_count
= 1;
793 static int insert_into_threadlist(struct target
*target
, struct threads
*t
)
795 struct linux_os
*linux_os
= (struct linux_os
*)
796 target
->rtos
->rtos_specific_params
;
797 struct threads
*temp
= linux_os
->thread_list
;
798 t
->threadid
= linux_os
->threadid_count
;
799 linux_os
->threadid_count
++;
804 linux_os
->thread_list
= t
;
816 static void linux_identify_current_threads(struct target
*target
)
818 struct linux_os
*linux_os
= (struct linux_os
*)
819 target
->rtos
->rtos_specific_params
;
820 struct threads
*thread_list
= linux_os
->thread_list
;
821 struct current_thread
*ct
= linux_os
->current_threads
;
822 struct threads
*t
= NULL
;
825 if (ct
->threadid
== -1) {
827 /* un-identified thread */
829 t
= calloc(1, sizeof(struct threads
));
830 t
->base_addr
= ct
->TS
;
833 if (fill_task_pid(target
, t
) != ERROR_OK
) {
837 ("linux identify_current_threads: unable to read pid");
842 /* search in the list of threads if pid
844 while ((thread_list
) && (found
== 0)) {
846 if (thread_list
->pid
== t
->pid
) {
848 if (thread_list
->base_addr
== t
->base_addr
) {
854 thread_list
= thread_list
->next
;
858 /* it is a new thread */
859 if (fill_task(target
, t
) != ERROR_OK
)
863 insert_into_threadlist(target
, t
);
864 t
->thread_info_addr
= 0xdeadbeef;
868 ct
->threadid
= t
->threadid
;
872 linux_os
->thread_count
++;
875 LOG_INFO("current thread core %x identified %s",
876 ct
->core_id
, t
->name
);
878 LOG_INFO("current thread core %x, reused %s",
879 ct
->core_id
, t
->name
);
885 tmp
.base_addr
= ct
->TS
;
886 get_name(target
, &tmp
);
887 LOG_INFO("current thread core %x , already identified %s !!!",
888 ct
->core_id
, tmp
.name
);
898 LOG_ERROR("unable to read pid");
904 static int linux_task_update(struct target
*target
, int context
)
906 struct linux_os
*linux_os
= (struct linux_os
*)
907 target
->rtos
->rtos_specific_params
;
908 struct threads
*thread_list
= linux_os
->thread_list
;
911 linux_os
->thread_count
= 0;
913 /*thread_list = thread_list->next; skip init_task*/
914 while (thread_list
) {
915 thread_list
->status
= 0; /*setting all tasks to dead state*/
917 free(thread_list
->context
);
918 thread_list
->context
= NULL
;
920 thread_list
= thread_list
->next
;
925 if (linux_os
->init_task_addr
== 0xdeadbeef) {
926 LOG_INFO("no init symbol\n");
929 int64_t start
= timeval_ms();
930 struct threads
*t
= calloc(1, sizeof(struct threads
));
931 uint32_t previous
= 0xdeadbeef;
932 t
->base_addr
= linux_os
->init_task_addr
;
933 retval
= get_current(target
, 0);
934 /*check that all current threads have been identified */
935 linux_identify_current_threads(target
);
937 while (((t
->base_addr
!= linux_os
->init_task_addr
) &&
938 (t
->base_addr
!= previous
)) || (loop
== 0)) {
939 /* for avoiding any permanent loop for any reason possibly due to
942 previous
= t
->base_addr
;
945 retval
= fill_task_pid(target
, t
);
948 if (retval
!= ERROR_OK
) {
953 thread_list
= linux_os
->thread_list
;
955 while (thread_list
) {
957 if (t
->pid
== thread_list
->pid
) {
959 if (t
->base_addr
== thread_list
->base_addr
) {
961 if (!thread_list
->status
) {
963 if (t
->base_addr
!= thread_list
->base_addr
)
964 LOG_INFO("thread base_addr has changed !!");
966 /* this is not a current thread */
967 thread_list
->base_addr
= t
->base_addr
;
968 thread_list
->status
= 1;
970 /* we don 't update this field any more */
972 /*thread_list->state = t->state;
973 thread_list->oncpu = t->oncpu;
974 thread_list->asid = t->asid;
977 thread_list
->context
=
978 cpu_context_read(target
,
979 thread_list
->base_addr
,
980 &thread_list
->thread_info_addr
);
982 /* it is a current thread no need to read context */
985 linux_os
->thread_count
++;
990 thread_list
= thread_list
->next
;
996 fill_task(target
, t
);
998 retval
= insert_into_threadlist(target
, t
);
999 t
->thread_info_addr
= 0xdeadbeef;
1003 cpu_context_read(target
, t
->base_addr
,
1004 &t
->thread_info_addr
);
1006 base_addr
= next_task(target
, t
);
1007 t
= calloc(1, sizeof(struct threads
));
1008 t
->base_addr
= base_addr
;
1009 linux_os
->thread_count
++;
1011 t
->base_addr
= next_task(target
, t
);
1014 LOG_INFO("update thread done %" PRId64
", mean%" PRId64
"\n",
1015 (timeval_ms() - start
), (timeval_ms() - start
) / loop
);
1017 linux_os
->threads_needs_update
= 0;
1021 static int linux_gdb_thread_packet(struct target
*target
,
1022 struct connection
*connection
, char const *packet
,
1026 struct linux_os
*linux_os
=
1027 (struct linux_os
*)target
->rtos
->rtos_specific_params
;
1029 if (linux_os
->init_task_addr
== 0xdeadbeef) {
1030 /* it has not been initialized */
1031 LOG_INFO("received thread request without init task address");
1032 gdb_put_packet(connection
, "l", 1);
1036 retval
= linux_get_tasks(target
, 1);
1038 if (retval
!= ERROR_OK
)
1039 return ERROR_TARGET_FAILURE
;
1041 char *out_str
= calloc(MAX_THREADS
* 17 + 10, 1);
1042 char *tmp_str
= out_str
;
1043 tmp_str
+= sprintf(tmp_str
, "m");
1044 struct threads
*temp
= linux_os
->thread_list
;
1047 tmp_str
+= sprintf(tmp_str
, "%016" PRIx64
, temp
->threadid
);
1050 tmp_str
+= sprintf(tmp_str
, ",");
1053 gdb_put_packet(connection
, out_str
, strlen(out_str
));
1058 static int linux_gdb_thread_update(struct target
*target
,
1059 struct connection
*connection
, char const *packet
,
1063 struct linux_os
*linux_os
= (struct linux_os
*)
1064 target
->rtos
->rtos_specific_params
;
1065 struct threads
*temp
= linux_os
->thread_list
;
1068 if (temp
->threadid
== linux_os
->preupdtate_threadid_count
+ 1) {
1069 /*LOG_INFO("FOUND");*/
1077 /*LOG_INFO("INTO GDB THREAD UPDATE FOUNDING START TASK");*/
1078 char *out_strr
= calloc(MAX_THREADS
* 17 + 10, 1);
1079 char *tmp_strr
= out_strr
;
1080 tmp_strr
+= sprintf(tmp_strr
, "m");
1081 /*LOG_INFO("CHAR MALLOC & M DONE");*/
1082 tmp_strr
+= sprintf(tmp_strr
, "%016" PRIx64
, temp
->threadid
);
1087 /*LOG_INFO("INTO GDB THREAD UPDATE WHILE");*/
1088 tmp_strr
+= sprintf(tmp_strr
, ",");
1090 sprintf(tmp_strr
, "%016" PRIx64
, temp
->threadid
);
1095 gdb_put_packet(connection
, out_strr
, strlen(out_strr
));
1096 linux_os
->preupdtate_threadid_count
=
1097 linux_os
->threadid_count
- 1;
1100 gdb_put_packet(connection
, "l", 1);
1105 static int linux_thread_extra_info(struct target
*target
,
1106 struct connection
*connection
, char const *packet
,
1109 int64_t threadid
= 0;
1110 struct linux_os
*linux_os
= (struct linux_os
*)
1111 target
->rtos
->rtos_specific_params
;
1112 sscanf(packet
, "qThreadExtraInfo,%" SCNx64
, &threadid
);
1113 /*LOG_INFO("lookup extra info for thread %" SCNx64, threadid);*/
1114 struct threads
*temp
= linux_os
->thread_list
;
1117 if (temp
->threadid
== threadid
) {
1118 char *pid
= " PID: ";
1119 char *pid_current
= "*PID: ";
1120 char *name
= "Name: ";
1121 int str_size
= strlen(pid
) + strlen(name
);
1122 char *tmp_str
= calloc(1, str_size
+ 50);
1123 char *tmp_str_ptr
= tmp_str
;
1125 /* discriminate current task */
1126 if (temp
->status
== 3)
1127 tmp_str_ptr
+= sprintf(tmp_str_ptr
, "%s",
1130 tmp_str_ptr
+= sprintf(tmp_str_ptr
, "%s", pid
);
1132 tmp_str_ptr
+= sprintf(tmp_str_ptr
, "%d, ", (int)temp
->pid
);
1133 sprintf(tmp_str_ptr
, "%s", name
);
1134 sprintf(tmp_str_ptr
, "%s", temp
->name
);
1135 char *hex_str
= calloc(1, strlen(tmp_str
) * 2 + 1);
1136 size_t pkt_len
= hexify(hex_str
, (const uint8_t *)tmp_str
,
1137 strlen(tmp_str
), strlen(tmp_str
) * 2 + 1);
1138 gdb_put_packet(connection
, hex_str
, pkt_len
);
1147 LOG_INFO("thread not found");
1151 static int linux_gdb_t_packet(struct connection
*connection
,
1152 struct target
*target
, char const *packet
, int packet_size
)
1155 struct linux_os
*linux_os
= (struct linux_os
*)
1156 target
->rtos
->rtos_specific_params
;
1157 int retval
= ERROR_OK
;
1158 sscanf(packet
, "T%" SCNx64
, &threadid
);
1160 if (linux_os
->threads_needs_update
== 0) {
1161 struct threads
*temp
= linux_os
->thread_list
;
1162 struct threads
*prev
= NULL
;
1165 if (temp
->threadid
== threadid
) {
1166 if (temp
->status
!= 0) {
1167 gdb_put_packet(connection
, "OK", 2);
1170 /* delete item in the list */
1171 linux_os
->thread_list
=
1172 liste_del_task(linux_os
->thread_list
,
1174 linux_os
->thread_count
--;
1175 gdb_put_packet(connection
, "E01", 3);
1185 LOG_INFO("gdb requested status on non existing thread");
1186 gdb_put_packet(connection
, "E01", 3);
1190 retval
= linux_task_update(target
, 1);
1191 struct threads
*temp
= linux_os
->thread_list
;
1194 if (temp
->threadid
== threadid
) {
1195 if (temp
->status
== 1) {
1196 gdb_put_packet(connection
, "OK", 2);
1199 gdb_put_packet(connection
, "E01", 3);
1211 static int linux_gdb_h_packet(struct connection
*connection
,
1212 struct target
*target
, char const *packet
, int packet_size
)
1214 struct linux_os
*linux_os
= (struct linux_os
*)
1215 target
->rtos
->rtos_specific_params
;
1216 struct current_thread
*ct
= linux_os
->current_threads
;
1218 /* select to display the current thread of the selected target */
1219 while ((ct
) && (ct
->core_id
!= target
->coreid
))
1222 int64_t current_gdb_thread_rq
;
1224 if (linux_os
->threads_lookup
== 1) {
1225 if ((ct
) && (ct
->threadid
== -1)) {
1226 ct
= linux_os
->current_threads
;
1228 while ((ct
) && (ct
->threadid
== -1))
1233 /* no current thread can be identified
1234 * any way with smp */
1235 LOG_INFO("no current thread identified");
1236 /* attempt to display the name of the 2 threads identified with
1239 ct
= linux_os
->current_threads
;
1241 while ((ct
) && (ct
->threadid
== -1)) {
1242 t
.base_addr
= ct
->TS
;
1243 get_name(target
, &t
);
1244 LOG_INFO("name of unidentified thread %s",
1249 gdb_put_packet(connection
, "OK", 2);
1253 if (packet
[1] == 'g') {
1254 sscanf(packet
, "Hg%16" SCNx64
, ¤t_gdb_thread_rq
);
1256 if (current_gdb_thread_rq
== 0) {
1257 target
->rtos
->current_threadid
= ct
->threadid
;
1258 gdb_put_packet(connection
, "OK", 2);
1260 target
->rtos
->current_threadid
=
1261 current_gdb_thread_rq
;
1262 gdb_put_packet(connection
, "OK", 2);
1264 } else if (packet
[1] == 'c') {
1265 sscanf(packet
, "Hc%16" SCNx64
, ¤t_gdb_thread_rq
);
1267 if ((current_gdb_thread_rq
== 0) ||
1268 (current_gdb_thread_rq
== ct
->threadid
)) {
1269 target
->rtos
->current_threadid
= ct
->threadid
;
1270 gdb_put_packet(connection
, "OK", 2);
1272 gdb_put_packet(connection
, "E01", 3);
1275 gdb_put_packet(connection
, "OK", 2);
1280 static int linux_thread_packet(struct connection
*connection
, char const *packet
,
1283 int retval
= ERROR_OK
;
1284 struct current_thread
*ct
;
1285 struct target
*target
= get_target_from_connection(connection
);
1286 struct linux_os
*linux_os
= (struct linux_os
*)
1287 target
->rtos
->rtos_specific_params
;
1289 switch (packet
[0]) {
1290 case 'T': /* Is thread alive?*/
1292 linux_gdb_t_packet(connection
, target
, packet
, packet_size
);
1294 case 'H': /* Set current thread */
1295 /* ( 'c' for step and continue, 'g' for all other operations )*/
1296 /*LOG_INFO(" H packet received '%s'", packet);*/
1297 linux_gdb_h_packet(connection
, target
, packet
, packet_size
);
1301 if (strncmp(packet
, "qSymbol", 7) == 0) {
1302 if (rtos_qsymbol(connection
, packet
, packet_size
) == 1) {
1303 linux_compute_virt2phys(target
,
1304 target
->rtos
->symbols
[INIT_TASK
].address
);
1308 } else if (strncmp(packet
, "qfThreadInfo", 12) == 0) {
1309 if (!linux_os
->thread_list
) {
1310 retval
= linux_gdb_thread_packet(target
,
1316 retval
= linux_gdb_thread_update(target
,
1322 } else if (strncmp(packet
, "qsThreadInfo", 12) == 0) {
1323 gdb_put_packet(connection
, "l", 1);
1325 } else if (strncmp(packet
, "qThreadExtraInfo,", 17) == 0) {
1326 linux_thread_extra_info(target
, connection
, packet
,
1330 retval
= GDB_THREAD_PACKET_NOT_CONSUMED
;
1335 /* previously response was : thread not found
1336 * gdb_put_packet(connection, "E01", 3); */
1337 retval
= GDB_THREAD_PACKET_NOT_CONSUMED
;
1341 if (linux_os
->threads_lookup
== 1) {
1342 ct
= linux_os
->current_threads
;
1344 while ((ct
) && (ct
->core_id
) != target
->coreid
)
1347 if ((ct
) && (ct
->threadid
== -1)) {
1348 ct
= linux_os
->current_threads
;
1350 while ((ct
) && (ct
->threadid
== -1))
1354 if ((ct
) && (ct
->threadid
!=
1355 target
->rtos
->current_threadid
)
1356 && (target
->rtos
->current_threadid
!= -1))
1357 LOG_WARNING("WARNING! current GDB thread do not match "
1358 "current thread running. "
1359 "Switch thread in GDB to threadid %d",
1362 LOG_INFO("threads_needs_update = 1");
1363 linux_os
->threads_needs_update
= 1;
1367 /* if a packet handler returned an error, exit input loop */
1368 if (retval
!= ERROR_OK
)
1375 static int linux_os_smp_init(struct target
*target
)
1377 struct target_list
*head
;
1378 /* keep only target->rtos */
1379 struct rtos
*rtos
= target
->rtos
;
1380 struct linux_os
*os_linux
=
1381 (struct linux_os
*)rtos
->rtos_specific_params
;
1382 struct current_thread
*ct
;
1384 foreach_smp_target(head
, target
->smp_targets
) {
1385 if (head
->target
->rtos
!= rtos
) {
1386 struct linux_os
*smp_os_linux
=
1387 (struct linux_os
*)head
->target
->rtos
->rtos_specific_params
;
1388 /* remap smp target on rtos */
1389 free(head
->target
->rtos
);
1390 head
->target
->rtos
= rtos
;
1391 /* reuse allocated ct */
1392 ct
= smp_os_linux
->current_threads
;
1394 ct
->TS
= 0xdeadbeef;
1395 ct
->core_id
= head
->target
->coreid
;
1396 os_linux
->current_threads
=
1397 add_current_thread(os_linux
->current_threads
, ct
);
1398 os_linux
->nr_cpus
++;
1406 static int linux_os_create(struct target
*target
)
1408 struct linux_os
*os_linux
= calloc(1, sizeof(struct linux_os
));
1409 struct current_thread
*ct
= calloc(1, sizeof(struct current_thread
));
1410 LOG_INFO("linux os creation\n");
1411 os_linux
->init_task_addr
= 0xdeadbeef;
1412 os_linux
->name
= "linux";
1413 os_linux
->thread_list
= NULL
;
1414 os_linux
->thread_count
= 0;
1415 target
->rtos
->current_threadid
= -1;
1416 os_linux
->nr_cpus
= 1;
1417 os_linux
->threads_lookup
= 0;
1418 os_linux
->threads_needs_update
= 0;
1419 os_linux
->threadid_count
= 1;
1420 os_linux
->current_threads
= NULL
;
1421 target
->rtos
->rtos_specific_params
= os_linux
;
1422 ct
->core_id
= target
->coreid
;
1424 ct
->TS
= 0xdeadbeef;
1425 os_linux
->current_threads
=
1426 add_current_thread(os_linux
->current_threads
, ct
);
1427 /* overload rtos thread default handler */
1428 target
->rtos
->gdb_thread_packet
= linux_thread_packet
;
1429 /* initialize a default virt 2 phys translation */
1430 os_linux
->phys_mask
= ~0xc0000000;
1431 os_linux
->phys_base
= 0x0;
1435 static char *linux_ps_command(struct target
*target
)
1437 struct linux_os
*linux_os
= (struct linux_os
*)
1438 target
->rtos
->rtos_specific_params
;
1439 int retval
= ERROR_OK
;
1442 if (linux_os
->threads_lookup
== 0)
1443 retval
= linux_get_tasks(target
, 1);
1445 if (linux_os
->threads_needs_update
!= 0)
1446 retval
= linux_task_update(target
, 0);
1449 if (retval
== ERROR_OK
) {
1450 struct threads
*temp
= linux_os
->thread_list
;
1452 LOG_INFO("allocation for %d threads line",
1453 linux_os
->thread_count
);
1454 display
= calloc((linux_os
->thread_count
+ 2) * 80, 1);
1460 tmp
+= sprintf(tmp
, "PID\t\tCPU\t\tASID\t\tNAME\n");
1461 tmp
+= sprintf(tmp
, "---\t\t---\t\t----\t\t----\n");
1468 "%" PRIu32
"\t\t%" PRIu32
"\t\t%" PRIx32
"\t\t%s\n",
1469 temp
->pid
, temp
->oncpu
,
1470 temp
->asid
, temp
->name
);
1474 "%" PRIu32
"\t\t%" PRIu32
"\t\t%" PRIx32
"\t\t%s\n",
1475 temp
->pid
, temp
->oncpu
,
1476 temp
->asid
, temp
->name
);
1486 display
= calloc(40, 1);
1487 sprintf(display
, "linux_ps_command failed\n");
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)