|
[ source navigation ] [ diff markup ] [ identifier search ] [ general search ] |
|||
|
001 /* Copyright (C) 2005 David Decotigny 002 Copyright (C) 2000-2004, The KOS team 003 004 This program is free software; you can redistribute it and/or 005 modify it under the terms of the GNU General Public License 006 as published by the Free Software Foundation; either version 2 007 of the License, or (at your option) any later version. 008 009 This program is distributed in the hope that it will be useful, 010 but WITHOUT ANY WARRANTY; without even the implied warranty of 011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 012 GNU General Public License for more details. 013 014 You should have received a copy of the GNU General Public License 015 along with this program; if not, write to the Free Software 016 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 017 USA. 018 */ 019 #ifndef _SOS_CPUCTXT_H_ 020 #define _SOS_CPUCTXT_H_ 021 022 023 /** 024 * @file cpu_context.h 025 * 026 * Low level API to manage kernel and user thread CPU contexts. Should 027 * be some kind of architecture-independent. 028 */ 029 030 #include <sos/types.h> 031 #include <sos/errno.h> 032 033 034 /** 035 * Opaque structure storing the CPU context of an inactive kernel or 036 * user thread, as saved by the low level primitives below or by the 037 * interrupt/exception handlers. 038 * 039 * @note This is an (architecture-independent) forward declaration: 040 * see cpu_context.c and the *.S files for its 041 * (architecture-dependent) definition. 042 */ 043 struct sos_cpu_state; 044 045 046 /** 047 * The type of the functions passed as arguments to the Kernel thread 048 * related functions. 049 */ 050 typedef void (sos_cpu_kstate_function_arg1_t(sos_ui32_t arg1)); 051 052 053 /** 054 * Function to create an initial context for a kernel thread starting 055 * its execution at function start_func with the argument initial_arg, 056 * and having the stack defined by stack_bottom/stack_size. When the 057 * start_func function returns, the function exit_func is called with 058 * argument exit_arg. 059 * 060 * @param kctxt The kernel thread CPU context to initialize. The 061 * address of the newly-initialized struct sos_cpu_state will be 062 * stored in this variable. The contents of this struct sos_cpu_state 063 * are actually located /inside/ the stack. 064 * 065 * @param start_func The address of the first instruction that will be 066 * executed when this context will be first transferred on 067 * CPU. Practically speaking, this is the address of a function that 068 * is assumed to take 1 argument. 069 * 070 * @param start_arg The value that will be passed as the argument to 071 * start_func when the thread starts. The stack will be setup 072 * accordingly to simulate a real call to the function and really 073 * passing this arguement. 074 * 075 * @param stack_bottom The lowest address of the stack. 076 * 077 * @param stack_size The size of the stack. 078 * 079 * @param exit_func The address of the instruction executed after the 080 * function start_func has returned. This function takes 1 parameter 081 * as argument: exit_arg. 082 * 083 * @param exit_arg The argument passed to the function exit_func. 084 * 085 * @note the newly created context is INTERRUPTIBLE by default ! 086 */ 087 sos_ret_t sos_cpu_kstate_init(struct sos_cpu_state **kctxt, 088 sos_cpu_kstate_function_arg1_t *start_func, 089 sos_ui32_t start_arg, 090 sos_vaddr_t stack_bottom, 091 sos_size_t stack_size, 092 sos_cpu_kstate_function_arg1_t *exit_func, 093 sos_ui32_t exit_arg); 094 095 096 /** 097 * Function that performs an immediate context-switch from one 098 * kernel/user thread to another one. It stores the current executing 099 * context in from_ctxt, and restores to_context on CPU. 100 * 101 * @param from_ctxt The address of the struct sos_cpu_state will be 102 * stored in this variable. Must NOT be NULL. 103 * 104 * @param to_ctxt The CPU will resume its execution with the struct 105 * sos_cpu_state located at this address. Must NOT be NULL. 106 */ 107 void sos_cpu_context_switch(struct sos_cpu_state **from_ctxt, 108 struct sos_cpu_state *to_ctxt); 109 110 111 /* 112 * Switch to the new given context (of a kernel/user thread) without 113 * saving the old context (of another kernel/user thread), and call 114 * the function reclaiming_func passing it the recalining_arg 115 * argument. The reclaining function is called from within the stack 116 * of the new context, so that it can (among other things) safely 117 * destroy the stack of the former context. 118 * 119 * @param switch_to_ctxt The context that will be restored on the CPU 120 * 121 * @param reclaiming_func The address of the function that will be 122 * called after having changed the stack, but before restoring the CPU 123 * context to switch_to_ctxt. 124 */ 125 void 126 sos_cpu_context_exit_to(struct sos_cpu_state *switch_to_ctxt, 127 sos_cpu_kstate_function_arg1_t *reclaiming_func, 128 sos_ui32_t reclaiming_arg) __attribute__((noreturn)); 129 130 /* ======================================================================= 131 * Public Accessor functions 132 */ 133 134 135 /** 136 * Return Program Counter stored in the saved kernel/user context 137 */ 138 sos_vaddr_t sos_cpu_context_get_PC(const struct sos_cpu_state *ctxt); 139 140 141 /** 142 * Return Stack Pointer stored in the saved kernel/user context 143 */ 144 sos_vaddr_t sos_cpu_context_get_SP(const struct sos_cpu_state *ctxt); 145 146 147 /** 148 * Dump the contents of the CPU context (bochs + x86_videomem) 149 */ 150 void sos_cpu_context_dump(const struct sos_cpu_state *ctxt); 151 152 153 /* ======================================================================= 154 * Public Accessor functions TO BE USED ONLY BY Exception handlers 155 */ 156 157 158 /** 159 * Return the argument passed by the CPU upon exception, as stored in the 160 * saved context 161 */ 162 sos_ui32_t sos_cpu_context_get_EX_info(const struct sos_cpu_state *ctxt); 163 164 165 /** 166 * Return the faulting address of the exception 167 */ 168 sos_vaddr_t 169 sos_cpu_context_get_EX_faulting_vaddr(const struct sos_cpu_state *ctxt); 170 171 172 /* ======================================================================= 173 * Macros controlling stack poisoning. 174 * Stack poisoning can be used to detect: 175 * - unitialized local variables 176 * - when the thread might have gone too deep in the stack 177 */ 178 /** The signature of the poison */ 179 #define SOS_CPU_STATE_STACK_POISON 0xa5 180 181 /** 182 * When set, mean that the whole stack is poisoned to detect use of 183 * unititialized variables 184 */ 185 #define SOS_CPU_STATE_DETECT_UNINIT_KERNEL_VARS 186 /* #undef SOS_CPU_STATE_DETECT_UNINIT_KERNEL_VARS */ 187 188 /** 189 * When set, mean that the bottom of the stack is poisoned to detect 190 * probable stack overflow. Its value indicates the number of bytes 191 * used for this detection. 192 */ 193 #define SOS_CPU_STATE_DETECT_KERNEL_STACK_OVERFLOW 64 194 /* #undef SOS_CPU_STATE_DETECT_KERNEL_STACK_OVERFLOW */ 195 196 #if defined(SOS_CPU_STATE_DETECT_KERNEL_STACK_OVERFLOW) 197 void 198 sos_cpu_state_prepare_detect_kernel_stack_overflow(const struct sos_cpu_state *ctxt, 199 sos_vaddr_t kernel_stack_bottom, 200 sos_size_t kernel_stack_size); 201 void sos_cpu_state_detect_kernel_stack_overflow(const struct sos_cpu_state *ctxt, 202 sos_vaddr_t kernel_stack_bottom, 203 sos_size_t kernel_stack_size); 204 #else 205 # define sos_cpu_state_prepare_detect_kernel_stack_overflow(ctxt,stkbottom,stksize) \ 206 ({ /* nop */ }) 207 # define sos_cpu_state_detect_kernel_stack_overflow(ctxt,stkbottom,stksize) \ 208 ({ /* nop */ }) 209 #endif 210 211 212 /* ======================================================================= 213 * Backtrace facility. To be used for DEBUGging purpose ONLY. 214 */ 215 216 217 /** 218 * The function called at each step of the backtrace iterations 219 * 220 * @param PC The address of the next instruction of the function that 221 * will be executed 222 * 223 * @param params The address of the array of the parameteres that have 224 * been passed to the function considered 225 * 226 * @param depth The index of the iteration (ie the depth of the 227 * current frame into the stack) 228 * 229 * @param custom_arg Whatever you want: this is the argument passed as 230 * custom_arg to sos_backtrace() 231 */ 232 typedef void (sos_backtrace_callback_t)(sos_vaddr_t PC, 233 sos_vaddr_t params, 234 sos_ui32_t depth, 235 void *custom_arg); 236 237 238 /** 239 * Call the backtracer callback on each frame stored in the cpu_state 240 * 241 * @param cpu_state The CPU context we want to explore. MUST be the 242 * context of a thread in Kernel mode, or NULL. When NULL: backtrace 243 * the current CPU context. 244 * 245 * @param max_depth The maximum number of frames to explore 246 * 247 * @param stack_bottom The lower boundary of the stack. This is used 248 * to make sure that the frame addresses fit inside the stack 249 * boudaries (ie are potentially correct). 250 * 251 * @param stack_size The size of the stack. Same comment. 252 * 253 * @param backtracer The function to call to handle the frame for each 254 * iteration 255 * 256 * @param custom_arg The arg passed as custom_arg to the backtracer 257 * 258 * @return The number of frames explored. 259 * 260 * @note Might be inaccurate when gcc's -fomit-frame-pointer has been 261 * used. 262 */ 263 sos_ui32_t sos_backtrace(const struct sos_cpu_state *cpu_state, 264 sos_ui32_t max_depth, 265 sos_vaddr_t stack_bottom, 266 sos_size_t stack_size, 267 sos_backtrace_callback_t * backtracer, 268 void *custom_arg); 269 270 #endif /* _SOS_CPUCTXT_H_ */
[ source navigation ] | [ diff markup ] | [ identifier search ] | [ general search ] |