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, write to the *
18 * Free Software Foundation, Inc., *
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
20 ***************************************************************************/
26 #include <helper/time_support.h>
27 #include <jtag/jtag.h>
28 #include "target/target.h"
29 #include "target/target_type.h"
30 #include "helper/log.h"
31 #include "helper/types.h"
33 #include "rtos_standard_stackings.h"
34 #include <target/register.h>
35 #include "server/gdb_server.h"
37 #define LINUX_USER_KERNEL_BORDER 0xc0000000
38 #include "linux_header.h"
40 #define MAX_THREADS 200
44 uint32_t init_task_addr
;
47 int preupdtate_threadid_count
;
50 int threads_needs_update
;
51 struct current_thread
*current_threads
;
52 struct threads
*thread_list
;
53 /* virt2phys parameter */
58 struct current_thread
{
65 struct current_thread
*next
;
70 uint32_t base_addr
; /* address to read magic */
71 uint32_t state
; /* magic value : filled only at creation */
72 uint32_t pid
; /* linux pid : id for identifying a thread */
73 uint32_t oncpu
; /* content cpu number in current thread */
74 uint32_t asid
; /* filled only at creation */
76 int status
; /* dead = 1 alive = 2 current = 3 alive and current */
77 /* value that should not change during the live of a thread ? */
78 uint32_t thread_info_addr
; /* contain latest thread_info_addr computed */
79 /* retrieve from thread_info */
80 struct cpu_context
*context
;
95 uint32_t preempt_count
;
97 struct cpu_context
*cpu_context_read(struct target
*target
, uint32_t base_addr
,
99 static int insert_into_threadlist(struct target
*target
, struct threads
*t
);
101 static int linux_os_create(struct target
*target
);
103 static int linux_os_dummy_update(struct rtos
*rtos
)
105 /* update is done only when thread request come
106 * too many thread to do it on each stop */
110 static int linux_compute_virt2phys(struct target
*target
, uint32_t address
)
112 struct linux_os
*linux_os
= (struct linux_os
*)
113 target
->rtos
->rtos_specific_params
;
115 int retval
= target
->type
->virt2phys(target
, address
, &pa
);
116 if (retval
!= ERROR_OK
) {
117 LOG_ERROR("Cannot compute linux virt2phys translation");
118 /* fixes default address */
119 linux_os
->phys_base
= 0;
123 linux_os
->init_task_addr
= address
;
124 address
= address
& linux_os
->phys_mask
;
125 linux_os
->phys_base
= pa
- address
;
129 static int linux_read_memory(struct target
*target
,
130 uint32_t address
, uint32_t size
, uint32_t count
,
134 struct linux_os
*linux_os
= (struct linux_os
*)
135 target
->rtos
->rtos_specific_params
;
136 uint32_t pa
= (address
& linux_os
->phys_mask
) + linux_os
->phys_base
;
138 if (address
< 0xc000000) {
139 LOG_ERROR("linux awareness : address in user space");
143 target_read_phys_memory(target
, pa
, size
, count
, buffer
);
145 target_read_memory(target
, address
, size
, count
, buffer
);
149 static char *reg_converter(char *buffer
, void *reg
, int size
)
153 for (i
= 0; i
< size
; i
++)
154 buffer
+= sprintf(buffer
, "%02x", ((uint8_t *) reg
)[i
]);
159 int fill_buffer(struct target
*target
, uint32_t addr
, uint8_t *buffer
)
162 if ((addr
& 0xfffffffc) != addr
)
163 LOG_INFO("unaligned address %x!!", addr
);
165 int retval
= linux_read_memory(target
, addr
, 4, 1, buffer
);
170 uint32_t get_buffer(struct target
*target
, const uint8_t *buffer
)
173 const uint8_t *value_ptr
= buffer
;
174 value
= target_buffer_get_u32(target
, value_ptr
);
178 static int linux_os_thread_reg_list(struct rtos
*rtos
,
179 int64_t thread_id
, char **hex_reg_list
)
181 struct target
*target
= rtos
->target
;
182 struct linux_os
*linux_os
= (struct linux_os
*)
183 target
->rtos
->rtos_specific_params
;
185 struct current_thread
*tmp
= linux_os
->current_threads
;
186 struct current_thread
*next
;
190 /* check if a current thread is requested */
194 if (next
->threadid
== thread_id
)
198 } while ((found
== 0) && (next
!= tmp
) && (next
!= NULL
));
201 /* search target to perfom the access */
202 struct reg
**reg_list
;
203 int reg_list_size
, reg_packet_size
= 0;
204 struct target_list
*head
;
208 if (head
->target
->coreid
== next
->core_id
) {
210 target
= head
->target
;
215 } while ((head
!= (struct target_list
*)NULL
) && (found
== 0));
220 "current thread %" PRIx64
": no target to perform access of core id %x",
226 /*LOG_INFO("thread %lx current on core %x",thread_id,
229 target_get_gdb_reg_list(target
, ®_list
, ®_list_size
);
231 if (retval
!= ERROR_OK
)
234 for (i
= 0; i
< reg_list_size
; i
++)
235 reg_packet_size
+= reg_list
[i
]->size
;
237 assert(reg_packet_size
> 0);
239 *hex_reg_list
= malloc(DIV_ROUND_UP(reg_packet_size
, 8) * 2);
241 hex_string
= *hex_reg_list
;
243 for (i
= 0; i
< reg_list_size
; i
++) {
244 if (!reg_list
[i
]->valid
)
245 reg_list
[i
]->type
->get(reg_list
[i
]);
247 hex_string
= reg_converter(hex_string
,
249 (reg_list
[i
]->size
) / 8);
255 struct threads
*temp
= linux_os
->thread_list
;
256 *hex_reg_list
= (char *)calloc(1, 500 * sizeof(char));
257 hex_string
= *hex_reg_list
;
259 for (i
= 0; i
< 16; i
++)
260 hex_string
+= sprintf(hex_string
, "%02x", 0);
262 while ((temp
!= NULL
) &&
263 (temp
->threadid
!= target
->rtos
->current_threadid
))
267 if (temp
->context
== NULL
)
268 temp
->context
= cpu_context_read(target
,
275 reg_converter(hex_string
, &temp
->context
->R4
, 4);
277 reg_converter(hex_string
, &temp
->context
->R5
, 4);
279 reg_converter(hex_string
, &temp
->context
->R6
, 4);
281 reg_converter(hex_string
, &temp
->context
->R7
, 4);
283 reg_converter(hex_string
, &temp
->context
->R8
, 4);
285 reg_converter(hex_string
, &temp
->context
->R9
, 4);
287 for (i
= 0; i
< 4; i
++) /*R10 = 0x0 */
288 hex_string
+= sprintf(hex_string
, "%02x", 0);
291 reg_converter(hex_string
, &temp
->context
->FP
, 4);
293 reg_converter(hex_string
, &temp
->context
->IP
, 4);
295 reg_converter(hex_string
, &temp
->context
->SP
, 4);
297 for (i
= 0; i
< 4; i
++)
298 hex_string
+= sprintf(hex_string
, "%02x", 0);
301 reg_converter(hex_string
, &temp
->context
->PC
, 4);
303 for (i
= 0; i
< 100; i
++) /*100 */
304 hex_string
+= sprintf(hex_string
, "%02x", 0);
306 uint32_t cpsr
= 0x00000000;
307 reg_converter(hex_string
, &cpsr
, 4);
313 static int linux_os_detect(struct target
*target
)
315 LOG_INFO("should no be called");
319 static int linux_os_smp_init(struct target
*target
);
320 static int linux_os_clean(struct target
*target
);
322 static char *linux_symbol_list
[] = {
327 static int linux_get_symbol_list_to_lookup(symbol_table_elem_t
*symbol_list
[])
330 *symbol_list
= (symbol_table_elem_t
*)
331 malloc(sizeof(symbol_table_elem_t
) * ARRAY_SIZE(linux_symbol_list
));
333 for (i
= 0; i
< ARRAY_SIZE(linux_symbol_list
); i
++)
334 (*symbol_list
)[i
].symbol_name
= linux_symbol_list
[i
];
339 static char *linux_ps_command(struct target
*target
);
341 const struct rtos_type Linux_os
= {
343 .detect_rtos
= linux_os_detect
,
344 .create
= linux_os_create
,
345 .smp_init
= linux_os_smp_init
,
346 .update_threads
= linux_os_dummy_update
,
347 .get_thread_reg_list
= linux_os_thread_reg_list
,
348 .get_symbol_list_to_lookup
= linux_get_symbol_list_to_lookup
,
349 .clean
= linux_os_clean
,
350 .ps_command
= linux_ps_command
,
353 static int linux_thread_packet(struct connection
*connection
, char *packet
,
355 static void linux_identify_current_threads(struct target
*target
);
358 int fill_task_pid(struct target
*target
, struct threads
*t
)
360 uint32_t pid_addr
= t
->base_addr
+ PID
;
362 int retval
= fill_buffer(target
, pid_addr
, buffer
);
364 if (retval
== ERROR_OK
) {
365 uint32_t val
= get_buffer(target
, buffer
);
368 LOG_ERROR("fill_task_pid: unable to read memory");
374 int fill_task(struct target
*target
, struct threads
*t
)
377 uint32_t pid_addr
= t
->base_addr
+ PID
;
378 uint32_t mem_addr
= t
->base_addr
+ MEM
;
379 uint32_t on_cpu
= t
->base_addr
+ ONCPU
;
380 uint8_t *buffer
= calloc(1, 4);
381 retval
= fill_buffer(target
, t
->base_addr
, buffer
);
383 if (retval
== ERROR_OK
) {
384 uint32_t val
= get_buffer(target
, buffer
);
387 LOG_ERROR("fill_task: unable to read memory");
389 retval
= fill_buffer(target
, pid_addr
, buffer
);
391 if (retval
== ERROR_OK
) {
392 uint32_t val
= get_buffer(target
, buffer
);
395 LOG_ERROR("fill task: unable to read memory");
397 retval
= fill_buffer(target
, on_cpu
, buffer
);
399 if (retval
== ERROR_OK
) {
400 uint32_t val
= get_buffer(target
, buffer
);
403 LOG_ERROR("fill task: unable to read memory");
405 retval
= fill_buffer(target
, mem_addr
, buffer
);
407 if (retval
== ERROR_OK
) {
408 uint32_t val
= get_buffer(target
, buffer
);
411 uint32_t asid_addr
= val
+ MM_CTX
;
412 retval
= fill_buffer(target
, asid_addr
, buffer
);
414 if (retval
== ERROR_OK
) {
415 val
= get_buffer(target
, buffer
);
419 ("fill task: unable to read memory -- ASID");
423 LOG_ERROR("fill task: unable to read memory");
430 int get_name(struct target
*target
, struct threads
*t
)
433 uint32_t full_name
[4];
434 uint32_t comm
= t
->base_addr
+ COMM
;
437 for (i
= 0; i
< 17; i
++)
440 retval
= linux_read_memory(target
, comm
, 4, 4, (uint8_t *) full_name
);
442 if (retval
!= ERROR_OK
) {
443 LOG_ERROR("get_name: unable to read memory\n");
447 uint32_t raw_name
= target_buffer_get_u32(target
,
450 t
->name
[3] = raw_name
>> 24;
451 t
->name
[2] = raw_name
>> 16;
452 t
->name
[1] = raw_name
>> 8;
453 t
->name
[0] = raw_name
;
455 target_buffer_get_u32(target
, (const uint8_t *)&full_name
[1]);
456 t
->name
[7] = raw_name
>> 24;
457 t
->name
[6] = raw_name
>> 16;
458 t
->name
[5] = raw_name
>> 8;
459 t
->name
[4] = raw_name
;
461 target_buffer_get_u32(target
, (const uint8_t *)&full_name
[2]);
462 t
->name
[11] = raw_name
>> 24;
463 t
->name
[10] = raw_name
>> 16;
464 t
->name
[9] = raw_name
>> 8;
465 t
->name
[8] = raw_name
;
467 target_buffer_get_u32(target
, (const uint8_t *)&full_name
[3]);
468 t
->name
[15] = raw_name
>> 24;
469 t
->name
[14] = raw_name
>> 16;
470 t
->name
[13] = raw_name
>> 8;
471 t
->name
[12] = raw_name
;
476 int get_current(struct target
*target
, int create
)
478 struct target_list
*head
;
483 uint8_t *buffer
= calloc(1, 4);
484 struct linux_os
*linux_os
= (struct linux_os
*)
485 target
->rtos
->rtos_specific_params
;
486 struct current_thread
*ctt
= linux_os
->current_threads
;
488 /* invalid current threads content */
489 while (ctt
!= NULL
) {
491 ctt
->TS
= 0xdeadbeef;
495 while (head
!= (struct target_list
*)NULL
) {
496 struct reg
**reg_list
;
500 if (target_get_gdb_reg_list(head
->target
, ®_list
,
501 ®_list_size
) != ERROR_OK
) {
503 return ERROR_TARGET_FAILURE
;
506 if (!reg_list
[13]->valid
)
507 reg_list
[13]->type
->get(reg_list
[13]);
509 buf
= reg_list
[13]->value
;
510 val
= get_buffer(target
, buf
);
511 ti_addr
= (val
& 0xffffe000);
512 uint32_t TS_addr
= ti_addr
+ 0xc;
513 retval
= fill_buffer(target
, TS_addr
, buffer
);
515 if (retval
== ERROR_OK
) {
516 uint32_t TS
= get_buffer(target
, buffer
);
517 uint32_t cpu
, on_cpu
= TS
+ ONCPU
;
518 retval
= fill_buffer(target
, on_cpu
, buffer
);
520 if (retval
== ERROR_OK
) {
521 /*uint32_t cpu = get_buffer(target, buffer);*/
522 struct current_thread
*ct
=
523 linux_os
->current_threads
;
524 cpu
= head
->target
->coreid
;
526 while ((ct
!= NULL
) && (ct
->core_id
!= (int32_t) cpu
))
529 if ((ct
!= NULL
) && (ct
->TS
== 0xdeadbeef))
533 ("error in linux current thread update");
537 t
= calloc(1, sizeof(struct threads
));
538 t
->base_addr
= ct
->TS
;
539 fill_task(target
, t
);
542 insert_into_threadlist(target
, t
);
544 t
->thread_info_addr
= 0xdeadbeef;
545 ct
->threadid
= t
->threadid
;
546 linux_os
->thread_count
++;
550 /*LOG_INFO("Creation of current thread %s",t->name);*/
564 struct cpu_context
*cpu_context_read(struct target
*target
, uint32_t base_addr
,
565 uint32_t *thread_info_addr_old
)
567 struct cpu_context
*context
= calloc(1, sizeof(struct cpu_context
));
568 uint32_t preempt_count_addr
= 0;
569 uint32_t registers
[10];
570 uint8_t *buffer
= calloc(1, 4);
571 uint32_t stack
= base_addr
+ QAT
;
572 uint32_t thread_info_addr
= 0;
573 uint32_t thread_info_addr_update
= 0;
574 int retval
= ERROR_FAIL
;
575 context
->R4
= 0xdeadbeef;
576 context
->R5
= 0xdeadbeef;
577 context
->R6
= 0xdeadbeef;
578 context
->R7
= 0xdeadbeef;
579 context
->R8
= 0xdeadbeef;
580 context
->R9
= 0xdeadbeef;
581 context
->IP
= 0xdeadbeef;
582 context
->FP
= 0xdeadbeef;
583 context
->SP
= 0xdeadbeef;
584 context
->PC
= 0xdeadbeef;
587 if (*thread_info_addr_old
== 0xdeadbeef) {
588 retval
= fill_buffer(target
, stack
, buffer
);
590 if (retval
== ERROR_OK
)
591 thread_info_addr
= get_buffer(target
, buffer
);
593 LOG_ERROR("cpu_context: unable to read memory");
595 thread_info_addr_update
= thread_info_addr
;
597 thread_info_addr
= *thread_info_addr_old
;
599 preempt_count_addr
= thread_info_addr
+ PREEMPT
;
600 retval
= fill_buffer(target
, preempt_count_addr
, buffer
);
602 if (retval
== ERROR_OK
)
603 context
->preempt_count
= get_buffer(target
, buffer
);
605 if (*thread_info_addr_old
!= 0xdeadbeef) {
607 ("cpu_context: cannot read at thread_info_addr");
609 if (*thread_info_addr_old
< LINUX_USER_KERNEL_BORDER
)
611 ("cpu_context : thread_info_addr in userspace!!!");
613 *thread_info_addr_old
= 0xdeadbeef;
617 LOG_ERROR("cpu_context: unable to read memory");
620 thread_info_addr
+= CPU_CONT
;
622 retval
= linux_read_memory(target
, thread_info_addr
, 4, 10,
623 (uint8_t *) registers
);
625 if (retval
!= ERROR_OK
) {
627 LOG_ERROR("cpu_context: unable to read memory\n");
632 target_buffer_get_u32(target
, (const uint8_t *)®isters
[0]);
634 target_buffer_get_u32(target
, (const uint8_t *)®isters
[1]);
636 target_buffer_get_u32(target
, (const uint8_t *)®isters
[2]);
638 target_buffer_get_u32(target
, (const uint8_t *)®isters
[3]);
640 target_buffer_get_u32(target
, (const uint8_t *)®isters
[4]);
642 target_buffer_get_u32(target
, (const uint8_t *)®isters
[5]);
644 target_buffer_get_u32(target
, (const uint8_t *)®isters
[6]);
646 target_buffer_get_u32(target
, (const uint8_t *)®isters
[7]);
648 target_buffer_get_u32(target
, (const uint8_t *)®isters
[8]);
650 target_buffer_get_u32(target
, (const uint8_t *)®isters
[9]);
652 if (*thread_info_addr_old
== 0xdeadbeef)
653 *thread_info_addr_old
= thread_info_addr_update
;
660 uint32_t next_task(struct target
*target
, struct threads
*t
)
662 uint8_t *buffer
= calloc(1, 4);
663 uint32_t next_addr
= t
->base_addr
+ NEXT
;
664 int retval
= fill_buffer(target
, next_addr
, buffer
);
666 if (retval
== ERROR_OK
) {
667 uint32_t val
= get_buffer(target
, buffer
);
672 LOG_ERROR("next task: unable to read memory");
679 struct current_thread
*add_current_thread(struct current_thread
*currents
,
680 struct current_thread
*ct
)
684 if (currents
== NULL
) {
688 struct current_thread
*temp
= currents
;
690 while (temp
->next
!= NULL
)
698 struct threads
*liste_del_task(struct threads
*task_list
, struct threads
**t
,
699 struct threads
*prev
)
701 LOG_INFO("del task %" PRId64
, (*t
)->threadid
);
702 prev
->next
= (*t
)->next
;
704 if (prev
== task_list
)
707 /* free content of threads */
716 struct threads
*liste_add_task(struct threads
*task_list
, struct threads
*t
,
717 struct threads
**last
)
722 if (task_list
== NULL
) {
726 struct threads
*temp
= task_list
;
728 while (temp
->next
!= NULL
)
742 static int current_pid(struct linux_os
*linux_os
, uint32_t pid
)
744 static int current_base_addr(struct linux_os
*linux_os
, uint32_t base_addr
)
747 struct current_thread
*ct
= linux_os
->current_threads
;
750 while ((ct
!= NULL
) && (ct
->pid
!= pid
))
752 while ((ct
!= NULL
) && (ct
->TS
!= base_addr
))
756 if ((ct
!= NULL
) && (ct
->pid
== pid
))
758 if ((ct
!= NULL
) && (ct
->TS
== base_addr
))
765 int linux_get_tasks(struct target
*target
, int context
)
769 struct linux_os
*linux_os
= (struct linux_os
*)
770 target
->rtos
->rtos_specific_params
;
771 linux_os
->thread_list
= NULL
;
772 linux_os
->thread_count
= 0;
774 if (linux_os
->init_task_addr
== 0xdeadbeef) {
775 LOG_INFO("no init symbol\n");
779 int64_t start
= timeval_ms();
781 struct threads
*t
= calloc(1, sizeof(struct threads
));
782 struct threads
*last
= NULL
;
783 t
->base_addr
= linux_os
->init_task_addr
;
784 /* retrieve the thread id , currently running in the different smp core */
785 get_current(target
, 1);
787 while (((t
->base_addr
!= linux_os
->init_task_addr
) &&
788 (t
->base_addr
!= 0)) || (loop
== 0)) {
790 fill_task(target
, t
);
791 retval
= get_name(target
, t
);
793 if (loop
> MAX_THREADS
) {
795 LOG_INFO("more than %d threads !!", MAX_THREADS
);
799 if (retval
!= ERROR_OK
) {
804 /* check that this thread is not one the current threads already
808 if (!current_pid(linux_os
, t
->pid
)) {
810 if (!current_base_addr(linux_os
, t
->base_addr
)) {
812 t
->threadid
= linux_os
->threadid_count
;
814 linux_os
->threadid_count
++;
816 linux_os
->thread_list
=
817 liste_add_task(linux_os
->thread_list
, t
, &last
);
818 /* no interest to fill the context if it is a current thread. */
819 linux_os
->thread_count
++;
820 t
->thread_info_addr
= 0xdeadbeef;
824 cpu_context_read(target
, t
->base_addr
,
825 &t
->thread_info_addr
);
827 /*LOG_INFO("thread %s is a current thread already created",t->name); */
831 uint32_t base_addr
= next_task(target
, t
);
832 t
= calloc(1, sizeof(struct threads
));
833 t
->base_addr
= base_addr
;
836 linux_os
->threads_lookup
= 1;
837 linux_os
->threads_needs_update
= 0;
838 linux_os
->preupdtate_threadid_count
= linux_os
->threadid_count
- 1;
839 /* check that all current threads have been identified */
841 LOG_INFO("complete time %" PRId64
", thread mean %" PRId64
"\n",
842 (timeval_ms() - start
),
843 (timeval_ms() - start
) / linux_os
->threadid_count
);
845 LOG_INFO("threadid count %d", linux_os
->threadid_count
);
851 static int clean_threadlist(struct target
*target
)
853 struct linux_os
*linux_os
= (struct linux_os
*)
854 target
->rtos
->rtos_specific_params
;
855 struct threads
*old
, *temp
= linux_os
->thread_list
;
857 while (temp
!= NULL
) {
870 static int linux_os_clean(struct target
*target
)
872 struct linux_os
*os_linux
= (struct linux_os
*)
873 target
->rtos
->rtos_specific_params
;
874 clean_threadlist(target
);
875 os_linux
->init_task_addr
= 0xdeadbeef;
876 os_linux
->name
= "linux";
877 os_linux
->thread_list
= NULL
;
878 os_linux
->thread_count
= 0;
879 os_linux
->nr_cpus
= 0;
880 os_linux
->threads_lookup
= 0;
881 os_linux
->threads_needs_update
= 0;
882 os_linux
->threadid_count
= 1;
886 static int insert_into_threadlist(struct target
*target
, struct threads
*t
)
888 struct linux_os
*linux_os
= (struct linux_os
*)
889 target
->rtos
->rtos_specific_params
;
890 struct threads
*temp
= linux_os
->thread_list
;
891 t
->threadid
= linux_os
->threadid_count
;
892 linux_os
->threadid_count
++;
897 linux_os
->thread_list
= t
;
899 while (temp
->next
!= NULL
)
909 static void linux_identify_current_threads(struct target
*target
)
911 struct linux_os
*linux_os
= (struct linux_os
*)
912 target
->rtos
->rtos_specific_params
;
913 struct threads
*thread_list
= linux_os
->thread_list
;
914 struct current_thread
*ct
= linux_os
->current_threads
;
915 struct threads
*t
= NULL
;
917 while ((ct
!= NULL
)) {
918 if (ct
->threadid
== -1) {
920 /* un-identified thread */
922 t
= calloc(1, sizeof(struct threads
));
923 t
->base_addr
= ct
->TS
;
926 if (fill_task_pid(target
, t
) != ERROR_OK
) {
930 ("linux identify_current_threads: unable to read pid");
935 /* search in the list of threads if pid
937 while ((thread_list
!= NULL
) && (found
== 0)) {
939 if (thread_list
->pid
== t
->pid
) {
941 if (thread_list
->base_addr
== t
->base_addr
) {
947 thread_list
= thread_list
->next
;
951 /* it is a new thread */
952 if (fill_task(target
, t
) != ERROR_OK
)
956 insert_into_threadlist(target
, t
);
957 t
->thread_info_addr
= 0xdeadbeef;
961 ct
->threadid
= t
->threadid
;
965 linux_os
->thread_count
++;
968 LOG_INFO("current thread core %x identified %s",
969 ct
->core_id
, t
->name
);
971 LOG_INFO("current thread core %x, reused %s",
972 ct
->core_id
, t
->name
);
978 tmp
.base_addr
= ct
->TS
;
979 get_name(target
, &tmp
);
980 LOG_INFO("current thread core %x , already identified %s !!!",
981 ct
->core_id
, tmp
.name
);
991 LOG_ERROR("unable to read pid");
997 static int linux_task_update(struct target
*target
, int context
)
999 struct linux_os
*linux_os
= (struct linux_os
*)
1000 target
->rtos
->rtos_specific_params
;
1001 struct threads
*thread_list
= linux_os
->thread_list
;
1004 linux_os
->thread_count
= 0;
1006 /*thread_list = thread_list->next; skip init_task*/
1007 while (thread_list
!= NULL
) {
1008 thread_list
->status
= 0; /*setting all tasks to dead state*/
1010 if (thread_list
->context
) {
1011 free(thread_list
->context
);
1012 thread_list
->context
= NULL
;
1015 thread_list
= thread_list
->next
;
1020 if (linux_os
->init_task_addr
== 0xdeadbeef) {
1021 LOG_INFO("no init symbol\n");
1024 int64_t start
= timeval_ms();
1025 struct threads
*t
= calloc(1, sizeof(struct threads
));
1026 uint32_t previous
= 0xdeadbeef;
1027 t
->base_addr
= linux_os
->init_task_addr
;
1028 retval
= get_current(target
, 0);
1029 /*check that all current threads have been identified */
1030 linux_identify_current_threads(target
);
1032 while (((t
->base_addr
!= linux_os
->init_task_addr
) &&
1033 (t
->base_addr
!= previous
)) || (loop
== 0)) {
1034 /* for avoiding any permanent loop for any reason possibly due to
1037 previous
= t
->base_addr
;
1040 retval
= fill_task_pid(target
, t
);
1043 if (retval
!= ERROR_OK
) {
1048 thread_list
= linux_os
->thread_list
;
1050 while (thread_list
!= NULL
) {
1052 if (t
->pid
== thread_list
->pid
) {
1054 if (t
->base_addr
== thread_list
->base_addr
) {
1056 if (!thread_list
->status
) {
1058 if (t
->base_addr
!= thread_list
->base_addr
)
1059 LOG_INFO("thread base_addr has changed !!");
1061 /* this is not a current thread */
1062 thread_list
->base_addr
= t
->base_addr
;
1063 thread_list
->status
= 1;
1065 /* we don 't update this field any more */
1067 /*thread_list->state = t->state;
1068 thread_list->oncpu = t->oncpu;
1069 thread_list->asid = t->asid;
1072 thread_list
->context
=
1073 cpu_context_read(target
,
1079 /* it is a current thread no need to read context */
1082 linux_os
->thread_count
++;
1087 thread_list
= thread_list
->next
;
1093 fill_task(target
, t
);
1094 get_name(target
, t
);
1095 retval
= insert_into_threadlist(target
, t
);
1096 t
->thread_info_addr
= 0xdeadbeef;
1100 cpu_context_read(target
, t
->base_addr
,
1101 &t
->thread_info_addr
);
1103 base_addr
= next_task(target
, t
);
1104 t
= calloc(1, sizeof(struct threads
));
1105 t
->base_addr
= base_addr
;
1106 linux_os
->thread_count
++;
1108 t
->base_addr
= next_task(target
, t
);
1111 LOG_INFO("update thread done %" PRId64
", mean%" PRId64
"\n",
1112 (timeval_ms() - start
), (timeval_ms() - start
) / loop
);
1114 linux_os
->threads_needs_update
= 0;
1118 int linux_gdb_thread_packet(struct target
*target
,
1119 struct connection
*connection
, char *packet
,
1123 struct linux_os
*linux_os
=
1124 (struct linux_os
*)target
->rtos
->rtos_specific_params
;
1126 if (linux_os
->init_task_addr
== 0xdeadbeef) {
1127 /* it has not been initialized */
1128 LOG_INFO("received thread request without init task address");
1129 gdb_put_packet(connection
, "l", 1);
1133 retval
= linux_get_tasks(target
, 1);
1135 if (retval
!= ERROR_OK
)
1136 return ERROR_TARGET_FAILURE
;
1138 char *out_str
= (char *)calloc(1, 350 * sizeof(int64_t));
1139 char *tmp_str
= out_str
;
1140 tmp_str
+= sprintf(tmp_str
, "m");
1141 struct threads
*temp
= linux_os
->thread_list
;
1142 tmp_str
+= sprintf(tmp_str
, "%016" PRIx64
, temp
->threadid
);
1145 while (temp
!= NULL
) {
1146 tmp_str
+= sprintf(tmp_str
, ",");
1147 tmp_str
+= sprintf(tmp_str
, "%016" PRIx64
, temp
->threadid
);
1151 gdb_put_packet(connection
, out_str
, strlen(out_str
));
1155 int linux_gdb_thread_update(struct target
*target
,
1156 struct connection
*connection
, char *packet
,
1160 struct linux_os
*linux_os
= (struct linux_os
*)
1161 target
->rtos
->rtos_specific_params
;
1162 struct threads
*temp
= linux_os
->thread_list
;
1164 while (temp
!= NULL
) {
1165 if (temp
->threadid
== linux_os
->preupdtate_threadid_count
+ 1) {
1166 /*LOG_INFO("FOUND");*/
1174 /*LOG_INFO("INTO GDB THREAD UPDATE FOUNDING START TASK");*/
1175 char *out_strr
= (char *)calloc(1, 350 * sizeof(int64_t));
1176 char *tmp_strr
= out_strr
;
1177 tmp_strr
+= sprintf(tmp_strr
, "m");
1178 /*LOG_INFO("CHAR MALLOC & M DONE");*/
1179 tmp_strr
+= sprintf(tmp_strr
, "%016" PRIx64
, temp
->threadid
);
1183 while (temp
!= NULL
) {
1184 /*LOG_INFO("INTO GDB THREAD UPDATE WHILE");*/
1185 tmp_strr
+= sprintf(tmp_strr
, ",");
1187 sprintf(tmp_strr
, "%016" PRIx64
, temp
->threadid
);
1192 gdb_put_packet(connection
, out_strr
, strlen(out_strr
));
1193 linux_os
->preupdtate_threadid_count
=
1194 linux_os
->threadid_count
- 1;
1197 gdb_put_packet(connection
, "l", 1);
1202 int linux_thread_extra_info(struct target
*target
,
1203 struct connection
*connection
, char *packet
,
1206 int64_t threadid
= 0;
1207 struct linux_os
*linux_os
= (struct linux_os
*)
1208 target
->rtos
->rtos_specific_params
;
1209 sscanf(packet
, "qThreadExtraInfo,%" SCNx64
, &threadid
);
1210 /*LOG_INFO("lookup extra info for thread %" SCNx64, threadid);*/
1211 struct threads
*temp
= linux_os
->thread_list
;
1213 while (temp
!= NULL
) {
1214 if (temp
->threadid
== threadid
) {
1215 char *pid
= " PID: ";
1216 char *pid_current
= "*PID: ";
1217 char *name
= "NAME: ";
1218 int str_size
= strlen(pid
) + strlen(name
);
1219 char *tmp_str
= (char *)calloc(1, str_size
+ 50);
1220 char *tmp_str_ptr
= tmp_str
;
1222 /* discriminate current task */
1223 if (temp
->status
== 3)
1224 tmp_str_ptr
+= sprintf(tmp_str_ptr
, "%s",
1227 tmp_str_ptr
+= sprintf(tmp_str_ptr
, "%s", pid
);
1230 sprintf(tmp_str_ptr
, "%d", (int)temp
->pid
);
1231 tmp_str_ptr
+= sprintf(tmp_str_ptr
, "%s", " | ");
1232 sprintf(tmp_str_ptr
, "%s", name
);
1233 sprintf(tmp_str_ptr
, "%s", temp
->name
);
1234 char *hex_str
= (char *)calloc(1, strlen(tmp_str
) * 2 + 1);
1235 int pkt_len
= hexify(hex_str
, tmp_str
, 0, strlen(tmp_str
) * 2 + 1);
1236 gdb_put_packet(connection
, hex_str
, pkt_len
);
1245 LOG_INFO("thread not found");
1249 int linux_gdb_T_packet(struct connection
*connection
,
1250 struct target
*target
, char *packet
, int packet_size
)
1253 struct linux_os
*linux_os
= (struct linux_os
*)
1254 target
->rtos
->rtos_specific_params
;
1255 int retval
= ERROR_OK
;
1256 sscanf(packet
, "T%" SCNx64
, &threadid
);
1258 if (linux_os
->threads_needs_update
== 0) {
1259 struct threads
*temp
= linux_os
->thread_list
;
1260 struct threads
*prev
= linux_os
->thread_list
;
1262 while (temp
!= NULL
) {
1263 if (temp
->threadid
== threadid
) {
1264 if (temp
->status
!= 0) {
1265 gdb_put_packet(connection
, "OK", 2);
1268 /* delete item in the list */
1269 linux_os
->thread_list
=
1270 liste_del_task(linux_os
->
1273 linux_os
->thread_count
--;
1274 gdb_put_packet(connection
, "E01", 3);
1284 LOG_INFO("gdb requested status on non existing thread");
1285 gdb_put_packet(connection
, "E01", 3);
1289 retval
= linux_task_update(target
, 1);
1290 struct threads
*temp
= linux_os
->thread_list
;
1292 while (temp
!= NULL
) {
1293 if (temp
->threadid
== threadid
) {
1294 if (temp
->status
== 1) {
1295 gdb_put_packet(connection
, "OK", 2);
1298 gdb_put_packet(connection
, "E01", 3);
1310 int linux_gdb_h_packet(struct connection
*connection
,
1311 struct target
*target
, char *packet
, int packet_size
)
1313 struct linux_os
*linux_os
= (struct linux_os
*)
1314 target
->rtos
->rtos_specific_params
;
1315 struct current_thread
*ct
= linux_os
->current_threads
;
1317 /* select to display the current thread of the selected target */
1318 while ((ct
!= NULL
) && (ct
->core_id
!= target
->coreid
))
1321 int64_t current_gdb_thread_rq
;
1323 if (linux_os
->threads_lookup
== 1) {
1324 if ((ct
!= NULL
) && (ct
->threadid
== -1)) {
1325 ct
= linux_os
->current_threads
;
1327 while ((ct
!= NULL
) && (ct
->threadid
== -1))
1332 /* no current thread can be identified
1333 * any way with smp */
1334 LOG_INFO("no current thread identified");
1335 /* attempt to display the name of the 2 threads identified with
1338 ct
= linux_os
->current_threads
;
1340 while ((ct
!= NULL
) && (ct
->threadid
== -1)) {
1341 t
.base_addr
= ct
->TS
;
1342 get_name(target
, &t
);
1343 LOG_INFO("name of unidentified thread %s",
1348 gdb_put_packet(connection
, "OK", 2);
1352 if (packet
[1] == 'g') {
1353 sscanf(packet
, "Hg%16" SCNx64
, ¤t_gdb_thread_rq
);
1355 if (current_gdb_thread_rq
== 0) {
1356 target
->rtos
->current_threadid
= ct
->threadid
;
1357 gdb_put_packet(connection
, "OK", 2);
1359 target
->rtos
->current_threadid
=
1360 current_gdb_thread_rq
;
1361 gdb_put_packet(connection
, "OK", 2);
1363 } else if (packet
[1] == 'c') {
1364 sscanf(packet
, "Hc%16" SCNx64
, ¤t_gdb_thread_rq
);
1366 if ((current_gdb_thread_rq
== 0) ||
1367 (current_gdb_thread_rq
== ct
->threadid
)) {
1368 target
->rtos
->current_threadid
= ct
->threadid
;
1369 gdb_put_packet(connection
, "OK", 2);
1371 gdb_put_packet(connection
, "E01", 3);
1374 gdb_put_packet(connection
, "OK", 2);
1379 static int linux_thread_packet(struct connection
*connection
, char *packet
,
1382 int retval
= ERROR_OK
;
1383 struct current_thread
*ct
;
1384 struct target
*target
= get_target_from_connection(connection
);
1385 struct linux_os
*linux_os
= (struct linux_os
*)
1386 target
->rtos
->rtos_specific_params
;
1388 switch (packet
[0]) {
1389 case 'T': /* Is thread alive?*/
1391 linux_gdb_T_packet(connection
, target
, packet
, packet_size
);
1393 case 'H': /* Set current thread */
1394 /* ( 'c' for step and continue, 'g' for all other operations )*/
1395 /*LOG_INFO(" H packet received '%s'", packet);*/
1396 linux_gdb_h_packet(connection
, target
, packet
, packet_size
);
1400 if (strncmp(packet
, "qSymbol", 7) == 0) {
1401 if (rtos_qsymbol(connection
, packet
, packet_size
) == 1) {
1402 linux_compute_virt2phys(target
,
1409 } else if (strncmp(packet
, "qfThreadInfo", 12) == 0) {
1410 if (linux_os
->thread_list
== NULL
) {
1411 retval
= linux_gdb_thread_packet(target
,
1417 retval
= linux_gdb_thread_update(target
,
1423 } else if (strncmp(packet
, "qsThreadInfo", 12) == 0) {
1424 gdb_put_packet(connection
, "l", 1);
1426 } else if (strncmp(packet
, "qThreadExtraInfo,", 17) == 0) {
1427 linux_thread_extra_info(target
, connection
, packet
,
1431 retval
= GDB_THREAD_PACKET_NOT_CONSUMED
;
1436 /* previously response was : thread not found
1437 * gdb_put_packet(connection, "E01", 3); */
1438 retval
= GDB_THREAD_PACKET_NOT_CONSUMED
;
1442 if (linux_os
->threads_lookup
== 1) {
1443 ct
= linux_os
->current_threads
;
1445 while ((ct
!= NULL
) && (ct
->core_id
) != target
->coreid
)
1448 if ((ct
!= NULL
) && (ct
->threadid
== -1)) {
1449 ct
= linux_os
->current_threads
;
1451 while ((ct
!= NULL
) && (ct
->threadid
== -1))
1455 if ((ct
!= NULL
) && (ct
->threadid
!=
1458 && (target
->rtos
->current_threadid
!= -1))
1459 LOG_WARNING("WARNING! current GDB thread do not match" \
1460 "current thread running." \
1461 "Switch thread in GDB to threadid %d",
1464 LOG_INFO("threads_needs_update = 1");
1465 linux_os
->threads_needs_update
= 1;
1469 /* if a packet handler returned an error, exit input loop */
1470 if (retval
!= ERROR_OK
)
1477 static int linux_os_smp_init(struct target
*target
)
1479 struct target_list
*head
;
1480 /* keep only target->rtos */
1481 struct rtos
*rtos
= target
->rtos
;
1482 struct linux_os
*os_linux
=
1483 (struct linux_os
*)rtos
->rtos_specific_params
;
1484 struct current_thread
*ct
;
1485 head
= target
->head
;
1487 while (head
!= (struct target_list
*)NULL
) {
1488 if (head
->target
->rtos
!= rtos
) {
1489 struct linux_os
*smp_os_linux
=
1490 (struct linux_os
*)head
->target
->rtos
->
1491 rtos_specific_params
;
1492 /* remap smp target on rtos */
1493 free(head
->target
->rtos
);
1494 head
->target
->rtos
= rtos
;
1495 /* reuse allocated ct */
1496 ct
= smp_os_linux
->current_threads
;
1498 ct
->TS
= 0xdeadbeef;
1499 ct
->core_id
= head
->target
->coreid
;
1500 os_linux
->current_threads
=
1501 add_current_thread(os_linux
->current_threads
, ct
);
1502 os_linux
->nr_cpus
++;
1512 static int linux_os_create(struct target
*target
)
1514 struct linux_os
*os_linux
= calloc(1, sizeof(struct linux_os
));
1515 struct current_thread
*ct
= calloc(1, sizeof(struct current_thread
));
1516 LOG_INFO("linux os creation\n");
1517 os_linux
->init_task_addr
= 0xdeadbeef;
1518 os_linux
->name
= "linux";
1519 os_linux
->thread_list
= NULL
;
1520 os_linux
->thread_count
= 0;
1521 target
->rtos
->current_threadid
= -1;
1522 os_linux
->nr_cpus
= 1;
1523 os_linux
->threads_lookup
= 0;
1524 os_linux
->threads_needs_update
= 0;
1525 os_linux
->threadid_count
= 1;
1526 os_linux
->current_threads
= NULL
;
1527 target
->rtos
->rtos_specific_params
= (void *)os_linux
;
1528 ct
->core_id
= target
->coreid
;
1530 ct
->TS
= 0xdeadbeef;
1531 os_linux
->current_threads
=
1532 add_current_thread(os_linux
->current_threads
, ct
);
1533 /* overload rtos thread default handler */
1534 target
->rtos
->gdb_thread_packet
= linux_thread_packet
;
1535 /* initialize a default virt 2 phys translation */
1536 os_linux
->phys_mask
= ~0xc0000000;
1537 os_linux
->phys_base
= 0x0;
1541 static char *linux_ps_command(struct target
*target
)
1543 struct linux_os
*linux_os
= (struct linux_os
*)
1544 target
->rtos
->rtos_specific_params
;
1545 int retval
= ERROR_OK
;
1548 if (linux_os
->threads_lookup
== 0)
1549 retval
= linux_get_tasks(target
, 1);
1551 if (linux_os
->threads_needs_update
!= 0)
1552 retval
= linux_task_update(target
, 0);
1555 if (retval
== ERROR_OK
) {
1556 struct threads
*temp
= linux_os
->thread_list
;
1558 LOG_INFO("allocation for %d threads line",
1559 linux_os
->thread_count
);
1560 display
= calloc((linux_os
->thread_count
+ 2) * 80, 1);
1566 tmp
+= sprintf(tmp
, "PID\t\tCPU\t\tASID\t\tNAME\n");
1567 tmp
+= sprintf(tmp
, "---\t\t---\t\t----\t\t----\n");
1569 while (temp
!= NULL
) {
1574 "%d\t\t%d\t\t%x\t\t%s\n",
1575 (int)temp
->pid
, temp
->oncpu
,
1576 temp
->asid
, temp
->name
);
1580 "%d\t\t%d\t\t%x\t\t%s\n",
1581 (int)temp
->pid
, temp
->oncpu
,
1582 temp
->asid
, temp
->name
);
1592 display
= calloc(40, 1);
1593 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)