2019-05-14 14:39:35 +02:00
|
|
|
#include <kernel.h>
|
2019-05-15 15:55:57 +02:00
|
|
|
#include <init/boot.h>
|
2019-05-15 19:11:47 +02:00
|
|
|
#include <ex/malloc.h>
|
|
|
|
#include <mm/mm.h>
|
2019-05-18 13:39:58 +02:00
|
|
|
#include <ke/idt.h>
|
2019-05-19 00:07:01 +02:00
|
|
|
#include <lib/buf.h>
|
|
|
|
#include <io/vga.h>
|
|
|
|
|
2019-05-14 14:39:35 +02:00
|
|
|
|
2019-05-18 12:58:54 +02:00
|
|
|
#define KPAGESIZE (4 * KB)
|
|
|
|
#define UPAGESIZE (2 * MB)
|
2019-05-15 02:26:55 +02:00
|
|
|
|
2019-05-14 14:39:35 +02:00
|
|
|
|
|
|
|
// Page directory pointer offset
|
2019-05-15 02:26:55 +02:00
|
|
|
typedef ulong pdpe_t;
|
2019-05-14 14:39:35 +02:00
|
|
|
|
|
|
|
// Page directory offset
|
2019-05-15 02:26:55 +02:00
|
|
|
typedef ulong pde_t;
|
2019-05-14 14:39:35 +02:00
|
|
|
|
|
|
|
// Page table entry
|
2019-05-15 02:26:55 +02:00
|
|
|
typedef ulong pte_t;
|
2019-05-14 14:39:35 +02:00
|
|
|
|
|
|
|
// paging.asm
|
|
|
|
void MmLoadPML4(void *);
|
|
|
|
void MmEnableWriteProtect(void);
|
|
|
|
void MmDisableWriteProtect(void);
|
|
|
|
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
MF_PRESENT = 1 << 0,
|
|
|
|
MF_READWRITE = 1 << 1,
|
|
|
|
MF_USERMODE = 1 << 2,
|
|
|
|
MF_WRITETHR = 1 << 3,
|
|
|
|
MF_CACHEDIS = 1 << 4,
|
|
|
|
MF_ACCESSED = 1 << 5,
|
2019-05-15 11:15:21 +02:00
|
|
|
MF_DIRTY = 1 << 6,
|
2019-05-15 15:55:57 +02:00
|
|
|
MF_HUGE = 1 << 7,
|
|
|
|
MF_NX = 1 << 31
|
2019-05-14 14:39:35 +02:00
|
|
|
};
|
|
|
|
|
2019-05-16 23:56:23 +02:00
|
|
|
#define RAM_MAX 32
|
2019-05-15 19:11:47 +02:00
|
|
|
#define NB_4K 150
|
|
|
|
// * 2 MB
|
2019-05-15 02:26:55 +02:00
|
|
|
|
2019-05-14 14:39:35 +02:00
|
|
|
//-----------
|
|
|
|
|
2019-05-18 12:58:54 +02:00
|
|
|
volatile pdpe_t MmPML4[512] __attribute__((__aligned__(KPAGESIZE)));
|
2019-05-14 14:39:35 +02:00
|
|
|
|
2019-05-18 12:58:54 +02:00
|
|
|
volatile pde_t MmPDP[512] __attribute__((__aligned__(KPAGESIZE)));
|
2019-05-14 14:39:35 +02:00
|
|
|
|
2019-05-18 12:58:54 +02:00
|
|
|
volatile pde_t MmPD[512 * RAM_MAX] __attribute__((__aligned__(KPAGESIZE)));;
|
2019-05-14 14:39:35 +02:00
|
|
|
|
2019-05-18 12:58:54 +02:00
|
|
|
volatile pte_t MmPT[512 * NB_4K] __attribute__((__aligned__(KPAGESIZE)));;
|
2019-05-14 14:39:35 +02:00
|
|
|
|
2019-05-15 15:55:57 +02:00
|
|
|
volatile ulong MmStackGuards[2] = { 0 };
|
|
|
|
|
|
|
|
//
|
|
|
|
// Creates our new page table structure and loads it
|
2019-05-18 13:39:58 +02:00
|
|
|
//
|
2019-05-14 14:39:35 +02:00
|
|
|
void MmInitPaging(void)
|
|
|
|
{
|
2019-05-15 19:11:47 +02:00
|
|
|
extern MemoryMap_t memoryMap;
|
2019-05-16 23:56:23 +02:00
|
|
|
ulong phRamSize = memoryMap.freeRamSize + memoryMap.nonfreeRamSize;
|
2019-05-15 21:02:16 +02:00
|
|
|
|
2019-05-15 15:55:57 +02:00
|
|
|
memzero((void *)&MmPML4[0], sizeof(MmPML4));
|
|
|
|
memzero((void *)&MmPDP[0], sizeof(MmPDP));
|
|
|
|
memzero((void *)&MmPD[0], sizeof(MmPD));
|
|
|
|
memzero((void *)&MmPT[0], sizeof(MmPT));
|
2019-05-15 02:26:55 +02:00
|
|
|
|
2019-05-16 23:56:23 +02:00
|
|
|
for (volatile ulong i = 0; i < 512 * NB_4K; i++) {
|
2019-05-15 15:55:57 +02:00
|
|
|
// STACK GUARD PAGE
|
2019-05-18 12:58:54 +02:00
|
|
|
if ((ulong)(i*KPAGESIZE) == (ulong)BtLoaderInfo.stackEndAddr) {
|
|
|
|
MmPT[i] = ((ulong)(i*KPAGESIZE));
|
2019-05-15 15:55:57 +02:00
|
|
|
MmStackGuards[0] = i;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2019-05-15 19:11:47 +02:00
|
|
|
// ENOMEM like
|
2019-05-18 12:58:54 +02:00
|
|
|
if ((ulong)(i*KPAGESIZE) > (ulong)phRamSize) {
|
2019-05-16 23:56:23 +02:00
|
|
|
break;
|
2019-05-15 15:55:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// STACK GARD PAGE
|
2019-05-18 12:58:54 +02:00
|
|
|
if ((ulong)(i*KPAGESIZE) == (ulong)BtLoaderInfo.kernelEndAddr) {
|
|
|
|
MmPT[i] = ((ulong)(i*KPAGESIZE));
|
2019-05-15 15:55:57 +02:00
|
|
|
MmStackGuards[1] = i;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2019-05-18 12:58:54 +02:00
|
|
|
MmPT[i] = ((ulong)(i*KPAGESIZE)) | MF_PRESENT | MF_READWRITE;
|
2019-05-15 11:15:21 +02:00
|
|
|
}
|
|
|
|
|
2019-05-16 23:56:23 +02:00
|
|
|
for (volatile ulong i = 0; i < NB_4K; i++) {
|
2019-05-15 15:55:57 +02:00
|
|
|
MmPD[i] = (ulong)(&MmPT[i*512])| MF_PRESENT | MF_READWRITE;
|
2019-05-15 11:15:21 +02:00
|
|
|
}
|
|
|
|
|
2019-05-16 23:56:23 +02:00
|
|
|
for (volatile ulong i = NB_4K; i < 512 * RAM_MAX; i++) {
|
2019-05-15 19:11:47 +02:00
|
|
|
// ENOMEM like
|
2019-05-18 12:58:54 +02:00
|
|
|
if ((ulong)(i* UPAGESIZE) > (ulong)phRamSize) {
|
2019-05-16 23:56:23 +02:00
|
|
|
break;
|
2019-05-15 19:11:47 +02:00
|
|
|
}
|
|
|
|
|
2019-05-16 23:56:23 +02:00
|
|
|
MmPD[i] = 0;
|
2019-05-18 12:58:54 +02:00
|
|
|
MmPD[i] = ((ulong)(i* UPAGESIZE)) | MF_PRESENT | MF_READWRITE | MF_HUGE;
|
2019-05-14 14:39:35 +02:00
|
|
|
}
|
|
|
|
|
2019-05-16 23:56:23 +02:00
|
|
|
for (volatile int i = 0; i < RAM_MAX; i++) {
|
2019-05-15 15:55:57 +02:00
|
|
|
MmPDP[i] = (ulong)(&MmPD[i*512])| MF_PRESENT | MF_READWRITE;
|
2019-05-15 02:26:55 +02:00
|
|
|
}
|
|
|
|
|
2019-05-15 15:55:57 +02:00
|
|
|
MmPML4[0] = (ulong)(&MmPDP[0])| MF_PRESENT | MF_READWRITE;
|
2019-05-14 14:39:35 +02:00
|
|
|
|
2019-05-16 23:56:23 +02:00
|
|
|
MmLoadPML4((void *)MmPML4);
|
2019-05-18 13:39:58 +02:00
|
|
|
DebugLog("\tPaging tables initialized at %p, %p\n", &MmPD, &MmPT);
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Reloads the page tables
|
|
|
|
//
|
|
|
|
void MmReloadPaging(void)
|
|
|
|
{
|
|
|
|
extern MemoryMap_t memoryMap;
|
|
|
|
ulong phRamSize = memoryMap.freeRamSize + memoryMap.nonfreeRamSize;
|
|
|
|
|
|
|
|
for (volatile ulong i = 0; i < 512 * NB_4K; i++) {
|
|
|
|
// STACK GUARD PAGE
|
|
|
|
if ((ulong)(i*KPAGESIZE) == (ulong)BtLoaderInfo.stackEndAddr) {
|
|
|
|
MmPT[i] = ((ulong)(i*KPAGESIZE));
|
|
|
|
MmStackGuards[0] = i;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ENOMEM like
|
|
|
|
if ((ulong)(i*KPAGESIZE) > (ulong)phRamSize) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// STACK GARD PAGE
|
|
|
|
if ((ulong)(i*KPAGESIZE) == (ulong)BtLoaderInfo.kernelEndAddr) {
|
|
|
|
MmPT[i] = ((ulong)(i*KPAGESIZE));
|
|
|
|
MmStackGuards[1] = i;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
MmPT[i] = ((ulong)(i*KPAGESIZE)) | MF_PRESENT | MF_READWRITE;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (volatile ulong i = 0; i < NB_4K; i++) {
|
|
|
|
MmPD[i] = (ulong)(&MmPT[i*512])| MF_PRESENT | MF_READWRITE;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (volatile ulong i = NB_4K; i < 512 * RAM_MAX; i++) {
|
|
|
|
// ENOMEM like
|
|
|
|
if ((ulong)(i* UPAGESIZE) > (ulong)phRamSize) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
MmPD[i] = 0;
|
|
|
|
MmPD[i] = ((ulong)(i* UPAGESIZE)) | MF_PRESENT | MF_READWRITE | MF_HUGE;
|
|
|
|
}
|
|
|
|
|
|
|
|
DebugLog("Paging tables reloaded at %p, %p\n", &MmPD, &MmPT);
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Page fault handler
|
|
|
|
//
|
|
|
|
static void PagingHandler(ISRFrame_t *regs)
|
|
|
|
{
|
2019-05-19 00:07:01 +02:00
|
|
|
bprintf(BStdOut, "\n\n%CPANIC\n%C[ISR 0x%x] Irrecoverable Kernel Page Fault at %p\n\n"
|
|
|
|
" Error code : 0x%x (%b)\n\n%C"
|
2019-05-18 20:31:02 +02:00
|
|
|
|
|
|
|
" RIP: %#016lx RSP: %#016lx RBP: %#016lx\n\n"
|
|
|
|
|
|
|
|
" SS: %#016lx CS: %#016lx CR0: %#016lx\n"
|
|
|
|
" CR2: %#016lx CR3: %#016lx CR4: %#016lx\n"
|
|
|
|
" CR8: %#016lx EFE: %#016lx \n\n"
|
|
|
|
|
|
|
|
" RAX: %#016lx RBX: %#016lx RCX: %#016lx\n"
|
|
|
|
" RDX: %#016lx RSI: %#016lx RDI: %#016lx\n"
|
|
|
|
|
|
|
|
" R8: %#016lx R9: %#016lx R10: %#016lx\n"
|
|
|
|
" R11: %#016lx R12: %#016lx R13: %#016lx\n"
|
|
|
|
" R14: %#016lx R15: %#016lx \n\n"
|
|
|
|
|
2019-05-18 13:39:58 +02:00
|
|
|
" RFLAGS: %#022b (%#06x)",
|
2019-05-19 00:07:01 +02:00
|
|
|
VGA_COLOR_WHITE,
|
|
|
|
VGA_COLOR_LIGHT_RED,
|
2019-05-18 13:39:58 +02:00
|
|
|
regs->intNo,
|
2019-05-18 20:31:02 +02:00
|
|
|
regs->cr2,
|
2019-05-18 13:39:58 +02:00
|
|
|
regs->ErrorCode,
|
|
|
|
regs->ErrorCode,
|
2019-05-19 00:07:01 +02:00
|
|
|
VGA_COLOR_WHITE,
|
2019-05-18 13:39:58 +02:00
|
|
|
regs->rip,
|
|
|
|
regs->rsp,
|
2019-05-18 20:31:02 +02:00
|
|
|
regs->rbp,
|
2019-05-18 13:39:58 +02:00
|
|
|
regs->ss,
|
2019-05-18 20:31:02 +02:00
|
|
|
regs->cs,
|
|
|
|
regs->cr0,
|
|
|
|
regs->cr2,
|
|
|
|
regs->cr3,
|
|
|
|
regs->cr4,
|
|
|
|
regs->cr8,
|
|
|
|
regs->efer,
|
|
|
|
regs->rax,
|
|
|
|
regs->rbx,
|
|
|
|
regs->rcx,
|
|
|
|
regs->rdx,
|
|
|
|
regs->rsi,
|
|
|
|
regs->rdi,
|
|
|
|
regs->r8,
|
|
|
|
regs->r9,
|
|
|
|
regs->r10,
|
|
|
|
regs->r11,
|
|
|
|
regs->r12,
|
|
|
|
regs->r13,
|
|
|
|
regs->r14,
|
|
|
|
regs->r15,
|
2019-05-18 13:39:58 +02:00
|
|
|
regs->rflags,
|
|
|
|
regs->rflags
|
|
|
|
);
|
2019-05-19 00:07:01 +02:00
|
|
|
|
|
|
|
bputc(BStdOut, '\n');
|
|
|
|
|
|
|
|
BStdOut->flusher(BStdOut);
|
|
|
|
|
|
|
|
KeHaltCPU();
|
2019-05-18 13:39:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void MmActivatePageHandler(void)
|
|
|
|
{
|
|
|
|
KeRegisterISR(PagingHandler, 0xe);
|
2019-05-15 02:26:55 +02:00
|
|
|
}
|