⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cpu_context.h

📁 Simple Operating Systems (简称SOS)是一个可以运行在X86平台上(包括QEMU
💻 H
字号:
/* Copyright (C) 2005  David Decotigny   Copyright (C) 2000-2004, The KOS team   This program is free software; you can redistribute it and/or   modify it under the terms of the GNU General Public License   as published by the Free Software Foundation; either version 2   of the License, or (at your option) any later version.      This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.      You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,   USA. */#ifndef _SOS_CPUCTXT_H_#define _SOS_CPUCTXT_H_/** * @file cpu_context.h * * Low level API to manage kernel and user thread CPU contexts. Should * be some kind of architecture-independent. */#include <sos/types.h>#include <sos/errno.h>/** * Prepare the system to deal with multiple CPU execution contexts */sos_ret_t sos_cpu_context_subsystem_setup();/** * Opaque structure storing the CPU context of an inactive kernel or * user thread, as saved by the low level primitives below or by the * interrupt/exception handlers. * * @note This is an (architecture-independent) forward declaration: * see cpu_context.c and the *.S files for its * (architecture-dependent) definition. */struct sos_cpu_state;/** * The type of the functions passed as arguments to the Kernel thread * related functions. */typedef void (sos_cpu_kstate_function_arg1_t(sos_ui32_t arg1));/** * Function to create an initial context for a kernel thread starting * its execution at function start_func with the argument initial_arg, * and having the stack defined by stack_bottom/stack_size. When the * start_func function returns, the function exit_func is called with * argument exit_arg. * * @param kctxt The kernel thread CPU context to initialize. The * address of the newly-initialized struct sos_cpu_state will be * stored in this variable. The contents of this struct sos_cpu_state * are actually located /inside/ the stack. * * @param start_func The address of the first instruction that will be * executed when this context will be first transferred on * CPU. Practically speaking, this is the address of a function that * is assumed to take 1 argument. * * @param start_arg The value that will be passed as the argument to * start_func when the thread starts. The stack will be setup * accordingly to simulate a real call to the function and really * passing this arguement. * * @param stack_bottom The lowest address of the stack. * * @param stack_size The size of the stack. * * @param exit_func The address of the instruction executed after the * function start_func has returned. This function takes 1 parameter * as argument: exit_arg. * * @param exit_arg The argument passed to the function exit_func. * * @note the newly created context is INTERRUPTIBLE by default ! */sos_ret_t sos_cpu_kstate_init(struct sos_cpu_state **kctxt,			      sos_cpu_kstate_function_arg1_t *start_func,			      sos_ui32_t  start_arg,			      sos_vaddr_t stack_bottom,			      sos_size_t  stack_size,			      sos_cpu_kstate_function_arg1_t *exit_func,			      sos_ui32_t  exit_arg);/** * Function to create an initial context for a user thread starting * its execution at function user_start_PC with the user_start_arg * argument. The address of the user stack before any modification by * the ustate_init() function is given by user_start_SP. The user * thread starts in user space first and needs a kernel stack for * the syscalls and for handling interrupts: the address of this * kernel stack is given by the kernel_stack_* parameters. * * @param uctxt The user thread CPU context to initialize. The * address of the newly-initialized struct sos_cpu_state will be * stored in this variable. The contents of this struct sos_cpu_state * are actually located /inside/ the kernel stack of the thread. * * @param user_start_PC The address of the first instruction that will * be executed in user mode when this context will be first * transferred on CPU. Practically speaking, this is the address of a * function that is assumed to take 1 argument. * * @param user_start_SP The initial user stack address. * * @param user_start_argX The 2 parameters passed to the initial user * thread function (in registers). * * @param kernel_stack_bottom The lowest address of the kernel stack * used to switch to user mode and to handle interrupts/exceptions. * * @param kernel_stack_size The size of the kernel stack (@see * kernel_stack_bottom). * * @note the newly thread context is INTERRUPTIBLE ! */sos_ret_t sos_cpu_ustate_init(struct sos_cpu_state **uctxt,			      sos_uaddr_t  user_start_PC,			      sos_ui32_t   user_start_arg1,			      sos_ui32_t   user_start_arg2,			      sos_uaddr_t  user_initial_SP,			      sos_vaddr_t  kernel_stack_bottom,			      sos_size_t   kernel_stack_size);/** * Function to create an initial context for a user thread, copy of an * existing user thread context. The user thread needs a kernel stack * for the syscalls and for handling interrupts: the address of this * kernel stack is given by the kernel_stack_* parameters. * * @param uctxt The user thread CPU context to initialize. The * address of the newly-initialized struct sos_cpu_state will be * stored in this variable. The contents of this struct sos_cpu_state * are actually located /inside/ the kernel stack of the thread. * * @param model_uctxt The user thread context that will be copied to * the new user thread context * * @param user_retval The parameter passed to the initial user * thread function. * * @param kernel_stack_bottom The lowest address of the kernel stack * used to switch to user mode and to handle interrupts/exceptions. * * @param kernel_stack_size The size of the kernel stack (@see * kernel_stack_bottom). * * @note the newly thread context is INTERRUPTIBLE ! */sos_ret_t sos_cpu_ustate_duplicate(struct sos_cpu_state **uctxt,				   const struct sos_cpu_state *model_uctxt,				   sos_ui32_t   user_retval,				   sos_vaddr_t  kernel_stack_bottom,				   sos_size_t   kernel_stack_size);/** * Function that performs an immediate context-switch from one * kernel/user thread to another one. It stores the current executing * context in from_ctxt, and restores to_context on CPU. * * @param from_ctxt The address of the struct sos_cpu_state will be * stored in this variable. Must NOT be NULL. * * @param to_ctxt The CPU will resume its execution with the struct * sos_cpu_state located at this address. Must NOT be NULL. */void sos_cpu_context_switch(struct sos_cpu_state **from_ctxt,			    struct sos_cpu_state *to_ctxt);/* * Switch to the new given context (of a kernel/user thread) without * saving the old context (of another kernel/user thread), and call * the function reclaiming_func passing it the recalining_arg * argument. The reclaining function is called from within the stack * of the new context, so that it can (among other things) safely * destroy the stack of the former context. * * @param switch_to_ctxt The context that will be restored on the CPU * * @param reclaiming_func The address of the function that will be * called after having changed the stack, but before restoring the CPU * context to switch_to_ctxt. */voidsos_cpu_context_exit_to(struct sos_cpu_state *switch_to_ctxt,			sos_cpu_kstate_function_arg1_t *reclaiming_func,			sos_ui32_t reclaiming_arg) __attribute__((noreturn));/* ======================================================================= * Public Accessor functions *//** * Return whether the saved context was in kernel or user context * * @return TRUE when context was interrupted when in user mode, FALSE * when in kernel mode, < 0 on error. */sos_ret_tsos_cpu_context_is_in_user_mode(const struct sos_cpu_state *ctxt);/** * Return Program Counter stored in the saved kernel/user context */sos_vaddr_t sos_cpu_context_get_PC(const struct sos_cpu_state *ctxt);/** * Return Stack Pointer stored in the saved kernel/user context */sos_vaddr_t sos_cpu_context_get_SP(const struct sos_cpu_state *ctxt);/** * Dump the contents of the CPU context (bochs + x86_videomem) */void sos_cpu_context_dump(const struct sos_cpu_state *ctxt);/* ======================================================================= * Public Accessor functions TO BE USED ONLY BY Exception handlers *//** * Return the argument passed by the CPU upon exception, as stored in the * saved context */sos_ui32_t sos_cpu_context_get_EX_info(const struct sos_cpu_state *ctxt);/** * Return the faulting address of the exception */sos_vaddr_tsos_cpu_context_get_EX_faulting_vaddr(const struct sos_cpu_state *ctxt);/** * Change the return address of the given context */sos_ret_tsos_cpu_context_set_EX_return_address(struct sos_cpu_state *ctxt,				      sos_vaddr_t ret_vaddr);/* ======================================================================= * Public Accessor functions TO BE USED ONLY BY the SYSCALL handler *//** * Low-level functions used by the syscall handler. They are * responsible for retrieving the arguments passed to the syscall when * a user thread makes a syscall. Some of these arguments are * available as registers' values in the user context, some of them * are user-space addresses given by these registers. * * @return SOS_OK on success, <0 otherwise */sos_ret_t sos_syscall_get1arg(const struct sos_cpu_state *user_ctxt,			      /* out */unsigned int *arg1);sos_ret_t sos_syscall_get2args(const struct sos_cpu_state *user_ctxt,			       /* out */unsigned int *arg1,			       /* out */unsigned int *arg2);sos_ret_t sos_syscall_get3args(const struct sos_cpu_state *user_ctxt,			       /* out */unsigned int *arg1,			       /* out */unsigned int *arg2,			       /* out */unsigned int *arg3);sos_ret_t sos_syscall_get4args(const struct sos_cpu_state *user_ctxt,			       /* out */unsigned int *arg1,			       /* out */unsigned int *arg2,			       /* out */unsigned int *arg3,			       /* out */unsigned int *arg4);sos_ret_t sos_syscall_get5args(const struct sos_cpu_state *user_ctxt,			       /* out */unsigned int *arg1,			       /* out */unsigned int *arg2,			       /* out */unsigned int *arg3,			       /* out */unsigned int *arg4,			       /* out */unsigned int *arg5);sos_ret_t sos_syscall_get6args(const struct sos_cpu_state *user_ctxt,			       /* out */unsigned int *arg1,			       /* out */unsigned int *arg2,			       /* out */unsigned int *arg3,			       /* out */unsigned int *arg4,			       /* out */unsigned int *arg5,			       /* out */unsigned int *arg6);sos_ret_t sos_syscall_get7args(const struct sos_cpu_state *user_ctxt,			       /* out */unsigned int *arg1,			       /* out */unsigned int *arg2,			       /* out */unsigned int *arg3,			       /* out */unsigned int *arg4,			       /* out */unsigned int *arg5,			       /* out */unsigned int *arg6,			       /* out */unsigned int *arg7);sos_ret_t sos_syscall_get8args(const struct sos_cpu_state *user_ctxt,			       /* out */unsigned int *arg1,			       /* out */unsigned int *arg2,			       /* out */unsigned int *arg3,			       /* out */unsigned int *arg4,			       /* out */unsigned int *arg5,			       /* out */unsigned int *arg6,			       /* out */unsigned int *arg7,			       /* out */unsigned int *arg8);/* ======================================================================= * Macros controlling stack poisoning. * Stack poisoning can be used to detect: *  - unitialized local variables *  - when the thread might have gone too deep in the stack *//** The signature of the poison */#define SOS_CPU_STATE_STACK_POISON 0xa5/** * When set, mean that the whole stack is poisoned to detect use of * unititialized variables */#define SOS_CPU_STATE_DETECT_UNINIT_KERNEL_VARS/* #undef SOS_CPU_STATE_DETECT_UNINIT_KERNEL_VARS *//** * When set, mean that the bottom of the stack is poisoned to detect * probable stack overflow. Its value indicates the number of bytes * used for this detection. */#define SOS_CPU_STATE_DETECT_KERNEL_STACK_OVERFLOW  64/* #undef SOS_CPU_STATE_DETECT_KERNEL_STACK_OVERFLOW */#if defined(SOS_CPU_STATE_DETECT_KERNEL_STACK_OVERFLOW)voidsos_cpu_state_prepare_detect_kernel_stack_overflow(const struct sos_cpu_state *ctxt,						   sos_vaddr_t kernel_stack_bottom,						   sos_size_t kernel_stack_size);void sos_cpu_state_detect_kernel_stack_overflow(const struct sos_cpu_state *ctxt,						sos_vaddr_t kernel_stack_bottom,						sos_size_t kernel_stack_size);#else# define sos_cpu_state_prepare_detect_kernel_stack_overflow(ctxt,stkbottom,stksize) \  ({ /* nop */ })# define sos_cpu_state_detect_kernel_stack_overflow(ctxt,stkbottom,stksize) \  ({ /* nop */ })#endif/* ======================================================================= * Backtrace facility. To be used for DEBUGging purpose ONLY. *//** * The function called at each step of the backtrace iterations * * @param PC The address of the next instruction of the function that * will be executed * * @param params The address of the array of the parameteres that have * been passed to the function considered * * @param depth The index of the iteration (ie the depth of the * current frame into the stack) * * @param custom_arg Whatever you want: this is the argument passed as * custom_arg to sos_backtrace() */typedef void (sos_backtrace_callback_t)(sos_vaddr_t PC,					sos_vaddr_t params,					sos_ui32_t depth,					void *custom_arg);/** * Call the backtracer callback on each frame stored in the cpu_state * * @param cpu_state The CPU context we want to explore. MUST be the * context of a thread in Kernel mode, or NULL. When NULL: backtrace * the current CPU context. * * @param max_depth The maximum number of frames to explore * * @param stack_bottom The lower boundary of the stack. This is used * to make sure that the frame addresses fit inside the stack * boudaries (ie are potentially correct). * * @param stack_size The size of the stack. Same comment. * * @param backtracer The function to call to handle the frame for each * iteration * * @param custom_arg The arg passed as custom_arg to the backtracer * * @return The number of frames explored. * * @note Might be inaccurate when gcc's -fomit-frame-pointer has been * used. */sos_ui32_t sos_backtrace(const struct sos_cpu_state *cpu_state,			 sos_ui32_t max_depth,			 sos_vaddr_t stack_bottom,			 sos_size_t stack_size,			 sos_backtrace_callback_t * backtracer,			 void *custom_arg);#endif /* _SOS_CPUCTXT_H_ */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -