|
[ source navigation ] [ diff markup ] [ identifier search ] [ general search ] |
|||
|
001 /* Copyright (C) 2000-2004, The KOS team !! 001 /* Copyright (C) 2005 David Decotigny 002 Copyright (C) 1999 Free Software Foundatio !! 002 Copyright (C) 2000-2004, The KOS team 003 003 004 This program is free software; you can redi 004 This program is free software; you can redistribute it and/or 005 modify it under the terms of the GNU Genera 005 modify it under the terms of the GNU General Public License 006 as published by the Free Software Foundatio 006 as published by the Free Software Foundation; either version 2 007 of the License, or (at your option) any lat 007 of the License, or (at your option) any later version. 008 008 009 This program is distributed in the hope tha 009 This program is distributed in the hope that it will be useful, 010 but WITHOUT ANY WARRANTY; without even the 010 but WITHOUT ANY WARRANTY; without even the implied warranty of 011 MERCHANTABILITY or FITNESS FOR A PARTICULAR 011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 012 GNU General Public License for more details 012 GNU General Public License for more details. 013 013 014 You should have received a copy of the GNU 014 You should have received a copy of the GNU General Public License 015 along with this program; if not, write to t 015 along with this program; if not, write to the Free Software 016 Foundation, Inc., 59 Temple Place - Suite 3 016 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 017 USA. 017 USA. 018 */ 018 */ 019 #ifndef _SOS_CPUCTXT_H_ 019 #ifndef _SOS_CPUCTXT_H_ 020 #define _SOS_CPUCTXT_H_ 020 #define _SOS_CPUCTXT_H_ 021 021 022 022 023 /** 023 /** 024 * @file cpu_context.h 024 * @file cpu_context.h 025 * 025 * 026 * Low level API to manage kernel and user thr 026 * Low level API to manage kernel and user thread CPU contexts. Should 027 * be some kind of architecture-independent. 027 * be some kind of architecture-independent. 028 */ 028 */ 029 029 030 #include <sos/types.h> 030 #include <sos/types.h> 031 #include <sos/errno.h> 031 #include <sos/errno.h> 032 032 033 033 034 /** 034 /** 035 * Opaque structure storing the CPU context of !! 035 * Prepare the system to deal with multiple CPU execution contexts 036 * thread, as saved by the low level primitive !! 036 */ >> 037 sos_ret_t sos_cpu_context_subsystem_setup(); >> 038 >> 039 >> 040 /** >> 041 * Opaque structure storing the CPU context of an inactive kernel or >> 042 * user thread, as saved by the low level primitives below or by the 037 * interrupt/exception handlers. 043 * interrupt/exception handlers. 038 * 044 * 039 * @note This is an (architecture-independent) 045 * @note This is an (architecture-independent) forward declaration: 040 * see cpu_context.c and the *.S files for its 046 * see cpu_context.c and the *.S files for its 041 * (architecture-dependent) definition. 047 * (architecture-dependent) definition. 042 */ 048 */ 043 struct sos_cpu_kstate; !! 049 struct sos_cpu_state; 044 050 045 051 046 /** 052 /** 047 * The type of the functions passed as argumen !! 053 * The type of the functions passed as arguments to the Kernel thread >> 054 * related functions. 048 */ 055 */ 049 typedef void (sos_cpu_kstate_function_arg1_t(s 056 typedef void (sos_cpu_kstate_function_arg1_t(sos_ui32_t arg1)); 050 057 051 058 052 /** 059 /** 053 * Function to create an initial context for a 060 * Function to create an initial context for a kernel thread starting 054 * its execution at function start_func with t 061 * its execution at function start_func with the argument initial_arg, 055 * and having the stack defined by stack_botto 062 * and having the stack defined by stack_bottom/stack_size. When the 056 * start_func function returns, the function e 063 * start_func function returns, the function exit_func is called with 057 * argument exit_arg. 064 * argument exit_arg. 058 * 065 * 059 * @param ctxt The kernel thread CPU context t !! 066 * @param kctxt The kernel thread CPU context to initialize. The 060 * address of the newly-initialized struct sos !! 067 * address of the newly-initialized struct sos_cpu_state will be 061 * stored in this variable. The contents of th !! 068 * stored in this variable. The contents of this struct sos_cpu_state 062 * are actually located /inside/ the stack. 069 * are actually located /inside/ the stack. 063 * 070 * 064 * @param start_func The address of the first 071 * @param start_func The address of the first instruction that will be 065 * executed when this context will be first tr 072 * executed when this context will be first transferred on 066 * CPU. Practically speaking, this is the addr 073 * CPU. Practically speaking, this is the address of a function that 067 * is assumed to take 1 argument. 074 * is assumed to take 1 argument. 068 * 075 * 069 * @param start_arg The value that will be pas 076 * @param start_arg The value that will be passed as the argument to 070 * start_func when the thread starts. The stac 077 * start_func when the thread starts. The stack will be setup 071 * accordingly to simulate a real call to the 078 * accordingly to simulate a real call to the function and really 072 * passing this arguement. 079 * passing this arguement. 073 * 080 * 074 * @param stack_bottom The lowest address of t 081 * @param stack_bottom The lowest address of the stack. 075 * 082 * 076 * @param stack_size The size of the stack. 083 * @param stack_size The size of the stack. 077 * 084 * 078 * @param exit_func The address of the instruc 085 * @param exit_func The address of the instruction executed after the 079 * function start_func has returned. This func 086 * function start_func has returned. This function takes 1 parameter 080 * as argument: exit_arg. 087 * as argument: exit_arg. 081 * 088 * 082 * @param exit_arg The argument passed to the 089 * @param exit_arg The argument passed to the function exit_func. 083 * 090 * 084 * @note the newly created context is INTERRUP 091 * @note the newly created context is INTERRUPTIBLE by default ! 085 */ 092 */ 086 sos_ret_t sos_cpu_kstate_init(struct sos_cpu_k !! 093 sos_ret_t sos_cpu_kstate_init(struct sos_cpu_state **kctxt, 087 sos_cpu_kstate_f 094 sos_cpu_kstate_function_arg1_t *start_func, 088 sos_ui32_t star 095 sos_ui32_t start_arg, 089 sos_vaddr_t stac 096 sos_vaddr_t stack_bottom, 090 sos_size_t stac 097 sos_size_t stack_size, 091 sos_cpu_kstate_f 098 sos_cpu_kstate_function_arg1_t *exit_func, 092 sos_ui32_t exit 099 sos_ui32_t exit_arg); 093 100 094 101 095 /** 102 /** 096 * Function that performs an immediate context !! 103 * Function to create an initial context for a user thread starting 097 * thread to another one. It stores the curren !! 104 * its execution at function user_start_PC with the user_start_arg 098 * from_ctxt, and restores to_context on CPU. !! 105 * argument. The address of the user stack before any modification by >> 106 * the ustate_init() function is given by user_start_SP. The user >> 107 * thread starts in user space first and needs a kernel stack for >> 108 * the syscalls and for handling interrupts: the address of this >> 109 * kernel stack is given by the kernel_stack_* parameters. >> 110 * >> 111 * @param uctxt The user thread CPU context to initialize. The >> 112 * address of the newly-initialized struct sos_cpu_state will be >> 113 * stored in this variable. The contents of this struct sos_cpu_state >> 114 * are actually located /inside/ the kernel stack of the thread. >> 115 * >> 116 * @param user_start_PC The address of the first instruction that will >> 117 * be executed in user mode when this context will be first >> 118 * transferred on CPU. Practically speaking, this is the address of a >> 119 * function that is assumed to take 1 argument. >> 120 * >> 121 * @param user_start_SP The initial user stack address. >> 122 * >> 123 * @param user_start_argX The 2 parameters passed to the initial user >> 124 * thread function (in registers). >> 125 * >> 126 * @param kernel_stack_bottom The lowest address of the kernel stack >> 127 * used to switch to user mode and to handle interrupts/exceptions. >> 128 * >> 129 * @param kernel_stack_size The size of the kernel stack (@see >> 130 * kernel_stack_bottom). >> 131 * >> 132 * @note the newly thread context is INTERRUPTIBLE ! >> 133 */ >> 134 sos_ret_t sos_cpu_ustate_init(struct sos_cpu_state **uctxt, >> 135 sos_uaddr_t user_start_PC, >> 136 sos_ui32_t user_start_arg1, >> 137 sos_ui32_t user_start_arg2, >> 138 sos_uaddr_t user_initial_SP, >> 139 sos_vaddr_t kernel_stack_bottom, >> 140 sos_size_t kernel_stack_size); >> 141 >> 142 >> 143 /** >> 144 * Function that performs an immediate context-switch from one >> 145 * kernel/user thread to another one. It stores the current executing >> 146 * context in from_ctxt, and restores to_context on CPU. 099 * 147 * 100 * @param from_ctxt The address of the struct !! 148 * @param from_ctxt The address of the struct sos_cpu_state will be 101 * stored in this variable. Must NOT be NULL. 149 * stored in this variable. Must NOT be NULL. 102 * 150 * 103 * @param to_ctxt The CPU will resume its exec 151 * @param to_ctxt The CPU will resume its execution with the struct 104 * sos_cpu_kstate located at this address. Mus !! 152 * sos_cpu_state located at this address. Must NOT be NULL. 105 */ 153 */ 106 void sos_cpu_kstate_switch(struct sos_cpu_ksta !! 154 void sos_cpu_context_switch(struct sos_cpu_state **from_ctxt, 107 struct sos_cpu_ksta !! 155 struct sos_cpu_state *to_ctxt); 108 156 109 157 110 /* 158 /* 111 * Switch to the new given context (of a kerne !! 159 * Switch to the new given context (of a kernel/user thread) without 112 * the old context (of another kernel thread), !! 160 * saving the old context (of another kernel/user thread), and call 113 * reclaiming_func passing it the recalining_a !! 161 * the function reclaiming_func passing it the recalining_arg 114 * reclaining function is called from within t !! 162 * argument. The reclaining function is called from within the stack 115 * context, so that it can (among other things !! 163 * of the new context, so that it can (among other things) safely 116 * stack of the former context. !! 164 * destroy the stack of the former context. 117 * 165 * 118 * @param switch_to_ctxt The context that will 166 * @param switch_to_ctxt The context that will be restored on the CPU 119 * 167 * 120 * @param reclaiming_func The address of the f 168 * @param reclaiming_func The address of the function that will be 121 * called after having changed the stack, but 169 * called after having changed the stack, but before restoring the CPU 122 * context to switch_to_ctxt. 170 * context to switch_to_ctxt. 123 */ 171 */ 124 void 172 void 125 sos_cpu_kstate_exit_to(struct sos_cpu_kstate * !! 173 sos_cpu_context_exit_to(struct sos_cpu_state *switch_to_ctxt, 126 sos_cpu_kstate_function !! 174 sos_cpu_kstate_function_arg1_t *reclaiming_func, 127 sos_ui32_t reclaiming_a !! 175 sos_ui32_t reclaiming_arg) __attribute__((noreturn)); 128 << 129 176 130 /* =========================================== 177 /* ======================================================================= 131 * Public Accessor functions 178 * Public Accessor functions 132 */ 179 */ 133 180 >> 181 >> 182 /** >> 183 * Return whether the saved context was in kernel or user context >> 184 * >> 185 * @return TRUE when context was interrupted when in user mode, FALSE >> 186 * when in kernel mode, < 0 on error. >> 187 */ >> 188 sos_ret_t >> 189 sos_cpu_context_is_in_user_mode(const struct sos_cpu_state *ctxt); >> 190 >> 191 134 /** 192 /** 135 * Return Program Counter stored in the saved !! 193 * Return Program Counter stored in the saved kernel/user context 136 */ 194 */ 137 sos_vaddr_t sos_cpu_kstate_get_PC(const struct !! 195 sos_vaddr_t sos_cpu_context_get_PC(const struct sos_cpu_state *ctxt); 138 196 139 197 140 /** 198 /** 141 * Return Stack Pointer stored in the saved co !! 199 * Return Stack Pointer stored in the saved kernel/user context 142 */ 200 */ 143 sos_vaddr_t sos_cpu_kstate_get_SP(const struct !! 201 sos_vaddr_t sos_cpu_context_get_SP(const struct sos_cpu_state *ctxt); 144 202 145 203 146 /** 204 /** 147 * Dump the contents of the CPU context (bochs 205 * Dump the contents of the CPU context (bochs + x86_videomem) 148 */ 206 */ 149 void sos_cpu_kstate_dump(const struct sos_cpu_ !! 207 void sos_cpu_context_dump(const struct sos_cpu_state *ctxt); 150 208 151 209 152 /* =========================================== 210 /* ======================================================================= 153 * Public Accessor functions TO BE USED ONLY B 211 * Public Accessor functions TO BE USED ONLY BY Exception handlers 154 */ 212 */ 155 213 156 214 157 /** 215 /** 158 * Return the argument passed by the CPU upon 216 * Return the argument passed by the CPU upon exception, as stored in the 159 * saved context 217 * saved context 160 */ 218 */ 161 sos_ui32_t sos_cpu_kstate_get_EX_info(const st !! 219 sos_ui32_t sos_cpu_context_get_EX_info(const struct sos_cpu_state *ctxt); 162 220 163 221 164 /** 222 /** 165 * Return the faulting address of the exceptio 223 * Return the faulting address of the exception 166 */ 224 */ 167 sos_vaddr_t 225 sos_vaddr_t 168 sos_cpu_kstate_get_EX_faulting_vaddr(const str !! 226 sos_cpu_context_get_EX_faulting_vaddr(const struct sos_cpu_state *ctxt); >> 227 >> 228 >> 229 /** >> 230 * Change the return address of the given context >> 231 */ >> 232 sos_ret_t >> 233 sos_cpu_context_set_EX_return_address(struct sos_cpu_state *ctxt, >> 234 sos_vaddr_t ret_vaddr); >> 235 >> 236 >> 237 /* ======================================================================= >> 238 * Public Accessor functions TO BE USED ONLY BY the SYSCALL handler >> 239 */ >> 240 >> 241 /** >> 242 * Low-level functions used by the syscall handler. They are >> 243 * responsible for retrieving the arguments passed to the syscall when >> 244 * a user thread makes a syscall. Some of these arguments are >> 245 * available as registers' values in the user context, some of them >> 246 * are user-space addresses given by these registers. >> 247 * >> 248 * @return SOS_OK on success, <0 otherwise >> 249 */ >> 250 sos_ret_t sos_syscall_get1arg(const struct sos_cpu_state *user_ctxt, >> 251 /* out */unsigned int *arg1); >> 252 >> 253 sos_ret_t sos_syscall_get2args(const struct sos_cpu_state *user_ctxt, >> 254 /* out */unsigned int *arg1, >> 255 /* out */unsigned int *arg2); >> 256 >> 257 sos_ret_t sos_syscall_get3args(const struct sos_cpu_state *user_ctxt, >> 258 /* out */unsigned int *arg1, >> 259 /* out */unsigned int *arg2, >> 260 /* out */unsigned int *arg3); >> 261 >> 262 sos_ret_t sos_syscall_get4args(const struct sos_cpu_state *user_ctxt, >> 263 /* out */unsigned int *arg1, >> 264 /* out */unsigned int *arg2, >> 265 /* out */unsigned int *arg3, >> 266 /* out */unsigned int *arg4); >> 267 >> 268 sos_ret_t sos_syscall_get5args(const struct sos_cpu_state *user_ctxt, >> 269 /* out */unsigned int *arg1, >> 270 /* out */unsigned int *arg2, >> 271 /* out */unsigned int *arg3, >> 272 /* out */unsigned int *arg4, >> 273 /* out */unsigned int *arg5); >> 274 >> 275 sos_ret_t sos_syscall_get6args(const struct sos_cpu_state *user_ctxt, >> 276 /* out */unsigned int *arg1, >> 277 /* out */unsigned int *arg2, >> 278 /* out */unsigned int *arg3, >> 279 /* out */unsigned int *arg4, >> 280 /* out */unsigned int *arg5, >> 281 /* out */unsigned int *arg6); >> 282 >> 283 sos_ret_t sos_syscall_get7args(const struct sos_cpu_state *user_ctxt, >> 284 /* out */unsigned int *arg1, >> 285 /* out */unsigned int *arg2, >> 286 /* out */unsigned int *arg3, >> 287 /* out */unsigned int *arg4, >> 288 /* out */unsigned int *arg5, >> 289 /* out */unsigned int *arg6, >> 290 /* out */unsigned int *arg7); >> 291 >> 292 sos_ret_t sos_syscall_get8args(const struct sos_cpu_state *user_ctxt, >> 293 /* out */unsigned int *arg1, >> 294 /* out */unsigned int *arg2, >> 295 /* out */unsigned int *arg3, >> 296 /* out */unsigned int *arg4, >> 297 /* out */unsigned int *arg5, >> 298 /* out */unsigned int *arg6, >> 299 /* out */unsigned int *arg7, >> 300 /* out */unsigned int *arg8); 169 301 170 302 171 /* =========================================== 303 /* ======================================================================= 172 * Macros controlling stack poisoning. 304 * Macros controlling stack poisoning. 173 * Stack poisoning can be used to detect: 305 * Stack poisoning can be used to detect: 174 * - unitialized local variables 306 * - unitialized local variables 175 * - when the thread might have gone too deep 307 * - when the thread might have gone too deep in the stack 176 */ 308 */ 177 /** The signature of the poison */ 309 /** The signature of the poison */ 178 #define SOS_CPU_KSTATE_STACK_POISON 0xa5 !! 310 #define SOS_CPU_STATE_STACK_POISON 0xa5 179 311 180 /** 312 /** 181 * When set, mean that the whole stack is pois 313 * When set, mean that the whole stack is poisoned to detect use of 182 * unititialized variables 314 * unititialized variables 183 */ 315 */ 184 #define SOS_CPU_KSTATE_DETECT_UNINIT_VARS !! 316 #define SOS_CPU_STATE_DETECT_UNINIT_KERNEL_VARS 185 /* #undef SOS_CPU_KSTATE_DETECT_UNINIT_VARS */ !! 317 /* #undef SOS_CPU_STATE_DETECT_UNINIT_KERNEL_VARS */ 186 318 187 /** 319 /** 188 * When set, mean that the bottom of the stack 320 * When set, mean that the bottom of the stack is poisoned to detect 189 * probable stack overflow. Its value indicate 321 * probable stack overflow. Its value indicates the number of bytes 190 * used for this detection. 322 * used for this detection. 191 */ 323 */ 192 #define SOS_CPU_KSTATE_DETECT_STACK_OVERFLOW !! 324 #define SOS_CPU_STATE_DETECT_KERNEL_STACK_OVERFLOW 64 193 /* #undef SOS_CPU_KSTATE_DETECT_STACK_OVERFLOW !! 325 /* #undef SOS_CPU_STATE_DETECT_KERNEL_STACK_OVERFLOW */ 194 326 195 #if defined(SOS_CPU_KSTATE_DETECT_STACK_OVERFL !! 327 #if defined(SOS_CPU_STATE_DETECT_KERNEL_STACK_OVERFLOW) 196 void 328 void 197 sos_cpu_kstate_prepare_detect_stack_overflow(c !! 329 sos_cpu_state_prepare_detect_kernel_stack_overflow(const struct sos_cpu_state *ctxt, 198 s !! 330 sos_vaddr_t kernel_stack_bottom, 199 s !! 331 sos_size_t kernel_stack_size); 200 void sos_cpu_kstate_detect_stack_overflow(cons !! 332 void sos_cpu_state_detect_kernel_stack_overflow(const struct sos_cpu_state *ctxt, 201 sos_ !! 333 sos_vaddr_t kernel_stack_bottom, 202 sos_ !! 334 sos_size_t kernel_stack_size); 203 #else 335 #else 204 # define sos_cpu_kstate_prepare_detect_stack_o !! 336 # define sos_cpu_state_prepare_detect_kernel_stack_overflow(ctxt,stkbottom,stksize) \ 205 ({ /* nop */ }) 337 ({ /* nop */ }) 206 # define sos_cpu_kstate_detect_stack_overflow( !! 338 # define sos_cpu_state_detect_kernel_stack_overflow(ctxt,stkbottom,stksize) \ 207 ({ /* nop */ }) 339 ({ /* nop */ }) 208 #endif 340 #endif 209 341 210 342 211 /* =========================================== 343 /* ======================================================================= 212 * Backtrace facility. To be used for DEBUGgin 344 * Backtrace facility. To be used for DEBUGging purpose ONLY. 213 */ 345 */ 214 346 215 347 216 /** 348 /** 217 * The function called at each step of the bac 349 * The function called at each step of the backtrace iterations 218 * 350 * 219 * @param PC The address of the next instructi 351 * @param PC The address of the next instruction of the function that 220 * will be executed 352 * will be executed 221 * 353 * 222 * @param params The address of the array of t 354 * @param params The address of the array of the parameteres that have 223 * been passed to the function considered 355 * been passed to the function considered 224 * 356 * 225 * @param depth The index of the iteration (ie 357 * @param depth The index of the iteration (ie the depth of the 226 * current frame into the stack) 358 * current frame into the stack) 227 * 359 * 228 * @param custom_arg Whatever you want: this i 360 * @param custom_arg Whatever you want: this is the argument passed as 229 * custom_arg to sos_backtrace() 361 * custom_arg to sos_backtrace() 230 */ 362 */ 231 typedef void (sos_backtrace_callback_t)(sos_va 363 typedef void (sos_backtrace_callback_t)(sos_vaddr_t PC, 232 sos_va 364 sos_vaddr_t params, 233 sos_ui 365 sos_ui32_t depth, 234 void * 366 void *custom_arg); 235 367 236 368 237 /** 369 /** 238 * Call the backtracer callback on each frame !! 370 * Call the backtracer callback on each frame stored in the cpu_state 239 * 371 * 240 * @param cpu_kstate The CPU context we want t !! 372 * @param cpu_state The CPU context we want to explore. MUST be the 241 * backtrace the current CPU context. !! 373 * context of a thread in Kernel mode, or NULL. When NULL: backtrace >> 374 * the current CPU context. 242 * 375 * 243 * @param max_depth The maximum number of fram 376 * @param max_depth The maximum number of frames to explore 244 * 377 * 245 * @param stack_bottom The lower boundary of t 378 * @param stack_bottom The lower boundary of the stack. This is used 246 * to make sure that the frame addresses fit i 379 * to make sure that the frame addresses fit inside the stack 247 * boudaries (ie are potentially correct). 380 * boudaries (ie are potentially correct). 248 * 381 * 249 * @param stack_size The size of the stack. Sa 382 * @param stack_size The size of the stack. Same comment. 250 * 383 * 251 * @param backtracer The function to call to h 384 * @param backtracer The function to call to handle the frame for each 252 * iteration 385 * iteration 253 * 386 * 254 * @param custom_arg The arg passed as custom_ 387 * @param custom_arg The arg passed as custom_arg to the backtracer 255 * 388 * 256 * @return The number of frames explored. 389 * @return The number of frames explored. 257 * 390 * 258 * @note Might be inaccurate when gcc's -fomit 391 * @note Might be inaccurate when gcc's -fomit-frame-pointer has been 259 * used. 392 * used. 260 */ 393 */ 261 sos_ui32_t sos_backtrace(const struct sos_cpu_ !! 394 sos_ui32_t sos_backtrace(const struct sos_cpu_state *cpu_state, 262 sos_ui32_t max_depth, 395 sos_ui32_t max_depth, 263 sos_vaddr_t stack_bot 396 sos_vaddr_t stack_bottom, 264 sos_size_t stack_size 397 sos_size_t stack_size, 265 sos_backtrace_callbac 398 sos_backtrace_callback_t * backtracer, 266 void *custom_arg); 399 void *custom_arg); 267 400 268 #endif /* _SOS_CPUCTXT_H_ */ 401 #endif /* _SOS_CPUCTXT_H_ */
[ source navigation ] | [ diff markup ] | [ identifier search ] | [ general search ] |