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_RX) 78 [THREAD_INFO_OFFSET_T_STACK_PTR] = THREAD_INFO_UNIMPLEMENTED, 79 #elif defined(CONFIG_RISCV) 80 [THREAD_INFO_OFFSET_T_STACK_PTR] = offsetof(struct k_thread, 81 callee_saved.sp), 82 #elif defined(CONFIG_SPARC) 83 [THREAD_INFO_OFFSET_T_STACK_PTR] = offsetof(struct k_thread, 84 callee_saved.o6), 85 #elif defined(CONFIG_ARCH_POSIX) 86 [THREAD_INFO_OFFSET_T_STACK_PTR] = offsetof(struct k_thread, 87 callee_saved.thread_status), 88 #elif defined(CONFIG_XTENSA) 89 /* Xtensa does not store stack pointers inside thread objects. 90 * The registers are saved in thread stack where there is 91 * no fixed location for this to work. So mark this as 92 * unimplemented to avoid the #warning below. 93 */ 94 [THREAD_INFO_OFFSET_T_STACK_PTR] = THREAD_INFO_UNIMPLEMENTED, 95 #elif defined(CONFIG_RX) 96 /* RX doesn't store *anything* inside thread objects yet */ 97 [THREAD_INFO_OFFSET_T_STACK_PTR] = THREAD_INFO_UNIMPLEMENTED, 98 #else 99 /* Use a special value so that OpenOCD knows that obtaining the stack 100 * pointer is not possible on this particular architecture. 101 */ 102 #warning Please define THREAD_INFO_OFFSET_T_STACK_PTR for this architecture 103 [THREAD_INFO_OFFSET_T_STACK_PTR] = THREAD_INFO_UNIMPLEMENTED, 104 #endif 105 /* Version 0 ends */ 106 107 [THREAD_INFO_OFFSET_T_NAME] = offsetof(struct k_thread, name), 108 [THREAD_INFO_OFFSET_T_ARCH] = offsetof(struct k_thread, arch), 109 #if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING) && defined(CONFIG_ARM) 110 [THREAD_INFO_OFFSET_T_PREEMPT_FLOAT] = offsetof(struct _thread_arch, 111 preempt_float), 112 [THREAD_INFO_OFFSET_T_COOP_FLOAT] = THREAD_INFO_UNIMPLEMENTED, 113 #elif defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING) && defined(CONFIG_ARM64) 114 [THREAD_INFO_OFFSET_T_PREEMPT_FLOAT] = offsetof(struct _thread_arch, 115 saved_fp_context), 116 [THREAD_INFO_OFFSET_T_COOP_FLOAT] = THREAD_INFO_UNIMPLEMENTED, 117 #elif defined(CONFIG_FPU) && defined(CONFIG_X86) 118 #if defined(CONFIG_X86_64) 119 [THREAD_INFO_OFFSET_T_PREEMPT_FLOAT] = offsetof(struct _thread_arch, 120 sse), 121 #else 122 [THREAD_INFO_OFFSET_T_PREEMPT_FLOAT] = offsetof(struct _thread_arch, 123 preempFloatReg), 124 #endif 125 [THREAD_INFO_OFFSET_T_COOP_FLOAT] = THREAD_INFO_UNIMPLEMENTED, 126 #else 127 [THREAD_INFO_OFFSET_T_PREEMPT_FLOAT] = THREAD_INFO_UNIMPLEMENTED, 128 [THREAD_INFO_OFFSET_T_COOP_FLOAT] = THREAD_INFO_UNIMPLEMENTED, 129 #endif 130 /* Version is still 1, but existence of following elements must be 131 * checked with _kernel_thread_info_num_offsets. 132 */ 133 #ifdef CONFIG_ARM_STORE_EXC_RETURN 134 /* ARM overwrites the LSB of the Link Register on the stack when 135 * this option is enabled. If this offset is not THREAD_INFO_UNIMPLEMENTED 136 * then the LSB needs to be restored from mode_exc_return. 137 */ 138 [THREAD_INFO_OFFSET_T_ARM_EXC_RETURN] = offsetof(struct _thread_arch, 139 mode_exc_return), 140 #else 141 [THREAD_INFO_OFFSET_T_ARM_EXC_RETURN] = THREAD_INFO_UNIMPLEMENTED, 142 #endif /* CONFIG_ARM_STORE_EXC_RETURN */ 143 #if defined(CONFIG_ARC) 144 [THREAD_INFO_OFFSET_T_ARC_RELINQUISH_CAUSE] = offsetof(struct _thread_arch, 145 relinquish_cause), 146 #else 147 [THREAD_INFO_OFFSET_T_ARC_RELINQUISH_CAUSE] = THREAD_INFO_UNIMPLEMENTED, 148 #endif /* CONFIG_ARC */ 149 }; 150 151 extern const size_t __attribute__((alias("_kernel_thread_info_offsets"))) 152 _kernel_openocd_offsets; 153 154 __attribute__((used, section(".dbg_thread_info"))) 155 const size_t _kernel_thread_info_num_offsets = ARRAY_SIZE(_kernel_thread_info_offsets); 156 extern const size_t __attribute__((alias("_kernel_thread_info_num_offsets"))) 157 _kernel_openocd_num_offsets; 158 159 __attribute__((used, section(".dbg_thread_info"))) 160 const uint8_t _kernel_thread_info_size_t_size = (uint8_t)sizeof(size_t); 161 extern const uint8_t __attribute__((alias("_kernel_thread_info_size_t_size"))) 162 _kernel_openocd_size_t_size; 163