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 = (uint32_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