SimpleOS

LXR

Navigation



Site hébergé par : enix

The LXR Cross Referencer for SOS

source navigation ]
diff markup ]
identifier search ]
general search ]
 
 
Article:1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 6.5 ] [ 7 ] [ 7.5 ] [ 8 ] [ 9 ] [ 9.5 ]

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  * Prepare the system to deal with multiple CPU execution contexts
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
043  * interrupt/exception handlers.
044  *
045  * @note This is an (architecture-independent) forward declaration:
046  * see cpu_context.c and the *.S files for its
047  * (architecture-dependent) definition.
048  */
049 struct sos_cpu_state;
050 
051 
052 /**
053  * The type of the functions passed as arguments to the Kernel thread
054  * related functions.
055  */
056 typedef void (sos_cpu_kstate_function_arg1_t(sos_ui32_t arg1));
057 
058 
059 /**
060  * Function to create an initial context for a kernel thread starting
061  * its execution at function start_func with the argument initial_arg,
062  * and having the stack defined by stack_bottom/stack_size. When the
063  * start_func function returns, the function exit_func is called with
064  * argument exit_arg.
065  *
066  * @param kctxt The kernel thread CPU context to initialize. The
067  * address of the newly-initialized struct sos_cpu_state will be
068  * stored in this variable. The contents of this struct sos_cpu_state
069  * are actually located /inside/ the stack.
070  *
071  * @param start_func The address of the first instruction that will be
072  * executed when this context will be first transferred on
073  * CPU. Practically speaking, this is the address of a function that
074  * is assumed to take 1 argument.
075  *
076  * @param start_arg The value that will be passed as the argument to
077  * start_func when the thread starts. The stack will be setup
078  * accordingly to simulate a real call to the function and really
079  * passing this arguement.
080  *
081  * @param stack_bottom The lowest address of the stack.
082  *
083  * @param stack_size The size of the stack.
084  *
085  * @param exit_func The address of the instruction executed after the
086  * function start_func has returned. This function takes 1 parameter
087  * as argument: exit_arg.
088  *
089  * @param exit_arg The argument passed to the function exit_func.
090  *
091  * @note the newly created context is INTERRUPTIBLE by default !
092  */
093 sos_ret_t sos_cpu_kstate_init(struct sos_cpu_state **kctxt,
094                               sos_cpu_kstate_function_arg1_t *start_func,
095                               sos_ui32_t  start_arg,
096                               sos_vaddr_t stack_bottom,
097                               sos_size_t  stack_size,
098                               sos_cpu_kstate_function_arg1_t *exit_func,
099                               sos_ui32_t  exit_arg);
100 
101 
102 /**
103  * Function to create an initial context for a user thread starting
104  * its execution at function user_start_PC with the user_start_arg
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 to create an initial context for a user thread, copy of an
145  * existing user thread context. The user thread needs a kernel stack
146  * for the syscalls and for handling interrupts: the address of this
147  * kernel stack is given by the kernel_stack_* parameters.
148  *
149  * @param uctxt The user thread CPU context to initialize. The
150  * address of the newly-initialized struct sos_cpu_state will be
151  * stored in this variable. The contents of this struct sos_cpu_state
152  * are actually located /inside/ the kernel stack of the thread.
153  *
154  * @param model_uctxt The user thread context that will be copied to
155  * the new user thread context
156  *
157  * @param user_retval The parameter passed to the initial user
158  * thread function.
159  *
160  * @param kernel_stack_bottom The lowest address of the kernel stack
161  * used to switch to user mode and to handle interrupts/exceptions.
162  *
163  * @param kernel_stack_size The size of the kernel stack (@see
164  * kernel_stack_bottom).
165  *
166  * @note the newly thread context is INTERRUPTIBLE !
167  */
168 sos_ret_t sos_cpu_ustate_duplicate(struct sos_cpu_state **uctxt,
169                                    const struct sos_cpu_state *model_uctxt,
170                                    sos_ui32_t   user_retval,
171                                    sos_vaddr_t  kernel_stack_bottom,
172                                    sos_size_t   kernel_stack_size);
173 
174 
175 /**
176  * Function that performs an immediate context-switch from one
177  * kernel/user thread to another one. It stores the current executing
178  * context in from_ctxt, and restores to_context on CPU.
179  *
180  * @param from_ctxt The address of the struct sos_cpu_state will be
181  * stored in this variable. Must NOT be NULL.
182  *
183  * @param to_ctxt The CPU will resume its execution with the struct
184  * sos_cpu_state located at this address. Must NOT be NULL.
185  */
186 void sos_cpu_context_switch(struct sos_cpu_state **from_ctxt,
187                             struct sos_cpu_state *to_ctxt);
188 
189 
190 /*
191  * Switch to the new given context (of a kernel/user thread) without
192  * saving the old context (of another kernel/user thread), and call
193  * the function reclaiming_func passing it the recalining_arg
194  * argument. The reclaining function is called from within the stack
195  * of the new context, so that it can (among other things) safely
196  * destroy the stack of the former context.
197  *
198  * @param switch_to_ctxt The context that will be restored on the CPU
199  *
200  * @param reclaiming_func The address of the function that will be
201  * called after having changed the stack, but before restoring the CPU
202  * context to switch_to_ctxt.
203  */
204 void
205 sos_cpu_context_exit_to(struct sos_cpu_state *switch_to_ctxt,
206                         sos_cpu_kstate_function_arg1_t *reclaiming_func,
207                         sos_ui32_t reclaiming_arg) __attribute__((noreturn));
208 
209 /* =======================================================================
210  * Public Accessor functions
211  */
212 
213 
214 /**
215  * Return whether the saved context was in kernel or user context
216  *
217  * @return TRUE when context was interrupted when in user mode, FALSE
218  * when in kernel mode, < 0 on error.
219  */
220 sos_ret_t
221 sos_cpu_context_is_in_user_mode(const struct sos_cpu_state *ctxt);
222 
223 
224 /**
225  * Return Program Counter stored in the saved kernel/user context
226  */
227 sos_vaddr_t sos_cpu_context_get_PC(const struct sos_cpu_state *ctxt);
228 
229 
230 /**
231  * Return Stack Pointer stored in the saved kernel/user context
232  */
233 sos_vaddr_t sos_cpu_context_get_SP(const struct sos_cpu_state *ctxt);
234 
235 
236 /**
237  * Dump the contents of the CPU context (bochs + x86_videomem)
238  */
239 void sos_cpu_context_dump(const struct sos_cpu_state *ctxt);
240 
241 
242 /* =======================================================================
243  * Public Accessor functions TO BE USED ONLY BY Exception handlers
244  */
245 
246 
247 /**
248  * Return the argument passed by the CPU upon exception, as stored in the
249  * saved context
250  */
251 sos_ui32_t sos_cpu_context_get_EX_info(const struct sos_cpu_state *ctxt);
252 
253 
254 /**
255  * Return the faulting address of the exception
256  */
257 sos_vaddr_t
258 sos_cpu_context_get_EX_faulting_vaddr(const struct sos_cpu_state *ctxt);
259 
260 
261 /**
262  * Change the return address of the given context
263  */
264 sos_ret_t
265 sos_cpu_context_set_EX_return_address(struct sos_cpu_state *ctxt,
266                                       sos_vaddr_t ret_vaddr);
267 
268 
269 /* =======================================================================
270  * Public Accessor functions TO BE USED ONLY BY the SYSCALL handler
271  */
272 
273 /**
274  * Low-level functions used by the syscall handler. They are
275  * responsible for retrieving the arguments passed to the syscall when
276  * a user thread makes a syscall. Some of these arguments are
277  * available as registers' values in the user context, some of them
278  * are user-space addresses given by these registers.
279  *
280  * @return SOS_OK on success, <0 otherwise
281  */
282 sos_ret_t sos_syscall_get1arg(const struct sos_cpu_state *user_ctxt,
283                               /* out */unsigned int *arg1);
284 
285 sos_ret_t sos_syscall_get2args(const struct sos_cpu_state *user_ctxt,
286                                /* out */unsigned int *arg1,
287                                /* out */unsigned int *arg2);
288 
289 sos_ret_t sos_syscall_get3args(const struct sos_cpu_state *user_ctxt,
290                                /* out */unsigned int *arg1,
291                                /* out */unsigned int *arg2,
292                                /* out */unsigned int *arg3);
293 
294 sos_ret_t sos_syscall_get4args(const struct sos_cpu_state *user_ctxt,
295                                /* out */unsigned int *arg1,
296                                /* out */unsigned int *arg2,
297                                /* out */unsigned int *arg3,
298                                /* out */unsigned int *arg4);
299 
300 sos_ret_t sos_syscall_get5args(const struct sos_cpu_state *user_ctxt,
301                                /* out */unsigned int *arg1,
302                                /* out */unsigned int *arg2,
303                                /* out */unsigned int *arg3,
304                                /* out */unsigned int *arg4,
305                                /* out */unsigned int *arg5);
306 
307 sos_ret_t sos_syscall_get6args(const struct sos_cpu_state *user_ctxt,
308                                /* out */unsigned int *arg1,
309                                /* out */unsigned int *arg2,
310                                /* out */unsigned int *arg3,
311                                /* out */unsigned int *arg4,
312                                /* out */unsigned int *arg5,
313                                /* out */unsigned int *arg6);
314 
315 sos_ret_t sos_syscall_get7args(const struct sos_cpu_state *user_ctxt,
316                                /* out */unsigned int *arg1,
317                                /* out */unsigned int *arg2,
318                                /* out */unsigned int *arg3,
319                                /* out */unsigned int *arg4,
320                                /* out */unsigned int *arg5,
321                                /* out */unsigned int *arg6,
322                                /* out */unsigned int *arg7);
323 
324 sos_ret_t sos_syscall_get8args(const struct sos_cpu_state *user_ctxt,
325                                /* out */unsigned int *arg1,
326                                /* out */unsigned int *arg2,
327                                /* out */unsigned int *arg3,
328                                /* out */unsigned int *arg4,
329                                /* out */unsigned int *arg5,
330                                /* out */unsigned int *arg6,
331                                /* out */unsigned int *arg7,
332                                /* out */unsigned int *arg8);
333 
334 
335 /* =======================================================================
336  * Macros controlling stack poisoning.
337  * Stack poisoning can be used to detect:
338  *  - unitialized local variables
339  *  - when the thread might have gone too deep in the stack
340  */
341 /** The signature of the poison */
342 #define SOS_CPU_STATE_STACK_POISON 0xa5
343 
344 /**
345  * When set, mean that the whole stack is poisoned to detect use of
346  * unititialized variables
347  */
348 #define SOS_CPU_STATE_DETECT_UNINIT_KERNEL_VARS
349 /* #undef SOS_CPU_STATE_DETECT_UNINIT_KERNEL_VARS */
350 
351 /**
352  * When set, mean that the bottom of the stack is poisoned to detect
353  * probable stack overflow. Its value indicates the number of bytes
354  * used for this detection.
355  */
356 #define SOS_CPU_STATE_DETECT_KERNEL_STACK_OVERFLOW  64
357 /* #undef SOS_CPU_STATE_DETECT_KERNEL_STACK_OVERFLOW */
358 
359 #if defined(SOS_CPU_STATE_DETECT_KERNEL_STACK_OVERFLOW)
360 void
361 sos_cpu_state_prepare_detect_kernel_stack_overflow(const struct sos_cpu_state *ctxt,
362                                                    sos_vaddr_t kernel_stack_bottom,
363                                                    sos_size_t kernel_stack_size);
364 void sos_cpu_state_detect_kernel_stack_overflow(const struct sos_cpu_state *ctxt,
365                                                 sos_vaddr_t kernel_stack_bottom,
366                                                 sos_size_t kernel_stack_size);
367 #else
368 # define sos_cpu_state_prepare_detect_kernel_stack_overflow(ctxt,stkbottom,stksize) \
369   ({ /* nop */ })
370 # define sos_cpu_state_detect_kernel_stack_overflow(ctxt,stkbottom,stksize) \
371   ({ /* nop */ })
372 #endif
373 
374 
375 /* =======================================================================
376  * Backtrace facility. To be used for DEBUGging purpose ONLY.
377  */
378 
379 
380 /**
381  * The function called at each step of the backtrace iterations
382  *
383  * @param PC The address of the next instruction of the function that
384  * will be executed
385  *
386  * @param params The address of the array of the parameteres that have
387  * been passed to the function considered
388  *
389  * @param depth The index of the iteration (ie the depth of the
390  * current frame into the stack)
391  *
392  * @param custom_arg Whatever you want: this is the argument passed as
393  * custom_arg to sos_backtrace()
394  */
395 typedef void (sos_backtrace_callback_t)(sos_vaddr_t PC,
396                                         sos_vaddr_t params,
397                                         sos_ui32_t depth,
398                                         void *custom_arg);
399 
400 
401 /**
402  * Call the backtracer callback on each frame stored in the cpu_state
403  *
404  * @param cpu_state The CPU context we want to explore. MUST be the
405  * context of a thread in Kernel mode, or NULL. When NULL: backtrace
406  * the current CPU context.
407  *
408  * @param max_depth The maximum number of frames to explore
409  *
410  * @param stack_bottom The lower boundary of the stack. This is used
411  * to make sure that the frame addresses fit inside the stack
412  * boudaries (ie are potentially correct).
413  *
414  * @param stack_size The size of the stack. Same comment.
415  *
416  * @param backtracer The function to call to handle the frame for each
417  * iteration
418  *
419  * @param custom_arg The arg passed as custom_arg to the backtracer
420  *
421  * @return The number of frames explored.
422  *
423  * @note Might be inaccurate when gcc's -fomit-frame-pointer has been
424  * used.
425  */
426 sos_ui32_t sos_backtrace(const struct sos_cpu_state *cpu_state,
427                          sos_ui32_t max_depth,
428                          sos_vaddr_t stack_bottom,
429                          sos_size_t stack_size,
430                          sos_backtrace_callback_t * backtracer,
431                          void *custom_arg);
432 
433 #endif /* _SOS_CPUCTXT_H_ */

source navigation ] diff markup ] identifier search ] general search ]