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
->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));
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 *hex_reg_list
= malloc(DIV_ROUND_UP(reg_packet_size
, 8) * 2);
239 hex_string
= *hex_reg_list
;
241 for (i
= 0; i
< reg_list_size
; i
++) {
242 if (!reg_list
[i
]->valid
)
243 reg_list
[i
]->type
->get(reg_list
[i
]);
245 hex_string
= reg_converter(hex_string
,
247 (reg_list
[i
]->size
) / 8);
253 struct threads
*temp
= linux_os
->thread_list
;
254 *hex_reg_list
= (char *)calloc(1, 500 * sizeof(char));
255 hex_string
= *hex_reg_list
;
257 for (i
= 0; i
< 16; i
++)
258 hex_string
+= sprintf(hex_string
, "%02x", 0);
260 while ((temp
!= NULL
) &&
261 (temp
->threadid
!= target
->rtos
->current_threadid
))
265 if (temp
->context
== NULL
)
266 temp
->context
= cpu_context_read(target
,
273 reg_converter(hex_string
, &temp
->context
->R4
, 4);
275 reg_converter(hex_string
, &temp
->context
->R5
, 4);
277 reg_converter(hex_string
, &temp
->context
->R6
, 4);
279 reg_converter(hex_string
, &temp
->context
->R7
, 4);
281 reg_converter(hex_string
, &temp
->context
->R8
, 4);
283 reg_converter(hex_string
, &temp
->context
->R9
, 4);
285 for (i
= 0; i
< 4; i
++) /*R10 = 0x0 */
286 hex_string
+= sprintf(hex_string
, "%02x", 0);
289 reg_converter(hex_string
, &temp
->context
->FP
, 4);
291 reg_converter(hex_string
, &temp
->context
->IP
, 4);
293 reg_converter(hex_string
, &temp
->context
->SP
, 4);
295 for (i
= 0; i
< 4; i
++)
296 hex_string
+= sprintf(hex_string
, "%02x", 0);
299 reg_converter(hex_string
, &temp
->context
->PC
, 4);
301 for (i
= 0; i
< 100; i
++) /*100 */
302 hex_string
+= sprintf(hex_string
, "%02x", 0);
304 uint32_t cpsr
= 0x00000000;
305 reg_converter(hex_string
, &cpsr
, 4);
311 static int linux_os_detect(struct target
*target
)
313 LOG_INFO("should no be called");
317 static int linux_os_smp_init(struct target
*target
);
318 static int linux_os_clean(struct target
*target
);
320 static char *linux_symbol_list
[] = {
325 static int linux_get_symbol_list_to_lookup(symbol_table_elem_t
*symbol_list
[])
328 *symbol_list
= (symbol_table_elem_t
*)
329 malloc(sizeof(symbol_table_elem_t
) * ARRAY_SIZE(linux_symbol_list
));
331 for (i
= 0; i
< ARRAY_SIZE(linux_symbol_list
); i
++)
332 (*symbol_list
)[i
].symbol_name
= linux_symbol_list
[i
];
337 static char *linux_ps_command(struct target
*target
);
339 const struct rtos_type Linux_os
= {
341 .detect_rtos
= linux_os_detect
,
342 .create
= linux_os_create
,
343 .smp_init
= linux_os_smp_init
,
344 .update_threads
= linux_os_dummy_update
,
345 .get_thread_reg_list
= linux_os_thread_reg_list
,
346 .get_symbol_list_to_lookup
= linux_get_symbol_list_to_lookup
,
347 .clean
= linux_os_clean
,
348 .ps_command
= linux_ps_command
,
351 static int linux_thread_packet(struct connection
*connection
, char *packet
,
353 static void linux_identify_current_threads(struct target
*target
);
356 int fill_task_pid(struct target
*target
, struct threads
*t
)
358 uint32_t pid_addr
= t
->base_addr
+ PID
;
360 int retval
= fill_buffer(target
, pid_addr
, buffer
);
362 if (retval
== ERROR_OK
) {
363 uint32_t val
= get_buffer(target
, buffer
);
366 LOG_ERROR("fill_task_pid: unable to read memory");
372 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");
421 LOG_ERROR("fill task: unable to read memory");
428 int get_name(struct target
*target
, struct threads
*t
)
431 uint32_t full_name
[4];
432 uint32_t comm
= t
->base_addr
+ COMM
;
435 for (i
= 0; i
< 17; i
++)
438 retval
= linux_read_memory(target
, comm
, 4, 4, (uint8_t *) full_name
);
440 if (retval
!= ERROR_OK
) {
441 LOG_ERROR("get_name: unable to read memory\n");
445 uint32_t raw_name
= target_buffer_get_u32(target
,
448 t
->name
[3] = raw_name
>> 24;
449 t
->name
[2] = raw_name
>> 16;
450 t
->name
[1] = raw_name
>> 8;
451 t
->name
[0] = raw_name
;
453 target_buffer_get_u32(target
, (const uint8_t *)&full_name
[1]);
454 t
->name
[7] = raw_name
>> 24;
455 t
->name
[6] = raw_name
>> 16;
456 t
->name
[5] = raw_name
>> 8;
457 t
->name
[4] = raw_name
;
459 target_buffer_get_u32(target
, (const uint8_t *)&full_name
[2]);
460 t
->name
[11] = raw_name
>> 24;
461 t
->name
[10] = raw_name
>> 16;
462 t
->name
[9] = raw_name
>> 8;
463 t
->name
[8] = raw_name
;
465 target_buffer_get_u32(target
, (const uint8_t *)&full_name
[3]);
466 t
->name
[15] = raw_name
>> 24;
467 t
->name
[14] = raw_name
>> 16;
468 t
->name
[13] = raw_name
>> 8;
469 t
->name
[12] = raw_name
;
474 int get_current(struct target
*target
, int create
)
476 struct target_list
*head
;
481 uint8_t *buffer
= calloc(1, 4);
482 struct linux_os
*linux_os
= (struct linux_os
*)
483 target
->rtos
->rtos_specific_params
;
484 struct current_thread
*ctt
= linux_os
->current_threads
;
486 /* invalid current threads content */
487 while (ctt
!= NULL
) {
489 ctt
->TS
= 0xdeadbeef;
493 while (head
!= (struct target_list
*)NULL
) {
494 struct reg
**reg_list
;
498 if (target_get_gdb_reg_list(head
->target
, ®_list
,
499 ®_list_size
) != ERROR_OK
) {
501 return ERROR_TARGET_FAILURE
;
504 if (!reg_list
[13]->valid
)
505 reg_list
[13]->type
->get(reg_list
[13]);
507 buf
= reg_list
[13]->value
;
508 val
= get_buffer(target
, buf
);
509 ti_addr
= (val
& 0xffffe000);
510 uint32_t TS_addr
= ti_addr
+ 0xc;
511 retval
= fill_buffer(target
, TS_addr
, buffer
);
513 if (retval
== ERROR_OK
) {
514 uint32_t TS
= get_buffer(target
, buffer
);
515 uint32_t cpu
, on_cpu
= TS
+ ONCPU
;
516 retval
= fill_buffer(target
, on_cpu
, buffer
);
518 if (retval
== ERROR_OK
) {
519 /*uint32_t cpu = get_buffer(target, buffer);*/
520 struct current_thread
*ct
=
521 linux_os
->current_threads
;
522 cpu
= head
->target
->coreid
;
524 while ((ct
!= NULL
) && (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);*/
562 struct cpu_context
*cpu_context_read(struct target
*target
, uint32_t base_addr
,
563 uint32_t *thread_info_addr_old
)
565 struct cpu_context
*context
= calloc(1, sizeof(struct cpu_context
));
566 uint32_t preempt_count_addr
= 0;
567 uint32_t registers
[10];
568 uint8_t *buffer
= calloc(1, 4);
569 uint32_t stack
= base_addr
+ QAT
;
570 uint32_t thread_info_addr
= 0;
571 uint32_t thread_info_addr_update
= 0;
572 int retval
= ERROR_FAIL
;
573 context
->R4
= 0xdeadbeef;
574 context
->R5
= 0xdeadbeef;
575 context
->R6
= 0xdeadbeef;
576 context
->R7
= 0xdeadbeef;
577 context
->R8
= 0xdeadbeef;
578 context
->R9
= 0xdeadbeef;
579 context
->IP
= 0xdeadbeef;
580 context
->FP
= 0xdeadbeef;
581 context
->SP
= 0xdeadbeef;
582 context
->PC
= 0xdeadbeef;
585 if (*thread_info_addr_old
== 0xdeadbeef) {
586 retval
= fill_buffer(target
, stack
, buffer
);
588 if (retval
== ERROR_OK
)
589 thread_info_addr
= get_buffer(target
, buffer
);
591 LOG_ERROR("cpu_context: unable to read memory");
593 thread_info_addr_update
= thread_info_addr
;
595 thread_info_addr
= *thread_info_addr_old
;
597 preempt_count_addr
= thread_info_addr
+ PREEMPT
;
598 retval
= fill_buffer(target
, preempt_count_addr
, buffer
);
600 if (retval
== ERROR_OK
)
601 context
->preempt_count
= get_buffer(target
, buffer
);
603 if (*thread_info_addr_old
!= 0xdeadbeef) {
605 ("cpu_context: cannot read at thread_info_addr");
607 if (*thread_info_addr_old
< LINUX_USER_KERNEL_BORDER
)
609 ("cpu_context : thread_info_addr in userspace!!!");
611 *thread_info_addr_old
= 0xdeadbeef;
615 LOG_ERROR("cpu_context: unable to read memory");
618 thread_info_addr
+= CPU_CONT
;
620 retval
= linux_read_memory(target
, thread_info_addr
, 4, 10,
621 (uint8_t *) registers
);
623 if (retval
!= ERROR_OK
) {
625 LOG_ERROR("cpu_context: unable to read memory\n");
630 target_buffer_get_u32(target
, (const uint8_t *)®isters
[0]);
632 target_buffer_get_u32(target
, (const uint8_t *)®isters
[1]);
634 target_buffer_get_u32(target
, (const uint8_t *)®isters
[2]);
636 target_buffer_get_u32(target
, (const uint8_t *)®isters
[3]);
638 target_buffer_get_u32(target
, (const uint8_t *)®isters
[4]);
640 target_buffer_get_u32(target
, (const uint8_t *)®isters
[5]);
642 target_buffer_get_u32(target
, (const uint8_t *)®isters
[6]);
644 target_buffer_get_u32(target
, (const uint8_t *)®isters
[7]);
646 target_buffer_get_u32(target
, (const uint8_t *)®isters
[8]);
648 target_buffer_get_u32(target
, (const uint8_t *)®isters
[9]);
650 if (*thread_info_addr_old
== 0xdeadbeef)
651 *thread_info_addr_old
= thread_info_addr_update
;
658 uint32_t next_task(struct target
*target
, struct threads
*t
)
660 uint8_t *buffer
= calloc(1, 4);
661 uint32_t next_addr
= t
->base_addr
+ NEXT
;
662 int retval
= fill_buffer(target
, next_addr
, buffer
);
664 if (retval
== ERROR_OK
) {
665 uint32_t val
= get_buffer(target
, buffer
);
670 LOG_ERROR("next task: unable to read memory");
677 struct current_thread
*add_current_thread(struct current_thread
*currents
,
678 struct current_thread
*ct
)
682 if (currents
== NULL
) {
686 struct current_thread
*temp
= currents
;
688 while (temp
->next
!= NULL
)
696 struct threads
*liste_del_task(struct threads
*task_list
, struct threads
**t
,
697 struct threads
*prev
)
699 LOG_INFO("del task %" PRId64
, (*t
)->threadid
);
700 prev
->next
= (*t
)->next
;
702 if (prev
== task_list
)
705 /* free content of threads */
714 struct threads
*liste_add_task(struct threads
*task_list
, struct threads
*t
,
715 struct threads
**last
)
720 if (task_list
== NULL
) {
724 struct threads
*temp
= task_list
;
726 while (temp
->next
!= NULL
)
740 static int current_pid(struct linux_os
*linux_os
, uint32_t pid
)
742 static int current_base_addr(struct linux_os
*linux_os
, uint32_t base_addr
)
745 struct current_thread
*ct
= linux_os
->current_threads
;
748 while ((ct
!= NULL
) && (ct
->pid
!= pid
))
750 while ((ct
!= NULL
) && (ct
->TS
!= base_addr
))
754 if ((ct
!= NULL
) && (ct
->pid
== pid
))
756 if ((ct
!= NULL
) && (ct
->TS
== base_addr
))
763 int linux_get_tasks(struct target
*target
, int context
)
767 struct linux_os
*linux_os
= (struct linux_os
*)
768 target
->rtos
->rtos_specific_params
;
769 linux_os
->thread_list
= NULL
;
770 linux_os
->thread_count
= 0;
772 if (linux_os
->init_task_addr
== 0xdeadbeef) {
773 LOG_INFO("no init symbol\n");
777 int64_t start
= timeval_ms();
779 struct threads
*t
= calloc(1, sizeof(struct threads
));
780 struct threads
*last
= NULL
;
781 t
->base_addr
= linux_os
->init_task_addr
;
782 /* retrieve the thread id , currently running in the different smp core */
783 get_current(target
, 1);
785 while (((t
->base_addr
!= linux_os
->init_task_addr
) &&
786 (t
->base_addr
!= 0)) || (loop
== 0)) {
788 fill_task(target
, t
);
789 retval
= get_name(target
, t
);
791 if (loop
> MAX_THREADS
) {
793 LOG_INFO("more than %d threads !!", MAX_THREADS
);
797 if (retval
!= ERROR_OK
) {
802 /* check that this thread is not one the current threads already
806 if (!current_pid(linux_os
, t
->pid
)) {
808 if (!current_base_addr(linux_os
, t
->base_addr
)) {
810 t
->threadid
= linux_os
->threadid_count
;
812 linux_os
->threadid_count
++;
814 linux_os
->thread_list
=
815 liste_add_task(linux_os
->thread_list
, t
, &last
);
816 /* no interest to fill the context if it is a current thread. */
817 linux_os
->thread_count
++;
818 t
->thread_info_addr
= 0xdeadbeef;
822 cpu_context_read(target
, t
->base_addr
,
823 &t
->thread_info_addr
);
825 /*LOG_INFO("thread %s is a current thread already created",t->name); */
829 uint32_t base_addr
= next_task(target
, t
);
830 t
= calloc(1, sizeof(struct threads
));
831 t
->base_addr
= base_addr
;
834 linux_os
->threads_lookup
= 1;
835 linux_os
->threads_needs_update
= 0;
836 linux_os
->preupdtate_threadid_count
= linux_os
->threadid_count
- 1;
837 /* check that all current threads have been identified */
839 LOG_INFO("complete time %" PRId64
", thread mean %" PRId64
"\n",
840 (timeval_ms() - start
),
841 (timeval_ms() - start
) / linux_os
->threadid_count
);
843 LOG_INFO("threadid count %d", linux_os
->threadid_count
);
849 static int clean_threadlist(struct target
*target
)
851 struct linux_os
*linux_os
= (struct linux_os
*)
852 target
->rtos
->rtos_specific_params
;
853 struct threads
*old
, *temp
= linux_os
->thread_list
;
855 while (temp
!= NULL
) {
868 static int linux_os_clean(struct target
*target
)
870 struct linux_os
*os_linux
= (struct linux_os
*)
871 target
->rtos
->rtos_specific_params
;
872 clean_threadlist(target
);
873 os_linux
->init_task_addr
= 0xdeadbeef;
874 os_linux
->name
= "linux";
875 os_linux
->thread_list
= NULL
;
876 os_linux
->thread_count
= 0;
877 os_linux
->nr_cpus
= 0;
878 os_linux
->threads_lookup
= 0;
879 os_linux
->threads_needs_update
= 0;
880 os_linux
->threadid_count
= 1;
884 static int insert_into_threadlist(struct target
*target
, struct threads
*t
)
886 struct linux_os
*linux_os
= (struct linux_os
*)
887 target
->rtos
->rtos_specific_params
;
888 struct threads
*temp
= linux_os
->thread_list
;
889 t
->threadid
= linux_os
->threadid_count
;
890 linux_os
->threadid_count
++;
895 linux_os
->thread_list
= t
;
897 while (temp
->next
!= NULL
)
907 static void linux_identify_current_threads(struct target
*target
)
909 struct linux_os
*linux_os
= (struct linux_os
*)
910 target
->rtos
->rtos_specific_params
;
911 struct threads
*thread_list
= linux_os
->thread_list
;
912 struct current_thread
*ct
= linux_os
->current_threads
;
913 struct threads
*t
= NULL
;
915 while ((ct
!= NULL
)) {
916 if (ct
->threadid
== -1) {
918 /* un-identified thread */
920 t
= calloc(1, sizeof(struct threads
));
921 t
->base_addr
= ct
->TS
;
924 if (fill_task_pid(target
, t
) != ERROR_OK
) {
928 ("linux identify_current_threads: unable to read pid");
933 /* search in the list of threads if pid
935 while ((thread_list
!= NULL
) && (found
== 0)) {
937 if (thread_list
->pid
== t
->pid
) {
939 if (thread_list
->base_addr
== t
->base_addr
) {
945 thread_list
= thread_list
->next
;
949 /* it is a new thread */
950 if (fill_task(target
, t
) != ERROR_OK
)
954 insert_into_threadlist(target
, t
);
955 t
->thread_info_addr
= 0xdeadbeef;
959 ct
->threadid
= t
->threadid
;
963 linux_os
->thread_count
++;
966 LOG_INFO("current thread core %x identified %s",
967 ct
->core_id
, t
->name
);
969 LOG_INFO("current thread core %x, reused %s",
970 ct
->core_id
, t
->name
);
976 tmp
.base_addr
= ct
->TS
;
977 get_name(target
, &tmp
);
978 LOG_INFO("current thread core %x , already identified %s !!!",
979 ct
->core_id
, tmp
.name
);
989 LOG_ERROR("unable to read pid");
995 static int linux_task_update(struct target
*target
, int context
)
997 struct linux_os
*linux_os
= (struct linux_os
*)
998 target
->rtos
->rtos_specific_params
;
999 struct threads
*thread_list
= linux_os
->thread_list
;
1002 linux_os
->thread_count
= 0;
1004 /*thread_list = thread_list->next; skip init_task*/
1005 while (thread_list
!= NULL
) {
1006 thread_list
->status
= 0; /*setting all tasks to dead state*/
1008 if (thread_list
->context
) {
1009 free(thread_list
->context
);
1010 thread_list
->context
= NULL
;
1013 thread_list
= thread_list
->next
;
1018 if (linux_os
->init_task_addr
== 0xdeadbeef) {
1019 LOG_INFO("no init symbol\n");
1022 int64_t start
= timeval_ms();
1023 struct threads
*t
= calloc(1, sizeof(struct threads
));
1024 uint32_t previous
= 0xdeadbeef;
1025 t
->base_addr
= linux_os
->init_task_addr
;
1026 retval
= get_current(target
, 0);
1027 /*check that all current threads have been identified */
1028 linux_identify_current_threads(target
);
1030 while (((t
->base_addr
!= linux_os
->init_task_addr
) &&
1031 (t
->base_addr
!= previous
)) || (loop
== 0)) {
1032 /* for avoiding any permanent loop for any reason possibly due to
1035 previous
= t
->base_addr
;
1038 retval
= fill_task_pid(target
, t
);
1041 if (retval
!= ERROR_OK
) {
1046 thread_list
= linux_os
->thread_list
;
1048 while (thread_list
!= NULL
) {
1050 if (t
->pid
== thread_list
->pid
) {
1052 if (t
->base_addr
== thread_list
->base_addr
) {
1054 if (!thread_list
->status
) {
1056 if (t
->base_addr
!= thread_list
->base_addr
)
1057 LOG_INFO("thread base_addr has changed !!");
1059 /* this is not a current thread */
1060 thread_list
->base_addr
= t
->base_addr
;
1061 thread_list
->status
= 1;
1063 /* we don 't update this field any more */
1065 /*thread_list->state = t->state;
1066 thread_list->oncpu = t->oncpu;
1067 thread_list->asid = t->asid;
1070 thread_list
->context
=
1071 cpu_context_read(target
,
1077 /* it is a current thread no need to read context */
1080 linux_os
->thread_count
++;
1085 thread_list
= thread_list
->next
;
1091 fill_task(target
, t
);
1092 get_name(target
, t
);
1093 retval
= insert_into_threadlist(target
, t
);
1094 t
->thread_info_addr
= 0xdeadbeef;
1098 cpu_context_read(target
, t
->base_addr
,
1099 &t
->thread_info_addr
);
1101 base_addr
= next_task(target
, t
);
1102 t
= calloc(1, sizeof(struct threads
));
1103 t
->base_addr
= base_addr
;
1104 linux_os
->thread_count
++;
1106 t
->base_addr
= next_task(target
, t
);
1109 LOG_INFO("update thread done %" PRId64
", mean%" PRId64
"\n",
1110 (timeval_ms() - start
), (timeval_ms() - start
) / loop
);
1112 linux_os
->threads_needs_update
= 0;
1116 int linux_gdb_thread_packet(struct target
*target
,
1117 struct connection
*connection
, char *packet
,
1121 struct linux_os
*linux_os
=
1122 (struct linux_os
*)target
->rtos
->rtos_specific_params
;
1124 if (linux_os
->init_task_addr
== 0xdeadbeef) {
1125 /* it has not been initialized */
1126 LOG_INFO("received thread request without init task address");
1127 gdb_put_packet(connection
, "l", 1);
1131 retval
= linux_get_tasks(target
, 1);
1133 if (retval
!= ERROR_OK
)
1134 return ERROR_TARGET_FAILURE
;
1136 char *out_str
= (char *)calloc(1, 350 * sizeof(int64_t));
1137 char *tmp_str
= out_str
;
1138 tmp_str
+= sprintf(tmp_str
, "m");
1139 struct threads
*temp
= linux_os
->thread_list
;
1140 tmp_str
+= sprintf(tmp_str
, "%016" PRIx64
, temp
->threadid
);
1143 while (temp
!= NULL
) {
1144 tmp_str
+= sprintf(tmp_str
, ",");
1145 tmp_str
+= sprintf(tmp_str
, "%016" PRIx64
, temp
->threadid
);
1149 gdb_put_packet(connection
, out_str
, strlen(out_str
));
1153 int linux_gdb_thread_update(struct target
*target
,
1154 struct connection
*connection
, char *packet
,
1158 struct linux_os
*linux_os
= (struct linux_os
*)
1159 target
->rtos
->rtos_specific_params
;
1160 struct threads
*temp
= linux_os
->thread_list
;
1162 while (temp
!= NULL
) {
1163 if (temp
->threadid
== linux_os
->preupdtate_threadid_count
+ 1) {
1164 /*LOG_INFO("FOUND");*/
1172 /*LOG_INFO("INTO GDB THREAD UPDATE FOUNDING START TASK");*/
1173 char *out_strr
= (char *)calloc(1, 350 * sizeof(int64_t));
1174 char *tmp_strr
= out_strr
;
1175 tmp_strr
+= sprintf(tmp_strr
, "m");
1176 /*LOG_INFO("CHAR MALLOC & M DONE");*/
1177 tmp_strr
+= sprintf(tmp_strr
, "%016" PRIx64
, temp
->threadid
);
1181 while (temp
!= NULL
) {
1182 /*LOG_INFO("INTO GDB THREAD UPDATE WHILE");*/
1183 tmp_strr
+= sprintf(tmp_strr
, ",");
1185 sprintf(tmp_strr
, "%016" PRIx64
, temp
->threadid
);
1190 gdb_put_packet(connection
, out_strr
, strlen(out_strr
));
1191 linux_os
->preupdtate_threadid_count
=
1192 linux_os
->threadid_count
- 1;
1195 gdb_put_packet(connection
, "l", 1);
1200 int linux_thread_extra_info(struct target
*target
,
1201 struct connection
*connection
, char *packet
,
1204 int64_t threadid
= 0;
1205 struct linux_os
*linux_os
= (struct linux_os
*)
1206 target
->rtos
->rtos_specific_params
;
1207 sscanf(packet
, "qThreadExtraInfo,%" SCNx64
, &threadid
);
1208 /*LOG_INFO("lookup extra info for thread %" SCNx64, threadid);*/
1209 struct threads
*temp
= linux_os
->thread_list
;
1211 while (temp
!= NULL
) {
1212 if (temp
->threadid
== threadid
) {
1213 char *pid
= " PID: ";
1214 char *pid_current
= "*PID: ";
1215 char *name
= "NAME: ";
1216 int str_size
= strlen(pid
) + strlen(name
);
1217 char *tmp_str
= (char *)calloc(1, str_size
+ 50);
1218 char *tmp_str_ptr
= tmp_str
;
1220 /* discriminate cuurent task */
1221 if (temp
->status
== 3)
1222 tmp_str_ptr
+= sprintf(tmp_str_ptr
, "%s",
1225 tmp_str_ptr
+= sprintf(tmp_str_ptr
, "%s", pid
);
1228 sprintf(tmp_str_ptr
, "%d", (int)temp
->pid
);
1229 tmp_str_ptr
+= sprintf(tmp_str_ptr
, "%s", " | ");
1230 sprintf(tmp_str_ptr
, "%s", name
);
1231 sprintf(tmp_str_ptr
, "%s", temp
->name
);
1233 (char *)calloc(1, strlen(tmp_str
) * 2 + 1);
1234 str_to_hex(hex_str
, tmp_str
);
1235 gdb_put_packet(connection
, hex_str
, strlen(hex_str
));
1244 LOG_INFO("thread not found");
1248 int linux_gdb_T_packet(struct connection
*connection
,
1249 struct target
*target
, char *packet
, int packet_size
)
1252 struct linux_os
*linux_os
= (struct linux_os
*)
1253 target
->rtos
->rtos_specific_params
;
1254 int retval
= ERROR_OK
;
1255 sscanf(packet
, "T%" SCNx64
, &threadid
);
1257 if (linux_os
->threads_needs_update
== 0) {
1258 struct threads
*temp
= linux_os
->thread_list
;
1259 struct threads
*prev
= linux_os
->thread_list
;
1261 while (temp
!= NULL
) {
1262 if (temp
->threadid
== threadid
) {
1263 if (temp
->status
!= 0) {
1264 gdb_put_packet(connection
, "OK", 2);
1267 /* delete item in the list */
1268 linux_os
->thread_list
=
1269 liste_del_task(linux_os
->
1272 linux_os
->thread_count
--;
1273 gdb_put_packet(connection
, "E01", 3);
1283 LOG_INFO("gdb requested status on non existing thread");
1284 gdb_put_packet(connection
, "E01", 3);
1288 retval
= linux_task_update(target
, 1);
1289 struct threads
*temp
= linux_os
->thread_list
;
1291 while (temp
!= NULL
) {
1292 if (temp
->threadid
== threadid
) {
1293 if (temp
->status
== 1) {
1294 gdb_put_packet(connection
, "OK", 2);
1297 gdb_put_packet(connection
, "E01", 3);
1309 int linux_gdb_h_packet(struct connection
*connection
,
1310 struct target
*target
, char *packet
, int packet_size
)
1312 struct linux_os
*linux_os
= (struct linux_os
*)
1313 target
->rtos
->rtos_specific_params
;
1314 struct current_thread
*ct
= linux_os
->current_threads
;
1316 /* select to display the current thread of the selected target */
1317 while ((ct
!= NULL
) && (ct
->core_id
!= target
->coreid
))
1320 int64_t current_gdb_thread_rq
;
1322 if (linux_os
->threads_lookup
== 1) {
1323 if ((ct
!= NULL
) && (ct
->threadid
== -1)) {
1324 ct
= linux_os
->current_threads
;
1326 while ((ct
!= NULL
) && (ct
->threadid
== -1))
1331 /* no current thread can be identified
1332 * any way with smp */
1333 LOG_INFO("no current thread identified");
1334 /* attempt to display the name of the 2 threads identified with
1337 ct
= linux_os
->current_threads
;
1339 while ((ct
!= NULL
) && (ct
->threadid
== -1)) {
1340 t
.base_addr
= ct
->TS
;
1341 get_name(target
, &t
);
1342 LOG_INFO("name of unidentified thread %s",
1347 gdb_put_packet(connection
, "OK", 2);
1351 if (packet
[1] == 'g') {
1352 sscanf(packet
, "Hg%16" SCNx64
, ¤t_gdb_thread_rq
);
1354 if (current_gdb_thread_rq
== 0) {
1355 target
->rtos
->current_threadid
= ct
->threadid
;
1356 gdb_put_packet(connection
, "OK", 2);
1358 target
->rtos
->current_threadid
=
1359 current_gdb_thread_rq
;
1360 gdb_put_packet(connection
, "OK", 2);
1362 } else if (packet
[1] == 'c') {
1363 sscanf(packet
, "Hc%16" SCNx64
, ¤t_gdb_thread_rq
);
1365 if ((current_gdb_thread_rq
== 0) ||
1366 (current_gdb_thread_rq
== ct
->threadid
)) {
1367 target
->rtos
->current_threadid
= ct
->threadid
;
1368 gdb_put_packet(connection
, "OK", 2);
1370 gdb_put_packet(connection
, "E01", 3);
1373 gdb_put_packet(connection
, "OK", 2);
1378 static int linux_thread_packet(struct connection
*connection
, char *packet
,
1381 int retval
= ERROR_OK
;
1382 struct current_thread
*ct
;
1383 struct target
*target
= get_target_from_connection(connection
);
1384 struct linux_os
*linux_os
= (struct linux_os
*)
1385 target
->rtos
->rtos_specific_params
;
1387 switch (packet
[0]) {
1388 case 'T': /* Is thread alive?*/
1390 linux_gdb_T_packet(connection
, target
, packet
, packet_size
);
1392 case 'H': /* Set current thread */
1393 /* ( 'c' for step and continue, 'g' for all other operations )*/
1394 /*LOG_INFO(" H packet received '%s'", packet);*/
1395 linux_gdb_h_packet(connection
, target
, packet
, packet_size
);
1399 if (strncmp(packet
, "qSymbol", 7) == 0) {
1400 if (rtos_qsymbol(connection
, packet
, packet_size
) == 1) {
1401 linux_compute_virt2phys(target
,
1408 } else if (strncmp(packet
, "qfThreadInfo", 12) == 0) {
1409 if (linux_os
->thread_list
== NULL
) {
1410 retval
= linux_gdb_thread_packet(target
,
1416 retval
= linux_gdb_thread_update(target
,
1422 } else if (strncmp(packet
, "qsThreadInfo", 12) == 0) {
1423 gdb_put_packet(connection
, "l", 1);
1425 } else if (strncmp(packet
, "qThreadExtraInfo,", 17) == 0) {
1426 linux_thread_extra_info(target
, connection
, packet
,
1430 retval
= GDB_THREAD_PACKET_NOT_CONSUMED
;
1435 /* previously response was : thread not found
1436 * gdb_put_packet(connection, "E01", 3); */
1437 retval
= GDB_THREAD_PACKET_NOT_CONSUMED
;
1441 if (linux_os
->threads_lookup
== 1) {
1442 ct
= linux_os
->current_threads
;
1444 while ((ct
!= NULL
) && (ct
->core_id
) != target
->coreid
)
1447 if ((ct
!= NULL
) && (ct
->threadid
== -1)) {
1448 ct
= linux_os
->current_threads
;
1450 while ((ct
!= NULL
) && (ct
->threadid
== -1))
1454 if ((ct
!= NULL
) && (ct
->threadid
!=
1457 && (target
->rtos
->current_threadid
!= -1))
1458 LOG_WARNING("WARNING! current GDB thread do not match" \
1459 "current thread running." \
1460 "Switch thread in GDB to threadid %d",
1463 LOG_INFO("threads_needs_update = 1");
1464 linux_os
->threads_needs_update
= 1;
1468 /* if a packet handler returned an error, exit input loop */
1469 if (retval
!= ERROR_OK
)
1476 static int linux_os_smp_init(struct target
*target
)
1478 struct target_list
*head
;
1479 /* keep only target->rtos */
1480 struct rtos
*rtos
= target
->rtos
;
1481 struct linux_os
*os_linux
=
1482 (struct linux_os
*)rtos
->rtos_specific_params
;
1483 struct current_thread
*ct
;
1484 head
= target
->head
;
1486 while (head
!= (struct target_list
*)NULL
) {
1487 if (head
->target
->rtos
!= rtos
) {
1488 struct linux_os
*smp_os_linux
=
1489 (struct linux_os
*)head
->target
->rtos
->
1490 rtos_specific_params
;
1491 /* remap smp target on rtos */
1492 free(head
->target
->rtos
);
1493 head
->target
->rtos
= rtos
;
1494 /* reuse allocated ct */
1495 ct
= smp_os_linux
->current_threads
;
1497 ct
->TS
= 0xdeadbeef;
1498 ct
->core_id
= head
->target
->coreid
;
1499 os_linux
->current_threads
=
1500 add_current_thread(os_linux
->current_threads
, ct
);
1501 os_linux
->nr_cpus
++;
1511 static int linux_os_create(struct target
*target
)
1513 struct linux_os
*os_linux
= calloc(1, sizeof(struct linux_os
));
1514 struct current_thread
*ct
= calloc(1, sizeof(struct current_thread
));
1515 LOG_INFO("linux os creation\n");
1516 os_linux
->init_task_addr
= 0xdeadbeef;
1517 os_linux
->name
= "linux";
1518 os_linux
->thread_list
= NULL
;
1519 os_linux
->thread_count
= 0;
1520 target
->rtos
->current_threadid
= -1;
1521 os_linux
->nr_cpus
= 1;
1522 os_linux
->threads_lookup
= 0;
1523 os_linux
->threads_needs_update
= 0;
1524 os_linux
->threadid_count
= 1;
1525 os_linux
->current_threads
= NULL
;
1526 target
->rtos
->rtos_specific_params
= (void *)os_linux
;
1527 ct
->core_id
= target
->coreid
;
1529 ct
->TS
= 0xdeadbeef;
1530 os_linux
->current_threads
=
1531 add_current_thread(os_linux
->current_threads
, ct
);
1532 /* overload rtos thread default handler */
1533 target
->rtos
->gdb_thread_packet
= linux_thread_packet
;
1534 /* initialize a default virt 2 phys translation */
1535 os_linux
->phys_mask
= ~0xc0000000;
1536 os_linux
->phys_base
= 0x0;
1540 static char *linux_ps_command(struct target
*target
)
1542 struct linux_os
*linux_os
= (struct linux_os
*)
1543 target
->rtos
->rtos_specific_params
;
1544 int retval
= ERROR_OK
;
1547 if (linux_os
->threads_lookup
== 0)
1548 retval
= linux_get_tasks(target
, 1);
1550 if (linux_os
->threads_needs_update
!= 0)
1551 retval
= linux_task_update(target
, 0);
1554 if (retval
== ERROR_OK
) {
1555 struct threads
*temp
= linux_os
->thread_list
;
1557 LOG_INFO("allocation for %d threads line",
1558 linux_os
->thread_count
);
1559 display
= calloc((linux_os
->thread_count
+ 2) * 80, 1);
1565 tmp
+= sprintf(tmp
, "PID\t\tCPU\t\tASID\t\tNAME\n");
1566 tmp
+= sprintf(tmp
, "---\t\t---\t\t----\t\t----\n");
1568 while (temp
!= NULL
) {
1573 "%d\t\t%d\t\t%x\t\t%s\n",
1574 (int)temp
->pid
, temp
->oncpu
,
1575 temp
->asid
, temp
->name
);
1579 "%d\t\t%d\t\t%x\t\t%s\n",
1580 (int)temp
->pid
, temp
->oncpu
,
1581 temp
->asid
, temp
->name
);
1591 display
= calloc(40, 1);
1592 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)