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));
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
) / sizeof(char *));
331 for (i
= 0; i
< sizeof(linux_symbol_list
) / sizeof(char *); 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");
426 int get_name(struct target
*target
, struct threads
*t
)
429 uint32_t full_name
[4];
430 uint32_t comm
= t
->base_addr
+ COMM
;
433 for (i
= 0; i
< 17; i
++)
436 retval
= linux_read_memory(target
, comm
, 4, 4, (uint8_t *) full_name
);
438 if (retval
!= ERROR_OK
) {
439 LOG_ERROR("get_name: unable to read memory\n");
443 uint32_t raw_name
= target_buffer_get_u32(target
,
446 t
->name
[3] = raw_name
>> 24;
447 t
->name
[2] = raw_name
>> 16;
448 t
->name
[1] = raw_name
>> 8;
449 t
->name
[0] = raw_name
;
451 target_buffer_get_u32(target
, (const uint8_t *)&full_name
[1]);
452 t
->name
[7] = raw_name
>> 24;
453 t
->name
[6] = raw_name
>> 16;
454 t
->name
[5] = raw_name
>> 8;
455 t
->name
[4] = raw_name
;
457 target_buffer_get_u32(target
, (const uint8_t *)&full_name
[2]);
458 t
->name
[11] = raw_name
>> 24;
459 t
->name
[10] = raw_name
>> 16;
460 t
->name
[9] = raw_name
>> 8;
461 t
->name
[8] = raw_name
;
463 target_buffer_get_u32(target
, (const uint8_t *)&full_name
[3]);
464 t
->name
[15] = raw_name
>> 24;
465 t
->name
[14] = raw_name
>> 16;
466 t
->name
[13] = raw_name
>> 8;
467 t
->name
[12] = raw_name
;
472 int get_current(struct target
*target
, int create
)
474 struct target_list
*head
;
479 uint8_t *buffer
= calloc(1, 4);
480 struct linux_os
*linux_os
= (struct linux_os
*)
481 target
->rtos
->rtos_specific_params
;
482 struct current_thread
*ctt
= linux_os
->current_threads
;
484 /* invalid current threads content */
485 while (ctt
!= NULL
) {
487 ctt
->TS
= 0xdeadbeef;
491 while (head
!= (struct target_list
*)NULL
) {
492 struct reg
**reg_list
;
496 if (target_get_gdb_reg_list(head
->target
, ®_list
,
497 ®_list_size
) != ERROR_OK
)
498 return ERROR_TARGET_FAILURE
;
500 if (!reg_list
[13]->valid
)
501 reg_list
[13]->type
->get(reg_list
[13]);
503 buf
= reg_list
[13]->value
;
504 val
= get_buffer(target
, buf
);
505 ti_addr
= (val
& 0xffffe000);
506 uint32_t TS_addr
= ti_addr
+ 0xc;
507 retval
= fill_buffer(target
, TS_addr
, buffer
);
509 if (retval
== ERROR_OK
) {
510 uint32_t TS
= get_buffer(target
, buffer
);
511 uint32_t cpu
, on_cpu
= TS
+ ONCPU
;
512 retval
= fill_buffer(target
, on_cpu
, buffer
);
514 if (retval
== ERROR_OK
) {
515 /*uint32_t cpu = get_buffer(target, buffer);*/
516 struct current_thread
*ct
=
517 linux_os
->current_threads
;
518 cpu
= head
->target
->coreid
;
520 while ((ct
!= NULL
) && (ct
->core_id
!= (int32_t) cpu
))
523 if ((ct
!= NULL
) && (ct
->TS
== 0xdeadbeef))
527 ("error in linux current thread update");
531 t
= calloc(1, sizeof(struct threads
));
532 t
->base_addr
= ct
->TS
;
533 fill_task(target
, t
);
536 insert_into_threadlist(target
, t
);
538 t
->thread_info_addr
= 0xdeadbeef;
539 ct
->threadid
= t
->threadid
;
540 linux_os
->thread_count
++;
544 /*LOG_INFO("Creation of current thread %s",t->name);*/
556 struct cpu_context
*cpu_context_read(struct target
*target
, uint32_t base_addr
,
557 uint32_t *thread_info_addr_old
)
559 struct cpu_context
*context
= calloc(1, sizeof(struct cpu_context
));
560 uint32_t preempt_count_addr
= 0;
561 uint32_t registers
[10];
562 uint8_t *buffer
= calloc(1, 4);
563 uint32_t stack
= base_addr
+ QAT
;
564 uint32_t thread_info_addr
= 0;
565 uint32_t thread_info_addr_update
= 0;
566 int retval
= ERROR_FAIL
;
567 context
->R4
= 0xdeadbeef;
568 context
->R5
= 0xdeadbeef;
569 context
->R6
= 0xdeadbeef;
570 context
->R7
= 0xdeadbeef;
571 context
->R8
= 0xdeadbeef;
572 context
->R9
= 0xdeadbeef;
573 context
->IP
= 0xdeadbeef;
574 context
->FP
= 0xdeadbeef;
575 context
->SP
= 0xdeadbeef;
576 context
->PC
= 0xdeadbeef;
579 if (*thread_info_addr_old
== 0xdeadbeef) {
580 retval
= fill_buffer(target
, stack
, buffer
);
582 if (retval
== ERROR_OK
)
583 thread_info_addr
= get_buffer(target
, buffer
);
585 LOG_ERROR("cpu_context: unable to read memory");
587 thread_info_addr_update
= thread_info_addr
;
589 thread_info_addr
= *thread_info_addr_old
;
591 preempt_count_addr
= thread_info_addr
+ PREEMPT
;
592 retval
= fill_buffer(target
, preempt_count_addr
, buffer
);
594 if (retval
== ERROR_OK
)
595 context
->preempt_count
= get_buffer(target
, buffer
);
597 if (*thread_info_addr_old
!= 0xdeadbeef) {
599 ("cpu_context: cannot read at thread_info_addr");
601 if (*thread_info_addr_old
< LINUX_USER_KERNEL_BORDER
)
603 ("cpu_context : thread_info_addr in userspace!!!");
605 *thread_info_addr_old
= 0xdeadbeef;
609 LOG_ERROR("cpu_context: unable to read memory");
612 thread_info_addr
+= CPU_CONT
;
614 retval
= linux_read_memory(target
, thread_info_addr
, 4, 10,
615 (uint8_t *) registers
);
617 if (retval
!= ERROR_OK
) {
618 LOG_ERROR("cpu_context: unable to read memory\n");
623 target_buffer_get_u32(target
, (const uint8_t *)®isters
[0]);
625 target_buffer_get_u32(target
, (const uint8_t *)®isters
[1]);
627 target_buffer_get_u32(target
, (const uint8_t *)®isters
[2]);
629 target_buffer_get_u32(target
, (const uint8_t *)®isters
[3]);
631 target_buffer_get_u32(target
, (const uint8_t *)®isters
[4]);
633 target_buffer_get_u32(target
, (const uint8_t *)®isters
[5]);
635 target_buffer_get_u32(target
, (const uint8_t *)®isters
[6]);
637 target_buffer_get_u32(target
, (const uint8_t *)®isters
[7]);
639 target_buffer_get_u32(target
, (const uint8_t *)®isters
[8]);
641 target_buffer_get_u32(target
, (const uint8_t *)®isters
[9]);
643 if (*thread_info_addr_old
== 0xdeadbeef)
644 *thread_info_addr_old
= thread_info_addr_update
;
649 uint32_t next_task(struct target
*target
, struct threads
*t
)
651 uint8_t *buffer
= calloc(1, 4);
652 uint32_t next_addr
= t
->base_addr
+ NEXT
;
653 int retval
= fill_buffer(target
, next_addr
, buffer
);
655 if (retval
== ERROR_OK
) {
656 uint32_t val
= get_buffer(target
, buffer
);
661 LOG_ERROR("next task: unable to read memory");
666 struct current_thread
*add_current_thread(struct current_thread
*currents
,
667 struct current_thread
*ct
)
671 if (currents
== NULL
) {
675 struct current_thread
*temp
= currents
;
677 while (temp
->next
!= NULL
)
685 struct threads
*liste_del_task(struct threads
*task_list
, struct threads
**t
,
686 struct threads
*prev
)
688 LOG_INFO("del task %" PRId64
, (*t
)->threadid
);
689 prev
->next
= (*t
)->next
;
691 if (prev
== task_list
)
694 /* free content of threads */
703 struct threads
*liste_add_task(struct threads
*task_list
, struct threads
*t
,
704 struct threads
**last
)
709 if (task_list
== NULL
) {
713 struct threads
*temp
= task_list
;
715 while (temp
->next
!= NULL
)
729 static int current_pid(struct linux_os
*linux_os
, uint32_t pid
)
731 static int current_base_addr(struct linux_os
*linux_os
, uint32_t base_addr
)
734 struct current_thread
*ct
= linux_os
->current_threads
;
737 while ((ct
!= NULL
) && (ct
->pid
!= pid
))
739 while ((ct
!= NULL
) && (ct
->TS
!= base_addr
))
743 if ((ct
!= NULL
) && (ct
->pid
== pid
))
745 if ((ct
!= NULL
) && (ct
->TS
== base_addr
))
752 int linux_get_tasks(struct target
*target
, int context
)
756 struct linux_os
*linux_os
= (struct linux_os
*)
757 target
->rtos
->rtos_specific_params
;
758 linux_os
->thread_list
= NULL
;
759 linux_os
->thread_count
= 0;
761 if (linux_os
->init_task_addr
== 0xdeadbeef) {
762 LOG_INFO("no init symbol\n");
766 int64_t start
= timeval_ms();
768 struct threads
*t
= calloc(1, sizeof(struct threads
));
769 struct threads
*last
= NULL
;
770 t
->base_addr
= linux_os
->init_task_addr
;
771 /* retrieve the thread id , currently running in the different smp core */
772 get_current(target
, 1);
774 while (((t
->base_addr
!= linux_os
->init_task_addr
) &&
775 (t
->base_addr
!= 0)) || (loop
== 0)) {
777 fill_task(target
, t
);
778 retval
= get_name(target
, t
);
780 if (loop
> MAX_THREADS
) {
781 LOG_INFO("more than %d threads !!", MAX_THREADS
);
785 if (retval
!= ERROR_OK
) {
790 /* check that this thread is not one the current threads already
794 if (!current_pid(linux_os
, t
->pid
)) {
796 if (!current_base_addr(linux_os
, t
->base_addr
)) {
798 t
->threadid
= linux_os
->threadid_count
;
800 linux_os
->threadid_count
++;
802 linux_os
->thread_list
=
803 liste_add_task(linux_os
->thread_list
, t
, &last
);
804 /* no interest to fill the context if it is a current thread. */
805 linux_os
->thread_count
++;
806 t
->thread_info_addr
= 0xdeadbeef;
810 cpu_context_read(target
, t
->base_addr
,
811 &t
->thread_info_addr
);
813 /*LOG_INFO("thread %s is a current thread already created",t->name); */
817 uint32_t base_addr
= next_task(target
, t
);
818 t
= calloc(1, sizeof(struct threads
));
819 t
->base_addr
= base_addr
;
822 linux_os
->threads_lookup
= 1;
823 linux_os
->threads_needs_update
= 0;
824 linux_os
->preupdtate_threadid_count
= linux_os
->threadid_count
- 1;
825 /* check that all current threads have been identified */
827 LOG_INFO("complete time %" PRId64
", thread mean %" PRId64
"\n",
828 (timeval_ms() - start
),
829 (timeval_ms() - start
) / linux_os
->threadid_count
);
831 LOG_INFO("threadid count %d", linux_os
->threadid_count
);
836 static int clean_threadlist(struct target
*target
)
838 struct linux_os
*linux_os
= (struct linux_os
*)
839 target
->rtos
->rtos_specific_params
;
840 struct threads
*old
, *temp
= linux_os
->thread_list
;
842 while (temp
!= NULL
) {
855 static int linux_os_clean(struct target
*target
)
857 struct linux_os
*os_linux
= (struct linux_os
*)
858 target
->rtos
->rtos_specific_params
;
859 clean_threadlist(target
);
860 os_linux
->init_task_addr
= 0xdeadbeef;
861 os_linux
->name
= "linux";
862 os_linux
->thread_list
= NULL
;
863 os_linux
->thread_count
= 0;
864 os_linux
->nr_cpus
= 0;
865 os_linux
->threads_lookup
= 0;
866 os_linux
->threads_needs_update
= 0;
867 os_linux
->threadid_count
= 1;
871 static int insert_into_threadlist(struct target
*target
, struct threads
*t
)
873 struct linux_os
*linux_os
= (struct linux_os
*)
874 target
->rtos
->rtos_specific_params
;
875 struct threads
*temp
= linux_os
->thread_list
;
876 t
->threadid
= linux_os
->threadid_count
;
877 linux_os
->threadid_count
++;
882 linux_os
->thread_list
= t
;
884 while (temp
->next
!= NULL
)
894 static void linux_identify_current_threads(struct target
*target
)
896 struct linux_os
*linux_os
= (struct linux_os
*)
897 target
->rtos
->rtos_specific_params
;
898 struct threads
*thread_list
= linux_os
->thread_list
;
899 struct current_thread
*ct
= linux_os
->current_threads
;
900 struct threads
*t
= NULL
;
902 while ((ct
!= NULL
)) {
903 if (ct
->threadid
== -1) {
905 /* un-identified thread */
907 t
= calloc(1, sizeof(struct threads
));
908 t
->base_addr
= ct
->TS
;
911 if (fill_task_pid(target
, t
) != ERROR_OK
) {
915 ("linux identify_current_threads: unable to read pid");
920 /* search in the list of threads if pid
922 while ((thread_list
!= NULL
) && (found
== 0)) {
924 if (thread_list
->pid
== t
->pid
) {
926 if (thread_list
->base_addr
== t
->base_addr
) {
932 thread_list
= thread_list
->next
;
936 /* it is a new thread */
937 if (fill_task(target
, t
) != ERROR_OK
)
941 insert_into_threadlist(target
, t
);
942 t
->thread_info_addr
= 0xdeadbeef;
946 ct
->threadid
= t
->threadid
;
950 linux_os
->thread_count
++;
953 LOG_INFO("current thread core %x identified %s",
954 ct
->core_id
, t
->name
);
956 LOG_INFO("current thread core %x, reused %s",
957 ct
->core_id
, t
->name
);
963 tmp
.base_addr
= ct
->TS
;
964 get_name(target
, &tmp
);
965 LOG_INFO("current thread core %x , already identified %s !!!",
966 ct
->core_id
, tmp
.name
);
976 LOG_ERROR("unable toread pid");
982 static int linux_task_update(struct target
*target
, int context
)
984 struct linux_os
*linux_os
= (struct linux_os
*)
985 target
->rtos
->rtos_specific_params
;
986 struct threads
*thread_list
= linux_os
->thread_list
;
989 linux_os
->thread_count
= 0;
991 /*thread_list = thread_list->next; skip init_task*/
992 while (thread_list
!= NULL
) {
993 thread_list
->status
= 0; /*setting all tasks to dead state*/
995 if (thread_list
->context
) {
996 free(thread_list
->context
);
997 thread_list
->context
= NULL
;
1000 thread_list
= thread_list
->next
;
1005 if (linux_os
->init_task_addr
== 0xdeadbeef) {
1006 LOG_INFO("no init symbol\n");
1009 int64_t start
= timeval_ms();
1010 struct threads
*t
= calloc(1, sizeof(struct threads
));
1011 uint32_t previous
= 0xdeadbeef;
1012 t
->base_addr
= linux_os
->init_task_addr
;
1013 retval
= get_current(target
, 0);
1014 /*check that all current threads have been identified */
1015 linux_identify_current_threads(target
);
1017 while (((t
->base_addr
!= linux_os
->init_task_addr
) &&
1018 (t
->base_addr
!= previous
)) || (loop
== 0)) {
1019 /* for avoiding any permanent loop for any reason possibly due to
1022 previous
= t
->base_addr
;
1025 retval
= fill_task_pid(target
, t
);
1028 if (retval
!= ERROR_OK
) {
1033 thread_list
= linux_os
->thread_list
;
1035 while (thread_list
!= NULL
) {
1037 if (t
->pid
== thread_list
->pid
) {
1039 if (t
->base_addr
== thread_list
->base_addr
) {
1041 if (!thread_list
->status
) {
1043 if (t
->base_addr
!= thread_list
->base_addr
)
1044 LOG_INFO("thread base_addr has changed !!");
1046 /* this is not a current thread */
1047 thread_list
->base_addr
= t
->base_addr
;
1048 thread_list
->status
= 1;
1050 /* we don 't update this field any more */
1052 /*thread_list->state = t->state;
1053 thread_list->oncpu = t->oncpu;
1054 thread_list->asid = t->asid;
1057 thread_list
->context
=
1058 cpu_context_read(target
,
1064 /* it is a current thread no need to read context */
1067 linux_os
->thread_count
++;
1072 thread_list
= thread_list
->next
;
1078 fill_task(target
, t
);
1079 get_name(target
, t
);
1080 retval
= insert_into_threadlist(target
, t
);
1081 t
->thread_info_addr
= 0xdeadbeef;
1085 cpu_context_read(target
, t
->base_addr
,
1086 &t
->thread_info_addr
);
1088 base_addr
= next_task(target
, t
);
1089 t
= calloc(1, sizeof(struct threads
));
1090 t
->base_addr
= base_addr
;
1091 linux_os
->thread_count
++;
1093 t
->base_addr
= next_task(target
, t
);
1096 LOG_INFO("update thread done %" PRId64
", mean%" PRId64
"\n",
1097 (timeval_ms() - start
), (timeval_ms() - start
) / loop
);
1099 linux_os
->threads_needs_update
= 0;
1103 int linux_gdb_thread_packet(struct target
*target
,
1104 struct connection
*connection
, char *packet
,
1108 struct linux_os
*linux_os
=
1109 (struct linux_os
*)target
->rtos
->rtos_specific_params
;
1111 if (linux_os
->init_task_addr
== 0xdeadbeef) {
1112 /* it has not been initialized */
1113 LOG_INFO("received thread request without init task address");
1114 gdb_put_packet(connection
, "l", 1);
1118 retval
= linux_get_tasks(target
, 1);
1120 if (retval
!= ERROR_OK
)
1121 return ERROR_TARGET_FAILURE
;
1123 char *out_str
= (char *)calloc(1, 350 * sizeof(int64_t));
1124 char *tmp_str
= out_str
;
1125 tmp_str
+= sprintf(tmp_str
, "m");
1126 struct threads
*temp
= linux_os
->thread_list
;
1127 tmp_str
+= sprintf(tmp_str
, "%016" PRIx64
, temp
->threadid
);
1130 while (temp
!= NULL
) {
1131 tmp_str
+= sprintf(tmp_str
, ",");
1132 tmp_str
+= sprintf(tmp_str
, "%016" PRIx64
, temp
->threadid
);
1136 gdb_put_packet(connection
, out_str
, strlen(out_str
));
1140 int linux_gdb_thread_update(struct target
*target
,
1141 struct connection
*connection
, char *packet
,
1145 struct linux_os
*linux_os
= (struct linux_os
*)
1146 target
->rtos
->rtos_specific_params
;
1147 struct threads
*temp
= linux_os
->thread_list
;
1149 while (temp
!= NULL
) {
1150 if (temp
->threadid
== linux_os
->preupdtate_threadid_count
+ 1) {
1151 /*LOG_INFO("FOUND");*/
1159 /*LOG_INFO("INTO GDB THREAD UPDATE FOUNDING START TASK");*/
1160 char *out_strr
= (char *)calloc(1, 350 * sizeof(int64_t));
1161 char *tmp_strr
= out_strr
;
1162 tmp_strr
+= sprintf(tmp_strr
, "m");
1163 /*LOG_INFO("CHAR MALLOC & M DONE");*/
1164 tmp_strr
+= sprintf(tmp_strr
, "%016" PRIx64
, temp
->threadid
);
1168 while (temp
!= NULL
) {
1169 /*LOG_INFO("INTO GDB THREAD UPDATE WHILE");*/
1170 tmp_strr
+= sprintf(tmp_strr
, ",");
1172 sprintf(tmp_strr
, "%016" PRIx64
, temp
->threadid
);
1177 gdb_put_packet(connection
, out_strr
, strlen(out_strr
));
1178 linux_os
->preupdtate_threadid_count
=
1179 linux_os
->threadid_count
- 1;
1182 gdb_put_packet(connection
, "l", 1);
1187 int linux_thread_extra_info(struct target
*target
,
1188 struct connection
*connection
, char *packet
,
1191 int64_t threadid
= 0;
1192 struct linux_os
*linux_os
= (struct linux_os
*)
1193 target
->rtos
->rtos_specific_params
;
1194 sscanf(packet
, "qThreadExtraInfo,%" SCNx64
, &threadid
);
1195 /*LOG_INFO("lookup extra info for thread %" SCNx64, threadid);*/
1196 struct threads
*temp
= linux_os
->thread_list
;
1198 while (temp
!= NULL
) {
1199 if (temp
->threadid
== threadid
) {
1200 char *pid
= " PID: ";
1201 char *pid_current
= "*PID: ";
1202 char *name
= "NAME: ";
1203 int str_size
= strlen(pid
) + strlen(name
);
1204 char *tmp_str
= (char *)calloc(1, str_size
+ 50);
1205 char *tmp_str_ptr
= tmp_str
;
1207 /* discriminate cuurent task */
1208 if (temp
->status
== 3)
1209 tmp_str_ptr
+= sprintf(tmp_str_ptr
, "%s",
1212 tmp_str_ptr
+= sprintf(tmp_str_ptr
, "%s", pid
);
1215 sprintf(tmp_str_ptr
, "%d", (int)temp
->pid
);
1216 tmp_str_ptr
+= sprintf(tmp_str_ptr
, "%s", " | ");
1217 sprintf(tmp_str_ptr
, "%s", name
);
1218 sprintf(tmp_str_ptr
, "%s", temp
->name
);
1220 (char *)calloc(1, strlen(tmp_str
) * 2 + 1);
1221 str_to_hex(hex_str
, tmp_str
);
1222 gdb_put_packet(connection
, hex_str
, strlen(hex_str
));
1231 LOG_INFO("thread not found");
1235 int linux_gdb_T_packet(struct connection
*connection
,
1236 struct target
*target
, char *packet
, int packet_size
)
1239 struct linux_os
*linux_os
= (struct linux_os
*)
1240 target
->rtos
->rtos_specific_params
;
1241 int retval
= ERROR_OK
;
1242 sscanf(packet
, "T%" SCNx64
, &threadid
);
1244 if (linux_os
->threads_needs_update
== 0) {
1245 struct threads
*temp
= linux_os
->thread_list
;
1246 struct threads
*prev
= linux_os
->thread_list
;
1248 while (temp
!= NULL
) {
1249 if (temp
->threadid
== threadid
) {
1250 if (temp
->status
!= 0) {
1251 gdb_put_packet(connection
, "OK", 2);
1254 /* delete item in the list */
1255 linux_os
->thread_list
=
1256 liste_del_task(linux_os
->
1259 linux_os
->thread_count
--;
1260 gdb_put_packet(connection
, "E01", 3);
1270 LOG_INFO("gdb requested status on non existing thread");
1271 gdb_put_packet(connection
, "E01", 3);
1275 retval
= linux_task_update(target
, 1);
1276 struct threads
*temp
= linux_os
->thread_list
;
1278 while (temp
!= NULL
) {
1279 if (temp
->threadid
== threadid
) {
1280 if (temp
->status
== 1) {
1281 gdb_put_packet(connection
, "OK", 2);
1284 gdb_put_packet(connection
, "E01", 3);
1296 int linux_gdb_h_packet(struct connection
*connection
,
1297 struct target
*target
, char *packet
, int packet_size
)
1299 struct linux_os
*linux_os
= (struct linux_os
*)
1300 target
->rtos
->rtos_specific_params
;
1301 struct current_thread
*ct
= linux_os
->current_threads
;
1303 /* select to display the current thread of the selected target */
1304 while ((ct
!= NULL
) && (ct
->core_id
!= target
->coreid
))
1307 int64_t current_gdb_thread_rq
;
1309 if (linux_os
->threads_lookup
== 1) {
1310 if ((ct
!= NULL
) && (ct
->threadid
== -1)) {
1311 ct
= linux_os
->current_threads
;
1313 while ((ct
!= NULL
) && (ct
->threadid
== -1))
1318 /* no current thread can be identified
1319 * any way with smp */
1320 LOG_INFO("no current thread identified");
1321 /* attempt to display the name of the 2 threads identified with
1324 ct
= linux_os
->current_threads
;
1326 while ((ct
!= NULL
) && (ct
->threadid
== -1)) {
1327 t
.base_addr
= ct
->TS
;
1328 get_name(target
, &t
);
1329 LOG_INFO("name of unidentified thread %s",
1334 gdb_put_packet(connection
, "OK", 2);
1338 if (packet
[1] == 'g') {
1339 sscanf(packet
, "Hg%16" SCNx64
, ¤t_gdb_thread_rq
);
1341 if (current_gdb_thread_rq
== 0) {
1342 target
->rtos
->current_threadid
= ct
->threadid
;
1343 gdb_put_packet(connection
, "OK", 2);
1345 target
->rtos
->current_threadid
=
1346 current_gdb_thread_rq
;
1347 gdb_put_packet(connection
, "OK", 2);
1349 } else if (packet
[1] == 'c') {
1350 sscanf(packet
, "Hc%16" SCNx64
, ¤t_gdb_thread_rq
);
1352 if ((current_gdb_thread_rq
== 0) ||
1353 (current_gdb_thread_rq
== ct
->threadid
)) {
1354 target
->rtos
->current_threadid
= ct
->threadid
;
1355 gdb_put_packet(connection
, "OK", 2);
1357 gdb_put_packet(connection
, "E01", 3);
1360 gdb_put_packet(connection
, "OK", 2);
1365 static int linux_thread_packet(struct connection
*connection
, char *packet
,
1368 int retval
= ERROR_OK
;
1369 struct current_thread
*ct
;
1370 struct target
*target
= get_target_from_connection(connection
);
1371 struct linux_os
*linux_os
= (struct linux_os
*)
1372 target
->rtos
->rtos_specific_params
;
1374 switch (packet
[0]) {
1375 case 'T': /* Is thread alive?*/
1377 linux_gdb_T_packet(connection
, target
, packet
, packet_size
);
1379 case 'H': /* Set current thread */
1380 /* ( 'c' for step and continue, 'g' for all other operations )*/
1381 /*LOG_INFO(" H packet received '%s'", packet);*/
1382 linux_gdb_h_packet(connection
, target
, packet
, packet_size
);
1386 if ((strstr(packet
, "qSymbol"))) {
1387 if (rtos_qsymbol(connection
, packet
, packet_size
) == 1) {
1388 gdb_put_packet(connection
, "OK", 2);
1390 linux_compute_virt2phys(target
,
1397 } else if (strstr(packet
, "qfThreadInfo")) {
1398 if (linux_os
->thread_list
== NULL
) {
1399 retval
= linux_gdb_thread_packet(target
,
1405 retval
= linux_gdb_thread_update(target
,
1411 } else if (strstr(packet
, "qsThreadInfo")) {
1412 gdb_put_packet(connection
, "l", 1);
1414 } else if (strstr(packet
, "qThreadExtraInfo,")) {
1415 linux_thread_extra_info(target
, connection
, packet
,
1419 retval
= GDB_THREAD_PACKET_NOT_CONSUMED
;
1424 /* previously response was : thread not found
1425 * gdb_put_packet(connection, "E01", 3); */
1426 retval
= GDB_THREAD_PACKET_NOT_CONSUMED
;
1430 if (linux_os
->threads_lookup
== 1) {
1431 ct
= linux_os
->current_threads
;
1433 while ((ct
!= NULL
) && (ct
->core_id
) != target
->coreid
)
1436 if ((ct
!= NULL
) && (ct
->threadid
== -1)) {
1437 ct
= linux_os
->current_threads
;
1439 while ((ct
!= NULL
) && (ct
->threadid
== -1))
1443 if ((ct
!= NULL
) && (ct
->threadid
!=
1446 && (target
->rtos
->current_threadid
!= -1))
1447 LOG_WARNING("WARNING! current GDB thread do not match" \
1448 "current thread running." \
1449 "Switch thread in GDB to threadid %d",
1452 LOG_INFO("threads_needs_update = 1");
1453 linux_os
->threads_needs_update
= 1;
1457 /* if a packet handler returned an error, exit input loop */
1458 if (retval
!= ERROR_OK
)
1465 static int linux_os_smp_init(struct target
*target
)
1467 struct target_list
*head
;
1468 /* keep only target->rtos */
1469 struct rtos
*rtos
= target
->rtos
;
1470 struct linux_os
*os_linux
=
1471 (struct linux_os
*)rtos
->rtos_specific_params
;
1472 struct current_thread
*ct
;
1473 head
= target
->head
;
1475 while (head
!= (struct target_list
*)NULL
) {
1476 if (head
->target
->rtos
!= rtos
) {
1477 struct linux_os
*smp_os_linux
=
1478 (struct linux_os
*)head
->target
->rtos
->
1479 rtos_specific_params
;
1480 /* remap smp target on rtos */
1481 free(head
->target
->rtos
);
1482 head
->target
->rtos
= rtos
;
1483 /* reuse allocated ct */
1484 ct
= smp_os_linux
->current_threads
;
1486 ct
->TS
= 0xdeadbeef;
1487 ct
->core_id
= head
->target
->coreid
;
1488 os_linux
->current_threads
=
1489 add_current_thread(os_linux
->current_threads
, ct
);
1490 os_linux
->nr_cpus
++;
1500 static int linux_os_create(struct target
*target
)
1502 struct linux_os
*os_linux
= calloc(1, sizeof(struct linux_os
));
1503 struct current_thread
*ct
= calloc(1, sizeof(struct current_thread
));
1504 LOG_INFO("linux os creation\n");
1505 os_linux
->init_task_addr
= 0xdeadbeef;
1506 os_linux
->name
= "linux";
1507 os_linux
->thread_list
= NULL
;
1508 os_linux
->thread_count
= 0;
1509 target
->rtos
->current_threadid
= -1;
1510 os_linux
->nr_cpus
= 1;
1511 os_linux
->threads_lookup
= 0;
1512 os_linux
->threads_needs_update
= 0;
1513 os_linux
->threadid_count
= 1;
1514 os_linux
->current_threads
= NULL
;
1515 target
->rtos
->rtos_specific_params
= (void *)os_linux
;
1516 ct
->core_id
= target
->coreid
;
1518 ct
->TS
= 0xdeadbeef;
1519 os_linux
->current_threads
=
1520 add_current_thread(os_linux
->current_threads
, ct
);
1521 /* overload rtos thread default handler */
1522 target
->rtos
->gdb_thread_packet
= linux_thread_packet
;
1523 /* initialize a default virt 2 phys translation */
1524 os_linux
->phys_mask
= ~0xc0000000;
1525 os_linux
->phys_base
= 0x0;
1529 static char *linux_ps_command(struct target
*target
)
1531 struct linux_os
*linux_os
= (struct linux_os
*)
1532 target
->rtos
->rtos_specific_params
;
1533 int retval
= ERROR_OK
;
1536 if (linux_os
->threads_lookup
== 0)
1537 retval
= linux_get_tasks(target
, 1);
1539 if (linux_os
->threads_needs_update
!= 0)
1540 retval
= linux_task_update(target
, 0);
1543 if (retval
== ERROR_OK
) {
1544 struct threads
*temp
= linux_os
->thread_list
;
1546 LOG_INFO("allocation for %d threads line",
1547 linux_os
->thread_count
);
1548 display
= calloc((linux_os
->thread_count
+ 2) * 80, 1);
1554 tmp
+= sprintf(tmp
, "PID\t\tCPU\t\tASID\t\tNAME\n");
1555 tmp
+= sprintf(tmp
, "---\t\t---\t\t----\t\t----\n");
1557 while (temp
!= NULL
) {
1562 "%d\t\t%d\t\t%x\t\t%s\n",
1563 (int)temp
->pid
, temp
->oncpu
,
1564 temp
->asid
, temp
->name
);
1568 "%d\t\t%d\t\t%x\t\t%s\n",
1569 (int)temp
->pid
, temp
->oncpu
,
1570 temp
->asid
, temp
->name
);
1580 display
= calloc(40, 1);
1581 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)