/**************************************************************************************
Copyright (c) 2002
The UbixOS Project
$Id$
**************************************************************************************/
#include <vmm/paging.h>
#include <vmm/memory.h>
#include <ubixos/idt.h>
#include <ubixos/gdt.h>
#include <ubixos/types.h>
#include <ubixos/schedule.h>
unsigned int *pageDirectory = 0x0;
int memoryStart = 0x100000;
void initPaging() {
int i=0,x=0;
unsigned int *pageTable;
int freePage = 0x0;
memoryStart += (numPages * 8);
pageDirectory = (unsigned int*)memoryStart;
memoryStart += 4096;
for (i=0;i<pageLength;i++) {
pageDirectory[i] = 0x0;
}
for (x=0;x<memoryStart;x+=0x400000) {
pageTable = (unsigned int *)memoryStart;
memoryStart += 4096;
pageDirectory[x/0x400000] = (unsigned int)pageTable | pageDefault;
for (i=0;i<1024;i++) {
pageTable[i] = 0x0;
}
for (i=0;i<1024;i++) {
pageTable[i] = freePage | 7;
freePage += 0x1000;
}
}
asm(
"movl %0,%%eax \n"
"movl %%eax,%%cr3 \n"
"movl %%cr0,%%eax \n"
"orl $0x80000000,%%eax \n"
"movl %%eax,%%cr0 \n"
: : "d" ((unsigned int *)(pageDirectory))
);
setVector(_pageFault,14,dPresent + dInt + dDpl3);
}
unsigned int allocPage() {
unsigned int page;
page = findFreepage(_current->id);
/*
if (memoryStart%4096 != 0) {
memoryStart += 4096 - memoryStart%4096;
}
page = memoryStart;
memoryStart += 4096;
*/
return(page);
}
void pageFault() {
uInt cr2 = 0,i = 0, page = 0,pi = 0;
uInt *pageTable;
asm(
"movl %%cr2,%%eax\n"
"movl %%eax,%0\n"
: "=g" (cr2)
);
pi = cr2/(1024*4096);
page = (cr2-(pi*(1024*4096)))/4096;
if (pageDirectory[pi] == 0) {
pageTable = (unsigned int*)allocPage();
pageDirectory[pi] = (unsigned int)pageTable | pageDefault;
for (i=0;i<1024;i++) {
pageTable[i] = 0;
}
pageTable[page] = allocPage() | pageDefault;
}
else {
pageTable = (unsigned int *)(pageDirectory[pi]-39);
pageTable[page] = allocPage() | pageDefault;
}
asm(
"movl %cr3,%eax\n"
"movl %eax,%cr3\n"
);
}
asm(
".global _pageFault \n"
"_pageFault: \n"
"xchgl %eax,(%esp) \n"
"pushl %ecx \n"
"pushl %edx \n"
"push %ds \n"
"push %es \n"
"push %fs \n"
"call pageFault \n"
"pop %fs \n"
"pop %es \n"
"pop %ds \n"
"popl %edx \n"
"popl %ecx \n"
"popl %eax \n"
"iret \n"
);