rtos: support gdb_get_register_packet
[openocd.git] / src / rtos / linux.c
blob74172b70a43c189b27d69cfe9e5e33f9c8cf72e0
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 *
5 * *
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. *
10 * *
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. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
18 ***************************************************************************/
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
24 #include <helper/time_support.h>
25 #include <jtag/jtag.h>
26 #include "target/target.h"
27 #include "target/target_type.h"
28 #include "helper/log.h"
29 #include "helper/types.h"
30 #include "rtos.h"
31 #include "rtos_standard_stackings.h"
32 #include <target/register.h>
33 #include "server/gdb_server.h"
35 #define LINUX_USER_KERNEL_BORDER 0xc0000000
36 #include "linux_header.h"
37 #define PHYS
38 #define MAX_THREADS 200
39 /* specific task */
40 struct linux_os {
41 const char *name;
42 uint32_t init_task_addr;
43 int thread_count;
44 int threadid_count;
45 int preupdtate_threadid_count;
46 int nr_cpus;
47 int threads_lookup;
48 int threads_needs_update;
49 struct current_thread *current_threads;
50 struct threads *thread_list;
51 /* virt2phys parameter */
52 uint32_t phys_mask;
53 uint32_t phys_base;
56 struct current_thread {
57 int64_t threadid;
58 int32_t core_id;
59 #ifdef PID_CHECK
60 uint32_t pid;
61 #endif
62 uint32_t TS;
63 struct current_thread *next;
66 struct threads {
67 char name[17];
68 uint32_t base_addr; /* address to read magic */
69 uint32_t state; /* magic value : filled only at creation */
70 uint32_t pid; /* linux pid : id for identifying a thread */
71 uint32_t oncpu; /* content cpu number in current thread */
72 uint32_t asid; /* filled only at creation */
73 int64_t threadid;
74 int status; /* dead = 1 alive = 2 current = 3 alive and current */
75 /* value that should not change during the live of a thread ? */
76 uint32_t thread_info_addr; /* contain latest thread_info_addr computed */
77 /* retrieve from thread_info */
78 struct cpu_context *context;
79 struct threads *next;
82 struct cpu_context {
83 uint32_t R4;
84 uint32_t R5;
85 uint32_t R6;
86 uint32_t R7;
87 uint32_t R8;
88 uint32_t R9;
89 uint32_t IP;
90 uint32_t FP;
91 uint32_t SP;
92 uint32_t PC;
93 uint32_t preempt_count;
95 struct cpu_context *cpu_context_read(struct target *target, uint32_t base_addr,
96 uint32_t *info_addr);
97 static int insert_into_threadlist(struct target *target, struct threads *t);
99 static int linux_os_create(struct target *target);
101 static int linux_os_dummy_update(struct rtos *rtos)
103 /* update is done only when thread request come
104 * too many thread to do it on each stop */
105 return 0;
108 static int linux_compute_virt2phys(struct target *target, target_addr_t address)
110 struct linux_os *linux_os = (struct linux_os *)
111 target->rtos->rtos_specific_params;
112 target_addr_t pa = 0;
113 int retval = target->type->virt2phys(target, address, &pa);
114 if (retval != ERROR_OK) {
115 LOG_ERROR("Cannot compute linux virt2phys translation");
116 /* fixes default address */
117 linux_os->phys_base = 0;
118 return ERROR_FAIL;
121 linux_os->init_task_addr = address;
122 address = address & linux_os->phys_mask;
123 linux_os->phys_base = pa - address;
124 return ERROR_OK;
127 static int linux_read_memory(struct target *target,
128 uint32_t address, uint32_t size, uint32_t count,
129 uint8_t *buffer)
131 #ifdef PHYS
132 struct linux_os *linux_os = (struct linux_os *)
133 target->rtos->rtos_specific_params;
134 uint32_t pa = (address & linux_os->phys_mask) + linux_os->phys_base;
135 #endif
136 if (address < 0xc000000) {
137 LOG_ERROR("linux awareness : address in user space");
138 return ERROR_FAIL;
140 #ifdef PHYS
141 target_read_phys_memory(target, pa, size, count, buffer);
142 #endif
143 target_read_memory(target, address, size, count, buffer);
144 return ERROR_OK;
147 int fill_buffer(struct target *target, uint32_t addr, uint8_t *buffer)
150 if ((addr & 0xfffffffc) != addr)
151 LOG_INFO("unaligned address %" PRIx32 "!!", addr);
153 int retval = linux_read_memory(target, addr, 4, 1, buffer);
154 return retval;
158 uint32_t get_buffer(struct target *target, const uint8_t *buffer)
160 uint32_t value = 0;
161 const uint8_t *value_ptr = buffer;
162 value = target_buffer_get_u32(target, value_ptr);
163 return value;
166 static int linux_os_thread_reg_list(struct rtos *rtos,
167 int64_t thread_id, struct rtos_reg **reg_list, int *num_regs)
169 struct target *target = rtos->target;
170 struct linux_os *linux_os = (struct linux_os *)
171 target->rtos->rtos_specific_params;
172 struct current_thread *tmp = linux_os->current_threads;
173 struct current_thread *next;
174 int found = 0;
175 int retval;
176 /* check if a current thread is requested */
177 next = tmp;
179 do {
180 if (next->threadid == thread_id)
181 found = 1;
182 else
183 next = next->next;
184 } while ((found == 0) && (next != tmp) && (next != NULL));
186 if (found == 0) {
187 LOG_ERROR("could not find thread: %" PRIx64, thread_id);
188 return ERROR_FAIL;
191 /* search target to perfom the access */
192 struct reg **gdb_reg_list;
193 struct target_list *head;
194 head = target->head;
195 found = 0;
196 do {
197 if (head->target->coreid == next->core_id) {
199 target = head->target;
200 found = 1;
201 } else
202 head = head->next;
204 } while ((head != (struct target_list *)NULL) && (found == 0));
206 if (found == 0) {
207 LOG_ERROR
209 "current thread %" PRIx64 ": no target to perform access of core id %" PRIx32,
210 thread_id,
211 next->core_id);
212 return ERROR_FAIL;
215 /*LOG_INFO("thread %lx current on core %x",thread_id, target->coreid);*/
216 retval = target_get_gdb_reg_list(target, &gdb_reg_list, num_regs, REG_CLASS_GENERAL);
217 if (retval != ERROR_OK)
218 return retval;
220 *reg_list = calloc(*num_regs, sizeof(struct rtos_reg));
222 for (int i = 0; i < *num_regs; ++i) {
223 if (!gdb_reg_list[i]->valid)
224 gdb_reg_list[i]->type->get(gdb_reg_list[i]);
226 (*reg_list)[i].number = gdb_reg_list[i]->number;
227 (*reg_list)[i].size = gdb_reg_list[i]->size;
229 buf_cpy(gdb_reg_list[i]->value, (*reg_list)[i].value, (*reg_list)[i].size);
232 return ERROR_OK;
235 static bool linux_os_detect(struct target *target)
237 LOG_INFO("should no be called");
238 return false;
241 static int linux_os_smp_init(struct target *target);
242 static int linux_os_clean(struct target *target);
243 #define INIT_TASK 0
244 static const char * const linux_symbol_list[] = {
245 "init_task",
246 NULL
249 static int linux_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[])
251 unsigned int i;
252 *symbol_list = (symbol_table_elem_t *)
253 calloc(ARRAY_SIZE(linux_symbol_list), sizeof(symbol_table_elem_t));
255 for (i = 0; i < ARRAY_SIZE(linux_symbol_list); i++)
256 (*symbol_list)[i].symbol_name = linux_symbol_list[i];
258 return 0;
261 static char *linux_ps_command(struct target *target);
263 const struct rtos_type Linux_os = {
264 .name = "linux",
265 .detect_rtos = linux_os_detect,
266 .create = linux_os_create,
267 .smp_init = linux_os_smp_init,
268 .update_threads = linux_os_dummy_update,
269 .get_thread_reg_list = linux_os_thread_reg_list,
270 .get_symbol_list_to_lookup = linux_get_symbol_list_to_lookup,
271 .clean = linux_os_clean,
272 .ps_command = linux_ps_command,
275 static int linux_thread_packet(struct connection *connection, char const *packet,
276 int packet_size);
277 static void linux_identify_current_threads(struct target *target);
279 #ifdef PID_CHECK
280 int fill_task_pid(struct target *target, struct threads *t)
282 uint32_t pid_addr = t->base_addr + PID;
283 uint8_t buffer[4];
284 int retval = fill_buffer(target, pid_addr, buffer);
286 if (retval == ERROR_OK) {
287 uint32_t val = get_buffer(target, buffer);
288 t->pid = val;
289 } else
290 LOG_ERROR("fill_task_pid: unable to read memory");
292 return retval;
294 #endif
296 int fill_task(struct target *target, struct threads *t)
298 int retval;
299 uint32_t pid_addr = t->base_addr + PID;
300 uint32_t mem_addr = t->base_addr + MEM;
301 uint32_t on_cpu = t->base_addr + ONCPU;
302 uint8_t *buffer = calloc(1, 4);
303 retval = fill_buffer(target, t->base_addr, buffer);
305 if (retval == ERROR_OK) {
306 uint32_t val = get_buffer(target, buffer);
307 t->state = val;
308 } else
309 LOG_ERROR("fill_task: unable to read memory");
311 retval = fill_buffer(target, pid_addr, buffer);
313 if (retval == ERROR_OK) {
314 uint32_t val = get_buffer(target, buffer);
315 t->pid = val;
316 } else
317 LOG_ERROR("fill task: unable to read memory");
319 retval = fill_buffer(target, on_cpu, buffer);
321 if (retval == ERROR_OK) {
322 uint32_t val = get_buffer(target, buffer);
323 t->oncpu = val;
324 } else
325 LOG_ERROR("fill task: unable to read memory");
327 retval = fill_buffer(target, mem_addr, buffer);
329 if (retval == ERROR_OK) {
330 uint32_t val = get_buffer(target, buffer);
332 if (val != 0) {
333 uint32_t asid_addr = val + MM_CTX;
334 retval = fill_buffer(target, asid_addr, buffer);
336 if (retval == ERROR_OK) {
337 val = get_buffer(target, buffer);
338 t->asid = val;
339 } else
340 LOG_ERROR
341 ("fill task: unable to read memory -- ASID");
342 } else
343 t->asid = 0;
344 } else
345 LOG_ERROR("fill task: unable to read memory");
347 free(buffer);
349 return retval;
352 int get_name(struct target *target, struct threads *t)
354 int retval;
355 uint32_t full_name[4];
356 uint32_t comm = t->base_addr + COMM;
357 int i;
359 for (i = 0; i < 17; i++)
360 t->name[i] = 0;
362 retval = linux_read_memory(target, comm, 4, 4, (uint8_t *) full_name);
364 if (retval != ERROR_OK) {
365 LOG_ERROR("get_name: unable to read memory\n");
366 return ERROR_FAIL;
369 uint32_t raw_name = target_buffer_get_u32(target,
370 (const uint8_t *)
371 &full_name[0]);
372 t->name[3] = raw_name >> 24;
373 t->name[2] = raw_name >> 16;
374 t->name[1] = raw_name >> 8;
375 t->name[0] = raw_name;
376 raw_name =
377 target_buffer_get_u32(target, (const uint8_t *)&full_name[1]);
378 t->name[7] = raw_name >> 24;
379 t->name[6] = raw_name >> 16;
380 t->name[5] = raw_name >> 8;
381 t->name[4] = raw_name;
382 raw_name =
383 target_buffer_get_u32(target, (const uint8_t *)&full_name[2]);
384 t->name[11] = raw_name >> 24;
385 t->name[10] = raw_name >> 16;
386 t->name[9] = raw_name >> 8;
387 t->name[8] = raw_name;
388 raw_name =
389 target_buffer_get_u32(target, (const uint8_t *)&full_name[3]);
390 t->name[15] = raw_name >> 24;
391 t->name[14] = raw_name >> 16;
392 t->name[13] = raw_name >> 8;
393 t->name[12] = raw_name;
394 return ERROR_OK;
398 int get_current(struct target *target, int create)
400 struct target_list *head;
401 head = target->head;
402 uint8_t *buf;
403 uint32_t val;
404 uint32_t ti_addr;
405 uint8_t *buffer = calloc(1, 4);
406 struct linux_os *linux_os = (struct linux_os *)
407 target->rtos->rtos_specific_params;
408 struct current_thread *ctt = linux_os->current_threads;
410 /* invalid current threads content */
411 while (ctt != NULL) {
412 ctt->threadid = -1;
413 ctt->TS = 0xdeadbeef;
414 ctt = ctt->next;
417 while (head != (struct target_list *)NULL) {
418 struct reg **reg_list;
419 int reg_list_size;
420 int retval;
422 if (target_get_gdb_reg_list(head->target, &reg_list,
423 &reg_list_size, REG_CLASS_GENERAL) != ERROR_OK) {
424 free(buffer);
425 return ERROR_TARGET_FAILURE;
428 if (!reg_list[13]->valid)
429 reg_list[13]->type->get(reg_list[13]);
431 buf = reg_list[13]->value;
432 val = get_buffer(target, buf);
433 ti_addr = (val & 0xffffe000);
434 uint32_t TS_addr = ti_addr + 0xc;
435 retval = fill_buffer(target, TS_addr, buffer);
437 if (retval == ERROR_OK) {
438 uint32_t TS = get_buffer(target, buffer);
439 uint32_t cpu, on_cpu = TS + ONCPU;
440 retval = fill_buffer(target, on_cpu, buffer);
442 if (retval == ERROR_OK) {
443 /*uint32_t cpu = get_buffer(target, buffer);*/
444 struct current_thread *ct =
445 linux_os->current_threads;
446 cpu = head->target->coreid;
448 while ((ct != NULL) && (ct->core_id != (int32_t) cpu))
449 ct = ct->next;
451 if ((ct != NULL) && (ct->TS == 0xdeadbeef))
452 ct->TS = TS;
453 else
454 LOG_ERROR
455 ("error in linux current thread update");
457 if (create && ct) {
458 struct threads *t;
459 t = calloc(1, sizeof(struct threads));
460 t->base_addr = ct->TS;
461 fill_task(target, t);
462 get_name(target, t);
463 t->oncpu = cpu;
464 insert_into_threadlist(target, t);
465 t->status = 3;
466 t->thread_info_addr = 0xdeadbeef;
467 ct->threadid = t->threadid;
468 linux_os->thread_count++;
469 #ifdef PID_CHECK
470 ct->pid = t->pid;
471 #endif
472 /*LOG_INFO("Creation of current thread %s",t->name);*/
477 free(reg_list);
478 head = head->next;
481 free(buffer);
483 return ERROR_OK;
486 struct cpu_context *cpu_context_read(struct target *target, uint32_t base_addr,
487 uint32_t *thread_info_addr_old)
489 struct cpu_context *context = calloc(1, sizeof(struct cpu_context));
490 uint32_t preempt_count_addr = 0;
491 uint32_t registers[10];
492 uint8_t *buffer = calloc(1, 4);
493 uint32_t stack = base_addr + QAT;
494 uint32_t thread_info_addr = 0;
495 uint32_t thread_info_addr_update = 0;
496 int retval = ERROR_FAIL;
497 context->R4 = 0xdeadbeef;
498 context->R5 = 0xdeadbeef;
499 context->R6 = 0xdeadbeef;
500 context->R7 = 0xdeadbeef;
501 context->R8 = 0xdeadbeef;
502 context->R9 = 0xdeadbeef;
503 context->IP = 0xdeadbeef;
504 context->FP = 0xdeadbeef;
505 context->SP = 0xdeadbeef;
506 context->PC = 0xdeadbeef;
507 retry:
509 if (*thread_info_addr_old == 0xdeadbeef) {
510 retval = fill_buffer(target, stack, buffer);
512 if (retval == ERROR_OK)
513 thread_info_addr = get_buffer(target, buffer);
514 else
515 LOG_ERROR("cpu_context: unable to read memory");
517 thread_info_addr_update = thread_info_addr;
518 } else
519 thread_info_addr = *thread_info_addr_old;
521 preempt_count_addr = thread_info_addr + PREEMPT;
522 retval = fill_buffer(target, preempt_count_addr, buffer);
524 if (retval == ERROR_OK)
525 context->preempt_count = get_buffer(target, buffer);
526 else {
527 if (*thread_info_addr_old != 0xdeadbeef) {
528 LOG_ERROR
529 ("cpu_context: cannot read at thread_info_addr");
531 if (*thread_info_addr_old < LINUX_USER_KERNEL_BORDER)
532 LOG_INFO
533 ("cpu_context : thread_info_addr in userspace!!!");
535 *thread_info_addr_old = 0xdeadbeef;
536 goto retry;
539 LOG_ERROR("cpu_context: unable to read memory");
542 thread_info_addr += CPU_CONT;
544 retval = linux_read_memory(target, thread_info_addr, 4, 10,
545 (uint8_t *) registers);
547 if (retval != ERROR_OK) {
548 free(buffer);
549 LOG_ERROR("cpu_context: unable to read memory\n");
550 return context;
553 context->R4 =
554 target_buffer_get_u32(target, (const uint8_t *)&registers[0]);
555 context->R5 =
556 target_buffer_get_u32(target, (const uint8_t *)&registers[1]);
557 context->R6 =
558 target_buffer_get_u32(target, (const uint8_t *)&registers[2]);
559 context->R7 =
560 target_buffer_get_u32(target, (const uint8_t *)&registers[3]);
561 context->R8 =
562 target_buffer_get_u32(target, (const uint8_t *)&registers[4]);
563 context->R9 =
564 target_buffer_get_u32(target, (const uint8_t *)&registers[5]);
565 context->IP =
566 target_buffer_get_u32(target, (const uint8_t *)&registers[6]);
567 context->FP =
568 target_buffer_get_u32(target, (const uint8_t *)&registers[7]);
569 context->SP =
570 target_buffer_get_u32(target, (const uint8_t *)&registers[8]);
571 context->PC =
572 target_buffer_get_u32(target, (const uint8_t *)&registers[9]);
574 if (*thread_info_addr_old == 0xdeadbeef)
575 *thread_info_addr_old = thread_info_addr_update;
577 free(buffer);
579 return context;
582 uint32_t next_task(struct target *target, struct threads *t)
584 uint8_t *buffer = calloc(1, 4);
585 uint32_t next_addr = t->base_addr + NEXT;
586 int retval = fill_buffer(target, next_addr, buffer);
588 if (retval == ERROR_OK) {
589 uint32_t val = get_buffer(target, buffer);
590 val = val - NEXT;
591 free(buffer);
592 return val;
593 } else
594 LOG_ERROR("next task: unable to read memory");
596 free(buffer);
598 return 0;
601 struct current_thread *add_current_thread(struct current_thread *currents,
602 struct current_thread *ct)
604 ct->next = NULL;
606 if (currents == NULL) {
607 currents = ct;
608 return currents;
609 } else {
610 struct current_thread *temp = currents;
612 while (temp->next != NULL)
613 temp = temp->next;
615 temp->next = ct;
616 return currents;
620 struct threads *liste_del_task(struct threads *task_list, struct threads **t,
621 struct threads *prev)
623 LOG_INFO("del task %" PRId64, (*t)->threadid);
624 prev->next = (*t)->next;
626 if (prev == task_list)
627 task_list = prev;
629 /* free content of threads */
630 if ((*t)->context)
631 free((*t)->context);
633 free(*t);
634 *t = prev;
635 return task_list;
638 struct threads *liste_add_task(struct threads *task_list, struct threads *t,
639 struct threads **last)
641 t->next = NULL;
643 if (*last == NULL)
644 if (task_list == NULL) {
645 task_list = t;
646 return task_list;
647 } else {
648 struct threads *temp = task_list;
650 while (temp->next != NULL)
651 temp = temp->next;
653 temp->next = t;
654 *last = t;
655 return task_list;
656 } else {
657 (*last)->next = t;
658 *last = t;
659 return task_list;
663 #ifdef PID_CHECK
664 static int current_pid(struct linux_os *linux_os, uint32_t pid)
665 #else
666 static int current_base_addr(struct linux_os *linux_os, uint32_t base_addr)
667 #endif
669 struct current_thread *ct = linux_os->current_threads;
670 #ifdef PID_CHECK
672 while ((ct != NULL) && (ct->pid != pid))
673 #else
674 while ((ct != NULL) && (ct->TS != base_addr))
675 #endif
676 ct = ct->next;
677 #ifdef PID_CHECK
678 if ((ct != NULL) && (ct->pid == pid))
679 #else
680 if ((ct != NULL) && (ct->TS == base_addr))
681 #endif
682 return 1;
684 return 0;
687 int linux_get_tasks(struct target *target, int context)
689 int loop = 0;
690 int retval = 0;
691 struct linux_os *linux_os = (struct linux_os *)
692 target->rtos->rtos_specific_params;
693 linux_os->thread_list = NULL;
694 linux_os->thread_count = 0;
696 if (linux_os->init_task_addr == 0xdeadbeef) {
697 LOG_INFO("no init symbol\n");
698 return ERROR_FAIL;
701 int64_t start = timeval_ms();
703 struct threads *t = calloc(1, sizeof(struct threads));
704 struct threads *last = NULL;
705 t->base_addr = linux_os->init_task_addr;
706 /* retrieve the thread id , currently running in the different smp core */
707 get_current(target, 1);
709 while (((t->base_addr != linux_os->init_task_addr) &&
710 (t->base_addr != 0)) || (loop == 0)) {
711 loop++;
712 fill_task(target, t);
713 retval = get_name(target, t);
715 if (loop > MAX_THREADS) {
716 free(t);
717 LOG_INFO("more than %d threads !!", MAX_THREADS);
718 return ERROR_FAIL;
721 if (retval != ERROR_OK) {
722 free(t);
723 return ERROR_FAIL;
726 /* check that this thread is not one the current threads already
727 * created */
728 #ifdef PID_CHECK
730 if (!current_pid(linux_os, t->pid)) {
731 #else
732 if (!current_base_addr(linux_os, t->base_addr)) {
733 #endif
734 t->threadid = linux_os->threadid_count;
735 t->status = 1;
736 linux_os->threadid_count++;
738 linux_os->thread_list =
739 liste_add_task(linux_os->thread_list, t, &last);
740 /* no interest to fill the context if it is a current thread. */
741 linux_os->thread_count++;
742 t->thread_info_addr = 0xdeadbeef;
744 if (context)
745 t->context =
746 cpu_context_read(target, t->base_addr,
747 &t->thread_info_addr);
748 } else {
749 /*LOG_INFO("thread %s is a current thread already created",t->name); */
750 free(t);
753 uint32_t base_addr = next_task(target, t);
754 t = calloc(1, sizeof(struct threads));
755 t->base_addr = base_addr;
758 linux_os->threads_lookup = 1;
759 linux_os->threads_needs_update = 0;
760 linux_os->preupdtate_threadid_count = linux_os->threadid_count - 1;
761 /* check that all current threads have been identified */
763 LOG_INFO("complete time %" PRId64 ", thread mean %" PRId64 "\n",
764 (timeval_ms() - start),
765 (timeval_ms() - start) / linux_os->threadid_count);
767 LOG_INFO("threadid count %d", linux_os->threadid_count);
768 free(t);
770 return ERROR_OK;
773 static int clean_threadlist(struct target *target)
775 struct linux_os *linux_os = (struct linux_os *)
776 target->rtos->rtos_specific_params;
777 struct threads *old, *temp = linux_os->thread_list;
779 while (temp != NULL) {
780 old = temp;
782 if (temp->context)
783 free(temp->context);
785 temp = temp->next;
786 free(old);
789 return ERROR_OK;
792 static int linux_os_clean(struct target *target)
794 struct linux_os *os_linux = (struct linux_os *)
795 target->rtos->rtos_specific_params;
796 clean_threadlist(target);
797 os_linux->init_task_addr = 0xdeadbeef;
798 os_linux->name = "linux";
799 os_linux->thread_list = NULL;
800 os_linux->thread_count = 0;
801 os_linux->nr_cpus = 0;
802 os_linux->threads_lookup = 0;
803 os_linux->threads_needs_update = 0;
804 os_linux->threadid_count = 1;
805 return ERROR_OK;
808 static int insert_into_threadlist(struct target *target, struct threads *t)
810 struct linux_os *linux_os = (struct linux_os *)
811 target->rtos->rtos_specific_params;
812 struct threads *temp = linux_os->thread_list;
813 t->threadid = linux_os->threadid_count;
814 linux_os->threadid_count++;
815 t->status = 1;
816 t->next = NULL;
818 if (temp == NULL)
819 linux_os->thread_list = t;
820 else {
821 while (temp->next != NULL)
822 temp = temp->next;
824 t->next = NULL;
825 temp->next = t;
828 return ERROR_OK;
831 static void linux_identify_current_threads(struct target *target)
833 struct linux_os *linux_os = (struct linux_os *)
834 target->rtos->rtos_specific_params;
835 struct threads *thread_list = linux_os->thread_list;
836 struct current_thread *ct = linux_os->current_threads;
837 struct threads *t = NULL;
839 while ((ct != NULL)) {
840 if (ct->threadid == -1) {
842 /* un-identified thread */
843 int found = 0;
844 t = calloc(1, sizeof(struct threads));
845 t->base_addr = ct->TS;
846 #ifdef PID_CHECK
848 if (fill_task_pid(target, t) != ERROR_OK) {
849 error_handling:
850 free(t);
851 LOG_ERROR
852 ("linux identify_current_threads: unable to read pid");
853 return;
855 #endif
857 /* search in the list of threads if pid
858 already present */
859 while ((thread_list != NULL) && (found == 0)) {
860 #ifdef PID_CHECK
861 if (thread_list->pid == t->pid) {
862 #else
863 if (thread_list->base_addr == t->base_addr) {
864 #endif
865 free(t);
866 t = thread_list;
867 found = 1;
869 thread_list = thread_list->next;
872 if (!found) {
873 /* it is a new thread */
874 if (fill_task(target, t) != ERROR_OK)
875 goto error_handling;
877 get_name(target, t);
878 insert_into_threadlist(target, t);
879 t->thread_info_addr = 0xdeadbeef;
882 t->status = 3;
883 ct->threadid = t->threadid;
884 #ifdef PID_CHECK
885 ct->pid = t->pid;
886 #endif
887 linux_os->thread_count++;
888 #if 0
889 if (found == 0)
890 LOG_INFO("current thread core %x identified %s",
891 ct->core_id, t->name);
892 else
893 LOG_INFO("current thread core %x, reused %s",
894 ct->core_id, t->name);
895 #endif
897 #if 0
898 else {
899 struct threads tmp;
900 tmp.base_addr = ct->TS;
901 get_name(target, &tmp);
902 LOG_INFO("current thread core %x , already identified %s !!!",
903 ct->core_id, tmp.name);
905 #endif
906 ct = ct->next;
909 return;
910 #ifndef PID_CHECK
911 error_handling:
912 free(t);
913 LOG_ERROR("unable to read pid");
914 return;
916 #endif
919 static int linux_task_update(struct target *target, int context)
921 struct linux_os *linux_os = (struct linux_os *)
922 target->rtos->rtos_specific_params;
923 struct threads *thread_list = linux_os->thread_list;
924 int retval;
925 int loop = 0;
926 linux_os->thread_count = 0;
928 /*thread_list = thread_list->next; skip init_task*/
929 while (thread_list != NULL) {
930 thread_list->status = 0; /*setting all tasks to dead state*/
932 if (thread_list->context) {
933 free(thread_list->context);
934 thread_list->context = NULL;
937 thread_list = thread_list->next;
940 int found = 0;
942 if (linux_os->init_task_addr == 0xdeadbeef) {
943 LOG_INFO("no init symbol\n");
944 return ERROR_FAIL;
946 int64_t start = timeval_ms();
947 struct threads *t = calloc(1, sizeof(struct threads));
948 uint32_t previous = 0xdeadbeef;
949 t->base_addr = linux_os->init_task_addr;
950 retval = get_current(target, 0);
951 /*check that all current threads have been identified */
952 linux_identify_current_threads(target);
954 while (((t->base_addr != linux_os->init_task_addr) &&
955 (t->base_addr != previous)) || (loop == 0)) {
956 /* for avoiding any permanent loop for any reason possibly due to
957 * target */
958 loop++;
959 previous = t->base_addr;
960 /* read only pid */
961 #ifdef PID_CHECK
962 retval = fill_task_pid(target, t);
963 #endif
965 if (retval != ERROR_OK) {
966 free(t);
967 return ERROR_FAIL;
970 thread_list = linux_os->thread_list;
972 while (thread_list != NULL) {
973 #ifdef PID_CHECK
974 if (t->pid == thread_list->pid) {
975 #else
976 if (t->base_addr == thread_list->base_addr) {
977 #endif
978 if (!thread_list->status) {
979 #ifdef PID_CHECK
980 if (t->base_addr != thread_list->base_addr)
981 LOG_INFO("thread base_addr has changed !!");
982 #endif
983 /* this is not a current thread */
984 thread_list->base_addr = t->base_addr;
985 thread_list->status = 1;
987 /* we don 't update this field any more */
989 /*thread_list->state = t->state;
990 thread_list->oncpu = t->oncpu;
991 thread_list->asid = t->asid;
993 if (context)
994 thread_list->context =
995 cpu_context_read(target,
996 thread_list->
997 base_addr,
998 &thread_list->
999 thread_info_addr);
1000 } else {
1001 /* it is a current thread no need to read context */
1004 linux_os->thread_count++;
1005 found = 1;
1006 break;
1007 } else {
1008 found = 0;
1009 thread_list = thread_list->next;
1013 if (found == 0) {
1014 uint32_t base_addr;
1015 fill_task(target, t);
1016 get_name(target, t);
1017 retval = insert_into_threadlist(target, t);
1018 t->thread_info_addr = 0xdeadbeef;
1020 if (context)
1021 t->context =
1022 cpu_context_read(target, t->base_addr,
1023 &t->thread_info_addr);
1025 base_addr = next_task(target, t);
1026 t = calloc(1, sizeof(struct threads));
1027 t->base_addr = base_addr;
1028 linux_os->thread_count++;
1029 } else
1030 t->base_addr = next_task(target, t);
1033 LOG_INFO("update thread done %" PRId64 ", mean%" PRId64 "\n",
1034 (timeval_ms() - start), (timeval_ms() - start) / loop);
1035 free(t);
1036 linux_os->threads_needs_update = 0;
1037 return ERROR_OK;
1040 int linux_gdb_thread_packet(struct target *target,
1041 struct connection *connection, char const *packet,
1042 int packet_size)
1044 int retval;
1045 struct linux_os *linux_os =
1046 (struct linux_os *)target->rtos->rtos_specific_params;
1048 if (linux_os->init_task_addr == 0xdeadbeef) {
1049 /* it has not been initialized */
1050 LOG_INFO("received thread request without init task address");
1051 gdb_put_packet(connection, "l", 1);
1052 return ERROR_OK;
1055 retval = linux_get_tasks(target, 1);
1057 if (retval != ERROR_OK)
1058 return ERROR_TARGET_FAILURE;
1060 char *out_str = calloc(MAX_THREADS * 17 + 10, 1);
1061 char *tmp_str = out_str;
1062 tmp_str += sprintf(tmp_str, "m");
1063 struct threads *temp = linux_os->thread_list;
1065 while (temp != NULL) {
1066 tmp_str += sprintf(tmp_str, "%016" PRIx64, temp->threadid);
1067 temp = temp->next;
1068 if (temp)
1069 tmp_str += sprintf(tmp_str, ",");
1072 gdb_put_packet(connection, out_str, strlen(out_str));
1073 free(out_str);
1074 return ERROR_OK;
1077 int linux_gdb_thread_update(struct target *target,
1078 struct connection *connection, char const *packet,
1079 int packet_size)
1081 int found = 0;
1082 struct linux_os *linux_os = (struct linux_os *)
1083 target->rtos->rtos_specific_params;
1084 struct threads *temp = linux_os->thread_list;
1086 while (temp != NULL) {
1087 if (temp->threadid == linux_os->preupdtate_threadid_count + 1) {
1088 /*LOG_INFO("FOUND");*/
1089 found = 1;
1090 break;
1091 } else
1092 temp = temp->next;
1095 if (found == 1) {
1096 /*LOG_INFO("INTO GDB THREAD UPDATE FOUNDING START TASK");*/
1097 char *out_strr = calloc(MAX_THREADS * 17 + 10, 1);
1098 char *tmp_strr = out_strr;
1099 tmp_strr += sprintf(tmp_strr, "m");
1100 /*LOG_INFO("CHAR MALLOC & M DONE");*/
1101 tmp_strr += sprintf(tmp_strr, "%016" PRIx64, temp->threadid);
1103 temp = temp->next;
1105 while (temp != NULL) {
1106 /*LOG_INFO("INTO GDB THREAD UPDATE WHILE");*/
1107 tmp_strr += sprintf(tmp_strr, ",");
1108 tmp_strr +=
1109 sprintf(tmp_strr, "%016" PRIx64, temp->threadid);
1110 temp = temp->next;
1113 /*tmp_str[0] = 0;*/
1114 gdb_put_packet(connection, out_strr, strlen(out_strr));
1115 linux_os->preupdtate_threadid_count =
1116 linux_os->threadid_count - 1;
1117 free(out_strr);
1118 } else
1119 gdb_put_packet(connection, "l", 1);
1121 return ERROR_OK;
1124 int linux_thread_extra_info(struct target *target,
1125 struct connection *connection, char const *packet,
1126 int packet_size)
1128 int64_t threadid = 0;
1129 struct linux_os *linux_os = (struct linux_os *)
1130 target->rtos->rtos_specific_params;
1131 sscanf(packet, "qThreadExtraInfo,%" SCNx64, &threadid);
1132 /*LOG_INFO("lookup extra info for thread %" SCNx64, threadid);*/
1133 struct threads *temp = linux_os->thread_list;
1135 while (temp != NULL) {
1136 if (temp->threadid == threadid) {
1137 char *pid = " PID: ";
1138 char *pid_current = "*PID: ";
1139 char *name = "Name: ";
1140 int str_size = strlen(pid) + strlen(name);
1141 char *tmp_str = calloc(1, str_size + 50);
1142 char *tmp_str_ptr = tmp_str;
1144 /* discriminate current task */
1145 if (temp->status == 3)
1146 tmp_str_ptr += sprintf(tmp_str_ptr, "%s",
1147 pid_current);
1148 else
1149 tmp_str_ptr += sprintf(tmp_str_ptr, "%s", pid);
1151 tmp_str_ptr += sprintf(tmp_str_ptr, "%d, ", (int)temp->pid);
1152 sprintf(tmp_str_ptr, "%s", name);
1153 sprintf(tmp_str_ptr, "%s", temp->name);
1154 char *hex_str = calloc(1, strlen(tmp_str) * 2 + 1);
1155 size_t pkt_len = hexify(hex_str, (const uint8_t *)tmp_str,
1156 strlen(tmp_str), strlen(tmp_str) * 2 + 1);
1157 gdb_put_packet(connection, hex_str, pkt_len);
1158 free(hex_str);
1159 free(tmp_str);
1160 return ERROR_OK;
1163 temp = temp->next;
1166 LOG_INFO("thread not found");
1167 return ERROR_OK;
1170 int linux_gdb_T_packet(struct connection *connection,
1171 struct target *target, char const *packet, int packet_size)
1173 int64_t threadid;
1174 struct linux_os *linux_os = (struct linux_os *)
1175 target->rtos->rtos_specific_params;
1176 int retval = ERROR_OK;
1177 sscanf(packet, "T%" SCNx64, &threadid);
1179 if (linux_os->threads_needs_update == 0) {
1180 struct threads *temp = linux_os->thread_list;
1181 struct threads *prev = linux_os->thread_list;
1183 while (temp != NULL) {
1184 if (temp->threadid == threadid) {
1185 if (temp->status != 0) {
1186 gdb_put_packet(connection, "OK", 2);
1187 return ERROR_OK;
1188 } else {
1189 /* delete item in the list */
1190 linux_os->thread_list =
1191 liste_del_task(linux_os->
1192 thread_list, &temp,
1193 prev);
1194 linux_os->thread_count--;
1195 gdb_put_packet(connection, "E01", 3);
1196 return ERROR_OK;
1200 /* for deletion */
1201 prev = temp;
1202 temp = temp->next;
1205 LOG_INFO("gdb requested status on non existing thread");
1206 gdb_put_packet(connection, "E01", 3);
1207 return ERROR_OK;
1209 } else {
1210 retval = linux_task_update(target, 1);
1211 struct threads *temp = linux_os->thread_list;
1213 while (temp != NULL) {
1214 if (temp->threadid == threadid) {
1215 if (temp->status == 1) {
1216 gdb_put_packet(connection, "OK", 2);
1217 return ERROR_OK;
1218 } else {
1219 gdb_put_packet(connection, "E01", 3);
1220 return ERROR_OK;
1224 temp = temp->next;
1228 return retval;
1231 int linux_gdb_h_packet(struct connection *connection,
1232 struct target *target, char const *packet, int packet_size)
1234 struct linux_os *linux_os = (struct linux_os *)
1235 target->rtos->rtos_specific_params;
1236 struct current_thread *ct = linux_os->current_threads;
1238 /* select to display the current thread of the selected target */
1239 while ((ct != NULL) && (ct->core_id != target->coreid))
1240 ct = ct->next;
1242 int64_t current_gdb_thread_rq;
1244 if (linux_os->threads_lookup == 1) {
1245 if ((ct != NULL) && (ct->threadid == -1)) {
1246 ct = linux_os->current_threads;
1248 while ((ct != NULL) && (ct->threadid == -1))
1249 ct = ct->next;
1252 if (ct == NULL) {
1253 /* no current thread can be identified
1254 * any way with smp */
1255 LOG_INFO("no current thread identified");
1256 /* attempt to display the name of the 2 threads identified with
1257 * get_current */
1258 struct threads t;
1259 ct = linux_os->current_threads;
1261 while ((ct != NULL) && (ct->threadid == -1)) {
1262 t.base_addr = ct->TS;
1263 get_name(target, &t);
1264 LOG_INFO("name of unidentified thread %s",
1265 t.name);
1266 ct = ct->next;
1269 gdb_put_packet(connection, "OK", 2);
1270 return ERROR_OK;
1273 if (packet[1] == 'g') {
1274 sscanf(packet, "Hg%16" SCNx64, &current_gdb_thread_rq);
1276 if (current_gdb_thread_rq == 0) {
1277 target->rtos->current_threadid = ct->threadid;
1278 gdb_put_packet(connection, "OK", 2);
1279 } else {
1280 target->rtos->current_threadid =
1281 current_gdb_thread_rq;
1282 gdb_put_packet(connection, "OK", 2);
1284 } else if (packet[1] == 'c') {
1285 sscanf(packet, "Hc%16" SCNx64, &current_gdb_thread_rq);
1287 if ((current_gdb_thread_rq == 0) ||
1288 (current_gdb_thread_rq == ct->threadid)) {
1289 target->rtos->current_threadid = ct->threadid;
1290 gdb_put_packet(connection, "OK", 2);
1291 } else
1292 gdb_put_packet(connection, "E01", 3);
1294 } else
1295 gdb_put_packet(connection, "OK", 2);
1297 return ERROR_OK;
1300 static int linux_thread_packet(struct connection *connection, char const *packet,
1301 int packet_size)
1303 int retval = ERROR_OK;
1304 struct current_thread *ct;
1305 struct target *target = get_target_from_connection(connection);
1306 struct linux_os *linux_os = (struct linux_os *)
1307 target->rtos->rtos_specific_params;
1309 switch (packet[0]) {
1310 case 'T': /* Is thread alive?*/
1312 linux_gdb_T_packet(connection, target, packet, packet_size);
1313 break;
1314 case 'H': /* Set current thread */
1315 /* ( 'c' for step and continue, 'g' for all other operations )*/
1316 /*LOG_INFO(" H packet received '%s'", packet);*/
1317 linux_gdb_h_packet(connection, target, packet, packet_size);
1318 break;
1319 case 'q':
1321 if (strncmp(packet, "qSymbol", 7) == 0) {
1322 if (rtos_qsymbol(connection, packet, packet_size) == 1) {
1323 linux_compute_virt2phys(target,
1324 target->rtos->
1325 symbols[INIT_TASK].
1326 address);
1329 break;
1330 } else if (strncmp(packet, "qfThreadInfo", 12) == 0) {
1331 if (linux_os->thread_list == NULL) {
1332 retval = linux_gdb_thread_packet(target,
1333 connection,
1334 packet,
1335 packet_size);
1336 break;
1337 } else {
1338 retval = linux_gdb_thread_update(target,
1339 connection,
1340 packet,
1341 packet_size);
1342 break;
1344 } else if (strncmp(packet, "qsThreadInfo", 12) == 0) {
1345 gdb_put_packet(connection, "l", 1);
1346 break;
1347 } else if (strncmp(packet, "qThreadExtraInfo,", 17) == 0) {
1348 linux_thread_extra_info(target, connection, packet,
1349 packet_size);
1350 break;
1351 } else {
1352 retval = GDB_THREAD_PACKET_NOT_CONSUMED;
1353 break;
1356 case 'Q':
1357 /* previously response was : thread not found
1358 * gdb_put_packet(connection, "E01", 3); */
1359 retval = GDB_THREAD_PACKET_NOT_CONSUMED;
1360 break;
1361 case 'c':
1362 case 's': {
1363 if (linux_os->threads_lookup == 1) {
1364 ct = linux_os->current_threads;
1366 while ((ct != NULL) && (ct->core_id) != target->coreid)
1367 ct = ct->next;
1369 if ((ct != NULL) && (ct->threadid == -1)) {
1370 ct = linux_os->current_threads;
1372 while ((ct != NULL) && (ct->threadid == -1))
1373 ct = ct->next;
1376 if ((ct != NULL) && (ct->threadid !=
1377 target->rtos->
1378 current_threadid)
1379 && (target->rtos->current_threadid != -1))
1380 LOG_WARNING("WARNING! current GDB thread do not match" \
1381 "current thread running." \
1382 "Switch thread in GDB to threadid %d",
1383 (int)ct->threadid);
1385 LOG_INFO("threads_needs_update = 1");
1386 linux_os->threads_needs_update = 1;
1390 /* if a packet handler returned an error, exit input loop */
1391 if (retval != ERROR_OK)
1392 return retval;
1395 return retval;
1398 static int linux_os_smp_init(struct target *target)
1400 struct target_list *head;
1401 /* keep only target->rtos */
1402 struct rtos *rtos = target->rtos;
1403 struct linux_os *os_linux =
1404 (struct linux_os *)rtos->rtos_specific_params;
1405 struct current_thread *ct;
1406 head = target->head;
1408 while (head != (struct target_list *)NULL) {
1409 if (head->target->rtos != rtos) {
1410 struct linux_os *smp_os_linux =
1411 (struct linux_os *)head->target->rtos->
1412 rtos_specific_params;
1413 /* remap smp target on rtos */
1414 free(head->target->rtos);
1415 head->target->rtos = rtos;
1416 /* reuse allocated ct */
1417 ct = smp_os_linux->current_threads;
1418 ct->threadid = -1;
1419 ct->TS = 0xdeadbeef;
1420 ct->core_id = head->target->coreid;
1421 os_linux->current_threads =
1422 add_current_thread(os_linux->current_threads, ct);
1423 os_linux->nr_cpus++;
1424 free(smp_os_linux);
1427 head = head->next;
1430 return ERROR_OK;
1433 static int linux_os_create(struct target *target)
1435 struct linux_os *os_linux = calloc(1, sizeof(struct linux_os));
1436 struct current_thread *ct = calloc(1, sizeof(struct current_thread));
1437 LOG_INFO("linux os creation\n");
1438 os_linux->init_task_addr = 0xdeadbeef;
1439 os_linux->name = "linux";
1440 os_linux->thread_list = NULL;
1441 os_linux->thread_count = 0;
1442 target->rtos->current_threadid = -1;
1443 os_linux->nr_cpus = 1;
1444 os_linux->threads_lookup = 0;
1445 os_linux->threads_needs_update = 0;
1446 os_linux->threadid_count = 1;
1447 os_linux->current_threads = NULL;
1448 target->rtos->rtos_specific_params = os_linux;
1449 ct->core_id = target->coreid;
1450 ct->threadid = -1;
1451 ct->TS = 0xdeadbeef;
1452 os_linux->current_threads =
1453 add_current_thread(os_linux->current_threads, ct);
1454 /* overload rtos thread default handler */
1455 target->rtos->gdb_thread_packet = linux_thread_packet;
1456 /* initialize a default virt 2 phys translation */
1457 os_linux->phys_mask = ~0xc0000000;
1458 os_linux->phys_base = 0x0;
1459 return JIM_OK;
1462 static char *linux_ps_command(struct target *target)
1464 struct linux_os *linux_os = (struct linux_os *)
1465 target->rtos->rtos_specific_params;
1466 int retval = ERROR_OK;
1467 char *display;
1469 if (linux_os->threads_lookup == 0)
1470 retval = linux_get_tasks(target, 1);
1471 else {
1472 if (linux_os->threads_needs_update != 0)
1473 retval = linux_task_update(target, 0);
1476 if (retval == ERROR_OK) {
1477 struct threads *temp = linux_os->thread_list;
1478 char *tmp;
1479 LOG_INFO("allocation for %d threads line",
1480 linux_os->thread_count);
1481 display = calloc((linux_os->thread_count + 2) * 80, 1);
1483 if (!display)
1484 goto error;
1486 tmp = display;
1487 tmp += sprintf(tmp, "PID\t\tCPU\t\tASID\t\tNAME\n");
1488 tmp += sprintf(tmp, "---\t\t---\t\t----\t\t----\n");
1490 while (temp != NULL) {
1491 if (temp->status) {
1492 if (temp->context)
1493 tmp +=
1494 sprintf(tmp,
1495 "%" PRId32 "\t\t%" PRId32 "\t\t%" PRIx32 "\t\t%s\n",
1496 temp->pid, temp->oncpu,
1497 temp->asid, temp->name);
1498 else
1499 tmp +=
1500 sprintf(tmp,
1501 "%" PRId32 "\t\t%" PRId32 "\t\t%" PRIx32 "\t\t%s\n",
1502 temp->pid, temp->oncpu,
1503 temp->asid, temp->name);
1506 temp = temp->next;
1509 return display;
1512 error:
1513 display = calloc(40, 1);
1514 sprintf(display, "linux_ps_command failed\n");
1515 return display;