#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; 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 = %d", z, sizeof(mMap), z + sizeof(mMap)); if(mmFreePages == NULL) { kprintf("1\n"); mmFreePages = (z + sizeof(mMap)); mmFreePages->First = mmFreePages; mmFreePages->Last = mmFreePages; mmFreePages->Next = NULL; mmFreePages->Previous = NULL; mmFreePages->pageAddr = z * 4096; mmFreePages->physicalAddr = z * 4096; kprintf("something goes wrong here"); } else { kprintf("2\n"); tmpMap = (z + sizeof(mMap)); tmp = mmFreePages->Last; tmp->Next = tmpMap; tmpMap->Previous = mmFreePages->Last; mmFreePages->Last = tmpMap; tmpMap->pageAddr = z * 4096; tmpMap->physicalAddr = z * 4096; kprintf("something goes wrong here"); } z+=sizeof(mMap)+1; // remove the first page from the list and return it // tmp = mmFreePages->First; kprintf("3\n"); mmFreePages->First = mmFreePages->First->Next; mmFreePages->First->Previous = NULL; kprintf("%d:%d - [0x%X] - [0x%X]\n", z, numPages, tmpMap->pageAddr, tmp); return tmp; } 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 = 0xFFFF0000; /* 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); }