# 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 = (u_int32_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