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