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 <printf.h>
#include <paging.h>
#include <stdint.h>
// for now, this will always remain the same.
// If this ever isn't the case, we'll add paramaters to the paging functions.
// We will also never need to mess with many bits,
// as we are not implimenting security for a bare metal fractal generator.
// Also, is this really the cleanest way to do things?
//after we get paging working, we can probably remove these structs and replace them with plain old uint_16ts.
void debug_print_memory() {
struct memory_table *memtable = (struct memory_table *)&_meminfo_loc;
printf(" __________________________________________________________________________\n");
printf("| type\tstart\t\t\tend\t\t\tsize\t\t |\n");
printf("|--------------------------------------------------------------------------|\n");
for(unsigned int i = 0; memtable[i].length > 0; i++) {
printf("| %u %u\t0x%p\t0x%p\t0x%p |\n", memtable[i].type, memtable[i].ACPI, memtable[i].base, (memtable[i].base + memtable[i].length), memtable[i].length);
}
printf("----------------------------------------------------------------------------\n");
}
/**
* You can critisise the quality of this function all you want, it's messy due to planning mistakes
* and I'm planning on sanatising it.
* BUT, don't critisise it _just_ for using goto, that's bullshit. See the following links.
*
* https://www.kernel.org/doc/html/v4.17/process/coding-style.html "goto" section
* https://koblents.com/Ches/Links/Month-Mar-2013/20-Using-Goto-in-Linux-Kernel-Code/
**/
bool map_page(uintptr_t virtual_addr, uintptr_t physical_addr, uint8_t size) {
printf("map page called\n");
if((virtual_addr % (1 << size)) || (physical_addr % (1 << size))) {
return 0;
}
page_table *table = (page_table *)PAGEMAP_LOCATION;
int pte_i = (virtual_addr >> 12) & 0x1ff;
int pde_i = (virtual_addr >> 21) & 0x1ff;
int pdpe_i = (virtual_addr >> 30) & 0x1ff;
int pml4e_i = (virtual_addr >> 39) & 0x1ff;
//TODO remove this debugging info
printf("Virtual offsets:\npte:\t\t%i\npde:\t\t%i\npdpe:\t\t%i\npml4e\t\t%i\n", pte_i, pde_i, pdpe_i, pml4e_i);
if(table->pml4e[pml4e_i].present) {
if(table->pml4e[pml4e_i].base_ptr != (uintptr_t)&table->pdpe[pdpe_i] >> 12) goto error;
if(table->pdpe[pdpe_i].present) {
if(size == PAGE_SIZE_1G) {
if(table->pdpe[pdpe_i].base_ptr == (uintptr_t)physical_addr >> 30 & 0x1ff)
return true;
goto error;
}
if(table->pdpe[pdpe_i].base_ptr != (uintptr_t)&table->pde[pde_i] >> 12) goto error;
if(table->pde[pde_i].present) {
if(size == PAGE_SIZE_2M) {
if(table->pde[pde_i].base_ptr == (uintptr_t)physical_addr >> 21 & 0x1ff)
return true;
goto error;
}
if(table->pde[pde_i].base_ptr != (uintptr_t)&table->pte[pte_i] >> 12) goto error;
if(table->pte[pte_i].present) {
if(table->pte[pte_i].base_ptr != ((physical_addr >> 12) & 0x1ff)) goto error;
return true;
}
else goto mod_page_pte;
}
else goto mod_page_pde;
}
else goto mod_page_pdpe;
}
else {
table->pml4e[pml4e_i].base_ptr = (uintptr_t)&table->pdpe[pdpe_i] >> 12;
table->pdpe[pml4e_i].read_write = 1;
table->pml4e[pml4e_i].present = 1;
mod_page_pdpe:
table->pdpe[pdpe_i].read_write = 1;
if(size == PAGE_SIZE_1G) {
table->pdpe[pdpe_i].size = 1;
table->pdpe[pdpe_i].base_ptr = physical_addr >> 30;
table->pdpe[pdpe_i].present = 1;
return true;
}
table->pdpe[pdpe_i].base_ptr = (uintptr_t)&table->pde[pde_i] >> 12;
table->pdpe[pdpe_i].present = 1;
mod_page_pde:
table->pde[pde_i].read_write = 1;
if(size == PAGE_SIZE_2M) {
table->pde[pde_i].size = 1;
table->pde[pde_i].base_ptr = physical_addr >> 21;
table->pde[pde_i].present = 1;
return true;
}
table->pde[pde_i].base_ptr = (uintptr_t)&table->pte[pte_i] >> 12;
table->pde[pde_i].present = 1;
mod_page_pte:
table->pte[pte_i].base_ptr = (physical_addr >> 12);
table->pte[pte_i].read_write = 1;
table->pte[pte_i].present = 1;
return true;
}
error:
printf("Page allocation error!\n");
return false;
}
|