build: cleanup src/rtos directory
[openocd.git] / src / rtos / linux.c
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, write to the *
18 * Free Software Foundation, Inc., *
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
20 ***************************************************************************/
21
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 #include <helper/time_support.h>
27 #include <jtag/jtag.h>
28 #include "target/target.h"
29 #include "target/target_type.h"
30 #include "helper/log.h"
31 #include "rtos.h"
32 #include "helper/log.h"
33 #include "rtos_standard_stackings.h"
34 #include <target/register.h>
35 #include "server/gdb_server.h"
36
37 #define LINUX_USER_KERNEL_BORDER 0xc0000000
38 #include "linux_header.h"
39 #define PHYS
40 #define MAX_THREADS 200
41 /* specific task */
42 struct linux_os {
43 char *name;
44 uint32_t init_task_addr;
45 int thread_count;
46 int threadid_count;
47 int preupdtate_threadid_count;
48 int nr_cpus;
49 int threads_lookup;
50 int threads_needs_update;
51 struct current_thread *current_threads;
52 struct threads *thread_list;
53 /* virt2phys parameter */
54 uint32_t phys_mask;
55 uint32_t phys_base;
56 };
57
58 struct current_thread {
59 int64_t threadid;
60 int32_t core_id;
61 #ifdef PID_CHECK
62 uint32_t pid;
63 #endif
64 uint32_t TS;
65 struct current_thread *next;
66 };
67
68 struct threads {
69 char name[17];
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 */
75 int64_t threadid;
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;
81 struct threads *next;
82 };
83
84 struct cpu_context {
85 uint32_t R4;
86 uint32_t R5;
87 uint32_t R6;
88 uint32_t R7;
89 uint32_t R8;
90 uint32_t R9;
91 uint32_t IP;
92 uint32_t FP;
93 uint32_t SP;
94 uint32_t PC;
95 uint32_t preempt_count;
96 };
97 struct cpu_context *cpu_context_read(struct target *target, uint32_t base_addr,
98 uint32_t *info_addr);
99 static int insert_into_threadlist(struct target *target, struct threads *t);
100
101 static int linux_os_create(struct target *target);
102
103 static int linux_os_dummy_update(struct rtos *rtos)
104 {
105 /* update is done only when thread request come
106 * too many thread to do it on each stop */
107 return 0;
108 }
109
110 static int linux_compute_virt2phys(struct target *target, uint32_t address)
111 {
112 struct linux_os *linux_os = (struct linux_os *)
113 target->rtos->rtos_specific_params;
114 uint32_t pa = 0;
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;
120 return ERROR_FAIL;
121 }
122
123 linux_os->init_task_addr = address;
124 address = address & linux_os->phys_mask;
125 linux_os->phys_base = pa - address;
126 return ERROR_OK;
127 }
128
129 static int linux_read_memory(struct target *target,
130 uint32_t address, uint32_t size, uint32_t count,
131 uint8_t *buffer)
132 {
133 #ifdef PHYS
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;
137 #endif
138 if (address < 0xc000000) {
139 LOG_ERROR("linux awareness : address in user space");
140 return ERROR_FAIL;
141 }
142 #ifdef PHYS
143 target->type->read_phys_memory(target, pa, size, count, buffer);
144 #endif
145 target->type->read_memory(target, address, size, count, buffer);
146 return ERROR_OK;
147 }
148
149 static char *reg_converter(char *buffer, void *reg, int size)
150 {
151 int i;
152
153 for (i = 0; i < size; i++)
154 buffer += sprintf(buffer, "%02x", ((uint8_t *) reg)[i]);
155
156 return buffer;
157 }
158
159 int fill_buffer(struct target *target, uint32_t addr, uint8_t *buffer)
160 {
161
162 if ((addr & 0xfffffffc) != addr)
163 LOG_INFO("unaligned address %x!!", addr);
164
165 int retval = linux_read_memory(target, addr, 4, 1, buffer);
166 return retval;
167
168 }
169
170 uint32_t get_buffer(struct target *target, const uint8_t *buffer)
171 {
172 uint32_t value = 0;
173 const uint8_t *value_ptr = buffer;
174 value = target_buffer_get_u32(target, value_ptr);
175 return value;
176 }
177
178 static int linux_os_thread_reg_list(struct rtos *rtos,
179 int64_t thread_id, char **hex_reg_list)
180 {
181 struct target *target = rtos->target;
182 struct linux_os *linux_os = (struct linux_os *)
183 target->rtos->rtos_specific_params;
184 int i = 0;
185 struct current_thread *tmp = linux_os->current_threads;
186 struct current_thread *next;
187 char *hex_string;
188 int found = 0;
189 int retval;
190 /* check if a current thread is requested */
191 next = tmp;
192
193 do {
194 if (next->threadid == thread_id)
195 found = 1;
196 else
197 next = next->next;
198 } while ((found == 0) && (next != tmp) && (next != NULL));
199
200 if (found == 1) {
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;
205 head = target->head;
206 found = 0;
207 do {
208 if (head->target->coreid == next->core_id) {
209
210 target = head->target;
211 found = 1;
212 } else
213 head = head->next;
214
215 } while ((head != (struct target_list *)NULL) && (found == 0));
216
217 if (found == 0) {
218 LOG_ERROR
219 (
220 "current thread %" PRIx64 ": no target to perform access of core id %x",
221 thread_id,
222 next->core_id);
223 return ERROR_FAIL;
224 }
225
226 /*LOG_INFO("thread %lx current on core %x",thread_id,
227 * target->coreid);*/
228 retval =
229 target_get_gdb_reg_list(target, &reg_list, &reg_list_size);
230
231 if (retval != ERROR_OK)
232 return retval;
233
234 for (i = 0; i < reg_list_size; i++)
235 reg_packet_size += reg_list[i]->size;
236
237 *hex_reg_list = malloc(DIV_ROUND_UP(reg_packet_size, 8) * 2);
238
239 hex_string = *hex_reg_list;
240
241 for (i = 0; i < reg_list_size; i++) {
242 if (!reg_list[i]->valid)
243 reg_list[i]->type->get(reg_list[i]);
244
245 hex_string = reg_converter(hex_string,
246 reg_list[i]->value,
247 (reg_list[i]->size) / 8);
248 }
249
250 free(reg_list);
251
252 } else {
253 struct threads *temp = linux_os->thread_list;
254 *hex_reg_list = (char *)calloc(1, 500 * sizeof(char));
255 hex_string = *hex_reg_list;
256
257 for (i = 0; i < 16; i++)
258 hex_string += sprintf(hex_string, "%02x", 0);
259
260 while ((temp != NULL) &&
261 (temp->threadid != target->rtos->current_threadid))
262 temp = temp->next;
263
264 if (temp != NULL) {
265 if (temp->context == NULL)
266 temp->context = cpu_context_read(target,
267 temp->
268 base_addr,
269 &temp->
270 thread_info_addr);
271
272 hex_string =
273 reg_converter(hex_string, &temp->context->R4, 4);
274 hex_string =
275 reg_converter(hex_string, &temp->context->R5, 4);
276 hex_string =
277 reg_converter(hex_string, &temp->context->R6, 4);
278 hex_string =
279 reg_converter(hex_string, &temp->context->R7, 4);
280 hex_string =
281 reg_converter(hex_string, &temp->context->R8, 4);
282 hex_string =
283 reg_converter(hex_string, &temp->context->R9, 4);
284
285 for (i = 0; i < 4; i++) /*R10 = 0x0 */
286 hex_string += sprintf(hex_string, "%02x", 0);
287
288 hex_string =
289 reg_converter(hex_string, &temp->context->FP, 4);
290 hex_string =
291 reg_converter(hex_string, &temp->context->IP, 4);
292 hex_string =
293 reg_converter(hex_string, &temp->context->SP, 4);
294
295 for (i = 0; i < 4; i++)
296 hex_string += sprintf(hex_string, "%02x", 0);
297
298 hex_string =
299 reg_converter(hex_string, &temp->context->PC, 4);
300
301 for (i = 0; i < 100; i++) /*100 */
302 hex_string += sprintf(hex_string, "%02x", 0);
303
304 uint32_t cpsr = 0x00000000;
305 hex_string = reg_converter(hex_string, &cpsr, 4);
306 }
307 }
308 return ERROR_OK;
309 }
310
311 static int linux_os_detect(struct target *target)
312 {
313 LOG_INFO("should no be called");
314 return 0;
315 }
316
317 static int linux_os_smp_init(struct target *target);
318 static int linux_os_clean(struct target *target);
319 #define INIT_TASK 0
320 static char *linux_symbol_list[] = {
321 "init_task",
322 NULL
323 };
324
325 static int linux_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[])
326 {
327 unsigned int i;
328 *symbol_list = (symbol_table_elem_t *)
329 malloc(sizeof(symbol_table_elem_t) / sizeof(char *));
330
331 for (i = 0; i < sizeof(linux_symbol_list) / sizeof(char *); i++)
332 (*symbol_list)[i].symbol_name = linux_symbol_list[i];
333
334 return 0;
335 }
336
337 static char *linux_ps_command(struct target *target);
338
339 const struct rtos_type Linux_os = {
340 .name = "linux",
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,
349 };
350
351 static int linux_thread_packet(struct connection *connection, char *packet,
352 int packet_size);
353 static void linux_identify_current_threads(struct target *target);
354
355 #ifdef PID_CHECK
356 int fill_task_pid(struct target *target, struct threads *t)
357 {
358 uint32_t pid_addr = t->base_addr + PID;
359 uint8_t buffer[4];
360 int retval = fill_buffer(target, pid_addr, buffer);
361
362 if (retval == ERROR_OK) {
363 uint32_t val = get_buffer(target, buffer);
364 t->pid = val;
365 } else
366 LOG_ERROR("fill_task_pid: unable to read memory");
367
368 return retval;
369 }
370 #endif
371
372 int fill_task(struct target *target, struct threads *t)
373 {
374 int retval;
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);
380
381 if (retval == ERROR_OK) {
382 uint32_t val = get_buffer(target, buffer);
383 t->state = val;
384 } else
385 LOG_ERROR("fill_task: unable to read memory");
386
387 retval = fill_buffer(target, pid_addr, buffer);
388
389 if (retval == ERROR_OK) {
390 uint32_t val = get_buffer(target, buffer);
391 t->pid = val;
392 } else
393 LOG_ERROR("fill task: unable to read memory");
394
395 retval = fill_buffer(target, on_cpu, buffer);
396
397 if (retval == ERROR_OK) {
398 uint32_t val = get_buffer(target, buffer);
399 t->oncpu = val;
400 } else
401 LOG_ERROR("fill task: unable to read memory");
402
403 retval = fill_buffer(target, mem_addr, buffer);
404
405 if (retval == ERROR_OK) {
406 uint32_t val = get_buffer(target, buffer);
407
408 if (val != 0) {
409 uint32_t asid_addr = val + MM_CTX;
410 retval = fill_buffer(target, asid_addr, buffer);
411
412 if (retval == ERROR_OK) {
413 val = get_buffer(target, buffer);
414 t->asid = val;
415 } else
416 LOG_ERROR
417 ("fill task: unable to read memory -- ASID");
418 } else
419 t->asid = 0;
420 } else
421 LOG_ERROR("fill task: unable to read memory");
422
423 return retval;
424 }
425
426 int get_name(struct target *target, struct threads *t)
427 {
428 int retval;
429 uint32_t full_name[4];
430 uint32_t comm = t->base_addr + COMM;
431 int i;
432
433 for (i = 0; i < 17; i++)
434 t->name[i] = 0;
435
436 retval = linux_read_memory(target, comm, 4, 4, (uint8_t *) full_name);
437
438 if (retval != ERROR_OK) {
439 LOG_ERROR("get_name: unable to read memory\n");
440 return ERROR_FAIL;
441 }
442
443 uint32_t raw_name = target_buffer_get_u32(target,
444 (const uint8_t *)
445 &full_name[0]);
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;
450 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;
456 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;
462 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;
468 return ERROR_OK;
469
470 }
471
472 int get_current(struct target *target, int create)
473 {
474 struct target_list *head;
475 head = target->head;
476 uint8_t *buf;
477 uint32_t val;
478 uint32_t ti_addr;
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;
483
484 /* invalid current threads content */
485 while (ctt != NULL) {
486 ctt->threadid = -1;
487 ctt->TS = 0xdeadbeef;
488 ctt = ctt->next;
489 }
490
491 while (head != (struct target_list *)NULL) {
492 struct reg **reg_list;
493 int reg_list_size;
494 int retval;
495
496 if (target_get_gdb_reg_list(head->target, &reg_list,
497 &reg_list_size) != ERROR_OK)
498 return ERROR_TARGET_FAILURE;
499
500 if (!reg_list[13]->valid)
501 reg_list[13]->type->get(reg_list[13]);
502
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);
508
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);
513
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;
519
520 while ((ct != NULL) && (ct->core_id != (int32_t) cpu))
521 ct = ct->next;
522
523 if ((ct != NULL) && (ct->TS == 0xdeadbeef))
524 ct->TS = TS;
525 else
526 LOG_ERROR
527 ("error in linux current thread update");
528
529 if (create) {
530 struct threads *t;
531 t = calloc(1, sizeof(struct threads));
532 t->base_addr = ct->TS;
533 fill_task(target, t);
534 get_name(target, t);
535 t->oncpu = cpu;
536 insert_into_threadlist(target, t);
537 t->status = 3;
538 t->thread_info_addr = 0xdeadbeef;
539 ct->threadid = t->threadid;
540 linux_os->thread_count++;
541 #ifdef PID_CHECK
542 ct->pid = t->pid;
543 #endif
544 /*LOG_INFO("Creation of current thread %s",t->name);*/
545 }
546 }
547 }
548
549 free(reg_list);
550 head = head->next;
551 }
552
553 return ERROR_OK;
554 }
555
556 struct cpu_context *cpu_context_read(struct target *target, uint32_t base_addr,
557 uint32_t *thread_info_addr_old)
558 {
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;
577 retry:
578
579 if (*thread_info_addr_old == 0xdeadbeef) {
580 retval = fill_buffer(target, stack, buffer);
581
582 if (retval == ERROR_OK)
583 thread_info_addr = get_buffer(target, buffer);
584 else
585 LOG_ERROR("cpu_context: unable to read memory");
586
587 thread_info_addr_update = thread_info_addr;
588 } else
589 thread_info_addr = *thread_info_addr_old;
590
591 preempt_count_addr = thread_info_addr + PREEMPT;
592 retval = fill_buffer(target, preempt_count_addr, buffer);
593
594 if (retval == ERROR_OK)
595 context->preempt_count = get_buffer(target, buffer);
596 else {
597 if (*thread_info_addr_old != 0xdeadbeef) {
598 LOG_ERROR
599 ("cpu_context: cannot read at thread_info_addr");
600
601 if (*thread_info_addr_old < LINUX_USER_KERNEL_BORDER)
602 LOG_INFO
603 ("cpu_context : thread_info_addr in userspace!!!");
604
605 *thread_info_addr_old = 0xdeadbeef;
606 goto retry;
607 }
608
609 LOG_ERROR("cpu_context: unable to read memory");
610 }
611
612 thread_info_addr += CPU_CONT;
613
614 retval = linux_read_memory(target, thread_info_addr, 4, 10,
615 (uint8_t *) registers);
616
617 if (retval != ERROR_OK) {
618 LOG_ERROR("cpu_context: unable to read memory\n");
619 return context;
620 }
621
622 context->R4 =
623 target_buffer_get_u32(target, (const uint8_t *)&registers[0]);
624 context->R5 =
625 target_buffer_get_u32(target, (const uint8_t *)&registers[1]);
626 context->R6 =
627 target_buffer_get_u32(target, (const uint8_t *)&registers[2]);
628 context->R7 =
629 target_buffer_get_u32(target, (const uint8_t *)&registers[3]);
630 context->R8 =
631 target_buffer_get_u32(target, (const uint8_t *)&registers[4]);
632 context->R9 =
633 target_buffer_get_u32(target, (const uint8_t *)&registers[5]);
634 context->IP =
635 target_buffer_get_u32(target, (const uint8_t *)&registers[6]);
636 context->FP =
637 target_buffer_get_u32(target, (const uint8_t *)&registers[7]);
638 context->SP =
639 target_buffer_get_u32(target, (const uint8_t *)&registers[8]);
640 context->PC =
641 target_buffer_get_u32(target, (const uint8_t *)&registers[9]);
642
643 if (*thread_info_addr_old == 0xdeadbeef)
644 *thread_info_addr_old = thread_info_addr_update;
645
646 return context;
647 }
648
649 uint32_t next_task(struct target *target, struct threads *t)
650 {
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);
654
655 if (retval == ERROR_OK) {
656 uint32_t val = get_buffer(target, buffer);
657 val = val - NEXT;
658 return val;
659 free(buffer);
660 } else
661 LOG_ERROR("next task: unable to read memory");
662
663 return 0;
664 }
665
666 struct current_thread *add_current_thread(struct current_thread *currents,
667 struct current_thread *ct)
668 {
669 ct->next = NULL;
670
671 if (currents == NULL) {
672 currents = ct;
673 return currents;
674 } else {
675 struct current_thread *temp = currents;
676
677 while (temp->next != NULL)
678 temp = temp->next;
679
680 temp->next = ct;
681 return currents;
682 }
683 }
684
685 struct threads *liste_del_task(struct threads *task_list, struct threads **t,
686 struct threads *prev)
687 {
688 LOG_INFO("del task %" PRId64, (*t)->threadid);
689 prev->next = (*t)->next;
690
691 if (prev == task_list)
692 task_list = prev;
693
694 /* free content of threads */
695 if ((*t)->context)
696 free((*t)->context);
697
698 free(*t);
699 *t = prev;
700 return task_list;
701 }
702
703 struct threads *liste_add_task(struct threads *task_list, struct threads *t,
704 struct threads **last)
705 {
706 t->next = NULL;
707
708 if (*last == NULL)
709 if (task_list == NULL) {
710 task_list = t;
711 return task_list;
712 } else {
713 struct threads *temp = task_list;
714
715 while (temp->next != NULL)
716 temp = temp->next;
717
718 temp->next = t;
719 *last = t;
720 return task_list;
721 } else {
722 (*last)->next = t;
723 *last = t;
724 return task_list;
725 }
726 }
727
728 #ifdef PID_CHECK
729 static int current_pid(struct linux_os *linux_os, uint32_t pid)
730 #else
731 static int current_base_addr(struct linux_os *linux_os, uint32_t base_addr)
732 #endif
733 {
734 struct current_thread *ct = linux_os->current_threads;
735 #ifdef PID_CHECK
736
737 while ((ct != NULL) && (ct->pid != pid))
738 #else
739 while ((ct != NULL) && (ct->TS != base_addr))
740 #endif
741 ct = ct->next;
742 #ifdef PID_CHECK
743 if ((ct != NULL) && (ct->pid == pid))
744 #else
745 if ((ct != NULL) && (ct->TS == base_addr))
746 #endif
747 return 1;
748
749 return 0;
750 }
751
752 int linux_get_tasks(struct target *target, int context)
753 {
754 int loop = 0;
755 int retval = 0;
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;
760
761 if (linux_os->init_task_addr == 0xdeadbeef) {
762 LOG_INFO("no init symbol\n");
763 return ERROR_FAIL;
764 }
765
766 int64_t start = timeval_ms();
767
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 retval = get_current(target, 1);
773
774 while (((t->base_addr != linux_os->init_task_addr) &&
775 (t->base_addr != 0)) || (loop == 0)) {
776 loop++;
777 retval = fill_task(target, t);
778 retval = get_name(target, t);
779
780 if (loop > MAX_THREADS) {
781 LOG_INFO("more than %d threads !!", MAX_THREADS);
782 return ERROR_FAIL;
783 }
784
785 if (retval != ERROR_OK) {
786 free(t);
787 return ERROR_FAIL;
788 }
789
790 /* check that this thread is not one the current threads already
791 * created */
792 #ifdef PID_CHECK
793
794 if (!current_pid(linux_os, t->pid)) {
795 #else
796 if (!current_base_addr(linux_os, t->base_addr)) {
797 #endif
798 t->threadid = linux_os->threadid_count;
799 t->status = 1;
800 linux_os->threadid_count++;
801
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;
807
808 if (context)
809 t->context =
810 cpu_context_read(target, t->base_addr,
811 &t->thread_info_addr);
812 } else {
813 /*LOG_INFO("thread %s is a current thread already created",t->name); */
814 free(t);
815 }
816
817 uint32_t base_addr = next_task(target, t);
818 t = calloc(1, sizeof(struct threads));
819 t->base_addr = base_addr;
820 }
821
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 */
826
827 LOG_INFO("complete time %" PRId64 ", thread mean %" PRId64 "\n",
828 (timeval_ms() - start),
829 (timeval_ms() - start) / linux_os->threadid_count);
830
831 LOG_INFO("threadid count %d", linux_os->threadid_count);
832
833 return ERROR_OK;
834 }
835
836 static int clean_threadlist(struct target *target)
837 {
838 struct linux_os *linux_os = (struct linux_os *)
839 target->rtos->rtos_specific_params;
840 struct threads *old, *temp = linux_os->thread_list;
841
842 while (temp != NULL) {
843 old = temp;
844
845 if (temp->context)
846 free(temp->context);
847
848 temp = temp->next;
849 free(old);
850 }
851
852 return ERROR_OK;
853 }
854
855 static int linux_os_clean(struct target *target)
856 {
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;
868 return ERROR_OK;
869 }
870
871 static int insert_into_threadlist(struct target *target, struct threads *t)
872 {
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++;
878 t->status = 1;
879 t->next = NULL;
880
881 if (temp == NULL)
882 linux_os->thread_list = t;
883 else {
884 while (temp->next != NULL)
885 temp = temp->next;
886
887 t->next = NULL;
888 temp->next = t;
889 }
890
891 return ERROR_OK;
892 }
893
894 static void linux_identify_current_threads(struct target *target)
895 {
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;
901
902 while ((ct != NULL)) {
903 if (ct->threadid == -1) {
904
905 /* un-identified thread */
906 int found = 0;
907 t = calloc(1, sizeof(struct threads));
908 t->base_addr = ct->TS;
909 #ifdef PID_CHECK
910
911 if (fill_task_pid(target, t) != ERROR_OK) {
912 error_handling:
913 free(t);
914 LOG_ERROR
915 ("linux identify_current_threads: unable to read pid");
916 return;
917 }
918 #endif
919
920 /* search in the list of threads if pid
921 already present */
922 while ((thread_list != NULL) && (found == 0)) {
923 #ifdef PID_CHECK
924 if (thread_list->pid == t->pid) {
925 #else
926 if (thread_list->base_addr == t->base_addr) {
927 #endif
928 free(t);
929 t = thread_list;
930 found = 1;
931 }
932 thread_list = thread_list->next;
933 }
934
935 if (!found) {
936 /* it is a new thread */
937 if (fill_task(target, t) != ERROR_OK)
938 goto error_handling;
939
940 get_name(target, t);
941 insert_into_threadlist(target, t);
942 t->thread_info_addr = 0xdeadbeef;
943 }
944
945 t->status = 3;
946 ct->threadid = t->threadid;
947 #ifdef PID_CHECK
948 ct->pid = t->pid;
949 #endif
950 linux_os->thread_count++;
951 #if 0
952 if (found == 0)
953 LOG_INFO("current thread core %x identified %s",
954 ct->core_id, t->name);
955 else
956 LOG_INFO("current thread core %x, reused %s",
957 ct->core_id, t->name);
958 #endif
959 }
960 #if 0
961 else {
962 struct threads tmp;
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);
967 }
968 #endif
969 ct = ct->next;
970 }
971
972 return;
973 #ifndef PID_CHECK
974 error_handling:
975 free(t);
976 LOG_ERROR("unable toread pid");
977 return;
978
979 #endif
980 }
981
982 static int linux_task_update(struct target *target, int context)
983 {
984 struct linux_os *linux_os = (struct linux_os *)
985 target->rtos->rtos_specific_params;
986 struct threads *thread_list = linux_os->thread_list;
987 int retval;
988 int loop = 0;
989 linux_os->thread_count = 0;
990
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*/
994
995 if (thread_list->context) {
996 free(thread_list->context);
997 thread_list->context = NULL;
998 }
999
1000 thread_list = thread_list->next;
1001 }
1002
1003 int found = 0;
1004
1005 if (linux_os->init_task_addr == 0xdeadbeef) {
1006 LOG_INFO("no init symbol\n");
1007 return ERROR_FAIL;
1008 }
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);
1016
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
1020 * target */
1021 loop++;
1022 previous = t->base_addr;
1023 /* read only pid */
1024 #ifdef PID_CHECK
1025 retval = fill_task_pid(target, t);
1026 #endif
1027
1028 if (retval != ERROR_OK) {
1029 free(t);
1030 return ERROR_FAIL;
1031 }
1032
1033 thread_list = linux_os->thread_list;
1034
1035 while (thread_list != NULL) {
1036 #ifdef PID_CHECK
1037 if (t->pid == thread_list->pid) {
1038 #else
1039 if (t->base_addr == thread_list->base_addr) {
1040 #endif
1041 if (!thread_list->status) {
1042 #ifdef PID_CHECK
1043 if (t->base_addr != thread_list->base_addr)
1044 LOG_INFO("thread base_addr has changed !!");
1045 #endif
1046 /* this is not a current thread */
1047 thread_list->base_addr = t->base_addr;
1048 thread_list->status = 1;
1049
1050 /* we don 't update this field any more */
1051
1052 /*thread_list->state = t->state;
1053 thread_list->oncpu = t->oncpu;
1054 thread_list->asid = t->asid;
1055 */
1056 if (context)
1057 thread_list->context =
1058 cpu_context_read(target,
1059 thread_list->
1060 base_addr,
1061 &thread_list->
1062 thread_info_addr);
1063 } else {
1064 /* it is a current thread no need to read context */
1065 }
1066
1067 linux_os->thread_count++;
1068 found = 1;
1069 break;
1070 } else {
1071 found = 0;
1072 thread_list = thread_list->next;
1073 }
1074 }
1075
1076 if (found == 0) {
1077 uint32_t base_addr;
1078 fill_task(target, t);
1079 get_name(target, t);
1080 retval = insert_into_threadlist(target, t);
1081 t->thread_info_addr = 0xdeadbeef;
1082
1083 if (context)
1084 t->context =
1085 cpu_context_read(target, t->base_addr,
1086 &t->thread_info_addr);
1087
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++;
1092 } else
1093 t->base_addr = next_task(target, t);
1094 }
1095
1096 LOG_INFO("update thread done %" PRId64 ", mean%" PRId64 "\n",
1097 (timeval_ms() - start), (timeval_ms() - start) / loop);
1098 free(t);
1099 linux_os->threads_needs_update = 0;
1100 return ERROR_OK;
1101 }
1102
1103 int linux_gdb_thread_packet(struct target *target,
1104 struct connection *connection, char *packet,
1105 int packet_size)
1106 {
1107 int retval;
1108 struct linux_os *linux_os =
1109 (struct linux_os *)target->rtos->rtos_specific_params;
1110
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);
1115 return ERROR_OK;
1116 }
1117
1118 retval = linux_get_tasks(target, 1);
1119
1120 if (retval != ERROR_OK)
1121 return ERROR_TARGET_FAILURE;
1122
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);
1128 temp = temp->next;
1129
1130 while (temp != NULL) {
1131 tmp_str += sprintf(tmp_str, ",");
1132 tmp_str += sprintf(tmp_str, "%016" PRIx64, temp->threadid);
1133 temp = temp->next;
1134 }
1135
1136 gdb_put_packet(connection, out_str, strlen(out_str));
1137 return ERROR_OK;
1138 }
1139
1140 int linux_gdb_thread_update(struct target *target,
1141 struct connection *connection, char *packet,
1142 int packet_size)
1143 {
1144 int found = 0;
1145 struct linux_os *linux_os = (struct linux_os *)
1146 target->rtos->rtos_specific_params;
1147 struct threads *temp = linux_os->thread_list;
1148
1149 while (temp != NULL) {
1150 if (temp->threadid == linux_os->preupdtate_threadid_count + 1) {
1151 /*LOG_INFO("FOUND");*/
1152 found = 1;
1153 break;
1154 } else
1155 temp = temp->next;
1156 }
1157
1158 if (found == 1) {
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);
1165
1166 temp = temp->next;
1167
1168 while (temp != NULL) {
1169 /*LOG_INFO("INTO GDB THREAD UPDATE WHILE");*/
1170 tmp_strr += sprintf(tmp_strr, ",");
1171 tmp_strr +=
1172 sprintf(tmp_strr, "%016" PRIx64, temp->threadid);
1173 temp = temp->next;
1174 }
1175
1176 /*tmp_str[0] = 0;*/
1177 gdb_put_packet(connection, out_strr, strlen(out_strr));
1178 linux_os->preupdtate_threadid_count =
1179 linux_os->threadid_count - 1;
1180 free(out_strr);
1181 } else
1182 gdb_put_packet(connection, "l", 1);
1183
1184 return ERROR_OK;
1185 }
1186
1187 int linux_thread_extra_info(struct target *target,
1188 struct connection *connection, char *packet,
1189 int packet_size)
1190 {
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;
1197
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;
1206
1207 /* discriminate cuurent task */
1208 if (temp->status == 3)
1209 tmp_str_ptr += sprintf(tmp_str_ptr, "%s",
1210 pid_current);
1211 else
1212 tmp_str_ptr += sprintf(tmp_str_ptr, "%s", pid);
1213
1214 tmp_str_ptr +=
1215 sprintf(tmp_str_ptr, "%d", (int)temp->pid);
1216 tmp_str_ptr += sprintf(tmp_str_ptr, "%s", " | ");
1217 tmp_str_ptr += sprintf(tmp_str_ptr, "%s", name);
1218 tmp_str_ptr += sprintf(tmp_str_ptr, "%s", temp->name);
1219 char *hex_str =
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));
1223 free(hex_str);
1224 free(tmp_str);
1225 return ERROR_OK;
1226 }
1227
1228 temp = temp->next;
1229 }
1230
1231 LOG_INFO("thread not found");
1232 return ERROR_OK;
1233 }
1234
1235 int linux_gdb_T_packet(struct connection *connection,
1236 struct target *target, char *packet, int packet_size)
1237 {
1238 int64_t threadid;
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);
1243
1244 if (linux_os->threads_needs_update == 0) {
1245 struct threads *temp = linux_os->thread_list;
1246 struct threads *prev = linux_os->thread_list;
1247
1248 while (temp != NULL) {
1249 if (temp->threadid == threadid) {
1250 if (temp->status != 0) {
1251 gdb_put_packet(connection, "OK", 2);
1252 return ERROR_OK;
1253 } else {
1254 /* delete item in the list */
1255 linux_os->thread_list =
1256 liste_del_task(linux_os->
1257 thread_list, &temp,
1258 prev);
1259 linux_os->thread_count--;
1260 gdb_put_packet(connection, "E01", 3);
1261 return ERROR_OK;
1262 }
1263 }
1264
1265 /* for deletion */
1266 prev = temp;
1267 temp = temp->next;
1268 }
1269
1270 LOG_INFO("gdb requested status on non existing thread");
1271 gdb_put_packet(connection, "E01", 3);
1272 return ERROR_OK;
1273
1274 } else {
1275 retval = linux_task_update(target, 1);
1276 struct threads *temp = linux_os->thread_list;
1277
1278 while (temp != NULL) {
1279 if (temp->threadid == threadid) {
1280 if (temp->status == 1) {
1281 gdb_put_packet(connection, "OK", 2);
1282 return ERROR_OK;
1283 } else {
1284 gdb_put_packet(connection, "E01", 3);
1285 return ERROR_OK;
1286 }
1287 }
1288
1289 temp = temp->next;
1290 }
1291 }
1292
1293 return retval;
1294 }
1295
1296 int linux_gdb_h_packet(struct connection *connection,
1297 struct target *target, char *packet, int packet_size)
1298 {
1299 struct linux_os *linux_os = (struct linux_os *)
1300 target->rtos->rtos_specific_params;
1301 struct current_thread *ct = linux_os->current_threads;
1302
1303 /* select to display the current thread of the selected target */
1304 while ((ct != NULL) && (ct->core_id != target->coreid))
1305 ct = ct->next;
1306
1307 int64_t current_gdb_thread_rq;
1308
1309 if (linux_os->threads_lookup == 1) {
1310 if ((ct != NULL) && (ct->threadid == -1)) {
1311 ct = linux_os->current_threads;
1312
1313 while ((ct != NULL) && (ct->threadid == -1))
1314 ct = ct->next;
1315 }
1316
1317 if (ct == NULL) {
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
1322 * get_current */
1323 struct threads t;
1324 ct = linux_os->current_threads;
1325
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",
1330 t.name);
1331 ct = ct->next;
1332 }
1333
1334 gdb_put_packet(connection, "OK", 2);
1335 return ERROR_OK;
1336 }
1337
1338 if (packet[1] == 'g') {
1339 sscanf(packet, "Hg%16" SCNx64, &current_gdb_thread_rq);
1340
1341 if (current_gdb_thread_rq == 0) {
1342 target->rtos->current_threadid = ct->threadid;
1343 gdb_put_packet(connection, "OK", 2);
1344 } else {
1345 target->rtos->current_threadid =
1346 current_gdb_thread_rq;
1347 gdb_put_packet(connection, "OK", 2);
1348 }
1349 } else if (packet[1] == 'c') {
1350 sscanf(packet, "Hc%16" SCNx64, &current_gdb_thread_rq);
1351
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);
1356 } else
1357 gdb_put_packet(connection, "E01", 3);
1358 }
1359 } else
1360 gdb_put_packet(connection, "OK", 2);
1361
1362 return ERROR_OK;
1363 }
1364
1365 static int linux_thread_packet(struct connection *connection, char *packet,
1366 int packet_size)
1367 {
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;
1373
1374 switch (packet[0]) {
1375 case 'T': /* Is thread alive?*/
1376
1377 linux_gdb_T_packet(connection, target, packet, packet_size);
1378 break;
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);
1383 break;
1384 case 'q':
1385
1386 if ((strstr(packet, "qSymbol"))) {
1387 if (rtos_qsymbol(connection, packet, packet_size) == 1) {
1388 gdb_put_packet(connection, "OK", 2);
1389
1390 linux_compute_virt2phys(target,
1391 target->rtos->
1392 symbols[INIT_TASK].
1393 address);
1394 }
1395
1396 break;
1397 } else if (strstr(packet, "qfThreadInfo")) {
1398 if (linux_os->thread_list == NULL) {
1399 retval = linux_gdb_thread_packet(target,
1400 connection,
1401 packet,
1402 packet_size);
1403 break;
1404 } else {
1405 retval = linux_gdb_thread_update(target,
1406 connection,
1407 packet,
1408 packet_size);
1409 break;
1410 }
1411 } else if (strstr(packet, "qsThreadInfo")) {
1412 gdb_put_packet(connection, "l", 1);
1413 break;
1414 } else if (strstr(packet, "qThreadExtraInfo,")) {
1415 linux_thread_extra_info(target, connection, packet,
1416 packet_size);
1417 break;
1418 } else {
1419 retval = GDB_THREAD_PACKET_NOT_CONSUMED;
1420 break;
1421 }
1422
1423 case 'Q':
1424 /* previously response was : thread not found
1425 * gdb_put_packet(connection, "E01", 3); */
1426 retval = GDB_THREAD_PACKET_NOT_CONSUMED;
1427 break;
1428 case 'c':
1429 case 's': {
1430 if (linux_os->threads_lookup == 1) {
1431 ct = linux_os->current_threads;
1432
1433 while ((ct != NULL) && (ct->core_id) != target->coreid)
1434 ct = ct->next;
1435
1436 if ((ct != NULL) && (ct->threadid == -1)) {
1437 ct = linux_os->current_threads;
1438
1439 while ((ct != NULL) && (ct->threadid == -1))
1440 ct = ct->next;
1441 }
1442
1443 if ((ct != NULL) && (ct->threadid !=
1444 target->rtos->
1445 current_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",
1450 (int)ct->threadid);
1451
1452 LOG_INFO("threads_needs_update = 1");
1453 linux_os->threads_needs_update = 1;
1454 }
1455 }
1456
1457 /* if a packet handler returned an error, exit input loop */
1458 if (retval != ERROR_OK)
1459 return retval;
1460 }
1461
1462 return retval;
1463 }
1464
1465 static int linux_os_smp_init(struct target *target)
1466 {
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;
1474
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;
1485 ct->threadid = -1;
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++;
1491 free(smp_os_linux);
1492 }
1493
1494 head = head->next;
1495 }
1496
1497 return ERROR_OK;
1498 }
1499
1500 static int linux_os_create(struct target *target)
1501 {
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;
1517 ct->threadid = -1;
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;
1526 return JIM_OK;
1527 }
1528
1529 static char *linux_ps_command(struct target *target)
1530 {
1531 struct linux_os *linux_os = (struct linux_os *)
1532 target->rtos->rtos_specific_params;
1533 int retval = ERROR_OK;
1534 char *display;
1535
1536 if (linux_os->threads_lookup == 0)
1537 retval = linux_get_tasks(target, 1);
1538 else {
1539 if (linux_os->threads_needs_update != 0)
1540 retval = linux_task_update(target, 0);
1541 }
1542
1543 if (retval == ERROR_OK) {
1544 struct threads *temp = linux_os->thread_list;
1545 char *tmp;
1546 LOG_INFO("allocation for %d threads line",
1547 linux_os->thread_count);
1548 display = calloc((linux_os->thread_count + 2) * 80, 1);
1549
1550 if (!display)
1551 goto error;
1552
1553 tmp = display;
1554 tmp += sprintf(tmp, "PID\t\tCPU\t\tASID\t\tNAME\n");
1555 tmp += sprintf(tmp, "---\t\t---\t\t----\t\t----\n");
1556
1557 while (temp != NULL) {
1558 if (temp->status) {
1559 if (temp->context)
1560 tmp +=
1561 sprintf(tmp,
1562 "%d\t\t%d\t\t%x\t\t%s\n",
1563 (int)temp->pid, temp->oncpu,
1564 temp->asid, temp->name);
1565 else
1566 tmp +=
1567 sprintf(tmp,
1568 "%d\t\t%d\t\t%x\t\t%s\n",
1569 (int)temp->pid, temp->oncpu,
1570 temp->asid, temp->name);
1571 }
1572
1573 temp = temp->next;
1574 }
1575
1576 return display;
1577 }
1578
1579 error:
1580 display = calloc(40, 1);
1581 sprintf(display, "linux_ps_command failed\n");
1582 return display;
1583 }

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)