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 int 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(1, 350 * sizeof(int64_t));
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(1, 350 * sizeof(int64_t));
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");
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)