00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 #include <vmm/vmm.h>
00031 #include <ubixos/sched.h>
00032 #include <ubixos/kpanic.h>
00033 #include <ubixos/spinlock.h>
00034 #include <lib/kprint.h>
00035 
00036 static spinLock_t fvpSpinLock = SPIN_LOCK_INITIALIZER;
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 void *vmmGetFreeVirtualPage(pidType pid, int count,int type) {
00048   int             x = 0, y = 0, c = 0;
00049   uInt32         *pageTableSrc = 0x0;
00050   uInt32         *pageDir = 0x0;
00051   uInt32          start_page = 0x0;
00052 
00053   
00054   spinLock(&fvpSpinLock);
00055   
00056   pageDir = (uInt32 *) parentPageDirAddr;
00057 
00058   
00059   if (_current->oInfo.vmStart <= 0x100000)
00060     kpanic("Invalid vmStart\n");
00061 
00062   if (type == VM_THRD) {
00063     start_page = (u_int32_t)(_current->td.vm_daddr + ctob(_current->td.vm_dsize));
00064     }
00065   else if (type == VM_TASK) {
00066     
00067     start_page = _current->oInfo.vmStart;
00068     }
00069   else
00070     K_PANIC("Invalid Type");
00071 
00072   
00073   for (x = (start_page / (1024 * 4096)); x < 1024; x++) {
00074     
00075     if ((pageDir[x] & PAGE_PRESENT) != PAGE_PRESENT) {
00076       
00077       pageDir[x] = (uInt32) vmmFindFreePage(_current->id) | PAGE_DEFAULT;
00078       
00079       pageTableSrc = (uInt32 *) (tablesBaseAddress + (4096 * 767));
00080       pageTableSrc[x] = pageDir[x];
00081       y = 1;
00082       
00083       asm(
00084           "movl %cr3,%eax\n"
00085           "movl %eax,%cr3\n"
00086         );
00087     }
00088     pageTableSrc = (uInt32 *) (tablesBaseAddress + (0x1000 * x));
00089     if (y != 0x0) {
00090       for (y = 0x0;y<pageEntries;y++) {
00091         pageTableSrc[y] = (uInt32)0x0;
00092         }
00093       }
00094     for (y = 0; y < 1024; y++) {
00095       
00096       if ((pageTableSrc[y] & PAGE_COW) == PAGE_COW) {
00097         kprintf("PAGE_COW");
00098         
00099         
00100         
00101         }
00102       if ((uInt32) pageTableSrc[y] == (uInt32) 0x0) {
00103         if (count > 0x1) {
00104           for (c = 0; c < count; c++) {
00105             if (y + c < 1024) {
00106       if ((pageTableSrc[y + c] & PAGE_COW) == PAGE_COW) {
00107         kprintf("PAGE-COW");
00108         
00109         
00110         
00111         }
00112 
00113               if ((uInt32) pageTableSrc[y + c] != (uInt32) 0x0) {
00114                 c = -1;
00115                 break;
00116                 }
00117               }
00118             }
00119           if (c != -1) {
00120             for (c = 0; c < count; c++) {
00121               if ((vmm_remapPage((uInt32) vmmFindFreePage(pid), ((x * (1024 * 4096)) + ((y + c) * 4096)),PAGE_DEFAULT)) == 0x0)
00122                 kpanic("vmmRemapPage: getFreeVirtualPage-1: [0x%X]\n",((x * (1024 * 4096)) + ((y + c) * 4096)));
00123               vmmClearVirtualPage((uInt32) ((x * (1024 * 4096)) + ((y + c) * 4096)));
00124             }
00125             if (type == VM_THRD)
00126               _current->td.vm_dsize += btoc(count * 0x1000);
00127             spinUnlock(&fvpSpinLock);
00128             return ((void *)((x * (1024 * 4096)) + (y * 4096)));
00129           }
00130         } else {
00131           
00132 
00133           
00134 
00135 
00136 
00137           if ((vmm_remapPage((uInt32) vmmFindFreePage(pid), ((x * (1024 * 4096)) + (y * 4096)),PAGE_DEFAULT)) == 0x0)
00138             kpanic("vmmRemapPage: getFreeVirtualPage-2\n");
00139 
00140           
00141           vmmClearVirtualPage((uInt32) ((x * (1024 * 4096)) + (y * 4096)));
00142 
00143           
00144           if (type == VM_THRD) {
00145             _current->td.vm_dsize += btoc(count * 0x1000);
00146             kprintf("vm_dsize: [0x%X]][0x%X]\n",ctob(_current->td.vm_dsize),_current->td.vm_dsize);
00147             }
00148           
00149 
00150           spinUnlock(&fvpSpinLock);
00151           return ((void *)((x * (1024 * 4096)) + (y * 4096)));
00152         }
00153       }
00154     }
00155   }
00156   
00157   spinUnlock(&fvpSpinLock);
00158   return (0x0);
00159 }
00160 
00161 
00162 
00163 
00164