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

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)