proc.c

00001 /***************************************************************************
00002                           proc.c  -  description
00003                              -------------------
00004     begin                : Sat Dec 27 2003
00005     copyright            : (C) 2003 by Dynacube Team
00006     email                : mdshah82@yahoo.com
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
00015  *                                                                         *
00016  ***************************************************************************/
00017 
00018  #include "proc/proc.h"
00019  #include "core/kerror.h"
00020  #include "common/ktypes.h"
00021  #include "mm/mm.h"
00022  #include "common/kconst.h"
00023  #include "core/ktask.h"
00024  #include "core/kinit.h"
00025  #include "common/ds/queue.h"
00026  #include "core/kint.h"
00027  #include "gui/svga.h"
00028  #include "fs/fat12.h"
00029 
00030  LDT _ldt[MAX_PROC] __attribute__((aligned (8)));
00031  SEG_DESC _ldte[MAX_PROC][3] __attribute__((aligned (8)));
00032 
00033  PROC _proc[MAX_PROC];
00034 
00035  DW cur_pid = MAX_PROC+1;
00036 
00037  DB which_task = 0; //Currently used USR_TSS
00038  
00039  SDB create(char *pathname)
00040  {
00041          DB pid, i, j;
00042          DD addr, base, limit;
00043          DW flags = 0;
00044    SDD pg_num[MAX_PROC_SIZE/_4KB] = {-1}; 
00045 
00046          SEG_DESC temp;
00047          char *c;
00048 
00049          for(pid=0 ; pid < MAX_PROC ; pid++)
00050          {
00051                  if(_proc[pid].avl == _true)
00052                  {
00053                           _proc[pid].avl = _false;
00054                                 break;
00055                  }
00056          }
00057 
00058          printf("\nPID: %d\n",pid);
00059    
00060          if(pid == MAX_PROC)
00061          {
00062                         printf("\nFork Failure");
00063                         return FORK_FAILURE;
00064    }
00065    
00066          for(i = 0 ; i < (MAX_PROC_SIZE/_4KB) ; i++)
00067          {
00068                  pg_num[i] = findpage();
00069 
00070                  if(pg_num[i] == PAGE_NOT_FOUND)
00071                  {
00072                           for(j = 0 ; j < i ; j++)
00073                                 freepage(pg_num[j]);
00074 
00075                         return FORK_FAILURE;
00076      }
00077 
00078                  addr = KERNEL_SIZE + (pg_num[i] * _4KB); //Physical
00079 
00080                  printf("\tA %x Pg %d",addr,pg_num[i]);
00081                  _pgte[pid][i] = addr | 7; //User R/W Present
00082          }
00083 
00084    //Only variables here & the rest in proc_init
00085    _proc[pid].esp    = MAX_PROC_SIZE-1;
00086    _proc[pid].eip    = 0;
00087 
00088    enq(&ready_q,pid);
00089    load(pathname,pid);
00090    return pid;
00091  }
00092 
00093  void schedule()
00094  {
00095          SEG_DESC tmp, *t;
00096          clearDESC(&tmp);
00097          DW ldt_flags = 0x882;//IA32 - 74 LDT_TYPE = 0010        0x4E2
00098          
00099         //       Choose ready_q and set cur_pid
00100     if(findq(&ready_q,GUI_PID) == 0)
00101     {
00102      cur_pid = GUI_PID; 
00103     }
00104     else
00105     {
00106       cur_pid = deq(&ready_q);
00107     
00108       if(cur_pid == NULL_PID)    
00109         cur_pid = deq(&ready_q);
00110     }
00111     
00112     if(_proc[cur_pid].avl)
00113      {
00114         if(_proc[NULL_PID].avl)
00115         {
00116           while(1)
00117            printf("in where it shouldn't be\n");
00118           memcpy((void *)(KERNEL_SIZE),(void *)null_proc,512);
00119         } 
00120 
00121         cur_pid = NULL_PID;
00122      }
00123 
00124          createDESC(&tmp,(_ldt[cur_pid].hibase<<16)|_ldt[cur_pid].lobase,_ldt[cur_pid].limit,ldt_flags);
00125          addDesc(LDT_USR_SEL,&tmp);
00126 
00127    _task[which_task].eip    = _proc[cur_pid].eip;
00128    _task[which_task].es     = _proc[cur_pid].es;
00129    _task[which_task].fs     = _proc[cur_pid].fs;
00130    _task[which_task].gs     = _proc[cur_pid].gs;
00131    
00132    _task[which_task].eax    = _proc[cur_pid].eax;
00133    _task[which_task].ebx    = _proc[cur_pid].ebx;
00134    _task[which_task].ecx    = _proc[cur_pid].ecx;
00135    _task[which_task].edx    = _proc[cur_pid].edx;
00136    _task[which_task].esi    = _proc[cur_pid].esi;
00137    _task[which_task].edi    = _proc[cur_pid].edi;
00138    _task[which_task].ebp    = _proc[cur_pid].ebp;
00139                             
00140    _task[which_task].cs                 = _proc[cur_pid].cs;
00141    _task[which_task].ds                 = _proc[cur_pid].ds;
00142    _task[which_task].ss                 = _proc[cur_pid].ss;
00143    _task[which_task].esp                = _proc[cur_pid].esp;
00144    _task[which_task].ss0                = _system.ss0;
00145    _task[which_task].esp0               = _system.esp0;
00146    _task[which_task].ldt_sel = LDT_USR_SEL*8;
00147    _task[which_task].eflags  = _proc[cur_pid].eflags;  //|(1<<9)
00148    _task[which_task].cr3                        = _proc[cur_pid].cr3; //(_system.cr3 & 0xFFF) | (((DD)_pgde) & 0xFFFFF000);
00149 
00150    _task[which_task].io_map  = 0x70;
00151 
00152    which_task = !which_task;
00153 
00154    //Clearing Busy Bit
00155     t = (SEG_DESC*)(GDT_BASE+SYS_TSS_SEL*8);
00156     t->flags_8_15 &= ~0x2;
00157     asm("ltr %%ax"::"a"(SYS_TSS_SEL*8));
00158     t->flags_8_15 &= ~0x2;  
00159 
00160   if(which_task)
00161   {
00162    t = (SEG_DESC*)(GDT_BASE+TASK1_TSS_SEL*8);
00163    t->flags_8_15 &= ~0x2;
00164    asm("lcall %0,$0"::"i"(TASK1_TSS_SEL*8));
00165   }
00166   else
00167   {
00168    t = (SEG_DESC*)(GDT_BASE+TASK2_TSS_SEL*8);
00169    t->flags_8_15 &= ~0x2;
00170    asm("lcall %0,$0"::"i"(TASK2_TSS_SEL*8));
00171   }
00172  }
00173 
00174 
00175  void proc_init()
00176  {
00177          DB pid;
00178    DB pg_dir_offset = (KERNEL_SIZE/_4MB)+((KERNEL_SIZE%_4MB)?1:0);
00179          DW flags = 0;
00180          DD base, limit;
00181    
00182          for(pid=0 ; pid < MAX_PROC ; pid++)
00183          {
00184                  _proc[pid].avl = _true;
00185      _proc[pid].msg_q_delim  = 0;
00186      _proc[pid].wait_int_num = 0xFFFF;
00187      _proc[pid].time_out     = 0;
00188 
00189    _pgde[pid+pg_dir_offset] = ((DD)_pgte[pid]) | 7; // _pgde[0 to 2] for kernel
00190 
00191    clearDESC(&_ldte[pid][0]);
00192    clearDESC(&_ldte[pid][1]);
00193    clearDESC(&_ldte[pid][2]);
00194 
00195    flags = ((F_G|F_D_B)<<8)|F_P|F_S|F_TYPE_CODE|F_TYPE_R|F_SD_DPL_3; //CODE
00196    base  = (pid+pg_dir_offset) << 22;
00197    limit = (MAX_PROC_SIZE/_4KB);
00198    createDESC(&_ldte[pid][0],base,limit,flags);
00199 
00200    flags = ((F_G|F_D_B)<<8)|F_P|F_S|F_TYPE_DATA|F_TYPE_W|F_SD_DPL_3;//|F_TYPE_E;//; //DATA
00201    base  = (pid+pg_dir_offset) << 22;
00202    limit = (MAX_PROC_SIZE/_4KB);
00203    createDESC(&_ldte[pid][1],base,limit,flags);
00204 
00205    flags = ((F_G|F_D_B)<<8)|F_P|F_S|F_TYPE_DATA|F_TYPE_W|F_SD_DPL_3|F_TYPE_E; //Stack
00206    base  = (pid+pg_dir_offset) << 22;
00207    limit = 0;
00208    createDESC(&_ldte[pid][2],base,limit,flags);
00209 
00210    _ldt[pid].hibase = (((DD)&_ldte[pid][0]) >> 16);
00211    _ldt[pid].lobase = (((DD)&_ldte[pid][0]) & 0xFFFF);
00212    _ldt[pid].limit  = 3*8 - 1;
00213 
00214    _proc[pid].cs = (0x0<<3)|(0x1<<2)|0x3;
00215    _proc[pid].ds = (0x1<<3)|(0x1<<2)|0x3;
00216    _proc[pid].ss = (0x2<<3)|(0x1<<2)|0x3;
00217    _proc[pid].es = (0x1<<3)|(0x1<<2)|0x3;
00218    _proc[pid].fs = (0x1<<3)|(0x1<<2)|0x3;
00219 
00220    _proc[pid].cr3 = (_system.cr3 & 0xFFF) | (((DD)_pgde) & 0xFFFFF000);
00221    _proc[pid].eflags = 2 | (1<<9);
00222          }       
00223  }
00224 
00225 
00226 void do_exit(DW pid)
00227  {
00228    DD i;
00229    printf("exit called\n");
00230    ginfo(400,350,"Exit Called");
00231    ginfo(400,400,itoa(pid,10));
00232 
00233    remove(&ready_q,pid);
00234 
00235    _proc[pid].avl = _true;
00236    _proc[pid].msg_q_delim  = 0;
00237    _proc[pid].wait_int_num = 0xFFFF;
00238    _proc[pid].time_out     = 0;
00239 
00240    for(i = 0; i<(MAX_PROC_SIZE/_4KB);i++)
00241    {
00242      freepage(((_pgte[pid][i] ^ 7) - KERNEL_SIZE)/_4KB);
00243    }
00244    printf("exit pid : %d",pid);
00245 
00246    //Close all windows
00247    _Z11destroy_wint(pid);
00248 
00249    //Close all files
00250    fscloseAll(pid);
00251  }
00252 
00253 SDB fork()
00254 {
00255   SDB pid;// = create();
00256   
00257   if(pid != FORK_FAILURE)  
00258   {
00259    //Setting the pid in the Child Process
00260    _proc[pid].eax = 0;
00261    // and the pid of child in the Parent Process
00262    _proc[cur_pid].eax = pid;
00263   }
00264         return pid;
00265 }
00266 
00267 SDW load(char *fname,DW pid)
00268 {
00269   fs_request fs_r;
00270   fs_r.type = LOAD;
00271 
00272         fs_r.load.fname = (DB *)fname;
00273   fs_r.from_pid = pid;
00274         if(addfsreq(&fs_r) != 0)
00275   {
00276     do_exit(pid);
00277   }
00278   else
00279   {
00280    remove(&ready_q,pid);
00281    enq(&fs_q,pid);
00282   }
00283 }
00284 
00285 void forkNULL()
00286 {
00287          DB pid, i, j;
00288          DD addr, base, limit;
00289          DW flags = 0;
00290    SDD pg_num[MAX_PROC_SIZE/_4KB] = {-1};
00291 
00292          SEG_DESC temp;
00293          char *c;
00294 
00295          for(pid=0 ; pid < MAX_PROC ; pid++)
00296          {
00297                  if(_proc[pid].avl == _true)
00298                  {
00299                           _proc[pid].avl = _false;
00300                                 break;
00301                  }
00302          }
00303 
00304          printf("\nPID: %d\n",pid);
00305 
00306          if(pid == MAX_PROC)
00307          {
00308                         printf("\nforkNULL Failure");
00309                         return FORK_FAILURE;
00310    }
00311 
00312          for(i = 0 ; i < (MAX_PROC_SIZE/_4KB) ; i++)
00313          {
00314                  pg_num[i] = findpage();
00315 
00316                  if(pg_num[i] == PAGE_NOT_FOUND)
00317                  {
00318                           for(j = 0 ; j < i ; j++)
00319                                 freepage(pg_num[j]);
00320 
00321                         return FORK_FAILURE;
00322      }
00323 
00324                  addr = KERNEL_SIZE + (pg_num[i] * _4KB); //Physical
00325 
00326                  printf("\tA %x Pg %d",addr,pg_num[i]);
00327                  _pgte[pid][i] = addr | 7; //User R/W Present
00328          }
00329 
00330    addr = KERNEL_SIZE + (pg_num[0] * _4KB); //Physical Addr
00331    kmemcpy((void *)(addr),null_proc,512);
00332 
00333    //Only variables here & the rest in proc_init
00334    _proc[pid].esp    = MAX_PROC_SIZE-1;
00335    _proc[pid].eip    = 0;
00336 }
00337 
00338 void reti()
00339 {
00340  DD i = 0 , j = 0, _delay = 0x1000;
00341  DB c;
00342  DW data = 0xFF, port = 0x60;
00343 
00344  asm("movl $0,%eax");
00345  asm("int %0"::"i"(0x30));
00346  
00347  BLOCK
00348 }
00349 
00350 void rogue()
00351 {
00352  DD i = 0 , j = 0, _delay = 0x1000;
00353  DB c;
00354  DW data = 0xFF, port = 0x60;
00355  
00356  asm("int $200");
00357 
00358  BLOCK  
00359 }
00360 
00361 
00362 void null_proc()
00363 {
00364   DB i = 0;
00365 
00366   char *str = "Hello";
00367 
00368   BLOCK
00369 }

Generated on Thu Jul 27 23:52:27 2006 for Dynacube by  doxygen 1.4.7