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 * api1.cpp, version 1.0 * 00009 ************************************************************ 00010 * * 00011 *The first panalix API * 00012 * * 00013 *28'07'04- first revision (1.0) * 00014 * * 00015 ***********************************************************/ 00016 00020 #include "src/common/shared.hpp" 00021 #include "src/memory/memset.hpp" 00022 #include "src/memory/align.hpp" 00023 #include "src/memory/alloc4k.hpp" 00024 #include "src/memory/heap.hpp" 00025 #include "src/ipc/msg.hpp" 00026 #include "src/thread/process.hpp" 00027 #include "src/thread/scheduler.hpp" 00028 #include "src/module/api1.hpp" 00029 00030 namespace API { 00031 namespace v1 { 00032 00033 //checks whether the whole object is in kernel space 00034 bool isKernelSpace(uint32 addr, uint32 size) 00035 { 00036 return (addr >= mem_kernel_start) || //it begins in kernel space 00037 (size > 0xffffffff-addr+1) || //it begins in user space, partly in kernel space, wraps over the 33bit 00038 (addr+size > mem_kernel_start); //begins in user space, ends in kernel space 00039 } 00040 00041 int req(struct env_t *env, int *args) 00042 { 00043 int i; 00044 // uint32 n,x; 00045 // struct Thread::thread_t *thread; 00046 // struct blist_s *bl; 00047 // struct mmap_s *mmaps; 00048 // struct IPC::Message::message *msg; 00049 i=0; 00050 //sanity 00051 if ((args==NULL)||(env==NULL)||(env->code==NULL)||(env->thread==NULL)||(Thread::Scheduler::multitasking_running==false)) 00052 return ESANITY; 00053 00054 switch(env->code->r.r_eax) 00055 { 00056 // API- send a message to thread args[0] of process %ebx, from user-level data starting at args[1] of size args[2] with flags of args[3]. returns EFAIL if data is in kernel space or the dest thread is not found. 00057 // case API_SENDMSG: 00058 // //sanity 00059 // if (isKernelSpace(args[2], args[3])) 00060 // return EFAIL; 00061 // //findout receiver 00062 // thread= Thread::ThreadGet(env->code->r.r_ebx, args[0]); 00063 // if (thread==NULL) 00064 // return EFAIL; 00065 // return env->thread->inbox.ksend(&thread->inbox, (void*)args[1], args[2], args[3]); 00066 00067 // API- recv a message, recv a message from a specified mailbox or return count of incoming messages. 00068 // %ebx=1 recv, %ebx=2 recv src, %ebx=3 count. 00069 // recv: return: args[0] with address to the message struct. 00070 case API_RECVMSG: 00071 // receive the message 00072 // allocate space in the user space for the data 00073 // copy the message 00074 // dispose the message from the original heap (a copy in the user space exists) 00075 // return 00076 // if (env->code->r.r_ebx==1) 00077 // { 00078 // i= env->thread->inbox.kreceive(&msg); 00079 // if (i!=ESUCCESS) return i; 00080 // i= env->mtree->memory_map.fitbelow(sizeof(msg)+msg->size, PAGE_ALIGN, mem_user_end+1, ME_USERDATA, NULL,0/*info*/, &n, 0/*threadno*/, NULL/*destroy*/, false); 00081 // if (i!=ESUCCESS) {ThreadFail("dropped message"); return i; } 00082 // for (x=0;x<msg->size+sizeof(msg);x+=PAGE_SIZE) 00083 // env->mtree->pte_alloc(x+n,PTE_WRITEABLE|PTE_USER); 00084 // memmove((void*)n, msg, sizeof(IPC::Message::message)+msg->size); 00085 // env->thread->inbox.free_msg(msg); 00086 // args[0]=n; 00087 // alert("\n");alert(n); 00088 // return ESUCCESS; 00089 // } 00090 // return EFAIL; 00091 // API- unalloc the space given with the message; %ebx is the address 00092 /* case API_FREEMSG: 00093 bl= env->mtree->memory_map.find(env->code->r.r_ebx); 00094 if (bl==NULL) return EFAIL; 00095 mmaps= bli_dt(bl,struct mmap_s*); 00096 if (mmaps->type != ME_USERDATA) return EINVAL; 00097 for(n=0;n<mmaps->size;n+=PAGE_SIZE) 00098 { 00099 x= env->mtree->pte_val(n+env->code->r.r_ebx); 00100 if (x&PTE_PRESENT) 00101 disalloc4k(x&0xfffff000); 00102 env->mtree->pte_umap(n+env->code->r.r_ebx); 00103 } 00104 env->mtree->memory_map.del(bl); 00105 return ESUCCESS;*/ 00106 // API- cout a given text to std output 00107 case API_COUT: 00108 cout((char*)args[0]); 00109 return ESUCCESS; 00110 // API- get the process & thread no 00111 case API_GETPROCNO: 00112 args[0]= env->proc->no; 00113 args[1]= env->thread->no; 00114 return ESUCCESS; 00115 // API- sleep thread 00116 case API_SLEEP: 00117 return Thread::sleep(*(uint64*)&args[0]); 00118 // API- morecore 00119 case API_MORECORE: 00120 args[0]=user_morecore(env, args[0]); 00121 return ESUCCESS; 00122 } 00123 00124 return EINVAL; 00125 } 00126 00127 00128 //allocate some virtual space for the process, and lazy it 00129 uint32 user_morecore(struct env_t *env, uint32 cnt) 00130 { 00131 int i; 00132 uint32 n; 00133 uint32 loc; 00134 //allocate virtual memory in the process's user space 00135 i= env->mtree->memory_map.fitbelow(cnt*PAGE_SIZE, PAGE_ALIGN, mem_user_end+1, ME_UDATA, NULL/*dt*/, 0/*info*/, &loc, 0, &UDATA_destroy, false); 00136 if (i!=ESUCCESS) return NULL; 00137 //now allocate physical memory to it; if possible, use demand-paging 00138 for (n=0;n<cnt;n++) { 00139 i= env->mtree->pte_alloc(loc+n*PAGE_SIZE, PTE_WRITEABLE); 00140 if (i!=ESUCCESS) { complain("!!fail and memory not regained"); return i; } 00141 } 00142 00143 return loc; 00144 } 00145 00146 //destroys the UDATA alloced for the process 00147 int UDATA_destroy(mmap_t *mt, mmap_s *ms) 00148 { 00149 notimpl(-1); 00150 } 00151 00152 }; /*namespace v1*/ 00153 }; /*namespace API*/ 00154 00155 00156 /*********************************************************** 00157 * * 00158 *panalix 0.06 (c) Adrian Panasiuk 2002-4 * 00159 *adek336[at]o2.pl, panalix.prv.pl * 00160 * * 00161 ***********************************************************/