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
< 0xc000000) {
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");