#include <mm/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; mMap *mmUsedPages = 0xFD000000; uInt32 freePages = 0, usedPages = 0; uInt32 z = 0, memStart = 0; uInt32 countMemory(); kTask_t *SYSTEM = 0xFC000000; void mmFreeVirtualPage(kTask_t *task, uInt32 memAddr) { mMap *tmp, *tmp2; for(tmp = task->FirstPage ; tmp != NULL ; tmp = tmp->Next) { if(tmp->pageAddr == memAddr) { freePages++; /* 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 */ mmFreePages->Last->Next = tmp; tmp->Previous = mmFreePages->Last; mmFreePages->Last = tmp; /* free contiguous blocks */ if(tmp->Link != NULL) { kprintf("Freeing contiguous memory\n"); for(tmp2 = tmp->Link ; tmp2 != NULL ; tmp2 = tmp2->Link) { mmFreePages->Last->Next = tmp2; tmp2->Previous = mmFreePages->Last; mmFreePages->Last = tmp2; } } kprintf("mmFreeVirtualPage: %d has been freed\n", memAddr); return; } } kpanic("mmFreeVirtualPage: attempted to free non-existant page\n"); return; } void * mmGetFreeVirtualPage(kTask_t *task) { mMap *tmp, *tmpMap; freePages--; // kprintf("Z = %d + sizeof %d + 1 = %d\n", z, sizeof(mMap), z + (sizeof(mMap)+1)); if(mmUsedPages == NULL) { mmUsedPages = (z + sizeof(mMap)); mmUsedPages->First = NULL; mmUsedPages->Last = NULL; z+=(sizeof(mMap)+1); } tmpMap = z; tmpMap->pageAddr = 10; tmpMap->physicalAddr = 10; tmpMap->Next = NULL; tmpMap->Previous = mmUsedPages->Last; mmUsedPages->Last = tmpMap; if(mmUsedPages->First == NULL) mmUsedPages->First = tmpMap; z+=(sizeof(mMap)+1); return tmpMap; } int vmmMemMapInit() { uInt32 memStart; mMap *tmpMap; _current = SYSTEM; /* Count System Memory */ numPages = countMemory(); freePages = numPages; // memStart = sizeof(mMap) * numPages; /* initialize free pages */ //kprintf("Initializing memory memStart = [%x]\n", memStart); /* initialize used pages (kernel space) */ z = 30000; /* Print Out Memory Information */ kprintf("Total 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); } uInt32 countMemory() { register uInt32 *mem = 0x0; unsigned long memCount = -1, tempMemory = 0x0; unsigned short memKb = 0; uInt8 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); }