Voxia OS v0.0.1
Hobby Project Operating System Targeting x86-64
Loading...
Searching...
No Matches
vm_manager.c
Go to the documentation of this file.
1#include "autoconf.h"
2#include "init/init.h"
3#include <hal/cpu/paging.h>
4#include <libk/serial.h>
7#include <memory/slab.h>
8#include <memory/vm_manager.h>
9#include <spinlock.h>
10#include <str.h>
11#include <type.h>
12
13#define RBT_TYPE virtual_memory_t
14#define RBT_ID_NAME start_address
15#include <libk/tree/rbt.h>
16
17#define PERCPU __attribute__((section(".data.percpu")))
18
20
22
24
26static struct slab_cache* vma_cache = NULL;
29static struct slab_cache* vma_page = NULL;
30
34 struct virtual_memory_tree_node* node =
36 memset(node, 0, sizeof(struct virtual_memory_tree_node));
39 node->next = 0;
40
41 switch ((uintptr_t)region) {
42 case VMA_REGION_A: {
43 node->next = page->vma_tree_zone_a.active;
44 page->vma_tree_zone_a.active = node;
45 break;
46 }
47 case VMA_REGION_B: {
48 node->next = page->vma_tree_zone_b.active;
49 page->vma_tree_zone_b.active = node;
50 break;
51 }
52 case VMA_REGION_C: {
53 node->next = page->vma_tree_zone_c.active;
54 page->vma_tree_zone_c.active = node;
55 break;
56 }
57 case VMA_REGION_KMODULE: {
58 node->next = page->vma_tree_zone_kmodule.active;
59 page->vma_tree_zone_kmodule.active = node;
60 break;
61 }
62 case VMA_REGION_PROCESS: {
63 node->next = page->vma_tree_zone_process.active;
64 page->vma_tree_zone_process.active = node;
65 break;
66 }
67 default:
69 break;
70 }
71}
72
74 auto p = (struct virtual_memory_page*)vxSlabAlloc(vma_page);
75 memset(p, 0, sizeof(struct virtual_memory_page));
76 p->tree = VMA_RBT_NIL;
77 return p;
78}
79
80INIT(vma) {
81 vxCreateSlabCache(&rbt_node_cache, "rbt_node", sizeof(rbt_node), 64, 0);
82 vxCreateSlabCache(&vma_cache, "vma", sizeof(virtual_memory_t), 64, 0);
83 vxCreateSlabCache(&vma_tree_zone_cache, "vma_tree_zone",
84 sizeof(struct virtual_memory_tree_node), 64, 0);
86 sizeof(virtual_memory_block_t), 64, 0);
87 vxCreateSlabCache(&vma_page, "vma_page",
88 sizeof(struct virtual_memory_page), 64, 0);
89
92 VMA_RBT_NIL->data->start_address = 0;
93 VMA_RBT_NIL->data->end_address = 0;
94 VMA_RBT_NIL->left = VMA_RBT_NIL->right = VMA_RBT_NIL->parent =
96
98 serial_trace("ok\n");
99}
100
102 uintptr_t virt_addr, size_t size) {
103 spin_acquire(&page->lock);
105 node->start_address = virt_addr;
106 node->end_address = virt_addr + size;
108 node->length = size;
109 node->flags = 0;
110 node->core = 0;
111
113 rbt_insert_node(&page->tree, n, node, VMA_RBT_NIL);
114 spin_release(&page->lock);
115}
116
118 spin_acquire(&page->lock);
119 struct rbt_node* n =
120 rbt_search_node(page->tree, virt_addr, VMA_RBT_NIL);
121 virtual_memory_t* ret = (n != VMA_RBT_NIL) ? n->data : NULL;
122 spin_release(&page->lock);
123 return ret;
124}
125
127 spin_acquire(&page->lock);
128 struct rbt_node* n =
129 rbt_search_node(page->tree, virt_addr, VMA_RBT_NIL);
130 if (n == VMA_RBT_NIL) {
131 spin_release(&page->lock);
132 return;
133 }
134 rbt_remove_node(&page->tree, n, VMA_RBT_NIL);
135 spin_release(&page->lock);
136}
137
138static void vma_rbt_debug_node(rbt_node* node, int level) {
139 if (node == VMA_RBT_NIL || node == NULL)
140 return;
141
142 vma_rbt_debug_node(node->left, level + 1);
143
144 for (int i = 0; i < level; i++)
145 serial_trace(" ");
146 serial_trace("start 0x%x - 0x%x\n", node->data->start_address,
147 node->data->end_address);
148
149 vma_rbt_debug_node(node->right, level + 1);
150}
151
152__attribute__((unused)) static void vma_rbt_debug(rbt_node* root) {
154}
155
157 mem_vma_region region, size_t size) {
158 spin_acquire(&page->lock);
159
160 struct virtual_memory_tree_node* curr = NULL;
161
162 switch (region) {
163 case VMA_REGION_A:
164 curr = page->vma_tree_zone_a.active;
165 break;
166 case VMA_REGION_B:
167 curr = page->vma_tree_zone_b.active;
168 break;
169 case VMA_REGION_C:
170 curr = page->vma_tree_zone_c.active;
171 break;
173 curr = page->vma_tree_zone_kmodule.active;
174 break;
176 curr = page->vma_tree_zone_process.active;
177 break;
178 default:
179 spin_release(&page->lock);
180 return 0;
181 }
182
183 uintptr_t result;
184
185 if (curr == NULL) {
186 vma_tree_add_locked(page, region, (uintptr_t)region,
187 (uintptr_t)region +
188 (uintptr_t)0x1000 * size);
189 result = (uintptr_t)region;
190 } else {
191 uintptr_t next_addr = curr->end_address;
192 vma_tree_add_locked(page, region, next_addr,
193 next_addr + (uintptr_t)0x1000 * size);
194 result = next_addr;
195 }
196
197 spin_release(&page->lock);
198 return result;
199}
202
203#undef RBT_ID_NAME
204#undef RBT_TYPE
typedef __attribute__
Definition msi.c:47
#define INIT(fn)
Definition init.h:26
static struct ioforge_device * root
Definition ioforge.c:25
volatile boolean_t paging_has_been_set
Definition paging.c:18
uintptr_t page
Definition paging.c:0
static rbt_node * rbt_search_node(rbt_node *root, uint64_t id, rbt_node *NIL)
Definition rbt.h:168
static void rbt_remove_node(rbt_node **root, rbt_node *z, rbt_node *NIL)
Definition rbt.h:238
static int rbt_insert_node(rbt_node **root, rbt_node *z, struct __rbt_type *data, rbt_node *NIL)
Definition rbt.h:123
#define serial_trace(...)
Definition serial.h:19
void * vxSlabAlloc(struct slab_cache *cache)
Definition slab.c:93
void slab_free(struct slab_cache *cache, void *obj)
Definition slab.c:235
void vxCreateSlabCache(struct slab_cache **cache, const char *name, const size_t obj_size, size_t alignment, const uintptr_t virt_addr)
Definition slab.c:44
void spin_acquire(spinlock_t *lock)
Definition spinlock.c:8
void spin_release(spinlock_t *lock)
Definition spinlock.c:19
void memset(void *ptr, int value, size_t num)
Definition rbt.h:26
rbt_node * right
Definition rbt.h:29
rbt_node * left
Definition rbt.h:28
struct __rbt_type * data
Definition rbt.h:27
struct virtual_memory_tree_node * next
Definition vm_manager.h:49
uintptr_t phys_address
Definition vm_manager.h:39
uintptr_t end_address
Definition vm_manager.h:38
uintptr_t start_address
Definition vm_manager.h:37
#define NULL
Definition type.h:76
uint8_t boolean_t
Definition type.h:89
unsigned long uintptr_t
Definition type.h:73
static struct slab_cache * vma_block_cache
Definition vm_manager.c:28
struct virtual_memory_page * create_vmm_page()
Definition vm_manager.c:73
static struct slab_cache * vma_page
Definition vm_manager.c:29
static void vma_rbt_debug_node(rbt_node *node, int level)
Definition vm_manager.c:138
virtual_memory_t * vma_find(struct virtual_memory_page *page, uintptr_t virt_addr)
Definition vm_manager.c:117
uintptr_t vma_lookup_free_vaddr(struct virtual_memory_page *page, mem_vma_region region, size_t size)
Definition vm_manager.c:156
void vma_register(struct virtual_memory_page *page, uintptr_t phys_address, uintptr_t virt_addr, size_t size)
Definition vm_manager.c:101
void vma_unregister(struct virtual_memory_page *page, uintptr_t virt_addr)
Definition vm_manager.c:126
static struct slab_cache * vma_tree_zone_cache
Definition vm_manager.c:27
static rbt_node * VMA_RBT_NIL
Definition vm_manager.c:21
static struct virtual_memory_page * kernel_vmm_page
Definition vm_manager.c:23
static struct slab_cache * vma_cache
Definition vm_manager.c:26
static void vma_tree_add_locked(struct virtual_memory_page *page, mem_vma_region region, uintptr_t start_address, uintptr_t end_address)
Definition vm_manager.c:31
static struct slab_cache * rbt_node_cache
Definition vm_manager.c:25
struct virtual_memory_page * get_kernel_vmm_page()
uintptr_t end_address
Definition vm_manager.h:1
uintptr_t start_address
Definition vm_manager.h:0
struct virtual_memory_block virtual_memory_block_t
Definition vm_manager.h:28
struct virtual_memory virtual_memory_t
Definition vm_manager.h:35
uintptr_t phys_address
Definition vm_manager.h:2
mem_vma_region
Definition vm_manager.h:12
@ VMA_REGION_KMODULE
Definition vm_manager.h:16
@ VMA_REGION_A
Definition vm_manager.h:13
@ VMA_REGION_C
Definition vm_manager.h:15
@ VMA_REGION_B
Definition vm_manager.h:14
@ VMA_REGION_PROCESS
Definition vm_manager.h:25
size_t size
Definition vnode.h:3