#include <vmm/vmm.h> #include <sys/io.h> #include <ubixos/kpanic.h> #include <lib/kprintf.h> #include <lib/kmalloc.h> #include <ubixos/vitals.h> #include <ubixos/spinlock.h> #include <assert.h> int numPages = 0; void mmFreeTaskPages(kTask_t *task) { /* just move the list to tail of the free page list */ if(task->FirstPage != NULL) { vmmFreePages->Last->Next = task->FirstPage; task->FirstPage->Previous = vmmFreePages->Last; vmmFreePages->Last = task->LastPage; /* TODO: zero out the memory last used */ kprintf("mmFreeTaskPages: Memory has been wiped\n"); } else kprintf("mmFreeTaskPages: Nothing to free!\n"); } void mmFreeVirtualPage(kTask_t *task, uInt32 memAddr) { mMap *tmp; for(tmp = task->FirstPage ; tmp != NULL ; tmp = tmp->Next) { if(tmp->pageAddr == memAddr) { /* remove the page from the task's used list */ if(tmp == task->FirstPage) { task->FirstPage = task->FirstPage->Next; } else { tmp->Previous->Next = tmp->Next; tmp->Next->Previous = tmp->Previous; tmp->Next = NULL; tmp->Previous = NULL; } /* add the page to the end free pages list */ vmmFreePages->Last->Next = tmp; tmp->Previous = vmmFreePages->Last; vmmFreePages->Last = tmp; kprintf("vmmFreeVirtualPage: %d has been freed\n", memAddr); return; } } kpanic("vmmFreeVirtualPage: attempted to free non-existant page\n"); return; } void * mmGetFreeVirtualPage(kTask_t *task) { mMap *tmp; if(vmmFreePages == NULL) { kprintf("Out of memory\n"); return NULL; } /* remove the first page from the list and return it */ tmp = vmmFreePages->First; vmmFreePages->First = vmmFreePages->First->Next; vmmFreePages->First->Previous = NULL; return tmp; } int mmMemMapInit() { uInt32 memStart, z; mMap *tmpMap; /* Count System Memory */ numPages = countMemory(); /* calculate the start of memory */ memStart = 0x101; memStart += (((sizeof(mMap) * numPages) + (sizeof(mMap) - 1)) / 0x1000); /* initialize free pages */ for(z = memStart ; z < numPages; z++) { if(vmmFreePages == NULL) { //UBU: replace this with static location vmmFreePages = kmalloc(sizeof(mMap)); vmmFreePages->First = vmmFreePages; vmmFreePages->Last = vmmFreePages; vmmFreePages->Next = NULL; vmmFreePages->Previous = NULL; vmmFreePages->pid = vmmID; vmmFreePages->pageAddr = z * 4096; vmmFreePages->status = memAvail; } else { //UBU: replace this with static location tmpMap = kmalloc(sizeof(mMap)); vmmFreePages->Last->Next = tmpMap; tmpMap->Previous = vmmFreePages->Last; vmmFreePages->Last = tmpMap; tmpMap->pid = vmmID; tmpMap->pageAddr = z * 4096; tmpMap->status = memAvail; } } /* initialize used pages (kernel space) */ for(z = 0 ; z < memStart; z++) { if(vmmUsedPages == NULL) { vmmUsedPages = kmalloc(sizeof(mMap)); vmmUsedPages->First = vmmUsedPages; vmmUsedPages->Last = vmmUsedPages; vmmUsedPages->Next = NULL; vmmUsedPages->Previous = NULL; vmmUsedPages->pid = vmmID; vmmUsedPages->pageAddr = z * 4096; vmmUsedPages->status = memNotavail; } else { tmpMap = kmalloc(sizeof(mMap)); vmmUsedPages->Last->Next = tmpMap; tmpMap->Previous = vmmUsedPages->Last; vmmUsedPages->Last = tmpMap; tmpMap->pid = vmmID; tmpMap->pageAddr = z * 4096; tmpMap->status = memNotavail; } } /* Print Out Memory Information */ kprintf("Real Memory: %iMB\n", ((numPages * 4096) / 1024) / 1024 ); kprintf("Available Memory: %iMB\n", ((freePages * 4096) / 1024) / 1024 ); kprintf("Used Memory: %iMB\n", ((usedPages * 4096) / 1024) / 1024 ); /* Return */ return (0); } int countMemory() { register uInt32 *mem = 0x0; unsigned long memCount = -1, tempMemory = 0x0; unsigned short memKb = 0; unsigned char irq1State, irq2State; unsigned long cr0 = 0x0; /* * Save The States Of Both IRQ 1 And 2 So We Can Turn Them Off And Restore * Them Later */ irq1State = inportByte(0x21); irq2State = inportByte(0xA1); /* Turn Off IRQ 1 And 2 To Prevent Chances Of Faults While Examining Memory */ outportByte(0x21, 0xFF); outportByte(0xA1, 0xFF); /* Save The State Of Register CR0 */ asm volatile ( "movl %%cr0, %%ebx\n" : "=a" (cr0) : : "ebx" ); asm volatile ("wbinvd"); asm volatile ( "movl %%ebx, %%cr0\n" : : "a" (cr0 | 0x00000001 | 0x40000000 | 0x20000000) : "ebx" ); while (memKb < 4096 && memCount != 0) { memKb++; if (memCount == -1) memCount = 0; memCount += 1024 * 1024; mem = (uInt32 *)memCount; tempMemory = *mem; *mem = 0x55AA55AA; asm("": : :"memory"); if (*mem != 0x55AA55AA) { memCount = 0; } else { *mem = 0xAA55AA55; asm("": : :"memory"); if (*mem != 0xAA55AA55) { memCount = 0; } } asm("": : :"memory"); *mem = tempMemory; } asm volatile ( "movl %%ebx, %%cr0\n" : : "a" (cr0) : "ebx" ); /* Restore States For Both IRQ 1 And 2 */ outportByte(0x21, irq1State); outportByte(0xA1, irq2State); /* Return Amount Of Memory In Pages */ return ((memKb * 1024 * 1024) / 4096); }