00001 /*********************************************************** 00002 *PANALIX 0.06, (c) Adrian Panasiuk 2002-4 * 00003 *adek336[at]o2.pl, panalix.prv.pl * 00004 *under GPLv3 license * 00005 * * 00006 *panalix - small osdev project * 00007 ************************************************************ 00008 * sysenter.cpp, version 1.0 * 00009 ************************************************************ 00010 * * 00011 *Sysenter, and the API is here. * 00012 * * 00013 *28'07'04- first revision (1.0) * 00014 * * 00015 ***********************************************************/ 00016 00017 #include "src/common/shared.hpp" 00018 #include "src/memory/memset.hpp" 00019 #include "src/memory/align.hpp" 00020 #include "src/memory/heap.hpp" 00021 #include "src/thread/process.hpp" 00022 #include "src/thread/scheduler.hpp" 00023 #include "src/module/api1.hpp" 00024 #include "src/arch/x86/gdt.hpp" 00025 #include "src/arch/x86/msr.hpp" 00026 #include "src/arch/x86/interr.hpp" 00027 #include "src/arch/x86/except_c.hpp" 00028 #include "src/arch/x86/sysenter.hpp" 00029 00030 namespace Arch { 00031 namespace x86 { 00032 namespace Sysenter { 00033 00034 const uint32 SYSENTTEMPBUF = 0x200; 00035 char SysenterTempBuf[SYSENTTEMPBUF]; 00036 00037 extern "C" void sysentry(); 00038 00039 void init() 00040 { 00041 union 00042 { 00043 uint64 q; 00044 uint32 l[2]; 00045 } uu; 00046 uu.l[1] = 0; 00047 /*write sep msr for the code selector*/ 00048 wrmsr(SYSENTER_CS_MSR, GDT::code_sel_kernel); 00049 /*kernel stack pointer*/ 00050 uu.l[0] = (uint32) &SysenterTempBuf[SYSENTTEMPBUF]; 00051 wrmsr(SYSENTER_ESP_MSR, uu.q); 00052 /*kernel entry point*/ 00053 uu.l[0] = (uint32) &sysentry; 00054 wrmsr(SYSENTER_EIP_MSR, uu.q); 00055 } 00056 00057 //this is the handler 00058 //upon enter, sysenter requires that the user stack holds 4 ints which can be accessed 00059 int SysEnter(class Arch::x86::Interr::except2_t *code) 00060 { 00061 env_t env; 00062 int *args; 00063 int i= ESUCCESS; 00064 // blocking routines will only block a single thread 00065 asm volatile("sti"); 00066 //get info 00067 EnvGet(&env); 00068 if (env.proc==NULL) 00069 sysfail("env.proc==NULL ;((("); 00070 args= (int*)(code->esp); 00071 //process 00072 switch ( env.proc->env.api ) { 00073 case API_NONE: 00074 if (code->r.r_eax + code->r.r_ebx != APIMAGIC) //checksum 00075 ProcFail("bad API_NONE request"); 00076 env.proc->env.api= code->r.r_eax; 00077 i= ESUCCESS; 00078 break; 00079 case API_v1: 00080 i= API::v1::req(&env,args); 00081 break; 00082 default: 00083 ProcFail("invalid api version"); 00084 break; 00085 } 00086 00087 code->r.r_eax= i; 00088 return ESUCCESS; 00089 } 00090 00091 00092 }; /*namespace Sysenter*/ 00093 }; /*namespace x86*/ 00094 }; /*namespace Arch*/ 00095 00096 00097 /*********************************************************** 00098 * * 00099 *panalix 0.06 (c) Adrian Panasiuk 2002-4 * 00100 *adek336[at]o2.pl, panalix.prv.pl * 00101 * * 00102 ***********************************************************/