stivale2: Implement unmap NULL using 4KiB pages
This commit is contained in:
parent
5488c8818b
commit
d9466f3d25
@ -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));
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user