blob: 989f82a98998061fe3baa02cb9fdf2c5c2a88e83 (
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
|
#include "page_early.h"
#include "panic.h"
#include <libc/stdio.h>
static struct page_early_state
{
struct memory_range *first;
struct memory_range *current;
struct memory_range *last;
}
early_state;
void page_early_init(void)
{
printf("initializing early page frame allocator\n");
struct kc_boot_data *boot_data = get_boot_data();
early_state.first = &boot_data->memory.entries[0];
early_state.last = &boot_data->memory.entries[boot_data->memory.count];
early_state.current = early_state.first;
/*printf("memory ranges\n");
struct memory_range *current = early_state.first;
do
{
printf("base %#0.16lx size %#0.16lx type %d\n", current->base, current->size, current->type);
current++;
}
while (current != early_state.last);
*/
}
void page_early_final(void)
{
if (early_state.first)
{
printf("finalizing early page allocator\n");
for (struct memory_range *current = early_state.first;
current < early_state.last;
current++)
{
while (current->type != RESERVED_MEMORY && current->size >= page_size(1))
{
current->size -= page_size(1);
enum memory_range_type type = current->type;
kc_phys_addr page = current->base + current->size;
// all pages are gonna be set allocated first
// to initialize the tracking structure at the other side
// and make setting the page free as simple as
// calling page_free();
page_set_allocated(page);
switch (type)
{
case SYSTEM_MEMORY:
page_set_present(page);
break;
case AVAILABLE_MEMORY:
page_set_present(page);
page_free(page);
break;
case FIRMWARE_MEMORY:
case MMIO_MEMORY:
break;
default:
break;
}
}
}
early_state = (struct page_early_state){NULL, NULL, NULL};
}
}
kc_phys_addr page_early_alloc(enum page_alloc_flags type)
{
// TODO: support low/conv/high allocations in early_alloc.
// currently we only have conventional allocations enforced
// by the conditions of the scanning loop
(void)type;
while(early_state.current)
{
if ((early_state.current->type == AVAILABLE_MEMORY) &&
(early_state.current->base > 0x10000) &&
(early_state.current->size > page_size(1)))
{
early_state.current->size -= page_size(1);
return early_state.current->base + early_state.current->size;
}
if (early_state.current == early_state.last)
{
early_state.current = NULL;
break;
}
early_state.current++;
}
printf("error: early allocator has run out of memory\n");
PANIC(OUT_OF_MEMORY);
}
|