1 /***************************************************************************
2 * Copyright (C) 2011 by STEricsson *
3 * Heythem Bouhaja heythem.bouhaja@stericsson.com : creation *
4 * Michel JAOUEN michel.jaouen@stericsson.com : adaptation to rtos *
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 <helper/time_support.h>
25 #include <jtag/jtag.h>
26 #include "target/target.h"
27 #include "target/target_type.h"
28 #include "helper/log.h"
29 #include "helper/types.h"
31 #include "rtos_standard_stackings.h"
32 #include <target/register.h>
33 #include "server/gdb_server.h"
35 #define LINUX_USER_KERNEL_BORDER 0xc0000000
36 #include "linux_header.h"
38 #define MAX_THREADS 200
42 uint32_t init_task_addr
;
45 int preupdtate_threadid_count
;
48 int threads_needs_update
;
49 struct current_thread
*current_threads
;
50 struct threads
*thread_list
;
51 /* virt2phys parameter */
56 struct current_thread
{
63 struct current_thread
*next
;
68 uint32_t base_addr
; /* address to read magic */
69 uint32_t state
; /* magic value : filled only at creation */
70 uint32_t pid
; /* linux pid : id for identifying a thread */
71 uint32_t oncpu
; /* content cpu number in current thread */
72 uint32_t asid
; /* filled only at creation */
74 int status
; /* dead = 1 alive = 2 current = 3 alive and current */
75 /* value that should not change during the live of a thread ? */
76 uint32_t thread_info_addr
; /* contain latest thread_info_addr computed */
77 /* retrieve from thread_info */
78 struct cpu_context
*context
;
93 uint32_t preempt_count
;
95 struct cpu_context
*cpu_context_read(struct target
*target
, uint32_t base_addr
,
97 static int insert_into_threadlist(struct target
*target
, struct threads
*t
);
99 static int linux_os_create(struct target
*target
);
101 static int linux_os_dummy_update(struct rtos
*rtos
)
103 /* update is done only when thread request come
104 * too many thread to do it on each stop */
108 static int linux_compute_virt2phys(struct target
*target
, target_addr_t address
)
110 struct linux_os
*linux_os
= (struct linux_os
*)
111 target
->rtos
->rtos_specific_params
;
112 target_addr_t pa
= 0;
113 int retval
= target
->type
->virt2phys(target
, address
, &pa
);
114 if (retval
!= ERROR_OK
) {
115 LOG_ERROR("Cannot compute linux virt2phys translation");
116 /* fixes default address */
117 linux_os
->phys_base
= 0;
121 linux_os
->init_task_addr
= address
;
122 address
= address
& linux_os
->phys_mask
;
123 linux_os
->phys_base
= pa
- address
;
127 static int linux_read_memory(struct target
*target
,
128 uint32_t address
, uint32_t size
, uint32_t count
,
132 struct linux_os
*linux_os
= (struct linux_os
*)
133 target
->rtos
->rtos_specific_params
;
134 uint32_t pa
= (address
& linux_os
->phys_mask
) + linux_os
->phys_base
;
136 if (address
< 0xc000000) {
137 LOG_ERROR("linux awareness : address in user space");
141 target_read_phys_memory(target
, pa
, size
, count
, buffer
);
143 target_read_memory(target
, address
, size
, count
, buffer
);
147 static char *reg_converter(char *buffer
, void *reg
, int size
)
151 for (i
= 0; i
< size
; i
++)
152 buffer
+= sprintf(buffer
, "%02x", ((uint8_t *) reg
)[i
]);
157 int fill_buffer(struct target
*target
, uint32_t addr
, uint8_t *buffer
)
160 if ((addr
& 0xfffffffc) != addr
)
161 LOG_INFO("unaligned address %" PRIx32
"!!", addr
);
163 int retval
= linux_read_memory(target
, addr
, 4, 1, buffer
);
168 uint32_t get_buffer(struct target
*target
, const uint8_t *buffer
)
171 const uint8_t *value_ptr
= buffer
;
172 value
= target_buffer_get_u32(target
, value_ptr
);
176 static int linux_os_thread_reg_list(struct rtos
*rtos
,
177 int64_t thread_id
, char **hex_reg_list
)
179 struct target
*target
= rtos
->target
;
180 struct linux_os
*linux_os
= (struct linux_os
*)
181 target
->rtos
->rtos_specific_params
;
183 struct current_thread
*tmp
= linux_os
->current_threads
;
184 struct current_thread
*next
;
188 /* check if a current thread is requested */
192 if (next
->threadid
== thread_id
)
196 } while ((found
== 0) && (next
!= tmp
) && (next
!= NULL
));
199 /* search target to perfom the access */
200 struct reg
**reg_list
;
201 int reg_list_size
, reg_packet_size
= 0;
202 struct target_list
*head
;
206 if (head
->target
->coreid
== next
->core_id
) {
208 target
= head
->target
;
213 } while ((head
!= (struct target_list
*)NULL
) && (found
== 0));
218 "current thread %" PRIx64
": no target to perform access of core id %" PRIx32
,
224 /*LOG_INFO("thread %lx current on core %x",thread_id,
227 target_get_gdb_reg_list(target
, ®_list
, ®_list_size
,
230 if (retval
!= ERROR_OK
)
233 for (i
= 0; i
< reg_list_size
; i
++)
234 reg_packet_size
+= reg_list
[i
]->size
;
236 assert(reg_packet_size
> 0);
238 *hex_reg_list
= malloc(DIV_ROUND_UP(reg_packet_size
, 8) * 2);
240 hex_string
= *hex_reg_list
;
242 for (i
= 0; i
< reg_list_size
; i
++) {
243 if (!reg_list
[i
]->valid
)
244 reg_list
[i
]->type
->get(reg_list
[i
]);
246 hex_string
= reg_converter(hex_string
,
248 (reg_list
[i
]->size
) / 8);
254 struct threads
*temp
= linux_os
->thread_list
;
255 *hex_reg_list
= calloc(1, 500 * sizeof(char));
256 hex_string
= *hex_reg_list
;
258 for (i
= 0; i
< 16; i
++)
259 hex_string
+= sprintf(hex_string
, "%02x", 0);
261 while ((temp
!= NULL
) &&
262 (temp
->threadid
!= target
->rtos
->current_threadid
))
266 if (temp
->context
== NULL
)
267 temp
->context
= cpu_context_read(target
,
274 reg_converter(hex_string
, &temp
->context
->R4
, 4);
276 reg_converter(hex_string
, &temp
->context
->R5
, 4);
278 reg_converter(hex_string
, &temp
->context
->R6
, 4);
280 reg_converter(hex_string
, &temp
->context
->R7
, 4);
282 reg_converter(hex_string
, &temp
->context
->R8
, 4);
284 reg_converter(hex_string
, &temp
->context
->R9
, 4);
286 for (i
= 0; i
< 4; i
++) /*R10 = 0x0 */
287 hex_string
+= sprintf(hex_string
, "%02x", 0);
290 reg_converter(hex_string
, &temp
->context
->FP
, 4);
292 reg_converter(hex_string
, &temp
->context
->IP
, 4);
294 reg_converter(hex_string
, &temp
->context
->SP
, 4);
296 for (i
= 0; i
< 4; i
++)
297 hex_string
+= sprintf(hex_string
, "%02x", 0);
300 reg_converter(hex_string
, &temp
->context
->PC
, 4);
302 for (i
= 0; i
< 100; i
++) /*100 */
303 hex_string
+= sprintf(hex_string
, "%02x", 0);
305 uint32_t cpsr
= 0x00000000;
306 reg_converter(hex_string
, &cpsr
, 4);
312 static bool linux_os_detect(struct target
*target
)
314 LOG_INFO("should no be called");
318 static int linux_os_smp_init(struct target
*target
);
319 static int linux_os_clean(struct target
*target
);
321 static const char * const linux_symbol_list
[] = {
326 static int linux_get_symbol_list_to_lookup(symbol_table_elem_t
*symbol_list
[])
329 *symbol_list
= (symbol_table_elem_t
*)
330 calloc(ARRAY_SIZE(linux_symbol_list
), sizeof(symbol_table_elem_t
));
332 for (i
= 0; i
< ARRAY_SIZE(linux_symbol_list
); i
++)
333 (*symbol_list
)[i
].symbol_name
= linux_symbol_list
[i
];
338 static char *linux_ps_command(struct target
*target
);
340 const struct rtos_type Linux_os
= {
342 .detect_rtos
= linux_os_detect
,
343 .create
= linux_os_create
,
344 .smp_init
= linux_os_smp_init
,
345 .update_threads
= linux_os_dummy_update
,
346 .get_thread_reg_list
= linux_os_thread_reg_list
,
347 .get_symbol_list_to_lookup
= linux_get_symbol_list_to_lookup
,
348 .clean
= linux_os_clean
,
349 .ps_command
= linux_ps_command
,
352 static int linux_thread_packet(struct connection
*connection
, char const *packet
,
354 static void linux_identify_current_threads(struct target
*target
);
357 int fill_task_pid(struct target
*target
, struct threads
*t
)
359 uint32_t pid_addr
= t
->base_addr
+ PID
;
361 int retval
= fill_buffer(target
, pid_addr
, buffer
);
363 if (retval
== ERROR_OK
) {
364 uint32_t val
= get_buffer(target
, buffer
);
367 LOG_ERROR("fill_task_pid: unable to read memory");
373 int fill_task(struct target
*target
, struct threads
*t
)
376 uint32_t pid_addr
= t
->base_addr
+ PID
;
377 uint32_t mem_addr
= t
->base_addr
+ MEM
;
378 uint32_t on_cpu
= t
->base_addr
+ ONCPU
;
379 uint8_t *buffer
= calloc(1, 4);
380 retval
= fill_buffer(target
, t
->base_addr
, buffer
);
382 if (retval
== ERROR_OK
) {
383 uint32_t val
= get_buffer(target
, buffer
);
386 LOG_ERROR("fill_task: unable to read memory");
388 retval
= fill_buffer(target
, pid_addr
, buffer
);
390 if (retval
== ERROR_OK
) {
391 uint32_t val
= get_buffer(target
, buffer
);
394 LOG_ERROR("fill task: unable to read memory");
396 retval
= fill_buffer(target
, on_cpu
, buffer
);
398 if (retval
== ERROR_OK
) {
399 uint32_t val
= get_buffer(target
, buffer
);
402 LOG_ERROR("fill task: unable to read memory");
404 retval
= fill_buffer(target
, mem_addr
, buffer
);
406 if (retval
== ERROR_OK
) {
407 uint32_t val
= get_buffer(target
, buffer
);
410 uint32_t asid_addr
= val
+ MM_CTX
;
411 retval
= fill_buffer(target
, asid_addr
, buffer
);
413 if (retval
== ERROR_OK
) {
414 val
= get_buffer(target
, buffer
);
418 ("fill task: unable to read memory -- ASID");
422 LOG_ERROR("fill task: unable to read memory");
429 int get_name(struct target
*target
, struct threads
*t
)
432 uint32_t full_name
[4];
433 uint32_t comm
= t
->base_addr
+ COMM
;
436 for (i
= 0; i
< 17; i
++)
439 retval
= linux_read_memory(target
, comm
, 4, 4, (uint8_t *) full_name
);
441 if (retval
!= ERROR_OK
) {
442 LOG_ERROR("get_name: unable to read memory\n");
446 uint32_t raw_name
= target_buffer_get_u32(target
,
449 t
->name
[3] = raw_name
>> 24;
450 t
->name
[2] = raw_name
>> 16;
451 t
->name
[1] = raw_name
>> 8;
452 t
->name
[0] = raw_name
;
454 target_buffer_get_u32(target
, (const uint8_t *)&full_name
[1]);
455 t
->name
[7] = raw_name
>> 24;
456 t
->name
[6] = raw_name
>> 16;
457 t
->name
[5] = raw_name
>> 8;
458 t
->name
[4] = raw_name
;
460 target_buffer_get_u32(target
, (const uint8_t *)&full_name
[2]);
461 t
->name
[11] = raw_name
>> 24;
462 t
->name
[10] = raw_name
>> 16;
463 t
->name
[9] = raw_name
>> 8;
464 t
->name
[8] = raw_name
;
466 target_buffer_get_u32(target
, (const uint8_t *)&full_name
[3]);
467 t
->name
[15] = raw_name
>> 24;
468 t
->name
[14] = raw_name
>> 16;
469 t
->name
[13] = raw_name
>> 8;
470 t
->name
[12] = raw_name
;
475 int get_current(struct target
*target
, int create
)
477 struct target_list
*head
;
482 uint8_t *buffer
= calloc(1, 4);
483 struct linux_os
*linux_os
= (struct linux_os
*)
484 target
->rtos
->rtos_specific_params
;
485 struct current_thread
*ctt
= linux_os
->current_threads
;
487 /* invalid current threads content */
488 while (ctt
!= NULL
) {
490 ctt
->TS
= 0xdeadbeef;
494 while (head
!= (struct target_list
*)NULL
) {
495 struct reg
**reg_list
;
499 if (target_get_gdb_reg_list(head
->target
, ®_list
,
500 ®_list_size
, REG_CLASS_GENERAL
) != ERROR_OK
) {
502 return ERROR_TARGET_FAILURE
;
505 if (!reg_list
[13]->valid
)
506 reg_list
[13]->type
->get(reg_list
[13]);
508 buf
= reg_list
[13]->value
;
509 val
= get_buffer(target
, buf
);
510 ti_addr
= (val
& 0xffffe000);
511 uint32_t TS_addr
= ti_addr
+ 0xc;
512 retval
= fill_buffer(target
, TS_addr
, buffer
);
514 if (retval
== ERROR_OK
) {
515 uint32_t TS
= get_buffer(target
, buffer
);
516 uint32_t cpu
, on_cpu
= TS
+ ONCPU
;
517 retval
= fill_buffer(target
, on_cpu
, buffer
);
519 if (retval
== ERROR_OK
) {
520 /*uint32_t cpu = get_buffer(target, buffer);*/
521 struct current_thread
*ct
=
522 linux_os
->current_threads
;
523 cpu
= head
->target
->coreid
;
525 while ((ct
!= NULL
) && (ct
->core_id
!= (int32_t) cpu
))
528 if ((ct
!= NULL
) && (ct
->TS
== 0xdeadbeef))
532 ("error in linux current thread update");
536 t
= calloc(1, sizeof(struct threads
));
537 t
->base_addr
= ct
->TS
;
538 fill_task(target
, t
);
541 insert_into_threadlist(target
, t
);
543 t
->thread_info_addr
= 0xdeadbeef;
544 ct
->threadid
= t
->threadid
;
545 linux_os
->thread_count
++;
549 /*LOG_INFO("Creation of current thread %s",t->name);*/
563 struct cpu_context
*cpu_context_read(struct target
*target
, uint32_t base_addr
,
564 uint32_t *thread_info_addr_old
)
566 struct cpu_context
*context
= calloc(1, sizeof(struct cpu_context
));
567 uint32_t preempt_count_addr
= 0;
568 uint32_t registers
[10];
569 uint8_t *buffer
= calloc(1, 4);
570 uint32_t stack
= base_addr
+ QAT
;
571 uint32_t thread_info_addr
= 0;
572 uint32_t thread_info_addr_update
= 0;
573 int retval
= ERROR_FAIL
;
574 context
->R4
= 0xdeadbeef;
575 context
->R5
= 0xdeadbeef;
576 context
->R6
= 0xdeadbeef;
577 context
->R7
= 0xdeadbeef;
578 context
->R8
= 0xdeadbeef;
579 context
->R9
= 0xdeadbeef;
580 context
->IP
= 0xdeadbeef;
581 context
->FP
= 0xdeadbeef;
582 context
->SP
= 0xdeadbeef;
583 context
->PC
= 0xdeadbeef;
586 if (*thread_info_addr_old
== 0xdeadbeef) {
587 retval
= fill_buffer(target
, stack
, buffer
);
589 if (retval
== ERROR_OK
)
590 thread_info_addr
= get_buffer(target
, buffer
);
592 LOG_ERROR("cpu_context: unable to read memory");
594 thread_info_addr_update
= thread_info_addr
;
596 thread_info_addr
= *thread_info_addr_old
;
598 preempt_count_addr
= thread_info_addr
+ PREEMPT
;
599 retval
= fill_buffer(target
, preempt_count_addr
, buffer
);
601 if (retval
== ERROR_OK
)
602 context
->preempt_count
= get_buffer(target
, buffer
);
604 if (*thread_info_addr_old
!= 0xdeadbeef) {
606 ("cpu_context: cannot read at thread_info_addr");
608 if (*thread_info_addr_old
< LINUX_USER_KERNEL_BORDER
)
610 ("cpu_context : thread_info_addr in userspace!!!");
612 *thread_info_addr_old
= 0xdeadbeef;
616 LOG_ERROR("cpu_context: unable to read memory");
619 thread_info_addr
+= CPU_CONT
;
621 retval
= linux_read_memory(target
, thread_info_addr
, 4, 10,
622 (uint8_t *) registers
);
624 if (retval
!= ERROR_OK
) {
626 LOG_ERROR("cpu_context: unable to read memory\n");
631 target_buffer_get_u32(target
, (const uint8_t *)®isters
[0]);
633 target_buffer_get_u32(target
, (const uint8_t *)®isters
[1]);
635 target_buffer_get_u32(target
, (const uint8_t *)®isters
[2]);
637 target_buffer_get_u32(target
, (const uint8_t *)®isters
[3]);
639 target_buffer_get_u32(target
, (const uint8_t *)®isters
[4]);
641 target_buffer_get_u32(target
, (const uint8_t *)®isters
[5]);
643 target_buffer_get_u32(target
, (const uint8_t *)®isters
[6]);
645 target_buffer_get_u32(target
, (const uint8_t *)®isters
[7]);
647 target_buffer_get_u32(target
, (const uint8_t *)®isters
[8]);
649 target_buffer_get_u32(target
, (const uint8_t *)®isters
[9]);
651 if (*thread_info_addr_old
== 0xdeadbeef)
652 *thread_info_addr_old
= thread_info_addr_update
;
659 uint32_t next_task(struct target
*target
, struct threads
*t
)
661 uint8_t *buffer
= calloc(1, 4);
662 uint32_t next_addr
= t
->base_addr
+ NEXT
;
663 int retval
= fill_buffer(target
, next_addr
, buffer
);
665 if (retval
== ERROR_OK
) {
666 uint32_t val
= get_buffer(target
, buffer
);
671 LOG_ERROR("next task: unable to read memory");
678 struct current_thread
*add_current_thread(struct current_thread
*currents
,
679 struct current_thread
*ct
)
683 if (currents
== NULL
) {
687 struct current_thread
*temp
= currents
;
689 while (temp
->next
!= NULL
)
697 struct threads
*liste_del_task(struct threads
*task_list
, struct threads
**t
,
698 struct threads
*prev
)
700 LOG_INFO("del task %" PRId64
, (*t
)->threadid
);
701 prev
->next
= (*t
)->next
;
703 if (prev
== task_list
)
706 /* free content of threads */
715 struct threads
*liste_add_task(struct threads
*task_list
, struct threads
*t
,
716 struct threads
**last
)
721 if (task_list
== NULL
) {
725 struct threads
*temp
= task_list
;
727 while (temp
->next
!= NULL
)
741 static int current_pid(struct linux_os
*linux_os
, uint32_t pid
)
743 static int current_base_addr(struct linux_os
*linux_os
, uint32_t base_addr
)
746 struct current_thread
*ct
= linux_os
->current_threads
;
749 while ((ct
!= NULL
) && (ct
->pid
!= pid
))
751 while ((ct
!= NULL
) && (ct
->TS
!= base_addr
))
755 if ((ct
!= NULL
) && (ct
->pid
== pid
))
757 if ((ct
!= NULL
) && (ct
->TS
== base_addr
))
764 int linux_get_tasks(struct target
*target
, int context
)
768 struct linux_os
*linux_os
= (struct linux_os
*)
769 target
->rtos
->rtos_specific_params
;
770 linux_os
->thread_list
= NULL
;
771 linux_os
->thread_count
= 0;
773 if (linux_os
->init_task_addr
== 0xdeadbeef) {
774 LOG_INFO("no init symbol\n");
778 int64_t start
= timeval_ms();
780 struct threads
*t
= calloc(1, sizeof(struct threads
));
781 struct threads
*last
= NULL
;
782 t
->base_addr
= linux_os
->init_task_addr
;
783 /* retrieve the thread id , currently running in the different smp core */
784 get_current(target
, 1);
786 while (((t
->base_addr
!= linux_os
->init_task_addr
) &&
787 (t
->base_addr
!= 0)) || (loop
== 0)) {
789 fill_task(target
, t
);
790 retval
= get_name(target
, t
);
792 if (loop
> MAX_THREADS
) {
794 LOG_INFO("more than %d threads !!", MAX_THREADS
);
798 if (retval
!= ERROR_OK
) {
803 /* check that this thread is not one the current threads already
807 if (!current_pid(linux_os
, t
->pid
)) {
809 if (!current_base_addr(linux_os
, t
->base_addr
)) {
811 t
->threadid
= linux_os
->threadid_count
;
813 linux_os
->threadid_count
++;
815 linux_os
->thread_list
=
816 liste_add_task(linux_os
->thread_list
, t
, &last
);
817 /* no interest to fill the context if it is a current thread. */
818 linux_os
->thread_count
++;
819 t
->thread_info_addr
= 0xdeadbeef;
823 cpu_context_read(target
, t
->base_addr
,
824 &t
->thread_info_addr
);
826 /*LOG_INFO("thread %s is a current thread already created",t->name); */
830 uint32_t base_addr
= next_task(target
, t
);
831 t
= calloc(1, sizeof(struct threads
));
832 t
->base_addr
= base_addr
;
835 linux_os
->threads_lookup
= 1;
836 linux_os
->threads_needs_update
= 0;
837 linux_os
->preupdtate_threadid_count
= linux_os
->threadid_count
- 1;
838 /* check that all current threads have been identified */
840 LOG_INFO("complete time %" PRId64
", thread mean %" PRId64
"\n",
841 (timeval_ms() - start
),
842 (timeval_ms() - start
) / linux_os
->threadid_count
);
844 LOG_INFO("threadid count %d", linux_os
->threadid_count
);
850 static int clean_threadlist(struct target
*target
)
852 struct linux_os
*linux_os
= (struct linux_os
*)
853 target
->rtos
->rtos_specific_params
;
854 struct threads
*old
, *temp
= linux_os
->thread_list
;
856 while (temp
!= NULL
) {
869 static int linux_os_clean(struct target
*target
)
871 struct linux_os
*os_linux
= (struct linux_os
*)
872 target
->rtos
->rtos_specific_params
;
873 clean_threadlist(target
);
874 os_linux
->init_task_addr
= 0xdeadbeef;
875 os_linux
->name
= "linux";
876 os_linux
->thread_list
= NULL
;
877 os_linux
->thread_count
= 0;
878 os_linux
->nr_cpus
= 0;
879 os_linux
->threads_lookup
= 0;
880 os_linux
->threads_needs_update
= 0;
881 os_linux
->threadid_count
= 1;
885 static int insert_into_threadlist(struct target
*target
, struct threads
*t
)
887 struct linux_os
*linux_os
= (struct linux_os
*)
888 target
->rtos
->rtos_specific_params
;
889 struct threads
*temp
= linux_os
->thread_list
;
890 t
->threadid
= linux_os
->threadid_count
;
891 linux_os
->threadid_count
++;
896 linux_os
->thread_list
= t
;
898 while (temp
->next
!= NULL
)
908 static void linux_identify_current_threads(struct target
*target
)
910 struct linux_os
*linux_os
= (struct linux_os
*)
911 target
->rtos
->rtos_specific_params
;
912 struct threads
*thread_list
= linux_os
->thread_list
;
913 struct current_thread
*ct
= linux_os
->current_threads
;
914 struct threads
*t
= NULL
;
916 while ((ct
!= NULL
)) {
917 if (ct
->threadid
== -1) {
919 /* un-identified thread */
921 t
= calloc(1, sizeof(struct threads
));
922 t
->base_addr
= ct
->TS
;
925 if (fill_task_pid(target
, t
) != ERROR_OK
) {
929 ("linux identify_current_threads: unable to read pid");
934 /* search in the list of threads if pid
936 while ((thread_list
!= NULL
) && (found
== 0)) {
938 if (thread_list
->pid
== t
->pid
) {
940 if (thread_list
->base_addr
== t
->base_addr
) {
946 thread_list
= thread_list
->next
;
950 /* it is a new thread */
951 if (fill_task(target
, t
) != ERROR_OK
)
955 insert_into_threadlist(target
, t
);
956 t
->thread_info_addr
= 0xdeadbeef;
960 ct
->threadid
= t
->threadid
;
964 linux_os
->thread_count
++;
967 LOG_INFO("current thread core %x identified %s",
968 ct
->core_id
, t
->name
);
970 LOG_INFO("current thread core %x, reused %s",
971 ct
->core_id
, t
->name
);
977 tmp
.base_addr
= ct
->TS
;
978 get_name(target
, &tmp
);
979 LOG_INFO("current thread core %x , already identified %s !!!",
980 ct
->core_id
, tmp
.name
);
990 LOG_ERROR("unable to read pid");
996 static int linux_task_update(struct target
*target
, int context
)
998 struct linux_os
*linux_os
= (struct linux_os
*)
999 target
->rtos
->rtos_specific_params
;
1000 struct threads
*thread_list
= linux_os
->thread_list
;
1003 linux_os
->thread_count
= 0;
1005 /*thread_list = thread_list->next; skip init_task*/
1006 while (thread_list
!= NULL
) {
1007 thread_list
->status
= 0; /*setting all tasks to dead state*/
1009 if (thread_list
->context
) {
1010 free(thread_list
->context
);
1011 thread_list
->context
= NULL
;
1014 thread_list
= thread_list
->next
;
1019 if (linux_os
->init_task_addr
== 0xdeadbeef) {
1020 LOG_INFO("no init symbol\n");
1023 int64_t start
= timeval_ms();
1024 struct threads
*t
= calloc(1, sizeof(struct threads
));
1025 uint32_t previous
= 0xdeadbeef;
1026 t
->base_addr
= linux_os
->init_task_addr
;
1027 retval
= get_current(target
, 0);
1028 /*check that all current threads have been identified */
1029 linux_identify_current_threads(target
);
1031 while (((t
->base_addr
!= linux_os
->init_task_addr
) &&
1032 (t
->base_addr
!= previous
)) || (loop
== 0)) {
1033 /* for avoiding any permanent loop for any reason possibly due to
1036 previous
= t
->base_addr
;
1039 retval
= fill_task_pid(target
, t
);
1042 if (retval
!= ERROR_OK
) {
1047 thread_list
= linux_os
->thread_list
;
1049 while (thread_list
!= NULL
) {
1051 if (t
->pid
== thread_list
->pid
) {
1053 if (t
->base_addr
== thread_list
->base_addr
) {
1055 if (!thread_list
->status
) {
1057 if (t
->base_addr
!= thread_list
->base_addr
)
1058 LOG_INFO("thread base_addr has changed !!");
1060 /* this is not a current thread */
1061 thread_list
->base_addr
= t
->base_addr
;
1062 thread_list
->status
= 1;
1064 /* we don 't update this field any more */
1066 /*thread_list->state = t->state;
1067 thread_list->oncpu = t->oncpu;
1068 thread_list->asid = t->asid;
1071 thread_list
->context
=
1072 cpu_context_read(target
,
1078 /* it is a current thread no need to read context */
1081 linux_os
->thread_count
++;
1086 thread_list
= thread_list
->next
;
1092 fill_task(target
, t
);
1093 get_name(target
, t
);
1094 retval
= insert_into_threadlist(target
, t
);
1095 t
->thread_info_addr
= 0xdeadbeef;
1099 cpu_context_read(target
, t
->base_addr
,
1100 &t
->thread_info_addr
);
1102 base_addr
= next_task(target
, t
);
1103 t
= calloc(1, sizeof(struct threads
));
1104 t
->base_addr
= base_addr
;
1105 linux_os
->thread_count
++;
1107 t
->base_addr
= next_task(target
, t
);
1110 LOG_INFO("update thread done %" PRId64
", mean%" PRId64
"\n",
1111 (timeval_ms() - start
), (timeval_ms() - start
) / loop
);
1113 linux_os
->threads_needs_update
= 0;
1117 int linux_gdb_thread_packet(struct target
*target
,
1118 struct connection
*connection
, char const *packet
,
1122 struct linux_os
*linux_os
=
1123 (struct linux_os
*)target
->rtos
->rtos_specific_params
;
1125 if (linux_os
->init_task_addr
== 0xdeadbeef) {
1126 /* it has not been initialized */
1127 LOG_INFO("received thread request without init task address");
1128 gdb_put_packet(connection
, "l", 1);
1132 retval
= linux_get_tasks(target
, 1);
1134 if (retval
!= ERROR_OK
)
1135 return ERROR_TARGET_FAILURE
;
1137 char *out_str
= calloc(MAX_THREADS
* 17 + 10, 1);
1138 char *tmp_str
= out_str
;
1139 tmp_str
+= sprintf(tmp_str
, "m");
1140 struct threads
*temp
= linux_os
->thread_list
;
1142 while (temp
!= NULL
) {
1143 tmp_str
+= sprintf(tmp_str
, "%016" PRIx64
, temp
->threadid
);
1146 tmp_str
+= sprintf(tmp_str
, ",");
1149 gdb_put_packet(connection
, out_str
, strlen(out_str
));
1154 int linux_gdb_thread_update(struct target
*target
,
1155 struct connection
*connection
, char const *packet
,
1159 struct linux_os
*linux_os
= (struct linux_os
*)
1160 target
->rtos
->rtos_specific_params
;
1161 struct threads
*temp
= linux_os
->thread_list
;
1163 while (temp
!= NULL
) {
1164 if (temp
->threadid
== linux_os
->preupdtate_threadid_count
+ 1) {
1165 /*LOG_INFO("FOUND");*/
1173 /*LOG_INFO("INTO GDB THREAD UPDATE FOUNDING START TASK");*/
1174 char *out_strr
= calloc(MAX_THREADS
* 17 + 10, 1);
1175 char *tmp_strr
= out_strr
;
1176 tmp_strr
+= sprintf(tmp_strr
, "m");
1177 /*LOG_INFO("CHAR MALLOC & M DONE");*/
1178 tmp_strr
+= sprintf(tmp_strr
, "%016" PRIx64
, temp
->threadid
);
1182 while (temp
!= NULL
) {
1183 /*LOG_INFO("INTO GDB THREAD UPDATE WHILE");*/
1184 tmp_strr
+= sprintf(tmp_strr
, ",");
1186 sprintf(tmp_strr
, "%016" PRIx64
, temp
->threadid
);
1191 gdb_put_packet(connection
, out_strr
, strlen(out_strr
));
1192 linux_os
->preupdtate_threadid_count
=
1193 linux_os
->threadid_count
- 1;
1196 gdb_put_packet(connection
, "l", 1);
1201 int linux_thread_extra_info(struct target
*target
,
1202 struct connection
*connection
, char const *packet
,
1205 int64_t threadid
= 0;
1206 struct linux_os
*linux_os
= (struct linux_os
*)
1207 target
->rtos
->rtos_specific_params
;
1208 sscanf(packet
, "qThreadExtraInfo,%" SCNx64
, &threadid
);
1209 /*LOG_INFO("lookup extra info for thread %" SCNx64, threadid);*/
1210 struct threads
*temp
= linux_os
->thread_list
;
1212 while (temp
!= NULL
) {
1213 if (temp
->threadid
== threadid
) {
1214 char *pid
= " PID: ";
1215 char *pid_current
= "*PID: ";
1216 char *name
= "Name: ";
1217 int str_size
= strlen(pid
) + strlen(name
);
1218 char *tmp_str
= calloc(1, str_size
+ 50);
1219 char *tmp_str_ptr
= tmp_str
;
1221 /* discriminate current task */
1222 if (temp
->status
== 3)
1223 tmp_str_ptr
+= sprintf(tmp_str_ptr
, "%s",
1226 tmp_str_ptr
+= sprintf(tmp_str_ptr
, "%s", pid
);
1228 tmp_str_ptr
+= sprintf(tmp_str_ptr
, "%d, ", (int)temp
->pid
);
1229 sprintf(tmp_str_ptr
, "%s", name
);
1230 sprintf(tmp_str_ptr
, "%s", temp
->name
);
1231 char *hex_str
= calloc(1, strlen(tmp_str
) * 2 + 1);
1232 size_t pkt_len
= hexify(hex_str
, (const uint8_t *)tmp_str
,
1233 strlen(tmp_str
), strlen(tmp_str
) * 2 + 1);
1234 gdb_put_packet(connection
, hex_str
, pkt_len
);
1243 LOG_INFO("thread not found");
1247 int linux_gdb_T_packet(struct connection
*connection
,
1248 struct target
*target
, char const *packet
, int packet_size
)
1251 struct linux_os
*linux_os
= (struct linux_os
*)
1252 target
->rtos
->rtos_specific_params
;
1253 int retval
= ERROR_OK
;
1254 sscanf(packet
, "T%" SCNx64
, &threadid
);
1256 if (linux_os
->threads_needs_update
== 0) {
1257 struct threads
*temp
= linux_os
->thread_list
;
1258 struct threads
*prev
= linux_os
->thread_list
;
1260 while (temp
!= NULL
) {
1261 if (temp
->threadid
== threadid
) {
1262 if (temp
->status
!= 0) {
1263 gdb_put_packet(connection
, "OK", 2);
1266 /* delete item in the list */
1267 linux_os
->thread_list
=
1268 liste_del_task(linux_os
->
1271 linux_os
->thread_count
--;
1272 gdb_put_packet(connection
, "E01", 3);
1282 LOG_INFO("gdb requested status on non existing thread");
1283 gdb_put_packet(connection
, "E01", 3);
1287 retval
= linux_task_update(target
, 1);
1288 struct threads
*temp
= linux_os
->thread_list
;
1290 while (temp
!= NULL
) {
1291 if (temp
->threadid
== threadid
) {
1292 if (temp
->status
== 1) {
1293 gdb_put_packet(connection
, "OK", 2);
1296 gdb_put_packet(connection
, "E01", 3);
1308 int linux_gdb_h_packet(struct connection
*connection
,
1309 struct target
*target
, char const *packet
, int packet_size
)
1311 struct linux_os
*linux_os
= (struct linux_os
*)
1312 target
->rtos
->rtos_specific_params
;
1313 struct current_thread
*ct
= linux_os
->current_threads
;
1315 /* select to display the current thread of the selected target */
1316 while ((ct
!= NULL
) && (ct
->core_id
!= target
->coreid
))
1319 int64_t current_gdb_thread_rq
;
1321 if (linux_os
->threads_lookup
== 1) {
1322 if ((ct
!= NULL
) && (ct
->threadid
== -1)) {
1323 ct
= linux_os
->current_threads
;
1325 while ((ct
!= NULL
) && (ct
->threadid
== -1))
1330 /* no current thread can be identified
1331 * any way with smp */
1332 LOG_INFO("no current thread identified");
1333 /* attempt to display the name of the 2 threads identified with
1336 ct
= linux_os
->current_threads
;
1338 while ((ct
!= NULL
) && (ct
->threadid
== -1)) {
1339 t
.base_addr
= ct
->TS
;
1340 get_name(target
, &t
);
1341 LOG_INFO("name of unidentified thread %s",
1346 gdb_put_packet(connection
, "OK", 2);
1350 if (packet
[1] == 'g') {
1351 sscanf(packet
, "Hg%16" SCNx64
, ¤t_gdb_thread_rq
);
1353 if (current_gdb_thread_rq
== 0) {
1354 target
->rtos
->current_threadid
= ct
->threadid
;
1355 gdb_put_packet(connection
, "OK", 2);
1357 target
->rtos
->current_threadid
=
1358 current_gdb_thread_rq
;
1359 gdb_put_packet(connection
, "OK", 2);
1361 } else if (packet
[1] == 'c') {
1362 sscanf(packet
, "Hc%16" SCNx64
, ¤t_gdb_thread_rq
);
1364 if ((current_gdb_thread_rq
== 0) ||
1365 (current_gdb_thread_rq
== ct
->threadid
)) {
1366 target
->rtos
->current_threadid
= ct
->threadid
;
1367 gdb_put_packet(connection
, "OK", 2);
1369 gdb_put_packet(connection
, "E01", 3);
1372 gdb_put_packet(connection
, "OK", 2);
1377 static int linux_thread_packet(struct connection
*connection
, char const *packet
,
1380 int retval
= ERROR_OK
;
1381 struct current_thread
*ct
;
1382 struct target
*target
= get_target_from_connection(connection
);
1383 struct linux_os
*linux_os
= (struct linux_os
*)
1384 target
->rtos
->rtos_specific_params
;
1386 switch (packet
[0]) {
1387 case 'T': /* Is thread alive?*/
1389 linux_gdb_T_packet(connection
, target
, packet
, packet_size
);
1391 case 'H': /* Set current thread */
1392 /* ( 'c' for step and continue, 'g' for all other operations )*/
1393 /*LOG_INFO(" H packet received '%s'", packet);*/
1394 linux_gdb_h_packet(connection
, target
, packet
, packet_size
);
1398 if (strncmp(packet
, "qSymbol", 7) == 0) {
1399 if (rtos_qsymbol(connection
, packet
, packet_size
) == 1) {
1400 linux_compute_virt2phys(target
,
1407 } else if (strncmp(packet
, "qfThreadInfo", 12) == 0) {
1408 if (linux_os
->thread_list
== NULL
) {
1409 retval
= linux_gdb_thread_packet(target
,
1415 retval
= linux_gdb_thread_update(target
,
1421 } else if (strncmp(packet
, "qsThreadInfo", 12) == 0) {
1422 gdb_put_packet(connection
, "l", 1);
1424 } else if (strncmp(packet
, "qThreadExtraInfo,", 17) == 0) {
1425 linux_thread_extra_info(target
, connection
, packet
,
1429 retval
= GDB_THREAD_PACKET_NOT_CONSUMED
;
1434 /* previously response was : thread not found
1435 * gdb_put_packet(connection, "E01", 3); */
1436 retval
= GDB_THREAD_PACKET_NOT_CONSUMED
;
1440 if (linux_os
->threads_lookup
== 1) {
1441 ct
= linux_os
->current_threads
;
1443 while ((ct
!= NULL
) && (ct
->core_id
) != target
->coreid
)
1446 if ((ct
!= NULL
) && (ct
->threadid
== -1)) {
1447 ct
= linux_os
->current_threads
;
1449 while ((ct
!= NULL
) && (ct
->threadid
== -1))
1453 if ((ct
!= NULL
) && (ct
->threadid
!=
1456 && (target
->rtos
->current_threadid
!= -1))
1457 LOG_WARNING("WARNING! current GDB thread do not match" \
1458 "current thread running." \
1459 "Switch thread in GDB to threadid %d",
1462 LOG_INFO("threads_needs_update = 1");
1463 linux_os
->threads_needs_update
= 1;
1467 /* if a packet handler returned an error, exit input loop */
1468 if (retval
!= ERROR_OK
)
1475 static int linux_os_smp_init(struct target
*target
)
1477 struct target_list
*head
;
1478 /* keep only target->rtos */
1479 struct rtos
*rtos
= target
->rtos
;
1480 struct linux_os
*os_linux
=
1481 (struct linux_os
*)rtos
->rtos_specific_params
;
1482 struct current_thread
*ct
;
1483 head
= target
->head
;
1485 while (head
!= (struct target_list
*)NULL
) {
1486 if (head
->target
->rtos
!= rtos
) {
1487 struct linux_os
*smp_os_linux
=
1488 (struct linux_os
*)head
->target
->rtos
->
1489 rtos_specific_params
;
1490 /* remap smp target on rtos */
1491 free(head
->target
->rtos
);
1492 head
->target
->rtos
= rtos
;
1493 /* reuse allocated ct */
1494 ct
= smp_os_linux
->current_threads
;
1496 ct
->TS
= 0xdeadbeef;
1497 ct
->core_id
= head
->target
->coreid
;
1498 os_linux
->current_threads
=
1499 add_current_thread(os_linux
->current_threads
, ct
);
1500 os_linux
->nr_cpus
++;
1510 static int linux_os_create(struct target
*target
)
1512 struct linux_os
*os_linux
= calloc(1, sizeof(struct linux_os
));
1513 struct current_thread
*ct
= calloc(1, sizeof(struct current_thread
));
1514 LOG_INFO("linux os creation\n");
1515 os_linux
->init_task_addr
= 0xdeadbeef;
1516 os_linux
->name
= "linux";
1517 os_linux
->thread_list
= NULL
;
1518 os_linux
->thread_count
= 0;
1519 target
->rtos
->current_threadid
= -1;
1520 os_linux
->nr_cpus
= 1;
1521 os_linux
->threads_lookup
= 0;
1522 os_linux
->threads_needs_update
= 0;
1523 os_linux
->threadid_count
= 1;
1524 os_linux
->current_threads
= NULL
;
1525 target
->rtos
->rtos_specific_params
= os_linux
;
1526 ct
->core_id
= target
->coreid
;
1528 ct
->TS
= 0xdeadbeef;
1529 os_linux
->current_threads
=
1530 add_current_thread(os_linux
->current_threads
, ct
);
1531 /* overload rtos thread default handler */
1532 target
->rtos
->gdb_thread_packet
= linux_thread_packet
;
1533 /* initialize a default virt 2 phys translation */
1534 os_linux
->phys_mask
= ~0xc0000000;
1535 os_linux
->phys_base
= 0x0;
1539 static char *linux_ps_command(struct target
*target
)
1541 struct linux_os
*linux_os
= (struct linux_os
*)
1542 target
->rtos
->rtos_specific_params
;
1543 int retval
= ERROR_OK
;
1546 if (linux_os
->threads_lookup
== 0)
1547 retval
= linux_get_tasks(target
, 1);
1549 if (linux_os
->threads_needs_update
!= 0)
1550 retval
= linux_task_update(target
, 0);
1553 if (retval
== ERROR_OK
) {
1554 struct threads
*temp
= linux_os
->thread_list
;
1556 LOG_INFO("allocation for %d threads line",
1557 linux_os
->thread_count
);
1558 display
= calloc((linux_os
->thread_count
+ 2) * 80, 1);
1564 tmp
+= sprintf(tmp
, "PID\t\tCPU\t\tASID\t\tNAME\n");
1565 tmp
+= sprintf(tmp
, "---\t\t---\t\t----\t\t----\n");
1567 while (temp
!= NULL
) {
1572 "%" PRId32
"\t\t%" PRId32
"\t\t%" PRIx32
"\t\t%s\n",
1573 temp
->pid
, temp
->oncpu
,
1574 temp
->asid
, temp
->name
);
1578 "%" PRId32
"\t\t%" PRId32
"\t\t%" PRIx32
"\t\t%s\n",
1579 temp
->pid
, temp
->oncpu
,
1580 temp
->asid
, temp
->name
);
1590 display
= calloc(40, 1);
1591 sprintf(display
, "linux_ps_command failed\n");