183 lines
3.7 KiB
C
183 lines
3.7 KiB
C
|
|
// vmm.c
|
|
// Author: Josh Holtrop
|
|
// Date: 09/30/03
|
|
|
|
PageDirectory *vmm_PDBR = 0;
|
|
dword vmm_first_virtual_address = 0;
|
|
|
|
|
|
void vmm_init()
|
|
{
|
|
if (!(vmm_PDBR = mm_palloc(1, PID_KERNEL)))
|
|
{
|
|
printf("ERROR! COULD NOT ALLOCATE PAGE FOR INITIAL PAGE DIRECTORY!!\n");
|
|
halt();
|
|
}
|
|
vmm_init_pagetable((dword)vmm_PDBR);
|
|
|
|
if (mm_totalmem % 4096)
|
|
vmm_first_virtual_address = mm_totalmem + (4096 - (mm_totalmem % 4096));
|
|
else
|
|
vmm_first_virtual_address = mm_totalmem;
|
|
|
|
if (vmm_mapn(0, 0, 0x03, mm_totalmem/4096+1))
|
|
{
|
|
printf("Could not page in all physical RAM!\n");
|
|
halt();
|
|
}
|
|
//we also need to map in the video framebuffer memory:
|
|
if (video_mode.PhysBasePtr > 0 && video_mode.BitsPerPixel > 0)
|
|
{
|
|
if (vmm_mapn(video_mode.PhysBasePtr, video_mode.PhysBasePtr, 0x03, (video_mode.BitsPerPixel/8 * video_mode.XResolution * video_mode.YResolution)/4096+1))
|
|
{
|
|
printf("Could not page in video memory at 0x%x!\n", video_mode.PhysBasePtr);
|
|
halt();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void vmm_enable_paging()
|
|
{
|
|
write_cr3((dword)vmm_PDBR);
|
|
write_cr0(0x80000000|read_cr0());
|
|
}
|
|
|
|
|
|
int vmm_map1(dword virtual, dword physical, dword flags)
|
|
{
|
|
if (virtual & 0x00000FFF)
|
|
return 1; // ERROR 1: address not page-aligned
|
|
if (physical & 0x00000FFF)
|
|
return 1; // ERROR 1: address not page-aligned
|
|
int pde = (virtual & 0xFFC00000) >> 22;
|
|
int pte = (virtual & 0x003FF000) >> 12;
|
|
if (!(vmm_PDBR->pageTables[pde] & 0x01))
|
|
{
|
|
vmm_PDBR->pageTables[pde] = (dword)mm_palloc(1, PID_KERNEL) | 0x7; //user, r/w, present
|
|
vmm_init_pagetable(vmm_PDBR->pageTables[pde] & 0xFFFFF000);
|
|
if (vmm_PDBR->pageTables[pde] == 0x07)
|
|
return 2; // ERROR 2: page table could not be created
|
|
}
|
|
PageTable *ptp = (PageTable *)(vmm_PDBR->pageTables[pde] & 0xFFFFF000);
|
|
if (ptp->page[pte] & 0x01)
|
|
return 3; // ERROR 3: page table entry already exists
|
|
ptp->page[pte] = physical | flags;
|
|
//invlpg();
|
|
return 0;
|
|
}
|
|
|
|
|
|
int vmm_mapn(dword virtual, dword physical, dword flags, dword n)
|
|
{
|
|
int mapped;
|
|
int result = 0;
|
|
dword va = virtual;
|
|
dword pa = physical;
|
|
for (mapped = 0; mapped < n; mapped++)
|
|
{
|
|
if (result = vmm_map1(va, pa, flags))
|
|
{
|
|
if (mapped > 0)
|
|
vmm_unmapn(virtual, mapped);
|
|
return result;
|
|
}
|
|
va += 4096;
|
|
pa += 4096;
|
|
}
|
|
//invlpg();
|
|
return 0;
|
|
}
|
|
|
|
int vmm_unmap1(dword virtual)
|
|
{
|
|
int pde = (virtual & 0xFFC00000) >> 22;
|
|
int pte = (virtual & 0x003FF000) >> 12;
|
|
if (virtual & 0x00000FFF)
|
|
return 1; // ERROR 1: address not page-aligned
|
|
if (!(vmm_PDBR->pageTables[pde] & 0x01))
|
|
return 2; // ERROR 2: page table not present
|
|
PageTable *ptp = (PageTable *)(vmm_PDBR->pageTables[pde] & 0xFFFFF000);
|
|
ptp->page[pte] = 0;
|
|
//invlpg();
|
|
return 0;
|
|
}
|
|
|
|
|
|
int vmm_unmapn(dword virtual, dword n)
|
|
{
|
|
int reslt;
|
|
int i;
|
|
for (i = 0; i < n; i++)
|
|
{
|
|
if (reslt = vmm_unmap1(virtual))
|
|
return reslt;
|
|
virtual += 4096;
|
|
}
|
|
vmm_walkPageTables();
|
|
//invlpg();
|
|
return 0;
|
|
}
|
|
|
|
|
|
void vmm_init_pagetable(dword address)
|
|
{
|
|
PageTable *ptp = (PageTable *)address;
|
|
int n;
|
|
for (n = 0; n < 1024; n++)
|
|
ptp->page[n] = 0;
|
|
}
|
|
|
|
|
|
int vmm_walkPageTables()
|
|
{
|
|
int pde;
|
|
int pte;
|
|
int used_ptes;
|
|
PageTable *ptp;
|
|
for (pde = 0; pde < 1024; pde++)
|
|
{
|
|
if (vmm_PDBR->pageTables[pde] & 0x01)
|
|
{
|
|
used_ptes = 0;
|
|
ptp = (PageTable *)(vmm_PDBR->pageTables[pde] & 0xFFFFF000);
|
|
for (pte = 0; pte < 1024; pte++)
|
|
{
|
|
if (ptp->page[pte] & 0x01) //page table entry present
|
|
used_ptes++;
|
|
}
|
|
if (!(used_ptes)) //no used pte's -- remove page table & page directory entry
|
|
{
|
|
mm_pfree(ptp);
|
|
vmm_PDBR->pageTables[pde] = 0;
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
void *malloc(dword bytes)
|
|
{
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
int free(void *ptr)
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|