/**************************************************************************************
$Id: paging.c,v 1.9 2002/04/21 13:06:50 reddawg Exp $


**************************************************************************************/

#include <mm/paging.h>
#include <ubixos/video.h>
#include <ubixos/mytypes.h>

unsigned int AllocToEnd(unsigned int size, unsigned int align);

volatile unsigned int *pageDir=NULL;
int freePage = 0x0;

void initPaging() {
  int i = 0,j = 0;
  unsigned int *pageTable;
  bse_end = 0x200000;
  pageDir = (unsigned int*)AllocToEnd(PAGE_SIZE, PAGE_SIZE);
  for (i=0;i<PAGE_LEN;i++) {
    pageDir[i] = 0x0;
    }
  pageTable = (unsigned int*)AllocToEnd(PAGE_SIZE,PAGE_SIZE);
  pageDir[0] = (unsigned int)pageTable | PAGE_DEFAULT;
  for (j=0;j<1024;j++) {
    pageTable[j] = 0x0;
    //pageTable[j] = freePage | 7;
    //freePage += 0x1000;
    }
  for (j=0;j<1024;j++) {
    pageTable[j] = 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 *)(pageDir))
    );
  }

unsigned int AllocToEnd(unsigned int size, unsigned int align) {
  unsigned int t;
  if (bse_end%align != 0) bse_end += align - bse_end%align;
    t = bse_end;
    bse_end += size;
  return t;
  }


//Ubu
unsigned int allocMem(unsigned int size) {
  unsigned int t;
  if (bse_end%4096 != 0) bse_end += 4096 - bse_end%4096;
    t = bse_end;
    bse_end += size;
  return t;
  }

void pageFault() {
  int cr2 = 0,i = 0, page = 0,pi = 0;
  unsigned int *pageTable;
  asm(
    "movl %%cr2,%%eax\n"
    "movl %%eax,%0\n"
    : "=g" (cr2)
    );
	pi = cr2/(1024*4096);
	page = (cr2-(pi*(1024*4096)))/4096;
	kprintf("int14: Page Fault\nRequest Address: %i, Page Table: %i, Page: %i\n",cr2,pi,page);
  if (pageDir[pi] == 0) {
    pageTable = (unsigned int*)AllocToEnd(PAGE_SIZE,PAGE_SIZE);
    pageDir[pi] = (unsigned int)pageTable | PAGE_DEFAULT;
    for (i=0;i<1024;i++) {
      pageTable[i] = 0;
      }
    pageTable[page] = freePage | 7;
    freePage += 0x1000;
    kprint(" Initialed Table: [");
    printlong((unsigned int)pageTable);
    kprint("] ");
    }
  else {
    pageTable = (unsigned int *)(pageDir[pi]-39);
    pageTable[page] = freePage | 7;
    freePage += 0x1000;
    }
  kprint("pageTable: ");
  printlong((unsigned int)pageTable);
  kprint(", freePage: ");
  printlong(freePage);
  kprint("\n");
  asm(
    "movl %cr3,%eax\n"
    "movl %eax,%cr3\n"
    );
  }