blob: 407aad6e3abda46b17bcb88f7a89a6706f6ebfe6 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
/* Bitmap Based Allocation:
* https://web.archive.org/web/20190316115948/http://www.brokenthorn.com/Resources/OSDev17.html
*/
#include <stdbool.h>
#include <stdint.h>
#include <libk/stdio.h>
#include <mm/memory_map.h>
#include <mm/physical_mm.h>
#include <kernel/halt.h>
extern uint32_t kernel_start;
extern uint32_t kernel_end;
uint32_t block_count;
uint32_t *memory_map;
void
physical_mm_init(void)
{
free_memory_regions_t *free_memory_regions = memory_map_get_free_regions();
/* TODO: Initialize these free memory regions */
printk("\nphysical_mm", "Free Memory Regions:");
for (int i = 0; i < free_memory_regions->n_regions; i++)
printk("physical_mm",
"start: 0x%.08x | length: 0x%.08x",
free_memory_regions->region_list[i]->addr_low,
free_memory_regions->region_list[i]->len_low);
/* TODO: De-initialize region used by the kernel */
printk("\nphysical_mm", "Kernel region:");
printk("physical_mm", "Start: 0x%x", &kernel_start);
printk("physical_mm", "End: 0x%x", &kernel_end);
printk("physical_mm",
"Size: 0x%x",
((uint32_t) &kernel_end) - ((uint32_t) &kernel_start));
}
ALWAYS_INLINE void
physical_mm_set(const uint32_t bit)
{
uint32_t memory_map_index = bit / BITMAP_ENTRY_SIZE;
uint32_t bitmask = 1 << (bit % BITMAP_ENTRY_SIZE);
memory_map[memory_map_index] |= bitmask;
}
ALWAYS_INLINE void
physical_mm_unset(const uint32_t bit)
{
uint32_t memory_map_index = bit / BITMAP_ENTRY_SIZE;
uint32_t bitmask = 1 << (bit % BITMAP_ENTRY_SIZE);
memory_map[memory_map_index] &= ~bitmask;
}
/* Returns:
* True if the bit is unset (block isn't in use)
* False if the bit is used (block is in use)
*/
ALWAYS_INLINE bool
physical_mm_test_bit(const uint32_t bit)
{
uint32_t memory_map_index = bit / BITMAP_ENTRY_SIZE;
uint32_t bitmask = 1 << (bit % BITMAP_ENTRY_SIZE);
return memory_map[memory_map_index] & bitmask;
}
uint32_t
physical_mm_find_first_free(void)
{
for (uint32_t i = 0; i < block_count / BITMAP_ENTRY_SIZE; i++)
/* All blocks in the entry aren't in use */
if (memory_map[i] != 0xffffffff)
/* Test each bit to see if it's zero */
for (uint32_t j = 0; j < BITMAP_ENTRY_SIZE; j++)
if (physical_mm_test_bit(i * BITMAP_ENTRY_SIZE + j))
return i * BITMAP_ENTRY_SIZE + j;
ASSERT_NOT_REACHED();
return -1;
}
|