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"
32 #include "helper/log.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
->type
->read_phys_memory(target
, pa
, size
, count
, buffer
);
145 target
->type
->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));
219 ("current thread %" PRIx64
": no target to perform access of core id %x",
220 thread_id
, next
->core_id
);
224 /*LOG_INFO("thread %lx current on core %x",thread_id,
227 target_get_gdb_reg_list(target
, ®_list
, ®_list_size
);
229 if (retval
!= ERROR_OK
)
232 for (i
= 0; i
< reg_list_size
; i
++)
233 reg_packet_size
+= reg_list
[i
]->size
;
235 *hex_reg_list
= malloc(DIV_ROUND_UP(reg_packet_size
, 8) * 2);
237 hex_string
= *hex_reg_list
;
239 for (i
= 0; i
< reg_list_size
; i
++) {
240 if (!reg_list
[i
]->valid
)
241 reg_list
[i
]->type
->get(reg_list
[i
]);
243 hex_string
= reg_converter(hex_string
,
245 (reg_list
[i
]->size
) / 8);
251 struct threads
*temp
= linux_os
->thread_list
;
252 *hex_reg_list
= (char *)calloc(1, 500 * sizeof(char));
253 hex_string
= *hex_reg_list
;
255 for (i
= 0; i
< 16; i
++)
256 hex_string
+= sprintf(hex_string
, "%02x", 0);
258 while ((temp
!= NULL
) &&
259 (temp
->threadid
!= target
->rtos
->current_threadid
))
263 if (temp
->context
== NULL
)
264 temp
->context
= cpu_context_read(target
,
271 reg_converter(hex_string
, &temp
->context
->R4
, 4);
273 reg_converter(hex_string
, &temp
->context
->R5
, 4);
275 reg_converter(hex_string
, &temp
->context
->R6
, 4);
277 reg_converter(hex_string
, &temp
->context
->R7
, 4);
279 reg_converter(hex_string
, &temp
->context
->R8
, 4);
281 reg_converter(hex_string
, &temp
->context
->R9
, 4);
283 for (i
= 0; i
< 4; i
++) /*R10 = 0x0 */
284 hex_string
+= sprintf(hex_string
, "%02x", 0);
287 reg_converter(hex_string
, &temp
->context
->FP
, 4);
289 reg_converter(hex_string
, &temp
->context
->IP
, 4);
291 reg_converter(hex_string
, &temp
->context
->SP
, 4);
293 for (i
= 0; i
< 4; i
++)
294 hex_string
+= sprintf(hex_string
, "%02x", 0);
297 reg_converter(hex_string
, &temp
->context
->PC
, 4);
299 for (i
= 0; i
< 100; i
++) { /*100 */
300 hex_string
+= sprintf(hex_string
, "%02x", 0);
303 uint32_t cpsr
= 0x00000000;
304 hex_string
= reg_converter(hex_string
, &cpsr
, 4);
310 static int linux_os_detect(struct target
*target
)
312 LOG_INFO("should no be called");
316 static int linux_os_smp_init(struct target
*target
);
317 static int linux_os_clean(struct target
*target
);
319 static char *linux_symbol_list
[] = {
324 static int linux_get_symbol_list_to_lookup(symbol_table_elem_t
*symbol_list
[])
327 *symbol_list
= (symbol_table_elem_t
*)
328 malloc(sizeof(symbol_table_elem_t
) / sizeof(char *));
330 for (i
= 0; i
< sizeof(linux_symbol_list
) / sizeof(char *); i
++)
331 (*symbol_list
)[i
].symbol_name
= linux_symbol_list
[i
];
336 static char *linux_ps_command(struct target
*target
);
338 const struct rtos_type Linux_os
= {
340 .detect_rtos
= linux_os_detect
,
341 .create
= linux_os_create
,
342 .smp_init
= linux_os_smp_init
,
343 .update_threads
= linux_os_dummy_update
,
344 .get_thread_reg_list
= linux_os_thread_reg_list
,
345 .get_symbol_list_to_lookup
= linux_get_symbol_list_to_lookup
,
346 .clean
= linux_os_clean
,
347 .ps_command
= linux_ps_command
,
350 static int linux_thread_packet(struct connection
*connection
, char *packet
,
352 static void linux_identify_current_threads(struct target
*target
);
355 int fill_task_pid(struct target
*target
, struct threads
*t
)
357 uint32_t pid_addr
= t
->base_addr
+ PID
;
359 int retval
= fill_buffer(target
, pid_addr
, buffer
);
361 if (retval
== ERROR_OK
) {
362 uint32_t val
= get_buffer(target
, buffer
);
365 LOG_ERROR("fill_task_pid: unable to read memory");
371 int fill_task(struct target
*target
, struct threads
*t
)
375 uint32_t pid_addr
= t
->base_addr
+ PID
;
376 uint32_t mem_addr
= t
->base_addr
+ MEM
;
377 uint32_t on_cpu
= t
->base_addr
+ ONCPU
;
378 uint8_t *buffer
= calloc(1, 4);
379 retval
= fill_buffer(target
, t
->base_addr
, buffer
);
381 if (retval
== ERROR_OK
) {
382 uint32_t val
= get_buffer(target
, buffer
);
385 LOG_ERROR("fill_task: unable to read memory");
387 retval
= fill_buffer(target
, pid_addr
, buffer
);
389 if (retval
== ERROR_OK
) {
390 uint32_t val
= get_buffer(target
, buffer
);
393 LOG_ERROR("fill task: unable to read memory");
395 retval
= fill_buffer(target
, on_cpu
, buffer
);
397 if (retval
== ERROR_OK
) {
398 uint32_t val
= get_buffer(target
, buffer
);
401 LOG_ERROR("fill task: unable to read memory");
403 retval
= fill_buffer(target
, mem_addr
, buffer
);
405 if (retval
== ERROR_OK
) {
406 uint32_t val
= get_buffer(target
, buffer
);
409 uint32_t asid_addr
= val
+ MM_CTX
;
410 retval
= fill_buffer(target
, asid_addr
, buffer
);
412 if (retval
== ERROR_OK
) {
413 val
= get_buffer(target
, buffer
);
417 ("fill task: unable to read memory -- ASID");
422 LOG_ERROR("fill task: unable to read memory");
427 int get_name(struct target
*target
, struct threads
*t
)
430 uint32_t full_name
[4];
431 uint32_t comm
= t
->base_addr
+ COMM
;
434 for (i
= 0; i
< 17; i
++)
437 retval
= linux_read_memory(target
, comm
, 4, 4, (uint8_t *) full_name
);
439 if (retval
!= ERROR_OK
) {
440 LOG_ERROR("get_name: unable to read memory\n");
444 uint32_t raw_name
= target_buffer_get_u32(target
,
447 t
->name
[3] = raw_name
>> 24;
448 t
->name
[2] = raw_name
>> 16;
449 t
->name
[1] = raw_name
>> 8;
450 t
->name
[0] = raw_name
;
452 target_buffer_get_u32(target
, (const uint8_t *)&full_name
[1]);
453 t
->name
[7] = raw_name
>> 24;
454 t
->name
[6] = raw_name
>> 16;
455 t
->name
[5] = raw_name
>> 8;
456 t
->name
[4] = raw_name
;
458 target_buffer_get_u32(target
, (const uint8_t *)&full_name
[2]);
459 t
->name
[11] = raw_name
>> 24;
460 t
->name
[10] = raw_name
>> 16;
461 t
->name
[9] = raw_name
>> 8;
462 t
->name
[8] = raw_name
;
464 target_buffer_get_u32(target
, (const uint8_t *)&full_name
[3]);
465 t
->name
[15] = raw_name
>> 24;
466 t
->name
[14] = raw_name
>> 16;
467 t
->name
[13] = raw_name
>> 8;
468 t
->name
[12] = raw_name
;
473 int get_current(struct target
*target
, int create
)
475 struct target_list
*head
;
480 uint8_t *buffer
= calloc(1, 4);
481 struct linux_os
*linux_os
= (struct linux_os
*)
482 target
->rtos
->rtos_specific_params
;
483 struct current_thread
*ctt
= linux_os
->current_threads
;
485 /* invalid current threads content */
486 while (ctt
!= NULL
) {
488 ctt
->TS
= 0xdeadbeef;
492 while (head
!= (struct target_list
*)NULL
) {
493 struct reg
**reg_list
;
497 if (target_get_gdb_reg_list(head
->target
, ®_list
,
500 return ERROR_TARGET_FAILURE
;
502 if (!reg_list
[13]->valid
)
503 reg_list
[13]->type
->get(reg_list
[13]);
505 buf
= reg_list
[13]->value
;
506 val
= get_buffer(target
, buf
);
507 ti_addr
= (val
& 0xffffe000);
508 uint32_t TS_addr
= ti_addr
+ 0xc;
509 retval
= fill_buffer(target
, TS_addr
, buffer
);
511 if (retval
== ERROR_OK
) {
512 uint32_t TS
= get_buffer(target
, buffer
);
513 uint32_t cpu
, on_cpu
= TS
+ ONCPU
;
514 retval
= fill_buffer(target
, on_cpu
, buffer
);
516 if (retval
== ERROR_OK
) {
517 /*uint32_t cpu = get_buffer(target, buffer);*/
518 struct current_thread
*ct
=
519 linux_os
->current_threads
;
520 cpu
= head
->target
->coreid
;
523 && (ct
->core_id
!= (int32_t) cpu
)) {
527 if ((ct
!= NULL
) && (ct
->TS
== 0xdeadbeef))
531 ("error in linux current thread update");
535 t
= calloc(1, sizeof(struct threads
));
536 t
->base_addr
= ct
->TS
;
537 fill_task(target
, t
);
540 insert_into_threadlist(target
, t
);
542 t
->thread_info_addr
= 0xdeadbeef;
543 ct
->threadid
= t
->threadid
;
544 linux_os
->thread_count
++;
548 /*LOG_INFO("Creation of current thread %s",t->name);*/
560 struct cpu_context
*cpu_context_read(struct target
*target
, uint32_t base_addr
,
561 uint32_t *thread_info_addr_old
)
563 struct cpu_context
*context
= calloc(1, sizeof(struct cpu_context
));
564 uint32_t preempt_count_addr
= 0;
565 uint32_t registers
[10];
566 uint8_t *buffer
= calloc(1, 4);
567 uint32_t stack
= base_addr
+ QAT
;
568 uint32_t thread_info_addr
= 0;
569 uint32_t thread_info_addr_update
= 0;
570 int retval
= ERROR_FAIL
;
571 context
->R4
= 0xdeadbeef;
572 context
->R5
= 0xdeadbeef;
573 context
->R6
= 0xdeadbeef;
574 context
->R7
= 0xdeadbeef;
575 context
->R8
= 0xdeadbeef;
576 context
->R9
= 0xdeadbeef;
577 context
->IP
= 0xdeadbeef;
578 context
->FP
= 0xdeadbeef;
579 context
->SP
= 0xdeadbeef;
580 context
->PC
= 0xdeadbeef;
583 if (*thread_info_addr_old
== 0xdeadbeef) {
584 retval
= fill_buffer(target
, stack
, buffer
);
586 if (retval
== ERROR_OK
)
587 thread_info_addr
= get_buffer(target
, buffer
);
589 LOG_ERROR("cpu_context: unable to read memory");
591 thread_info_addr_update
= thread_info_addr
;
593 thread_info_addr
= *thread_info_addr_old
;
595 preempt_count_addr
= thread_info_addr
+ PREEMPT
;
596 retval
= fill_buffer(target
, preempt_count_addr
, buffer
);
598 if (retval
== ERROR_OK
)
599 context
->preempt_count
= get_buffer(target
, buffer
);
601 if (*thread_info_addr_old
!= 0xdeadbeef) {
603 ("cpu_context: cannot read at thread_info_addr");
605 if (*thread_info_addr_old
< LINUX_USER_KERNEL_BORDER
)
607 ("cpu_context : thread_info_addr in userspace!!!");
609 *thread_info_addr_old
= 0xdeadbeef;
613 LOG_ERROR("cpu_context: unable to read memory");
616 thread_info_addr
+= CPU_CONT
;
618 retval
= linux_read_memory(target
, thread_info_addr
, 4, 10,
619 (uint8_t *) registers
);
621 if (retval
!= ERROR_OK
) {
622 LOG_ERROR("cpu_context: unable to read memory\n");
627 target_buffer_get_u32(target
, (const uint8_t *)®isters
[0]);
629 target_buffer_get_u32(target
, (const uint8_t *)®isters
[1]);
631 target_buffer_get_u32(target
, (const uint8_t *)®isters
[2]);
633 target_buffer_get_u32(target
, (const uint8_t *)®isters
[3]);
635 target_buffer_get_u32(target
, (const uint8_t *)®isters
[4]);
637 target_buffer_get_u32(target
, (const uint8_t *)®isters
[5]);
639 target_buffer_get_u32(target
, (const uint8_t *)®isters
[6]);
641 target_buffer_get_u32(target
, (const uint8_t *)®isters
[7]);
643 target_buffer_get_u32(target
, (const uint8_t *)®isters
[8]);
645 target_buffer_get_u32(target
, (const uint8_t *)®isters
[9]);
647 if (*thread_info_addr_old
== 0xdeadbeef)
648 *thread_info_addr_old
= thread_info_addr_update
;
653 uint32_t next_task(struct target
*target
, struct threads
*t
)
655 uint8_t *buffer
= calloc(1, 4);
656 uint32_t next_addr
= t
->base_addr
+ NEXT
;
657 int retval
= fill_buffer(target
, next_addr
, buffer
);
659 if (retval
== ERROR_OK
) {
660 uint32_t val
= get_buffer(target
, buffer
);
665 LOG_ERROR("next task: unable to read memory");
670 struct current_thread
*add_current_thread(struct current_thread
*currents
,
671 struct current_thread
*ct
)
675 if (currents
== NULL
) {
679 struct current_thread
*temp
= currents
;
681 while (temp
->next
!= NULL
)
689 struct threads
*liste_del_task(struct threads
*task_list
, struct threads
**t
,
690 struct threads
*prev
)
692 LOG_INFO("del task %" PRId64
, (*t
)->threadid
);
693 prev
->next
= (*t
)->next
;
695 if (prev
== task_list
)
698 /* free content of threads */
707 struct threads
*liste_add_task(struct threads
*task_list
, struct threads
*t
,
708 struct threads
**last
)
713 if (task_list
== NULL
) {
717 struct threads
*temp
= task_list
;
719 while (temp
->next
!= NULL
)
733 static int current_pid(struct linux_os
*linux_os
, uint32_t pid
)
735 static int current_base_addr(struct linux_os
*linux_os
, uint32_t base_addr
)
738 struct current_thread
*ct
= linux_os
->current_threads
;
741 while ((ct
!= NULL
) && (ct
->pid
!= pid
))
743 while ((ct
!= NULL
) && (ct
->TS
!= base_addr
))
747 if ((ct
!= NULL
) && (ct
->pid
== pid
))
749 if ((ct
!= NULL
) && (ct
->TS
== base_addr
))
756 int linux_get_tasks(struct target
*target
, int context
)
760 struct linux_os
*linux_os
= (struct linux_os
*)
761 target
->rtos
->rtos_specific_params
;
762 linux_os
->thread_list
= NULL
;
763 linux_os
->thread_count
= 0;
765 if (linux_os
->init_task_addr
== 0xdeadbeef) {
766 LOG_INFO("no init symbol\n");
770 int64_t start
= timeval_ms();
772 struct threads
*t
= calloc(1, sizeof(struct threads
));
773 struct threads
*last
= NULL
;
774 t
->base_addr
= linux_os
->init_task_addr
;
775 /* retrieve the thread id , currently running in the different smp core */
776 retval
= get_current(target
, 1);
778 while (((t
->base_addr
!= linux_os
->init_task_addr
) &&
783 retval
= fill_task(target
, t
);
784 retval
= get_name(target
, t
);
786 if (loop
> MAX_THREADS
) {
787 LOG_INFO("more than %d threads !!", MAX_THREADS
);
791 if (retval
!= ERROR_OK
) {
796 /* check that this thread is not one the current threads already
800 if (!current_pid(linux_os
, t
->pid
)) {
802 if (!current_base_addr(linux_os
, t
->base_addr
)) {
804 t
->threadid
= linux_os
->threadid_count
;
806 linux_os
->threadid_count
++;
808 linux_os
->thread_list
=
809 liste_add_task(linux_os
->thread_list
, t
, &last
);
810 /* no interest to fill the context if it is a current thread. */
811 linux_os
->thread_count
++;
812 t
->thread_info_addr
= 0xdeadbeef;
816 cpu_context_read(target
, t
->base_addr
,
817 &t
->thread_info_addr
);
819 /*LOG_INFO("thread %s is a current thread already created",t->name); */
823 uint32_t base_addr
= next_task(target
, t
);
824 t
= calloc(1, sizeof(struct threads
));
825 t
->base_addr
= base_addr
;
828 linux_os
->threads_lookup
= 1;
829 linux_os
->threads_needs_update
= 0;
830 linux_os
->preupdtate_threadid_count
= linux_os
->threadid_count
- 1;
831 /* check that all current threads have been identified */
833 LOG_INFO("complete time %" PRId64
", thread mean %" PRId64
"\n",
834 (timeval_ms() - start
),
835 (timeval_ms() - start
) / linux_os
->threadid_count
);
837 LOG_INFO("threadid count %d", linux_os
->threadid_count
);
842 static int clean_threadlist(struct target
*target
)
844 struct linux_os
*linux_os
= (struct linux_os
*)
845 target
->rtos
->rtos_specific_params
;
846 struct threads
*old
, *temp
= linux_os
->thread_list
;
848 while (temp
!= NULL
) {
861 static int linux_os_clean(struct target
*target
)
864 struct linux_os
*os_linux
= (struct linux_os
*)
865 target
->rtos
->rtos_specific_params
;
866 clean_threadlist(target
);
867 os_linux
->init_task_addr
= 0xdeadbeef;
868 os_linux
->name
= "linux";
869 os_linux
->thread_list
= NULL
;
870 os_linux
->thread_count
= 0;
871 os_linux
->nr_cpus
= 0;
872 os_linux
->threads_lookup
= 0;
873 os_linux
->threads_needs_update
= 0;
874 os_linux
->threadid_count
= 1;
878 static int insert_into_threadlist(struct target
*target
, struct threads
*t
)
880 struct linux_os
*linux_os
= (struct linux_os
*)
881 target
->rtos
->rtos_specific_params
;
882 struct threads
*temp
= linux_os
->thread_list
;
883 t
->threadid
= linux_os
->threadid_count
;
884 linux_os
->threadid_count
++;
889 linux_os
->thread_list
= t
;
891 while (temp
->next
!= NULL
)
901 static void linux_identify_current_threads(struct target
*target
)
903 struct linux_os
*linux_os
= (struct linux_os
*)
904 target
->rtos
->rtos_specific_params
;
905 struct threads
*thread_list
= linux_os
->thread_list
;
906 struct current_thread
*ct
= linux_os
->current_threads
;
907 struct threads
*t
= NULL
;
909 while ((ct
!= NULL
)) {
910 if (ct
->threadid
== -1) {
912 /* un-identified thread */
914 t
= calloc(1, sizeof(struct threads
));
915 t
->base_addr
= ct
->TS
;
918 if (fill_task_pid(target
, t
) != ERROR_OK
) {
922 ("linux identify_current_threads: unable to read pid");
927 /* search in the list of threads if pid
929 while ((thread_list
!= NULL
) && (found
== 0)) {
931 if (thread_list
->pid
== t
->pid
) {
933 if (thread_list
->base_addr
== t
->base_addr
) {
939 thread_list
= thread_list
->next
;
943 /* it is a new thread */
944 if (fill_task(target
, t
) != ERROR_OK
)
948 insert_into_threadlist(target
, t
);
949 t
->thread_info_addr
= 0xdeadbeef;
953 ct
->threadid
= t
->threadid
;
957 linux_os
->thread_count
++;
960 LOG_INFO("current thread core %x identified %s",
961 ct
->core_id
, t
->name
);
963 LOG_INFO("current thread core %x, reused %s",
964 ct
->core_id
, t
->name
);
970 tmp
.base_addr
= ct
->TS
;
971 get_name(target
, &tmp
);
972 LOG_INFO("current thread core %x , already identified %s !!!",
973 ct
->core_id
, tmp
.name
);
983 LOG_ERROR("unable toread pid");
989 static int linux_task_update(struct target
*target
, int context
)
991 struct linux_os
*linux_os
= (struct linux_os
*)
992 target
->rtos
->rtos_specific_params
;
993 struct threads
*thread_list
= linux_os
->thread_list
;
996 linux_os
->thread_count
= 0;
998 /*thread_list = thread_list->next; skip init_task*/
999 while (thread_list
!= NULL
) {
1000 thread_list
->status
= 0; /*setting all tasks to dead state*/
1002 if (thread_list
->context
) {
1003 free(thread_list
->context
);
1004 thread_list
->context
= NULL
;
1007 thread_list
= thread_list
->next
;
1013 if (linux_os
->init_task_addr
== 0xdeadbeef) {
1014 LOG_INFO("no init symbol\n");
1017 int64_t start
= timeval_ms();
1018 struct threads
*t
= calloc(1, sizeof(struct threads
));
1019 uint32_t previous
= 0xdeadbeef;
1020 t
->base_addr
= linux_os
->init_task_addr
;
1021 retval
= get_current(target
, 0);
1022 /*check that all current threads have been identified */
1023 linux_identify_current_threads(target
);
1025 while (((t
->base_addr
!= linux_os
->init_task_addr
) &&
1026 (t
->base_addr
!= previous
)) || (loop
== 0)) {
1027 /* for avoiding any permanent loop for any reason possibly due to
1030 previous
= t
->base_addr
;
1033 retval
= fill_task_pid(target
, t
);
1036 if (retval
!= ERROR_OK
) {
1041 thread_list
= linux_os
->thread_list
;
1043 while (thread_list
!= NULL
) {
1046 if (t
->pid
== thread_list
->pid
) {
1048 if (t
->base_addr
== thread_list
->base_addr
) {
1051 if (!thread_list
->status
) {
1055 thread_list
->base_addr
) {
1057 ("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
);
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
,
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
= (char *)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
;
1143 tmp_str
+= sprintf(tmp_str
, "%016" PRIx64
, temp
->threadid
);
1146 while (temp
!= NULL
) {
1147 tmp_str
+= sprintf(tmp_str
, ",");
1148 tmp_str
+= sprintf(tmp_str
, "%016" PRIx64
, temp
->threadid
);
1152 gdb_put_packet(connection
, out_str
, strlen(out_str
));
1156 int linux_gdb_thread_update(struct target
*target
,
1157 struct connection
*connection
, char *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
= (char *)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 *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
= (char *)calloc(1, str_size
+ 50);
1221 char *tmp_str_ptr
= tmp_str
;
1223 /* discriminate cuurent 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 tmp_str_ptr
+= sprintf(tmp_str_ptr
, "%s", name
);
1234 tmp_str_ptr
+= sprintf(tmp_str_ptr
, "%s", temp
->name
);
1236 (char *)calloc(1, strlen(tmp_str
) * 2 + 1);
1237 str_to_hex(hex_str
, tmp_str
);
1238 gdb_put_packet(connection
, hex_str
, strlen(hex_str
));
1247 LOG_INFO("thread not found");
1251 int linux_gdb_T_packet(struct connection
*connection
,
1252 struct target
*target
, char *packet
, int packet_size
)
1255 struct linux_os
*linux_os
= (struct linux_os
*)
1256 target
->rtos
->rtos_specific_params
;
1257 int retval
= ERROR_OK
;
1258 sscanf(packet
, "T%" SCNx64
, &threadid
);
1260 if (linux_os
->threads_needs_update
== 0) {
1261 struct threads
*temp
= linux_os
->thread_list
;
1262 struct threads
*prev
= linux_os
->thread_list
;
1264 while (temp
!= NULL
) {
1265 if (temp
->threadid
== threadid
) {
1266 if (temp
->status
!= 0) {
1267 gdb_put_packet(connection
, "OK", 2);
1270 /* delete item in the list */
1271 linux_os
->thread_list
=
1272 liste_del_task(linux_os
->
1275 linux_os
->thread_count
--;
1276 gdb_put_packet(connection
, "E01", 3);
1286 LOG_INFO("gdb requested status on non existing thread");
1287 gdb_put_packet(connection
, "E01", 3);
1291 retval
= linux_task_update(target
, 1);
1292 struct threads
*temp
= linux_os
->thread_list
;
1294 while (temp
!= NULL
) {
1295 if (temp
->threadid
== threadid
) {
1296 if (temp
->status
== 1) {
1297 gdb_put_packet(connection
, "OK", 2);
1300 gdb_put_packet(connection
, "E01", 3);
1312 int linux_gdb_h_packet(struct connection
*connection
,
1313 struct target
*target
, char *packet
, int packet_size
)
1315 struct linux_os
*linux_os
= (struct linux_os
*)
1316 target
->rtos
->rtos_specific_params
;
1317 struct current_thread
*ct
= linux_os
->current_threads
;
1319 /* select to display the current thread of the selected target */
1320 while ((ct
!= NULL
) && (ct
->core_id
!= target
->coreid
))
1323 int64_t current_gdb_thread_rq
;
1325 if (linux_os
->threads_lookup
== 1) {
1326 if ((ct
!= NULL
) && (ct
->threadid
== -1)) {
1327 ct
= linux_os
->current_threads
;
1329 while ((ct
!= NULL
) && (ct
->threadid
== -1))
1334 /* no current thread can be identified */
1335 /* any way with smp */
1336 LOG_INFO("no current thread identified");
1337 /* attempt to display the name of the 2 threads identified with
1340 ct
= linux_os
->current_threads
;
1342 while ((ct
!= NULL
) && (ct
->threadid
== -1)) {
1343 t
.base_addr
= ct
->TS
;
1344 get_name(target
, &t
);
1345 LOG_INFO("name of unidentified thread %s",
1350 gdb_put_packet(connection
, "OK", 2);
1354 if (packet
[1] == 'g') {
1355 sscanf(packet
, "Hg%16" SCNx64
, ¤t_gdb_thread_rq
);
1357 if (current_gdb_thread_rq
== 0) {
1358 target
->rtos
->current_threadid
= ct
->threadid
;
1359 gdb_put_packet(connection
, "OK", 2);
1361 target
->rtos
->current_threadid
=
1362 current_gdb_thread_rq
;
1363 gdb_put_packet(connection
, "OK", 2);
1365 } else if (packet
[1] == 'c') {
1366 sscanf(packet
, "Hc%16" SCNx64
, ¤t_gdb_thread_rq
);
1368 if ((current_gdb_thread_rq
== 0) ||
1369 (current_gdb_thread_rq
== ct
->threadid
)) {
1370 target
->rtos
->current_threadid
= ct
->threadid
;
1371 gdb_put_packet(connection
, "OK", 2);
1373 gdb_put_packet(connection
, "E01", 3);
1376 gdb_put_packet(connection
, "OK", 2);
1381 static int linux_thread_packet(struct connection
*connection
, char *packet
,
1384 int retval
= ERROR_OK
;
1385 struct current_thread
*ct
;
1386 struct target
*target
= get_target_from_connection(connection
);
1387 struct linux_os
*linux_os
= (struct linux_os
*)
1388 target
->rtos
->rtos_specific_params
;
1390 switch (packet
[0]) {
1391 case 'T': /* Is thread alive?*/
1393 linux_gdb_T_packet(connection
, target
, packet
, packet_size
);
1395 case 'H': /* Set current thread */
1396 /* ( 'c' for step and continue, 'g' for all other operations )*/
1397 /*LOG_INFO(" H packet received '%s'", packet);*/
1398 linux_gdb_h_packet(connection
, target
, packet
, packet_size
);
1402 if ((strstr(packet
, "qSymbol"))) {
1403 if (rtos_qsymbol(connection
, packet
, packet_size
) == 1) {
1404 gdb_put_packet(connection
, "OK", 2);
1406 linux_compute_virt2phys(target
,
1413 } else if (strstr(packet
, "qfThreadInfo")) {
1414 if (linux_os
->thread_list
== NULL
) {
1415 retval
= linux_gdb_thread_packet(target
,
1421 retval
= linux_gdb_thread_update(target
,
1427 } else if (strstr(packet
, "qsThreadInfo")) {
1428 gdb_put_packet(connection
, "l", 1);
1430 } else if (strstr(packet
, "qThreadExtraInfo,")) {
1431 linux_thread_extra_info(target
, connection
, packet
,
1435 retval
= GDB_THREAD_PACKET_NOT_CONSUMED
;
1440 /* previously response was : thread not found
1441 * gdb_put_packet(connection, "E01", 3); */
1442 retval
= GDB_THREAD_PACKET_NOT_CONSUMED
;
1446 if (linux_os
->threads_lookup
== 1) {
1447 ct
= linux_os
->current_threads
;
1450 && (ct
->core_id
) != target
->coreid
) {
1454 if ((ct
!= NULL
) && (ct
->threadid
== -1)) {
1455 ct
= linux_os
->current_threads
;
1458 && (ct
->threadid
== -1)) {
1463 if ((ct
!= NULL
) && (ct
->threadid
!=
1466 && (target
->rtos
->current_threadid
!= -1))
1467 LOG_WARNING("WARNING! current GDB thread do not match"\
1468 "current thread running."\
1469 "Switch thread in GDB to threadid %d", (int)ct
->threadid
);
1471 LOG_INFO("threads_needs_update = 1");
1472 linux_os
->threads_needs_update
= 1;
1476 /* if a packet handler returned an error, exit input loop */
1477 if (retval
!= ERROR_OK
)
1484 static int linux_os_smp_init(struct target
*target
)
1486 struct target_list
*head
;
1487 /* keep only target->rtos */
1488 struct rtos
*rtos
= target
->rtos
;
1489 struct linux_os
*os_linux
=
1490 (struct linux_os
*)rtos
->rtos_specific_params
;
1491 struct current_thread
*ct
;
1492 head
= target
->head
;
1494 while (head
!= (struct target_list
*)NULL
) {
1495 if (head
->target
->rtos
!= rtos
) {
1496 struct linux_os
*smp_os_linux
=
1497 (struct linux_os
*)head
->target
->rtos
->
1498 rtos_specific_params
;
1499 /* remap smp target on rtos */
1500 free(head
->target
->rtos
);
1501 head
->target
->rtos
= rtos
;
1502 /* reuse allocated ct */
1503 ct
= smp_os_linux
->current_threads
;
1505 ct
->TS
= 0xdeadbeef;
1506 ct
->core_id
= head
->target
->coreid
;
1507 os_linux
->current_threads
=
1508 add_current_thread(os_linux
->current_threads
, ct
);
1509 os_linux
->nr_cpus
++;
1519 static int linux_os_create(struct target
*target
)
1521 struct linux_os
*os_linux
= calloc(1, sizeof(struct linux_os
));
1522 struct current_thread
*ct
= calloc(1, sizeof(struct current_thread
));
1523 LOG_INFO("linux os creation\n");
1524 os_linux
->init_task_addr
= 0xdeadbeef;
1525 os_linux
->name
= "linux";
1526 os_linux
->thread_list
= NULL
;
1527 os_linux
->thread_count
= 0;
1528 target
->rtos
->current_threadid
= -1;
1529 os_linux
->nr_cpus
= 1;
1530 os_linux
->threads_lookup
= 0;
1531 os_linux
->threads_needs_update
= 0;
1532 os_linux
->threadid_count
= 1;
1533 os_linux
->current_threads
= NULL
;
1534 target
->rtos
->rtos_specific_params
= (void *)os_linux
;
1535 ct
->core_id
= target
->coreid
;
1537 ct
->TS
= 0xdeadbeef;
1538 os_linux
->current_threads
=
1539 add_current_thread(os_linux
->current_threads
, ct
);
1540 /* overload rtos thread default handler */
1541 target
->rtos
->gdb_thread_packet
= linux_thread_packet
;
1542 /* initialize a default virt 2 phys translation */
1543 os_linux
->phys_mask
= ~0xc0000000;
1544 os_linux
->phys_base
= 0x0;
1548 static char *linux_ps_command(struct target
*target
)
1550 struct linux_os
*linux_os
= (struct linux_os
*)
1551 target
->rtos
->rtos_specific_params
;
1552 int retval
= ERROR_OK
;
1555 if (linux_os
->threads_lookup
== 0) {
1556 retval
= linux_get_tasks(target
, 1);
1558 if (linux_os
->threads_needs_update
!= 0)
1559 retval
= linux_task_update(target
, 0);
1562 if (retval
== ERROR_OK
) {
1563 struct threads
*temp
= linux_os
->thread_list
;
1565 LOG_INFO("allocation for %d threads line",
1566 linux_os
->thread_count
);
1567 display
= calloc((linux_os
->thread_count
+ 2) * 80, 1);
1573 tmp
+= sprintf(tmp
, "PID\t\tCPU\t\tASID\t\tNAME\n");
1574 tmp
+= sprintf(tmp
, "---\t\t---\t\t----\t\t----\n");
1576 while (temp
!= NULL
) {
1581 "%d\t\t%d\t\t%x\t\t%s\n",
1582 (int)temp
->pid
, temp
->oncpu
,
1583 temp
->asid
, temp
->name
);
1587 "%d\t\t%d\t\t%x\t\t%s\n",
1588 (int)temp
->pid
, temp
->oncpu
,
1589 temp
->asid
, temp
->name
);
1599 display
= calloc(40, 1);
1600 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)