1 /* 2 * Copyright (c) 2017 Intel Corporation 3 * Copyright 2023 NXP 4 * 5 * SPDX-License-Identifier: Apache-2.0 6 */ 7 8 #include <zephyr/kernel.h> 9 10 #define THREAD_INFO_UNIMPLEMENTED 0xffffffff 11 12 enum { 13 THREAD_INFO_OFFSET_VERSION, 14 THREAD_INFO_OFFSET_K_CURR_THREAD, 15 THREAD_INFO_OFFSET_K_THREADS, 16 THREAD_INFO_OFFSET_T_ENTRY, 17 THREAD_INFO_OFFSET_T_NEXT_THREAD, 18 THREAD_INFO_OFFSET_T_STATE, 19 THREAD_INFO_OFFSET_T_USER_OPTIONS, 20 THREAD_INFO_OFFSET_T_PRIO, 21 THREAD_INFO_OFFSET_T_STACK_PTR, 22 THREAD_INFO_OFFSET_T_NAME, 23 THREAD_INFO_OFFSET_T_ARCH, 24 THREAD_INFO_OFFSET_T_PREEMPT_FLOAT, 25 THREAD_INFO_OFFSET_T_COOP_FLOAT, 26 THREAD_INFO_OFFSET_T_ARM_EXC_RETURN, 27 THREAD_INFO_OFFSET_T_ARC_RELINQUISH_CAUSE, 28 }; 29 30 #if CONFIG_MP_MAX_NUM_CPUS > 1 31 #error "This code doesn't work properly with multiple CPUs enabled" 32 #endif 33 34 /* Forward-compatibility notes: 1) Only append items to this table; otherwise 35 * debugger plugin versions that expect fewer items will read garbage values. 36 * 2) Avoid incompatible changes that affect the interpretation of existing 37 * items. But if you have to do them, increment THREAD_INFO_OFFSET_VERSION 38 * and submit a patch for debugger plugins to deal with both the old and new 39 * scheme. 40 * Only version 1 is backward compatible to version 0. 41 */ 42 __attribute__((used, section(".dbg_thread_info"))) 43 const size_t _kernel_thread_info_offsets[] = { 44 /* Version 0 starts */ 45 [THREAD_INFO_OFFSET_VERSION] = 1, 46 [THREAD_INFO_OFFSET_K_CURR_THREAD] = offsetof(struct _cpu, current), 47 [THREAD_INFO_OFFSET_K_THREADS] = offsetof(struct z_kernel, threads), 48 [THREAD_INFO_OFFSET_T_ENTRY] = offsetof(struct k_thread, entry), 49 [THREAD_INFO_OFFSET_T_NEXT_THREAD] = offsetof(struct k_thread, 50 next_thread), 51 [THREAD_INFO_OFFSET_T_STATE] = offsetof(struct _thread_base, 52 thread_state), 53 [THREAD_INFO_OFFSET_T_USER_OPTIONS] = offsetof(struct _thread_base, 54 user_options), 55 [THREAD_INFO_OFFSET_T_PRIO] = offsetof(struct _thread_base, prio), 56 #if defined(CONFIG_ARM64) 57 /* We are assuming that the SP of interest is SP_EL1 */ 58 [THREAD_INFO_OFFSET_T_STACK_PTR] = offsetof(struct k_thread, 59 callee_saved.sp_elx), 60 #elif defined(CONFIG_ARM) 61 [THREAD_INFO_OFFSET_T_STACK_PTR] = offsetof(struct k_thread, 62 callee_saved.psp), 63 #elif defined(CONFIG_ARC) 64 [THREAD_INFO_OFFSET_T_STACK_PTR] = offsetof(struct k_thread, 65 callee_saved.sp), 66 #elif defined(CONFIG_X86) 67 #if defined(CONFIG_X86_64) 68 [THREAD_INFO_OFFSET_T_STACK_PTR] = offsetof(struct k_thread, 69 callee_saved.rsp), 70 #else 71 [THREAD_INFO_OFFSET_T_STACK_PTR] = offsetof(struct k_thread, 72 callee_saved.esp), 73 #endif 74 #elif defined(CONFIG_MIPS) 75 [THREAD_INFO_OFFSET_T_STACK_PTR] = offsetof(struct k_thread, 76 callee_saved.sp), 77 #elif defined(CONFIG_NIOS2) 78 [THREAD_INFO_OFFSET_T_STACK_PTR] = offsetof(struct k_thread, 79 callee_saved.sp), 80 #elif defined(CONFIG_RISCV) 81 [THREAD_INFO_OFFSET_T_STACK_PTR] = offsetof(struct k_thread, 82 callee_saved.sp), 83 #elif defined(CONFIG_SPARC) 84 [THREAD_INFO_OFFSET_T_STACK_PTR] = offsetof(struct k_thread, 85 callee_saved.o6), 86 #elif defined(CONFIG_ARCH_POSIX) 87 [THREAD_INFO_OFFSET_T_STACK_PTR] = offsetof(struct k_thread, 88 callee_saved.thread_status), 89 #elif defined(CONFIG_XTENSA) 90 /* Xtensa does not store stack pointers inside thread objects. 91 * The registers are saved in thread stack where there is 92 * no fixed location for this to work. So mark this as 93 * unimplemented to avoid the #warning below. 94 */ 95 [THREAD_INFO_OFFSET_T_STACK_PTR] = THREAD_INFO_UNIMPLEMENTED, 96 #else 97 /* Use a special value so that OpenOCD knows that obtaining the stack 98 * pointer is not possible on this particular architecture. 99 */ 100 #warning Please define THREAD_INFO_OFFSET_T_STACK_PTR for this architecture 101 [THREAD_INFO_OFFSET_T_STACK_PTR] = THREAD_INFO_UNIMPLEMENTED, 102 #endif 103 /* Version 0 ends */ 104 105 [THREAD_INFO_OFFSET_T_NAME] = offsetof(struct k_thread, name), 106 [THREAD_INFO_OFFSET_T_ARCH] = offsetof(struct k_thread, arch), 107 #if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING) && defined(CONFIG_ARM) 108 [THREAD_INFO_OFFSET_T_PREEMPT_FLOAT] = offsetof(struct _thread_arch, 109 preempt_float), 110 [THREAD_INFO_OFFSET_T_COOP_FLOAT] = THREAD_INFO_UNIMPLEMENTED, 111 #elif defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING) && defined(CONFIG_ARM64) 112 [THREAD_INFO_OFFSET_T_PREEMPT_FLOAT] = offsetof(struct _thread_arch, 113 saved_fp_context), 114 [THREAD_INFO_OFFSET_T_COOP_FLOAT] = THREAD_INFO_UNIMPLEMENTED, 115 #elif defined(CONFIG_FPU) && defined(CONFIG_X86) 116 #if defined(CONFIG_X86_64) 117 [THREAD_INFO_OFFSET_T_PREEMPT_FLOAT] = offsetof(struct _thread_arch, 118 sse), 119 #else 120 [THREAD_INFO_OFFSET_T_PREEMPT_FLOAT] = offsetof(struct _thread_arch, 121 preempFloatReg), 122 #endif 123 [THREAD_INFO_OFFSET_T_COOP_FLOAT] = THREAD_INFO_UNIMPLEMENTED, 124 #else 125 [THREAD_INFO_OFFSET_T_PREEMPT_FLOAT] = THREAD_INFO_UNIMPLEMENTED, 126 [THREAD_INFO_OFFSET_T_COOP_FLOAT] = THREAD_INFO_UNIMPLEMENTED, 127 #endif 128 /* Version is still 1, but existence of following elements must be 129 * checked with _kernel_thread_info_num_offsets. 130 */ 131 #ifdef CONFIG_ARM_STORE_EXC_RETURN 132 /* ARM overwrites the LSB of the Link Register on the stack when 133 * this option is enabled. If this offset is not THREAD_INFO_UNIMPLEMENTED 134 * then the LSB needs to be restored from mode_exc_return. 135 */ 136 [THREAD_INFO_OFFSET_T_ARM_EXC_RETURN] = offsetof(struct _thread_arch, 137 mode_exc_return), 138 #else 139 [THREAD_INFO_OFFSET_T_ARM_EXC_RETURN] = THREAD_INFO_UNIMPLEMENTED, 140 #endif /* CONFIG_ARM_STORE_EXC_RETURN */ 141 #if defined(CONFIG_ARC) 142 [THREAD_INFO_OFFSET_T_ARC_RELINQUISH_CAUSE] = offsetof(struct _thread_arch, 143 relinquish_cause), 144 #else 145 [THREAD_INFO_OFFSET_T_ARC_RELINQUISH_CAUSE] = THREAD_INFO_UNIMPLEMENTED, 146 #endif /* CONFIG_ARC */ 147 }; 148 149 extern const size_t __attribute__((alias("_kernel_thread_info_offsets"))) 150 _kernel_openocd_offsets; 151 152 __attribute__((used, section(".dbg_thread_info"))) 153 const size_t _kernel_thread_info_num_offsets = ARRAY_SIZE(_kernel_thread_info_offsets); 154 extern const size_t __attribute__((alias("_kernel_thread_info_num_offsets"))) 155 _kernel_openocd_num_offsets; 156 157 __attribute__((used, section(".dbg_thread_info"))) 158 const uint8_t _kernel_thread_info_size_t_size = (uint8_t)sizeof(size_t); 159 extern const uint8_t __attribute__((alias("_kernel_thread_info_size_t_size"))) 160 _kernel_openocd_size_t_size; 161