mirror of
https://github.com/usatiuk/ficus.git
synced 2025-10-29 00:27:52 +01:00
refactor AddressSpace to be a class
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <new>
|
||||
|
||||
#include "gdt.hpp"
|
||||
#include "globals.hpp"
|
||||
@@ -13,7 +14,11 @@
|
||||
#include "paging.hpp"
|
||||
#include "serial.hpp"
|
||||
|
||||
struct AddressSpace BOOT_AddressSpace;
|
||||
AddressSpace *BOOT_AddressSpace;
|
||||
alignas(AddressSpace) char BOOT_AddressSpace_storage[sizeof(AddressSpace)];
|
||||
|
||||
AddressSpace *KERN_AddressSpace;
|
||||
alignas(AddressSpace) char KERN_AddressSpace_storage[sizeof(AddressSpace)];
|
||||
|
||||
extern void kmain();
|
||||
|
||||
@@ -42,27 +47,28 @@ extern "C" void _start(void) {
|
||||
barrier();
|
||||
map_hddm(get_cr3());
|
||||
barrier();
|
||||
BOOT_AddressSpace.PML4 = (uint64_t *) HHDM_P2V(get_cr3());
|
||||
new (BOOT_AddressSpace_storage) AddressSpace((uint64_t *) HHDM_P2V(get_cr3()));
|
||||
BOOT_AddressSpace = reinterpret_cast<AddressSpace *>(BOOT_AddressSpace_storage);
|
||||
|
||||
limine_fb_save_response(&BOOT_AddressSpace);
|
||||
limine_fb_save_response(BOOT_AddressSpace);
|
||||
limine_mm_save_response();
|
||||
|
||||
parse_limine_memmap(limine_mm_entries, limine_mm_count, LIMINE_MEMMAP_USABLE);
|
||||
|
||||
KERN_AddressSpace = static_cast<AddressSpace *>(get4k());
|
||||
assert2(!init_addr_space(KERN_AddressSpace), "Couldn't init kernel address space!");
|
||||
|
||||
uint64_t *KERN_AddressSpace_PML4 = static_cast<uint64_t *>(get4k());
|
||||
for (int i = 0; i < 512; i++)
|
||||
((struct AddressSpace *) (KERN_AddressSpace))->PML4[i] = 0x02;
|
||||
KERN_AddressSpace_PML4[i] = 0x02;
|
||||
map_hddm((uint64_t *) HHDM_V2P(KERN_AddressSpace_PML4));
|
||||
|
||||
map_hddm((uint64_t *) HHDM_V2P(((struct AddressSpace *) (KERN_AddressSpace))->PML4));
|
||||
new (KERN_AddressSpace_storage) AddressSpace(KERN_AddressSpace_PML4);
|
||||
KERN_AddressSpace = reinterpret_cast<AddressSpace *>(KERN_AddressSpace_storage);
|
||||
|
||||
// TODO: Accurate kernel length
|
||||
for (int i = 0; i < 100000; i++) {
|
||||
map((void *) (kernel_virt_base + i * 4096), (void *) (kernel_phys_base + i * 4096), PAGE_RW, KERN_AddressSpace);
|
||||
KERN_AddressSpace->map((void *) (kernel_virt_base + i * 4096), (void *) (kernel_phys_base + i * 4096), PAGE_RW);
|
||||
}
|
||||
|
||||
uint64_t real_new_cr3 = (uint64_t) HHDM_V2P(((struct AddressSpace *) (KERN_AddressSpace))->PML4);
|
||||
uint64_t real_new_cr3 = (uint64_t) HHDM_V2P(KERN_AddressSpace_PML4);
|
||||
uint64_t *new_stack_top = &KERN_stack[KERN_STACK_SIZE - 1];// Don't forget in which direction the stack grows...
|
||||
|
||||
barrier();
|
||||
|
||||
@@ -34,7 +34,7 @@ void init_kern_heap() {
|
||||
KERN_HeapBegin->len = 4096 - (sizeof(struct HeapEntry));
|
||||
KERN_HeapBegin->next = NULL;
|
||||
KERN_HeapBegin->prev = NULL;
|
||||
map((void *) KERN_HeapVirtBegin, (void *) HHDM_V2P(KERN_HeapBegin), PAGE_RW, KERN_AddressSpace);
|
||||
KERN_AddressSpace->map((void *) KERN_HeapVirtBegin, (void *) HHDM_V2P(KERN_HeapBegin), PAGE_RW);
|
||||
KERN_HeapBegin = (struct HeapEntry *) KERN_HeapVirtBegin;
|
||||
KERN_HeapEnd = (KERN_HeapVirtBegin + 4096);
|
||||
initialized = true;
|
||||
@@ -44,7 +44,7 @@ static void extend_heap(size_t n_pages) {
|
||||
for (size_t i = 0; i < n_pages; i++) {
|
||||
void *p = get4k();
|
||||
assert2(p != NULL, "Kernel out of memory!");
|
||||
map((void *) KERN_HeapEnd, (void *) HHDM_V2P(p), PAGE_RW, KERN_AddressSpace);
|
||||
KERN_AddressSpace->map((void *) KERN_HeapEnd, (void *) HHDM_V2P(p), PAGE_RW);
|
||||
KERN_HeapEnd += 4096;
|
||||
}
|
||||
allocated.fetch_add(n_pages * 4096);
|
||||
@@ -263,9 +263,9 @@ static struct HeapEntry *try_shrink_heap(struct HeapEntry *entry) {
|
||||
assert(((uint64_t) totallen & 0xFFF) == 0);
|
||||
uint64_t total_pages = totallen / 4096;
|
||||
for (uint64_t i = 0; i < total_pages; i++) {
|
||||
free4k((void *) HHDM_P2V(virt2real((void *) (KERN_HeapEnd + 4096 * i), KERN_AddressSpace)));
|
||||
free4k((void *) HHDM_P2V(KERN_AddressSpace->virt2real((void *) (KERN_HeapEnd + 4096 * i))));
|
||||
allocated.fetch_sub(4096);
|
||||
unmap((void *) (KERN_HeapEnd + 4096 * i), KERN_AddressSpace);
|
||||
KERN_AddressSpace->unmap((void *) (KERN_HeapEnd + 4096 * i));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ struct {
|
||||
uint64_t len;
|
||||
} framebufferAddrs[10];
|
||||
|
||||
void limine_fb_save_response(struct AddressSpace *boot_address_space) {
|
||||
void limine_fb_save_response(AddressSpace *boot_address_space) {
|
||||
if (framebuffer_request.response == NULL || framebuffer_request.response->framebuffer_count < 1) {
|
||||
framebuffer_count = 0;
|
||||
return;
|
||||
@@ -29,17 +29,17 @@ void limine_fb_save_response(struct AddressSpace *boot_address_space) {
|
||||
if (framebuffer_count >= 10) framebuffer_count = 10;
|
||||
for (int i = 0; i < framebuffer_count; i++) {
|
||||
memcpy(&framebuffers[i], framebuffer_request.response->framebuffers[i], sizeof(struct limine_framebuffer));
|
||||
framebufferAddrs[i].base = virt2real(framebuffers[i].address, boot_address_space);
|
||||
framebufferAddrs[i].base = boot_address_space->virt2real(framebuffers[i].address);
|
||||
}
|
||||
}
|
||||
|
||||
void limine_fb_remap(struct AddressSpace *space) {
|
||||
void limine_fb_remap(AddressSpace *space) {
|
||||
for (int i = 0; i < framebuffer_count; i++) {
|
||||
void *base = framebuffers[i].address;
|
||||
void *realbase = framebufferAddrs[i].base;
|
||||
// TODO: Proper map
|
||||
for (int i = 0; i < 100000; i++) {
|
||||
map(base + i * 4096, realbase + i * 4096, PAGE_RW, space);
|
||||
space->map(base + i * 4096, realbase + i * 4096, PAGE_RW);
|
||||
}
|
||||
}
|
||||
_tlb_flush();
|
||||
|
||||
@@ -8,21 +8,12 @@
|
||||
#include "misc.hpp"
|
||||
#include "serial.hpp"
|
||||
|
||||
struct AddressSpace *KERN_AddressSpace;
|
||||
|
||||
int init_addr_space(struct AddressSpace *space) {
|
||||
assert2(space != NULL, "Got null!");
|
||||
space->PML4 = static_cast<uint64_t *>(get4k());
|
||||
if (space->PML4 == NULL) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Returns a free page frame in HHDM
|
||||
uint64_t *get_free_frame() {
|
||||
static uint64_t *get_free_frame() {
|
||||
uint64_t *res = static_cast<uint64_t *>(get4k());
|
||||
if (res)
|
||||
for (int j = 0; j < 512; j++)
|
||||
res[j] = 0;
|
||||
assert(res != nullptr);
|
||||
for (int j = 0; j < 512; j++)
|
||||
res[j] = 0;
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -34,19 +25,30 @@ static inline void invlpg(void *m) {
|
||||
: "memory");
|
||||
}
|
||||
|
||||
void *virt2real(void *virt, struct AddressSpace *space) {
|
||||
AddressSpace::AddressSpace() {
|
||||
PML4 = static_cast<uint64_t *>(get4k());
|
||||
}
|
||||
|
||||
AddressSpace::AddressSpace(uint64_t *PML4) : PML4(PML4) {}
|
||||
|
||||
AddressSpace::~AddressSpace() {
|
||||
// TODO:
|
||||
free4k(PML4);
|
||||
}
|
||||
|
||||
void *AddressSpace::virt2real(void *virt) {
|
||||
assert2(((uint64_t) virt & 0xFFF) == 0, "Trying to unmap non-aligned memory!");
|
||||
|
||||
// Assuming everything related to paging is HHDM
|
||||
assert2((uint64_t) space->PML4 >= HHDM_BEGIN, "CR3 here must be in HDDM!");
|
||||
assert2((uint64_t) space->PML4 < kernel_virt_base, "CR3 here must be in HDDM!");
|
||||
assert2((uint64_t) PML4 >= HHDM_BEGIN, "CR3 here must be in HDDM!");
|
||||
assert2((uint64_t) PML4 < kernel_virt_base, "CR3 here must be in HDDM!");
|
||||
|
||||
uint64_t pml4i = (uint64_t) virt >> 39 & 0x01FF;
|
||||
uint64_t pdpei = (uint64_t) virt >> 30 & 0x01FF;
|
||||
uint64_t pdei = (uint64_t) virt >> 21 & 0x01FF;
|
||||
uint64_t ptsi = (uint64_t) virt >> 12 & 0x01FF;
|
||||
|
||||
uint64_t *pml4e = space->PML4 + pml4i;
|
||||
uint64_t *pml4e = PML4 + pml4i;
|
||||
if (!((*pml4e) & PAGE_PRESENT)) return 0;
|
||||
|
||||
uint64_t *pdpeb = (uint64_t *) HHDM_P2V((*pml4e & 0x000FFFFFFFFFF000ULL));
|
||||
@@ -68,13 +70,13 @@ void *virt2real(void *virt, struct AddressSpace *space) {
|
||||
return (void *) (*ptse & 0x000FFFFFFFFFF000ULL);
|
||||
}
|
||||
|
||||
int map(void *virt, void *real, uint32_t flags, struct AddressSpace *space) {
|
||||
int AddressSpace::map(void *virt, void *real, uint32_t flags) {
|
||||
assert2(((uint64_t) virt & 0xFFF) == 0, "Trying to map non-aligned memory!");
|
||||
assert2(((uint64_t) real & 0xFFF) == 0, "Trying to map to non-aligned memory!");
|
||||
|
||||
// Assuming everything related to paging is HHDM
|
||||
assert2((uint64_t) space->PML4 >= HHDM_BEGIN, "CR3 here must be in HDDM!");
|
||||
assert2((uint64_t) space->PML4 < kernel_virt_base, "CR3 here must be in HDDM!");
|
||||
assert2((uint64_t) PML4 >= HHDM_BEGIN, "CR3 here must be in HDDM!");
|
||||
assert2((uint64_t) PML4 < kernel_virt_base, "CR3 here must be in HDDM!");
|
||||
|
||||
uint64_t pml4i = (uint64_t) virt >> 39 & 0x01FF;
|
||||
uint64_t pdpei = (uint64_t) virt >> 30 & 0x01FF;
|
||||
@@ -82,7 +84,7 @@ int map(void *virt, void *real, uint32_t flags, struct AddressSpace *space) {
|
||||
uint64_t ptsi = (uint64_t) virt >> 12 & 0x01FF;
|
||||
|
||||
|
||||
uint64_t *pml4e = space->PML4 + pml4i;
|
||||
uint64_t *pml4e = PML4 + pml4i;
|
||||
|
||||
if (!(*pml4e & PAGE_PRESENT)) {
|
||||
uint64_t *newp = get_free_frame();
|
||||
@@ -123,19 +125,19 @@ int map(void *virt, void *real, uint32_t flags, struct AddressSpace *space) {
|
||||
invlpg((void *) ((uint64_t) virt & 0x000FFFFFFFFFF000ULL));
|
||||
return 1;
|
||||
}
|
||||
int unmap(void *virt, struct AddressSpace *space) {
|
||||
int AddressSpace::unmap(void *virt) {
|
||||
assert2(((uint64_t) virt & 0xFFF) == 0, "Trying to map non-aligned memory!");
|
||||
|
||||
// Assuming everything related to paging is HHDM
|
||||
assert2((uint64_t) space->PML4 >= HHDM_BEGIN, "CR3 here must be in HDDM!");
|
||||
assert2((uint64_t) space->PML4 < kernel_virt_base, "CR3 here must be in HDDM!");
|
||||
assert2((uint64_t) PML4 >= HHDM_BEGIN, "CR3 here must be in HDDM!");
|
||||
assert2((uint64_t) PML4 < kernel_virt_base, "CR3 here must be in HDDM!");
|
||||
|
||||
uint64_t pml4i = (uint64_t) virt >> 39 & 0x01FF;
|
||||
uint64_t pdpei = (uint64_t) virt >> 30 & 0x01FF;
|
||||
uint64_t pdei = (uint64_t) virt >> 21 & 0x01FF;
|
||||
uint64_t ptsi = (uint64_t) virt >> 12 & 0x01FF;
|
||||
|
||||
uint64_t *pml4e = space->PML4 + pml4i;
|
||||
uint64_t *pml4e = PML4 + pml4i;
|
||||
|
||||
assert((*pml4e & PAGE_PRESENT));
|
||||
|
||||
|
||||
@@ -8,14 +8,22 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
struct AddressSpace {
|
||||
class AddressSpace {
|
||||
public:
|
||||
AddressSpace();
|
||||
AddressSpace(uint64_t *PML4);
|
||||
~AddressSpace();
|
||||
|
||||
void *virt2real(void *virt);
|
||||
int map(void *virt, void *real, uint32_t flags);
|
||||
int unmap(void *virt);
|
||||
|
||||
private:
|
||||
// Pointer to PML4 in HDDM
|
||||
uint64_t *PML4;
|
||||
};
|
||||
|
||||
extern struct AddressSpace *KERN_AddressSpace;
|
||||
|
||||
int init_addr_space(struct AddressSpace *space);
|
||||
extern AddressSpace *KERN_AddressSpace;
|
||||
|
||||
extern uintptr_t kernel_phys_base;
|
||||
extern uintptr_t kernel_virt_base;
|
||||
@@ -34,10 +42,6 @@ void limine_kern_save_response();
|
||||
#define PAGE_USER (1 << 2)
|
||||
#define PAGE_PRESENT (0x01ULL)
|
||||
|
||||
int map(void *virt, void *real, uint32_t flags, struct AddressSpace *space);
|
||||
int unmap(void *virt, struct AddressSpace *space);
|
||||
void *virt2real(void *virt, struct AddressSpace *space);
|
||||
|
||||
void map_hddm(uint64_t *pml4);
|
||||
|
||||
extern "C" void _tlb_flush();
|
||||
|
||||
Reference in New Issue
Block a user