Newer
Older
ubixos / src / sys / vmm / paging.c
@reddawg reddawg on 28 May 2002 2 KB Its Been lots of work
/**************************************************************************************
 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"
    );