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 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 %" PRIx32
"!!", 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 %" PRIx32
,
226 /*LOG_INFO("thread %lx current on core %x",thread_id,
229 target_get_gdb_reg_list(target
, ®_list
, ®_list_size
,
232 if (retval
!= ERROR_OK
)
235 for (i
= 0; i
< reg_list_size
; i
++)
236 reg_packet_size
+= reg_list
[i
]->size
;
238 assert(reg_packet_size
> 0);
240 *hex_reg_list
= malloc(DIV_ROUND_UP(reg_packet_size
, 8) * 2);
242 hex_string
= *hex_reg_list
;
244 for (i
= 0; i
< reg_list_size
; i
++) {
245 if (!reg_list
[i
]->valid
)
246 reg_list
[i
]->type
->get(reg_list
[i
]);
248 hex_string
= reg_converter(hex_string
,
250 (reg_list
[i
]->size
) / 8);
256 struct threads
*temp
= linux_os
->thread_list
;
257 *hex_reg_list
= calloc(1, 500 * sizeof(char));
258 hex_string
= *hex_reg_list
;
260 for (i
= 0; i
< 16; i
++)
261 hex_string
+= sprintf(hex_string
, "%02x", 0);
263 while ((temp
!= NULL
) &&
264 (temp
->threadid
!= target
->rtos
->current_threadid
))
268 if (temp
->context
== NULL
)
269 temp
->context
= cpu_context_read(target
,
276 reg_converter(hex_string
, &temp
->context
->R4
, 4);
278 reg_converter(hex_string
, &temp
->context
->R5
, 4);
280 reg_converter(hex_string
, &temp
->context
->R6
, 4);
282 reg_converter(hex_string
, &temp
->context
->R7
, 4);
284 reg_converter(hex_string
, &temp
->context
->R8
, 4);
286 reg_converter(hex_string
, &temp
->context
->R9
, 4);
288 for (i
= 0; i
< 4; i
++) /*R10 = 0x0 */
289 hex_string
+= sprintf(hex_string
, "%02x", 0);
292 reg_converter(hex_string
, &temp
->context
->FP
, 4);
294 reg_converter(hex_string
, &temp
->context
->IP
, 4);
296 reg_converter(hex_string
, &temp
->context
->SP
, 4);
298 for (i
= 0; i
< 4; i
++)
299 hex_string
+= sprintf(hex_string
, "%02x", 0);
302 reg_converter(hex_string
, &temp
->context
->PC
, 4);
304 for (i
= 0; i
< 100; i
++) /*100 */
305 hex_string
+= sprintf(hex_string
, "%02x", 0);
307 uint32_t cpsr
= 0x00000000;
308 reg_converter(hex_string
, &cpsr
, 4);
314 static int linux_os_detect(struct target
*target
)
316 LOG_INFO("should no be called");
320 static int linux_os_smp_init(struct target
*target
);
321 static int linux_os_clean(struct target
*target
);
323 static const char * const linux_symbol_list
[] = {
328 static int linux_get_symbol_list_to_lookup(symbol_table_elem_t
*symbol_list
[])
331 *symbol_list
= (symbol_table_elem_t
*)
332 calloc(ARRAY_SIZE(linux_symbol_list
), sizeof(symbol_table_elem_t
));
334 for (i
= 0; i
< ARRAY_SIZE(linux_symbol_list
); i
++)
335 (*symbol_list
)[i
].symbol_name
= linux_symbol_list
[i
];
340 static char *linux_ps_command(struct target
*target
);
342 const struct rtos_type Linux_os
= {
344 .detect_rtos
= linux_os_detect
,
345 .create
= linux_os_create
,
346 .smp_init
= linux_os_smp_init
,
347 .update_threads
= linux_os_dummy_update
,
348 .get_thread_reg_list
= linux_os_thread_reg_list
,
349 .get_symbol_list_to_lookup
= linux_get_symbol_list_to_lookup
,
350 .clean
= linux_os_clean
,
351 .ps_command
= linux_ps_command
,
354 static int linux_thread_packet(struct connection
*connection
, char const *packet
,
356 static void linux_identify_current_threads(struct target
*target
);
359 int fill_task_pid(struct target
*target
, struct threads
*t
)
361 uint32_t pid_addr
= t
->base_addr
+ PID
;
363 int retval
= fill_buffer(target
, pid_addr
, buffer
);
365 if (retval
== ERROR_OK
) {
366 uint32_t val
= get_buffer(target
, buffer
);
369 LOG_ERROR("fill_task_pid: unable to read memory");
375 int fill_task(struct target
*target
, struct threads
*t
)
378 uint32_t pid_addr
= t
->base_addr
+ PID
;
379 uint32_t mem_addr
= t
->base_addr
+ MEM
;
380 uint32_t on_cpu
= t
->base_addr
+ ONCPU
;
381 uint8_t *buffer
= calloc(1, 4);
382 retval
= fill_buffer(target
, t
->base_addr
, buffer
);
384 if (retval
== ERROR_OK
) {
385 uint32_t val
= get_buffer(target
, buffer
);
388 LOG_ERROR("fill_task: unable to read memory");
390 retval
= fill_buffer(target
, pid_addr
, buffer
);
392 if (retval
== ERROR_OK
) {
393 uint32_t val
= get_buffer(target
, buffer
);
396 LOG_ERROR("fill task: unable to read memory");
398 retval
= fill_buffer(target
, on_cpu
, buffer
);
400 if (retval
== ERROR_OK
) {
401 uint32_t val
= get_buffer(target
, buffer
);
404 LOG_ERROR("fill task: unable to read memory");
406 retval
= fill_buffer(target
, mem_addr
, buffer
);
408 if (retval
== ERROR_OK
) {
409 uint32_t val
= get_buffer(target
, buffer
);
412 uint32_t asid_addr
= val
+ MM_CTX
;
413 retval
= fill_buffer(target
, asid_addr
, buffer
);
415 if (retval
== ERROR_OK
) {
416 val
= get_buffer(target
, buffer
);
420 ("fill task: unable to read memory -- ASID");
424 LOG_ERROR("fill task: unable to read memory");
431 int get_name(struct target
*target
, struct threads
*t
)
434 uint32_t full_name
[4];
435 uint32_t comm
= t
->base_addr
+ COMM
;
438 for (i
= 0; i
< 17; i
++)
441 retval
= linux_read_memory(target
, comm
, 4, 4, (uint8_t *) full_name
);
443 if (retval
!= ERROR_OK
) {
444 LOG_ERROR("get_name: unable to read memory\n");
448 uint32_t raw_name
= target_buffer_get_u32(target
,
451 t
->name
[3] = raw_name
>> 24;
452 t
->name
[2] = raw_name
>> 16;
453 t
->name
[1] = raw_name
>> 8;
454 t
->name
[0] = raw_name
;
456 target_buffer_get_u32(target
, (const uint8_t *)&full_name
[1]);
457 t
->name
[7] = raw_name
>> 24;
458 t
->name
[6] = raw_name
>> 16;
459 t
->name
[5] = raw_name
>> 8;
460 t
->name
[4] = raw_name
;
462 target_buffer_get_u32(target
, (const uint8_t *)&full_name
[2]);
463 t
->name
[11] = raw_name
>> 24;
464 t
->name
[10] = raw_name
>> 16;
465 t
->name
[9] = raw_name
>> 8;
466 t
->name
[8] = raw_name
;
468 target_buffer_get_u32(target
, (const uint8_t *)&full_name
[3]);
469 t
->name
[15] = raw_name
>> 24;
470 t
->name
[14] = raw_name
>> 16;
471 t
->name
[13] = raw_name
>> 8;
472 t
->name
[12] = raw_name
;
477 int get_current(struct target
*target
, int create
)
479 struct target_list
*head
;
484 uint8_t *buffer
= calloc(1, 4);
485 struct linux_os
*linux_os
= (struct linux_os
*)
486 target
->rtos
->rtos_specific_params
;
487 struct current_thread
*ctt
= linux_os
->current_threads
;
489 /* invalid current threads content */
490 while (ctt
!= NULL
) {
492 ctt
->TS
= 0xdeadbeef;
496 while (head
!= (struct target_list
*)NULL
) {
497 struct reg
**reg_list
;
501 if (target_get_gdb_reg_list(head
->target
, ®_list
,
502 ®_list_size
, REG_CLASS_GENERAL
) != ERROR_OK
) {
504 return ERROR_TARGET_FAILURE
;
507 if (!reg_list
[13]->valid
)
508 reg_list
[13]->type
->get(reg_list
[13]);
510 buf
= reg_list
[13]->value
;
511 val
= get_buffer(target
, buf
);
512 ti_addr
= (val
& 0xffffe000);
513 uint32_t TS_addr
= ti_addr
+ 0xc;
514 retval
= fill_buffer(target
, TS_addr
, buffer
);
516 if (retval
== ERROR_OK
) {
517 uint32_t TS
= get_buffer(target
, buffer
);
518 uint32_t cpu
, on_cpu
= TS
+ ONCPU
;
519 retval
= fill_buffer(target
, on_cpu
, buffer
);
521 if (retval
== ERROR_OK
) {
522 /*uint32_t cpu = get_buffer(target, buffer);*/
523 struct current_thread
*ct
=
524 linux_os
->current_threads
;
525 cpu
= head
->target
->coreid
;
527 while ((ct
!= NULL
) && (ct
->core_id
!= (int32_t) cpu
))
530 if ((ct
!= NULL
) && (ct
->TS
== 0xdeadbeef))
534 ("error in linux current thread update");
538 t
= calloc(1, sizeof(struct threads
));
539 t
->base_addr
= ct
->TS
;
540 fill_task(target
, t
);
543 insert_into_threadlist(target
, t
);
545 t
->thread_info_addr
= 0xdeadbeef;
546 ct
->threadid
= t
->threadid
;
547 linux_os
->thread_count
++;
551 /*LOG_INFO("Creation of current thread %s",t->name);*/
565 struct cpu_context
*cpu_context_read(struct target
*target
, uint32_t base_addr
,
566 uint32_t *thread_info_addr_old
)
568 struct cpu_context
*context
= calloc(1, sizeof(struct cpu_context
));
569 uint32_t preempt_count_addr
= 0;
570 uint32_t registers
[10];
571 uint8_t *buffer
= calloc(1, 4);
572 uint32_t stack
= base_addr
+ QAT
;
573 uint32_t thread_info_addr
= 0;
574 uint32_t thread_info_addr_update
= 0;
575 int retval
= ERROR_FAIL
;
576 context
->R4
= 0xdeadbeef;
577 context
->R5
= 0xdeadbeef;
578 context
->R6
= 0xdeadbeef;
579 context
->R7
= 0xdeadbeef;
580 context
->R8
= 0xdeadbeef;
581 context
->R9
= 0xdeadbeef;
582 context
->IP
= 0xdeadbeef;
583 context
->FP
= 0xdeadbeef;
584 context
->SP
= 0xdeadbeef;
585 context
->PC
= 0xdeadbeef;
588 if (*thread_info_addr_old
== 0xdeadbeef) {
589 retval
= fill_buffer(target
, stack
, buffer
);
591 if (retval
== ERROR_OK
)
592 thread_info_addr
= get_buffer(target
, buffer
);
594 LOG_ERROR("cpu_context: unable to read memory");
596 thread_info_addr_update
= thread_info_addr
;
598 thread_info_addr
= *thread_info_addr_old
;
600 preempt_count_addr
= thread_info_addr
+ PREEMPT
;
601 retval
= fill_buffer(target
, preempt_count_addr
, buffer
);
603 if (retval
== ERROR_OK
)
604 context
->preempt_count
= get_buffer(target
, buffer
);
606 if (*thread_info_addr_old
!= 0xdeadbeef) {
608 ("cpu_context: cannot read at thread_info_addr");
610 if (*thread_info_addr_old
< LINUX_USER_KERNEL_BORDER
)
612 ("cpu_context : thread_info_addr in userspace!!!");
614 *thread_info_addr_old
= 0xdeadbeef;
618 LOG_ERROR("cpu_context: unable to read memory");
621 thread_info_addr
+= CPU_CONT
;
623 retval
= linux_read_memory(target
, thread_info_addr
, 4, 10,
624 (uint8_t *) registers
);
626 if (retval
!= ERROR_OK
) {
628 LOG_ERROR("cpu_context: unable to read memory\n");
633 target_buffer_get_u32(target
, (const uint8_t *)®isters
[0]);
635 target_buffer_get_u32(target
, (const uint8_t *)®isters
[1]);
637 target_buffer_get_u32(target
, (const uint8_t *)®isters
[2]);
639 target_buffer_get_u32(target
, (const uint8_t *)®isters
[3]);
641 target_buffer_get_u32(target
, (const uint8_t *)®isters
[4]);
643 target_buffer_get_u32(target
, (const uint8_t *)®isters
[5]);
645 target_buffer_get_u32(target
, (const uint8_t *)®isters
[6]);
647 target_buffer_get_u32(target
, (const uint8_t *)®isters
[7]);
649 target_buffer_get_u32(target
, (const uint8_t *)®isters
[8]);
651 target_buffer_get_u32(target
, (const uint8_t *)®isters
[9]);
653 if (*thread_info_addr_old
== 0xdeadbeef)
654 *thread_info_addr_old
= thread_info_addr_update
;
661 uint32_t next_task(struct target
*target
, struct threads
*t
)
663 uint8_t *buffer
= calloc(1, 4);
664 uint32_t next_addr
= t
->base_addr
+ NEXT
;
665 int retval
= fill_buffer(target
, next_addr
, buffer
);
667 if (retval
== ERROR_OK
) {
668 uint32_t val
= get_buffer(target
, buffer
);
673 LOG_ERROR("next task: unable to read memory");
680 struct current_thread
*add_current_thread(struct current_thread
*currents
,
681 struct current_thread
*ct
)
685 if (currents
== NULL
) {
689 struct current_thread
*temp
= currents
;
691 while (temp
->next
!= NULL
)
699 struct threads
*liste_del_task(struct threads
*task_list
, struct threads
**t
,
700 struct threads
*prev
)
702 LOG_INFO("del task %" PRId64
, (*t
)->threadid
);
703 prev
->next
= (*t
)->next
;
705 if (prev
== task_list
)
708 /* free content of threads */
717 struct threads
*liste_add_task(struct threads
*task_list
, struct threads
*t
,
718 struct threads
**last
)
723 if (task_list
== NULL
) {
727 struct threads
*temp
= task_list
;
729 while (temp
->next
!= NULL
)
743 static int current_pid(struct linux_os
*linux_os
, uint32_t pid
)
745 static int current_base_addr(struct linux_os
*linux_os
, uint32_t base_addr
)
748 struct current_thread
*ct
= linux_os
->current_threads
;
751 while ((ct
!= NULL
) && (ct
->pid
!= pid
))
753 while ((ct
!= NULL
) && (ct
->TS
!= base_addr
))
757 if ((ct
!= NULL
) && (ct
->pid
== pid
))
759 if ((ct
!= NULL
) && (ct
->TS
== base_addr
))
766 int linux_get_tasks(struct target
*target
, int context
)
770 struct linux_os
*linux_os
= (struct linux_os
*)
771 target
->rtos
->rtos_specific_params
;
772 linux_os
->thread_list
= NULL
;
773 linux_os
->thread_count
= 0;
775 if (linux_os
->init_task_addr
== 0xdeadbeef) {
776 LOG_INFO("no init symbol\n");
780 int64_t start
= timeval_ms();
782 struct threads
*t
= calloc(1, sizeof(struct threads
));
783 struct threads
*last
= NULL
;
784 t
->base_addr
= linux_os
->init_task_addr
;
785 /* retrieve the thread id , currently running in the different smp core */
786 get_current(target
, 1);
788 while (((t
->base_addr
!= linux_os
->init_task_addr
) &&
789 (t
->base_addr
!= 0)) || (loop
== 0)) {
791 fill_task(target
, t
);
792 retval
= get_name(target
, t
);
794 if (loop
> MAX_THREADS
) {
796 LOG_INFO("more than %d threads !!", MAX_THREADS
);
800 if (retval
!= ERROR_OK
) {
805 /* check that this thread is not one the current threads already
809 if (!current_pid(linux_os
, t
->pid
)) {
811 if (!current_base_addr(linux_os
, t
->base_addr
)) {
813 t
->threadid
= linux_os
->threadid_count
;
815 linux_os
->threadid_count
++;
817 linux_os
->thread_list
=
818 liste_add_task(linux_os
->thread_list
, t
, &last
);
819 /* no interest to fill the context if it is a current thread. */
820 linux_os
->thread_count
++;
821 t
->thread_info_addr
= 0xdeadbeef;
825 cpu_context_read(target
, t
->base_addr
,
826 &t
->thread_info_addr
);
828 /*LOG_INFO("thread %s is a current thread already created",t->name); */
832 uint32_t base_addr
= next_task(target
, t
);
833 t
= calloc(1, sizeof(struct threads
));
834 t
->base_addr
= base_addr
;
837 linux_os
->threads_lookup
= 1;
838 linux_os
->threads_needs_update
= 0;
839 linux_os
->preupdtate_threadid_count
= linux_os
->threadid_count
- 1;
840 /* check that all current threads have been identified */
842 LOG_INFO("complete time %" PRId64
", thread mean %" PRId64
"\n",
843 (timeval_ms() - start
),
844 (timeval_ms() - start
) / linux_os
->threadid_count
);
846 LOG_INFO("threadid count %d", linux_os
->threadid_count
);
852 static int clean_threadlist(struct target
*target
)
854 struct linux_os
*linux_os
= (struct linux_os
*)
855 target
->rtos
->rtos_specific_params
;
856 struct threads
*old
, *temp
= linux_os
->thread_list
;
858 while (temp
!= NULL
) {
871 static int linux_os_clean(struct target
*target
)
873 struct linux_os
*os_linux
= (struct linux_os
*)
874 target
->rtos
->rtos_specific_params
;
875 clean_threadlist(target
);
876 os_linux
->init_task_addr
= 0xdeadbeef;
877 os_linux
->name
= "linux";
878 os_linux
->thread_list
= NULL
;
879 os_linux
->thread_count
= 0;
880 os_linux
->nr_cpus
= 0;
881 os_linux
->threads_lookup
= 0;
882 os_linux
->threads_needs_update
= 0;
883 os_linux
->threadid_count
= 1;
887 static int insert_into_threadlist(struct target
*target
, struct threads
*t
)
889 struct linux_os
*linux_os
= (struct linux_os
*)
890 target
->rtos
->rtos_specific_params
;
891 struct threads
*temp
= linux_os
->thread_list
;
892 t
->threadid
= linux_os
->threadid_count
;
893 linux_os
->threadid_count
++;
898 linux_os
->thread_list
= t
;
900 while (temp
->next
!= NULL
)
910 static void linux_identify_current_threads(struct target
*target
)
912 struct linux_os
*linux_os
= (struct linux_os
*)
913 target
->rtos
->rtos_specific_params
;
914 struct threads
*thread_list
= linux_os
->thread_list
;
915 struct current_thread
*ct
= linux_os
->current_threads
;
916 struct threads
*t
= NULL
;
918 while ((ct
!= NULL
)) {
919 if (ct
->threadid
== -1) {
921 /* un-identified thread */
923 t
= calloc(1, sizeof(struct threads
));
924 t
->base_addr
= ct
->TS
;
927 if (fill_task_pid(target
, t
) != ERROR_OK
) {
931 ("linux identify_current_threads: unable to read pid");
936 /* search in the list of threads if pid
938 while ((thread_list
!= NULL
) && (found
== 0)) {
940 if (thread_list
->pid
== t
->pid
) {
942 if (thread_list
->base_addr
== t
->base_addr
) {
948 thread_list
= thread_list
->next
;
952 /* it is a new thread */
953 if (fill_task(target
, t
) != ERROR_OK
)
957 insert_into_threadlist(target
, t
);
958 t
->thread_info_addr
= 0xdeadbeef;
962 ct
->threadid
= t
->threadid
;
966 linux_os
->thread_count
++;
969 LOG_INFO("current thread core %x identified %s",
970 ct
->core_id
, t
->name
);
972 LOG_INFO("current thread core %x, reused %s",
973 ct
->core_id
, t
->name
);
979 tmp
.base_addr
= ct
->TS
;
980 get_name(target
, &tmp
);
981 LOG_INFO("current thread core %x , already identified %s !!!",
982 ct
->core_id
, tmp
.name
);
992 LOG_ERROR("unable to read pid");
998 static int linux_task_update(struct target
*target
, int context
)
1000 struct linux_os
*linux_os
= (struct linux_os
*)
1001 target
->rtos
->rtos_specific_params
;
1002 struct threads
*thread_list
= linux_os
->thread_list
;
1005 linux_os
->thread_count
= 0;
1007 /*thread_list = thread_list->next; skip init_task*/
1008 while (thread_list
!= NULL
) {
1009 thread_list
->status
= 0; /*setting all tasks to dead state*/
1011 if (thread_list
->context
) {
1012 free(thread_list
->context
);
1013 thread_list
->context
= NULL
;
1016 thread_list
= thread_list
->next
;
1021 if (linux_os
->init_task_addr
== 0xdeadbeef) {
1022 LOG_INFO("no init symbol\n");
1025 int64_t start
= timeval_ms();
1026 struct threads
*t
= calloc(1, sizeof(struct threads
));
1027 uint32_t previous
= 0xdeadbeef;
1028 t
->base_addr
= linux_os
->init_task_addr
;
1029 retval
= get_current(target
, 0);
1030 /*check that all current threads have been identified */
1031 linux_identify_current_threads(target
);
1033 while (((t
->base_addr
!= linux_os
->init_task_addr
) &&
1034 (t
->base_addr
!= previous
)) || (loop
== 0)) {
1035 /* for avoiding any permanent loop for any reason possibly due to
1038 previous
= t
->base_addr
;
1041 retval
= fill_task_pid(target
, t
);
1044 if (retval
!= ERROR_OK
) {
1049 thread_list
= linux_os
->thread_list
;
1051 while (thread_list
!= NULL
) {
1053 if (t
->pid
== thread_list
->pid
) {
1055 if (t
->base_addr
== thread_list
->base_addr
) {
1057 if (!thread_list
->status
) {
1059 if (t
->base_addr
!= thread_list
->base_addr
)
1060 LOG_INFO("thread base_addr has changed !!");
1062 /* this is not a current thread */
1063 thread_list
->base_addr
= t
->base_addr
;
1064 thread_list
->status
= 1;
1066 /* we don 't update this field any more */
1068 /*thread_list->state = t->state;
1069 thread_list->oncpu = t->oncpu;
1070 thread_list->asid = t->asid;
1073 thread_list
->context
=
1074 cpu_context_read(target
,
1080 /* it is a current thread no need to read context */
1083 linux_os
->thread_count
++;
1088 thread_list
= thread_list
->next
;
1094 fill_task(target
, t
);
1095 get_name(target
, t
);
1096 retval
= insert_into_threadlist(target
, t
);
1097 t
->thread_info_addr
= 0xdeadbeef;
1101 cpu_context_read(target
, t
->base_addr
,
1102 &t
->thread_info_addr
);
1104 base_addr
= next_task(target
, t
);
1105 t
= calloc(1, sizeof(struct threads
));
1106 t
->base_addr
= base_addr
;
1107 linux_os
->thread_count
++;
1109 t
->base_addr
= next_task(target
, t
);
1112 LOG_INFO("update thread done %" PRId64
", mean%" PRId64
"\n",
1113 (timeval_ms() - start
), (timeval_ms() - start
) / loop
);
1115 linux_os
->threads_needs_update
= 0;
1119 int linux_gdb_thread_packet(struct target
*target
,
1120 struct connection
*connection
, char const *packet
,
1124 struct linux_os
*linux_os
=
1125 (struct linux_os
*)target
->rtos
->rtos_specific_params
;
1127 if (linux_os
->init_task_addr
== 0xdeadbeef) {
1128 /* it has not been initialized */
1129 LOG_INFO("received thread request without init task address");
1130 gdb_put_packet(connection
, "l", 1);
1134 retval
= linux_get_tasks(target
, 1);
1136 if (retval
!= ERROR_OK
)
1137 return ERROR_TARGET_FAILURE
;
1139 char *out_str
= calloc(1, 350 * sizeof(int64_t));
1140 char *tmp_str
= out_str
;
1141 tmp_str
+= sprintf(tmp_str
, "m");
1142 struct threads
*temp
= linux_os
->thread_list
;
1144 while (temp
!= NULL
) {
1145 tmp_str
+= sprintf(tmp_str
, "%016" PRIx64
, temp
->threadid
);
1148 tmp_str
+= sprintf(tmp_str
, ",");
1151 gdb_put_packet(connection
, out_str
, strlen(out_str
));
1156 int linux_gdb_thread_update(struct target
*target
,
1157 struct connection
*connection
, char const *packet
,
1161 struct linux_os
*linux_os
= (struct linux_os
*)
1162 target
->rtos
->rtos_specific_params
;
1163 struct threads
*temp
= linux_os
->thread_list
;
1165 while (temp
!= NULL
) {
1166 if (temp
->threadid
== linux_os
->preupdtate_threadid_count
+ 1) {
1167 /*LOG_INFO("FOUND");*/
1175 /*LOG_INFO("INTO GDB THREAD UPDATE FOUNDING START TASK");*/
1176 char *out_strr
= calloc(1, 350 * sizeof(int64_t));
1177 char *tmp_strr
= out_strr
;
1178 tmp_strr
+= sprintf(tmp_strr
, "m");
1179 /*LOG_INFO("CHAR MALLOC & M DONE");*/
1180 tmp_strr
+= sprintf(tmp_strr
, "%016" PRIx64
, temp
->threadid
);
1184 while (temp
!= NULL
) {
1185 /*LOG_INFO("INTO GDB THREAD UPDATE WHILE");*/
1186 tmp_strr
+= sprintf(tmp_strr
, ",");
1188 sprintf(tmp_strr
, "%016" PRIx64
, temp
->threadid
);
1193 gdb_put_packet(connection
, out_strr
, strlen(out_strr
));
1194 linux_os
->preupdtate_threadid_count
=
1195 linux_os
->threadid_count
- 1;
1198 gdb_put_packet(connection
, "l", 1);
1203 int linux_thread_extra_info(struct target
*target
,
1204 struct connection
*connection
, char const *packet
,
1207 int64_t threadid
= 0;
1208 struct linux_os
*linux_os
= (struct linux_os
*)
1209 target
->rtos
->rtos_specific_params
;
1210 sscanf(packet
, "qThreadExtraInfo,%" SCNx64
, &threadid
);
1211 /*LOG_INFO("lookup extra info for thread %" SCNx64, threadid);*/
1212 struct threads
*temp
= linux_os
->thread_list
;
1214 while (temp
!= NULL
) {
1215 if (temp
->threadid
== threadid
) {
1216 char *pid
= " PID: ";
1217 char *pid_current
= "*PID: ";
1218 char *name
= "NAME: ";
1219 int str_size
= strlen(pid
) + strlen(name
);
1220 char *tmp_str
= calloc(1, str_size
+ 50);
1221 char *tmp_str_ptr
= tmp_str
;
1223 /* discriminate current task */
1224 if (temp
->status
== 3)
1225 tmp_str_ptr
+= sprintf(tmp_str_ptr
, "%s",
1228 tmp_str_ptr
+= sprintf(tmp_str_ptr
, "%s", pid
);
1231 sprintf(tmp_str_ptr
, "%d", (int)temp
->pid
);
1232 tmp_str_ptr
+= sprintf(tmp_str_ptr
, "%s", " | ");
1233 sprintf(tmp_str_ptr
, "%s", name
);
1234 sprintf(tmp_str_ptr
, "%s", temp
->name
);
1235 char *hex_str
= calloc(1, strlen(tmp_str
) * 2 + 1);
1236 int pkt_len
= hexify(hex_str
, tmp_str
, 0, strlen(tmp_str
) * 2 + 1);
1237 gdb_put_packet(connection
, hex_str
, pkt_len
);
1246 LOG_INFO("thread not found");
1250 int linux_gdb_T_packet(struct connection
*connection
,
1251 struct target
*target
, char const *packet
, int packet_size
)
1254 struct linux_os
*linux_os
= (struct linux_os
*)
1255 target
->rtos
->rtos_specific_params
;
1256 int retval
= ERROR_OK
;
1257 sscanf(packet
, "T%" SCNx64
, &threadid
);
1259 if (linux_os
->threads_needs_update
== 0) {
1260 struct threads
*temp
= linux_os
->thread_list
;
1261 struct threads
*prev
= linux_os
->thread_list
;
1263 while (temp
!= NULL
) {
1264 if (temp
->threadid
== threadid
) {
1265 if (temp
->status
!= 0) {
1266 gdb_put_packet(connection
, "OK", 2);
1269 /* delete item in the list */
1270 linux_os
->thread_list
=
1271 liste_del_task(linux_os
->
1274 linux_os
->thread_count
--;
1275 gdb_put_packet(connection
, "E01", 3);
1285 LOG_INFO("gdb requested status on non existing thread");
1286 gdb_put_packet(connection
, "E01", 3);
1290 retval
= linux_task_update(target
, 1);
1291 struct threads
*temp
= linux_os
->thread_list
;
1293 while (temp
!= NULL
) {
1294 if (temp
->threadid
== threadid
) {
1295 if (temp
->status
== 1) {
1296 gdb_put_packet(connection
, "OK", 2);
1299 gdb_put_packet(connection
, "E01", 3);
1311 int linux_gdb_h_packet(struct connection
*connection
,
1312 struct target
*target
, char const *packet
, int packet_size
)
1314 struct linux_os
*linux_os
= (struct linux_os
*)
1315 target
->rtos
->rtos_specific_params
;
1316 struct current_thread
*ct
= linux_os
->current_threads
;
1318 /* select to display the current thread of the selected target */
1319 while ((ct
!= NULL
) && (ct
->core_id
!= target
->coreid
))
1322 int64_t current_gdb_thread_rq
;
1324 if (linux_os
->threads_lookup
== 1) {
1325 if ((ct
!= NULL
) && (ct
->threadid
== -1)) {
1326 ct
= linux_os
->current_threads
;
1328 while ((ct
!= NULL
) && (ct
->threadid
== -1))
1333 /* no current thread can be identified
1334 * any way with smp */
1335 LOG_INFO("no current thread identified");
1336 /* attempt to display the name of the 2 threads identified with
1339 ct
= linux_os
->current_threads
;
1341 while ((ct
!= NULL
) && (ct
->threadid
== -1)) {
1342 t
.base_addr
= ct
->TS
;
1343 get_name(target
, &t
);
1344 LOG_INFO("name of unidentified thread %s",
1349 gdb_put_packet(connection
, "OK", 2);
1353 if (packet
[1] == 'g') {
1354 sscanf(packet
, "Hg%16" SCNx64
, ¤t_gdb_thread_rq
);
1356 if (current_gdb_thread_rq
== 0) {
1357 target
->rtos
->current_threadid
= ct
->threadid
;
1358 gdb_put_packet(connection
, "OK", 2);
1360 target
->rtos
->current_threadid
=
1361 current_gdb_thread_rq
;
1362 gdb_put_packet(connection
, "OK", 2);
1364 } else if (packet
[1] == 'c') {
1365 sscanf(packet
, "Hc%16" SCNx64
, ¤t_gdb_thread_rq
);
1367 if ((current_gdb_thread_rq
== 0) ||
1368 (current_gdb_thread_rq
== ct
->threadid
)) {
1369 target
->rtos
->current_threadid
= ct
->threadid
;
1370 gdb_put_packet(connection
, "OK", 2);
1372 gdb_put_packet(connection
, "E01", 3);
1375 gdb_put_packet(connection
, "OK", 2);
1380 static int linux_thread_packet(struct connection
*connection
, char const *packet
,
1383 int retval
= ERROR_OK
;
1384 struct current_thread
*ct
;
1385 struct target
*target
= get_target_from_connection(connection
);
1386 struct linux_os
*linux_os
= (struct linux_os
*)
1387 target
->rtos
->rtos_specific_params
;
1389 switch (packet
[0]) {
1390 case 'T': /* Is thread alive?*/
1392 linux_gdb_T_packet(connection
, target
, packet
, packet_size
);
1394 case 'H': /* Set current thread */
1395 /* ( 'c' for step and continue, 'g' for all other operations )*/
1396 /*LOG_INFO(" H packet received '%s'", packet);*/
1397 linux_gdb_h_packet(connection
, target
, packet
, packet_size
);
1401 if (strncmp(packet
, "qSymbol", 7) == 0) {
1402 if (rtos_qsymbol(connection
, packet
, packet_size
) == 1) {
1403 linux_compute_virt2phys(target
,
1410 } else if (strncmp(packet
, "qfThreadInfo", 12) == 0) {
1411 if (linux_os
->thread_list
== NULL
) {
1412 retval
= linux_gdb_thread_packet(target
,
1418 retval
= linux_gdb_thread_update(target
,
1424 } else if (strncmp(packet
, "qsThreadInfo", 12) == 0) {
1425 gdb_put_packet(connection
, "l", 1);
1427 } else if (strncmp(packet
, "qThreadExtraInfo,", 17) == 0) {
1428 linux_thread_extra_info(target
, connection
, packet
,
1432 retval
= GDB_THREAD_PACKET_NOT_CONSUMED
;
1437 /* previously response was : thread not found
1438 * gdb_put_packet(connection, "E01", 3); */
1439 retval
= GDB_THREAD_PACKET_NOT_CONSUMED
;
1443 if (linux_os
->threads_lookup
== 1) {
1444 ct
= linux_os
->current_threads
;
1446 while ((ct
!= NULL
) && (ct
->core_id
) != target
->coreid
)
1449 if ((ct
!= NULL
) && (ct
->threadid
== -1)) {
1450 ct
= linux_os
->current_threads
;
1452 while ((ct
!= NULL
) && (ct
->threadid
== -1))
1456 if ((ct
!= NULL
) && (ct
->threadid
!=
1459 && (target
->rtos
->current_threadid
!= -1))
1460 LOG_WARNING("WARNING! current GDB thread do not match" \
1461 "current thread running." \
1462 "Switch thread in GDB to threadid %d",
1465 LOG_INFO("threads_needs_update = 1");
1466 linux_os
->threads_needs_update
= 1;
1470 /* if a packet handler returned an error, exit input loop */
1471 if (retval
!= ERROR_OK
)
1478 static int linux_os_smp_init(struct target
*target
)
1480 struct target_list
*head
;
1481 /* keep only target->rtos */
1482 struct rtos
*rtos
= target
->rtos
;
1483 struct linux_os
*os_linux
=
1484 (struct linux_os
*)rtos
->rtos_specific_params
;
1485 struct current_thread
*ct
;
1486 head
= target
->head
;
1488 while (head
!= (struct target_list
*)NULL
) {
1489 if (head
->target
->rtos
!= rtos
) {
1490 struct linux_os
*smp_os_linux
=
1491 (struct linux_os
*)head
->target
->rtos
->
1492 rtos_specific_params
;
1493 /* remap smp target on rtos */
1494 free(head
->target
->rtos
);
1495 head
->target
->rtos
= rtos
;
1496 /* reuse allocated ct */
1497 ct
= smp_os_linux
->current_threads
;
1499 ct
->TS
= 0xdeadbeef;
1500 ct
->core_id
= head
->target
->coreid
;
1501 os_linux
->current_threads
=
1502 add_current_thread(os_linux
->current_threads
, ct
);
1503 os_linux
->nr_cpus
++;
1513 static int linux_os_create(struct target
*target
)
1515 struct linux_os
*os_linux
= calloc(1, sizeof(struct linux_os
));
1516 struct current_thread
*ct
= calloc(1, sizeof(struct current_thread
));
1517 LOG_INFO("linux os creation\n");
1518 os_linux
->init_task_addr
= 0xdeadbeef;
1519 os_linux
->name
= "linux";
1520 os_linux
->thread_list
= NULL
;
1521 os_linux
->thread_count
= 0;
1522 target
->rtos
->current_threadid
= -1;
1523 os_linux
->nr_cpus
= 1;
1524 os_linux
->threads_lookup
= 0;
1525 os_linux
->threads_needs_update
= 0;
1526 os_linux
->threadid_count
= 1;
1527 os_linux
->current_threads
= NULL
;
1528 target
->rtos
->rtos_specific_params
= os_linux
;
1529 ct
->core_id
= target
->coreid
;
1531 ct
->TS
= 0xdeadbeef;
1532 os_linux
->current_threads
=
1533 add_current_thread(os_linux
->current_threads
, ct
);
1534 /* overload rtos thread default handler */
1535 target
->rtos
->gdb_thread_packet
= linux_thread_packet
;
1536 /* initialize a default virt 2 phys translation */
1537 os_linux
->phys_mask
= ~0xc0000000;
1538 os_linux
->phys_base
= 0x0;
1542 static char *linux_ps_command(struct target
*target
)
1544 struct linux_os
*linux_os
= (struct linux_os
*)
1545 target
->rtos
->rtos_specific_params
;
1546 int retval
= ERROR_OK
;
1549 if (linux_os
->threads_lookup
== 0)
1550 retval
= linux_get_tasks(target
, 1);
1552 if (linux_os
->threads_needs_update
!= 0)
1553 retval
= linux_task_update(target
, 0);
1556 if (retval
== ERROR_OK
) {
1557 struct threads
*temp
= linux_os
->thread_list
;
1559 LOG_INFO("allocation for %d threads line",
1560 linux_os
->thread_count
);
1561 display
= calloc((linux_os
->thread_count
+ 2) * 80, 1);
1567 tmp
+= sprintf(tmp
, "PID\t\tCPU\t\tASID\t\tNAME\n");
1568 tmp
+= sprintf(tmp
, "---\t\t---\t\t----\t\t----\n");
1570 while (temp
!= NULL
) {
1575 "%" PRId32
"\t\t%" PRId32
"\t\t%" PRIx32
"\t\t%s\n",
1576 temp
->pid
, temp
->oncpu
,
1577 temp
->asid
, temp
->name
);
1581 "%" PRId32
"\t\t%" PRId32
"\t\t%" PRIx32
"\t\t%s\n",
1582 temp
->pid
, temp
->oncpu
,
1583 temp
->asid
, temp
->name
);
1593 display
= calloc(40, 1);
1594 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)