OpenOCD
linux.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 /***************************************************************************
4  * Copyright (C) 2011 by STEricsson *
5  * Heythem Bouhaja heythem.bouhaja@stericsson.com : creation *
6  * Michel JAOUEN michel.jaouen@stericsson.com : adaptation to rtos *
7  ***************************************************************************/
8 
9 #ifdef HAVE_CONFIG_H
10 #include "config.h"
11 #endif
12 
13 #include <helper/time_support.h>
14 #include <jtag/jtag.h>
15 #include "target/target.h"
16 #include "target/target_type.h"
17 #include "helper/log.h"
18 #include "helper/types.h"
19 #include "rtos.h"
21 #include <target/register.h>
22 #include <target/smp.h>
23 #include "server/gdb_server.h"
24 
25 #define LINUX_USER_KERNEL_BORDER 0xc0000000
26 #include "linux_header.h"
27 #define PHYS
28 #define MAX_THREADS 200
29 /* specific task */
30 struct linux_os {
31  const char *name;
32  uint32_t init_task_addr;
36  int nr_cpus;
41  /* virt2phys parameter */
42  uint32_t phys_mask;
43  uint32_t phys_base;
44 };
45 
47  int64_t threadid;
48  int32_t core_id;
49 #ifdef PID_CHECK
50  uint32_t pid;
51 #endif
52  uint32_t TS;
54 };
55 
56 struct threads {
57  char name[17];
58  uint32_t base_addr; /* address to read magic */
59  uint32_t state; /* magic value : filled only at creation */
60  uint32_t pid; /* linux pid : id for identifying a thread */
61  uint32_t oncpu; /* content cpu number in current thread */
62  uint32_t asid; /* filled only at creation */
63  int64_t threadid;
64  int status; /* dead = 1 alive = 2 current = 3 alive and current */
65  /* value that should not change during the live of a thread ? */
66  uint32_t thread_info_addr; /* contain latest thread_info_addr computed */
67  /* retrieve from thread_info */
69  struct threads *next;
70 };
71 
72 struct cpu_context {
73  uint32_t R4;
74  uint32_t R5;
75  uint32_t R6;
76  uint32_t R7;
77  uint32_t R8;
78  uint32_t R9;
79  uint32_t IP;
80  uint32_t FP;
81  uint32_t SP;
82  uint32_t PC;
83  uint32_t preempt_count;
84 };
85 static struct cpu_context *cpu_context_read(struct target *target, uint32_t base_addr,
86  uint32_t *info_addr);
87 static int insert_into_threadlist(struct target *target, struct threads *t);
88 
89 static int linux_os_create(struct target *target);
90 
91 static int linux_os_dummy_update(struct rtos *rtos)
92 {
93  /* update is done only when thread request come
94  * too many thread to do it on each stop */
95  return 0;
96 }
97 
99 {
100  struct linux_os *linux_os = (struct linux_os *)
102  target_addr_t pa = 0;
103  int retval = target->type->virt2phys(target, address, &pa);
104  if (retval != ERROR_OK) {
105  LOG_ERROR("Cannot compute linux virt2phys translation");
106  /* fixes default address */
107  linux_os->phys_base = 0;
108  return ERROR_FAIL;
109  }
110 
113  linux_os->phys_base = pa - address;
114  return ERROR_OK;
115 }
116 
117 static int linux_read_memory(struct target *target,
118  uint32_t address, uint32_t size, uint32_t count,
119  uint8_t *buffer)
120 {
121 #ifdef PHYS
122  struct linux_os *linux_os = (struct linux_os *)
124  uint32_t pa = (address & linux_os->phys_mask) + linux_os->phys_base;
125 #endif
126  if (address < 0xc0000000) {
127  LOG_ERROR("linux awareness : address in user space");
128  return ERROR_FAIL;
129  }
130 #ifdef PHYS
132 #endif
134  return ERROR_OK;
135 }
136 
137 static int fill_buffer(struct target *target, uint32_t addr, uint8_t *buffer)
138 {
139 
140  if ((addr & 0xfffffffc) != addr)
141  LOG_INFO("unaligned address %" PRIx32 "!!", addr);
142 
143  int retval = linux_read_memory(target, addr, 4, 1, buffer);
144  return retval;
145 
146 }
147 
148 static uint32_t get_buffer(struct target *target, const uint8_t *buffer)
149 {
150  uint32_t value = 0;
151  const uint8_t *value_ptr = buffer;
152  value = target_buffer_get_u32(target, value_ptr);
153  return value;
154 }
155 
156 static int linux_os_thread_reg_list(struct rtos *rtos,
157  int64_t thread_id, struct rtos_reg **reg_list, int *num_regs)
158 {
159  struct target *target = rtos->target;
160  struct linux_os *linux_os = (struct linux_os *)
162  struct current_thread *tmp = linux_os->current_threads;
163  struct current_thread *next;
164  int found = 0;
165  int retval;
166  /* check if a current thread is requested */
167  next = tmp;
168 
169  do {
170  if (next->threadid == thread_id)
171  found = 1;
172  else
173  next = next->next;
174  } while ((found == 0) && (next != tmp) && (next));
175 
176  if (found == 0) {
177  LOG_ERROR("could not find thread: %" PRIx64, thread_id);
178  return ERROR_FAIL;
179  }
180 
181  /* search target to perform the access */
182  struct reg **gdb_reg_list;
183  struct target_list *head;
184  found = 0;
186  if (head->target->coreid == next->core_id) {
187  target = head->target;
188  found = 1;
189  break;
190  }
191  }
192 
193  if (found == 0) {
194  LOG_ERROR
195  (
196  "current thread %" PRIx64 ": no target to perform access of core id %" PRIx32,
197  thread_id,
198  next->core_id);
199  return ERROR_FAIL;
200  }
201 
202  /*LOG_INFO("thread %lx current on core %x",thread_id, target->coreid);*/
203  retval = target_get_gdb_reg_list(target, &gdb_reg_list, num_regs, REG_CLASS_GENERAL);
204  if (retval != ERROR_OK)
205  return retval;
206 
207  *reg_list = calloc(*num_regs, sizeof(struct rtos_reg));
208 
209  for (int i = 0; i < *num_regs; ++i) {
210  if (!gdb_reg_list[i]->valid)
211  gdb_reg_list[i]->type->get(gdb_reg_list[i]);
212 
213  (*reg_list)[i].number = gdb_reg_list[i]->number;
214  (*reg_list)[i].size = gdb_reg_list[i]->size;
215 
216  buf_cpy(gdb_reg_list[i]->value, (*reg_list)[i].value, (*reg_list)[i].size);
217  }
218 
219  return ERROR_OK;
220 }
221 
222 static bool linux_os_detect(struct target *target)
223 {
224  LOG_INFO("should no be called");
225  return false;
226 }
227 
228 static int linux_os_smp_init(struct target *target);
229 static int linux_os_clean(struct target *target);
230 #define INIT_TASK 0
231 static const char * const linux_symbol_list[] = {
232  "init_task",
233  NULL
234 };
235 
236 static int linux_get_symbol_list_to_lookup(struct symbol_table_elem *symbol_list[])
237 {
238  unsigned int i;
239  *symbol_list = (struct symbol_table_elem *)
240  calloc(ARRAY_SIZE(linux_symbol_list), sizeof(struct symbol_table_elem));
241 
242  for (i = 0; i < ARRAY_SIZE(linux_symbol_list); i++)
243  (*symbol_list)[i].symbol_name = linux_symbol_list[i];
244 
245  return 0;
246 }
247 
248 static char *linux_ps_command(struct target *target);
249 
250 const struct rtos_type linux_rtos = {
251  .name = "linux",
252  .detect_rtos = linux_os_detect,
253  .create = linux_os_create,
254  .smp_init = linux_os_smp_init,
255  .update_threads = linux_os_dummy_update,
256  .get_thread_reg_list = linux_os_thread_reg_list,
257  .get_symbol_list_to_lookup = linux_get_symbol_list_to_lookup,
258  .clean = linux_os_clean,
259  .ps_command = linux_ps_command,
260 };
261 
262 static int linux_thread_packet(struct connection *connection, char const *packet,
263  int packet_size);
264 static void linux_identify_current_threads(struct target *target);
265 
266 #ifdef PID_CHECK
267 int fill_task_pid(struct target *target, struct threads *t)
268 {
269  uint32_t pid_addr = t->base_addr + PID;
270  uint8_t buffer[4];
271  int retval = fill_buffer(target, pid_addr, buffer);
272 
273  if (retval == ERROR_OK) {
274  uint32_t val = get_buffer(target, buffer);
275  t->pid = val;
276  } else
277  LOG_ERROR("fill_task_pid: unable to read memory");
278 
279  return retval;
280 }
281 #endif
282 
283 static int fill_task(struct target *target, struct threads *t)
284 {
285  int retval;
286  uint32_t pid_addr = t->base_addr + PID;
287  uint32_t mem_addr = t->base_addr + MEM;
288  uint32_t on_cpu = t->base_addr + ONCPU;
289  uint8_t *buffer = calloc(1, 4);
290  retval = fill_buffer(target, t->base_addr, buffer);
291 
292  if (retval == ERROR_OK) {
293  uint32_t val = get_buffer(target, buffer);
294  t->state = val;
295  } else
296  LOG_ERROR("fill_task: unable to read memory");
297 
298  retval = fill_buffer(target, pid_addr, buffer);
299 
300  if (retval == ERROR_OK) {
301  uint32_t val = get_buffer(target, buffer);
302  t->pid = val;
303  } else
304  LOG_ERROR("fill task: unable to read memory");
305 
306  retval = fill_buffer(target, on_cpu, buffer);
307 
308  if (retval == ERROR_OK) {
309  uint32_t val = get_buffer(target, buffer);
310  t->oncpu = val;
311  } else
312  LOG_ERROR("fill task: unable to read memory");
313 
314  retval = fill_buffer(target, mem_addr, buffer);
315 
316  if (retval == ERROR_OK) {
317  uint32_t val = get_buffer(target, buffer);
318 
319  if (val != 0) {
320  uint32_t asid_addr = val + MM_CTX;
321  retval = fill_buffer(target, asid_addr, buffer);
322 
323  if (retval == ERROR_OK) {
324  val = get_buffer(target, buffer);
325  t->asid = val;
326  } else
327  LOG_ERROR
328  ("fill task: unable to read memory -- ASID");
329  } else
330  t->asid = 0;
331  } else
332  LOG_ERROR("fill task: unable to read memory");
333 
334  free(buffer);
335 
336  return retval;
337 }
338 
339 static int get_name(struct target *target, struct threads *t)
340 {
341  int retval;
342  uint32_t full_name[4];
343  uint32_t comm = t->base_addr + COMM;
344  int i;
345 
346  for (i = 0; i < 17; i++)
347  t->name[i] = 0;
348 
349  retval = linux_read_memory(target, comm, 4, 4, (uint8_t *) full_name);
350 
351  if (retval != ERROR_OK) {
352  LOG_ERROR("get_name: unable to read memory\n");
353  return ERROR_FAIL;
354  }
355 
356  uint32_t raw_name = target_buffer_get_u32(target,
357  (const uint8_t *)
358  &full_name[0]);
359  t->name[3] = raw_name >> 24;
360  t->name[2] = raw_name >> 16;
361  t->name[1] = raw_name >> 8;
362  t->name[0] = raw_name;
363  raw_name =
364  target_buffer_get_u32(target, (const uint8_t *)&full_name[1]);
365  t->name[7] = raw_name >> 24;
366  t->name[6] = raw_name >> 16;
367  t->name[5] = raw_name >> 8;
368  t->name[4] = raw_name;
369  raw_name =
370  target_buffer_get_u32(target, (const uint8_t *)&full_name[2]);
371  t->name[11] = raw_name >> 24;
372  t->name[10] = raw_name >> 16;
373  t->name[9] = raw_name >> 8;
374  t->name[8] = raw_name;
375  raw_name =
376  target_buffer_get_u32(target, (const uint8_t *)&full_name[3]);
377  t->name[15] = raw_name >> 24;
378  t->name[14] = raw_name >> 16;
379  t->name[13] = raw_name >> 8;
380  t->name[12] = raw_name;
381  return ERROR_OK;
382 
383 }
384 
385 static int get_current(struct target *target, int create)
386 {
387  struct target_list *head;
388  uint8_t *buf;
389  uint32_t val;
390  uint32_t ti_addr;
391  uint8_t *buffer = calloc(1, 4);
392  struct linux_os *linux_os = (struct linux_os *)
394  struct current_thread *ctt = linux_os->current_threads;
395 
396  /* invalid current threads content */
397  while (ctt) {
398  ctt->threadid = -1;
399  ctt->TS = 0xdeadbeef;
400  ctt = ctt->next;
401  }
402 
404  struct reg **reg_list;
405  int reg_list_size;
406  int retval;
407 
408  if (target_get_gdb_reg_list(head->target, &reg_list,
409  &reg_list_size, REG_CLASS_GENERAL) != ERROR_OK) {
410  free(buffer);
411  return ERROR_TARGET_FAILURE;
412  }
413 
414  if (!reg_list[13]->valid)
415  reg_list[13]->type->get(reg_list[13]);
416 
417  buf = reg_list[13]->value;
418  val = get_buffer(target, buf);
419  ti_addr = (val & 0xffffe000);
420  uint32_t ts_addr = ti_addr + 0xc;
421  retval = fill_buffer(target, ts_addr, buffer);
422 
423  if (retval == ERROR_OK) {
424  uint32_t TS = get_buffer(target, buffer);
425  uint32_t cpu, on_cpu = TS + ONCPU;
426  retval = fill_buffer(target, on_cpu, buffer);
427 
428  if (retval == ERROR_OK) {
429  /*uint32_t cpu = get_buffer(target, buffer);*/
430  struct current_thread *ct =
432  cpu = head->target->coreid;
433 
434  while ((ct) && (ct->core_id != (int32_t) cpu))
435  ct = ct->next;
436 
437  if ((ct) && (ct->TS == 0xdeadbeef))
438  ct->TS = TS;
439  else
440  LOG_ERROR
441  ("error in linux current thread update");
442 
443  if (create && ct) {
444  struct threads *t;
445  t = calloc(1, sizeof(struct threads));
446  t->base_addr = ct->TS;
447  fill_task(target, t);
448  get_name(target, t);
449  t->oncpu = cpu;
451  t->status = 3;
452  t->thread_info_addr = 0xdeadbeef;
453  ct->threadid = t->threadid;
455 #ifdef PID_CHECK
456  ct->pid = t->pid;
457 #endif
458  /*LOG_INFO("Creation of current thread %s",t->name);*/
459  }
460  }
461  }
462 
463  free(reg_list);
464  }
465 
466  free(buffer);
467 
468  return ERROR_OK;
469 }
470 
471 static struct cpu_context *cpu_context_read(struct target *target, uint32_t base_addr,
472  uint32_t *thread_info_addr_old)
473 {
474  struct cpu_context *context = calloc(1, sizeof(struct cpu_context));
475  uint32_t preempt_count_addr = 0;
476  uint32_t registers[10];
477  uint8_t *buffer = calloc(1, 4);
478  uint32_t stack = base_addr + QAT;
479  uint32_t thread_info_addr = 0;
480  uint32_t thread_info_addr_update = 0;
481  int retval = ERROR_FAIL;
482  context->R4 = 0xdeadbeef;
483  context->R5 = 0xdeadbeef;
484  context->R6 = 0xdeadbeef;
485  context->R7 = 0xdeadbeef;
486  context->R8 = 0xdeadbeef;
487  context->R9 = 0xdeadbeef;
488  context->IP = 0xdeadbeef;
489  context->FP = 0xdeadbeef;
490  context->SP = 0xdeadbeef;
491  context->PC = 0xdeadbeef;
492 retry:
493 
494  if (*thread_info_addr_old == 0xdeadbeef) {
495  retval = fill_buffer(target, stack, buffer);
496 
497  if (retval == ERROR_OK)
498  thread_info_addr = get_buffer(target, buffer);
499  else
500  LOG_ERROR("cpu_context: unable to read memory");
501 
502  thread_info_addr_update = thread_info_addr;
503  } else
504  thread_info_addr = *thread_info_addr_old;
505 
506  preempt_count_addr = thread_info_addr + PREEMPT;
507  retval = fill_buffer(target, preempt_count_addr, buffer);
508 
509  if (retval == ERROR_OK)
510  context->preempt_count = get_buffer(target, buffer);
511  else {
512  if (*thread_info_addr_old != 0xdeadbeef) {
513  LOG_ERROR
514  ("cpu_context: cannot read at thread_info_addr");
515 
516  if (*thread_info_addr_old < LINUX_USER_KERNEL_BORDER)
517  LOG_INFO
518  ("cpu_context : thread_info_addr in userspace!!!");
519 
520  *thread_info_addr_old = 0xdeadbeef;
521  goto retry;
522  }
523 
524  LOG_ERROR("cpu_context: unable to read memory");
525  }
526 
527  thread_info_addr += CPU_CONT;
528 
529  retval = linux_read_memory(target, thread_info_addr, 4, 10,
530  (uint8_t *) registers);
531 
532  if (retval != ERROR_OK) {
533  free(buffer);
534  LOG_ERROR("cpu_context: unable to read memory\n");
535  return context;
536  }
537 
538  context->R4 =
539  target_buffer_get_u32(target, (const uint8_t *)&registers[0]);
540  context->R5 =
541  target_buffer_get_u32(target, (const uint8_t *)&registers[1]);
542  context->R6 =
543  target_buffer_get_u32(target, (const uint8_t *)&registers[2]);
544  context->R7 =
545  target_buffer_get_u32(target, (const uint8_t *)&registers[3]);
546  context->R8 =
547  target_buffer_get_u32(target, (const uint8_t *)&registers[4]);
548  context->R9 =
549  target_buffer_get_u32(target, (const uint8_t *)&registers[5]);
550  context->IP =
551  target_buffer_get_u32(target, (const uint8_t *)&registers[6]);
552  context->FP =
553  target_buffer_get_u32(target, (const uint8_t *)&registers[7]);
554  context->SP =
555  target_buffer_get_u32(target, (const uint8_t *)&registers[8]);
556  context->PC =
557  target_buffer_get_u32(target, (const uint8_t *)&registers[9]);
558 
559  if (*thread_info_addr_old == 0xdeadbeef)
560  *thread_info_addr_old = thread_info_addr_update;
561 
562  free(buffer);
563 
564  return context;
565 }
566 
567 static uint32_t next_task(struct target *target, struct threads *t)
568 {
569  uint8_t *buffer = calloc(1, 4);
570  uint32_t next_addr = t->base_addr + NEXT;
571  int retval = fill_buffer(target, next_addr, buffer);
572 
573  if (retval == ERROR_OK) {
574  uint32_t val = get_buffer(target, buffer);
575  val = val - NEXT;
576  free(buffer);
577  return val;
578  } else
579  LOG_ERROR("next task: unable to read memory");
580 
581  free(buffer);
582 
583  return 0;
584 }
585 
586 static struct current_thread *add_current_thread(struct current_thread *currents,
587  struct current_thread *ct)
588 {
589  ct->next = NULL;
590 
591  if (!currents) {
592  currents = ct;
593  return currents;
594  } else {
595  struct current_thread *temp = currents;
596 
597  while (temp->next)
598  temp = temp->next;
599 
600  temp->next = ct;
601  return currents;
602  }
603 }
604 
605 static struct threads *liste_del_task(struct threads *task_list, struct threads **t,
606  struct threads *prev)
607 {
608  LOG_INFO("del task %" PRId64, (*t)->threadid);
609  if (prev)
610  prev->next = (*t)->next;
611  else
612  task_list = (*t)->next;
613 
614  /* free content of threads */
615  free((*t)->context);
616 
617  free(*t);
618  *t = prev ? prev : task_list;
619  return task_list;
620 }
621 
622 static struct threads *liste_add_task(struct threads *task_list, struct threads *t,
623  struct threads **last)
624 {
625  t->next = NULL;
626 
627  if (!*last) {
628  if (!task_list) {
629  task_list = t;
630  return task_list;
631  } else {
632  struct threads *temp = task_list;
633 
634  while (temp->next)
635  temp = temp->next;
636 
637  temp->next = t;
638  *last = t;
639  return task_list;
640  }
641  } else {
642  (*last)->next = t;
643  *last = t;
644  return task_list;
645  }
646 }
647 
648 #ifdef PID_CHECK
649 static int current_pid(struct linux_os *linux_os, uint32_t pid)
650 #else
651 static int current_base_addr(struct linux_os *linux_os, uint32_t base_addr)
652 #endif
653 {
655 #ifdef PID_CHECK
656 
657  while ((ct) && (ct->pid != pid))
658 #else
659  while ((ct) && (ct->TS != base_addr))
660 #endif
661  ct = ct->next;
662 #ifdef PID_CHECK
663  if ((ct) && (ct->pid == pid))
664 #else
665  if ((ct) && (ct->TS == base_addr))
666 #endif
667  return 1;
668 
669  return 0;
670 }
671 
672 static int linux_get_tasks(struct target *target, int context)
673 {
674  int loop = 0;
675  int retval = 0;
676  struct linux_os *linux_os = (struct linux_os *)
679  linux_os->thread_count = 0;
680 
681  if (linux_os->init_task_addr == 0xdeadbeef) {
682  LOG_INFO("no init symbol\n");
683  return ERROR_FAIL;
684  }
685 
686  int64_t start = timeval_ms();
687 
688  struct threads *t = calloc(1, sizeof(struct threads));
689  struct threads *last = NULL;
691  /* retrieve the thread id , currently running in the different smp core */
692  get_current(target, 1);
693 
694  while (((t->base_addr != linux_os->init_task_addr) &&
695  (t->base_addr != 0)) || (loop == 0)) {
696  loop++;
697  fill_task(target, t);
698  retval = get_name(target, t);
699 
700  if (loop > MAX_THREADS) {
701  free(t);
702  LOG_INFO("more than %d threads !!", MAX_THREADS);
703  return ERROR_FAIL;
704  }
705 
706  if (retval != ERROR_OK) {
707  free(t);
708  return ERROR_FAIL;
709  }
710 
711  /* check that this thread is not one the current threads already
712  * created */
713  uint32_t base_addr;
714 #ifdef PID_CHECK
715 
716  if (!current_pid(linux_os, t->pid)) {
717 #else
719 #endif
721  t->status = 1;
723 
725  liste_add_task(linux_os->thread_list, t, &last);
726  /* no interest to fill the context if it is a current thread. */
728  t->thread_info_addr = 0xdeadbeef;
729 
730  if (context)
731  t->context =
733  &t->thread_info_addr);
734  base_addr = next_task(target, t);
735  } else {
736  /*LOG_INFO("thread %s is a current thread already created",t->name); */
737  base_addr = next_task(target, t);
738  free(t);
739  }
740 
741  t = calloc(1, sizeof(struct threads));
742  t->base_addr = base_addr;
743  }
744 
748  /* check that all current threads have been identified */
749 
750  LOG_INFO("complete time %" PRId64 ", thread mean %" PRId64 "\n",
751  (timeval_ms() - start),
753 
754  LOG_INFO("threadid count %d", linux_os->threadid_count);
755  free(t);
756 
757  return ERROR_OK;
758 }
759 
760 static int clean_threadlist(struct target *target)
761 {
762  struct linux_os *linux_os = (struct linux_os *)
764  struct threads *old, *temp = linux_os->thread_list;
765 
766  while (temp) {
767  old = temp;
768 
769  free(temp->context);
770 
771  temp = temp->next;
772  free(old);
773  }
774 
775  return ERROR_OK;
776 }
777 
778 static int linux_os_clean(struct target *target)
779 {
780  struct linux_os *os_linux = (struct linux_os *)
783  os_linux->init_task_addr = 0xdeadbeef;
784  os_linux->name = "linux";
785  os_linux->thread_list = NULL;
786  os_linux->thread_count = 0;
787  os_linux->nr_cpus = 0;
788  os_linux->threads_lookup = 0;
789  os_linux->threads_needs_update = 0;
790  os_linux->threadid_count = 1;
791  return ERROR_OK;
792 }
793 
794 static int insert_into_threadlist(struct target *target, struct threads *t)
795 {
796  struct linux_os *linux_os = (struct linux_os *)
798  struct threads *temp = linux_os->thread_list;
801  t->status = 1;
802  t->next = NULL;
803 
804  if (!temp)
805  linux_os->thread_list = t;
806  else {
807  while (temp->next)
808  temp = temp->next;
809 
810  t->next = NULL;
811  temp->next = t;
812  }
813 
814  return ERROR_OK;
815 }
816 
818 {
819  struct linux_os *linux_os = (struct linux_os *)
823  struct threads *t = NULL;
824 
825  while ((ct)) {
826  if (ct->threadid == -1) {
827 
828  /* un-identified thread */
829  int found = 0;
830  t = calloc(1, sizeof(struct threads));
831  t->base_addr = ct->TS;
832 #ifdef PID_CHECK
833 
834  if (fill_task_pid(target, t) != ERROR_OK) {
835 error_handling:
836  free(t);
837  LOG_ERROR
838  ("linux identify_current_threads: unable to read pid");
839  return;
840  }
841 #endif
842 
843  /* search in the list of threads if pid
844  already present */
845  while ((thread_list) && (found == 0)) {
846 #ifdef PID_CHECK
847  if (thread_list->pid == t->pid) {
848 #else
849  if (thread_list->base_addr == t->base_addr) {
850 #endif
851  free(t);
852  t = thread_list;
853  found = 1;
854  }
856  }
857 
858  if (!found) {
859  /* it is a new thread */
860  if (fill_task(target, t) != ERROR_OK)
861  goto error_handling;
862 
863  get_name(target, t);
865  t->thread_info_addr = 0xdeadbeef;
866  }
867 
868  t->status = 3;
869  ct->threadid = t->threadid;
870 #ifdef PID_CHECK
871  ct->pid = t->pid;
872 #endif
874 #if 0
875  if (found == 0)
876  LOG_INFO("current thread core %x identified %s",
877  ct->core_id, t->name);
878  else
879  LOG_INFO("current thread core %x, reused %s",
880  ct->core_id, t->name);
881 #endif
882  }
883 #if 0
884  else {
885  struct threads tmp;
886  tmp.base_addr = ct->TS;
887  get_name(target, &tmp);
888  LOG_INFO("current thread core %x , already identified %s !!!",
889  ct->core_id, tmp.name);
890  }
891 #endif
892  ct = ct->next;
893  }
894 
895  return;
896 #ifndef PID_CHECK
897 error_handling:
898  free(t);
899  LOG_ERROR("unable to read pid");
900  return;
901 
902 #endif
903 }
904 
905 static int linux_task_update(struct target *target, int context)
906 {
907  struct linux_os *linux_os = (struct linux_os *)
910  int retval;
911  int loop = 0;
912  linux_os->thread_count = 0;
913 
914  /*thread_list = thread_list->next; skip init_task*/
915  while (thread_list) {
916  thread_list->status = 0; /*setting all tasks to dead state*/
917 
918  free(thread_list->context);
920 
922  }
923 
924  int found = 0;
925 
926  if (linux_os->init_task_addr == 0xdeadbeef) {
927  LOG_INFO("no init symbol\n");
928  return ERROR_FAIL;
929  }
930  int64_t start = timeval_ms();
931  struct threads *t = calloc(1, sizeof(struct threads));
932  uint32_t previous = 0xdeadbeef;
934  retval = get_current(target, 0);
935  /*check that all current threads have been identified */
937 
938  while (((t->base_addr != linux_os->init_task_addr) &&
939  (t->base_addr != previous)) || (loop == 0)) {
940  /* for avoiding any permanent loop for any reason possibly due to
941  * target */
942  loop++;
943  previous = t->base_addr;
944  /* read only pid */
945 #ifdef PID_CHECK
946  retval = fill_task_pid(target, t);
947 #endif
948 
949  if (retval != ERROR_OK) {
950  free(t);
951  return ERROR_FAIL;
952  }
953 
954  thread_list = linux_os->thread_list;
955 
956  while (thread_list) {
957 #ifdef PID_CHECK
958  if (t->pid == thread_list->pid) {
959 #else
960  if (t->base_addr == thread_list->base_addr) {
961 #endif
962  if (!thread_list->status) {
963 #ifdef PID_CHECK
964  if (t->base_addr != thread_list->base_addr)
965  LOG_INFO("thread base_addr has changed !!");
966 #endif
967  /* this is not a current thread */
968  thread_list->base_addr = t->base_addr;
969  thread_list->status = 1;
970 
971  /* we don 't update this field any more */
972 
973  /*thread_list->state = t->state;
974  thread_list->oncpu = t->oncpu;
975  thread_list->asid = t->asid;
976  */
977  if (context)
978  thread_list->context =
980  thread_list->base_addr,
981  &thread_list->thread_info_addr);
982  } else {
983  /* it is a current thread no need to read context */
984  }
985 
987  found = 1;
988  break;
989  } else {
990  found = 0;
991  thread_list = thread_list->next;
992  }
993  }
994 
995  if (found == 0) {
996  uint32_t base_addr;
997  fill_task(target, t);
998  get_name(target, t);
999  retval = insert_into_threadlist(target, t);
1000  t->thread_info_addr = 0xdeadbeef;
1001 
1002  if (context)
1003  t->context =
1005  &t->thread_info_addr);
1006 
1007  base_addr = next_task(target, t);
1008  t = calloc(1, sizeof(struct threads));
1009  t->base_addr = base_addr;
1011  } else
1012  t->base_addr = next_task(target, t);
1013  }
1014 
1015  LOG_INFO("update thread done %" PRId64 ", mean%" PRId64 "\n",
1016  (timeval_ms() - start), (timeval_ms() - start) / loop);
1017  free(t);
1019  return ERROR_OK;
1020 }
1021 
1023  struct connection *connection, char const *packet,
1024  int packet_size)
1025 {
1026  int retval;
1027  struct linux_os *linux_os =
1029 
1030  if (linux_os->init_task_addr == 0xdeadbeef) {
1031  /* it has not been initialized */
1032  LOG_INFO("received thread request without init task address");
1033  gdb_put_packet(connection, "l", 1);
1034  return ERROR_OK;
1035  }
1036 
1037  retval = linux_get_tasks(target, 1);
1038 
1039  if (retval != ERROR_OK)
1040  return ERROR_TARGET_FAILURE;
1041 
1042  char *out_str = calloc(MAX_THREADS * 17 + 10, 1);
1043  if (!out_str) {
1044  LOG_ERROR("Out of memory");
1045  return ERROR_FAIL;
1046  }
1047  char *tmp_str = out_str;
1048  tmp_str += sprintf(tmp_str, "m");
1049  struct threads *temp = linux_os->thread_list;
1050 
1051  while (temp) {
1052  tmp_str += sprintf(tmp_str, "%016" PRIx64, temp->threadid);
1053  temp = temp->next;
1054  if (temp)
1055  tmp_str += sprintf(tmp_str, ",");
1056  }
1057 
1058  gdb_put_packet(connection, out_str, strlen(out_str));
1059  free(out_str);
1060  return ERROR_OK;
1061 }
1062 
1064  struct connection *connection, char const *packet,
1065  int packet_size)
1066 {
1067  int found = 0;
1068  struct linux_os *linux_os = (struct linux_os *)
1070  struct threads *temp = linux_os->thread_list;
1071 
1072  while (temp) {
1073  if (temp->threadid == linux_os->preupdtate_threadid_count + 1) {
1074  /*LOG_INFO("FOUND");*/
1075  found = 1;
1076  break;
1077  } else
1078  temp = temp->next;
1079  }
1080 
1081  if (found == 1) {
1082  /*LOG_INFO("INTO GDB THREAD UPDATE FOUNDING START TASK");*/
1083  char *out_strr = calloc(MAX_THREADS * 17 + 10, 1);
1084  char *tmp_strr = out_strr;
1085  tmp_strr += sprintf(tmp_strr, "m");
1086  /*LOG_INFO("CHAR MALLOC & M DONE");*/
1087  tmp_strr += sprintf(tmp_strr, "%016" PRIx64, temp->threadid);
1088 
1089  temp = temp->next;
1090 
1091  while (temp) {
1092  /*LOG_INFO("INTO GDB THREAD UPDATE WHILE");*/
1093  tmp_strr += sprintf(tmp_strr, ",");
1094  tmp_strr +=
1095  sprintf(tmp_strr, "%016" PRIx64, temp->threadid);
1096  temp = temp->next;
1097  }
1098 
1099  /*tmp_str[0] = 0;*/
1100  gdb_put_packet(connection, out_strr, strlen(out_strr));
1102  linux_os->threadid_count - 1;
1103  free(out_strr);
1104  } else
1105  gdb_put_packet(connection, "l", 1);
1106 
1107  return ERROR_OK;
1108 }
1109 
1111  struct connection *connection, char const *packet,
1112  int packet_size)
1113 {
1114  int64_t threadid = 0;
1115  struct linux_os *linux_os = (struct linux_os *)
1117  sscanf(packet, "qThreadExtraInfo,%" SCNx64, &threadid);
1118  /*LOG_INFO("lookup extra info for thread %" SCNx64, threadid);*/
1119  struct threads *temp = linux_os->thread_list;
1120 
1121  while (temp) {
1122  if (temp->threadid == threadid) {
1123  char *tmp_str = alloc_printf("%cPID: %" PRIu32 ", Name: %s",
1124  temp->status == 3 ? '*' : ' ',
1125  temp->pid, temp->name);
1126  if (!tmp_str) {
1127  LOG_ERROR("Out of memory");
1128  return ERROR_FAIL;
1129  }
1130  char *hex_str = calloc(1, strlen(tmp_str) * 2 + 1);
1131  size_t pkt_len = hexify(hex_str, (const uint8_t *)tmp_str,
1132  strlen(tmp_str), strlen(tmp_str) * 2 + 1);
1133  gdb_put_packet(connection, hex_str, pkt_len);
1134  free(hex_str);
1135  free(tmp_str);
1136  return ERROR_OK;
1137  }
1138 
1139  temp = temp->next;
1140  }
1141 
1142  LOG_INFO("thread not found");
1143  return ERROR_OK;
1144 }
1145 
1147  struct target *target, char const *packet, int packet_size)
1148 {
1149  int64_t threadid;
1150  struct linux_os *linux_os = (struct linux_os *)
1152  int retval = ERROR_OK;
1153  sscanf(packet, "T%" SCNx64, &threadid);
1154 
1155  if (linux_os->threads_needs_update == 0) {
1156  struct threads *temp = linux_os->thread_list;
1157  struct threads *prev = NULL;
1158 
1159  while (temp) {
1160  if (temp->threadid == threadid) {
1161  if (temp->status != 0) {
1162  gdb_put_packet(connection, "OK", 2);
1163  return ERROR_OK;
1164  } else {
1165  /* delete item in the list */
1168  &temp, prev);
1170  gdb_put_packet(connection, "E01", 3);
1171  return ERROR_OK;
1172  }
1173  }
1174 
1175  /* for deletion */
1176  prev = temp;
1177  temp = temp->next;
1178  }
1179 
1180  LOG_INFO("gdb requested status on non existing thread");
1181  gdb_put_packet(connection, "E01", 3);
1182  return ERROR_OK;
1183 
1184  } else {
1185  retval = linux_task_update(target, 1);
1186  struct threads *temp = linux_os->thread_list;
1187 
1188  while (temp) {
1189  if (temp->threadid == threadid) {
1190  if (temp->status == 1) {
1191  gdb_put_packet(connection, "OK", 2);
1192  return ERROR_OK;
1193  } else {
1194  gdb_put_packet(connection, "E01", 3);
1195  return ERROR_OK;
1196  }
1197  }
1198 
1199  temp = temp->next;
1200  }
1201  }
1202 
1203  return retval;
1204 }
1205 
1207  struct target *target, char const *packet, int packet_size)
1208 {
1209  struct linux_os *linux_os = (struct linux_os *)
1211  struct current_thread *ct = linux_os->current_threads;
1212 
1213  /* select to display the current thread of the selected target */
1214  while ((ct) && (ct->core_id != target->coreid))
1215  ct = ct->next;
1216 
1217  int64_t current_gdb_thread_rq;
1218 
1219  if (linux_os->threads_lookup == 1) {
1220  if ((ct) && (ct->threadid == -1)) {
1221  ct = linux_os->current_threads;
1222 
1223  while ((ct) && (ct->threadid == -1))
1224  ct = ct->next;
1225  }
1226 
1227  if (!ct) {
1228  /* no current thread can be identified
1229  * any way with smp */
1230  LOG_INFO("no current thread identified");
1231  /* attempt to display the name of the 2 threads identified with
1232  * get_current */
1233  struct threads t;
1234  ct = linux_os->current_threads;
1235 
1236  while ((ct) && (ct->threadid == -1)) {
1237  t.base_addr = ct->TS;
1238  get_name(target, &t);
1239  LOG_INFO("name of unidentified thread %s",
1240  t.name);
1241  ct = ct->next;
1242  }
1243 
1244  gdb_put_packet(connection, "OK", 2);
1245  return ERROR_OK;
1246  }
1247 
1248  if (packet[1] == 'g') {
1249  sscanf(packet, "Hg%16" SCNx64, &current_gdb_thread_rq);
1250 
1251  if (current_gdb_thread_rq == 0) {
1252  target->rtos->current_threadid = ct->threadid;
1253  gdb_put_packet(connection, "OK", 2);
1254  } else {
1256  current_gdb_thread_rq;
1257  gdb_put_packet(connection, "OK", 2);
1258  }
1259  } else if (packet[1] == 'c') {
1260  sscanf(packet, "Hc%16" SCNx64, &current_gdb_thread_rq);
1261 
1262  if ((current_gdb_thread_rq == 0) ||
1263  (current_gdb_thread_rq == ct->threadid)) {
1264  target->rtos->current_threadid = ct->threadid;
1265  gdb_put_packet(connection, "OK", 2);
1266  } else
1267  gdb_put_packet(connection, "E01", 3);
1268  }
1269  } else
1270  gdb_put_packet(connection, "OK", 2);
1271 
1272  return ERROR_OK;
1273 }
1274 
1275 static int linux_thread_packet(struct connection *connection, char const *packet,
1276  int packet_size)
1277 {
1278  int retval = ERROR_OK;
1279  struct current_thread *ct;
1281  struct linux_os *linux_os = (struct linux_os *)
1283 
1284  switch (packet[0]) {
1285  case 'T': /* Is thread alive?*/
1286 
1287  linux_gdb_t_packet(connection, target, packet, packet_size);
1288  break;
1289  case 'H': /* Set current thread */
1290  /* ( 'c' for step and continue, 'g' for all other operations )*/
1291  /*LOG_INFO(" H packet received '%s'", packet);*/
1292  linux_gdb_h_packet(connection, target, packet, packet_size);
1293  break;
1294  case 'q':
1295 
1296  if (strncmp(packet, "qSymbol", 7) == 0) {
1297  if (rtos_qsymbol(connection, packet, packet_size) == 1) {
1300  }
1301 
1302  break;
1303  } else if (strncmp(packet, "qfThreadInfo", 12) == 0) {
1304  if (!linux_os->thread_list) {
1306  connection,
1307  packet,
1308  packet_size);
1309  break;
1310  } else {
1312  connection,
1313  packet,
1314  packet_size);
1315  break;
1316  }
1317  } else if (strncmp(packet, "qsThreadInfo", 12) == 0) {
1318  gdb_put_packet(connection, "l", 1);
1319  break;
1320  } else if (strncmp(packet, "qThreadExtraInfo,", 17) == 0) {
1322  packet_size);
1323  break;
1324  } else {
1326  break;
1327  }
1328 
1329  case 'Q':
1330  /* previously response was : thread not found
1331  * gdb_put_packet(connection, "E01", 3); */
1333  break;
1334  case 'c':
1335  case 's': {
1336  if (linux_os->threads_lookup == 1) {
1337  ct = linux_os->current_threads;
1338 
1339  while ((ct) && (ct->core_id) != target->coreid)
1340  ct = ct->next;
1341 
1342  if ((ct) && (ct->threadid == -1)) {
1343  ct = linux_os->current_threads;
1344 
1345  while ((ct) && (ct->threadid == -1))
1346  ct = ct->next;
1347  }
1348 
1349  if ((ct) && (ct->threadid !=
1351  && (target->rtos->current_threadid != -1))
1352  LOG_WARNING("WARNING! current GDB thread do not match "
1353  "current thread running. "
1354  "Switch thread in GDB to threadid %d",
1355  (int)ct->threadid);
1356 
1357  LOG_INFO("threads_needs_update = 1");
1359  }
1360  }
1361 
1362  /* if a packet handler returned an error, exit input loop */
1363  if (retval != ERROR_OK)
1364  return retval;
1365  }
1366 
1367  return retval;
1368 }
1369 
1370 static int linux_os_smp_init(struct target *target)
1371 {
1372  struct target_list *head;
1373  /* keep only target->rtos */
1374  struct rtos *rtos = target->rtos;
1375  struct linux_os *os_linux =
1376  (struct linux_os *)rtos->rtos_specific_params;
1377  struct current_thread *ct;
1378 
1380  if (head->target->rtos != rtos) {
1381  struct linux_os *smp_os_linux =
1382  (struct linux_os *)head->target->rtos->rtos_specific_params;
1383  /* remap smp target on rtos */
1384  free(head->target->rtos);
1385  head->target->rtos = rtos;
1386  /* reuse allocated ct */
1387  ct = smp_os_linux->current_threads;
1388  ct->threadid = -1;
1389  ct->TS = 0xdeadbeef;
1390  ct->core_id = head->target->coreid;
1391  os_linux->current_threads =
1392  add_current_thread(os_linux->current_threads, ct);
1393  os_linux->nr_cpus++;
1394  free(smp_os_linux);
1395  }
1396  }
1397 
1398  return ERROR_OK;
1399 }
1400 
1401 static int linux_os_create(struct target *target)
1402 {
1403  struct linux_os *os_linux = calloc(1, sizeof(struct linux_os));
1404  struct current_thread *ct = calloc(1, sizeof(struct current_thread));
1405  LOG_INFO("linux os creation\n");
1406  os_linux->init_task_addr = 0xdeadbeef;
1407  os_linux->name = "linux";
1408  os_linux->thread_list = NULL;
1409  os_linux->thread_count = 0;
1410  target->rtos->current_threadid = -1;
1411  os_linux->nr_cpus = 1;
1412  os_linux->threads_lookup = 0;
1413  os_linux->threads_needs_update = 0;
1414  os_linux->threadid_count = 1;
1415  os_linux->current_threads = NULL;
1416  target->rtos->rtos_specific_params = os_linux;
1417  ct->core_id = target->coreid;
1418  ct->threadid = -1;
1419  ct->TS = 0xdeadbeef;
1420  os_linux->current_threads =
1421  add_current_thread(os_linux->current_threads, ct);
1422  /* overload rtos thread default handler */
1424  /* initialize a default virt 2 phys translation */
1425  os_linux->phys_mask = ~0xc0000000;
1426  os_linux->phys_base = 0x0;
1427  return JIM_OK;
1428 }
1429 
1430 static char *linux_ps_command(struct target *target)
1431 {
1432  struct linux_os *linux_os = (struct linux_os *)
1434  int retval = ERROR_OK;
1435  char *display;
1436 
1437  if (linux_os->threads_lookup == 0)
1438  retval = linux_get_tasks(target, 1);
1439  else {
1440  if (linux_os->threads_needs_update != 0)
1441  retval = linux_task_update(target, 0);
1442  }
1443 
1444  if (retval == ERROR_OK) {
1445  struct threads *temp = linux_os->thread_list;
1446  char *tmp;
1447  LOG_INFO("allocation for %d threads line",
1449  display = calloc((linux_os->thread_count + 2) * 80, 1);
1450 
1451  if (!display)
1452  goto error;
1453 
1454  tmp = display;
1455  tmp += sprintf(tmp, "PID\t\tCPU\t\tASID\t\tNAME\n");
1456  tmp += sprintf(tmp, "---\t\t---\t\t----\t\t----\n");
1457 
1458  while (temp) {
1459  if (temp->status) {
1460  if (temp->context)
1461  tmp +=
1462  sprintf(tmp,
1463  "%" PRIu32 "\t\t%" PRIu32 "\t\t%" PRIx32 "\t\t%s\n",
1464  temp->pid, temp->oncpu,
1465  temp->asid, temp->name);
1466  else
1467  tmp +=
1468  sprintf(tmp,
1469  "%" PRIu32 "\t\t%" PRIu32 "\t\t%" PRIx32 "\t\t%s\n",
1470  temp->pid, temp->oncpu,
1471  temp->asid, temp->name);
1472  }
1473 
1474  temp = temp->next;
1475  }
1476 
1477  return display;
1478  }
1479 
1480 error:
1481  display = calloc(40, 1);
1482  sprintf(display, "linux_ps_command failed\n");
1483  return display;
1484 }
void * buf_cpy(const void *from, void *_to, unsigned int size)
Copies size bits out of from and into to.
Definition: binarybuffer.c:43
size_t hexify(char *hex, const uint8_t *bin, size_t count, size_t length)
Convert binary data into a string of hexadecimal pairs.
Definition: binarybuffer.c:380
uint64_t buffer
Pointer to data buffer to send over SPI.
Definition: dw-spi-helper.h:0
uint32_t size
Size of dw_spi_transaction::buffer.
Definition: dw-spi-helper.h:4
uint32_t address
Starting address. Sector aligned.
Definition: dw-spi-helper.h:0
int gdb_put_packet(struct connection *connection, const char *buffer, int len)
Definition: gdb_server.c:525
static struct target * get_target_from_connection(struct connection *connection)
Definition: gdb_server.h:35
The JTAG interface can be implemented with a software or hardware fifo.
#define PID
Definition: kitprog.c:38
static struct current_thread * add_current_thread(struct current_thread *currents, struct current_thread *ct)
Definition: linux.c:586
static int fill_task(struct target *target, struct threads *t)
Definition: linux.c:283
#define INIT_TASK
Definition: linux.c:230
static int clean_threadlist(struct target *target)
Definition: linux.c:760
static int linux_os_thread_reg_list(struct rtos *rtos, int64_t thread_id, struct rtos_reg **reg_list, int *num_regs)
Definition: linux.c:156
static int current_base_addr(struct linux_os *linux_os, uint32_t base_addr)
Definition: linux.c:651
static int linux_thread_extra_info(struct target *target, struct connection *connection, char const *packet, int packet_size)
Definition: linux.c:1110
static void linux_identify_current_threads(struct target *target)
Definition: linux.c:817
static char * linux_ps_command(struct target *target)
Definition: linux.c:1430
static int linux_os_smp_init(struct target *target)
Definition: linux.c:1370
static uint32_t next_task(struct target *target, struct threads *t)
Definition: linux.c:567
static int linux_gdb_thread_update(struct target *target, struct connection *connection, char const *packet, int packet_size)
Definition: linux.c:1063
static int linux_get_symbol_list_to_lookup(struct symbol_table_elem *symbol_list[])
Definition: linux.c:236
static int insert_into_threadlist(struct target *target, struct threads *t)
Definition: linux.c:794
static int get_current(struct target *target, int create)
Definition: linux.c:385
static int linux_gdb_h_packet(struct connection *connection, struct target *target, char const *packet, int packet_size)
Definition: linux.c:1206
static struct threads * liste_add_task(struct threads *task_list, struct threads *t, struct threads **last)
Definition: linux.c:622
static int linux_compute_virt2phys(struct target *target, target_addr_t address)
Definition: linux.c:98
static int linux_os_clean(struct target *target)
Definition: linux.c:778
static int fill_buffer(struct target *target, uint32_t addr, uint8_t *buffer)
Definition: linux.c:137
static const char *const linux_symbol_list[]
Definition: linux.c:231
static bool linux_os_detect(struct target *target)
Definition: linux.c:222
#define LINUX_USER_KERNEL_BORDER
Definition: linux.c:25
static int linux_get_tasks(struct target *target, int context)
Definition: linux.c:672
static struct cpu_context * cpu_context_read(struct target *target, uint32_t base_addr, uint32_t *info_addr)
Definition: linux.c:471
#define MAX_THREADS
Definition: linux.c:28
static int linux_read_memory(struct target *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
Definition: linux.c:117
static int get_name(struct target *target, struct threads *t)
Definition: linux.c:339
const struct rtos_type linux_rtos
Definition: linux.c:250
static int linux_gdb_thread_packet(struct target *target, struct connection *connection, char const *packet, int packet_size)
Definition: linux.c:1022
static int linux_os_dummy_update(struct rtos *rtos)
Definition: linux.c:91
static int linux_task_update(struct target *target, int context)
Definition: linux.c:905
static uint32_t get_buffer(struct target *target, const uint8_t *buffer)
Definition: linux.c:148
static int linux_os_create(struct target *target)
Definition: linux.c:1401
static int linux_thread_packet(struct connection *connection, char const *packet, int packet_size)
Definition: linux.c:1275
static int linux_gdb_t_packet(struct connection *connection, struct target *target, char const *packet, int packet_size)
Definition: linux.c:1146
static struct threads * liste_del_task(struct threads *task_list, struct threads **t, struct threads *prev)
Definition: linux.c:605
#define CPU_CONT
Definition: linux_header.h:35
#define MEM
Definition: linux_header.h:32
#define NEXT
Definition: linux_header.h:30
#define COMM
Definition: linux_header.h:31
#define ONCPU
Definition: linux_header.h:33
#define MM_CTX
Definition: linux_header.h:37
#define PREEMPT
Definition: linux_header.h:36
#define QAT
Definition: linux_header.h:29
static int64_t start
Definition: log.c:54
char * alloc_printf(const char *format,...)
Definition: log.c:375
#define LOG_WARNING(expr ...)
Definition: log.h:130
#define ERROR_FAIL
Definition: log.h:174
#define LOG_ERROR(expr ...)
Definition: log.h:133
#define LOG_INFO(expr ...)
Definition: log.h:127
#define ERROR_OK
Definition: log.h:168
int rtos_qsymbol(struct connection *connection, char const *packet, int packet_size)
Definition: rtos.c:211
#define GDB_THREAD_PACKET_NOT_CONSUMED
Definition: rtos.h:114
target_addr_t addr
Start address to search for the control block.
Definition: rtt/rtt.c:28
#define foreach_smp_target(pos, head)
Definition: smp.h:15
uint32_t R6
Definition: linux.c:75
uint32_t IP
Definition: linux.c:79
uint32_t preempt_count
Definition: linux.c:83
uint32_t SP
Definition: linux.c:81
uint32_t R8
Definition: linux.c:77
uint32_t R7
Definition: linux.c:76
uint32_t R4
Definition: linux.c:73
uint32_t FP
Definition: linux.c:80
uint32_t R9
Definition: linux.c:78
uint32_t R5
Definition: linux.c:74
uint32_t PC
Definition: linux.c:82
uint32_t TS
Definition: linux.c:52
int32_t core_id
Definition: linux.c:48
struct current_thread * next
Definition: linux.c:53
int64_t threadid
Definition: linux.c:47
Definition: linux.c:30
uint32_t phys_mask
Definition: linux.c:42
struct threads * thread_list
Definition: linux.c:40
uint32_t phys_base
Definition: linux.c:43
int threads_needs_update
Definition: linux.c:38
int nr_cpus
Definition: linux.c:36
int threadid_count
Definition: linux.c:34
struct current_thread * current_threads
Definition: linux.c:39
uint32_t init_task_addr
Definition: linux.c:32
int threads_lookup
Definition: linux.c:37
const char * name
Definition: linux.c:31
int thread_count
Definition: linux.c:33
int preupdtate_threadid_count
Definition: linux.c:35
int(* get)(struct reg *reg)
Definition: register.h:152
Definition: register.h:111
bool valid
Definition: register.h:126
uint32_t size
Definition: register.h:132
uint8_t * value
Definition: register.h:122
uint32_t number
Definition: register.h:115
const struct reg_arch_type * type
Definition: register.h:141
Definition: rtos.h:53
Definition: rtos.h:59
int(* create)(struct target *target)
Definition: rtos.h:62
const char * name
Definition: rtos.h:60
Definition: rtos.h:36
int(* gdb_thread_packet)(struct connection *connection, char const *packet, int packet_size)
Definition: rtos.h:48
struct symbol_table_elem * symbols
Definition: rtos.h:39
struct target * target
Definition: rtos.h:40
void * rtos_specific_params
Definition: rtos.h:50
int64_t current_threadid
Definition: rtos.h:43
Table should be terminated by an element with NULL in symbol_name.
Definition: rtos.h:23
symbol_address_t address
Definition: rtos.h:25
const char * symbol_name
Definition: rtos.h:24
struct target * target
Definition: target.h:214
int(* virt2phys)(struct target *target, target_addr_t address, target_addr_t *physical)
Definition: target_type.h:252
Definition: target.h:116
int32_t coreid
Definition: target.h:120
struct list_head * smp_targets
Definition: target.h:188
struct rtos * rtos
Definition: target.h:183
struct target_type * type
Definition: target.h:117
Definition: linux.c:56
uint32_t oncpu
Definition: linux.c:61
uint32_t pid
Definition: linux.c:60
uint32_t asid
Definition: linux.c:62
uint32_t state
Definition: linux.c:59
int64_t threadid
Definition: linux.c:63
uint32_t base_addr
Definition: linux.c:58
int status
Definition: linux.c:64
char name[17]
Definition: linux.c:57
struct threads * next
Definition: linux.c:69
struct cpu_context * context
Definition: linux.c:68
uint32_t thread_info_addr
Definition: linux.c:66
int target_read_phys_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer)
Definition: target.c:1252
int target_get_gdb_reg_list(struct target *target, struct reg **reg_list[], int *reg_list_size, enum target_register_class reg_class)
Obtain the registers for GDB.
Definition: target.c:1369
int target_read_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer)
Read count items of size bytes from the memory of target at the address given.
Definition: target.c:1238
uint32_t target_buffer_get_u32(struct target *target, const uint8_t *buffer)
Definition: target.c:316
@ REG_CLASS_GENERAL
Definition: target.h:112
#define ERROR_TARGET_FAILURE
Definition: target.h:791
int64_t timeval_ms(void)
#define ARRAY_SIZE(x)
Compute the number of elements of a variable length array.
Definition: types.h:57
uint64_t target_addr_t
Definition: types.h:335
#define NULL
Definition: usb.h:16
uint8_t count[4]
Definition: vdebug.c:22