feat: start of paging setup
This commit is contained in:
@@ -2,58 +2,80 @@
|
||||
// Created by rick on 21-02-21.
|
||||
//
|
||||
|
||||
#include <attributes.h>
|
||||
#include <stdbool.h>
|
||||
#include <sys/types.h>
|
||||
#include <attributes.h>
|
||||
|
||||
#include <myke/mem/paging.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#define TABLE_ADDR_MASK 0xFFFFF000
|
||||
#define DIRECTORY_SIZE 1024
|
||||
#define PAGING_DIR_INDEX(virt) ((virt) >> 22)
|
||||
#define PAGING_TABLE_INDEX(virt) ((virt) >> 12 & 0x03FF)
|
||||
|
||||
const uint32_t x = TABLE_ADDR_MASK;
|
||||
typedef struct {
|
||||
union {
|
||||
struct {
|
||||
bool present: 1;
|
||||
bool read_write: 1;
|
||||
bool user_mode: 1;
|
||||
bool write_through: 1;
|
||||
bool cache_disabled: 1;
|
||||
bool accessed: 1;
|
||||
char ignored: 1;
|
||||
bool page_size: 1;
|
||||
bool global: 1; // ignored
|
||||
uint8_t avail: 3;
|
||||
} att_packed;
|
||||
uint32_t addr;
|
||||
};
|
||||
} att_packed page_directory_entry;
|
||||
#define KERNEL_OFFSET 0xC0000000
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
struct {
|
||||
bool present: 1;
|
||||
bool read_write: 1;
|
||||
bool user_supervisor: 1;
|
||||
bool write_through: 1;
|
||||
bool cache_disabled: 1;
|
||||
bool accessed: 1;
|
||||
bool dirty: 1;
|
||||
char ignored: 1;
|
||||
bool global: 1;
|
||||
uint8_t available: 3;
|
||||
} att_packed;
|
||||
uint32_t addr;
|
||||
};
|
||||
} att_packed page_table_entry;
|
||||
// One page table, only 4M
|
||||
#define PAGING_STATE_EARLY 0
|
||||
#define PAGING_STATE_FULL 60
|
||||
|
||||
page_directory_entry page_directory[DIRECTORY_SIZE] att_aligned(4096);
|
||||
page_directory_entry att_aligned(4096) kernel_page_directory[DIRECTORY_SIZE] = {0};
|
||||
|
||||
void page_pre_init() {
|
||||
for (int i = 0; i < DIRECTORY_SIZE; ++i) {
|
||||
page_directory[i].read_write = true;
|
||||
page_directory[i].user_mode = false;
|
||||
page_directory[i].present = false;
|
||||
int paging_state = PAGING_STATE_EARLY;
|
||||
|
||||
void paging_load_directory(uintptr_t physical_address) {
|
||||
asm volatile("mov %%eax, %%cr3" : : "a" (physical_address));
|
||||
}
|
||||
|
||||
uintptr_t paging_get_current_directory_physical() {
|
||||
uintptr_t directory_address;
|
||||
asm volatile("mov %%cr3, %%eax" : "=a" (directory_address));
|
||||
return directory_address;
|
||||
}
|
||||
|
||||
page_directory_entry *paging_get_current() {
|
||||
return kernel_page_directory;
|
||||
}
|
||||
|
||||
int paging_map_4m(uintptr_t physical_address, uintptr_t virtual_address, int count, int mode) {
|
||||
if (virtual_address & ~PAGING_MASK_4M || physical_address & PAGING_MASK_4M) {
|
||||
// address not 4M aligned
|
||||
return PAGING_RESULT_ALIGN;
|
||||
}
|
||||
page_directory_entry *dir = paging_get_current();
|
||||
for (int i = 0; i < count; ++i) {
|
||||
page_directory_entry current_val = dir[PAGING_DIR_INDEX(virtual_address) + i];
|
||||
if (current_val & DIRECTORY_PRESENT_MASK) {
|
||||
return PAGING_RESULT_INUSE;
|
||||
}
|
||||
}
|
||||
page_directory_entry mask = DIRECTORY_PAGE_SIZE_MASK;
|
||||
if (mode & PAGING_MODE_RW) {
|
||||
mask |= DIRECTORY_RW_MASK;
|
||||
}
|
||||
if (mode & PAGING_MODE_US) {
|
||||
mask |= DIRECTORY_US_MASK;
|
||||
}
|
||||
for (int i = 0; i < count; ++i) {
|
||||
dir[PAGING_DIR_INDEX(virtual_address) + i] = physical_address & mask;
|
||||
}
|
||||
paging_load_directory((uintptr_t) dir);
|
||||
return PAGING_RESULT_OK;
|
||||
}
|
||||
|
||||
int paging_map_memory(uintptr_t physical_address, uintptr_t virtual_address, int count, int mode) {
|
||||
if (mode & PAGING_MODE_4M) {
|
||||
return paging_map_4m(physical_address, virtual_address, count, mode);
|
||||
}
|
||||
if (paging_state < PAGING_STATE_FULL) {
|
||||
// can't allocate 4K pages yet
|
||||
if ((virtual_address & ~PAGING_MASK_4M) != (physical_address & ~PAGING_MASK_4M)) {
|
||||
return PAGING_RESULT_ERR; // not in same pos in 4M page
|
||||
}
|
||||
int table_index = PAGING_TABLE_INDEX(virtual_address);
|
||||
int pages = DIV_ROUND_UP(table_index + count, 1024);
|
||||
return paging_map_4m(physical_address & PAGING_MASK_4M,
|
||||
virtual_address & PAGING_MASK_4M,
|
||||
pages,
|
||||
mode | PAGING_MODE_4M);
|
||||
}
|
||||
return PAGING_RESULT_ERR;
|
||||
}
|
||||
Reference in New Issue
Block a user