UbixOS  2.0
getfreevirtualpage.c
Go to the documentation of this file.
1  /*-
2  * Copyright (c) 2002-2018 The UbixOS Project.
3  * All rights reserved.
4  *
5  * This was developed by Christopher W. Olsen for the UbixOS Project.
6  *
7  * Redistribution and use in source and binary forms, with or without modification, are permitted
8  * provided that the following conditions are met:
9  *
10  * 1) Redistributions of source code must retain the above copyright notice, this list of
11  * conditions, the following disclaimer and the list of authors.
12  * 2) Redistributions in binary form must reproduce the above copyright notice, this list of
13  * conditions, the following disclaimer and the list of authors in the documentation and/or
14  * other materials provided with the distribution.
15  * 3) Neither the name of the UbixOS Project nor the names of its contributors may be used to
16  * endorse or promote products derived from this software without specific prior written
17  * permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
20  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
22  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
24  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
26  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include <vmm/vmm.h>
30 #include <ubixos/sched.h>
31 #include <ubixos/kpanic.h>
32 #include <ubixos/spinlock.h>
33 #include <lib/kprintf.h>
34 
35 static struct spinLock fvpSpinLock = SPIN_LOCK_INITIALIZER;
36 
37 /************************************************************************
38 
39  Function: void *vmm_getFreeVirtualPage(pidType pid,int count);
40  Description: Returns A Free Page Mapped To The VM Space
41  Notes:
42 
43  2016-01-21 MrOlsen - I'm not 100% happy with this, i know I can make the calculations much faster
44 
45  08/11/02 - This Will Return Next Avilable Free Page Of Tasks VM Space
46 
47  ************************************************************************/
48 void *vmm_getFreeVirtualPage(pidType pid, int count, int type) {
49  int y = 0, counter = 0, pdI = 0x0, ptI = 0x0;
50 
51  uint32_t *pageDirectory = 0x0;
52  uint32_t *pageTable = 0x0;
53 
54  uint32_t start_page = 0x0;
55  uint32_t map_from = 0x0;
56 
57  spinLock(&fvpSpinLock);
58 
59  pageDirectory = (uint32_t *) PD_BASE_ADDR;
60 
61  /* Lets Search For A Free Page */
62  if (_current->oInfo.vmStart <= 0x100000)
63  kpanic("Invalid vmStart\n");
64 
65  /* Get Our Starting Address */
66  if (type == VM_THRD) {
67  start_page = (uint32_t) (_current->td.vm_daddr + ctob(_current->td.vm_dsize));
68  }
69  else if (type == VM_TASK) {
70  start_page = _current->oInfo.vmStart;
71  }
72  else
73  K_PANIC("Invalid Type");
74 
75 
76  /* Locate Initial Page Table */
77  keepMapping:
78  pdI = PD_INDEX(start_page);
79 
80  if (pdI > PD_INDEX(VMM_USER_END)) {
81  map_from = 0x0;
82  goto doneMapping;
83  }
84 
85  /* If Page Directory Is Not Yet Allocated Allocate It */
86  if ((pageDirectory[pdI] & PAGE_PRESENT) != PAGE_PRESENT) {
87  vmm_allocPageTable(pdI, pid);
88  }
89 
90  pageTable = (uint32_t *) (PT_BASE_ADDR + (pdI * PAGE_SIZE));
91 
92  ptI = PT_INDEX(start_page);
93 
94  for (y = ptI; y < PT_ENTRIES && counter < count; y++, counter++) {
95 
96  /* Loop Through The Page Table Find An UnAllocated Page */
97  if ((pageTable[y] & PAGE_PRESENT) == PAGE_PRESENT) {
98  if ((pageTable[y] & PAGE_COW) == PAGE_COW)
99  kprintf("COW PAGE NOT CLEANED!");
100 
101  start_page += (PAGE_SIZE * counter);
102  map_from = 0x0;
103  counter = 0;
104  goto keepMapping;
105  }
106 
107  if (map_from == 0x0)
108  map_from = start_page;
109  }
110 
111  if (counter < count) {
112  start_page += (PAGE_SIZE * counter);
113  goto keepMapping;
114  }
115 
116  gotPages:
117  if (type == VM_THRD)
118  _current->td.vm_dsize += btoc(count * PAGE_SIZE);
119  else if (type == VM_TASK)
120  _current->oInfo.vmStart = map_from + (count * PAGE_SIZE);
121 
122  //_current->oInfo.vmStart += (count * PAGE_SIZE);
123 
124  for (counter = 0; counter < count; counter++) {
125  if ((vmm_remapPage((uint32_t) vmm_findFreePage(pid), (map_from + (counter * PAGE_SIZE)), PAGE_DEFAULT, pid, 0)) == 0x0)
126  kpanic("vmmRemapPage: getFreeVirtualPage-1: (%i)[0x%X]\n", type, map_from + (counter * PAGE_SIZE));
127 
128  bzero((map_from + (counter * PAGE_SIZE)), PAGE_SIZE);
129  }
130 
131  doneMapping:
132  spinUnlock(&fvpSpinLock);
133  return (map_from);
134 }
spinlock.h
VM_THRD
#define VM_THRD
Definition: paging.h:51
PAGE_COW
#define PAGE_COW
Definition: paging.h:64
K_PANIC
#define K_PANIC(msg)
Definition: kpanic.h:32
ctob
#define ctob(x)
Definition: paging.h:74
spinUnlock
void spinUnlock(spinLock_t *lock)
Definition: spinlock.c:36
vmm.h
SPIN_LOCK_INITIALIZER
#define SPIN_LOCK_INITIALIZER
Definition: spinlock.h:36
sched.h
kpanic
void kpanic(const char *fmt,...)
print panic message and halt system
Definition: kpanic.c:41
bzero
#define bzero(buf, size)
Definition: gpt.h:37
btoc
#define btoc(x)
Definition: paging.h:75
taskStruct::td
struct thread td
Definition: sched.h:78
osInfo::vmStart
uInt32 vmStart
Definition: sched.h:54
spinLock
void spinLock(spinLock_t *lock)
Definition: spinlock.c:55
VM_TASK
#define VM_TASK
Definition: paging.h:52
kpanic.h
vmm_findFreePage
uint32_t vmm_findFreePage(pidType pid)
Definition: vmm_memory.c:221
PT_ENTRIES
#define PT_ENTRIES
Definition: paging.h:49
kprintf.h
PD_INDEX
#define PD_INDEX(v_addr)
Definition: paging.h:40
PAGE_DEFAULT
#define PAGE_DEFAULT
Definition: paging.h:68
vmm_remapPage
int vmm_remapPage(uint32_t, uint32_t, uint16_t, pidType, int haveLock)
Definition: paging.c:199
PD_BASE_ADDR
#define PD_BASE_ADDR
Definition: paging.h:45
uint32_t
__uint32_t uint32_t
Definition: types.h:46
thread::vm_dsize
u_long vm_dsize
Definition: thread.h:44
_current
kTask_t * _current
Definition: sched.c:50
PT_INDEX
#define PT_INDEX(v_addr)
Definition: paging.h:42
pidType
int pidType
Definition: types.h:75
thread::vm_daddr
u_long vm_daddr
Definition: thread.h:43
vmm_getFreeVirtualPage
void * vmm_getFreeVirtualPage(pidType pid, int count, int type)
Definition: getfreevirtualpage.c:47
spinLock
Definition: spinlock.h:41
PAGE_SIZE
#define PAGE_SIZE
Definition: paging.h:37
kprintf
int kprintf(const char *,...)
Definition: kprintf.c:259
VMM_USER_END
#define VMM_USER_END
Definition: vmm.h:59
PT_BASE_ADDR
#define PT_BASE_ADDR
Definition: paging.h:46
PAGE_PRESENT
#define PAGE_PRESENT
Definition: paging.h:55
taskStruct::oInfo
struct osInfo oInfo
Definition: sched.h:69
vmm_allocPageTable
int vmm_allocPageTable(uint32_t, pidType)
Definition: vmm_allocpagetable.c:7