getfreevirtualpage.c

Go to the documentation of this file.
00001 /*****************************************************************************************
00002  Copyright (c) 2002-2004 The UbixOS Project
00003  All rights reserved.
00004 
00005  Redistribution and use in source and binary forms, with or without modification, are
00006  permitted provided that the following conditions are met:
00007 
00008  Redistributions of source code must retain the above copyright notice, this list of
00009  conditions, the following disclaimer and the list of authors.  Redistributions in binary
00010  form must reproduce the above copyright notice, this list of conditions, the following
00011  disclaimer and the list of authors in the documentation and/or other materials provided
00012  with the distribution. Neither the name of the UbixOS Project nor the names of its
00013  contributors may be used to endorse or promote products derived from this software
00014  without specific prior written permission.
00015 
00016  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
00017  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00018  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
00019  THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00020  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
00021  OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00022  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
00023  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00024  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00025 
00026  $Id: getfreevirtualpage_8c-source.html 88 2016-01-12 00:11:29Z reddawg $
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 Function: void *vmmGetFreeVirtualPage(pidType pid,int count);
00041 Description: Returns A Free Page Mapped To The VM Space
00042 Notes:
00043 
00044 08/11/02 - This Will Return Next Avilable Free Page Of Tasks VM Space
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   /* Lets Search For A Free Page */
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     //kprintf("vmStart");
00067     start_page = _current->oInfo.vmStart;
00068     }
00069   else
00070     K_PANIC("Invalid Type");
00071 
00072   //for (x = ((_current->td.vm_daddr + _current->td.vm_dsize) / (1024 * 4096)); x < 1024; x++) {
00073   for (x = (start_page / (1024 * 4096)); x < 1024; x++) {
00074     /* Set Page Table Address */
00075     if ((pageDir[x] & PAGE_PRESENT) != PAGE_PRESENT) {
00076       /* If Page Table Is Non Existant Then Set It Up */
00077       pageDir[x] = (uInt32) vmmFindFreePage(_current->id) | PAGE_DEFAULT;
00078       /* Also Add It To Virtual Space So We Can Make Changes Later */
00079       pageTableSrc = (uInt32 *) (tablesBaseAddress + (4096 * 767));
00080       pageTableSrc[x] = pageDir[x];
00081       y = 1;
00082       /* Reload Page Directory */
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       /* Loop Through The Page Table Find An UnAllocated Page */
00096       if ((pageTableSrc[y] & PAGE_COW) == PAGE_COW) {
00097         kprintf("PAGE_COW");
00098         //_current->td.vm_dsize += btoc(0x1000);
00099         /* HACK MEMORY LEAK */
00100         //pageTableSrc[y] = 0x0;
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         //_current->td.vm_dsize += btoc(0x1000);
00109         /* HACK MEMORY LEAK */
00110         //pageTableSrc[y + c] = 0x0;
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           /* Map A Physical Page To The Virtual Page */
00132 
00133           /*
00134            * remapPage((uInt32)vmmFindFreePage(pid),((x*(1024*4096))+(y*4096))
00135            * ,pid);
00136            */
00137           if ((vmm_remapPage((uInt32) vmmFindFreePage(pid), ((x * (1024 * 4096)) + (y * 4096)),PAGE_DEFAULT)) == 0x0)
00138             kpanic("vmmRemapPage: getFreeVirtualPage-2\n");
00139 
00140           /* Clear This Page So No Garbage Is There */
00141           vmmClearVirtualPage((uInt32) ((x * (1024 * 4096)) + (y * 4096)));
00142 
00143           /* Return The Address Of The Newly Allocate Page */
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           //kprintf("(0x%X:0x%X)",_current->td.vm_dsize,vmm_getPhysicalAddr(((x * (1024 * 4096)) + (y * 4096))));
00149 //          kprintf("(0x%X:0x%X)",_current->td.vm_dsize + _current->td.vm_daddr,((x * (1024 * 4096)) + (y * 4096)));
00150           spinUnlock(&fvpSpinLock);
00151           return ((void *)((x * (1024 * 4096)) + (y * 4096)));
00152         }
00153       }
00154     }
00155   }
00156   /* If No Free Page Was Found Return NULL */
00157   spinUnlock(&fvpSpinLock);
00158   return (0x0);
00159 }
00160 
00161 /***
00162  END
00163  ***/
00164 

Generated on Fri Dec 15 11:18:55 2006 for UbixOS V2 by  doxygen 1.4.7