Skip to content

Commit d0671b0

Browse files
committed
kbtstrp cleanup
1 parent 3149c15 commit d0671b0

8 files changed

Lines changed: 119 additions & 148 deletions

File tree

include/stdbigos/error.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ typedef enum {
77
ERR_CRITICAL_INTERNAL_FAILURE,
88
ERR_HARDWARE_NOT_COMPATIBLE,
99
ERR_ALL_ADDRESS_SPACES_IN_USE,
10-
ERR_PHISICAL_MEMORY_FULL,
10+
ERR_PHYSICAL_MEMORY_FULL,
1111
} error_t;
1212

1313
const char* get_error_msg(error_t err);

src/bootstrap/bootstrap_memory_services.c

Lines changed: 40 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <debug/debug_stdio.h>
44
#include <stdbigos/string.h>
55

6+
// TODO: This shouldn't be here
67
u64 align_up(u64 val, u64 align) {
78
return (val + align - 1) & ~(align - 1);
89
}
@@ -23,48 +24,49 @@ u64 get_ram_size() {
2324
return s_mem_size;
2425
}
2526

26-
// This shouldn't be here
27+
// TODO: This also shouldn't be here
2728
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
2829
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
2930

30-
// I know this algorithm is very naive, but busy_memory_regions_amount most likely won't exceed 6
31-
error_t allocate_phisical_memory_region(void* dt, phisical_memory_region_t busy_memory_regions[],
32-
u64 busy_memory_regions_amount, u64 allocation_size, u64 aligment,
33-
phisical_memory_region_t* pmrOUT) {
34-
u64 unavalible_regions_in_dt_amount = 0;
35-
u64 unavalible_regions_amount = 0;
31+
// I know this algorithm is very naive, but busy memory regions amount most likely won't exceed 6
32+
error_t allocate_physical_memory_region(void* dt, u64 size, u64 align, physical_memory_region_t* pmrOUT) {
33+
static physical_memory_region_t allocated_memory_regions[16] = {0};
34+
static u64 allocated_regions_end_idx = 0;
35+
if(allocated_regions_end_idx >= sizeof(allocated_memory_regions) / sizeof(allocated_memory_regions[0]))
36+
return ERR_CRITICAL_INTERNAL_FAILURE;
3637
//TEST:
37-
unavalible_regions_in_dt_amount = 1;
38+
u64 unavaliable_regions_amount = 0;
39+
unavaliable_regions_amount = 1;
40+
physical_memory_region_t unavaliable_regions[unavaliable_regions_amount];
41+
unavaliable_regions[0] = (physical_memory_region_t){.address = (void*)0x80000000, .size = 160 * kiB};
42+
// TODO: read the rest of the unavalible memory regions and the region of kboot from the dt
3843
//!TEST
39-
phisical_memory_region_t unavalible_regions[unavalible_regions_in_dt_amount + busy_memory_regions_amount];
40-
if(busy_memory_regions)
41-
memcpy(unavalible_regions, busy_memory_regions, busy_memory_regions_amount * sizeof(phisical_memory_region_t));
42-
// TODO: read the rest of the unavalible memory regions from the dt
43-
//TEST:
44-
unavalible_regions[busy_memory_regions_amount] = (phisical_memory_region_t){.address = (void*)0x80000000, .size = 160 * 1024};
45-
//!TEST
46-
unavalible_regions_amount = unavalible_regions_in_dt_amount + busy_memory_regions_amount;
47-
48-
void* curr_addr = (void*)align_up((u64)get_ram_start(), aligment);
44+
void* curr_region_start = (void*)align_up((u64)get_ram_start(), align);
4945

50-
while((curr_addr + allocation_size) < (get_ram_start() + get_ram_size())) {
46+
physical_memory_region_t* busy_regions_ptrs[] = {allocated_memory_regions, unavaliable_regions};
47+
u64 busy_regions_sizes[] = {allocated_regions_end_idx, unavaliable_regions_amount};
48+
while((curr_region_start + size) < (get_ram_start() + get_ram_size())) {
5149
bool overlap = false;
52-
for(u64 i = 0; i < unavalible_regions_amount; ++i) {
53-
void* region_start = unavalible_regions[i].address;
54-
void* region_end = unavalible_regions[i].address + unavalible_regions[i].size;
55-
if(MAX(curr_addr, region_start) < MIN(curr_addr + allocation_size, region_end)) {
56-
curr_addr = region_end;
57-
curr_addr = (void*)align_up((u64)curr_addr, aligment);
58-
overlap = true;
59-
break;
50+
for(u64 reg_idx = 0; reg_idx < sizeof(busy_regions_ptrs) / sizeof(busy_regions_ptrs[0]); ++reg_idx) {
51+
for(u64 i = 0; i < busy_regions_sizes[reg_idx]; ++i) {
52+
void* busy_region_start = busy_regions_ptrs[reg_idx][i].address;
53+
void* busy_region_end = busy_regions_ptrs[reg_idx][i].address + busy_regions_ptrs[reg_idx][i].size;
54+
if(MAX(curr_region_start, busy_region_start) < MIN(curr_region_start + size, busy_region_end)) {
55+
curr_region_start = busy_region_end;
56+
curr_region_start = (void*)align_up((u64)curr_region_start, align);
57+
overlap = true;
58+
break;
59+
}
6060
}
61+
if(overlap) break;
6162
}
6263
if(!overlap) {
63-
*pmrOUT = (phisical_memory_region_t){.address = curr_addr, .size = allocation_size};
64+
*pmrOUT = (physical_memory_region_t){.address = curr_region_start, .size = size};
65+
allocated_memory_regions[allocated_regions_end_idx++] = *pmrOUT;
6466
return ERR_NONE;
6567
}
6668
}
67-
return ERR_PHISICAL_MEMORY_FULL;
69+
return ERR_PHYSICAL_MEMORY_FULL;
6870
}
6971

7072
typedef enum : u8 {
@@ -215,30 +217,24 @@ static void load_elf_segment_at_address(void* elf_img, elf64_program_header_t ph
215217
}
216218

217219
error_t load_elf_at_address(void* elf_img, void* target_addr, void** elf_entry_OUT) {
218-
if(((u64)target_addr & 0xfff) != 0) { // if targed_addr is not aligned to 4kiB then elf alignemnts will be broken
219-
return ERR_INVALID_ARGUMENT;
220-
}
221220
const elf64_header_t* header = elf_img;
222-
if(header->magic[0] != 0x7f || header->magic[1] != 'E' || header->magic[2] != 'L' || header->magic[3] != 'F') {
221+
if(((u64)target_addr & 0xfff) != 0) // if targed_addr is not aligned to 4kiB then elf alignments will be broken
223222
return ERR_INVALID_ARGUMENT;
224-
}
225-
if(header->version != 0x01) { return ERR_INVALID_ARGUMENT; }
226-
if(header->class != 0x02) { // Only elf64 is supported
223+
if(header->magic[0] != 0x7f || header->magic[1] != 'E' || header->magic[2] != 'L' || header->magic[3] != 'F')
227224
return ERR_INVALID_ARGUMENT;
228-
}
229-
if(header->data != 0x01) { // Only little-endian is supported
225+
if(header->version != 0x01) return ERR_INVALID_ARGUMENT;
226+
if(header->class != 0x02) // Only elf64 is supported
230227
return ERR_INVALID_ARGUMENT;
231-
}
232-
if(header->machine != EM_RISCV) { // Only riscv is supported
228+
if(header->data != 0x01) // Only little-endian is supported
233229
return ERR_INVALID_ARGUMENT;
234-
}
235-
if(header->entry == 0) { // ELF doesnt have an entry point
230+
if(header->machine != EM_RISCV) // Only riscv is supported
231+
return ERR_INVALID_ARGUMENT;
232+
if(header->entry == 0) // ELF doesnt have an entry point
236233
return ERR_INVALID_ARGUMENT;
237-
}
238234
*elf_entry_OUT = target_addr + header->entry;
239235
const elf64_program_header_t* segment_table = elf_img + header->start_of_program_headers;
240236
for(u64 i = 0; i < header->size_of_program_headrs; ++i) {
241-
if(segment_table[i].type == PT_LOAD) { load_elf_segment_at_address(elf_img, segment_table[i], target_addr); }
237+
if(segment_table[i].type == PT_LOAD) load_elf_segment_at_address(elf_img, segment_table[i], target_addr);
242238
}
243239
return ERR_NONE;
244240
}

src/bootstrap/bootstrap_memory_services.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,19 @@
77
typedef struct {
88
void* address;
99
u64 size;
10-
} phisical_memory_region_t;
10+
} physical_memory_region_t;
11+
12+
// TODO: This probably shouldn't be here
13+
#define kiB (1ull << 10)
14+
#define MiB (1ull << 20)
15+
#define GiB (1ull << 30)
1116

1217
u64 align_up(u64 val, u64 align);
1318
void set_ram_params(void* ram_start, u64 ram_size);
1419
void* get_ram_start();
1520
u64 get_ram_size();
1621

17-
error_t allocate_phisical_memory_region(void* dt, phisical_memory_region_t busy_memory_regions[],
18-
u64 busy_memory_regions_amount, u64 allocation_size, u64 aligment,
19-
phisical_memory_region_t* pmrOUT);
20-
21-
error_t load_elf_at_address(void* elf_img, void* target_addr, void** elf_entry_OUT);
22+
[[nodiscard]] error_t allocate_physical_memory_region(void* dt, u64 size, u64 align, physical_memory_region_t* pmrOUT);
23+
[[nodiscard]] error_t load_elf_at_address(void* elf_img, void* target_addr, void** elf_entry_OUT);
2224

2325
#endif // !__BOOTSTRAP_BOOTSTRAP_MEMORY_SERVICES_H__

src/bootstrap/bootstrap_page_table.c

Lines changed: 37 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,13 @@
55
#include <stdbigos/string.h>
66

77
#include "bootstrap_memory_services.h"
8-
#include "bootstrap_panic.h"
98

109
//===============================
1110
//=== INTERNAL ====
1211
//===============================
1312

1413
static virtual_memory_scheme_t s_active_vms = VMS_BARE;
15-
static phisical_memory_region_t s_page_mem_regs[5] = {0};
14+
static physical_memory_region_t s_page_mem_regs[5] = {0};
1615

1716
static inline reg_t create_satp(virtual_memory_scheme_t vms, u16 asid, ppn_t ppn) {
1817
return ((u64)((vms == -1 ? 0 : vms + 8)) << 60) | ((u64)asid << 44) | ((u64)ppn & 0xfffffffffff);
@@ -37,37 +36,25 @@ static inline void read_page_table_entry(u64 pte, u8* flagsOUT, u8* rswOUT, ppn_
3736
if(ppnOUT) *ppnOUT = (pte >> 10) & 0xfffffffffff;
3837
}
3938

40-
static bool add_to_vpn_reg(u64 vpn_reg[], u32* inx, u64 val, u64 size) {
41-
for(u32 i = 0; i < *inx; ++i) {
42-
if(vpn_reg[i] == val) return true;
43-
}
44-
vpn_reg[(*inx)++] = val;
45-
if(*inx >= size) return false;
46-
return true;
47-
}
48-
4939
ppn_t get_page_frame(page_size_t ps) {
5040
static u64 number_of_allocated_pages[PAGE_SIZE_AMOUNT] = {0};
51-
return (u64)(s_page_mem_regs[ps].address + number_of_allocated_pages[ps] * (0x1000 << (9 * ps))) >> 12;
41+
return (u64)(s_page_mem_regs[ps].address + (number_of_allocated_pages[ps]++) * ((4 * kiB) << (9 * ps))) >> 12;
5242
}
5343

5444
static void page_table_add_entry(u64 root_pt_ppn, page_size_t ps, vpn_t vpn, ppn_t ppn, bool R, bool W, bool X) {
5545
u16 vpn_slice[5] = {
56-
(vpn >> 9 * 0) & 0x1ff,
57-
(vpn >> 9 * 1) & 0x1ff,
58-
(vpn >> 9 * 2) & 0x1ff,
59-
(vpn >> 9 * 3) & 0x1ff,
60-
(vpn >> 9 * 4) & 0x1ff,
46+
(vpn >> 9 * 0) & 0x1ff, (vpn >> 9 * 1) & 0x1ff, (vpn >> 9 * 2) & 0x1ff,
47+
(vpn >> 9 * 3) & 0x1ff, (vpn >> 9 * 4) & 0x1ff,
6148
};
62-
u64 (*current_page)[512] = (u64(*)[512])(root_pt_ppn << 12);
49+
u64(*current_page)[512] = (u64(*)[512])(root_pt_ppn << 12);
6350
for(i8 lvl = s_active_vms + 2; lvl >= ps; --lvl) {
6451
u8 flags = 0;
6552
ppn_t current_ppn = 0;
6653
u64* current_pte = &(*current_page)[vpn_slice[lvl]];
6754
read_page_table_entry(*current_pte, &flags, nullptr, &current_ppn);
6855
if((flags & PTEF_V) == 0) {
6956
current_ppn = get_page_frame(PAGE_SIZE_4kB);
70-
memset((void*)(current_ppn << 12), 0, 0x1000);
57+
memset((void*)(current_ppn << 12), 0, 4 * kiB);
7158
*current_pte = create_page_table_entry(PTEF_V | PTEF_G, 0, current_ppn);
7259
}
7360
current_page = (u64(*)[512])(current_ppn << 12);
@@ -79,26 +66,31 @@ static void page_table_add_entry(u64 root_pt_ppn, page_size_t ps, vpn_t vpn, ppn
7966
(*current_page)[vpn_slice[ps]] = create_page_table_entry(flags, 0, ppn);
8067
}
8168

69+
static bool add_to_vpn_reg(u64 vpn_reg[], u32* inx, u64 val, u64 size) {
70+
for(u32 i = 0; i < *inx; ++i) {
71+
if(vpn_reg[i] == val) return true;
72+
}
73+
vpn_reg[(*inx)++] = val;
74+
if(*inx >= size) return false;
75+
return true;
76+
}
77+
8278
//===============================
8379
//=== !!! INTERNAL !!! ====
8480
//===============================
8581

86-
void init_boot_page_table_managment(virtual_memory_scheme_t vms) {
82+
u16 initialize_virtual_memory(virtual_memory_scheme_t vms) {
8783
s_active_vms = vms;
88-
}
89-
90-
void set_page_memory_regions(phisical_memory_region_t mem_regions[5]) {
91-
memcpy(s_page_mem_regs, mem_regions, 5 * sizeof(phisical_memory_region_t));
92-
const char* page_names[] = {"kilo", "mega", "giga", "tera", "peta"};
93-
DEBUG_PRINTF("[i] page memory region set:\n");
94-
for(u8 i = 0; i < 5; ++i) {
95-
DEBUG_PRINTF("\t[i] %s page to: %lx, size: %lu\n", page_names[i], (u64)mem_regions[i].address,
96-
mem_regions[i].size);
97-
}
84+
reg_t satp = create_satp(VMS_BARE, UINT16_MAX, 0);
85+
CSR_WRITE(satp, satp);
86+
satp = CSR_READ(satp);
87+
u16 asid_max_val = 0;
88+
read_satp(satp, nullptr, &asid_max_val, nullptr);
89+
return asid_max_val;
9890
}
9991

10092
required_memory_space_t calc_required_memory_for_page_table(region_t* regions, u64 regions_amount) {
101-
constexpr u32 vpn_reg_size = 1024;
93+
constexpr u32 vpn_reg_size = 256;
10294
u64 vpn_reg[vpn_reg_size] = {0};
10395
u32 vpn_reg_inx = 0;
10496
u32 max_vpn_reg_inx = 0;
@@ -111,17 +103,17 @@ required_memory_space_t calc_required_memory_for_page_table(region_t* regions, u
111103
u32 new_vpn_reg_inx = 0;
112104
for(u32 i = 0; i < vpn_reg_inx; ++i)
113105
if(!add_to_vpn_reg(new_vpn_reg, &new_vpn_reg_inx, vpn_reg[i] >> 9, vpn_reg_size))
114-
return (required_memory_space_t){{0}, .error = true};
106+
return (required_memory_space_t){{0}, .error = ERR_CRITICAL_INTERNAL_FAILURE};
115107
page_amounts[PAGE_SIZE_4kB] += new_vpn_reg_inx;
116108
for(u64 i = 0; i < regions_amount; ++i) {
117109
if(regions[i].ps == lvl) {
118110
u64 size_left = regions[i].size;
119111
u64 curr_addr = regions[i].addr;
120-
const u64 size_dif = 0x1000 << (9 * lvl);
112+
const u64 size_dif = (4 * kiB) << (9 * lvl);
121113
while(size_left > 0) {
122114
u32 old_inx = new_vpn_reg_inx;
123115
if(!add_to_vpn_reg(new_vpn_reg, &new_vpn_reg_inx, curr_addr >> (12 + 9 * lvl), vpn_reg_size))
124-
return (required_memory_space_t){{0}, .error = true};
116+
return (required_memory_space_t){{0}, .error = ERR_CRITICAL_INTERNAL_FAILURE};
125117
if(old_inx == new_vpn_reg_inx) {
126118
DEBUG_PRINTF("overaping mem regions, i: %lu page: %lu\n", i,
127119
(curr_addr - regions[i].addr) / size_dif);
@@ -136,31 +128,32 @@ required_memory_space_t calc_required_memory_for_page_table(region_t* regions, u
136128
vpn_reg_inx = new_vpn_reg_inx;
137129
memcpy(vpn_reg, new_vpn_reg, new_vpn_reg_inx * sizeof(u64));
138130
}
139-
required_memory_space_t ret = {{0}, false};
131+
required_memory_space_t ret = {{0}, ERR_NONE};
140132
memcpy(ret.require_page_amounts, page_amounts, sizeof(page_amounts));
141133
return ret;
142134
}
143135

144-
u16 initialize_virtual_memory() {
145-
reg_t satp = create_satp(VMS_BARE, UINT16_MAX, 0);
146-
CSR_WRITE(satp, satp);
147-
satp = CSR_READ(satp);
148-
u16 asid_max_val = 0;
149-
read_satp(satp, nullptr, &asid_max_val, nullptr);
150-
return asid_max_val;
136+
void set_page_memory_regions(physical_memory_region_t mem_regions[5]) {
137+
memcpy(s_page_mem_regs, mem_regions, 5 * sizeof(physical_memory_region_t));
138+
const char* page_names[] = {"kilo", "mega", "giga", "tera", "peta"};
139+
DEBUG_PRINTF("[i] page memory region set:\n");
140+
for(u8 i = 0; i < 5; ++i) {
141+
DEBUG_PRINTF("\t[i] %s page to: 0x%lx, size: %lu\n", page_names[i], (u64)mem_regions[i].address,
142+
mem_regions[i].size);
143+
}
151144
}
152145

153146
ppn_t create_page_table(region_t regions[], u64 regions_amount) {
154147
ppn_t root_ppn = get_page_frame(PAGE_SIZE_4kB);
155-
memset((void*)(root_ppn << 12), 0, 0x1000);
148+
memset((void*)(root_ppn << 12), 0, (4 * kiB));
156149
for(u64 i = 0; i < regions_amount; ++i) {
157150
u64 size_left = regions[i].size;
158151
u64 curr_addr = regions[i].addr;
159152
u64 map_addr = regions[i].map_address;
160153
while(size_left > 0) {
161154
ppn_t use_ppn = (regions[i].mapped) ? (map_addr >> 12) : get_page_frame(regions[i].ps);
162155
page_table_add_entry(root_ppn, regions[i].ps, curr_addr >> 12, use_ppn, 1, 1, 1);
163-
const u64 size_dif = 0x1000 << (9 * regions[i].ps);
156+
const u64 size_dif = (4 * kiB) << (9 * regions[i].ps);
164157
if(regions[i].mapped) map_addr += size_dif;
165158
curr_addr += size_dif;
166159
if(size_left < size_dif) size_left = size_dif;

src/bootstrap/bootstrap_page_table.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,12 @@ typedef struct {
1616

1717
typedef struct {
1818
u64 require_page_amounts[PAGE_SIZE_AMOUNT];
19-
bool error;
19+
error_t error;
2020
} required_memory_space_t;
2121

22-
void init_boot_page_table_managment(virtual_memory_scheme_t vms);
23-
void set_page_memory_regions(phisical_memory_region_t mem_regions[5]);
22+
[[nodiscard]] u16 initialize_virtual_memory(virtual_memory_scheme_t vms);
2423
[[nodiscard]] required_memory_space_t calc_required_memory_for_page_table(region_t* regions, u64 regions_amount);
25-
[[nodiscard]] u16 initialize_virtual_memory();
26-
[[nodiscard]] ppn_t get_page_frame(page_size_t ps);
24+
void set_page_memory_regions(physical_memory_region_t mem_regions[5]);
2725
[[nodiscard]] ppn_t create_page_table(region_t* regions, u64 regions_amount);
2826

2927
#endif

0 commit comments

Comments
 (0)