stivale2: Implement unmap NULL using 4KiB pages

This commit is contained in:
mintsuki 2021-04-14 21:57:23 +02:00
parent 5488c8818b
commit d9466f3d25
4 changed files with 33 additions and 23 deletions

View File

@ -31,14 +31,15 @@ pagemap_t new_pagemap(int lv) {
return pagemap;
}
void map_page(pagemap_t pagemap, uint64_t virt_addr, uint64_t phys_addr, uint64_t flags) {
void map_page(pagemap_t pagemap, uint64_t virt_addr, uint64_t phys_addr, uint64_t flags, bool hugepages) {
// Calculate the indices in the various tables using the virtual address
size_t pml5_entry = (virt_addr & ((uint64_t)0x1ff << 48)) >> 48;
size_t pml4_entry = (virt_addr & ((uint64_t)0x1ff << 39)) >> 39;
size_t pml3_entry = (virt_addr & ((uint64_t)0x1ff << 30)) >> 30;
size_t pml2_entry = (virt_addr & ((uint64_t)0x1ff << 21)) >> 21;
size_t pml1_entry = (virt_addr & ((uint64_t)0x1ff << 12)) >> 12;
pt_entry_t *pml5, *pml4, *pml3, *pml2;
pt_entry_t *pml5, *pml4, *pml3, *pml2, *pml1;
// Paging levels
switch (pagemap.levels) {
@ -58,8 +59,12 @@ level4:
pml3 = get_next_level(pml4, pml4_entry);
pml2 = get_next_level(pml3, pml3_entry);
// Set the entry as present and point it to the passed physical address
// Also set the specified flags
// We only use 2MiB pages else we would not have enough space
pml2[pml2_entry] = (pt_entry_t)(phys_addr | flags | (1 << 7));
if (hugepages) {
pml2[pml2_entry] = (pt_entry_t)(phys_addr | flags | (1 << 7));
return;
}
pml1 = get_next_level(pml2, pml2_entry);
pml1[pml1_entry] = (pt_entry_t)(phys_addr | flags | (1 << 7));
}

View File

@ -2,8 +2,7 @@
#define __MM__VMM_H__
#include <stdint.h>
#define PAGE_SIZE ((uint64_t)0x200000)
#include <stdbool.h>
typedef struct {
int levels;
@ -11,6 +10,6 @@ typedef struct {
} pagemap_t;
pagemap_t new_pagemap(int lv);
void map_page(pagemap_t pagemap, uint64_t virt_addr, uint64_t phys_addr, uint64_t flags);
void map_page(pagemap_t pagemap, uint64_t virt_addr, uint64_t phys_addr, uint64_t flags, bool hugepages);
#endif

View File

@ -218,15 +218,21 @@ pagemap_t stivale_build_pagemap(bool level5pg, bool unmap_null) {
uint64_t higher_half_base = level5pg ? 0xff00000000000000 : 0xffff800000000000;
// Map 0 to 2GiB at 0xffffffff80000000
for (uint64_t i = 0; i < 0x80000000; i += PAGE_SIZE) {
map_page(pagemap, 0xffffffff80000000 + i, i, 0x03);
for (uint64_t i = 0; i < 0x80000000; i += 0x200000) {
map_page(pagemap, 0xffffffff80000000 + i, i, 0x03, true);
}
// Map 0 to 4GiB at higher half base and 0
for (uint64_t i = 0; i < 0x100000000; i += PAGE_SIZE) {
// Sub 2MiB mappings
for (uint64_t i = 0; i < 0x200000; i += 0x1000) {
if (!(i == 0 && unmap_null))
map_page(pagemap, i, i, 0x03);
map_page(pagemap, higher_half_base + i, i, 0x03);
map_page(pagemap, i, i, 0x03, false);
map_page(pagemap, higher_half_base + i, i, 0x03, false);
}
// Map 2MiB to 4GiB at higher half base and 0
for (uint64_t i = 0x200000; i < 0x100000000; i += 0x200000) {
map_page(pagemap, i, i, 0x03, true);
map_page(pagemap, higher_half_base + i, i, 0x03, true);
}
size_t _memmap_entries = memmap_entries;
@ -247,14 +253,14 @@ pagemap_t stivale_build_pagemap(bool level5pg, bool unmap_null) {
if (base >= top)
continue;
uint64_t aligned_base = ALIGN_DOWN(base, PAGE_SIZE);
uint64_t aligned_top = ALIGN_UP(top, PAGE_SIZE);
uint64_t aligned_base = ALIGN_DOWN(base, 0x200000);
uint64_t aligned_top = ALIGN_UP(top, 0x200000);
uint64_t aligned_length = aligned_top - aligned_base;
for (uint64_t i = 0; i < aligned_length; i += PAGE_SIZE) {
for (uint64_t i = 0; i < aligned_length; i += 0x200000) {
uint64_t page = aligned_base + i;
map_page(pagemap, page, page, 0x03);
map_page(pagemap, higher_half_base + page, page, 0x03);
map_page(pagemap, page, page, 0x03, true);
map_page(pagemap, higher_half_base + page, page, 0x03, true);
}
}

View File

@ -23,15 +23,15 @@ struct stivale2_header_tag_smp smp_request = {
.flags = 0
};
struct stivale2_tag fb_mtrr_request = {
.identifier = STIVALE2_HEADER_TAG_FB_MTRR_ID,
struct stivale2_tag unmap_null_request = {
.identifier = STIVALE2_HEADER_TAG_UNMAP_NULL_ID,
.next = (uint64_t)&smp_request
};
struct stivale2_header_tag_framebuffer framebuffer_request = {
.tag = {
.identifier = STIVALE2_HEADER_TAG_FRAMEBUFFER_ID,
.next = (uint64_t)&fb_mtrr_request
.next = (uint64_t)&unmap_null_request
},
.framebuffer_width = 0,
.framebuffer_height = 0,