LF OS
Hobby operating system for amd64 with high ambitions
Loading...
Searching...
No Matches
mm.c
Go to the documentation of this file.
1#include "arch.h"
2#include "mm.h"
3#include "vm.h"
4#include "log.h"
5#include "panic.h"
6
7#define PRESENT_BIT 1
8
15
17
19 entry->start = 0;
20 entry->count = 0;
21 entry->status = MM_UNKNOWN;
22}
23
26
27 while(current) {
28 if(current->status == MM_FREE && current->count >= count) {
29 current->count -= count;
30 void* ret = (void*)current->start;
31
32 if(current->count) {
33 current->start += 4096 * count;
34 }
35 else {
37 }
38
39 return ret;
40 }
41
42 current = current->next;
43 }
44
45 panic_message("Out of memory in mm_alloc_pages");
46}
47
49 mm_page_list_entry_t* previous = 0;
50
51 while(start) {
52 if(start->status == MM_UNKNOWN && start->start == 0 && start->count == 0) {
53 return start;
54 }
55
56 previous = start;
57 start = start->next;
58 }
59
61
62 for(unsigned long i = 0; i < 4096 / sizeof(mm_page_list_entry_t); i++) {
63 new[i].start = 0;
64 new[i].count = 0;
65 new[i].status = MM_UNKNOWN;
66
67 if(i) {
68 new[i - 1].next = new + i;
69 }
70 }
71
72 previous->next = new;
73 return new;
74}
75
76void mm_bootstrap(ptr_t usable_page) {
77 while(usable_page % 4096);
78
79 // bootstrap memory management with the first page given to us
80 mm_page_list_entry_t* page_list = (mm_page_list_entry_t*)usable_page;
81 mm_physical_page_list = page_list;
82
83 for(unsigned long i = 0; i < 4096 / sizeof(mm_page_list_entry_t); i++) {
84 page_list[i].start = 0;
85 page_list[i].count = 0;
86 page_list[i].status = MM_UNKNOWN;
87 page_list[i].next = &page_list[i + 1];
88 }
89
90 page_list[(4096 / sizeof(mm_page_list_entry_t)) - 1].next = 0;
91}
92
94 if(!count) {
95 return;
96 }
97
98 if(!mm_physical_page_list && status == MM_FREE) {
99 mm_bootstrap(start);
100 return;
101 }
102 else if(!mm_physical_page_list && status != MM_FREE) {
103 panic_message("mm not bootstrapped with free page first!");
104 }
105
107 while(current) {
108 if(start >= current->start && start + (count * 4096) <= current->start + (current->count * 4096)) {
109 if(current->status == status) {
110 return;
111 }
112 else {
113 mm_page_status_t old_status = current->status;
114
115 ptr_t start_first = current->start;
116 uint64_t count_first = (start - start_first) / 4096;
117
118 if(count_first == 0) {
119 mm_del_page_list_entry(current);
120 }
121 else {
122 current->start = start_first;
123 current->count = count_first;
124 }
125
126 ptr_t start_second = start + (count * 4096);
127 uint64_t count_second = (current->start + (current->count * 4096)) - (start + (count * 4096));
128
129 if(count_second) {
131 entry->start = start_second;
132 entry->count = count_second;
133 entry->status = old_status;
134 }
135
137 entry->start = start;
138 entry->count = count;
139 entry->status = status;
140
141 return;
142 }
143 }
144
145 current = current->next;
146 }
147
149 new->start = start;
150 new->count = count;
151 new->status = status;
152}
153
156
157 while(current) {
158 if(current->status == MM_FREE) {
159 logd("mm", "%d free pages starting at 0x%x\n", current->count, current->start);
160 }
161
162 current = current->next;
163 }
164}
165
167 ptr_t res = 0;
169
170 while(current) {
171 if(current->start + current->count > res) {
172 res = current->start + (current->count * 4096);
173 }
174
175 current = current->next;
176 }
177
178 return res;
179}
uint64_t ptr_t
Definition arch.h:17
unsigned long uint64_t
Definition arch.h:14
#define ALLOCATOR_REGION_KERNEL_HEAP
Definition vm.h:25
#define logd(component, fmt,...)
Definition log.h:28
void mm_bootstrap(ptr_t usable_page)
Definition mm.c:76
void * mm_alloc_pages(uint64_t count)
Definition mm.c:24
void mm_print_physical_free_regions(void)
Definition mm.c:154
void mm_mark_physical_pages(ptr_t start, uint64_t count, mm_page_status_t status)
Definition mm.c:93
ptr_t mm_highest_address(void)
Definition mm.c:166
void mm_del_page_list_entry(mm_page_list_entry_t *entry)
Definition mm.c:18
void * next
Definition mm.c:12
uint64_t count
Definition mm.c:11
mm_page_list_entry_t * mm_get_page_list_entry(mm_page_list_entry_t *start)
Definition mm.c:48
mm_page_list_entry_t * mm_physical_page_list
Definition mm.c:16
mm_page_status_t status
Definition mm.c:13
Definition mm.c:9
mm_page_status_t
Definition mm.h:11
@ MM_UNKNOWN
Definition mm.h:12
@ MM_FREE
Definition mm.h:13
void panic_message(const char *message)
Definition panic.c:64
static void * entry
Definition syscalls.h:34
ptr_t vm_context_alloc_pages(struct vm_table *context, region_t region, size_t num)
Definition vm.c:560
struct vm_table * VM_KERNEL_CONTEXT
Definition vm.c:16