Voxia OS v0.0.1
Hobby Project Operating System Targeting x86-64
Loading...
Searching...
No Matches
phys_base_allocator.c
Go to the documentation of this file.
2#include "init/init.h"
3#include "libk/stivale2.h"
4#include <type.h>
5#include "memory/entry.h"
6#include <hal/cpu/paging.h>
7#include <spinlock.h>
8#include <libk/debug/debug.h>
9#include <libk/serial.h>
10#include <str.h>
11#include <memory/memory_utils.h>
12
17
20size_t dma_bitmap_size = 0;
24
25extern size_t
27
28static const char* pMemoryType(uint32_t type) {
29 switch (type) {
31 return "USABLE";
33 return "RESERVED";
35 return "ACPI_RECLAIMABLE";
37 return "ACPI_NVS";
39 return "BAD_MEMORY";
41 return "BOOTLOADER_RECLAIMABLE";
43 return "KERNEL_AND_MODULES";
45 return "FRAMEBUFFER";
46 case 0x7373:
47 return "DMA";
48 default:
49 return "UNKNOWN";
50 }
51}
52
53INIT(phys_base_allocator) {
54 LOG_INFO("PHYS", "memory entries %d", ctx->memory.memory_entries);
55
56 memory_entry_t* smallest_entry = NULL;
57
58 for (register uint64_t i = 0; i < ctx->memory.memory_entries; i++) {
59 memory_entry_t* entry = &ctx->memory.memory_map[i];
60 higher_base_length_ += entry->length;
61
62 if (entry->type == ENTRY_MMAP_USABLE) {
63 usable_total += entry->length;
64 }
65 }
66
67 uintptr_t smalest_base1 = __UINT64_MAX__;
68 uintptr_t smalest_base2 = __UINT64_MAX__;
69
70 // mencari base addr terkecil ke 2 untuk keperluan DMA
71 for (uint64_t i = 0; i < ctx->memory.memory_entries; i++) {
72 memory_entry_t* entry = &ctx->memory.memory_map[i];
73
74 if (entry->type != ENTRY_MMAP_USABLE)
75 continue;
76
77 if (entry->base > 0) {
78 if (entry->base < smalest_base1) {
79 smalest_base2 = smalest_base1;
80 smalest_base1 = entry->base;
81 } else if (entry->base < smalest_base2
82 && entry->base != smalest_base1) {
83 smalest_base2 = entry->base;
84 smallest_entry = entry;
85 smallest_free_entry_base = entry->base;
86 }
87 }
88 }
89
90 LOG_INFO("PHYS", "smalest base 1 : 0x%x", smalest_base1);
91 LOG_INFO("PHYS", "smalest base 2 : 0x%x", smalest_base2);
92
93 if (smallest_entry == NULL) {
94 LOG_ERROR("PHYS", "failed to find DMA region");
95 return; // atau panic
96 }
97
98 smallest_entry->type = STIVALE2_MMAP_RESERVED;
99 LOG_INFO("PHYS", "DMA base 0x%x size %d kb", smallest_free_entry_base,
100 smallest_entry->length / 1024);
101
102 // metadata
105
106 LOG_INFO("MEMORY", "metadata count %d with size %d kb", metadata_count,
107 metadata_size / 1024);
108
109 for (uint64_t i = 0; i < ctx->memory.memory_entries; i++) {
110 memory_entry_t* entry = &ctx->memory.memory_map[i];
111
112 if (entry->length >= metadata_size
113 && entry->type == STIVALE2_MMAP_USABLE) {
114 LOG_INFO("MEMORY",
115 "found suitale place for metadata 0x%x length "
116 "%d kb",
117 entry->base, entry->length / 1024);
118
119 // phys_boot_metadata = (memory_4k_block
120 // *)(entry->base);
121 bitmap_base_ = (uint8_t*) (entry->base);
122 entry->length -= metadata_size;
123 entry->base += metadata_size;
124 break;
125 }
126 }
127
129
130 for (uint64_t i = 0; i < ctx->memory.memory_entries; i++) {
131 memory_entry_t* entry = &ctx->memory.memory_map[i];
132
133 if (entry->type != ENTRY_MMAP_USABLE)
134 continue;
135
136 uint64_t metadata_index = entry->base / 0x1000;
137 uint64_t metadata_end = entry->length / 0x1000;
138 for (uint64_t j = metadata_index;
139 j < (metadata_index + metadata_end); j++) {
140 bitmap_base_[j / 8] &= ~(1 << (j % 8));
141 }
142 }
143
144 // {
145 // smallest_entry->type = 0x7373;
146 // uint64_t metadata_index = smallest_entry->base / 0x1000;
147 // uint64_t metadata_end = smallest_entry->length / 0x1000;
148 // for (uint64_t j = metadata_index; j < (metadata_index +
149 // metadata_end); j++)
150 // {
151 // bitmap_base_[j / 8] |= (1 << (j % 8));
152 // }
153 // }
154
155 // find first smallest entry
156 for (uint64_t i = 0; i < higher_base_length_ / BLOCK_SIZE; i++) {
157 if ((bitmap_base_[i / 8] & (1 << (i % 8))) == 0) {
158 LOG_INFO("MEMORY", "found smallest entry at index %d",
159 i);
160 break;
161 }
162 }
163
164 // mark smallest entry sebagai reserved atau digunakan
165 LOG_INFO("MEMORY", "usable memory size : %d mb",
166 usable_total / 1024 / 1024);
167 for (uint64_t i = 0; i < ctx->memory.memory_entries; i++) {
168 memory_entry_t* entry = &ctx->memory.memory_map[i];
169 LOG_INFO("MEMORY",
170 "entry %d base 0x%x -- 0x%x length %d (%d Kb) type %s",
171 i, entry->base, entry->base + entry->length,
172 entry->length, entry->length / 1024,
173 pMemoryType(entry->type));
174 }
175
176 // dma allocator
177 // dma_bitmap_count = smallest_entry->length / BLOCK_SIZE / 8;
178 // dma_bitmap_size = ALIGN_UP(dma_bitmap_count * sizeof(uint8_t),
179 // BLOCK_SIZE);
180
181 // dma_bitmap_base_ = (uint8_t *)(smallest_entry->base);
182 // memset(dma_bitmap_base_, 0, dma_bitmap_size);
183}
184
185static spinlock_t pmm_lock = {0};
186
189 uint64_t total_blocks = higher_base_length_ / BLOCK_SIZE;
190 uint64_t consecutive = 0;
191 uint64_t start = 0;
192
193 uint64_t i = 0;
194
195 while (i < total_blocks) {
196 uint64_t word_idx = i / 64;
197 uint64_t bit_idx = i % 64;
198
199 uint64_t word;
200 memcopy(&word, &bitmap_base_[word_idx * 8], sizeof(word));
201
202 word >>= bit_idx;
203
204 if (bit_idx == 0 && word == (uint64_t) -1) {
205 i += 64;
206 consecutive = 0;
207 continue;
208 }
209
210 if (word == (uint64_t) -1) {
211 i += 64 - bit_idx;
212 consecutive = 0;
213 continue;
214 }
215
216 for (uint64_t b = bit_idx; b < 64 && i < total_blocks;
217 b++, i++) {
218 bool used = (bitmap_base_[i / 8] >> (i % 8)) & 1;
219 if (!used) {
220 if (consecutive == 0)
221 start = i;
222 consecutive++;
223 if (consecutive == block) {
224 // Set bit berturut-turut
225 for (uint64_t j = start;
226 j < start + block; j++)
227 bitmap_base_[j / 8] |=
228 (1 << (j % 8));
229
231 return (void*) (start * BLOCK_SIZE);
232 }
233 } else {
234 consecutive = 0;
235 }
236 }
237 }
238
240 return NULL;
241}
242
244 if (block == 0)
245 return NULL;
246
247 return NULL;
248}
249
251 uint64_t count = 0;
252 uint64_t total_blocks = higher_base_length_ / BLOCK_SIZE;
253
254 for (uint64_t i = 0; i < total_blocks; i++) {
255 if (!(bitmap_base_[i / 8] & (1 << (i % 8)))) {
256 count++;
257 }
258 }
259
260 return count;
261}
262
265 uint64_t index = (uint64_t) ptr / BLOCK_SIZE;
266 for (uint64_t i = index; i < index + size; i++) {
267 bitmap_base_[i / 8] &= ~(1 << (i % 8));
268 }
270}
271
273 uint64_t total_blocks = usable_total / BLOCK_SIZE;
275 uint64_t used_blocks = total_blocks - free_blocks;
276
277 KDEBUG(DEBUG_LEVEL_INFO, "used memory : %d mb / %d mb (%d mb free)\n",
278 used_blocks * BLOCK_SIZE / 1024 / 1024,
279 total_blocks * BLOCK_SIZE / 1024 / 1024,
280 free_blocks * BLOCK_SIZE / 1024 / 1024);
281}
int count
Definition cache.h:2
@ DEBUG_LEVEL_INFO
Definition debug.h:8
#define KDEBUG(...)
Definition debug.h:16
boolean_t used
Definition ehci.hpp:6
@ ENTRY_MMAP_ACPI_NVS
Definition entry.h:10
@ ENTRY_MMAP_ACPI_RECLAIMABLE
Definition entry.h:9
@ ENTRY_MMAP_KERNEL_AND_MODULES
Definition entry.h:13
@ ENTRY_MMAP_RESERVED
Definition entry.h:8
@ ENTRY_MMAP_FRAMEBUFFER
Definition entry.h:14
@ ENTRY_MMAP_BAD_MEMORY
Definition entry.h:11
@ ENTRY_MMAP_BOOTLOADER_RECLAIMABLE
Definition entry.h:12
@ ENTRY_MMAP_USABLE
Definition entry.h:7
#define INIT(fn)
Definition init.h:26
#define ALIGN_UP(x, align)
Definition memory_utils.h:6
uint64_t metadata_size
size_t dma_bitmap_size
uint8_t * dma_bitmap_base_
uint8_t * bitmap_base_
struct stivale2_struct_tag_memmap * saved_memmap_info
void * phys_base_alloc(uint64_t block)
static spinlock_t pmm_lock
void vxPhysBaseFree(void *ptr, uint64_t size)
uint64_t higher_base_length_
void pmm_log_usage()
uint64_t smallest_free_entry_base
uint64_t pys_base_get_free_block_count()
size_t __fast_phys_base_find_free_block__(uint64_t *bitmap, size_t num_words)
uint64_t usable_total
size_t dma_bitmap_count
uint64_t metadata_count
static const char * pMemoryType(uint32_t type)
void * phys_base_alloc_on_top(uint64_t block)
#define BLOCK_SIZE
#define LOG_ERROR(mod, fmt,...)
Definition serial.h:25
#define LOG_INFO(mod, fmt,...)
Definition serial.h:20
void spin_acquire(spinlock_t *lock)
Definition spinlock.c:8
void spin_release(spinlock_t *lock)
Definition spinlock.c:19
#define STIVALE2_MMAP_USABLE
Definition stivale2.h:155
#define STIVALE2_MMAP_RESERVED
Definition stivale2.h:156
void memset(void *ptr, int value, size_t num)
void memcopy(void *dest, void *src, size_t size)
#define NULL
Definition type.h:76
unsigned int uint32_t
Definition type.h:19
unsigned long uintptr_t
Definition type.h:73
unsigned long uint64_t
Definition type.h:25
unsigned char uint8_t
Definition type.h:7
uint8_t type
Definition vnode.h:2
size_t size
Definition vnode.h:3
uint64_t ptr
Definition xhci.hpp:0