OpenOCD
zephyr.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 /***************************************************************************
4  * Copyright (C) 2017 by Intel Corporation
5  * Leandro Pereira <leandro.pereira@intel.com>
6  * Daniel Glöckner <dg@emlix.com>*
7  * Copyright (C) 2021 by Synopsys, Inc.
8  * Evgeniy Didin <didin@synopsys.com>
9  ***************************************************************************/
10 
11 #ifdef HAVE_CONFIG_H
12 #include "config.h"
13 #endif
14 
15 #include <helper/time_support.h>
16 #include <jtag/jtag.h>
17 
18 #include "helper/log.h"
19 #include "helper/types.h"
20 #include "rtos.h"
22 #include "target/target.h"
23 #include "target/target_type.h"
24 #include "target/armv7m.h"
25 #include "target/arc.h"
26 
27 #define UNIMPLEMENTED 0xFFFFFFFFU
28 
29 /* ARC specific defines */
30 #define ARC_AUX_SEC_BUILD_REG 0xdb
31 #define ARC_REG_NUM 38
32 
33 /* ARM specific defines */
34 #define ARM_XPSR_OFFSET 28
35 
36 struct zephyr_thread {
37  uint32_t ptr, next_ptr;
38  uint32_t entry;
39  uint32_t stack_pointer;
40  uint8_t state;
41  uint8_t user_options;
42  int8_t prio;
43  char name[64];
44 };
45 
62 };
63 
64 struct zephyr_params {
65  const char *target_name;
66  uint8_t size_width;
67  uint8_t pointer_width;
68  uint32_t num_offsets;
69  uint32_t offsets[OFFSET_MAX];
74  struct zephyr_params *params,
75  struct rtos_reg *callee_saved_reg_list,
76  struct rtos_reg **reg_list, int *num_regs);
77 };
78 
79 static const struct stack_register_offset arm_callee_saved[] = {
80  { ARMV7M_R13, 32, 32 },
81  { ARMV7M_R4, 0, 32 },
82  { ARMV7M_R5, 4, 32 },
83  { ARMV7M_R6, 8, 32 },
84  { ARMV7M_R7, 12, 32 },
85  { ARMV7M_R8, 16, 32 },
86  { ARMV7M_R9, 20, 32 },
87  { ARMV7M_R10, 24, 32 },
88  { ARMV7M_R11, 28, 32 },
89 };
90 
91 static const struct stack_register_offset arc_callee_saved[] = {
92  { ARC_R13, 0, 32 },
93  { ARC_R14, 4, 32 },
94  { ARC_R15, 8, 32 },
95  { ARC_R16, 12, 32 },
96  { ARC_R17, 16, 32 },
97  { ARC_R18, 20, 32 },
98  { ARC_R19, 24, 32 },
99  { ARC_R20, 28, 32 },
100  { ARC_R21, 32, 32 },
101  { ARC_R22, 36, 32 },
102  { ARC_R23, 40, 32 },
103  { ARC_R24, 44, 32 },
104  { ARC_R25, 48, 32 },
105  { ARC_GP, 52, 32 },
106  { ARC_FP, 56, 32 },
107  { ARC_R30, 60, 32 }
108 };
110  .stack_registers_size = 36,
111  .stack_growth_direction = -1,
112  .num_output_registers = ARRAY_SIZE(arm_callee_saved),
113  .register_offsets = arm_callee_saved,
114 };
115 
117  .stack_registers_size = 64,
118  .stack_growth_direction = -1,
119  .num_output_registers = ARRAY_SIZE(arc_callee_saved),
120  .register_offsets = arc_callee_saved,
121 };
122 
123 static const struct stack_register_offset arm_cpu_saved[] = {
124  { ARMV7M_R0, 0, 32 },
125  { ARMV7M_R1, 4, 32 },
126  { ARMV7M_R2, 8, 32 },
127  { ARMV7M_R3, 12, 32 },
128  { ARMV7M_R4, -1, 32 },
129  { ARMV7M_R5, -1, 32 },
130  { ARMV7M_R6, -1, 32 },
131  { ARMV7M_R7, -1, 32 },
132  { ARMV7M_R8, -1, 32 },
133  { ARMV7M_R9, -1, 32 },
134  { ARMV7M_R10, -1, 32 },
135  { ARMV7M_R11, -1, 32 },
136  { ARMV7M_R12, 16, 32 },
137  { ARMV7M_R13, -2, 32 },
138  { ARMV7M_R14, 20, 32 },
139  { ARMV7M_PC, 24, 32 },
140  { ARMV7M_XPSR, 28, 32 },
141 };
142 
143 static struct stack_register_offset arc_cpu_saved[] = {
144  { ARC_R0, -1, 32 },
145  { ARC_R1, -1, 32 },
146  { ARC_R2, -1, 32 },
147  { ARC_R3, -1, 32 },
148  { ARC_R4, -1, 32 },
149  { ARC_R5, -1, 32 },
150  { ARC_R6, -1, 32 },
151  { ARC_R7, -1, 32 },
152  { ARC_R8, -1, 32 },
153  { ARC_R9, -1, 32 },
154  { ARC_R10, -1, 32 },
155  { ARC_R11, -1, 32 },
156  { ARC_R12, -1, 32 },
157  { ARC_R13, -1, 32 },
158  { ARC_R14, -1, 32 },
159  { ARC_R15, -1, 32 },
160  { ARC_R16, -1, 32 },
161  { ARC_R17, -1, 32 },
162  { ARC_R18, -1, 32 },
163  { ARC_R19, -1, 32 },
164  { ARC_R20, -1, 32 },
165  { ARC_R21, -1, 32 },
166  { ARC_R22, -1, 32 },
167  { ARC_R23, -1, 32 },
168  { ARC_R24, -1, 32 },
169  { ARC_R25, -1, 32 },
170  { ARC_GP, -1, 32 },
171  { ARC_FP, -1, 32 },
172  { ARC_SP, -1, 32 },
173  { ARC_ILINK, -1, 32 },
174  { ARC_R30, -1, 32 },
175  { ARC_BLINK, 0, 32 },
176  { ARC_LP_COUNT, -1, 32 },
177  { ARC_PCL, -1, 32 },
178  { ARC_PC, -1, 32 },
179  { ARC_LP_START, -1, 32 },
180  { ARC_LP_END, -1, 32 },
181  { ARC_STATUS32, 4, 32 }
182 };
183 
184 
191 };
192 
194  const uint8_t *stack_data,
195  const struct rtos_register_stacking *stacking, target_addr_t stack_ptr)
196 {
197  return rtos_cortex_m_stack_align(target, stack_data, stacking,
198  stack_ptr, ARM_XPSR_OFFSET);
199 }
200 
202  .stack_registers_size = 32,
203  .stack_growth_direction = -1,
204  .num_output_registers = ARRAY_SIZE(arm_cpu_saved),
205  .calculate_process_stack = zephyr_cortex_m_stack_align,
206  .register_offsets = arm_cpu_saved,
207 };
208 
210  .stack_registers_size = 32 + 18 * 4,
211  .stack_growth_direction = -1,
212  .num_output_registers = ARRAY_SIZE(arm_cpu_saved),
213  .calculate_process_stack = zephyr_cortex_m_stack_align,
214  .register_offsets = arm_cpu_saved,
215 };
216 
217 /* stack_registers_size is 8 because besides caller registers
218  * there are only blink and Status32 registers on stack left */
221  .stack_growth_direction = -1,
222  .num_output_registers = ARRAY_SIZE(arc_cpu_saved),
223  .register_offsets = arc_cpu_saved,
224 };
225 
226 /* ARCv2 specific implementation */
228  struct zephyr_params *params,
229  struct rtos_reg *callee_saved_reg_list,
230  struct rtos_reg **reg_list, int *num_regs)
231 {
232 
233  uint32_t real_stack_addr;
234  int retval = 0;
235  int num_callee_saved_regs;
236  const struct rtos_register_stacking *stacking;
237 
238  /* Getting real stack address from Kernel thread struct */
239  retval = target_read_u32(rtos->target, *addr, &real_stack_addr);
240  if (retval != ERROR_OK)
241  return retval;
242 
243  /* Getting callee registers */
245  params->callee_saved_stacking,
246  real_stack_addr, &callee_saved_reg_list,
247  &num_callee_saved_regs);
248  if (retval != ERROR_OK)
249  return retval;
250 
251  stacking = params->cpu_saved_nofp_stacking;
252 
253  /* Getting blink and status32 registers */
254  retval = rtos_generic_stack_read(rtos->target, stacking,
255  real_stack_addr + num_callee_saved_regs * 4,
256  reg_list, num_regs);
257  if (retval != ERROR_OK)
258  return retval;
259 
260  for (int i = 0; i < num_callee_saved_regs; i++)
261  buf_cpy(callee_saved_reg_list[i].value,
262  (*reg_list)[callee_saved_reg_list[i].number].value,
263  callee_saved_reg_list[i].size);
264 
265  /* The blink, sp, pc offsets in arc_cpu_saved structure may be changed,
266  * but the registers number shall not. So the next code searches the
267  * offsetst of these registers in arc_cpu_saved structure. */
268  unsigned short blink_offset = 0, pc_offset = 0, sp_offset = 0;
269  for (size_t i = 0; i < ARRAY_SIZE(arc_cpu_saved); i++) {
270  if (arc_cpu_saved[i].number == ARC_BLINK)
271  blink_offset = i;
272  if (arc_cpu_saved[i].number == ARC_SP)
273  sp_offset = i;
274  if (arc_cpu_saved[i].number == ARC_PC)
275  pc_offset = i;
276  }
277 
278  if (blink_offset == 0 || sp_offset == 0 || pc_offset == 0) {
279  LOG_ERROR("Basic registers offsets are missing, check <arc_cpu_saved> struct");
280  return ERROR_FAIL;
281  }
282 
283  /* Put blink value into PC */
284  buf_cpy((*reg_list)[blink_offset].value,
285  (*reg_list)[pc_offset].value, sizeof((*reg_list)[blink_offset].value));
286 
287  /* Put address after callee/caller in SP. */
288  int64_t stack_top;
289 
290  stack_top = real_stack_addr + num_callee_saved_regs * 4
292  buf_cpy(&stack_top, (*reg_list)[sp_offset].value, sizeof(stack_top));
293 
294  return retval;
295 }
296 
297 /* ARM Cortex-M-specific implementation */
299  struct zephyr_params *params,
300  struct rtos_reg *callee_saved_reg_list,
301  struct rtos_reg **reg_list, int *num_regs)
302 {
303 
304  int retval = 0;
305  int num_callee_saved_regs;
306  const struct rtos_register_stacking *stacking;
307 
309  params->callee_saved_stacking,
310  *addr, &callee_saved_reg_list,
311  &num_callee_saved_regs);
312  if (retval != ERROR_OK)
313  return retval;
314 
316  callee_saved_reg_list[0].value);
317 
319  stacking = params->cpu_saved_fp_stacking;
320  else
321  stacking = params->cpu_saved_nofp_stacking;
322 
323  retval = rtos_generic_stack_read(rtos->target, stacking, *addr, reg_list,
324  num_regs);
325  if (retval != ERROR_OK)
326  return retval;
327 
328  for (int i = 1; i < num_callee_saved_regs; i++)
329  buf_cpy(callee_saved_reg_list[i].value,
330  (*reg_list)[callee_saved_reg_list[i].number].value,
331  callee_saved_reg_list[i].size);
332  return 0;
333 }
334 
335 static struct zephyr_params zephyr_params_list[] = {
336  {
337  .target_name = "cortex_m",
338  .pointer_width = 4,
339  .callee_saved_stacking = &arm_callee_saved_stacking,
340  .cpu_saved_nofp_stacking = &arm_cpu_saved_nofp_stacking,
341  .cpu_saved_fp_stacking = &arm_cpu_saved_fp_stacking,
342  .get_cpu_state = &zephyr_get_arm_state,
343  },
344  {
345  .target_name = "cortex_r4",
346  .pointer_width = 4,
347  .callee_saved_stacking = &arm_callee_saved_stacking,
348  .cpu_saved_nofp_stacking = &arm_cpu_saved_nofp_stacking,
349  .cpu_saved_fp_stacking = &arm_cpu_saved_fp_stacking,
350  .get_cpu_state = &zephyr_get_arm_state,
351  },
352  {
353  .target_name = "hla_target",
354  .pointer_width = 4,
355  .callee_saved_stacking = &arm_callee_saved_stacking,
356  .cpu_saved_nofp_stacking = &arm_cpu_saved_nofp_stacking,
357  .cpu_saved_fp_stacking = &arm_cpu_saved_fp_stacking,
358  .get_cpu_state = &zephyr_get_arm_state,
359 
360  },
361  {
362  .target_name = "arcv2",
363  .pointer_width = 4,
364  .callee_saved_stacking = &arc_callee_saved_stacking,
365  .cpu_saved_nofp_stacking = &arc_cpu_saved_stacking,
366  .get_cpu_state = &zephyr_get_arc_state,
367  },
368  {
369  .target_name = NULL
370  }
371 };
372 
373 static const struct symbol_table_elem zephyr_symbol_list[] = {
374  {
375  .symbol_name = "_kernel",
376  .optional = false
377  },
378  {
379  .symbol_name = "_kernel_thread_info_offsets",
380  .optional = false
381  },
382  {
383  .symbol_name = "_kernel_thread_info_size_t_size",
384  .optional = false
385  },
386  {
387  .symbol_name = "_kernel_thread_info_num_offsets",
388  .optional = true
389  },
390  {
391  .symbol_name = NULL
392  }
393 };
394 
395 static bool zephyr_detect_rtos(struct target *target)
396 {
397  if (!target->rtos->symbols) {
398  LOG_INFO("Zephyr: no symbols while detecting RTOS");
399  return false;
400  }
401 
402  for (enum zephyr_symbol_values symbol = ZEPHYR_VAL__KERNEL;
403  symbol != ZEPHYR_VAL_COUNT; symbol++) {
404  LOG_INFO("Zephyr: does it have symbol %d (%s)?", symbol,
405  target->rtos->symbols[symbol].optional ? "optional" : "mandatory");
406 
407  if (target->rtos->symbols[symbol].optional)
408  continue;
409  if (target->rtos->symbols[symbol].address == 0)
410  return false;
411  }
412 
413  LOG_INFO("Zephyr: all mandatory symbols found");
414 
415  return true;
416 }
417 
418 static int zephyr_create(struct target *target)
419 {
420  const char *name;
421 
423 
424  LOG_INFO("Zephyr: looking for target: %s", name);
425 
426  /* ARC specific, check if EM target has security subsystem
427  * In case of ARC_HAS_SECURE zephyr option enabled
428  * the thread stack contains blink,sec_stat,status32 register
429  * values. If ARC_HAS_SECURE is disabled, only blink and status32
430  * register values are saved on stack. */
431  if (!strcmp(name, "arcv2")) {
432  uint32_t value;
433  struct arc_common *arc = target_to_arc(target);
434  /* Reading SEC_BUILD bcr */
436  if (value != 0) {
437  LOG_DEBUG("ARC EM board has security subsystem, changing offsets");
439  /* After reading callee registers in stack
440  * now blink,sec_stat,status32 registers
441  * are located. */
443  }
444  }
445 
446  for (struct zephyr_params *p = zephyr_params_list; p->target_name; p++) {
447  if (!strcmp(p->target_name, name)) {
448  LOG_INFO("Zephyr: target known, params at %p", p);
450  return ERROR_OK;
451  }
452  }
453 
454  LOG_ERROR("Could not find target in Zephyr compatibility list");
455  return ERROR_FAIL;
456 }
457 
458 struct zephyr_array {
459  void *ptr;
460  size_t elements;
461 };
462 
463 static void zephyr_array_init(struct zephyr_array *array)
464 {
465  array->ptr = NULL;
466  array->elements = 0;
467 }
468 
469 static void zephyr_array_free(struct zephyr_array *array)
470 {
471  free(array->ptr);
472  zephyr_array_init(array);
473 }
474 
475 static void *zephyr_array_append(struct zephyr_array *array, size_t size)
476 {
477  if (!(array->elements % 16)) {
478  void *ptr = realloc(array->ptr, (array->elements + 16) * size);
479 
480  if (!ptr) {
481  LOG_ERROR("Out of memory");
482  return NULL;
483  }
484 
485  array->ptr = ptr;
486  }
487 
488  return (unsigned char *)array->ptr + (array->elements++) * size;
489 }
490 
491 static void *zephyr_array_detach_ptr(struct zephyr_array *array)
492 {
493  void *ptr = array->ptr;
494 
495  zephyr_array_init(array);
496 
497  return ptr;
498 }
499 
500 static uint32_t zephyr_kptr(const struct rtos *rtos, enum zephyr_offsets off)
501 {
502  const struct zephyr_params *params = rtos->rtos_specific_params;
503 
504  return rtos->symbols[ZEPHYR_VAL__KERNEL].address + params->offsets[off];
505 }
506 
507 static int zephyr_fetch_thread(const struct rtos *rtos,
508  struct zephyr_thread *thread, uint32_t ptr)
509 {
510  const struct zephyr_params *param = rtos->rtos_specific_params;
511  int retval;
512 
513  thread->ptr = ptr;
514 
515  retval = target_read_u32(rtos->target, ptr + param->offsets[OFFSET_T_ENTRY],
516  &thread->entry);
517  if (retval != ERROR_OK)
518  return retval;
519 
520  retval = target_read_u32(rtos->target,
521  ptr + param->offsets[OFFSET_T_NEXT_THREAD],
522  &thread->next_ptr);
523  if (retval != ERROR_OK)
524  return retval;
525 
526  retval = target_read_u32(rtos->target,
527  ptr + param->offsets[OFFSET_T_STACK_POINTER],
528  &thread->stack_pointer);
529  if (retval != ERROR_OK)
530  return retval;
531 
532  retval = target_read_u8(rtos->target, ptr + param->offsets[OFFSET_T_STATE],
533  &thread->state);
534  if (retval != ERROR_OK)
535  return retval;
536 
537  retval = target_read_u8(rtos->target,
538  ptr + param->offsets[OFFSET_T_USER_OPTIONS],
539  &thread->user_options);
540  if (retval != ERROR_OK)
541  return retval;
542 
543  uint8_t prio;
544  retval = target_read_u8(rtos->target,
545  ptr + param->offsets[OFFSET_T_PRIO], &prio);
546  if (retval != ERROR_OK)
547  return retval;
548  thread->prio = prio;
549 
550  thread->name[0] = '\0';
551  if (param->offsets[OFFSET_T_NAME] != UNIMPLEMENTED) {
552  retval = target_read_buffer(rtos->target,
553  ptr + param->offsets[OFFSET_T_NAME],
554  sizeof(thread->name) - 1, (uint8_t *)thread->name);
555  if (retval != ERROR_OK)
556  return retval;
557 
558  thread->name[sizeof(thread->name) - 1] = '\0';
559  }
560 
561  LOG_DEBUG("Fetched thread%" PRIx32 ": {entry@0x%" PRIx32
562  ", state=%" PRIu8 ", useropts=%" PRIu8 ", prio=%" PRId8 "}",
563  ptr, thread->entry, thread->state, thread->user_options, thread->prio);
564 
565  return ERROR_OK;
566 }
567 
568 static int zephyr_fetch_thread_list(struct rtos *rtos, uint32_t current_thread)
569 {
570  struct zephyr_array thread_array;
571  struct zephyr_thread thread;
572  struct thread_detail *td;
573  int64_t curr_id = -1;
574  uint32_t curr;
575  int retval;
576 
578  &curr);
579  if (retval != ERROR_OK) {
580  LOG_ERROR("Could not fetch current thread pointer");
581  return retval;
582  }
583 
584  zephyr_array_init(&thread_array);
585 
586  for (; curr; curr = thread.next_ptr) {
587  retval = zephyr_fetch_thread(rtos, &thread, curr);
588  if (retval != ERROR_OK)
589  goto error;
590 
591  td = zephyr_array_append(&thread_array, sizeof(*td));
592  if (!td)
593  goto error;
594 
595  td->threadid = thread.ptr;
596  td->exists = true;
597 
598  if (thread.name[0])
599  td->thread_name_str = strdup(thread.name);
600  else
601  td->thread_name_str = alloc_printf("thr_%" PRIx32 "_%" PRIx32,
602  thread.entry, thread.ptr);
603  td->extra_info_str = alloc_printf("prio:%" PRId8 ",useropts:%" PRIu8,
604  thread.prio, thread.user_options);
605  if (!td->thread_name_str || !td->extra_info_str)
606  goto error;
607 
608  if (td->threadid == current_thread)
609  curr_id = (int64_t)thread_array.elements - 1;
610  }
611 
612  LOG_DEBUG("Got information for %zu threads", thread_array.elements);
613 
615 
616  rtos->thread_count = (int)thread_array.elements;
617  rtos->thread_details = zephyr_array_detach_ptr(&thread_array);
618 
619  rtos->current_threadid = curr_id;
621 
622  return ERROR_OK;
623 
624 error:
625  td = thread_array.ptr;
626  for (size_t i = 0; i < thread_array.elements; i++) {
627  free(td[i].thread_name_str);
628  free(td[i].extra_info_str);
629  }
630 
631  zephyr_array_free(&thread_array);
632 
633  return ERROR_FAIL;
634 }
635 
636 static int zephyr_update_threads(struct rtos *rtos)
637 {
638  struct zephyr_params *param;
639  int retval;
640 
642  return ERROR_FAIL;
643 
644  param = (struct zephyr_params *)rtos->rtos_specific_params;
645 
646  if (!rtos->symbols) {
647  LOG_ERROR("No symbols for Zephyr");
648  return ERROR_FAIL;
649  }
650 
651  if (rtos->symbols[ZEPHYR_VAL__KERNEL].address == 0) {
652  LOG_ERROR("Can't obtain kernel struct from Zephyr");
653  return ERROR_FAIL;
654  }
655 
657  LOG_ERROR("Please build Zephyr with CONFIG_OPENOCD option set");
658  return ERROR_FAIL;
659  }
660 
661  retval = target_read_u8(rtos->target,
663  &param->size_width);
664  if (retval != ERROR_OK) {
665  LOG_ERROR("Couldn't determine size of size_t from host");
666  return retval;
667  }
668 
669  if (param->size_width != 4) {
670  LOG_ERROR("Only size_t of 4 bytes are supported");
671  return ERROR_FAIL;
672  }
673 
675  retval = target_read_u32(rtos->target,
677  &param->num_offsets);
678  if (retval != ERROR_OK) {
679  LOG_ERROR("Couldn't not fetch number of offsets from Zephyr");
680  return retval;
681  }
682 
683  if (param->num_offsets <= OFFSET_T_STACK_POINTER) {
684  LOG_ERROR("Number of offsets too small");
685  return ERROR_FAIL;
686  }
687  } else {
688  retval = target_read_u32(rtos->target,
690  &param->offsets[OFFSET_VERSION]);
691  if (retval != ERROR_OK) {
692  LOG_ERROR("Couldn't not fetch offsets from Zephyr");
693  return retval;
694  }
695 
696  if (param->offsets[OFFSET_VERSION] > 1) {
697  LOG_ERROR("Unexpected OpenOCD support version %" PRIu32,
698  param->offsets[OFFSET_VERSION]);
699  return ERROR_FAIL;
700  }
701  switch (param->offsets[OFFSET_VERSION]) {
702  case 0:
703  param->num_offsets = OFFSET_T_STACK_POINTER + 1;
704  break;
705  case 1:
706  param->num_offsets = OFFSET_T_COOP_FLOAT + 1;
707  break;
708  }
709  }
710  /* We can fetch the whole array for version 0, as they're supposed
711  * to grow only */
712  uint32_t address;
714  for (size_t i = 0; i < OFFSET_MAX; i++, address += param->size_width) {
715  if (i >= param->num_offsets) {
716  param->offsets[i] = UNIMPLEMENTED;
717  continue;
718  }
719 
720  retval = target_read_u32(rtos->target, address, &param->offsets[i]);
721  if (retval != ERROR_OK) {
722  LOG_ERROR("Could not fetch offsets from Zephyr");
723  return ERROR_FAIL;
724  }
725  }
726 
727  LOG_DEBUG("Zephyr OpenOCD support version %" PRId32,
728  param->offsets[OFFSET_VERSION]);
729 
730  uint32_t current_thread;
731  retval = target_read_u32(rtos->target,
733  if (retval != ERROR_OK) {
734  LOG_ERROR("Could not obtain current thread ID");
735  return retval;
736  }
737 
739  if (retval != ERROR_OK) {
740  LOG_ERROR("Could not obtain thread list");
741  return retval;
742  }
743 
744  return ERROR_OK;
745 }
746 
747 static int zephyr_get_thread_reg_list(struct rtos *rtos, int64_t thread_id,
748  struct rtos_reg **reg_list, int *num_regs)
749 {
750  struct zephyr_params *params;
751  struct rtos_reg *callee_saved_reg_list = NULL;
753  int retval;
754 
755  LOG_INFO("Getting thread %" PRId64 " reg list", thread_id);
756 
757  if (!rtos)
758  return ERROR_FAIL;
759 
760  if (thread_id == 0)
761  return ERROR_FAIL;
762 
763  params = rtos->rtos_specific_params;
764  if (!params)
765  return ERROR_FAIL;
766 
767  addr = thread_id + params->offsets[OFFSET_T_STACK_POINTER]
769 
770  retval = params->get_cpu_state(rtos, &addr, params, callee_saved_reg_list, reg_list, num_regs);
771 
772  free(callee_saved_reg_list);
773 
774  return retval;
775 }
776 
777 static int zephyr_get_symbol_list_to_lookup(struct symbol_table_elem **symbol_list)
778 {
779  *symbol_list = malloc(sizeof(zephyr_symbol_list));
780  if (!*symbol_list) {
781  LOG_ERROR("Out of memory");
782  return ERROR_FAIL;
783  }
784 
785  memcpy(*symbol_list, zephyr_symbol_list, sizeof(zephyr_symbol_list));
786  return ERROR_OK;
787 }
788 
789 const struct rtos_type zephyr_rtos = {
790  .name = "Zephyr",
791 
792  .detect_rtos = zephyr_detect_rtos,
793  .create = zephyr_create,
794  .update_threads = zephyr_update_threads,
795  .get_thread_reg_list = zephyr_get_thread_reg_list,
796  .get_symbol_list_to_lookup = zephyr_get_symbol_list_to_lookup,
797 };
static struct arc_common * target_to_arc(struct target *target)
Definition: arc.h:256
#define CHECK_RETVAL(action)
Definition: arc.h:246
@ ARC_R5
Definition: arc.h:55
@ ARC_LP_COUNT
Definition: arc.h:82
@ ARC_R18
Definition: arc.h:68
@ ARC_R17
Definition: arc.h:67
@ ARC_R2
Definition: arc.h:52
@ ARC_R21
Definition: arc.h:71
@ ARC_R4
Definition: arc.h:54
@ ARC_R15
Definition: arc.h:65
@ ARC_R12
Definition: arc.h:62
@ ARC_R14
Definition: arc.h:64
@ ARC_R11
Definition: arc.h:61
@ ARC_R7
Definition: arc.h:57
@ ARC_R20
Definition: arc.h:70
@ ARC_ILINK
Definition: arc.h:79
@ ARC_R6
Definition: arc.h:56
@ ARC_R16
Definition: arc.h:66
@ ARC_BLINK
Definition: arc.h:81
@ ARC_R24
Definition: arc.h:74
@ ARC_GP
Definition: arc.h:76
@ ARC_FP
Definition: arc.h:77
@ ARC_R22
Definition: arc.h:72
@ ARC_PC
Definition: arc.h:89
@ ARC_R8
Definition: arc.h:58
@ ARC_R30
Definition: arc.h:80
@ ARC_SP
Definition: arc.h:78
@ ARC_STATUS32
Definition: arc.h:92
@ ARC_R9
Definition: arc.h:59
@ ARC_R19
Definition: arc.h:69
@ ARC_R13
Definition: arc.h:63
@ ARC_LP_START
Definition: arc.h:90
@ ARC_LP_END
Definition: arc.h:91
@ ARC_R3
Definition: arc.h:53
@ ARC_PCL
Definition: arc.h:88
@ ARC_R1
Definition: arc.h:51
@ ARC_R25
Definition: arc.h:75
@ ARC_R0
Definition: arc.h:50
@ ARC_R23
Definition: arc.h:73
@ ARC_R10
Definition: arc.h:60
int arc_jtag_read_aux_reg_one(struct arc_jtag *jtag_info, uint32_t addr, uint32_t *value)
Wrapper function to ease reading of one AUX register.
Definition: arc_jtag.c:398
const char * name
Definition: armv4_5.c:76
@ ARMV7M_R1
Definition: armv7m.h:108
@ ARMV7M_R6
Definition: armv7m.h:114
@ ARMV7M_R2
Definition: armv7m.h:109
@ ARMV7M_R3
Definition: armv7m.h:110
@ ARMV7M_R14
Definition: armv7m.h:124
@ ARMV7M_R9
Definition: armv7m.h:118
@ ARMV7M_R12
Definition: armv7m.h:122
@ ARMV7M_R0
Definition: armv7m.h:107
@ ARMV7M_R13
Definition: armv7m.h:123
@ ARMV7M_PC
Definition: armv7m.h:125
@ ARMV7M_R7
Definition: armv7m.h:115
@ ARMV7M_R4
Definition: armv7m.h:112
@ ARMV7M_XPSR
Definition: armv7m.h:127
@ ARMV7M_R8
Definition: armv7m.h:117
@ ARMV7M_R11
Definition: armv7m.h:120
@ ARMV7M_R10
Definition: armv7m.h:119
@ ARMV7M_R5
Definition: armv7m.h:113
void * buf_cpy(const void *from, void *_to, unsigned size)
Copies size bits out of from and into to.
Definition: binarybuffer.c:43
enum esirisc_reg_num number
Definition: esirisc.c:87
The JTAG interface can be implemented with a software or hardware fifo.
char * alloc_printf(const char *format,...)
Definition: log.c:364
#define ERROR_FAIL
Definition: log.h:170
#define LOG_ERROR(expr ...)
Definition: log.h:132
#define LOG_INFO(expr ...)
Definition: log.h:126
#define LOG_DEBUG(expr ...)
Definition: log.h:109
#define ERROR_OK
Definition: log.h:164
int rtos_generic_stack_read(struct target *target, const struct rtos_register_stacking *stacking, int64_t stack_ptr, struct rtos_reg **reg_list, int *num_regs)
Definition: rtos.c:602
void rtos_free_threadlist(struct rtos *rtos)
Definition: rtos.c:695
target_addr_t rtos_cortex_m_stack_align(struct target *target, const uint8_t *stack_data, const struct rtos_register_stacking *stacking, target_addr_t stack_ptr, size_t xpsr_offset)
target_addr_t addr
Start address to search for the control block.
Definition: rtt/rtt.c:28
size_t size
Size of the control block search area.
Definition: rtt/rtt.c:30
struct arc_jtag jtag_info
Definition: arc.h:188
Definition: rtos.h:53
uint8_t value[16]
Definition: rtos.h:56
const struct stack_register_offset * register_offsets
Definition: rtos.h:104
unsigned char stack_registers_size
Definition: rtos.h:92
Definition: rtos.h:59
const char * name
Definition: rtos.h:60
Definition: rtos.h:36
int thread_count
Definition: rtos.h:47
struct thread_detail * thread_details
Definition: rtos.h:46
struct symbol_table_elem * symbols
Definition: rtos.h:39
struct target * target
Definition: rtos.h:40
void * rtos_specific_params
Definition: rtos.h:50
threadid_t current_thread
Definition: rtos.h:45
int64_t current_threadid
Definition: rtos.h:43
signed short offset
Definition: rtos.h:85
Table should be terminated by an element with NULL in symbol_name.
Definition: rtos.h:23
symbol_address_t address
Definition: rtos.h:25
bool optional
Definition: rtos.h:26
const char * symbol_name
Definition: rtos.h:24
Definition: target.h:116
struct rtos * rtos
Definition: target.h:183
char * extra_info_str
Definition: rtos.h:33
char * thread_name_str
Definition: rtos.h:32
bool exists
Definition: rtos.h:31
threadid_t threadid
Definition: rtos.h:30
void * ptr
Definition: zephyr.c:459
size_t elements
Definition: zephyr.c:460
const char * target_name
Definition: zephyr.c:65
const struct rtos_register_stacking * cpu_saved_nofp_stacking
Definition: zephyr.c:71
uint8_t size_width
Definition: zephyr.c:66
uint32_t offsets[OFFSET_MAX]
Definition: zephyr.c:69
const struct rtos_register_stacking * cpu_saved_fp_stacking
Definition: zephyr.c:72
uint8_t pointer_width
Definition: zephyr.c:67
uint32_t num_offsets
Definition: zephyr.c:68
const struct rtos_register_stacking * callee_saved_stacking
Definition: zephyr.c:70
int(* get_cpu_state)(struct rtos *rtos, target_addr_t *addr, struct zephyr_params *params, struct rtos_reg *callee_saved_reg_list, struct rtos_reg **reg_list, int *num_regs)
Definition: zephyr.c:73
int8_t prio
Definition: zephyr.c:42
uint32_t next_ptr
Definition: zephyr.c:37
uint32_t entry
Definition: zephyr.c:38
uint32_t ptr
Definition: zephyr.c:37
uint8_t state
Definition: zephyr.c:40
uint32_t stack_pointer
Definition: zephyr.c:39
uint8_t user_options
Definition: zephyr.c:41
char name[64]
Definition: zephyr.c:43
int target_read_buffer(struct target *target, target_addr_t address, uint32_t size, uint8_t *buffer)
Definition: target.c:2407
int target_read_u8(struct target *target, target_addr_t address, uint8_t *value)
Definition: target.c:2598
int target_read_u32(struct target *target, target_addr_t address, uint32_t *value)
Definition: target.c:2550
uint32_t target_buffer_get_u32(struct target *target, const uint8_t *buffer)
Definition: target.c:316
const char * target_type_name(const struct target *target)
Get the target type name.
Definition: target.c:736
#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
static int zephyr_get_symbol_list_to_lookup(struct symbol_table_elem **symbol_list)
Definition: zephyr.c:777
static const struct rtos_register_stacking arm_cpu_saved_fp_stacking
Definition: zephyr.c:209
static target_addr_t zephyr_cortex_m_stack_align(struct target *target, const uint8_t *stack_data, const struct rtos_register_stacking *stacking, target_addr_t stack_ptr)
Definition: zephyr.c:193
static const struct stack_register_offset arc_callee_saved[]
Definition: zephyr.c:91
static const struct stack_register_offset arm_callee_saved[]
Definition: zephyr.c:79
static void * zephyr_array_detach_ptr(struct zephyr_array *array)
Definition: zephyr.c:491
static int zephyr_fetch_thread(const struct rtos *rtos, struct zephyr_thread *thread, uint32_t ptr)
Definition: zephyr.c:507
static const struct rtos_register_stacking arm_cpu_saved_nofp_stacking
Definition: zephyr.c:201
static int zephyr_create(struct target *target)
Definition: zephyr.c:418
static int zephyr_get_arm_state(struct rtos *rtos, target_addr_t *addr, struct zephyr_params *params, struct rtos_reg *callee_saved_reg_list, struct rtos_reg **reg_list, int *num_regs)
Definition: zephyr.c:298
static void zephyr_array_free(struct zephyr_array *array)
Definition: zephyr.c:469
static void * zephyr_array_append(struct zephyr_array *array, size_t size)
Definition: zephyr.c:475
static const struct rtos_register_stacking arm_callee_saved_stacking
Definition: zephyr.c:109
const struct rtos_type zephyr_rtos
Definition: zephyr.c:789
static int zephyr_fetch_thread_list(struct rtos *rtos, uint32_t current_thread)
Definition: zephyr.c:568
static void zephyr_array_init(struct zephyr_array *array)
Definition: zephyr.c:463
#define UNIMPLEMENTED
Definition: zephyr.c:27
#define ARC_AUX_SEC_BUILD_REG
Definition: zephyr.c:30
static const struct symbol_table_elem zephyr_symbol_list[]
Definition: zephyr.c:373
static int zephyr_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, struct rtos_reg **reg_list, int *num_regs)
Definition: zephyr.c:747
static struct zephyr_params zephyr_params_list[]
Definition: zephyr.c:335
static struct stack_register_offset arc_cpu_saved[]
Definition: zephyr.c:143
zephyr_offsets
Definition: zephyr.c:46
@ OFFSET_MAX
Definition: zephyr.c:61
@ OFFSET_T_PRIO
Definition: zephyr.c:54
@ OFFSET_T_ARM_EXC_RETURN
Definition: zephyr.c:60
@ OFFSET_T_NAME
Definition: zephyr.c:56
@ OFFSET_T_USER_OPTIONS
Definition: zephyr.c:53
@ OFFSET_T_STACK_POINTER
Definition: zephyr.c:55
@ OFFSET_T_ARCH
Definition: zephyr.c:57
@ OFFSET_VERSION
Definition: zephyr.c:47
@ OFFSET_K_CURR_THREAD
Definition: zephyr.c:48
@ OFFSET_T_STATE
Definition: zephyr.c:52
@ OFFSET_T_ENTRY
Definition: zephyr.c:50
@ OFFSET_T_NEXT_THREAD
Definition: zephyr.c:51
@ OFFSET_T_COOP_FLOAT
Definition: zephyr.c:59
@ OFFSET_T_PREEMPT_FLOAT
Definition: zephyr.c:58
@ OFFSET_K_THREADS
Definition: zephyr.c:49
static int zephyr_update_threads(struct rtos *rtos)
Definition: zephyr.c:636
zephyr_symbol_values
Definition: zephyr.c:185
@ ZEPHYR_VAL__KERNEL_OPENOCD_SIZE_T_SIZE
Definition: zephyr.c:188
@ ZEPHYR_VAL__KERNEL
Definition: zephyr.c:186
@ ZEPHYR_VAL_COUNT
Definition: zephyr.c:190
@ ZEPHYR_VAL__KERNEL_OPENOCD_OFFSETS
Definition: zephyr.c:187
@ ZEPHYR_VAL__KERNEL_OPENOCD_NUM_OFFSETS
Definition: zephyr.c:189
static const struct rtos_register_stacking arc_callee_saved_stacking
Definition: zephyr.c:116
static int zephyr_get_arc_state(struct rtos *rtos, target_addr_t *addr, struct zephyr_params *params, struct rtos_reg *callee_saved_reg_list, struct rtos_reg **reg_list, int *num_regs)
Definition: zephyr.c:227
static bool zephyr_detect_rtos(struct target *target)
Definition: zephyr.c:395
#define ARC_REG_NUM
Definition: zephyr.c:31
#define ARM_XPSR_OFFSET
Definition: zephyr.c:34
static struct rtos_register_stacking arc_cpu_saved_stacking
Definition: zephyr.c:219
static const struct stack_register_offset arm_cpu_saved[]
Definition: zephyr.c:123
static uint32_t zephyr_kptr(const struct rtos *rtos, enum zephyr_offsets off)
Definition: zephyr.c:500