diff --git a/src/sys/Makefile.inc b/src/sys/Makefile.inc index 34cbfc7..d843e43 100644 --- a/src/sys/Makefile.inc +++ b/src/sys/Makefile.inc @@ -2,5 +2,5 @@ # global 'sys' options INCLUDES = -I../include -CFLAGS = -Wall -nostdlib -nostdinc -fno-builtin -fno-exceptions -O -DNOTIMP -DLD_DEBUG -D VMMDEBUG #-DVFSDEBUG -DDEBUG #-DVMMDEBUG #-DVFSDEBUG +CFLAGS = -Wall -nostdlib -nostdinc -fno-builtin -fno-exceptions -O -DNOTIMP -DLD_DEBUG -DVMMDEBUG #-DVFSDEBUG -DDEBUG #-DVMMDEBUG #-DVFSDEBUG KERNEL = ubix.elf diff --git a/src/sys/include/vmm/paging.h b/src/sys/include/vmm/paging.h index f26188a..129c190 100644 --- a/src/sys/include/vmm/paging.h +++ b/src/sys/include/vmm/paging.h @@ -51,41 +51,27 @@ #define PAGE_SHIFT 12 /* LOG2(PAGE_SIZE) */ #define PAGE_SIZE (1<> 12) & 0x3FF) -#define PDI(x) (x >> 22) +#define PAGE_KERNEL_ENTRY 0x300 /* First kernel page entry */ +#define PAGE_DIR_SPACE 0x2FF /* Virtual Area For Pages 4MB */ + +#define PTI(x) ((x >> 12) & 0x3FF) /* Return page directory index of address */ +#define PDI(x) (x >> 22) /* Return page table index of address */ #define trunc_page(x) ((x) & ~PAGE_MASK) #define round_page(x) (((x) + PAGE_MASK) & ~PAGE_MASK) #define ctob(x) ((x)<>PAGE_SHIFT) -int vmm_cleanVirtualSpace(u_int32_t addr); -int vmm_zeroVirtualPage(u_int32_t pageAddr); -void vmm_unmapPages(u_int32_t addr,u_int32_t count,u_int16_t flags); -void *vmm_mapFromTask(pidType pid,u_int32_t baseAddr,u_int32_t size); -void *vmm_copyVirtualSpace(pidType); -void *vmmCreateVirtualSpace(pidType); -void *vmm_getFreeVirtualPage_old(pidType,int,int); -void *vmm_getFreeVirtualPage(pidType,int,int,u_int32_t); -void *vmm_getFreeKernelPage(pidType pid,u_int32_t count); -u_int32_t vmm_getPhysicalAddr(u_int32_t); -void vmm_setPageAttributes(u_int32_t,u_int16_t); -int vmm_remapPage(u_int32_t,u_int32_t,u_int16_t); -int vmm_pagingInit(); -void *vmm_getFreeMallocPage(u_int16_t count); -void vmm_pageFault(u_int32_t,u_int32_t,u_int32_t); -void _vmm_pageFault(); int mmap(struct thread *,struct mmap_args *); int obreak(struct thread *,struct obreak_args *); int munmap(struct thread *,struct munmap_args *); - -extern u_int32_t *kernelPageDirectory; - #endif /*** diff --git a/src/sys/include/vmm/vmm.h b/src/sys/include/vmm/vmm.h index b63a2f2..1567e1b 100644 --- a/src/sys/include/vmm/vmm.h +++ b/src/sys/include/vmm/vmm.h @@ -33,8 +33,6 @@ #include #include -#define memAvail 1 -#define memNotavail 2 #define vmmID -3 #define vmmMemoryMapAddr 0xE6667000 @@ -46,21 +44,47 @@ int cowCounter; } mMap; +/* Externs */ extern int numPages; extern mMap *vmmMemoryMap; +extern u_int32_t *kernelPageDirectory; -int vmm_init(); -int vmmMemMapInit(); -int countMemory(); +/* Callable Functions */ +void *vmm_getFreeVirtualPage_old(pidType,int,int); +void *vmm_getFreeVirtualPage(pidType pid,int count,int type,u_int32_t startAddr); /* Returns free virtual page */ +void *vmm_getFreeKernelPage(pidType pid,u_int32_t count); +void *vmm_getFreeMallocPage(u_int16_t count); u_int32_t vmm_findFreePage(pidType pid); +int vmm_cleanVirtualSpace(u_int32_t addr); +int vmm_zeroVirtualPage(u_int32_t pageAddr); +void vmm_unmapPages(u_int32_t addr,u_int32_t count,u_int16_t flags); +void *vmm_mapFromTask(pidType pid,u_int32_t baseAddr,u_int32_t size); +void *vmm_copyVirtualSpace(pidType); +void *vmmCreateVirtualSpace(pidType); +u_int32_t vmm_getPhysicalAddr(u_int32_t); +void vmm_setPageAttributes(u_int32_t,u_int16_t); +int vmm_remapPage(u_int32_t,u_int32_t,u_int16_t); void vmm_freePage(u_int32_t pageAddr); void vmm_adjustCowCounter(u_int32_t pageAddr,int adjustment); void vmm_freeProcessPages(pidType pid); +/* Interrupt Functions */ +void vmm_pageFault(u_int32_t,u_int32_t,u_int32_t); +void _vmm_pageFault(); + +/* Initialization Functions */ +int vmm_pagingInit(); +int vmm_init(); +int vmm_memMapInit(); +int vmm_countMemory(); + #endif /*** $Log$ + Revision 1.3 2009/07/08 21:20:13 reddawg + Getting There + END ***/ diff --git a/src/sys/kernel/exec.c b/src/sys/kernel/exec.c index 72de9e4..845a3be 100644 --- a/src/sys/kernel/exec.c +++ b/src/sys/kernel/exec.c @@ -381,12 +381,7 @@ /* Need to rewrite this routine? */ tmpFd = (struct file *)kmalloc(sizeof(struct file)); if (fopen(tmpFd,file,"r") == 0x0) { - //kprintf("[0x%X]\n",tmpFd); - //kfree(tmpFd); //We need this but it's being done in fopen right now - //UBU WHY? - kpanic("WTF!"); return; - _current->imageFd = 0x0; } kprintf("Sys EXEC: %i 0x%X 0x%X\n",tmpFd->size,ap,ep); @@ -463,6 +458,10 @@ Allocate Memory Im Going To Have To Make This Load Memory With Correct Settings so it helps us in the future */ + + /* Lets Release Any Pages That Might Be Already Mapped */ + vmm_unmapPages(programHeader[i].phVaddr,seg_size >> PAGE_SHIFT,0x0); + for (x = 0x0;x < seg_size;x += 0x1000) { /* Make readonly and read/write !!! */ if (vmm_remapPage(vmm_findFreePage(_current->id),((programHeader[i].phVaddr & 0xFFFFF000) + x),PAGE_DEFAULT) == 0x0) @@ -537,7 +536,7 @@ _current->td.vm_dsize = seg_size >> PAGE_SHIFT; _current->td.vm_daddr = seg_addr; - kprintf("STATING: [0x%X][0x%X]\n",_current->td.vm_dsize,_current->td.vm_daddr); + kprintf("STARTING-*: [0x%X][0x%X]\n",_current->td.vm_dsize,_current->td.vm_daddr); argv = (char **)ap; envp = (char **)ep; @@ -548,7 +547,7 @@ if (argv[1] != 0x0) { //UBU argc = (int)argv[0]; - args = (char *)vmm_getFreeVirtualPage(_current->id,1,VM_TASK,-1); + args = (char *)vmm_getFreeVirtualPage(_current->id,1,VM_TASK,0x300000); //! do we need this? memset(args,0x0,0x1000); x = 0x0; @@ -567,7 +566,7 @@ //QUESTION Why did I feel a need to add vm_dsize to vm_daddr kprintf("First: 0x%X, 0x%X\n",_current->td.vm_dsize,_current->td.vm_daddr); - vmm_cleanVirtualSpace((u_int32_t)_current->td.vm_daddr);// + (_current->td.vm_dsize << PAGE_SIZE)); + vmm_cleanVirtualSpace((u_int32_t)_current->td.vm_daddr + (_current->td.vm_dsize << PAGE_SHIFT)); //! Adjust iframe @@ -740,7 +739,7 @@ //QUESTION Why did I add dsize to daddr? kprintf("Second: 0x%X, 0x%X\n",_current->td.vm_dsize,_current->td.vm_daddr); - vmm_cleanVirtualSpace((u_int32_t)_current->td.vm_daddr);// + (_current->td.vm_dsize << PAGE_SIZE)); + vmm_cleanVirtualSpace((u_int32_t)_current->td.vm_daddr + (_current->td.vm_dsize << PAGE_SHIFT)); //! Adjust iframe diff --git a/src/sys/kernel/ld.c b/src/sys/kernel/ld.c index 3fc2147..b516f95 100644 --- a/src/sys/kernel/ld.c +++ b/src/sys/kernel/ld.c @@ -100,6 +100,8 @@ Settings so it helps us in the future */ //kprintf("LD.phMemsz: 0x%X\n",programHeader[i].phMemsz); + kprintf("phMemsz: %i",programHeader[i].phMemsz >> PAGE_SHIFT); + vmm_unmapPages(programHeader[i].phVaddr + LD_START,programHeader[i].phMemsz >> PAGE_SHIFT,0x0); for (x=0;x < (programHeader[i].phMemsz);x += 0x1000) { /* make r/w or ro */ if (((programHeader[i].phVaddr & 0xFFFFF00) + x + LD_START) > 0xC0000000) diff --git a/src/sys/vmm/getfreekernelpage.c b/src/sys/vmm/getfreekernelpage.c index 6e6e6de..41e3184 100644 --- a/src/sys/vmm/getfreekernelpage.c +++ b/src/sys/vmm/getfreekernelpage.c @@ -2,26 +2,26 @@ Copyright (c) 2002, 2009 The UbixOS Project All rights reserved. -Redistribution and use in source and binary forms, with or without modification, are -permitted provided that the following conditions are met: + Redistribution and use in source and binary forms, with or without modification, are + permitted provided that the following conditions are met: -Redistributions of source code must retain the above copyright notice, this list of -conditions, the following disclaimer and the list of authors. Redistributions in binary -form must reproduce the above copyright notice, this list of conditions, the following -disclaimer and the list of authors in the documentation and/or other materials provided -with the distribution. Neither the name of the UbixOS Project nor the names of its -contributors may be used to endorse or promote products derived from this software -without specific prior written permission. + Redistributions of source code must retain the above copyright notice, this list of + conditions, the following disclaimer and the list of authors. Redistributions in binary + form must reproduce the above copyright notice, this list of conditions, the following + disclaimer and the list of authors in the documentation and/or other materials provided + with the distribution. Neither the name of the UbixOS Project nor the names of its + contributors may be used to endorse or promote products derived from this software + without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT -OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR -TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. $Id$ @@ -41,8 +41,8 @@ Description: Returns A Free Page Mapped To The VM Space Notes: -06/12/09 - Moved Function From paging.c To Replace This One 07/30/02 - This Returns A Free Page In The Top 1GB For The Kernel +06/12/09 - Moved Function From paging.c To Replace This One ************************************************************************/ void *vmm_getFreeKernelPage(pidType pid, u_int32_t count) { @@ -54,17 +54,17 @@ spinLock(&vmmGFPlock); /* Lets Search For A Free Page */ - for (x = 768; x < 1024; x++) { + for (x = PAGE_KERNEL_ENTRY; x < 1024; x++) { /* Set Page Table Address */ pageTableSrc = (u_int32_t *) (PAGE_TABLES_BASE_ADDR + (4096 * x)); for (y = 0; y < 1024; y++) { /* Loop Through The Page Table Find An UnAllocated Page */ - if ((u_int32_t) pageTableSrc[y] == (u_int32_t) 0x0) { + if ((u_int32_t) pageTableSrc[y] == 0x0) { if (count > 1) { for (c = 0; c < count; c++) { if (y + c < 1024) { - if ((u_int32_t) pageTableSrc[y + c] != (u_int32_t) 0x0) { + if ((u_int32_t) pageTableSrc[y + c] != 0x0) { c = -1; break; } @@ -74,7 +74,7 @@ if (c != -1) { for (c = 0; c < count; c++) { if ((vmm_remapPage((u_int32_t) vmm_findFreePage(pid), ((x * (1024 * 4096)) + ((y + c) * 4096)),KERNEL_PAGE_DEFAULT)) == 0x0) - K_PANIC("vmmRemapPage failed: gfkp-1\n"); + K_PANIC("vmm_remapPage: failed"); if (vmm_zeroVirtualPage((u_int32_t) ((x * (1024 * 4096)) + ((y + c) * 4096))) == 0x1) K_PANIC("vmm_zeroVirtualPage: failed\n"); } @@ -86,11 +86,12 @@ else { /* Map A Physical Page To The Virtual Page */ if ((vmm_remapPage((u_int32_t) vmm_findFreePage(pid), ((x * (1024 * 4096)) + (y * 4096)),KERNEL_PAGE_DEFAULT)) == 0x0) - K_PANIC("vmmRemapPage failed: gfkp-2\n"); + K_PANIC("vmm_remapPage: failed"); /* Clear This Page So No Garbage Is There */ if (vmm_zeroVirtualPage((u_int32_t) ((x * (1024 * 4096)) + (y * 4096))) == 0x1) K_PANIC("vmm_zeroVirtualPage: Failed\n"); + /* Return The Address Of The Newly Allocate Page */ spinUnlock(&vmmGFPlock); return ((void *)((x * (1024 * 4096)) + (y * 4096))); @@ -107,12 +108,14 @@ /*** $Log$ + Revision 1.4 2009/07/09 00:49:50 reddawg + Lots of fixes and renaming to the vmm portion of the kernel + Revision 1.3 2009/07/08 21:20:13 reddawg Getting There Revision 1.2 2009/07/08 16:05:56 reddawg Sync - END ***/ diff --git a/src/sys/vmm/paging.c b/src/sys/vmm/paging.c index 4280887..f169442 100644 --- a/src/sys/vmm/paging.c +++ b/src/sys/vmm/paging.c @@ -28,7 +28,6 @@ *****************************************************************************************/ #include -#include #include #include #include @@ -63,16 +62,12 @@ /* Allocate A Page Of Memory For Kernels Page Directory */ kernelPageDirectory = (u_int32_t *) vmm_findFreePage(sysID); - if (kernelPageDirectory == 0x0) { + + if (kernelPageDirectory == 0x0) K_PANIC("Error: vmm_findFreePage Failed"); - return (0x1); - } /* end if */ /* Clear The Memory To Ensure There Is No Garbage */ - //QUESTION Can't we do a memset here? - for (i = 0x0; i < PAGE_ENTRIES; i++) { - kernelPageDirectory[i] = (u_int32_t)0x0; - } /* end for */ + memset(kernelPageDirectory,0x0,PAGE_SIZE); /* Allocate a page for the first 4MB of memory */ if ((pageTable = (u_int32_t *) vmm_findFreePage(sysID)) == 0x0) @@ -81,11 +76,11 @@ kernelPageDirectory[0x0] = (u_int32_t) ((u_int32_t)pageTable | KERNEL_PAGE_DEFAULT); /* Make Sure The Page Table Is Clean */ - memset(pageTable,0x0,0x1000); + memset(pageTable,0x0,PAGE_SIZE); /* - * Map the first 1MB of Memory to the kernel MM space because our kernel starts - * at 0x30000 + * Map the first 1MB of Memory to the kernel MM space because our kernel starts at 0x30000 + * This is mapped 1:1 * Do not map page at address 0x0 this is reserved for null... */ for (i = 0x1; i < (PAGE_ENTRIES / 0x4); i++) { @@ -96,12 +91,12 @@ * Create page tables for the top 1GB of VM space. This space is set aside * for kernel space and will be shared with each process */ - for (i = 768; i < PAGE_ENTRIES; i++) { + for (i = PAGE_KERNEL_ENTRY; i < PAGE_ENTRIES; i++) { if ((pageTable = (u_int32_t *) vmm_findFreePage(sysID)) == 0x0) K_PANIC("Error: vmm_findFreePage Failed"); /* Make Sure The Page Table Is Clean */ - memset(pageTable,0x0,0x1000); + vmm_zeroVirtualPage((u_int32_t)pageTable); /* Map In The Page Directory */ kernelPageDirectory[i] = (u_int32_t) ((u_int32_t) (pageTable) | KERNEL_PAGE_DEFAULT); @@ -112,9 +107,9 @@ K_PANIC("Error: vmm_findFreePage Failed"); /* Clean Page Table */ - memset(pageTable,0x0,0x1000); + memset(pageTable,0x0,PAGE_SIZE); - kernelPageDirectory[767] = ((u_int32_t) pageTable | KERNEL_PAGE_DEFAULT); + kernelPageDirectory[PAGE_DIR_SPACE] = ((u_int32_t) pageTable | KERNEL_PAGE_DEFAULT); for (i = 0; i < PAGE_ENTRIES; i++) { pageTable[i] = kernelPageDirectory[i]; @@ -169,7 +164,6 @@ u_int16_t destPageTableIndex = 0x0; u_int32_t *pageDir = 0x0; u_int32_t *pageTable = 0x0; - short i = 0x0; assert((sourceAddr & 0xFFF) == 0x0); assert((destAddr & 0xFFF) == 0x0); @@ -218,8 +212,7 @@ pageTable = (u_int32_t *) (PAGE_TABLES_BASE_ADDR + (0x1000 * destPageDirectoryIndex)); /* Zero out the page table */ - for (i = 0x0;i < PAGE_ENTRIES;i++) - pageTable[i] = 0x0; + memset(pageTable,0x0,PAGE_SIZE); } /* Set Address To Page Table */ @@ -230,6 +223,8 @@ /* If The Page Is Mapped In Free It Before We Remap */ if ((pageTable[destPageTableIndex] & PAGE_PRESENT) == PAGE_PRESENT) { + kprintf("ADDR: 0x%X",destAddr); + K_PANIC("Mapping To Existing Page!"); if ((pageTable[destPageTableIndex] & PAGE_STACK) == PAGE_STACK) kprintf("Stack Page: [0x%X]\n",destAddr); diff --git a/src/sys/vmm/unmappage.c b/src/sys/vmm/unmappage.c index b2fbe34..5e2e1e8 100644 --- a/src/sys/vmm/unmappage.c +++ b/src/sys/vmm/unmappage.c @@ -56,11 +56,21 @@ dI = PDI(baseAddr); tI = PTI(baseAddr); + pageTable = (u_int32_t *)PARENT_PAGEDIR_ADDR; + + if ((pageTable[dI] & PAGE_PRESENT) != PAGE_PRESENT) { + #ifdef VMMDEBUG + kprintf("vmm_unmapPages: page not present"); + #endif + return; + } + pageTable = (u_int32_t *)(PAGE_TABLES_BASE_ADDR + (4096*dI)); - for (y=tI;y<(tI + count);y++) { + for (y = tI;y <= (tI + count);y++) { if (flags == 0) - vmm_freePage((u_int32_t)(pageTable[y] & 0xFFFFF000)); + if ((pageTable[y] & PAGE_PRESENT) == PAGE_PRESENT) + vmm_freePage((u_int32_t)(pageTable[y] & 0xFFFFF000)); pageTable[y] = 0x0; } @@ -74,6 +84,9 @@ /*** $Log$ + Revision 1.3 2009/07/08 16:06:37 reddawg + Trying To Hunt Down Bugs + Revision 1.2 2009/07/08 16:05:56 reddawg Sync diff --git a/src/sys/vmm/vmm_init.c b/src/sys/vmm/vmm_init.c index b6e8d37..23ebfbc 100644 --- a/src/sys/vmm/vmm_init.c +++ b/src/sys/vmm/vmm_init.c @@ -39,7 +39,7 @@ */ int vmm_init() { - if (vmmMemMapInit() != 0x0) + if (vmm_memMapInit() != 0x0) K_PANIC("Couldn't Initialize vmmMemMap"); if (vmm_pagingInit() != 0x0) diff --git a/src/sys/vmm/vmm_memory.c b/src/sys/vmm/vmm_memory.c index 3767452..d6fe5f8 100644 --- a/src/sys/vmm/vmm_memory.c +++ b/src/sys/vmm/vmm_memory.c @@ -36,13 +36,11 @@ #include #include -static u_int32_t freePages = 0; -static spinLock_t vmmSpinLock = SPIN_LOCK_INITIALIZER; -static spinLock_t vmmCowSpinLock = SPIN_LOCK_INITIALIZER; - - -int numPages = 0x0; -mMap *vmmMemoryMap = (mMap *) 0x101000; +static u_int32_t freePages = 0x0; +static spinLock_t vmmSpinLock = SPIN_LOCK_INITIALIZER; +static spinLock_t vmmCowSpinLock = SPIN_LOCK_INITIALIZER; +int numPages = 0x0; +mMap *vmmMemoryMap = (mMap *) 0x101000; /************************************************************************ @@ -54,12 +52,12 @@ 02/20/2004 - Made It Report Real And Available Memory ************************************************************************/ -int vmmMemMapInit() { +int vmm_memMapInit() { int i = 0x0; int memStart = 0x0; /* Count System Memory */ - numPages = countMemory(); + numPages = vmm_countMemory(); /* Set Memory Map To Point To First Physical Page That We Will Use */ vmmMemoryMap = (mMap *) 0x101000; @@ -67,9 +65,9 @@ /* Initialize Map Make All Pages Not Available */ for (i = 0x0; i < numPages; i++) { vmmMemoryMap[i].cowCounter = 0x0; - vmmMemoryMap[i].status = memNotavail; + vmmMemoryMap[i].status = PAGE_UNAVAILABLE; vmmMemoryMap[i].pid = vmmID; - vmmMemoryMap[i].pageAddr = i * 4096; + vmmMemoryMap[i].pageAddr = i * 0x1000; } /* Calculate Start Of Free Memory */ @@ -77,10 +75,10 @@ memStart += (((sizeof(mMap) * numPages) + (sizeof(mMap) - 1)) / 0x1000); /* Initialize All Free Pages To Available */ - vmmMemoryMap[(0x100000 / 0x1000)].status = memAvail; + vmmMemoryMap[(0x100000 / 0x1000)].status = PAGE_AVAILABLE; freePages++; for (i = memStart; i < numPages; i++) { - vmmMemoryMap[i].status = memAvail; + vmmMemoryMap[i].status = PAGE_AVAILABLE; freePages++; } @@ -94,19 +92,22 @@ /************************************************************************ - Function: int countMemory(); + Function: int vmm_countMemory(); Description: This Function Counts The Systems Physical Memory Notes: 02/20/2004 - Inspect For Quality And Approved + 07/09/2009 - Renamed Function ************************************************************************/ -int countMemory() { - register u_int32_t *mem = 0x0; - unsigned long memCount = -1, tempMemory = 0x0; - unsigned short memKb = 0; - unsigned char irq1State, irq2State; - unsigned long cr0 = 0x0; +int vmm_countMemory() { + register u_int32_t *mem = 0x0; + unsigned long memCount = -1; + unsigned long tempMemory = 0x0; + unsigned long cr0 = 0x0; + unsigned short memKb = 0x0; + unsigned char irq1State; + unsigned char irq2State; /* * Save The States Of Both IRQ 1 And 2 So We Can Turn Them Off And Restore @@ -122,17 +123,18 @@ /* Save The State Of Register CR0 */ asm volatile ( "movl %%cr0, %%ebx\n" - : "=a" (cr0) + : "=a" (cr0) : - : "ebx" + : "ebx" ); asm volatile ("wbinvd"); + asm volatile ( "movl %%ebx, %%cr0\n" : - : "a" (cr0 | 0x00000001 | 0x40000000 | 0x20000000) - : "ebx" + : "a" (cr0 | 0x00000001 | 0x40000000 | 0x20000000) + : "ebx" ); while (memKb < 4096 && memCount != 0) { @@ -198,8 +200,8 @@ * If We Found A Free Page Set It To Not Available After That Set Its Own * And Return The Address */ - if ((vmmMemoryMap[i].status == memAvail) && (vmmMemoryMap[i].cowCounter == 0)) { - vmmMemoryMap[i].status = memNotavail; + if ((vmmMemoryMap[i].status == PAGE_AVAILABLE) && (vmmMemoryMap[i].cowCounter == 0)) { + vmmMemoryMap[i].status = PAGE_UNAVAILABLE; vmmMemoryMap[i].pid = pid; freePages--; if (systemVitals) @@ -219,7 +221,7 @@ /************************************************************************ - Function: int freePage(u_int32_t pageAddr); + Function: int vmm_freePage(u_int32_t pageAddr); Description: This Function Marks The Page As Free @@ -228,6 +230,7 @@ ************************************************************************/ void vmm_freePage(u_int32_t pageAddr) { int pageIndex = 0x0; + assert((pageAddr & 0xFFF) == 0x0); spinLock(&vmmSpinLock); @@ -238,7 +241,7 @@ /* Check If Page COW Is Greater Then 0 If It Is Dec It If Not Free It */ if (vmmMemoryMap[pageIndex].cowCounter == 0) { /* Set Page As Avail So It Can Be Used Again */ - vmmMemoryMap[pageIndex].status = memAvail; + vmmMemoryMap[pageIndex].status = PAGE_AVAILABLE; vmmMemoryMap[pageIndex].cowCounter = 0x0; vmmMemoryMap[pageIndex].pid = -2; freePages++; @@ -268,16 +271,20 @@ ************************************************************************/ void vmm_adjustCowCounter(u_int32_t baseAddr, int adjustment) { int vmmMemoryMapIndex = (baseAddr / 4096); + assert((baseAddr & 0xFFF) == 0x0); + spinLock(&vmmSpinLock); /* Adjust COW Counter */ vmmMemoryMap[vmmMemoryMapIndex].cowCounter += adjustment; - if (vmmMemoryMap[vmmMemoryMapIndex].cowCounter == 0) { + assert(vmmMemoryMap[vmmMemoryMapIndex].cowCounter >= 0x0); + + if (vmmMemoryMap[vmmMemoryMapIndex].cowCounter == 0x0) { vmmMemoryMap[vmmMemoryMapIndex].cowCounter = 0x0; vmmMemoryMap[vmmMemoryMapIndex].pid = vmmID; - vmmMemoryMap[vmmMemoryMapIndex].status = memAvail; + vmmMemoryMap[vmmMemoryMapIndex].status = PAGE_AVAILABLE; freePages++; systemVitals->freePages = freePages; } @@ -323,7 +330,7 @@ if (vmmMemoryMap[i].pid == pid) { /* Check To See If The cowCounter Is Zero If So We Can Ree It */ if (vmmMemoryMap[i].cowCounter == 0) { - vmmMemoryMap[i].status = memAvail; + vmmMemoryMap[i].status = PAGE_AVAILABLE; vmmMemoryMap[i].cowCounter = 0x0; vmmMemoryMap[i].pid = vmmID; freePages++; @@ -338,6 +345,9 @@ /*** $Log$ + Revision 1.3 2009/07/08 21:20:13 reddawg + Getting There + Revision 1.2 2009/07/08 16:05:56 reddawg Sync diff --git a/src/sys/vmm/vmm_virtual.c b/src/sys/vmm/vmm_virtual.c index b926802..95d2ac6 100644 --- a/src/sys/vmm/vmm_virtual.c +++ b/src/sys/vmm/vmm_virtual.c @@ -237,12 +237,15 @@ return (0x0); } /* end func */ -void *vmm_getFreeVirtualPage(pidType pid, int count,int type,u_int32_t start_addr) { - int x = 0, y = 0, c = 0; - u_int32_t *pageTableSrc = 0x0; - u_int32_t *pageDir = 0x0; - u_int32_t start_page = 0x0; +void *vmm_getFreeVirtualPage(pidType pid,int count,int type,u_int32_t start_addr) { + int x = 0; + int y = 0x0; + int c = 0x0; + u_int32_t *pageTableSrc = 0x0; + u_int32_t *pageDir = 0x0; + u_int32_t start_page = 0x0; + assert(count > 0); spinLock(&fvpSpinLock); @@ -250,18 +253,18 @@ /* Lets Search For A Free Page */ if (_current->oInfo.vmStart <= 0x100000) - kpanic("Invalid vmStart\n"); + K_PANIC("Invalid vmStart\n"); if (type == VM_THRD) { start_page = (u_int32_t)(_current->td.vm_daddr + ctob(_current->td.vm_dsize)); } else if (type == VM_TASK) { - //kprintf("vmStart"); start_page = _current->oInfo.vmStart; } else K_PANIC("Invalid Type"); + /* Start at suggest address if supplied */ if (start_addr != -1) { start_page = start_addr; #ifdef VMM_DEBUG @@ -269,11 +272,12 @@ #endif } - for (x = PDI(start_page); x < 1024; x++) { + for (x = PDI(start_page); x < PAGE_ENTRIES; x++) { /* Set Page Table Address */ if ((pageDir[x] & PAGE_PRESENT) != PAGE_PRESENT) { /* If Page Table Is Non Existant Then Set It Up */ pageDir[x] = (u_int32_t) vmm_findFreePage(_current->id) | PAGE_DEFAULT; + /* Also Add It To Virtual Space So We Can Make Changes Later */ pageTableSrc = (u_int32_t *) (PAGE_TABLES_BASE_ADDR + (4096 * 767)); pageTableSrc[x] = pageDir[x]; @@ -290,10 +294,10 @@ pageTableSrc[y] = (u_int32_t)0x0; } } - for (y = 0; y < 1024; y++) { + for (y = 0; y < PAGE_ENTRIES; y++) { /* Loop Through The Page Table Find An UnAllocated Page */ if ((pageTableSrc[y] & PAGE_COW) == PAGE_COW) { - kprintf("PAGE_COW"); + kprintf("PAGE_COW: 0x%X", (x * (0x400000) + (y * 0x1000))); //_current->td.vm_dsize += btoc(0x1000); /* HACK MEMORY LEAK */ //pageTableSrc[y] = 0x0; @@ -302,12 +306,12 @@ if (count > 0x1) { for (c = 0; c < count; c++) { if (y + c < 1024) { - if ((pageTableSrc[y + c] & PAGE_COW) == PAGE_COW) { - kprintf("PAGE-COW"); - //_current->td.vm_dsize += btoc(0x1000); - /* HACK MEMORY LEAK */ - //pageTableSrc[y + c] = 0x0; - } + if ((pageTableSrc[y + c] & PAGE_COW) == PAGE_COW) { + kprintf("PAGE-COW"); + //_current->td.vm_dsize += btoc(0x1000); + /* HACK MEMORY LEAK */ + //pageTableSrc[y + c] = 0x0; + } if ((u_int32_t) pageTableSrc[y + c] != (u_int32_t) 0x0) { c = -1; @@ -406,7 +410,7 @@ K_PANIC("ZVP: Failed"); /* Map The Top 1GB Region Of The VM Space */ - for (x = 768; x < PAGE_ENTRIES; x++) { + for (x = PAGE_KERNEL_ENTRY; x < PAGE_ENTRIES; x++) { newPageDirectory[x] = parentPageDirectory[x]; } @@ -420,9 +424,10 @@ if (parentPageDirectory[x] != 0) { /* Set Parent To Propper Page Table */ parentPageTable = (u_int32_t *) (PAGE_TABLES_BASE_ADDR + (0x1000 * x)); + /* Allocate A New Page Table */ if ((newPageTable = (u_int32_t *) vmm_getFreeKernelPage(pid,1)) == 0x0) - kpanic("Error: newPageTable == NULL, File: %s, Line: %i\n",__FILE__,__LINE__); + K_PANIC("Error: newPageTable == NULL"); /* Set Parent And New Pages To COW */ for (i = 0; i < PAGE_ENTRIES; i++) { @@ -433,7 +438,7 @@ if (((u_int32_t) parentPageTable[i] & PAGE_STACK) == PAGE_STACK) { /* Alloc A New Page For This Stack Page */ if ((newStackPage = (u_int32_t *) vmm_getFreeKernelPage(pid,1)) == 0x0) - kpanic("Error: newStackPage == NULL, File: %s, Line: %i\n",__FILE__,__LINE__); + K_PANIC("Error: newStackPage == NULL"); /* Set Pointer To Parents Stack Page */ parentStackPage = (u_int32_t *) (((1024 * 4096) * x) + (4096 * i)); @@ -467,18 +472,20 @@ /* Put New Page Table Into New Page Directory */ newPageDirectory[x] = (vmm_getPhysicalAddr((u_int32_t) newPageTable) | PAGE_DEFAULT); + /* Unmap Page From Kernel Space But Keep It Marked As Not Avail */ vmm_unmapPages((u_int32_t) newPageTable, 1, 1); - } else { + } + else { newPageDirectory[x] = (u_int32_t) 0x0; + } } - } /* * Allocate A New Page For The The First Page Table Where We Will Map The * Lower Region */ if ((newPageTable = (u_int32_t *) vmm_getFreeKernelPage(pid,1)) == 0x0) - kpanic("Error: newPageTable == NULL, File: %s, Line: %i\n",__FILE__,__LINE__); + K_PANIC("Error: newPageTable == NULL"); /* Flush The Page From Garbage In Memory */ if (vmm_zeroVirtualPage((u_int32_t)newPageTable) == 0x1) @@ -486,29 +493,36 @@ /* Map This Into The Page Directory */ newPageDirectory[0] = (vmm_getPhysicalAddr((u_int32_t) newPageTable) | PAGE_DEFAULT); + /* Set Address Of Parents Page Table */ parentPageTable = (u_int32_t *) PAGE_TABLES_BASE_ADDR; + /* Map The First 1MB Worth Of Pages */ for (x = 0; x < (PAGE_ENTRIES / 4); x++) { newPageTable[x] = parentPageTable[x]; - } + } + /* Map The Next 3MB Worth Of Pages But Make Them COW */ for (x = (PAGE_ENTRIES / 4) + 1; x < PAGE_ENTRIES; x++) { /* If Page Is Avaiable Map It */ if ((parentPageTable[x] & 0xFFFFF000) != 0x0) { /* Set Pages To COW */ newPageTable[x] = (((u_int32_t) parentPageTable[x] & 0xFFFFF000) | (PAGE_DEFAULT | PAGE_COW)); + + /* NOTE Why +2? */ /* Increment The COW Counter For This Page */ if (((u_int32_t) parentPageTable[x] & PAGE_COW) == PAGE_COW) { vmm_adjustCowCounter(((u_int32_t) parentPageTable[x] & 0xFFFFF000), 1); - } else { + } + else { vmm_adjustCowCounter(((u_int32_t) parentPageTable[x] & 0xFFFFF000), 2); parentPageTable[x] = newPageTable[x]; + } } - } else { + else { newPageTable[x] = (u_int32_t) 0x0; + } } - } /* Set Virtual Mapping For Page Directory */ newPageTable[256] = (vmm_getPhysicalAddr((u_int32_t) newPageDirectory) | PAGE_DEFAULT); @@ -517,19 +531,25 @@ * To Worry About Mapping Them In Later How Ever I'm Concerned This May * Become A Security Issue */ + /* First Lets Unmap The Previously Allocated Page Table */ vmm_unmapPages((u_int32_t) newPageTable, 1, 1); + /* Allocate A New Page Table */ if ((newPageTable = (u_int32_t *) vmm_getFreeKernelPage(pid,1)) == 0x0) - kpanic("Error: newPageTable == NULL, File: %s, Line: %i\n",__FILE__,__LINE__); + K_PANIC("Error: newPageTable == NULL"); + /* First Set Our Page Directory To Contain This */ newPageDirectory[767] = vmm_getPhysicalAddr((u_int32_t) newPageTable) | PAGE_DEFAULT; + /* Now Lets Build The Page Table */ for (x = 0; x < PAGE_ENTRIES; x++) { newPageTable[x] = newPageDirectory[x]; - } + } + /* Now We Are Done So Lets Unmap This Page */ vmm_unmapPages((u_int32_t) newPageTable, 1, 1); + /* Now We Are Done With The Page Directory So Lets Unmap That Too */ vmm_unmapPages((u_int32_t) newPageDirectory, 1, 1); @@ -583,7 +603,7 @@ } /* Map The Top 1GB Region Of The VM Space */ - for (x = 768; x < PAGE_ENTRIES; x++) { + for (x = PAGE_KERNEL_ENTRY; x < PAGE_ENTRIES; x++) { newPageDirectory[x] = parentPageDirectory[x]; } @@ -632,6 +652,9 @@ /* $Log$ + Revision 1.10 2009/07/09 00:49:50 reddawg + Lots of fixes and renaming to the vmm portion of the kernel + END */